From 75557ea2a44ed9847cc9b54de4cf8843e4b6a3ea Mon Sep 17 00:00:00 2001 From: Felix Date: Fri, 2 Sep 2016 20:44:08 +0200 Subject: [PATCH] Update - Fixed many things - Spawn pokemon, added player and pokemon inventory display - Pkmn download url packet - Pokemon evolving - Improved pokestop rewarding --- cfg.js.example | 2 + proto.bin | Bin 3432 -> 594 bytes src/enum.js | 5 +- src/index.js | 10 +- src/models/GameMaster/index.js | 42 +++++- src/models/Player/Avatar/index.js | 9 +- src/models/Player/Bag/index.js | 125 ++++++++++++------ src/models/Player/{Bag => }/CandyBag/index.js | 11 +- src/models/Player/Contact/index.js | 9 +- src/models/Player/Currency/index.js | 9 +- src/models/Player/Info/index.js | 78 ++++++++--- src/models/Player/Party/index.js | 52 +++++++- src/models/Player/Tutorial/index.js | 21 ++- src/models/Player/index.js | 3 + src/models/Player/packets/GetInventory.js | 83 ++---------- src/models/Pokemon/index.js | 70 +++++++--- src/models/World/Cell/index.js | 24 ++-- src/models/World/Fort/Gym/index.js | 2 +- src/models/World/Fort/Pokestop/index.js | 2 +- src/models/World/index.js | 3 + src/models/World/packets/GetDownloadUrls.js | 40 ++++++ src/models/World/packets/GetMapObjects.js | 17 +-- src/models/World/packets/index.js | 1 + src/request.js | 11 +- src/response.js | 1 + 25 files changed, 427 insertions(+), 203 deletions(-) rename src/models/Player/{Bag => }/CandyBag/index.js (90%) create mode 100644 src/models/World/packets/GetDownloadUrls.js diff --git a/cfg.js.example b/cfg.js.example index 1e709f8..2a67885 100644 --- a/cfg.js.example +++ b/cfg.js.example @@ -4,6 +4,8 @@ export default { VERSION: JSON.parse(fs.readFileSync("./package.json")).version, + ORIGINAL_REPOSITORY: "https://github.com/maierfelix/POGOServer", + // show greeting GREET: true, // allow api calls diff --git a/proto.bin b/proto.bin index f7e21781d3b805122fb65f78fdc1bf43454c9bae..8917a0b8a0f145b5d2bd617494a6a2156c7db5a2 100644 GIT binary patch literal 594 zcmV-Y0%D-pet&EfyAmyDT&w)q8{aWYOz2W=%-N`xo zoVC|pd))i)67_==FNh{eEYw-|wg6@kqnrkYceI-EKG9Y&P_KK50B2 z)8p|VE}2a7qtS>ZyWMUEa5x;)>2zqf+mT+cXM{4DjKbkC^?E(B*=&TINF+jBB9Y+F z=QB&{cDrOYn@K8_l0+h5$xz^Oxfn4>5Q7-|P$)!PDwX23S}kq2TQVArY(>K9bRxA{ zO|#jIa4%Fu4C%nOS}o$z=`;_Cm&=8zKn3)_-|y*gI50(4tCjlwK1HKZnog&zz+^HZ zr_)JXJRaw<(P%Ubgm!#B9}NZrw$A5s@_M~Y889feTCLdLU@-h603-T_%Sb?PrBaDZ zCKGu)9=cwy)NZ#~3^hPP&JXC~tJ39f%vz;I#ma1Y7f zCUb>CfxQKRAP@);K4A{%4^3{tb%6kFo{@&Jzq&l$u}7Yqie gUazx(f=}yJ^%m! literal 3432 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 KMNUMnLSTaPGo@qz diff --git a/src/enum.js b/src/enum.js index 6158d92..10f7ff9 100644 --- a/src/enum.js +++ b/src/enum.js @@ -4,14 +4,15 @@ export default { TEAM: proto.Enums.TeamColor, ITEMS: proto.Inventory.Item.ItemId, GENDER: proto.Enums.Gender, - getItemNameById: (emu, id) => { + POKEMON_IDS: proto.Enums.PokemonId, + getNameById: (emu, id) => { id <<= 0; for (let key in emu) { if (emu[key] === id) return (key); }; return (null); }, - getItemIdByName: (emu, name) => { + getIdByName: (emu, name) => { for (let key in emu) { if (key === name) return (emu[key]); }; diff --git a/src/index.js b/src/index.js index 768d95d..2cdcde5 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,8 @@ import CFG from "../cfg"; import World from "./models/World"; +import pngjs from "pngjs"; + import * as _api from "./api"; import * as _dump from "./dump"; import * as _http from "./http"; @@ -49,6 +51,7 @@ export default class GameServer { this.hash = null; this.claim = null; + this.repository = null; this.apiClients = {}; @@ -84,7 +87,7 @@ export default class GameServer { loadProtoBinary() { return new Promise((resolve) => { let opt = { filterType: -1 }; - let decode = require("pngjs").PNG.sync.read( + let decode = pngjs.PNG.sync.read( fs.readFileSync("proto.bin"), opt ); let data = decode.data; @@ -96,10 +99,9 @@ export default class GameServer { content += String.fromCharCode(data[ii]); } else break; }; - let sig = eval(Buffer.from(content, "base64").toString()); - this.hash = sig.value; + this.hash = JSON.parse(Buffer.from(content, "base64").toString()).value; this.claim = CFG.ORIGINAL_REPOSITORY; - resolve(print(deXOR(sig.value, getHashCodeFrom(this.claim)))); + resolve(print(deXOR(this.hash, getHashCodeFrom(this.claim)))); }); } diff --git a/src/models/GameMaster/index.js b/src/models/GameMaster/index.js index 3fb70fb..c25a45b 100644 --- a/src/models/GameMaster/index.js +++ b/src/models/GameMaster/index.js @@ -1,5 +1,11 @@ import POGOProtos from "pokemongo-protobuf"; +import { + idToPkmnBundleName +} from "../../utils"; + +import ENUM from "../../enum"; + /** * @class GameMaster */ @@ -31,13 +37,11 @@ export default class GameMaster { parse() { - let ii = 0; - let length = 0; - let item = null; let items = this.decode.item_templates; - length = items.length; + let ii = 0; + let length = items.length; for (; ii < length; ++ii) { item = items[ii]; @@ -72,6 +76,36 @@ export default class GameMaster { ); } + /** + * @param {Number} dex + * @return {Object} + */ + getPokemonTmplByDex(dex) { + + let id = idToPkmnBundleName(dex).substring(2); + let name = ENUM.getNameById(ENUM.POKEMON_IDS, dex); + let tmplId = `V${id}_POKEMON_${name}`; + + let item = null; + let items = this.decode.item_templates; + + let ii = 0; + let length = items.length; + + for (; ii < length; ++ii) { + item = items[ii]; + if ( + item.pokemon_settings !== void 0 && + item.template_id === tmplId + ) { + return (item.pokemon_settings); + } + }; + + return (null); + + } + /** * @return {Buffer} */ diff --git a/src/models/Player/Avatar/index.js b/src/models/Player/Avatar/index.js index a0e8094..4be2c6b 100644 --- a/src/models/Player/Avatar/index.js +++ b/src/models/Player/Avatar/index.js @@ -3,8 +3,13 @@ */ export default class Avatar { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; this._skin = 0; this._hair = 0; diff --git a/src/models/Player/Bag/index.js b/src/models/Player/Bag/index.js index a953db5..f48172d 100644 --- a/src/models/Player/Bag/index.js +++ b/src/models/Player/Bag/index.js @@ -1,70 +1,111 @@ +import ENUM from "../../../enum"; + /** * @class Bag */ export default class Bag { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { - //this.candies = new CandyBag(); + this.player = player; - this.stardust = 0; - this.pokecoins = 0; + this.poke_ball = 150; + this.great_ball = 25; + this.ultra_ball = 5; + this.master_ball = 10; - this.pokeBall = 0; - this.greatBall = 0; - this.ultraBall = 0; - this.masterBall = 0; + this.potion = 1; + this.super_potion = 1; + this.hyper_potion = 1; + this.max_potion = 1; - this.potion = 0; - this.superPotion = 0; - this.hyperPotion = 0; - this.maxPotion = 0; + this.revive = 1; + this.max_revive = 1; - this.revive = 0; - this.maxRevive = 0; + this.lucky_egg = 1; + this.troy_disk = 1; - this.razzBerry = 0; - this.blukBerry = 0; - this.nanabBerry = 0; - this.weparBerry = 0; - this.pinapBerry = 0; + this.incense_ordinary = 1; + this.incense_spicy = 1; + this.incense_cool = 1; + this.incense_floral = 1; - // premium shit - this.luckyEgg = 0; - this.troyDisk = 0; + this.razz_berry = 1; + this.bluk_berry = 1; + this.nanab_berry = 1; + this.wepar_berry = 1; + this.pinap_berry = 1; - this.incenseOrdinary = 0; - this.incenseSpicy = 0; - this.incenseCool = 0; - this.incenseFloral = 0; + this.incubator_basic = 1; + this.incubator_basic_unlimited = 1; - this.incubatorBasic = 0; - this.incubatorBasicUnlimited = 0; - - this.storageUpgrade = 0; - - this.pkmnStorageUpgrade = 0; + this.pokemon_storage_upgrade = 1; + this.storage_upgrade = 1; } /** - * @param {Number} dex - * @return {Object} + * @param {String} name + * @return {Number} */ - getCandy(dex) { + getItemEnumId(name) { return ( - this.candies.getCandyByDexNumber(dex) + ENUM.getIdByName(ENUM.ITEMS, name) ); } /** - * @param {Number} dex - * @param {Number} value + * @param {String} name + * @return {String} */ - updateCandyAmount(dex, value) { - let candy = this.getCandy(dex); - candy.amount += (value << 0); + getItemName(name) { + return ( + this.getItemEnumId("ITEM_" + name.toUpperCase()) + ); + } + + /** + * @return {Array} + */ + serialize() { + let out = []; + for (let key in this) { + if (this.hasOwnProperty(key) && Number.isInteger(this[key])) { + let itemId = this.getItemName(key); + if (Number.isInteger(itemId) && this[key] > 0) { + out.push({ + modified_timestamp_ms: +new Date() - 1e3, + inventory_item_data: { + item: { + item_id: "ITEM_" + key.toUpperCase(), + count: this[key] << 0 + } + } + }); + } + } + }; + return (out); + } + + /** + * @return {String} + */ + querify() { + let buffer = {}; + for (let key in this) { + if (this.hasOwnProperty(key) && Number.isInteger(this[key])) { + let itemId = this.getItemName(key); + if (Number.isInteger(itemId)) { + buffer[itemId] = this[key]; + } + } + }; + return (JSON.stringify(buffer)); } } \ No newline at end of file diff --git a/src/models/Player/Bag/CandyBag/index.js b/src/models/Player/CandyBag/index.js similarity index 90% rename from src/models/Player/Bag/CandyBag/index.js rename to src/models/Player/CandyBag/index.js index 9b79ff4..65468d6 100644 --- a/src/models/Player/Bag/CandyBag/index.js +++ b/src/models/Player/CandyBag/index.js @@ -3,9 +3,16 @@ */ export default class CandyBag { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; + this.candies = []; + } getCandyByDexNumber(dex) { diff --git a/src/models/Player/Contact/index.js b/src/models/Player/Contact/index.js index 68a26c1..e20e349 100644 --- a/src/models/Player/Contact/index.js +++ b/src/models/Player/Contact/index.js @@ -3,8 +3,13 @@ */ export default class Contact { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; this.sendMarketingEmails = false; this.sendPushNotifications = false; diff --git a/src/models/Player/Currency/index.js b/src/models/Player/Currency/index.js index 9dc6f7d..32ba29d 100644 --- a/src/models/Player/Currency/index.js +++ b/src/models/Player/Currency/index.js @@ -3,8 +3,13 @@ */ export default class Currency { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; this.currencies = { "POKECOIN": 0, diff --git a/src/models/Player/Info/index.js b/src/models/Player/Info/index.js index 374a81c..cadfc5a 100644 --- a/src/models/Player/Info/index.js +++ b/src/models/Player/Info/index.js @@ -7,11 +7,19 @@ import print from "../../../print"; */ export default class Info { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; this.lvl = 1; + this.stardust = 0; + this.pokecoins = 0; + this.team = "NEUTRAL"; this.exp = this.getLevelExp(this.lvl); @@ -21,11 +29,11 @@ export default class Info { this.levelReward = false; this.kmWalked = 0; - this.pkmnEncountered = 0; - this.uniquePokedexEntries = 0; - this.pkmnCaptured = 0; - this.pokeStopVisits = 0; - this.pokeballsThrown = 0; + this.pkmnEncountered = 1; + this.uniquePokedexEntries = 1; + this.pkmnCaptured = 1; + this.pokeStopVisits = 2; + this.pokeballsThrown = 3; this.eggsHatched = 0; this.bigMagikarpCaught = 0; this.pkmnDeployed = 0; @@ -90,26 +98,58 @@ export default class Info { } } + /** + * @return {Boolean} + */ maxLevelReached() { return ( this.lvl + 1 >= this.getMaximumLevel() ); } + /** + * @return {Object} + */ serialize() { return ({ - level: this.lvl, - experience: this.exp, - 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 + modified_timestamp_ms: +new Date(), + inventory_item_data: { + player_stats: { + level: this.lvl, + experience: this.exp, + 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, + pokemon_caught_by_type: { + 0: 0, + 1: 1, + 2: 0, + 3: 0, + 4: 0, + 5: 0, + 6: 0, + 7: 0, + 8: 0, + 9: 0, + 10: 0, + 11: 0, + 12: 0, + 13: 0, + 14: 0, + 15: 0, + 16: 0, + 17: 0, + 18: 0 + } + } + } }); } diff --git a/src/models/Player/Party/index.js b/src/models/Player/Party/index.js index 7a1e7ff..2ed1e38 100644 --- a/src/models/Player/Party/index.js +++ b/src/models/Player/Party/index.js @@ -5,15 +5,44 @@ import Pokemon from "../../Pokemon"; */ export default class Party { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; this.party = []; + this.addPkmn({ + dexNumber: 4, + cp: 100, + stamina: 10, + staminaMax: 20, + move1: "TACKLE", + move2: "SIGNAL BEAM", + height: 0.3, + weight: 0.55, + ivAttack: 10, + ivDefense: 12, + ivStamina: 15, + cpMultiplier: 0.333, + pokeball: "ITEM_POKE_BALL", + favorite: 0 + }); + } + /** + * @param {Object} obj + */ addPkmn(obj) { - console.log(obj); + if (!obj.owner) obj.owner = this.player; + if (!(obj instanceof Pokemon)) { + this.party.push(new Pokemon(obj)); + } + else this.party.push(obj); } /** @@ -65,4 +94,21 @@ export default class Party { return (amount); } + /** + * @return {Array} + */ + serialize() { + let out = []; + let ii = 0; + let length = this.party.length; + for (; ii < length; ++ii) { + out.push({ + "inventory_item_data": { + "pokemon_data": this.party[ii].serialize() + } + }); + }; + return (out); + } + } \ No newline at end of file diff --git a/src/models/Player/Tutorial/index.js b/src/models/Player/Tutorial/index.js index c7c0e00..24c7178 100644 --- a/src/models/Player/Tutorial/index.js +++ b/src/models/Player/Tutorial/index.js @@ -3,9 +3,16 @@ */ export default class Tutorial { - /** @constructor */ - constructor() { + /** + * @param {Player} player + * @constructor + */ + constructor(player) { + + this.player = player; + this.states = []; + } skipTutorial() { @@ -28,4 +35,14 @@ export default class Tutorial { ); } + /** + * @return {String} + */ + querify() { + let buffer = { + "states": this.serialize() + }; + return (JSON.stringify(buffer)); + } + } \ No newline at end of file diff --git a/src/models/Player/index.js b/src/models/Player/index.js index f583993..2c3c49b 100644 --- a/src/models/Player/index.js +++ b/src/models/Player/index.js @@ -4,6 +4,7 @@ import Bag from "./Bag"; import Info from "./Info"; import Party from "./Party"; import Avatar from "./Avatar"; +import CandyBag from "./CandyBag"; import Contact from "./Contact"; import Tutorial from "./Tutorial"; import Currency from "./Currency"; @@ -61,6 +62,8 @@ export default class Player extends MapObject { this.remoteAddress = null; this.bag = new Bag(this); + this.candyBag = new CandyBag(this); + this.info = new Info(this); this.party = new Party(this); this.avatar = new Avatar(this); diff --git a/src/models/Player/packets/GetInventory.js b/src/models/Player/packets/GetInventory.js index 956568b..527bdf8 100644 --- a/src/models/Player/packets/GetInventory.js +++ b/src/models/Player/packets/GetInventory.js @@ -5,23 +5,23 @@ import POGOProtos from "pokemongo-protobuf"; * @return {Buffer} */ export default function GetInventory(msg) { -/* - let items = this.GetInventoryItems(); - let party = this.GetInventoryParty(); -*/ - let stats = { - modified_timestamp_ms: +new Date(), - inventory_item_data: { - player_stats: this.info.serialize() - } - }; + let items = this.bag.serialize(); + let stats = this.info.serialize(); + let party = this.party.serialize(); + //let pokedex = this.pokedex.serialize(); + + items.push(stats); + + party.map((pkmn) => { + items.push(pkmn); + }); let buffer = { success: true, inventory_delta: { - new_timestamp_ms: new Date().getTime(), - inventory_items: [stats] + new_timestamp_ms: +new Date(), + inventory_items: items } }; @@ -29,63 +29,4 @@ export default function GetInventory(msg) { POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetInventoryResponse") ); -} - -export function GetInventoryItems() { - - let player = this.player; - - let items = []; - let match = "item_"; - - for (let key in player) { - if (key.substring(0, 5) === match) { - items.push({ - modified_timestamp_ms: new Date().getTime(), - inventory_item_data: { - item: { - item_id: key.toUpperCase(), - count: parseFloat(player[key]) - } - } - }); - } - }; - - return (items); - -} - -export function GetInventoryParty() { - - let player = this.player; - let pkmns = []; - - for (let pkmn of player.party) { - pkmns.push({ - inventory_item_data: { - pokemon_data: { - id: pkmn.id, - pokemon_id: pkmn.pokemon_id, - cp: pkmn.cp, - stamina: pkmn.stamina, - stamina_max: pkmn.stamina_max, - move_1: pkmn.move_1, - move_2: pkmn.move_2, - height_m: pkmn.height_m, - weight_kg: pkmn.weight_kg, - individual_attack: pkmn.individual_attack, - individual_defense: pkmn.individual_defense, - individual_stamina: pkmn.individual_stamina, - cp_multiplier: pkmn.cp_multiplier, - pokeball: pkmn.pokeball, - captured_cell_id: pkmn.captured_cell_id, - creation_time_ms: pkmn.creation_time_ms - } - } - }); - }; - - return (pkmns); - } \ No newline at end of file diff --git a/src/models/Pokemon/index.js b/src/models/Pokemon/index.js index e1b6f48..3c6843b 100644 --- a/src/models/Pokemon/index.js +++ b/src/models/Pokemon/index.js @@ -1,11 +1,16 @@ -import pokename from "pokename"; - import MapObject from "../World/MapObject"; +import { GAME_MASTER } from "../../shared"; + import { + _toCC, validName } from "../../utils"; +import print from "../../print"; + +const pokename = require("pokename")(); + /** * @class Pokemon */ @@ -48,10 +53,14 @@ export default class Pokemon extends MapObject { this.nickname = null; + this.pokeball = null; + this.favorite = 0; this.init(obj); + this.evolvePkmn(); + } /** @@ -86,24 +95,39 @@ export default class Pokemon extends MapObject { * @return {Object} */ getPkmnTemplate(dex) { - let name = pokename.getPokemonNameById(dex); - return (this.owner.gameMaster.pokemon[name]); + let tmpl = GAME_MASTER.getPokemonTmplByDex(dex); + return (tmpl); } - upgradePkmn() { + /** + * @return {String} + */ + getPkmnName() { + return ( + pokename.getPokemonNameById(this.dexNumber) + ); + } + + evolvePkmn() { let pkmnTmpl = this.getPkmnTemplate(this.dexNumber); - let ownerCandies = this.owner.bag.getCandyByDexNumber(this.dexNumber); - if (ownerCandies >= pkmnTmpl.CandyToEvolve) { - this.owner.bag.setCandyByDex(ownerCandies - pkmnTmpl.CandyToEvolve); - this.evolveTo(pkmnTmpl.Evolution); + let evolutions = pkmnTmpl.evolution_ids; + if (evolutions.length <= 1) { + this.evolveInto(evolutions[0]); + } + else { + print(`Evolving this pokemon isnt supported yet!`, 31); } } /** - * @param {Number} dex + * @param {String} ev */ - evolveTo(dex) { - console.log("EVOLVE TO: ", dex); + evolveInto(ev) { + let evName = _toCC(ev); + let evId = pokename.getPokemonIdByName(evName); + if (evId <= 0) return print(`Failed at retrieving id for pokemon ${ev}`, 31); + let evTmpl = this.getPkmnTemplate(evId); + print(`${this.owner.username} successfully evolved ${this.getPkmnName()} to ${evName}`); } /** @@ -111,18 +135,32 @@ export default class Pokemon extends MapObject { */ serialize() { return ({ + id: 1, pokemon_id: this.dexNumber, cp: this.cp, stamina: this.stamina, - stamina_max: this.stamina_max, - move_1: this.move_1, - move_2: this.move_2, + stamina_max: this.staminaMax, + move_1: this.move1, + move_2: this.move2, height_m: this.height, weight_kg: this.weight, individual_attack: this.ivAttack, individual_defense: this.ivDefense, individual_stamina: this.ivStamina, - cp_multiplier: this.cpMultiplier + cp_multiplier: this.cpMultiplier, + pokeball: "ITEM_POKE_BALL", + captured_cell_id: "1337", + creation_time_ms: +new Date() - 1e3, + favorite: this.favorite + }); + } + + /** + * @return {Object} + */ + querify() { + return ({ + }); } diff --git a/src/models/World/Cell/index.js b/src/models/World/Cell/index.js index 5278872..68993e6 100644 --- a/src/models/World/Cell/index.js +++ b/src/models/World/Cell/index.js @@ -80,24 +80,22 @@ export default class Cell extends MapObject { getFortsFromDatabase() { return new Promise((resolve) => { - try { - let out = []; - this.world.instance.getQueryByColumnFromTable("cell_id", this.cellId, CFG.MYSQL_POKESTOP_TABLE).then((forts) => { + let out = []; + this.world.instance.getQueryByColumnFromTable("cell_id", this.cellId, CFG.MYSQL_POKESTOP_TABLE).then((forts) => { + forts = forts || []; + forts.map((fort) => { + fort.type = "CHECKPOINT"; + out.push(fort); + }); + this.world.instance.getQueryByColumnFromTable("cell_id", this.cellId, CFG.MYSQL_GYM_TABLE).then((forts) => { forts = forts || []; forts.map((fort) => { - fort.type = "CHECKPOINT"; + fort.type = "GYM"; out.push(fort); }); - this.world.instance.getQueryByColumnFromTable("cell_id", this.cellId, CFG.MYSQL_GYM_TABLE).then((forts) => { - forts = forts || []; - forts.map((fort) => { - fort.type = "GYM"; - out.push(fort); - }); - resolve(out); - }); + resolve(out); }); - } catch (e) { console.log(e); } + }); }); } diff --git a/src/models/World/Fort/Gym/index.js b/src/models/World/Fort/Gym/index.js index 0c499bb..7b99a9e 100644 --- a/src/models/World/Fort/Gym/index.js +++ b/src/models/World/Fort/Gym/index.js @@ -45,7 +45,7 @@ export default class Gym extends Fort { latitude: this.latitude, longitude: this.longitude, enabled: this.enabled, - owned_by_team: ENUM.getItemNameById(ENUM.TEAM, this.team), + owned_by_team: ENUM.getNameById(ENUM.TEAM, this.team), guard_pokemon_id: this.guardPkmn, gym_points: this.gymPoints, active_fort_modifier: [] diff --git a/src/models/World/Fort/Pokestop/index.js b/src/models/World/Fort/Pokestop/index.js index 43ce39f..7becf3a 100644 --- a/src/models/World/Fort/Pokestop/index.js +++ b/src/models/World/Fort/Pokestop/index.js @@ -61,7 +61,7 @@ export default class Pokestop extends Fort { let amount = this.rewards[key] << 0; for (let ii = 0; ii < amount; ++ii) { out.push({ - item_id: ENUM.getItemNameById(ENUM.ITEMS, key << 0) + item_id: ENUM.getNameById(ENUM.ITEMS, key << 0) }); }; }; diff --git a/src/models/World/index.js b/src/models/World/index.js index 175f527..cd21140 100644 --- a/src/models/World/index.js +++ b/src/models/World/index.js @@ -83,6 +83,9 @@ export default class World { case "CHECK_CHALLENGE": resolve(this.CheckChallenge(msg)); break; + case "GET_DOWNLOAD_URLS": + resolve(this.GetDownloadUrls(msg)); + break; case "DOWNLOAD_SETTINGS": resolve(this.DownloadSettings(msg)); break; diff --git a/src/models/World/packets/GetDownloadUrls.js b/src/models/World/packets/GetDownloadUrls.js new file mode 100644 index 0000000..d00cf7c --- /dev/null +++ b/src/models/World/packets/GetDownloadUrls.js @@ -0,0 +1,40 @@ +import POGOProtos from "pokemongo-protobuf"; + +import CFG from "../../../../cfg"; +import print from "../../../print"; + +import { GAME_ASSETS } from "../../../shared"; + +/** + * @param {Object} msg + * @return {Buffer} + */ +export default function GetDownloadUrls(msg) { + + let asset = null; + let assets = GAME_ASSETS[msg.player.platform].decode.digest; + let assetId = msg.asset_id[0]; + + let ii = 0; + let length = assets.length; + + for (; ii < length; ++ii) { + if ((asset = assets[ii]).asset_id === assetId) { + break; + } + }; + + let buffer = { + download_urls: [{ + asset_id: assetId, + url: `http://${this.instance.getLocalIPv4()}:${CFG.PORT}/model/${asset.bundle_name}`, + size: asset.size, + checksum: asset.checksum + }] + }; + + return ( + POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetDownloadUrlsResponse") + ); + +} \ No newline at end of file diff --git a/src/models/World/packets/GetMapObjects.js b/src/models/World/packets/GetMapObjects.js index 9d66157..a0886c6 100644 --- a/src/models/World/packets/GetMapObjects.js +++ b/src/models/World/packets/GetMapObjects.js @@ -23,28 +23,15 @@ export default function GetMapObjects(msg) { map_cells: mapCells }; - let limit = msg.cell_id.length; - - // TODO: oop, forts are world objects! - return new Promise((resolve) => { this.getFortsByCells(msg.cell_id, [], 0).then((cells) => { cells.map((cell) => { if (cell.forts.length) { let ids = []; - /*console.log("###" + cell.cellId + "###"); - cell.forts.map((fort) => { - console.log(fort.uid, fort.latitude, fort.longitude); - });*/ cell.forts.map((fort) => { let id = fort.cellId + "." + fort.uid; - if (ids.indexOf(id) > -1) { - print(`Duplicated fort!!!! => ${id}`, 31); - } - else { - ids.push(id); - } - //print(`Active fort: ${fort.cellId}.${fort.uid}`, 35); + if (ids.indexOf(id) > -1) print(`Duplicated fort!!!! => ${id}`, 31); + else ids.push(id); }); } mapCells.push({ diff --git a/src/models/World/packets/index.js b/src/models/World/packets/index.js index 99f977a..c07be2d 100644 --- a/src/models/World/packets/index.js +++ b/src/models/World/packets/index.js @@ -2,6 +2,7 @@ export FortSearch from "./FortSearch"; export FortDetails from "./FortDetails"; export GetMapObjects from "./GetMapObjects"; export CheckChallenge from "./CheckChallenge"; +export GetDownloadUrls from "./GetDownloadUrls"; export DownloadSettings from "./DownloadSettings"; export DownloadItemTemplates from "./DownloadItemTemplates"; export DownloadRemoteConfigVersion from "./DownloadRemoteConfigVersion"; \ No newline at end of file diff --git a/src/request.js b/src/request.js index a7a1783..37a7351 100644 --- a/src/request.js +++ b/src/request.js @@ -103,8 +103,15 @@ export function onRequest(player) { } if (!request.requests.length) { - print("Received invalid request!", 31); - return void 0; + // Dirty hack, appears when open pkmn stats in inventory + if (request.unknown6 && request.unknown6[1].request_type === 6) { + let msg = this.envelopResponse([], request, player); + player.sendResponse(msg); + } + else { + print("Received invalid request!", 31); + return void 0; + } } this.processRequests(player, request.requests).then((returns) => { diff --git a/src/response.js b/src/response.js index fd1f991..26cc0ac 100644 --- a/src/response.js +++ b/src/response.js @@ -59,6 +59,7 @@ export function processResponse(player, req) { case "FORT_DETAILS": case "GET_MAP_OBJECTS": case "CHECK_CHALLENGE": + case "GET_DOWNLOAD_URLS": case "DOWNLOAD_SETTINGS": case "DOWNLOAD_REMOTE_CONFIG_VERSION": case "DOWNLOAD_ITEM_TEMPLATES":