From 93f551228e8db4b5ed9f7c60ab67056a7e6abdfe Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Wed, 28 Jun 2023 18:43:28 -0500 Subject: [PATCH] yeah so detaching is in but odd client id bug --- client/src/gateway.ts | 5 ++ client/src/index.ts | 20 +++++- client/src/protocol/message_c2s.ts | 97 ++++++++++++++++++++++++++++- client/src/protocol/message_s2c.ts | 12 ++-- protocol/src/lib.rs | 13 +++- protocol/src/pbuf/message_c2s.proto | 8 ++- protocol/src/pbuf/message_s2c.proto | 2 +- server/src/entity.rs | 2 +- server/src/handler.rs | 35 ++++++++++- server/src/manager.rs | 24 ++++++- server/src/module.rs | 90 +++++++++++++++++++++++++- server/src/planet.rs | 2 +- 12 files changed, 288 insertions(+), 22 deletions(-) diff --git a/client/src/gateway.ts b/client/src/gateway.ts index c5515bc3138003b180c9603ca14cca5a976fce21..0c1becbd8ed40a71fa8b0a04f1c3e98cec83ab74 100644 --- a/client/src/gateway.ts +++ b/client/src/gateway.ts @@ -16,6 +16,8 @@ import { MessageS2CHello_packetInfo, MessageS2CModuleAdd, MessageS2CModuleAdd_packetInfo, + MessageS2CModuleRemove, + MessageS2CModuleRemove_packetInfo, MessageS2CModulesUpdate, MessageS2CModulesUpdate_packetInfo, MessageS2CModuleTreeUpdate, @@ -194,6 +196,9 @@ export async function gateway_connect(gateway_url: string, username: string): Pr children: pkt.module!.children, }; global.tree.set(pkt.module!.id, module); + } else if (pkt_id == MessageS2CModuleRemove_packetInfo.type) { + let pkt = MessageS2CModuleRemove.decode(pkt_data); + global.clicked = pkt.module!.id; } else if (pkt_id == MessageS2CModuleTreeUpdate_packetInfo.type) { let pkt = MessageS2CModuleTreeUpdate.decode(pkt_data); let modules: Map = new Map(); diff --git a/client/src/index.ts b/client/src/index.ts index 5ff9a935a1d696b099c9e48422dd6fc0e9eb6523..44982eb2c29eefddbdf5809fcb2c61443fceda22 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -7,7 +7,7 @@ import { MessageC2SAuthenticateAndBeamOut, MessageC2SAuthenticateAndBeamOut_packetInfo, MessageC2SInput, - MessageC2SInput_packetInfo, MessageC2SModuleGrabBegin, MessageC2SModuleGrabBegin_packetInfo, MessageC2SModuleGrabEnd, MessageC2SModuleGrabEnd_packetInfo, MessageC2SMouseInput, MessageC2SMouseInput_packetInfo + MessageC2SInput_packetInfo, MessageC2SModuleDetach, MessageC2SModuleDetach_packetInfo, MessageC2SModuleGrabBegin, MessageC2SModuleGrabBegin_packetInfo, MessageC2SModuleGrabEnd, MessageC2SModuleGrabEnd_packetInfo, MessageC2SMouseInput, MessageC2SMouseInput_packetInfo } from "./protocol/message_c2s"; import {encode} from "./serde"; import {InputType} from "./protocol/input"; @@ -156,10 +156,25 @@ async function client_main(server: string, username: string, texture_quality: st worldposY: worldY, }).finish(); global.clicked = global.modules[i].id; - global.client?.socket.send(encode(MessageC2SModuleGrabBegin_packetInfo.type, msg)) + global.client?.socket.send(encode(MessageC2SModuleGrabBegin_packetInfo.type, msg)); } } } + global.tree.forEach((value: AttachedModule, key: number) => { + let relativeX = value.x - worldX; + let relativeY = value.y - worldY; + let rot = -value.rotation; + relativeX = relativeX*Math.cos(rot) - relativeY*Math.sin(rot); + relativeY = relativeX*Math.sin(rot) + relativeY*Math.cos(rot); + if (-25 < relativeX && relativeX < 25) { + if (-25 < relativeY && relativeY < 25) { + let msg = MessageC2SModuleDetach.encode({ + moduleId: key, + }).finish(); + global.client?.socket.send(encode(MessageC2SModuleDetach_packetInfo.type, msg)); + } + } + }); let msg = MessageC2SMouseInput.encode({ worldposX: worldX, @@ -379,7 +394,6 @@ 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)]; diff --git a/client/src/protocol/message_c2s.ts b/client/src/protocol/message_c2s.ts index 2ecc6790c3c6c982f5c5cdc5c0a9c1118f9c88c6..ba671db8e293f939339452c1c9f44f039b2aaa86 100644 --- a/client/src/protocol/message_c2s.ts +++ b/client/src/protocol/message_c2s.ts @@ -333,7 +333,7 @@ export interface MessageC2SModuleGrabEnd { export enum MessageC2SModuleGrabEnd_packetInfo { unknown = 0, - type = 16, + type = 15, UNRECOGNIZED = -1, } @@ -342,7 +342,7 @@ export function messageC2SModuleGrabEnd_packetInfoFromJSON(object: any): Message case 0: case "unknown": return MessageC2SModuleGrabEnd_packetInfo.unknown; - case 16: + case 15: case "type": return MessageC2SModuleGrabEnd_packetInfo.type; case -1: @@ -364,6 +364,43 @@ export function messageC2SModuleGrabEnd_packetInfoToJSON(object: MessageC2SModul } } +export interface MessageC2SModuleDetach { + moduleId: number; +} + +export enum MessageC2SModuleDetach_packetInfo { + unknown = 0, + type = 16, + UNRECOGNIZED = -1, +} + +export function messageC2SModuleDetach_packetInfoFromJSON(object: any): MessageC2SModuleDetach_packetInfo { + switch (object) { + case 0: + case "unknown": + return MessageC2SModuleDetach_packetInfo.unknown; + case 16: + case "type": + return MessageC2SModuleDetach_packetInfo.type; + case -1: + case "UNRECOGNIZED": + default: + return MessageC2SModuleDetach_packetInfo.UNRECOGNIZED; + } +} + +export function messageC2SModuleDetach_packetInfoToJSON(object: MessageC2SModuleDetach_packetInfo): string { + switch (object) { + case MessageC2SModuleDetach_packetInfo.unknown: + return "unknown"; + case MessageC2SModuleDetach_packetInfo.type: + return "type"; + case MessageC2SModuleDetach_packetInfo.UNRECOGNIZED: + default: + return "UNRECOGNIZED"; + } +} + function createBaseMessageC2SHello(): MessageC2SHello { return { version: 0, requestedUsername: "", nextState: 0, token: "", user: "" }; } @@ -1067,6 +1104,62 @@ export const MessageC2SModuleGrabEnd = { }, }; +function createBaseMessageC2SModuleDetach(): MessageC2SModuleDetach { + return { moduleId: 0 }; +} + +export const MessageC2SModuleDetach = { + encode(message: MessageC2SModuleDetach, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.moduleId !== 0) { + writer.uint32(8).uint32(message.moduleId); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): MessageC2SModuleDetach { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMessageC2SModuleDetach(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag != 8) { + break; + } + + message.moduleId = reader.uint32(); + continue; + } + if ((tag & 7) == 4 || tag == 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): MessageC2SModuleDetach { + return { moduleId: isSet(object.moduleId) ? Number(object.moduleId) : 0 }; + }, + + toJSON(message: MessageC2SModuleDetach): unknown { + const obj: any = {}; + message.moduleId !== undefined && (obj.moduleId = Math.round(message.moduleId)); + return obj; + }, + + create, I>>(base?: I): MessageC2SModuleDetach { + return MessageC2SModuleDetach.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): MessageC2SModuleDetach { + const message = createBaseMessageC2SModuleDetach(); + message.moduleId = object.moduleId ?? 0; + return message; + }, +}; + type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; export type DeepPartial = T extends Builtin ? T diff --git a/client/src/protocol/message_s2c.ts b/client/src/protocol/message_s2c.ts index 2ef655b65aea80cc507b0e58e94a3623a5eef5a8..1c20c8ff6f3a0721e6b9086a72d3180abfe0ba59 100644 --- a/client/src/protocol/message_s2c.ts +++ b/client/src/protocol/message_s2c.ts @@ -352,7 +352,7 @@ export function messageS2CModuleAdd_packetInfoToJSON(object: MessageS2CModuleAdd } export interface MessageS2CModuleRemove { - module: AttachedModule | undefined; + module: Module | undefined; } export enum MessageS2CModuleRemove_packetInfo { @@ -948,7 +948,7 @@ function createBaseMessageS2CModuleRemove(): MessageS2CModuleRemove { export const MessageS2CModuleRemove = { encode(message: MessageS2CModuleRemove, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { if (message.module !== undefined) { - AttachedModule.encode(message.module, writer.uint32(10).fork()).ldelim(); + Module.encode(message.module, writer.uint32(10).fork()).ldelim(); } return writer; }, @@ -965,7 +965,7 @@ export const MessageS2CModuleRemove = { break; } - message.module = AttachedModule.decode(reader, reader.uint32()); + message.module = Module.decode(reader, reader.uint32()); continue; } if ((tag & 7) == 4 || tag == 0) { @@ -977,12 +977,12 @@ export const MessageS2CModuleRemove = { }, fromJSON(object: any): MessageS2CModuleRemove { - return { module: isSet(object.module) ? AttachedModule.fromJSON(object.module) : undefined }; + return { module: isSet(object.module) ? Module.fromJSON(object.module) : undefined }; }, toJSON(message: MessageS2CModuleRemove): unknown { const obj: any = {}; - message.module !== undefined && (obj.module = message.module ? AttachedModule.toJSON(message.module) : undefined); + message.module !== undefined && (obj.module = message.module ? Module.toJSON(message.module) : undefined); return obj; }, @@ -993,7 +993,7 @@ export const MessageS2CModuleRemove = { fromPartial, I>>(object: I): MessageS2CModuleRemove { const message = createBaseMessageS2CModuleRemove(); message.module = (object.module !== undefined && object.module !== null) - ? AttachedModule.fromPartial(object.module) + ? Module.fromPartial(object.module) : undefined; return message; }, diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 9064b9303e2e4c338924e4b770ba12c8f19d220e..5c4912b6af7b838abcd7f5eb8b32def2a5391d24 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -1,6 +1,7 @@ use crate::message_c2s::{ MessageC2SAuthenticateAndBeamOut, MessageC2SChat, MessageC2SGoodbye, MessageC2SHello, - MessageC2SInput, MessageC2SModuleGrabBegin, MessageC2SModuleGrabEnd, MessageC2SMouseInput, MessageC2SPing, + MessageC2SInput, MessageC2SModuleDetach, MessageC2SModuleGrabBegin, MessageC2SModuleGrabEnd, + MessageC2SMouseInput, MessageC2SPing }; use crate::message_s2c::{ MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModulesUpdate, @@ -28,6 +29,7 @@ pub enum MessageC2S { MouseInput(MessageC2SMouseInput), ModuleGrabBegin(MessageC2SModuleGrabBegin), ModuleGrabEnd(MessageC2SModuleGrabEnd), + ModuleDetach(MessageC2SModuleDetach), } #[derive(Debug)] @@ -89,6 +91,11 @@ impl TryFrom<&[u8]> for MessageC2S { { MessageC2S::ModuleGrabEnd(MessageC2SModuleGrabEnd::parse_from_bytes(&pkt.packet_data)?) } + _id if _id + == message_c2s::message_c2smodule_detach::Packet_info::type_.value() as i64 => + { + MessageC2S::ModuleDetach(MessageC2SModuleDetach::parse_from_bytes(&pkt.packet_data)?) + } _id => { return Err(format!("Unrecognized C2S packet {}", _id).into()); } @@ -139,6 +146,10 @@ impl TryInto> for MessageC2S { message_c2s::message_c2smodule_grab_end::Packet_info::type_.value(), p.write_to_bytes()?, ), + MessageC2S::ModuleDetach(p) => ( + message_c2s::message_c2smodule_detach::Packet_info::type_.value(), + p.write_to_bytes()?, + ), }; let pkt = PacketWrapper { diff --git a/protocol/src/pbuf/message_c2s.proto b/protocol/src/pbuf/message_c2s.proto index 298ed2d09a08ad94d15cdbc5824daa87cc362fcc..8033d084f4058b9f1e1bd4bb6cebfcdc565439cc 100644 --- a/protocol/src/pbuf/message_c2s.proto +++ b/protocol/src/pbuf/message_c2s.proto @@ -68,9 +68,15 @@ message MessageC2SModuleGrabBegin { } message MessageC2SModuleGrabEnd { - enum packet_info { unknown = 0; type = 0x10; } + enum packet_info { unknown = 0; type = 0x0f; } uint32 module_id = 1; double worldpos_x = 2; double worldpos_y = 3; } + +message MessageC2SModuleDetach { + enum packet_info { unknown = 0; type = 0x10; } + + uint32 module_id = 1; +} diff --git a/protocol/src/pbuf/message_s2c.proto b/protocol/src/pbuf/message_s2c.proto index 0db942baae7f030393d8fac8a1a04200e3eb1cac..72c58336c12acdc5cdaa32cefdf333e01bedd037 100644 --- a/protocol/src/pbuf/message_s2c.proto +++ b/protocol/src/pbuf/message_s2c.proto @@ -65,5 +65,5 @@ message MessageS2CModuleAdd { message MessageS2CModuleRemove { enum packet_info { unknown = 0; type = 0x0e; } - protocol.module.AttachedModule module = 1; + protocol.module.Module module = 1; } diff --git a/server/src/entity.rs b/server/src/entity.rs index 654f0f39ed482d3b49ce388e307371d5406b5e41..2cc580d414b5f4ab53ef02dbf0ff7b6e32b915c3 100644 --- a/server/src/entity.rs +++ b/server/src/entity.rs @@ -185,7 +185,7 @@ impl EntityHandler { } } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Entity { Player(Player), Planet(Planet), diff --git a/server/src/handler.rs b/server/src/handler.rs index ed46466179c07f5b02929f6965a72797e31cf999..301180932d41b001c1b99d9a802fe8726dee91d3 100644 --- a/server/src/handler.rs +++ b/server/src/handler.rs @@ -10,7 +10,7 @@ use async_std::{channel::Receiver, sync::RwLock}; use async_tungstenite::WebSocketStream; use futures::stream::{SplitSink, SplitStream}; use futures::{FutureExt, SinkExt, StreamExt}; -use log::{debug, error, info, warn}; +use log::{debug, error, info, warn, trace}; use nalgebra::{point, vector, Matrix, Vector2}; use rand::Rng; use rapier2d_f64::prelude::{ @@ -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, MessageS2CModuleTreeUpdate, + MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong, MessageS2CModuleAdd, MessageS2CModuleTreeUpdate, MessageS2CModuleRemove, }; use starkingdoms_protocol::module::ModuleType; use starkingdoms_protocol::state::State; @@ -444,6 +444,37 @@ pub async fn handle_client( MessageC2S::MouseInput(p) => { //debug!("[{}] player input: {:?}", remote_addr, p); } + MessageC2S::ModuleDetach(p) => { + let mut entities = entities.write().await; + let mut data_handle = data.write().await; + let mut module: Option = None; + debug!("[{}] detach: {:?}", remote_addr, p); + debug!("[{}] {:?}", remote_addr, entities.entities); + if let Entity::AttachedModule(p_module) = entities.entities.get_mut(&p.module_id).unwrap() { + module = Some(p_module.clone()); + } + let player_id = entities.get_player_id(remote_addr).unwrap(); + let module_id = AttachedModule::detach(&mut data_handle, &mut entities, + player_id, + module.unwrap()); + let module = entities.get_module_from_id(module_id).unwrap(); + let body = data_handle.rigid_body_set.get(module.handle).unwrap(); + let prot_module = 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: module_id, + flags: module.flags, + special_fields: Default::default(), + }; + let msg = MessageS2C::ModuleRemove(MessageS2CModuleRemove { + module: Some(prot_module).into(), + special_fields: Default::default(), + }) + .try_into()?; + send!(client_tx, msg).await?; + } MessageC2S::ModuleGrabBegin(p) => { if let Entity::Module(module) = entities.write().await.entities.get_mut(&p.module_id).unwrap() { //debug!("[{}] grab begin: {:?}, flags: {}", remote_addr, p, module.flags); diff --git a/server/src/manager.rs b/server/src/manager.rs index 8b9ee7d4aaa430a7220e06ecdad88af5e211198a..e7adb3704f205c574b75e320c15891d0e27fe478 100644 --- a/server/src/manager.rs +++ b/server/src/manager.rs @@ -26,7 +26,7 @@ pub struct ClientManager { pub usernames: Arc>>, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Player { pub handle: RigidBodyHandle, pub input: PlayerInput, @@ -53,9 +53,29 @@ impl Player { } modules } + pub fn find_parent(&self, module: AttachedModule, entities: &EntityHandler) -> Option<(u8, EntityId)> { + for (slot, attachment) in self.children.iter().enumerate() { + if let Some(attachment) = attachment { + if let Entity::AttachedModule(child_module) = + entities.entities.get(&attachment.child).unwrap() + { + debug!("player child: {:?}", *child_module); + debug!("player target: {:?}", module); + if *child_module == module { + return Some((slot as u8, entities.get_player_id(self.addr).unwrap())); + } + let parent = child_module.find_parent(module.clone(), entities); + if let Some(_) = parent { + return parent; + } + } + } + } + None + } } -#[derive(Default, Clone)] +#[derive(Default, Clone, Debug)] pub struct PlayerInput { pub up: bool, pub left: bool, diff --git a/server/src/module.rs b/server/src/module.rs index 3398266fb9032b1be4f87c8e359a23c0fc77acc2..5c81d79a3686d411dc17c0cd96f5d621f82a2f10 100644 --- a/server/src/module.rs +++ b/server/src/module.rs @@ -22,7 +22,7 @@ pub struct ModuleTemplate { pub module_type: ModuleType, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct AttachedModule { pub handle: RigidBodyHandle, pub module_type: ModuleType, @@ -151,6 +151,71 @@ impl AttachedModule { entities.entities = entity_map; Ok(attached_id) } + pub fn detach( + data: &mut PhysicsData, + entities: &mut EntityHandler, + player_id: EntityId, + module: AttachedModule, + ) -> EntityId { + let mut entity_map = entities.entities.clone(); + + // player not in parent search + // also no parents included in parent search + let player = entities.get_player_from_id(player_id).unwrap(); + let (slot, parent_id) = player.find_parent(module.clone(), entities).unwrap(); + let parent_entity = entity_map + .get_mut(&parent_id) + .expect("parent id does not exist"); + + match parent_entity { + Entity::Player(ref mut player) => { + if let Some(child) = player.children[slot as usize].clone() { + data.impulse_joint_set.remove(child.connection, true); + } + player.children[slot as usize] = None; + } + Entity::AttachedModule(ref mut module) => { + if let Some(child) = &module.children[slot as usize] { + data.impulse_joint_set.remove(child.connection, true); + } + module.children[slot as usize] = None; + } + _ => { + panic!("unexpected parent"); + } + }; + // remove joint + let tree = module.search_modules(entities); + let new_module = Module { + handle: module.handle, + module_type: module.module_type, + lifetime: 0., + flags: 0, + }; + entity_map.remove(&entities.get_id_from_attached(module.clone()).unwrap()); + let id = get_entity_id(); + entity_map.insert(id, Entity::Module(new_module)); + for element in tree { + for child in element.clone().children { + if let Some(child) = child { + debug!("child: {:?}", child); + data.impulse_joint_set.remove(child.connection, true); + let child_body = entities.get_attached_from_id(child.child).unwrap(); + let new_module = Module { + handle: child_body.handle, + module_type: child_body.module_type, + lifetime: 0., + flags: 0, + }; + entity_map.remove(&entities.get_id_from_attached(child_body.clone()).unwrap()); + let attached_id = get_entity_id(); + entity_map.insert(attached_id, Entity::Module(new_module)); + } + } + } + entities.entities = entity_map; + id + } pub fn attach_new( data: &mut PhysicsData, entities: &mut EntityHandler, @@ -320,9 +385,30 @@ impl AttachedModule { } modules } + + pub fn find_parent(&self, module: AttachedModule, entities: &EntityHandler) -> Option<(u8, EntityId)> { + for (slot, attachment) in self.children.iter().enumerate() { + if let Some(attachment) = attachment { + if let Entity::AttachedModule(child_module) = + entities.entities.get(&attachment.child).unwrap() + { + debug!("child: {:?}", *child_module); + debug!("target: {:?}", module); + if *child_module == module { + return Some((slot as u8, entities.get_id_from_attached(self.clone()).unwrap())); + } + let parent = child_module.find_parent(module.clone(), entities); + if let Some(_) = parent { + return parent; + } + } + } + } + None + } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct Attachment { pub child: EntityId, pub connection: ImpulseJointHandle, diff --git a/server/src/planet.rs b/server/src/planet.rs index d758c8db0b539d676be2f67500fa8c16453c716d..ca998c2ac517f78167d33d83f825fa980b841700 100644 --- a/server/src/planet.rs +++ b/server/src/planet.rs @@ -15,7 +15,7 @@ use crate::{manager::ClientHandlerMessage, SCALE}; pub const GRAVITY: f64 = 0.02; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Planet { pub planet_type: PlanetType, pub body_handle: RigidBodyHandle,