diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/init.moon | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/server/init.moon b/src/server/init.moon new file mode 100644 index 0000000..9c2c22f --- /dev/null +++ b/src/server/init.moon @@ -0,0 +1,143 @@ + +ecs = require("ecs") +log = require("log") +world = require("world") +net = require("net") +NetworkedComponent = require("ecs.networked") +PredictedComponent = require("ecs.predicted") +player_movement = require("shared.player_movement") + +x = {} + +x.initialize = () -> + world.domain = "server" + if not world.hub + log.error("Running server init, but no world hub has been created",{"server"}) + print("World was:",world) + error("World.hub has not been set") + + log.info("Server initalized",{"server"}) + world.level_sync.name = "levels.lobby" + + pawns = {} -- peerid to entity lookup + net.register_message("RequestLevel",{}) + world.hub\listen("RequestLevel", "RespondLevel", (from_client, data) -> + log.info("Got reqeust for level info" .. tostring(from_client), {"net","server"}) + world.hub\send(from_client, "RespondLevel",{ + name: world.level_sync.name + data: world.level_sync.data + }) + ) + net.register_message("RequestPeers",{}) + world.hub\listen("RequestPeers", "RespondPeers", (from_client, data) -> + log.info("Got request for player info" .. tostring(from_client), {"net","server"}) + players = {} + for peerid, ent in pairs(world.level_sync.peers) + players[peerid] = ent\get("net")\pack! + log.info("Got data for player" .. peerid .. ":" .. players[peerid], {"net","server"}) + world.hub\send(from_client, "RespondPeers", players) + ) + net.register_message("RequestEntities",{}) + world\check! + world.hub\listen("RequestEntities", "RespondEntities", (from_client, data) -> + log.info("Got request for entities from " .. tostring(from_client), {"net","server"}) + log.info("Responding with:" .. tostring(world.level_sync.ents), {"net","server"}) + log.info("At request for entities, level is " .. tostring(world.level_sync.name), {"net","server"}) + if world.level_sync.name == "levels.game" + return -- Don't sync here, instead send a R + world\check! + -- Simplified way to send entities + nents = {} + for i, entity in pairs(world.level_sync.ents) + ent_net = entity\get("net") + if not ent_net + error("Server entity does not have a net component:" .. tostring(entity)) + if not ent_net.properties.type + error("Failed to find net entity type for " .. tostring(net_ent) .. " net component was: " .. tostring(ent_net.net_properties)) + nents[i] = ent_net\pack! + world.hub\send(from_client, "RespondEntities", nents) + ) + world.hub\listen("Join", "CreatePawn", (from_client, data) -> + assert(world.hub, "Join should only be called on the server") + log.info("Got player joining:" .. tostring(from_client), {"net","server"}) + --pawn = ecs.Entity! + --spawn_loc = assert(world.level_sync.ref\get_spawn_location!, "Failed to find inital spawn location") + --net = NetworkedComponent("net",{ + --type: "player" + --pos: spawn_loc + --ang: 0 + --vel: {0,0,0} + --acc: {0,0,0} + --player_name: "name" + --last_update: am.eval_js("Date.now()") + --peerid: from_client + --}) + --pawn\add(net, "net") + --pred = PredictedComponent("pred",{acc:{0,0,0}, vel: {0,0,0}, pos: {0,0,0}}, "net", player_movement) + --pawn\add(pred, "pred") + --world.level_sync.peers[from_client] = pawn + + --world.hub\broadcast("CreatePawn", net\pack!) + + -- Surface Join events to the browser for integration tests. + -- Guarded so it is a no-op in non-HTML environments. + if am and am.eval_js and am.to_json + js = string.format("window._hubJoinReceived = true; window._hubJoinData = %s;", am.to_json(data or {})) + am.eval_js(js) + ) + require("levels.lobby") + lobby = ecs.Entity! + lobby\add(ecs.NetworkedComponent("lobby_peer",{ + type: "level", + level_name: world.level_sync.name + level_data: {world.hub.peer.id} + }), "net") + world.level_sync.ref = { + id: "level from server/init.moon" + get_spawn_location: () -> + {0,0,0} + } + net.register_message("SuggestPlayerUpdate",{ + optional: { + pos: "table" -- x, y, z + ang: "number" -- 0->360 + vel: "table" -- x, y, z + acc: "table" -- x, y, z + player_name: "string" + last_update: "number" + } + }) + world.hub\listen("SuggestPlayerUpdate","UpdateName",(from_client, data) -> + log.debug("Got player update from " .. from_client .. ":" .. tostring(data), {"net","server","player"}) + net = world.level_sync.peers[from_client]\get("net") + if not net + error("Got message from client" .. tostring(from_client) .. " but no such client exists!") + if data.player_name + net.properties.player_name = data.player_name + if data.pos + net.properties.pos = data.pos + if data.vel + net.properties.vel = data.vel + if data.last_update + net.properties.last_update = data.last_update + if data.acc + for i = 1,3 + if not (data.acc[i] and type(data.acc[i] == "number")) + log.warn("Peer " .. from_client .. " sent bad acceleration", {"net","player"}) + return + v = vec3(data.acc[1], data.acc[2], data.acc[3]) + if math.length(v) > 1 + log.warn("Peer " .. from_client .. " sent too much acceleration: " .. tostring(math.length(v)),{"net","player"}) + return + net.properties.acc = data.acc + ) + world.hub\listen("RequestRole","Request role", (clientid, _) -> + client_data = world.level_sync.client_data + log.info("Responding with role:" .. tostring(client_data[clientid]), {"net","server"}) + world.hub\send(clientid, "RespondRole", client_data[clientid]) + ) + + + world.domain = "client" + +x |
