forked from NewEriduPubSec/JaneDoe-ZS
Compare commits
10 commits
5982523c98
...
3043d45ac9
Author | SHA1 | Date | |
---|---|---|---|
|
3043d45ac9 | ||
|
05e8ef740d | ||
|
950a3725ea | ||
|
157832198c | ||
|
55780314d1 | ||
|
db2677be50 | ||
|
a7a1f4da37 | ||
220fbc42f0 | |||
7d7bd76ae8 | |||
26fe9551d4 |
29 changed files with 3347 additions and 176 deletions
32
assets/FileCfg/MainCityBgmConfigTemplateTb.json
Normal file
32
assets/FileCfg/MainCityBgmConfigTemplateTb.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
[
|
||||
{
|
||||
"ID": 0,
|
||||
"PlayEventName": "Play_BGM_Maincity",
|
||||
"StateName": "Normal"
|
||||
},
|
||||
{
|
||||
"ID": 1001,
|
||||
"PlayEventName": "Play_BGM_Maincity",
|
||||
"StateName": "Hack_Maincity"
|
||||
},
|
||||
{
|
||||
"ID": 1002,
|
||||
"PlayEventName": "Play_BGM_Maincity",
|
||||
"StateName": "WorkShop_OnMission"
|
||||
},
|
||||
{
|
||||
"ID": 1003,
|
||||
"PlayEventName": "Play_BGM_Maincity",
|
||||
"StateName": "SummerActivity_Ready"
|
||||
},
|
||||
{
|
||||
"ID": 1004,
|
||||
"PlayEventName": "Play_BGM_Maincity",
|
||||
"StateName": "SummerActivity_Start"
|
||||
},
|
||||
{
|
||||
"ID": 1005,
|
||||
"PlayEventName": "Play_BGM_Maincity",
|
||||
"StateName": "Mission_Accomplish"
|
||||
}
|
||||
]
|
1433
assets/GachaConfig/gacha.jsonc
Normal file
1433
assets/GachaConfig/gacha.jsonc
Normal file
File diff suppressed because it is too large
Load diff
|
@ -18,3 +18,5 @@ tracing.workspace = true
|
|||
|
||||
# Internal
|
||||
proto.workspace = true
|
||||
jsonc-parser = { version = "0.23.0", features = ["serde"] }
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
|
|
255
nap_data/src/gacha/gacha_config.rs
Normal file
255
nap_data/src/gacha/gacha_config.rs
Normal file
|
@ -0,0 +1,255 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use chrono::{prelude::Local, DateTime};
|
||||
use proto::GachaAddedItemType;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use tracing;
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct ExtraItemsPolicy {
|
||||
pub id: u32,
|
||||
pub count: u32,
|
||||
#[serde(default)]
|
||||
pub apply_on_owned_count: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct ProbabilityPoint {
|
||||
pub start_pity: u32,
|
||||
pub start_chance_percent: f64,
|
||||
#[serde(default)]
|
||||
pub increment_percent: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct ProbabilityModel {
|
||||
#[serde(default)]
|
||||
pub clear_status_on_higher_rarity_pulled: bool,
|
||||
pub points: Vec<ProbabilityPoint>,
|
||||
// This value is for display only, so it's set when
|
||||
// the maximum guarantee is not equal to the
|
||||
// automatically calculated value (commonly, less than).
|
||||
#[serde(default)]
|
||||
pub maximum_guarantee_pity: u32,
|
||||
|
||||
#[serde(skip_deserializing)]
|
||||
probability_percents: Vec<f64>,
|
||||
}
|
||||
|
||||
impl ProbabilityModel {
|
||||
fn get_maximum_guarantee(&self) -> u32 {
|
||||
self.probability_percents.len() as u32 - 1
|
||||
}
|
||||
|
||||
pub fn post_configure(&mut self, tag: &String) {
|
||||
self.points.sort_by_key(|point| point.start_pity);
|
||||
|
||||
let mut probability_percents: Vec<f64> = vec![0.0];
|
||||
for (i, point) in self.points.iter().enumerate() {
|
||||
if i > 0 {
|
||||
let last_point = &self.points[i - 1];
|
||||
let last_stop_percent = last_point.start_chance_percent
|
||||
+ last_point.increment_percent
|
||||
* (point.start_pity - last_point.start_pity) as f64;
|
||||
if last_stop_percent > point.start_chance_percent {
|
||||
tracing::warn!("Gacha - ProbabilityModel '{tag}': The start chance of '{point:?}' is less than the value inherited from the previous point.");
|
||||
}
|
||||
}
|
||||
|
||||
let mut max_pity = 2000;
|
||||
if i < self.points.len() - 1 {
|
||||
let next_point = &self.points[i + 1];
|
||||
max_pity = next_point.start_pity - 1;
|
||||
let max_probability = point.start_chance_percent
|
||||
+ point.increment_percent
|
||||
* (next_point.start_pity - 1 - point.start_pity) as f64;
|
||||
assert!(max_probability < 100.0, "Gacha - ProbabilityModel '{tag}': Probability already reached 100% in '{point:?}' (though points with higher pity left)");
|
||||
}
|
||||
|
||||
let mut pity = point.start_pity;
|
||||
let mut percent = point.start_chance_percent;
|
||||
while pity <= max_pity {
|
||||
if max_pity >= 2000 && percent >= 100.0 {
|
||||
probability_percents.push(100.0);
|
||||
break;
|
||||
}
|
||||
probability_percents.push(percent);
|
||||
percent += point.increment_percent;
|
||||
pity += 1;
|
||||
}
|
||||
assert!(pity <= 2000, "Gacha - ProbabilityModel '{tag}' (point {i}): Haven't reached 100% guarantee probability at Pity 2001. The current probability is {percent}%. Crazy.");
|
||||
}
|
||||
|
||||
self.probability_percents = probability_percents;
|
||||
if self.maximum_guarantee_pity <= 0 {
|
||||
self.maximum_guarantee_pity = self.get_maximum_guarantee();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_chance_percent(&self, pity: &u32) -> f64 {
|
||||
// The vec length is 1 bigger than the maximum pity (1-based)
|
||||
let guarantee_pity = self.probability_percents.len() - 1;
|
||||
let idx = *pity as usize;
|
||||
if idx > guarantee_pity {
|
||||
return self.probability_percents[guarantee_pity];
|
||||
}
|
||||
self.probability_percents[idx]
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct CategoryGuaranteePolicy {
|
||||
pub included_category_tags: HashSet<String>,
|
||||
pub trigger_on_failure_times: u32,
|
||||
pub clear_status_on_target_changed: bool,
|
||||
pub chooseable: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct TenPullDiscount {
|
||||
pub use_limit: u32,
|
||||
pub discounted_prize: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct AdvancedGuarantee {
|
||||
pub use_limit: u32,
|
||||
pub rarity: u32,
|
||||
pub guarantee_pity: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct MustGainItem {
|
||||
pub use_limit: u32,
|
||||
pub rarity: u32,
|
||||
pub category_tag: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct FreeSelectItem {
|
||||
pub milestones: Vec<u32>,
|
||||
pub rarity: u32,
|
||||
pub category_tags: Vec<String>,
|
||||
pub free_select_progress_record_tag: String,
|
||||
pub free_select_usage_record_tag: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct DiscountPolicyCollection {
|
||||
pub ten_pull_discount_map: HashMap<String, TenPullDiscount>,
|
||||
pub must_gain_item_map: HashMap<String, MustGainItem>,
|
||||
pub advanced_guarantee_map: HashMap<String, AdvancedGuarantee>,
|
||||
pub free_select_map: HashMap<String, FreeSelectItem>,
|
||||
}
|
||||
|
||||
impl DiscountPolicyCollection {
|
||||
pub fn post_configure(&mut self) {
|
||||
for (tag, ten_pull_discount) in self.ten_pull_discount_map.iter() {
|
||||
let discounted_prize = ten_pull_discount.discounted_prize;
|
||||
assert!(discounted_prize < 10, "Gacha - DiscountPolicy '{tag}': ten_pull_discount's value should be smaller than 10 (read {discounted_prize}).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct GachaCategoryInfo {
|
||||
#[serde(default)]
|
||||
pub is_promotional_items: bool,
|
||||
pub item_ids: Vec<u32>,
|
||||
pub category_weight: u32,
|
||||
#[serde(default, deserialize_with = "from_str")]
|
||||
pub item_type: GachaAddedItemType,
|
||||
}
|
||||
|
||||
pub fn from_str<'de, D>(deserializer: D) -> Result<GachaAddedItemType, D::Error>
|
||||
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)]
|
||||
pub struct GachaAvailableItemsInfo {
|
||||
pub rarity: u32,
|
||||
#[serde(default)]
|
||||
pub extra_items_policy_tags: Vec<String>,
|
||||
pub categories: HashMap<String, GachaCategoryInfo>,
|
||||
pub probability_model_tag: String,
|
||||
#[serde(default)]
|
||||
pub category_guarantee_policy_tags: Vec<String>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct CharacterGachaPool {
|
||||
pub gacha_schedule_id: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
pub comment: String,
|
||||
pub gacha_type: u32,
|
||||
pub cost_item_id: u32,
|
||||
pub start_time: DateTime<Local>,
|
||||
pub end_time: DateTime<Local>,
|
||||
#[serde(default)]
|
||||
pub discount_policy_tags: Vec<String>,
|
||||
pub sharing_guarantee_info_category: String,
|
||||
pub gacha_items: Vec<GachaAvailableItemsInfo>,
|
||||
}
|
||||
|
||||
impl CharacterGachaPool {
|
||||
pub fn is_still_open(&self, now: &DateTime<Local>) -> bool {
|
||||
self.start_time <= *now && *now <= self.end_time
|
||||
}
|
||||
|
||||
pub fn post_configure(&mut self, probability_model_map: &HashMap<String, ProbabilityModel>) {
|
||||
self.gacha_items
|
||||
.sort_by_key(|item_list| u32::MAX - item_list.rarity);
|
||||
for items_info in self.gacha_items.iter_mut() {
|
||||
assert!(probability_model_map.contains_key(&items_info.probability_model_tag), "Gacha - CharacterGachaPool '{}': Specified ProbabilityModel tag '{}' that does not exist.", self.gacha_schedule_id, items_info.probability_model_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct GachaCommonProperties {
|
||||
pub up_item_category_tag: String,
|
||||
pub s_item_rarity: u32,
|
||||
pub a_item_rarity: u32,
|
||||
// TODO: PostConfigure check
|
||||
pub ten_pull_discount_tag: String,
|
||||
pub newcomer_advanced_s_tag: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct GachaConfiguration {
|
||||
pub character_gacha_pool_list: Vec<CharacterGachaPool>,
|
||||
pub probability_model_map: HashMap<String, ProbabilityModel>,
|
||||
pub category_guarantee_policy_map: HashMap<String, CategoryGuaranteePolicy>,
|
||||
pub extra_items_policy_map: HashMap<String, ExtraItemsPolicy>,
|
||||
pub discount_policies: DiscountPolicyCollection,
|
||||
pub common_properties: GachaCommonProperties,
|
||||
}
|
||||
|
||||
impl GachaConfiguration {
|
||||
pub fn post_configure(&mut self) {
|
||||
assert!(
|
||||
self.category_guarantee_policy_map
|
||||
.contains_key(&self.common_properties.up_item_category_tag),
|
||||
"The UP category should be valid in policy map."
|
||||
);
|
||||
|
||||
for (tag, policy) in self.probability_model_map.iter_mut() {
|
||||
policy.post_configure(&tag);
|
||||
}
|
||||
self.discount_policies.post_configure();
|
||||
for character_pool in self.character_gacha_pool_list.iter_mut() {
|
||||
character_pool.post_configure(&self.probability_model_map);
|
||||
}
|
||||
}
|
||||
}
|
45
nap_data/src/gacha/mod.rs
Normal file
45
nap_data/src/gacha/mod.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
use gacha_config::GachaConfiguration;
|
||||
use jsonc_parser::{parse_to_serde_value, ParseOptions};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{action::ActionConfig, DataLoadError};
|
||||
|
||||
pub mod gacha_config;
|
||||
|
||||
const GACHA_CONFIG_NAME: &str = "gacha.jsonc";
|
||||
static GACHACONF: OnceLock<GachaConfiguration> = OnceLock::new();
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct EventGraphConfig {
|
||||
pub event_id: u32,
|
||||
pub actions: Vec<ActionConfig>,
|
||||
}
|
||||
|
||||
pub(crate) fn load_gacha_config(path: &str) -> Result<(), DataLoadError> {
|
||||
let jsonc_data = std::fs::read_to_string(format!("{path}/{GACHA_CONFIG_NAME}"))
|
||||
.map_err(|err| DataLoadError::IoError(err))?;
|
||||
|
||||
let json_value = parse_to_serde_value(
|
||||
&jsonc_data,
|
||||
&ParseOptions {
|
||||
allow_comments: true,
|
||||
allow_loose_object_property_names: false,
|
||||
allow_trailing_commas: true,
|
||||
},
|
||||
)
|
||||
.map_err(|err| DataLoadError::JsoncParseError(err))?
|
||||
.unwrap();
|
||||
|
||||
let mut result = serde_json::from_value::<GachaConfiguration>(json_value)
|
||||
.map_err(|err| DataLoadError::FromJsonError(String::from("GachaConfiguration"), err))?;
|
||||
result.post_configure();
|
||||
|
||||
GACHACONF.set(result).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn global_gacha_config() -> &'static GachaConfiguration {
|
||||
GACHACONF.get().unwrap()
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
pub mod action;
|
||||
pub mod event;
|
||||
pub mod gacha;
|
||||
pub mod tables;
|
||||
|
||||
use std::{collections::HashMap, sync::OnceLock};
|
||||
|
||||
use jsonc_parser::errors::ParseError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -12,6 +14,7 @@ pub struct AssetsConfig {
|
|||
pub filecfg_path: String,
|
||||
pub event_config_path: String,
|
||||
pub usm_keys_path: String,
|
||||
pub gacha_config_path: String,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -20,6 +23,8 @@ pub enum DataLoadError {
|
|||
IoError(#[from] std::io::Error),
|
||||
#[error("from_json failed for type {0}, error: {1}")]
|
||||
FromJsonError(String, serde_json::Error),
|
||||
#[error("jsonc_parser parse as json error: {0}")]
|
||||
JsoncParseError(#[from] ParseError),
|
||||
}
|
||||
|
||||
static USM_KEY_MAP: OnceLock<HashMap<u32, u64>> = OnceLock::new();
|
||||
|
@ -31,6 +36,7 @@ pub fn init_data(config: &AssetsConfig) -> Result<(), DataLoadError> {
|
|||
tracing::warn!("failed to load USM keys, in-game cutscenes will not work! Reason: {err}");
|
||||
USM_KEY_MAP.set(HashMap::new()).unwrap();
|
||||
}
|
||||
gacha::load_gacha_config(&config.gacha_config_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
12
nap_data/src/tables/main_city_bgm_config_template.rs
Normal file
12
nap_data/src/tables/main_city_bgm_config_template.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
template_id!(MainCityBgmConfig u32 id);
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[serde(rename_all = "PascalCase")]
|
||||
pub struct MainCityBgmConfigTemplate {
|
||||
#[serde(rename = "ID")]
|
||||
pub id: MainCityBgmConfigID,
|
||||
pub play_event_name: String,
|
||||
pub state_name: String,
|
||||
}
|
|
@ -84,6 +84,7 @@ template_tables! {
|
|||
WeaponTemplate;
|
||||
MainCityObjectTemplate;
|
||||
MainCityDefaultObjectTemplate;
|
||||
MainCityBgmConfigTemplate;
|
||||
ArchiveFileQuestTemplate;
|
||||
ArchiveBattleQuestTemplate;
|
||||
}
|
||||
|
|
|
@ -41,3 +41,4 @@ tracing-bunyan-formatter.workspace = true
|
|||
common.workspace = true
|
||||
data.workspace = true
|
||||
proto.workspace = true
|
||||
chrono = { version = "0.4.38", features = ["serde"] }
|
||||
|
|
|
@ -87,5 +87,6 @@ impl CommandManager {
|
|||
player::procedure "[player_uid] [procedure_id]" "changes current beginner procedure id, parameter -1 can be used for skipping it";
|
||||
avatar::add "[player_uid] [avatar_id]" "gives avatar with specified id to player";
|
||||
item::add_weapon "[player_uid] [weapon_id]" "gives weapon with specified id to player";
|
||||
player::kick "[player_uid] [reason]" "kick the specified player (reason is optional)";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use data::tables::{AvatarBaseID, ProcedureConfigID};
|
||||
use proto::PlayerSyncScNotify;
|
||||
use proto::{DisconnectReason, DisconnectScNotify, PlayerSyncScNotify};
|
||||
|
||||
use crate::ServerState;
|
||||
|
||||
|
@ -126,3 +126,45 @@ pub async fn procedure(
|
|||
"successfully changed procedure_id to {procedure_id:?}"
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn kick(
|
||||
args: ArgSlice<'_>,
|
||||
state: &ServerState,
|
||||
) -> Result<String, Box<dyn std::error::Error>> {
|
||||
const USAGE: &str = "Usage: player kick [player_uid]";
|
||||
|
||||
if args.len() > 2 {
|
||||
return Ok(USAGE.to_string());
|
||||
}
|
||||
|
||||
let uid = args[0].parse::<u32>()?;
|
||||
let default_reason = DisconnectReason::ServerKick.into();
|
||||
let reason = match args.get(1) {
|
||||
Some(arg) => match arg.parse::<i32>() {
|
||||
Ok(val) => val,
|
||||
Err(_err) => default_reason,
|
||||
},
|
||||
None => default_reason,
|
||||
};
|
||||
let reason_str = match DisconnectReason::try_from(reason) {
|
||||
Ok(converted_enum) => converted_enum.as_str_name().to_owned(),
|
||||
Err(_err) => reason.to_string(),
|
||||
};
|
||||
|
||||
let Some(player_lock) = state.player_mgr.get_player(uid).await else {
|
||||
return Ok(String::from("player not found"));
|
||||
};
|
||||
|
||||
let session_id = player_lock.lock().await.current_session_id();
|
||||
|
||||
if let Some(session) = session_id.map(|id| state.session_mgr.get(id)).flatten() {
|
||||
session
|
||||
.notify(DisconnectScNotify { reason: reason })
|
||||
.await?;
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
|
||||
session.shutdown().await?;
|
||||
Ok(format!("kicked player, uid: {uid}, reason: {reason_str}"))
|
||||
} else {
|
||||
Ok(format!("player uid: {uid} is not online yet."))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ impl Default for NapGSConfig {
|
|||
filecfg_path: String::from("assets/FileCfg"),
|
||||
event_config_path: String::from("assets/EventConfig"),
|
||||
usm_keys_path: String::from("assets/VideoUSMEncKeys.json"),
|
||||
gacha_config_path: String::from("assets/GachaConfig"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,620 @@
|
|||
use std::{
|
||||
cmp::min,
|
||||
collections::{
|
||||
hash_map::Entry::{Occupied, Vacant},
|
||||
HashSet,
|
||||
},
|
||||
};
|
||||
|
||||
use data::{
|
||||
gacha::{gacha_config::*, global_gacha_config},
|
||||
tables::{AvatarBaseID, WeaponID},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use chrono::{DateTime, Local};
|
||||
use proto::*;
|
||||
|
||||
pub async fn on_get_gacha_data(
|
||||
_session: &NetSession,
|
||||
_player: &mut Player,
|
||||
req: GetGachaDataCsReq,
|
||||
) -> NetResult<GetGachaDataScRsp> {
|
||||
if req.gacha_type != 3 {
|
||||
// tracing::info!("non-supported gacha type {}", body.gacha_type);
|
||||
Ok(GetGachaDataScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
gacha_type: req.gacha_type,
|
||||
gacha_data: Some(GachaData::default()),
|
||||
})
|
||||
} else {
|
||||
// tracing::info!("construct gacha info");
|
||||
Ok(GetGachaDataScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
gacha_type: req.gacha_type,
|
||||
gacha_data: Some(generate_all_gacha_info(_player, &Local::now())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn on_do_gacha(
|
||||
_session: &NetSession,
|
||||
_player: &mut Player,
|
||||
req: DoGachaCsReq,
|
||||
) -> NetResult<DoGachaScRsp> {
|
||||
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,
|
||||
&req.gacha_parent_schedule_id,
|
||||
&pull_time,
|
||||
);
|
||||
if let None = target_pool {
|
||||
tracing::info!(
|
||||
"refuse gacha because: pool of parent_schedule_id {} not found",
|
||||
req.gacha_parent_schedule_id
|
||||
);
|
||||
return Ok(DoGachaScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
};
|
||||
let target_pool = target_pool.unwrap();
|
||||
|
||||
// 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;
|
||||
if target_pool.discount_policy_tags.contains(&discount_tag) {
|
||||
let gacha_bin = &mut gacha_model.gacha_bin;
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap();
|
||||
let discount_policy = gachaconf
|
||||
.discount_policies
|
||||
.ten_pull_discount_map
|
||||
.get(discount_tag)
|
||||
.unwrap();
|
||||
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 {
|
||||
tracing::info!(
|
||||
"refuse gacha because: expected cost item {cost_count}, found {}",
|
||||
req.cost_item_count
|
||||
);
|
||||
return Ok(DoGachaScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
} else {
|
||||
// TODO: cost resource
|
||||
}
|
||||
|
||||
let mut gain_item_list: Vec<GainItemInfo> = 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.clone().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()
|
||||
});
|
||||
pull_count -= 1;
|
||||
gacha_model.gacha_bin.gacha_records.push(pull_result);
|
||||
}
|
||||
|
||||
Ok(DoGachaScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
gain_item_list,
|
||||
gacha_data: Some(generate_all_gacha_info(_player, &pull_time)),
|
||||
cost_item_count: req.cost_item_count,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn on_gacha_free_agent(
|
||||
_session: &NetSession,
|
||||
_player: &mut Player,
|
||||
req: GachaFreeAgentCsReq,
|
||||
) -> NetResult<GachaFreeAgentScRsp> {
|
||||
let gachaconf = global_gacha_config();
|
||||
let gacha_model = &mut _player.gacha_model;
|
||||
let role_model = &mut _player.role_model;
|
||||
let pull_time = Local::now();
|
||||
let target_pool = get_gacha_pool(
|
||||
&gachaconf.character_gacha_pool_list,
|
||||
&req.gacha_parent_schedule_id,
|
||||
&pull_time,
|
||||
);
|
||||
if let None = target_pool {
|
||||
tracing::info!(
|
||||
"refuse free agent because: pool of parent_schedule_id {} not found",
|
||||
req.gacha_parent_schedule_id
|
||||
);
|
||||
return Ok(GachaFreeAgentScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
};
|
||||
let target_pool = target_pool.unwrap();
|
||||
let gacha_bin = &mut _player.gacha_model.gacha_bin;
|
||||
let sharing_guarantee_category_tag = &target_pool.sharing_guarantee_info_category;
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(sharing_guarantee_category_tag)
|
||||
.unwrap();
|
||||
|
||||
let mut free_select_policy: Option<&FreeSelectItem> = None;
|
||||
let mut free_select_progress: u32 = 0;
|
||||
let mut free_select_required_pull: u32 = 0;
|
||||
for discount_policy_tag in target_pool.discount_policy_tags.iter() {
|
||||
if gachaconf
|
||||
.discount_policies
|
||||
.free_select_map
|
||||
.contains_key(discount_policy_tag)
|
||||
{
|
||||
let policy = gachaconf
|
||||
.discount_policies
|
||||
.free_select_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap();
|
||||
let free_select_demand_idx = usize::try_from(
|
||||
*(status_bin
|
||||
.discount_usage_map
|
||||
.get(&policy.free_select_usage_record_tag)
|
||||
.unwrap()),
|
||||
)
|
||||
.unwrap();
|
||||
if policy.milestones.len() <= free_select_demand_idx {
|
||||
continue;
|
||||
}
|
||||
|
||||
let free_select_actual_progress = status_bin
|
||||
.discount_usage_map
|
||||
.get(&policy.free_select_progress_record_tag)
|
||||
.unwrap();
|
||||
free_select_policy = Some(policy);
|
||||
free_select_required_pull = policy
|
||||
.milestones
|
||||
.get(free_select_demand_idx)
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
free_select_progress = min(free_select_required_pull, *free_select_actual_progress);
|
||||
}
|
||||
}
|
||||
|
||||
if let None = free_select_policy {
|
||||
tracing::info!(
|
||||
"refuse free agent because: pool of parent_schedule_id {} hasn't defined free agent discount yet (or used up chance)",
|
||||
req.gacha_parent_schedule_id
|
||||
);
|
||||
return Ok(GachaFreeAgentScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
} else if free_select_progress < free_select_required_pull {
|
||||
tracing::info!(
|
||||
"refuse free agent because: use pulled {free_select_progress} (after last free agent) in parent_schedule_id {}, required {free_select_required_pull}",
|
||||
req.gacha_parent_schedule_id
|
||||
);
|
||||
return Ok(GachaFreeAgentScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
let free_select_policy = free_select_policy.unwrap();
|
||||
let mut has_demanded_item = false;
|
||||
for rarity_items in target_pool.gacha_items.iter() {
|
||||
if rarity_items.rarity != free_select_policy.rarity {
|
||||
continue;
|
||||
}
|
||||
for (category_tag, category) in rarity_items.categories.iter() {
|
||||
if !free_select_policy.category_tags.contains(category_tag) {
|
||||
continue;
|
||||
}
|
||||
has_demanded_item |= category.item_ids.contains(&req.avatar_id);
|
||||
}
|
||||
}
|
||||
if !has_demanded_item {
|
||||
tracing::info!(
|
||||
"refuse free agent because: pool of parent_schedule_id {} doesn't have demanded item {}",
|
||||
req.gacha_parent_schedule_id, req.avatar_id
|
||||
);
|
||||
return Ok(GachaFreeAgentScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
role_model.add_avatar(AvatarBaseID::new(req.avatar_id).unwrap());
|
||||
(*status_bin
|
||||
.discount_usage_map
|
||||
.get_mut(&free_select_policy.free_select_usage_record_tag)
|
||||
.unwrap()) += 1;
|
||||
(*status_bin
|
||||
.discount_usage_map
|
||||
.get_mut(&free_select_policy.free_select_progress_record_tag)
|
||||
.unwrap()) -= free_select_required_pull;
|
||||
|
||||
Ok(GachaFreeAgentScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn on_choose_gacha_up(
|
||||
_session: &NetSession,
|
||||
_player: &mut Player,
|
||||
req: ChooseGachaUpCsReq,
|
||||
) -> NetResult<ChooseGachaUpScRsp> {
|
||||
let gachaconf = global_gacha_config();
|
||||
let gacha_model = &mut _player.gacha_model;
|
||||
let pull_time = Local::now();
|
||||
let target_pool = get_gacha_pool(
|
||||
&gachaconf.character_gacha_pool_list,
|
||||
&req.gacha_parent_schedule_id,
|
||||
&pull_time,
|
||||
);
|
||||
if let None = target_pool {
|
||||
return Ok(ChooseGachaUpScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
};
|
||||
let target_pool = target_pool.unwrap();
|
||||
|
||||
for rarity_items in target_pool.gacha_items.iter() {
|
||||
if rarity_items.rarity != gachaconf.common_properties.s_item_rarity {
|
||||
continue;
|
||||
}
|
||||
for guarantee_policy_tag in rarity_items.category_guarantee_policy_tags.iter() {
|
||||
let category_guarantee_policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(guarantee_policy_tag)
|
||||
.unwrap();
|
||||
if !category_guarantee_policy.chooseable {
|
||||
continue;
|
||||
}
|
||||
let mut up_category: Option<&String> = None;
|
||||
for (category_tag, category) in rarity_items.categories.iter() {
|
||||
if category.item_ids.contains(&req.item_id) {
|
||||
up_category = Some(category_tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let None = up_category {
|
||||
return Ok(ChooseGachaUpScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
});
|
||||
};
|
||||
let up_category = up_category.unwrap();
|
||||
|
||||
let progress_bin = gacha_model
|
||||
.gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap()
|
||||
.rarity_status_map
|
||||
.get_mut(&rarity_items.rarity)
|
||||
.unwrap();
|
||||
match progress_bin
|
||||
.categories_chosen_guarantee_item_map
|
||||
.entry(guarantee_policy_tag.clone())
|
||||
{
|
||||
Occupied(mut occupied_entry) => {
|
||||
occupied_entry.insert(req.item_id);
|
||||
}
|
||||
Vacant(vacant_entry) => {
|
||||
vacant_entry.insert(req.item_id);
|
||||
}
|
||||
};
|
||||
match progress_bin
|
||||
.categories_chosen_guarantee_category_map
|
||||
.entry(up_category.clone())
|
||||
{
|
||||
Occupied(mut occupied_entry) => {
|
||||
occupied_entry.insert(up_category.clone());
|
||||
}
|
||||
Vacant(vacant_entry) => {
|
||||
vacant_entry.insert(up_category.clone());
|
||||
}
|
||||
};
|
||||
return Ok(ChooseGachaUpScRsp {
|
||||
retcode: Retcode::RetSucc.into(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ChooseGachaUpScRsp {
|
||||
retcode: Retcode::RetFail.into(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
fn generate_gacha_info_from_pool(
|
||||
gacha_bin: &GachaModelBin,
|
||||
target_pool: &CharacterGachaPool,
|
||||
common_properties: &GachaCommonProperties,
|
||||
) -> Gacha {
|
||||
let gachaconf = data::gacha::global_gacha_config();
|
||||
let sharing_guarantee_category_tag = &target_pool.sharing_guarantee_info_category;
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get(sharing_guarantee_category_tag)
|
||||
.unwrap();
|
||||
let pity_s = status_bin
|
||||
.rarity_status_map
|
||||
.get(&common_properties.s_item_rarity)
|
||||
.unwrap()
|
||||
.pity;
|
||||
let pity_a = status_bin
|
||||
.rarity_status_map
|
||||
.get(&common_properties.a_item_rarity)
|
||||
.unwrap()
|
||||
.pity;
|
||||
|
||||
let mut discount_ten_roll_prize: u32 = 0;
|
||||
let mut discount_avaliable_num: u32 = 0;
|
||||
let mut advanced_s_guarantee: u32 = 0;
|
||||
let mut free_select_progress: u32 = 0;
|
||||
let mut free_select_required_pull: u32 = 0;
|
||||
let mut free_select_policy: Option<&FreeSelectItem> = None;
|
||||
for discount_policy_tag in target_pool.discount_policy_tags.iter() {
|
||||
if common_properties.newcomer_advanced_s_tag == *discount_policy_tag {
|
||||
let policy = gachaconf
|
||||
.discount_policies
|
||||
.advanced_guarantee_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap();
|
||||
if status_bin
|
||||
.discount_usage_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap()
|
||||
< &policy.use_limit
|
||||
{
|
||||
advanced_s_guarantee = policy.guarantee_pity - pity_s + 1;
|
||||
}
|
||||
} else if common_properties.ten_pull_discount_tag == *discount_policy_tag {
|
||||
let policy = gachaconf
|
||||
.discount_policies
|
||||
.ten_pull_discount_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap();
|
||||
let discount_usage = status_bin
|
||||
.discount_usage_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap();
|
||||
if discount_usage < &policy.use_limit {
|
||||
discount_ten_roll_prize = policy.discounted_prize;
|
||||
discount_avaliable_num = policy.use_limit - discount_usage;
|
||||
}
|
||||
} else if gachaconf
|
||||
.discount_policies
|
||||
.free_select_map
|
||||
.contains_key(discount_policy_tag)
|
||||
{
|
||||
let policy = gachaconf
|
||||
.discount_policies
|
||||
.free_select_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap();
|
||||
let free_select_demand_idx = usize::try_from(
|
||||
*(status_bin
|
||||
.discount_usage_map
|
||||
.get(&policy.free_select_usage_record_tag)
|
||||
.unwrap()),
|
||||
)
|
||||
.unwrap();
|
||||
if policy.milestones.len() <= free_select_demand_idx {
|
||||
continue;
|
||||
}
|
||||
|
||||
let free_select_actual_progress = status_bin
|
||||
.discount_usage_map
|
||||
.get(&policy.free_select_progress_record_tag)
|
||||
.unwrap();
|
||||
free_select_policy = Some(policy);
|
||||
free_select_required_pull = policy
|
||||
.milestones
|
||||
.get(free_select_demand_idx)
|
||||
.unwrap()
|
||||
.to_owned();
|
||||
free_select_progress = min(free_select_required_pull, *free_select_actual_progress);
|
||||
}
|
||||
}
|
||||
|
||||
let mut up_s_item_list: Vec<u32> = vec![];
|
||||
let mut up_a_item_list: Vec<u32> = vec![];
|
||||
let mut free_select_item_list: Vec<u32> = vec![];
|
||||
let mut chooseable_up_list: Vec<u32> = vec![];
|
||||
let mut chosen_up_item: u32 = 0;
|
||||
let mut s_guarantee: u32 = 0;
|
||||
let mut a_guarantee: u32 = 0;
|
||||
for rarity_items in target_pool.gacha_items.iter() {
|
||||
let mut chooseable_up_included_category_tags: Option<&HashSet<String>> = None;
|
||||
let mut chooseable_policy_tag: Option<&String> = None;
|
||||
for guarantee_policy_tag in rarity_items.category_guarantee_policy_tags.iter() {
|
||||
let category_guarantee_policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(guarantee_policy_tag)
|
||||
.unwrap();
|
||||
if !category_guarantee_policy.chooseable {
|
||||
continue;
|
||||
}
|
||||
chooseable_policy_tag = Some(guarantee_policy_tag);
|
||||
chooseable_up_included_category_tags =
|
||||
Some(&category_guarantee_policy.included_category_tags);
|
||||
if let Some(item) = status_bin
|
||||
.rarity_status_map
|
||||
.get(&rarity_items.rarity)
|
||||
.unwrap()
|
||||
.categories_chosen_guarantee_item_map
|
||||
.get(guarantee_policy_tag)
|
||||
{
|
||||
chosen_up_item = item.clone();
|
||||
}
|
||||
}
|
||||
|
||||
for (category_tag, category) in rarity_items.categories.iter() {
|
||||
let probability_model = gachaconf
|
||||
.probability_model_map
|
||||
.get(&rarity_items.probability_model_tag)
|
||||
.unwrap();
|
||||
let maximum_pity = &probability_model.maximum_guarantee_pity;
|
||||
if rarity_items.rarity == common_properties.s_item_rarity {
|
||||
if category.is_promotional_items {
|
||||
up_s_item_list = category.item_ids.clone();
|
||||
}
|
||||
// tracing::info!("pity_s: {pity_s}");
|
||||
// thread 'tokio-runtime-worker' panicked at nap_gameserver\src\handlers\gacha.rs:369:31:
|
||||
// attempt to subtract with overflow
|
||||
s_guarantee = maximum_pity - min(pity_s, maximum_pity.clone()) + 1;
|
||||
}
|
||||
if rarity_items.rarity == common_properties.a_item_rarity {
|
||||
if category.is_promotional_items {
|
||||
up_a_item_list = category.item_ids.clone();
|
||||
}
|
||||
// tracing::info!("pity_a: {pity_a}");
|
||||
a_guarantee = maximum_pity - min(pity_a, maximum_pity.clone()) + 1;
|
||||
}
|
||||
|
||||
if let Some(val) = free_select_policy {
|
||||
if val.rarity == rarity_items.rarity && val.category_tags.contains(category_tag) {
|
||||
free_select_item_list.append(&mut category.item_ids.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(tags) = chooseable_up_included_category_tags {
|
||||
if tags.contains(category_tag) {
|
||||
chooseable_up_list.append(&mut category.item_ids.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(priority_policy_tag) = chooseable_policy_tag {
|
||||
// if let Some(item) = status_bin
|
||||
// .rarity_status_map
|
||||
// .get(&rarity_items.rarity)
|
||||
// .unwrap()
|
||||
// .categories_chosen_guarantee_item_map
|
||||
// .get(priority_policy_tag)
|
||||
// {
|
||||
if rarity_items.rarity == gachaconf.common_properties.s_item_rarity {
|
||||
up_s_item_list = vec![];
|
||||
} else if rarity_items.rarity == gachaconf.common_properties.a_item_rarity {
|
||||
up_a_item_list = vec![];
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
let need_item_info_list: Vec<NeedItemInfo> = vec![NeedItemInfo {
|
||||
need_item_id: target_pool.cost_item_id,
|
||||
need_item_count: 1,
|
||||
}];
|
||||
|
||||
let mut result = Gacha {
|
||||
gacha_schedule_id: target_pool.gacha_schedule_id,
|
||||
gacha_parent_schedule_id: target_pool.gacha_parent_schedule_id,
|
||||
gacha_type: target_pool.gacha_type,
|
||||
start_timestamp: target_pool.start_time.timestamp(),
|
||||
end_timestamp: target_pool.end_time.timestamp(),
|
||||
discount_avaliable_num,
|
||||
discount_ten_roll_prize,
|
||||
advanced_s_guarantee,
|
||||
s_guarantee,
|
||||
a_guarantee,
|
||||
need_item_info_list,
|
||||
free_select_progress,
|
||||
free_select_required_pull,
|
||||
free_select_item_list,
|
||||
chosen_up_item,
|
||||
// nammdglepbk: 563,
|
||||
// hgmcofcjmbg: 101,
|
||||
// akggbhgkifd: chooseable_up_list.clone(),
|
||||
chooseable_up_list,
|
||||
..Gacha::default()
|
||||
};
|
||||
if up_s_item_list.len() > 0 {
|
||||
result.up_s_item_list = up_s_item_list;
|
||||
}
|
||||
if up_a_item_list.len() > 0 {
|
||||
result.up_a_item_list = up_a_item_list;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn generate_all_gacha_info(_player: &Player, now: &DateTime<Local>) -> GachaData {
|
||||
let gachaconf = global_gacha_config();
|
||||
let gacha_bin = &_player.gacha_model.gacha_bin;
|
||||
let mut gacha_list: Vec<Gacha> = vec![];
|
||||
for target_pool in gachaconf.character_gacha_pool_list.iter() {
|
||||
if target_pool.is_still_open(now) {
|
||||
gacha_list.push(generate_gacha_info_from_pool(
|
||||
&gacha_bin,
|
||||
target_pool,
|
||||
&gachaconf.common_properties,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// tracing::info!("gacha_list: {:?}", gacha_list);
|
||||
GachaData {
|
||||
random_number: 6167,
|
||||
gacha_pool: Some(GachaPool { gacha_list }),
|
||||
..GachaData::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_gacha_pool<'conf>(
|
||||
character_gacha_pool_list: &'conf Vec<CharacterGachaPool>,
|
||||
gacha_parent_schedule_id: &u32,
|
||||
pull_time: &DateTime<Local>,
|
||||
) -> Option<&'conf CharacterGachaPool> {
|
||||
for target_pool in character_gacha_pool_list.iter() {
|
||||
if &target_pool.gacha_parent_schedule_id == gacha_parent_schedule_id
|
||||
&& target_pool.is_still_open(pull_time)
|
||||
{
|
||||
return Some(target_pool);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -119,6 +119,9 @@ req_handlers! {
|
|||
event_graph::RunEventGraph;
|
||||
quest::BeginArchiveBattleQuest;
|
||||
quest::FinishArchiveQuest;
|
||||
gacha::DoGacha;
|
||||
gacha::ChooseGachaUp;
|
||||
gacha::GachaFreeAgent;
|
||||
}
|
||||
|
||||
notify_handlers! {
|
||||
|
|
|
@ -85,7 +85,12 @@ pub async fn on_begin_archive_battle_quest(
|
|||
let quest_id = ArchiveBattleQuestID::new(req.quest_id).ok_or(Retcode::RetFail)?;
|
||||
|
||||
player.game_instance = GameInstance::Hollow(
|
||||
HollowGame::create_archive_battle(quest_id, ELocalPlayType::ArchiveBattle, &req.avatars)
|
||||
HollowGame::create_archive_battle(
|
||||
quest_id,
|
||||
ELocalPlayType::ArchiveBattle,
|
||||
&req.avatars,
|
||||
req.buddy_id,
|
||||
)
|
||||
.map_err(LogicError::from)?,
|
||||
);
|
||||
|
||||
|
|
25
nap_gameserver/src/logic/battle/buddy.rs
Normal file
25
nap_gameserver/src/logic/battle/buddy.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use proto::EquippedBuddyData;
|
||||
|
||||
use crate::logic::{BaseProperty, BuddyTeamType};
|
||||
|
||||
pub struct EquippedBuddyDataItem {
|
||||
pub buddy_id: u32,
|
||||
pub buddy_team: BuddyTeamType,
|
||||
pub override_property_map: HashMap<BaseProperty, i32>,
|
||||
}
|
||||
|
||||
impl EquippedBuddyDataItem {
|
||||
pub fn to_client(&self) -> EquippedBuddyData {
|
||||
EquippedBuddyData {
|
||||
buddy_id: self.buddy_id,
|
||||
r#type: self.buddy_team.to_protocol().into(),
|
||||
mp_property_override_map: self
|
||||
.override_property_map
|
||||
.iter()
|
||||
.map(|(prop, value)| (*prop as u32, *value))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
mod avatar;
|
||||
pub use avatar::InLevelAvatarDataItem;
|
||||
mod buddy;
|
||||
mod team;
|
||||
|
||||
pub use avatar::InLevelAvatarDataItem;
|
||||
pub use buddy::EquippedBuddyDataItem;
|
||||
pub use team::TeamDataItem;
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use super::InLevelAvatarDataItem;
|
||||
use crate::logic::BuddyTeamType;
|
||||
|
||||
use super::{EquippedBuddyDataItem, InLevelAvatarDataItem};
|
||||
|
||||
pub struct TeamDataItem {
|
||||
pub avatar_member_list: Vec<InLevelAvatarDataItem>,
|
||||
pub equipped_buddy_list: Vec<EquippedBuddyDataItem>,
|
||||
}
|
||||
|
||||
impl TeamDataItem {
|
||||
pub fn new(avatars: &[u32]) -> Self {
|
||||
pub fn new(avatars: &[u32], buddy_id: u32) -> Self {
|
||||
Self {
|
||||
avatar_member_list: avatars
|
||||
.iter()
|
||||
|
@ -16,6 +19,13 @@ impl TeamDataItem {
|
|||
mp_property_override: HashMap::new(),
|
||||
})
|
||||
.collect(),
|
||||
equipped_buddy_list: (buddy_id != 0)
|
||||
.then_some(vec![EquippedBuddyDataItem {
|
||||
buddy_id,
|
||||
buddy_team: BuddyTeamType::Assisting,
|
||||
override_property_map: HashMap::new(),
|
||||
}])
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,3 +259,22 @@ pub enum BaseProperty {
|
|||
Luck = 5,
|
||||
AllDamageResist = 43,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(i32)]
|
||||
pub enum BuddyTeamType {
|
||||
Unknown = 0,
|
||||
Fighting = 1,
|
||||
Assisting = 2,
|
||||
}
|
||||
|
||||
impl BuddyTeamType {
|
||||
pub fn to_protocol(&self) -> ::proto::BuddyTeamType {
|
||||
match *self {
|
||||
Self::Unknown => ::proto::BuddyTeamType::Unknown,
|
||||
Self::Fighting => ::proto::BuddyTeamType::Fighting,
|
||||
Self::Assisting => ::proto::BuddyTeamType::Assisting,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
505
nap_gameserver/src/logic/gacha/gacha_model.rs
Normal file
505
nap_gameserver/src/logic/gacha/gacha_model.rs
Normal file
|
@ -0,0 +1,505 @@
|
|||
use data::gacha;
|
||||
use data::gacha::gacha_config::*;
|
||||
use proto::*;
|
||||
|
||||
use chrono::{DateTime, Local};
|
||||
use rand::{thread_rng, Rng};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
|
||||
pub struct GachaModel {
|
||||
pub gacha_bin: GachaModelBin,
|
||||
}
|
||||
|
||||
impl Default for GachaModel {
|
||||
fn default() -> GachaModel {
|
||||
let result = GachaModel {
|
||||
gacha_bin: GachaModelBin::default(),
|
||||
};
|
||||
result.post_deserialize()
|
||||
}
|
||||
}
|
||||
|
||||
impl GachaModel {
|
||||
pub fn from_bin(gacha_bin: GachaModelBin) -> Self {
|
||||
let result = Self { gacha_bin };
|
||||
result.post_deserialize()
|
||||
}
|
||||
|
||||
pub fn to_bin(&self) -> GachaModelBin {
|
||||
self.gacha_bin.clone()
|
||||
}
|
||||
|
||||
pub fn post_deserialize(mut self) -> GachaModel {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
for gacha_pool in gachaconf.character_gacha_pool_list.iter() {
|
||||
let gacha_comp_bin = &mut self.gacha_bin;
|
||||
let mut gacha_status_map = &mut gacha_comp_bin.gacha_status_map;
|
||||
let status_bin = get_or_add(
|
||||
&mut gacha_status_map,
|
||||
&gacha_pool.sharing_guarantee_info_category,
|
||||
);
|
||||
for rarity_items in gacha_pool.gacha_items.iter() {
|
||||
let progress_bin =
|
||||
get_or_add(&mut status_bin.rarity_status_map, &rarity_items.rarity);
|
||||
if progress_bin.pity <= 0 {
|
||||
progress_bin.pity = 1;
|
||||
}
|
||||
for category_guarantee_policy_tag in
|
||||
rarity_items.category_guarantee_policy_tags.iter()
|
||||
{
|
||||
get_or_add(
|
||||
&mut progress_bin.categories_progress_map,
|
||||
&category_guarantee_policy_tag,
|
||||
);
|
||||
|
||||
let guarantee_policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(category_guarantee_policy_tag)
|
||||
.unwrap();
|
||||
if !guarantee_policy.chooseable {
|
||||
continue;
|
||||
}
|
||||
get_or_add(
|
||||
&mut progress_bin.categories_chosen_guarantee_progress_map,
|
||||
&category_guarantee_policy_tag,
|
||||
);
|
||||
}
|
||||
}
|
||||
for discount_policy_tag in gacha_pool.discount_policy_tags.iter() {
|
||||
if gachaconf
|
||||
.discount_policies
|
||||
.free_select_map
|
||||
.contains_key(discount_policy_tag)
|
||||
{
|
||||
let policy = gachaconf
|
||||
.discount_policies
|
||||
.free_select_map
|
||||
.get(discount_policy_tag)
|
||||
.unwrap();
|
||||
get_or_add(
|
||||
&mut status_bin.discount_usage_map,
|
||||
&policy.free_select_progress_record_tag,
|
||||
);
|
||||
get_or_add(
|
||||
&mut status_bin.discount_usage_map,
|
||||
&policy.free_select_usage_record_tag,
|
||||
);
|
||||
} else {
|
||||
get_or_add(&mut status_bin.discount_usage_map, &discount_policy_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn perform_pull_pool<'bin, 'conf>(
|
||||
&'bin mut self,
|
||||
pull_time: &DateTime<Local>,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
) -> GachaRecordBin {
|
||||
let mut gacha_bin = &mut self.gacha_bin;
|
||||
let (rarity_items, progress_bin, status_bin, probability_model) =
|
||||
determine_rarity(&gacha_bin, target_pool);
|
||||
let (category_tag, category) = determine_category(rarity_items, progress_bin, target_pool);
|
||||
let result = determine_gacha_result(
|
||||
pull_time,
|
||||
category,
|
||||
target_pool,
|
||||
status_bin,
|
||||
progress_bin,
|
||||
rarity_items,
|
||||
);
|
||||
update_pity(&mut gacha_bin, rarity_items, probability_model, target_pool);
|
||||
update_category_guarantee_info(&mut gacha_bin, rarity_items, &category_tag, target_pool);
|
||||
update_discount(&mut gacha_bin, target_pool, &category_tag, rarity_items);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
fn get_or_add<'a, K: Eq + PartialEq + Hash + Clone, V: Default, S: BuildHasher>(
|
||||
map: &'a mut HashMap<K, V, S>,
|
||||
key: &K,
|
||||
) -> &'a mut V {
|
||||
if !map.contains_key(key) {
|
||||
map.insert(key.clone(), V::default());
|
||||
}
|
||||
map.get_mut(key).unwrap()
|
||||
}
|
||||
|
||||
fn rand_rarity<'bin, 'conf>(
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
status_bin: &'bin GachaStatusBin,
|
||||
) -> (
|
||||
&'conf GachaAvailableItemsInfo,
|
||||
&'bin GachaProgressBin,
|
||||
&'conf ProbabilityModel,
|
||||
) {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
let mut rng = thread_rng();
|
||||
let rarity_status_map = &status_bin.rarity_status_map;
|
||||
// gacha_items is already sorted by rarity descendingly in its post_configure.
|
||||
for rarity_items in target_pool.gacha_items.iter() {
|
||||
// Surely any judgement should be made on the current pity.
|
||||
let progress_bin = rarity_status_map.get(&rarity_items.rarity).unwrap();
|
||||
let pity = progress_bin.pity;
|
||||
let probability_model = gachaconf
|
||||
.probability_model_map
|
||||
.get(&rarity_items.probability_model_tag)
|
||||
.unwrap();
|
||||
if rng.gen_range(0.0..100.0) <= probability_model.get_chance_percent(&pity) {
|
||||
return (rarity_items, progress_bin, probability_model);
|
||||
}
|
||||
}
|
||||
panic!("The user failed to get any items.");
|
||||
}
|
||||
|
||||
fn determine_rarity<'bin, 'conf>(
|
||||
gacha_bin: &'bin GachaModelBin,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
) -> (
|
||||
&'conf GachaAvailableItemsInfo,
|
||||
&'bin GachaProgressBin,
|
||||
&'bin GachaStatusBin,
|
||||
&'conf ProbabilityModel,
|
||||
) {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get(&target_pool.sharing_guarantee_info_category)
|
||||
.expect(&format!(
|
||||
"post_deserialize forgot StatusBin/sharing_guarantee_info_category: {}",
|
||||
target_pool.sharing_guarantee_info_category
|
||||
));
|
||||
let (mut rarity_items, mut progress_bin, mut probability_model) =
|
||||
rand_rarity(target_pool, &status_bin);
|
||||
|
||||
// We should take AdvancedGuarantee discount into consideration.
|
||||
for discount_tag in target_pool.discount_policy_tags.iter() {
|
||||
if let Some(discount) = gachaconf
|
||||
.discount_policies
|
||||
.advanced_guarantee_map
|
||||
.get(discount_tag)
|
||||
{
|
||||
if discount.rarity <= rarity_items.rarity {
|
||||
continue;
|
||||
}
|
||||
if status_bin
|
||||
.discount_usage_map
|
||||
.get(discount_tag)
|
||||
.expect(&format!(
|
||||
"post_deserialize forgot StatusBin/discount_usage_map: {}",
|
||||
discount_tag
|
||||
))
|
||||
>= &discount.use_limit
|
||||
{
|
||||
continue;
|
||||
}
|
||||
let higher_progress_bin =
|
||||
status_bin
|
||||
.rarity_status_map
|
||||
.get(&discount.rarity)
|
||||
.expect(&format!(
|
||||
"post_deserialize forgot StatusBin/rarity_status_map: {}",
|
||||
&discount.rarity
|
||||
));
|
||||
if higher_progress_bin.pity >= discount.guarantee_pity {
|
||||
let mut found_rarity_items = false;
|
||||
for gacha_items in target_pool.gacha_items.iter() {
|
||||
if gacha_items.rarity == discount.rarity {
|
||||
rarity_items = gacha_items;
|
||||
probability_model = gachaconf
|
||||
.probability_model_map
|
||||
.get(&gacha_items.probability_model_tag)
|
||||
.unwrap();
|
||||
found_rarity_items = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert!(found_rarity_items, "Handle AdvancedGuarantee Discount ({discount_tag}) error: The target rarity does not exist in this pool.");
|
||||
progress_bin = higher_progress_bin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(rarity_items, progress_bin, status_bin, probability_model)
|
||||
}
|
||||
|
||||
fn determine_category<'bin, 'conf>(
|
||||
rarity_items: &'conf GachaAvailableItemsInfo,
|
||||
progress_bin: &'bin GachaProgressBin,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
) -> (String, &'conf GachaCategoryInfo) {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
let mut category_tag_inited = false;
|
||||
let mut category_tag_result: HashSet<String> = HashSet::new();
|
||||
// First of all, if there's a chooseable category and
|
||||
// it is SELECTED then we MUST give that category's item.
|
||||
for guarantee_policy_tag in rarity_items.category_guarantee_policy_tags.iter() {
|
||||
let category_guarantee_policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(guarantee_policy_tag)
|
||||
.unwrap();
|
||||
if !category_guarantee_policy.chooseable {
|
||||
continue;
|
||||
}
|
||||
// As we found a policy defined chooseable, we
|
||||
// should head to look whether the user chose
|
||||
// the category he want.
|
||||
if let Some(category_tag) = progress_bin
|
||||
.categories_chosen_guarantee_category_map
|
||||
.get(guarantee_policy_tag)
|
||||
{
|
||||
// User chose a category; our work are done here.
|
||||
category_tag_result.insert(category_tag.clone());
|
||||
category_tag_inited = true;
|
||||
}
|
||||
}
|
||||
// Then we should take a look at MustGainItem.
|
||||
if !category_tag_inited {
|
||||
for discount_policy_tag in target_pool.discount_policy_tags.iter() {
|
||||
if let Some(discount) = gachaconf
|
||||
.discount_policies
|
||||
.must_gain_item_map
|
||||
.get(discount_policy_tag)
|
||||
{
|
||||
if discount.rarity != rarity_items.rarity {
|
||||
continue;
|
||||
}
|
||||
category_tag_result.insert(discount.category_tag.clone());
|
||||
category_tag_inited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise, just select as normal.
|
||||
if !category_tag_inited {
|
||||
for tag in rarity_items.categories.keys() {
|
||||
category_tag_result.insert(tag.clone());
|
||||
}
|
||||
for guarantee_policy_tag in rarity_items.category_guarantee_policy_tags.iter() {
|
||||
let category_guarantee_policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(guarantee_policy_tag)
|
||||
.unwrap();
|
||||
let failure_times = progress_bin.categories_progress_map
|
||||
.get(guarantee_policy_tag)
|
||||
.expect(&format!("post_deserialize forgot StatusBin/rarity_status_map[{}]/categories_progress_map: {}", &rarity_items.rarity, guarantee_policy_tag));
|
||||
if failure_times >= &category_guarantee_policy.trigger_on_failure_times {
|
||||
category_tag_result = category_tag_result
|
||||
.intersection(&category_guarantee_policy.included_category_tags)
|
||||
.cloned()
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
// category_tag_inited = true;
|
||||
}
|
||||
|
||||
let mut categories: Vec<(String, &GachaCategoryInfo)> = vec![];
|
||||
let mut weight_sum = 0;
|
||||
for result_tag in category_tag_result {
|
||||
let category = rarity_items.categories.get(&result_tag).unwrap();
|
||||
categories.push((result_tag, category));
|
||||
weight_sum += category.category_weight;
|
||||
}
|
||||
|
||||
let randomnum = rand::thread_rng().gen_range(0..weight_sum);
|
||||
let mut enumerated_ranges_end = 0;
|
||||
for category in categories.into_iter() {
|
||||
if randomnum <= enumerated_ranges_end + category.1.category_weight {
|
||||
return (category.0, category.1);
|
||||
}
|
||||
enumerated_ranges_end += category.1.category_weight;
|
||||
}
|
||||
panic!("No category is chosen.");
|
||||
}
|
||||
|
||||
fn determine_gacha_result<'bin, 'conf>(
|
||||
pull_time: &DateTime<Local>,
|
||||
category: &'conf GachaCategoryInfo,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
status_bin: &'bin GachaStatusBin,
|
||||
progress_bin: &'bin GachaProgressBin,
|
||||
rarity_items: &'conf GachaAvailableItemsInfo,
|
||||
) -> GachaRecordBin {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
let item_pool_len = category.item_ids.len() as u32;
|
||||
let mut item_id: Option<&u32> = None;
|
||||
// We should see whether user's search priority exists.
|
||||
for guarantee_policy_tag in rarity_items.category_guarantee_policy_tags.iter() {
|
||||
let category_guarantee_policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(guarantee_policy_tag)
|
||||
.unwrap();
|
||||
if !category_guarantee_policy.chooseable {
|
||||
continue;
|
||||
}
|
||||
// Firstly, judge whether the user failed enough times.
|
||||
// The user is limited to get only this category's item,
|
||||
// so we should record the user's failure to get his
|
||||
// selected item elsewhere.
|
||||
if progress_bin
|
||||
.categories_chosen_guarantee_progress_map
|
||||
.get(guarantee_policy_tag)
|
||||
.unwrap()
|
||||
< &category_guarantee_policy.trigger_on_failure_times
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// We directly look whether user chose an UP item.
|
||||
if let Some(item) = progress_bin
|
||||
.categories_chosen_guarantee_item_map
|
||||
.get(guarantee_policy_tag)
|
||||
{
|
||||
item_id = Some(item);
|
||||
}
|
||||
}
|
||||
|
||||
let item_id = match item_id {
|
||||
Some(val) => val,
|
||||
None => category
|
||||
.item_ids
|
||||
.get(rand::thread_rng().gen_range(0..item_pool_len) as usize)
|
||||
.unwrap(),
|
||||
};
|
||||
let mut extra_item_id: u32 = 0;
|
||||
let mut extra_item_count: u32 = 0;
|
||||
|
||||
for extra_items_policy_tag in rarity_items.extra_items_policy_tags.iter() {
|
||||
let extra_items_policy = gachaconf
|
||||
.extra_items_policy_map
|
||||
.get(extra_items_policy_tag)
|
||||
.unwrap();
|
||||
// TODO: apply_on_owned_count in a context with bag
|
||||
// TODO: That's what RoleModel should do, not me.
|
||||
if extra_items_policy.apply_on_owned_count == 0 {
|
||||
extra_item_id = extra_items_policy.id;
|
||||
extra_item_count = extra_items_policy.count;
|
||||
}
|
||||
}
|
||||
let extra_item_bin = GachaExtraItemBin {
|
||||
extra_item_id,
|
||||
extra_item_count,
|
||||
currently_gained: 0,
|
||||
};
|
||||
GachaRecordBin {
|
||||
pull_timestamp: pull_time.timestamp(),
|
||||
obtained_item_id: item_id.clone(),
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_pity<'bin, 'conf>(
|
||||
gacha_bin: &'bin mut GachaModelBin,
|
||||
rarity_items: &'conf GachaAvailableItemsInfo,
|
||||
probability_model: &'conf ProbabilityModel,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
) {
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap();
|
||||
for (rarity, rarity_status) in status_bin.rarity_status_map.iter_mut() {
|
||||
if (rarity == &rarity_items.rarity)
|
||||
|| (probability_model.clear_status_on_higher_rarity_pulled
|
||||
&& rarity < &rarity_items.rarity)
|
||||
{
|
||||
rarity_status.pity = 1;
|
||||
} else {
|
||||
rarity_status.pity += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_category_guarantee_info<'bin, 'conf>(
|
||||
gacha_bin: &'bin mut GachaModelBin,
|
||||
rarity_items: &'conf GachaAvailableItemsInfo,
|
||||
category_tag: &String,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
) {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap();
|
||||
let progress_bin = status_bin
|
||||
.rarity_status_map
|
||||
.get_mut(&rarity_items.rarity)
|
||||
.unwrap();
|
||||
for policy_tag in rarity_items.category_guarantee_policy_tags.iter() {
|
||||
let policy = gachaconf
|
||||
.category_guarantee_policy_map
|
||||
.get(policy_tag)
|
||||
.unwrap();
|
||||
// TODO: Chooseable guarantee not implemented
|
||||
let prev_failure = progress_bin
|
||||
.categories_progress_map
|
||||
.get_mut(policy_tag)
|
||||
.expect(&format!(
|
||||
"post_deserialize forgot StatusBin/rarity_status_map[{}]/categories_progress_map: {}",
|
||||
rarity_items.rarity, policy_tag
|
||||
));
|
||||
if policy.included_category_tags.contains(category_tag) {
|
||||
*prev_failure = 0;
|
||||
} else {
|
||||
*prev_failure += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_discount<'bin, 'conf>(
|
||||
gacha_bin: &'bin mut GachaModelBin,
|
||||
target_pool: &'conf CharacterGachaPool,
|
||||
category_tag: &String,
|
||||
rarity_items: &GachaAvailableItemsInfo,
|
||||
) {
|
||||
let gachaconf = gacha::global_gacha_config();
|
||||
for (policy_tag, policy) in gachaconf.discount_policies.must_gain_item_map.iter() {
|
||||
if *category_tag != policy.category_tag {
|
||||
continue;
|
||||
}
|
||||
if !target_pool.discount_policy_tags.contains(policy_tag) {
|
||||
continue;
|
||||
}
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap();
|
||||
let usage = status_bin.discount_usage_map.get_mut(policy_tag).unwrap();
|
||||
if *usage < policy.use_limit {
|
||||
*usage += 1;
|
||||
}
|
||||
}
|
||||
for (policy_tag, policy) in gachaconf.discount_policies.advanced_guarantee_map.iter() {
|
||||
if rarity_items.rarity != policy.rarity {
|
||||
continue;
|
||||
}
|
||||
if !target_pool.discount_policy_tags.contains(policy_tag) {
|
||||
continue;
|
||||
}
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap();
|
||||
let usage = status_bin.discount_usage_map.get_mut(policy_tag).unwrap();
|
||||
if *usage < policy.use_limit {
|
||||
*usage += 1;
|
||||
}
|
||||
}
|
||||
for (policy_tag, policy) in gachaconf.discount_policies.free_select_map.iter() {
|
||||
if !target_pool.discount_policy_tags.contains(policy_tag) {
|
||||
continue;
|
||||
}
|
||||
let status_bin = gacha_bin
|
||||
.gacha_status_map
|
||||
.get_mut(&target_pool.sharing_guarantee_info_category)
|
||||
.unwrap();
|
||||
let progress = status_bin
|
||||
.discount_usage_map
|
||||
.get_mut(&policy.free_select_progress_record_tag)
|
||||
.unwrap();
|
||||
*progress += 1;
|
||||
}
|
||||
}
|
4
nap_gameserver/src/logic/gacha/mod.rs
Normal file
4
nap_gameserver/src/logic/gacha/mod.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
mod gacha_model;
|
||||
mod record;
|
||||
|
||||
pub use gacha_model::GachaModel;
|
0
nap_gameserver/src/logic/gacha/record.rs
Normal file
0
nap_gameserver/src/logic/gacha/record.rs
Normal file
|
@ -1,4 +1,4 @@
|
|||
use data::tables::{AvatarBaseID, SectionConfigID};
|
||||
use data::tables::{AvatarBaseID, MainCityBgmConfigID, SectionConfigID};
|
||||
use proto::*;
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -14,6 +14,7 @@ use super::NapGameMode;
|
|||
pub struct FrontendGame {
|
||||
section_id: SectionConfigID,
|
||||
frontend_avatar_id: AvatarBaseID,
|
||||
main_city_bgm: MainCityBgmConfigID,
|
||||
scene_unit_mgr: SceneUnitManager,
|
||||
camera_x: u32,
|
||||
camera_y: u32,
|
||||
|
@ -30,6 +31,8 @@ pub enum FrontendGameError {
|
|||
}
|
||||
|
||||
impl FrontendGame {
|
||||
const DEFAULT_BGM_ID: u32 = 1005;
|
||||
|
||||
pub fn new(
|
||||
section_id: SectionConfigID,
|
||||
avatar_id: AvatarBaseID,
|
||||
|
@ -40,6 +43,7 @@ impl FrontendGame {
|
|||
let instance = Self {
|
||||
section_id,
|
||||
main_city_time,
|
||||
main_city_bgm: MainCityBgmConfigID::new_unchecked(Self::DEFAULT_BGM_ID),
|
||||
scene_unit_mgr: SceneUnitManager::new(section_id),
|
||||
frontend_avatar_id: avatar_id,
|
||||
camera_x: 0xFFFFFFFF,
|
||||
|
@ -65,6 +69,7 @@ impl NapGameMode for FrontendGame {
|
|||
hall_scene_info: Some(HallSceneInfo {
|
||||
section_id: self.section_id.value(),
|
||||
frontend_avatar_id: self.frontend_avatar_id.value(),
|
||||
main_city_bgm_id: self.main_city_bgm.value(),
|
||||
camera_x: self.camera_x,
|
||||
camera_y: self.camera_y,
|
||||
transform: self
|
||||
|
|
|
@ -4,7 +4,7 @@ use proto::{DungeonInfo, DungeonItemData, FightSceneInfo, SceneInfo, WeatherPool
|
|||
use thiserror::Error;
|
||||
|
||||
use crate::logic::{
|
||||
battle::{InLevelAvatarDataItem, TeamDataItem},
|
||||
battle::{EquippedBuddyDataItem, InLevelAvatarDataItem, TeamDataItem},
|
||||
ELocalPlayType, ESceneType, TimePeriodType, WeatherType,
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ impl HollowGame {
|
|||
weather: WeatherType::SunShine,
|
||||
start_timestamp: util::cur_timestamp() as i64,
|
||||
play_type,
|
||||
team_data: TeamDataItem::new(avatars),
|
||||
team_data: TeamDataItem::new(avatars, 0),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ impl HollowGame {
|
|||
archive_battle_quest_id: ArchiveBattleQuestID,
|
||||
play_type: ELocalPlayType,
|
||||
avatars: &[u32],
|
||||
buddy_id: u32,
|
||||
) -> Result<Self, HollowGameError> {
|
||||
let template = archive_battle_quest_id.template();
|
||||
|
||||
|
@ -56,7 +57,7 @@ impl HollowGame {
|
|||
weather: WeatherType::SunShine,
|
||||
start_timestamp: util::cur_timestamp() as i64,
|
||||
play_type,
|
||||
team_data: TeamDataItem::new(avatars),
|
||||
team_data: TeamDataItem::new(avatars, buddy_id),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +95,12 @@ impl NapGameMode for HollowGame {
|
|||
.iter()
|
||||
.map(InLevelAvatarDataItem::to_client)
|
||||
.collect(),
|
||||
buddy_list: self
|
||||
.team_data
|
||||
.equipped_buddy_list
|
||||
.iter()
|
||||
.map(EquippedBuddyDataItem::to_client)
|
||||
.collect(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pub mod battle;
|
||||
mod enums;
|
||||
pub mod gacha;
|
||||
pub mod game;
|
||||
pub mod item;
|
||||
pub mod math;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use data::tables::{self, AvatarBaseID};
|
||||
use proto::{ItemStatic, PlayerDataBin, Retcode};
|
||||
|
||||
use super::gacha::GachaModel;
|
||||
use super::game::{FrontendGame, FrontendGameError, GameInstance, LogicError};
|
||||
use super::item::{ItemModel, ItemUID};
|
||||
use super::main_city_model::MainCityModel;
|
||||
|
@ -16,6 +17,7 @@ pub struct Player {
|
|||
pub role_model: RoleModel,
|
||||
pub item_model: ItemModel,
|
||||
pub main_city_model: MainCityModel,
|
||||
pub gacha_model: GachaModel,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
|
@ -28,6 +30,7 @@ impl Player {
|
|||
role_model: Some(self.role_model.to_bin()),
|
||||
item_model: Some(self.item_model.to_bin()),
|
||||
main_city_model: Some(self.main_city_model.to_bin()),
|
||||
gacha_model: Some(self.gacha_model.to_bin()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +47,7 @@ impl Player {
|
|||
.main_city_model
|
||||
.map(MainCityModel::from_bin)
|
||||
.unwrap_or_default(),
|
||||
gacha_model: bin.gacha_model.map(GachaModel::from_bin).unwrap_or_default(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +62,12 @@ impl Player {
|
|||
.add_resource(ItemStatic::FrontendGold as u32, 1_000_000);
|
||||
self.item_model
|
||||
.add_resource(ItemStatic::GameDiamond as u32, 1_000_000);
|
||||
self.item_model
|
||||
.add_resource(ItemStatic::GachaTicketEvent as u32, 30_000);
|
||||
self.item_model
|
||||
.add_resource(ItemStatic::GachaTicketStandard as u32, 30_000);
|
||||
self.item_model
|
||||
.add_resource(ItemStatic::GachaTicketBangboo as u32, 30_000);
|
||||
self.item_model.add_resource(ItemStatic::Energy as u32, 240);
|
||||
}
|
||||
|
||||
|
|
|
@ -247,4 +247,8 @@ impl NetSession {
|
|||
pub fn set_state(&self, state: NetSessionState) {
|
||||
self.state.store(state, std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
|
||||
pub async fn shutdown(&self) -> Result<(), std::io::Error> {
|
||||
self.writer.lock().await.shutdown().await
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ pub struct Nkhnlakggmj {
|
|||
pub iddehlcpjjn: ::prost::alloc::string::String,
|
||||
#[xor(10163)]
|
||||
#[prost(int64, tag = "14")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(8852)]
|
||||
#[prost(uint32, tag = "8")]
|
||||
pub ppnbkmndpjc: u32,
|
||||
|
@ -829,7 +829,7 @@ pub struct Fkkojjgepnb {
|
|||
pub lchdjcdjiik: u32,
|
||||
#[xor(4851)]
|
||||
#[prost(int64, tag = "3")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(8589)]
|
||||
#[prost(int32, tag = "505")]
|
||||
pub lecpejadije: i32,
|
||||
|
@ -2270,7 +2270,7 @@ pub struct PlayerSyncScNotify {
|
|||
#[prost(message, optional, tag = "12")]
|
||||
pub gchokpdeeci: ::core::option::Option<Mbhjjoafcmc>,
|
||||
#[prost(message, optional, tag = "13")]
|
||||
pub kplhefeipee: ::core::option::Option<Onacbnhpicf>,
|
||||
pub buddy: ::core::option::Option<BuddySync>,
|
||||
#[prost(message, optional, tag = "14")]
|
||||
pub mobpkchjfai: ::core::option::Option<Phnapedndek>,
|
||||
#[prost(message, optional, tag = "15")]
|
||||
|
@ -2406,7 +2406,7 @@ pub struct Khhjipglbll {
|
|||
pub bcbcjioepod: u32,
|
||||
#[xor(2704)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[prost(uint32, repeated, tag = "11")]
|
||||
pub avatars: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(9370)]
|
||||
|
@ -2760,7 +2760,7 @@ pub struct Iedkhplmbab {
|
|||
pub struct StartTrialFightingMissionCsReq {
|
||||
#[xor(15246)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(3842)]
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub quest_id: u32,
|
||||
|
@ -2800,8 +2800,8 @@ pub struct Eoaebmjlfjc {
|
|||
pub struct EquippedBuddyData {
|
||||
#[xor(8856)]
|
||||
#[prost(uint32, tag = "9")]
|
||||
pub buddy: u32,
|
||||
#[prost(enumeration = "Hneekphmejf", tag = "6")]
|
||||
pub buddy_id: u32,
|
||||
#[prost(enumeration = "BuddyTeamType", tag = "6")]
|
||||
pub r#type: i32,
|
||||
#[prost(map = "uint32, int32", tag = "10")]
|
||||
pub mp_property_override_map: ::std::collections::HashMap<u32, i32>,
|
||||
|
@ -4512,7 +4512,7 @@ pub struct Kancdiinhgh {
|
|||
#[prost(uint64, tag = "2")]
|
||||
pub dbkpbkpcoog: u64,
|
||||
#[prost(uint64, tag = "3")]
|
||||
pub phkcdmjheen: u64,
|
||||
pub end_timestamp: u64,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(2438)]
|
||||
|
@ -5821,7 +5821,7 @@ pub struct Mcmkalpefjk {
|
|||
pub struct Aibcmljaojd {
|
||||
#[xor(3014)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub naffoonclpe: u32,
|
||||
pub main_city_bgm_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(1091)]
|
||||
|
@ -5916,7 +5916,7 @@ pub struct Lpjpfoaehlg {
|
|||
pub lbmgeignmef: u32,
|
||||
#[xor(2510)]
|
||||
#[prost(uint32, tag = "8")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -6844,7 +6844,7 @@ pub struct Pofhbffcjap {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Nhffnnompfh {
|
||||
pub struct ChooseGachaUpScRsp {
|
||||
#[xor(4109)]
|
||||
#[prost(int32, tag = "2")]
|
||||
pub retcode: i32,
|
||||
|
@ -7859,7 +7859,7 @@ pub struct LogBattleStatistics {
|
|||
#[prost(message, optional, tag = "13")]
|
||||
pub ncfafdpojjh: ::core::option::Option<Bacignlfind>,
|
||||
#[prost(message, repeated, tag = "14")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<Jaokcopjeip>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<Jaokcopjeip>,
|
||||
#[prost(uint32, tag = "15")]
|
||||
pub mlagnchinll: u32,
|
||||
#[prost(message, optional, tag = "17")]
|
||||
|
@ -8223,7 +8223,7 @@ pub struct Ihhaahinlik {
|
|||
#[prost(int64, tag = "3")]
|
||||
pub dbkpbkpcoog: i64,
|
||||
#[prost(int64, tag = "4")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -8538,7 +8538,7 @@ pub struct HallSceneInfo {
|
|||
pub hoagdhfnhhp: u32,
|
||||
#[xor(4796)]
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub naffoonclpe: u32,
|
||||
pub main_city_bgm_id: u32,
|
||||
#[prost(message, optional, tag = "12")]
|
||||
pub position: ::core::option::Option<Transform>,
|
||||
#[xor(6272)]
|
||||
|
@ -8695,7 +8695,7 @@ pub struct BeginArchiveBattleQuestCsReq {
|
|||
pub quest_id: u32,
|
||||
#[xor(1830)]
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[prost(bool, tag = "1")]
|
||||
pub is_story: bool,
|
||||
#[prost(uint32, repeated, tag = "2")]
|
||||
|
@ -9108,7 +9108,7 @@ pub struct Gkfhklbbcpo {
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Enkkecgonaf {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub abalhhfapla: u32,
|
||||
pub cost_item_count: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -9176,7 +9176,7 @@ pub struct Bijjamapnjm {
|
|||
pub struct Bffgkjikbhp {
|
||||
#[xor(3555)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(10954)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub lbmgeignmef: u32,
|
||||
|
@ -9395,7 +9395,7 @@ pub struct Kmkbpddeaoe {
|
|||
pub struct Bhmhgadoncc {
|
||||
#[xor(5509)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(10314)]
|
||||
#[prost(int32, tag = "12")]
|
||||
pub nledmfjbmmo: i32,
|
||||
|
@ -9603,7 +9603,7 @@ pub struct Gfpehbhpgfb {
|
|||
pub avatars: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(8960)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub abalhhfapla: u32,
|
||||
pub cost_item_count: u32,
|
||||
#[xor(8889)]
|
||||
#[prost(uint32, tag = "6")]
|
||||
pub damhjcgieco: u32,
|
||||
|
@ -9668,7 +9668,7 @@ pub struct Cbccakknimc {
|
|||
pub struct Bfkkjofnjjo {
|
||||
#[xor(4795)]
|
||||
#[prost(uint32, tag = "10")]
|
||||
pub abalhhfapla: u32,
|
||||
pub cost_item_count: u32,
|
||||
#[xor(5066)]
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub cmacbfkaoma: u32,
|
||||
|
@ -10605,7 +10605,7 @@ pub struct Npdgpemipij {
|
|||
#[prost(int32, tag = "5")]
|
||||
pub peamchapinf: i32,
|
||||
#[prost(string, tag = "2")]
|
||||
pub phkcdmjheen: ::prost::alloc::string::String,
|
||||
pub end_timestamp: ::prost::alloc::string::String,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(5101)]
|
||||
|
@ -10824,7 +10824,7 @@ pub struct Gccdaofpapp {
|
|||
pub struct Ihilkekkdmh {
|
||||
#[xor(10553)]
|
||||
#[prost(uint32, tag = "13")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(13840)]
|
||||
#[prost(int32, tag = "1")]
|
||||
pub retcode: i32,
|
||||
|
@ -12389,7 +12389,7 @@ pub struct InteractWithUnitCsReq {
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Ofcdfiihahe {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub abalhhfapla: u32,
|
||||
pub cost_item_count: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -12833,7 +12833,7 @@ pub struct Okkjjhonnik {
|
|||
pub ajichmhgblg: u32,
|
||||
#[xor(1870)]
|
||||
#[prost(uint32, tag = "7")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -12926,7 +12926,7 @@ pub struct Hdjijldgmab {
|
|||
pub struct Cnmgfcllhpl {
|
||||
#[xor(11487)]
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(665)]
|
||||
|
@ -13423,7 +13423,7 @@ pub struct Jlldijenmoc {
|
|||
pub dphghojclod: u32,
|
||||
#[xor(8783)]
|
||||
#[prost(int64, tag = "2")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(525)]
|
||||
#[prost(uint32, tag = "8")]
|
||||
pub leagnodilli: u32,
|
||||
|
@ -13731,19 +13731,19 @@ pub struct Omdfkjoopce {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Effclengcpo {
|
||||
pub struct DoGachaCsReq {
|
||||
#[xor(13734)]
|
||||
#[prost(uint32, tag = "15")]
|
||||
pub eglpecifagd: u32,
|
||||
#[xor(4101)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
#[xor(8588)]
|
||||
#[prost(uint32, tag = "13")]
|
||||
pub madciamhahg: u32,
|
||||
pub random_number: u32,
|
||||
#[xor(10835)]
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub abalhhfapla: u32,
|
||||
pub cost_item_count: u32,
|
||||
#[xor(3853)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub gacha_type: u32,
|
||||
|
@ -14035,10 +14035,10 @@ pub struct Nffblkigaan {
|
|||
pub weapon_uid: u32,
|
||||
#[xor(2492)]
|
||||
#[prost(uint32, tag = "9")]
|
||||
pub eijhjbplhih: u32,
|
||||
pub need_item_id: u32,
|
||||
#[xor(13312)]
|
||||
#[prost(uint32, tag = "8")]
|
||||
pub bplmpghdklb: u32,
|
||||
pub need_item_count: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -15705,7 +15705,7 @@ pub struct Gcffmmdgobe {
|
|||
#[prost(int32, tag = "1")]
|
||||
pub opmgaofadph: i32,
|
||||
#[prost(int32, tag = "2")]
|
||||
pub abalhhfapla: i32,
|
||||
pub cost_item_count: i32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(1224)]
|
||||
|
@ -16201,13 +16201,13 @@ pub struct ClientSystemsInfo {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Feanepokfam {
|
||||
pub struct NeedItemInfo {
|
||||
#[xor(156)]
|
||||
#[prost(uint32, tag = "15")]
|
||||
pub bplmpghdklb: u32,
|
||||
pub need_item_count: u32,
|
||||
#[xor(11997)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub eijhjbplhih: u32,
|
||||
pub need_item_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(1140)]
|
||||
|
@ -16216,7 +16216,7 @@ pub struct Feanepokfam {
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Onlmpmgcdle {
|
||||
#[prost(message, repeated, tag = "13")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<EquippedBuddyData>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<EquippedBuddyData>,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(5211)]
|
||||
|
@ -16488,7 +16488,7 @@ pub struct DungeonItemData {
|
|||
#[prost(message, repeated, tag = "6")]
|
||||
pub dldfgemogip: ::prost::alloc::vec::Vec<Ljcocgillfb>,
|
||||
#[prost(message, repeated, tag = "14")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<BuddyInfo>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<BuddyInfo>,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -16638,7 +16638,7 @@ pub struct Ejjimjcohgg {
|
|||
pub feanogfdcjh: u32,
|
||||
#[xor(3653)]
|
||||
#[prost(uint32, tag = "9")]
|
||||
pub naffoonclpe: u32,
|
||||
pub main_city_bgm_id: u32,
|
||||
#[prost(message, repeated, tag = "3")]
|
||||
pub imfhefkhano: ::prost::alloc::vec::Vec<Ckndhmekhfm>,
|
||||
}
|
||||
|
@ -16647,14 +16647,14 @@ pub struct Ejjimjcohgg {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Akjiehealco {
|
||||
pub struct DoGachaScRsp {
|
||||
#[prost(message, optional, tag = "6")]
|
||||
pub gacha_data: ::core::option::Option<GachaData>,
|
||||
#[prost(message, repeated, tag = "13")]
|
||||
pub mjajbddaemm: ::prost::alloc::vec::Vec<Depahhdodeb>,
|
||||
pub gain_item_list: ::prost::alloc::vec::Vec<GainItemInfo>,
|
||||
#[xor(12395)]
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub abalhhfapla: u32,
|
||||
pub cost_item_count: u32,
|
||||
#[xor(14106)]
|
||||
#[prost(int32, tag = "5")]
|
||||
pub retcode: i32,
|
||||
|
@ -17052,7 +17052,7 @@ pub struct Fkibbohbdin {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Onacbnhpicf {
|
||||
pub struct BuddySync {
|
||||
#[prost(uint32, repeated, tag = "1")]
|
||||
pub kghfhlopgjb: ::prost::alloc::vec::Vec<u32>,
|
||||
#[prost(uint32, repeated, tag = "9")]
|
||||
|
@ -17066,7 +17066,7 @@ pub struct Onacbnhpicf {
|
|||
#[prost(uint32, tag = "3")]
|
||||
pub lpfeinagkha: u32,
|
||||
#[prost(message, repeated, tag = "2")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<BuddyInfo>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<BuddyInfo>,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -17252,7 +17252,7 @@ pub struct Ipfpofcbnjp {
|
|||
pub struct Ilehibpgief {
|
||||
#[xor(14424)]
|
||||
#[prost(int64, tag = "4")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[prost(uint32, repeated, tag = "6")]
|
||||
pub pjilpbkknan: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(4341)]
|
||||
|
@ -17266,7 +17266,7 @@ pub struct Ilehibpgief {
|
|||
pub struct Fjppbkgebcl {
|
||||
#[xor(7354)]
|
||||
#[prost(uint32, tag = "8")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -17842,7 +17842,7 @@ pub struct Odijcgldmia {
|
|||
#[prost(uint32, tag = "11")]
|
||||
pub bpegheknole: u32,
|
||||
#[prost(message, repeated, tag = "14")]
|
||||
pub bapbocgilep: ::prost::alloc::vec::Vec<Feanepokfam>,
|
||||
pub bapbocgilep: ::prost::alloc::vec::Vec<NeedItemInfo>,
|
||||
#[prost(map = "uint32, uint32", tag = "10")]
|
||||
pub maeegjdknkg: ::std::collections::HashMap<u32, u32>,
|
||||
#[prost(uint32, repeated, tag = "9")]
|
||||
|
@ -17850,20 +17850,20 @@ pub struct Odijcgldmia {
|
|||
#[prost(string, tag = "3")]
|
||||
pub fnanndecaan: ::prost::alloc::string::String,
|
||||
#[prost(message, repeated, tag = "13")]
|
||||
pub pbalmllekpp: ::prost::alloc::vec::Vec<Feanepokfam>,
|
||||
pub need_item_info_list: ::prost::alloc::vec::Vec<NeedItemInfo>,
|
||||
#[prost(message, repeated, tag = "6")]
|
||||
pub mplcofohjnl: ::prost::alloc::vec::Vec<Feanepokfam>,
|
||||
pub mplcofohjnl: ::prost::alloc::vec::Vec<NeedItemInfo>,
|
||||
#[xor(5947)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub r#type: u32,
|
||||
#[prost(message, repeated, tag = "8")]
|
||||
pub dnadnehoogk: ::prost::alloc::vec::Vec<Feanepokfam>,
|
||||
pub dnadnehoogk: ::prost::alloc::vec::Vec<NeedItemInfo>,
|
||||
#[xor(5194)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub dgaafhidocl: u32,
|
||||
#[xor(11358)]
|
||||
#[prost(uint32, tag = "12")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -18737,7 +18737,7 @@ pub struct Ilghjldjhcl {
|
|||
pub hbmnikpdgon: ::prost::alloc::string::String,
|
||||
#[xor(9518)]
|
||||
#[prost(int64, tag = "9")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(1810)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub oeaieooemng: u32,
|
||||
|
@ -18990,7 +18990,7 @@ pub struct Cobgikcepkp {
|
|||
#[prost(int32, tag = "1")]
|
||||
pub imhfejennof: i32,
|
||||
#[prost(string, tag = "4")]
|
||||
pub phkcdmjheen: ::prost::alloc::string::String,
|
||||
pub end_timestamp: ::prost::alloc::string::String,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -20840,7 +20840,7 @@ pub struct Ghgbhljlmde {
|
|||
pub bikhplpcalp: ::std::collections::HashMap<u32, u32>,
|
||||
#[xor(4986)]
|
||||
#[prost(uint32, tag = "6")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(1495)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub ihgcjhffkdf: u32,
|
||||
|
@ -20969,8 +20969,8 @@ pub struct Acobofkfjgj {
|
|||
pub struct Oidkngmaipi {
|
||||
#[xor(8441)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub buddy: u32,
|
||||
#[prost(enumeration = "Hneekphmejf", tag = "7")]
|
||||
pub buddy_id: u32,
|
||||
#[prost(enumeration = "BuddyTeamType", tag = "7")]
|
||||
pub ddogpdoomde: i32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
|
@ -21192,7 +21192,7 @@ pub struct Labghjgfhhh {
|
|||
pub lbmgeignmef: u32,
|
||||
#[xor(13505)]
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -21227,7 +21227,7 @@ pub struct Gmgoddaldob {
|
|||
#[prost(uint32, tag = "1")]
|
||||
pub pmnjlmekmbc: u32,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[prost(bool, tag = "3")]
|
||||
pub majldghlkab: bool,
|
||||
#[prost(bytes = "vec", tag = "4")]
|
||||
|
@ -21748,7 +21748,7 @@ pub struct GetBuddyDataScRsp {
|
|||
#[prost(uint32, tag = "12")]
|
||||
pub lpfeinagkha: u32,
|
||||
#[prost(message, repeated, tag = "5")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<BuddyInfo>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<BuddyInfo>,
|
||||
#[prost(uint32, repeated, tag = "10")]
|
||||
pub kghfhlopgjb: ::prost::alloc::vec::Vec<u32>,
|
||||
}
|
||||
|
@ -22137,7 +22137,7 @@ pub struct Kakpeoaekgb {
|
|||
pub struct Mbchikbhcmp {
|
||||
#[xor(8473)]
|
||||
#[prost(uint32, tag = "10")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[prost(bool, tag = "6")]
|
||||
pub aobemkmdkgo: bool,
|
||||
#[prost(message, repeated, tag = "14")]
|
||||
|
@ -22212,9 +22212,9 @@ pub struct Mbokdhgpobc {
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Gacha {
|
||||
#[prost(uint32, repeated, tag = "1425")]
|
||||
pub jkbfeediiho: ::prost::alloc::vec::Vec<u32>,
|
||||
pub chooseable_up_list: ::prost::alloc::vec::Vec<u32>,
|
||||
#[prost(uint32, repeated, tag = "15")]
|
||||
pub nfngmliibdf: ::prost::alloc::vec::Vec<u32>,
|
||||
pub up_s_item_list: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(1098)]
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub obabhacfokn: u32,
|
||||
|
@ -22222,7 +22222,7 @@ pub struct Gacha {
|
|||
pub ioiebkbcnoi: ::prost::alloc::string::String,
|
||||
#[xor(13960)]
|
||||
#[prost(uint32, tag = "698")]
|
||||
pub gbmmbcbefmp: u32,
|
||||
pub advanced_s_guarantee: u32,
|
||||
#[xor(1462)]
|
||||
#[prost(uint32, tag = "10")]
|
||||
pub kagiddohcmk: u32,
|
||||
|
@ -22230,30 +22230,30 @@ pub struct Gacha {
|
|||
#[prost(uint32, tag = "1921")]
|
||||
pub nammdglepbk: u32,
|
||||
#[prost(message, repeated, tag = "3")]
|
||||
pub pbalmllekpp: ::prost::alloc::vec::Vec<Feanepokfam>,
|
||||
pub need_item_info_list: ::prost::alloc::vec::Vec<NeedItemInfo>,
|
||||
#[xor(9792)]
|
||||
#[prost(int64, tag = "14")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(6233)]
|
||||
#[prost(uint32, tag = "563")]
|
||||
pub dimlpkbggfc: u32,
|
||||
pub discount_ten_roll_prize: u32,
|
||||
#[prost(bool, tag = "1756")]
|
||||
pub nkeigieepgn: bool,
|
||||
#[prost(uint32, repeated, tag = "755")]
|
||||
pub hbhckgpjian: ::prost::alloc::vec::Vec<u32>,
|
||||
pub free_select_item_list: ::prost::alloc::vec::Vec<u32>,
|
||||
#[prost(string, tag = "2")]
|
||||
pub mpmnlphpdlk: ::prost::alloc::string::String,
|
||||
pub drop_history_webview: ::prost::alloc::string::String,
|
||||
#[xor(4816)]
|
||||
#[prost(uint32, tag = "13")]
|
||||
pub pladpclalgn: u32,
|
||||
pub gacha_schedule_id: u32,
|
||||
#[xor(11392)]
|
||||
#[prost(uint32, tag = "574")]
|
||||
pub fjhglcclbgm: u32,
|
||||
pub free_select_required_pull: u32,
|
||||
#[prost(uint32, repeated, tag = "6")]
|
||||
pub goainlmbhnn: ::prost::alloc::vec::Vec<u32>,
|
||||
pub up_a_item_list: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(8288)]
|
||||
#[prost(uint32, tag = "12")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
#[xor(8537)]
|
||||
#[prost(uint32, tag = "1662")]
|
||||
pub pcjdafaaimg: u32,
|
||||
|
@ -22273,29 +22273,29 @@ pub struct Gacha {
|
|||
pub gacha_type: u32,
|
||||
#[xor(5057)]
|
||||
#[prost(uint32, tag = "244")]
|
||||
pub ahidoimfiof: u32,
|
||||
pub s_guarantee: u32,
|
||||
#[xor(1870)]
|
||||
#[prost(int64, tag = "8")]
|
||||
pub start_timestamp: i64,
|
||||
#[xor(562)]
|
||||
#[prost(uint32, tag = "726")]
|
||||
pub mkiplhjemoi: u32,
|
||||
pub free_select_progress: u32,
|
||||
#[xor(8338)]
|
||||
#[prost(uint32, tag = "96")]
|
||||
pub ihjnkoijdgh: u32,
|
||||
#[xor(4210)]
|
||||
#[prost(uint32, tag = "789")]
|
||||
pub gokmdbojehm: u32,
|
||||
pub a_guarantee: u32,
|
||||
#[prost(uint32, repeated, tag = "4")]
|
||||
pub akggbhgkifd: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(1056)]
|
||||
#[prost(uint32, tag = "2002")]
|
||||
pub kikannccmmo: u32,
|
||||
pub discount_avaliable_num: u32,
|
||||
#[prost(string, tag = "7")]
|
||||
pub jahbjmphipl: ::prost::alloc::string::String,
|
||||
pub gacha_info_list_webview: ::prost::alloc::string::String,
|
||||
#[xor(9009)]
|
||||
#[prost(uint32, tag = "419")]
|
||||
pub ekjlhhdekka: u32,
|
||||
pub chosen_up_item: u32,
|
||||
#[prost(string, tag = "923")]
|
||||
pub fjohnbicmce: ::prost::alloc::string::String,
|
||||
#[xor(1379)]
|
||||
|
@ -22404,7 +22404,7 @@ pub struct Aecgodfnpao {
|
|||
pub lbmgeignmef: u32,
|
||||
#[xor(7503)]
|
||||
#[prost(uint32, tag = "12")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -22612,7 +22612,7 @@ pub struct Ghojoimpnad {
|
|||
pub ndcnfidonje: u32,
|
||||
#[xor(8060)]
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(15324)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub lbmgeignmef: u32,
|
||||
|
@ -22699,7 +22699,7 @@ pub struct Mcjgjlpjfjc {
|
|||
pub gebpolkeieh: u32,
|
||||
#[xor(4412)]
|
||||
#[prost(int64, tag = "1")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -23294,7 +23294,7 @@ pub struct GachaData {
|
|||
pub cmamhfldihg: ::core::option::Option<Dpgipnmocnj>,
|
||||
#[xor(9369)]
|
||||
#[prost(uint32, tag = "13")]
|
||||
pub madciamhahg: u32,
|
||||
pub random_number: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -23399,7 +23399,7 @@ pub struct Nalkdbjimgk {
|
|||
pub aohakmnfinf: u32,
|
||||
#[xor(2280)]
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(4620)]
|
||||
|
@ -24021,7 +24021,7 @@ pub struct Himappelgdm {
|
|||
pub gppmclpnjoe: u32,
|
||||
#[xor(4244)]
|
||||
#[prost(uint64, tag = "11")]
|
||||
pub phkcdmjheen: u64,
|
||||
pub end_timestamp: u64,
|
||||
#[xor(6824)]
|
||||
#[prost(uint32, tag = "7")]
|
||||
pub enhandfaalc: u32,
|
||||
|
@ -24257,7 +24257,7 @@ pub struct Enaagloodio {
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Ecjcmfjjgdp {
|
||||
#[prost(int32, tag = "1")]
|
||||
pub buddy: i32,
|
||||
pub buddy_id: i32,
|
||||
#[prost(int32, repeated, tag = "2")]
|
||||
pub jpncidefiba: ::prost::alloc::vec::Vec<i32>,
|
||||
#[prost(message, optional, tag = "3")]
|
||||
|
@ -24558,13 +24558,13 @@ pub struct Obpccjhnbpe {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Pahjnbjogon {
|
||||
pub struct ChooseGachaUpCsReq {
|
||||
#[xor(3180)]
|
||||
#[prost(uint32, tag = "6")]
|
||||
pub item_id: u32,
|
||||
#[xor(1511)]
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[derive(proto_gen::XorFields)]
|
||||
|
@ -24653,7 +24653,7 @@ pub struct Eindafcpkce {
|
|||
#[prost(int32, tag = "1")]
|
||||
pub nkiegkopoeg: i32,
|
||||
#[prost(int32, tag = "2")]
|
||||
pub abalhhfapla: i32,
|
||||
pub cost_item_count: i32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(3276)]
|
||||
|
@ -25751,7 +25751,7 @@ pub struct DungeonInfo {
|
|||
#[prost(message, optional, tag = "3")]
|
||||
pub ncfafdpojjh: ::core::option::Option<Kalfjemiaaa>,
|
||||
#[prost(message, optional, tag = "8")]
|
||||
pub kplhefeipee: ::core::option::Option<EquippedBuddyData>,
|
||||
pub buddy: ::core::option::Option<EquippedBuddyData>,
|
||||
#[prost(bool, tag = "1724")]
|
||||
pub gjhgpapkmod: bool,
|
||||
#[prost(bool, tag = "1109")]
|
||||
|
@ -25769,7 +25769,7 @@ pub struct DungeonInfo {
|
|||
#[prost(map = "uint32, int32", tag = "7")]
|
||||
pub njfikojmpcm: ::std::collections::HashMap<u32, i32>,
|
||||
#[prost(message, repeated, tag = "1395")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<EquippedBuddyData>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<EquippedBuddyData>,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub dungeon_item_data: ::core::option::Option<DungeonItemData>,
|
||||
#[prost(message, optional, tag = "5")]
|
||||
|
@ -26395,7 +26395,7 @@ pub struct Pfcmihnfmme {
|
|||
pub cfnblioopmp: u32,
|
||||
#[xor(13350)]
|
||||
#[prost(int64, tag = "15")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(13289)]
|
||||
#[prost(int64, tag = "5")]
|
||||
pub kehdpankopd: i64,
|
||||
|
@ -27252,7 +27252,7 @@ pub struct Aicalelcmii {
|
|||
pub kplhkiofbah: bool,
|
||||
#[xor(3343)]
|
||||
#[prost(uint32, tag = "7")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(4100)]
|
||||
|
@ -27531,10 +27531,10 @@ pub struct TipsInfo {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Ieimfkpmegp {
|
||||
pub struct GachaFreeAgentCsReq {
|
||||
#[xor(378)]
|
||||
#[prost(uint32, tag = "12")]
|
||||
pub dcealmadfgi: u32,
|
||||
pub gacha_parent_schedule_id: u32,
|
||||
#[xor(1946)]
|
||||
#[prost(uint32, tag = "7")]
|
||||
pub avatar_id: u32,
|
||||
|
@ -28249,8 +28249,8 @@ pub struct Flpgnabkedc {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Igapopdfcef {
|
||||
#[prost(enumeration = "Obpfhejepck", tag = "15")]
|
||||
pub struct DisconnectScNotify {
|
||||
#[prost(enumeration = "DisconnectReason", tag = "15")]
|
||||
pub reason: i32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
|
@ -28678,7 +28678,7 @@ pub struct Bkkmkacnhne {}
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Dpijpabbknc {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub buddy: ::core::option::Option<StringEntry>,
|
||||
pub buddy_id: ::core::option::Option<StringEntry>,
|
||||
#[prost(enumeration = "Afnpekehlge", tag = "2")]
|
||||
pub ddogpdoomde: i32,
|
||||
}
|
||||
|
@ -29634,7 +29634,7 @@ pub struct Jlgmobeofhe {
|
|||
pub jipabmjagbi: u32,
|
||||
#[xor(12923)]
|
||||
#[prost(uint32, tag = "4")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(11558)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub pmnjlmekmbc: u32,
|
||||
|
@ -30207,7 +30207,7 @@ pub struct Dlenhbdpddl {
|
|||
#[prost(uint32, tag = "5")]
|
||||
pub uid: u32,
|
||||
#[prost(message, repeated, tag = "7")]
|
||||
pub lmailahlomk: ::prost::alloc::vec::Vec<Fjppbkgebcl>,
|
||||
pub buddy_list: ::prost::alloc::vec::Vec<Fjppbkgebcl>,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(1394)]
|
||||
|
@ -30566,7 +30566,7 @@ pub struct Jcfdccfejcg {
|
|||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Jaokcopjeip {
|
||||
#[prost(int32, tag = "1")]
|
||||
pub buddy: i32,
|
||||
pub buddy_id: i32,
|
||||
#[prost(int64, tag = "2")]
|
||||
pub cjehpadgajn: i64,
|
||||
#[prost(int32, tag = "3")]
|
||||
|
@ -31149,7 +31149,7 @@ pub struct Bgheihedbcb {
|
|||
pub apociobpoho: u32,
|
||||
#[xor(9137)]
|
||||
#[prost(int64, tag = "2")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[prost(bool, tag = "4")]
|
||||
pub mgfcmlpkjkg: bool,
|
||||
#[xor(438)]
|
||||
|
@ -31470,7 +31470,7 @@ pub struct Nnbooaekcml {
|
|||
pub ncjcmkgfpej: ::prost::alloc::vec::Vec<Bnpkpfadbdd>,
|
||||
#[xor(15963)]
|
||||
#[prost(int32, tag = "13")]
|
||||
pub eijhjbplhih: i32,
|
||||
pub need_item_id: i32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(816)]
|
||||
|
@ -31687,7 +31687,7 @@ pub struct Amhlhmjgcpk {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Idonpiailid {
|
||||
pub struct GachaFreeAgentScRsp {
|
||||
#[xor(3883)]
|
||||
#[prost(int32, tag = "3")]
|
||||
pub retcode: i32,
|
||||
|
@ -32158,7 +32158,7 @@ pub struct Hphfnebchnb {
|
|||
pub struct Hoeafbihgpd {
|
||||
#[xor(1739)]
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
}
|
||||
#[derive(proto_gen::CmdID)]
|
||||
#[cmdid(3238)]
|
||||
|
@ -32445,21 +32445,21 @@ pub struct Mkaecbehadi {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct Depahhdodeb {
|
||||
pub struct GainItemInfo {
|
||||
#[xor(9764)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub num: u32,
|
||||
#[xor(12647)]
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub ollapieolpm: u32,
|
||||
pub extra_item_count: u32,
|
||||
#[prost(map = "uint32, uint32", tag = "4")]
|
||||
pub nkdheebkjjl: ::std::collections::HashMap<u32, u32>,
|
||||
pub extra_items: ::std::collections::HashMap<u32, u32>,
|
||||
#[xor(11858)]
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub item_id: u32,
|
||||
#[xor(6146)]
|
||||
#[prost(uint32, tag = "8")]
|
||||
pub dghfjhiikkn: u32,
|
||||
pub extra_item_id: u32,
|
||||
#[xor(10021)]
|
||||
#[prost(uint32, tag = "9")]
|
||||
pub uid: u32,
|
||||
|
@ -32766,7 +32766,7 @@ pub struct Lipadknfagg {
|
|||
pub abdfdamklia: bool,
|
||||
#[xor(1841)]
|
||||
#[prost(int64, tag = "1696")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(15522)]
|
||||
#[prost(int64, tag = "14")]
|
||||
pub jkjhhbpcaon: i64,
|
||||
|
@ -32871,7 +32871,7 @@ pub struct Gojokjnppnp {
|
|||
pub mlfannobjdp: bool,
|
||||
#[xor(1038)]
|
||||
#[prost(int64, tag = "4")]
|
||||
pub phkcdmjheen: i64,
|
||||
pub end_timestamp: i64,
|
||||
#[xor(5317)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub ialhcipedom: u32,
|
||||
|
@ -33225,7 +33225,7 @@ pub struct Gkegfnbpiok {
|
|||
pub star: u32,
|
||||
#[xor(15011)]
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(810)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub exp: u32,
|
||||
|
@ -33399,7 +33399,7 @@ pub struct Jcincgmdflc {
|
|||
pub olcifcglpdd: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(3275)]
|
||||
#[prost(uint32, tag = "11")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[xor(10845)]
|
||||
#[prost(uint32, tag = "13")]
|
||||
pub quest_id: u32,
|
||||
|
@ -33777,7 +33777,7 @@ pub struct Jhinopamaoa {
|
|||
pub avatars: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(6842)]
|
||||
#[prost(uint32, tag = "14")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[prost(uint32, repeated, tag = "3")]
|
||||
pub obpdhglkbgk: ::prost::alloc::vec::Vec<u32>,
|
||||
#[xor(8158)]
|
||||
|
@ -34490,7 +34490,7 @@ pub struct Jiflifhgkhk {
|
|||
pub is_story: bool,
|
||||
#[xor(7590)]
|
||||
#[prost(uint32, tag = "5")]
|
||||
pub buddy: u32,
|
||||
pub buddy_id: u32,
|
||||
#[prost(bool, tag = "14")]
|
||||
pub jcflmpbcojd: bool,
|
||||
}
|
||||
|
@ -48346,32 +48346,32 @@ impl DungeonContentDropPoolType {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum Hneekphmejf {
|
||||
Jhlmmfkphgb = 0,
|
||||
Kjppindjool = 1,
|
||||
Ehemncmjnkg = 2,
|
||||
Lddkjjhcikb = 3,
|
||||
pub enum BuddyTeamType {
|
||||
None = 0,
|
||||
Unknown = 1,
|
||||
Fighting = 2,
|
||||
Assisting = 3,
|
||||
}
|
||||
impl Hneekphmejf {
|
||||
impl BuddyTeamType {
|
||||
/// 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 {
|
||||
Hneekphmejf::Jhlmmfkphgb => "HNEEKPHMEJF_JHLMMFKPHGB",
|
||||
Hneekphmejf::Kjppindjool => "HNEEKPHMEJF_KJPPINDJOOL",
|
||||
Hneekphmejf::Ehemncmjnkg => "HNEEKPHMEJF_EHEMNCMJNKG",
|
||||
Hneekphmejf::Lddkjjhcikb => "HNEEKPHMEJF_LDDKJJHCIKB",
|
||||
BuddyTeamType::None => "BUDDY_TEAM_TYPE_NONE",
|
||||
BuddyTeamType::Unknown => "BUDDY_TEAM_TYPE_UNKNOWN",
|
||||
BuddyTeamType::Fighting => "BUDDY_TEAM_TYPE_FIGHTING",
|
||||
BuddyTeamType::Assisting => "BUDDY_TEAM_TYPE_ASSISTING",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"HNEEKPHMEJF_JHLMMFKPHGB" => Some(Self::Jhlmmfkphgb),
|
||||
"HNEEKPHMEJF_KJPPINDJOOL" => Some(Self::Kjppindjool),
|
||||
"HNEEKPHMEJF_EHEMNCMJNKG" => Some(Self::Ehemncmjnkg),
|
||||
"HNEEKPHMEJF_LDDKJJHCIKB" => Some(Self::Lddkjjhcikb),
|
||||
"BUDDY_TEAM_TYPE_NONE" => Some(Self::None),
|
||||
"BUDDY_TEAM_TYPE_UNKNOWN" => Some(Self::Unknown),
|
||||
"BUDDY_TEAM_TYPE_FIGHTING" => Some(Self::Fighting),
|
||||
"BUDDY_TEAM_TYPE_ASSISTING" => Some(Self::Assisting),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -54259,9 +54259,9 @@ pub enum ItemStatic {
|
|||
FrontendGold = 10,
|
||||
GameDiamond = 100,
|
||||
RechargeDiamond = 101,
|
||||
Lcdlfoheaim = 110,
|
||||
Mndhfchkhcl = 111,
|
||||
Fcffdnjnemf = 112,
|
||||
GachaTicketStandard = 110,
|
||||
GachaTicketEvent = 111,
|
||||
GachaTicketBangboo = 112,
|
||||
Exp = 201,
|
||||
Energy = 501,
|
||||
Gdglcfmgoji = 3000001,
|
||||
|
@ -54280,9 +54280,9 @@ impl ItemStatic {
|
|||
ItemStatic::FrontendGold => "ITEM_STATIC_FRONTEND_GOLD",
|
||||
ItemStatic::GameDiamond => "ITEM_STATIC_GAME_DIAMOND",
|
||||
ItemStatic::RechargeDiamond => "ITEM_STATIC_RECHARGE_DIAMOND",
|
||||
ItemStatic::Lcdlfoheaim => "ItemStatic_LCDLFOHEAIM",
|
||||
ItemStatic::Mndhfchkhcl => "ItemStatic_MNDHFCHKHCL",
|
||||
ItemStatic::Fcffdnjnemf => "ItemStatic_FCFFDNJNEMF",
|
||||
ItemStatic::GachaTicketStandard => "ItemStatic_GACHA_TICKET_STANDARD",
|
||||
ItemStatic::GachaTicketEvent => "ItemStatic_GACHA_TICKET_EVENT",
|
||||
ItemStatic::GachaTicketBangboo => "ItemStatic_GACHA_TICKET_BANGBOO",
|
||||
ItemStatic::Exp => "ITEM_STATIC_EXP",
|
||||
ItemStatic::Energy => "ITEM_STATIC_ENERGY",
|
||||
ItemStatic::Gdglcfmgoji => "ItemStatic_GDGLCFMGOJI",
|
||||
|
@ -54298,9 +54298,9 @@ impl ItemStatic {
|
|||
"ITEM_STATIC_FRONTEND_GOLD" => Some(Self::FrontendGold),
|
||||
"ITEM_STATIC_GAME_DIAMOND" => Some(Self::GameDiamond),
|
||||
"ITEM_STATIC_RECHARGE_DIAMOND" => Some(Self::RechargeDiamond),
|
||||
"ItemStatic_LCDLFOHEAIM" => Some(Self::Lcdlfoheaim),
|
||||
"ItemStatic_MNDHFCHKHCL" => Some(Self::Mndhfchkhcl),
|
||||
"ItemStatic_FCFFDNJNEMF" => Some(Self::Fcffdnjnemf),
|
||||
"ItemStatic_GACHA_TICKET_STANDARD" => Some(Self::GachaTicketStandard),
|
||||
"ItemStatic_GACHA_TICKET_EVENT" => Some(Self::GachaTicketEvent),
|
||||
"ItemStatic_GACHA_TICKET_BANGBOO" => Some(Self::GachaTicketBangboo),
|
||||
"ITEM_STATIC_EXP" => Some(Self::Exp),
|
||||
"ITEM_STATIC_ENERGY" => Some(Self::Energy),
|
||||
"ItemStatic_GDGLCFMGOJI" => Some(Self::Gdglcfmgoji),
|
||||
|
@ -55320,50 +55320,62 @@ impl Jiedoddkipa {
|
|||
#[derive(proto_gen::XorFields)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
|
||||
#[repr(i32)]
|
||||
pub enum Obpfhejepck {
|
||||
pub enum DisconnectReason {
|
||||
Domjllafeac = 0,
|
||||
Gdbjccehcdb = 1,
|
||||
/// 您的账号在其他地方登录,请检查是否存在账号泄露风险,是否要重新登录游戏?
|
||||
ServerRelogin = 1,
|
||||
Clcbejonokn = 2,
|
||||
Jlimlghggke = 3,
|
||||
Omjjggajcbh = 4,
|
||||
Kdpiceebneb = 5,
|
||||
/// 游戏正在维护中,请等维护完成后再尝试登录。
|
||||
ServerShutdown = 3,
|
||||
/// UID:"3"
|
||||
/// 您已掉线,请返回登录界面重试
|
||||
ServerKick = 4,
|
||||
/// 登录状态已失效,请重新登录
|
||||
AccountPasswordChange = 5,
|
||||
/// 您已断开链接,请重新登录
|
||||
Nmcpihldicf = 6,
|
||||
/// 您的卡死问题已处理完成,请重新登录游戏
|
||||
Ihcmpplkgkn = 7,
|
||||
/// 您的PSN™的好友关系已解绑,现在可自由处理游戏内好友关系
|
||||
Lgjemnlahcp = 8,
|
||||
Mfgomdhiejh = 9,
|
||||
}
|
||||
impl Obpfhejepck {
|
||||
impl DisconnectReason {
|
||||
/// 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 {
|
||||
Obpfhejepck::Domjllafeac => "OBPFHEJEPCK_DOMJLLAFEAC",
|
||||
Obpfhejepck::Gdbjccehcdb => "OBPFHEJEPCK_GDBJCCEHCDB",
|
||||
Obpfhejepck::Clcbejonokn => "OBPFHEJEPCK_CLCBEJONOKN",
|
||||
Obpfhejepck::Jlimlghggke => "OBPFHEJEPCK_JLIMLGHGGKE",
|
||||
Obpfhejepck::Omjjggajcbh => "OBPFHEJEPCK_OMJJGGAJCBH",
|
||||
Obpfhejepck::Kdpiceebneb => "OBPFHEJEPCK_KDPICEEBNEB",
|
||||
Obpfhejepck::Nmcpihldicf => "OBPFHEJEPCK_NMCPIHLDICF",
|
||||
Obpfhejepck::Ihcmpplkgkn => "OBPFHEJEPCK_IHCMPPLKGKN",
|
||||
Obpfhejepck::Lgjemnlahcp => "OBPFHEJEPCK_LGJEMNLAHCP",
|
||||
Obpfhejepck::Mfgomdhiejh => "OBPFHEJEPCK_MFGOMDHIEJH",
|
||||
DisconnectReason::Domjllafeac => "DISCONNECT_REASON_DOMJLLAFEAC",
|
||||
DisconnectReason::ServerRelogin => "DISCONNECT_REASON_SERVER_RELOGIN",
|
||||
DisconnectReason::Clcbejonokn => "DISCONNECT_REASON_CLCBEJONOKN",
|
||||
DisconnectReason::ServerShutdown => "DISCONNECT_REASON_SERVER_SHUTDOWN",
|
||||
DisconnectReason::ServerKick => "DISCONNECT_REASON_SERVER_KICK",
|
||||
DisconnectReason::AccountPasswordChange => {
|
||||
"DISCONNECT_REASON_ACCOUNT_PASSWORD_CHANGE"
|
||||
}
|
||||
DisconnectReason::Nmcpihldicf => "DISCONNECT_REASON_NMCPIHLDICF",
|
||||
DisconnectReason::Ihcmpplkgkn => "DISCONNECT_REASON_IHCMPPLKGKN",
|
||||
DisconnectReason::Lgjemnlahcp => "DISCONNECT_REASON_LGJEMNLAHCP",
|
||||
DisconnectReason::Mfgomdhiejh => "DISCONNECT_REASON_MFGOMDHIEJH",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
|
||||
match value {
|
||||
"OBPFHEJEPCK_DOMJLLAFEAC" => Some(Self::Domjllafeac),
|
||||
"OBPFHEJEPCK_GDBJCCEHCDB" => Some(Self::Gdbjccehcdb),
|
||||
"OBPFHEJEPCK_CLCBEJONOKN" => Some(Self::Clcbejonokn),
|
||||
"OBPFHEJEPCK_JLIMLGHGGKE" => Some(Self::Jlimlghggke),
|
||||
"OBPFHEJEPCK_OMJJGGAJCBH" => Some(Self::Omjjggajcbh),
|
||||
"OBPFHEJEPCK_KDPICEEBNEB" => Some(Self::Kdpiceebneb),
|
||||
"OBPFHEJEPCK_NMCPIHLDICF" => Some(Self::Nmcpihldicf),
|
||||
"OBPFHEJEPCK_IHCMPPLKGKN" => Some(Self::Ihcmpplkgkn),
|
||||
"OBPFHEJEPCK_LGJEMNLAHCP" => Some(Self::Lgjemnlahcp),
|
||||
"OBPFHEJEPCK_MFGOMDHIEJH" => Some(Self::Mfgomdhiejh),
|
||||
"DISCONNECT_REASON_DOMJLLAFEAC" => Some(Self::Domjllafeac),
|
||||
"DISCONNECT_REASON_SERVER_RELOGIN" => Some(Self::ServerRelogin),
|
||||
"DISCONNECT_REASON_CLCBEJONOKN" => Some(Self::Clcbejonokn),
|
||||
"DISCONNECT_REASON_SERVER_SHUTDOWN" => Some(Self::ServerShutdown),
|
||||
"DISCONNECT_REASON_SERVER_KICK" => Some(Self::ServerKick),
|
||||
"DISCONNECT_REASON_ACCOUNT_PASSWORD_CHANGE" => {
|
||||
Some(Self::AccountPasswordChange)
|
||||
}
|
||||
"DISCONNECT_REASON_NMCPIHLDICF" => Some(Self::Nmcpihldicf),
|
||||
"DISCONNECT_REASON_IHCMPPLKGKN" => Some(Self::Ihcmpplkgkn),
|
||||
"DISCONNECT_REASON_LGJEMNLAHCP" => Some(Self::Lgjemnlahcp),
|
||||
"DISCONNECT_REASON_MFGOMDHIEJH" => Some(Self::Mfgomdhiejh),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,92 @@ pub struct MainCityModelBin {
|
|||
#[prost(uint32, tag = "3")]
|
||||
pub section_id: u32,
|
||||
}
|
||||
/// The progress record of a specified rarity. All maps' keys are category_guarantee_policy_tag.
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GachaProgressBin {
|
||||
/// The pity (counting how many pulls) of this pull (in previous record) or the next pull (in status).
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub pity: u32,
|
||||
/// The failure times of this category.
|
||||
#[prost(map = "string, uint32", tag = "2")]
|
||||
pub categories_progress_map: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
u32,
|
||||
>,
|
||||
/// The selected priority (category) for a Chooseable category.
|
||||
#[prost(map = "string, string", tag = "3")]
|
||||
pub categories_chosen_guarantee_category_map: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
::prost::alloc::string::String,
|
||||
>,
|
||||
/// The selectedpriority (a specified item) for a Chooseable category.
|
||||
#[prost(map = "string, uint32", tag = "4")]
|
||||
pub categories_chosen_guarantee_item_map: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
u32,
|
||||
>,
|
||||
/// The failure times for selected priority (a specified item).
|
||||
#[prost(map = "string, uint32", tag = "5")]
|
||||
pub categories_chosen_guarantee_progress_map: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
u32,
|
||||
>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GachaExtraItemBin {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub extra_item_id: u32,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub extra_item_count: u32,
|
||||
/// How many objects of the main item obtained in gacha is present in the player's bag (before gacha).
|
||||
/// This is used for something like converting when there're extra characters.
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub currently_gained: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GachaRecordBin {
|
||||
#[prost(int64, tag = "1")]
|
||||
pub pull_timestamp: i64,
|
||||
#[prost(uint32, tag = "2")]
|
||||
pub obtained_item_id: u32,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub gacha_id: u32,
|
||||
/// The progress BEFORE this gacha is performed. uint32 is rarity.
|
||||
#[prost(map = "uint32, message", tag = "4")]
|
||||
pub progress_map: ::std::collections::HashMap<u32, GachaProgressBin>,
|
||||
#[prost(message, optional, tag = "5")]
|
||||
pub extra_item_bin: ::core::option::Option<GachaExtraItemBin>,
|
||||
#[prost(enumeration = "GachaAddedItemType", tag = "6")]
|
||||
pub item_type: i32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GachaStatusBin {
|
||||
#[prost(map = "uint32, message", tag = "1")]
|
||||
pub rarity_status_map: ::std::collections::HashMap<u32, GachaProgressBin>,
|
||||
#[prost(map = "string, uint32", tag = "2")]
|
||||
pub discount_usage_map: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
u32,
|
||||
>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct GachaModelBin {
|
||||
/// Gacha Status query. string is sharing_guarantee_info_category.
|
||||
#[prost(map = "string, message", tag = "1")]
|
||||
pub gacha_status_map: ::std::collections::HashMap<
|
||||
::prost::alloc::string::String,
|
||||
GachaStatusBin,
|
||||
>,
|
||||
#[prost(message, repeated, tag = "2")]
|
||||
pub gacha_records: ::prost::alloc::vec::Vec<GachaRecordBin>,
|
||||
#[prost(uint32, tag = "3")]
|
||||
pub random_number: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PlayerDataBin {
|
||||
|
@ -130,4 +216,38 @@ pub struct PlayerDataBin {
|
|||
pub item_model: ::core::option::Option<ItemModelBin>,
|
||||
#[prost(message, optional, tag = "5")]
|
||||
pub main_city_model: ::core::option::Option<MainCityModelBin>,
|
||||
#[prost(message, optional, tag = "6")]
|
||||
pub gacha_model: ::core::option::Option<GachaModelBin>,
|
||||
}
|
||||
#[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<Self> {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue