diff --git a/nap_data/src/gacha/gacha_config.rs b/nap_data/src/gacha/gacha_config.rs index fa777ed..c539ac3 100644 --- a/nap_data/src/gacha/gacha_config.rs +++ b/nap_data/src/gacha/gacha_config.rs @@ -1,7 +1,8 @@ use std::collections::{HashMap, HashSet}; use chrono::{prelude::Local, DateTime}; -use serde::Deserialize; +use proto::GachaAddedItemType; +use serde::{Deserialize, Deserializer}; use tracing; #[derive(Debug, Default, Deserialize)] @@ -147,6 +148,21 @@ pub struct GachaCategoryInfo { pub is_promotional_items: bool, pub item_ids: Vec, pub category_weight: u32, + #[serde(default, deserialize_with = "from_str")] + pub item_type: GachaAddedItemType, +} + +pub fn from_str<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let s: String = Deserialize::deserialize(deserializer)?; + + let result = GachaAddedItemType::from_str_name(&s); + match result { + Some(val) => Ok(val), + None => Ok(GachaAddedItemType::None) + } } #[derive(Debug, Default, Deserialize)] diff --git a/nap_gameserver/src/commands/player.rs b/nap_gameserver/src/commands/player.rs index e0e00fe..1a5aa98 100644 --- a/nap_gameserver/src/commands/player.rs +++ b/nap_gameserver/src/commands/player.rs @@ -138,12 +138,13 @@ pub async fn kick( } let uid = args[0].parse::()?; + let default_reason = DisconnectReason::ServerKick.into(); let reason = match args.get(1) { Some(arg) => match arg.parse::() { Ok(val) => val, - Err(_err) => 1, + Err(_err) => default_reason, }, - None => 1, + None => default_reason, }; let reason_str = match DisconnectReason::try_from(reason) { Ok(converted_enum) => converted_enum.as_str_name().to_owned(), diff --git a/nap_gameserver/src/handlers/gacha.rs b/nap_gameserver/src/handlers/gacha.rs index dcc8de4..31fd93a 100644 --- a/nap_gameserver/src/handlers/gacha.rs +++ b/nap_gameserver/src/handlers/gacha.rs @@ -1,8 +1,11 @@ -use data::gacha::{gacha_config::*, global_gacha_config}; +use data::{ + gacha::{gacha_config::*, global_gacha_config}, + tables::{AvatarBaseID, WeaponID}, +}; -use proto::*; use super::*; use chrono::{DateTime, Local}; +use proto::*; pub async fn on_get_gacha_data( _session: &NetSession, @@ -33,6 +36,8 @@ pub async fn on_do_gacha( ) -> NetResult { let gachaconf = global_gacha_config(); let gacha_model = &mut _player.gacha_model; + let item_model = &mut _player.item_model; + let role_model = &mut _player.role_model; let pull_time = Local::now(); let target_pool = get_gacha_pool( &gachaconf.character_gacha_pool_list, @@ -47,9 +52,9 @@ pub async fn on_do_gacha( }; let target_pool = target_pool.unwrap(); - // TODO: Validate cost_item_count - // tracing::info!("cost_item_count: {}", body.cost_item_count); + // tracing::info!("cost_item_count: {}", req.cost_item_count); let mut pull_count = if req.cost_item_count > 1 { 10 } else { 1 }; + let mut cost_count = pull_count; if pull_count == 10 { let discount_tag = &gachaconf.common_properties.ten_pull_discount_tag; @@ -67,18 +72,53 @@ pub async fn on_do_gacha( let usage = status_bin.discount_usage_map.get_mut(discount_tag).unwrap(); if *usage < discount_policy.use_limit { *usage += 1; + cost_count = discount_policy.discounted_prize; } } } + if cost_count != req.cost_item_count { + return Ok(DoGachaScRsp { + retcode: Retcode::RetFail.into(), + ..Default::default() + }); + } else { + // TODO: cost resource + } let mut gain_item_list: Vec = vec![]; while pull_count > 0 { let pull_result = gacha_model.perform_pull_pool(&pull_time, target_pool); let extra_item_bin = pull_result.extra_item_bin.unwrap(); + let uid = match GachaAddedItemType::try_from(pull_result.item_type) { + Ok(enum_val) => match enum_val { + GachaAddedItemType::Weapon => match WeaponID::new(pull_result.obtained_item_id) { + Some(id) => item_model.add_weapon(id).value(), + None => 0, + }, + GachaAddedItemType::Character => { + match AvatarBaseID::new(pull_result.obtained_item_id) { + Some(id) => { + role_model.add_avatar(id); + 0 + } + None => 0, + } + } + _ => 0, + }, + Err(_err) => 0, + }; + if extra_item_bin.extra_item_id != 0 { + item_model.add_resource( + extra_item_bin.extra_item_id, + extra_item_bin.extra_item_count, + ); + } gain_item_list.push(GainItemInfo { item_id: pull_result.obtained_item_id, extra_item_id: extra_item_bin.extra_item_id, extra_item_count: extra_item_bin.extra_item_count, + uid, num: 1, ..GainItemInfo::default() }); @@ -193,9 +233,9 @@ fn generate_gacha_info_from_pool( s_guarantee, a_guarantee, need_item_info_list, - // iehkehofjop: target_pool.gacha_parent_schedule_id, - // eggcehlgkii: 223, - // ijoahiepmfo: 101, + lpklhoobkbh: target_pool.gacha_parent_schedule_id, + nammdglepbk: 593, + hgmcofcjmbg: 101, ..Gacha::default() } } @@ -211,6 +251,8 @@ fn generate_all_gacha_info(_player: &Player) -> GachaData { &gachaconf.common_properties, )); } + + // tracing::info!("gacha_list: {:?}", gacha_list); GachaData { random_number: 0, gacha_pool: Some(GachaPool { gacha_list }), diff --git a/nap_gameserver/src/logic/gacha/gacha_model.rs b/nap_gameserver/src/logic/gacha/gacha_model.rs index 75a457a..5f70037 100644 --- a/nap_gameserver/src/logic/gacha/gacha_model.rs +++ b/nap_gameserver/src/logic/gacha/gacha_model.rs @@ -295,6 +295,7 @@ fn determine_gacha_result<'bin, 'conf>( gacha_id: target_pool.gacha_schedule_id.clone(), progress_map: status_bin.rarity_status_map.clone(), extra_item_bin: Some(extra_item_bin), + item_type: category.item_type.into(), } } diff --git a/nap_proto/out/bin.rs b/nap_proto/out/bin.rs index 7f93d83..01bb4aa 100644 --- a/nap_proto/out/bin.rs +++ b/nap_proto/out/bin.rs @@ -162,6 +162,8 @@ pub struct GachaRecordBin { pub progress_map: ::std::collections::HashMap, #[prost(message, optional, tag = "5")] pub extra_item_bin: ::core::option::Option, + #[prost(enumeration = "GachaAddedItemType", tag = "6")] + pub item_type: i32, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -204,3 +206,35 @@ pub struct PlayerDataBin { #[prost(message, optional, tag = "6")] pub gacha_model: ::core::option::Option, } +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum GachaAddedItemType { + None = 0, + Weapon = 1, + Character = 2, + Bangboo = 3, +} +impl GachaAddedItemType { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + GachaAddedItemType::None => "GACHA_ADDED_ITEM_TYPE_NONE", + GachaAddedItemType::Weapon => "GACHA_ADDED_ITEM_TYPE_WEAPON", + GachaAddedItemType::Character => "GACHA_ADDED_ITEM_TYPE_CHARACTER", + GachaAddedItemType::Bangboo => "GACHA_ADDED_ITEM_TYPE_BANGBOO", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "GACHA_ADDED_ITEM_TYPE_NONE" => Some(Self::None), + "GACHA_ADDED_ITEM_TYPE_WEAPON" => Some(Self::Weapon), + "GACHA_ADDED_ITEM_TYPE_CHARACTER" => Some(Self::Character), + "GACHA_ADDED_ITEM_TYPE_BANGBOO" => Some(Self::Bangboo), + _ => None, + } + } +}