Did some code clean-up

Added TODOs for some changes that need to be made
This commit is contained in:
2025-07-23 13:52:50 -04:00
parent 9fcd1741de
commit f10cac3794
4 changed files with 99 additions and 20 deletions

View File

@@ -193,9 +193,6 @@ pub(crate) async fn handle_login_req(
if let Some(mut state) = connection_service.get_connection_mut(&connection_id) {
let writer_clone = state.writer.clone().unwrap();
create_chat_client_handler(writer_clone, chat_handler.clone()).await?;
}
if let Some(mut state) = connection_service.get_connection_mut(&connection_id) {
state.chat_handler = Some(chat_handler);
}

View File

@@ -264,6 +264,14 @@ pub(crate) async fn handle_select_char_req(
state.character_id = Some(request.char_id as i8);
}
//TODO: All of the following packet code needs to be moved to their own functions
// We instead want to make our world service connection then request a player connection event
// from the world service to the game logic service. Then we have the game logic service send
// the appropriate events back and should cause the packet service to send the appropriate packets.
//TODO: Switch server packet is used to accept the client into the server and should be sent after
// the world service connection is established and confirm the client is in the correct map.
let data = SrvSwitchServer {
port: 0,
session_id: 0,
@@ -277,6 +285,9 @@ pub(crate) async fn handle_select_char_req(
send_packet(&mut locked_stream, &response_packet).await?;
}
//TODO: Get the character data from the character service should be moved to the game logic service
// as it needs to be sent to all the other nearby clients as well.
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)
@@ -429,7 +440,8 @@ pub(crate) async fn handle_select_char_req(
send_packet(&mut locked_stream, &response_packet).await?;
}
// Send the billing message (we don't use this, so we just send the defaults to allow)
// Send the billing message (we don't actually use this, so we just send the defaults to allow)
// This tells the client to actually switch from character select to the game world
let data = SrvBillingMessage {
function_type: 0x1001,
pay_flag: 2,

View File

@@ -282,11 +282,38 @@ async fn handle_world_events(
Some(crate::world_client::world::world_event::Event::NpcSpawn(npc_spawn)) => {
debug!("Processing NPC spawn event: {:?}", npc_spawn);
// Convert to the appropriate game packet and send to client
// This would involve creating a spawn packet and sending it through the connection's writer
let npc = WorldObject {
id: npc_spawn.id,
object_type: 2,
x: npc_spawn.pos_x,
y: npc_spawn.pos_y,
z: 0.0,
map_id: 0,
name: "NPC".to_string(),
hp: npc_spawn.hp,
max_hp: npc_spawn.hp,
};
// if let Err(e) = spawn_npc(&npc, connection_service.clone(), session_id.clone()).await {
// error!("Failed to spawn npc for session {}: {}", session_id, e);
// }
}
Some(crate::world_client::world::world_event::Event::MobSpawn(mob_spawn)) => {
debug!("Processing mob spawn event: {:?}", mob_spawn);
// Convert to the appropriate game packet and send to client
let mob = WorldObject {
id: mob_spawn.id,
object_type: 3,
x: mob_spawn.pos_x,
y: mob_spawn.pos_y,
z: 0.0,
map_id: 0,
name: "Mob".to_string(),
hp: mob_spawn.hp,
max_hp: mob_spawn.hp,
};
if let Err(e) = spawn_mob(&mob, connection_service.clone(), session_id.clone()).await {
error!("Failed to spawn mob for session {}: {}", session_id, e);
}
}
Some(crate::world_client::world::world_event::Event::ObjectDespawn(despawn)) => {
debug!("Processing object despawn event: {:?}", despawn);

View File

@@ -113,16 +113,6 @@ impl MyWorldService {
}
}
pub fn get_nearby_objects_for_client(&self, session_id: &str, x: f32, y: f32, z: f32, map_id: i32, radius: f32) -> Vec<WorldObject> {
// This is a placeholder implementation
// In a real implementation, you would query the game logic service or maintain a spatial index
debug!("Getting nearby objects for client {} at ({}, {}, {}) in map {} with radius {}",
session_id, x, y, z, map_id, radius);
// Return empty list for now - this will be populated by game logic service
vec![]
}
/// Send nearby objects to a connecting client
pub async fn send_nearby_objects_to_client(&self, session_id: &str, client_id: &str, x: f32, y: f32, z: f32, map_id: i32) {
debug!("Sending nearby objects to client {} at ({}, {}, {}) in map {}", client_id, x, y, z, map_id);
@@ -170,7 +160,7 @@ impl MyWorldService {
x: obj.x,
y: obj.y,
z: obj.z,
map_id: map_id,
map_id,
name: format!("Object_{}", obj.id), // Default name
hp: obj.hp, // Default HP
max_hp: obj.max_hp, // Default max HP
@@ -212,7 +202,8 @@ impl MyWorldService {
/// Convert a game logic object to a WorldEvent based on its type
fn convert_game_logic_object_to_world_event(&self, obj: &client_game_logic::Object, client_id: &str) -> Option<WorldEvent> {
// Object types: 1 = Player, 2 = NPC, 3 = Mob (based on common MMORPG conventions)
// Object types: 1 = Player, 2 = NPC, 3 = Mob
//TODO: switch these magic numbers with the actual type names defined like how we did it in the chat service
match obj.r#type {
2 => {
// NPC
@@ -339,7 +330,56 @@ impl WorldService for MyWorldService {
let req = request.into_inner();
debug!("GetNearbyObjects request: {:?}", req);
let objects = self.get_nearby_objects_for_client(&req.session_id, req.x, req.y, req.z, req.map_id, req.radius);
let mut objects = vec![];
if let Some(game_logic_manager) = &self.game_logic_manager {
match game_logic_manager.get_nearby_objects(req.map_id as u32, &req.session_id, req.x, req.y, req.z).await {
Ok(response) => {
debug!("Received {} nearby objects from game logic service", response.objects.len());
if !response.objects.is_empty() {
// Convert game logic objects to WorldObjects for batch sending
let world_objects: Vec<WorldObject> = response.objects
.into_iter()
.filter_map(|obj| {
// Filter out players for now, only include NPCs and Mobs
//TODO: switch these magic numbers with the actual type names defined like how we did it in the chat service
match obj.r#type {
1 => {
// Player - skip for now
debug!("Skipping player object {} for nearby objects", obj.id);
None
}
2 | 3 => {
// NPC or Mob - include in batch
Some(WorldObject {
id: obj.id as u32,
object_type: obj.r#type,
x: obj.x,
y: obj.y,
z: obj.z,
map_id: req.map_id,
name: format!("Object_{}", obj.id), // Default name
hp: obj.hp, // Default HP
max_hp: obj.max_hp, // Default max HP
})
}
_ => {
debug!("Unknown object type {} for object {}", obj.r#type, obj.id);
None
}
}
})
.collect();
objects = world_objects;
}
}
Err(e) => {
warn!("Failed to get nearby objects from game logic service for client {}: {}", req.session_id, e);
}
}
} else {
debug!("No game logic manager available, skipping nearby objects");
}
let response = NearbyObjectsResponse {
objects,
@@ -556,8 +596,10 @@ impl WorldGameLogicService for MyWorldGameLogicService {
event: Some(world_event::Event::NpcSpawn(npc_spawn)),
};
// Broadcast to clients - for now broadcast to all clients in the map
// In a real implementation, you'd determine the map from the event
// world_service.broadcast_to_clients_in_map(game_event.map_id, world_event);
//TODO: call the spawn npc function as this is a single spawn
// this might not ever get called as we spawn all NPCs at the start
// Could be useful if we allow quests or scripted NPC spawning in the future
}
Some(world::game_logic_event::Event::MobSpawn(mob_spawn)) => {
let _world_event = WorldEvent {
@@ -565,13 +607,14 @@ impl WorldGameLogicService for MyWorldGameLogicService {
event: Some(world_event::Event::MobSpawn(mob_spawn)),
};
// Broadcast to clients
//TODO: call the spawn mob function as this is a single spawn
}
Some(world::game_logic_event::Event::ObjectDespawn(despawn)) => {
let _world_event = WorldEvent {
client_ids: game_event.client_ids.clone(),
event: Some(world_event::Event::ObjectDespawn(despawn)),
};
// Broadcast to clients
//TODO: Just tell everyone that the object is gone
}
_ => {
debug!("Unhandled game logic event type");