1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Complete bare minimum to seem logged in

This commit is contained in:
NGnius (Graham)
2025-03-01 16:22:57 -05:00
parent fe30e783ad
commit 7e31f6fe1d
55 changed files with 1147 additions and 81 deletions

View File

@@ -12,17 +12,14 @@ To get CardLife to use these servers, replace the `ServerConfig.json` file in th
To get Robocraft to use these servers, place [this servenvmulti.config](assets/robocraft/serenvmulti.config) file in the game files. To get Robocraft to use these servers, place [this servenvmulti.config](assets/robocraft/serenvmulti.config) file in the game files.
You may also need to add the following to your OS's `hosts` file:
```
127.0.0.1 robocraftstaticdata.s3.amazonaws.com
```
The `hosts` file can be found at `/etc/hosts` on Linux and `C:\Windows\system32\drivers\etc\hosts` on Windows. Usually this requires elevated permissions (root/admin) to edit.
// TODO Don't expect people to run these servers on their own computer // TODO Don't expect people to run these servers on their own computer
## Privacy ## Privacy
No data is collected or logged, except in dev mode. Some personal identifiers are sent but only exist ephemerally. No data is collected or logged, except in dev mode. Some personal identifiers are sent but only exist ephemerally.
## Development
### Robocraft
Run all of the servers using their respective `run_debug.sh` scripts and use the `dev` profile in `servenvmulti.config` to point the game to your local dev servers.

View File

@@ -0,0 +1,68 @@
use polariton::operation::{Typed, Arr};
pub struct ChatChannelInfo {
pub channel_name: String,
pub members: Vec<ChatChannelMember>,
pub channel_ty: ChatChannelType,
}
impl ChatChannelInfo {
pub fn as_transmissible(&self) -> Typed {
Typed::HashMap(vec![
(Typed::Str("channelName".into()), Typed::Str(self.channel_name.clone().into())),
(Typed::Str("members".into()), Typed::Arr(Arr {
ty: 104, // hashtable
items: self.members.iter().map(|x| x.as_transmissible()).collect(),
})),
(Typed::Str("channelType".into()), Typed::Int(self.channel_ty as _)),
].into())
}
}
pub struct ChatChannelMember {
pub name: String,
pub use_custom_avatar: bool,
pub state: ChatPlayerState,
pub custom_avatar: Vec<u8>, // always PNG?
pub avatar_id: i32,
}
impl ChatChannelMember {
pub fn as_transmissible(&self) -> Typed {
Typed::HashMap(vec![
(Typed::Str("name".into()), Typed::Str(self.name.clone().into())),
(Typed::Str("useCustomAvatar".into()), Typed::Bool(self.use_custom_avatar.into())),
(Typed::Str("state".into()), Typed::Int(self.state as _)),
if self.use_custom_avatar {
(Typed::Str("customAvatar".into()), Typed::Bytes(self.custom_avatar.clone().into()))
} else {
(Typed::Str("avatarId".into()), Typed::Int(self.avatar_id))
},
].into())
}
}
#[allow(dead_code)]
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum ChatChannelType {
None = 0,
Public = 1,
Battle = 2,
BattleTeam = 3,
Platoon = 4,
Custom = 5,
Clan = 6,
Private = 7,
CustomGame = 8,
}
#[allow(dead_code)]
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum ChatPlayerState {
Idk0 = 0,
Idk1 = 1,
Idk2 = 2,
// FIXME
}

View File

@@ -0,0 +1 @@
pub mod channel;

View File

@@ -0,0 +1,58 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Arr};
use crate::data::channel::*;
const PARAM_KEY: u8 = 18;
pub(super) fn all_channels_provider() -> SimpleFunc<11, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Arr(Arr {
ty: 104, // hashtable
items: vec![
ChatChannelInfo {
channel_name: "RE_public_channel0".to_owned(),
members: vec![
ChatChannelMember {
name: "RE_chat0_username0".to_owned(),
use_custom_avatar: false,
state: ChatPlayerState::Idk1,
custom_avatar: Vec::default(),
avatar_id: 2,
},
ChatChannelMember {
name: "RE_chat0_username1".to_owned(),
use_custom_avatar: false,
state: ChatPlayerState::Idk2,
custom_avatar: Vec::default(),
avatar_id: 3,
},
],
channel_ty: ChatChannelType::Public,
}.as_transmissible(),
ChatChannelInfo {
channel_name: "RE_custom_channel1".to_owned(),
members: vec![
ChatChannelMember {
name: "RE_chat1_username0".to_owned(),
use_custom_avatar: false,
state: ChatPlayerState::Idk0,
custom_avatar: Vec::default(),
avatar_id: 2,
},
ChatChannelMember {
name: "RE_chat1_username1".to_owned(),
use_custom_avatar: false,
state: ChatPlayerState::Idk1,
custom_avatar: Vec::default(),
avatar_id: 3,
},
],
channel_ty: ChatChannelType::Custom,
}.as_transmissible(),
],
}));
Ok(params.into())
})
}

View File

@@ -1,6 +1,7 @@
mod more_auth; mod more_auth;
mod chat_ignores; mod chat_ignores;
mod pending_sanctions; mod pending_sanctions;
mod all_joined_channels;
use polariton_server::operations::OperationsHandler; use polariton_server::operations::OperationsHandler;
@@ -9,5 +10,6 @@ pub fn handler() -> OperationsHandler<crate::UserTy> {
.without_state(more_auth::MoreLobbyAuth) .without_state(more_auth::MoreLobbyAuth)
.without_state(chat_ignores::ignores_provider()) .without_state(chat_ignores::ignores_provider())
.without_state(pending_sanctions::pending_sanctions_checker()) .without_state(pending_sanctions::pending_sanctions_checker())
.without_state(all_joined_channels::all_channels_provider())
//.without_state(polariton_server::operations::Ack::<00000, _>::default()) //.without_state(polariton_server::operations::Ack::<00000, _>::default())
} }

View File

@@ -1,6 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone)]
pub enum GameMode { pub enum GameMode {
BattleArena = 0, BattleArena = 0,
SuddenDeath = 1, SuddenDeath = 1,
@@ -26,8 +27,16 @@ impl GameMode {
} }
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone)]
pub enum MapVisibility { pub enum MapVisibility {
Good = 0, Good = 0,
Poor = 1, Poor = 1,
Bad = 2, // VeryPoor Bad = 2, // VeryPoor
} }
#[repr(u8)]
#[derive(Copy, Clone)]
pub enum CustomGameInviteCode {
NoInvite = 0,
PendingInvite = 1,
}

