mirror of
https://github.com/maierfelix/POGOserver.git
synced 2026-09-29 04:47:30 -05:00
Update
- Extended enums - Improved stdin - Fixed bugs related with player gender, team and currency serialisation - Added basic level up rewards, player profile and ser avatar handling - Load player settings out of game master - Added option to dump assets by console command "/dump"
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import proto from "node-pogo-protos";
|
||||
|
||||
export default {
|
||||
TEAM: proto.Enums.TeamColor,
|
||||
ITEMS: proto.Inventory.Item.ItemId,
|
||||
GENDER: proto.Enums.Gender,
|
||||
getItemNameById: (emu, id) => {
|
||||
id <<= 0;
|
||||
for (let key in emu) {
|
||||
|
||||
13
src/index.js
13
src/index.js
@@ -1,6 +1,7 @@
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import request from "request";
|
||||
import readline from "readline";
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import {
|
||||
@@ -44,6 +45,8 @@ export default class GameServer {
|
||||
|
||||
this.db = null;
|
||||
|
||||
this.repository = null;
|
||||
|
||||
this.apiClients = {};
|
||||
|
||||
this.socket = null;
|
||||
@@ -62,6 +65,7 @@ export default class GameServer {
|
||||
this.getLatestVersion().then((latest) => {
|
||||
let current = require("../package.json").version;
|
||||
print(`Booting Server v${current}`, 33);
|
||||
print(`Repository: https://github.com/${this.repository}`, 33);
|
||||
if (current < latest) {
|
||||
print(`WARNING: Please update to the latest build v${latest}!`, 33);
|
||||
}
|
||||
@@ -81,6 +85,7 @@ export default class GameServer {
|
||||
url = url.replace("git://", "");
|
||||
url = url.replace(".git", "");
|
||||
url = url.replace("github.com/", "");
|
||||
this.repository = url;
|
||||
url = `${base}/${url}/${branch}/package.json`;
|
||||
resolve(url);
|
||||
});
|
||||
@@ -190,7 +195,13 @@ inherit(GameServer, _mysql_create);
|
||||
|
||||
const server = new GameServer();
|
||||
|
||||
process.openStdin().addListener("data", (data) => {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
terminal: false
|
||||
});
|
||||
|
||||
rl.on("line", (data) => {
|
||||
server.stdinInput(data);
|
||||
});
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export default class Avatar {
|
||||
this._hat = 0;
|
||||
this._shoes = 0;
|
||||
this._eyes = 0;
|
||||
this._gender = 0;
|
||||
this._gender = "MALE";
|
||||
this._backpack = 0;
|
||||
|
||||
}
|
||||
@@ -105,7 +105,7 @@ export default class Avatar {
|
||||
return (this._gender);
|
||||
}
|
||||
set gender(value) {
|
||||
if (this.between(value, 0, 1)) {
|
||||
if (value === "MALE" || value === "FEMALE") {
|
||||
this._gender = value;
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,7 @@ export default class Avatar {
|
||||
hat: this.hat,
|
||||
shoes: this.shoes,
|
||||
eyes: this.eyes,
|
||||
gender: this.gender,
|
||||
gender: this.gender ? "FEMALE" : "MALE",
|
||||
backpack: this.backpack
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export default class Currency {
|
||||
constructor() {
|
||||
|
||||
this.currencies = {
|
||||
"POKECOINS": 0,
|
||||
"POKECOIN": 0,
|
||||
"STARDUST": 0
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { GAME_MASTER } from "../../../shared";
|
||||
|
||||
import print from "../../../print";
|
||||
|
||||
/**
|
||||
* @class Info
|
||||
*/
|
||||
@@ -6,13 +10,15 @@ export default class Info {
|
||||
/** @constructor */
|
||||
constructor() {
|
||||
|
||||
this.lvl = 0;
|
||||
this.lvl = 1;
|
||||
|
||||
this.team = 0;
|
||||
this.team = "NEUTRAL";
|
||||
|
||||
this.exp = 0;
|
||||
this.prevLvlExp = 0;
|
||||
this.nextLvlExp = 0;
|
||||
this.exp = this.getLevelExp(this.lvl);
|
||||
this.prevLvlExp = this.getLevelExp(this.lvl);
|
||||
this.nextLvlExp = this.getLevelExp(this.lvl + 1);
|
||||
|
||||
this.levelReward = false;
|
||||
|
||||
this.kmWalked = 0;
|
||||
this.pkmnEncountered = 0;
|
||||
@@ -35,13 +41,13 @@ export default class Info {
|
||||
|
||||
getLevelSettings() {
|
||||
return (
|
||||
this.owner.gameMaster("PLAYER_LEVEL_SETTINGS")
|
||||
GAME_MASTER.settings.PLAYER_LEVEL_SETTINGS.player_level
|
||||
);
|
||||
}
|
||||
|
||||
getMaximumLevel() {
|
||||
return (
|
||||
Object.keys(this.getLevelSettings().player_level).length
|
||||
this.getLevelSettings().required_experience.length
|
||||
);
|
||||
}
|
||||
|
||||
@@ -55,29 +61,45 @@ export default class Info {
|
||||
return (1);
|
||||
}
|
||||
|
||||
getLevelExp(lvl) {
|
||||
return (
|
||||
this.getLevelSettings().required_experience[lvl - 1]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Number} exp
|
||||
*/
|
||||
upgradeExp(exp) {
|
||||
let levels = this.getLevelSettings().required_experience;
|
||||
let maxLevel = this.getMaximumLevel();
|
||||
let currentLevel = this.getCurrentLevel();
|
||||
if (currentLevel + 1 <= maxLevel) {
|
||||
this.lvl += 1;
|
||||
this.exp += exp;
|
||||
this.prevLvlExp = levels[this.lvl - 1];
|
||||
this.nextLvlExp = levels[this.lvl + 1];
|
||||
}
|
||||
else {
|
||||
this.exp += exp;
|
||||
if (!this.maxLevelReached()) {
|
||||
let currentLevelExp = this.getLevelExp(this.lvl);
|
||||
let nextLevelExp = this.getLevelExp(this.lvl + 1);
|
||||
let leftExp = nextLevelExp - this.exp;
|
||||
this.levelReward = false;
|
||||
if (this.exp + exp >= nextLevelExp) {
|
||||
this.lvl += 1;
|
||||
this.prevLvlExp = nextLevelExp;
|
||||
this.nextLvlExp = this.getLevelExp(this.lvl + 1);
|
||||
this.exp += leftExp + 1;
|
||||
this.levelReward = true;
|
||||
this.upgradeExp(exp - leftExp);
|
||||
}
|
||||
else {
|
||||
this.exp += exp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maxLevelReached() {
|
||||
return (
|
||||
this.lvl + 1 >= this.getMaximumLevel()
|
||||
);
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return ({
|
||||
level: this.lvl,
|
||||
experience: this.exp,
|
||||
prev_level_xp: this.prevLvlExp,
|
||||
next_level_xp: this.nextLvlExp,
|
||||
km_walked: this.kmWalked,
|
||||
pokemons_encountered: this.pkmnEncountered,
|
||||
|
||||
@@ -119,6 +119,15 @@ export default class Player extends MapObject {
|
||||
getPacket(type, msg) {
|
||||
return new Promise((resolve) => {
|
||||
switch (type) {
|
||||
case "LEVEL_UP_REWARDS":
|
||||
resolve(this.LevelUpRewards(msg));
|
||||
break;
|
||||
case "GET_PLAYER_PROFILE":
|
||||
resolve(this.GetPlayerProfile(msg));
|
||||
break;
|
||||
case "SET_AVATAR":
|
||||
resolve(this.SetAvatar(msg));
|
||||
break;
|
||||
case "GET_PLAYER":
|
||||
resolve(this.GetPlayer(msg));
|
||||
break;
|
||||
@@ -138,6 +147,26 @@ export default class Player extends MapObject {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
getPlayerData() {
|
||||
return ({
|
||||
creation_timestamp_ms: +new Date(),
|
||||
username: this.username,
|
||||
team: this.info.team,
|
||||
tutorial_state: this.tutorial.serialize(),
|
||||
avatar: this.avatar.serialize(),
|
||||
max_pokemon_storage: 250,
|
||||
max_item_storage: 350,
|
||||
daily_bonus: {},
|
||||
equipped_badge: {},
|
||||
contact_settings: this.contact.serialize(),
|
||||
currencies: this.currency.serialize(),
|
||||
remaining_codename_claims: 0
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inherit(Player, _packets);
|
||||
@@ -1,5 +1,7 @@
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
import ENUM from "../../../enum";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
@@ -7,22 +9,12 @@ import POGOProtos from "pokemongo-protobuf";
|
||||
export default function GetPlayer(msg) {
|
||||
|
||||
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.currency.serialize()
|
||||
success: true,
|
||||
player_data: this.getPlayerData()
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize({ success: true, player_data: buffer }, "POGOProtos.Networking.Responses.GetPlayerResponse")
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetPlayerResponse")
|
||||
);
|
||||
|
||||
}
|
||||
@@ -2,6 +2,18 @@ import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
export default function GetPlayerProfile() {
|
||||
|
||||
let buffer = ({
|
||||
result: "SUCCESS",
|
||||
start_time: +new Date(),
|
||||
badges: [
|
||||
{
|
||||
badge_type: "BADGE_TRAVEL_KM",
|
||||
end_value: 2674,
|
||||
current_value: 1337
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.GetPlayerProfileResponse")
|
||||
);
|
||||
|
||||
28
src/models/Player/packets/LevelUpRewards.js
Normal file
28
src/models/Player/packets/LevelUpRewards.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function LevelUpRewards(msg) {
|
||||
|
||||
let buffer = {
|
||||
result: "SUCCESS",
|
||||
items_awarded: [
|
||||
{
|
||||
item_id: "ITEM_POKE_BALL",
|
||||
item_count: 2
|
||||
},
|
||||
{
|
||||
item_id: "ITEM_TROY_DISK",
|
||||
item_count: 2
|
||||
}
|
||||
],
|
||||
items_unlocked: []
|
||||
};
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.LevelUpRewardsResponse")
|
||||
);
|
||||
|
||||
}
|
||||
22
src/models/Player/packets/SetAvatar.js
Normal file
22
src/models/Player/packets/SetAvatar.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import POGOProtos from "pokemongo-protobuf";
|
||||
|
||||
/**
|
||||
* @param {Object} msg
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export default function SetAvatar(msg) {
|
||||
|
||||
for (let key in msg.player_avatar) {
|
||||
this.avatar[key] = msg.player_avatar[key];
|
||||
};
|
||||
|
||||
let buffer = ({
|
||||
status: "SUCCESS",
|
||||
player_data: this.getPlayerData()
|
||||
});
|
||||
|
||||
return (
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.SetAvatarResponse")
|
||||
);
|
||||
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
export SetAvatar from "./SetAvatar";
|
||||
export GetPlayer from "./GetPlayer";
|
||||
export GetInventory from "./GetInventory";
|
||||
export GetAuthTicket from "./GetAuthTicket";
|
||||
export LevelUpRewards from "./LevelUpRewards";
|
||||
export GetHatchedEggs from "./GetHatchedEggs";
|
||||
export GetAssetDigest from "./GetAssetDigest";
|
||||
export GetPlayerProfile from "./GetPlayerProfile";
|
||||
|
||||
@@ -59,7 +59,7 @@ export default class Cell extends MapObject {
|
||||
this.processDeletedFort(this.addFort(fort));
|
||||
});
|
||||
this.synced = true;
|
||||
print(`Synced ${this.cellId} with database..`, 33);
|
||||
//print(`Synced ${this.cellId} with database..`, 33);
|
||||
resolve(this.forts);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
validName
|
||||
} from "../../../../utils";
|
||||
|
||||
import ENUM from "../../../../enum";
|
||||
|
||||
/**
|
||||
* @class Gym
|
||||
*/
|
||||
@@ -20,7 +22,7 @@ export default class Gym extends Fort {
|
||||
|
||||
super(obj);
|
||||
|
||||
this.team = "RED";
|
||||
this.team = 0;
|
||||
|
||||
this.guardPkmn = 0;
|
||||
this.guardPkmnCp = 0;
|
||||
@@ -43,7 +45,7 @@ export default class Gym extends Fort {
|
||||
latitude: this.latitude,
|
||||
longitude: this.longitude,
|
||||
enabled: this.enabled,
|
||||
owned_by_team: this.team,
|
||||
owned_by_team: ENUM.getItemNameById(ENUM.TEAM, this.team),
|
||||
guard_pokemon_id: this.guardPkmn,
|
||||
gym_points: this.gymPoints,
|
||||
active_fort_modifier: []
|
||||
|
||||
@@ -27,6 +27,8 @@ export default class Fort extends MapObject {
|
||||
|
||||
this.init(obj);
|
||||
|
||||
this.uid += this.type[0].toUpperCase();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,8 @@ import print from "../../../print";
|
||||
*/
|
||||
export default function FortSearch(msg) {
|
||||
|
||||
let player = msg.player;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.getFortDataById(msg.fort_id).then((fort) => {
|
||||
if (!fort) return void 0;
|
||||
@@ -19,6 +21,7 @@ export default function FortSearch(msg) {
|
||||
cooldown_complete_timestamp_ms: +new Date() + fort.cooldown,
|
||||
chain_hack_sequence_number: 2
|
||||
});
|
||||
player.info.upgradeExp(fort.experience);
|
||||
resolve(
|
||||
POGOProtos.serialize(buffer, "POGOProtos.Networking.Responses.FortSearchResponse")
|
||||
);
|
||||
|
||||
@@ -39,12 +39,12 @@ export default function GetMapObjects(msg) {
|
||||
cell.forts.map((fort) => {
|
||||
let id = fort.cellId + "." + fort.uid;
|
||||
if (ids.indexOf(id) > -1) {
|
||||
print(`Duplicated!!!! => ${id}`, 31);
|
||||
print(`Duplicated fort!!!! => ${id}`, 31);
|
||||
}
|
||||
else {
|
||||
ids.push(id);
|
||||
}
|
||||
print(`Active fort: ${fort.cellId}.${fort.uid}`, 35);
|
||||
//print(`Active fort: ${fort.cellId}.${fort.uid}`, 35);
|
||||
});
|
||||
}
|
||||
mapCells.push({
|
||||
|
||||
@@ -14,8 +14,8 @@ export default {
|
||||
pokemon_visible_range: 70.00196078431372,
|
||||
poke_nav_range_meters: 751.0156862745098,
|
||||
encounter_range_meters: 50.25098039215686,
|
||||
get_map_objects_min_refresh_seconds: 4,
|
||||
get_map_objects_max_refresh_seconds: 4,
|
||||
get_map_objects_min_refresh_seconds: 16,
|
||||
get_map_objects_max_refresh_seconds: 16,
|
||||
get_map_objects_min_distance_meters: 10.007843017578125,
|
||||
google_maps_api_key: CFG.GMAPS_KEY
|
||||
},
|
||||
|
||||
@@ -43,8 +43,11 @@ export function processCommand(cmd, data) {
|
||||
case "/spawn":
|
||||
this.spawnPkmnAtPlayer(data[1], data[2], data[3] || 1);
|
||||
break;
|
||||
case "/update":
|
||||
eval(fs.readFileSync("update.js", "utf8"));
|
||||
case "/dump":
|
||||
print("Preparing dump session..");
|
||||
this.onFirstRun(() => {
|
||||
print("Dumped assets successfully!");
|
||||
});
|
||||
break;
|
||||
default:
|
||||
print(`${cmd} is not a valid command!`, 31);
|
||||
@@ -53,11 +56,9 @@ export function processCommand(cmd, data) {
|
||||
};
|
||||
|
||||
export function stdinInput(data) {
|
||||
data = data.toString().substring(0, data.length - 2);
|
||||
if (data.length < 1) return void 0;
|
||||
data = data.split(" ");
|
||||
var cmd = data[0];
|
||||
this.processCommand(cmd, data);
|
||||
if (data.length <= 1) return void 0;
|
||||
let cmds = data.split(" ");
|
||||
this.processCommand(cmds[0], cmds.splice(0, 1));
|
||||
};
|
||||
|
||||
export function uncaughtException(excp) {
|
||||
|
||||
@@ -40,10 +40,13 @@ export function processResponse(player, req) {
|
||||
try {
|
||||
switch (req.request_type) {
|
||||
// Player
|
||||
case "SET_AVATAR":
|
||||
case "GET_PLAYER":
|
||||
case "GET_INVENTORY":
|
||||
case "GET_ASSET_DIGEST":
|
||||
case "GET_HATCHED_EGGS":
|
||||
case "LEVEL_UP_REWARDS":
|
||||
case "GET_PLAYER_PROFILE":
|
||||
case "CHECK_AWARDED_BADGES":
|
||||
player.getPacket(req.request_type, msg).then((result) => {
|
||||
print(`Success: ${req.request_type} => ${result.toString().length}`);
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as shared from "./shared";
|
||||
import GameMaster from "./models/GameMaster";
|
||||
|
||||
import {
|
||||
_toCC,
|
||||
capitalize,
|
||||
idToPkmnBundleName
|
||||
} from "./utils";
|
||||
@@ -141,12 +142,13 @@ export function parseGameMaster() {
|
||||
}
|
||||
|
||||
export function onFirstRun(resolve) {
|
||||
// make sure to login first!
|
||||
print(`Attempt to login with ${_toCC(CFG.DOWNLOAD_PROVIDER)}..`, 33);
|
||||
pogo.login({
|
||||
provider: CFG.DOWNLOAD_PROVIDER, // google or ptc
|
||||
username: CFG.DOWNLOAD_USERNAME,
|
||||
password: CFG.DOWNLOAD_PASSWORD
|
||||
}).then(() => {
|
||||
print(`Successfully logged in!`);
|
||||
this.downloadAssetDigests().then(() => {
|
||||
this.downloadAssets().then(resolve);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user