~starkingdoms/starkingdoms

93f551228e8db4b5ed9f7c60ab67056a7e6abdfe — ghostlyzsh 2 years ago f257871
yeah so detaching is in but odd client id bug
M client/src/gateway.ts => client/src/gateway.ts +5 -0
@@ 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<number, AttachedModule> = new Map<number, AttachedModule>();

M client/src/index.ts => client/src/index.ts +17 -3
@@ 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)];


M client/src/protocol/message_c2s.ts => client/src/protocol/message_c2s.ts +95 -2
@@ 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 extends Exact<DeepPartial<MessageC2SModuleDetach>, I>>(base?: I): MessageC2SModuleDetach {
    return MessageC2SModuleDetach.fromPartial(base ?? {});
  },

  fromPartial<I extends Exact<DeepPartial<MessageC2SModuleDetach>, 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> = T extends Builtin ? T

M client/src/protocol/message_s2c.ts => client/src/protocol/message_s2c.ts +6 -6
@@ 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 extends Exact<DeepPartial<MessageS2CModuleRemove>, 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;
  },

M protocol/src/lib.rs => protocol/src/lib.rs +12 -1
@@ 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<Vec<u8>> 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 {

M protocol/src/pbuf/message_c2s.proto => protocol/src/pbuf/message_c2s.proto +7 -1
@@ 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;
}

M protocol/src/pbuf/message_s2c.proto => protocol/src/pbuf/message_s2c.proto +1 -1
@@ 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;
}

M server/src/entity.rs => server/src/entity.rs +1 -1
@@ 185,7 185,7 @@ impl EntityHandler {
    }
}

#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum Entity {
    Player(Player),
    Planet(Planet),

M server/src/handler.rs => server/src/handler.rs +33 -2
@@ 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<AttachedModule> = 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);

M server/src/manager.rs => server/src/manager.rs +22 -2
@@ 26,7 26,7 @@ pub struct ClientManager {
    pub usernames: Arc<RwLock<HashMap<SocketAddr, String>>>,
}

#[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,

M server/src/module.rs => server/src/module.rs +88 -2
@@ 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,

M server/src/planet.rs => server/src/planet.rs +1 -1
@@ 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,