- add: Character service can now actually create a character correctly in the database

- add: character db client to allow the character service to talk to the database service
- update: character.proto to make character data shared
This commit is contained in:
2025-01-07 13:41:07 -05:00
parent c6c502fd8a
commit cb6ee657f0
13 changed files with 318 additions and 72 deletions

View File

@@ -4,6 +4,6 @@ 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"])
.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,7 @@
use crate::char::character_service_client::CharacterServiceClient;
use crate::char::{GetCharacterRequest, GetCharacterListRequest, GetCharacterListResponse, Character, EquippedItem, DeleteCharacterRequest, Empty};
use crate::character::character_service_client::CharacterServiceClient;
use crate::character::{CreateCharacterRequest, CreateCharacterResponse, DeleteCharacterRequest, DeleteCharacterResponse, Empty, GetCharacterListRequest, GetCharacterListResponse, GetCharacterRequest};
use tonic::transport::Channel;
use utils::null_string::NullTerminatedString;
#[derive(Clone, Debug)]
pub struct CharacterClient {
@@ -22,16 +23,21 @@ impl CharacterClient {
Ok(response.into_inner())
}
pub async fn create_character(&mut self, user_id: &str) -> Result<GetCharacterListResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = GetCharacterListRequest {
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,
race: race as i32,
face: face as i32,
hair: hair as i32,
stone: stone as i32,
};
let response = self.client.get_character_list(request).await?;
let response = self.client.create_character(request).await?;
Ok(response.into_inner())
}
pub async fn delete_character(&mut self, user_id: &str, char_id: &str) -> Result<Empty, Box<dyn std::error::Error + Send + Sync>> {
pub async fn delete_character(&mut self, user_id: &str, char_id: &str) -> Result<DeleteCharacterResponse, Box<dyn std::error::Error + Send + Sync>> {
let request = DeleteCharacterRequest {
user_id: user_id.to_string(),
char_id: char_id.to_string(),

View File

@@ -56,13 +56,13 @@ pub(crate) async fn handle_char_list_req(stream: &mut TcpStream, packet: Packet,
let character_info = CharInfo {
name: NullTerminatedString(character.name),
race: character.race as u8,
level: character.level as u16,
job: character.job as u16,
race: character.looks.unwrap().race as u8,
level: character.stats.unwrap().level as u16,
job: character.stats.unwrap().job as u16,
remain_secs_until_delete: character.delete_time as u32,
platinium: 0,
face: character.face as u32,
hair: character.hair as u32,
face: character.looks.unwrap().face as u32,
hair: character.looks.unwrap().hair as u32,
items: item_list,
};
characters.push(character_info);
@@ -89,9 +89,19 @@ pub(crate) async fn handle_create_char_req(stream: &mut TcpStream, packet: Packe
// send the data to the character service to create the character
let mut character_client = character_client.lock().await;
character_client.create_character(&user_id.to_string()).await?;
let data = SrvCreateCharReply { result: srv_create_char_reply::Result::Ok, platininum: 0 };
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,
3 => srv_create_char_reply::Result::InvalidValue,
4 => srv_create_char_reply::Result::TooManyChars,
5 => srv_create_char_reply::Result::Blocked,
_ => srv_create_char_reply::Result::Failed
};
let data = SrvCreateCharReply { result, platininum: 0 };
let response_packet = Packet::new(PacketType::PakccCreateCharReply, &data)?;
send_packet(stream, &response_packet).await?;
@@ -110,10 +120,10 @@ pub(crate) async fn handle_delete_char_req(stream: &mut TcpStream, packet: Packe
}
let mut character_client = character_client.lock().await;
character_client.delete_character(&user_id.to_string(), &request.char_id.to_string());
let delete_response = character_client.delete_character(&user_id.to_string(), &request.char_id.to_string()).await?;
let character_name = request.name;
let data = SrvDeleteCharReply { remaining_time: 0, name: character_name };
let data = SrvDeleteCharReply { remaining_time: delete_response.remaining_time as u32, name: character_name };
let response_packet = Packet::new(PacketType::PakccDeleteCharReply, &data)?;
send_packet(stream, &response_packet).await?;
@@ -133,7 +143,7 @@ pub(crate) async fn handle_select_char_req(stream: &mut TcpStream, packet: Packe
}
let mut character_client = character_client.lock().await;
character_client.get_character(&user_id.to_string(), request.char_id);
let character_data = character_client.get_character(&user_id.to_string(), request.char_id).await?;
let mut equipped_item_list: [EquippedItem; (MAX_VISIBLE_ITEMS as usize)] = core::array::from_fn(|i| EquippedItem::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());

View File

@@ -40,7 +40,10 @@ mod connection_service;
pub mod auth {
tonic::include_proto!("auth"); // Path matches the package name in auth.proto
}
pub mod char {
pub mod character_common {
tonic::include_proto!("character_common"); // Path matches the package name in auth.proto
}
pub mod character {
tonic::include_proto!("character"); // Path matches the package name in auth.proto
}