From 753e9b0f510cf47c74dc85d7b0461a511a4abb53 Mon Sep 17 00:00:00 2001 From: "NG (Graham)" Date: Sat, 24 Jan 2026 18:15:42 -0500 Subject: [PATCH] Add warning when awarding XP via promo code or shop purchase to address #76 --- rc_core/src/persist/config/cubes_json.rs | 2 + rc_core/src/persist/item_shop.rs | 56 +++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/rc_core/src/persist/config/cubes_json.rs b/rc_core/src/persist/config/cubes_json.rs index 9f85777..e27187f 100644 --- a/rc_core/src/persist/config/cubes_json.rs +++ b/rc_core/src/persist/config/cubes_json.rs @@ -59,6 +59,7 @@ impl CubeConfig { let battle_res = self.battle.validate_in(&mut validation_info, self, "battle"); let chat_res = self.chat.validate_in(&mut validation_info, self, "chat"); let factory_res = self.factory.validate_in(&mut validation_info, self, "factory"); + let shop_res = self.shop.validate_in(&mut validation_info, self, "shop"); let settings_res = self.settings.validate_in(&mut validation_info, self, "settings"); validation_info.info(super::ValidationMessage { @@ -70,6 +71,7 @@ impl CubeConfig { battle_res && chat_res && factory_res + && shop_res && settings_res && validation_info.is_ok() } diff --git a/rc_core/src/persist/item_shop.rs b/rc_core/src/persist/item_shop.rs index 3ff30d8..7eb66c3 100644 --- a/rc_core/src/persist/item_shop.rs +++ b/rc_core/src/persist/item_shop.rs @@ -10,7 +10,8 @@ pub struct ItemShopConfig { impl super::config::SelfValidator for ItemShopConfig { type Context = crate::ConfigImpl; - fn validate(&self, info: &mut super::config::ValidationInfo, _ctx: &Self::Context) -> bool { + fn validate(&self, info: &mut super::config::ValidationInfo, ctx: &Self::Context) -> bool { + let mut is_ok = true; let daily_count = self.items.iter().filter(|x| matches!(x.recurrence, Recurrence::Daily)).count(); if daily_count < 6 { info.warn(crate::persist::config::ValidationMessage { @@ -35,8 +36,14 @@ impl super::config::SelfValidator for ItemShopConfig { message: "More than 3 weekly items in shop so some will never be shown".to_owned(), }); } + for (i, item) in self.items.iter().enumerate() { + is_ok &= item.validate_in(info, ctx, &format!("items[{}]", i)); + } + for (code_name, item_code) in self.promo_codes.iter() { + is_ok &= item_code.validate_in(info, ctx, &format!("promo_codes[\"{}\"]", code_name)); + } // TODO - true + is_ok } } @@ -85,6 +92,16 @@ impl ItemBundle { } } +impl super::config::SelfValidator for ItemBundle { + type Context = crate::ConfigImpl; + fn validate(&self, info: &mut super::config::ValidationInfo, ctx: &Self::Context) -> bool { + for (i, give) in self.gives.iter().enumerate() { + give.validate_in(info, ctx, &format!("gives[{}]", i)); + } + true + } +} + #[derive(Serialize, Deserialize, Clone, Copy, Debug)] pub enum ShopCategory { Cube, @@ -174,6 +191,19 @@ impl std::convert::From for crate::persist::config::ShopGain { } } +impl super::config::SelfValidator for ItemPurchase { + type Context = crate::ConfigImpl; + fn validate(&self, info: &mut super::config::ValidationInfo, _ctx: &Self::Context) -> bool { + if matches!(self, Self::Experience { xp: _ }) { + info.warn(crate::persist::config::ValidationMessage { + path: vec!["xp".to_owned()], + message: "Experience rewards cause (client-side only) UI desync of the XP bar".to_owned(), + }); + } + true + } +} + #[derive(Serialize, Deserialize, Clone, Debug)] pub struct ItemCode { #[serde(default)] @@ -187,6 +217,16 @@ pub struct ItemCode { pub gives: Vec, } +impl super::config::SelfValidator for ItemCode { + type Context = crate::ConfigImpl; + fn validate(&self, info: &mut super::config::ValidationInfo, ctx: &Self::Context) -> bool { + for (i, give) in self.gives.iter().enumerate() { + give.validate_in(info, ctx, &format!("gives[{}]", i)); + } + true + } +} + pub fn default_items() -> Vec { vec![ // weekly (top row of 3) @@ -352,5 +392,17 @@ pub fn default_codes() -> std::collections::HashMap { value: 1.5, gives: vec![] }); + map.insert("LEVEL10".to_owned(), ItemCode { + message: Some("Please re-log".to_owned()), + bundle_id: None, + promo_id: None, + is_serial: false, + value: 1.5, + gives: vec![ + ItemPurchase::Experience { + xp: 10_000, + } + ] + }); map }