From 42475c9b38ce1e06fb55822ffef3615440d12bb6 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sat, 1 Mar 2014 13:47:42 +0100 Subject: [PATCH 1/4] nc.ns --- app/Lib/Utilities/NotificationCenter.js | 68 +++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/app/Lib/Utilities/NotificationCenter.js b/app/Lib/Utilities/NotificationCenter.js index 7c8b6db..6448de7 100755 --- a/app/Lib/Utilities/NotificationCenter.js +++ b/app/Lib/Utilities/NotificationCenter.js @@ -6,6 +6,74 @@ function () { function NotificationCenter () { this.topics = {}; this.subUid = -1; +/* + var i = 0; + this.nc = { + client: { + view: { + mesh: { + create: i++, + add: i++, + remove: i++, + update: i++ + }, + playerInfo: { + createAndAdd: i++, + remove: i++, + update: i++ + }, + preloadBar: { + update: i++ + }, + fullScreen: { + change: i++ + }, + debugMode: { + toggle: i++ + }, + gameInfo: { + toggle: i++ + } + events: { + ready: i++ + } + }, + input: { + handAction: { + request: i++ + }, + xy: { + change: i++ + } + }, + server: { + gameCommand: { + send: i++ + } + } + }, + core: { + game: { + gameObject: { + add: i++, + remove: i++ + } + events: { + level: { + loaded: i++ + } + } + } + }, + server: { + pipeToLobby: function(v) { return v + "-ns.server.pipeToLobby")} + }, + lobby: { + + } + + }; + */ } NotificationCenter.prototype.trigger = function (topic /*, arguments*/) { From d83376d5c73e8338f5686536f0cc94ff3d1c895b Mon Sep 17 00:00:00 2001 From: Jeena Date: Sat, 1 Mar 2014 14:07:03 +0100 Subject: [PATCH 2/4] refactored Server and Lobby --- app/Bootstrap/HttpServer.js | 2 +- app/Game/{Server => Channel}/Channel.js | 8 ++++---- app/Game/{Server => Channel}/Collision/Detector.js | 0 .../{Server => Channel}/Control/PlayerController.js | 0 app/Game/{Server => Channel}/GameController.js | 12 ++++++------ app/Game/{Server => Channel}/GameObjects/Doll.js | 2 +- .../{Server => Channel}/GameObjects/GameObject.js | 0 app/Game/{Server => Channel}/GameObjects/Item.js | 0 .../{Server => Channel}/GameObjects/Items/RagDoll.js | 0 .../GameObjects/Items/Skateboard.js | 0 .../{Server => Channel}/GameObjects/SpectatorDoll.js | 0 app/Game/{Server => Channel}/GameObjects/Tile.js | 0 app/Game/{Server => Channel}/Loader/Level.js | 0 app/Game/{Server => Channel}/Loader/TiledLevel.js | 0 app/Game/{Server => Channel}/Physics/Engine.js | 0 .../PipeToLobby.js => Channel/PipeToServer.js} | 10 +++++----- app/Game/{Server => Channel}/Player.js | 0 app/Game/{Server => Channel}/User.js | 0 app/Lib/Utilities/Extensions.js | 2 +- app/Lib/Utilities/NotificationCenter.js | 2 +- app/{Lobby => Server}/Api.js | 0 app/{Lobby => Server}/Coordinator.js | 6 +++--- app/{Lobby => Server}/PipeToChannel.js | 0 app/{Lobby => Server}/User.js | 0 channel.js | 10 +++++----- server.js | 4 ++-- 26 files changed, 29 insertions(+), 29 deletions(-) rename app/Game/{Server => Channel}/Channel.js (95%) rename app/Game/{Server => Channel}/Collision/Detector.js (100%) rename app/Game/{Server => Channel}/Control/PlayerController.js (100%) rename app/Game/{Server => Channel}/GameController.js (96%) rename app/Game/{Server => Channel}/GameObjects/Doll.js (98%) rename app/Game/{Server => Channel}/GameObjects/GameObject.js (100%) rename app/Game/{Server => Channel}/GameObjects/Item.js (100%) rename app/Game/{Server => Channel}/GameObjects/Items/RagDoll.js (100%) rename app/Game/{Server => Channel}/GameObjects/Items/Skateboard.js (100%) rename app/Game/{Server => Channel}/GameObjects/SpectatorDoll.js (100%) rename app/Game/{Server => Channel}/GameObjects/Tile.js (100%) rename app/Game/{Server => Channel}/Loader/Level.js (100%) rename app/Game/{Server => Channel}/Loader/TiledLevel.js (100%) rename app/Game/{Server => Channel}/Physics/Engine.js (100%) rename app/Game/{Server/PipeToLobby.js => Channel/PipeToServer.js} (77%) rename app/Game/{Server => Channel}/Player.js (100%) rename app/Game/{Server => Channel}/User.js (100%) rename app/{Lobby => Server}/Api.js (100%) rename app/{Lobby => Server}/Coordinator.js (97%) rename app/{Lobby => Server}/PipeToChannel.js (100%) rename app/{Lobby => Server}/User.js (100%) diff --git a/app/Bootstrap/HttpServer.js b/app/Bootstrap/HttpServer.js index e333b45..b2a7183 100755 --- a/app/Bootstrap/HttpServer.js +++ b/app/Bootstrap/HttpServer.js @@ -1,7 +1,7 @@ define([ 'http', 'node-static', - 'Lobby/Api' + 'Server/Api' ], function (http, nodeStatic, Api) { diff --git a/app/Game/Server/Channel.js b/app/Game/Channel/Channel.js similarity index 95% rename from app/Game/Server/Channel.js rename to app/Game/Channel/Channel.js index a422c26..28bb2f2 100755 --- a/app/Game/Server/Channel.js +++ b/app/Game/Channel/Channel.js @@ -1,7 +1,7 @@ define([ - "Game/Server/GameController", + "Game/Channel/GameController", "Lib/Utilities/NotificationCenter", - "Game/Server/User", + "Game/Channel/User", "Lib/Utilities/Protocol/Helper", "Lib/Utilities/Options", "Game/Config/Settings" @@ -9,7 +9,7 @@ function (GameController, Nc, User, ProtocolHelper, Options, Settings) { - function Channel (pipeToLobby, name, options) { + function Channel (pipeToServer, name, options) { var self = this; @@ -20,7 +20,7 @@ this.name = name; this.users = {}; - this.pipeToLobby = pipeToLobby; + this.pipeToServer = pipeToServer; this.gameController = new GameController(this); diff --git a/app/Game/Server/Collision/Detector.js b/app/Game/Channel/Collision/Detector.js similarity index 100% rename from app/Game/Server/Collision/Detector.js rename to app/Game/Channel/Collision/Detector.js diff --git a/app/Game/Server/Control/PlayerController.js b/app/Game/Channel/Control/PlayerController.js similarity index 100% rename from app/Game/Server/Control/PlayerController.js rename to app/Game/Channel/Control/PlayerController.js diff --git a/app/Game/Server/GameController.js b/app/Game/Channel/GameController.js similarity index 96% rename from app/Game/Server/GameController.js rename to app/Game/Channel/GameController.js index c40ef36..e447fae 100755 --- a/app/Game/Server/GameController.js +++ b/app/Game/Channel/GameController.js @@ -1,15 +1,15 @@ define([ "Game/Core/GameController", - "Game/Server/Physics/Engine", + "Game/Channel/Physics/Engine", "Game/Config/Settings", - "Game/Server/Control/PlayerController", + "Game/Channel/Control/PlayerController", "Lib/Utilities/RequestAnimFrame", "Lib/Utilities/NotificationCenter", "Lib/Vendor/Box2D", - "Game/Server/Player", - "Game/Server/GameObjects/GameObject", - "Game/Server/GameObjects/Doll", - "Game/Server/GameObjects/Items/RagDoll" + "Game/Channel/Player", + "Game/Channel/GameObjects/GameObject", + "Game/Channel/GameObjects/Doll", + "Game/Channel/GameObjects/Items/RagDoll" ], function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, Nc, Box2D, Player, GameObject, Doll, RagDoll) { diff --git a/app/Game/Server/GameObjects/Doll.js b/app/Game/Channel/GameObjects/Doll.js similarity index 98% rename from app/Game/Server/GameObjects/Doll.js rename to app/Game/Channel/GameObjects/Doll.js index 4d2738d..8349094 100755 --- a/app/Game/Server/GameObjects/Doll.js +++ b/app/Game/Channel/GameObjects/Doll.js @@ -1,6 +1,6 @@ define([ "Game/Core/GameObjects/Doll", - "Game/Server/GameObjects/Item", + "Game/Channel/GameObjects/Item", "Lib/Vendor/Box2D", "Lib/Utilities/NotificationCenter" ], diff --git a/app/Game/Server/GameObjects/GameObject.js b/app/Game/Channel/GameObjects/GameObject.js similarity index 100% rename from app/Game/Server/GameObjects/GameObject.js rename to app/Game/Channel/GameObjects/GameObject.js diff --git a/app/Game/Server/GameObjects/Item.js b/app/Game/Channel/GameObjects/Item.js similarity index 100% rename from app/Game/Server/GameObjects/Item.js rename to app/Game/Channel/GameObjects/Item.js diff --git a/app/Game/Server/GameObjects/Items/RagDoll.js b/app/Game/Channel/GameObjects/Items/RagDoll.js similarity index 100% rename from app/Game/Server/GameObjects/Items/RagDoll.js rename to app/Game/Channel/GameObjects/Items/RagDoll.js diff --git a/app/Game/Server/GameObjects/Items/Skateboard.js b/app/Game/Channel/GameObjects/Items/Skateboard.js similarity index 100% rename from app/Game/Server/GameObjects/Items/Skateboard.js rename to app/Game/Channel/GameObjects/Items/Skateboard.js diff --git a/app/Game/Server/GameObjects/SpectatorDoll.js b/app/Game/Channel/GameObjects/SpectatorDoll.js similarity index 100% rename from app/Game/Server/GameObjects/SpectatorDoll.js rename to app/Game/Channel/GameObjects/SpectatorDoll.js diff --git a/app/Game/Server/GameObjects/Tile.js b/app/Game/Channel/GameObjects/Tile.js similarity index 100% rename from app/Game/Server/GameObjects/Tile.js rename to app/Game/Channel/GameObjects/Tile.js diff --git a/app/Game/Server/Loader/Level.js b/app/Game/Channel/Loader/Level.js similarity index 100% rename from app/Game/Server/Loader/Level.js rename to app/Game/Channel/Loader/Level.js diff --git a/app/Game/Server/Loader/TiledLevel.js b/app/Game/Channel/Loader/TiledLevel.js similarity index 100% rename from app/Game/Server/Loader/TiledLevel.js rename to app/Game/Channel/Loader/TiledLevel.js diff --git a/app/Game/Server/Physics/Engine.js b/app/Game/Channel/Physics/Engine.js similarity index 100% rename from app/Game/Server/Physics/Engine.js rename to app/Game/Channel/Physics/Engine.js diff --git a/app/Game/Server/PipeToLobby.js b/app/Game/Channel/PipeToServer.js similarity index 77% rename from app/Game/Server/PipeToLobby.js rename to app/Game/Channel/PipeToServer.js index 33dc741..396ff55 100755 --- a/app/Game/Server/PipeToLobby.js +++ b/app/Game/Channel/PipeToServer.js @@ -1,11 +1,11 @@ define([ "Lib/Utilities/NotificationCenter", - "Game/Server/Channel" + "Game/Channel/Channel" ], function (Nc, Channel) { - function PipeToLobby (process) { + function PipeToServer (process) { var self = this; @@ -28,7 +28,7 @@ function (Nc, Channel) { }); } - PipeToLobby.prototype.send = function (recipient, data) { + PipeToServer.prototype.send = function (recipient, data) { var message = { recipient: recipient, data: data @@ -37,10 +37,10 @@ function (Nc, Channel) { this.process.send(message); }; - PipeToLobby.prototype.onMessage = function (message) { + PipeToServer.prototype.onMessage = function (message) { Nc.trigger(message.recipient + '/controlCommand', message); } - return PipeToLobby; + return PipeToServer; }); \ No newline at end of file diff --git a/app/Game/Server/Player.js b/app/Game/Channel/Player.js similarity index 100% rename from app/Game/Server/Player.js rename to app/Game/Channel/Player.js diff --git a/app/Game/Server/User.js b/app/Game/Channel/User.js similarity index 100% rename from app/Game/Server/User.js rename to app/Game/Channel/User.js diff --git a/app/Lib/Utilities/Extensions.js b/app/Lib/Utilities/Extensions.js index 6af99e1..1f9c032 100755 --- a/app/Lib/Utilities/Extensions.js +++ b/app/Lib/Utilities/Extensions.js @@ -8,7 +8,7 @@ function() { return f + this.substr(1); } - if(GLOBALS.context == "Server") { + if(GLOBALS.context == "Channel") { console.checkpoint = function (s) { console.log(' \033[32mbeep - \033[0m' + s); diff --git a/app/Lib/Utilities/NotificationCenter.js b/app/Lib/Utilities/NotificationCenter.js index 6448de7..578cc6a 100755 --- a/app/Lib/Utilities/NotificationCenter.js +++ b/app/Lib/Utilities/NotificationCenter.js @@ -66,7 +66,7 @@ function () { } }, server: { - pipeToLobby: function(v) { return v + "-ns.server.pipeToLobby")} + pipeToServer: function(v) { return v + "-ns.server.pipeToServer")} }, lobby: { diff --git a/app/Lobby/Api.js b/app/Server/Api.js similarity index 100% rename from app/Lobby/Api.js rename to app/Server/Api.js diff --git a/app/Lobby/Coordinator.js b/app/Server/Coordinator.js similarity index 97% rename from app/Lobby/Coordinator.js rename to app/Server/Coordinator.js index b1d2d60..454afae 100755 --- a/app/Lobby/Coordinator.js +++ b/app/Server/Coordinator.js @@ -1,7 +1,7 @@ define([ - "Lobby/User", - "Game/Server/Channel", - "Lobby/PipeToChannel", + "Server/User", + "Game/Channel/Channel", + "Server/PipeToChannel", "Lib/Utilities/NotificationCenter" ], diff --git a/app/Lobby/PipeToChannel.js b/app/Server/PipeToChannel.js similarity index 100% rename from app/Lobby/PipeToChannel.js rename to app/Server/PipeToChannel.js diff --git a/app/Lobby/User.js b/app/Server/User.js similarity index 100% rename from app/Lobby/User.js rename to app/Server/User.js diff --git a/channel.js b/channel.js index 6d397d8..3294623 100755 --- a/channel.js +++ b/channel.js @@ -1,4 +1,4 @@ -GLOBALS = { context: "Server" }; +GLOBALS = { context: "Channel" }; var requirejs = require('requirejs'); requirejs.config({ @@ -10,11 +10,11 @@ requirejs.config({ var inspector = {}; requirejs([ - "Game/Server/PipeToLobby" + "Game/Channel/PipeToServer" ], -function (PipeToLobby) { - var PipeToLobby = new PipeToLobby(process); +function (PipeToServer) { + var PipeToServer = new PipeToServer(process); - inspector.PipeToLobby = PipeToLobby; + inspector.PipeToServer = PipeToServer; }); \ No newline at end of file diff --git a/server.js b/server.js index 21dd3ef..9d829aa 100755 --- a/server.js +++ b/server.js @@ -1,4 +1,4 @@ -GLOBALS = { context: "Server" }; +GLOBALS = { context: "Channel" }; var requirejs = require('requirejs'); var inspector; @@ -23,7 +23,7 @@ var options = { requirejs([ "Bootstrap/HttpServer", "Bootstrap/Socket", - "Lobby/Coordinator" + "Server/Coordinator" ], function (HttpServer, Socket, Coordinator) { From 810a74a28b7ab1a777765e7e224cfd26f31290c9 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sat, 1 Mar 2014 23:11:36 +0100 Subject: [PATCH 3/4] fixed #58 --- .gitignore | 1 - app/Game/Channel/Channel.js | 31 ++- app/Game/Channel/GameController.js | 2 +- app/Game/Channel/PipeToServer.js | 8 +- app/Game/Client/Networker.js | 18 +- app/Game/Config/Settings.js | 1 + app/Game/Core/GameController.js | 10 +- app/Lib/Utilities/NotificationCenter.js | 7 +- app/Server/Api.js | 89 ++++--- app/Server/Coordinator.js | 112 +++------ app/Server/PipeToChannel.js | 16 +- app/Server/User.js | 135 ++++++----- static/html/index.html | 296 ++++++++++++++++++------ 13 files changed, 445 insertions(+), 281 deletions(-) mode change 100755 => 100644 app/Server/Coordinator.js mode change 100755 => 100644 app/Server/User.js diff --git a/.gitignore b/.gitignore index 5deab03..16c263b 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ node_modules/ *.log .DS_Store -pixi.js/ lab/audio/ diff --git a/app/Game/Channel/Channel.js b/app/Game/Channel/Channel.js index 28bb2f2..7344a25 100755 --- a/app/Game/Channel/Channel.js +++ b/app/Game/Channel/Channel.js @@ -9,7 +9,7 @@ function (GameController, Nc, User, ProtocolHelper, Options, Settings) { - function Channel (pipeToServer, name, options) { + function Channel (pipeToServer, options) { var self = this; @@ -17,7 +17,7 @@ levelUids: Settings.DEFAULT_LEVELS }); - this.name = name; + this.name = options.channelName; this.users = {}; this.pipeToServer = pipeToServer; @@ -34,11 +34,13 @@ Nc.on('broadcastGameCommand', this.broadcastGameCommand, this); Nc.on('broadcastGameCommandExcept', this.broadcastGameCommandExcept, this); - console.checkpoint('channel ' + name + ' created'); - } + console.checkpoint('channel ' + this.name + ' created'); - Channel.validateName = function (name) { - return true; + setTimeout(function() { + if(Object.keys(self.users).length < 1) { + self.destroy(); + } + }, Settings.CHANNEL_DESTRUCTION_TIME * 1000); } @@ -81,11 +83,22 @@ Channel.prototype.onReleaseUser = function (userId) { var user = this.users[userId]; - this.broadcastControlCommandExcept("userLeft", user.id, user); - Nc.trigger('user/left', user); - delete this.users[user.id]; + Nc.trigger('user/left', userId); + delete this.users[userId]; + + this.broadcastControlCommand("userLeft", userId); + + // FIXME: if this was the last user terminate forked process + if(Object.keys(this.users).length < 1) { + this.destroy(); + } } + Channel.prototype.destroy = function() { + console.checkpoint("channel (" + this.name + ") destroyed"); + this.pipeToServer.destroy(); + }; + // Sending commands diff --git a/app/Game/Channel/GameController.js b/app/Game/Channel/GameController.js index e447fae..f7fdc6b 100755 --- a/app/Game/Channel/GameController.js +++ b/app/Game/Channel/GameController.js @@ -21,7 +21,7 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N Parent.call(this); Nc.on('user/joined', this.onUserJoined, this); - Nc.on('user/left', this.onUserLeft, this); // FIXME: refactor this.userLeft -> this.onUserLeft, even in core and client + Nc.on('user/left', this.onUserLeft, this); Nc.on('user/resetLevel', this.onResetLevel, this); Nc.on('user/clientReady', this.onClientReady, this); Nc.on('player/killed', this.onPlayerKilled, this); diff --git a/app/Game/Channel/PipeToServer.js b/app/Game/Channel/PipeToServer.js index 396ff55..113ceca 100755 --- a/app/Game/Channel/PipeToServer.js +++ b/app/Game/Channel/PipeToServer.js @@ -17,10 +17,9 @@ function (Nc, Channel) { process.on('message', function (message, handle) { if(message.data.hasOwnProperty('CREATE')) { - self.channel = new Channel(this, message.data['CREATE']); + self.channel = new Channel(self, message.data.options); } else if (message.data.hasOwnProperty('KILL')) { self.channel.destroy(); - process.exit(0); } else { self.onMessage(message); } @@ -41,6 +40,11 @@ function (Nc, Channel) { Nc.trigger(message.recipient + '/controlCommand', message); } + PipeToServer.prototype.destroy = function() { + this.send('coordinator', {destroy:this.channel.name}); + this.process.exit(0); + }; + return PipeToServer; }); \ No newline at end of file diff --git a/app/Game/Client/Networker.js b/app/Game/Client/Networker.js index bc665ca..258a618 100755 --- a/app/Game/Client/Networker.js +++ b/app/Game/Client/Networker.js @@ -20,7 +20,8 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { var self = this; this.socketLink.on('message', function (message) { - if(Settings.NETWORK_LOG_INCOMING) { + var m = JSON.parse(message) + if(Settings.NETWORK_LOG_INCOMING && !m.gameCommand) { console.log('INCOMING', message); } ProtocolHelper.applyCommand(message, self); @@ -35,8 +36,13 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { Networker.prototype.onConnect = function () { console.log('connected.') var channel = JSON.parse(localStorage["channel"]); + var player = JSON.parse(localStorage["player"]); if(channel.name) { - this.sendCommand('join', channel.name); + var options = { + channelName: channel.name, + nickname: player.nickname + } + this.sendCommand('join', options); } else { window.location.href = "/"; } @@ -67,6 +73,11 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { this.initPing(); } + Networker.prototype.onJoinError = function(options) { + alert(options.message); + window.location.href = "/"; + }; + Networker.prototype.onLevelLoaded = function() { for (var userId in this.users) { this.gameController.createPlayer(this.users[userId]); @@ -116,8 +127,7 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { } Networker.prototype.onUserLeft = function (userId) { - var user = this.users[userId]; - this.gameController.onUserLeft(user); + this.gameController.onUserLeft(userId); delete this.users[userId]; } diff --git a/app/Game/Config/Settings.js b/app/Game/Config/Settings.js index 9cf9fd3..29efe6e 100755 --- a/app/Game/Config/Settings.js +++ b/app/Game/Config/Settings.js @@ -62,6 +62,7 @@ define(function() { // NETWORKING WORLD_UPDATE_BROADCAST_INTERVAL: 70, + CHANNEL_DESTRUCTION_TIME: 30, NETWORK_LOG_INCOMING: false, NETWORK_LOG_OUTGOING: false } diff --git a/app/Game/Core/GameController.js b/app/Game/Core/GameController.js index 499e5a8..820c2e4 100755 --- a/app/Game/Core/GameController.js +++ b/app/Game/Core/GameController.js @@ -79,14 +79,18 @@ function (PhysicsEngine, TiledLevel, Player, Nc) { } */ - GameController.prototype.onUserLeft = function (user) { - var player = this.players[user.id]; + GameController.prototype.onUserLeft = function (userId) { + var player = this.players[userId]; + if(!player) { + console.warn("User (", userId ,") left who has not joined"); + return; + } var i = this.gameObjects.animated.indexOf(player); if(i>=0) this.gameObjects.animated.splice(i, 1); player.destroy(); - delete this.players[user.id]; + delete this.players[userId]; } GameController.prototype.createPlayer = function(user) { diff --git a/app/Lib/Utilities/NotificationCenter.js b/app/Lib/Utilities/NotificationCenter.js index 578cc6a..76d3d3f 100755 --- a/app/Lib/Utilities/NotificationCenter.js +++ b/app/Lib/Utilities/NotificationCenter.js @@ -65,11 +65,8 @@ function () { } } }, - server: { - pipeToServer: function(v) { return v + "-ns.server.pipeToServer")} - }, - lobby: { - + channel: { + pipeToServer: function(v) { return v + "-ns.channel.pipeToServer")} } }; diff --git a/app/Server/Api.js b/app/Server/Api.js index 4efd2ff..846deb5 100644 --- a/app/Server/Api.js +++ b/app/Server/Api.js @@ -5,48 +5,65 @@ define([ function (Nc, ProtocolHelper) { - function Api(coordinator) { - this.coordinator = coordinator; - this.isError = false; - this.output = null; - } + function Api(coordinator) { + this.coordinator = coordinator; + this.isError = false; + this.output = null; + } - Api.prototype.handleCall = function(queryParameters) { + Api.prototype.handleCall = function(queryParameters) { - var command; - try { - var message = JSON.parse(queryParameters); - command = message.command; - } catch(e) { - console.error(e) - } + var command, + output = null; + + try { + var message = JSON.parse(queryParameters); + command = message.command; + } catch(e) { + this.isError = true; + output = "JSON syntax error"; + console.error(e) + } - var output = null; - switch(command) { - case "getChannels": - output = this.coordinator.getChannels(); - break; - default: - this.isError = true; - output = "Command not found"; - break; - } + switch(command) { + case "getChannels": + output = this.coordinator.getChannels(); + break; + case "createChannel": + // FIXME: sanitize input + output = this.createChannel(message.options); + break; + default: + this.isError = true; + output = "Command not found"; + break; + } - this.output = output; - } + this.output = output; + } - Api.prototype.getOutput = function() { - var output = {}; - var key = this.isError ? "error" : "success"; - output[key] = this.output; - return JSON.stringify(output); - - }; + Api.prototype.createChannel = function(options) { + var result = this.coordinator.createChannel(options); + if(result !== false) { + return result; + } else { + this.isError = true; + return "Could not create channel, name might already exist."; + } + }; - Api.prototype.getContentType = function() { - return "application/json"; - }; + Api.prototype.getOutput = function() { + var output = {}; + var key = this.isError ? "error" : "success"; + output[key] = this.output; + return JSON.stringify(output); + + }; + + Api.prototype.getContentType = function() { + return "application/json"; + }; - return Api; + return Api; }); \ No newline at end of file diff --git a/app/Server/Coordinator.js b/app/Server/Coordinator.js old mode 100755 new mode 100644 index 454afae..317534d --- a/app/Server/Coordinator.js +++ b/app/Server/Coordinator.js @@ -2,106 +2,64 @@ define([ "Server/User", "Game/Channel/Channel", "Server/PipeToChannel", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/NotificationCenter", + "Game/Config/Settings" ], -function (User, Channel, PipeToChannel, Nc) { +function (User, Channel, PipeToChannel, Nc, Settings) { - function Coordinator () { - this.channelPipes = {}; - this.lobbyUsers = {}; + function Coordinator() { + this.channelPipes = {}; + + Nc.on('coordinator/message', this.onMessage, this); console.checkpoint('create Coordinator'); } Coordinator.prototype.createUser = function (socketLink) { - var user = new User(socketLink, this); - console.checkpoint('creating user'); - this.assignUserToLobby(user); - } - - Coordinator.prototype.assignUserToLobby = function (user) { - if(user.channelPipe) { - //user.channel.releaseUser(user); -> generate message - } - this.lobbyUsers[user.id] = user; - console.checkpoint('assign user to lobby'); + new User(socketLink, this); } Coordinator.prototype.assignUserToChannel = function (user, channelName) { - - if(user.channelPipe) { - //user.channel.releaseUser(user); -> generate message - } - - if(!Channel.validateName(channelName)) { - //TODO send validation error - return false; - } - - var channelPipe = this.channelPipes[channelName]; - if(!channelPipe) { - this.createPipe(channelName); - } - - //channel.addUser(user); - //user.setChannel(channel); - Nc.trigger('user/joined', user); - - delete this.lobbyUsers[user.id]; + var channelPipe = this.channelPipes[channelName]; + user.setChannelPipe(channelPipe); } - Coordinator.prototype.removeUser = function (user) { - - Nc.trigger('user/left', user); - //NotificationCenter.off('channel/' + user.channel.channelName + '/user/' + user.id); - - delete this.lobbyUsers[user.id]; + Coordinator.prototype.onDestroyPipe = function(channelName) { + delete this.channelPipes[channelName]; } - Coordinator.prototype.createPipe = function(channelName) { - - var channelPipe = new PipeToChannel(channelName); - this.channelPipes[channelName] = channelPipe; - - - Nc.on('channel/' + channelName + '/message', function (data) { - channelPipe.send('channel', data); - }, this); - - // sending info to user - Nc.on('user/joined', function (user) { - /* - Nc.on('channel/' + channelName + '/user/' + user.id, function (recipient, data) { - channelPipe.send(recipient, data); - }, this); - */ - - channelPipe.send('channel', { addUser: user.id }); - - }, this); - - Nc.on('user/left', function (user) { - channelPipe.send('channel', { releaseUser: user.id }); - }, this); - - Nc.on('user/controlCommand', function (userId, data) { - channelPipe.sendToUser(userId, data); - }, this); - - return channelPipe; - }; - Coordinator.prototype.getChannels = function(options) { - var list = []; + var list = []; for (var channelName in this.channelPipes) { list.push({ name: channelName }); } return list; + } + + Coordinator.prototype.createChannel = function(options) { + if(this.channelPipes[options.channelName]) { + return false; + } + + var channelPipe = new PipeToChannel(options); + this.channelPipes[options.channelName] = channelPipe; + return { + channelName: options.channelName, + link: "#" + options.channelName, + timeout: Settings.CHANNEL_DESTRUCTION_TIME + } }; - return Coordinator; + Coordinator.prototype.onMessage = function(message) { + if(message.destroy) { + delete this.channelPipes[message.destroy]; + } + }; + + return Coordinator; + }); \ No newline at end of file diff --git a/app/Server/PipeToChannel.js b/app/Server/PipeToChannel.js index 8c6fe29..e23285e 100755 --- a/app/Server/PipeToChannel.js +++ b/app/Server/PipeToChannel.js @@ -7,21 +7,21 @@ function (Nc, childProcess) { var fork = childProcess.fork; - function PipeToChannel (channelName) { + function PipeToChannel (options) { - this.channelPipe = null; + this.fork = null; try { - this.channelPipe = fork('channel.js'); + this.fork = fork('channel.js'); } catch (err) { throw 'Failed to fork channel! (' + err + ')'; } - console.checkpoint('creating channel process for ' + channelName); + console.checkpoint('creating channel process for ' + options.channelName); - this.send('channel/' + channelName, { CREATE: channelName }); + this.send('channel/' + options.channelName, { CREATE: true, options: options }); - this.channelPipe.on('message', this.onMessage.bind(this)); + this.fork.on('message', this.onMessage.bind(this)); var self = this; } @@ -33,7 +33,7 @@ function (Nc, childProcess) { data: data } - this.channelPipe.send(message); + this.fork.send(message); } // If user already created @@ -43,7 +43,7 @@ function (Nc, childProcess) { data: data } - this.channelPipe.send(message); + this.fork.send(message); } PipeToChannel.prototype.onMessage = function (message) { diff --git a/app/Server/User.js b/app/Server/User.js old mode 100755 new mode 100644 index 57fe570..95f7654 --- a/app/Server/User.js +++ b/app/Server/User.js @@ -1,60 +1,77 @@ -define([ - "Game/Core/User", - "Lib/Utilities/Protocol/Helper", - "Lib/Utilities/NotificationCenter" -], - -function (Parent, ProtocolHelper, Nc) { - - function User (socketLink, coordinator) { - Parent.call(this, socketLink.id); - - this.coordinator = coordinator; - this.channelProcess = null; - this.socketLink = socketLink; - - socketLink.on('message', this.onMessage.bind(this)); - socketLink.on('disconnect', this.onDisconnect.bind(this)); - - Nc.on("user/" + this.socketLink.id + "/message", this.socketLink.send, this.socketLink); - } - - User.prototype = Object.create(Parent.prototype); - - - // Socket callbacks - - User.prototype.onMessage = function (message) { - ProtocolHelper.applyCommand(message, this); - } - - User.prototype.onDisconnect = function () { - this.coordinator.removeUser(this); - } - - - // User command callbacks - // Remember: control commands are coordinator relevant commands - - User.prototype.onJoin = function(options) { - this.coordinator.assignUserToChannel(this, options); - }; - - User.prototype.onLeave = function(options) { - this.coordinator.assignUserToLobby(this); - }; - - User.prototype.onGameCommand = function(options) { - // repacking for transport via pipe - var message = ProtocolHelper.encodeCommand("gameCommand", options); - Nc.trigger("user/controlCommand", this.id, message); - }; - - User.prototype.onPing = function(timestamp) { - var message = ProtocolHelper.encodeCommand("pong", timestamp); - Nc.trigger("user/" + this.socketLink.id + "/message", message); - }; - - return User; - +define([ + "Game/Core/User", + "Lib/Utilities/Protocol/Helper", + "Lib/Utilities/NotificationCenter" +], + +function (Parent, ProtocolHelper, Nc) { + + function User (socketLink, coordinator) { + Parent.call(this, socketLink.id); + + this.coordinator = coordinator; + this.socketLink = socketLink; + this.channelPipe = null; + + socketLink.on('message', this.onMessage.bind(this)); + socketLink.on('disconnect', this.onDisconnect.bind(this)); + + Nc.on("user/" + this.socketLink.id + "/message", this.socketLink.send, this.socketLink); + } + + User.prototype = Object.create(Parent.prototype); + + User.prototype.setChannelPipe = function(channelPipe) { + if(channelPipe) { + this.channelPipe = channelPipe; + } else { + var message = ProtocolHelper.encodeCommand("joinError", {message:"Channel not found"}); + this.socketLink.send(message); + } + }; + + + // Socket callbacks + + User.prototype.onMessage = function (message) { + ProtocolHelper.applyCommand(message, this); + } + + User.prototype.onDisconnect = function () { + if(!this.channelPipe) { + console.warn("Disconnecting user without a channel."); + return; + } + + this.channelPipe.send('channel', { releaseUser: this.id }); + } + + + // User command callbacks + // Remember: control commands are coordinator relevant commands + + User.prototype.onJoin = function(options) { + this.coordinator.assignUserToChannel(this, options.channelName); + + if(!this.channelPipe) { + console.warn("Can not join user because channel (" + options.channelName + ") does not exist.") + return; + } + + this.channelPipe.send('channel', { addUser: this.id }); + }; + + User.prototype.onGameCommand = function(options) { + // repacking for transport via pipe + var message = ProtocolHelper.encodeCommand("gameCommand", options); + this.channelPipe.sendToUser(this.id, message); + }; + + User.prototype.onPing = function(timestamp) { + var message = ProtocolHelper.encodeCommand("pong", timestamp); + Nc.trigger("user/" + this.socketLink.id + "/message", message); + }; + + return User; + }); \ No newline at end of file diff --git a/static/html/index.html b/static/html/index.html index eda77ba..88b6423 100644 --- a/static/html/index.html +++ b/static/html/index.html @@ -2,42 +2,92 @@ Chuck Lobby + -
+
+

Chuck

- - - - - - - - - - - -
Name
- -
-

- - -

- + +
+
+

Create your own!

+

+
+ Maps +
    +
  • + +
  • +
  • + +
  • +
+
+ +

+ + +

+
+
+ +
+

+ +

+

+ + +

+
+ +
+

Channel list

+ + + + + + + + +
NameType
+

+ + + +

+
+
+ \ No newline at end of file From 39bdac0d7ba00df4a4d129dab994b27173d73e33 Mon Sep 17 00:00:00 2001 From: Jeena Date: Sun, 2 Mar 2014 01:15:33 +0100 Subject: [PATCH 4/4] fixed #57 --- app/Game/Channel/Channel.js | 26 ++++--- app/Game/Channel/GameController.js | 9 --- app/Game/Channel/Player.js | 4 +- app/Game/Channel/User.js | 11 +-- app/Game/Client/GameController.js | 12 +-- app/Game/Client/Networker.js | 11 ++- app/Game/Client/Player.js | 8 +- app/Game/Core/GameController.js | 2 +- app/Game/Core/Player.js | 3 +- app/Game/Core/User.js | 8 +- app/Server/User.js | 8 +- static/html/index.html | 116 ++++++++++++++++------------- 12 files changed, 118 insertions(+), 100 deletions(-) diff --git a/app/Game/Channel/Channel.js b/app/Game/Channel/Channel.js index 7344a25..d9628a9 100755 --- a/app/Game/Channel/Channel.js +++ b/app/Game/Channel/Channel.js @@ -46,22 +46,26 @@ // Channel command callbacks - Channel.prototype.onAddUser = function (userId) { + Channel.prototype.onAddUser = function (options) { var self = this; if(!this.gameController.level || !this.gameController.level.isLoaded) { var token = Nc.on("game/level/loaded", function() { - self.sendJoinSuccess(userId); + self.sendJoinSuccess(options); Nc.off(token); }); } else { - self.sendJoinSuccess(userId); + self.sendJoinSuccess(options); } } - Channel.prototype.sendJoinSuccess = function(userId) { - var user = new User(userId, this); - var joinedUsers = Object.keys(this.users); + Channel.prototype.sendJoinSuccess = function(options) { + var user = new User(options.id, options); + + var joinedUsers = []; + for(var userId in this.users) { + joinedUsers.push(this.users[userId].options) + } var levelUid = null; if(this.gameController.level) { @@ -71,14 +75,16 @@ this.users[user.id] = user; var options = { - userId: user.id, - channelName: this.name, + user: user.options, joinedUsers: joinedUsers, levelUid: levelUid }; - Nc.trigger('user/' + user.id + "/joinSuccess", options); - Nc.trigger('user/joined', user); + //Nc.trigger('user/' + user.id + "/joinSuccess", options); + user.sendControlCommand("joinSuccess", options); + Nc.trigger('user/joined', user); + + this.broadcastControlCommandExcept("userJoined", user.options, user); }; Channel.prototype.onReleaseUser = function (userId) { diff --git a/app/Game/Channel/GameController.js b/app/Game/Channel/GameController.js index f7fdc6b..9131742 100755 --- a/app/Game/Channel/GameController.js +++ b/app/Game/Channel/GameController.js @@ -88,15 +88,6 @@ function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, N }, respawnTime * 1000); }; - /* - GameController.prototype.createPlayer = function(user) { - var player = new Player(user.id, this.physicsEngine); - player.setPlayerController(new PlayerController(player)) - - return player; - }; - */ - GameController.prototype.updateWorld = function () { var update = this.getWorldUpdateObject(false); diff --git a/app/Game/Channel/Player.js b/app/Game/Channel/Player.js index 6cbdebb..188160c 100755 --- a/app/Game/Channel/Player.js +++ b/app/Game/Channel/Player.js @@ -5,8 +5,8 @@ define([ function (Parent, Nc) { - function Player(id, physicsEngine) { - Parent.call(this, id, physicsEngine); + function Player(id, physicsEngine, user) { + Parent.call(this, id, physicsEngine, user); } Player.prototype = Object.create(Parent.prototype); diff --git a/app/Game/Channel/User.js b/app/Game/Channel/User.js index c573a7f..486b8de 100755 --- a/app/Game/Channel/User.js +++ b/app/Game/Channel/User.js @@ -7,20 +7,13 @@ define([ function(Parent, Nc, ProtocolHelper, ProtocolParser) { - function User(id, channel) { - Parent.call(this, id); + function User(id, options) { + Parent.call(this, id, options); - this.channel = channel; this.player = null; this.isReady = false; var self = this; - Nc.on('user/joined', function(user) { // FIXME: use sendToAllUsersExcept instead - if(user.id != self.id) { - self.sendControlCommand("userJoined", user.id); - } - }); - Nc.on('user/' + this.id + "/joinSuccess", function(options) { self.sendControlCommand("joinSuccess", options); }); diff --git a/app/Game/Client/GameController.js b/app/Game/Client/GameController.js index 2146858..f1e1c6e 100755 --- a/app/Game/Client/GameController.js +++ b/app/Game/Client/GameController.js @@ -208,10 +208,12 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque }; var sortedPlayers = playersArray.sort(function(a,b) { - if(a.score > b.score) return 1; - if(a.score < b.score) return -1; - if(a.deaths < b.deaths) return 1; - if(a.deaths > b.deaths) return -1; + if(a.stats.score > b.stats.score) return -1; + if(a.stats.score < b.stats.score) return 1; + if(a.stats.deaths < b.stats.deaths) return -1; + if(a.stats.deaths > b.stats.deaths) return 1; + if(a.stats.health > b.stats.health) return -1; + if(a.stats.health < b.stats.health) return 1; return 0; }); @@ -236,7 +238,7 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, reque var lines = []; sortedPlayers.forEach(function(player, i) { - var name = player == this.me ? "You" : "Player " + (Object.keys(this.players).indexOf(player.id) + 1); + var name = player.getNickname(); lines.push( pad("" + (i + 1) + ".", 2, false) + " " + pad(name, 12, true) + diff --git a/app/Game/Client/Networker.js b/app/Game/Client/Networker.js index 258a618..dbf7d8a 100755 --- a/app/Game/Client/Networker.js +++ b/app/Game/Client/Networker.js @@ -13,7 +13,6 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { this.socketLink = socketLink; this.gameController = null; this.users = {}; - this.userId = null; this.socketLink.on('connect', this.onConnect.bind(this)); this.socketLink.on('disconnect', this.onDisconnect.bind(this)); @@ -57,12 +56,11 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { Networker.prototype.onJoinSuccess = function (options) { console.log("join success") - this.userId = options.userId; this.gameController = new GameController(); this.gameController.loadLevel(options.levelUid); - this.onUserJoined(options.userId); + this.onUserJoined(options.user); if (options.joinedUsers) { for(var i = 0; i < options.joinedUsers.length; i++) { @@ -114,9 +112,10 @@ function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { // Commands from server - Networker.prototype.onUserJoined = function (userId) { - var user = new User(userId); - this.users[userId] = user; + Networker.prototype.onUserJoined = function (options) { + var user = new User(options.id, options); + console.log(options.nickname) + this.users[user.id] = user; if (this.gameController && this.gameController.level diff --git a/app/Game/Client/Player.js b/app/Game/Client/Player.js index aa84f28..b21171c 100755 --- a/app/Game/Client/Player.js +++ b/app/Game/Client/Player.js @@ -6,8 +6,8 @@ define([ function (Parent, Nc, Settings) { - function Player(id, physicsEngine) { - Parent.call(this, id, physicsEngine); + function Player(id, physicsEngine, user) { + Parent.call(this, id, physicsEngine, user); this.playerInfoView = null; this.playerInfoViewVisibleTimeout = null; @@ -81,6 +81,10 @@ function (Parent, Nc, Settings) { } }; + Player.prototype.getNickname = function() { + return this.user.options.nickname; + }; + Player.prototype.render = function() { // dolls are self responsible diff --git a/app/Game/Core/GameController.js b/app/Game/Core/GameController.js index 820c2e4..1579d68 100755 --- a/app/Game/Core/GameController.js +++ b/app/Game/Core/GameController.js @@ -94,7 +94,7 @@ function (PhysicsEngine, TiledLevel, Player, Nc) { } GameController.prototype.createPlayer = function(user) { - var player = new Player(user.id, this.physicsEngine); + var player = new Player(user.id, this.physicsEngine, user); this.players[user.id] = player; return player; }; diff --git a/app/Game/Core/Player.js b/app/Game/Core/Player.js index a47b06a..7209806 100755 --- a/app/Game/Core/Player.js +++ b/app/Game/Core/Player.js @@ -10,13 +10,14 @@ define([ function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { - function Player (id, physicsEngine) { + function Player (id, physicsEngine, user) { this.stats = { health: 100, deaths: 0, score: 0 } + this.user = user; this.physicsEngine = physicsEngine; this.playerController = null; this.doll; diff --git a/app/Game/Core/User.js b/app/Game/Core/User.js index 3934880..de3264f 100755 --- a/app/Game/Core/User.js +++ b/app/Game/Core/User.js @@ -1,7 +1,13 @@ define(function () { - function User (id) { + function User (id, options) { this.id = id; + this.options = options; + + this.options.id = this.id; + if(!this.options.nickname) { + this.options.nickname = this.id; + } } return User; diff --git a/app/Server/User.js b/app/Server/User.js index 95f7654..40b96a4 100644 --- a/app/Server/User.js +++ b/app/Server/User.js @@ -7,7 +7,7 @@ define([ function (Parent, ProtocolHelper, Nc) { function User (socketLink, coordinator) { - Parent.call(this, socketLink.id); + Parent.call(this, socketLink.id, {}); this.coordinator = coordinator; this.socketLink = socketLink; @@ -58,7 +58,11 @@ function (Parent, ProtocolHelper, Nc) { return; } - this.channelPipe.send('channel', { addUser: this.id }); + var userOptions = { + id: this.id, + nickname: options.nickname + } + this.channelPipe.send('channel', { addUser: userOptions }); }; User.prototype.onGameCommand = function(options) { diff --git a/static/html/index.html b/static/html/index.html index 88b6423..70127b6 100644 --- a/static/html/index.html +++ b/static/html/index.html @@ -47,7 +47,7 @@ -
+

-
+

Channel list

@@ -113,7 +113,7 @@ } document.body.className = ""; } else { - console.error("Ajax error: " + xhr.status + " " + xhr.statusText) + console.error("Ajax error: " + xhr.status + " " + xhr.responseText) $("#list").innerHTML = ""; document.body.className = "offline"; } @@ -172,65 +172,77 @@ } $("form#createform").onsubmit = function(e) { - var maps = []; - var checkboxes = document.querySelectorAll("form#createform input[name=maps]"); - for (var i = 0; i < checkboxes.length; i++) { - var checkbox = checkboxes[i]; - if(checkbox.checked) { - maps.push(checkbox.value); + try { + + var maps = []; + var checkboxes = document.querySelectorAll("form#createform input[name=maps]"); + for (var i = 0; i < checkboxes.length; i++) { + var checkbox = checkboxes[i]; + if(checkbox.checked) { + maps.push(checkbox.value); + } + }; + + if(maps.length == 0) { + alert("Please choose at least one map.") + return false; } - }; - if(maps.length == 0) { - alert("Please choose at least one map.") - return false; + var name = $("#customname").value; + if(!name) { + alert("Please provide a channel name.") + return false; + } + + localStorage["customname"] = name; + + var options = { + channelName: name, + maps: maps, + maxUsers: 10, + minUsers: 2 + } + + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if(xhr.readyState == 4) { + if(xhr.status == 200) { + onCreateSuccess(JSON.parse(xhr.responseText).success); + } else { + console.log(xhr.responseText) + alert(JSON.parse(xhr.responseText).error) + } + } + } + xhr.open("POST", "/api", true); + xhr.send(JSON.stringify({command:"createChannel", options: options})); + } catch(e) { + console.error(e) } - var name = $("#customname").value; - if(!name) { - alert("Please provide a channel name.") - return false; - } - - localStorage["customname"] = name; - - var options = { - channelName: name, - maps: maps, - maxUsers: 10, - minUsers: 2 - } - - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if(xhr.readyState == 4) { - if(xhr.status == 200) { - onCreateSuccess(JSON.parse(xhr.responseText).success); - } else { - console.log(xhr.responseText) - alert(JSON.parse(xhr.responseText).error) - } - } - } - xhr.open("POST", "/api", true); - xhr.send(JSON.stringify({command:"createChannel", options: options})); return false; } $("form#customjoinform").onsubmit = function(e) { - var nickname = $("#nick").value; - if(!nickname || nickname.length < 3) { - alert("nickname too short") - return false; + try { + var nickname = $("#nick").value; + if(!nickname || nickname.length < 3) { + alert("nickname too short") + return false; + } + localStorage["player"] = JSON.stringify({nickname: nickname}); + + var name = $("#customname").value; + localStorage["channel"] = JSON.stringify({ + name: name + }); + + window.location.href = "/game.html"; + + } catch(e) { + console.error(e) } - localStorage["player"] = JSON.stringify({nickname: nickname}); - var name = $("form#createform input[name=channel]").value; - localStorage["channel"] = JSON.stringify({ - name: name - }); - - window.location.href = "/game.html"; return false; }