Proper character HP in battle, fix some ordering issues
This commit is contained in:
parent
eb641d67fb
commit
0e0a78abaa
15 changed files with 234 additions and 64 deletions
|
@ -41,6 +41,8 @@ tracing-subscriber = { version = "0.3.18", features = [
|
||||||
] }
|
] }
|
||||||
tracing-bunyan-formatter = "0.3.9"
|
tracing-bunyan-formatter = "0.3.9"
|
||||||
|
|
||||||
|
itertools = "0.13.0"
|
||||||
|
|
||||||
common = { version = "0.1.0", path = "common" }
|
common = { version = "0.1.0", path = "common" }
|
||||||
protocol = { version = "0.1.0", path = "protocol" }
|
protocol = { version = "0.1.0", path = "protocol" }
|
||||||
qwer = { version = "0.1.0", path = "qwer", features = ["full"] }
|
qwer = { version = "0.1.0", path = "qwer", features = ["full"] }
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
pub fn load_or_create_config(path: &str, defaults: &str) -> String {
|
pub fn load_or_create_config(path: &str, defaults: &str) -> String {
|
||||||
std::fs::read_to_string(path).map_or_else(
|
std::fs::read_to_string(path).map_or_else(
|
||||||
|_| {
|
|_| {
|
||||||
|
@ -7,3 +9,17 @@ pub fn load_or_create_config(path: &str, defaults: &str) -> String {
|
||||||
|data| data,
|
|data| data,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cur_timestamp_ms() -> i64 {
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_millis() as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cur_timestamp_seconds() -> i64 {
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs() as i64
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ hex.workspace = true
|
||||||
lazy_static.workspace = true
|
lazy_static.workspace = true
|
||||||
paste.workspace = true
|
paste.workspace = true
|
||||||
sysinfo.workspace = true
|
sysinfo.workspace = true
|
||||||
|
itertools.workspace = true
|
||||||
|
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
|
@ -92,21 +92,25 @@ impl DungeonManager {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let add_dungeon = dungeon_info.clone();
|
||||||
|
let add_scene = scene_info.clone();
|
||||||
|
let cur_scene_uid = scene_info.get_uid();
|
||||||
|
|
||||||
Ok(PlayerOperationResult::with_changes(
|
Ok(PlayerOperationResult::with_changes(
|
||||||
ptc_enter_scene,
|
ptc_enter_scene,
|
||||||
PlayerInfo {
|
PlayerInfo {
|
||||||
dungeon_collection: Some(DungeonCollection {
|
dungeon_collection: Some(DungeonCollection {
|
||||||
dungeons: Some(PropertyHashMap::Modify {
|
dungeons: Some(PropertyHashMap::Modify {
|
||||||
to_add: vec![(dungeon_info.uid, dungeon_info.clone())],
|
to_add: vec![(add_dungeon.uid, add_dungeon)],
|
||||||
to_remove: Vec::new(),
|
to_remove: Vec::new(),
|
||||||
}),
|
}),
|
||||||
scenes: Some(PropertyHashMap::Modify {
|
scenes: Some(PropertyHashMap::Modify {
|
||||||
to_add: vec![(scene_info.get_uid(), scene_info.clone())],
|
to_add: vec![(add_scene.get_uid(), add_scene)],
|
||||||
to_remove: Vec::new(),
|
to_remove: Vec::new(),
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
scene_uid: Some(scene_info.get_uid()),
|
scene_uid: Some(cur_scene_uid),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
|
@ -259,6 +263,8 @@ impl DungeonManager {
|
||||||
.get_mut(&cur_scene_uid)
|
.get_mut(&cur_scene_uid)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let dungeon_uid = hollow_scene.get_dungeon_uid();
|
||||||
|
|
||||||
if let SceneInfo::Hollow {
|
if let SceneInfo::Hollow {
|
||||||
hollow_system_ui_state,
|
hollow_system_ui_state,
|
||||||
..
|
..
|
||||||
|
@ -271,12 +277,33 @@ impl DungeonManager {
|
||||||
hollow_system_ui_state.insert(HollowSystemType::Menu, HollowSystemUIState::Close);
|
hollow_system_ui_state.insert(HollowSystemType::Menu, HollowSystemUIState::Close);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let add_scene = hollow_scene.clone();
|
||||||
|
|
||||||
|
let quest_data = player.quest_data.as_ref().unwrap();
|
||||||
|
let mut dungeon_quest = quest_data
|
||||||
|
.quests
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.get(&dungeon_uid, &1001000101)
|
||||||
|
.unwrap()
|
||||||
|
.clone();
|
||||||
|
dungeon_quest.set_progress(1);
|
||||||
|
dungeon_quest.set_finished_count(1);
|
||||||
|
dungeon_quest.set_state(QuestState::Finished);
|
||||||
|
|
||||||
PlayerOperationResult::with_changes(
|
PlayerOperationResult::with_changes(
|
||||||
cur_scene_uid,
|
cur_scene_uid,
|
||||||
PlayerInfo {
|
PlayerInfo {
|
||||||
dungeon_collection: Some(DungeonCollection {
|
dungeon_collection: Some(DungeonCollection {
|
||||||
scenes: Some(PropertyHashMap::Modify {
|
scenes: Some(PropertyHashMap::Modify {
|
||||||
to_add: vec![(cur_scene_uid, hollow_scene.clone())],
|
to_add: vec![(cur_scene_uid, add_scene)],
|
||||||
|
to_remove: Vec::new(),
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
quest_data: Some(QuestData {
|
||||||
|
quests: Some(PropertyDoubleKeyHashMap::Modify {
|
||||||
|
to_add: vec![(dungeon_uid, 1001000101, dungeon_quest)],
|
||||||
to_remove: Vec::new(),
|
to_remove: Vec::new(),
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -1,22 +1,14 @@
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
|
|
||||||
const BASE_UID: u64 = 1000000;
|
pub struct UniqueIDManager(AtomicU64);
|
||||||
|
|
||||||
pub struct UniqueIDManager {
|
|
||||||
uid_counter: AtomicU64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UniqueIDManager {
|
impl UniqueIDManager {
|
||||||
|
const BASE_UID: u64 = 1000000;
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
Self {
|
Self(AtomicU64::new(Self::BASE_UID))
|
||||||
uid_counter: AtomicU64::new(BASE_UID),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&self) -> u64 {
|
pub fn next(&self) -> u64 {
|
||||||
let uid = self.uid_counter.load(Ordering::SeqCst) + 1;
|
self.0.fetch_add(1, Ordering::SeqCst) + 1
|
||||||
self.uid_counter.store(uid, Ordering::SeqCst);
|
|
||||||
|
|
||||||
uid
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub async fn listen(bind_addr: &str) -> Result<()> {
|
||||||
|
|
||||||
tracing::info!("New session from {client_addr}");
|
tracing::info!("New session from {client_addr}");
|
||||||
|
|
||||||
let mut session = NetworkSession::new(client_socket, client_addr);
|
let mut session = NetworkSession::new(client_socket);
|
||||||
tokio::spawn(
|
tokio::spawn(
|
||||||
async move {
|
async move {
|
||||||
log_error!(
|
log_error!(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use common::util;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -28,15 +28,11 @@ pub async fn on_rpc_beginnerbattle_begin_arg(
|
||||||
session: &NetworkSession,
|
session: &NetworkSession,
|
||||||
arg: &RpcBeginnerbattleBeginArg,
|
arg: &RpcBeginnerbattleBeginArg,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let cur_timestamp = SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.unwrap()
|
|
||||||
.as_secs();
|
|
||||||
|
|
||||||
session
|
session
|
||||||
.send_rpc_ret(RpcBeginnerbattleBeginRet::new(format!(
|
.send_rpc_ret(RpcBeginnerbattleBeginRet::new(format!(
|
||||||
"{cur_timestamp}-{}",
|
"{}-{}",
|
||||||
arg.battle_id
|
arg.battle_id,
|
||||||
|
util::cur_timestamp_seconds()
|
||||||
)))
|
)))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
use itertools::Itertools;
|
||||||
use qwer::{phashmap, phashset, PropertyHashMap, PropertyHashSet};
|
use qwer::{phashmap, phashset, PropertyHashMap, PropertyHashSet};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::data;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub async fn on_rpc_hollow_move_arg(
|
pub async fn on_rpc_hollow_move_arg(
|
||||||
|
@ -59,7 +62,7 @@ pub async fn on_rpc_end_battle_arg(session: &NetworkSession, arg: &RpcEndBattleA
|
||||||
quest_id: 1001000101,
|
quest_id: 1001000101,
|
||||||
success: true,
|
success: true,
|
||||||
reward_items: phashmap![],
|
reward_items: phashmap![],
|
||||||
statistics: phashmap![],
|
statistics: phashmap![(QuestStatisticsType::ArrivedLevel, 1)],
|
||||||
};
|
};
|
||||||
|
|
||||||
session
|
session
|
||||||
|
@ -211,12 +214,31 @@ pub async fn on_rpc_start_hollow_quest_arg(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
tracing::info!("start hollow quest: {arg:?}");
|
tracing::info!("start hollow quest: {arg:?}");
|
||||||
|
|
||||||
|
// Set avatar HP properties
|
||||||
for (_idx, avatar_uid) in &arg.avatar_map {
|
for (_idx, avatar_uid) in &arg.avatar_map {
|
||||||
// Set character HP
|
let player_info = session.get_player();
|
||||||
|
let items = player_info.items.as_ref().unwrap();
|
||||||
|
let Some(ItemInfo::Avatar { id, .. }) = items
|
||||||
|
.iter()
|
||||||
|
.find(|(uid, _)| **uid == *avatar_uid)
|
||||||
|
.map(|(_, item)| item)
|
||||||
|
else {
|
||||||
|
return session
|
||||||
|
.send_rpc_ret(RpcStartHollowQuestRet::error(
|
||||||
|
ErrorCode::ObjectNotExist,
|
||||||
|
Vec::new(),
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
};
|
||||||
|
|
||||||
|
let avatar_config = data::iter_avatar_config_collection()
|
||||||
|
.find(|c| c.id == *id)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let update_properties = PtcPropertyChangedArg {
|
let update_properties = PtcPropertyChangedArg {
|
||||||
scene_unit_uid: *avatar_uid,
|
scene_unit_uid: *avatar_uid,
|
||||||
is_partial: true,
|
is_partial: true,
|
||||||
changed_properties: phashmap![(1, 500), (111, 500)],
|
changed_properties: phashmap![(1, avatar_config.hp), (111, avatar_config.hp)],
|
||||||
};
|
};
|
||||||
|
|
||||||
session.send_rpc_arg(129, &update_properties).await?;
|
session.send_rpc_arg(129, &update_properties).await?;
|
||||||
|
@ -227,6 +249,7 @@ pub async fn on_rpc_start_hollow_quest_arg(
|
||||||
let avatars = arg
|
let avatars = arg
|
||||||
.avatar_map
|
.avatar_map
|
||||||
.iter()
|
.iter()
|
||||||
|
.sorted_by_key(|kv| kv.0)
|
||||||
.map(|(_idx, uid)| *uid)
|
.map(|(_idx, uid)| *uid)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let (dungeon_uid, scene_uid) = *dungeon_manager
|
let (dungeon_uid, scene_uid) = *dungeon_manager
|
||||||
|
|
|
@ -227,7 +227,7 @@ pub async fn on_rpc_enter_world_arg(
|
||||||
|
|
||||||
let quest_manager = session.context.quest_manager.borrow();
|
let quest_manager = session.context.quest_manager.borrow();
|
||||||
quest_manager.add_world_quest(QuestInfo::MainCity {
|
quest_manager.add_world_quest(QuestInfo::MainCity {
|
||||||
id: 10020001,
|
id: 10020002,
|
||||||
finished_count: 0,
|
finished_count: 0,
|
||||||
collection_uid: 0,
|
collection_uid: 0,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
|
|
|
@ -3,7 +3,6 @@ use atomic_refcell::{AtomicRef, AtomicRefMut};
|
||||||
use protocol::*;
|
use protocol::*;
|
||||||
use qwer::{OctData, ProtocolHeader};
|
use qwer::{OctData, ProtocolHeader};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
|
@ -16,25 +15,27 @@ use super::{packet::PacketHandler, Packet, RequestBody, ResponseBody};
|
||||||
|
|
||||||
pub struct NetworkSession {
|
pub struct NetworkSession {
|
||||||
client_socket: Arc<Mutex<TcpStream>>,
|
client_socket: Arc<Mutex<TcpStream>>,
|
||||||
client_addr: SocketAddr,
|
|
||||||
cur_rpc_uid: u64,
|
cur_rpc_uid: u64,
|
||||||
pub ns_prop_mgr: net_stream::PropertyManager,
|
pub ns_prop_mgr: net_stream::PropertyManager,
|
||||||
pub context: GameContext,
|
pub context: GameContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkSession {
|
impl NetworkSession {
|
||||||
pub fn new(client_socket: TcpStream, client_addr: SocketAddr) -> Self {
|
pub fn new(client_socket: TcpStream) -> Self {
|
||||||
let ns_prop_mgr = net_stream::PropertyManager::default();
|
let ns_prop_mgr = net_stream::PropertyManager::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
client_socket: Arc::new(Mutex::new(client_socket)),
|
client_socket: Arc::new(Mutex::new(client_socket)),
|
||||||
client_addr,
|
|
||||||
cur_rpc_uid: 0,
|
cur_rpc_uid: 0,
|
||||||
context: GameContext::new(ns_prop_mgr.player_info.clone()),
|
context: GameContext::new(ns_prop_mgr.player_info.clone()),
|
||||||
ns_prop_mgr,
|
ns_prop_mgr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn client_socket(&self) -> MutexGuard<'_, TcpStream> {
|
||||||
|
self.client_socket.lock().await
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_player_uid(&self) -> u64 {
|
pub fn get_player_uid(&self) -> u64 {
|
||||||
self.get_player().uid.unwrap()
|
self.get_player().uid.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -55,20 +56,10 @@ impl NetworkSession {
|
||||||
self.ns_prop_mgr.player_info.try_borrow_mut().unwrap()
|
self.ns_prop_mgr.player_info.try_borrow_mut().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn client_socket(&self) -> MutexGuard<'_, TcpStream> {
|
|
||||||
self.client_socket.lock().await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run(&mut self) -> Result<()> {
|
pub async fn run(&mut self) -> Result<()> {
|
||||||
let channel_id = match self.read_handshake().await {
|
let Some(_channel_id) = self.read_handshake().await? else {
|
||||||
Ok(channel_id) => channel_id,
|
return Ok(());
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => return Ok(()),
|
|
||||||
Err(e) => return Err(e.into()),
|
|
||||||
};
|
};
|
||||||
tracing::info!(
|
|
||||||
"Session ({}) bound to channel {channel_id}",
|
|
||||||
self.client_addr
|
|
||||||
);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let packet = match Packet::read(&mut *self.client_socket().await).await {
|
let packet = match Packet::read(&mut *self.client_socket().await).await {
|
||||||
|
@ -83,8 +74,12 @@ impl NetworkSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_handshake(&mut self) -> Result<u16, std::io::Error> {
|
async fn read_handshake(&mut self) -> Result<Option<u16>> {
|
||||||
self.client_socket().await.read_u16_le().await
|
match self.client_socket().await.read_u16_le().await {
|
||||||
|
Ok(channel_id) => Ok(Some(channel_id)),
|
||||||
|
Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => Ok(None),
|
||||||
|
Err(e) => return Err(e.into()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_rpc_ret(&self, data: impl OctData) -> Result<()> {
|
pub async fn send_rpc_ret(&self, data: impl OctData) -> Result<()> {
|
||||||
|
|
|
@ -5,9 +5,101 @@ use super::*;
|
||||||
pub enum ErrorCode {
|
pub enum ErrorCode {
|
||||||
Fail = -1,
|
Fail = -1,
|
||||||
Success = 0,
|
Success = 0,
|
||||||
|
Timeout = 1,
|
||||||
|
EntityNotExist = 2,
|
||||||
|
InvalidVersion = 3,
|
||||||
|
InvalidTemplateID = 4,
|
||||||
|
InvalidConfigVersion = 5,
|
||||||
|
ObjectNotExist = 100,
|
||||||
|
ConfigError = 101,
|
||||||
|
NoEnoughRes = 102,
|
||||||
|
NoEnoughEXP = 103,
|
||||||
|
NoEnoughItem = 104,
|
||||||
|
NoEnoughMaterials = 105,
|
||||||
|
NoEnoughGoods = 106,
|
||||||
|
NoEnoughCurrency = 107,
|
||||||
|
CannotFindGoods = 108,
|
||||||
|
AvatarMaxLevelLimit = 109,
|
||||||
|
AvatarMaxStarLimit = 110,
|
||||||
|
AvatarMaxAdvanceLevelLimit = 111,
|
||||||
|
EquipMaxLevelLimit = 112,
|
||||||
|
EquipMaxStarLimit = 113,
|
||||||
|
SceneAlreadyDestroyed = 114,
|
||||||
|
StageAlreadyDestroyed = 115,
|
||||||
|
ErrorSrcPosition = 116,
|
||||||
|
ErrorGraph = 117,
|
||||||
|
NodeFinished = 118,
|
||||||
|
NodeRunFailure = 119,
|
||||||
|
UnknownAvatarSkill = 120,
|
||||||
|
AvatarSkillMaxLevelLimit = 121,
|
||||||
|
AvatarTalentMaxLevelLimit = 122,
|
||||||
|
AvatarStarNotEnough = 123,
|
||||||
|
InvalidActionMovePath = 124,
|
||||||
|
ActionIDNotExist = 125,
|
||||||
|
NickNameMaxLength = 126,
|
||||||
|
NickNameIllegal = 127,
|
||||||
|
Ban = 128,
|
||||||
|
RepeatedLogin = 129,
|
||||||
|
FuncNotOpen = 130,
|
||||||
|
TokenError = 131,
|
||||||
|
PlayerNotExist = 132,
|
||||||
|
InvalidParam = 133,
|
||||||
|
ItemBeOccupy = 134,
|
||||||
|
ItemBeLock = 135,
|
||||||
|
EquipGachaClose = 136,
|
||||||
|
InvalidQuestState = 137,
|
||||||
|
QuestMaxFinishCnt = 138,
|
||||||
|
NoEnoughTimes = 139,
|
||||||
|
BattleReportLimit = 140,
|
||||||
|
BattleReportInvalid = 141,
|
||||||
|
MaxLevelLimit = 142,
|
||||||
|
MaxStarLimit = 143,
|
||||||
|
MaxRefineLimit = 144,
|
||||||
|
AlreadyGet = 145,
|
||||||
|
RepeatedModName = 146,
|
||||||
|
VHSStoreUnlock = 147,
|
||||||
|
VHSStoreAlreadSlot = 148,
|
||||||
|
VHSStoreSlotNumErr = 149,
|
||||||
|
FuncNotUnlock = 150,
|
||||||
|
VHSStoreRamenContinueEat = 151,
|
||||||
|
VHSStoreAlreadyUnlock = 152,
|
||||||
|
AFKGamePlayClose = 153,
|
||||||
|
InitiativeItemUnlock = 154,
|
||||||
|
InitiativeItemLevel = 155,
|
||||||
|
PrepareAvatarsFail = 156,
|
||||||
|
AlreadyAFK = 157,
|
||||||
|
HollowDoEvtListNotEmpty = 158,
|
||||||
|
HollowEvtNotCompleted = 159,
|
||||||
|
HollowMoveFail = 160,
|
||||||
|
BuyNumOverflow = 161,
|
||||||
|
PackgeOverflow = 162,
|
||||||
|
ReplacePkg = 163,
|
||||||
|
FileLenghCheckFaild = 164,
|
||||||
|
HashCheckFaild = 165,
|
||||||
|
DiskNotEnough = 166,
|
||||||
|
NotReachable = 167,
|
||||||
|
ServerException = 168,
|
||||||
|
RequestException = 169,
|
||||||
|
OherDownLoadError = 170,
|
||||||
|
QuestProgressNotEnough = 171,
|
||||||
|
ConditionComplete = 172,
|
||||||
|
ConditionNoComplete = 173,
|
||||||
|
PayErrCode0 = 174,
|
||||||
|
PayErrCode1 = 175,
|
||||||
|
PayErrCode2 = 176,
|
||||||
|
PayErrCode3 = 177,
|
||||||
|
PayErrCode4 = 178,
|
||||||
|
PayErrCode5 = 179,
|
||||||
|
NoWhite = 180,
|
||||||
|
NoWhiteDevice = 181,
|
||||||
|
NoWhiteIp = 182,
|
||||||
|
SdkError = 183,
|
||||||
|
StopServer = 184,
|
||||||
|
AccountServerError = 185,
|
||||||
|
CloseServer = 187,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum HollowQuestType {
|
pub enum HollowQuestType {
|
||||||
Common = 0,
|
Common = 0,
|
||||||
|
@ -48,7 +140,7 @@ pub enum FightRanking {
|
||||||
S = 5,
|
S = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Hash, Clone, Debug, PartialEq, Eq)]
|
#[derive(OctData, Hash, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum BattleRewardType {
|
pub enum BattleRewardType {
|
||||||
Client = 1,
|
Client = 1,
|
||||||
|
@ -79,7 +171,7 @@ pub enum HollowBattleEventType {
|
||||||
LevelFin = 5,
|
LevelFin = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum QuestType {
|
pub enum QuestType {
|
||||||
ArchiveFile = 1,
|
ArchiveFile = 1,
|
||||||
|
@ -113,7 +205,7 @@ pub enum ActionState {
|
||||||
Error = 3,
|
Error = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum DungeonContentDropPoolType {
|
pub enum DungeonContentDropPoolType {
|
||||||
Card = 0,
|
Card = 0,
|
||||||
|
@ -143,14 +235,14 @@ pub enum UIType {
|
||||||
Archive = 3,
|
Archive = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum ACTPerformShowMoment {
|
pub enum ACTPerformShowMoment {
|
||||||
Begin = 0,
|
Begin = 0,
|
||||||
End = 1,
|
End = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum HollowSystemType {
|
pub enum HollowSystemType {
|
||||||
Card = 1,
|
Card = 1,
|
||||||
|
@ -170,7 +262,7 @@ pub enum HollowSystemUIState {
|
||||||
Brighten = 2,
|
Brighten = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum HollowShopType {
|
pub enum HollowShopType {
|
||||||
All = 0,
|
All = 0,
|
||||||
|
@ -203,7 +295,7 @@ pub enum WeatherType {
|
||||||
Thunder = 5,
|
Thunder = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum PropertyType {
|
pub enum PropertyType {
|
||||||
Hp = 1,
|
Hp = 1,
|
||||||
|
@ -333,7 +425,7 @@ pub enum PropertyType {
|
||||||
EnumCount = 10351,
|
EnumCount = 10351,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(i16)]
|
#[repr(i16)]
|
||||||
pub enum ScenePropertyType {
|
pub enum ScenePropertyType {
|
||||||
Stamina = 1001,
|
Stamina = 1001,
|
||||||
|
@ -535,7 +627,7 @@ pub enum QuestState {
|
||||||
Finished = 3,
|
Finished = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(OctData, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(OctData, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum QuestStatisticsType {
|
pub enum QuestStatisticsType {
|
||||||
ArrivedLevel = 1,
|
ArrivedLevel = 1,
|
||||||
|
|
|
@ -658,6 +658,30 @@ macro_rules! polymorphic_quest_info {
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_state(&mut self, state: QuestState) {
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
$name::$variant { state: ref mut c, .. } => *c = state,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_progress(&mut self, progress: u16) {
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
$name::$variant { progress: ref mut c, .. } => *c = progress,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_finished_count(&mut self, finished_count: i32) {
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
$name::$variant { finished_count: ref mut c, .. } => *c = finished_count,
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,3 +13,4 @@ protocol = []
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder.workspace = true
|
byteorder.workspace = true
|
||||||
qwer-derive.workspace = true
|
qwer-derive.workspace = true
|
||||||
|
itertools.workspace = true
|
||||||
|
|
|
@ -612,7 +612,7 @@ fn test_dkhashmap_iter() {
|
||||||
|
|
||||||
impl<K, V> OctData for PropertyHashMap<K, V>
|
impl<K, V> OctData for PropertyHashMap<K, V>
|
||||||
where
|
where
|
||||||
K: OctData + Eq + std::hash::Hash,
|
K: OctData + Eq + Ord + std::hash::Hash,
|
||||||
V: OctData,
|
V: OctData,
|
||||||
{
|
{
|
||||||
fn marshal_to<W: std::io::Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
fn marshal_to<W: std::io::Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
||||||
|
@ -721,8 +721,8 @@ where
|
||||||
|
|
||||||
impl<K1, K2, V> OctData for PropertyDoubleKeyHashMap<K1, K2, V>
|
impl<K1, K2, V> OctData for PropertyDoubleKeyHashMap<K1, K2, V>
|
||||||
where
|
where
|
||||||
K1: OctData + Eq + std::hash::Hash,
|
K1: OctData + Eq + Ord + std::hash::Hash,
|
||||||
K2: OctData + Eq + std::hash::Hash,
|
K2: OctData + Eq + Ord + std::hash::Hash,
|
||||||
V: OctData,
|
V: OctData,
|
||||||
{
|
{
|
||||||
fn marshal_to<W: std::io::Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
fn marshal_to<W: std::io::Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt};
|
use byteorder::{ReadBytesExt, WriteBytesExt};
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
pub use qwer_derive::OctData;
|
pub use qwer_derive::OctData;
|
||||||
|
|
||||||
|
@ -133,12 +134,12 @@ where
|
||||||
|
|
||||||
impl<K, V> OctData for HashMap<K, V>
|
impl<K, V> OctData for HashMap<K, V>
|
||||||
where
|
where
|
||||||
K: OctData + Eq + Hash,
|
K: OctData + Eq + Hash + Ord,
|
||||||
V: OctData,
|
V: OctData,
|
||||||
{
|
{
|
||||||
default fn marshal_to<W: Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
default fn marshal_to<W: Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
||||||
(self.len() as i32).marshal_to(w, bt_property_tag)?;
|
(self.len() as i32).marshal_to(w, bt_property_tag)?;
|
||||||
for (key, value) in self {
|
for (key, value) in self.iter().sorted_by_key(|kv| kv.0) {
|
||||||
key.marshal_to(w, bt_property_tag)?;
|
key.marshal_to(w, bt_property_tag)?;
|
||||||
value.marshal_to(w, bt_property_tag)?;
|
value.marshal_to(w, bt_property_tag)?;
|
||||||
}
|
}
|
||||||
|
@ -164,8 +165,8 @@ where
|
||||||
#[cfg(feature = "collection")]
|
#[cfg(feature = "collection")]
|
||||||
impl<K1, K2, V> OctData for DoubleKeyHashMap<K1, K2, V>
|
impl<K1, K2, V> OctData for DoubleKeyHashMap<K1, K2, V>
|
||||||
where
|
where
|
||||||
K1: OctData + Eq + Hash,
|
K1: OctData + Eq + Hash + Ord,
|
||||||
K2: OctData + Eq + Hash,
|
K2: OctData + Eq + Hash + Ord,
|
||||||
V: OctData,
|
V: OctData,
|
||||||
{
|
{
|
||||||
fn marshal_to<W: Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
fn marshal_to<W: Write>(&self, w: &mut W, bt_property_tag: u16) -> Result<()> {
|
||||||
|
|
Loading…
Reference in a new issue