~starkingdoms/starkingdoms

dd1fbffa27b9b47a6d9015efd2cf033a68c9da57 — ghostlyzsh 2 years ago fecb8b0
tree added to client, multiple attachment bug also patched
M client/src/gateway.ts => client/src/gateway.ts +36 -0
@@ 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<GatewayClient> {
    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`);
            }

M client/src/index.ts => client/src/index.ts +43 -9
@@ 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<number, AttachedModule>,
}

export interface Keys {


@@ 65,6 66,7 @@ export const global: GlobalData = {
    direction_radians: 0,
    mouse_x: 0,
    mouse_y: 0,
    tree: new Map<number, AttachedModule>(),
}

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"
}

M server/src/handler.rs => server/src/handler.rs +13 -3
@@ 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(),

M server/src/manager.rs => server/src/manager.rs +3 -0
@@ 117,4 117,7 @@ pub enum ClientHandlerMessage {
    ModulesUpdate {
        modules: Vec<starkingdoms_protocol::module::Module>,
    },
    ModuleTreeUpdate {
        modules: Vec<starkingdoms_protocol::module::AttachedModule>,
    },
}

M server/src/module.rs => server/src/module.rs +22 -10
@@ 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<EntityId, ()> {
        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(),

M server/src/timer.rs => server/src/timer.rs +49 -29
@@ 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<RigidBodyHandle> =
                        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<starkingdoms_protocol::module::Module> = modules
                    let this_player = entities.get_player_id(*addr);
                    let mut attached_modules: Vec<starkingdoms_protocol::module::AttachedModule> = Vec::new();
                    let unattached_modules = entities.get_all_attached();
                    let mut unattached_modules: Vec<starkingdoms_protocol::module::Module> = 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<starkingdoms_protocol::module::Module> = 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(_) => (),