mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Add social server and implement all op codes up until chat room connection blocks further requests
This commit is contained in:
33
rc_services_room/src/data/custom_games.rs
Normal file
33
rc_services_room/src/data/custom_games.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum GameMode {
|
||||
BattleArena = 0,
|
||||
SuddenDeath = 1,
|
||||
Pit = 2,
|
||||
TestMode = 3,
|
||||
SinglePlayer = 4,
|
||||
TeamDeathmatch = 5,
|
||||
Campaign = 6,
|
||||
}
|
||||
|
||||
impl GameMode {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
GameMode::BattleArena => "BattleArena",
|
||||
GameMode::SuddenDeath => "SuddenDeath",
|
||||
GameMode::Pit => "Pit",
|
||||
GameMode::TestMode => "TestMode",
|
||||
GameMode::SinglePlayer => "SinglePlayerTDM",
|
||||
GameMode::TeamDeathmatch => "TeamDeathmatch",
|
||||
GameMode::Campaign => "Campaign",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
pub enum MapVisibility {
|
||||
Good = 0,
|
||||
Poor = 1,
|
||||
Bad = 2, // VeryPoor
|
||||
}
|
||||
93
rc_services_room/src/data/garage_bay.rs
Normal file
93
rc_services_room/src/data/garage_bay.rs
Normal file
@@ -0,0 +1,93 @@
|
||||
use polariton::operation::{Typed, Arr};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[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 name: String,
|
||||
pub cubes: u32,
|
||||
pub crf_id: u32, // 0 means not uploaded
|
||||
pub was_rated: bool, // ignored when not on CRF
|
||||
pub movement_categories: Vec<MovementCategory>,
|
||||
pub uuid: (u32, u32),
|
||||
pub thumbnail_version: u32,
|
||||
pub total_robot_cpu: u32,
|
||||
pub total_cosmetic_cpu: u32,
|
||||
pub total_robot_ranking: u32,
|
||||
pub bay_cpu: u32,
|
||||
pub tutorial_robot: bool, // assumed to be false (when omitted)
|
||||
pub starter_robot_index: i32, // assumed to be -1 (whem omitted)
|
||||
pub control_type: i32, // enum???
|
||||
pub control_options: Vec<bool>,
|
||||
pub mastery_level: i32,
|
||||
pub bay_skin_id: String,
|
||||
pub weapon_order: Vec<i32>,
|
||||
}
|
||||
|
||||
impl GarageSlotInfo {
|
||||
pub fn as_transmissible(&self) -> Typed {
|
||||
Typed::HashMap(vec![
|
||||
(Typed::Str("name".into()), Typed::Str(self.name.clone().into())),
|
||||
(Typed::Str("numberCubes".into()), Typed::Int(self.cubes as i32)),
|
||||
(Typed::Str("crfId".into()), Typed::Int(self.crf_id as i32)),
|
||||
(Typed::Str("wasRated".into()), Typed::Bool(self.was_rated.into())),
|
||||
(Typed::Str("movementCategories".into()), Typed::Arr(Arr {
|
||||
ty: 105, // int
|
||||
items: self.movement_categories.iter().map(|x| Typed::Int((*x as i32) * 100_000)).collect(),
|
||||
})),
|
||||
(Typed::Str("uniqueId1".into()), Typed::Int(self.uuid.0 as i32)),
|
||||
(Typed::Str("uniqueId2".into()), Typed::Int(self.uuid.1 as i32)),
|
||||
(Typed::Str("thumbnailVersion".into()), Typed::Int(self.thumbnail_version as i32)),
|
||||
(Typed::Str("totalRobotCPU".into()), Typed::Int(self.total_robot_cpu as i32)),
|
||||
(Typed::Str("totalCosmeticCPU".into()), Typed::Int(self.total_cosmetic_cpu as i32)),
|
||||
(Typed::Str("totalRobotRanking".into()), Typed::Int(self.total_robot_ranking as i32)),
|
||||
(Typed::Str("bayCpu".into()), Typed::Int(self.bay_cpu as i32)),
|
||||
(Typed::Str("tutorialRobot".into()), Typed::Bool(self.tutorial_robot.into())),
|
||||
(Typed::Str("starterRobotIndex".into()), Typed::Int(self.starter_robot_index)),
|
||||
(Typed::Str("controlType".into()), Typed::Int(self.control_type)),
|
||||
(Typed::Str("controlOptions".into()), Typed::Arr(Arr {
|
||||
ty: 111, // bool
|
||||
items: self.control_options.iter().map(|&x| Typed::Bool(x.into())).collect(),
|
||||
})),
|
||||
(Typed::Str("masteryLevel".into()), Typed::Int(self.mastery_level)),
|
||||
(Typed::Str("baySkinId".into()), Typed::Str(self.bay_skin_id.clone().into())),
|
||||
(Typed::Str("weaponOrder".into()), Typed::Arr(Arr {
|
||||
ty: 105, // int
|
||||
items: self.weapon_order.iter().map(|x| Typed::Int(*x)).collect(),
|
||||
})),
|
||||
].into())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
124
rc_services_room/src/data/item_shop_bundle.rs
Normal file
124
rc_services_room/src/data/item_shop_bundle.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use polariton::operation::Typed;
|
||||
|
||||
pub struct ItemShopBundle {
|
||||
pub sku: String,
|
||||
pub bundle_name_key: String,
|
||||
pub sprite: String,
|
||||
pub is_sprite_full_size: bool,
|
||||
pub category: ItemShopCategory,
|
||||
pub currency: CurrencyType, // str
|
||||
pub price: i32,
|
||||
pub discount_time: i64, // seconds since unix epoch
|
||||
pub discount_price: i32,
|
||||
pub recurrence: ItemShopRecurrence,
|
||||
pub owns_required_cube: bool,
|
||||
//pub is_discounted: bool,
|
||||
pub is_limited_edition: bool,
|
||||
}
|
||||
|
||||
impl ItemShopBundle {
|
||||
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 sku_bytes = self.sku.as_bytes();
|
||||
let mut total_len = writer.write(&encode_7_bit_i32(sku_bytes.len() as i32))?;
|
||||
total_len += writer.write(sku_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(bundle_name_key_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(sprite_bytes)?;
|
||||
|
||||
total_len += writer.write(&[self.is_sprite_full_size as u8])?;
|
||||
|
||||
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(currency_bytes)?;
|
||||
|
||||
total_len += writer.write(&self.price.to_le_bytes())?;
|
||||
|
||||
total_len += writer.write(&self.discount_time.to_le_bytes())?;
|
||||
|
||||
total_len += writer.write(&self.discount_price.to_le_bytes())?;
|
||||
|
||||
total_len += writer.write(&(self.recurrence as i32).to_le_bytes())?;
|
||||
|
||||
total_len += writer.write(&[self.owns_required_cube as u8])?;
|
||||
|
||||
total_len += writer.write(&(self.category as i32).to_le_bytes())?;
|
||||
|
||||
total_len += writer.write(&[self.is_limited_edition as u8])?;
|
||||
|
||||
Ok(total_len)
|
||||
}
|
||||
|
||||
pub fn as_transmissible_vec(items: Vec<Self>) -> Typed {
|
||||
let mut buf = Vec::new();
|
||||
let mut writer = std::io::Cursor::new(&mut buf);
|
||||
writer.write(&(items.len() as i32).to_le_bytes()).unwrap();
|
||||
for item in items.iter() {
|
||||
item.dump(&mut writer).unwrap();
|
||||
}
|
||||
Typed::Bytes(buf.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ItemShopCategory {
|
||||
Cube = 0,
|
||||
GarageBaySkin = 1,
|
||||
Bundle = 2,
|
||||
DeathEffect = 3,
|
||||
SpawnEffect = 4,
|
||||
Emotigram = 5,
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ItemShopRecurrence {
|
||||
Daily = 0,
|
||||
Weekly = 1,
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum CurrencyType {
|
||||
Robits = 0,
|
||||
CosmeticCredits = 1,
|
||||
}
|
||||
|
||||
impl CurrencyType {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Robits => "Robits",
|
||||
Self::CosmeticCredits => "CosmeticCredits",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -12,3 +12,7 @@ pub mod cpu_limits;
|
||||
pub mod cosmetic_limits;
|
||||
pub mod taunts_config;
|
||||
pub mod customisation_info;
|
||||
pub mod garage_bay;
|
||||
pub mod custom_games;
|
||||
pub mod tech_tree;
|
||||
pub mod item_shop_bundle;
|
||||
|
||||
28
rc_services_room/src/data/tech_tree.rs
Normal file
28
rc_services_room/src/data/tech_tree.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use polariton::operation::{Typed, Arr};
|
||||
|
||||
pub struct TechTreeNode {
|
||||
pub main_cube_id: i32, // hex
|
||||
pub position_x: i32,
|
||||
pub position_y: i32,
|
||||
pub is_unlocked: bool,
|
||||
pub is_unlockable: bool,
|
||||
pub tech_points: u32,
|
||||
pub neighbours: Vec<i32>, // cube IDs, hex
|
||||
}
|
||||
|
||||
impl TechTreeNode {
|
||||
pub fn as_transmissible(&self) -> Typed {
|
||||
Typed::HashMap(vec![
|
||||
(Typed::Str("mainCubeId".into()), Typed::Str(hex::encode(self.main_cube_id.to_le_bytes()).into())),
|
||||
(Typed::Str("positionX".into()), Typed::Int(self.position_x)),
|
||||
(Typed::Str("positionY".into()), Typed::Int(self.position_y)),
|
||||
(Typed::Str("isUnlocked".into()), Typed::Bool(self.is_unlocked.into())),
|
||||
(Typed::Str("isUnlockable".into()), Typed::Bool(self.is_unlockable.into())),
|
||||
(Typed::Str("tp".into()), Typed::Int(self.tech_points as i32)),
|
||||
(Typed::Str("neighbours".into()), Typed::Arr(Arr {
|
||||
ty: 115, // str
|
||||
items: self.neighbours.iter().map(|cube_id| Typed::Str(hex::encode(cube_id.to_le_bytes()).into())).collect(),
|
||||
})),
|
||||
].into())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user