mirror of
https://github.com/maierfelix/POGOserver.git
synced 2026-07-05 09:41:00 -05:00
Added mongodb, many updates & bug fixes
- Added mongodb database - Removed dumps - Added jwt google auth decode plugin - Added long decode plugin - Updated protos to latest commit - Updated readme - Added avatar saving - Fixed bug, where username, level and exp didnt got displayed - Default username is "undefined" - Clear console stdin - Save players into db stdin - Seperated login/register phase - Added decode long util method
This commit is contained in:
parent
dbddba2eee
commit
e9ccb672dc
6
POGOProtos/Data/Battle/BattleType.proto
vendored
6
POGOProtos/Data/Battle/BattleType.proto
vendored
|
|
@ -3,6 +3,6 @@ package POGOProtos.Data.Battle;
|
|||
|
||||
enum BattleType {
|
||||
BATTLE_TYPE_UNSET = 0;
|
||||
NORMAL = 1;
|
||||
TRAINING = 2;
|
||||
}
|
||||
BATTLE_TYPE_NORMAL = 1;
|
||||
BATTLE_TYPE_TRAINING = 2;
|
||||
}
|
||||
|
|
|
|||
6
POGOProtos/Enums/PokemonRarity.proto
vendored
6
POGOProtos/Enums/PokemonRarity.proto
vendored
|
|
@ -2,7 +2,7 @@ syntax = "proto3";
|
|||
package POGOProtos.Enums;
|
||||
|
||||
enum PokemonRarity {
|
||||
NORMAL = 0;
|
||||
LEGENDARY = 1;
|
||||
MYTHIC = 2;
|
||||
POKEMON_RARITY_NORMAL = 0;
|
||||
POKEMON_RARITY_LEGENDARY = 1;
|
||||
POKEMON_RARITY_MYTHIC = 2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ message RequestEnvelope {
|
|||
uint64 request_id = 3;
|
||||
repeated .POGOProtos.Networking.Requests.Request requests = 4;
|
||||
|
||||
repeated .POGOProtos.Networking.Envelopes.Unknown6 unknown6 = 6;
|
||||
// Unknown6 is required to get a response.
|
||||
// For an example check https://github.com/keyphact/pgoapi/blob/75eba6b5b630841ee4f7c2ea983f15874fb0862d/pgoapi/rpc_api.py#L192-L212
|
||||
.POGOProtos.Networking.Envelopes.Unknown6 unknown6 = 6;
|
||||
double latitude = 7;
|
||||
double longitude = 8;
|
||||
double altitude = 9;
|
||||
|
|
|
|||
|
|
@ -14,10 +14,4 @@ message ResponseEnvelope {
|
|||
|
||||
repeated bytes returns = 100;
|
||||
string error = 101;
|
||||
|
||||
message Unknown7 {
|
||||
bytes unknown71 = 1;
|
||||
int64 unknown72 = 2;
|
||||
bytes unknown73 = 3;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
101
POGOProtos/Networking/Envelopes/Signature.proto
vendored
Normal file
101
POGOProtos/Networking/Envelopes/Signature.proto
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
syntax = "proto3";
|
||||
package POGOProtos.Networking.Envelopes;
|
||||
|
||||
message Signature {
|
||||
|
||||
message LocationFix {
|
||||
string provider = 1; // "network", "gps", "fused", possibly others
|
||||
uint64 timestamp_since_start = 2; // in ms
|
||||
float latitude = 13;
|
||||
float longitude = 14;
|
||||
|
||||
// ??? shows up in struct, dunno where these go
|
||||
// float device_speed;
|
||||
// float device_course;
|
||||
float horizontal_accuracy = 20; // iOS only? (range seems to be -1 to +1)
|
||||
float altitude = 21;
|
||||
float vertical_accuracy = 22; // iOS only? (range seems to be ~10-12)
|
||||
uint64 provider_status = 26; // Usually 3 (possibly GPS status: 1 = no fix, 2 = acquiring/inaccurate, 3 = fix acquired)
|
||||
// On iOS there are some LocationFixes with unk26=1 and everything else empty
|
||||
uint32 floor = 27; // No idea what this is, seems to be optional
|
||||
uint64 location_type = 28; // Always 1 (if there is data at all)
|
||||
}
|
||||
|
||||
// don't really care about this since we're not using it
|
||||
message AndroidGpsInfo {
|
||||
uint64 time_to_fix = 1;
|
||||
repeated int32 satellites_prn = 2;
|
||||
repeated float snr = 3;
|
||||
repeated float azimuth = 4;
|
||||
repeated float elevation = 5;
|
||||
repeated bool has_almanac = 6;
|
||||
repeated bool has_ephemeris = 7;
|
||||
repeated bool used_in_fix = 8;
|
||||
}
|
||||
|
||||
message SensorInfo {
|
||||
uint64 timestamp_snapshot = 1; // in ms
|
||||
double magnetometer_x = 3;
|
||||
double magnetometer_y = 4;
|
||||
double magnetometer_z = 5;
|
||||
double angle_normalized_x = 6;
|
||||
double angle_normalized_y = 7;
|
||||
double angle_normalized_z = 8;
|
||||
double accel_raw_x = 10;
|
||||
double accel_raw_y = 11;
|
||||
double accel_raw_z = 12;
|
||||
double gyroscope_raw_x = 13;
|
||||
double gyroscope_raw_y = 14;
|
||||
double gyroscope_raw_z = 15;
|
||||
double accel_normalized_x = 16;
|
||||
double accel_normalized_y = 17;
|
||||
double accel_normalized_z = 18;
|
||||
uint64 accelerometer_axes = 19; // Always 3
|
||||
}
|
||||
|
||||
message DeviceInfo {
|
||||
string device_id = 1; // Hex string
|
||||
string android_board_name = 2;
|
||||
string android_bootloader = 3;
|
||||
string device_brand = 4; // On Android: product.brand
|
||||
string device_model = 5; // On Android: product.device
|
||||
string device_model_identifier = 6; // Android only, build.display.id
|
||||
string device_model_boot = 7; // On Android: boot.hardware
|
||||
string hardware_manufacturer = 8; // On Android: product.manufacturer
|
||||
string hardware_model = 9; // On Android: product.model
|
||||
string firmware_brand = 10; // On Android: product.name, on iOS: "iPhone OS"
|
||||
string firmware_tags = 12; // Android only, build.tags
|
||||
string firmware_type = 13; // On Android: build.type, on iOS instead: iOS version
|
||||
string firmware_fingerprint = 14; // Android only, build.fingerprint
|
||||
}
|
||||
|
||||
message ActivityStatus {
|
||||
// all of these had 1 as their value
|
||||
uint64 start_time_ms = 1;
|
||||
bool unknown_status = 2;
|
||||
bool walking = 3;
|
||||
bool running = 4;
|
||||
bool stationary = 5;
|
||||
bool automotive = 6;
|
||||
bool tilting = 7;
|
||||
bool cycling = 8;
|
||||
bytes status = 9;
|
||||
}
|
||||
|
||||
uint64 timestamp_since_start = 2; // in ms
|
||||
repeated LocationFix location_fix = 4;
|
||||
AndroidGpsInfo gps_info = 5;
|
||||
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 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
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ message Unknown6 {
|
|||
Unknown2 unknown2 = 2;
|
||||
|
||||
message Unknown2 {
|
||||
bytes unknown1 = 1;
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ message GetGymDetailsResponse {
|
|||
.POGOProtos.Data.Gym.GymState gym_state = 1;
|
||||
string name = 2;
|
||||
repeated string urls = 3;
|
||||
POGOProtos.Networking.Responses.GetGymDetailsResponse.Result result = 4;
|
||||
.POGOProtos.Networking.Responses.GetGymDetailsResponse.Result result = 4;
|
||||
string description = 5;
|
||||
|
||||
enum Result {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ syntax = "proto3";
|
|||
package POGOProtos.Networking.Responses;
|
||||
|
||||
message UseItemGymResponse {
|
||||
POGOProtos.Networking.Responses.UseItemGymResponse.Result result = 1;
|
||||
.POGOProtos.Networking.Responses.UseItemGymResponse.Result result = 1;
|
||||
int64 updated_gp = 2; // Gym Points (?)
|
||||
|
||||
enum Result {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ package POGOProtos.Settings.Master.Item;
|
|||
import "POGOProtos/Enums/ItemEffect.proto";
|
||||
|
||||
message FoodAttributes {
|
||||
repeated POGOProtos.Enums.ItemEffect item_effect = 1;
|
||||
repeated .POGOProtos.Enums.ItemEffect item_effect = 1;
|
||||
repeated float item_effect_percent = 2;
|
||||
float growth_percent = 3;
|
||||
}
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -1,4 +1,12 @@
|
|||
# POGOServer
|
||||
````
|
||||
______ _____ _____ _____
|
||||
| ___ \ _ | __ \ _ |
|
||||
| |_/ / | | | | \/ | | | ___ ___ _ ____ _____ _ __
|
||||
| __/| | | | | __| | | |/ __|/ _ \ '__\ \ / / _ \ '__|
|
||||
| | \ \_/ / |_\ \ \_/ /\__ \ __/ | \ V / __/ |
|
||||
\_| \___/ \____/\___/ |___/\___|_| \_/ \___|_|
|
||||
````
|
||||
|
||||
<a href="#">
|
||||
<img src="https://img.shields.io/badge/Pokemon%20GO-0.31.0-blue.svg?style=flat-square" />
|
||||
</a>
|
||||
|
|
|
|||
18
cfg.js
18
cfg.js
|
|
@ -4,10 +4,24 @@ export const SERVER_GAME_MODE = 0;
|
|||
export const SERVER_TICK_INTERVAL = 1; // better dont change
|
||||
export const SERVER_SAVE_INTERVAL = 120000; // all 120s
|
||||
export const SERVER_MAX_CONNECTIONS = 64;
|
||||
export const SERVER_PLAYER_CONNECTION_TIMEOUT = 60000; // 1min
|
||||
export const SERVER_PLAYER_CONNECTION_TIMEOUT = 1e3 * 60 * 30; // 30min
|
||||
|
||||
export const SERVER_DEFAULT_CONSOLE_COLOR = 32;
|
||||
|
||||
export const ASSET_DIGEST_PATH = "asset_digest";
|
||||
|
||||
export const MINIMUM_CLIENT_VERSION = "0.31.0";
|
||||
export const MINIMUM_CLIENT_VERSION = "0.31.0";
|
||||
|
||||
//lets require/import the mongodb native drivers.
|
||||
var mongodb = require('mongodb');
|
||||
|
||||
//We need to work with "MongoClient" interface in order to connect to a mongodb server.
|
||||
var MongoClient = mongodb.MongoClient;
|
||||
|
||||
export const SERVER_MONGO_PORT = 27017;
|
||||
export const SERVER_MONGO_HOST_IP = "localhost";
|
||||
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";
|
||||
17378
dumps/dump.json
17378
dumps/dump.json
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -20,7 +20,10 @@
|
|||
"body-parser": "^1.15.2",
|
||||
"concat-stream": "^1.5.1",
|
||||
"nodemon": "^1.7.1",
|
||||
"protobufjs": "^5.0.1"
|
||||
"protobufjs": "^5.0.1",
|
||||
"mongodb": "^2.2.5",
|
||||
"jwt-decode": "^2.1.0",
|
||||
"long": "^3.2.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
|
|
|||
103
src/database.js
103
src/database.js
|
|
@ -0,0 +1,103 @@
|
|||
import mongodb from "mongodb";
|
||||
|
||||
import * as CFG from "../cfg";
|
||||
|
||||
/**
|
||||
* @param {Function} resolve
|
||||
*/
|
||||
export function setupMongo(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();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export function loadCollection(name) {
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.db.instance.listCollections({name: name}).next((err, exists) => {
|
||||
if (!exists) this.createCollection(name).then((coll) => resolve());
|
||||
else {
|
||||
this.db.instance.collection(name, (err, coll) => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export function createCollection(name) {
|
||||
return new Promise((resolve) => {
|
||||
this.db.instance.createCollection(name, {}, (err, coll) => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getUserByEmail(email) {
|
||||
return new Promise((resolve) => {
|
||||
let collection = this.getUserCollection();
|
||||
collection.find({email: email}).toArray((err, docs) => {
|
||||
resolve(docs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function getUserCollection() {
|
||||
return (
|
||||
this.db.instance.collection(CFG.SERVER_MONGO_COLLECTION_USERS)
|
||||
);
|
||||
}
|
||||
|
||||
export function createUser(obj) {
|
||||
|
||||
let collection = this.getUserCollection();
|
||||
|
||||
let user = {
|
||||
username: obj.username,
|
||||
email: obj.email,
|
||||
position: obj.position,
|
||||
exp: obj.exp,
|
||||
stardust: obj.stardust,
|
||||
pokecoins: obj.pokecoins,
|
||||
avatar: obj.avatar
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
collection.insert([user], (error, result) => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export function updateUser(obj) {
|
||||
|
||||
let collection = this.getUserCollection();
|
||||
|
||||
let user = {
|
||||
username: obj.username,
|
||||
email: obj.email,
|
||||
position: obj.position,
|
||||
exp: obj.exp,
|
||||
stardust: obj.stardust,
|
||||
pokecoins: obj.pokecoins,
|
||||
avatar: obj.avatar
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
collection.update({email: obj.email}, user, (error, result) => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
11
src/index.js
11
src/index.js
|
|
@ -1,9 +1,11 @@
|
|||
import fs from "fs";
|
||||
import http from "http";
|
||||
import proto from "./proto";
|
||||
import querystring from "querystring";
|
||||
|
||||
import { inherit } from "./utils";
|
||||
import {
|
||||
inherit,
|
||||
decodeLong
|
||||
} from "./utils";
|
||||
|
||||
import * as CFG from "../cfg";
|
||||
|
||||
|
|
@ -30,6 +32,11 @@ class GameServer {
|
|||
CRASH: false
|
||||
};
|
||||
|
||||
this.db = {
|
||||
instance: null,
|
||||
collections: {}
|
||||
};
|
||||
|
||||
this.proto = null;
|
||||
this.socket = null;
|
||||
this.player = null;
|
||||
|
|
|
|||
18
src/packets/Data.DownloadUrlEntry.js
Normal file
18
src/packets/Data.DownloadUrlEntry.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import proto from "../proto";
|
||||
|
||||
/**
|
||||
* @param {Object}
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function DownloadUrlEntry(obj) {
|
||||
|
||||
return (
|
||||
new proto.Data.DownloadUrlEntry({
|
||||
url: obj.url,
|
||||
asset_id: obj.id,
|
||||
size: obj.size,
|
||||
checksum: obj.checksum
|
||||
})
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ export default function ResponseEnvelope(obj) {
|
|||
status_code: obj.status,
|
||||
unknown6: new proto.Networking.Envelopes.Unknown6Response({
|
||||
response_type: 6,
|
||||
response_data: new proto.Networking.Envelopes.Unknown6Response.Unknown2({
|
||||
unknown2: new proto.Networking.Envelopes.Unknown6Response.Unknown2({
|
||||
unknown1: 1
|
||||
})
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export default function DownloadSettings(obj) {
|
|||
get_map_objects_min_refresh_seconds: 5,
|
||||
get_map_objects_max_refresh_seconds: 30,
|
||||
get_map_objects_min_distance_meters: 10,
|
||||
google_maps_api_key: "AIzaSyDF9rkP8lhcddBtvH9gVFzjnNo13WtmJIM"
|
||||
google_maps_api_key: CFG.SERVER_GMAPS_API_KEY
|
||||
}),
|
||||
inventory_settings: new proto.Settings.InventorySettings({
|
||||
max_pokemon: 1000,
|
||||
|
|
|
|||
25
src/packets/Responses.GetDownloadUrls.js
Normal file
25
src/packets/Responses.GetDownloadUrls.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import proto from "../proto";
|
||||
|
||||
import DownloadUrlEntry from "./Data.DownloadUrlEntry";
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function GetDownloadUrls() {
|
||||
|
||||
let download_urls = [
|
||||
DownloadUrlEntry({
|
||||
url: "",
|
||||
asset_id: "",
|
||||
size: 0,
|
||||
checksum: 0
|
||||
})
|
||||
];
|
||||
|
||||
return (
|
||||
new proto.Networking.Responses.GetDownloadUrlsResponse({
|
||||
download_urls: download_urls
|
||||
}).encode()
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -10,37 +10,81 @@ export default function GetInventoryData(obj) {
|
|||
new proto.Networking.Responses.GetInventoryResponse({
|
||||
success: true,
|
||||
inventory_delta: new proto.Inventory.InventoryDelta({
|
||||
original_timestamp_ms: new Date().getTime * 1000,
|
||||
new_timestamp_ms: new Date().getTime * 1000,
|
||||
inventory_items: [
|
||||
// player stats
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
pokemon_data: new proto.Data.PokemonData({
|
||||
id: 123781297398,
|
||||
pokemon_id: 25,
|
||||
cp: 10000000000,
|
||||
is_egg: false,
|
||||
height_m: 100,
|
||||
weight_kg: 1,
|
||||
move_1: 219,
|
||||
move_2: 26,
|
||||
deployed_fort_id: 0,
|
||||
owner_name: "",
|
||||
origin: 0,
|
||||
individual_attack: 100,
|
||||
individual_defense: 100,
|
||||
individual_stamina: 100,
|
||||
cp_multiplier: 100,
|
||||
pokeball: 1,
|
||||
creation_time_ms: new Date().getTime() * 1000
|
||||
"player_stats": new proto.Data.Player.PlayerStats({
|
||||
"level": 99,
|
||||
"experience": 1304364,
|
||||
"prev_level_xp": 900000,
|
||||
"next_level_xp": 1350000,
|
||||
"km_walked": 54.55459213256836,
|
||||
"pokemons_encountered": 3942,
|
||||
"unique_pokedex_entries": 93,
|
||||
"pokemons_captured": 3569,
|
||||
"evolutions": 782,
|
||||
"poke_stop_visits": 3113,
|
||||
"pokeballs_thrown": 5783,
|
||||
"eggs_hatched": 27,
|
||||
"big_magikarp_caught": 11,
|
||||
"battle_attack_won": 36,
|
||||
"battle_attack_total": 44,
|
||||
"battle_defended_won": 0,
|
||||
"battle_training_won": 1,
|
||||
"battle_training_total": 2,
|
||||
"prestige_raised_total": 190,
|
||||
"prestige_dropped_total": 27000,
|
||||
"pokemon_deployed": 2,
|
||||
"small_rattata_caught": 79
|
||||
})
|
||||
})
|
||||
}),
|
||||
// pokedex entry
|
||||
new proto.Inventory.InventoryItem({
|
||||
inventory_item_data: new proto.Inventory.InventoryItemData({
|
||||
item: new proto.Inventory.Item({
|
||||
item_id: 4,
|
||||
count: 1000
|
||||
"pokedex_entry": new proto.Data.PokedexEntry({
|
||||
"pokemon_id": 147,
|
||||
"times_encountered": 7,
|
||||
"times_captured": 6,
|
||||
"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({
|
||||
"id": 151,
|
||||
"pokemon_id": 151,
|
||||
"cp": 9454,
|
||||
"stamina": 53,
|
||||
"stamina_max": 53,
|
||||
"move_1": 221,
|
||||
"move_2": 80,
|
||||
"deployed_fort_id": "",
|
||||
"owner_name": "",
|
||||
"is_egg": false,
|
||||
"egg_km_walked_target": 0,
|
||||
"egg_km_walked_start": 0,
|
||||
"origin": 0,
|
||||
"height_m": 0.3461824357509613,
|
||||
"weight_kg": 2.0753486156463623,
|
||||
"individual_attack": 2,
|
||||
"individual_defense": 0,
|
||||
"individual_stamina": 9,
|
||||
"cp_multiplier": 0.5974000096321106,
|
||||
"pokeball": 2,
|
||||
"battles_attacked": 0,
|
||||
"battles_defended": 0,
|
||||
"egg_incubator_id": "",
|
||||
"creation_time_ms": new Date().getTime() * 1000,
|
||||
"num_upgrades": 0,
|
||||
"additional_cp_multiplier": 0,
|
||||
"favorite": 0,
|
||||
"nickname": "Ad°0lf_fH$TL3R",
|
||||
"from_fort": 0
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
52
src/packets/Responses.GetMapObjects.js
Normal file
52
src/packets/Responses.GetMapObjects.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import proto from "../proto";
|
||||
|
||||
/**
|
||||
* @param {Request} request
|
||||
* @return {Object}
|
||||
*/
|
||||
export default function GetMapObjects(request) {
|
||||
|
||||
var cells = proto.Networking.Requests.Messages.GetMapObjectsMessage.decode(request.request_message.toBuffer()).cell_id;
|
||||
|
||||
var cellsRes = [];
|
||||
|
||||
cells.forEach((cell)=>{
|
||||
cellsRes.push(new proto.Map.MapCell({
|
||||
s2_cell_id: cell,
|
||||
current_timestamp_ms: new Date().getTime() * 1000,
|
||||
forts: [
|
||||
new proto.Map.Fort.FortData({
|
||||
id: "wuff",
|
||||
last_modified_timestamp_ms: new Date().getTime() * 1000,
|
||||
latitude: 39.1893730163574220,
|
||||
longitude: -96.5853271484375000,
|
||||
owned_by_team: 2,
|
||||
guard_pokemon_id: 150,
|
||||
guard_pokemon_cp: 2000,
|
||||
gym_points: 1000,
|
||||
is_in_battle: false,
|
||||
enabled: true,
|
||||
type: proto.Map.Fort.FortType.GYM,
|
||||
sponsor: proto.Map.Fort.FortSponsor.MCDONALDS,
|
||||
rendering_type: proto.Map.Fort.FortRenderingType.DEFAULT
|
||||
})
|
||||
],
|
||||
spawn_points: [ ],
|
||||
deleted_objects: [ ],
|
||||
is_truncated_list: false,
|
||||
fort_summaries: [ ],
|
||||
decimated_spawn_points: [ ],
|
||||
wild_pokemons: [ ],
|
||||
catchable_pokemons: [ ],
|
||||
nearby_pokemons: [ ]
|
||||
}));
|
||||
});
|
||||
|
||||
return (
|
||||
new proto.Networking.Responses.GetMapObjectsResponse({
|
||||
status: 1,
|
||||
map_cells: cellsRes
|
||||
}).encode()
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ function getPlayerDataPacket(obj) {
|
|||
new proto.Data.PlayerData({
|
||||
creation_timestamp_ms: 1467936859925,
|
||||
username: obj.username,
|
||||
team: obj.team,
|
||||
team: proto.Enums.TeamColor.YELLOW,
|
||||
tutorial_state: obj.tutorial_state,
|
||||
avatar: new proto.Data.Player.PlayerAvatar(obj.avatar),
|
||||
max_pokemon_storage: 250,
|
||||
|
|
@ -18,7 +18,6 @@ function getPlayerDataPacket(obj) {
|
|||
daily_bonus: new proto.Data.Player.DailyBonus({
|
||||
next_defender_bonus_collect_timestamp_ms: 1470174535972
|
||||
}),
|
||||
// equipped_badge: new proto.Data.Player.EquippedBadge({}),
|
||||
contact_settings: new proto.Data.Player.ContactSettings({
|
||||
send_marketing_emails: true
|
||||
}),
|
||||
|
|
@ -40,17 +39,25 @@ function buildPlayerData(obj) {
|
|||
let pokecoins = obj.pokecoins;
|
||||
let stardust = obj.stardust;
|
||||
|
||||
let avatar = {
|
||||
skin: 2,
|
||||
let avatar = obj.avatar || {
|
||||
skin: 0,
|
||||
hair: 2,
|
||||
shirt: 1,
|
||||
pants: 2,
|
||||
hat: 1,
|
||||
hat: 0,
|
||||
shoes: 2,
|
||||
eyes: 3,
|
||||
gender: proto.Enums.Gender.MALE,
|
||||
backpack: 1
|
||||
};
|
||||
|
||||
let tutorial_state = [0, 1, 3, 4, 7];
|
||||
let tutorial_state = [
|
||||
proto.Enums.TutorialState.LEGAL_SCREEN,
|
||||
proto.Enums.TutorialState.AVATAR_SELECTION,
|
||||
proto.Enums.TutorialState.POKEMON_CAPTURE,
|
||||
proto.Enums.TutorialState.NAME_SELECTION,
|
||||
proto.Enums.TutorialState.FIRST_TIME_EXPERIENCE_COMPLETE
|
||||
];
|
||||
|
||||
let currencies = [
|
||||
new proto.Data.Player.Currency({
|
||||
|
|
@ -87,7 +94,7 @@ export default function GetPlayer(obj) {
|
|||
new proto.Networking.Responses.GetPlayerResponse({
|
||||
success: true,
|
||||
player_data: packet
|
||||
}).encode()
|
||||
})
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -49,6 +49,7 @@ export default function ItemTemplates(obj) {
|
|||
"damage_window_end_ms": 3400,
|
||||
"energy_delta": -20
|
||||
}),
|
||||
// unused but saved here for later use
|
||||
move_sequence_settings: new proto.Settings.Master.MoveSequenceSettings({
|
||||
"sequence": ["anim attacker atk-move", "f2fvfx attacker acid_fast", "sfx attacker 051-0_acid", "wait 0.15", "vfx defender acid_fast_hit", "anim defender damageS01", "wait 0.35", "sys ui-sync", "sys complete"]
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -7,8 +7,11 @@ export GetInventory from "./Responses.GetInventory";
|
|||
export GetPlayer from "./Responses.GetPlayer";
|
||||
export GetPlayerProfile from "./Responses.GetPlayerProfile";
|
||||
|
||||
export GetMapObjects from "./Responses.GetMapObjects";
|
||||
|
||||
export ItemTemplates from "./Responses.ItemTemplates";
|
||||
export CheckAwardedBadges from "./Responses.CheckAwardedBadges";
|
||||
export GetDownloadUrls from "./Responses.GetDownloadUrls";
|
||||
|
||||
export AuthTicket from "./Envelopes.AuthTicket";
|
||||
export ResponseEnvelope from "./Envelopes.ResponseEnvelope";
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@ class Player {
|
|||
|
||||
this.uid = -1;
|
||||
|
||||
this.name = null;
|
||||
|
||||
this.email = null;
|
||||
|
||||
this._username = "undefined";
|
||||
|
||||
this.position = {
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
|
|
@ -59,6 +58,16 @@ class Player {
|
|||
this.uid = getHashCodeFrom(String(email));
|
||||
}
|
||||
|
||||
updateByObject(obj) {
|
||||
|
||||
for (let key in obj) {
|
||||
if (this.hasOwnProperty(key)) {
|
||||
this[key] = obj[key];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Request} req
|
||||
*/
|
||||
|
|
@ -74,6 +83,21 @@ class Player {
|
|||
|
||||
}
|
||||
|
||||
updateAvatar(req) {
|
||||
|
||||
let data = proto.Networking.Requests.Messages.SetAvatarMessage.decode(req.request_message.toBuffer());
|
||||
|
||||
this.avatar = data.player_avatar;
|
||||
|
||||
}
|
||||
|
||||
get username() {
|
||||
return (this._username);
|
||||
}
|
||||
set username(name) {
|
||||
this._username = name;
|
||||
}
|
||||
|
||||
get latitude() {
|
||||
return (this.position.latitude);
|
||||
}
|
||||
|
|
@ -175,7 +199,10 @@ export function updatePlayers() {
|
|||
}
|
||||
|
||||
export function savePlayers() {
|
||||
this.print("Saving players into database..");
|
||||
for (let client of this.clients) {
|
||||
this.savePlayer(client);
|
||||
};
|
||||
this.print("Saved players into database");
|
||||
return void 0;
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +210,6 @@ export function savePlayers() {
|
|||
* @param {Player} player
|
||||
*/
|
||||
export function savePlayer(player) {
|
||||
this.print(`${player.remoteAddress} saved into database`, 34);
|
||||
return void 0;
|
||||
this.updateUser(player);
|
||||
//this.print(`${player.remoteAddress} saved into database`, 34);
|
||||
}
|
||||
|
|
@ -12,6 +12,13 @@ export function processCommand(cmd, data) {
|
|||
this.print("Killed the server!", 31);
|
||||
process.exit();
|
||||
break;
|
||||
case "/clear":
|
||||
process.stdout.write("\x1Bc");
|
||||
this.greet();
|
||||
break;
|
||||
case "/save":
|
||||
this.savePlayers();
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
176
src/request.js
176
src/request.js
|
|
@ -16,7 +16,9 @@ import {
|
|||
GetPlayer,
|
||||
GetPlayerProfile,
|
||||
ItemTemplates,
|
||||
GetAssetDigest
|
||||
GetAssetDigest,
|
||||
GetDownloadUrls,
|
||||
GetMapObjects
|
||||
} from "./packets";
|
||||
|
||||
import { decodeRequestEnvelope } from "./utils";
|
||||
|
|
@ -98,10 +100,10 @@ export function onRequest(req, res) {
|
|||
return void 0;
|
||||
}
|
||||
|
||||
let answer = this.processRequests(request.requests);
|
||||
let msg = this.envelopResponse(1, request.request_id, answer, !!request.auth_ticket, request.unknown6);
|
||||
|
||||
this.send(msg);
|
||||
this.processRequests(request.requests).then((answer) => {
|
||||
let msg = this.envelopResponse(1, request.request_id, answer, request.hasOwnProperty("auth_ticket"), request.unknown6);
|
||||
this.send(msg);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -133,16 +135,77 @@ export function envelopResponse(status, id, response, auth, unknown6) {
|
|||
*/
|
||||
export function processRequests(requests) {
|
||||
|
||||
let ii = 0;
|
||||
let length = requests.length;
|
||||
return new Promise((resolve) => {
|
||||
let ii = 0;
|
||||
let counter = 0;
|
||||
let length = requests.length;
|
||||
let body = [];
|
||||
for (; ii < length; ++ii) {
|
||||
this.processRequest(requests[ii]).then((request) => {
|
||||
counter++;
|
||||
body.push(request);
|
||||
if (counter >= length) resolve(body);
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
let body = [];
|
||||
}
|
||||
|
||||
for (; ii < length; ++ii) {
|
||||
body.push(this.processRequest(requests[ii]));
|
||||
};
|
||||
/**
|
||||
* @param {Object} doc
|
||||
*/
|
||||
export function registerPlayer(doc) {
|
||||
|
||||
return (body);
|
||||
let player = this.player;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.createUser(player).then(() => {
|
||||
this.print(`${this.player.email.replace("@gmail.com", "")} registered!`, 36);
|
||||
this.loginPlayer(doc).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} doc
|
||||
*/
|
||||
export function loginPlayer(doc) {
|
||||
|
||||
let buffer = null;
|
||||
let player = this.player;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.getUserByEmail(player.email).then((doc) => {
|
||||
player.updateByObject(doc[0]);
|
||||
buffer = GetPlayer(doc[0]).encode();
|
||||
resolve(buffer);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
export function forwardPlayer() {
|
||||
|
||||
let player = this.player;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.getUserByEmail(player.email).then((doc) => {
|
||||
doc = doc[0];
|
||||
if (doc === void 0) {
|
||||
this.registerPlayer(doc).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.loginPlayer(doc).then((res) => {
|
||||
resolve(res);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -152,16 +215,15 @@ export function processRequests(requests) {
|
|||
*/
|
||||
export function processRequest(request) {
|
||||
|
||||
let buffer = null;
|
||||
let buffer = null;
|
||||
let player = this.player;
|
||||
|
||||
switch (request.request_type){
|
||||
return new Promise((resolve) => {
|
||||
|
||||
switch (request.request_type) {
|
||||
case REQUEST.GET_PLAYER:
|
||||
buffer = GetPlayer({
|
||||
username: "MrHuhn",
|
||||
team: 1,
|
||||
pokecoins: 1337,
|
||||
stardust: 1338
|
||||
});
|
||||
this.forwardPlayer().then((res) => resolve(res));
|
||||
return void 0;
|
||||
break;
|
||||
case REQUEST.GET_HATCHED_EGGS:
|
||||
buffer = GetHatchedEggs();
|
||||
|
|
@ -189,10 +251,82 @@ export function processRequest(request) {
|
|||
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 = new proto.Networking.Responses.SetAvatarResponse({
|
||||
status: proto.Networking.Responses.SetAvatarResponse.Status.SUCCESS,
|
||||
player_data: GetPlayer({
|
||||
username: "TollNicht",
|
||||
team: 1,
|
||||
pokecoins: 1337,
|
||||
stardust: 1338,
|
||||
avatar: player.avatar
|
||||
}).player_data
|
||||
}).encode();
|
||||
this.savePlayer(player);
|
||||
break;
|
||||
case REQUEST.SFIDA_ACTION_LOG:
|
||||
buffer = new proto.Networking.Responses.SfidaActionLogResponse({
|
||||
result: proto.Networking.Responses.SfidaActionLogResponse.Result.SUCCESS,
|
||||
log_entries: [
|
||||
new proto.Data.Logs.ActionLogEntry({
|
||||
sfida: true,
|
||||
timestamp_ms: new Date().getTime() * 1000,
|
||||
catch_pokemon: new proto.Data.Logs.CatchPokemonLogEntry({
|
||||
result: 1,
|
||||
pokemon_id: proto.Enums.PokemonId.BULBASAUR,
|
||||
combat_points: 10,
|
||||
pokemon_data_id: 1
|
||||
}),
|
||||
fort_search: new proto.Data.Logs.FortSearchLogEntry({
|
||||
result: 1,
|
||||
fort_id: "roflcopter",
|
||||
eggs: 0,
|
||||
items: [
|
||||
new proto.Inventory.Item.ItemData({
|
||||
item_id: proto.Inventory.Item.ItemId.ITEM_POKE_BALL,
|
||||
count: 1,
|
||||
unseen: false
|
||||
})
|
||||
]
|
||||
})
|
||||
})
|
||||
]
|
||||
}).encode();
|
||||
break;
|
||||
case REQUEST.MARK_TUTORIAL_COMPLETE:
|
||||
buffer = new proto.Networking.Respones.MarkTutorialCompleteResponse({
|
||||
success: true,
|
||||
player_data: GetPlayer({
|
||||
username: "TollNicht",
|
||||
team: 1,
|
||||
pokecoins: 1337,
|
||||
stardust: 1338,
|
||||
avatar: player.avatar
|
||||
}).player_data
|
||||
});
|
||||
break;
|
||||
case REQUEST.LEVEL_UP_REWARDS:
|
||||
buffer = new proto.Networking.Responses.LevelUpRewardsResponse({
|
||||
result: proto.Networking.Responses.LevelUpRewardsResponse.Result.SUCCESS,
|
||||
items_awarded: [],
|
||||
items_unlocked: []
|
||||
});
|
||||
break;
|
||||
default:
|
||||
this.print(`Unknown request: ${this.getRequestType(request)}`, 31);
|
||||
break;
|
||||
};
|
||||
|
||||
return (buffer);
|
||||
resolve(buffer);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
20
src/setup.js
20
src/setup.js
|
|
@ -6,15 +6,21 @@ export function setup() {
|
|||
|
||||
this.print("Booting server...", 33);
|
||||
|
||||
if (CFG.SERVER_PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
this.setupMongo(() => {
|
||||
|
||||
this.socket = this.createHTTPServer();
|
||||
this.print("Database connection established");
|
||||
|
||||
setTimeout(this::this.cycle, 1);
|
||||
if (CFG.SERVER_PORT < 1) {
|
||||
this.print("Invalid port!", 31);
|
||||
return void 0;
|
||||
}
|
||||
|
||||
this.print(`Server running at ${CFG.SERVER_HOST_IP}:${CFG.SERVER_PORT}`);
|
||||
this.socket = this.createHTTPServer();
|
||||
|
||||
setTimeout(this::this.cycle, 1);
|
||||
|
||||
this.print(`Server running at ${CFG.SERVER_HOST_IP}:${CFG.SERVER_PORT}`);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
17
src/utils.js
17
src/utils.js
|
|
@ -1,3 +1,4 @@
|
|||
import Long from "long";
|
||||
import proto from "./proto";
|
||||
|
||||
/**
|
||||
|
|
@ -40,4 +41,18 @@ export function getHashCodeFrom(str) {
|
|||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Number} hi
|
||||
* @param {Number} lo
|
||||
* @param {Boolean} unsigned
|
||||
* @return {Number}
|
||||
*/
|
||||
export function decodeLong(hi, lo, unsigned) {
|
||||
|
||||
let value = Long.fromBits(hi, lo, !!unsigned);
|
||||
|
||||
return (parseInt(value.toString()));
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user