- 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:
Felix
2016-09-01 19:26:01 +02:00
parent 71472cd425
commit 8483b6d739
20 changed files with 185 additions and 52 deletions

View File

@@ -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) {

View File

@@ -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);
});

View File

@@ -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
});
}

View File

@@ -7,7 +7,7 @@ export default class Currency {
constructor() {
this.currencies = {
"POKECOINS": 0,
"POKECOIN": 0,
"STARDUST": 0
};

View File

@@ -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,

View File

@@ -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);

View File

@@ -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")
);
}

View File

@@ -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")
);

View 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")
);
}

View 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")
);
}

View File

@@ -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";

View File

@@ -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);
});
}

View File

@@ -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: []

View File

@@ -27,6 +27,8 @@ export default class Fort extends MapObject {
this.init(obj);
this.uid += this.type[0].toUpperCase();
}
/**

View File

@@ -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")
);

View File

@@ -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({

View File

@@ -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
},

View File

@@ -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) {

View File

@@ -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}`);

View File

@@ -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);
});