mirror of
https://github.com/maierfelix/POGOserver.git
synced 2026-07-09 13:46:11 -05:00
Big update
- Added asset session downloader - Added on off option logging request types - Updated proto files - Updated readme.md - Smoother setup process - Added various console commands - Added claim codename packet - Added encounter packet - Added *fixed* download url packet - Various changes, cant remember at all
This commit is contained in:
parent
1db70b4d96
commit
bf4e26e338
|
|
@ -7,11 +7,12 @@ message CatchPokemonLogEntry {
|
|||
.POGOProtos.Data.Logs.CatchPokemonLogEntry.Result result = 1;
|
||||
.POGOProtos.Enums.PokemonId pokemon_id = 2;
|
||||
int32 combat_points = 3;
|
||||
uint64 pokemon_data_id = 4;
|
||||
fixed64 pokemon_data_id = 4;
|
||||
|
||||
enum Result {
|
||||
UNSET = 0;
|
||||
POKEMON_CAPTURED = 1;
|
||||
POKEMON_FLED = 2;
|
||||
POKEMON_HATCHED = 3;
|
||||
}
|
||||
}
|
||||
1
POGOProtos/Data/PlayerData.proto
vendored
1
POGOProtos/Data/PlayerData.proto
vendored
|
|
@ -21,4 +21,5 @@ message PlayerData {
|
|||
.POGOProtos.Data.Player.EquippedBadge equipped_badge = 12;
|
||||
.POGOProtos.Data.Player.ContactSettings contact_settings = 13;
|
||||
repeated .POGOProtos.Data.Player.Currency currencies = 14;
|
||||
int32 remaining_codename_claims = 15;
|
||||
}
|
||||
|
|
|
|||
7
POGOProtos/Map/Fort/FortData.proto
vendored
7
POGOProtos/Map/Fort/FortData.proto
vendored
|
|
@ -3,6 +3,7 @@ package POGOProtos.Map.Fort;
|
|||
|
||||
import "POGOProtos/Enums/PokemonId.proto";
|
||||
import "POGOProtos/Enums/TeamColor.proto";
|
||||
import "POGOProtos/Inventory/Item/ItemId.proto";
|
||||
import "POGOProtos/Map/Fort/FortType.proto";
|
||||
import "POGOProtos/Map/Fort/FortSponsor.proto";
|
||||
import "POGOProtos/Map/Fort/FortRenderingType.proto";
|
||||
|
|
@ -32,14 +33,12 @@ message FortData {
|
|||
bool is_in_battle = 11;
|
||||
|
||||
//// Fields related to pokestops only
|
||||
repeated .POGOProtos.Inventory.Item.ItemId active_fort_modifier = 12;
|
||||
.POGOProtos.Map.Fort.FortLureInfo lure_info = 13;
|
||||
|
||||
// Timestamp when the pokestop can be activated again to get items / xp
|
||||
int64 cooldown_complete_timestamp_ms = 14;
|
||||
|
||||
.POGOProtos.Map.Fort.FortSponsor sponsor = 15;
|
||||
.POGOProtos.Map.Fort.FortRenderingType rendering_type = 16;
|
||||
|
||||
// Might represent the type of item applied to the pokestop, right now only lures can be applied
|
||||
bytes active_fort_modifier = 12;
|
||||
.POGOProtos.Map.Fort.FortLureInfo lure_info = 13;
|
||||
}
|
||||
|
|
|
|||
12
POGOProtos/Map/Pokemon/NearbyPokemon.proto
vendored
12
POGOProtos/Map/Pokemon/NearbyPokemon.proto
vendored
|
|
@ -4,9 +4,9 @@ package POGOProtos.Map.Pokemon;
|
|||
import "POGOProtos/Enums/PokemonId.proto";
|
||||
|
||||
message NearbyPokemon {
|
||||
.POGOProtos.Enums.PokemonId pokemon_id = 1;
|
||||
float distance_in_meters = 2;
|
||||
fixed64 encounter_id = 3;
|
||||
string fort_id = 4;
|
||||
string fort_image_url = 5;
|
||||
}
|
||||
.POGOProtos.Enums.PokemonId pokemon_id = 1;
|
||||
float distance_in_meters = 2;
|
||||
fixed64 encounter_id = 3;
|
||||
string fort_id = 4;
|
||||
string fort_image_url = 5;
|
||||
}
|
||||
|
|
|
|||
18
POGOProtos/Networking/Envelopes/Signature.proto
vendored
18
POGOProtos/Networking/Envelopes/Signature.proto
vendored
|
|
@ -5,7 +5,7 @@ message Signature {
|
|||
|
||||
message LocationFix {
|
||||
string provider = 1; // "network", "gps", "fused", possibly others
|
||||
uint64 timestamp_since_start = 2; // in ms
|
||||
uint64 timestamp_snapshot = 2; // in ms since start
|
||||
float latitude = 13;
|
||||
float longitude = 14;
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ message Signature {
|
|||
}
|
||||
|
||||
message SensorInfo {
|
||||
uint64 timestamp_snapshot = 1; // in ms
|
||||
uint64 timestamp_snapshot = 1; // in ms since start
|
||||
double magnetometer_x = 3;
|
||||
double magnetometer_y = 4;
|
||||
double magnetometer_z = 5;
|
||||
|
|
@ -69,6 +69,7 @@ message Signature {
|
|||
string firmware_fingerprint = 14; // Android only, build.fingerprint
|
||||
}
|
||||
|
||||
// Only used in iOS - Android just sends an empty version
|
||||
message ActivityStatus {
|
||||
// all of these had 1 as their value
|
||||
uint64 start_time_ms = 1;
|
||||
|
|
@ -88,14 +89,11 @@ message Signature {
|
|||
SensorInfo sensor_info = 7;
|
||||
DeviceInfo device_info = 8;
|
||||
ActivityStatus activity_status = 9;
|
||||
uint32 location_hash1 = 10; // Location1 hashed based on the auth_token - xxHash32
|
||||
uint32 location_hash2 = 20; // Location2 hashed based on the auth_token - xxHash32
|
||||
bytes unknown22 = 22; // possibly replay check. Generation unknown but pointed to by 0001B8614
|
||||
uint64 location_hash1 = 10; // Location1 hashed signed based on the auth_token or auth_info - xxHash32
|
||||
uint64 location_hash2 = 20; // Location2 hashed (unsigned) - xxHash32
|
||||
bytes session_hash = 22; // 16 bytes, unique per session
|
||||
uint64 timestamp = 23; // epoch timestamp in ms
|
||||
repeated uint64 request_hash = 24; // hashes of each request message in a hashArray - xxhash64
|
||||
|
||||
// Addresses for the corresponding hash functions:
|
||||
// xxHash32 00054D28
|
||||
// xxhash64 000546C8 - Feeds into 00053D40
|
||||
repeated int64 request_hash = 24; // hashes of each request message in a hashArray signed based on the auth_token or auth_info - xxhash64
|
||||
int64 unknown25 = 25; // for 0.33 its static -8537042734809897855 or 0x898654dd2753a481, generated via xxHash64("\"b8fa9757195897aae92c53dbcf8a60fb3d86d745\"".ToByteArray(), 0x88533787)
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ message Unknown6 {
|
|||
|
||||
message Unknown2 {
|
||||
bytes encrypted_signature = 1; // This are the bytes of POGOProtos/Networking/Envelopes/Signature.proto encrypted.
|
||||
// For an example check https://github.com/keyphact/pgoapi/blob/75eba6b5b630841ee4f7c2ea983f15874fb0862d/pgoapi/rpc_api.py#L192-L212
|
||||
// For an example check https://github.com/keyphact/pgoapi/blob/75eba6b5b630841ee4f7c2ea983f15874fb0862d/pgoapi/rpc_api.py#L192-L212
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ message GetGymDetailsMessage {
|
|||
double player_longitude = 3;
|
||||
double gym_latitude = 4;
|
||||
double gym_longitude = 5;
|
||||
string client_version = 6;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,4 @@ syntax = "proto3";
|
|||
package POGOProtos.Networking.Requests.Messages;
|
||||
|
||||
message GetPlayerMessage {
|
||||
// Human readable app version, e.g. "0.31.1"
|
||||
string app_version = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,17 @@
|
|||
syntax = "proto3";
|
||||
package POGOProtos.Networking.Responses;
|
||||
|
||||
import "POGOProtos/Networking/Responses/FortDetailsResponse.proto";
|
||||
|
||||
message AddFortModifierResponse {
|
||||
// Initialized by assist.py
|
||||
.POGOProtos.Networking.Responses.AddFortModifierResponse.Result result = 1;
|
||||
.POGOProtos.Networking.Responses.FortDetailsResponse fort_details = 2;
|
||||
|
||||
enum Result {
|
||||
NO_RESULT_SET = 0;
|
||||
SUCCESS = 1;
|
||||
FORT_ALREADY_HAS_MODIFIER = 2;
|
||||
TOO_FAR_AWAY = 3;
|
||||
NO_ITEM_IN_INVENTORY = 4;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
syntax = "proto3";
|
||||
package POGOProtos.Networking.Responses;
|
||||
|
||||
// TODO: Might be incorrect, please test.
|
||||
import "POGOProtos/Data/PlayerData.proto";
|
||||
|
||||
message ClaimCodenameResponse {
|
||||
string codename = 1;
|
||||
string user_message = 2;
|
||||
bool is_assignable = 3;
|
||||
.POGOProtos.Networking.Responses.ClaimCodenameResponse.Status status = 4;
|
||||
.POGOProtos.Data.PlayerData updated_player = 5;
|
||||
|
||||
enum Status {
|
||||
UNSET = 0;
|
||||
|
|
|
|||
2
POGOProtos/Settings/GlobalSettings.proto
vendored
2
POGOProtos/Settings/GlobalSettings.proto
vendored
|
|
@ -5,6 +5,7 @@ import "POGOProtos/Settings/FortSettings.proto";
|
|||
import "POGOProtos/Settings/MapSettings.proto";
|
||||
import "POGOProtos/Settings/LevelSettings.proto";
|
||||
import "POGOProtos/Settings/InventorySettings.proto";
|
||||
import "POGOProtos/Settings/GpsSettings.proto";
|
||||
|
||||
message GlobalSettings {
|
||||
.POGOProtos.Settings.FortSettings fort_settings = 2;
|
||||
|
|
@ -12,4 +13,5 @@ message GlobalSettings {
|
|||
.POGOProtos.Settings.LevelSettings level_settings = 4;
|
||||
.POGOProtos.Settings.InventorySettings inventory_settings = 5;
|
||||
string minimum_client_version = 6;
|
||||
.POGOProtos.Settings.GpsSettings gps_settings = 7;
|
||||
}
|
||||
|
|
|
|||
9
POGOProtos/Settings/GpsSettings.proto
vendored
Normal file
9
POGOProtos/Settings/GpsSettings.proto
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
syntax = "proto3";
|
||||
package POGOProtos.Settings;
|
||||
|
||||
message GpsSettings {
|
||||
float driving_warning_speed_meters_per_second = 1;
|
||||
float driving_warning_cooldown_minutes = 2;
|
||||
float driving_speed_sample_interval_seconds = 3;
|
||||
int32 driving_speed_sample_count = 4;
|
||||
}
|
||||
|
|
@ -16,4 +16,5 @@ message GymBattleSettings {
|
|||
int32 dodge_duration_ms = 12;
|
||||
int32 minimum_player_level = 13;
|
||||
int32 swap_duration_ms = 14;
|
||||
float dodge_damage_reduction_percent = 15;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,4 +44,11 @@ You need a running mongodb service, enter your credentials into ``./cfg.js``.
|
|||
|
||||
If everything went fine, it should look like:
|
||||
|
||||

|
||||

|
||||
|
||||
## Todo
|
||||
- Viewing a pokemon shows invalid data (wrong weight, height, type etc.)
|
||||
- Transfer button doesnt trigger (maybe related to above?)
|
||||
- Items doesnt show
|
||||
- Pokemon models get downloaded correctly, but somehow they dont load properly. They show on map, but not in pokemon info screen, pokedex or while encountering.
|
||||
- Players exp bar is bugged, proto related?
|
||||
9
cfg.js
9
cfg.js
|
|
@ -6,9 +6,11 @@ export const SERVER_SAVE_INTERVAL = 1e3 * 60; // 1min
|
|||
export const SERVER_MAX_CONNECTIONS = 64;
|
||||
export const SERVER_PLAYER_CONNECTION_TIMEOUT = 1e3 * 60 * 30; // 30min
|
||||
|
||||
export const SERVER_LOG_REQUESTS = true;
|
||||
|
||||
export const SERVER_DEFAULT_CONSOLE_COLOR = 32;
|
||||
|
||||
export const ASSET_DIGEST_PATH = "asset_digest";
|
||||
export const ASSET_DIGEST_PATH = "0005368950BD6068_ASSET_DIGEST";
|
||||
|
||||
export const MINIMUM_CLIENT_VERSION = "0.33.0";
|
||||
|
||||
|
|
@ -18,4 +20,7 @@ export const SERVER_MONGO_DB_NAME = "pokemongo";
|
|||
export const SERVER_MONGO_COLLECTION_USERS = "users";
|
||||
export const SERVER_MONGO_URL = `mongodb://${SERVER_MONGO_HOST_IP}:${SERVER_MONGO_PORT}/${SERVER_MONGO_DB_NAME}`;
|
||||
|
||||
export const SERVER_GMAPS_API_KEY = "AIzaSyDF9rkP8lhcddBtvH9gVFzjnNo13WtmJIM";
|
||||
export const SERVER_GMAPS_API_KEY = "AIzaSyDF9rkP8lhcddBtvH9gVFzjnNo13WtmJIM";
|
||||
|
||||
export const SERVER_POGO_CLIENT_USERNAME = "USERNAME";
|
||||
export const SERVER_POGO_CLIENT_PASSWORD = "PASSWORD";
|
||||
|
|
@ -49,7 +49,7 @@ export function resetTimers() {
|
|||
this.saveTick++;
|
||||
// Save interval
|
||||
if (this.saveTick >= CFG.SERVER_SAVE_INTERVAL) {
|
||||
this.savePlayers();
|
||||
this.saveAllPlayers();
|
||||
this.saveTick = 0;
|
||||
}
|
||||
return void 0;
|
||||
|
|
|
|||
|
|
@ -2,20 +2,19 @@ import mongodb from "mongodb";
|
|||
|
||||
import * as CFG from "../cfg";
|
||||
|
||||
/**
|
||||
* @param {Function} resolve
|
||||
*/
|
||||
export function setupMongo(resolve) {
|
||||
export function setupMongo() {
|
||||
|
||||
mongodb.MongoClient.connect(CFG.SERVER_MONGO_URL, (error, db) => {
|
||||
if (error) {
|
||||
this.print("Unable to connect to database", 31);
|
||||
} else {
|
||||
this.db.instance = db;
|
||||
this.loadCollection(CFG.SERVER_MONGO_COLLECTION_USERS).then(() => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
mongodb.MongoClient.connect(CFG.SERVER_MONGO_URL, (error, db) => {
|
||||
if (error) {
|
||||
this.print("Unable to connect to database", 31);
|
||||
} else {
|
||||
this.db.instance = db;
|
||||
this.loadCollection(CFG.SERVER_MONGO_COLLECTION_USERS).then(() => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -70,7 +69,9 @@ export function createUser(obj) {
|
|||
stardust: obj.stardust,
|
||||
pokecoins: obj.pokecoins,
|
||||
avatar: obj.avatar,
|
||||
contact_settings: obj.contact_settings
|
||||
team: obj.team,
|
||||
contact_settings: obj.contact_settings,
|
||||
tutorial_state: obj.tutorial_state
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
|
|
@ -93,7 +94,9 @@ export function updateUser(obj) {
|
|||
stardust: obj.stardust,
|
||||
pokecoins: obj.pokecoins,
|
||||
avatar: obj.avatar,
|
||||
contact_settings: obj.contact_settings
|
||||
team: obj.team,
|
||||
contact_settings: obj.contact_settings,
|
||||
tutorial_state: obj.tutorial_state
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
|
|
|
|||
44
src/index.js
44
src/index.js
|
|
@ -3,12 +3,13 @@ import http from "http";
|
|||
import proto from "./proto";
|
||||
|
||||
import {
|
||||
inherit,
|
||||
decodeLong
|
||||
inherit
|
||||
} from "./utils";
|
||||
|
||||
import * as CFG from "../cfg";
|
||||
|
||||
import pogodown from "pogo-asset-downloader";
|
||||
|
||||
import * as _setup from "./setup";
|
||||
import * as _cycle from "./cycle";
|
||||
import * as _player from "./player";
|
||||
|
|
@ -62,7 +63,7 @@ class GameServer {
|
|||
|
||||
clientAlreadyConnected(client) {
|
||||
|
||||
let remoteAddress = client.connection.remoteAddress;
|
||||
let remoteAddress = client.headers.host;
|
||||
|
||||
let ii = 0, length = this.clients.length;
|
||||
|
||||
|
|
@ -76,14 +77,45 @@ class GameServer {
|
|||
|
||||
}
|
||||
|
||||
createAssetDownloadSession() {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
pogodown.login({
|
||||
username: CFG.SERVER_POGO_CLIENT_USERNAME,
|
||||
password: CFG.SERVER_POGO_CLIENT_PASSWORD,
|
||||
downloadModels: false
|
||||
}).then(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} assets
|
||||
*/
|
||||
generateDownloadUrlByAssetId(assets) {
|
||||
return new Promise((resolve) => {
|
||||
pogodown.getAssetByAssetId(assets).then((response) => {
|
||||
// maybe cache and provide own local download link?
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {HTTP}
|
||||
*/
|
||||
createHTTPServer() {
|
||||
let server = http.createServer((req, res) => {
|
||||
if (this.clients.length >= CFG.SERVER_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.connection);
|
||||
this.addPlayer(req);
|
||||
}
|
||||
let chunks = [];
|
||||
req.on("data", (chunk) => {
|
||||
|
|
@ -93,7 +125,7 @@ class GameServer {
|
|||
let buffer = Buffer.concat(chunks);
|
||||
req.body = buffer;
|
||||
this.request = req;
|
||||
this.onRequest(req, res);
|
||||
this.routeRequest(req, res);
|
||||
});
|
||||
});
|
||||
server.listen(CFG.SERVER_PORT);
|
||||
|
|
@ -106,7 +138,7 @@ class GameServer {
|
|||
*/
|
||||
print(msg, color) {
|
||||
color = Number.isInteger(color) ? color : CFG.SERVER_DEFAULT_CONSOLE_COLOR;
|
||||
console.log(`\x1b[${color};1m${msg}\x1b[0m`);
|
||||
console.log(`[Console] \x1b[${color};1m${msg}\x1b[0m`);
|
||||
}
|
||||
|
||||
greet() {
|
||||
|
|
|
|||
9
src/modes/default_player.json
Normal file
9
src/modes/default_player.json
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"exp": 0,
|
||||
"level": 5,
|
||||
"stardust": 1000,
|
||||
"pokecoins": 0,
|
||||
"team": 0,
|
||||
"items": [],
|
||||
"pokemons": []
|
||||
}
|
||||
0
src/modes/global_settings.json
Normal file
0
src/modes/global_settings.json
Normal file
|
|
@ -10,7 +10,9 @@ export default function CheckAwardedBadges(obj) {
|
|||
|
||||
return (
|
||||
new proto.Networking.Responses.CheckAwardedBadgesResponse({
|
||||
success: true
|
||||
success: true,
|
||||
awarded_badges: [],
|
||||
awarded_badge_levels: []
|
||||
}).encode()
|
||||
);
|
||||
|
||||
|
|
|
|||
25
src/packets/Responses.ClaimCodeName.js
Normal file
25
src/packets/Responses.ClaimCodeName.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import proto from "../proto";
|
||||
|
||||
import { GetPlayer } from "./";
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Player} player
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function ClaimCodeName(req, player) {
|
||||
|
||||
let data = proto.Networking.Requests.Messages.ClaimCodenameMessage.decode(req.request_message.toBuffer());
|
||||
|
||||
player.username = data.codename;
|
||||
|
||||
return (
|
||||
new proto.Networking.Responses.ClaimCodenameResponse({
|
||||
codename: data.codename,
|
||||
user_message: data.codename,
|
||||
is_assignable: true,
|
||||
status: 1
|
||||
}).encode()
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -9,8 +9,8 @@ export default function DownloadRemoteConfigVersion(obj) {
|
|||
return (
|
||||
new proto.Networking.Responses.DownloadRemoteConfigVersionResponse({
|
||||
result: 1,
|
||||
item_templates_timestamp_ms: 1468540960537,
|
||||
asset_digest_timestamp_ms: 1467338276561000
|
||||
item_templates_timestamp_ms: new Date().getTime() * 1e3,
|
||||
asset_digest_timestamp_ms: new Date().getTime() * 1e3
|
||||
}).encode()
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,30 +10,37 @@ export default function DownloadSettings(obj) {
|
|||
|
||||
return (
|
||||
new proto.Networking.Responses.DownloadSettingsResponse({
|
||||
hash: "54b359c97e46900f87211ef6e6dd0b7f2a3ea1f5",
|
||||
hash: "2788184af4004004d6ab0740f7632983332106f6",
|
||||
settings: new proto.Settings.GlobalSettings({
|
||||
fort_settings: new proto.Settings.FortSettings({
|
||||
interaction_range_meters: 40,
|
||||
max_total_deployed_pokemon: 10,
|
||||
max_player_deployed_pokemon: 1,
|
||||
deploy_stamina_multiplier: 2,
|
||||
far_interaction_range_meters: 1000
|
||||
"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: new proto.Settings.MapSettings({
|
||||
pokemon_visible_range: 70,
|
||||
poke_nav_range_meters: 751,
|
||||
encounter_range_meters: 50,
|
||||
get_map_objects_min_refresh_seconds: 10,
|
||||
get_map_objects_max_refresh_seconds: 30,
|
||||
get_map_objects_min_distance_meters: 10,
|
||||
google_maps_api_key: CFG.SERVER_GMAPS_API_KEY
|
||||
"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": 30.01568603515625,
|
||||
"get_map_objects_min_distance_meters": 10.007843017578125,
|
||||
"google_maps_api_key": CFG.SERVER_GMAPS_API_KEY
|
||||
}),
|
||||
inventory_settings: new proto.Settings.InventorySettings({
|
||||
max_pokemon: 1000,
|
||||
max_bag_items: 1000,
|
||||
base_pokemon: 250,
|
||||
base_bag_items: 350,
|
||||
base_eggs: 9
|
||||
"max_pokemon": 1000,
|
||||
"max_bag_items": 1000,
|
||||
"base_pokemon": 250,
|
||||
"base_bag_items": 350,
|
||||
"base_eggs": 9
|
||||
}),
|
||||
gps_settings: new proto.Settings.GpsSettings({
|
||||
driving_warning_speed_meters_per_second: 10,
|
||||
driving_warning_cooldown_minutes: 0,
|
||||
driving_speed_sample_interval_seconds: 0,
|
||||
driving_speed_sample_count: 0
|
||||
}),
|
||||
minimum_client_version: CFG.MINIMUM_CLIENT_VERSION
|
||||
})
|
||||
|
|
|
|||
|
|
@ -10,46 +10,68 @@ import { decodeLong } from "../utils";
|
|||
*/
|
||||
export default function Encounter(req) {
|
||||
|
||||
let data = proto.Networking.Requests.Messages.EncounterMessage.decode(req.request_message.toBuffer());
|
||||
|
||||
let encounter_id = decodeLong(
|
||||
data.encounter_id.high, data.encounter_id.low, data.encounter_id.unsigned
|
||||
);
|
||||
let id = decodeLong({
|
||||
"low": 0,
|
||||
"high": 0,
|
||||
"unsigned": true
|
||||
});
|
||||
|
||||
return (
|
||||
new proto.Networking.Responses.EncounterResponse({
|
||||
wild_pokemon: new proto.Map.Pokemon.WildPokemon({
|
||||
encounter_id: 11810991820755313517,
|
||||
last_modified_timestamp_ms: 1470787552996,
|
||||
latitude: 39.19047143172622,
|
||||
longitude: -96.58502161502839,
|
||||
spawn_point_id: "87bdd289c69",
|
||||
pokemon_data: new proto.Data.PokemonData({
|
||||
pokemon_id: 19,
|
||||
cp: 277,
|
||||
stamina: 41,
|
||||
stamina_max: 41,
|
||||
move_1: 221,
|
||||
move_2: 26,
|
||||
height_m: 0.22802678267819977,
|
||||
weight_kg: 1.3452539511871338,
|
||||
individual_attack: 9,
|
||||
individual_defense: 13,
|
||||
individual_stamina: 14,
|
||||
cp_multiplier: 0.5663545199394226
|
||||
wild_pokemon: new proto.Map.Pokemon.WildPokemon({
|
||||
encounter_id: decodeLong({
|
||||
"low": -1477718883,
|
||||
"high": -1178282273,
|
||||
"unsigned": true
|
||||
}),
|
||||
time_till_hidden_ms: 730176
|
||||
last_modified_timestamp_ms: decodeLong({
|
||||
"low": 2047340539,
|
||||
"high": 342,
|
||||
"unsigned": false
|
||||
}),
|
||||
latitude: 39.19071817474392,
|
||||
longitude: -96.58505386390713,
|
||||
spawn_point_id: "87bdcd8e959",
|
||||
pokemon_data: new proto.Data.PokemonData({
|
||||
id: id,
|
||||
pokemon_id: 17,
|
||||
cp: 48,
|
||||
stamina: 22,
|
||||
stamina_max: 22,
|
||||
move_1: 210,
|
||||
move_2: 45,
|
||||
deployed_fort_id: "",
|
||||
owner_name: "",
|
||||
is_egg: false,
|
||||
egg_km_walked_target: 0,
|
||||
egg_km_walked_start: 0,
|
||||
origin: 0,
|
||||
height_m: 0.8371214866638184,
|
||||
weight_kg: 19.039264678955078,
|
||||
individual_attack: 6,
|
||||
individual_defense: 12,
|
||||
individual_stamina: 7,
|
||||
cp_multiplier: 0.16639786958694458,
|
||||
pokeball: 0,
|
||||
captured_cell_id: id,
|
||||
battles_attacked: 0,
|
||||
battles_defended: 0,
|
||||
egg_incubator_id: "",
|
||||
creation_time_ms: id,
|
||||
num_upgrades: 0,
|
||||
additional_cp_multiplier: 0,
|
||||
favorite: 0,
|
||||
nickname: "",
|
||||
from_fort: 0
|
||||
}),
|
||||
time_till_hidden_ms: 336009
|
||||
}),
|
||||
background: proto.Networking.Responses.EncounterResponse.Background.PARK,
|
||||
status: proto.Networking.Responses.EncounterResponse.Status.ENCOUNTER_SUCCESS,
|
||||
background: 0,
|
||||
status: 1,
|
||||
capture_probability: new proto.Data.Capture.CaptureProbability({
|
||||
pokeball_type: [1, 2, 3],
|
||||
capture_probability: [
|
||||
0.352886438369751,
|
||||
0.47944003343582153,
|
||||
0.5812440514564514
|
||||
],
|
||||
reticle_difficulty_scale: 2
|
||||
capture_probability: [0.6009692549705505, 0.7479367256164551, 0.8407744765281677],
|
||||
reticle_difficulty_scale: 0
|
||||
})
|
||||
}).encode()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import * as CFG from "../../cfg";
|
|||
let asset = fs.readFileSync(CFG.ASSET_DIGEST_PATH);
|
||||
|
||||
/**
|
||||
* @param {Object} obj
|
||||
* @param {Request} req
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function GetAssetDigest(obj) {
|
||||
export default function GetAssetDigest(req) {
|
||||
|
||||
return (asset);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,24 +2,42 @@ import proto from "../proto";
|
|||
|
||||
import DownloadUrlEntry from "./Data.DownloadUrlEntry";
|
||||
|
||||
import {
|
||||
getDownloadUrlByAssetId
|
||||
} from "../utils.js";
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function GetDownloadUrls() {
|
||||
export default function GetDownloadUrls(req, download) {
|
||||
|
||||
let download_urls = [
|
||||
DownloadUrlEntry({
|
||||
asset_id: "9649e04b-ccd8-4b1c-b066-cc75ed4c0976/1467338147687000",
|
||||
url: "https://storage.googleapis.com/cloud_assets_pgorelease/bundles/android/pm0101?generation=1467338147687000&GoogleAccessId=pgorelease-service-account@pgorelease.iam.gserviceaccount.com&Expires=1469970173&Signature=CY4YbWipMVMUzyDgHGceoo2NO429spFyH39p%2FSMltBlQOBYLcRD8panRgTH8tuMc3uB65rtp613IkGwUMaMMXx40v0NBECEsRXcggYxYluO2k4waShMyOmWHOomMPKwGXg5ot93wLH6aXFwv0%2FD%2FUaqZDrJYJ9bMRcsF2KlPPy363XbrbcSCcT19otqU3D9yjWU1mDbzRy9yZRqmaCu%2FPtWHKKWnUKiN2f2UqL8Gbulex8BDpm4OKf4lXnOwAKYDpcAMph%2FC3LKVhvoRuryzPRJgXojb1CvfHaY0svUFoKq0N%2FuFl9hzR8RAVLsAPaD%2FpKuql4BUm%2BZtoc%2BWi0lQXA%3D%3D",
|
||||
size: 169205,
|
||||
checksum: 0xbe30d925
|
||||
})
|
||||
];
|
||||
let data = proto.Networking.Requests.Messages.GetDownloadUrlsMessage.decode(req.request_message.toBuffer());
|
||||
|
||||
return (
|
||||
new proto.Networking.Responses.GetDownloadUrlsResponse({
|
||||
download_urls: download_urls
|
||||
}).encode()
|
||||
);
|
||||
let key = data.asset_id[0];
|
||||
|
||||
let download_urls = [];
|
||||
|
||||
let obj = getDownloadUrlByAssetId(key);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
|
||||
download(key).then((asset) => {
|
||||
download_urls.push(
|
||||
new proto.Data.DownloadUrlEntry({
|
||||
url: asset[0].asset,
|
||||
asset_id: key,
|
||||
size: obj.size,
|
||||
checksum: obj.checksum
|
||||
})
|
||||
);
|
||||
let output = (
|
||||
new proto.Networking.Responses.GetDownloadUrlsResponse({
|
||||
download_urls: download_urls
|
||||
}).encode()
|
||||
);
|
||||
resolve(output);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -13,21 +13,39 @@ export default function GetInventoryData(obj) {
|
|||
success: true,
|
||||
inventory_delta: new proto.Inventory.InventoryDelta({
|
||||
inventory_items: [
|
||||
// player stats
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"candy": new proto.Inventory.Candy({
|
||||
"family_id": 48,
|
||||
"candy": 3
|
||||
})
|
||||
})
|
||||
}),
|
||||
new proto.Inventory.InventoryItem({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"candy": new proto.Inventory.Candy({
|
||||
"family_id": 16,
|
||||
"candy": 3
|
||||
})
|
||||
})
|
||||
}),
|
||||
new proto.Inventory.InventoryItem({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"player_stats": new proto.Data.Player.PlayerStats({
|
||||
"level": 98,
|
||||
"experience": 2000,
|
||||
"prev_level_xp": 1000,
|
||||
"next_level_xp": 6000,
|
||||
"km_walked": 0.55459213256836,
|
||||
"pokemons_encountered": 1,
|
||||
"unique_pokedex_entries": 1,
|
||||
"pokemons_captured": 1,
|
||||
"level": 3,
|
||||
"experience": 0,
|
||||
"prev_level_xp": 0,
|
||||
"next_level_xp": 0,
|
||||
"km_walked": 1.017870306968689,
|
||||
"pokemons_encountered": 6,
|
||||
"unique_pokedex_entries": 3,
|
||||
"pokemons_captured": 3,
|
||||
"evolutions": 0,
|
||||
"poke_stop_visits": 1,
|
||||
"pokeballs_thrown": 1,
|
||||
"poke_stop_visits": 25,
|
||||
"pokeballs_thrown": 11,
|
||||
"eggs_hatched": 0,
|
||||
"big_magikarp_caught": 0,
|
||||
"battle_attack_won": 0,
|
||||
|
|
@ -42,66 +60,109 @@ export default function GetInventoryData(obj) {
|
|||
})
|
||||
})
|
||||
}),
|
||||
// player camera
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
"player_camera": new proto.Data.Player.PlayerCamera({
|
||||
is_default_camera: true
|
||||
})
|
||||
})
|
||||
}),
|
||||
// player currencies
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
"player_currency": new proto.Data.Player.PlayerCurrency({
|
||||
gems: 0
|
||||
})
|
||||
})
|
||||
}),
|
||||
// item
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"item": new proto.Inventory.Item.ItemData({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_MASTER_BALL,
|
||||
count: 4,
|
||||
unseen: false
|
||||
"item_id": 901,
|
||||
"count": 1,
|
||||
"unseen": true
|
||||
})
|
||||
})
|
||||
}),
|
||||
// pokedex entry
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"pokemon_data": new proto.Data.PokemonData({
|
||||
"id": 16,
|
||||
"pokemon_id": proto.Enums.PokemonId.PIDGEY,
|
||||
"cp": 10,
|
||||
"stamina": 10,
|
||||
"stamina_max": 10,
|
||||
"move_1": 219,
|
||||
"move_2": 121,
|
||||
"deployed_fort_id": "",
|
||||
"owner_name": "",
|
||||
"is_egg": false,
|
||||
"egg_km_walked_target": 0,
|
||||
"egg_km_walked_start": 0,
|
||||
"origin": 0,
|
||||
"height_m": 0.29406625032424927,
|
||||
"weight_kg": 2.070491313934326,
|
||||
"individual_attack": 3,
|
||||
"individual_defense": 5,
|
||||
"individual_stamina": 10,
|
||||
"cp_multiplier": 0.09399999678134918,
|
||||
"pokeball": 1,
|
||||
"captured_cell_id": 2277362944,
|
||||
"battles_attacked": 0,
|
||||
"battles_defended": 0,
|
||||
"egg_incubator_id": "",
|
||||
"creation_time_ms": 9029623884583797000,
|
||||
"num_upgrades": 0,
|
||||
"additional_cp_multiplier": 0,
|
||||
"favorite": 0,
|
||||
"nickname": "",
|
||||
"from_fort": 0
|
||||
})
|
||||
})
|
||||
}),
|
||||
new proto.Inventory.InventoryItem({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"item": new proto.Inventory.Item.ItemData({
|
||||
"item_id": 1,
|
||||
"count": 145,
|
||||
"unseen": false
|
||||
})
|
||||
})
|
||||
}),
|
||||
new proto.Inventory.InventoryItem({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": {
|
||||
"candy": new proto.Inventory.Candy({
|
||||
"family_id": 7,
|
||||
"candy": 3
|
||||
})
|
||||
}
|
||||
}),
|
||||
new proto.Inventory.InventoryItem({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"pokedex_entry": new proto.Data.PokedexEntry({
|
||||
"pokemon_id": 6,
|
||||
"times_encountered": 1,
|
||||
"pokemon_id": 16,
|
||||
"times_encountered": 3,
|
||||
"times_captured": 1,
|
||||
"evolution_stone_pieces": 0,
|
||||
"evolution_stones": 0
|
||||
})
|
||||
})
|
||||
}),
|
||||
// pokemon
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
"pokemon_data": new proto.Data.PokemonData({
|
||||
pokemon_id: 19,
|
||||
cp: 277,
|
||||
stamina: 41,
|
||||
stamina_max: 41,
|
||||
move_1: 221,
|
||||
move_2: 26,
|
||||
height_m: 0.22802678267819977,
|
||||
weight_kg: 1.3452539511871338,
|
||||
individual_attack: 9,
|
||||
individual_defense: 13,
|
||||
individual_stamina: 14,
|
||||
cp_multiplier: 0.5663545199394226,
|
||||
additional_cp_multiplier: 0,
|
||||
favorite: 0,
|
||||
nickname: "BauerVomLande",
|
||||
owner_name: "Administrator",
|
||||
origin: 0,
|
||||
is_egg: false
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"egg_incubators": new proto.Inventory.EggIncubators({
|
||||
"egg_incubator": [
|
||||
new proto.Inventory.EggIncubator({
|
||||
"id": "EggIncubatorProto-2589714687259241229",
|
||||
"item_id": 901,
|
||||
"incubator_type": 1,
|
||||
"uses_remaining": 0,
|
||||
"pokemon_id": 0,
|
||||
"start_km_walked": 0,
|
||||
"target_km_walked": 0
|
||||
})
|
||||
]
|
||||
})
|
||||
})
|
||||
}),
|
||||
new proto.Inventory.InventoryItem({
|
||||
"modified_timestamp_ms": new Date().getTime() * 1e3,
|
||||
"inventory_item_data": new proto.Inventory.InventoryItemData({
|
||||
"item": new proto.Inventory.Item.ItemData({
|
||||
"item_id": 401,
|
||||
"count": 2,
|
||||
"unseen": true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import proto from "../proto";
|
||||
|
||||
import {
|
||||
decodeLong
|
||||
} from "../utils";
|
||||
|
||||
/**
|
||||
* @param {Request} request
|
||||
* @return {Object}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import proto from "../proto";
|
||||
|
||||
/**
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
|
|
@ -16,10 +15,12 @@ function getPlayerDataPacket(obj) {
|
|||
max_pokemon_storage: 250,
|
||||
max_item_storage: 350,
|
||||
daily_bonus: new proto.Data.Player.DailyBonus({
|
||||
next_collected_timestamp_ms: 1470174535972,
|
||||
next_defender_bonus_collect_timestamp_ms: 1470174535972
|
||||
}),
|
||||
contact_settings: new proto.Data.Player.ContactSettings(obj.contact_settings),
|
||||
currencies: obj.currencies
|
||||
currencies: obj.currencies,
|
||||
remaining_codename_claims: 0
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,8 @@ export default function LevelUpRewards(obj) {
|
|||
|
||||
return (
|
||||
new proto.Networking.Responses.LevelUpRewardsResponse({
|
||||
result: proto.Networking.Responses.LevelUpRewardsResponse.Result.SUCCESS,
|
||||
items_awarded: [
|
||||
new proto.Inventory.Item.ItemAward({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_GREAT_BALL,
|
||||
item_count: 2
|
||||
})
|
||||
],
|
||||
result: 2,
|
||||
items_awarded: [],
|
||||
items_unlocked: []
|
||||
}).encode()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { GetPlayer } from "./";
|
|||
export default function MarkTutorialComplete(player) {
|
||||
|
||||
return (
|
||||
new proto.Networking.Respones.MarkTutorialCompleteResponse({
|
||||
new proto.Networking.Responses.MarkTutorialCompleteResponse({
|
||||
success: true,
|
||||
player_data: GetPlayer(player).player_data
|
||||
}).encode()
|
||||
|
|
|
|||
|
|
@ -14,14 +14,21 @@ export default function SfidaActionLog(obj) {
|
|||
log_entries: [
|
||||
new proto.Data.Logs.ActionLogEntry({
|
||||
timestamp_ms: (new Date().getTime() - 1e4) * 1e3,
|
||||
sfida: false,
|
||||
catch_pokemon: null,
|
||||
fort_search: new proto.Data.Logs.FortSearchLogEntry({
|
||||
result: proto.Data.Logs.FortSearchLogEntry.Result.SUCCESS,
|
||||
fort_id: "wurf",
|
||||
fort_id: "",
|
||||
items: [
|
||||
new proto.Inventory.Item.ItemData({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_MASTER_BALL,
|
||||
count: 2,
|
||||
unseen: false
|
||||
}),
|
||||
new proto.Inventory.Item.ItemData({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_ULTRA_BALL,
|
||||
count: 2,
|
||||
unseen: false
|
||||
})
|
||||
]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export CheckAwardedBadges from "./Responses.CheckAwardedBadges";
|
|||
export GetDownloadUrls from "./Responses.GetDownloadUrls";
|
||||
|
||||
export MarkTutorialComplete from "./Responses.MarkTutorialComplete";
|
||||
export ClaimCodeName from "./Responses.ClaimCodeName";
|
||||
|
||||
export LevelUpRewards from "./Responses.LevelUpRewards";
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class Player {
|
|||
this.uid = -1;
|
||||
|
||||
this.email = null;
|
||||
this._username = "Administrator";
|
||||
this._username = "undefined";
|
||||
|
||||
this.position = {
|
||||
latitude: 0,
|
||||
|
|
@ -35,21 +35,25 @@ class Player {
|
|||
|
||||
this.exp = 0;
|
||||
|
||||
this.stardust = 1337;
|
||||
this.pokecoins = 1338;
|
||||
this.stardust = 0;
|
||||
this.pokecoins = 0;
|
||||
|
||||
this.team = proto.Enums.TeamColor.BLUE;
|
||||
|
||||
this.avatar = {
|
||||
skin: 0,
|
||||
hair: 2,
|
||||
shirt: 1,
|
||||
pants: 2,
|
||||
hair: 0,
|
||||
shirt: 0,
|
||||
pants: 0,
|
||||
hat: 0,
|
||||
shoes: 2,
|
||||
eyes: 3,
|
||||
gender: proto.Enums.Gender.MALE,
|
||||
backpack: 1
|
||||
shoes: 0,
|
||||
eyes: 0,
|
||||
gender: 0,
|
||||
backpack: 0
|
||||
};
|
||||
|
||||
this.tutorial_state = [32, 1, 3, 4, 7];
|
||||
|
||||
this.badges = null;
|
||||
this.pokedex = null;
|
||||
this.inventory = null;
|
||||
|
|
@ -181,7 +185,7 @@ export function getPlayerIndex(player) {
|
|||
*/
|
||||
export function getPlayerByRequest(req) {
|
||||
return (
|
||||
this.getPlayerByIP(req.connection.remoteAddress)
|
||||
this.getPlayerByIP(req.headers.host)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -203,16 +207,35 @@ export function getPlayerByIP(ip) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Request} connection
|
||||
* @param {String} name
|
||||
*/
|
||||
export function addPlayer(connection) {
|
||||
export function getPlayerByName(name) {
|
||||
|
||||
let ii = 0, length = this.clients.length;
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
if (this.clients[ii].username === name) {
|
||||
return (this.clients[ii]);
|
||||
}
|
||||
};
|
||||
|
||||
return (null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
*/
|
||||
export function addPlayer(req) {
|
||||
|
||||
let connection = req.connection;
|
||||
|
||||
this.clients.push(new Player({
|
||||
timeout: this.time,
|
||||
connection: connection,
|
||||
response: this.response,
|
||||
remotePort: connection.remotePort,
|
||||
remoteAddress: connection.remoteAddress
|
||||
remoteAddress: req.headers.host
|
||||
}));
|
||||
|
||||
}
|
||||
|
|
@ -234,17 +257,45 @@ export function removePlayer(player) {
|
|||
|
||||
}
|
||||
|
||||
export function updatePlayers() {
|
||||
//this.print("Updating players");
|
||||
return void 0;
|
||||
/**
|
||||
* @param {String} name
|
||||
*/
|
||||
export function kickPlayer(name) {
|
||||
|
||||
if (
|
||||
name === null ||
|
||||
name === void 0 ||
|
||||
typeof name === "string" &&
|
||||
name.length <= 1
|
||||
) {
|
||||
this.print(`Invalid player name!`, 31);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
let player = this.getPlayerByName(name);
|
||||
|
||||
if (player !== null) {
|
||||
this.removePlayer(player);
|
||||
this.print(`Kicked ${name} from the server!`);
|
||||
}
|
||||
else this.print(`Failed to kick ${name} from the server!`, 31);
|
||||
|
||||
}
|
||||
|
||||
export function savePlayers() {
|
||||
export function updatePlayers() {
|
||||
//this.print("Updating players");
|
||||
}
|
||||
|
||||
export function saveAllPlayers() {
|
||||
for (let client of this.clients) {
|
||||
this.savePlayer(client);
|
||||
};
|
||||
this.print("Saved players into database");
|
||||
return void 0;
|
||||
}
|
||||
|
||||
export function removeAllPlayers() {
|
||||
for (let client of this.clients) {
|
||||
this.removePlayer(client);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -281,6 +332,9 @@ export function forwardPlayer() {
|
|||
|
||||
return new Promise((resolve) => {
|
||||
this.getUserByEmail(player.email).then((doc) => {
|
||||
if (player.email.length) {
|
||||
this.print(`${player.email.replace("@gmail.com", "")} authenticated!`, 36);
|
||||
}
|
||||
if (doc === void 0) {
|
||||
this.registerPlayer(doc).then((res) => {
|
||||
resolve(res);
|
||||
|
|
@ -306,6 +360,7 @@ export function registerPlayer(doc) {
|
|||
return new Promise((resolve) => {
|
||||
this.createUser(player).then(() => {
|
||||
this.print(`${this.player.email.replace("@gmail.com", "")} registered!`, 36);
|
||||
player.tutorial_state = [];
|
||||
this.loginPlayer(doc).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,24 +4,60 @@ export function processCommand(cmd, data) {
|
|||
switch (cmd) {
|
||||
// How many active connections there are
|
||||
case "/clients":
|
||||
let length = this.clients.length;
|
||||
this.print(`${length} connected player${length === 1 ? "": "s"}!`, 33);
|
||||
var length = this.clients.length;
|
||||
this.print(`${length}:${CFG.SERVER_MAX_CONNECTIONS} connected players!`, 33);
|
||||
break;
|
||||
// Kill the server
|
||||
// Exit the server
|
||||
case "/exit":
|
||||
this.print("Killed the server!", 31);
|
||||
process.exit();
|
||||
this.socket.close(() => {
|
||||
this.print("Closed http server!", 33);
|
||||
this.db.instance.close(() => {
|
||||
this.print("Closed database connection!", 33);
|
||||
this.print("Killed the server!", 31);
|
||||
setTimeout(() => process.exit(1), 2e3);
|
||||
});
|
||||
});
|
||||
break;
|
||||
case "/kick":
|
||||
this.kickPlayer(data[1]);
|
||||
break;
|
||||
case "/killall":
|
||||
var length = this.clients.length;
|
||||
this.removeAllPlayers();
|
||||
var result = length - this.clients.length;
|
||||
this.print(`Removed ${result} player${result === 1 ? "": "s"}!`);
|
||||
break;
|
||||
case "/clear":
|
||||
process.stdout.write("\x1Bc");
|
||||
this.greet();
|
||||
break;
|
||||
case "/help":
|
||||
this.printHelp();
|
||||
break;
|
||||
case "/save":
|
||||
this.savePlayers();
|
||||
this.saveAllPlayers();
|
||||
var length = this.clients.length;
|
||||
this.print(`Saved ${length} player${length === 1 ? "": "s"} into database!`);
|
||||
break;
|
||||
default:
|
||||
this.print(`${cmd} is not a valid command!`, 31);
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
export function printHelp() {
|
||||
|
||||
console.log("\x1b[36;1m===================================== HELP =====================================\x1b[0m");
|
||||
this.print("clients : how many players are connected");
|
||||
this.print("exit : exit the server");
|
||||
this.print("kick [PlayerUsername] : kick player by username");
|
||||
this.print("kickall : kick all players");
|
||||
this.print("clear : clear the server console");
|
||||
this.print("save : save all palyers into database");
|
||||
console.log("\n\x1b[36;1m================================================================================\x1b[0m");
|
||||
|
||||
};
|
||||
|
||||
export function stdinInput(data) {
|
||||
data = data.toString().substring(0, data.length - 2);
|
||||
if (data.length < 1) return void 0;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ import {
|
|||
GetInventory
|
||||
} from "./packets";
|
||||
|
||||
import { decodeRequestEnvelope } from "./utils";
|
||||
import {
|
||||
decodeLong,
|
||||
decodeRequestEnvelope
|
||||
} from "./utils";
|
||||
|
||||
import jwtDecode from "jwt-decode";
|
||||
|
||||
|
|
@ -81,16 +84,20 @@ export function onRequest(req, res) {
|
|||
// Validate email verification
|
||||
if (player.authenticated) {
|
||||
if (!player.email_verified) {
|
||||
this.print(`${player.email.replace("@gmail.com", "")}'s email isnt verified, kicking..`, 31);
|
||||
this.removePlayer(player);
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
|
||||
let request = proto.Networking.Envelopes.RequestEnvelope.decode(req.body);
|
||||
|
||||
console.log("#####");
|
||||
request.requests.map((request) => {
|
||||
console.log("Got request:", this.getRequestType(request));
|
||||
}).join(",");
|
||||
if (CFG.SERVER_LOG_REQUESTS) {
|
||||
console.log("#####");
|
||||
request.requests.map((request) => {
|
||||
console.log("Got request:", this.getRequestType(request));
|
||||
}).join(",");
|
||||
}
|
||||
|
||||
if (!player.authenticated) {
|
||||
this.send(this.authenticatePlayer());
|
||||
|
|
@ -98,7 +105,7 @@ export function onRequest(req, res) {
|
|||
}
|
||||
|
||||
this.processRequests(request.requests).then((answer) => {
|
||||
let msg = this.envelopResponse(1, request.request_id, answer, request.hasOwnProperty("auth_ticket"), request.unknown6);
|
||||
let msg = this.envelopResponse(1, request.request_id, answer, request.hasOwnProperty("auth_ticket"));
|
||||
this.send(msg);
|
||||
});
|
||||
|
||||
|
|
@ -109,10 +116,9 @@ export function onRequest(req, res) {
|
|||
* @param {Long} id
|
||||
* @param {Array} response
|
||||
* @param {Boolean} auth
|
||||
* @param {Buffer} unknown6
|
||||
* @return {Buffer}
|
||||
*/
|
||||
export function envelopResponse(status, id, response, auth, unknown6) {
|
||||
export function envelopResponse(status, id, response, auth) {
|
||||
|
||||
let answer = ResponseEnvelope({
|
||||
id: id,
|
||||
|
|
@ -133,19 +139,56 @@ export function envelopResponse(status, id, response, auth, unknown6) {
|
|||
export function processRequests(requests) {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
let ii = 0;
|
||||
|
||||
let index = 0;
|
||||
let length = requests.length;
|
||||
let body = [];
|
||||
for (; ii < length; ++ii) {
|
||||
this.processResponse(requests[ii]).then((request) => {
|
||||
|
||||
let loop = (index) => {
|
||||
this.processResponse(requests[index]).then((request) => {
|
||||
body.push(request);
|
||||
if (ii + 1 >= length) resolve(body);
|
||||
if (++index >= length) resolve(body);
|
||||
else return loop(index);
|
||||
});
|
||||
};
|
||||
|
||||
loop(0);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @param {Response} res
|
||||
*/
|
||||
export function routeRequest(req, res) {
|
||||
|
||||
let url = String(req.url);
|
||||
let route = url.substring(url.lastIndexOf("/") + 1);
|
||||
let host = req.headers.host;
|
||||
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
console.log(`Unknown request url: https://${req.headers.host}${req.url}`);
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
* @return {Boolean}
|
||||
|
|
|
|||
1210
src/res/index.js
Normal file
1210
src/res/index.js
Normal file
File diff suppressed because it is too large
Load Diff
178
src/response.js
178
src/response.js
|
|
@ -26,7 +26,8 @@ import {
|
|||
NicknamePokemon,
|
||||
UpgradePokemon,
|
||||
EvolvePokemon,
|
||||
SetFavoritePokemon
|
||||
SetFavoritePokemon,
|
||||
ClaimCodeName
|
||||
} from "./packets";
|
||||
|
||||
/**
|
||||
|
|
@ -40,87 +41,102 @@ export function processResponse(request) {
|
|||
|
||||
return new Promise((resolve) => {
|
||||
|
||||
switch (request.request_type) {
|
||||
case REQUEST.GET_PLAYER:
|
||||
this.forwardPlayer().then((res) => resolve(res));
|
||||
return void 0;
|
||||
break;
|
||||
case REQUEST.GET_HATCHED_EGGS:
|
||||
buffer = GetHatchedEggs();
|
||||
break;
|
||||
case REQUEST.GET_INVENTORY:
|
||||
buffer = GetInventory();
|
||||
break;
|
||||
case REQUEST.CHECK_AWARDED_BADGES:
|
||||
buffer = CheckAwardedBadges();
|
||||
break;
|
||||
case REQUEST.DOWNLOAD_SETTINGS:
|
||||
buffer = DownloadSettings();
|
||||
break;
|
||||
case REQUEST.DOWNLOAD_ITEM_TEMPLATES:
|
||||
buffer = ItemTemplates();
|
||||
break;
|
||||
case REQUEST.DOWNLOAD_REMOTE_CONFIG_VERSION:
|
||||
buffer = DownloadRemoteConfigVersion();
|
||||
try {
|
||||
switch (request.request_type) {
|
||||
case REQUEST.GET_PLAYER:
|
||||
this.forwardPlayer().then((res) => resolve(res));
|
||||
return void 0;
|
||||
break;
|
||||
case REQUEST.GET_ASSET_DIGEST:
|
||||
buffer = GetAssetDigest();
|
||||
break;
|
||||
case REQUEST.GET_PLAYER_PROFILE:
|
||||
buffer = GetPlayerProfile();
|
||||
break;
|
||||
case REQUEST.GET_MAP_OBJECTS:
|
||||
this.player.updatePosition(request);
|
||||
buffer = GetMapObjects(request);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.GET_DOWNLOAD_URLS:
|
||||
buffer = GetDownloadUrls();
|
||||
break;
|
||||
case REQUEST.SET_AVATAR:
|
||||
player.updateAvatar(request);
|
||||
buffer = SetAvatar(player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.SFIDA_ACTION_LOG:
|
||||
buffer = SfidaActionLog();
|
||||
break;
|
||||
case REQUEST.MARK_TUTORIAL_COMPLETE:
|
||||
buffer = MarkTutorialComplete(player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.LEVEL_UP_REWARDS:
|
||||
buffer = LevelUpRewards();
|
||||
break;
|
||||
case REQUEST.FORT_DETAILS:
|
||||
buffer = FortDetails(request);
|
||||
break;
|
||||
case REQUEST.FORT_SEARCH:
|
||||
buffer = FortSearch();
|
||||
break;
|
||||
case REQUEST.SET_CONTACT_SETTINGS:
|
||||
player.updateContactSettings(request);
|
||||
buffer = SetContactSettings(player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.ENCOUNTER:
|
||||
buffer = Encounter(request);
|
||||
break;
|
||||
case REQUEST.NICKNAME_POKEMON:
|
||||
buffer = NicknamePokemon(request);
|
||||
break;
|
||||
case REQUEST.UPGRADE_POKEMON:
|
||||
buffer = UpgradePokemon(request);
|
||||
break;
|
||||
case REQUEST.EVOLVE_POKEMON:
|
||||
buffer = EvolvePokemon(request);
|
||||
break;
|
||||
case REQUEST.SET_FAVORITE_POKEMON:
|
||||
buffer = SetFavoritePokemon(request);
|
||||
break;
|
||||
default:
|
||||
this.print(`Unknown request: ${this.getRequestType(request)}`, 31);
|
||||
break;
|
||||
case REQUEST.GET_HATCHED_EGGS:
|
||||
buffer = GetHatchedEggs();
|
||||
break;
|
||||
case REQUEST.GET_INVENTORY:
|
||||
buffer = GetInventory();
|
||||
break;
|
||||
case REQUEST.CHECK_AWARDED_BADGES:
|
||||
buffer = CheckAwardedBadges();
|
||||
break;
|
||||
case REQUEST.DOWNLOAD_SETTINGS:
|
||||
buffer = DownloadSettings();
|
||||
break;
|
||||
case REQUEST.DOWNLOAD_ITEM_TEMPLATES:
|
||||
buffer = ItemTemplates();
|
||||
break;
|
||||
case REQUEST.DOWNLOAD_REMOTE_CONFIG_VERSION:
|
||||
buffer = DownloadRemoteConfigVersion();
|
||||
break;
|
||||
case REQUEST.GET_ASSET_DIGEST:
|
||||
buffer = GetAssetDigest(request);
|
||||
break;
|
||||
case REQUEST.GET_PLAYER_PROFILE:
|
||||
buffer = GetPlayerProfile();
|
||||
break;
|
||||
case REQUEST.GET_MAP_OBJECTS:
|
||||
this.player.updatePosition(request);
|
||||
buffer = GetMapObjects(request);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.GET_DOWNLOAD_URLS:
|
||||
GetDownloadUrls(request, this.generateDownloadUrlByAssetId).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
return void 0;
|
||||
break;
|
||||
case REQUEST.SET_AVATAR:
|
||||
player.updateAvatar(request);
|
||||
buffer = SetAvatar(player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.SFIDA_ACTION_LOG:
|
||||
buffer = SfidaActionLog();
|
||||
break;
|
||||
case REQUEST.MARK_TUTORIAL_COMPLETE:
|
||||
buffer = MarkTutorialComplete(player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.CLAIM_CODENAME:
|
||||
buffer = ClaimCodeName(request, player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.LEVEL_UP_REWARDS:
|
||||
buffer = LevelUpRewards();
|
||||
break;
|
||||
case REQUEST.FORT_DETAILS:
|
||||
buffer = FortDetails(request);
|
||||
break;
|
||||
case REQUEST.FORT_SEARCH:
|
||||
buffer = FortSearch();
|
||||
break;
|
||||
case REQUEST.SET_CONTACT_SETTINGS:
|
||||
player.updateContactSettings(request);
|
||||
buffer = SetContactSettings(player);
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.ENCOUNTER:
|
||||
buffer = Encounter(request);
|
||||
break;
|
||||
case REQUEST.NICKNAME_POKEMON:
|
||||
buffer = NicknamePokemon(request);
|
||||
break;
|
||||
case REQUEST.UPGRADE_POKEMON:
|
||||
buffer = UpgradePokemon(request);
|
||||
break;
|
||||
case REQUEST.EVOLVE_POKEMON:
|
||||
buffer = EvolvePokemon(request);
|
||||
break;
|
||||
case REQUEST.SET_FAVORITE_POKEMON:
|
||||
buffer = SetFavoritePokemon(request);
|
||||
break;
|
||||
case REQUEST.CATCH_POKEMON:
|
||||
let data = proto.Networking.Requests.Messages.CatchPokemonMessage.decode(request.request_message.toBuffer());
|
||||
console.log(data);
|
||||
break;
|
||||
default:
|
||||
this.print(`Unknown request: ${this.getRequestType(request)}`, 31);
|
||||
break;
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
};
|
||||
|
||||
resolve(buffer);
|
||||
|
|
|
|||
23
src/setup.js
23
src/setup.js
|
|
@ -4,23 +4,26 @@ import * as CFG from "../cfg";
|
|||
|
||||
export function setup() {
|
||||
|
||||
this.print("Booting server...", 33);
|
||||
this.print("Booting server..", 33);
|
||||
|
||||
this.setupMongo(() => {
|
||||
this.createAssetDownloadSession().then(() => {
|
||||
this.print("Created asset download session");
|
||||
this.setupMongo().then(() => {
|
||||
|
||||
this.print("Database connection established");
|
||||
this.print("Database connection established");
|
||||
|
||||
if (CFG.SERVER_PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
if (CFG.SERVER_PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
this.socket = this.createHTTPServer();
|
||||
this.socket = this.createHTTPServer();
|
||||
|
||||
setTimeout(this::this.cycle, 1);
|
||||
setTimeout(this::this.cycle, 1);
|
||||
|
||||
this.print(`Server running at ${CFG.SERVER_HOST_IP}:${CFG.SERVER_PORT}`);
|
||||
this.print(`Server running at ${CFG.SERVER_HOST_IP}:${CFG.SERVER_PORT}`);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
72
src/utils.js
72
src/utils.js
|
|
@ -1,5 +1,8 @@
|
|||
import Long from "long";
|
||||
import proto from "./proto";
|
||||
import { DownloadUrls } from "./res";
|
||||
|
||||
import * as CFG from "../cfg";
|
||||
|
||||
/**
|
||||
* @param {Object} cls
|
||||
|
|
@ -44,15 +47,74 @@ export function getHashCodeFrom(str) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {Number} hi
|
||||
* @param {Number} lo
|
||||
* @param {Boolean} unsigned
|
||||
* @param {Long} long
|
||||
* @return {Number}
|
||||
*/
|
||||
export function decodeLong(hi, lo, unsigned) {
|
||||
export function decodeLong(long) {
|
||||
|
||||
let value = Long.fromBits(hi, lo, !!unsigned);
|
||||
let value = Long.fromBits(long.high, long.low, !!long.unsigned);
|
||||
|
||||
return (parseInt(value.toString()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} pm
|
||||
* @return {Object}
|
||||
*/
|
||||
export function getDownloadUrl(pm) {
|
||||
|
||||
let ii = 0;
|
||||
let length = DownloadUrls.length;
|
||||
|
||||
let node = null;
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
node = DownloadUrls[ii];
|
||||
if (node.bundle_name === pm) {
|
||||
return (node);
|
||||
}
|
||||
};
|
||||
|
||||
return (null);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} pm
|
||||
* @return {Object}
|
||||
*/
|
||||
export function getDownloadUrlByAssetId(id) {
|
||||
|
||||
let ii = 0;
|
||||
let length = DownloadUrls.length;
|
||||
|
||||
let node = null;
|
||||
let index = 0;
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
node = DownloadUrls[ii];
|
||||
if (node.asset_id.substring(index) === id) {
|
||||
return (node);
|
||||
}
|
||||
};
|
||||
|
||||
return (null);
|
||||
|
||||
}
|
||||
|
||||
export function getGenerationIdByAssetId(asset_id) {
|
||||
|
||||
let index = asset_id.lastIndexOf("/") + 1;
|
||||
|
||||
return (
|
||||
parseInt(asset_id.substring(index))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
export function randomRequestId() {
|
||||
return (
|
||||
1e18 - Math.floor(Math.random() * 1e18)
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user