- Refactored config
- Fixed mongodb bug, where player avatar didnt got saved into db
- Deleted requests.js, instead use protobuf
- Player parallelism should work now, dont share instanced player object
anymore *facepalm*
- Updated version
This commit is contained in:
Felix 2016-08-19 12:19:48 +02:00
parent 0df066ff3c
commit 31a230caf7
26 changed files with 276 additions and 355 deletions

80
cfg.js
View File

@ -1,51 +1,45 @@
export const MINIMUM_CLIENT_VERSION = "0.33.0";
export default {
export const SERVER_GAME_MODE = 0;
export const SERVER_TICK_INTERVAL = 1; // better dont change
export const SERVER_SAVE_INTERVAL = 1e3 * 60; // 1min
export const SERVER_MAX_CONNECTIONS = 64;
export const SERVER_PLAYER_CONNECTION_TIMEOUT = 1e3 * 60 * 30; // 30min
// Server settings
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,
export const SERVER_BOOT_TIMEOUT = 10e3;
// Choose a database type
DATABASE_TYPE: "MYSQL",
export const SERVER_DEFAULT_CONSOLE_COLOR = 32;
// MySQL credentials
MYSQL_PORT: 3306,
MYSQL_HOST_IP: "127.0.0.1",
MYSQL_DB_NAME: "pogosql",
MYSQL_USERNAME: "root",
MYSQL_PASSWORD: "",
MYSQL_TABLE: "users",
// HTTP
export const SERVER_PORT = 3000;
export const SERVER_HOST_IP = "127.0.0.1";
// MongoDB credentials
MONGO_PORT: 27017,
MONGO_HOST_IP: "127.0.0.1",
MONGO_DB_NAME: "pokemongo",
MONGO_COLLECTION_USERS: "users",
// Either mongo or mysql
export const SERVER_USE_DATABASE = "MONGO";
// Used for asset download session
DOWNLOAD_PROVIDER: "GOOGLE",
DOWNLOAD_USERNAME: "USERNAME",
DOWNLOAD_PASSWORD: "PASSWORD",
// MONGODB
export const SERVER_MONGO_PORT = 27017;
export const SERVER_MONGO_HOST_IP = "127.0.0.1";
export const SERVER_MONGO_DB_NAME = "pokemongo";
export const SERVER_MONGO_COLLECTION_USERS = "users";
// Google maps api key
GMAPS_KEY: "AIzaSyDF9rkP8lhcddBtvH9gVFzjnNo13WtmJIM",
// MYSQL
export const SERVER_MYSQL_PORT = 3306;
export const SERVER_MYSQL_HOST_IP = "127.0.0.1";
export const SERVER_MYSQL_DB_NAME = "pogosql";
export const SERVER_MYSQL_USERNAME = "root";
export const SERVER_MYSQL_PASSWORD = "";
export const SERVER_MYSQL_TABLE = "users";
// Server debug options
DEBUG_DUMP_PATH: "./logs/",
DEBUG_DUMP_TRAFFIC: true,
DEBUG_LOG_REQUESTS: true
// account used for pogo-asset-downloader lib
export const SERVER_POGO_CLIENT_PROVIDER = "GOOGLE"; // either google or ptc
export const SERVER_POGO_CLIENT_USERNAME = "USERNAME";
export const SERVER_POGO_CLIENT_PASSWORD = "PASSWORD";
export const SERVER_GMAPS_API_KEY = "AIzaSyDF9rkP8lhcddBtvH9gVFzjnNo13WtmJIM";
// path to save logs into
export const SERVER_DUMP_PATH = "./logs/";
// save traffic dumps into /logs
export const SERVER_DUMP_TRAFFIC = true;
// show request types in console
export const SERVER_LOG_REQUESTS = true;
// transfer account progress from official servers
export const SERVER_CLONE_NEW_ACCOUNTS_FROM_OFFICIAL_SERVER = false;
}

View File