View File

@@ -1,45 +1,13 @@
use polariton::operation::{Typed, Arr}; use polariton::operation::{Typed, Arr};
#[allow(dead_code)] use super::weapon_list::ItemCategory;
#[derive(Copy, Clone)]
pub enum MovementCategory {
NotAFunctionalItem = 0,
Wheel = 1,
Hover = 2,
Wing = 3,
Rudder = 4,
Thruster = 5,
InsectLeg = 6,
MechLeg = 7,
Ski = 8,
TankTrack = 9,
Rotor = 10,
SprinterLeg = 11,
Propeller = 12,
Laser = 100,
Plasma = 200,
Mortar = 250,
Rail = 300,
Nano = 400,
Tesla = 500,
Aeroflak = 600,
Ion = 650,
Seeker = 701,
Chaingun = 750,
ShieldModule = 800,
GhostModule = 801,
BlinkModule = 802,
EmpModule = 803,
WindowmakerModule = 804,
EnergyModule = 900,
}
pub struct GarageSlotInfo { pub struct GarageSlotInfo {
pub name: String, pub name: String,
pub cubes: u32, pub cubes: u32,
pub crf_id: u32, // 0 means not uploaded pub crf_id: u32, // 0 means not uploaded
pub was_rated: bool, // ignored when not on CRF pub was_rated: bool, // ignored when not on CRF
pub movement_categories: Vec<MovementCategory>, pub movement_categories: Vec<ItemCategory>,
pub uuid: (u32, u32), pub uuid: (u32, u32),
pub thumbnail_version: u32, pub thumbnail_version: u32,
pub total_robot_cpu: u32, pub total_robot_cpu: u32,
@@ -76,14 +44,7 @@ impl GarageSlotInfo {
(Typed::Str("tutorialRobot".into()), Typed::Bool(self.tutorial_robot.into())), (Typed::Str("tutorialRobot".into()), Typed::Bool(self.tutorial_robot.into())),
(Typed::Str("starterRobotIndex".into()), Typed::Int(self.starter_robot_index)), (Typed::Str("starterRobotIndex".into()), Typed::Int(self.starter_robot_index)),
(Typed::Str("controlType".into()), Typed::Int(self.control_type as i32)), (Typed::Str("controlType".into()), Typed::Int(self.control_type as i32)),
(Typed::Str("controlOptions".into()), Typed::Arr(Arr { (Typed::Str("controlOptions".into()), self.control_options.as_transmissible()),
ty: 111, // bool
items: vec![
Typed::Bool(self.control_options.vertical_strafing.into()),
Typed::Bool(self.control_options.sideways_driving.into()),
Typed::Bool(self.control_options.tracks_turn_on_spot.into()),
],
})),
(Typed::Str("masteryLevel".into()), Typed::Int(self.mastery_level)), (Typed::Str("masteryLevel".into()), Typed::Int(self.mastery_level)),
(Typed::Str("baySkinId".into()), Typed::Str(self.bay_skin_id.clone().into())), (Typed::Str("baySkinId".into()), Typed::Str(self.bay_skin_id.clone().into())),
(Typed::Str("weaponOrder".into()), Typed::Arr(Arr { (Typed::Str("weaponOrder".into()), Typed::Arr(Arr {
@@ -109,4 +70,17 @@ pub struct ControlOptions {
pub tracks_turn_on_spot: bool, pub tracks_turn_on_spot: bool,
} }
impl ControlOptions {
pub fn as_transmissible(&self) -> Typed {
Typed::Arr(Arr {
ty: 111, // bool
items: vec![
Typed::Bool(self.vertical_strafing.into()),
Typed::Bool(self.sideways_driving.into()),
Typed::Bool(self.tracks_turn_on_spot.into()),
],
})
}
}

View File

@@ -30,21 +30,21 @@ impl ItemShopBundle {
fn dump(&self, writer: &mut dyn Write) -> std::io::Result<usize> { fn dump(&self, writer: &mut dyn Write) -> std::io::Result<usize> {
let sku_bytes = self.sku.as_bytes(); let sku_bytes = self.sku.as_bytes();
let mut total_len = writer.write(&encode_7_bit_i32(sku_bytes.len() as i32))?; let mut total_len = writer.write(&super::encode_7_bit_i32(sku_bytes.len() as i32))?;
total_len += writer.write(sku_bytes)?; total_len += writer.write(sku_bytes)?;
let bundle_name_key_bytes = self.bundle_name_key.as_bytes(); let bundle_name_key_bytes = self.bundle_name_key.as_bytes();
total_len += writer.write(&encode_7_bit_i32(bundle_name_key_bytes.len() as i32))?; total_len += writer.write(&super::encode_7_bit_i32(bundle_name_key_bytes.len() as i32))?;
total_len += writer.write(bundle_name_key_bytes)?; total_len += writer.write(bundle_name_key_bytes)?;
let sprite_bytes = self.sprite.as_bytes(); let sprite_bytes = self.sprite.as_bytes();
total_len += writer.write(&encode_7_bit_i32(sprite_bytes.len() as i32))?; total_len += writer.write(&super::encode_7_bit_i32(sprite_bytes.len() as i32))?;
total_len += writer.write(sprite_bytes)?; total_len += writer.write(sprite_bytes)?;
total_len += writer.write(&[self.is_sprite_full_size as u8])?; total_len += writer.write(&[self.is_sprite_full_size as u8])?;
let currency_bytes = self.currency.as_str().as_bytes(); let currency_bytes = self.currency.as_str().as_bytes();
total_len += writer.write(&encode_7_bit_i32(currency_bytes.len() as i32))?; total_len += writer.write(&super::encode_7_bit_i32(currency_bytes.len() as i32))?;
total_len += writer.write(currency_bytes)?; total_len += writer.write(currency_bytes)?;
total_len += writer.write(&self.price.to_le_bytes())?; total_len += writer.write(&self.price.to_le_bytes())?;
@@ -108,17 +108,3 @@ impl CurrencyType {
} }
} }
} }
fn encode_7_bit_i32(mut src: i32) -> Vec<u8> {
let mut out = Vec::with_capacity(5);
while src != 0 {
let last_7 = (src & 0x7F) as u8;
src = src >> 7;
if src != 0 {
out.push(last_7 | 0x80);
} else {
out.push(last_7);
}
}
out
}

View File

@@ -16,3 +16,29 @@ pub mod garage_bay;
pub mod custom_games; pub mod custom_games;
pub mod tech_tree; pub mod tech_tree;
pub mod item_shop_bundle; pub mod item_shop_bundle;
pub mod player_robopass_season;
pub mod weapon_upgrade;
pub mod player_rank;
pub mod robot_data;
pub mod quest;
pub(self) fn encode_7_bit_i32(mut src: i32) -> Vec<u8> {
let mut out = Vec::with_capacity(5);
while src != 0 {
let last_7 = (src & 0x7F) as u8;
src = src >> 7;
if src != 0 {
out.push(last_7 | 0x80);
} else {
out.push(last_7);
}
}
out
}
pub(self) fn write_str_for_binreader(s: &str, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
let s_bytes = s.as_bytes();
let mut total_len = writer.write(&encode_7_bit_i32(s_bytes.len() as i32))?;
total_len += writer.write(s_bytes)?;
Ok(total_len)
}

View File

@@ -0,0 +1,21 @@
use polariton::operation::{Typed, Dict, Arr};
pub struct PlayerRankStaticInfo {
pub sub_rank_thresholds: Vec<i32>,
}
impl PlayerRankStaticInfo {
pub fn as_transmissible(&self) -> Typed {
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("subRankCount".into()), Typed::Int(self.sub_rank_thresholds.len() as i32)),
(Typed::Str("subRankThresholds".into()), Typed::Arr(Arr {
ty: 105, // int
items: self.sub_rank_thresholds.iter().map(|x| Typed::Int(*x)).collect(),
})),
],
})
}
}

View File

@@ -0,0 +1,25 @@
use polariton::operation::{Typed, Dict};
pub struct PlayerRoboPassSeasonInfo {
pub delta_xp_to_show: i32,
pub grade: i32,
pub has_deluxe: bool,
pub progress_in_grade: f32,
pub xp_from_start: i32,
}
impl PlayerRoboPassSeasonInfo {
pub fn as_transmissible(&self) -> Typed {
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("deltaXpToShow".into()), Typed::Int(self.delta_xp_to_show)),
(Typed::Str("grade".into()), Typed::Int(self.grade)),
(Typed::Str("hasDeluxe".into()), Typed::Bool(self.has_deluxe.into())),
(Typed::Str("progressInGrade".into()), Typed::Float(self.progress_in_grade)),
(Typed::Str("xpFromSeasonStart".into()), Typed::Int(self.xp_from_start)),
],
})
}
}

