Skip to content

Commit

Permalink
Fixing login/logout
Browse files Browse the repository at this point in the history
  • Loading branch information
artemijan committed Jan 27, 2025
1 parent d0fcd6f commit 5cfe41c
Show file tree
Hide file tree
Showing 31 changed files with 227 additions and 56 deletions.
35 changes: 31 additions & 4 deletions game/src/client_thread/handler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::controller::Controller;
use crate::cp_factory::build_client_packet;
use crate::ls_thread::LoginHandler;
use anyhow::{bail, Error};
use async_trait::async_trait;
use entities::dao::char_info::CharacterInfo;
Expand All @@ -11,13 +12,14 @@ use l2_core::crypt::login::Encryption;
use l2_core::dto::InboundConnection;
use l2_core::errors::Packet;
use l2_core::session::SessionKey;
use l2_core::shared_packets::gs_2_ls::PlayerLogout;
use l2_core::traits::handlers::{InboundHandler, PacketHandler, PacketSender};
use l2_core::traits::Shutdown;
use std::sync::Arc;
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
use tokio::net::TcpStream;
use tokio::sync::{Mutex, Notify};
use tracing::{info, instrument};
use tracing::{error, info, instrument};

#[derive(Debug, Clone, PartialEq)]
#[allow(unused)]
Expand Down Expand Up @@ -45,6 +47,7 @@ pub struct ClientHandler {
session_key: Option<SessionKey>,
pub user: Option<user::Model>,
}

