diff --git a/gameserver/src/net/gateway.rs b/gameserver/src/net/gateway.rs index 57d1a10..a07d6a8 100644 --- a/gameserver/src/net/gateway.rs +++ b/gameserver/src/net/gateway.rs @@ -71,8 +71,8 @@ impl Gateway { } async fn establish_kcp_session(&mut self, data: u32, addr: SocketAddr) -> Result<()> { - tracing::info!("New connection from {addr}"); let (conv_id, session_token) = self.next_conv_pair(); + tracing::info!("New connection from addr: {addr} with conv_id: {conv_id}"); self.sessions.lock().await.insert( conv_id, @@ -127,6 +127,13 @@ impl Gateway { return; }; + // TODO: Temporary fix + if session.read().await.is_destroyed { + drop(session); + self.sessions.lock().await.remove(&conv_id); + return; + } + tokio::spawn(async move { if let Err(err) = Box::pin(session.write().await.consume(&data)).await { tracing::error!("An error occurred while processing session ({addr}): {err}"); diff --git a/gameserver/src/net/handlers/battle.rs b/gameserver/src/net/handlers/battle.rs index cb2687b..4e5106e 100644 --- a/gameserver/src/net/handlers/battle.rs +++ b/gameserver/src/net/handlers/battle.rs @@ -190,38 +190,38 @@ async fn create_battle_info(caster_id: u32, skill_index: u32) -> SceneBattleInfo battle_info.buff_list.push(buffs); } - // pf score object - if player.battle_config.battle_type == BattleType::PF && battle_info.stage_id < 30309041 { - battle_info.battle_target_info.insert( - 1, - BattleTargetList { - battle_target_list: vec![BattleTarget { - id: 10002, - progress: 0, - ..Default::default() - }], - }, - ); + // pf score object + if player.battle_config.battle_type == BattleType::PF { + if battle_info.stage_id >= 30309011 { + battle_info.battle_target_info.insert( + 1, + BattleTargetList { + battle_target_list: vec![BattleTarget { + id: 10003, + progress: 0, + ..Default::default() + }], + }, + ); + } else { + battle_info.battle_target_info.insert( + 1, + BattleTargetList { + battle_target_list: vec![BattleTarget { + id: 10002, + progress: 0, + ..Default::default() + }], + }, + ); + } - } - else { // idk wtf im doing, someone pls optimal it, but atleast it work - battle_info.battle_target_info.insert( - 1, - BattleTargetList { - battle_target_list: vec![BattleTarget { - id: 10003, - progress: 0, - ..Default::default() - }], - }, - ); - } for i in 2..=4 { battle_info .battle_target_info .insert(i, BattleTargetList::default()); } -if player.battle_config.battle_type == BattleType::PF { + battle_info.battle_target_info.insert( 5, BattleTargetList { @@ -239,7 +239,8 @@ if player.battle_config.battle_type == BattleType::PF { ], }, ); - } + } + // Apocalyptic Shadow if player.battle_config.battle_type == BattleType::AS { battle_info.battle_target_info.insert( diff --git a/gameserver/src/net/handlers/chat.rs b/gameserver/src/net/handlers/chat.rs index f516eb0..ee0f7df 100644 --- a/gameserver/src/net/handlers/chat.rs +++ b/gameserver/src/net/handlers/chat.rs @@ -1,3 +1,5 @@ +use std::sync::atomic::Ordering; + use crate::{ net::{ tools::{FreesrData, MultiPathAvatar}, @@ -11,7 +13,8 @@ use super::*; const SERVER_UID: u32 = 727; const SERVER_HEAD_ICON: u32 = 201008; const SERVER_CHAT_BUBBLE_ID: u32 = 220005; -const SERVER_CHAT_HISTORY: [&str; 4] = [ +const SERVER_CHAT_HISTORY: [&str; 5] = [ + "'dvd' render a dvd bouncing effect. you need to put the image into your game folder, with name \"image.png\"", "'sync'", "'mc {mc_id}' mc_id can be set from 8001 to 8006", "'march {march_id}' march_id can be set 1001 or 1224", @@ -155,6 +158,23 @@ pub async fn on_send_msg_cs_req( .await .unwrap(); } + "dvd" => { + session.toggle_dvd().await; + session + .send(RevcMsgScNotify { + msg_type: body.msg_type, + text: format!( + "DVD toggled to {}", + session.dvd_running.load(Ordering::SeqCst) + ), + emote: body.emote, + from_uid: SERVER_UID, + to_uid: 25, + chat_type: body.chat_type, + }) + .await + .unwrap(); + } _ => {} } } diff --git a/gameserver/src/net/handlers/player.rs b/gameserver/src/net/handlers/player.rs index d8eb3e8..09f740a 100644 --- a/gameserver/src/net/handlers/player.rs +++ b/gameserver/src/net/handlers/player.rs @@ -24,12 +24,12 @@ pub async fn on_player_heart_beat_cs_req( ) { res.client_time_ms = body.client_time_ms; res.server_time_ms = cur_timestamp_ms(); - res.download_data = Some(ClientDownloadData { - version: 51, - time: res.server_time_ms as i64, - data: rbase64::decode("bG9jYWwgZnVuY3Rpb24gYmV0YV90ZXh0KG9iaikKICAgIGxvY2FsIGdhbWVPYmplY3QgPSBDUy5Vbml0eUVuZ2luZS5HYW1lT2JqZWN0LkZpbmQoIlVJUm9vdC9BYm92ZURpYWxvZy9CZXRhSGludERpYWxvZyhDbG9uZSkiKQoKICAgIGlmIGdhbWVPYmplY3QgdGhlbgogICAgICAgIGxvY2FsIHRleHRDb21wb25lbnQgPSBnYW1lT2JqZWN0OkdldENvbXBvbmVudEluQ2hpbGRyZW4odHlwZW9mKENTLlJQRy5DbGllbnQuTG9jYWxpemVkVGV4dCkpCgogICAgICAgIGlmIHRleHRDb21wb25lbnQgdGhlbgogICAgICAgICAgICB0ZXh0Q29tcG9uZW50LnRleHQgPSAiUm9iaW5TUiBpcyBhIGZyZWUgYW5kIG9wZW4gc291cmNlIHNvZnR3YXJlLiBkaXNjb3JkLmdnL3JldmVyc2Vkcm9vbXMiCiAgICAgICAgZW5kCiAgICBlbHNlCiAgICBlbmQKZW5kCgpiZXRhX3RleHQoKQ==").unwrap(), - njddjhapnbo: 0 - }); + // res.download_data = Some(ClientDownloadData { + // version: 51, + // time: res.server_time_ms as i64, + // data: rbase64::decode("bG9jYWwgZnVuY3Rpb24gYmV0YV90ZXh0KG9iaikKICAgIGxvY2FsIGdhbWVPYmplY3QgPSBDUy5Vbml0eUVuZ2luZS5HYW1lT2JqZWN0LkZpbmQoIlVJUm9vdC9BYm92ZURpYWxvZy9CZXRhSGludERpYWxvZyhDbG9uZSkiKQoKICAgIGlmIGdhbWVPYmplY3QgdGhlbgogICAgICAgIGxvY2FsIHRleHRDb21wb25lbnQgPSBnYW1lT2JqZWN0OkdldENvbXBvbmVudEluQ2hpbGRyZW4odHlwZW9mKENTLlJQRy5DbGllbnQuTG9jYWxpemVkVGV4dCkpCgogICAgICAgIGlmIHRleHRDb21wb25lbnQgdGhlbgogICAgICAgICAgICB0ZXh0Q29tcG9uZW50LnRleHQgPSAiUm9iaW5TUiBpcyBhIGZyZWUgYW5kIG9wZW4gc291cmNlIHNvZnR3YXJlLiBkaXNjb3JkLmdnL3JldmVyc2Vkcm9vbXMiCiAgICAgICAgZW5kCiAgICBlbHNlCiAgICBlbmQKZW5kCgpiZXRhX3RleHQoKQ==").unwrap(), + // njddjhapnbo: 0 + // }); } pub async fn on_player_login_finish_cs_req( @@ -53,7 +53,9 @@ pub async fn on_player_login_finish_cs_req( ..Default::default() }), }) - .await + .await?; + + Ok(()) } pub async fn on_get_multi_path_avatar_info_cs_req( diff --git a/gameserver/src/net/session.rs b/gameserver/src/net/session.rs index 107065b..6899711 100644 --- a/gameserver/src/net/session.rs +++ b/gameserver/src/net/session.rs @@ -2,14 +2,18 @@ use std::{ io::Error, net::SocketAddr, pin::Pin, - sync::Arc, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, task::{Context, Poll}, + time::Duration, }; use anyhow::Result; use mhy_kcp::Kcp; use prost::Message; -use proto::CmdID; +use proto::{ClientDownloadData, ClientDownloadDataScNotify, CmdID, CmdPlayerType}; use tokio::{io::AsyncWrite, net::UdpSocket, sync::Mutex}; use crate::util; @@ -21,26 +25,64 @@ struct RemoteEndPoint { addr: SocketAddr, } +#[derive(Clone)] pub struct PlayerSession { pub token: u32, - kcp: Mutex>, + kcp: Arc>>, start_time: u64, + pub dvd_running: Arc, + pub is_destroyed: bool, } impl PlayerSession { pub fn new(socket: Arc, addr: SocketAddr, conv: u32, token: u32) -> Self { Self { token, - kcp: Mutex::new(Kcp::new( + kcp: Arc::new(Mutex::new(Kcp::new( conv, token, false, RemoteEndPoint { socket, addr }, - )), + ))), start_time: util::cur_timestamp_secs(), + dvd_running: Arc::new(AtomicBool::new(false)), + is_destroyed: false, } } + pub async fn toggle_dvd(&mut self) { + if self.dvd_running.swap(true, Ordering::SeqCst) { + self.dvd_running.store(false, Ordering::SeqCst); + self.send(ClientDownloadDataScNotify { + download_data: Some(ClientDownloadData { + version: 51, + time: util::cur_timestamp_ms() as i64, + data: rbase64::decode("bG9jYWwgZnVuY3Rpb24gZGVzdHJveSgpCiAgICBsb2NhbCBleGlzdGluZ0NhbnZhc0dPID0gQ1MuVW5pdHlFbmdpbmUuR2FtZU9iamVjdC5GaW5kKCJJbWFnZUJveENhbnZhcyIpCiAgICBpZiBleGlzdGluZ0NhbnZhc0dPIHRoZW4KICAgICAgICBDUy5Vbml0eUVuZ2luZS5PYmplY3QuRGVzdHJveShleGlzdGluZ0NhbnZhc0dPKQogICAgZW5kCgogICAgQ1NIQVJQX0xJU1RfQ0xBU1MgPSBuaWwKICAgIFRFWFRVUkVfTElTVCA9IG5pbAogICAgQ09NUE9ORU5UX0xJU1QgPSBuaWwKICAgIERJUkVDVElPTiA9IG5pbAogICAgU1BFRUQgPSBuaWwKZW5kCgp4cGNhbGwoZGVzdHJveSwgZnVuY3Rpb24oZXJyb3IpCiAgICBDUy5NaUhvWW8uU0RLLk5ldHdvcmtNYW5hZ2VyLlNob3dOZXR3b3JrRXJyb3IoMCwgdG9zdHJpbmcoZXJyb3IpKQplbmQpCg==").unwrap(), + njddjhapnbo: 0 + }) + }).await.unwrap(); + return; + } + + let dvd_running = Arc::clone(&self.dvd_running); + let session = self.clone(); + + tokio::spawn(async move { + let body = ClientDownloadDataScNotify { + download_data: Some(ClientDownloadData { + version: 51, + time: util::cur_timestamp_ms() as i64, + data: rbase64::decode("bG9jYWwgZnVuY3Rpb24gbWFpbigpCiAgICBpZiBub3QgVEVYVFVSRV9MSVNUIG9yIG5vdCBDT01QT05FTlRfTElTVCB0aGVuCiAgICAgICAgLS0gY2hlY2sgaWYgaGF2ZSBpbWFnZQogICAgICAgIGlmIG5vdCBDUy5TeXN0ZW0uSU8uRmlsZS5FeGlzdHMoImltYWdlLnBuZyIpIHRoZW4KICAgICAgICAgICAgQ1MuTWlIb1lvLlNESy5OZXR3b3JrTWFuYWdlci5TaG93TmV0d29ya0Vycm9yKDAsCiAgICAgICAgICAgICAgICAiaW1hZ2UucG5nIG5vdCBleGlzdCEgcGxlYXNlIHB1dCBpbWFnZS5wbmcgaW4geW91ciBnYW1lIGRpcmVjdG9yeSEiKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBlbmQKCiAgICAgICAgQ1MuVW5pdHlFbmdpbmUuQXBwbGljYXRpb24udGFyZ2V0RnJhbWVSYXRlID0gMzYwCiAgICAgICAgQ1MuVW5pdHlFbmdpbmUuUXVhbGl0eVNldHRpbmdzLnZTeW5jQ291bnQgPSAwCgogICAgICAgIENTSEFSUF9MSVNUX0NMQVNTID0gQ1MuU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdChDUy5TeXN0ZW0uT2JqZWN0KQogICAgICAgIFRFWFRVUkVfTElTVCA9IENTSEFSUF9MSVNUX0NMQVNTKCkKICAgICAgICBDT01QT05FTlRfTElTVCA9IENTSEFSUF9MSVNUX0NMQVNTKCkKICAgICAgICBESVJFQ1RJT04gPSAic2UiCiAgICAgICAgU1BFRUQgPSA1CgogICAgICAgIGxvY2FsIGltYWdlQnl0ZXMgPSBDUy5TeXN0ZW0uSU8uRmlsZS5SZWFkQWxsQnl0ZXMoImltYWdlLnBuZyIpCiAgICAgICAgbG9jYWwgdGV4dHVyZSA9IENTLlVuaXR5RW5naW5lLlRleHR1cmUyRCgyLCAyKQogICAgICAgIENTLlVuaXR5RW5naW5lLkltYWdlQ29udmVyc2lvbi5Mb2FkSW1hZ2UodGV4dHVyZSwgaW1hZ2VCeXRlcykKICAgICAgICBURVhUVVJFX0xJU1Q6QWRkKHRleHR1cmUpCgogICAgICAgIGxvY2FsIGV4aXN0aW5nQ2FudmFzR08gPSBDUy5Vbml0eUVuZ2luZS5HYW1lT2JqZWN0LkZpbmQoIkltYWdlQm94Q2FudmFzIikKICAgICAgICBpZiBleGlzdGluZ0NhbnZhc0dPIHRoZW4KICAgICAgICAgICAgQ1MuVW5pdHlFbmdpbmUuT2JqZWN0LkRlc3Ryb3koZXhpc3RpbmdDYW52YXNHTykKICAgICAgICBlbmQKCiAgICAgICAgbG9jYWwgY2FudmFzR08gPSBDUy5Vbml0eUVuZ2luZS5HYW1lT2JqZWN0KCJJbWFnZUJveENhbnZhcyIpCiAgICAgICAgbG9jYWwgY2FudmFzID0gY2FudmFzR086QWRkQ29tcG9uZW50KHR5cGVvZihDUy5Vbml0eUVuZ2luZS5DYW52YXMpKQogICAgICAgIGNhbnZhcy5yZW5kZXJNb2RlID0gQ1MuVW5pdHlFbmdpbmUuUmVuZGVyTW9kZS5TY3JlZW5TcGFjZU92ZXJsYXkKCgogICAgICAgIGxvY2FsIGNhbnZhc1NjYWxlciA9IGNhbnZhc0dPOkFkZENvbXBvbmVudCh0eXBlb2YoQ1MuVW5pdHlFbmdpbmUuVUkuQ2FudmFzU2NhbGVyKSkKICAgICAgICBjYW52YXNTY2FsZXIudWlTY2FsZU1vZGUgPSBDUy5Vbml0eUVuZ2luZS5VSS5DYW52YXNTY2FsZXIuU2NhbGVNb2RlLlNjYWxlV2l0aFNjcmVlblNpemUKICAgICAgICBjYW52YXNTY2FsZXIucmVmZXJlbmNlUmVzb2x1dGlvbiA9IENTLlVuaXR5RW5naW5lLlZlY3RvcjIoQ1MuVW5pdHlFbmdpbmUuU2NyZWVuLndpZHRoLAogICAgICAgICAgICBDUy5Vbml0eUVuZ2luZS5TY3JlZW4uaGVpZ2h0KQoKCiAgICAgICAgbG9jYWwgaW1hZ2VCb3hHTyA9IENTLlVuaXR5RW5naW5lLkdhbWVPYmplY3QoIkltYWdlQm94IikKICAgICAgICBpbWFnZUJveEdPLnRyYW5zZm9ybS5wYXJlbnQgPSBjYW52YXNHTy50cmFuc2Zvcm0KCiAgICAgICAgbG9jYWwgaW1hZ2UgPSBpbWFnZUJveEdPOkFkZENvbXBvbmVudCh0eXBlb2YoQ1MuVW5pdHlFbmdpbmUuVUkuSW1hZ2UpKQoKICAgICAgICBsb2NhbCB0ZXh0dXJlID0gVEVYVFVSRV9MSVNUWzBdCgogICAgICAgIGltYWdlLnNwcml0ZSA9IENTLlVuaXR5RW5naW5lLlNwcml0ZS5DcmVhdGUodGV4dHVyZSwgQ1MuVW5pdHlFbmdpbmUuUmVjdCgwLCAwLCB0ZXh0dXJlLndpZHRoLCB0ZXh0dXJlLmhlaWdodCksCiAgICAgICAgICAgIENTLlVuaXR5RW5naW5lLlZlY3RvcjIoMC41LCAwLjUpKQoKICAgICAgICBDT01QT05FTlRfTElTVDpBZGQoaW1hZ2VCb3hHTzpHZXRDb21wb25lbnQodHlwZW9mKENTLlVuaXR5RW5naW5lLlJlY3RUcmFuc2Zvcm0pKSkKICAgICAgICBDT01QT05FTlRfTElTVFswXS5zaXplRGVsdGEgPSBDUy5Vbml0eUVuZ2luZS5WZWN0b3IyKHRleHR1cmUud2lkdGggLyAyLCB0ZXh0dXJlLmhlaWdodCAvIDIpCiAgICAgICAgQ09NUE9ORU5UX0xJU1RbMF0uYW5jaG9yZWRQb3NpdGlvbiA9IENTLlVuaXR5RW5naW5lLlZlY3RvcjIoMCwgMCkKICAgIGVsc2UKICAgICAgICBsb2NhbCBpbWFnZVJlY3RUcmFuc2Zvcm0gPSBDT01QT05FTlRfTElTVFswXQogICAgICAgIGxvY2FsIG1fcmlnaHQgPSAoQ1MuVW5pdHlFbmdpbmUuU2NyZWVuLndpZHRoIC8gMikgLSBpbWFnZVJlY3RUcmFuc2Zvcm0uc2l6ZURlbHRhLnggLyAyIC0tIE1heCByaWdodCBib3VuZGFyeQogICAgICAgIGxvY2FsIG1fdG9wID0gKENTLlVuaXR5RW5naW5lLlNjcmVlbi5oZWlnaHQgLyAyKSAtIGltYWdlUmVjdFRyYW5zZm9ybS5zaXplRGVsdGEueSAvIDIgIC0tIE1heCB0b3AgYm91bmRhcnkKICAgICAgICBsb2NhbCBtX2JvdCA9IC1tX3RvcCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBCb3R0b20gYm91bmRhcnkKICAgICAgICBsb2NhbCBtX2xlZnQgPSAtbV9yaWdodCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtLSBMZWZ0IGJvdW5kYXJ5CiAgICAgICAgbG9jYWwgcG9zaXRpb24gPSBpbWFnZVJlY3RUcmFuc2Zvcm0uYW5jaG9yZWRQb3NpdGlvbgogICAgICAgIGxvY2FsIHggPSBwb3NpdGlvbi54CiAgICAgICAgbG9jYWwgeSA9IHBvc2l0aW9uLnkKCiAgICAgICAgLS0gTW92ZSBiYXNlZCBvbiBkaXJlY3Rpb24KICAgICAgICBpZiBESVJFQ1RJT04gPT0gIm5lIiB0aGVuCiAgICAgICAgICAgIHggPSB4ICsgU1BFRUQKICAgICAgICAgICAgeSA9IHkgLSBTUEVFRAogICAgICAgIGVsc2VpZiBESVJFQ1RJT04gPT0gIm53IiB0aGVuCiAgICAgICAgICAgIHggPSB4IC0gU1BFRUQKICAgICAgICAgICAgeSA9IHkgLSBTUEVFRAogICAgICAgIGVsc2VpZiBESVJFQ1RJT04gPT0gInNlIiB0aGVuCiAgICAgICAgICAgIHggPSB4ICsgU1BFRUQKICAgICAgICAgICAgeSA9IHkgKyBTUEVFRAogICAgICAgIGVsc2VpZiBESVJFQ1RJT04gPT0gInN3IiB0aGVuCiAgICAgICAgICAgIHggPSB4IC0gU1BFRUQKICAgICAgICAgICAgeSA9IHkgKyBTUEVFRAogICAgICAgIGVuZAoKICAgICAgICAtLSBCb3R0b20gYm91bmRhcnkgY2hlY2sgKHdoZW4gbW92aW5nIGRvd253YXJkKQogICAgICAgIGlmIHkgPD0gbV9ib3QgdGhlbgogICAgICAgICAgICBpZiBESVJFQ1RJT04gPT0gIm53IiB0aGVuCiAgICAgICAgICAgICAgICBESVJFQ1RJT04gPSAic3ciCiAgICAgICAgICAgIGVsc2VpZiBESVJFQ1RJT04gPT0gIm5lIiB0aGVuCiAgICAgICAgICAgICAgICBESVJFQ1RJT04gPSAic2UiCiAgICAgICAgICAgIGVuZAogICAgICAgICAgICB5ID0gbV9ib3QgLS0gRml4IHRoZSBwb3NpdGlvbiB0byBiZSBleGFjdGx5IGF0IHRoZSBib3R0b20gYm91bmRhcnkKICAgICAgICBlbmQKCiAgICAgICAgLS0gVG9wIGJvdW5kYXJ5IGNoZWNrICh3aGVuIG1vdmluZyB1cHdhcmQpCiAgICAgICAgaWYgeSA+PSBtX3RvcCB0aGVuCiAgICAgICAgICAgIGlmIERJUkVDVElPTiA9PSAic2UiIHRoZW4KICAgICAgICAgICAgICAgIERJUkVDVElPTiA9ICJuZSIKICAgICAgICAgICAgZWxzZWlmIERJUkVDVElPTiA9PSAic3ciIHRoZW4KICAgICAgICAgICAgICAgIERJUkVDVElPTiA9ICJudyIKICAgICAgICAgICAgZW5kCiAgICAgICAgICAgIHkgPSBtX3RvcCAtLSBGaXggdGhlIHBvc2l0aW9uIHRvIGJlIGV4YWN0bHkgYXQgdGhlIHRvcCBib3VuZGFyeQogICAgICAgIGVuZAoKICAgICAgICAtLSBMZWZ0IGJvdW5kYXJ5IGNoZWNrICh3aGVuIG1vdmluZyBsZWZ0KQogICAgICAgIGlmIHggPD0gbV9sZWZ0IHRoZW4KICAgICAgICAgICAgaWYgRElSRUNUSU9OID09ICJudyIgdGhlbgogICAgICAgICAgICAgICAgRElSRUNUSU9OID0gIm5lIgogICAgICAgICAgICBlbHNlaWYgRElSRUNUSU9OID09ICJzdyIgdGhlbgogICAgICAgICAgICAgICAgRElSRUNUSU9OID0gInNlIgogICAgICAgICAgICBlbmQKICAgICAgICAgICAgeCA9IG1fbGVmdCAtLSBGaXggdGhlIHBvc2l0aW9uIHRvIGJlIGV4YWN0bHkgYXQgdGhlIGxlZnQgYm91bmRhcnkKICAgICAgICBlbmQKCiAgICAgICAgLS0gUmlnaHQgYm91bmRhcnkgY2hlY2sgKHdoZW4gbW92aW5nIHJpZ2h0KQogICAgICAgIGlmIHggPj0gbV9yaWdodCB0aGVuCiAgICAgICAgICAgIGlmIERJUkVDVElPTiA9PSAibmUiIHRoZW4KICAgICAgICAgICAgICAgIERJUkVDVElPTiA9ICJudyIKICAgICAgICAgICAgZWxzZWlmIERJUkVDVElPTiA9PSAic2UiIHRoZW4KICAgICAgICAgICAgICAgIERJUkVDVElPTiA9ICJzdyIKICAgICAgICAgICAgZW5kCiAgICAgICAgICAgIHggPSBtX3JpZ2h0IC0tIEZpeCB0aGUgcG9zaXRpb24gdG8gYmUgZXhhY3RseSBhdCB0aGUgcmlnaHQgYm91bmRhcnkKICAgICAgICBlbmQKCiAgICAgICAgLS0gVXBkYXRlIHBvc2l0aW9uCiAgICAgICAgaW1hZ2VSZWN0VHJhbnNmb3JtLmFuY2hvcmVkUG9zaXRpb24gPSBDUy5Vbml0eUVuZ2luZS5WZWN0b3IyKHgsIHkpCiAgICBlbmQKZW5kCgp4cGNhbGwobWFpbiwgZnVuY3Rpb24oZXJyb3IpCiAgICBDUy5NaUhvWW8uU0RLLk5ldHdvcmtNYW5hZ2VyLlNob3dOZXR3b3JrRXJyb3IoMCwgdG9zdHJpbmcoZXJyb3IpKQplbmQpCg==").unwrap(), + njddjhapnbo: 0 + }) + }; + while dvd_running.load(Ordering::SeqCst) { + session.send(body.clone()).await.unwrap(); + std::thread::sleep(Duration::from_secs_f64(1.0 / 60.0)); // 60fps + } + }); + } + pub async fn consume(&mut self, buffer: &[u8]) -> Result<()> { { let mut kcp = self.kcp.lock().await; @@ -56,6 +98,12 @@ impl PlayerSession { } for packet in packets { + // TODO: Temporary fix + if packet.cmd_type == CmdPlayerType::CmdPlayerLogoutCsReq as u16 { + self.is_destroyed = true; + self.dvd_running.store(false, Ordering::SeqCst); + return Ok(()); + }; Self::on_message(self, packet.cmd_type, packet.body).await?; } diff --git a/gameserver/src/tools/resources.rs b/gameserver/src/tools/resources.rs index 508c34e..ae81c1e 100644 --- a/gameserver/src/tools/resources.rs +++ b/gameserver/src/tools/resources.rs @@ -4,7 +4,7 @@ use std::{collections::HashMap, fs, sync::LazyLock}; #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct Vector { - pub x: i32, // or f32 depending on your needs + pub x: i32, pub y: i32, pub z: i32, } diff --git a/proto/out/_.rs b/proto/out/_.rs index 9e9b2d2..54236b7 100644 --- a/proto/out/_.rs +++ b/proto/out/_.rs @@ -2897,6 +2897,15 @@ pub struct Cijjendfjlo { #[prost(uint32, tag = "1")] pub kklaobblgce: u32, } +/// Obf: CIJNHLEPACK +#[derive(proto_derive::CmdID)] +#[cmdid(15)] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ClientDownloadDataScNotify { + #[prost(message, optional, tag = "2")] + pub download_data: ::core::option::Option, +} #[derive(proto_derive::CmdID)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)]