View File

@@ -0,0 +1,66 @@
#![allow(dead_code)]
use std::io::Write;
use polariton::operation::Typed;
pub struct DailyQuestsInfo {
pub can_remove_quest: bool,
pub player_quests: Vec<QuestInfo>,
pub completed_quests: Vec<QuestInfo>,
}
impl DailyQuestsInfo {
pub fn as_transmissible(&self) -> Typed {
let mut buf = Vec::new();
let mut writer = std::io::Cursor::new(&mut buf);
self.dump(&mut writer).unwrap();
Typed::Bytes(buf.into())
}
fn dump(&self, writer: &mut dyn Write) -> std::io::Result<usize> {
let mut total_len = writer.write(&[self.can_remove_quest as u8])?;
total_len += QuestInfo::dump_many(writer, &self.player_quests)?;
total_len += QuestInfo::dump_many(writer, &self.completed_quests)?;
Ok(total_len)
}
}
pub struct QuestInfo {
pub id: String,
pub name: String,
pub description: String,
pub xp: i32,
pub premium_xp: i32,
pub robits: i32,
pub premium_robits: i32,
pub progress_count: i32,
pub target_count: i32,
pub seen: bool,
}
impl QuestInfo {
fn dump(&self, writer: &mut dyn Write) -> std::io::Result<usize> {
let mut total_len = super::write_str_for_binreader(&self.id, writer)?;
total_len += super::write_str_for_binreader(&self.name, writer)?;
total_len += super::write_str_for_binreader(&self.description, writer)?;
total_len += writer.write(&self.xp.to_le_bytes())?;
total_len += writer.write(&self.premium_xp.to_le_bytes())?;
total_len += writer.write(&self.robits.to_le_bytes())?;
total_len += writer.write(&self.premium_robits.to_le_bytes())?;
total_len += writer.write(&self.progress_count.to_le_bytes())?;
total_len += writer.write(&self.target_count.to_le_bytes())?;
total_len += writer.write(&[self.seen as u8])?;
Ok(total_len)
}
fn dump_many(writer: &mut dyn Write, quests: &[QuestInfo]) -> std::io::Result<usize> {
let mut total_len = writer.write(&(quests.len() as i16).to_le_bytes())?;
for quest in quests.iter() {
total_len += quest.dump(writer)?;
}
Ok(total_len)
}
}

View File

@@ -0,0 +1,23 @@
use polariton::operation::Typed;
pub struct PrebuiltRobotInfo {
//pub id: String,
pub name: String,
pub class: String,
pub category: String,
pub robot_data: Vec<u8>,
pub colour_data: Vec<u8>,
}
impl PrebuiltRobotInfo {
pub fn as_transmissible(&self) -> Typed {
Typed::HashMap(vec![
//(Typed::Str("[key]".into()), Typed::Str(self.id.clone().into())),
(Typed::Str("Name".into()), Typed::Str(self.name.clone().into())),
(Typed::Str("Class".into()), Typed::Str(self.class.clone().into())),
(Typed::Str("Category".into()), Typed::Str(self.category.clone().into())),
(Typed::Str("RobotData".into()), Typed::Bytes(self.robot_data.clone().into())),
(Typed::Str("ColourData".into()), Typed::Bytes(self.colour_data.clone().into())),
].into())
}
}

View File

@@ -210,4 +210,8 @@ impl ItemCategory {
ItemCategory::EnergyModule => "EnergyModule", ItemCategory::EnergyModule => "EnergyModule",
} }
} }
pub fn but_bigger(&self) -> i32 {
(*self as i32) * 100_000
}
} }

View File

