mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Add upgrade and dismantle vehicle slot functionality for #14
This commit is contained in:
@@ -261,4 +261,13 @@ impl <C: Clone> super::ConfigProvider<C> for CubeConfig {
|
||||
database: self.settings.server.database.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn garage_upgrades(&self) -> super::GarageUpgrades {
|
||||
super::GarageUpgrades {
|
||||
increments: self.settings.garage_upgrades.iter().map(|inc| super::GarageUpgradeIncrement {
|
||||
cpu: inc.cpu,
|
||||
cost: inc.cost,
|
||||
}).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ mod cubes_json;
|
||||
pub use cubes_json::CubeConfig;
|
||||
|
||||
mod traits;
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig};
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement};
|
||||
|
||||
pub type ConfigImpl = CubeConfig;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ pub trait ConfigProvider<C: Clone> {
|
||||
fn login_messages(&self) -> DevMessageProvider<C>;
|
||||
fn public_channels(&self) -> Typed<C>;
|
||||
fn server_config(&self) -> ServerConfig;
|
||||
fn garage_upgrades(&self) -> GarageUpgrades;
|
||||
}
|
||||
|
||||
pub struct CompleteCampaignProvider {
|
||||
@@ -88,3 +89,27 @@ pub struct TypedDevMessage<C> {
|
||||
pub struct ServerConfig {
|
||||
pub database: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GarageUpgrades {
|
||||
pub increments: Vec<GarageUpgradeIncrement>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GarageUpgradeIncrement {
|
||||
pub cpu: u32,
|
||||
pub cost: u32,
|
||||
}
|
||||
|
||||
impl GarageUpgrades {
|
||||
pub fn slot_upgrades<C>(&self) -> Typed<C> {
|
||||
Typed::HashMap(vec![
|
||||
(Typed::Str("cpuIncreaseCost".into()), Typed::Dict(polariton::operation::Dict {
|
||||
key_ty: polariton::serdes::TypePrefix::Int, // int
|
||||
val_ty: polariton::serdes::TypePrefix::Int, // int
|
||||
// (CPU limit, upgrade cost)
|
||||
items: self.increments.iter().map(|inc| (Typed::Int(inc.cpu as _), Typed::Int(inc.cost as _))).collect(),
|
||||
}))
|
||||
].into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ pub struct Settings {
|
||||
pub gameplay: super::GameplaySettings,
|
||||
#[serde(default = "default_dev_messages")]
|
||||
pub banners: Vec<BannerMessage>,
|
||||
#[serde(default = "default_slot_upgrades")]
|
||||
pub garage_upgrades: Vec<GarageSlotUpgrade>,
|
||||
#[serde(default = "default_server_conf")]
|
||||
pub server: ServerSettings,
|
||||
}
|
||||
@@ -35,6 +37,37 @@ fn default_dev_messages() -> Vec<BannerMessage> {
|
||||
Vec::default()
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct GarageSlotUpgrade {
|
||||
pub cpu: u32,
|
||||
pub cost: u32,
|
||||
}
|
||||
|
||||
fn default_slot_upgrades() -> Vec<GarageSlotUpgrade> {
|
||||
vec![
|
||||
GarageSlotUpgrade {
|
||||
cpu: 100,
|
||||
cost: 100,
|
||||
},
|
||||
GarageSlotUpgrade {
|
||||
cpu: 200,
|
||||
cost: 200,
|
||||
},
|
||||
GarageSlotUpgrade {
|
||||
cpu: 1_000,
|
||||
cost: 1_000,
|
||||
},
|
||||
GarageSlotUpgrade {
|
||||
cpu: 2_000,
|
||||
cost: 2_000,
|
||||
},
|
||||
GarageSlotUpgrade {
|
||||
cpu: 10_000,
|
||||
cost: 10_000,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct ServerSettings {
|
||||
#[serde(default = "default_db_conn")]
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::persist::config::ConfigProvider;
|
||||
|
||||
pub struct AccountProvider {
|
||||
cubes: std::sync::Arc<Vec<u32>>,
|
||||
garage_upgrades: std::sync::Arc<crate::persist::config::GarageUpgrades>,
|
||||
secret: Vec<u8>,
|
||||
db: std::sync::Arc<rc_database::Database>,
|
||||
}
|
||||
@@ -17,6 +18,7 @@ impl AccountProvider {
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::NotConnected, e))?;
|
||||
Ok(Self {
|
||||
cubes: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::ids(conf)),
|
||||
garage_upgrades: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::garage_upgrades(conf)),
|
||||
secret: std::fs::read(&token_path)?,
|
||||
db: std::sync::Arc::new(db),
|
||||
})
|
||||
@@ -47,6 +49,7 @@ impl <C: Clone> super::UserProvider<C> for AccountProvider {
|
||||
account: user_info,
|
||||
perms: user_perms,
|
||||
cubes: self.cubes.clone(),
|
||||
garage_upgrades: self.garage_upgrades.clone(),
|
||||
extensions: ext,
|
||||
db: self.db.clone(),
|
||||
}))
|
||||
@@ -127,6 +130,7 @@ struct UserData {
|
||||
account: rc_database::schema::user::Model,
|
||||
perms: rc_database::schema::permissions::Model,
|
||||
cubes: std::sync::Arc<Vec<u32>>,
|
||||
garage_upgrades: std::sync::Arc<crate::persist::config::GarageUpgrades>,
|
||||
extensions: std::collections::HashMap<std::any::TypeId, Box<dyn std::any::Any + Send + Sync + 'static>>,
|
||||
db: std::sync::Arc<rc_database::Database>,
|
||||
}
|
||||
@@ -354,6 +358,45 @@ impl <C: Clone> super::User<C> for UserData {
|
||||
})
|
||||
}
|
||||
|
||||
async fn upgrade_slot(&self, increments: i32) -> Result<polariton::operation::Typed<C>, i16> {
|
||||
if increments <= 0 {
|
||||
// no-op
|
||||
return Ok(polariton::operation::Typed::Bool(true));
|
||||
}
|
||||
let selected_slot = self.db.garage_selected(self.account.id).await.map_err(|e| {
|
||||
log::error!("Failed to retrieve selected vehicle slot for user_id {}: {}", self.account.id, e);
|
||||
DATABASE_ERR
|
||||
})?.ok_or_else(|| {
|
||||
log::error!("No selected vehicle slot for user_id {}", self.account.id);
|
||||
DATABASE_ERR
|
||||
})?;
|
||||
let inc_opt = self.garage_upgrades.increments.iter().enumerate().filter(|(_i, inc)| inc.cpu <= selected_slot.bay_cpu).last();
|
||||
if let Some((i, _)) = inc_opt {
|
||||
let max_upgrade = self.garage_upgrades.increments.len() - 1;
|
||||
let upgrade_to = i + (increments as usize);
|
||||
if upgrade_to > max_upgrade {
|
||||
// over-upgraded
|
||||
Ok(polariton::operation::Typed::Bool(false))
|
||||
} else {
|
||||
let upgrade_to_cpu = self.garage_upgrades.increments[upgrade_to].cpu;
|
||||
let entity = rc_database::schema::garage::ActiveModel {
|
||||
bay_cpu: rc_database::sea_orm::ActiveValue::Set(upgrade_to_cpu),
|
||||
..Default::default()
|
||||
};
|
||||
self.db.update_garage_by_user_id_and_slot(entity, self.account.id, selected_slot.slot).await.map_err(|e| {
|
||||
log::error!("Failed to upgrade selected vehicle slot to bay cpu of {} for user_id {}: {}", upgrade_to_cpu, self.account.id, e);
|
||||
DATABASE_ERR
|
||||
})?;
|
||||
// TODO subtract upgrade cost from user free currency total
|
||||
Ok(polariton::operation::Typed::Bool(true))
|
||||
}
|
||||
} else {
|
||||
// probably a bad/changed garage update config
|
||||
log::warn!("No vehicle slot upgrade found for bay CPU {} for user_id {}", selected_slot.bay_cpu, self.account.id);
|
||||
Ok(polariton::operation::Typed::Bool(false))
|
||||
}
|
||||
}
|
||||
|
||||
fn signup_date(&self) -> i64 {
|
||||
super::since_windows_epoch(self.account.creation_time)
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ pub trait User<C> {
|
||||
async fn save_slot(&self, vehicle: VehicleData) -> Result<(), i16>;
|
||||
async fn save_slot_order(&self, slots: Vec<i32>) -> Result<(), i16>;
|
||||
async fn new_slot(&self, reset_slot: Option<i32>) -> Result<NewSlotData<C>, i16>;
|
||||
async fn upgrade_slot(&self, increments: i32) -> Result<polariton::operation::Typed<C>, i16>;
|
||||
fn signup_date(&self) -> i64;
|
||||
async fn singleplayer_robots(&self) -> Result<polariton::operation::Typed<C>, i16>;
|
||||
}
|
||||
|
||||
35
rc_services_room/src/operations/garage_slot_dismantle.rs
Normal file
35
rc_services_room/src/operations/garage_slot_dismantle.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use polariton::operation::{ParameterTable, Typed, OperationResponse};
|
||||
|
||||
const CODE: u8 = 42;
|
||||
|
||||
const SLOT_PARAM_KEY: u8 = 43;
|
||||
|
||||
pub(super) fn garage_slot_dismantler() -> GarageSlotDismantler {
|
||||
GarageSlotDismantler
|
||||
}
|
||||
|
||||
async fn do_handling(params: ParameterTable<()>, user: &crate::UserTy) -> Result<ParameterTable, i16> {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Int(slot)) = params.remove(&SLOT_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
user_info.new_slot(Some(slot)).await?;
|
||||
}
|
||||
Ok(params.into())
|
||||
}
|
||||
|
||||
pub struct GarageSlotDismantler;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl polariton_server::operations::Operation<()> for GarageSlotDismantler {
|
||||
type User = crate::UserTy;
|
||||
|
||||
async fn handle_async(&self, params: ParameterTable<()>, user: &Self::User) -> OperationResponse<()> {
|
||||
polariton_server::operations::result_to_op_resp::<CODE, ()>(do_handling(params, user).await)
|
||||
}
|
||||
}
|
||||
|
||||
impl polariton_server::operations::OperationCode for GarageSlotDismantler {
|
||||
fn op_code() -> u8 {
|
||||
CODE
|
||||
}
|
||||
}
|
||||
36
rc_services_room/src/operations/garage_slot_upgrade.rs
Normal file
36
rc_services_room/src/operations/garage_slot_upgrade.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use polariton::operation::{ParameterTable, Typed, OperationResponse};
|
||||
|
||||
const CODE: u8 = 39;
|
||||
|
||||
const CPU_INCREMENT_PARAM_KEY: u8 = 7;
|
||||
const SUCCESS_PARAM_KEY: u8 = 39;
|
||||
|
||||
pub(super) fn garage_slot_upgrage_provider() -> GarageSlotUpgrade {
|
||||
GarageSlotUpgrade
|
||||
}
|
||||
|
||||
async fn do_handling(params: ParameterTable<()>, user: &crate::UserTy) -> Result<ParameterTable, i16> {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Int(increments)) = params.remove(&CPU_INCREMENT_PARAM_KEY) {
|
||||
let user_info = user.user()?;
|
||||
params.insert(SUCCESS_PARAM_KEY, user_info.upgrade_slot(increments).await?);
|
||||
}
|
||||
Ok(params.into())
|
||||
}
|
||||
|
||||
pub struct GarageSlotUpgrade;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl polariton_server::operations::Operation<()> for GarageSlotUpgrade {
|
||||
type User = crate::UserTy;
|
||||
|
||||
async fn handle_async(&self, params: ParameterTable<()>, user: &Self::User) -> OperationResponse<()> {
|
||||
polariton_server::operations::result_to_op_resp::<CODE, ()>(do_handling(params, user).await)
|
||||
}
|
||||
}
|
||||
|
||||
impl polariton_server::operations::OperationCode for GarageSlotUpgrade {
|
||||
fn op_code() -> u8 {
|
||||
CODE
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ pub(super) fn garage_slot_order_provider() -> GarageSlotsOrderProvider {
|
||||
async fn do_handling(params: ParameterTable<()>, user: &crate::UserTy) -> Result<ParameterTable, i16> {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Arr(order)) = params.remove(&SLOT_ORDER_PARAM_KEY) {
|
||||
log::info!("Slot order is {}", order);
|
||||
//log::info!("Slot order is {}", order);
|
||||
let mut order_i32 = Vec::with_capacity(order.items.len());
|
||||
for item in order.items.iter() {
|
||||
if let Typed::Int(item) = item {
|
||||
|
||||
@@ -1,25 +1,39 @@
|
||||
use polariton_server::operations::SimpleFunc;
|
||||
use polariton::{operation::{Dict, ParameterTable, Typed}, serdes::TypePrefix};
|
||||
use polariton::operation::{ParameterTable, OperationResponse};
|
||||
use rc_core::ConfigProvider;
|
||||
|
||||
const CODE: u8 = 1;
|
||||
|
||||
const PARAM_KEY: u8 = 1;
|
||||
|
||||
pub(super) fn garage_upgrades_provider() -> SimpleFunc<1, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
SimpleFunc::new(|params, _| {
|
||||
pub(super) fn garage_upgrades_provider(conf: &rc_core::ConfigImpl) -> GarageUpgradesProvider {
|
||||
GarageUpgradesProvider {
|
||||
upgrades: <rc_core::ConfigImpl as ConfigProvider<()>>::garage_upgrades(conf),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GarageUpgradesProvider {
|
||||
upgrades: rc_core::persist::config::GarageUpgrades,
|
||||
}
|
||||
|
||||
impl GarageUpgradesProvider {
|
||||
async fn do_handling(&self, params: ParameterTable) -> Result<ParameterTable, i16> {
|
||||
let mut params = params.to_dict();
|
||||
params.insert(PARAM_KEY, Typed::HashMap(vec![
|
||||
(Typed::Str("cpuIncreaseCost".into()), Typed::Dict(Dict {
|
||||
key_ty: TypePrefix::Int, // int
|
||||
val_ty: TypePrefix::Int, // int
|
||||
items: vec![
|
||||
// (CPU limit, upgrade cost)
|
||||
(Typed::Int(100), Typed::Int(100)),
|
||||
(Typed::Int(200), Typed::Int(200)),
|
||||
(Typed::Int(1_000), Typed::Int(1_000)),
|
||||
(Typed::Int(2_000), Typed::Int(2_000)), // max regular bot CPU
|
||||
(Typed::Int(10_000), Typed::Int(10_000)), // max mega bot cpu
|
||||
],
|
||||
}))
|
||||
].into()));
|
||||
params.insert(PARAM_KEY, self.upgrades.slot_upgrades());
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl polariton_server::operations::Operation<()> for GarageUpgradesProvider {
|
||||
type User = crate::UserTy;
|
||||
|
||||
async fn handle_async(&self, params: ParameterTable<()>, _user: &Self::User) -> OperationResponse<()> {
|
||||
polariton_server::operations::result_to_op_resp::<CODE, ()>(self.do_handling(params).await)
|
||||
}
|
||||
}
|
||||
|
||||
impl polariton_server::operations::OperationCode for GarageUpgradesProvider {
|
||||
fn op_code() -> u8 {
|
||||
CODE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,8 @@ mod garage_slot_limit;
|
||||
mod garage_slot_add;
|
||||
mod garage_slots_order;
|
||||
mod garage_slot_select;
|
||||
mod garage_slot_dismantle;
|
||||
mod garage_slot_upgrade;
|
||||
|
||||
use polariton_server::operations::OperationsHandler;
|
||||
|
||||
@@ -132,7 +134,7 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
|
||||
.add(avatar_info::get_avatar_provider())
|
||||
.add(custom_game_session::get_custom_session_provider())
|
||||
.add(user_xp::get_user_xp_provider())
|
||||
.add(garage_upgrades::garage_upgrades_provider())
|
||||
.add(garage_upgrades::garage_upgrades_provider(&init_ctx.cubes))
|
||||
.add(game_event_params::event_system_params_provider())
|
||||
.add(garage_bay_uuid::garage_id_provider())
|
||||
.add(tech_tree_data::tech_tree_layout_provider(&init_ctx.cubes))
|
||||
@@ -190,4 +192,6 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
|
||||
.add(garage_slot_add::garage_slot_add_provider())
|
||||
.add(garage_slots_order::garage_slot_order_provider())
|
||||
.add(garage_slot_select::garage_slot_selector())
|
||||
.add(garage_slot_dismantle::garage_slot_dismantler())
|
||||
.add(garage_slot_upgrade::garage_slot_upgrage_provider())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user