- chore: ran cargo fix on the codebase

This commit is contained in:
2025-03-07 21:03:15 -05:00
parent 3b789d0fd4
commit b6f2d3f456
59 changed files with 1324 additions and 523 deletions

View File

@@ -14,7 +14,7 @@ serde = { version = "1.0", features = ["derive"] }
bytes = { version = "1.8.0", features = ["std", "serde"] }
tracing = "0.1"
tracing-subscriber = "0.3.18"
bincode = { version = "2.0.0-rc.3", features = ["derive", "serde"] }
bincode = { version = "2.0.0", features = ["derive", "serde"] }
thiserror = "2.0.3"
lazy_static = "1.5.0"
prometheus = "0.13.4"

View File

@@ -4,6 +4,13 @@ fn main() {
.build_server(false) // Generate gRPC server code?
.compile_well_known_types(true)
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
.compile_protos(&["../proto/auth.proto", "../proto/character.proto", "../proto/character_common.proto"], &["../proto"])
.compile_protos(
&[
"../proto/auth.proto",
"../proto/character.proto",
"../proto/character_common.proto",
],
&["../proto"],
)
.unwrap_or_else(|e| panic!("Failed to compile protos {:?}", e));
}

View File

@@ -1,6 +1,9 @@
use crate::auth::auth_service_client::AuthServiceClient;
use crate::auth::{LoginRequest, LoginResponse, LogoutRequest, ValidateSessionRequest, ValidateSessionResponse, ValidateTokenRequest, ValidateTokenResponse};
use crate::common::{Empty};
use crate::auth::{
LoginRequest, LoginResponse, LogoutRequest, ValidateSessionRequest, ValidateSessionResponse,
ValidateTokenRequest, ValidateTokenResponse,
};
use crate::common::Empty;
use tonic::transport::Channel;
#[derive(Clone, Debug)]
@@ -14,7 +17,12 @@ impl AuthClient {
Ok(AuthClient { client })
}
pub async fn login(&mut self, username: &str, password: &str, ip_address: &str) -> Result<LoginResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn login(
&mut self,
username: &str,
password: &str,
ip_address: &str,
) -> Result<LoginResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = LoginRequest {
username: username.to_string(),
password: password.to_string(),
@@ -25,34 +33,46 @@ impl AuthClient {
Ok(response.into_inner())
}
pub async fn login_token(&mut self, token: &str) -> Result<ValidateTokenResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn login_token(
&mut self,
token: &str,
) -> Result<ValidateTokenResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = ValidateTokenRequest {
token: token.to_string()
token: token.to_string(),
};
let response = self.client.validate_token(request).await?;
Ok(response.into_inner())
}
pub async fn validate_session(&mut self, session_id: &str) -> Result<ValidateSessionResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn validate_session(
&mut self,
session_id: &str,
) -> Result<ValidateSessionResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = ValidateSessionRequest {
session_id: session_id.to_string()
session_id: session_id.to_string(),
};
let response = self.client.validate_session(request).await?;
Ok(response.into_inner())
}
pub async fn refresh_session(&mut self, session_id: &str) -> Result<ValidateSessionResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn refresh_session(
&mut self,
session_id: &str,
) -> Result<ValidateSessionResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = ValidateSessionRequest {
session_id: session_id.to_string()
session_id: session_id.to_string(),
};
let response = self.client.refresh_session(request).await?;
Ok(response.into_inner())
}
pub async fn logout(&mut self, session_id: &str) -> Result<Empty, Box<dyn std::error::Error + Send + Sync>> {
pub async fn logout(
&mut self,
session_id: &str,
) -> Result<Empty, Box<dyn std::error::Error + Send + Sync>> {
let request = LogoutRequest {
session_id: session_id.to_string(),
};

View File

@@ -1,6 +1,6 @@
use std::collections::VecDeque;
use std::sync::Arc;
use tokio::sync::{Semaphore, Mutex};
use tokio::sync::{Mutex, Semaphore};
const MAX_PACKET_SIZE: usize = 0xFFF;

View File

@@ -1,5 +1,9 @@
use crate::character::character_service_client::CharacterServiceClient;
use crate::character::{CreateCharacterRequest, CreateCharacterResponse, DeleteCharacterRequest, DeleteCharacterResponse, GetCharacterListRequest, GetCharacterListResponse, GetCharacterRequest, GetCharacterResponse};
use crate::character::{
CreateCharacterRequest, CreateCharacterResponse, DeleteCharacterRequest,
DeleteCharacterResponse, GetCharacterListRequest, GetCharacterListResponse,
GetCharacterRequest, GetCharacterResponse,
};
use tonic::transport::Channel;
use utils::null_string::NullTerminatedString;
@@ -14,7 +18,10 @@ impl CharacterClient {
Ok(CharacterClient { client })
}
pub async fn get_character_list(&mut self, user_id: &str) -> Result<GetCharacterListResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn get_character_list(
&mut self,
user_id: &str,
) -> Result<GetCharacterListResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = GetCharacterListRequest {
user_id: user_id.to_string(),
};
@@ -23,7 +30,15 @@ impl CharacterClient {
Ok(response.into_inner())
}
pub async fn create_character(&mut self, user_id: &str, name: NullTerminatedString, race: u8, face: u8, hair: u8, stone: u8) -> Result<CreateCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn create_character(
&mut self,
user_id: &str,
name: NullTerminatedString,
race: u8,
face: u8,
hair: u8,
stone: u8,
) -> Result<CreateCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = CreateCharacterRequest {
user_id: user_id.to_string(),
name: name.0,
@@ -37,18 +52,27 @@ impl CharacterClient {
Ok(response.into_inner())
}
pub async fn delete_character(&mut self, user_id: &str, char_id: &str, delete_type: i32) -> Result<DeleteCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn delete_character(
&mut self,
user_id: &str,
char_id: &str,
delete_type: i32,
) -> Result<DeleteCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = DeleteCharacterRequest {
user_id: user_id.to_string(),
char_id: char_id.to_string(),
delete_type
delete_type,
};
let response = self.client.delete_character(request).await?;
Ok(response.into_inner())
}
pub async fn get_character(&mut self, user_id: &str, char_id: u8) -> Result<GetCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
pub async fn get_character(
&mut self,
user_id: &str,
char_id: u8,
) -> Result<GetCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = GetCharacterRequest {
user_id: user_id.to_string(),
char_id: char_id.to_string(),

View File

@@ -1,7 +1,7 @@
use crate::connection_state::ConnectionState;
use dashmap::DashMap;
use std::sync::Arc;
use uuid::Uuid;
use crate::connection_state::ConnectionState;
#[derive(Clone, Debug)]
pub struct ConnectionService {
@@ -17,15 +17,21 @@ impl ConnectionService {
pub fn add_connection(&self) -> String {
let connection_id = Uuid::new_v4().to_string();
self.connections.insert(connection_id.clone(), ConnectionState::new());
self.connections
.insert(connection_id.clone(), ConnectionState::new());
connection_id
}
pub fn get_connection(&self, connection_id: &str) -> Option<ConnectionState> {
self.connections.get(connection_id).map(|entry| entry.clone())
self.connections
.get(connection_id)
.map(|entry| entry.clone())
}
pub fn get_connection_mut(&self, connection_id: &str) -> Option<dashmap::mapref::one::RefMut<'_, String, ConnectionState>> {
pub fn get_connection_mut(
&self,
connection_id: &str,
) -> Option<dashmap::mapref::one::RefMut<'_, String, ConnectionState>> {
self.connections.get_mut(connection_id)
}

View File

@@ -1,4 +1,4 @@
use crate::enums::{EquippedPosition, BulletType, RidingItem};
use crate::enums::{BulletType, EquippedPosition, RidingItem};
pub(crate) const MIN_SELL_TYPE: u32 = 1;
pub(crate) const MAX_SELL_TYPE: u32 = 11;

View File

@@ -74,7 +74,6 @@ impl EquippedPosition {
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum MoveMode {

View File

@@ -26,7 +26,13 @@ use tracing::{debug, error, info, warn};
use utils::null_string::NullTerminatedString;
use utils::service_discovery;
pub(crate) async fn handle_alive_req(stream: &mut TcpStream, packet: Packet, auth_client: Arc<Mutex<AuthClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_alive_req(
stream: &mut TcpStream,
packet: Packet,
auth_client: Arc<Mutex<AuthClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
if let Some(mut state) = connection_service.get_connection(&connection_id) {
let session_id = state.session_id.clone().unwrap();
debug!("Attempting to refresh session {}", session_id);
@@ -42,15 +48,27 @@ pub(crate) async fn handle_alive_req(stream: &mut TcpStream, packet: Packet, aut
}
}
pub(crate) async fn handle_accept_req(stream: &mut TcpStream, packet: Packet) -> Result<(), Box<dyn Error + Send + Sync>> {
let data = SrvAcceptReply { result: srv_accept_reply::Result::Accepted, rand_value: 0 };
pub(crate) async fn handle_accept_req(
stream: &mut TcpStream,
packet: Packet,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let data = SrvAcceptReply {
result: srv_accept_reply::Result::Accepted,
rand_value: 0,
};
let response_packet = Packet::new(PacketType::PakssAcceptReply, &data)?;
send_packet(stream, &response_packet).await?;
Ok(())
}
pub(crate) async fn handle_join_server_req(stream: &mut TcpStream, packet: Packet, auth_client: Arc<Mutex<AuthClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_join_server_req(
stream: &mut TcpStream,
packet: Packet,
auth_client: Arc<Mutex<AuthClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let request = CliJoinServerTokenReq::decode(packet.payload.as_slice());
debug!("{:?}", request);
@@ -61,13 +79,21 @@ pub(crate) async fn handle_join_server_req(stream: &mut TcpStream, packet: Packe
if (!session.valid) {
warn!("Invalid session ID: {}", session_id);
let data = SrvJoinServerReply { result: srv_join_server_reply::Result::Failed, id: 0, pay_flag: 0 };
let data = SrvJoinServerReply {
result: srv_join_server_reply::Result::Failed,
id: 0,
pay_flag: 0,
};
let response_packet = Packet::new(PacketType::PakscJoinServerReply, &data)?;
send_packet(stream, &response_packet).await?;
return Err("Session not valid".into());
}
let data = SrvJoinServerReply { result: srv_join_server_reply::Result::Ok, id: 1, pay_flag: 0 };
let data = SrvJoinServerReply {
result: srv_join_server_reply::Result::Ok,
id: 1,
pay_flag: 0,
};
let response_packet = Packet::new(PacketType::PakscJoinServerReply, &data)?;
send_packet(stream, &response_packet).await?;
Ok(())
@@ -76,7 +102,13 @@ pub(crate) async fn handle_join_server_req(stream: &mut TcpStream, packet: Packe
}
}
pub(crate) async fn handle_logout_req(stream: &mut TcpStream, packet: Packet, auth_client: Arc<Mutex<AuthClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_logout_req(
stream: &mut TcpStream,
packet: Packet,
auth_client: Arc<Mutex<AuthClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
if let Some(mut state) = connection_service.get_connection(&connection_id) {
let session_id = state.session_id.clone().unwrap();
let mut auth_client = auth_client.lock().await;
@@ -92,8 +124,18 @@ pub(crate) async fn handle_logout_req(stream: &mut TcpStream, packet: Packet, au
}
}
pub(crate) async fn handle_login_req(stream: &mut TcpStream, packet: Packet, auth_client: Arc<Mutex<AuthClient>>, connection_service: Arc<ConnectionService>, connection_id: String, addr: SocketAddr) -> Result<(), Box<dyn Error + Send + Sync>> {
debug!("decoding packet payload of size {}", packet.payload.as_slice().len());
pub(crate) async fn handle_login_req(
stream: &mut TcpStream,
packet: Packet,
auth_client: Arc<Mutex<AuthClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
addr: SocketAddr,
) -> Result<(), Box<dyn Error + Send + Sync>> {
debug!(
"decoding packet payload of size {}",
packet.payload.as_slice().len()
);
let data = CliLoginTokenReq::decode(packet.payload.as_slice())?;
debug!("{:?}", data);
@@ -103,7 +145,12 @@ pub(crate) async fn handle_login_req(stream: &mut TcpStream, packet: Packet, aut
if response.valid == false {
info!("Login failed: Invalid credentials");
let data = SrvLoginReply { result: srv_login_reply::Result::UnknownAccount, right: 0, type_: 0, servers_info: Vec::new() };
let data = SrvLoginReply {
result: srv_login_reply::Result::UnknownAccount,
right: 0,
type_: 0,
servers_info: Vec::new(),
};
let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?;
send_packet(stream, &response_packet).await?;
} else {
@@ -114,14 +161,23 @@ pub(crate) async fn handle_login_req(stream: &mut TcpStream, packet: Packet, aut
state.session_id = Some(response.session_id);
}
let consul_url = env::var("CONSUL_URL").unwrap_or_else(|_| "http://127.0.0.1:8500".to_string());
let servers = service_discovery::get_service_address(&consul_url, "character-service").await.unwrap_or_else(|err| {
warn!(err);
Vec::new()
});
let consul_url =
env::var("CONSUL_URL").unwrap_or_else(|_| "http://127.0.0.1:8500".to_string());
let servers =
service_discovery::get_service_address(&consul_url, "character-service")
.await
.unwrap_or_else(|err| {
warn!(err);
Vec::new()
});
if servers.len() == 0 {
let data = SrvLoginReply { result: srv_login_reply::Result::Failed, right: 0, type_: 0, servers_info: Vec::new() };
let data = SrvLoginReply {
result: srv_login_reply::Result::Failed,
right: 0,
type_: 0,
servers_info: Vec::new(),
};
let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?;
send_packet(stream, &response_packet).await?;
return Ok(());
@@ -130,19 +186,33 @@ pub(crate) async fn handle_login_req(stream: &mut TcpStream, packet: Packet, aut
let mut server_info: Vec<ServerInfo> = Vec::new();
let mut id = 0;
for server in servers {
let mut name = server.ServiceMeta.get("name").unwrap_or(&"".to_string()).clone();
let is_test = server.ServiceTags.contains(&"test".to_string()) || server.ServiceTags.contains(&"staging".to_string());
let mut name = server
.ServiceMeta
.get("name")
.unwrap_or(&"".to_string())
.clone();
let is_test = server.ServiceTags.contains(&"test".to_string())
|| server.ServiceTags.contains(&"staging".to_string());
if is_test {
name = format!("@{}", name);
} else {
name = format!(" {}", name);
}
server_info.push(ServerInfo { test: u8::from(is_test), name: NullTerminatedString::new(&name), id });
server_info.push(ServerInfo {
test: u8::from(is_test),
name: NullTerminatedString::new(&name),
id,
});
id = id + 1;
}
debug!("Server info: {:?}", server_info);
let data = SrvLoginReply { result: srv_login_reply::Result::Ok, right: 0, type_: 0, servers_info: server_info };
let data = SrvLoginReply {
result: srv_login_reply::Result::Ok,
right: 0,
type_: 0,
servers_info: server_info,
};
let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?;
send_packet(stream, &response_packet).await?;
}
@@ -153,19 +223,34 @@ pub(crate) async fn handle_login_req(stream: &mut TcpStream, packet: Packet, aut
Code::Unauthenticated => {
info!("Login failed: Invalid credentials");
let data = SrvLoginReply { result: srv_login_reply::Result::UnknownAccount, right: 0, type_: 0, servers_info: Vec::new() };
let data = SrvLoginReply {
result: srv_login_reply::Result::UnknownAccount,
right: 0,
type_: 0,
servers_info: Vec::new(),
};
let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?;
send_packet(stream, &response_packet).await?;
}
Code::Unavailable => {
warn!("Login failed: Service is unavailable");
let data = SrvLoginReply { result: srv_login_reply::Result::Failed, right: 0, type_: 0, servers_info: Vec::new() };
let data = SrvLoginReply {
result: srv_login_reply::Result::Failed,
right: 0,
type_: 0,
servers_info: Vec::new(),
};
let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?;
send_packet(stream, &response_packet).await?;
}
_ => {
error!("Unexpected error: {}", tonic_status.message());
let data = SrvLoginReply { result: srv_login_reply::Result::Failed, right: 0, type_: 0, servers_info: Vec::new() };
let data = SrvLoginReply {
result: srv_login_reply::Result::Failed,
right: 0,
type_: 0,
servers_info: Vec::new(),
};
let response_packet = Packet::new(PacketType::PaklcLoginReply, &data)?;
send_packet(stream, &response_packet).await?;
}
@@ -177,21 +262,30 @@ pub(crate) async fn handle_login_req(stream: &mut TcpStream, packet: Packet, aut
Ok(())
}
pub(crate) async fn handle_server_select_req(stream: &mut TcpStream, packet: Packet, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_server_select_req(
stream: &mut TcpStream,
packet: Packet,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let request = CliSrvSelectReq::decode(packet.payload.as_slice())?;
debug!("{:?}", request);
if let Some(mut state) = connection_service.get_connection_mut(&connection_id) {
state.additional_data.insert("server".to_string(), request.server_id.to_string());
state.additional_data.insert("channel".to_string(), request.channel_id.to_string());
state
.additional_data
.insert("server".to_string(), request.server_id.to_string());
state
.additional_data
.insert("channel".to_string(), request.channel_id.to_string());
}
let data = SrvSrvSelectReply {
result: srv_srv_select_reply::Result::Ok,
session_id: 0, // Client should already have this value
crypt_val: 0, // This is only for the old encryption
session_id: 0, // Client should already have this value
crypt_val: 0, // This is only for the old encryption
ip: NullTerminatedString::new(""), // If this is empty, the client should stay connected (requires client change)
port: 0, // See comment about ip above
port: 0, // See comment about ip above
};
let response_packet = Packet::new(PacketType::PaklcSrvSelectReply, &data)?;
@@ -199,18 +293,26 @@ pub(crate) async fn handle_server_select_req(stream: &mut TcpStream, packet: Pac
Ok(())
}
pub(crate) async fn handle_channel_list_req(stream: &mut TcpStream, packet: Packet) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_channel_list_req(
stream: &mut TcpStream,
packet: Packet,
) -> Result<(), Box<dyn Error + Send + Sync>> {
let request = CliChannelListReq::decode(packet.payload.as_slice());
debug!("{:?}", request);
let consul_url = env::var("CONSUL_URL").unwrap_or_else(|_| "http://127.0.0.1:8500".to_string());
let channels = service_discovery::get_service_address(&consul_url, "world-service").await.unwrap_or_else(|err| {
warn!(err);
Vec::new()
});
let channels = service_discovery::get_service_address(&consul_url, "world-service")
.await
.unwrap_or_else(|err| {
warn!(err);
Vec::new()
});
if channels.len() == 0 {
let data = SrvChannelListReply { id: request?.server_id, channels: Vec::new() };
let data = SrvChannelListReply {
id: request?.server_id,
channels: Vec::new(),
};
let response_packet = Packet::new(PacketType::PaklcChannelListReply, &data)?;
send_packet(stream, &response_packet).await?;
return Ok(());
@@ -220,14 +322,30 @@ pub(crate) async fn handle_channel_list_req(stream: &mut TcpStream, packet: Pack
let mut channel_info: Vec<ChannelInfo> = Vec::new();
let mut id = 1;
for channel in channels {
let name = format!("{}", channel.ServiceMeta.get("name").unwrap_or(&"".to_string()).clone());
channel_info.push(ChannelInfo { id: id, low_age: 0, high_age: 0, capacity: 0, name: NullTerminatedString::new(&name) });
let name = format!(
"{}",
channel
.ServiceMeta
.get("name")
.unwrap_or(&"".to_string())
.clone()
);
channel_info.push(ChannelInfo {
id: id,
low_age: 0,
high_age: 0,
capacity: 0,
name: NullTerminatedString::new(&name),
});
id = id + 1;
}
debug!("Channel info: {:?}", channel_info);
let data = SrvChannelListReply { id: request?.server_id, channels: channel_info };
let data = SrvChannelListReply {
id: request?.server_id,
channels: channel_info,
};
let response_packet = Packet::new(PacketType::PaklcChannelListReply, &data)?;
send_packet(stream, &response_packet).await?;
Ok(())
}
}

View File

@@ -30,9 +30,15 @@ pub(crate) fn convert_slot(slot: i32) -> srv_char_list_reply::EquippedPosition {
}
}
pub(crate) async fn handle_char_list_req(stream: &mut TcpStream, packet: Packet, character_client: Arc<Mutex<CharacterClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::srv_char_list_reply::*;
pub(crate) async fn handle_char_list_req(
stream: &mut TcpStream,
packet: Packet,
character_client: Arc<Mutex<CharacterClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::cli_char_list_req::*;
use crate::packets::srv_char_list_reply::*;
let request = CliCharListReq::decode(packet.payload.as_slice());
debug!("{:?}", request);
@@ -40,16 +46,21 @@ pub(crate) async fn handle_char_list_req(stream: &mut TcpStream, packet: Packet,
let session_id;
if let Some(mut state) = connection_service.get_connection(&connection_id) {
user_id = state.user_id.expect("Missing user id in connection state");
session_id = state.session_id.expect("Missing session id in connection state");
session_id = state
.session_id
.expect("Missing session id in connection state");
}
// query the character service for the character list for this user
let mut character_client = character_client.lock().await;
let character_list = character_client.get_character_list(&user_id.to_string()).await?;
let character_list = character_client
.get_character_list(&user_id.to_string())
.await?;
let mut characters = vec![];
let mut character_id_list: Vec<u32> = Vec::new();
for character in character_list.characters {
let mut item_list: [EquippedItem; (MAX_VISIBLE_ITEMS as usize)] = core::array::from_fn(|i| EquippedItem::default());
let mut item_list: [EquippedItem; (MAX_VISIBLE_ITEMS as usize)] =
core::array::from_fn(|i| EquippedItem::default());
for item in character.items {
if item.slot < MAX_VISIBLE_ITEMS as i32 {
@@ -89,7 +100,13 @@ pub(crate) async fn handle_char_list_req(stream: &mut TcpStream, packet: Packet,
Ok(())
}
pub(crate) async fn handle_create_char_req(stream: &mut TcpStream, packet: Packet, character_client: Arc<Mutex<CharacterClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_create_char_req(
stream: &mut TcpStream,
packet: Packet,
character_client: Arc<Mutex<CharacterClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::cli_create_char_req::*;
use crate::packets::srv_create_char_reply::*;
let request = CliCreateCharReq::decode(packet.payload.as_slice())?;
@@ -99,14 +116,24 @@ pub(crate) async fn handle_create_char_req(stream: &mut TcpStream, packet: Packe
let session_id;
if let Some(mut state) = connection_service.get_connection(&connection_id) {
user_id = state.user_id.expect("Missing user id in connection state");
session_id = state.session_id.expect("Missing session id in connection state");
session_id = state
.session_id
.expect("Missing session id in connection state");
}
// send the data to the character service to create the character
let mut character_client = character_client.lock().await;
let create_character_response = character_client.create_character(&user_id.to_string(), request.name, request.race, request.face, request.hair, request.stone).await?;
let result = match create_character_response.result
{
let create_character_response = character_client
.create_character(
&user_id.to_string(),
request.name,
request.race,
request.face,
request.hair,
request.stone,
)
.await?;
let result = match create_character_response.result {
0 => srv_create_char_reply::Result::Ok,
1 => srv_create_char_reply::Result::Failed,
2 => srv_create_char_reply::Result::NameTaken,
@@ -116,14 +143,23 @@ pub(crate) async fn handle_create_char_req(stream: &mut TcpStream, packet: Packe
_ => srv_create_char_reply::Result::Failed,
};
let data = SrvCreateCharReply { result, platininum: 0 };
let data = SrvCreateCharReply {
result,
platininum: 0,
};
let response_packet = Packet::new(PacketType::PakccCreateCharReply, &data)?;
send_packet(stream, &response_packet).await?;
Ok(())
}
pub(crate) async fn handle_delete_char_req(stream: &mut TcpStream, packet: Packet, character_client: Arc<Mutex<CharacterClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_delete_char_req(
stream: &mut TcpStream,
packet: Packet,
character_client: Arc<Mutex<CharacterClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::cli_delete_char_req::*;
use crate::packets::srv_delete_char_reply::*;
let request = CliDeleteCharReq::decode(packet.payload.as_slice())?;
@@ -135,12 +171,20 @@ pub(crate) async fn handle_delete_char_req(stream: &mut TcpStream, packet: Packe
if let Some(mut state) = connection_service.get_connection(&connection_id) {
user_id = state.user_id.expect("Missing user id in connection state");
session_id = state.session_id.expect("Missing session id in connection state");
session_id = state
.session_id
.expect("Missing session id in connection state");
character_id_list = state.character_list.expect("Missing character id list");
}
let mut character_client = character_client.lock().await;
let delete_response = character_client.delete_character(&user_id.to_string(), &character_id_list[request.char_id as usize].to_string(), request.is_delete as i32).await?;
let delete_response = character_client
.delete_character(
&user_id.to_string(),
&character_id_list[request.char_id as usize].to_string(),
request.is_delete as i32,
)
.await?;
let character_name = request.name;
let data = SrvDeleteCharReply {
@@ -153,13 +197,19 @@ pub(crate) async fn handle_delete_char_req(stream: &mut TcpStream, packet: Packe
Ok(())
}
pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packet, character_client: Arc<Mutex<CharacterClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_select_char_req(
stream: &mut TcpStream,
packet: Packet,
character_client: Arc<Mutex<CharacterClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::cli_select_char_req::*;
use crate::packets::srv_switch_server::*;
use crate::packets::srv_select_char_reply::*;
use crate::packets::srv_billing_message::*;
use crate::packets::srv_inventory_data::*;
use crate::packets::srv_quest_data::*;
use crate::packets::srv_billing_message::*;
use crate::packets::srv_select_char_reply::*;
use crate::packets::srv_switch_server::*;
use crate::types::{HotbarItem, StatusEffect};
let request = CliSelectCharReq::decode(packet.payload.as_slice())?;
debug!("{:?}", request);
@@ -168,7 +218,10 @@ pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packe
let mut character_id_list: Vec<u32> = Vec::new();
if let Some(mut state) = connection_service.get_connection_mut(&connection_id) {
user_id = state.user_id.expect("Missing user id in connection state");
character_id_list = state.character_list.clone().expect("Missing character id list");
character_id_list = state
.character_list
.clone()
.expect("Missing character id list");
state.character_id = Some(request.char_id as i8);
}
@@ -182,7 +235,12 @@ pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packe
send_packet(stream, &response_packet).await?;
let mut character_client = character_client.lock().await;
let character_data = character_client.get_character(&user_id.to_string(), character_id_list[request.char_id as usize] as u8).await?;
let character_data = character_client
.get_character(
&user_id.to_string(),
character_id_list[request.char_id as usize] as u8,
)
.await?;
let character = character_data.character.unwrap_or_default();
@@ -191,15 +249,17 @@ pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packe
let stats = character.stats.unwrap();
let skills = character.skills;
let items = character.items;
let mut equipped_item_list: [EquippedItem; (MAX_VISIBLE_ITEMS as usize)] = core::array::from_fn(|i| EquippedItem::default());
let mut inventory: [srv_inventory_data::Item; (MAX_ITEMS as usize)] = core::array::from_fn(|i| srv_inventory_data::Item::default());
let mut equipped_item_list: [EquippedItem; (MAX_VISIBLE_ITEMS as usize)] =
core::array::from_fn(|i| EquippedItem::default());
let mut inventory: [srv_inventory_data::Item; (MAX_ITEMS as usize)] =
core::array::from_fn(|i| srv_inventory_data::Item::default());
let mut skill_list: [u16; (MAX_SKILL_COUNT as usize)] = core::array::from_fn(|i| {
if i < skills.len() {
return skills[i] as u16;
}
0
0
});
for item in items {
if item.slot < MAX_VISIBLE_ITEMS as i32 {
let slot = convert_slot(item.slot) as usize;
@@ -229,8 +289,10 @@ pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packe
};
}
let mut effect_list: [StatusEffect; (MAX_STATUS_EFFECTS as usize)] = core::array::from_fn(|i| StatusEffect::default());
let mut hotbar_list: [HotbarItem; (MAX_HOTBAR_ITEMS as usize)] = core::array::from_fn(|i| HotbarItem::default());
let mut effect_list: [StatusEffect; (MAX_STATUS_EFFECTS as usize)] =
core::array::from_fn(|i| StatusEffect::default());
let mut hotbar_list: [HotbarItem; (MAX_HOTBAR_ITEMS as usize)] =
core::array::from_fn(|i| HotbarItem::default());
let data = SrvSelectCharReply {
race: looks.race as u8,
map: position.map_id as u16,
@@ -289,8 +351,10 @@ pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packe
send_packet(stream, &response_packet).await?;
// Now we need to build the Quest data
let mut quests: [srv_quest_data::Quest; (MAX_QUESTS as usize)] = core::array::from_fn(|i| srv_quest_data::Quest::default());
let mut wishlist: [srv_quest_data::Item; (MAX_WISHLIST as usize)] = core::array::from_fn(|i| srv_quest_data::Item::default());
let mut quests: [srv_quest_data::Quest; (MAX_QUESTS as usize)] =
core::array::from_fn(|i| srv_quest_data::Quest::default());
let mut wishlist: [srv_quest_data::Item; (MAX_WISHLIST as usize)] =
core::array::from_fn(|i| srv_quest_data::Item::default());
let data = SrvQuestData {
episodes: [0; (MAX_CONDITIONS_EPISODE as usize)],

View File

@@ -14,7 +14,13 @@ fn distance(x1: f64, y1: f64, x2: f64, y2: f64) -> u16 {
dist.round() as u16
}
pub(crate) async fn handle_change_map_req(stream: &mut TcpStream, packet: Packet, character_client: Arc<Mutex<CharacterClient>>, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_change_map_req(
stream: &mut TcpStream,
packet: Packet,
character_client: Arc<Mutex<CharacterClient>>,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::cli_change_map_req::*;
use crate::packets::srv_change_map_reply::*;
let request = CliChangeMapReq::decode(packet.payload.as_slice())?;
@@ -26,13 +32,25 @@ pub(crate) async fn handle_change_map_req(stream: &mut TcpStream, packet: Packet
let session_id;
if let Some(mut state) = connection_service.get_connection(&connection_id) {
user_id = state.user_id.expect("Missing user id in connection state");
session_id = state.session_id.expect("Missing session id in connection state");
char_id = state.character_id.expect("Missing character id in connection state");
character_id_list = state.character_list.clone().expect("Missing character id list");
session_id = state
.session_id
.expect("Missing session id in connection state");
char_id = state
.character_id
.expect("Missing character id in connection state");
character_id_list = state
.character_list
.clone()
.expect("Missing character id list");
}
let mut character_client = character_client.lock().await;
let character_data = character_client.get_character(&user_id.to_string(), character_id_list[char_id as usize] as u8).await?;
let character_data = character_client
.get_character(
&user_id.to_string(),
character_id_list[char_id as usize] as u8,
)
.await?;
let character = character_data.character.unwrap_or_default();
let stats = character.stats.unwrap();
@@ -61,7 +79,12 @@ pub(crate) async fn handle_change_map_req(stream: &mut TcpStream, packet: Packet
Ok(())
}
pub(crate) async fn handle_mouse_cmd_req(stream: &mut TcpStream, packet: Packet, connection_service: Arc<ConnectionService>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub(crate) async fn handle_mouse_cmd_req(
stream: &mut TcpStream,
packet: Packet,
connection_service: Arc<ConnectionService>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::packets::cli_mouse_cmd::*;
use crate::packets::srv_mouse_cmd::*;
let request = CliMouseCmd::decode(packet.payload.as_slice())?;
@@ -70,14 +93,24 @@ pub(crate) async fn handle_mouse_cmd_req(stream: &mut TcpStream, packet: Packet,
let mut char_id = 0;
let mut character_id_list: Vec<u32> = Vec::new();
if let Some(mut state) = connection_service.get_connection(&connection_id) {
char_id = state.character_id.expect("Missing character id in connection state");
character_id_list = state.character_list.clone().expect("Missing character id list");
char_id = state
.character_id
.expect("Missing character id in connection state");
character_id_list = state
.character_list
.clone()
.expect("Missing character id list");
}
let data = SrvMouseCmd {
id: character_id_list[char_id as usize] as u16,
target_id: request.target_id,
distance: distance(520000 as f64, 520000 as f64, request.x as f64, request.y as f64),
distance: distance(
520000 as f64,
520000 as f64,
request.x as f64,
request.y as f64,
),
x: request.x,
y: request.y,
z: request.z,
@@ -85,4 +118,4 @@ pub(crate) async fn handle_mouse_cmd_req(stream: &mut TcpStream, packet: Packet,
let response_packet = Packet::new(PacketType::PakwcMouseCmd, &data)?;
send_packet(stream, &response_packet).await?;
Ok(())
}
}

View File

@@ -1,7 +1,10 @@
use crate::auth_client::AuthClient;
use crate::bufferpool::BufferPool;
use crate::character_client::CharacterClient;
use crate::connection_service::ConnectionService;
use crate::metrics::{ACTIVE_CONNECTIONS, PACKETS_RECEIVED};
use crate::packet::Packet;
use crate::router::PacketRouter;
use dotenv::dotenv;
use std::collections::HashMap;
use std::env;
@@ -18,24 +21,21 @@ use tracing::{debug, error, info, warn};
use utils::consul_registration;
use utils::service_discovery::get_service_address;
use warp::Filter;
use crate::character_client::CharacterClient;
use crate::connection_service::ConnectionService;
use crate::router::PacketRouter;
mod packet_type;
mod packet;
mod router;
mod packets;
mod enums;
mod dataconsts;
mod types;
mod handlers;
mod bufferpool;
mod metrics;
mod auth_client;
mod bufferpool;
mod character_client;
mod connection_state;
mod connection_service;
mod connection_state;
mod dataconsts;
mod enums;
mod handlers;
mod metrics;
mod packet;
mod packet_type;
mod packets;
mod router;
mod types;
pub mod common {
tonic::include_proto!("common");
@@ -57,7 +57,10 @@ const MAX_CONCURRENT_CONNECTIONS: usize = 100;
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv().ok();
tracing_subscriber::fmt()
.with_max_level(Level::from_str(&env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string())).unwrap_or_else(|_| Level::INFO))
.with_max_level(
Level::from_str(&env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string()))
.unwrap_or_else(|_| Level::INFO),
)
.init();
// Set the gRPC server address
@@ -67,7 +70,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let consul_url = env::var("CONSUL_URL").unwrap_or_else(|_| "http://127.0.0.1:8500".to_string());
let service_name = env::var("SERVICE_NAME").unwrap_or_else(|_| "packet-service".to_string());
let service_address = env::var("PACKET_SERVICE_ADDR").unwrap_or_else(|_| "127.0.0.1".to_string());
let service_address =
env::var("PACKET_SERVICE_ADDR").unwrap_or_else(|_| "127.0.0.1".to_string());
let service_port = port.clone();
let health_check_url = format!("http://{}:{}/health", service_address, health_port);
let health_check_endpoint_addr = format!("{}:{}", service_address, health_port);
@@ -89,17 +93,23 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
meta,
&health_check_url,
)
.await?;
.await?;
// Start health-check endpoint
consul_registration::start_health_check(addr.as_str()).await?;
let auth_address = auth_node.get(0).unwrap();
let auth_url = format!("http://{}:{}", auth_address.ServiceAddress, auth_address.ServicePort);
let auth_url = format!(
"http://{}:{}",
auth_address.ServiceAddress, auth_address.ServicePort
);
let auth_client = Arc::new(Mutex::new(AuthClient::connect(&auth_url).await?));
let character_address = character_node.get(0).unwrap();
let character_url = format!("http://{}:{}", character_address.ServiceAddress, character_address.ServicePort);
let character_url = format!(
"http://{}:{}",
character_address.ServiceAddress, character_address.ServicePort
);
let character_client = Arc::new(Mutex::new(CharacterClient::connect(&character_url).await?));
let full_addr = format!("{}:{}", &addr, port);
@@ -130,17 +140,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tokio::spawn(async move {
let _permit = permit;
let connection_id = packet_router.connection_service.add_connection();
if let Err(e) = packet_router.handle_connection(&mut socket, pool, connection_id.clone()).await {
if let Err(e) = packet_router
.handle_connection(&mut socket, pool, connection_id.clone())
.await
{
error!("Error handling connection: {}", e);
}
packet_router.connection_service.remove_connection(&connection_id);
packet_router
.connection_service
.remove_connection(&connection_id);
});
}
});
utils::signal_handler::wait_for_signal().await;
consul_registration::deregister_service(&consul_url, service_id.as_str()).await.expect("");
consul_registration::deregister_service(&consul_url, service_id.as_str())
.await
.expect("");
info!("service {} deregistered", service_name);
Ok(())
}

View File

@@ -1,5 +1,8 @@
use prometheus::{Encoder, TextEncoder, Counter, Gauge, Histogram, register_counter, register_gauge, register_histogram};
use lazy_static::lazy_static;
use prometheus::{
register_counter, register_gauge, register_histogram, Counter, Encoder, Gauge, Histogram,
TextEncoder,
};
lazy_static! {
// Counter to track the number of packets received

View File

@@ -13,15 +13,15 @@ pub struct Packet {
pub payload: Vec<u8>,
}
pub trait PacketPayload: Encode + Decode {
fn encode(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> {
pub trait PacketPayload {
fn encode(&self) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync>> where Self: Encode {
let config = bincode::config::standard().with_fixed_int_encoding();
Ok(bincode::encode_to_vec(self, config)?)
}
fn decode(data: &[u8]) -> Result<Self, Box<dyn std::error::Error + Send + Sync>>
where
Self: Sized,
Self: Sized, Self: Decode<()>
{
let config = bincode::config::standard().with_fixed_int_encoding();
Ok(bincode::decode_from_slice(data, config)?.0)
@@ -29,7 +29,10 @@ pub trait PacketPayload: Encode + Decode {
}
impl Packet {
pub fn new<T: PacketPayload>(packet_type: PacketType, payload: &T) -> Result<Self, Box<dyn Error + Send + Sync>> {
pub fn new<T: PacketPayload + bincode::Encode>(
packet_type: PacketType,
payload: &T,
) -> Result<Self, Box<dyn Error + Send + Sync>> {
let encoded_payload = <T as PacketPayload>::encode(payload)?;
let packet_size = (6 + encoded_payload.len()) as u16;
// let packet_crc = crc::crc16::checksum_x25(&encoded_payload);
@@ -97,7 +100,7 @@ impl Packet {
raw
}
pub fn parse<T: PacketPayload>(&self) -> Result<T, Box<dyn Error + Send + Sync>> {
pub fn parse<T: PacketPayload + bincode::Decode<()>>(&self) -> Result<T, Box<dyn Error + Send + Sync>> {
<T as PacketPayload>::decode(&self.payload)
}
}

View File

@@ -21,7 +21,12 @@ pub struct PacketRouter {
}
impl PacketRouter {
pub async fn handle_connection(&self, stream: &mut TcpStream, pool: Arc<BufferPool>, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub async fn handle_connection(
&self,
stream: &mut TcpStream,
pool: Arc<BufferPool>,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
ACTIVE_CONNECTIONS.inc();
while let Some(mut buffer) = pool.acquire().await {
// Read data into the buffer
@@ -46,7 +51,8 @@ impl PacketRouter {
Ok(packet) => {
debug!("Parsed Packet: {:?}", packet);
// Handle the parsed packet (route it, process it, etc.)
self.route_packet(stream, packet, connection_id.clone()).await?;
self.route_packet(stream, packet, connection_id.clone())
.await?;
}
Err(e) => warn!("Failed to parse packet: {}", e),
}
@@ -67,28 +73,131 @@ impl PacketRouter {
Ok(())
}
pub async fn route_packet(&self, stream: &mut TcpStream, packet: Packet, connection_id: String) -> Result<(), Box<dyn Error + Send + Sync>> {
pub async fn route_packet(
&self,
stream: &mut TcpStream,
packet: Packet,
connection_id: String,
) -> Result<(), Box<dyn Error + Send + Sync>> {
debug!("Routing packet: {:?}", packet);
match packet.packet_type {
// Generic Server Packets
PacketType::PakcsAlive => auth::handle_alive_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsAlive => {
auth::handle_alive_req(
stream,
packet,
self.auth_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsAcceptReq => auth::handle_accept_req(stream, packet).await,
PacketType::PakcsJoinServerTokenReq => auth::handle_join_server_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsJoinServerTokenReq => {
auth::handle_join_server_req(
stream,
packet,
self.auth_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
// Login Packets
PacketType::PakcsLoginTokenReq => auth::handle_login_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id, stream.peer_addr()?).await,
PacketType::PakcsLogoutReq => auth::handle_logout_req(stream, packet, self.auth_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsSrvSelectReq => auth::handle_server_select_req(stream, packet, self.connection_service.clone(), connection_id).await,
PacketType::PakcsLoginTokenReq => {
auth::handle_login_req(
stream,
packet,
self.auth_client.clone(),
self.connection_service.clone(),
connection_id,
stream.peer_addr()?,
)
.await
}
PacketType::PakcsLogoutReq => {
auth::handle_logout_req(
stream,
packet,
self.auth_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsSrvSelectReq => {
auth::handle_server_select_req(
stream,
packet,
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsChannelListReq => auth::handle_channel_list_req(stream, packet).await,
// Character Packets
PacketType::PakcsCharListReq => character::handle_char_list_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsCreateCharReq => character::handle_create_char_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsDeleteCharReq => character::handle_delete_char_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsSelectCharReq => character::handle_select_char_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsCharListReq => {
character::handle_char_list_req(
stream,
packet,
self.character_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsCreateCharReq => {
character::handle_create_char_req(
stream,
packet,
self.character_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsDeleteCharReq => {
character::handle_delete_char_req(
stream,
packet,
self.character_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsSelectCharReq => {
character::handle_select_char_req(
stream,
packet,
self.character_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
// World Packets
PacketType::PakcsChangeMapReq => world::handle_change_map_req(stream, packet, self.character_client.clone(), self.connection_service.clone(), connection_id).await,
PacketType::PakcsMouseCmd => world::handle_mouse_cmd_req(stream, packet, self.connection_service.clone(), connection_id).await,
PacketType::PakcsChangeMapReq => {
world::handle_change_map_req(
stream,
packet,
self.character_client.clone(),
self.connection_service.clone(),
connection_id,
)
.await
}
PacketType::PakcsMouseCmd => {
world::handle_mouse_cmd_req(
stream,
packet,
self.connection_service.clone(),
connection_id,
)
.await
}
// 1 => chat::handle_chat(packet).await?,
// 2 => movement::handle_movement(packet).await?,

View File

@@ -1,5 +1,5 @@
use std::time::{Duration};
use bincode::{Encode, Decode};
use bincode::{Decode, Encode};
use std::time::Duration;
// `HotbarItem` structure converted to Rust.
#[derive(Debug, Clone, Copy, Encode, Decode, Default)]
@@ -10,7 +10,7 @@ pub(crate) struct HotbarItem {
// `Skill` structure converted to Rust.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode, Default)]
pub(crate) struct Skill {
pub(crate) struct Skill {
id: u16,
level: u8,
}