Files
robinsr/gameserver/src/net/packet.rs

204 lines
5.3 KiB
Rust
Raw Normal View History

2024-03-29 09:46:31 +03:00
use anyhow::Result;
use paste::paste;
use tracing::Instrument;
use proto::*;
use super::PlayerSession;
use super::handlers::*;
2024-03-29 09:46:31 +03:00
const HEAD_MAGIC: u32 = 0x9D74C714;
const TAIL_MAGIC: u32 = 0xD7A152C8;
2024-10-23 04:49:46 +07:00
#[derive(Debug)]
pub struct NetOperation {
pub head: u32,
pub param1: u32,
pub param2: u32,
pub data: u32,
pub tail: u32,
}
#[derive(Debug)]
2024-03-29 09:46:31 +03:00
pub struct NetPacket {
pub cmd_type: u16,
pub head: Vec<u8>,
pub body: Vec<u8>,
}
impl From<NetPacket> for Vec<u8> {
fn from(value: NetPacket) -> Self {
let mut out = Self::new();
out.extend(HEAD_MAGIC.to_be_bytes());
out.extend(value.cmd_type.to_be_bytes());
out.extend((value.head.len() as u16).to_be_bytes());
out.extend((value.body.len() as u32).to_be_bytes());
out.extend(value.head);
out.extend(value.body);
out.extend(TAIL_MAGIC.to_be_bytes());
out
}
}
2024-10-23 04:49:46 +07:00
impl From<&[u8]> for NetPacket {
fn from(value: &[u8]) -> Self {
assert_eq!(
u32::from_be_bytes(value[0..4].try_into().unwrap()),
HEAD_MAGIC
);
let cmd_type = u16::from_be_bytes(value[4..6].try_into().unwrap());
2024-03-29 09:46:31 +03:00
2024-10-23 04:49:46 +07:00
let head_length = usize::from(u16::from_be_bytes(value[6..8].try_into().unwrap()));
2024-03-29 09:46:31 +03:00
2024-10-23 04:49:46 +07:00
let body_length = u32::from_be_bytes(value[8..12].try_into().unwrap()) as usize;
2024-03-29 09:46:31 +03:00
2024-10-23 04:49:46 +07:00
let head_start = 12;
let head_end = head_start + head_length;
let head = value[head_start..head_end].to_vec();
2024-03-29 09:46:31 +03:00
2024-10-23 04:49:46 +07:00
let body_start = head_end;
let body_end = body_start + body_length;
let body = value[body_start..body_end].to_vec();
2024-03-29 09:46:31 +03:00
2024-10-23 04:49:46 +07:00
assert_eq!(
u32::from_be_bytes(value[body_end..body_end + 4].try_into().unwrap()),
TAIL_MAGIC
);
Self {
2024-03-29 09:46:31 +03:00
cmd_type,
head,
body,
2024-10-23 04:49:46 +07:00
}
}
}
impl From<&[u8]> for NetOperation {
fn from(value: &[u8]) -> Self {
Self {
head: u32::from_be_bytes(value[..4].try_into().unwrap()),
param1: u32::from_be_bytes(value[4..8].try_into().unwrap()),
param2: u32::from_be_bytes(value[8..12].try_into().unwrap()),
data: u32::from_be_bytes(value[12..16].try_into().unwrap()),
tail: u32::from_be_bytes(value[16..20].try_into().unwrap()),
}
}
}
impl From<NetOperation> for Vec<u8> {
fn from(value: NetOperation) -> Self {
let mut buf = Self::with_capacity(20);
buf.extend(value.head.to_be_bytes());
buf.extend(value.param1.to_be_bytes());
buf.extend(value.param2.to_be_bytes());
buf.extend(value.data.to_be_bytes());
buf.extend(value.tail.to_be_bytes());
buf
2024-03-29 09:46:31 +03:00
}
}
macro_rules! trait_handler {
($($name:tt;)*) => {
2024-03-29 09:46:31 +03:00
pub trait CommandHandler {
$(
paste! {
async fn [<on_$name:snake _cs_req>](session: &mut PlayerSession, request: &[<$name CsReq>]) -> Result<()> {
let mut response = proto::[<$name ScRsp>]::default();
let _ = [<on_$name:snake _cs_req>](session, request, &mut response).await;
session.send(response).await?;
Ok(())
2024-03-29 09:46:31 +03:00
}
}
)*
2026-07-17 06:03:18 +07:00
async fn on_message(session: &mut PlayerSession, cmd_id: u16, payload: Vec<u8>) -> Result<()> {
2024-03-29 09:46:31 +03:00
use ::prost::Message;
2026-07-17 06:03:18 +07:00
if PlayerSession::should_send_dummy_rsp(cmd_id) {
session.send_dummy_response(cmd_id).await?;
2024-03-29 09:46:31 +03:00
return Ok(());
}
2026-07-17 06:03:18 +07:00
match cmd_id {
2024-03-29 09:46:31 +03:00
$(
2026-07-17 06:03:18 +07:00
cmd_id if cmd_id == paste! { <proto::[<$name CsReq>] as proto::CmdID>::CMD_ID } => {
let body = paste! { proto::[<$name CsReq>]::decode(&mut &payload[..])? };
2024-03-29 09:46:31 +03:00
paste! {
Self::[<on_$name:snake _cs_req>](session, &body)
2026-07-17 06:03:18 +07:00
.instrument(tracing::info_span!(stringify!([<on_$name:snake>]), cmd_id = cmd_id))
2024-03-29 09:46:31 +03:00
.await
}
}
)*
_ => {
2026-07-17 06:03:18 +07:00
tracing::warn!("Unknown command ID: {cmd_id}");
2024-03-29 09:46:31 +03:00
Ok(())
},
}
}
}
};
}
trait_handler! {
PlayerGetToken;
PlayerLogin;
GetMissionStatus;
GetBasicInfo;
GetAvatarData;
GetAllLineupData;
GetCurLineupData;
GetCurSceneInfo;
PlayerHeartBeat;
2025-05-24 05:50:15 +07:00
SetAvatarEnhancedId;
TakePromotionReward;
2024-05-29 15:56:07 +07:00
// Entity move (dummy!)
SceneEntityMove;
2024-08-03 14:19:36 +07:00
// Inventory (dummy!)
GetBag;
GetArchiveData;
DressAvatar;
TakeOffEquipment;
DressRelicAvatar;
TakeOffRelic;
2026-07-17 06:03:18 +07:00
RankUpAvatar;
2024-08-03 14:19:36 +07:00
// Chat (dummy!)
SendMsg;
GetPrivateChatHistory;
GetFriendListInfo;
GetFriendLoginInfo;
2024-08-03 14:19:36 +07:00
// In-game lineup
JoinLineup;
ChangeLineupLeader;
ReplaceLineup;
QuitLineup;
2024-08-03 14:19:36 +07:00
// Battle
StartCocoonStage;
PveBattleResult;
SceneCastSkill;
2026-02-25 13:25:25 +07:00
QuickStartCocoonStage;
SceneEnterStage;
2024-08-03 14:19:36 +07:00
// Teleport
GetEnteredScene;
GetSceneMapInfo;
EnterScene;
2024-08-03 14:19:36 +07:00
// Optional
GetMail;
GetGachaInfo;
DoGacha;
PlayerLoginFinish;
GetBigDataAllRecommend;
// SetClientPaused;
2024-03-29 09:46:31 +03:00
}