@@ -0,0 +1,29 @@
use polariton::operation::{Typed, Dict};
use super::{cube_list::ItemTier, weapon_list::ItemCategory};
pub struct WeaponUpgradeInfo {
pub tier: ItemTier,
pub type_: ItemCategory,
pub xp: f64,
pub rating: i32,
pub rank: i32,
pub power: i32,
}
impl WeaponUpgradeInfo {
pub fn as_transmissible(&self) -> Typed {
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("weaponSize".into()), Typed::Int(self.tier as _)),
(Typed::Str("weaponType".into()), Typed::Int(self.type_ as _)),
(Typed::Str("weaponXp".into()), Typed::Double(self.xp)),
(Typed::Str("weaponRating".into()), Typed::Int(self.rating)),
(Typed::Str("weaponRank".into()), Typed::Int(self.rank)),
(Typed::Str("weaponPower".into()), Typed::Int(self.power)),
],
})
}
}

View File

@@ -0,0 +1,14 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const TEST_PARAM_KEY: u8 = 166;
const TEST_GROUP_PARAM_KEY: u8 = 167;
pub(super) fn test_group_provider() -> SimpleFunc<55, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(TEST_PARAM_KEY, Typed::Str("RE_AB_test".into()));
params.insert(TEST_GROUP_PARAM_KEY, Typed::Str("RE_AB_test_group".into()));
Ok(params.into())
})
}

View File

@@ -19,9 +19,9 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
ty: 104, // hashtable ty: 104, // hashtable
items: vec![ items: vec![
CustomisationData { CustomisationData {
id: "skin0".to_string(), id: "RC_MothershipSkin_Neptune_01".to_string(),
localised_name: "Default".to_string(), localised_name: "Neptune 01".to_string(),
skin_scene_name: "TODO_skin".to_string(), skin_scene_name: "RC_MothershipSkin_Neptune_01".to_string(),
simulation_prefab: "TODO_sim_prefab".to_string(), simulation_prefab: "TODO_sim_prefab".to_string(),
preview_image_name: "TODO_preview_img".to_string(), preview_image_name: "TODO_preview_img".to_string(),
is_default: true, is_default: true,

View File

@@ -0,0 +1,16 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PROGRESS_PARAM_KEY: u8 = 199;
const LEVEL_PARAM_KEY: u8 = 81;
const GAINED_XP_PARAM_KEY: u8 = 205;
pub(super) fn building_xp_save_provider() -> SimpleFunc<170, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PROGRESS_PARAM_KEY, Typed::Float(1.0));
params.insert(LEVEL_PARAM_KEY, Typed::Int(31337));
params.insert(GAINED_XP_PARAM_KEY, Typed::Int(0));
Ok(params.into())
})
}

View File

@@ -0,0 +1,21 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
const PARAM_KEY: u8 = 79;
pub(super) fn building_xp_config_provider() -> SimpleFunc<199, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 104, // hashtable
items: vec![
(Typed::Str("BuildXPSettings".into()), Typed::HashMap(vec![
(Typed::Str("buildModePeriodUserEarnXP".into()), Typed::Float(1.0)), // TODO what are the time units?
(Typed::Str("buildModePeriodUserInactivity".into()), Typed::Float(2.0)),
].into())),
],
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,14 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 17;
pub(super) fn chat_settings_provider() -> SimpleFunc<18, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("chatEnabled".into()), Typed::Bool(true.into())),
].into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,15 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 100;
pub(super) fn robot_shop_submission_infos_provider() -> SimpleFunc<95, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("submissionCount".into()), Typed::Int(0)),
(Typed::Str("maxSubmissions".into()), Typed::Int(10)),
].into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,15 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Arr};
const PARAM_KEY: u8 = 216;
pub(super) fn cube_awards_provider() -> SimpleFunc<206, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Arr(Arr {
ty: 115, // str
items: Vec::default(),
}));
Ok(params.into())
})
}

View File

@@ -6,7 +6,7 @@ use polariton::operation::{ParameterTable, Typed, Dict};
use crate::data::cube_list::*; use crate::data::cube_list::*;
const PARAM_KEY: u8 = 1; const PARAM_KEY: u8 = 1;
// const DEFAULT_CUBE_ID: u32 = 227205318; const DEFAULT_CUBE_ID: u32 = 227205318;
pub(super) fn cube_list_provider() -> SimpleFunc<2, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> { pub(super) fn cube_list_provider() -> SimpleFunc<2, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| { SimpleFunc::new(|params, _| {
@@ -16,7 +16,7 @@ pub(super) fn cube_list_provider() -> SimpleFunc<2, crate::UserTy, impl (Fn(Para
val_ty: 104, // hashtable val_ty: 104, // hashtable
items: vec![ items: vec![
//(u32 in base16 aka hex, hashtable) //(u32 in base16 aka hex, hashtable)
(Typed::Str("DEADBEEF".into()), CubeInfo { CubeInfo {
cpu: 1, cpu: 1,
health: 1, health: 1,
health_boost: 1.0, health_boost: 1.0,
@@ -36,7 +36,7 @@ pub(super) fn cube_list_provider() -> SimpleFunc<2, crate::UserTy, impl (Fn(Para
cosmetic: false, cosmetic: false,
variant_of: "0".to_string(), variant_of: "0".to_string(),
ignore_in_weapon_list: true, ignore_in_weapon_list: true,
}.as_transmissible()), }.as_transmissible_key_val(DEFAULT_CUBE_ID),
CubeInfo { CubeInfo {
cpu: 1, cpu: 1,
health: 1, health: 1,

View File

@@ -0,0 +1,15 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
use crate::data::custom_games::*;
const PARAM_KEY: u8 = 168;
//const INVITE_PARAM_KEY: u8 = 189; // hashtable (refer to C# CheckIfHasBeenInvitedToCustomGameSessionRequest)
pub(super) fn pending_invite_provider() -> SimpleFunc<0, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Int(CustomGameInviteCode::NoInvite as _));
Ok(params.into())
})
}

View File

@@ -0,0 +1,25 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
use crate::data::custom_games::*;
const PARAM_KEY: u8 = 168;
pub(super) fn team_setup_provider() -> SimpleFunc<162, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 105, // int
items: vec![
(Typed::Str(GameMode::BattleArena.as_str().into()), Typed::Int(10)),
(Typed::Str(GameMode::SuddenDeath.as_str().into()), Typed::Int(10)),
(Typed::Str(GameMode::Pit.as_str().into()), Typed::Int(10)),
(Typed::Str(GameMode::TestMode.as_str().into()), Typed::Int(10)),
(Typed::Str(GameMode::SinglePlayer.as_str().into()), Typed::Int(1)),
(Typed::Str(GameMode::TeamDeathmatch.as_str().into()), Typed::Int(10)),
(Typed::Str(GameMode::Campaign.as_str().into()), Typed::Int(6)),
] }));
Ok(params.into())
})
}

View File

@@ -0,0 +1,31 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::ParameterTable;
use crate::data::quest::*;
const PARAM_KEY: u8 = 155; // int
pub(super) fn player_daily_quests_provider() -> SimpleFunc<13, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, DailyQuestsInfo {
can_remove_quest: true,
player_quests: vec![
QuestInfo {
id: "RE_quest_id0".to_owned(),
name: "RE_quest_name0".to_owned(),
description: "RE_quest_description0".to_owned(),
xp: 1_000,
premium_xp: 2_000,
robits: 1_000,
premium_robits: 1_000,
progress_count: 1,
target_count: 3,
seen: true,
}
],
completed_quests: Vec::default(),
}.as_transmissible());
Ok(params.into())
})
}