impl ClientHandler {
pub fn get_protocol(&self) -> Option<i32> {
self.protocol
Expand Down Expand Up @@ -82,7 +85,7 @@ impl ClientHandler {
pub fn get_account_chars(&self) -> Option<&Vec<CharacterInfo>> {
self.account_chars.as_ref()
}

pub fn try_get_account_chars_mut(&mut self) -> anyhow::Result<&mut Vec<CharacterInfo>> {
self.account_chars.as_mut().ok_or(anyhow::anyhow!(
"Programming error, or possible cheating - missing characters."
Expand Down Expand Up @@ -160,8 +163,32 @@ impl PacketHandler for ClientHandler {
Ok(())
}

fn on_disconnect(&mut self) {
info!("Client disconnected");
async fn on_disconnect(&mut self) {
info!("Disconnecting Client...");
let Some(user) = self.user.as_ref() else {
return;
};
self.controller.logout_account(&user.username);
let packet = match PlayerLogout::new(&user.username) {
Err(e) => {
error!("Cannot build logout packet: {}", e);
//exit function
return;
}
Ok(p) => p,
};

if let Err(err) = self
.controller
.message_broker
.notify(LoginHandler::HANDLER_ID, Box::new(packet))
.await
{
error!(
"Error while sending logout to login server, cause: {:?}",
err
);
}
}

fn get_stream_reader_mut(&self) -> &Arc<Mutex<OwnedReadHalf>> {
Expand Down
4 changes: 3 additions & 1 deletion game/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use l2_core::shared_packets::common::PacketType;
use l2_core::traits::IpBan;
use std::sync::Arc;
use std::time::Duration;
use tracing::info;

#[derive(Clone, Debug)]
pub struct Controller {
Expand Down Expand Up @@ -58,8 +59,9 @@ impl Controller {
},
)
}
pub fn remove_online_account(&self, account: &str) {
pub fn logout_account(&self, account: &str) {
self.online_accounts.remove(account);
info!("Logged out online account: {}", account);
}
}

Expand Down
13 changes: 11 additions & 2 deletions game/src/cp_factory.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
use crate::client_thread::ClientHandler;
use crate::packets::from_client::auth::AuthLogin;
use crate::packets::from_client::char_create::CreateCharRequest;
use crate::packets::from_client::extended::{CheckCharName, GoLobby};
use crate::packets::from_client::extended::{
CheckCharName, GoLobby, RequestUserBanInfo, SendClientIni,
};
use crate::packets::from_client::new_char_request::NewCharacterRequest;
use crate::packets::from_client::noop::NoOp;
use crate::packets::from_client::protocol::ProtocolVersion;
use crate::packets::HandleablePacket;
use anyhow::bail;
use l2_core::shared_packets::common::ReadablePacket;
use tracing::error;
use crate::packets::from_client::logout::Logout;

pub fn build_client_packet(
data: &[u8],
Expand All @@ -22,6 +25,7 @@ pub fn build_client_packet(
AuthLogin::PACKET_ID => Ok(Box::new(AuthLogin::read(packet_body)?)),
NewCharacterRequest::PACKET_ID => Ok(Box::new(NewCharacterRequest::read(packet_body)?)),
CreateCharRequest::PACKET_ID => Ok(Box::new(CreateCharRequest::read(packet_body)?)),
Logout::PACKET_ID => Ok(Box::new(Logout::read(packet_body)?)),
0xD0 => build_ex_client_packet(packet_body),
_ => {
error!("Unknown GS packet ID:0x{:02X}", data[0]);
Expand All @@ -41,8 +45,13 @@ pub fn build_ex_client_packet(
match Some(packet_id) {
GoLobby::EX_PACKET_ID => Ok(Box::new(GoLobby::read(packet_body)?)),
CheckCharName::EX_PACKET_ID => Ok(Box::new(CheckCharName::read(packet_body)?)),
SendClientIni::EX_PACKET_ID => Ok(Box::new(SendClientIni::read(packet_body)?)),
RequestUserBanInfo::EX_PACKET_ID => Ok(Box::new(RequestUserBanInfo::read(packet_body)?)),
_ => {
error!("Unknown extended GS packet ID:0x{:02X}", data[0]);
error!(
"Unknown extended GS packet ID: 0x{:X}",
u16::from_le_bytes([data[0], data[1]])
);
Ok(Box::new(NoOp::read(data)?))
}
}
Expand Down
2 changes: 1 addition & 1 deletion game/src/ls_thread/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl PacketHandler for LoginHandler {
Ok(())
}

fn on_disconnect(&mut self) {
async fn on_disconnect(&mut self){
self.controller.message_broker.unregister_packet_handler(Self::HANDLER_ID);
info!("Login server disconnected");
}
Expand Down
4 changes: 2 additions & 2 deletions game/src/packets/from_client/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ impl HandleablePacket for AuthLogin {
PlayerLoginResponse::SYSTEM_ERROR_LOGIN_LATER,
)?))
.await?;
controller.remove_online_account(&self.login_name);
controller.logout_account(&self.login_name);
bail!("Login failed {}", self.login_name);
}
}
} else {
controller.remove_online_account(&self.login_name);
controller.logout_account(&self.login_name);
bail!("Account already in game {}", self.login_name);
}
}
Expand Down
6 changes: 5 additions & 1 deletion game/src/packets/from_client/extended/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
mod go_to_lobby;
mod check_char_name;
mod send_client_ini;
mod req_user_ban_info;

pub use go_to_lobby::*;
pub use check_char_name::*;
pub use check_char_name::*;
pub use send_client_ini::*;
pub use req_user_ban_info::*;
25 changes: 25 additions & 0 deletions game/src/packets/from_client/extended/req_user_ban_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::client_thread::ClientHandler;
use crate::packets::HandleablePacket;
use async_trait::async_trait;
use l2_core::shared_packets::common::ReadablePacket;

#[derive(Debug, Clone)]
pub struct RequestUserBanInfo;

impl ReadablePacket for RequestUserBanInfo {
const PACKET_ID: u8 = 0xD0;
const EX_PACKET_ID: Option<u16> = Some(0x138);

fn read(_: &[u8]) -> anyhow::Result<Self> {
Ok(Self {})
}
}

#[async_trait]
impl HandleablePacket for RequestUserBanInfo {
type HandlerType = ClientHandler;
async fn handle(&self, _: &mut Self::HandlerType) -> anyhow::Result<()> {
//todo: I don't know what this packet is needed for, in L2J it is also not handled
Ok(())
}
}
25 changes: 25 additions & 0 deletions game/src/packets/from_client/extended/send_client_ini.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::client_thread::ClientHandler;
use crate::packets::HandleablePacket;
use async_trait::async_trait;
use l2_core::shared_packets::common::ReadablePacket;

#[derive(Debug, Clone)]
pub struct SendClientIni;

impl ReadablePacket for SendClientIni {
const PACKET_ID: u8 = 0xD0;
const EX_PACKET_ID: Option<u16> = Some(0x104);

fn read(_: &[u8]) -> anyhow::Result<Self> {
Ok(Self {})
}
}

#[async_trait]
impl HandleablePacket for SendClientIni {
type HandlerType = ClientHandler;
async fn handle(&self, _: &mut Self::HandlerType) -> anyhow::Result<()> {
//todo: I don't know what this packet is needed for, in L2J it is also not handled
Ok(())
}
}
32 changes: 32 additions & 0 deletions game/src/packets/from_client/logout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use crate::client_thread::ClientHandler;
use crate::ls_thread::LoginHandler;
use crate::packets::HandleablePacket;
use async_trait::async_trait;
use l2_core::shared_packets::common::ReadablePacket;
use l2_core::shared_packets::gs_2_ls::PlayerLogout;
use l2_core::traits::handlers::PacketHandler;
use l2_core::traits::Shutdown;
use tracing::info;

#[derive(Debug, Clone)]
pub struct Logout;

impl ReadablePacket for Logout {
const PACKET_ID: u8 = 0x00;
const EX_PACKET_ID: Option<u16> = None;
fn read(_: &[u8]) -> anyhow::Result<Self> {
Ok(Self {})
}
}

#[async_trait]
impl HandleablePacket for Logout {
type HandlerType = ClientHandler;
async fn handle(&self, handler: &mut Self::HandlerType) -> anyhow::Result<()> {
//todo handle proper logout mechanism: olympiad,
// in battle state, on RB and so on, offline trade, etc...
info!("Player logged out: {:?}", handler.user);
handler.get_shutdown_listener().notify_one();
Ok(())
}
}
3 changes: 2 additions & 1 deletion game/src/packets/from_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod auth;
pub mod noop;
pub mod new_char_request;
pub mod extended;
pub mod char_create;
pub mod char_create;
pub mod logout;
2 changes: 1 addition & 1 deletion game/src/packets/handleable/kick_player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ impl HandleablePacket for KickPlayer {
type HandlerType = LoginHandler;
async fn handle(&self, ph: &mut Self::HandlerType) -> anyhow::Result<()> {
let controller = ph.get_controller();
controller.remove_online_account(&self.account_name);
controller.logout_account(&self.account_name);
Ok(())
}
}
1 change: 1 addition & 0 deletions l2-core/src/shared_packets/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use macro_common::SendablePacketImpl;
use num_enum::TryFromPrimitive;
use std::str::FromStr;
use std::{fmt::Debug, net::Ipv4Addr};
use crate as l2_core;

pub trait SendablePacket: Debug + Send + Sync {
fn get_bytes_mut(&mut self) -> &mut [u8] {
Expand Down
1 change: 1 addition & 0 deletions l2-core/src/shared_packets/gs_2_ls/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::shared_packets::read::ReadablePacketBuffer;
use crate::shared_packets::write::SendablePacketBuffer;
use num_traits::ToBytes;
use macro_common::SendablePacketImpl;
use crate as l2_core;

#[derive(Clone, Debug, Default, SendablePacketImpl)]
pub struct RequestAuthGS {
Expand Down
1 change: 1 addition & 0 deletions l2-core/src/shared_packets/gs_2_ls/blowfish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::shared_packets::common::{ReadablePacket, SendablePacket};
use crate::shared_packets::read::ReadablePacketBuffer;
use crate::shared_packets::write::SendablePacketBuffer;
use macro_common::SendablePacketImpl;
use crate as l2_core;

#[derive(Clone, Debug, SendablePacketImpl)]
pub struct BlowFish {
Expand Down
7 changes: 6 additions & 1 deletion l2-core/src/shared_packets/gs_2_ls/change_password.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use macro_common::SendablePacketImpl;
use crate::shared_packets::common::ReadablePacket;
use crate::shared_packets::read::ReadablePacketBuffer;
use crate as l2_core;
use crate::shared_packets::write::SendablePacketBuffer;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, SendablePacketImpl)]
pub struct ChangePassword {
pub account: String,
pub char_name: String,
pub current_password: String,
pub new_password: String,
buffer: SendablePacketBuffer,
}

impl ReadablePacket for ChangePassword {
Expand All @@ -17,6 +21,7 @@ const EX_PACKET_ID: Option<u16> = None;
let mut buffer = ReadablePacketBuffer::new(data.to_vec());
buffer.read_byte();
Ok(Self {
buffer: SendablePacketBuffer::empty(),
account: buffer.read_string(),
char_name: buffer.read_string(),
current_password: buffer.read_string(),
Expand Down
3 changes: 2 additions & 1 deletion l2-core/src/shared_packets/gs_2_ls/gs_status.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use macro_common::SendablePacketImpl;
use crate::config::gs::GSServer;
use crate::shared_packets::common::{GSStatus, ReadablePacket, SendablePacket};
use crate::shared_packets::common::{GSStatus, ReadablePacket};
use crate::shared_packets::read::ReadablePacketBuffer;
use crate::shared_packets::write::SendablePacketBuffer;
use crate as l2_core;

#[derive(Clone, Debug, Default, SendablePacketImpl)]
pub struct GSStatusUpdate {
Expand Down
3 changes: 2 additions & 1 deletion l2-core/src/shared_packets/gs_2_ls/player_auth_request.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use macro_common::SendablePacketImpl;
use crate::session::SessionKey;
use crate::shared_packets::common::{ReadablePacket, SendablePacket};
use crate::shared_packets::common::{ReadablePacket};
use crate::shared_packets::read::ReadablePacketBuffer;
use crate::shared_packets::write::SendablePacketBuffer;
use crate as l2_core;

#[derive(Clone, Debug, SendablePacketImpl)]
pub struct PlayerAuthRequest {
Expand Down
1 change: 1 addition & 0 deletions l2-core/src/shared_packets/gs_2_ls/player_in_game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::shared_packets::common::{ReadablePacket, SendablePacket};
use crate::shared_packets::read::ReadablePacketBuffer;
use crate::shared_packets::write::SendablePacketBuffer;
use macro_common::SendablePacketImpl;
use crate as l2_core;

#[derive(Clone, Debug, SendablePacketImpl)]
pub struct PlayerInGame {
Expand Down
25 changes: 21 additions & 4 deletions l2-core/src/shared_packets/gs_2_ls/player_logout.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
use crate as l2_core;
use crate::shared_packets::common::ReadablePacket;
use crate::shared_packets::read::ReadablePacketBuffer;
use crate::shared_packets::write::SendablePacketBuffer;
use macro_common::SendablePacketImpl;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, SendablePacketImpl)]
pub struct PlayerLogout {
pub acc: String,
pub buffer: SendablePacketBuffer,
}
impl PlayerLogout {
pub fn new(acc: &str) -> anyhow::Result<Self> {
let mut inst = Self {
acc: String::new(),
buffer: SendablePacketBuffer::new(),
};
inst.buffer.write(Self::PACKET_ID)?;
inst.buffer.write_string(Some(acc))?;
Ok(inst)
}
}

impl ReadablePacket for PlayerLogout {
const PACKET_ID: u8 = 0x03;
const EX_PACKET_ID: Option<u16> = None;
const EX_PACKET_ID: Option<u16> = None;

fn read(data: &[u8]) -> anyhow::Result<Self> {
let mut buffer = ReadablePacketBuffer::new(data.to_vec());
buffer.read_byte();
let acc = buffer.read_string();
Ok(Self { acc })
Ok(Self {
acc,
buffer: SendablePacketBuffer::empty(),
})
}
}
Loading

0 comments on commit 5cfe41c

Please sign in to comment.