mirror of
https://github.com/maierfelix/POGOserver.git
synced 2026-07-04 01:01:30 -05:00
Update
- Global shared print method - API hearbeat and reconnecting feature - Serialize avatar - Basic player authentication - New packet structure for classes - Safer url routing
This commit is contained in:
parent
c66efe50b4
commit
dbde45fe73
23
src/api.js
23
src/api.js
|
|
@ -2,6 +2,7 @@ import fs from "fs";
|
|||
import url from "url";
|
||||
import prompt from "prompt";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
prompt.start({
|
||||
|
|
@ -27,7 +28,7 @@ export function processApiCall(req, res, route) {
|
|||
try {
|
||||
json = JSON.parse(raw);
|
||||
} catch (e) {
|
||||
this.print(e, 31);
|
||||
print(e, 31);
|
||||
this.answerApiCall(res, "");
|
||||
return void 0;
|
||||
}
|
||||
|
|
@ -44,7 +45,7 @@ export function processApiCall(req, res, route) {
|
|||
this.answerApiCall(res, JSON.stringify(result));
|
||||
}
|
||||
else {
|
||||
this.print(`${hoster} isnt logged in! Kicking..`, 31);
|
||||
print(`${hoster} isnt logged in! Kicking..`, 31);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,11 +69,11 @@ export function grantApiAccess(req, res, route) {
|
|||
if (result.grant === "y" || result.grant === "yes") {
|
||||
save.allowedApiHosts.push(hoster);
|
||||
fs.writeFileSync(".save", JSON.stringify(save), "utf8");
|
||||
this.print(`Successfully added ${hoster} to allowed API hosts!`);
|
||||
print(`Successfully added ${hoster} to allowed API hosts!`);
|
||||
this.processApiCall(req, res, route);
|
||||
}
|
||||
else {
|
||||
this.print(`Denied API access for ${hoster}`, 31);
|
||||
print(`Denied API access for ${hoster}`, 31);
|
||||
this.answerApiCall(res, "");
|
||||
}
|
||||
});
|
||||
|
|
@ -104,9 +105,9 @@ export function api_login(data) {
|
|||
) {
|
||||
success = true;
|
||||
if (!this.apiClients[data.host]) {
|
||||
this.print(`API access for ${data.host} granted!`);
|
||||
print(`API access for ${data.host} granted!`);
|
||||
}
|
||||
this.print(`${data.host} logged in!`, 36);
|
||||
print(`${data.host} logged in!`, 36);
|
||||
this.apiClients[data.host] = {
|
||||
timestamp: +new Date()
|
||||
};
|
||||
|
|
@ -116,9 +117,15 @@ export function api_login(data) {
|
|||
});
|
||||
}
|
||||
|
||||
export function api_heartBeat() {
|
||||
return ({
|
||||
timestamp: +new Date()
|
||||
});
|
||||
}
|
||||
|
||||
export function api_getConnectedPlayers() {
|
||||
return ({
|
||||
connected_players: this.world.players.length
|
||||
connected_players: this.world.connectedPlayers
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +138,7 @@ export function api_getServerVersion() {
|
|||
export function api_spawnPkmnToPlayer(data) {
|
||||
let name = String(data.player);
|
||||
let pkmn = String(data.pkmn).toUpperCase();
|
||||
this.print(`Spawned 1x ${pkmn}'s to ${name}!`);
|
||||
print(`Spawned 1x ${pkmn}'s to ${name}!`);
|
||||
return ({
|
||||
success: true
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
export function startCycle() {
|
||||
|
|
@ -61,12 +62,12 @@ export function playerTimeoutTick() {
|
|||
let players = this.world.players;
|
||||
|
||||
let ii = 0;
|
||||
let length = players.length;
|
||||
let length = this.world.connectedPlayers;
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
player = players[ii];
|
||||
if (this.time - player.timeout >= maxTimeout) {
|
||||
this.print(`${player.remoteAddress} timed out`, 34);
|
||||
print(`${player.remoteAddress} timed out`, 34);
|
||||
this.savePlayer(player);
|
||||
this.removePlayer(player);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import fs from "fs";
|
||||
|
||||
import print from "../print";
|
||||
import CFG from "../../cfg";
|
||||
|
||||
export function createTableIfNotExists(name) {
|
||||
|
|
@ -30,7 +32,7 @@ export function createTables() {
|
|||
|
||||
export function createTable(name) {
|
||||
|
||||
this.print(`Creating table ${name}`, 36);
|
||||
print(`Creating table ${name}`, 36);
|
||||
|
||||
let query = `
|
||||
CREATE TABLE IF NOT EXISTS ${name} (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import mysql from "mysql";
|
||||
|
||||
import print from "../print";
|
||||
import CFG from "../../cfg";
|
||||
|
||||
export function setupDatabaseConnection() {
|
||||
|
|
@ -15,20 +16,20 @@ export function setupDatabaseConnection() {
|
|||
return new Promise((resolve) => {
|
||||
connection.connect((error) => {
|
||||
if (error) {
|
||||
this.print("MySQL " + error, 31);
|
||||
print("MySQL " + error, 31);
|
||||
this.retry("Retrying again in ", () => this.setupDatabaseConnection().then(resolve), 5);
|
||||
return void 0;
|
||||
}
|
||||
this.db = connection;
|
||||
this.createTableIfNotExists(CFG.MYSQL_USERS_TABLE).then(() => {
|
||||
this.createTableIfNotExists(CFG.MYSQL_OWNED_PKMN_TABLE).then(() => {
|
||||
this.print(`\x1b[36;1mMySQL\x1b[0m\x1b[32;1m connection established\x1b[0m`);
|
||||
print(`\x1b[36;1mMySQL\x1b[0m\x1b[32;1m connection established\x1b[0m`);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
connection.on("error", (error) => {
|
||||
this.print("MySQL " + error, 31);
|
||||
print("MySQL " + error, 31);
|
||||
this.retry("Trying to reconnect in ", () => this.setupDatabaseConnection().then(resolve), 5);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import fse from "fs-extra";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
/**
|
||||
|
|
@ -69,7 +70,7 @@ export function dumpTraffic(req, res) {
|
|||
let decoded = JSON.stringify(out, null, 2);
|
||||
fse.outputFileSync(CFG.DEBUG_DUMP_PATH + Date.now(), decoded);
|
||||
} catch (e) {
|
||||
this.print("Dump traffic: " + e, 31);
|
||||
print("Dump traffic: " + e, 31);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import http from "http";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
/**
|
||||
|
|
@ -8,7 +9,7 @@ import CFG from "../cfg";
|
|||
export function createHTTPServer() {
|
||||
let server = http.createServer((req, res) => {
|
||||
if (this.world.isFull()) {
|
||||
this.print(`Server is full! Refused ${req.headers.host}`, 31);
|
||||
print(`Server is full! Refused ${req.headers.host}`, 31);
|
||||
return void 0;
|
||||
}
|
||||
let chunks = [];
|
||||
|
|
@ -27,10 +28,10 @@ export function createHTTPServer() {
|
|||
|
||||
export function shutdown() {
|
||||
this.socket.close(() => {
|
||||
this.print("Closed http server!", 33);
|
||||
print("Closed http server!", 33);
|
||||
this.closeConnection(() => {
|
||||
this.print("Closed database connection!", 33);
|
||||
this.print("Server shutdown!", 31);
|
||||
print("Closed database connection!", 33);
|
||||
print("Server shutdown!", 31);
|
||||
setTimeout(() => process.exit(1), 2e3);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
17
src/index.js
17
src/index.js
|
|
@ -7,6 +7,7 @@ import {
|
|||
_toCC
|
||||
} from "./utils";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
import World from "./models/World";
|
||||
|
|
@ -59,7 +60,7 @@ export default class GameServer {
|
|||
|
||||
if (CFG.GREET) this.greet();
|
||||
|
||||
this.print(`Booting Server v${require("../package.json").version}-dev`, 33);
|
||||
print(`Booting Server v${require("../package.json").version}-dev`, 33);
|
||||
|
||||
this.world = new World(this);
|
||||
|
||||
|
|
@ -67,16 +68,6 @@ export default class GameServer {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} msg
|
||||
* @param {Number} color
|
||||
* @param {Boolean} nl
|
||||
*/
|
||||
print(msg, color, newline) {
|
||||
color = Number.isInteger(color) ? color : CFG.DEFAULT_CONSOLE_COLOR;
|
||||
process.stdout.write(`[Console] \x1b[${color};1m${msg}\x1b[0m${newline === void 0 ? "\n" : ""}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} obj
|
||||
* @return {Boolean}
|
||||
|
|
@ -96,7 +87,7 @@ export default class GameServer {
|
|||
retry(msg, fn, timer) {
|
||||
process.stdout.clearLine();
|
||||
process.stdout.cursorTo(0);
|
||||
this.print(`${msg}${timer}s`, 33, true);
|
||||
print(`${msg}${timer}s`, 33, true);
|
||||
if (timer >= 1) setTimeout(() => this.retry(msg, fn, --timer), 1e3);
|
||||
else {
|
||||
process.stdout.write("\n");
|
||||
|
|
@ -124,7 +115,7 @@ export default class GameServer {
|
|||
try {
|
||||
return POGOProtos.parseWithUnknown(buffer, schema);
|
||||
} catch (e) {
|
||||
this.print(e, 31);
|
||||
print(e, 31);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,4 +120,18 @@ export default class Avatar {
|
|||
}
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return ({
|
||||
skin: this.skin,
|
||||
hair: this.hair,
|
||||
shirt: this.shirt,
|
||||
pants: this.pants,
|
||||
hat: this.hat,
|
||||
shoes: this.shoes,
|
||||
eyes: this.eyes,
|
||||
gender: this.gender,
|
||||
backpack: this.backpack
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ export default class CandyBag {
|
|||
/**
|
||||
* @return {String}
|
||||
*/
|
||||
serializeCandies() {
|
||||
serialize() {
|
||||
|
||||
let str = "";
|
||||
let candies = this.candies;
|
||||
|
|
|
|||
47
src/models/Player/Tutorial/index.js
Normal file
47
src/models/Player/Tutorial/index.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import Candy from "./Candy";
|
||||
|
||||
/**
|
||||
* @class Tutorial
|
||||
*/
|
||||
export default class Tutorial {
|
||||
|
||||
/** @constructor */
|
||||
constructor() {
|
||||
|
||||
this.states = [];
|
||||
|
||||
this.LEGAL_SCREEN = 0;
|
||||
this.AVATAR_SELECTION = 1;
|
||||
this.ACCOUNT_CREATION = 2;
|
||||
this.POKEMON_CAPTURE = 3;
|
||||
this.NAME_SELECTION = 4;
|
||||
this.POKEMON_BERRY = 5;
|
||||
this.USE_ITEM = 6;
|
||||
this.FIRST_TIME_EXPERIENCE_COMPLETE = 7;
|
||||
this.POKESTOP_TUTORIAL = 8;
|
||||
this.GYM_TUTORIAL = 9;
|
||||
|
||||
}
|
||||
|
||||
passLegalScreen() {
|
||||
|
||||
}
|
||||
|
||||
passAvatarSelection() {
|
||||
|
||||
}
|
||||
|
||||
passAccountCreation() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Array}
|
||||
*/
|
||||
serialize() {
|
||||
return (
|
||||
this.states
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,14 @@
|
|||
import Avatar from "./Avatar";
|
||||
import MapObject from "../World/MapObject";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
import jwtDecode from "jwt-decode";
|
||||
|
||||
import print from "../../print";
|
||||
import CFG from "../../../cfg";
|
||||
|
||||
import * as _packets from "./packets";
|
||||
|
||||
import { inherit } from "../../utils";
|
||||
|
||||
import { GAME_MASTER } from "../../master";
|
||||
|
||||
|
|
@ -16,10 +25,30 @@ export default class Player extends MapObject {
|
|||
|
||||
super(null);
|
||||
|
||||
this.request = obj.request;
|
||||
this.response = obj.response;
|
||||
this.world = obj.world;
|
||||
|
||||
this._team = 0;
|
||||
|
||||
this.username = "unknown";
|
||||
|
||||
this._email = null;
|
||||
this.email_verified = false;
|
||||
|
||||
this.isPTCAccount = false;
|
||||
this.isGoogleAccount = false;
|
||||
|
||||
this.hasSignature = false;
|
||||
|
||||
this.authenticated = false;
|
||||
|
||||
this.request = null;
|
||||
this.response = null;
|
||||
|
||||
this.remoteAddress = null;
|
||||
|
||||
this.maxPkmnStorage = 250;
|
||||
this.maxItemStorage = 350;
|
||||
|
||||
this.authenticated = 0;
|
||||
/*
|
||||
this.bag = new Bag(this);
|
||||
this.info = new Info(this);
|
||||
|
|
@ -28,6 +57,96 @@ export default class Player extends MapObject {
|
|||
this.pokedex = new Pokedex(this);
|
||||
this.tutorial = new Tutorial(this);
|
||||
*/
|
||||
|
||||
this.refreshSocket(obj.request, obj.response);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
get team() {
|
||||
return (this._team);
|
||||
}
|
||||
set team(value) {
|
||||
this.team = value;
|
||||
}
|
||||
|
||||
get email() {
|
||||
return (this._email);
|
||||
}
|
||||
set email(value) {
|
||||
this.email = value;
|
||||
this.username = this.email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
sendResponse(buffer) {
|
||||
this.response.end(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
refreshSocket(req, res) {
|
||||
this.request = req;
|
||||
this.response = res;
|
||||
}
|
||||
|
||||
authenticate() {
|
||||
|
||||
let request = POGOProtos.parseWithUnknown(this.request.body, "POGOProtos.Networking.Envelopes.RequestEnvelope")
|
||||
|
||||
let msg = this.GetAuthTicket(request.request_id);
|
||||
|
||||
let token = request.auth_info;
|
||||
|
||||
if (!token || !token.provider) {
|
||||
print("Invalid authentication token! Kicking..", 31);
|
||||
this.world.removePlayer(this);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
if (token.provider === "google") {
|
||||
if (token.token !== null) {
|
||||
let decoded = jwtDecode(token.token.contents);
|
||||
this.email = decoded.email;
|
||||
this.email_verified = decoded.email_verified;
|
||||
this.isGoogleAccount = true;
|
||||
print(`${this.email} connected!`, 36);
|
||||
}
|
||||
else {
|
||||
print("Invalid authentication token! Kicking..", 31);
|
||||
this.world.removePlayer(this);
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
print("Invalid provider! Kicking..", 31);
|
||||
this.world.removePlayer(this);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
this.authenticated = true;
|
||||
|
||||
this.sendResponse(msg);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @param {Object} msg
|
||||
*/
|
||||
getPacket(type, msg) {
|
||||
return new Promise((resolve) => {
|
||||
switch (type) {
|
||||
case "GET_PLAYER":
|
||||
resolve(this.GetPlayer(msg));
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherit(Player, _packets);
|
||||
20
src/models/Player/packets/GetAuthTicket.js
Normal file
20
src/models/Player/packets/GetAuthTicket.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
export default function GetAuthTicket(id) {
|
||||
|
||||
let buffer = ({
|
||||
status_code: 53,
|
||||
request_id: id,
|
||||
api_url: "pgorelease.nianticlabs.com/custom",
|
||||
auth_ticket: {
|
||||
start: new Buffer(""),
|
||||
expire_timestamp_ms: 9999999999999,
|
||||
end: new Buffer("")
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Envelopes.ResponseEnvelope")
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
export function GetInventory() {
|
||||
export default function GetInventory() {
|
||||
|
||||
let stats = this.GetInventoryPlayer();
|
||||
let items = this.GetInventoryItems();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,25 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
export function GetPlayer() {
|
||||
/**
|
||||
* @param {Object} msg
|
||||
*/
|
||||
export default function GetPlayer(msg) {
|
||||
|
||||
return (POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetPlayerResponse"));
|
||||
let buffer = {
|
||||
creation_timestamp_ms: new Date().getTime(),
|
||||
username: this.username,
|
||||
team: this.team,
|
||||
tutorial_state: this.tutorial.serialize(),
|
||||
avatar: this.avatar.serialize(),
|
||||
max_pokemon_storage: this.maxPkmnStorage,
|
||||
max_item_storage: this.maxItemStorage,
|
||||
daily_bonus: {
|
||||
next_defender_bonus_collect_timestamp_ms: +new Date()
|
||||
},
|
||||
contact_settings: this.contact.serialize(),
|
||||
currencies: this.currencies.serialize()
|
||||
}
|
||||
|
||||
return (POGOProtos.serialize({ success: true, player_data: buffer }, "POGOProtos.Networking.Responses.GetPlayerResponse"));
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
export function GetPlayerProfile() {
|
||||
export default function GetPlayerProfile() {
|
||||
|
||||
return (POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetPlayerProfileResponse"));
|
||||
|
||||
|
|
|
|||
4
src/models/Player/packets/index.js
Normal file
4
src/models/Player/packets/index.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export GetPlayer from "./GetPlayer";
|
||||
export GetInventory from "./GetInventory";
|
||||
export GetAuthTicket from "./GetAuthTicket";
|
||||
export GetPlayerProfile from "./GetPlayerProfile";
|
||||
|
|
@ -18,12 +18,16 @@ export default class World {
|
|||
|
||||
}
|
||||
|
||||
get connectedPlayers() {
|
||||
return (this.players.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isFull() {
|
||||
return (
|
||||
this.players.length >= CFG.MAX_CONNECTIONS
|
||||
this.connectedPlayers >= CFG.MAX_CONNECTIONS
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -40,27 +44,25 @@ export default class World {
|
|||
return (player);
|
||||
}
|
||||
else {
|
||||
this.addPlayer(req, res);
|
||||
player = this.addPlayer(req, res);
|
||||
return (player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} client
|
||||
* @param {Request} req
|
||||
* @return {Boolean}
|
||||
*/
|
||||
playerAlreadyConnected(client) {
|
||||
|
||||
let players = this.players;
|
||||
playerAlreadyConnected(req) {
|
||||
|
||||
let ii = 0;
|
||||
let length = players.length;
|
||||
let length = this.connectedPlayers;
|
||||
|
||||
let remoteAddress = client.headers.host;
|
||||
let remoteAddress = req.headers.host;
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
if (players[ii].remoteAddress === remoteAddress) {
|
||||
if (this.players[ii].remoteAddress === remoteAddress) {
|
||||
return (true);
|
||||
}
|
||||
};
|
||||
|
|
@ -77,7 +79,7 @@ export default class World {
|
|||
let players = this.players;
|
||||
|
||||
let ii = 0;
|
||||
let length = players.length;
|
||||
let length = this.connectedPlayers;
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
if (players[ii].remoteAddress === ip) {
|
||||
|
|
@ -92,23 +94,29 @@ export default class World {
|
|||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @return {Player}
|
||||
*/
|
||||
addPlayer(req, res) {
|
||||
|
||||
let player = new Player({
|
||||
world: this,
|
||||
request: req,
|
||||
response: res
|
||||
});
|
||||
|
||||
player.remoteAddress = req.headers.host;
|
||||
|
||||
this.players.push(player);
|
||||
|
||||
return (player);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Player} player
|
||||
*/
|
||||
removePlayer(player) {
|
||||
console.log(player);
|
||||
console.log("Remove:", player.email);
|
||||
}
|
||||
|
||||
spawnFort() {
|
||||
|
|
@ -123,4 +131,18 @@ export default class World {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @param {Object} msg
|
||||
*/
|
||||
getPacket(type, msg) {
|
||||
return new Promise((resolve) => {
|
||||
switch (type) {
|
||||
case "CHECK_CHALLENGE":
|
||||
console.log(type, msg);
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
11
src/print.js
Normal file
11
src/print.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import CFG from "../cfg";
|
||||
|
||||
/**
|
||||
* @param {String} msg
|
||||
* @param {Number} color
|
||||
* @param {Boolean} nl
|
||||
*/
|
||||
export default function print(msg, color, newline) {
|
||||
color = Number.isInteger(color) ? color : CFG.DEFAULT_CONSOLE_COLOR;
|
||||
process.stdout.write(`[Console] \x1b[${color};1m${msg}\x1b[0m${newline === void 0 ? "\n" : ""}`);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import fs from "fs";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
const helpMessage = fs.readFileSync(".help", "utf8");
|
||||
|
|
@ -10,7 +11,7 @@ export function processCommand(cmd, data) {
|
|||
// How many active connections there are
|
||||
case "/players":
|
||||
var length = players.length;
|
||||
this.print(`${length}:${CFG.MAX_CONNECTIONS} connected players!`, 33);
|
||||
print(`${length}:${CFG.MAX_CONNECTIONS} connected players!`, 33);
|
||||
break;
|
||||
// Exit the server
|
||||
case "/exit":
|
||||
|
|
@ -23,7 +24,7 @@ export function processCommand(cmd, data) {
|
|||
var length = players.length;
|
||||
this.removeAllPlayers();
|
||||
var result = length - players.length;
|
||||
this.print(`Removed ${result} player${result === 1 ? "": "s"}!`);
|
||||
print(`Removed ${result} player${result === 1 ? "": "s"}!`);
|
||||
break;
|
||||
case "/clear":
|
||||
process.stdout.write("\x1Bc");
|
||||
|
|
@ -37,7 +38,7 @@ export function processCommand(cmd, data) {
|
|||
case "/save":
|
||||
this.saveAllPlayers();
|
||||
var length = players.length;
|
||||
this.print(`Saved ${length} player${length === 1 ? "": "s"} into database!`);
|
||||
print(`Saved ${length} player${length === 1 ? "": "s"} into database!`);
|
||||
break;
|
||||
case "/spawn":
|
||||
this.spawnPkmnAtPlayer(data[1], data[2], data[3] || 1);
|
||||
|
|
@ -46,7 +47,7 @@ export function processCommand(cmd, data) {
|
|||
eval(fs.readFileSync("update.js", "utf8"));
|
||||
break;
|
||||
default:
|
||||
this.print(`${cmd} is not a valid command!`, 31);
|
||||
print(`${cmd} is not a valid command!`, 31);
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
|
@ -62,15 +63,15 @@ export function stdinInput(data) {
|
|||
export function uncaughtException(excp) {
|
||||
switch (excp.errno) {
|
||||
case "EADDRINUSE":
|
||||
this.print(`Port ${CFG.PORT} is already in use!`, 31);
|
||||
print(`Port ${CFG.PORT} is already in use!`, 31);
|
||||
break;
|
||||
case "EACCES":
|
||||
this.print("No root privileges!", 31);
|
||||
print("No root privileges!", 31);
|
||||
break;
|
||||
default:
|
||||
console.log("Unhandled exception occurred: ", excp.code);
|
||||
console.log(excp.stack);
|
||||
break;
|
||||
};
|
||||
this.print("The server has crashed!", 31);
|
||||
print("The server has crashed!", 31);
|
||||
};
|
||||
|
|
@ -3,6 +3,7 @@ import url from "url";
|
|||
import pcrypt from "pcrypt";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
/**
|
||||
|
|
@ -36,16 +37,6 @@ export function routeRequest(req, res) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {Array} route
|
||||
*/
|
||||
export function processRpcRequest(req, res, route) {
|
||||
let player = this.world.getPlayerByRequest(req, res);
|
||||
if (route[2] === "rpc") this.onRequest(player, req);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
|
|
@ -62,16 +53,29 @@ export function processModelRequest(req, res, route) {
|
|||
let folder = player.isAndroid ? "android/" : "ios/";
|
||||
fs.readFile("data/" + folder + name, (error, data) => {
|
||||
if (error) {
|
||||
this.print(`Error file resolving model ${name}:` + error, 31);
|
||||
print(`Error file resolving model ${name}:` + error, 31);
|
||||
return void 0;
|
||||
}
|
||||
this.print(`Sent ${name} to ${player.email}`, 36);
|
||||
print(`Sent ${name} to ${player.email}`, 36);
|
||||
res.end(data);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
* @param {Array} route
|
||||
*/
|
||||
export function processRpcRequest(req, res, route) {
|
||||
let player = this.world.getPlayerByRequest(req, res);
|
||||
if (route[2] === "rpc") {
|
||||
player.refreshSocket(req, res);
|
||||
this.onRequest(player, req);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Player} player
|
||||
* @param {Request} req
|
||||
|
|
@ -89,12 +93,12 @@ export function onRequest(player, req) {
|
|||
}
|
||||
|
||||
if (!player.authenticated) {
|
||||
player.sendResponse(this.authenticatePlayer(player));
|
||||
player.authenticate();
|
||||
return void 0;
|
||||
}
|
||||
|
||||
if (!request.requests.length) {
|
||||
this.print("Received invalid request!", 31);
|
||||
print("Received invalid request!", 31);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +136,7 @@ export function envelopResponse(status, returns, req, player, auth) {
|
|||
player.isAndroid = !player.isIOS;
|
||||
player.hasSignature = true;
|
||||
player.asset_digest = this.assets[player.isAndroid ? "android" : "ios"];
|
||||
this.print(`${player.email} is playing with an ${player.isIOS ? "Apple" : "Android"} device!`, 36);
|
||||
print(`${player.email} is playing with an ${player.isIOS ? "Apple" : "Android"} device!`, 36);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
import {
|
||||
|
|
@ -8,16 +9,17 @@ import {
|
|||
} from "./utils";
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Request} req
|
||||
* @param {String} type
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export function parseMessage(req) {
|
||||
let proto = `POGOProtos.Networking.Requests.Messages.${cc}Message`;
|
||||
export function parseMessage(req, type) {
|
||||
let proto = `POGOProtos.Networking.Requests.Messages.${type}Message`;
|
||||
if (req.request_message) {
|
||||
try {
|
||||
return (this.parseProtobuf(req.request_message, proto));
|
||||
} catch (e) {
|
||||
this.print(`Failed to parse ${cc}: ${e}`, 31);
|
||||
print(`Failed to parse ${type}: ${e}`, 31);
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
|
|
@ -33,18 +35,30 @@ export function processResponse(player, req) {
|
|||
let buffer = null;
|
||||
|
||||
let cc = _toCC(req.request_type);
|
||||
let msg = this.parseMessage(req);
|
||||
let msg = this.parseMessage(req, cc);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
|
||||
try {
|
||||
switch (req.request_type) {
|
||||
case "GET_PLAYER":
|
||||
player.getPacket("GET_PLAYER", msg).then((result) => {
|
||||
resolve(result);
|
||||
});
|
||||
return void 0;
|
||||
break;
|
||||
case "CHECK_CHALLENGE":
|
||||
player.world.getPacket("CHECK_CHALLENGE", msg).then((result) => {
|
||||
resolve(result);
|
||||
});
|
||||
return void 0;
|
||||
break;
|
||||
default:
|
||||
this.print(`Unknown request: ${req.request_type}`, 31);
|
||||
print(`Unknown request: ${req.request_type}`, 31);
|
||||
break;
|
||||
};
|
||||
} catch (e) {
|
||||
this.print(`Response error: ${e}`, 31);
|
||||
print(`Response error: ${e}`, 31);
|
||||
};
|
||||
|
||||
resolve(buffer);
|
||||
|
|
|
|||
27
src/setup.js
27
src/setup.js
|
|
@ -3,6 +3,7 @@ import fse from "fs-extra";
|
|||
import pogo from "pogo-asset-downloader";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
import * as master from "./master";
|
||||
|
|
@ -19,7 +20,7 @@ export function setup() {
|
|||
let save = JSON.parse(fs.readFileSync(".save", "utf8"));
|
||||
|
||||
if (save.isFirstRun) {
|
||||
this.print("Required assets are missing! Preparing dump session..", 33);
|
||||
print("Required assets are missing! Preparing dump session..", 33);
|
||||
setTimeout(() => {
|
||||
this.onFirstRun(() => {
|
||||
save.isFirstRun = false;
|
||||
|
|
@ -33,7 +34,7 @@ export function setup() {
|
|||
// make sure all assets got loaded properly
|
||||
this.validateAssets().then(() => {
|
||||
|
||||
this.print(`Downloaded assets are valid! Proceeding..`);
|
||||
print(`Downloaded assets are valid! Proceeding..`);
|
||||
|
||||
master.GAME_MASTER = this.parseGameMaster();
|
||||
|
||||
|
|
@ -41,18 +42,18 @@ export function setup() {
|
|||
|
||||
this.setupDatabaseConnection().then(() => {
|
||||
if (CFG.PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
this.socket = this.createHTTPServer();
|
||||
setTimeout(this::this.cycle, 1);
|
||||
let localIPv4 = this.getLocalIPv4();
|
||||
this.print(`Server listening at ${localIPv4}:${CFG.PORT}`, 33);
|
||||
print(`Server listening at ${localIPv4}:${CFG.PORT}`, 33);
|
||||
});
|
||||
|
||||
}).catch((e) => {
|
||||
//fse.removeSync(CFG.DUMP_ASSET_PATH);
|
||||
this.print("Error: " + e + " was not found!", 31);
|
||||
print("Error: " + e + " was not found!", 31);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -131,7 +132,7 @@ export function parseGameMaster() {
|
|||
master = this.parseProtobuf(data, "POGOProtos.Networking.Responses.DownloadItemTemplatesResponse");
|
||||
let Master = new GameMaster(master);
|
||||
} catch (e) {
|
||||
this.print(e, 31);
|
||||
print(e, 31);
|
||||
}
|
||||
return (master);
|
||||
}
|
||||
|
|
@ -147,7 +148,7 @@ export function onFirstRun(resolve) {
|
|||
this.downloadAssets().then(resolve);
|
||||
});
|
||||
}).catch((e) => {
|
||||
this.print(e, 31);
|
||||
print(e, 31);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -189,11 +190,11 @@ export function downloadModels() {
|
|||
let caps = capitalize(name);
|
||||
caps = name === "ios" ? "iOS" : caps;
|
||||
pogo.setPlatform(name);
|
||||
this.print(`Preparing to dump ${caps} assets..`, 36);
|
||||
print(`Preparing to dump ${caps} assets..`, 36);
|
||||
this.dumpPkmnModels(CFG.DUMP_ASSET_PATH + name + "/", () => {
|
||||
this.print(`Dumped ${CFG.MAX_POKEMON_NATIONAL_ID} ${caps} assets successfully!`);
|
||||
print(`Dumped ${CFG.MAX_POKEMON_NATIONAL_ID} ${caps} assets successfully!`);
|
||||
if (++index >= limit) {
|
||||
this.print("Dumped all assets successfully!");
|
||||
print("Dumped all assets successfully!");
|
||||
resolve();
|
||||
return void 0;
|
||||
}
|
||||
|
|
@ -216,16 +217,16 @@ export function dumpPkmnModels(path, resolve) {
|
|||
if (++index <= limit) ids.push(index);
|
||||
pogo.getAssetByPokemonId(ids).then((downloads) => {
|
||||
downloads.map((item) => {
|
||||
this.print(`Dumping model ${item.name}..`, 35);
|
||||
print(`Dumping model ${item.name}..`, 35);
|
||||
try {
|
||||
fs.writeFileSync(path + item.name, item.body);
|
||||
}
|
||||
catch (e) {
|
||||
this.print(`Error while dumping model ${item.name}:` + e, 31);
|
||||
print(`Error while dumping model ${item.name}:` + e, 31);
|
||||
}
|
||||
});
|
||||
if (index >= limit) {
|
||||
//this.print(`Dumped ${limit} assets successfully!`);
|
||||
//print(`Dumped ${limit} assets successfully!`);
|
||||
resolve();
|
||||
return void 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user