View File

@@ -2,6 +2,7 @@ use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict}; use polariton::operation::{ParameterTable, Typed, Dict};
use crate::data::garage_bay::*; use crate::data::garage_bay::*;
use crate::data::weapon_list::ItemCategory;
const SLOTS_PARAM_KEY: u8 = 44; const SLOTS_PARAM_KEY: u8 = 44;
const SELECTED_SLOT_PARAM_KEY: u8 = 43; const SELECTED_SLOT_PARAM_KEY: u8 = 43;
@@ -15,11 +16,11 @@ pub(super) fn garage_slot_provider() -> SimpleFunc<40, crate::UserTy, impl (Fn(P
val_ty: 104, // hashmap val_ty: 104, // hashmap
items: vec![ items: vec![
(Typed::Int(0), GarageSlotInfo { (Typed::Int(0), GarageSlotInfo {
name: "Reverse-engineer great success!".to_owned(), name: "Reverse-engineer great success! slot_name".to_owned(),
cubes: 1, cubes: 1,
crf_id: 0, crf_id: 0,
was_rated: false, was_rated: false,
movement_categories: vec![MovementCategory::Wheel], movement_categories: vec![ItemCategory::Wheel],
uuid: (2,4), uuid: (2,4),
thumbnail_version: 0, thumbnail_version: 0,
total_robot_cpu: 1, total_robot_cpu: 1,

View File

@@ -8,8 +8,8 @@ pub(super) fn garage_upgrades_provider() -> SimpleFunc<1, crate::UserTy, impl (F
let mut params = params.to_dict(); let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::HashMap(vec![ params.insert(PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("cpuIncreaseCost".into()), Typed::Dict(Dict { (Typed::Str("cpuIncreaseCost".into()), Typed::Dict(Dict {
key_ty: 110, // int key_ty: 105, // int
val_ty: 110, // int val_ty: 105, // int
items: vec![ items: vec![
// (CPU limit, upgrade cost) // (CPU limit, upgrade cost)
(Typed::Int(100), Typed::Int(100)), (Typed::Int(100), Typed::Int(100)),

View File

@@ -0,0 +1,14 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
// const CAMPAIGN_ID_PARAM_KEY: u8 = 22; // str
// const DIFFICULTY_PARAM_KEY: u8 = 22; // int
const AVAILABLE_PARAM_KEY: u8 = 89; // bool
pub(super) fn completed_campaign_provider() -> SimpleFunc<77, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(AVAILABLE_PARAM_KEY, Typed::Bool(false.into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,19 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
const PARAM_KEY: u8 = 1;
pub(super) fn league_battle_parameters_provider() -> SimpleFunc<57, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Dict(Dict {
key_ty: 115, //str
val_ty: 42, // obj
items: vec![
(Typed::Str("playerLevelRequired".into()), Typed::Int(10)),
(Typed::Str("minCpu".into()), Typed::Int(100)),
],
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,33 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
use crate::data::weapon_list::ItemCategory;
use crate::data::garage_bay::*;
const SLOT_PARAM_KEY: u8 = 45; // uint
const DATA_PARAM_KEY: u8 = 49; // byte arr
const CUBES_COUNT_PARAM_KEY: u8 = 51; // int
const WEAPON_ORDER_PARAM_KEY: u8 = 52; // int arr
const MOVEMENT_CATEGORIES_PARAM_KEY: u8 = 56; // int arr
const CONTROL_TYPE_PARAM_KEY: u8 = 59; // int
const CONTROL_OPTIONS_PARAM_KEY: u8 = 60; // bool arr
const MASTERY_LEVEL_PARAM_KEY: u8 = 18; // int
pub(super) fn garage_machine_provider() -> SimpleFunc<43, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
if let Some(garage_slot) = params.get(&SLOT_PARAM_KEY) {
log::debug!("Got machine request for slot {:?}", garage_slot);
} else {
params.insert(SLOT_PARAM_KEY, Typed::Int(0));
}
params.insert(DATA_PARAM_KEY, Typed::Bytes(vec![0u8, 0u8, 0u8, 0u8].into())); // first 4 bytes are i32 for length of rest of data
params.insert(CUBES_COUNT_PARAM_KEY, Typed::Int(1));
params.insert(WEAPON_ORDER_PARAM_KEY, Typed::IntArr(vec![0].into()));
params.insert(MOVEMENT_CATEGORIES_PARAM_KEY, Typed::IntArr(vec![ItemCategory::Wheel.but_bigger()].into()));
params.insert(CONTROL_TYPE_PARAM_KEY, Typed::Int(ControlType::Camera as _));
params.insert(CONTROL_OPTIONS_PARAM_KEY, ControlOptions { vertical_strafing: false, sideways_driving: false, tracks_turn_on_spot: false, }.as_transmissible());
params.insert(MASTERY_LEVEL_PARAM_KEY, Typed::Int(0));
Ok(params.into())
})
}

View File

@@ -0,0 +1,19 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
// const USERNAME_PARAM_KEY: u8 = 30; // str
const SLOT_PARAM_KEY: u8 = 31; // int
const DATA_PARAM_KEY: u8 = 33; // byte arr
pub(super) fn garage_machine_colour_provider() -> SimpleFunc<33, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
if let Some(garage_slot) = params.get(&SLOT_PARAM_KEY) {
log::debug!("Got machine colour request for slot {:?}", garage_slot);
} else {
params.insert(SLOT_PARAM_KEY, Typed::Int(0));
}
params.insert(DATA_PARAM_KEY, Typed::Bytes(vec![0u8, 0u8, 0u8, 0u8].into())); // first 4 bytes are i32 for length of rest of data
Ok(params.into())
})
}

View File

@@ -43,6 +43,34 @@ mod game_event_params;
mod garage_bay_uuid; mod garage_bay_uuid;
mod tech_tree_data; mod tech_tree_data;
mod item_shop_bundles; mod item_shop_bundles;
mod robot_customisations;
mod player_data;
mod player_robopass;
mod weapon_upgrades;
mod player_rank;
mod ab_test_group;
mod league_limits;
mod crf_limits;
mod robot_mastery_settings;
mod player_started_purchase;
mod custom_games_team;
mod custom_games_invite;
mod chat_settings;
mod prebuilt_robots;
mod prebuilt_colours;
mod robopass_preview_items;
mod singleplayer_campaigns;
mod purchases;
mod building_xp_config;
mod weapon_rating_static;
mod weapon_xp_static;
mod machine;
mod machine_colour;
mod last_completed_campaign;
mod daily_quests;
mod cube_awards;
mod robot_sanction;
mod building_xp;
use polariton_server::operations::OperationsHandler; use polariton_server::operations::OperationsHandler;
@@ -95,5 +123,37 @@ pub fn handler() -> OperationsHandler<crate::UserTy> {
.without_state(garage_bay_uuid::garage_id_provider()) .without_state(garage_bay_uuid::garage_id_provider())
.without_state(tech_tree_data::tech_tree_layout_provider()) .without_state(tech_tree_data::tech_tree_layout_provider())
.without_state(item_shop_bundles::item_bundle_provider()) .without_state(item_shop_bundles::item_bundle_provider())
.without_state(robot_customisations::bay_customisations_provider())
.without_state(player_data::player_data_provider())
.without_state(player_robopass::player_robopass_season_provider())
.without_state(weapon_upgrades::weapons_upgrade_provider())
.without_state(polariton_server::operations::Ack::<172, _>::default()) // custom game change robot tier (param 67 is tier)
.without_state(player_rank::rank_provider())
.without_state(player_rank::rank_static_provider())
.without_state(ab_test_group::test_group_provider())
.without_state(league_limits::league_battle_parameters_provider())
.without_state(crf_limits::robot_shop_submission_infos_provider())
.without_state(robot_mastery_settings::robot_mastery_settings_provider())
.without_state(player_started_purchase::started_purchase_provider())
.without_state(custom_games_team::team_setup_provider())
.without_state(polariton_server::operations::Ack::<152, _>::default()) // custom game player state changed (188 is desired state)
.without_state(custom_games_invite::pending_invite_provider())
.without_state(chat_settings::chat_settings_provider())
.without_state(prebuilt_robots::garage_robot_data_provider())
.without_state(prebuilt_colours::garage_colour_combo_provider())
.without_state(robopass_preview_items::robopass_preview_provider())
.without_state(singleplayer_campaigns::singleplayer_campaigns_provider())
.without_state(purchases::pending_purchases_provider())
.without_state(building_xp_config::building_xp_config_provider())
.without_state(weapon_rating_static::weapon_rating_provider())
.without_state(weapon_xp_static::weapon_xp_provider())
.without_state(machine::garage_machine_provider())
.without_state(machine_colour::garage_machine_colour_provider())
.without_state(last_completed_campaign::completed_campaign_provider())
.without_state(daily_quests::player_daily_quests_provider())
.without_state(tech_points::tech_points_awards_provider())
.without_state(cube_awards::cube_awards_provider())
.without_state(robot_sanction::robot_sanction_provider())
.without_state(building_xp::building_xp_save_provider())
//.without_state(polariton_server::operations::Ack::<70, _>::default()) //.without_state(polariton_server::operations::Ack::<70, _>::default())
} }

View File

@@ -0,0 +1,38 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Arr};
use crate::data::{garage_bay::*, weapon_list::ItemCategory};
const GARAGE_SLOT_KEY: u8 = 45;
const NAME_KEY: u8 = 42;
const CRF_ID_KEY: u8 = 35;
const ROBOT_CPU_KEY: u8 = 177;
const CONTROL_TYPE_KEY: u8 = 59;
const CONTROL_OPTIONS_KEY: u8 = 60;
const WEAPON_ORDER_KEY: u8 = 52;
const ITEM_CATEGORY_KEY: u8 = 56;
pub(super) fn player_data_provider() -> SimpleFunc<61, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(GARAGE_SLOT_KEY, Typed::Int(0));
params.insert(NAME_KEY, Typed::Str("Reverse-engineer great success!".into()));
params.insert(CRF_ID_KEY, Typed::Int(0));
params.insert(ROBOT_CPU_KEY, Typed::Int(1));
params.insert(CONTROL_TYPE_KEY, Typed::Int(ControlType::Camera as _));
params.insert(CONTROL_OPTIONS_KEY, ControlOptions { vertical_strafing: false, sideways_driving: false, tracks_turn_on_spot: false, }.as_transmissible());
params.insert(WEAPON_ORDER_KEY, Typed::Arr(Arr {
ty: 105, // int
items: vec![
Typed::Int(0),
],
}));
params.insert(ITEM_CATEGORY_KEY, Typed::Arr(Arr {
ty: 105, // int
items: vec![
Typed::Int(ItemCategory::Wheel.but_bigger()),
],
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,26 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
use crate::data::player_rank::*;
const PARAM_KEY: u8 = 80;
pub(super) fn rank_provider() -> SimpleFunc<80, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Int(3));
Ok(params.into())
})
}
const STATIC_PARAM_KEY: u8 = 1;
pub(super) fn rank_static_provider() -> SimpleFunc<126, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(STATIC_PARAM_KEY, PlayerRankStaticInfo {
sub_rank_thresholds: vec![1, 2, 3, 4, 5],
}.as_transmissible());
Ok(params.into())
})
}

View File

@@ -0,0 +1,20 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::ParameterTable;
use crate::data::player_robopass_season::*;
const PARAM_KEY: u8 = 237;
pub(super) fn player_robopass_season_provider() -> SimpleFunc<178, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, PlayerRoboPassSeasonInfo {
delta_xp_to_show: 42,
grade: 1,
has_deluxe: true,
progress_in_grade: 0.5,
xp_from_start: 12345,
}.as_transmissible());
Ok(params.into())
})
}

View File

@@ -0,0 +1,12 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 135;
pub(super) fn started_purchase_provider() -> SimpleFunc<54, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Bool(false.into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,12 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 1;
pub(super) fn garage_colour_combo_provider() -> SimpleFunc<37, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Str("[[0,1,2,3]]".into())); // why tf is this a JSON in a string??? (list of lists of bytes)
Ok(params.into())
})
}

View File

@@ -0,0 +1,26 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
use crate::data::robot_data::*;
const PARAM_KEY: u8 = 1;
pub(super) fn garage_robot_data_provider() -> SimpleFunc<4, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 104, // hashmap
items: vec![
(Typed::Str(format!("{}_{}", 12345, 54321).into()), PrebuiltRobotInfo {
name: "Reverse-engineer great success! prebuilt_name".to_owned(),
class: "RE_robot_class0".to_owned(),
category: "RE_robot_category0".to_owned(),
robot_data: vec![0u8, 0u8, 0u8, 0u8], // first 4 bytes are i32 for the cube count (we want it to be 0)
colour_data: vec![0u8, 0u8, 0u8, 0u8],
}.as_transmissible()),
]
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,17 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
const PARAM_KEY: u8 = 88;
pub(super) fn pending_purchases_provider() -> SimpleFunc<81, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
// TODO implement purchases system
params.insert(PARAM_KEY, Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 104, // hashtable
items: vec![],
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,16 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
const PARAM_KEY: u8 = 1;
pub(super) fn robopass_preview_provider() -> SimpleFunc<167, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 104, // hashtable
items: vec![],
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,17 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
//const BAY_ID_KEY: u8 = 54; // in
const BAY_SKIN_KEY: u8 = 234;
const SPAWN_EFFECT_KEY: u8 = 235;
const DEATH_EFFECT_KEY: u8 = 236;
pub(super) fn bay_customisations_provider() -> SimpleFunc<218, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(BAY_SKIN_KEY, Typed::Str("RC_MothershipSkin_Neptune_01".into()));
params.insert(SPAWN_EFFECT_KEY, Typed::Str("RE_todo_spawn_effect".into()));
params.insert(DEATH_EFFECT_KEY, Typed::Str("RE_todo_death_effect".into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,14 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 193;
pub(super) fn robot_mastery_settings_provider() -> SimpleFunc<73, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("RobitsRewardForCRFRobotCreator".into()), Typed::Int(1_000)),
].into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,19 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Arr};
const ROBOT_ID_PARAM_KEY: u8 = 54; // str (in)
const SANCTION_JSONS_PARAM_KEY: u8 = 102; // str arr (out; list of jsons)
pub(super) fn robot_sanction_provider() -> SimpleFunc<174, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
if let Some(Typed::Str(s)) = params.get(&ROBOT_ID_PARAM_KEY) {
log::debug!("Got sanction check for robot {}", s.string);
}
params.insert(SANCTION_JSONS_PARAM_KEY, Typed::Arr(Arr {
ty: 115, // str
items: Vec::default(),
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,22 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const CAMPAIGNS_BYTES_PARAM_KEY: u8 = 64; // list of bytes (serialised data)
const CAMPAIGNS_WAVES_PARAM_KEY: u8 = 70; // hashtable
const CAMPAIGNS_VERSIONS_PARAM_KEY: u8 = 69; // hashtable
pub(super) fn singleplayer_campaigns_provider() -> SimpleFunc<65, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
// TODO implement serialisation of Campaign[] properly
params.insert(CAMPAIGNS_BYTES_PARAM_KEY, Typed::Bytes(vec![0u8, 0u8, 0u8, 0u8].into())); // first 4 bytes are i32 for length of the rest
params.insert(CAMPAIGNS_WAVES_PARAM_KEY, Typed::HashMap(vec![].into()));
params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("CurrentVersionNumber".into()), Typed::Int(0)),
(Typed::Str("LockedCampaignsInfo".into()), Typed::HashMap(vec![
(Typed::Str("0".into()), Typed::Bool(false.into()))
].into())),
].into()));
Ok(params.into())
})
}

