From 6ac186a1cfbcab671c112c3602576663cee187e1 Mon Sep 17 00:00:00 2001 From: YYHEggEgg <53960525+YYHEggEgg@users.noreply.github.com> Date: Wed, 31 Jul 2024 00:37:43 +0800 Subject: [PATCH] command: player kick [uid] [reason] --- nap_gameserver/src/commands/mod.rs | 1 + nap_gameserver/src/commands/player.rs | 43 ++++++++++++++++- nap_gameserver/src/net/session.rs | 4 ++ nap_proto/out/_.rs | 68 +++++++++++++-------------- 4 files changed, 81 insertions(+), 35 deletions(-) diff --git a/nap_gameserver/src/commands/mod.rs b/nap_gameserver/src/commands/mod.rs index 8480297..d976fe3 100644 --- a/nap_gameserver/src/commands/mod.rs +++ b/nap_gameserver/src/commands/mod.rs @@ -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)"; } } diff --git a/nap_gameserver/src/commands/player.rs b/nap_gameserver/src/commands/player.rs index 0aeaea2..e0e00fe 100644 --- a/nap_gameserver/src/commands/player.rs +++ b/nap_gameserver/src/commands/player.rs @@ -1,5 +1,5 @@ use data::tables::{AvatarBaseID, ProcedureConfigID}; -use proto::PlayerSyncScNotify; +use proto::{DisconnectReason, DisconnectScNotify, PlayerSyncScNotify}; use crate::ServerState; @@ -126,3 +126,44 @@ pub async fn procedure( "successfully changed procedure_id to {procedure_id:?}" )) } + +pub async fn kick( + args: ArgSlice<'_>, + state: &ServerState, +) -> Result> { + const USAGE: &str = "Usage: player kick [player_uid]"; + + if args.len() > 2 { + return Ok(USAGE.to_string()); + } + + let uid = args[0].parse::()?; + let reason = match args.get(1) { + Some(arg) => match arg.parse::() { + Ok(val) => val, + Err(_err) => 1, + }, + None => 1, + }; + 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.")) + } +} diff --git a/nap_gameserver/src/net/session.rs b/nap_gameserver/src/net/session.rs index f3457f6..b749992 100644 --- a/nap_gameserver/src/net/session.rs +++ b/nap_gameserver/src/net/session.rs @@ -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 + } } diff --git a/nap_proto/out/_.rs b/nap_proto/out/_.rs index 6a6db9c..631596b 100644 --- a/nap_proto/out/_.rs +++ b/nap_proto/out/_.rs @@ -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)] @@ -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,9 +55320,9 @@ 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, @@ -55332,38 +55332,38 @@ pub enum Obpfhejepck { 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::Jlimlghggke => "DISCONNECT_REASON_JLIMLGHGGKE", + DisconnectReason::Omjjggajcbh => "DISCONNECT_REASON_OMJJGGAJCBH", + DisconnectReason::Kdpiceebneb => "DISCONNECT_REASON_KDPICEEBNEB", + 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 { 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_JLIMLGHGGKE" => Some(Self::Jlimlghggke), + "DISCONNECT_REASON_OMJJGGAJCBH" => Some(Self::Omjjggajcbh), + "DISCONNECT_REASON_KDPICEEBNEB" => Some(Self::Kdpiceebneb), + "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, } }