diff --git a/hack/kiwitest/kiwitest.js b/hack/kiwitest/kiwitest.js new file mode 100644 index 0000000..4702c49 --- /dev/null +++ b/hack/kiwitest/kiwitest.js @@ -0,0 +1,31 @@ +const socketio = require("socket.io-client"); + +const client = socketio("https://planetside-2-api.herokuapp.com", { + transports: ["websocket"], + extraHeaders: { + Origin: "https://ps2.nice.kiwi", + }, +}); + +client.on("connect", (e) => { + console.log("Connected to server", { e }); + client.emit("worlds-update-request"); +}); + +client.on("worlds-update", (e) => { + console.log(e); +}); + +client.on("disconnect", () => { + console.log("Disconnected from server"); +}); + +client.on("error", (e) => { + console.log({ error: e }); +}); + +client.on("connect_error", (e) => { + console.log({ + connectError: e, + }); +}); diff --git a/hack/kiwitest/package-lock.json b/hack/kiwitest/package-lock.json new file mode 100644 index 0000000..b05be92 --- /dev/null +++ b/hack/kiwitest/package-lock.json @@ -0,0 +1,443 @@ +{ + "name": "kiwitest", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "socket.io-client": "2.x", + "ws": "^8.11.0" + } + }, + "node_modules/after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", + "dev": true + }, + "node_modules/arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", + "dev": true + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", + "dev": true + }, + "node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/engine.io-client": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "dev": true, + "dependencies": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "dev": true, + "dependencies": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "node_modules/has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "dependencies": { + "isarray": "2.0.1" + } + }, + "node_modules/has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==", + "dev": true + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", + "dev": true + }, + "node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==", + "dev": true + }, + "node_modules/parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==", + "dev": true + }, + "node_modules/socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "dev": true, + "dependencies": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "node_modules/socket.io-parser": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", + "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", + "dev": true, + "dependencies": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==", + "dev": true + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==", + "dev": true + } + }, + "dependencies": { + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", + "dev": true + }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", + "dev": true + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "engine.io-client": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", + "integrity": "sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==", + "dev": true, + "requires": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.4.2", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + }, + "dependencies": { + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "requires": {} + } + } + }, + "engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", + "dev": true + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==", + "dev": true + }, + "parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==", + "dev": true + }, + "socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.3.tgz", + "integrity": "sha512-qOg87q1PMWWTeO01768Yh9ogn7chB9zkKtQnya41Y355S0UmpXgpcrFwAgjYJxu9BdKug5r5e9YtVSeWhKBUZg==", + "dev": true, + "requires": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==", + "dev": true + }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "requires": {} + }, + "xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", + "dev": true + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==", + "dev": true + } + } +} diff --git a/hack/kiwitest/package.json b/hack/kiwitest/package.json new file mode 100644 index 0000000..ba23408 --- /dev/null +++ b/hack/kiwitest/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "socket.io-client": "2.x", + "ws": "^8.11.0" + } +} diff --git a/hack/kiwitest/raw.js b/hack/kiwitest/raw.js new file mode 100644 index 0000000..048d655 --- /dev/null +++ b/hack/kiwitest/raw.js @@ -0,0 +1,22 @@ +const WebSocket = require("ws"); + +const wsc = new WebSocket( + "wss://planetside-2-api.herokuapp.com/socket.io/?EIO=3&transport=websocket", + { + origin: "https://ps2.nice.kiwi", + } +); + +wsc.on("open", () => { + wsc.send(`42["worlds-update-request"]`); +}); + +wsc.on("message", (e) => { + const messageRaw = e.toString(); + + if (messageRaw.startsWith("42")) { + const [event, message] = JSON.parse(messageRaw.slice(2)); + console.log({ message }); + wsc.close(); + } +}); diff --git a/src/cache.ts b/src/cache.ts index 1262ee6..a3797da 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -20,7 +20,7 @@ export class Cache { return item; } - async put(id: string, world: T): Promise { + async put(id: string, world: T, ttl: number = 60 * 3): Promise { if (this.disableCache) { return world; } @@ -28,7 +28,7 @@ export class Cache { this.cache.set(id, world); await this.kv.put(id, JSON.stringify(world), { - expirationTtl: 60 * 3, + expirationTtl: ttl, }); return world; diff --git a/src/fetcher.ts b/src/fetcher.ts index 50e1966..22c6809 100644 --- a/src/fetcher.ts +++ b/src/fetcher.ts @@ -1,6 +1,7 @@ import { Cache } from "./cache"; import { fisuFetchWorld } from "./sources/fisu"; import { honuFetchWorld } from "./sources/honu"; +import { kiwiFetchWorld } from "./sources/kiwi"; import { saerroFetchWorld } from "./sources/saerro"; import { voidwellFetchWorld } from "./sources/voidwell"; import { DebugPayload, Flags, OnePayload, ServiceResponse } from "./types"; @@ -33,7 +34,7 @@ export const getWorld = async (id: string, cache: Cache, flags: Flags) => { return cached; } - const [saerro, fisu, honu, voidwell] = await Promise.all([ + const [saerro, fisu, honu, voidwell, kiwi] = await Promise.all([ !flags.disableSaerro ? saerroFetchWorld(id, cache).catch((e) => { console.error("SAERRO ERROR:", e); @@ -53,6 +54,9 @@ export const getWorld = async (id: string, cache: Cache, flags: Flags) => { () => defaultServiceResponse ) : defaultServiceResponse, + !flags.disableKiwi + ? kiwiFetchWorld(id, cache).catch(() => defaultServiceResponse) + : defaultServiceResponse, ]); const debug: DebugPayload = { @@ -61,18 +65,21 @@ export const getWorld = async (id: string, cache: Cache, flags: Flags) => { fisu: fisu.raw, honu: honu.raw, voidwell: voidwell.raw, + kiwi: kiwi.raw, }, timings: { saerro: saerro?.timings || null, fisu: fisu?.timings || null, honu: honu?.timings || null, voidwell: voidwell?.timings || null, + kiwi: kiwi?.timings || null, }, lastFetchTimes: { saerro: saerro.cachedAt, fisu: fisu.cachedAt, honu: honu.cachedAt, voidwell: voidwell.cachedAt, + kiwi: kiwi.cachedAt, }, }; @@ -81,6 +88,7 @@ export const getWorld = async (id: string, cache: Cache, flags: Flags) => { fisu.population.total, honu.population.total, voidwell.population.total, + kiwi.population.total, ].filter((x) => x > 0); if (totalPopulations.length === 0) { @@ -127,6 +135,7 @@ export const getWorld = async (id: string, cache: Cache, flags: Flags) => { fisu: fisu.population.total, honu: honu.population.total, voidwell: voidwell.population.total, + kiwi: kiwi.population.total, }, }; diff --git a/src/handlers.ts b/src/handlers.ts index 487fbe4..b4f905f 100644 --- a/src/handlers.ts +++ b/src/handlers.ts @@ -38,7 +38,7 @@ export const handleAll = async ( flags: Flags ): Promise => { const cached = await cache.get(`all${debug ? ".debug" : ""}`); - if (cached) { + if (false && cached) { return new Response(JSON.stringify(cached), { headers: { "content-type": "application/json", diff --git a/src/index.ts b/src/index.ts index 252bb49..1a69b57 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,11 +35,14 @@ router } ) .get("/population~/health", async () => { - const [saerro, voidwell, honu, fisu] = await Promise.all([ + const [saerro, voidwell, honu, fisu, kiwi] = await Promise.all([ fetch("https://saerro.ps2.live/health").then((r) => r.status === 200), fetch("https://voidwell.com/").then((r) => r.status === 200), fetch("https://wt.honu.pw/api/health").then((r) => r.status === 200), fetch("https://ps2.fisu.pw").then((r) => r.status === 200), + fetch("https://planetside-2-api.herokuapp.com").then( + (r) => r.status === 200 + ), ]); return new Response( @@ -48,10 +51,11 @@ router voidwell, honu, fisu, + kiwi, }), { headers: { "content-type": "application/json" }, - status: saerro || voidwell || honu || fisu ? 200 : 502, + status: saerro || voidwell || honu || fisu || kiwi ? 200 : 502, } ); }) @@ -70,6 +74,7 @@ export default { disableHonu: env.DISABLE_HONU === "1", disableSaerro: env.DISABLE_SAERRO === "1", disableVoidwell: env.DISABLE_VOIDWELL === "1", + disableKiwi: env.DISABLE_KIWI === "1", voidwellUsePS4: env.VOIDWELL_USE_PS4 === "1", fisuUsePS4EU: env.FISU_USE_PS4EU === "1", }; diff --git a/src/sources/kiwi.ts b/src/sources/kiwi.ts new file mode 100644 index 0000000..3174026 --- /dev/null +++ b/src/sources/kiwi.ts @@ -0,0 +1,82 @@ +import { Cache } from "../cache"; +import { ServiceResponse } from "../types"; + +type KiwiResponse = { + worldId: number; + stats: { + population: { + nc: number; + tr: number; + vs: number; + total: number; + }; + }; +}[]; + +const kiwiFetchAllWorlds = async (cache: Cache): Promise => { + return new Promise(async (resolve, reject) => { + const cached = await cache.get("kiwi"); + if (cached) { + return cached; + } + let resp = await fetch( + "https://planetside-2-api.herokuapp.com/socket.io/?EIO=3&transport=websocket", + { + headers: { + Upgrade: "websocket", + Origin: "https://ps2.nice.kiwi", + }, + } + ); + const ws = resp.webSocket; + if (!ws) { + throw new Error("kiwi: No websocket"); + } + + ws.accept(); + + ws.addEventListener("message", async (e) => { + let payload = e.data as string; + if (payload.startsWith("42")) { + ws.close(); + + const [, data]: [string, KiwiResponse] = JSON.parse(payload.slice(2)); + await cache.put("kiwi", data); + resolve(data); + } + }); + + ws.send(`42["worlds-update-request"]`); + }); +}; + +export const kiwiFetchWorld = async ( + worldID: string, + cache: Cache +): Promise> => { + const start = Date.now(); + const resp = await kiwiFetchAllWorlds(cache); + const end = Date.now(); + + const data = resp.find((w) => w.worldId === Number(worldID)); + + if (!data) { + throw new Error(`kiwi: World ${worldID} not found`); + } + + return { + population: { + total: data.stats.population.total, + nc: data.stats.population.nc, + tr: data.stats.population.tr, + vs: data.stats.population.vs, + }, + raw: data, + cachedAt: new Date(), + timings: { + enter: start, + exit: end, + upstream: end - start, + }, + }; +}; diff --git a/src/sources/saerro.ts b/src/sources/saerro.ts index 2b56f75..37477b6 100644 --- a/src/sources/saerro.ts +++ b/src/sources/saerro.ts @@ -51,7 +51,7 @@ export const saerroFetchWorld = async ( const world = json.data.allWorlds.find((w) => w.id === Number(id)); if (!world) { - throw new Error(`World ${id} not found`); + throw new Error(`saerro: World ${id} not found`); } return { diff --git a/src/types.ts b/src/types.ts index c7faedc..b8c0c99 100644 --- a/src/types.ts +++ b/src/types.ts @@ -22,6 +22,7 @@ export interface Env { DISABLE_FISU: "1" | undefined; DISABLE_SAERRO: "1" | undefined; DISABLE_VOIDWELL: "1" | undefined; + DISABLE_KIWI: "1" | undefined; DISABLE_CACHE: "1" | undefined; VOIDWELL_USE_PS4: "1" | undefined; FISU_USE_PS4EU: "1" | undefined; @@ -40,6 +41,7 @@ export type OnePayload = { fisu: number | null; honu: number | null; voidwell: number | null; + kiwi: number | null; }; }; @@ -49,18 +51,21 @@ export type DebugPayload = { fisu: any; honu: any; voidwell: any; + kiwi: any; }; timings: { saerro: any; fisu: any; honu: any; voidwell: any; + kiwi: any; }; lastFetchTimes: { saerro?: Date; fisu?: Date; honu?: Date; voidwell?: Date; + kiwi?: Date; }; }; @@ -69,6 +74,7 @@ export type Flags = { disableFisu: boolean; disableSaerro: boolean; disableVoidwell: boolean; + disableKiwi: boolean; voidwellUsePS4: boolean; fisuUsePS4EU: boolean; }; diff --git a/wrangler.toml b/wrangler.toml index 3334206..54c769e 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -11,6 +11,7 @@ DISABLE_HONU = "0" DISABLE_FISU = "0" DISABLE_SAERRO = "0" DISABLE_VOIDWELL = "0" +DISABLE_KIWI = "0" DISABLE_CACHE = "0" VOIDWELL_USE_PS4 = "0" FISU_USE_PS4EU = "0"