View File

@@ -1,12 +1,22 @@
use polariton_server::operations::SimpleFunc; use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed}; use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 214; const CURRENT_PARAM_KEY: u8 = 214;
pub(super) fn tech_points_provider() -> SimpleFunc<187, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> { pub(super) fn tech_points_provider() -> SimpleFunc<187, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| { SimpleFunc::new(|params, _| {
let mut params = params.to_dict(); let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Int(1337)); params.insert(CURRENT_PARAM_KEY, Typed::Int(1337));
Ok(params.into())
})
}
const UNCLAIMED_PARAM_KEY: u8 = 212;
pub(super) fn tech_points_awards_provider() -> SimpleFunc<185, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(UNCLAIMED_PARAM_KEY, Typed::Int(0));
Ok(params.into()) Ok(params.into())
}) })
} }

View File

@@ -0,0 +1,33 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
const PARAM_KEY: u8 = 1;
pub(super) fn weapon_rating_provider() -> SimpleFunc<127, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("subRankCount".into()), Typed::Int(2)),
(Typed::Str("subRankInterval".into()), Typed::Int(10)),
(Typed::Str("gainsPerRank".into()), Typed::ObjArr(vec![
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("win".into()), Typed::Int(7)),
(Typed::Str("loss".into()), Typed::Int(3)),
],
}),
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("win".into()), Typed::Int(11)),
(Typed::Str("loss".into()), Typed::Int(3)),
],
})
].into())),
].into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,23 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
use crate::data::weapon_upgrade::*;
const PARAM_KEY: u8 = 38;
pub(super) fn weapons_upgrade_provider() -> SimpleFunc<82, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::ObjArr(vec![
WeaponUpgradeInfo {
tier: crate::data::cube_list::ItemTier::T0,
type_: crate::data::weapon_list::ItemCategory::Laser,
xp: 4.2,
rating: 1,
rank: 1,
power: 1,
}.as_transmissible(),
].into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,42 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Dict};
use crate::data::cube_list::ItemTier;
const PARAM_KEY: u8 = 1;
pub(super) fn weapon_xp_provider() -> SimpleFunc<129, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::HashMap(vec![
(Typed::Str("maxPower".into()), Typed::Int(2)),
(Typed::Str("powerLevelsPerTier".into()), Typed::Dict(Dict {
key_ty: 105, // int
val_ty: 122, // obj arr
items: vec![
(Typed::Int(ItemTier::T0 as _), Typed::ObjArr(vec![
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("xp".into()), Typed::Int(1_000)),
(Typed::Str("costRobits".into()), Typed::Int(1_000)),
(Typed::Str("damageMultiplier".into()), Typed::Float(1.1)),
],
}),
Typed::Dict(Dict {
key_ty: 115, // str
val_ty: 42, // obj
items: vec![
(Typed::Str("xp".into()), Typed::Int(2_000)),
(Typed::Str("costRobits".into()), Typed::Int(2_000)),
(Typed::Str("damageMultiplier".into()), Typed::Float(1.2)),
],
}),
].into())),
],
})),
].into()));
Ok(params.into())
})
}

