Queue up Arg packets instead of sending instantly
Change send_rpc_arg to push_rpc_arg. Queue up and Send all Arg packets after handler finish
This commit is contained in:
parent
07560e605a
commit
1609636e90
8 changed files with 81 additions and 56 deletions
|
@ -52,21 +52,21 @@ impl<T> PlayerOperationResult<T>
|
|||
where
|
||||
T: Send + Sync,
|
||||
{
|
||||
pub const fn unwrap(&self) -> &T {
|
||||
&self.result
|
||||
pub fn take(self) -> T {
|
||||
self.result
|
||||
}
|
||||
|
||||
pub async fn send_changes(&mut self, session: &NetworkSession) -> Result<&T> {
|
||||
pub async fn send_changes(mut self, session: &NetworkSession) -> Result<T> {
|
||||
if self.player_info_changes.is_some() {
|
||||
let ptc_player_info_changed = PtcPlayerInfoChangedArg {
|
||||
player_uid: session.player_uid().raw(),
|
||||
player_info: self.player_info_changes.take().unwrap(),
|
||||
};
|
||||
|
||||
session.send_rpc_arg(101, &ptc_player_info_changed).await?;
|
||||
session.push_rpc_arg(101, ptc_player_info_changed).await?;
|
||||
}
|
||||
|
||||
Ok(self.unwrap())
|
||||
Ok(self.take())
|
||||
}
|
||||
|
||||
pub const fn ret(result: T) -> Self {
|
||||
|
|
|
@ -421,7 +421,7 @@ impl DungeonManager {
|
|||
pub fn enter_battle(&self, scene_uid: u64) -> PlayerOperationResult<PtcEnterSceneArg> {
|
||||
let hollow_scene_uid = *self.player.read().scene_uid.as_ref().unwrap();
|
||||
let hollow_scene = self.set_cur_hollow_battle(scene_uid, hollow_scene_uid);
|
||||
let ptc_enter_scene = self.enter_scene(scene_uid).unwrap().unwrap().clone();
|
||||
let ptc_enter_scene = self.enter_scene(scene_uid).unwrap().take().clone();
|
||||
|
||||
let player = self.player.read();
|
||||
let dungeon_collection = player.dungeon_collection.as_ref().unwrap();
|
||||
|
|
|
@ -86,7 +86,7 @@ impl ItemManager {
|
|||
};
|
||||
|
||||
// Unlock & equip default weapon
|
||||
let weapon_uid = *self.unlock_weapon(10012).unwrap();
|
||||
let weapon_uid = self.unlock_weapon(10012).take();
|
||||
self.equip_weapon(weapon_uid, uid);
|
||||
|
||||
let mut player_info = self.player_info.write();
|
||||
|
|
|
@ -21,12 +21,12 @@ pub async fn on_rpc_hollow_move(
|
|||
.move_to(destination_pos, scene_uid);
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_HOLLOW_GRID_ID, &ptc_hollow_grid)
|
||||
.push_rpc_arg(PTC_HOLLOW_GRID_ID, ptc_hollow_grid)
|
||||
.await?;
|
||||
|
||||
if let Some(ptc_sync_hollow_event) = ptc_sync_hollow_event {
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, &ptc_sync_hollow_event)
|
||||
.push_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, ptc_sync_hollow_event)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ pub async fn on_rpc_hollow_move(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_POSITION_IN_HOLLOW_CHANGED_ID, &pos)
|
||||
.push_rpc_arg(PTC_POSITION_IN_HOLLOW_CHANGED_ID, pos)
|
||||
.await?;
|
||||
|
||||
Ok(RpcHollowMoveRet::new(
|
||||
|
@ -57,10 +57,10 @@ pub async fn on_rpc_end_battle(
|
|||
|
||||
if !hollow_finished {
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, &sync_event)
|
||||
.push_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, sync_event)
|
||||
.await?;
|
||||
} else {
|
||||
let _ = *session
|
||||
let _ = session
|
||||
.context
|
||||
.dungeon_manager
|
||||
.hollow_finished()
|
||||
|
@ -76,7 +76,7 @@ pub async fn on_rpc_end_battle(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_DUNGEON_QUEST_FINISHED_ID, &ptc_dungeon_quest_finished)
|
||||
.push_rpc_arg(PTC_DUNGEON_QUEST_FINISHED_ID, ptc_dungeon_quest_finished)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -90,9 +90,9 @@ pub async fn on_rpc_end_battle(
|
|||
.clone();
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_SYNC_HOLLOW_GRID_MAPS_ID,
|
||||
&session.context.hollow_grid_manager.sync_hollow_maps(
|
||||
session.context.hollow_grid_manager.sync_hollow_maps(
|
||||
player_uid,
|
||||
session.context.dungeon_manager.get_cur_scene_uid(),
|
||||
),
|
||||
|
@ -109,14 +109,14 @@ pub async fn on_rpc_end_battle(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_POSITION_IN_HOLLOW_CHANGED_ID,
|
||||
&ptc_position_in_hollow_changed,
|
||||
ptc_position_in_hollow_changed,
|
||||
)
|
||||
.await?;
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_ENTER_SCENE_ID, &ptc_enter_scene)
|
||||
.push_rpc_arg(PTC_ENTER_SCENE_ID, ptc_enter_scene)
|
||||
.await?;
|
||||
|
||||
Ok(RpcEndBattleRet::new(
|
||||
|
@ -156,18 +156,18 @@ pub async fn on_rpc_run_hollow_event_graph(
|
|||
specials: phashmap![],
|
||||
};
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, &finish_perform)
|
||||
.push_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, finish_perform)
|
||||
.await?;
|
||||
|
||||
let (ptc_hollow_grid, ptc_sync_hollow_event) =
|
||||
session.context.hollow_grid_manager.move_to(22, scene_uid);
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_HOLLOW_GRID_ID, &ptc_hollow_grid)
|
||||
.push_rpc_arg(PTC_HOLLOW_GRID_ID, ptc_hollow_grid)
|
||||
.await?;
|
||||
if let Some(ptc_sync_hollow_event) = ptc_sync_hollow_event {
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, &ptc_sync_hollow_event)
|
||||
.push_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, ptc_sync_hollow_event)
|
||||
.await?;
|
||||
}
|
||||
} else {
|
||||
|
@ -178,15 +178,15 @@ pub async fn on_rpc_run_hollow_event_graph(
|
|||
|
||||
if !hollow_finished {
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, &sync_hollow_event)
|
||||
.push_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, sync_hollow_event)
|
||||
.await?;
|
||||
}
|
||||
session
|
||||
.send_rpc_arg(PTC_HOLLOW_GRID_ID, &hollow_grid)
|
||||
.push_rpc_arg(PTC_HOLLOW_GRID_ID, hollow_grid)
|
||||
.await?;
|
||||
|
||||
if hollow_finished {
|
||||
let _ = *session
|
||||
let _ = session
|
||||
.context
|
||||
.dungeon_manager
|
||||
.hollow_finished()
|
||||
|
@ -202,7 +202,7 @@ pub async fn on_rpc_run_hollow_event_graph(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_DUNGEON_QUEST_FINISHED_ID, &ptc_dungeon_quest_finished)
|
||||
.push_rpc_arg(PTC_DUNGEON_QUEST_FINISHED_ID, ptc_dungeon_quest_finished)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ pub async fn on_rpc_run_hollow_event_graph(
|
|||
.scene_uid
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let battle_scene_uid = *session
|
||||
let battle_scene_uid = session
|
||||
.context
|
||||
.dungeon_manager
|
||||
.create_fight(trigger_battle_id, hollow_uid)
|
||||
|
@ -231,14 +231,14 @@ pub async fn on_rpc_run_hollow_event_graph(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_POSITION_IN_HOLLOW_CHANGED_ID,
|
||||
&ptc_position_in_hollow_changed,
|
||||
ptc_position_in_hollow_changed,
|
||||
)
|
||||
.await?;
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_ENTER_SCENE_ID,
|
||||
session
|
||||
.context
|
||||
|
@ -288,7 +288,7 @@ pub async fn on_rpc_start_hollow_quest(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_PROPERTY_CHANGED_ID, &update_properties)
|
||||
.push_rpc_arg(PTC_PROPERTY_CHANGED_ID, update_properties)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ pub async fn on_rpc_start_hollow_quest(
|
|||
.sorted_by_key(|kv| kv.0)
|
||||
.map(|(_idx, uid)| *uid)
|
||||
.collect::<Vec<_>>();
|
||||
let (dungeon_uid, scene_uid) = *session
|
||||
let (dungeon_uid, scene_uid) = session
|
||||
.context
|
||||
.dungeon_manager
|
||||
.create_hollow(10001, 10010001, &avatars)
|
||||
|
@ -336,9 +336,9 @@ pub async fn on_rpc_start_hollow_quest(
|
|||
session.context.hollow_grid_manager.init_default_map();
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_SYNC_HOLLOW_GRID_MAPS_ID,
|
||||
&session
|
||||
session
|
||||
.context
|
||||
.hollow_grid_manager
|
||||
.sync_hollow_maps(session.player_uid().raw(), scene_uid),
|
||||
|
@ -355,9 +355,9 @@ pub async fn on_rpc_start_hollow_quest(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_POSITION_IN_HOLLOW_CHANGED_ID,
|
||||
&ptc_position_in_hollow_changed,
|
||||
ptc_position_in_hollow_changed,
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -380,11 +380,11 @@ pub async fn on_rpc_start_hollow_quest(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, &ptc_sync_hollow_event_info)
|
||||
.push_rpc_arg(PTC_SYNC_HOLLOW_EVENT_INFO_ID, ptc_sync_hollow_event_info)
|
||||
.await?;
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_ENTER_SCENE_ID, &ptc_enter_scene)
|
||||
.push_rpc_arg(PTC_ENTER_SCENE_ID, ptc_enter_scene)
|
||||
.await?;
|
||||
Ok(RpcStartHollowQuestRet::new())
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ macro_rules! protocol_handlers {
|
|||
.instrument(tracing::info_span!(stringify!([<on_$name:snake>]), protocol_id = protocol_id))
|
||||
.await?;
|
||||
|
||||
session.flush_rpc_queue().await?;
|
||||
session.send_rpc_ret(ret).await
|
||||
}
|
||||
)*
|
||||
|
|
|
@ -22,7 +22,7 @@ pub async fn on_rpc_mod_nick_name(
|
|||
};
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_PLAYER_INFO_CHANGED_ID, &player_info_changed)
|
||||
.push_rpc_arg(PTC_PLAYER_INFO_CHANGED_ID, player_info_changed)
|
||||
.await?;
|
||||
Ok(RpcModNickNameRet::new())
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ pub async fn on_rpc_run_event_graph(
|
|||
);
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_EVENT_INFO_ID, &ptc_sync_event_info)
|
||||
.push_rpc_arg(PTC_SYNC_EVENT_INFO_ID, ptc_sync_event_info)
|
||||
.await?;
|
||||
|
||||
Ok(RpcRunEventGraphRet::new())
|
||||
|
@ -89,7 +89,7 @@ pub async fn on_rpc_finish_event_graph_perform_show(
|
|||
);
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_EVENT_INFO_ID, &ptc_sync_event_info)
|
||||
.push_rpc_arg(PTC_SYNC_EVENT_INFO_ID, ptc_sync_event_info)
|
||||
.await?;
|
||||
|
||||
Ok(RpcFinishEventGraphPerformShowRet::new())
|
||||
|
@ -152,7 +152,7 @@ pub async fn on_rpc_interact_with_unit(
|
|||
);
|
||||
|
||||
session
|
||||
.send_rpc_arg(PTC_SYNC_EVENT_INFO_ID, &ptc_sync_event_info)
|
||||
.push_rpc_arg(PTC_SYNC_EVENT_INFO_ID, ptc_sync_event_info)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
@ -206,25 +206,25 @@ pub async fn enter_main_city(session: &NetworkSession) -> Result<()> {
|
|||
let hall_scene_uid = session.context.dungeon_manager.get_default_scene_uid();
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_ENTER_SECTION_ID,
|
||||
session
|
||||
.context
|
||||
.dungeon_manager
|
||||
.enter_scene_section(hall_scene_uid, 2)
|
||||
.unwrap(),
|
||||
.take(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_SYNC_SCENE_UNIT_ID,
|
||||
&session.context.scene_unit_manager.sync(hall_scene_uid, 2),
|
||||
session.context.scene_unit_manager.sync(hall_scene_uid, 2),
|
||||
)
|
||||
.await?;
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_ENTER_SCENE_ID,
|
||||
session
|
||||
.context
|
||||
|
@ -305,24 +305,24 @@ pub async fn on_rpc_enter_world(
|
|||
if CONFIGURATION.skip_tutorial {
|
||||
Box::pin(enter_main_city(session)).await?;
|
||||
} else {
|
||||
let fresh_scene_uid = *session.context.dungeon_manager.create_fresh().unwrap();
|
||||
let fresh_scene_uid = session.context.dungeon_manager.create_fresh().take();
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_ENTER_SCENE_ID,
|
||||
session
|
||||
.context
|
||||
.dungeon_manager
|
||||
.enter_scene(fresh_scene_uid)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
.take(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_SYNC_SCENE_TIME_ID,
|
||||
&PtcSyncSceneTimeArg {
|
||||
PtcSyncSceneTimeArg {
|
||||
timestamp: 3600 * 8 * 1000,
|
||||
last_timestamp: 0,
|
||||
},
|
||||
|
@ -341,9 +341,9 @@ pub async fn on_rpc_reenter_world(
|
|||
tracing::warn!("OnRpcReenterWorld: world re-entrance is not implemented yet, kicking player!");
|
||||
|
||||
session
|
||||
.send_rpc_arg(
|
||||
.push_rpc_arg(
|
||||
PTC_KICK_PLAYER_ID,
|
||||
&PtcKickPlayerArg {
|
||||
PtcKickPlayerArg {
|
||||
reason_id: 2,
|
||||
reason_str: String::new(),
|
||||
},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use protocol::{AccountInfo, PlayerInfo};
|
||||
use qwer::{OctData, ProtocolHeader};
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
@ -33,9 +34,12 @@ impl PlayerUID {
|
|||
}
|
||||
}
|
||||
|
||||
struct QueueItem(pub u16, pub Vec<u8>);
|
||||
|
||||
pub struct NetworkSession {
|
||||
client_socket: Arc<Mutex<TcpStream>>,
|
||||
cur_rpc_uid: u64,
|
||||
outgoing_rpc_queue: Mutex<VecDeque<QueueItem>>,
|
||||
pub ns_prop_mgr: net_stream::PropertyManager,
|
||||
pub context: GameContext,
|
||||
account_uid: OnceCell<AccountUID>,
|
||||
|
@ -49,6 +53,7 @@ impl NetworkSession {
|
|||
Self {
|
||||
client_socket: Arc::new(Mutex::new(client_socket)),
|
||||
cur_rpc_uid: 0,
|
||||
outgoing_rpc_queue: Mutex::new(VecDeque::new()),
|
||||
context: GameContext::new(ns_prop_mgr.player_info.clone()),
|
||||
ns_prop_mgr,
|
||||
account_uid: OnceCell::new(),
|
||||
|
@ -108,13 +113,32 @@ impl NetworkSession {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn send_rpc_arg(&self, protocol_id: u16, data: &impl OctData) -> Result<()> {
|
||||
let header: Vec<u8> = ProtocolHeader::default().into();
|
||||
|
||||
pub async fn push_rpc_arg(&self, protocol_id: u16, data: impl OctData) -> Result<()> {
|
||||
let mut payload = Vec::new();
|
||||
let mut cursor = Cursor::new(&mut payload);
|
||||
data.marshal_to(&mut cursor, 0)?;
|
||||
|
||||
self.outgoing_rpc_queue
|
||||
.lock()
|
||||
.await
|
||||
.push_back(QueueItem(protocol_id, payload));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn flush_rpc_queue(&self) -> Result<()> {
|
||||
let mut queue = self.outgoing_rpc_queue.lock().await;
|
||||
|
||||
while let Some(QueueItem(protocol_id, payload)) = queue.pop_front() {
|
||||
self.send_rpc_arg(protocol_id, payload).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_rpc_arg(&self, protocol_id: u16, payload: Vec<u8>) -> Result<()> {
|
||||
let header: Vec<u8> = ProtocolHeader::default().into();
|
||||
|
||||
let body: Vec<u8> = RequestBody {
|
||||
protocol_id,
|
||||
payload,
|
||||
|
|
Loading…
Reference in a new issue