~starkingdoms/starkingdoms

317954ef75ec4d951fd7fa70b22b11a0127bdf49 — c0repwn3r 2 years ago 899987c
input + cleanup
M client/package.json => client/package.json +1 -1
@@ 7,7 7,7 @@
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "protobuf": "mkdir -p ./src/protocol && protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/protocol -I ../protocol/src/pbuf ../protocol/src/pbuf/starkingdoms-protocol.proto"
    "protobuf": "mkdir -p ./src/protocol && protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/protocol -I ../protocol/src/pbuf ../protocol/src/pbuf/starkingdoms-protocol.proto && sed -i 's/\\/\\* eslint-disable \\*\\//\\/\\/@ts-nocheck/' src/protocol/*.ts"
  },
  "devDependencies": {
    "ts-proto": "^1.146.0",

M client/src/gateway.ts => client/src/gateway.ts +2 -2
@@ 74,7 74,7 @@ export async function gateway_connect(gateway_url: string, username: string): Pr
    let handshake_start_msg;
    if (global.can_beam_out) {
        handshake_start_msg = MessageC2SHello.encode({
            version: 3,
            version: 4,
            requestedUsername: username,
            nextState: State.Play,
            user: window.localStorage.getItem("user")!,


@@ 82,7 82,7 @@ export async function gateway_connect(gateway_url: string, username: string): Pr
        }).finish();
    } else {
        handshake_start_msg = MessageC2SHello.encode({
            version: 3,
            version: 4,
            requestedUsername: username,
            nextState: State.Play,
            // @ts-ignore

M client/src/index.ts => client/src/index.ts +70 -1
@@ 7,9 7,10 @@ import {
    MessageC2SAuthenticateAndBeamOut,
    MessageC2SAuthenticateAndBeamOut_packetInfo,
    MessageC2SInput,
    MessageC2SInput_packetInfo
    MessageC2SInput_packetInfo, MessageC2SMouseInput, MessageC2SMouseInput_packetInfo
} from "./protocol/message_c2s";
import {encode} from "./serde";
import {InputType} from "./protocol/input";

logSetup();
const logger = new Logger("client");


@@ 110,6 111,71 @@ async function client_main(server: string, username: string, texture_quality: st
    }

    global.canvas.style.setProperty("background-image", `url("/assets/final/${texture_quality}/starfield.png")`);
    let canvas = document.getElementById("canvas")!;

    document.onmousedown = (e) => {
        let canvasLeft = canvas.offsetLeft + canvas.clientLeft;
        let canvasTop = canvas.offsetTop + canvas.clientTop;

        let screenspaceX = e.pageX - canvasLeft;
        let screenspaceY = e.pageY - canvasTop;

        // convert screenspace to worldspace
        if (global.me !== null) {
            let worldX = screenspaceX + global.me?.x;
            let worldY = screenspaceY + global.me?.y;

            let button: InputType;
            if (e.button == 0) {
                button = InputType.Left;
            } else if (e.button == 1) {
                button = InputType.Middle;
            } else if (e.button == 2) {
                button = InputType.Right;
            }

            let msg = MessageC2SMouseInput.encode({
                worldposX: worldX,
                worldposY: worldY,
                released: false,
                button: button!
            }).finish();

            global.client?.socket.send(encode(MessageC2SMouseInput_packetInfo.type, msg))
        }
    }

    document.onmouseup = (e) => {
        let canvasLeft = canvas.offsetLeft + canvas.clientLeft;
        let canvasTop = canvas.offsetTop + canvas.clientTop;

        let screenspaceX = e.pageX - canvasLeft;
        let screenspaceY = e.pageY - canvasTop;

        // convert screenspace to worldspace
        if (global.me !== null) {
            let worldX = screenspaceX + global.me?.x;
            let worldY = screenspaceY + global.me?.y;

            let button: InputType;
            if (e.button == 0) {
                button = InputType.Left;
            } else if (e.button == 1) {
                button = InputType.Middle;
            } else if (e.button == 2) {
                button = InputType.Right;
            }

            let msg = MessageC2SMouseInput.encode({
                worldposX: worldX,
                worldposY: worldY,
                released: true,
                button: button!
            }).finish();

            global.client?.socket.send(encode(MessageC2SMouseInput_packetInfo.type, msg))
        }
    }

    document.onkeydown = (e) => {
        if (e.code == "ArrowLeft" || e.code == "KeyA") { // arrow-left


@@ 213,6 279,9 @@ async function client_main(server: string, username: string, texture_quality: st

            global.context.save();

            // x_{screen} = x_{world} - player_{x_{world}}
            // x_{world} = x_{screen} + player_{x_{world}}

            global.context.translate(module.x - global.me!.x, module.y - global.me!.y);

            global.context.rotate(module.rotation);

M client/src/protocol/goodbye_reason.ts => client/src/protocol/goodbye_reason.ts +18 -12
@@ 1,35 1,39 @@
/* eslint-disable */
//@ts-nocheck

export const protobufPackage = "protocol.goodbye_reason";

export enum GoodbyeReason {
  UnsupportedProtocol = 0,
  UnexpectedPacket = 1,
  UnexpectedNextState = 2,
  UsernameTaken = 3,
  PingPongTimeout = 4,
  Done = 5,
  UNKNOWN = 0,
  UnsupportedProtocol = 1,
  UnexpectedPacket = 2,
  UnexpectedNextState = 3,
  UsernameTaken = 4,
  PingPongTimeout = 5,
  Done = 6,
  UNRECOGNIZED = -1,
}

export function goodbyeReasonFromJSON(object: any): GoodbyeReason {
  switch (object) {
    case 0:
    case "UNKNOWN":
      return GoodbyeReason.UNKNOWN;
    case 1:
    case "UnsupportedProtocol":
      return GoodbyeReason.UnsupportedProtocol;
    case 1:
    case 2:
    case "UnexpectedPacket":
      return GoodbyeReason.UnexpectedPacket;
    case 2:
    case 3:
    case "UnexpectedNextState":
      return GoodbyeReason.UnexpectedNextState;
    case 3:
    case 4:
    case "UsernameTaken":
      return GoodbyeReason.UsernameTaken;
    case 4:
    case 5:
    case "PingPongTimeout":
      return GoodbyeReason.PingPongTimeout;
    case 5:
    case 6:
    case "Done":
      return GoodbyeReason.Done;
    case -1:


@@ 41,6 45,8 @@ export function goodbyeReasonFromJSON(object: any): GoodbyeReason {

export function goodbyeReasonToJSON(object: GoodbyeReason): string {
  switch (object) {
    case GoodbyeReason.UNKNOWN:
      return "UNKNOWN";
    case GoodbyeReason.UnsupportedProtocol:
      return "UnsupportedProtocol";
    case GoodbyeReason.UnexpectedPacket:

A client/src/protocol/input.ts => client/src/protocol/input.ts +48 -0
@@ 0,0 1,48 @@
//@ts-nocheck

export const protobufPackage = "protocol.input";

export enum InputType {
  UNKNOWN = 0,
  Left = 1,
  Middle = 2,
  Right = 3,
  UNRECOGNIZED = -1,
}

export function inputTypeFromJSON(object: any): InputType {
  switch (object) {
    case 0:
    case "UNKNOWN":
      return InputType.UNKNOWN;
    case 1:
    case "Left":
      return InputType.Left;
    case 2:
    case "Middle":
      return InputType.Middle;
    case 3:
    case "Right":
      return InputType.Right;
    case -1:
    case "UNRECOGNIZED":
    default:
      return InputType.UNRECOGNIZED;
  }
}

export function inputTypeToJSON(object: InputType): string {
  switch (object) {
    case InputType.UNKNOWN:
      return "UNKNOWN";
    case InputType.Left:
      return "Left";
    case InputType.Middle:
      return "Middle";
    case InputType.Right:
      return "Right";
    case InputType.UNRECOGNIZED:
    default:
      return "UNRECOGNIZED";
  }
}

M client/src/protocol/message_c2s.ts => client/src/protocol/message_c2s.ts +141 -4
@@ 1,7 1,7 @@
// @ts-nocheck

//@ts-nocheck
import * as _m0 from "protobufjs/minimal";
import { GoodbyeReason, goodbyeReasonFromJSON, goodbyeReasonToJSON } from "./goodbye_reason";
import { InputType, inputTypeFromJSON, inputTypeToJSON } from "./input";
import { State, stateFromJSON, stateToJSON } from "./state";

export const protobufPackage = "protocol.message_c2s";


@@ 13,8 13,8 @@ export interface MessageC2SHello {
  requestedUsername: string;
  /** The state the connection will go into after the handshake. */
  nextState: State;
  token?: string | undefined;
  user?: string | undefined;
  token: string;
  user: string;
}

export enum MessageC2SHello_packetInfo {


@@ 246,6 246,46 @@ export function messageC2SAuthenticateAndBeamOut_packetInfoToJSON(
  }
}

export interface MessageC2SMouseInput {
  worldposX: number;
  worldposY: number;
  button: InputType;
  released: boolean;
}

export enum MessageC2SMouseInput_packetInfo {
  unknown = 0,
  type = 13,
  UNRECOGNIZED = -1,
}

export function messageC2SMouseInput_packetInfoFromJSON(object: any): MessageC2SMouseInput_packetInfo {
  switch (object) {
    case 0:
    case "unknown":
      return MessageC2SMouseInput_packetInfo.unknown;
    case 13:
    case "type":
      return MessageC2SMouseInput_packetInfo.type;
    case -1:
    case "UNRECOGNIZED":
    default:
      return MessageC2SMouseInput_packetInfo.UNRECOGNIZED;
  }
}

export function messageC2SMouseInput_packetInfoToJSON(object: MessageC2SMouseInput_packetInfo): string {
  switch (object) {
    case MessageC2SMouseInput_packetInfo.unknown:
      return "unknown";
    case MessageC2SMouseInput_packetInfo.type:
      return "type";
    case MessageC2SMouseInput_packetInfo.UNRECOGNIZED:
    default:
      return "UNRECOGNIZED";
  }
}

function createBaseMessageC2SHello(): MessageC2SHello {
  return { version: 0, requestedUsername: "", nextState: 0, token: "", user: "" };
}


@@ 684,6 724,103 @@ export const MessageC2SAuthenticateAndBeamOut = {
  },
};

function createBaseMessageC2SMouseInput(): MessageC2SMouseInput {
  return { worldposX: 0, worldposY: 0, button: 0, released: false };
}

export const MessageC2SMouseInput = {
  encode(message: MessageC2SMouseInput, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
    if (message.worldposX !== 0) {
      writer.uint32(9).double(message.worldposX);
    }
    if (message.worldposY !== 0) {
      writer.uint32(17).double(message.worldposY);
    }
    if (message.button !== 0) {
      writer.uint32(24).int32(message.button);
    }
    if (message.released === true) {
      writer.uint32(32).bool(message.released);
    }
    return writer;
  },

  decode(input: _m0.Reader | Uint8Array, length?: number): MessageC2SMouseInput {
    const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
    let end = length === undefined ? reader.len : reader.pos + length;
    const message = createBaseMessageC2SMouseInput();
    while (reader.pos < end) {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          if (tag != 9) {
            break;
          }

          message.worldposX = reader.double();
          continue;
        case 2:
          if (tag != 17) {
            break;
          }

          message.worldposY = reader.double();
          continue;
        case 3:
          if (tag != 24) {
            break;
          }

          message.button = reader.int32() as any;
          continue;
        case 4:
          if (tag != 32) {
            break;
          }

          message.released = reader.bool();
          continue;
      }
      if ((tag & 7) == 4 || tag == 0) {
        break;
      }
      reader.skipType(tag & 7);
    }
    return message;
  },

  fromJSON(object: any): MessageC2SMouseInput {
    return {
      worldposX: isSet(object.worldposX) ? Number(object.worldposX) : 0,
      worldposY: isSet(object.worldposY) ? Number(object.worldposY) : 0,
      button: isSet(object.button) ? inputTypeFromJSON(object.button) : 0,
      released: isSet(object.released) ? Boolean(object.released) : false,
    };
  },

  toJSON(message: MessageC2SMouseInput): unknown {
    const obj: any = {};
    message.worldposX !== undefined && (obj.worldposX = message.worldposX);
    message.worldposY !== undefined && (obj.worldposY = message.worldposY);
    message.button !== undefined && (obj.button = inputTypeToJSON(message.button));
    message.released !== undefined && (obj.released = message.released);
    return obj;
  },

  create<I extends Exact<DeepPartial<MessageC2SMouseInput>, I>>(base?: I): MessageC2SMouseInput {
    return MessageC2SMouseInput.fromPartial(base ?? {});
  },

  fromPartial<I extends Exact<DeepPartial<MessageC2SMouseInput>, I>>(object: I): MessageC2SMouseInput {
    const message = createBaseMessageC2SMouseInput();
    message.worldposX = object.worldposX ?? 0;
    message.worldposY = object.worldposY ?? 0;
    message.button = object.button ?? 0;
    message.released = object.released ?? false;
    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 +1 -1
@@ 1,4 1,4 @@
/* eslint-disable */
//@ts-nocheck
import * as _m0 from "protobufjs/minimal";
import { GoodbyeReason, goodbyeReasonFromJSON, goodbyeReasonToJSON } from "./goodbye_reason";
import { Module } from "./module";

M client/src/protocol/module.ts => client/src/protocol/module.ts +21 -15
@@ 1,24 1,28 @@
/* eslint-disable */
//@ts-nocheck
import * as _m0 from "protobufjs/minimal";

export const protobufPackage = "protocol.module";

export enum ModuleType {
  Cargo = 0,
  LandingThruster = 1,
  Hub = 2,
  UNKNOWN = 0,
  Cargo = 1,
  LandingThruster = 2,
  Hub = 3,
  UNRECOGNIZED = -1,
}

export function moduleTypeFromJSON(object: any): ModuleType {
  switch (object) {
    case 0:
    case "UNKNOWN":
      return ModuleType.UNKNOWN;
    case 1:
    case "Cargo":
      return ModuleType.Cargo;
    case 1:
    case 2:
    case "LandingThruster":
      return ModuleType.LandingThruster;
    case 2:
    case 3:
    case "Hub":
      return ModuleType.Hub;
    case -1:


@@ 30,6 34,8 @@ export function moduleTypeFromJSON(object: any): ModuleType {

export function moduleTypeToJSON(object: ModuleType): string {
  switch (object) {
    case ModuleType.UNKNOWN:
      return "UNKNOWN";
    case ModuleType.Cargo:
      return "Cargo";
    case ModuleType.LandingThruster:


@@ 59,13 65,13 @@ export const Module = {
      writer.uint32(8).int32(message.moduleType);
    }
    if (message.rotation !== 0) {
      writer.uint32(21).float(message.rotation);
      writer.uint32(17).double(message.rotation);
    }
    if (message.x !== 0) {
      writer.uint32(29).float(message.x);
      writer.uint32(25).double(message.x);
    }
    if (message.y !== 0) {
      writer.uint32(37).float(message.y);
      writer.uint32(33).double(message.y);
    }
    return writer;
  },


@@ 85,25 91,25 @@ export const Module = {
          message.moduleType = reader.int32() as any;
          continue;
        case 2:
          if (tag != 21) {
          if (tag != 17) {
            break;
          }

          message.rotation = reader.float();
          message.rotation = reader.double();
          continue;
        case 3:
          if (tag != 29) {
          if (tag != 25) {
            break;
          }

          message.x = reader.float();
          message.x = reader.double();
          continue;
        case 4:
          if (tag != 37) {
          if (tag != 33) {
            break;
          }

          message.y = reader.float();
          message.y = reader.double();
          continue;
      }
      if ((tag & 7) == 4 || tag == 0) {

M client/src/protocol/planet.ts => client/src/protocol/planet.ts +19 -13
@@ 1,20 1,24 @@
/* eslint-disable */
//@ts-nocheck
import * as _m0 from "protobufjs/minimal";

export const protobufPackage = "protocol.planet";

export enum PlanetType {
  Earth = 0,
  Moon = 1,
  UNKNOWN = 0,
  Earth = 1,
  Moon = 2,
  UNRECOGNIZED = -1,
}

export function planetTypeFromJSON(object: any): PlanetType {
  switch (object) {
    case 0:
    case "UNKNOWN":
      return PlanetType.UNKNOWN;
    case 1:
    case "Earth":
      return PlanetType.Earth;
    case 1:
    case 2:
    case "Moon":
      return PlanetType.Moon;
    case -1:


@@ 26,6 30,8 @@ export function planetTypeFromJSON(object: any): PlanetType {

export function planetTypeToJSON(object: PlanetType): string {
  switch (object) {
    case PlanetType.UNKNOWN:
      return "UNKNOWN";
    case PlanetType.Earth:
      return "Earth";
    case PlanetType.Moon:


@@ 57,13 63,13 @@ export const Planet = {
      writer.uint32(8).int32(message.planetType);
    }
    if (message.x !== 0) {
      writer.uint32(21).float(message.x);
      writer.uint32(17).double(message.x);
    }
    if (message.y !== 0) {
      writer.uint32(29).float(message.y);
      writer.uint32(25).double(message.y);
    }
    if (message.radius !== 0) {
      writer.uint32(37).float(message.radius);
      writer.uint32(33).double(message.radius);
    }
    return writer;
  },


@@ 83,25 89,25 @@ export const Planet = {
          message.planetType = reader.int32() as any;
          continue;
        case 2:
          if (tag != 21) {
          if (tag != 17) {
            break;
          }

          message.x = reader.float();
          message.x = reader.double();
          continue;
        case 3:
          if (tag != 29) {
          if (tag != 25) {
            break;
          }

          message.y = reader.float();
          message.y = reader.double();
          continue;
        case 4:
          if (tag != 37) {
          if (tag != 33) {
            break;
          }

          message.radius = reader.float();
          message.radius = reader.double();
          continue;
      }
      if ((tag & 7) == 4 || tag == 0) {

M client/src/protocol/player.ts => client/src/protocol/player.ts +10 -10
@@ 1,4 1,4 @@
/* eslint-disable */
//@ts-nocheck
import * as _m0 from "protobufjs/minimal";

export const protobufPackage = "protocol.player";


@@ 21,13 21,13 @@ function createBasePlayer(): Player {
export const Player = {
  encode(message: Player, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
    if (message.rotation !== 0) {
      writer.uint32(13).float(message.rotation);
      writer.uint32(9).double(message.rotation);
    }
    if (message.x !== 0) {
      writer.uint32(21).float(message.x);
      writer.uint32(17).double(message.x);
    }
    if (message.y !== 0) {
      writer.uint32(29).float(message.y);
      writer.uint32(25).double(message.y);
    }
    if (message.username !== "") {
      writer.uint32(34).string(message.username);


@@ 43,25 43,25 @@ export const Player = {
      const tag = reader.uint32();
      switch (tag >>> 3) {
        case 1:
          if (tag != 13) {
          if (tag != 9) {
            break;
          }

          message.rotation = reader.float();
          message.rotation = reader.double();
          continue;
        case 2:
          if (tag != 21) {
          if (tag != 17) {
            break;
          }

          message.x = reader.float();
          message.x = reader.double();
          continue;
        case 3:
          if (tag != 29) {
          if (tag != 25) {
            break;
          }

          message.y = reader.float();
          message.y = reader.double();
          continue;
        case 4:
          if (tag != 34) {

M client/src/protocol/starkingdoms-protocol.ts => client/src/protocol/starkingdoms-protocol.ts +1 -1
@@ 1,4 1,4 @@
// @ts-nocheck
//@ts-nocheck
import * as Long from "long";
import * as _m0 from "protobufjs/minimal";


M client/src/protocol/state.ts => client/src/protocol/state.ts +10 -4
@@ 1,19 1,23 @@
/* eslint-disable */
//@ts-nocheck

export const protobufPackage = "protocol.state";

export enum State {
  Handshake = 0,
  Play = 1,
  UNKNOWN = 0,
  Handshake = 1,
  Play = 2,
  UNRECOGNIZED = -1,
}

export function stateFromJSON(object: any): State {
  switch (object) {
    case 0:
    case "UNKNOWN":
      return State.UNKNOWN;
    case 1:
    case "Handshake":
      return State.Handshake;
    case 1:
    case 2:
    case "Play":
      return State.Play;
    case -1:


@@ 25,6 29,8 @@ export function stateFromJSON(object: any): State {

export function stateToJSON(object: State): string {
  switch (object) {
    case State.UNKNOWN:
      return "UNKNOWN";
    case State.Handshake:
      return "Handshake";
    case State.Play:

A docker/README.md => docker/README.md +1 -0
@@ 0,0 1,1 @@
These files contain essential configuration files used by Ansible to manage and deploy StarKingdoms servers. **DO NOT TOUCH THESE FILES.**
\ No newline at end of file

M protocol/build.rs => protocol/build.rs +1 -0
@@ 10,5 10,6 @@ fn main() {
        .input("src/pbuf/state.proto")
        .input("src/pbuf/goodbye_reason.proto")
        .input("src/pbuf/module.proto")
        .input("src/pbuf/input.proto")
        .run_from_script();
}

M protocol/src/lib.rs => protocol/src/lib.rs +12 -4
@@ 1,12 1,12 @@
use std::error::Error;
use protobuf::{Enum, Message};
use crate::message_c2s::{MessageC2SAuthenticateAndBeamOut, MessageC2SChat, MessageC2SGoodbye, MessageC2SHello, MessageC2SInput, MessageC2SPing};
use crate::message_c2s::{MessageC2SAuthenticateAndBeamOut, MessageC2SChat, MessageC2SGoodbye, MessageC2SHello, MessageC2SInput, MessageC2SMouseInput, MessageC2SPing};
use crate::message_s2c::{MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong, MessageS2CModulesUpdate};
use crate::planet::PlanetType;
use crate::starkingdoms_protocol::PacketWrapper;
include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));

pub const PROTOCOL_VERSION: u32 = 3;
pub const PROTOCOL_VERSION: u32 = 4;

pub mod api;



@@ 17,7 17,8 @@ pub enum MessageC2S {
    Chat(MessageC2SChat),
    Ping(MessageC2SPing),
    Input(MessageC2SInput),
    AuthenticateAndBeamOut(MessageC2SAuthenticateAndBeamOut)
    AuthenticateAndBeamOut(MessageC2SAuthenticateAndBeamOut),
    MouseInput(MessageC2SMouseInput)
}

#[derive(Debug)]


@@ 55,6 56,9 @@ impl TryFrom<&[u8]> for MessageC2S {
            },
            _id if _id == message_c2s::message_c2sauthenticate_and_beam_out::Packet_info::type_.value() as i64 => {
                MessageC2S::AuthenticateAndBeamOut(MessageC2SAuthenticateAndBeamOut::parse_from_bytes(&pkt.packet_data)?)
            },
            _id if _id == message_c2s::message_c2smouse_input::Packet_info::type_.value() as i64 => {
                MessageC2S::MouseInput(MessageC2SMouseInput::parse_from_bytes(&pkt.packet_data)?)
            }
            _id => { return Err(format!("Unrecognized C2S packet {}", _id).into()); }
        };


@@ 85,6 89,9 @@ impl TryInto<Vec<u8>> for MessageC2S {
            },
            MessageC2S::AuthenticateAndBeamOut(p) => {
                (message_c2s::message_c2sauthenticate_and_beam_out::Packet_info::type_.value(), p.write_to_bytes()?)
            },
            MessageC2S::MouseInput(p) => {
                (message_c2s::message_c2smouse_input::Packet_info::type_.value(), p.write_to_bytes()?)
            }
        };



@@ 175,7 182,8 @@ impl planet::PlanetType {
    pub fn as_texture_id(&self) -> String {
        match self {
            PlanetType::Earth => "earth".to_string(),
            PlanetType::Moon => "moon".to_string()
            PlanetType::Moon => "moon".to_string(),
            PlanetType::UNKNOWN => "missing".to_string()
        }
    }
}

M protocol/src/pbuf/goodbye_reason.proto => protocol/src/pbuf/goodbye_reason.proto +7 -6
@@ 2,10 2,11 @@ syntax = "proto3";
package protocol.goodbye_reason;

enum GoodbyeReason {
  UnsupportedProtocol = 0;
  UnexpectedPacket = 1;
  UnexpectedNextState = 2;
  UsernameTaken = 3;
  PingPongTimeout = 4;
  Done = 5;
  UNKNOWN = 0;
  UnsupportedProtocol = 1;
  UnexpectedPacket = 2;
  UnexpectedNextState = 3;
  UsernameTaken = 4;
  PingPongTimeout = 5;
  Done = 6;
}
\ No newline at end of file

A protocol/src/pbuf/input.proto => protocol/src/pbuf/input.proto +9 -0
@@ 0,0 1,9 @@
syntax = "proto3";
package protocol.input;

enum InputType {
  UNKNOWN = 0;
  Left = 1;
  Middle = 2;
  Right = 3;
}
\ No newline at end of file

M protocol/src/pbuf/message_c2s.proto => protocol/src/pbuf/message_c2s.proto +12 -0
@@ 3,6 3,7 @@ package protocol.message_c2s;

import "state.proto";
import "goodbye_reason.proto";
import "input.proto";

message MessageC2SHello {
  enum packet_info { unknown = 0; type = 0x01; }


@@ 38,6 39,8 @@ message MessageC2SInput {
  bool down_pressed = 2;
  bool left_pressed = 3;
  bool right_pressed = 4;


}

message MessageC2SAuthenticateAndBeamOut {


@@ 45,4 48,13 @@ message MessageC2SAuthenticateAndBeamOut {

  string user_id = 1; // The user ID that the client is authenticating as
  string token = 2;   // The token from the authentication server that the user is authenticating as
}

message MessageC2SMouseInput {
  enum packet_info { unknown = 0; type = 0x0d; }

  double worldpos_x = 1;
  double worldpos_y = 2;
  protocol.input.InputType button = 3;
  bool released = 4;
}
\ No newline at end of file

M protocol/src/pbuf/module.proto => protocol/src/pbuf/module.proto +7 -6
@@ 3,13 3,14 @@ package protocol.module;

message Module {
    ModuleType module_type = 1;
    float rotation = 2;
    float x = 3;
    float y = 4;
    double rotation = 2;
    double x = 3;
    double y = 4;
}

enum ModuleType {
    Cargo = 0;
    LandingThruster = 1;
    Hub = 2;
    UNKNOWN = 0;
    Cargo = 1;
    LandingThruster = 2;
    Hub = 3;
}

M protocol/src/pbuf/planet.proto => protocol/src/pbuf/planet.proto +6 -5
@@ 3,12 3,13 @@ package protocol.planet;

message Planet {
  PlanetType planet_type = 1;  // Type of the planet
  float x = 2;          // Translation on the X axis, in game units
  float y = 3;          // Translation on the Y axis, in game units
  float radius = 4;     // The radius of the planet extending out from (x, y)
  double x = 2;          // Translation on the X axis, in game units
  double y = 3;          // Translation on the Y axis, in game units
  double radius = 4;     // The radius of the planet extending out from (x, y)
}

enum PlanetType {
  Earth = 0;
  Moon = 1;
  UNKNOWN = 0;
  Earth = 1;
  Moon = 2;
}
\ No newline at end of file

M protocol/src/pbuf/player.proto => protocol/src/pbuf/player.proto +3 -3
@@ 2,8 2,8 @@ syntax = "proto3";
package protocol.player;

message Player {
  float rotation = 1;   // The rotation, clockwise, in degrees, of the player
  float x = 2;          // The translation on the X axis, in game units, of the player
  float y = 3;          // The translation on the Y axis, in game units, of the player
  double rotation = 1;   // The rotation, clockwise, in degrees, of the player
  double x = 2;          // The translation on the X axis, in game units, of the player
  double y = 3;          // The translation on the Y axis, in game units, of the player
  string username = 4;  // The username of the player
}
\ No newline at end of file

M protocol/src/pbuf/starkingdoms-protocol.proto => protocol/src/pbuf/starkingdoms-protocol.proto +1 -0
@@ 7,6 7,7 @@ import public "goodbye_reason.proto";
import public "message_s2c.proto";
import public "player.proto";
import public "planet.proto";
import public "input.proto";

message PacketWrapper {
  int64 packet_id = 1;    // What is the Packet ID of this packet?

M protocol/src/pbuf/state.proto => protocol/src/pbuf/state.proto +3 -2
@@ 2,6 2,7 @@ syntax = "proto3";
package protocol.state;

enum State {
  Handshake = 0;
  Play = 1;
  UNKNOWN = 0;
  Handshake = 1;
  Play = 2;
}
\ No newline at end of file

M server/src/entity.rs => server/src/entity.rs +11 -17
@@ 58,12 58,11 @@ impl EntityHandler {
        players
    }
    pub fn get_player_from_id(&self, id: EntityId) -> Option<Player> {
        if let Some(entity) = self.entities.get(&id) {
            if let Entity::Player(player) = entity {
                return Some(player.clone());
            }
        if let Some(Entity::Player(player)) = self.entities.get(&id) {
            Some(player.clone())
        } else {
            None
        }
        None
    }
    pub fn get_player_id(&self, addr: SocketAddr) -> Option<EntityId> {
        for (id, entity) in self.entities.iter() {


@@ 106,10 105,8 @@ impl EntityHandler {
        module_count
    }
    pub fn get_module_from_id(&self, id: EntityId) -> Option<Module> {
        if let Some(entity) = self.entities.get(&id) {
            if let Entity::Module(module) = entity {
                return Some(module.clone());
            }
        if let Some(Entity::Module(module)) = self.entities.get(&id) {
            return Some(module.clone());
        }
        None
    }


@@ 133,10 130,8 @@ impl EntityHandler {
        modules
    }
    pub fn get_attached_from_id(&self, id: EntityId) -> Option<AttachedModule> {
        if let Some(entity) = self.entities.get(&id) {
            if let Entity::AttachedModule(module) = entity {
                return Some(module.clone());
            }
        if let Some(Entity::AttachedModule(module)) = self.entities.get(&id) {
            return Some(module.clone());
        }
        None
    }


@@ 156,12 151,11 @@ impl EntityHandler {
        let mut planets = vec![];

        for planet in self.get_planets() {
            // TODO: Adjust codegen to use f64
            planets.push(starkingdoms_protocol::planet::Planet {
                planet_type: planet.planet_type.into(),
                x: (planet.position.0 * SCALE) as f32,
                y: (planet.position.1 * SCALE) as f32,
                radius: planet.radius as f32, // DO NOT * SCALE
                x: planet.position.0 * SCALE,
                y: planet.position.1 * SCALE,
                radius: planet.radius, // DO NOT * SCALE. THIS VALUE IS NOT SCALED!
                special_fields: Default::default(),
            });
        }

M server/src/handler.rs => server/src/handler.rs +4 -0
@@ 90,6 90,7 @@ pub async fn handle_client(mgr: ClientManager, entities: Arc<RwLock<EntityHandle

        if let Some(pkt) = recv!(client_rx)? {
            match state {
                State::UNKNOWN => unreachable!(),
                State::Handshake => {
                    match pkt {
                        MessageC2S::Hello(pkt) => {


@@ 298,6 299,9 @@ pub async fn handle_client(mgr: ClientManager, entities: Arc<RwLock<EntityHandle
                                    error!("[{}] error beaming out: {}", remote_addr, e);
                                }
                            }
                        },
                        MessageC2S::MouseInput(p) => {
                            debug!("[{}] player input: {:?}", remote_addr, p);
                        }
                    }
                }

M server/src/manager.rs => server/src/manager.rs +11 -16
@@ 1,5 1,4 @@
use std::collections::HashMap;
use std::f64::consts::PI;
use std::net::SocketAddr;
use std::sync::Arc;
use nalgebra::point;


@@ 39,11 38,9 @@ impl Player {
    }
    pub fn search_modules(&self, entities: &EntityHandler) -> Vec<AttachedModule> {
        let mut modules = Vec::new();
        for child in &self.children {
            if let Some(attachment) = child {
                if let Entity::AttachedModule(child_module) = entities.entities.get(&attachment.child).unwrap() {
                    modules.append(&mut child_module.search_modules(entities));
                }
        for attachment in self.children.iter().flatten() {
            if let Entity::AttachedModule(child_module) = entities.entities.get(&attachment.child).unwrap() {
                modules.append(&mut child_module.search_modules(entities));
            }
        }
        modules


@@ 79,7 76,7 @@ impl AttachedModule {

        let loose_id = entities.get_from_module(&module).expect("loose module does not exist");
        let loose_body = data.rigid_body_set.get(module.handle).expect("loose module does not exist");
        let mut parent_entity = entity_map.get_mut(&parent).expect("parent id does not exist");
        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


@@ 91,8 88,8 @@ impl AttachedModule {
                panic!("unexpected parent");
            }
        };
        let parent_body = data.rigid_body_set
            .get(parent_handle).unwrap();
        //let parent_body = data.rigid_body_set
        //    .get(parent_handle).unwrap();
        // create attachment module
        let module_collider = ColliderBuilder::cuboid(25.0 / SCALE, 25.0 / SCALE)
            .mass_properties(loose_body.mass_properties().local_mprops)


@@ 147,7 144,7 @@ impl AttachedModule {

        //let loose_id = entities.get_from_module(&module).expect("loose module does not exist");
        //let loose_body = data.rigid_body_set.get(module.handle).expect("loose module does not exist");
        let mut parent_entity = entity_map.get_mut(&parent).expect("parent id does not exist");
        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


@@ 214,14 211,12 @@ impl AttachedModule {
            lifetime: 10.,
        }
    }

    pub fn search_modules(&self, entities: &EntityHandler) -> Vec<AttachedModule> {
        let mut modules = Vec::new();
        for child in &self.children {
            if let Some(attachment) = child {
                let child_module = entities.entities.get(&attachment.child).unwrap();
                if let Entity::AttachedModule(child_module) = entities.entities.get(&attachment.child).unwrap() {
                    modules.append(&mut child_module.search_modules(entities));
                }
        for attachment in self.children.iter().flatten() {
            if let Entity::AttachedModule(child_module) = entities.entities.get(&attachment.child).unwrap() {
                modules.append(&mut child_module.search_modules(entities));
            }
        }
        modules

M server/src/planet.rs => server/src/planet.rs +3 -3
@@ 111,9 111,9 @@ impl Planets {
            // TODO: Adjust codegen to use f64
            planets.push(starkingdoms_protocol::planet::Planet {
                planet_type: planet.planet_type.into(),
                x: (planet.position.0 * SCALE) as f32,
                y: (planet.position.1 * SCALE) as f32,
                radius: planet.radius as f32, // DO NOT * SCALE
                x: planet.position.0 * SCALE,
                y: planet.position.1 * SCALE,
                radius: planet.radius, // DO NOT * SCALE - THIS VALUE IS NOT SCALED!
                special_fields: Default::default(),
            });
        }

M server/src/timer.rs => server/src/timer.rs +9 -9
@@ 1,5 1,5 @@
use std::{time::Duration, sync::Arc, f64::consts::PI};
use log::{debug, warn, info};
use log::{warn, info};
use nalgebra::{vector, point};
use rand::Rng;
use rapier2d_f64::prelude::{PhysicsPipeline, ColliderBuilder, RigidBodyBuilder, MassProperties, RigidBodyHandle};


@@ 97,7 97,7 @@ pub async fn timer_main(mgr: ClientManager, physics_data_orig: Arc<RwLock<Physic
                entities.write().await.entities.insert(get_entity_id(), Entity::Module(module));
            }
            let mut entities = entities.write().await;
            for mut module in entities.get_modules().iter_mut() {
            for module in entities.get_modules().iter_mut() {
                let module_handle = module.handle;
                let module_body = physics_data.rigid_body_set.get_mut(module_handle).unwrap();
                module_body.reset_forces(true);


@@ 222,9 222,9 @@ pub async fn timer_main(mgr: ClientManager, physics_data_orig: Arc<RwLock<Physic

                // TODO: Figure out how to adjust codegen to use f64
                protocol_players.push(Player {
                    rotation: rotation as f32,
                    x: (translation.x * SCALE) as f32,
                    y: (translation.y * SCALE) as f32,
                    rotation,
                    x: (translation.x * SCALE),
                    y: (translation.y * SCALE),
                    username,
                    special_fields: Default::default(),
                });


@@ 253,7 253,7 @@ pub async fn timer_main(mgr: ClientManager, physics_data_orig: Arc<RwLock<Physic
                    modules.append(&mut attached_modules.iter().map(|m| {
                        let module = m.to_module();
                        info!("{:?}", module);
                        return module;
                        module
                    }).collect());
                    modules.iter().for_each(|module| {
                        if attached_handles.contains(&module.handle) {


@@ 265,9 265,9 @@ pub async fn timer_main(mgr: ClientManager, physics_data_orig: Arc<RwLock<Physic
                            let body = physics_data.rigid_body_set.get(module.handle).unwrap();
                            return starkingdoms_protocol::module::Module {
                                module_type: module.module_type.into(),
                                rotation: body.rotation().angle() as f32,
                                x: (body.translation().x * SCALE) as f32,
                                y: (body.translation().y * SCALE) as f32,
                                rotation: body.rotation().angle(),
                                x: body.translation().x * SCALE,
                                y: body.translation().y * SCALE,
                                special_fields: Default::default(),
                            };
                        }).collect();

M spacetime => spacetime +5 -0
@@ 47,6 47,7 @@ sub_help() {
  echo "    build_docker_web_stable - Build the web dockerfile and push it as web-stable" # done
  echo "    build_docker_stable - Build the stable api, web and server containers" # done
  echo "    infra [action] - Run an infrastructure command. Requires an infrastructure key" # done
  echo "    client_protobuf - Rebuild the client protocol bindings" # done
}

check_install_cargo() {


@@ 95,6 96,10 @@ sub_run_http() {
  cd client && yarn && yarn run dev
}

sub_client_protobuf() {
  cd client && yarn && yarn protobuf
}

sub_build_server() {
  check_all
  exec_spacetime server dev "$SCRIPT_DIR" "$SERVER_MODS"