View File

@@ -50,3 +50,21 @@ pub enum ClanType {
Open = 1, Open = 1,
Closed = 2, Closed = 2,
} }
pub struct ClanInfo {
pub clan_name: String,
pub clan_description: String,
pub clan_type: ClanType,
pub clan_size: i32,
}
impl ClanInfo {
pub fn as_transmissible(&self) -> Typed {
Typed::HashMap(vec![
(Typed::Str("clanName".into()), Typed::Str(self.clan_name.clone().into())),
(Typed::Str("clanDescription".into()), Typed::Str(self.clan_description.clone().into())),
(Typed::Str("clanType".into()), Typed::Int(self.clan_type as i32)),
(Typed::Str("clanSize".into()), Typed::Int(self.clan_size)),
].into())
}
}

View File

@@ -3,6 +3,10 @@ mod friend_list;
mod settings; mod settings;
mod clan_invite; mod clan_invite;
mod clan_info; mod clan_info;
mod search_clan;
mod season_rewards;
mod previous_battle_rewards;
mod platoon_data;
use polariton_server::operations::OperationsHandler; use polariton_server::operations::OperationsHandler;
@@ -16,4 +20,9 @@ pub fn handler() -> OperationsHandler<crate::UserTy> {
.without_state(clan_invite::clan_invites_provider()) .without_state(clan_invite::clan_invites_provider())
.without_state(polariton_server::operations::Ack::<19, _>::default()) // get pending platoon invite (this is equivalent to having no pending invite) .without_state(polariton_server::operations::Ack::<19, _>::default()) // get pending platoon invite (this is equivalent to having no pending invite)
.without_state(clan_info::clan_info_provider()) .without_state(clan_info::clan_info_provider())
.without_state(search_clan::search_clans_provider())
.without_state(polariton_server::operations::Ack::<52, _>::default()) // validate pending season rewards (this just always needs to be ack-ed)
.without_state(season_rewards::season_rewards_provider())
.without_state(previous_battle_rewards::pending_battle_rewards_provider())
.without_state(platoon_data::platoon_provider())
} }

