mirror of
https://github.com/maierfelix/POGOserver.git
synced 2026-04-21 00:47:20 -05:00
Update
- Cleaner game master handling - Added contact and currency player subclasses - Authentication works - Cleaner device sig parsing, handle unknown as repeated field - Added various player and world packets - Seperate settings object for DownloadSettings request - Basic GetMapObjects response - Removed unnecessary code in request.js - Extended response.js - Outsourced parseSignature into utils.js
This commit is contained in:
parent
dbde45fe73
commit
aa3743b4bd
|
|
@ -4,6 +4,8 @@ import POGOProtos from "pokemongo-protobuf";
|
|||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
import { _toCC } from "./utils";
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Array} res
|
||||
|
|
|
|||
12
src/index.js
12
src/index.js
|
|
@ -45,8 +45,6 @@ export default class GameServer {
|
|||
|
||||
this.apiClients = {};
|
||||
|
||||
this.assets = {};
|
||||
this.master = null;
|
||||
this.socket = null;
|
||||
this.cycleInstance = null;
|
||||
|
||||
|
|
@ -119,16 +117,6 @@ export default class GameServer {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
*/
|
||||
parseSignature(req) {
|
||||
let key = pcrypt.decrypt(req.unknown6.unknown2.encrypted_signature);
|
||||
return (
|
||||
POGOProtos.parseWithUnknown(key, "POGOProtos.Networking.Envelopes.Signature")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} path
|
||||
* @return {Boolean}
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
/**
|
||||
* Global shared parsed
|
||||
* game master file
|
||||
* @type {GameMaster}
|
||||
*/
|
||||
export let GAME_MASTER = null;
|
||||
|
|
@ -1,29 +1,41 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @class GameMaster
|
||||
*/
|
||||
export default class GameMaster {
|
||||
|
||||
/**
|
||||
* @param {Buffer} buffer
|
||||
* @param {Object} decode
|
||||
* @constructor
|
||||
*/
|
||||
constructor(buffer) {
|
||||
constructor(decode) {
|
||||
|
||||
this.settings = this.buildSettings();
|
||||
|
||||
this.buffer = buffer;
|
||||
this.decode = decode;
|
||||
this.buffer = this.encode();
|
||||
|
||||
this.parse();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Buffer}
|
||||
*/
|
||||
encode() {
|
||||
return (
|
||||
POGOProtos.serialize(this.decode, "POGOProtos.Networking.Responses.DownloadItemTemplatesResponse")
|
||||
);
|
||||
}
|
||||
|
||||
parse() {
|
||||
|
||||
let ii = 0;
|
||||
let length = 0;
|
||||
|
||||
let item = null;
|
||||
let items = this.buffer.item_templates;
|
||||
let items = this.decode.item_templates;
|
||||
|
||||
length = items.length;
|
||||
|
||||
|
|
@ -60,4 +72,13 @@ export default class GameMaster {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Buffer}
|
||||
*/
|
||||
serialize() {
|
||||
return (
|
||||
this.buffer
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
24
src/models/Player/Contact/index.js
Normal file
24
src/models/Player/Contact/index.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* @class Contact
|
||||
*/
|
||||
export default class Contact {
|
||||
|
||||
/** @constructor */
|
||||
constructor() {
|
||||
|
||||
this.sendMarketingEmails = false;
|
||||
this.sendPushNotifications = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
serialize() {
|
||||
return ({
|
||||
send_marketing_emails: this.sendMarketingEmails,
|
||||
send_push_notifications: this.sendPushNotifications
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
30
src/models/Player/Currency/index.js
Normal file
30
src/models/Player/Currency/index.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* @class Currency
|
||||
*/
|
||||
export default class Currency {
|
||||
|
||||
/** @constructor */
|
||||
constructor() {
|
||||
|
||||
this.currencies = {
|
||||
"POKECOINS": 0,
|
||||
"STARDUST": 0
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Array}
|
||||
*/
|
||||
serialize() {
|
||||
let out = [];
|
||||
for (let key in this.currencies) {
|
||||
out.push({
|
||||
name: key,
|
||||
amount: this.currencies[key]
|
||||
});
|
||||
};
|
||||
return (out);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @class Info
|
||||
*/
|
||||
class Info {
|
||||
export default class Info {
|
||||
|
||||
/** @constructor */
|
||||
constructor() {
|
||||
|
|
@ -68,23 +68,21 @@ class Info {
|
|||
}
|
||||
}
|
||||
|
||||
getPlayerInfo() {
|
||||
serialize() {
|
||||
return ({
|
||||
player_stats: {
|
||||
level: this.lvl,
|
||||
experience: this.exp,
|
||||
prev_level_xp: this.prevLvlExp,
|
||||
next_level_xp: this.nextLvlExp,
|
||||
km_walked: this.kmWalked,
|
||||
pokemons_encountered: this.pkmnEncountered,
|
||||
unique_pokedex_entries: this.uniquePokedexEntries,
|
||||
pokemons_captured: this.pkmnCaptured,
|
||||
poke_stop_visits: this.pokeStopVisits,
|
||||
pokeballs_thrown: this.pokeballsThrown,
|
||||
eggs_hatched: this.eggsHatched,
|
||||
big_magikarp_caught: this.bigMagikarpCaught,
|
||||
pokemon_deployed: this.pkmnDeployed
|
||||
}
|
||||
level: this.lvl,
|
||||
experience: this.exp,
|
||||
prev_level_xp: this.prevLvlExp,
|
||||
next_level_xp: this.nextLvlExp,
|
||||
km_walked: this.kmWalked,
|
||||
pokemons_encountered: this.pkmnEncountered,
|
||||
unique_pokedex_entries: this.uniquePokedexEntries,
|
||||
pokemons_captured: this.pkmnCaptured,
|
||||
poke_stop_visits: this.pokeStopVisits,
|
||||
pokeballs_thrown: this.pokeballsThrown,
|
||||
eggs_hatched: this.eggsHatched,
|
||||
big_magikarp_caught: this.bigMagikarpCaught,
|
||||
pokemon_deployed: this.pkmnDeployed
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import Pokemon from "../../Pokemon";
|
||||
|
||||
/**
|
||||
* @class Party
|
||||
*/
|
||||
class Party {
|
||||
export default class Party {
|
||||
|
||||
/** @constructor */
|
||||
constructor() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import Candy from "./Candy";
|
||||
|
||||
/**
|
||||
* @class Tutorial
|
||||
*/
|
||||
|
|
@ -7,38 +5,24 @@ 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() {
|
||||
|
||||
skipTutorial() {
|
||||
this.states = [
|
||||
"LEGAL_SCREEN",
|
||||
"AVATAR_SELECTION",
|
||||
"POKEMON_CAPTURE",
|
||||
"NAME_SELECTION",
|
||||
"FIRST_TIME_EXPERIENCE_COMPLETE"
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Array}
|
||||
*/
|
||||
serialize() {
|
||||
this.skipTutorial();
|
||||
return (
|
||||
this.states
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
import Avatar from "./Avatar";
|
||||
import MapObject from "../World/MapObject";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
import jwtDecode from "jwt-decode";
|
||||
|
||||
import Info from "./Info";
|
||||
import Party from "./Party";
|
||||
import Avatar from "./Avatar";
|
||||
import Contact from "./Contact";
|
||||
import Tutorial from "./Tutorial";
|
||||
import Currency from "./Currency";
|
||||
|
||||
import MapObject from "../World/MapObject";
|
||||
|
||||
import print from "../../print";
|
||||
import CFG from "../../../cfg";
|
||||
|
||||
import * as _packets from "./packets";
|
||||
|
||||
import { inherit } from "../../utils";
|
||||
import {
|
||||
inherit,
|
||||
parseSignature
|
||||
} from "../../utils";
|
||||
|
||||
import { GAME_MASTER } from "../../master";
|
||||
import { GAME_MASTER } from "../../shared";
|
||||
|
||||
/**
|
||||
* @class Player
|
||||
|
|
@ -28,15 +38,20 @@ export default class Player extends MapObject {
|
|||
this.world = obj.world;
|
||||
|
||||
this._team = 0;
|
||||
this._email = null;
|
||||
|
||||
this.username = "unknown";
|
||||
|
||||
this._email = null;
|
||||
this.email_verified = false;
|
||||
|
||||
this.platform = null;
|
||||
|
||||
this.isPTCAccount = false;
|
||||
this.isGoogleAccount = false;
|
||||
|
||||
this.isIOS = false;
|
||||
this.isAndroid = false;
|
||||
|
||||
this.hasSignature = false;
|
||||
|
||||
this.authenticated = false;
|
||||
|
|
@ -49,13 +64,17 @@ export default class Player extends MapObject {
|
|||
this.maxPkmnStorage = 250;
|
||||
this.maxItemStorage = 350;
|
||||
|
||||
this.info = new Info(this);
|
||||
this.party = new Party(this);
|
||||
this.avatar = new Avatar(this);
|
||||
this.contact = new Contact(this);
|
||||
this.currency = new Currency(this);
|
||||
this.tutorial = new Tutorial(this);
|
||||
|
||||
/*
|
||||
this.bag = new Bag(this);
|
||||
this.info = new Info(this);
|
||||
this.pary = new Party(this);
|
||||
this.avatar = new Avatar(this);
|
||||
this.pokedex = new Pokedex(this);
|
||||
this.tutorial = new Tutorial(this);
|
||||
*/
|
||||
|
||||
this.refreshSocket(obj.request, obj.response);
|
||||
|
|
@ -66,15 +85,15 @@ export default class Player extends MapObject {
|
|||
return (this._team);
|
||||
}
|
||||
set team(value) {
|
||||
this.team = value;
|
||||
this._team = value;
|
||||
}
|
||||
|
||||
get email() {
|
||||
return (this._email);
|
||||
}
|
||||
set email(value) {
|
||||
this.email = value;
|
||||
this.username = this.email;
|
||||
this._email = value;
|
||||
this.username = value.replace("@gmail.com", "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -89,13 +108,13 @@ export default class Player extends MapObject {
|
|||
* @param {Response} res
|
||||
*/
|
||||
refreshSocket(req, res) {
|
||||
this.request = req;
|
||||
this.request = POGOProtos.parseWithUnknown(req.body, "POGOProtos.Networking.Envelopes.RequestEnvelope");
|
||||
this.response = res;
|
||||
}
|
||||
|
||||
authenticate() {
|
||||
|
||||
let request = POGOProtos.parseWithUnknown(this.request.body, "POGOProtos.Networking.Envelopes.RequestEnvelope")
|
||||
let request = this.request;
|
||||
|
||||
let msg = this.GetAuthTicket(request.request_id);
|
||||
|
||||
|
|
@ -133,6 +152,23 @@ export default class Player extends MapObject {
|
|||
|
||||
}
|
||||
|
||||
getDevicePlatform() {
|
||||
|
||||
let request = this.request;
|
||||
|
||||
if (request.unknown6 && request.unknown6[0]) {
|
||||
let sig = parseSignature(request);
|
||||
if (sig.device_info !== void 0) {
|
||||
this.hasSignature = true;
|
||||
this.isIOS = sig.device_info.device_brand === "Apple";
|
||||
this.isAndroid = !this.isIOS;
|
||||
this.platform = this.isIOS ? "ios" : "android";
|
||||
print(`${this.email} is playing with an ${this.isIOS ? "Apple" : "Android"} device!`, 36);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} type
|
||||
* @param {Object} msg
|
||||
|
|
@ -143,6 +179,18 @@ export default class Player extends MapObject {
|
|||
case "GET_PLAYER":
|
||||
resolve(this.GetPlayer(msg));
|
||||
break;
|
||||
case "GET_INVENTORY":
|
||||
resolve(this.GetInventory(msg));
|
||||
break;
|
||||
case "GET_ASSET_DIGEST":
|
||||
resolve(this.GetAssetDigest(msg));
|
||||
break;
|
||||
case "GET_HATCHED_EGGS":
|
||||
resolve(this.GetHatchedEggs(msg));
|
||||
break;
|
||||
case "CHECK_AWARDED_BADGES":
|
||||
resolve(this.CheckAwardedBadges(msg));
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
19
src/models/Player/packets/CheckAwardedBadges.js
Normal file
19
src/models/Player/packets/CheckAwardedBadges.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function CheckAwardedBadges(msg) {
|
||||
|
||||
let buffer = {
|
||||
success: true,
|
||||
awarded_badges: [],
|
||||
awarded_badge_levels: []
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.CheckAwardedBadgesResponse")
|
||||
);
|
||||
|
||||
}
|
||||
13
src/models/Player/packets/GetAssetDigest.js
Normal file
13
src/models/Player/packets/GetAssetDigest.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import * as shared from "../../../shared";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function GetAssetDigest(msg) {
|
||||
return (
|
||||
shared.GAME_ASSETS[this.platform].buffer
|
||||
);
|
||||
}
|
||||
21
src/models/Player/packets/GetHatchedEggs.js
Normal file
21
src/models/Player/packets/GetHatchedEggs.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function GetHatchedEggs(msg) {
|
||||
|
||||
let buffer = {
|
||||
success: true,
|
||||
pokemon_id: [],
|
||||
experience_awarded: [],
|
||||
candy_awarded: [],
|
||||
stardust_awarded: []
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetHatchedEggsResponse")
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -1,47 +1,33 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
export default function GetInventory() {
|
||||
|
||||
let stats = this.GetInventoryPlayer();
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function GetInventory(msg) {
|
||||
/*
|
||||
let items = this.GetInventoryItems();
|
||||
let party = this.GetInventoryParty();
|
||||
*/
|
||||
|
||||
let buffer = ({
|
||||
let stats = {
|
||||
modified_timestamp_ms: +new Date(),
|
||||
inventory_item_data: {
|
||||
player_stats: this.info.serialize()
|
||||
}
|
||||
};
|
||||
|
||||
let buffer = {
|
||||
success: true,
|
||||
inventory_delta: {
|
||||
new_timestamp_ms: new Date().getTime(),
|
||||
inventory_items: stats.concat(items).concat(party)
|
||||
inventory_items: [stats]
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetInventoryResponse"));
|
||||
|
||||
}
|
||||
|
||||
export function GetInventoryPlayer() {
|
||||
|
||||
let player = this.player;
|
||||
|
||||
return ({
|
||||
modified_timestamp_ms: new Date().getTime(),
|
||||
inventory_item_data: {
|
||||
player_stats: {
|
||||
level: player.level,
|
||||
experience: player.exp,
|
||||
prev_level_xp: "21000",
|
||||
next_level_xp: "36000",
|
||||
km_walked: 3.921541213989258,
|
||||
pokemons_encountered: 75,
|
||||
unique_pokedex_entries: 25,
|
||||
pokemons_captured: 71,
|
||||
poke_stop_visits: 123,
|
||||
pokeballs_thrown: 74,
|
||||
eggs_hatched: 1,
|
||||
big_magikarp_caught: 1,
|
||||
pokemon_deployed: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetInventoryResponse")
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import POGOProtos from "pokemongo-protobuf";
|
|||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function GetPlayer(msg) {
|
||||
|
||||
|
|
@ -17,9 +18,11 @@ export default function GetPlayer(msg) {
|
|||
next_defender_bonus_collect_timestamp_ms: +new Date()
|
||||
},
|
||||
contact_settings: this.contact.serialize(),
|
||||
currencies: this.currencies.serialize()
|
||||
}
|
||||
currencies: this.currency.serialize()
|
||||
};
|
||||
|
||||
return (POGOProtos.serialize({ success: true, player_data: buffer }, "POGOProtos.Networking.Responses.GetPlayerResponse"));
|
||||
return (
|
||||
POGOProtos.serialize({ success: true, player_data: buffer }, "POGOProtos.Networking.Responses.GetPlayerResponse")
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ import POGOProtos from "pokemongo-protobuf";
|
|||
|
||||
export default function GetPlayerProfile() {
|
||||
|
||||
return (POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetPlayerProfileResponse"));
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetPlayerProfileResponse")
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
export GetPlayer from "./GetPlayer";
|
||||
export GetInventory from "./GetInventory";
|
||||
export GetAuthTicket from "./GetAuthTicket";
|
||||
export GetPlayerProfile from "./GetPlayerProfile";
|
||||
export GetHatchedEggs from "./GetHatchedEggs";
|
||||
export GetAssetDigest from "./GetAssetDigest";
|
||||
export GetPlayerProfile from "./GetPlayerProfile";
|
||||
export CheckAwardedBadges from "./CheckAwardedBadges";
|
||||
|
|
@ -17,6 +17,8 @@ export default class Pokemon extends MapObject {
|
|||
*/
|
||||
constructor(obj) {
|
||||
|
||||
super(null);
|
||||
|
||||
this.id = 0;
|
||||
this.dexNumber = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ import Player from "../Player";
|
|||
|
||||
import CFG from "../../../cfg";
|
||||
|
||||
import * as _packets from "./packets";
|
||||
|
||||
import { inherit } from "../../utils";
|
||||
|
||||
/**
|
||||
* @class World
|
||||
*/
|
||||
|
|
@ -138,11 +142,25 @@ export default class World {
|
|||
getPacket(type, msg) {
|
||||
return new Promise((resolve) => {
|
||||
switch (type) {
|
||||
case "GET_MAP_OBJECTS":
|
||||
resolve(this.GetMapObjects(msg));
|
||||
break;
|
||||
case "CHECK_CHALLENGE":
|
||||
console.log(type, msg);
|
||||
resolve(this.CheckChallenge(msg));
|
||||
break;
|
||||
case "DOWNLOAD_SETTINGS":
|
||||
resolve(this.DownloadSettings(msg));
|
||||
break;
|
||||
case "DOWNLOAD_REMOTE_CONFIG_VERSION":
|
||||
resolve(this.DownloadRemoteConfigVersion(msg));
|
||||
break;
|
||||
case "DOWNLOAD_ITEM_TEMPLATES":
|
||||
resolve(this.DownloadItemTemplates(msg));
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inherit(World, _packets);
|
||||
16
src/models/World/packets/CheckChallenge.js
Normal file
16
src/models/World/packets/CheckChallenge.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
*/
|
||||
export default function CheckChallenge(msg) {
|
||||
|
||||
let buffer = {
|
||||
challenge_url: " "
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.CheckChallengeResponse")
|
||||
);
|
||||
|
||||
}
|
||||
13
src/models/World/packets/DownloadItemTemplates.js
Normal file
13
src/models/World/packets/DownloadItemTemplates.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import * as shared from "../../../shared";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function DownloadItemTemplates(msg) {
|
||||
return (
|
||||
shared.GAME_MASTER.serialize()
|
||||
);
|
||||
}
|
||||
19
src/models/World/packets/DownloadRemoteConfigVersion.js
Normal file
19
src/models/World/packets/DownloadRemoteConfigVersion.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
*/
|
||||
export default function DownloadRemoteConfigVersion(msg) {
|
||||
|
||||
let buffer = {
|
||||
"result": "SUCCESS",
|
||||
"item_templates_timestamp_ms": "1471650700946",
|
||||
"asset_digest_timestamp_ms": "1467338276561000",
|
||||
"$unknownFields": []
|
||||
}
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.DownloadRemoteConfigVersionResponse")
|
||||
);
|
||||
|
||||
}
|
||||
20
src/models/World/packets/DownloadSettings.js
Normal file
20
src/models/World/packets/DownloadSettings.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import Settings from "../../../modes";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function DownloadSettings(msg) {
|
||||
|
||||
let buffer = {
|
||||
hash: "2788184af4004004d6ab0740f7632983332106f6",
|
||||
settings: Settings.GAME_SETTINGS
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.DownloadSettingsResponse")
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Request} request
|
||||
*/
|
||||
export function GetMapObject(request) {
|
||||
|
||||
let player = this.player;
|
||||
|
||||
let latitude = player.latitude;
|
||||
let longitude = player.longitude;
|
||||
|
||||
return new Promise(() => {
|
||||
// db call
|
||||
//
|
||||
});
|
||||
|
||||
}
|
||||
38
src/models/World/packets/GetMapObjects.js
Normal file
38
src/models/World/packets/GetMapObjects.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function GetMapObjects(msg) {
|
||||
|
||||
let latitude = msg.latitude;
|
||||
let longitude = msg.longitude;
|
||||
|
||||
let cells = [];
|
||||
|
||||
let buffer = {
|
||||
status: "SUCCESS",
|
||||
map_cells: cells
|
||||
};
|
||||
|
||||
for (let cell in msg.cell_id) {
|
||||
cells.push({
|
||||
s2_cell_id: cell,
|
||||
current_timestamp_ms: +new Date(),
|
||||
forts: [],
|
||||
spawn_points: [],
|
||||
deleted_objects: [],
|
||||
fort_summaries: [],
|
||||
decimated_spawn_points: [],
|
||||
wild_pokemons: [],
|
||||
catchable_pokemons: [],
|
||||
nearby_pokemons: []
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetMapObjectsResponse")
|
||||
);
|
||||
|
||||
}
|
||||
5
src/models/World/packets/index.js
Normal file
5
src/models/World/packets/index.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export GetMapObjects from "./GetMapObjects";
|
||||
export CheckChallenge from "./CheckChallenge";
|
||||
export DownloadSettings from "./DownloadSettings";
|
||||
export DownloadItemTemplates from "./DownloadItemTemplates";
|
||||
export DownloadRemoteConfigVersion from "./DownloadRemoteConfigVersion";
|
||||
31
src/modes/index.js
Normal file
31
src/modes/index.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import CFG from "../../cfg";
|
||||
|
||||
export default {
|
||||
GAME_SETTINGS: {
|
||||
fort_settings: {
|
||||
interaction_range_meters: 40.25098039215686,
|
||||
max_total_deployed_pokemon: 10,
|
||||
max_player_deployed_pokemon: 1,
|
||||
deploy_stamina_multiplier: 8.062745098039215,
|
||||
deploy_attack_multiplier: 0,
|
||||
far_interaction_range_meters: 1000.0156862745098
|
||||
},
|
||||
map_settings: {
|
||||
pokemon_visible_range: 70.00196078431372,
|
||||
poke_nav_range_meters: 751.0156862745098,
|
||||
encounter_range_meters: 50.25098039215686,
|
||||
get_map_objects_min_refresh_seconds: 10.007843017578125,
|
||||
get_map_objects_max_refresh_seconds: 11.01568603515625,
|
||||
get_map_objects_min_distance_meters: 10.007843017578125,
|
||||
google_maps_api_key: CFG.GMAPS_KEY
|
||||
},
|
||||
inventory_settings: {
|
||||
max_pokemon: 1000,
|
||||
max_bag_items: 1000,
|
||||
base_pokemon: 250,
|
||||
base_bag_items: 350,
|
||||
base_eggs: 9
|
||||
},
|
||||
minimum_client_version: CFG.MINIMUM_CLIENT_VERSION
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import fs from "fs";
|
||||
import url from "url";
|
||||
import pcrypt from "pcrypt";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import print from "./print";
|
||||
|
|
@ -72,23 +71,22 @@ 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);
|
||||
this.onRequest(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Player} player
|
||||
* @param {Request} req
|
||||
*/
|
||||
export function onRequest(player, req) {
|
||||
export function onRequest(player) {
|
||||
|
||||
let request = this.parseProtobuf(req.body, "POGOProtos.Networking.Envelopes.RequestEnvelope");
|
||||
let request = player.request;
|
||||
request.requests = request.requests || [];
|
||||
|
||||
if (CFG.DEBUG_LOG_REQUESTS) {
|
||||
console.log("#####");
|
||||
print("#####");
|
||||
request.requests.map((request) => {
|
||||
console.log("Got request:", request.request_type);
|
||||
print(request.request_type, 35);
|
||||
}).join(",");
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +95,10 @@ export function onRequest(player, req) {
|
|||
return void 0;
|
||||
}
|
||||
|
||||
if (player.hasSignature === false) {
|
||||
player.getDevicePlatform();
|
||||
}
|
||||
|
||||
if (!request.requests.length) {
|
||||
print("Received invalid request!", 31);
|
||||
return void 0;
|
||||
|
|
@ -106,42 +108,31 @@ export function onRequest(player, req) {
|
|||
if (CFG.DEBUG_DUMP_TRAFFIC) {
|
||||
this.dumpTraffic(request, returns);
|
||||
}
|
||||
let msg = this.envelopResponse(1, returns, request, player, !!request.auth_ticket);
|
||||
let msg = this.envelopResponse(returns, request, player);
|
||||
player.sendResponse(msg);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} status
|
||||
* @param {Array} returns
|
||||
* @param {Request} req
|
||||
* @param {Request} request
|
||||
* @param {Player} player
|
||||
* @param {Boolean} auth
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export function envelopResponse(status, returns, req, player, auth) {
|
||||
export function envelopResponse(returns, request, player) {
|
||||
|
||||
let buffer = req;
|
||||
let buffer = request;
|
||||
|
||||
delete buffer.requests;
|
||||
|
||||
buffer.returns = returns;
|
||||
|
||||
// get players device platform one time
|
||||
if (player.hasSignature === false && buffer.unknown6 && buffer.unknown6.unknown2) {
|
||||
let sig = this.parseSignature(buffer);
|
||||
if (sig.device_info !== void 0) {
|
||||
player.isIOS = sig.device_info.device_brand === "Apple";
|
||||
player.isAndroid = !player.isIOS;
|
||||
player.hasSignature = true;
|
||||
player.asset_digest = this.assets[player.isAndroid ? "android" : "ios"];
|
||||
print(`${player.email} is playing with an ${player.isIOS ? "Apple" : "Android"} device!`, 36);
|
||||
}
|
||||
if (request.auth_ticket) {
|
||||
print("Authenticate!", 31);
|
||||
buffer.auth_ticket = AuthTicket();
|
||||
}
|
||||
|
||||
if (auth) buffer.auth_ticket = AuthTicket();
|
||||
|
||||
if (buffer.unknown6) {
|
||||
buffer.unknown6 = [{
|
||||
"response_type": 6,
|
||||
|
|
@ -153,7 +144,7 @@ export function envelopResponse(status, returns, req, player, auth) {
|
|||
}];
|
||||
}
|
||||
|
||||
buffer.status_code = status;
|
||||
buffer.status_code = 1;
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Envelopes.ResponseEnvelope")
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@ export function parseMessage(req, type) {
|
|||
*/
|
||||
export function processResponse(player, req) {
|
||||
|
||||
let buffer = null;
|
||||
|
||||
let cc = _toCC(req.request_type);
|
||||
let msg = this.parseMessage(req, cc);
|
||||
|
||||
|
|
@ -41,14 +39,26 @@ export function processResponse(player, req) {
|
|||
|
||||
try {
|
||||
switch (req.request_type) {
|
||||
// Player
|
||||
case "GET_PLAYER":
|
||||
player.getPacket("GET_PLAYER", msg).then((result) => {
|
||||
case "GET_INVENTORY":
|
||||
case "GET_ASSET_DIGEST":
|
||||
case "GET_HATCHED_EGGS":
|
||||
case "CHECK_AWARDED_BADGES":
|
||||
player.getPacket(req.request_type, msg).then((result) => {
|
||||
print(`Success: ${req.request_type} => ${result.toString().length}`);
|
||||
resolve(result);
|
||||
});
|
||||
return void 0;
|
||||
break;
|
||||
// Global
|
||||
case "GET_MAP_OBJECTS":
|
||||
case "CHECK_CHALLENGE":
|
||||
player.world.getPacket("CHECK_CHALLENGE", msg).then((result) => {
|
||||
case "DOWNLOAD_SETTINGS":
|
||||
case "DOWNLOAD_REMOTE_CONFIG_VERSION":
|
||||
case "DOWNLOAD_ITEM_TEMPLATES":
|
||||
player.world.getPacket(req.request_type, msg).then((result) => {
|
||||
print(`Success: ${req.request_type} => ${result.toString().length}`);
|
||||
resolve(result);
|
||||
});
|
||||
return void 0;
|
||||
|
|
@ -61,8 +71,6 @@ export function processResponse(player, req) {
|
|||
print(`Response error: ${e}`, 31);
|
||||
};
|
||||
|
||||
resolve(buffer);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
12
src/setup.js
12
src/setup.js
|
|
@ -6,7 +6,7 @@ import POGOProtos from "pokemongo-protobuf";
|
|||
import print from "./print";
|
||||
import CFG from "../cfg";
|
||||
|
||||
import * as master from "./master";
|
||||
import * as shared from "./shared";
|
||||
|
||||
import GameMaster from "./models/GameMaster";
|
||||
|
||||
|
|
@ -36,9 +36,8 @@ export function setup() {
|
|||
|
||||
print(`Downloaded assets are valid! Proceeding..`);
|
||||
|
||||
master.GAME_MASTER = this.parseGameMaster();
|
||||
|
||||
this.master = POGOProtos.serialize(fs.readFileSync(CFG.DUMP_ASSET_PATH + "game_master"), "POGOProtos.Networking.Responses.DownloadItemTemplatesResponse");
|
||||
let parsedMaster = this.parseGameMaster();
|
||||
shared.GAME_MASTER = new GameMaster(parsedMaster);
|
||||
|
||||
this.setupDatabaseConnection().then(() => {
|
||||
if (CFG.PORT < 1) {
|
||||
|
|
@ -98,10 +97,10 @@ export function validateModels() {
|
|||
}
|
||||
else {
|
||||
let buffer = fs.readFileSync(path + "asset_digest");
|
||||
this.assets[name] = {
|
||||
shared.GAME_ASSETS[name] = {
|
||||
buffer: buffer,
|
||||
decode: this.parseProtobuf(buffer, "POGOProtos.Networking.Responses.GetAssetDigestResponse")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// validate models inside folder
|
||||
|
|
@ -130,7 +129,6 @@ export function parseGameMaster() {
|
|||
try {
|
||||
let data = fs.readFileSync(CFG.DUMP_ASSET_PATH + "game_master");
|
||||
master = this.parseProtobuf(data, "POGOProtos.Networking.Responses.DownloadItemTemplatesResponse");
|
||||
let Master = new GameMaster(master);
|
||||
} catch (e) {
|
||||
print(e, 31);
|
||||
}
|
||||
|
|
|
|||
6
src/shared.js
Normal file
6
src/shared.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/**
|
||||
* Global shared assets
|
||||
*/
|
||||
|
||||
export let GAME_ASSETS = {};
|
||||
export let GAME_MASTER = null;
|
||||
13
src/utils.js
13
src/utils.js
|
|
@ -1,3 +1,6 @@
|
|||
import POGOProtos from "pokemongo-protobuf";
|
||||
import pcrypt from "pcrypt";
|
||||
|
||||
import CFG from "../cfg";
|
||||
|
||||
/**
|
||||
|
|
@ -79,4 +82,14 @@ export function validUsername(str) {
|
|||
return (
|
||||
!!(rx_username.test(str))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
*/
|
||||
export function parseSignature(req) {
|
||||
let key = pcrypt.decrypt(req.unknown6[0].unknown2.encrypted_signature);
|
||||
return (
|
||||
POGOProtos.parseWithUnknown(key, "POGOProtos.Networking.Envelopes.Signature")
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user