166 lines
4.7 KiB
Rust
166 lines
4.7 KiB
Rust
use tokio::sync::Mutex;
|
|
use tracing::{debug, error, warn};
|
|
use trigger_protocol::EnterSceneScNotify;
|
|
use trigger_sv::{
|
|
message::{
|
|
BindClientSessionMessage, BindClientSessionOkMessage, ChangeGameStateMessage,
|
|
ForwardClientProtocolMessage, GameStateCallback, GameStateCallbackMessage, Header,
|
|
UnbindClientSessionMessage, WithOpcode,
|
|
},
|
|
net::ServerType,
|
|
};
|
|
|
|
use crate::{logic::GameState, session::BattleSession, AppState};
|
|
|
|
pub async fn handle_message(state: &'static AppState, packet: trigger_sv::message::NetworkPacket) {
|
|
match packet.opcode {
|
|
BindClientSessionMessage::OPCODE => {
|
|
if let Some(message) = packet.get_message() {
|
|
on_bind_client_session(state, packet.header, message).await;
|
|
}
|
|
}
|
|
UnbindClientSessionMessage::OPCODE => {
|
|
if let Some(message) = packet.get_message() {
|
|
on_unbind_client_session(state, packet.header, message).await;
|
|
}
|
|
}
|
|
ChangeGameStateMessage::OPCODE => {
|
|
if let Some(message) = packet.get_message() {
|
|
on_change_game_state(state, packet.header, message).await;
|
|
}
|
|
}
|
|
ForwardClientProtocolMessage::OPCODE => {
|
|
if let Some(message) = packet.get_message() {
|
|
on_forward_client_message(state, packet.header, message).await;
|
|
}
|
|
}
|
|
opcode => warn!("unhandled server message, opcode: {opcode}"),
|
|
}
|
|
}
|
|
|
|
async fn on_change_game_state(
|
|
state: &'static AppState,
|
|
_header: Header,
|
|
message: ChangeGameStateMessage,
|
|
) {
|
|
let Some(session) = state.sessions.get(&message.session_id) else {
|
|
return;
|
|
};
|
|
|
|
let mut session = session.lock().await;
|
|
|
|
debug!(
|
|
"changing game state for player with uid {}, request: {:?}",
|
|
session.player_uid, message
|
|
);
|
|
|
|
let Some(game_state) = GameState::new(&state.filecfg, &message.data) else {
|
|
error!("unsupported game state data received: {:?}", message.data);
|
|
return;
|
|
};
|
|
|
|
debug!(
|
|
"created fight scene for player with uid {}: quest_id: {}, play_type: {:?}",
|
|
session.player_uid,
|
|
game_state.dungeon.quest_id,
|
|
game_state.scene.get_play_type()
|
|
);
|
|
|
|
let enter_scene_notify = EnterSceneScNotify {
|
|
scene_info: Some(game_state.scene.get_protocol_scene_info()),
|
|
dungeon_info: Some(game_state.dungeon.get_protocol_dungeon_info()),
|
|
};
|
|
|
|
session.game_state = Some(game_state);
|
|
|
|
state
|
|
.network_mgr
|
|
.send_to(
|
|
ServerType::GameServer,
|
|
0,
|
|
GameStateCallbackMessage {
|
|
session_id: session.id,
|
|
protocol_units: vec![enter_scene_notify.into()],
|
|
scene_save_data: None,
|
|
callback: GameStateCallback::Loaded,
|
|
},
|
|
)
|
|
.await;
|
|
}
|
|
|
|
async fn on_forward_client_message(
|
|
state: &'static AppState,
|
|
_header: Header,
|
|
message: ForwardClientProtocolMessage,
|
|
) {
|
|
let Some(session) = state.sessions.get(&message.session_id) else {
|
|
return;
|
|
};
|
|
|
|
let mut session = session.lock().await;
|
|
|
|
for callback in crate::session::message::handle_client_message(
|
|
&mut session,
|
|
message.request_id,
|
|
message.message,
|
|
) {
|
|
state
|
|
.network_mgr
|
|
.send_to(
|
|
ServerType::GameServer,
|
|
0,
|
|
GameStateCallbackMessage {
|
|
session_id: session.id,
|
|
protocol_units: Vec::new(),
|
|
scene_save_data: None,
|
|
callback,
|
|
},
|
|
)
|
|
.await;
|
|
}
|
|
}
|
|
|
|
async fn on_unbind_client_session(
|
|
state: &'static AppState,
|
|
_header: Header,
|
|
message: UnbindClientSessionMessage,
|
|
) {
|
|
if let Some((_, session)) = state.sessions.remove(&message.session_id) {
|
|
let session = session.lock().await;
|
|
debug!(
|
|
"unregistered session with id {} (player_uid: {})",
|
|
session.id, session.player_uid
|
|
);
|
|
}
|
|
}
|
|
|
|
async fn on_bind_client_session(
|
|
state: &'static AppState,
|
|
header: Header,
|
|
message: BindClientSessionMessage,
|
|
) {
|
|
state.sessions.insert(
|
|
message.session_id,
|
|
Mutex::new(BattleSession {
|
|
id: message.session_id,
|
|
player_uid: message.player_uid,
|
|
game_state: None,
|
|
}),
|
|
);
|
|
|
|
debug!(
|
|
"registered new session, id: {}, player_uid: {}",
|
|
message.session_id, message.player_uid
|
|
);
|
|
|
|
state
|
|
.network_mgr
|
|
.send_to(
|
|
header.sender_type.try_into().unwrap(),
|
|
header.sender_id,
|
|
BindClientSessionOkMessage {
|
|
session_id: message.session_id,
|
|
},
|
|
)
|
|
.await;
|
|
}
|