- chore: ran cargo fix on the codebase
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ impl EquippedPosition {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum MoveMode {
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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?,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user