View File

@@ -0,0 +1,15 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::ParameterTable;
//const PLATOON_ID_PARAM_KEY: u8 = 16;
//const PLATOON_LEADER_PARAM_KEY: u8 = 17;
//const USER_LIST_PARAM_KEY: u8 = 7;
pub(super) fn platoon_provider() -> SimpleFunc<18, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
//let mut params = params.to_dict();
// if platoon ID is not provided, you're not in a platoon
//Ok(params.into())
Ok(params)
})
}

View File

@@ -0,0 +1,13 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const PARAM_KEY: u8 = 60;
//const USER_PARAM_KEY: u8 = 1; // str (username)
pub(super) fn pending_battle_rewards_provider() -> SimpleFunc<54, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(PARAM_KEY, Typed::Bool(false.into()));
Ok(params.into())
})
}

View File

@@ -0,0 +1,37 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed, Arr};
use crate::data::clan::*;
// params in TODO
const STRING_PARAM_KEY: u8 = 39;
/*const DAYS_SINCE_ACTIVE_PARAM_KEY: u8 = 40;
const START_RANGE_PARAM_KEY: u8 = 41;
const END_RANGE_PARAM_KEY: u8 = 43;
const TYPES_PARAM_KEY: u8 = 34;*/
// params out
const RESULTS_PARAM_KEY: u8 = 42;
pub(super) fn search_clans_provider() -> SimpleFunc<32, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
if let Some(Typed::Str(s)) = params.get(&STRING_PARAM_KEY) {
if !s.string.is_empty() {
log::debug!("Got clan search string `{}`", s.string);
}
}
params.insert(RESULTS_PARAM_KEY, Typed::Arr(Arr {
ty: 104, // hashmap
items: vec![
ClanInfo {
clan_name: "".to_owned(),
clan_description: "".to_owned(),
clan_type: ClanType::Closed,
clan_size: 1,
}.as_transmissible(),
],
}));
Ok(params.into())
})
}

View File

@@ -0,0 +1,26 @@
use polariton_server::operations::SimpleFunc;
use polariton::operation::{ParameterTable, Typed};
const MONTH_PARAM_KEY: u8 = 49;
const YEAR_PARAM_KEY: u8 = 63;
const ROBITS_PARAM_KEY: u8 = 47;
const IS_CLAIMED_PARAM_KEY: u8 = 46;
const CLAN_AVERAGE_PARAM_KEY: u8 = 54;
const CLAN_TOTAL_PARAM_KEY: u8 = 55;
const CLAN_NAME_PARAM_KEY: u8 = 31;
const PLAYER_XP_PARAM_KEY: u8 = 57;
pub(super) fn season_rewards_provider() -> SimpleFunc<50, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
SimpleFunc::new(|params, _| {
let mut params = params.to_dict();
params.insert(MONTH_PARAM_KEY, Typed::Int(02));
params.insert(YEAR_PARAM_KEY, Typed::Int(2025));
params.insert(ROBITS_PARAM_KEY, Typed::Int(42));
params.insert(IS_CLAIMED_PARAM_KEY, Typed::Bool(true.into()));
params.insert(CLAN_AVERAGE_PARAM_KEY, Typed::Int(67));
params.insert(CLAN_TOTAL_PARAM_KEY, Typed::Int(42_123));
params.insert(CLAN_NAME_PARAM_KEY, Typed::Str("RE_clan_name_rewards".into()));
params.insert(PLAYER_XP_PARAM_KEY, Typed::Int(10_000));
Ok(params.into())
})
}