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