mirror of
https://github.com/maierfelix/POGOserver.git
synced 2026-07-08 05:04:05 -05:00
Dump models and asset digest on first start
- Now dumps models and asset_digest on first start into /data - Reworked the route request routine - Added local ip4 display (is this ok?) - Model download urls are now routed to the server itself (need to get this more efficient) - Updated version to 0.3.4
This commit is contained in:
parent
31a230caf7
commit
8b61647a6d
10
cfg.js
10
cfg.js
|
|
@ -4,10 +4,8 @@ export default {
|
|||
MAX_CONNECTIONS: 64,
|
||||
PORT: 3000,
|
||||
GAME_MODE: 0,
|
||||
TICK_INTERVAL: 1,
|
||||
SAVE_INTERVAL: 60000,
|
||||
PLAYER_CONNECTION_TIMEOUT: 1800000,
|
||||
BOOT_TIMEOUT: 10000,
|
||||
MINIMUM_CLIENT_VERSION: "0.33.0",
|
||||
DEFAULT_CONSOLE_COLOR: 32,
|
||||
TRANSFER_ACCOUNTS: false,
|
||||
|
|
@ -40,6 +38,12 @@ export default {
|
|||
// Server debug options
|
||||
DEBUG_DUMP_PATH: "./logs/",
|
||||
DEBUG_DUMP_TRAFFIC: true,
|
||||
DEBUG_LOG_REQUESTS: true
|
||||
DEBUG_LOG_REQUESTS: true,
|
||||
|
||||
// Better dont touch these
|
||||
TICK_INTERVAL: 1,
|
||||
BOOT_TIMEOUT: 10000,
|
||||
// Currently supported pokemon
|
||||
MAX_POKEMON_NATIONAL_ID: 151
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "POGOServer",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.4",
|
||||
"description": "",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\"",
|
||||
"babel-node": "babel-node --presets=es2015",
|
||||
"start": "nodemon --ignore tmp/ --exec npm run babel-node -- ./src/index.js"
|
||||
"start": "nodemon --ignore tmp/ --ignore data/ --ignore logs/ --exec npm run babel-node -- ./src/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.x",
|
||||
|
|
|
|||
40
src/index.js
40
src/index.js
|
|
@ -43,6 +43,7 @@ class GameServer {
|
|||
collections: {}
|
||||
};
|
||||
|
||||
this.asset = null;
|
||||
this.socket = null;
|
||||
this.cycleInstance = null;
|
||||
|
||||
|
|
@ -57,6 +58,9 @@ class GameServer {
|
|||
this.clients = [];
|
||||
|
||||
this.greet();
|
||||
|
||||
this.print(`Booting Server v${require("../package.json").version}...`, 33);
|
||||
|
||||
this.setup();
|
||||
|
||||
}
|
||||
|
|
@ -77,40 +81,6 @@ class GameServer {
|
|||
|
||||
}
|
||||
|
||||
createAssetDownloadSession() {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
pogodown.login({
|
||||
provider: String(CFG.DOWNLOAD_PROVIDER).toLowerCase(),
|
||||
username: CFG.DOWNLOAD_USERNAME,
|
||||
password: CFG.DOWNLOAD_PASSWORD,
|
||||
downloadModels: false
|
||||
}).then((asset) => {
|
||||
if (asset && asset.digest && asset.digest.length) {
|
||||
this.print("Created asset download session");
|
||||
resolve(asset);
|
||||
}
|
||||
else {
|
||||
this.print("Failed to download asset digest!", 31);
|
||||
return void 0;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} assets
|
||||
*/
|
||||
generateDownloadUrlByAssetId(assets) {
|
||||
return new Promise((resolve) => {
|
||||
pogodown.getAssetByAssetId(assets).then((response) => {
|
||||
// maybe cache and provide own local download link?
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {HTTP}
|
||||
*/
|
||||
|
|
@ -134,7 +104,7 @@ class GameServer {
|
|||
let buffer = Buffer.concat(chunks);
|
||||
req.body = buffer;
|
||||
player.updateResponse(res);
|
||||
this.routeRequest(req);
|
||||
this.routeRequest(req, res);
|
||||
});
|
||||
});
|
||||
server.listen(CFG.PORT);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default function FortSearch(obj) {
|
|||
items_awarded: [
|
||||
new proto.Inventory.Item.ItemAward({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_MASTER_BALL,
|
||||
item_count: 10
|
||||
item_count: 3
|
||||
}),
|
||||
new proto.Inventory.Item.ItemAward({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_ULTRA_BALL,
|
||||
|
|
|
|||
|
|
@ -7,30 +7,8 @@ import CFG from "../../cfg";
|
|||
* @param {Request} req
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function GetAssetDigest(asset, req) {
|
||||
export default function GetAssetDigest(req) {
|
||||
|
||||
let data = proto.Networking.Requests.Messages.GetAssetDigestMessage.decode(req.request_message.toBuffer());
|
||||
|
||||
let digests = [];
|
||||
|
||||
asset.digest.map((item) => {
|
||||
digests.push(
|
||||
new proto.Data.AssetDigestEntry({
|
||||
asset_id: item.getAssetId(),
|
||||
bundle_name: item.getBundleName(),
|
||||
version: item.getVersion(),
|
||||
checksum: item.getChecksum(),
|
||||
size: item.getSize(),
|
||||
key: item.getKey()
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
new proto.Networking.Responses.GetAssetDigestResponse({
|
||||
timestamp_ms: new Date().getTime() * 1e3,
|
||||
digest: digests
|
||||
}).encode()
|
||||
);
|
||||
return (fs.readFileSync("data/asset_digest"));
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ import proto from "../proto";
|
|||
|
||||
import DownloadUrlEntry from "./Data.DownloadUrlEntry";
|
||||
|
||||
import CFG from "../../cfg";
|
||||
|
||||
import {
|
||||
getDownloadUrlByAssetId
|
||||
} from "../utils.js";
|
||||
|
|
@ -9,7 +11,7 @@ import {
|
|||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function GetDownloadUrls(asset, req, download) {
|
||||
export default function GetDownloadUrls(asset, ip, req) {
|
||||
|
||||
let data = proto.Networking.Requests.Messages.GetDownloadUrlsMessage.decode(req.request_message.toBuffer());
|
||||
|
||||
|
|
@ -26,25 +28,20 @@ export default function GetDownloadUrls(asset, req, download) {
|
|||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
|
||||
download(key).then((asset) => {
|
||||
console.log(node);
|
||||
download_urls.push(
|
||||
new proto.Data.DownloadUrlEntry({
|
||||
url: asset[0].asset,
|
||||
asset_id: key,
|
||||
size: parseInt(node.size),
|
||||
checksum: parseInt(node.checksum)
|
||||
})
|
||||
);
|
||||
let output = (
|
||||
new proto.Networking.Responses.GetDownloadUrlsResponse({
|
||||
download_urls: download_urls
|
||||
}).encode()
|
||||
);
|
||||
resolve(output);
|
||||
});
|
||||
|
||||
download_urls.push(
|
||||
new proto.Data.DownloadUrlEntry({
|
||||
asset_id: key,
|
||||
url: `http://${ip}:${CFG.PORT}/model/${node.bundle_name}`,
|
||||
size: node.size,
|
||||
checksum: node.checksum
|
||||
})
|
||||
);
|
||||
let output = (
|
||||
new proto.Networking.Responses.GetDownloadUrlsResponse({
|
||||
download_urls: download_urls
|
||||
}).encode()
|
||||
);
|
||||
resolve(output);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -11,9 +11,11 @@ import {
|
|||
*/
|
||||
export default function GetMapObjects(player, request) {
|
||||
|
||||
var cells = proto.Networking.Requests.Messages.GetMapObjectsMessage.decode(request.request_message.toBuffer()).cell_id;
|
||||
let cells = proto.Networking.Requests.Messages.GetMapObjectsMessage.decode(request.request_message.toBuffer()).cell_id;
|
||||
|
||||
var cellsRes = [];
|
||||
let cellsRes = [];
|
||||
|
||||
let pokemon_id = 121;
|
||||
|
||||
cells.forEach((cell) => {
|
||||
cellsRes.push(new proto.Map.MapCell({
|
||||
|
|
@ -59,7 +61,7 @@ export default function GetMapObjects(player, request) {
|
|||
longitude: longitude,
|
||||
spawn_point_id: "87bdd289c69",
|
||||
pokemon_data: new proto.Data.PokemonData({
|
||||
pokemon_id: 145,
|
||||
pokemon_id: pokemon_id,
|
||||
cp: 277,
|
||||
stamina: 41,
|
||||
stamina_max: 41,
|
||||
|
|
@ -80,7 +82,7 @@ export default function GetMapObjects(player, request) {
|
|||
new proto.Map.Pokemon.MapPokemon({
|
||||
spawn_point_id: "87bdd289c69",
|
||||
encounter_id: 11810991820755313517,
|
||||
pokemon_id: 145,
|
||||
pokemon_id: pokemon_id,
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
expiration_timestamp_ms: (new Date().getTime() + 1e6) * 1e3
|
||||
|
|
@ -90,7 +92,7 @@ export default function GetMapObjects(player, request) {
|
|||
cell.nearby_pokemons = [
|
||||
new proto.Map.Pokemon.NearbyPokemon({
|
||||
distance_in_meters: 200.0,
|
||||
pokemon_id: 145
|
||||
pokemon_id: pokemon_id
|
||||
})
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class Player {
|
|||
this.gender = 0;
|
||||
this.backpack = 0;
|
||||
|
||||
this.tutorial_state = [32, 1, 3, 4, 7];
|
||||
this.tutorial_state = [];
|
||||
|
||||
this.badges = null;
|
||||
this.pokedex = null;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import pogo from "node-pogo-protos";
|
||||
import path from "path";
|
||||
|
||||
export default pogo;
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import fs from "fs";
|
||||
import url from "url";
|
||||
import proto from "./proto";
|
||||
|
||||
import CFG from "../cfg";
|
||||
|
|
@ -9,6 +11,45 @@ import {
|
|||
|
||||
const REQUEST = proto.Networking.Requests.RequestType;
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
export function routeRequest(req, res) {
|
||||
|
||||
let player = this.getPlayerByRequest(req);
|
||||
|
||||
let parsed = url.parse(req.url).pathname;
|
||||
let route = parsed.split("/");
|
||||
let host = req.headers.host;
|
||||
|
||||
switch (route[1]) {
|
||||
case "plfe":
|
||||
case "custom":
|
||||
if (route[2] === "rpc") this.onRequest(req);
|
||||
break;
|
||||
case "model":
|
||||
// make sure no random dudes can access download
|
||||
if (!player.authenticated || !player.email_verified) return void 0;
|
||||
let name = route[2];
|
||||
if (name && name.length > 1) {
|
||||
fs.readFile("data/" + name, (error, data) => {
|
||||
if (error) {
|
||||
this.print(`Error file resolving model ${name}:` + error, 31);
|
||||
return void 0;
|
||||
}
|
||||
this.print(`Sent ${name} to ${player.email}`, 36);
|
||||
res.end(data);
|
||||
});
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown request url: https://${req.headers.host}${req.url}`);
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @return {String}
|
||||
|
|
@ -118,26 +159,6 @@ export function processRequests(player, requests) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
*/
|
||||
export function routeRequest(req) {
|
||||
|
||||
let url = String(req.url);
|
||||
let route = url.substring(url.lastIndexOf("/") + 1);
|
||||
let host = req.headers.host;
|
||||
|
||||
switch (route) {
|
||||
case "rpc":
|
||||
this.onRequest(req);
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown request url: https://${req.headers.host}${req.url}`);
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @return {Boolean}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ export function processResponse(player, req) {
|
|||
buffer = DownloadRemoteConfigVersion(req);
|
||||
break;
|
||||
case REQUEST.GET_ASSET_DIGEST:
|
||||
buffer = GetAssetDigest(this.asset, req);
|
||||
buffer = GetAssetDigest(req);
|
||||
break;
|
||||
case REQUEST.GET_PLAYER_PROFILE:
|
||||
buffer = GetPlayerProfile();
|
||||
|
|
@ -81,7 +81,7 @@ export function processResponse(player, req) {
|
|||
return void 0;
|
||||
break;
|
||||
case REQUEST.GET_DOWNLOAD_URLS:
|
||||
GetDownloadUrls(this.asset, req, this.generateDownloadUrlByAssetId).then((res) => {
|
||||
GetDownloadUrls(this.asset, this.getLocalIPv4(), req).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
return void 0;
|
||||
|
|
|
|||
107
src/setup.js
107
src/setup.js
|
|
@ -1,36 +1,91 @@
|
|||
import fs from "fs";
|
||||
import fse from "fs-extra";
|
||||
import pogo from "pogo-asset-downloader";
|
||||
import proto from "./proto";
|
||||
|
||||
import CFG from "../cfg";
|
||||
|
||||
export function setup() {
|
||||
|
||||
this.print(`Booting Server v${require("../package.json").version}...`, 33);
|
||||
let isFirstRun = !!fse.ensureDirSync("data/");
|
||||
|
||||
let assetSessionLoaded = false;
|
||||
if (isFirstRun) {
|
||||
this.print("Preparing to dump required assets..", 36);
|
||||
setTimeout(() => {
|
||||
this.onFirstRun(() => {
|
||||
this.setup();
|
||||
});
|
||||
}, 1e3);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (!assetSessionLoaded) {
|
||||
this.print("Boot timeout, please check your login details!", 31);
|
||||
this.asset = this.parseAssetDigest();
|
||||
|
||||
this.setupDatabaseConnection().then(() => {
|
||||
if (CFG.PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
}, CFG.BOOT_TIMEOUT);
|
||||
|
||||
this.createAssetDownloadSession().then((asset) => {
|
||||
assetSessionLoaded = true;
|
||||
this.asset = asset;
|
||||
this.setupDatabaseConnection().then(() => {
|
||||
|
||||
if (CFG.PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
this.socket = this.createHTTPServer();
|
||||
|
||||
setTimeout(this::this.cycle, 1);
|
||||
|
||||
let localIPv4 = this.getLocalIPv4();
|
||||
|
||||
this.print(`Server running at ${localIPv4}:${CFG.PORT}`);
|
||||
|
||||
});
|
||||
this.socket = this.createHTTPServer();
|
||||
setTimeout(this::this.cycle, 1);
|
||||
let localIPv4 = this.getLocalIPv4();
|
||||
this.print(`Server running at ${localIPv4}:${CFG.PORT}`);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export function parseAssetDigest() {
|
||||
let asset = null;
|
||||
try {
|
||||
asset = proto.Networking.Responses.GetAssetDigestResponse.decode(fs.readFileSync("data/asset_digest"));
|
||||
} catch (e) {
|
||||
this.print(e, 31);
|
||||
}
|
||||
return (asset);
|
||||
}
|
||||
|
||||
export function onFirstRun(resolve) {
|
||||
pogo.login({
|
||||
provider: CFG.DOWNLOAD_PROVIDER, // google or ptc
|
||||
username: CFG.DOWNLOAD_USERNAME,
|
||||
password: CFG.DOWNLOAD_PASSWORD
|
||||
}).then((asset) => {
|
||||
this.print(`Dumping asset digest..`, 35);
|
||||
fs.writeFileSync("data/asset_digest", asset.toBuffer());
|
||||
this.dumpPkmnModels(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function dumpPkmnModels(resolve) {
|
||||
|
||||
let limit = CFG.MAX_POKEMON_NATIONAL_ID;
|
||||
|
||||
const dump = (index) => {
|
||||
let ids = [];
|
||||
if (++index <= limit) ids.push(index);
|
||||
if (++index <= limit) ids.push(index);
|
||||
if (++index <= limit) ids.push(index);
|
||||
pogo.getAssetByPokemonId(ids).then((downloads) => {
|
||||
downloads.map((item) => {
|
||||
this.print(`Dumping model ${item.name}..`, 35);
|
||||
try {
|
||||
fs.writeFileSync("data/" + item.name, item.body);
|
||||
}
|
||||
catch (e) {
|
||||
this.print(`Error while dumping model ${item.name}:` + e, 31);
|
||||
}
|
||||
});
|
||||
if (index >= limit) {
|
||||
this.print(`Dumped ${limit} assets successfully!`);
|
||||
resolve();
|
||||
return void 0;
|
||||
}
|
||||
setTimeout(() => dump(index), 2e3);
|
||||
});
|
||||
};
|
||||
|
||||
dump(0);
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user