@ -1,6 +1,6 @@
{
"name": "POGOServer",
"version": "0.3.1",
"version": "0.3.2",
"description": "",
"repository": {
"type": "git",

View File

@ -1,7 +1,7 @@
import * as CFG from "../cfg";
import CFG from "../cfg";
export function startCycle() {
this.cycleInstance = setTimeout(() => this.cycle(), CFG.SERVER_TICK_INTERVAL);
this.cycleInstance = setTimeout(() => this.cycle(), CFG.TICK_INTERVAL);
}
export function stopCycle() {
@ -48,7 +48,7 @@ export function resetTimers() {
}
this.saveTick++;
// Save interval
if (this.saveTick >= CFG.SERVER_SAVE_INTERVAL) {
if (this.saveTick >= CFG.SAVE_INTERVAL) {
this.saveAllPlayers();
this.saveTick = 0;
}
@ -58,7 +58,7 @@ export function resetTimers() {
export function playerTimeoutTick() {
let client = null;
let maxTimeout = CFG.SERVER_PLAYER_CONNECTION_TIMEOUT;
let maxTimeout = CFG.PLAYER_CONNECTION_TIMEOUT;
let ii = 0, length = this.clients.length;

View File

@ -1,10 +1,10 @@
import mongodb from "mongodb";
import * as CFG from "../../cfg";
import CFG from "../../cfg";
export function setupConnection() {
let url = `mongodb://${CFG.SERVER_MONGO_HOST_IP}:${CFG.SERVER_MONGO_PORT}/${CFG.SERVER_MONGO_DB_NAME}`;
let url = `mongodb://${CFG.MONGO_HOST_IP}:${CFG.MONGO_PORT}/${CFG.MONGO_DB_NAME}`;
return new Promise((resolve) => {
mongodb.MongoClient.connect(url, (error, db) => {
@ -14,7 +14,7 @@ export function setupConnection() {
return void 0;
} else {
this.db.instance = db;
this.loadCollection(CFG.SERVER_MONGO_COLLECTION_USERS).then(() => {
this.loadCollection(CFG.MONGO_COLLECTION_USERS).then(() => {
this.print(`\x1b[36;1mMongoDB\x1b[0m\x1b[32;1m connection established\x1b[0m`);
resolve();
});
@ -81,7 +81,7 @@ export function getUserByEmail(email) {
export function getUserCollection() {
return (
this.db.instance.collection(CFG.SERVER_MONGO_COLLECTION_USERS)
this.db.instance.collection(CFG.MONGO_COLLECTION_USERS)
);
}
@ -133,14 +133,14 @@ export function getUserData(obj) {
team: obj.team,
skin: obj.skin,
hair: obj.skin,
shirt: obj.skin,
pants: obj.skin,
hat: obj.skin,
shoes: obj.skin,
eyes: obj.skin,
gender: obj.skin,
backpack: obj.skin,
hair: obj.hair,
shirt: obj.shirt,
pants: obj.pants,
hat: obj.hat,
shoes: obj.shoes,
eyes: obj.eyes,
gender: obj.gender,
backpack: obj.backpack,
latitude: obj.latitude,
longitude: obj.latitude,

View File

@ -1,15 +1,15 @@
import mysql from "mysql";
import * as CFG from "../../cfg";
import CFG from "../../cfg";
export function setupConnection() {
let connection = mysql.createConnection({
host : CFG.SERVER_MYSQL_HOST_IP,
port : CFG.SERVER_MYSQL_PORT,
database : CFG.SERVER_MYSQL_DB_NAME,
user : CFG.SERVER_MYSQL_USERNAME,
password : CFG.SERVER_MYSQL_PASSWORD
host : CFG.MYSQL_HOST_IP,
port : CFG.MYSQL_PORT,
database : CFG.MYSQL_DB_NAME,
user : CFG.MYSQL_USERNAME,
password : CFG.MYSQL_PASSWORD
});
return new Promise((resolve) => {
@ -44,13 +44,13 @@ export function closeConnection(resolve) {
export function createTableIfNoExists() {
return new Promise((resolve) => {
this.db.instance.query(`SHOW TABLES LIKE '${CFG.SERVER_MYSQL_TABLE}';`, (e, rows, fields) => {
this.db.instance.query(`SHOW TABLES LIKE '${CFG.MYSQL_TABLE}';`, (e, rows, fields) => {
if (e) console.log(e);
else {
// exists
if (rows && rows.length) resolve();
// create user table
else this.createTable(CFG.SERVER_MYSQL_TABLE).then(resolve);
else this.createTable(CFG.MYSQL_TABLE).then(resolve);
}
});
});
@ -60,7 +60,7 @@ export function createTableIfNoExists() {
* @param {String} name
*/
export function createTable(name) {
this.print(`Creating table ${CFG.SERVER_MYSQL_TABLE}`, 36);
this.print(`Creating table ${CFG.MYSQL_TABLE}`, 36);
return new Promise((resolve) => {
let query = `
CREATE TABLE ${name} (
@ -100,7 +100,7 @@ export function createTable(name) {
*/
export function getUserByEmail(email) {
return new Promise((resolve) => {
this.db.instance.query(`SELECT * FROM ${CFG.SERVER_MYSQL_TABLE} WHERE email=? LIMIT 1`, [email], (e, rows, fields) => {
this.db.instance.query(`SELECT * FROM ${CFG.MYSQL_TABLE} WHERE email=? LIMIT 1`, [email], (e, rows, fields) => {
if (e) console.log(e);
if (rows && rows.length) resolve(rows[0]);
else resolve(void 0);
@ -141,7 +141,7 @@ export function updateUser(obj) {
*/
export function getUserQuery(cmd, after) {
return (`
${cmd} ${CFG.SERVER_MYSQL_TABLE}
${cmd} ${CFG.MYSQL_TABLE}
SET
username=?,
email=?,

View File

@ -1,4 +1,5 @@
import fs from "fs";
import os from "os";
import fse from "fs-extra";
import http from "http";
import proto from "./proto";
@ -8,7 +9,7 @@ import {
inherit
} from "./utils";
import * as CFG from "../cfg";
import CFG from "../cfg";
import pogodown from "pogo-asset-downloader";
@ -42,11 +43,7 @@ class GameServer {
collections: {}
};
this.proto = null;
this.socket = null;
this.player = null;
this.request = null;
this.response = null;
this.cycleInstance = null;
// Timer things
@ -84,9 +81,9 @@ class GameServer {
return new Promise((resolve) => {
pogodown.login({
provider: String(CFG.SERVER_POGO_CLIENT_PROVIDER).toLowerCase(),
username: CFG.SERVER_POGO_CLIENT_USERNAME,
password: CFG.SERVER_POGO_CLIENT_PASSWORD,
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) {
@ -119,15 +116,16 @@ class GameServer {
*/
createHTTPServer() {
let server = http.createServer((req, res) => {
if (this.clients.length >= CFG.SERVER_MAX_CONNECTIONS) {
if (this.clients.length >= CFG.MAX_CONNECTIONS) {
this.print(`Server is full! Refused ${req.headers.host}`, 31);
return void 0;
}
this.response = res;
// client already connected
if (!this.clientAlreadyConnected(req)) {
this.addPlayer(req);
}
let player = null;
if (this.clientAlreadyConnected(req)) player = this.getPlayerByRequest(req);
else player = this.addPlayer(req, res);
let chunks = [];
req.on("data", (chunk) => {
chunks.push(chunk);
@ -135,11 +133,11 @@ class GameServer {
req.on("end", () => {
let buffer = Buffer.concat(chunks);
req.body = buffer;
this.request = req;
this.routeRequest(req, res);
player.updateResponse(res);
this.routeRequest(req);
});
});
server.listen(CFG.SERVER_PORT);
server.listen(CFG.PORT);
return (server);
}
@ -147,7 +145,7 @@ class GameServer {
return new Promise((resolve) => {
let name = String(CFG.SERVER_USE_DATABASE).toUpperCase();
let name = String(CFG.DATABASE_TYPE).toUpperCase();
switch (name) {
case "MONGO":
@ -186,7 +184,7 @@ class GameServer {
* @param {Boolean} nl
*/
print(msg, color, nl) {
color = Number.isInteger(color) ? color : CFG.SERVER_DEFAULT_CONSOLE_COLOR;
color = Number.isInteger(color) ? color : CFG.DEFAULT_CONSOLE_COLOR;
process.stdout.write(`[Console] \x1b[${color};1m${msg}\x1b[0m${nl === void 0 ? "\n" : ""}`);
}
@ -216,13 +214,25 @@ class GameServer {
try {
let decoded = JSON.stringify(decode(req, res, opts), null, 2);
fse.outputFileSync(CFG.SERVER_DUMP_PATH + Date.now(), decoded);
fse.outputFileSync(CFG.DEBUG_DUMP_PATH + Date.now(), decoded);
} catch (e) {
this.print("Dump traffic: " + e, 31);
}
}
getLocalIPv4() {
let address = null;
let interfaces = os.networkInterfaces();
for (var dev in interfaces) {
interfaces[dev].filter((details) => details.family === "IPv4" && details.internal === false ? address = details.address: void 0);
};
return (address);
}
greet() {
console.log(greetMessage);
}

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,6 +1,6 @@
import proto from "../proto";
import * as CFG from "../../cfg";
import CFG from "../../cfg";
/**
* @param {Request} req
@ -30,7 +30,7 @@ export default function DownloadSettings(req) {
"get_map_objects_min_refresh_seconds": 10.007843017578125,
"get_map_objects_max_refresh_seconds": 30.01568603515625,
"get_map_objects_min_distance_meters": 10.007843017578125,
"google_maps_api_key": CFG.SERVER_GMAPS_API_KEY
"google_maps_api_key": CFG.GMAPS_KEY
}),
inventory_settings: new proto.Settings.InventorySettings({
"max_pokemon": 1000,

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";
@ -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: 3
item_count: 10
}),
new proto.Inventory.Item.ItemAward({
item_id: proto.Inventory.Item.ItemId.ITEM_ULTRA_BALL,

View File

@ -1,7 +1,7 @@
import fs from "fs";
import proto from "../proto";
import * as CFG from "../../cfg";
import CFG from "../../cfg";
/**
* @param {Request} req

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,6 +1,6 @@
import proto from "../proto";
import * as CFG from "../../cfg";
import CFG from "../../cfg";
/**
* @param {Object} obj

View File

@ -1,4 +1,4 @@
import * as CFG from "../../cfg";
import CFG from "../../cfg";
import proto from "../proto";

View File

@ -1,12 +1,19 @@
import proto from "./proto";
import * as CFG from "../cfg";
import CFG from "../cfg";
import {
getHashCodeFrom,
decodeRequestEnvelope
} from "./utils";
import {
ResponseEnvelope,
ResponseEnvelopeAuth
} from "./packets";
import jwtDecode from "jwt-decode";
import { GetPlayer } from "./packets";
/**
@ -55,7 +62,9 @@ class Player {
this.isPTCAccount = false;
this.isGoogleAccount = false;
this.response = obj.response;
this.request = obj.request;
// gets updated after each chunk end event
this.response = null;
this.connection = obj.connection;
this.timeout = obj.timeout;
@ -77,6 +86,20 @@ class Player {
this.uid = getHashCodeFrom(String(email));
}
/**
* @param {Buffer} buffer
*/
sendResponse(buffer) {
this.response.end(buffer);
}
/**
* @param {Response} res
*/
updateResponse(res) {
this.response = res;
}
updateByObject(obj) {
for (let key in obj) {
if (this.hasOwnProperty(key)) {
@ -199,18 +222,23 @@ export function getPlayerByName(name) {
/**
* @param {Request} req
* @return {Player}
*/
export function addPlayer(req) {
let connection = req.connection;
this.clients.push(new Player({
let player = new Player({
timeout: this.time,
connection: connection,
response: this.response,
request: req,
remotePort: connection.remotePort,
remoteAddress: req.headers.host
}));
});
this.clients.push(player);
return (player);
}
@ -283,24 +311,10 @@ export function savePlayer(player) {
});
}
export function loginPlayer() {
let buffer = null;
let player = this.player;
return new Promise((resolve) => {
this.getUserByEmail(player.email).then((doc) => {
player.updateByObject(doc);
buffer = GetPlayer(player).encode();
resolve(buffer);
});
});
}
export function forwardPlayer() {
let player = this.player;
/**
* @param {Player} player
*/
export function forwardPlayer(player) {
return new Promise((resolve) => {
this.getUserByEmail(player.email).then((doc) => {
@ -309,12 +323,12 @@ export function forwardPlayer() {
this.print(`${player.email.replace("@gmail.com", "")} authenticated via ${provider}!`, 36);
}
if (doc) {
this.loginPlayer().then((res) => {
this.loginPlayer(player).then((res) => {
resolve(res);
});
}
else {
this.registerPlayer().then((res) => {
this.registerPlayer(player).then((res) => {
resolve(res);
});
}
@ -323,18 +337,90 @@ export function forwardPlayer() {
}
export function registerPlayer() {
/**
* @param {Player} player
*/
export function loginPlayer(player) {
let player = this.player;
return new Promise((resolve) => {
this.getUserByEmail(player.email).then((doc) => {
player.updateByObject(doc);
let buffer = GetPlayer(player).encode();
resolve(buffer);
});
});
}
/**
* @param {Player} player
*/
export function registerPlayer(player) {
return new Promise((resolve) => {
this.createUser(player).then(() => {
this.print(`${this.player.email.replace("@gmail.com", "")} registered!`, 36);
this.print(`${player.email.replace("@gmail.com", "")} registered!`, 36);
player.tutorial_state = [];
this.loginPlayer().then((res) => {
this.loginPlayer(player).then((res) => {
resolve(res);
});
});
});
}
}
/**
* @param {Player} player
* @return {Buffer}
*/
export function authenticatePlayer(player) {
let request = decodeRequestEnvelope(player.request.body);
let msg = ResponseEnvelopeAuth({
id: request.request_id
});
let token = request.auth_info;
// TODO: Support PTC server authentification
if (!token || !token.provider) {
this.print("Invalid authentication token! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
if (token.provider === "google") {
if (token.token !== null) {
let decoded = jwtDecode(token.token.contents);
player.generateUid(decoded.email);
player.email = decoded.email;
player.email_verified = decoded.email_verified;
player.isGoogleAccount = true;
this.print(`${player.email.replace("@gmail.com", "")} connected!`, 36);
}
else {
this.print("Invalid authentication token! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
}
else if (token.provider === "ptc") {
let decoded = token.token.contents;
player.isPTCAccount = true;
this.print("PTC auth isnt supported yet! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
else {
this.print("Invalid provider! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
player.authenticated = true;
return (msg);
}

View File

@ -1,6 +1,6 @@
import fs from "fs";
import * as CFG from "../cfg";
import CFG from "../cfg";
const helpMessage = fs.readFileSync(".help", "utf8");
@ -9,7 +9,7 @@ export function processCommand(cmd, data) {
// How many active connections there are
case "/clients":
var length = this.clients.length;
this.print(`${length}:${CFG.SERVER_MAX_CONNECTIONS} connected players!`, 33);
this.print(`${length}:${CFG.MAX_CONNECTIONS} connected players!`, 33);
break;
// Exit the server
case "/exit":
@ -30,7 +30,7 @@ export function processCommand(cmd, data) {
break;
case "/help":
console.log("\x1b[36;1m==================================== HELP =====================================\x1b[0m");
console.log(`\x1b[${CFG.SERVER_DEFAULT_CONSOLE_COLOR};1m${helpMessage}\x1b[0m`);
console.log(`\x1b[${CFG.DEFAULT_CONSOLE_COLOR};1m${helpMessage}\x1b[0m`);
console.log("\x1b[36;1m===============================================================================\x1b[0m");
break;
case "/save":
@ -58,7 +58,7 @@ export function stdinInput(data) {
export function uncaughtException(excp) {
switch (excp.errno) {
case "EADDRINUSE":
this.print(`Port ${CFG.SERVER_PORT} is already in use!`, 31);
this.print(`Port ${CFG.PORT} is already in use!`, 31);
break;
case "EACCES":
this.print("No root privileges!", 31);

View File

@ -1,78 +1,13 @@
import proto from "./proto";
import * as CFG from "../cfg";
import { REQUEST } from "./requests";
import CFG from "../cfg";
import {
ResponseEnvelope,
ResponseEnvelopeAuth,
AuthTicket,
GetInventory
AuthTicket
} from "./packets";
import {
decodeLong,
decodeRequestEnvelope
} from "./utils";
import jwtDecode from "jwt-decode";
/**
* @return {Buffer}
*/
export function authenticatePlayer() {
let player = this.player;
let request = decodeRequestEnvelope(this.getRequestBody());
let msg = ResponseEnvelopeAuth({
id: request.request_id
});
let token = request.auth_info;
// TODO: Support PTC server authentification
if (!token || !token.provider) {
this.print("Invalid authentication token! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
if (token.provider === "google") {
if (token.token !== null) {
let decoded = jwtDecode(token.token.contents);
player.generateUid(decoded.email);
player.email = decoded.email;
player.email_verified = decoded.email_verified;
player.isGoogleAccount = true;
this.print(`${player.email.replace("@gmail.com", "")} connected!`, 36);
}
else {
this.print("Invalid authentication token! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
}
else if (token.provider === "ptc") {
let decoded = token.token.contents;
player.isPTCAccount = true;
this.print("PTC auth isnt supported yet! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
else {
this.print("Invalid provider! Kicking..", 31);
this.removePlayer(player);
return void 0;
}
player.authenticated = true;
return (msg);
}
const REQUEST = proto.Networking.Requests.RequestType;
/**
* @param {Request} req
@ -92,14 +27,10 @@ export function getRequestType(req) {
/**
* @param {Request} req
* @param {Response} res
*/
export function onRequest(req, res) {
export function onRequest(req) {
this.player = this.getPlayerByRequest(req);
this.player.response = res;
let player = this.player;
let player = this.getPlayerByRequest(req);
// Validate email verification
if (player.authenticated) {
@ -117,7 +48,7 @@ export function onRequest(req, res) {
return void 0;
}
if (CFG.SERVER_LOG_REQUESTS) {
if (CFG.DEBUG_LOG_REQUESTS) {
console.log("#####");
request.requests.map((request) => {
console.log("Got request:", this.getRequestType(request));
@ -125,16 +56,16 @@ export function onRequest(req, res) {
}
if (!player.authenticated) {
this.send(this.authenticatePlayer());
player.sendResponse(this.authenticatePlayer(player));
return void 0;
}
this.processRequests(request.requests).then((answer) => {
this.processRequests(player, request.requests).then((answer) => {
let msg = this.envelopResponse(1, request.request_id, answer, !!request.auth_ticket);
if (CFG.SERVER_DUMP_TRAFFIC) {
if (CFG.DEBUG_DUMP_TRAFFIC) {
this.dumpTraffic(req.body, msg);
}
this.send(msg);
player.sendResponse(msg);
});
}
@ -161,10 +92,11 @@ export function envelopResponse(status, id, response, auth) {
}
/**
* @param {Player} player
* @param {Array} requests
* @return {Array}
*/
export function processRequests(requests) {
export function processRequests(player, requests) {
return new Promise((resolve) => {
@ -173,7 +105,7 @@ export function processRequests(requests) {
let body = [];
let loop = (index) => {
this.processResponse(requests[index]).then((request) => {
this.processResponse(player, requests[index]).then((request) => {
body.push(request);
if (++index >= length) resolve(body);
else return loop(index);
@ -188,9 +120,8 @@ export function processRequests(requests) {
/**
* @param {Request} req
* @param {Response} res
*/
export function routeRequest(req, res) {
export function routeRequest(req) {
let url = String(req.url);
let route = url.substring(url.lastIndexOf("/") + 1);
@ -198,17 +129,7 @@ export function routeRequest(req, res) {
switch (route) {
case "rpc":
this.onRequest(req, res);
break;
case "oauth":
let out = null;
let buffer = req.body.toString();
let signature = "321187995bc7cdc2b5fc91b11a96e2baa8602c62";
if (/Email.*com.nianticlabs.pokemongo/.test(buffer)) {
out = new Buffer(buffer.replace(/&client_sig=[^&]*&/, "&client_sig=" + signature + "&"));
}
console.log("OAUTH", out);
if (out instanceof Buffer) this.send(out);
this.onRequest(req);
break;
default:
console.log(`Unknown request url: https://${req.headers.host}${req.url}`);
@ -223,22 +144,4 @@ export function routeRequest(req, res) {
*/
export function validRequest(req) {
return (true);
}
/**
* @return {Buffer}
*/
export function getRequestBody() {
return (
this.request.body
);
}
/**
* @param {Buffer} buffer
*/
export function send(buffer) {
this.player.response.end(buffer);
}

View File

@ -1,73 +0,0 @@
export const REQUEST = {
METHOD_UNSET: 0, // No implementation required
PLAYER_UPDATE: 1, // Implemented [R & M]
GET_PLAYER: 2, // Implemented [R & M]
GET_INVENTORY: 4, // Implemented [R & M]
DOWNLOAD_SETTINGS: 5, // Implemented [R & M]
DOWNLOAD_ITEM_TEMPLATES: 6, // Implemented [R & M]
DOWNLOAD_REMOTE_CONFIG_VERSION: 7, // Implemented [R & M]
FORT_SEARCH: 101, // Implemented [R & M]
ENCOUNTER: 102, // Implemented [R & M]
CATCH_POKEMON: 103, // Implemented [R & M]
FORT_DETAILS: 104, // Implemented [R & M]
ITEM_USE: 105, // Can't find this one
GET_MAP_OBJECTS: 106, // Implemented [R & M]
FORT_DEPLOY_POKEMON: 110, // Implemented [R & M]
FORT_RECALL_POKEMON: 111, // Implemented [R & M]
RELEASE_POKEMON: 112, // Implemented [R & M]
USE_ITEM_POTION: 113, // Implemented [R & M]
USE_ITEM_CAPTURE: 114, // Implemented [R & M]
USE_ITEM_FLEE: 115, // Can't find this one
USE_ITEM_REVIVE: 116, // Implemented [R & M]
TRADE_SEARCH: 117, // Not yet implemented in the game
TRADE_OFFER: 118, // Not yet implemented in the game
TRADE_RESPONSE: 119, // Not yet implemented in the game
TRADE_RESULT: 120, // Not yet implemented in the game
GET_PLAYER_PROFILE: 121, // Implemented [R & M]
GET_ITEM_PACK: 122, // Can't find this one
BUY_ITEM_PACK: 123, // Can't find this one
BUY_GEM_PACK: 124, // Can't find this one
EVOLVE_POKEMON: 125, // Implemented [R & M]
GET_HATCHED_EGGS: 126, // Implemented [R & M]
ENCOUNTER_TUTORIAL_COMPLETE: 127, // Implemented [R & M]
LEVEL_UP_REWARDS: 128, // Implemented [R & M]
CHECK_AWARDED_BADGES: 129, // Implemented [R & M]
USE_ITEM_GYM: 133, // Implemented [R & M]
GET_GYM_DETAILS: 134, // Implemented [R & M]
START_GYM_BATTLE: 135, // Implemented [R & M]
ATTACK_GYM: 136, // Implemented [R & M]
RECYCLE_INVENTORY_ITEM: 137, // Implemented [R & M]
COLLECT_DAILY_BONUS: 138, // Implemented [R & M]
USE_ITEM_XP_BOOST: 139, // Implemented [R & M]
USE_ITEM_EGG_INCUBATOR: 140, // Implemented [R & M]
USE_INCENSE: 141, // Implemented [R & M]
GET_INCENSE_POKEMON: 142, // Implemented [R & M]
INCENSE_ENCOUNTER: 143, // Implemented [R & M]
ADD_FORT_MODIFIER: 144, // Implemented [R & M]
DISK_ENCOUNTER: 145, // Implemented [R & M]
COLLECT_DAILY_DEFENDER_BONUS: 146, // Implemented [R & M]
UPGRADE_POKEMON: 147, // Implemented [R & M]
SET_FAVORITE_POKEMON: 148, // Implemented [R & M]
NICKNAME_POKEMON: 149, // Implemented [R & M]
EQUIP_BADGE: 150, // Implemented [R & M]
SET_CONTACT_SETTINGS: 151, // Implemented [R & M]
GET_ASSET_DIGEST: 300, // Implemented [R & M]
GET_DOWNLOAD_URLS: 301, // Implemented [R & M]
GET_SUGGESTED_CODENAMES: 401, // Implemented [R & M]
CHECK_CODENAME_AVAILABLE: 402, // Implemented [R & M] TEST RESPONSE
CLAIM_CODENAME: 403, // Implemented [R & M] TEST RESPONSE
SET_AVATAR: 404, // Implemented [R & M]
SET_PLAYER_TEAM: 405, // Implemented [R & M]
MARK_TUTORIAL_COMPLETE: 406, // Implemented [R & M]
LOAD_SPAWN_POINTS: 500, // Can't find this one
ECHO: 666, // Implemented [R & M]
DEBUG_UPDATE_INVENTORY: 700,
DEBUG_DELETE_PLAYER: 701,
SFIDA_REGISTRATION: 800, // Not yet released.
SFIDA_ACTION_LOG: 801, // Not yet released.
SFIDA_CERTIFICATION: 802, // Not yet released.
SFIDA_UPDATE: 803, // Not yet released.
SFIDA_ACTION: 804, // Not yet released.
SFIDA_DOWSER: 805, // Not yet released.
SFIDA_CAPTURE: 806 // Not yet released.
};

View File

@ -1,7 +1,6 @@
import proto from "./proto";
import * as CFG from "../cfg";
import { REQUEST } from "./requests";
import CFG from "../cfg";
import {
GetInventory,
@ -30,21 +29,23 @@ import {
ClaimCodeName
} from "./packets";
const REQUEST = proto.Networking.Requests.RequestType;
/**
* @param {Player} player
* @param {Request} req
* @return {Buffer}
*/
export function processResponse(request) {
export function processResponse(player, req) {
let buffer = null;
let player = this.player;
return new Promise((resolve) => {
try {
switch (request.request_type) {
switch (req.request_type) {
case REQUEST.GET_PLAYER:
this.forwardPlayer().then((res) => resolve(res));
this.forwardPlayer(player).then((res) => resolve(res));
return void 0;
break;
case REQUEST.GET_HATCHED_EGGS:
@ -57,36 +58,36 @@ export function processResponse(request) {
buffer = CheckAwardedBadges();
break;
case REQUEST.DOWNLOAD_SETTINGS:
buffer = DownloadSettings(request);
buffer = DownloadSettings(req);
break;
case REQUEST.DOWNLOAD_ITEM_TEMPLATES:
buffer = ItemTemplates();
break;
case REQUEST.DOWNLOAD_REMOTE_CONFIG_VERSION:
buffer = DownloadRemoteConfigVersion(request);
buffer = DownloadRemoteConfigVersion(req);
break;
case REQUEST.GET_ASSET_DIGEST:
buffer = GetAssetDigest(this.asset, request);
buffer = GetAssetDigest(this.asset, req);
break;
case REQUEST.GET_PLAYER_PROFILE:
buffer = GetPlayerProfile();
break;
case REQUEST.GET_MAP_OBJECTS:
this.player.updatePosition(request);
buffer = GetMapObjects(player, request);
player.updatePosition(req);
buffer = GetMapObjects(player, req);
this.savePlayer(player).then(() => {
resolve(buffer);
});
return void 0;
break;
case REQUEST.GET_DOWNLOAD_URLS:
GetDownloadUrls(this.asset, request, this.generateDownloadUrlByAssetId).then((res) => {
GetDownloadUrls(this.asset, req, this.generateDownloadUrlByAssetId).then((res) => {
resolve(res);
});
return void 0;
break;
case REQUEST.SET_AVATAR:
player.updateAvatar(request);
player.updateAvatar(req);
buffer = SetAvatar(player);
this.savePlayer(player).then(() => {
resolve(buffer);
@ -104,7 +105,7 @@ export function processResponse(request) {
return void 0;
break;
case REQUEST.CLAIM_CODENAME:
buffer = ClaimCodeName(request, player);
buffer = ClaimCodeName(req, player);
this.savePlayer(player).then(() => {
resolve(buffer);
});
@ -114,13 +115,13 @@ export function processResponse(request) {
buffer = LevelUpRewards();
break;
case REQUEST.FORT_DETAILS:
buffer = FortDetails(request);
buffer = FortDetails(req);
break;
case REQUEST.FORT_SEARCH:
buffer = FortSearch();
break;
case REQUEST.SET_CONTACT_SETTINGS:
player.updateContactSettings(request);
player.updateContactSettings(req);
buffer = SetContactSettings(player);
this.savePlayer(player).then(() => {
resolve(buffer);
@ -128,26 +129,26 @@ export function processResponse(request) {
return void 0;
break;
case REQUEST.ENCOUNTER:
buffer = Encounter(request);
buffer = Encounter(req);
break;
case REQUEST.NICKNAME_POKEMON:
buffer = NicknamePokemon(request);
buffer = NicknamePokemon(req);
break;
case REQUEST.UPGRADE_POKEMON:
buffer = UpgradePokemon(request);
buffer = UpgradePokemon(req);
break;
case REQUEST.EVOLVE_POKEMON:
buffer = EvolvePokemon(request);
buffer = EvolvePokemon(req);
break;
case REQUEST.SET_FAVORITE_POKEMON:
buffer = SetFavoritePokemon(request);
buffer = SetFavoritePokemon(req);
break;
case REQUEST.CATCH_POKEMON:
let data = proto.Networking.Requests.Messages.CatchPokemonMessage.decode(request.request_message.toBuffer());
let data = proto.Networking.Requests.Messages.CatchPokemonMessage.decode(req.request_message.toBuffer());
console.log(data);
break;
default:
this.print(`Unknown request: ${this.getRequestType(request)}`, 31);
this.print(`Unknown request: ${this.getRequestType(req)}`, 31);
break;
};
} catch (e) {

View File

@ -1,6 +1,4 @@
import path from "path";
import * as CFG from "../cfg";
import CFG from "../cfg";
export function setup() {
@ -12,14 +10,14 @@ export function setup() {
if (!assetSessionLoaded) {
this.print("Boot timeout, please check your login details!", 31);
}
}, CFG.SERVER_BOOT_TIMEOUT);
}, CFG.BOOT_TIMEOUT);
this.createAssetDownloadSession().then((asset) => {
assetSessionLoaded = true;
this.asset = asset;
this.setupDatabaseConnection().then(() => {
if (CFG.SERVER_PORT < 1) {
if (CFG.PORT < 1) {
this.print("Invalid port!", 31);
return void 0;
}
@ -28,7 +26,9 @@ export function setup() {
setTimeout(this::this.cycle, 1);
this.print(`Server running at ${CFG.SERVER_HOST_IP}:${CFG.SERVER_PORT}`);
let localIPv4 = this.getLocalIPv4();
this.print(`Server running at ${localIPv4}:${CFG.PORT}`);
});
});

View File

@ -1,7 +1,7 @@
import Long from "long";
import proto from "./proto";
import * as CFG from "../cfg";
import CFG from "../cfg";
/**
* @param {Object} cls