From dd1fbffa27b9b47a6d9015efd2cf033a68c9da57 Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Mon, 26 Jun 2023 15:45:03 -0500 Subject: [PATCH] tree added to client, multiple attachment bug also patched --- client/src/gateway.ts | 36 ++++++++++++++++++++ client/src/index.ts | 52 ++++++++++++++++++++++++----- server/src/handler.rs | 16 +++++++-- server/src/manager.rs | 3 ++ server/src/module.rs | 32 ++++++++++++------ server/src/timer.rs | 78 +++++++++++++++++++++++++++---------------- 6 files changed, 166 insertions(+), 51 deletions(-) diff --git a/client/src/gateway.ts b/client/src/gateway.ts index 1b042be1620a55d09e8e1664c94896c8ef7e54fc..a8f6e26a6254d941415dd9699547b1ed8f6d21b6 100644 --- a/client/src/gateway.ts +++ b/client/src/gateway.ts @@ -14,8 +14,12 @@ import { MessageS2CGoodbye_packetInfo, MessageS2CHello, MessageS2CHello_packetInfo, + MessageS2CModuleAdd, + MessageS2CModuleAdd_packetInfo, MessageS2CModulesUpdate, MessageS2CModulesUpdate_packetInfo, + MessageS2CModuleTreeUpdate, + MessageS2CModuleTreeUpdate_packetInfo, MessageS2CPlanetData, MessageS2CPlanetData_packetInfo, MessageS2CPlayersUpdate, MessageS2CPlayersUpdate_packetInfo, @@ -23,6 +27,7 @@ import { } from "./protocol/message_s2c"; import {GoodbyeReason} from "./protocol/goodbye_reason"; import {global} from "./index"; +import {AttachedModule, Attachment, ModuleType} from "./protocol/module"; const logger = new Logger("Gateway"); @@ -37,6 +42,14 @@ export interface GatewayClient { ping_timeout_left: Timeout; // its fine } +export interface AttachedModule { + module_type: ModuleType, + rotation: number, + x: number, + y: number, + children: Attachment[], +} + export async function gateway_connect(gateway_url: string, username: string): Promise { logger.info("FAST CONNECT - Connecting to gateway socket at " + gateway_url); @@ -170,6 +183,29 @@ export async function gateway_connect(gateway_url: string, username: string): Pr } else if (pkt_id == MessageS2CModulesUpdate_packetInfo.type) { let pkt = MessageS2CModulesUpdate.decode(pkt_data); global.modules = pkt.modules; + } else if (pkt_id == MessageS2CModuleAdd_packetInfo.type) { + let pkt = MessageS2CModuleAdd.decode(pkt_data); + let module = { + module_type: pkt.module.moduleType, + rotation: pkt.module.rotation, + x: pkt.module.x, + y: pkt.module.y, + children: pkt.module.children, + }; + global.tree.set(pkt.module.id, module); + } else if (pkt_id == MessageS2CModuleTreeUpdate_packetInfo.type) { + let pkt = MessageS2CModuleTreeUpdate.decode(pkt_data); + let modules: AttachedModule[] = []; + pkt.tree.forEach((value: AttachedModule) => { + modules.push({ + module_type: value.moduleType, + rotation: value.rotation, + x: value.x, + y: value.y, + children: value.children, + }); + }); + global.tree = modules; } else { logger.warn(`server sent unexpected packet ${pkt_id} for state Play`); } diff --git a/client/src/index.ts b/client/src/index.ts index 4b028c9e5d9f52c910424ad7358094a43a2a84e5..2a098f28bf43905c5675ccd3b41e9633d63d700b 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -1,5 +1,5 @@ import {Logger, logSetup} from "./logger"; -import {gateway_connect, GatewayClient} from "./gateway"; +import {gateway_connect, GatewayClient, AttachedModule} from "./gateway"; import {Player} from "./protocol/player"; import {Planet, PlanetType} from "./protocol/planet"; import {Module, ModuleType} from "./protocol/module"; @@ -33,6 +33,7 @@ export interface GlobalData { direction_radians: number, mouse_x: number, mouse_y: number, + tree: Map, } export interface Keys { @@ -65,6 +66,7 @@ export const global: GlobalData = { direction_radians: 0, mouse_x: 0, mouse_y: 0, + tree: new Map(), } async function client_main(server: string, username: string, texture_quality: string) { @@ -345,7 +347,7 @@ async function client_main(server: string, username: string, texture_quality: st if (global.me !== null) { let module = global.modules[i]; // @ts-ignore - let tex = global.spritesheet!["frames"][module_type_to_tex_id(module.moduleType)]; + let tex = global.spritesheet!["frames"][module_type_to_tex_id(module.moduleType, false)]; global.context.save(); @@ -387,6 +389,28 @@ async function client_main(server: string, username: string, texture_quality: st } } + global.tree.forEach((value: AttachedModule, key: number) => { + if (global.me !== null) { + console.log(value.x + ", " + value.y); + // @ts-ignore + let tex = global.spritesheet!["frames"][module_type_to_tex_id(value.module_type, true)]; + + global.context.save(); + global.context.translate(value.x - global.me!.x, value.y - global.me!.y); + global.context.rotate(value.rotation); + + global.context.drawImage(global.spritesheet_img!, + tex.frame.x, + tex.frame.y, + tex.frame.w, + tex.frame.h, + -25, + -25, 50, 50); + + global.context.restore(); + } + }); + for (let i = 0; i < global.players.length; i++) { if (global.me !== null) { let player = global.players[i]; @@ -436,13 +460,23 @@ function planet_type_to_tex_id(ty: PlanetType): string { } return "unknown.png" } -function module_type_to_tex_id(ty: ModuleType): string { - if (ty == ModuleType.Cargo) { - return "cargo_off.png" - } else if (ty == ModuleType.LandingThruster) { - return "landingthruster_off.png" - } else if (ty == ModuleType.Hub) { - return "hub_off.png" +function module_type_to_tex_id(ty: ModuleType, is_on: boolean): string { + if (!is_on) { + if (ty == ModuleType.Cargo) { + return "cargo_off.png" + } else if (ty == ModuleType.LandingThruster) { + return "landingthruster_off.png" + } else if (ty == ModuleType.Hub) { + return "hub_off.png" + } + } else { + if (ty == ModuleType.Cargo) { + return "cargo_on.png" + } else if (ty == ModuleType.LandingThruster) { + return "landingthruster_on.png" + } else if (ty == ModuleType.Hub) { + return "hub_on.png" + } } return "unknown.png" } diff --git a/server/src/handler.rs b/server/src/handler.rs index f6714bafc3922c8a9c3177436795856486e38a91..8f31d36faeee39b138e594a6b6f225aca9266db3 100644 --- a/server/src/handler.rs +++ b/server/src/handler.rs @@ -19,7 +19,7 @@ use rapier2d_f64::prelude::{ use starkingdoms_protocol::goodbye_reason::GoodbyeReason; use starkingdoms_protocol::message_s2c::{ MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModulesUpdate, - MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong, MessageS2CModuleAdd, + MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong, MessageS2CModuleAdd, MessageS2CModuleTreeUpdate, }; use starkingdoms_protocol::module::ModuleType; use starkingdoms_protocol::state::State; @@ -89,6 +89,16 @@ pub async fn handle_client( send!(client_tx, msg).await?; } } + ClientHandlerMessage::ModuleTreeUpdate { modules } => { + if matches!(state, State::Play) { + let msg = MessageS2C::ModuleTreeUpdate(MessageS2CModuleTreeUpdate { + tree: modules, + special_fields: Default::default(), + }) + .try_into()?; + send!(client_tx, msg).await?; + } + } } } else { info!("channel closed, shutting down"); @@ -506,8 +516,8 @@ pub async fn handle_client( let body = data_handle.rigid_body_set.get_mut(module.unwrap().handle).unwrap(); body.set_position(Isometry::new(Vector2::new(p.worldpos_x/SCALE, p.worldpos_y/SCALE),body.rotation().angle()), true); } else { - if let Some(id) = attached_id { - let prot_module = entities.get_attached_from_id(id).unwrap().to_protocol(&entities, &mut data_handle); + if let Some(Ok(id)) = attached_id { + let prot_module = entities.get_attached_from_id(id).unwrap().to_protocol(&entities, &mut data_handle.rigid_body_set); let msg = MessageS2C::ModuleAdd(MessageS2CModuleAdd { module: Some(prot_module).into(), special_fields: Default::default(), diff --git a/server/src/manager.rs b/server/src/manager.rs index 891d22662995c0e9c038837b25936e871caaf65b..8b9ee7d4aaa430a7220e06ecdad88af5e211198a 100644 --- a/server/src/manager.rs +++ b/server/src/manager.rs @@ -117,4 +117,7 @@ pub enum ClientHandlerMessage { ModulesUpdate { modules: Vec, }, + ModuleTreeUpdate { + modules: Vec, + }, } diff --git a/server/src/module.rs b/server/src/module.rs index 5d69aaa0c38cf0e078054d570c228ff5fa58da13..3398266fb9032b1be4f87c8e359a23c0fc77acc2 100644 --- a/server/src/module.rs +++ b/server/src/module.rs @@ -2,7 +2,7 @@ use std::f64::consts::PI; use log::debug; use nalgebra::{Vector2, point, vector, Isometry, Isometry2, Complex, Unit}; -use rapier2d_f64::prelude::{RigidBodyHandle, Real, MassProperties, ColliderBuilder, RigidBodyBuilder, FixedJointBuilder, ImpulseJointHandle}; +use rapier2d_f64::prelude::{RigidBodyHandle, Real, MassProperties, ColliderBuilder, RigidBodyBuilder, FixedJointBuilder, ImpulseJointHandle, RigidBodySet}; use starkingdoms_protocol::module::ModuleType; use crate::{entity::{EntityId, EntityHandler, Entity, get_entity_id}, manager::PhysicsData, SCALE}; @@ -37,15 +37,27 @@ impl AttachedModule { player_id: EntityId, module: Module, attachment_slot: usize, - ) -> EntityId { + ) -> Result { let mut entity_map = entities.entities.clone(); let parent_entity = entity_map .get_mut(&parent) .expect("parent id does not exist"); let parent_handle = match parent_entity { - Entity::Player(player) => player.handle, - Entity::AttachedModule(module) => module.handle, + Entity::Player(player) => { + if let Some(_child) = &player.children[attachment_slot] { + return Err(()); + } else { + player.handle + } + }, + Entity::AttachedModule(module) => { + if let Some(_child) = &module.children[attachment_slot] { + return Err(()); + } else { + module.handle + } + }, _ => { panic!("unexpected parent"); } @@ -137,7 +149,7 @@ impl AttachedModule { entity_map.remove(&entities.get_from_module(&module).unwrap()); entity_map.insert(attached_id, Entity::AttachedModule(attached_module)); entities.entities = entity_map; - attached_id + Ok(attached_id) } pub fn attach_new( data: &mut PhysicsData, @@ -269,12 +281,12 @@ impl AttachedModule { handle: self.handle, module_type: self.module_type, lifetime: 10., - flags: 0, + flags: 1, }) } - pub fn to_protocol(&self, entities: &EntityHandler, data: &mut PhysicsData) -> starkingdoms_protocol::module::AttachedModule { - let body = data.rigid_body_set.get(self.handle).unwrap(); + pub fn to_protocol(&self, entities: &EntityHandler, data: &RigidBodySet) -> starkingdoms_protocol::module::AttachedModule { + let body = data.get(self.handle).unwrap(); let children = self.children.to_vec(); let mut prot_children = Vec::new(); for i in 1..children.len() { @@ -289,8 +301,8 @@ impl AttachedModule { starkingdoms_protocol::module::AttachedModule { module_type: self.module_type.into(), rotation: body.rotation().angle(), - x: body.translation().x, - y: body.translation().y, + x: body.translation().x * SCALE, + y: body.translation().y * SCALE, id: entities.get_id_from_attached(self.clone()).unwrap(), children: prot_children, special_fields: Default::default(), diff --git a/server/src/timer.rs b/server/src/timer.rs index ecea7a59b999dd3ec4f883b324cddf7458c63225..1b95a51c5fca3c3311bcd29578e0d7502adc8f77 100644 --- a/server/src/timer.rs +++ b/server/src/timer.rs @@ -305,38 +305,48 @@ pub async fn timer_main( warn!("unable to send position packet: {}", e); } }; - let mut modules = entities.read().await.get_modules_id(); - let attached_modules = entities.read().await.get_all_attached(); + let modules = entities.read().await.get_modules_id(); let entities = entities.read().await; - let attached_handles: Vec = - attached_modules.iter().map(|m| m.handle).collect(); - modules.append( - &mut attached_modules - .iter() - .map(|m| { - let module = m.to_module_id(&entities); - //info!("{:?}", module); - module - }) - .collect(), - ); - modules.iter().for_each(|(id, module)| { - if attached_handles.contains(&module.handle) { - /*info!( - "{:?}", - physics_data - .rigid_body_set - .get(module.handle) - .unwrap() - .translation() - );*/ - } - }); - let protocol_modules: Vec = modules + let this_player = entities.get_player_id(*addr); + let mut attached_modules: Vec = Vec::new(); + let unattached_modules = entities.get_all_attached(); + let mut unattached_modules: Vec = unattached_modules + .iter() + .filter(|m| { + match this_player { + Some(id) => { + if m.player_id != id { + true + } else { + attached_modules.push(m.to_protocol(&entities, &physics_data.rigid_body_set)); + false + } + } + None => { + true + } + } + }) + .map(|m| { + let (id, module) = m.to_module_id(&entities); + //info!("{:?}", module); + let body = physics_data.rigid_body_set.get(module.handle).unwrap(); + starkingdoms_protocol::module::Module { + module_type: module.module_type.into(), + rotation: body.rotation().angle(), + x: body.translation().x * SCALE, + y: body.translation().y * SCALE, + id, + flags: module.flags, + special_fields: Default::default(), + } + }) + .collect(); + let mut protocol_modules: Vec = modules .iter() .map(|(id, module)| { let body = physics_data.rigid_body_set.get(module.handle).unwrap(); - return starkingdoms_protocol::module::Module { + starkingdoms_protocol::module::Module { module_type: module.module_type.into(), rotation: body.rotation().angle(), x: body.translation().x * SCALE, @@ -344,9 +354,10 @@ pub async fn timer_main( id: *id, flags: module.flags, special_fields: Default::default(), - }; + } }) .collect(); + protocol_modules.append(&mut unattached_modules); match client_thread .tx .send(ClientHandlerMessage::ModulesUpdate { @@ -360,6 +371,15 @@ pub async fn timer_main( } }; + match client_thread.tx.send(ClientHandlerMessage::ModuleTreeUpdate { + modules: attached_modules + }).await { + Ok(_) => (), + Err(e) => { + warn!("unable to send module tree update packet: {}", e); + } + } + let planet_data = entities.to_protocol(); match client_thread.tx.send(planet_data).await { Ok(_) => (),