diff --git a/cardshifter.html b/cardshifter.html index 92a56bc..d9461f3 100644 --- a/cardshifter.html +++ b/cardshifter.html @@ -1,28 +1,28 @@ - - Cardshifter + + Cardshifter - - + + - - + + - - - + + + - - + + - - - - - - - -
- + + + + + + + +
+ \ No newline at end of file diff --git a/cardshifter.js b/cardshifter.js index ec3a389..a02a2bb 100644 --- a/cardshifter.js +++ b/cardshifter.js @@ -1,13 +1,13 @@ var CardshifterApp = angular.module("CardshifterApp", ["ngRoute"]); CardshifterApp.config(function($routeProvider) { - $routeProvider - .when("/", { // default page is Login - controller: "LoginController", - templateUrl: "login/login.html", - }) - .when("/lobby", { - controller: "LobbyController", - templateUrl: "lobby/lobby.html", - }) + $routeProvider + .when("/", { // default page is Login + controller: "LoginController", + templateUrl: "login/login.html", + }) + .when("/lobby", { + controller: "LobbyController", + templateUrl: "lobby/lobby.html", + }) }); \ No newline at end of file diff --git a/lobby/lobby_controller.js b/lobby/lobby_controller.js index 216dca0..b7ace7c 100644 --- a/lobby/lobby_controller.js +++ b/lobby/lobby_controller.js @@ -1,50 +1,50 @@ CardshifterApp.controller("LobbyController", function($scope, $interval, $timeout) { - var CHAT_FEED_LIMIT = 10; - var POLL_FREQ = 2000; - var MESSAGE_DELAY = 3000; + var CHAT_FEED_LIMIT = 10; + var POLL_FREQ = 2000; + var MESSAGE_DELAY = 3000; - $scope.users = []; - $scope.chatMessages = []; + $scope.users = []; + $scope.chatMessages = []; - var getUsersMessage = new CardshifterServerAPI.messageTypes.ServerQueryMessage("USERS", ""); - CardshifterServerAPI.sendMessage(getUsersMessage); + var getUsersMessage = new CardshifterServerAPI.messageTypes.ServerQueryMessage("USERS", ""); + CardshifterServerAPI.sendMessage(getUsersMessage); - $interval(function() { // update chat and users - while(message = CardshifterServerAPI.getMessage()) { - switch(message.command) { - case "userstatus": + $interval(function() { // update chat and users + while(message = CardshifterServerAPI.getMessage()) { + switch(message.command) { + case "userstatus": // do conditional checking if user is offline if(message.status === "OFFLINE") { - for(var i = 0, length = $scope.users.length; i < length; i++) { - // if the user described in the message is the user in this iteration - if($scope.users[i].name === message.name) { - $scope.users.splice(i, 1); // remove that user from the array - } - } + for(var i = 0, length = $scope.users.length; i < length; i++) { + // if the user described in the message is the user in this iteration + if($scope.users[i].name === message.name) { + $scope.users.splice(i, 1); // remove that user from the array + } + } } else { - $scope.users.push(message); + $scope.users.push(message); } - break; - case "chat": - if($scope.chatMessages.length === CHAT_FEED_LIMIT) { - // remove the latest (opposite of earliest) chat message - $scope.chatMessages.shift(); - } - $scope.chatMessages.push(message); - break; - } - } - }, POLL_FREQ); + break; + case "chat": + if($scope.chatMessages.length === CHAT_FEED_LIMIT) { + // remove the latest (opposite of earliest) chat message + $scope.chatMessages.shift(); + } + $scope.chatMessages.push(message); + break; + } + } + }, POLL_FREQ); - $scope.sendMessage = function() { - $scope.sending = true; - var chatMessage = new CardshifterServerAPI.messageTypes.ChatMessage($scope.user_chat_message); - CardshifterServerAPI.sendMessage(chatMessage); + $scope.sendMessage = function() { + $scope.sending = true; + var chatMessage = new CardshifterServerAPI.messageTypes.ChatMessage($scope.user_chat_message); + CardshifterServerAPI.sendMessage(chatMessage); - $scope.user_chat_message = ""; // clear the input box - $timeout(function() { // allow another message to be sent in 3 seconds - $scope.sending = false; - }, MESSAGE_DELAY); - } + $scope.user_chat_message = ""; // clear the input box + $timeout(function() { // allow another message to be sent in 3 seconds + $scope.sending = false; + }, MESSAGE_DELAY); + } }); \ No newline at end of file diff --git a/login/login.html b/login/login.html index a7c9989..11fd9d3 100644 --- a/login/login.html +++ b/login/login.html @@ -1,38 +1,38 @@
-

Cardshifter login

-
-
- - -
-
-
- - -
- - - -
-
-
-
- - -
-
- - -
-
- - - -
-
+

Cardshifter login

+
+
+ + +
+
+
+ + +
+ + + +
+
+
+
+ + +
+
+ + +
+
+ + + +
+
diff --git a/login/login_alt.html b/login/login_alt.html index df0bef6..b3f94ea 100644 --- a/login/login_alt.html +++ b/login/login_alt.html @@ -2,13 +2,13 @@ - Cardshifter Login + Cardshifter Login - + @@ -31,30 +31,30 @@
- +
- - + +
-
- - -
+
+ + +
- - - + + +
@@ -62,46 +62,46 @@
- + - -
+ +
- - + +
-
- - -
+
+ + +
- - + +
- - Test message to server: +
- - - + +
-
- + +
diff --git a/login/login_controller.js b/login/login_controller.js index d2c4980..44aa12c 100644 --- a/login/login_controller.js +++ b/login/login_controller.js @@ -1,37 +1,37 @@ CardshifterApp.controller("LoginController", function($scope, $location, $rootScope) { - var SUCCESS = 200; + var SUCCESS = 200; - $scope.login = function() { - $scope.loggedIn = true; - var finalServer = ($scope.server === "other" ? $scope.other_server : $scope.server); + $scope.login = function() { + $scope.loggedIn = true; + var finalServer = ($scope.server === "other" ? $scope.other_server : $scope.server); - CardshifterServerAPI.init(finalServer, $scope.is_secure, function() { - var login = new CardshifterServerAPI.messageTypes.LoginMessage($scope.username); + CardshifterServerAPI.init(finalServer, $scope.is_secure, function() { + var login = new CardshifterServerAPI.messageTypes.LoginMessage($scope.username); - try { - CardshifterServerAPI.sendMessage(login, function(serverResponse) { - if(serverResponse.status === SUCCESS && serverResponse.message === "OK") { - $rootScope.$apply(function() { - $location.path("/lobby"); - }); - } else { - // I don't actually know what the server will respond with - // notify the user that there was an issue logging in (custom server issue ???) + try { + CardshifterServerAPI.sendMessage(login, function(serverResponse) { + if(serverResponse.status === SUCCESS && serverResponse.message === "OK") { + $rootScope.$apply(function() { + $location.path("/lobby"); + }); + } else { + // I don't actually know what the server will respond with + // notify the user that there was an issue logging in (custom server issue ???) - console.log("server message: " + serverResponse.message); - $scope.loggedIn = false; - } - }); + console.log("server message: " + serverResponse.message); + $scope.loggedIn = false; + } + }); - } catch(e) { - // notify the user that there was an issue logging in (loginmessage issue) - console.log("LoginMessage error(error 2): " + e); - $scope.loggedIn = false; - } - }, function() { - // notify the user that there was an issue logging in (websocket issue) - console.log("Websocket error(error 1)"); - $scope.loggedIn = false; - }); - } + } catch(e) { + // notify the user that there was an issue logging in (loginmessage issue) + console.log("LoginMessage error(error 2): " + e); + $scope.loggedIn = false; + } + }, function() { + // notify the user that there was an issue logging in (websocket issue) + console.log("Websocket error(error 1)"); + $scope.loggedIn = false; + }); + } }); \ No newline at end of file diff --git a/server_interface/server_interface.js b/server_interface/server_interface.js index e0f6b77..9cfdddd 100644 --- a/server_interface/server_interface.js +++ b/server_interface/server_interface.js @@ -1,32 +1,32 @@ (function(window, undefined) { - // checks if the string begins with either ws:// or wss:// - var wsProtocolFinder = /ws(s)*:\/\//; - var SOCKET_OPEN = 1; + // checks if the string begins with either ws:// or wss:// + var wsProtocolFinder = /ws(s)*:\/\//; + var SOCKET_OPEN = 1; - function Message(command) { - this.command = command; - } + function Message(command) { + this.command = command; + } - function NotInitializedException(message) { - this.name = "NotInitializedException"; - this.message = message; - } - function SocketNotReadyException(message, readyState) { - this.name = "SocketNotReadyException" - this.message = message; - this.readyState = readyState; - } + function NotInitializedException(message) { + this.name = "NotInitializedException"; + this.message = message; + } + function SocketNotReadyException(message, readyState) { + this.name = "SocketNotReadyException" + this.message = message; + this.readyState = readyState; + } - /** - Returns all the keys of obj and it's inherited keys + /** + Returns all the keys of obj and it's inherited keys - @param obj:Object -- The object - @return Object -- a new Object, containing obj's keys and inherited keys - @source http://stackoverflow.com/questions/8779249/how-to-stringify-inherited-objects-to-json + @param obj:Object -- The object + @return Object -- a new Object, containing obj's keys and inherited keys + @source http://stackoverflow.com/questions/8779249/how-to-stringify-inherited-objects-to-json - This is used so JSON.stringify can get the .command of a message. - */ - function flatten(obj) { + This is used so JSON.stringify can get the .command of a message. + */ + function flatten(obj) { var result = Object.create(obj); for(var key in result) { result[key] = result[key]; @@ -34,270 +34,270 @@ return result; } - window.CardshifterServerAPI = { - socket: null, - incomingMessages: [], - messageTypes: { - /** - * Incoming login message. - *

- * A login message from a client to add a user to the available users on the server. - * This login message is required before any other action or message can be performed between a client and a server. - * @constructor - * @param username the incoming user name passed from client to server, not null - * @example Message: { "command":"login","username":"JohnDoe" } - */ - LoginMessage: function(username) { - this.username = username; - }, + window.CardshifterServerAPI = { + socket: null, + incomingMessages: [], + messageTypes: { + /** + * Incoming login message. + *

+ * A login message from a client to add a user to the available users on the server. + * This login message is required before any other action or message can be performed between a client and a server. + * @constructor + * @param username the incoming user name passed from client to server, not null + * @example Message: { "command":"login","username":"JohnDoe" } + */ + LoginMessage: function(username) { + this.username = username; + }, - /** - * Request available targets for a specific action to be performed by an entity. - *

- * These in-game messages request a list of al available targets for a given action and entity. - * The client uses this request in order to point out targets (hopefully with a visual aid such as highlighting targets) - * that an entity (such as a creature card, or a player) can perform an action on (for example attack or enchant a card. - * @constructor - * @param gameId The Id of this game currently being played - * @param id The Id of this entity which requests to perform an action - * @param action The name of this action requested to be performed - */ - RequestTargetsMessage: function(gameId, id, action) { - this.gamdId = gameId; - this.id = id; - this.action = action; - }, + /** + * Request available targets for a specific action to be performed by an entity. + *

+ * These in-game messages request a list of al available targets for a given action and entity. + * The client uses this request in order to point out targets (hopefully with a visual aid such as highlighting targets) + * that an entity (such as a creature card, or a player) can perform an action on (for example attack or enchant a card. + * @constructor + * @param gameId The Id of this game currently being played + * @param id The Id of this entity which requests to perform an action + * @param action The name of this action requested to be performed + */ + RequestTargetsMessage: function(gameId, id, action) { + this.gamdId = gameId; + this.id = id; + this.action = action; + }, - /** - * Make a specific type of request to the server. - *

- * This is used to request an action from the server which requires server-side information. - * @constructor - * @param request This request - * @param message The message accompanying this request - */ - ServerQueryMessage: function(request, message) { - this.request = request; - this.message = message; - - this.toString = function() { - return "ServerQueryMessage: Request" + this.request + " message: " + this.message; - }; - }, - - - /** - * Request to start a new game. - *

- * This is sent from the Client to the Server when this player invites another player (including AI) to start a new game of a chosen type. - * @constructor - * @param opponent The Id of the player entity being invited by this player - * @param gameType The type / mod of the game chosen by this player - */ - StartGameRequest: function(opponent, gameType) { - this.opponent = opponent; - this.gameType = gameType; - }, - - /** - * Serialize message from JSON to byte. - *

- * Primarily used for libGDX client. - * Constructor. - * @param type This message type - */ - TransformerMessage: function(type) { - this.type = type; - }, - - /** - * Message for a game entity to use a certain ability. - *

- * Game entities (e.g., cards, players) may have one or more ability actions that they can perform. - * Certain abilities can have multiple targets, hence the use of an array. - * @constructor. (multiple targets) - *

- * Used for multiple target actions. - * - * @param gameId This current game - * @param entity This game entity performing an action - * @param action This action - * @param targets The set of multiple targets affected by this action - */ - UseAbilityMessage: function(gameId, id, action, targets) { - this.gameId = gameId; - this.id = id; - this.action = action; - this.targets = targets; - - this.toString = function() { - return "UseAbilityMessage" + - "[id=" + this.id + - ", action=" + this.action + - ", gameId=" + this.gameId + - ", targets=" + this.targets.toString() + - "]"; - }; - }, - - /** - * Chat message in game lobby. - *

- * These are messages printed to the game lobby which are visible to all users present at the time the message is posted. - * @constructor - * @param message The content of this chat message - */ - ChatMessage: function(message) { - this.chatId = 1; - this.from = "unused"; - this.message = message; - - this.toString = function() { - return "ChatMessage [chatId=" + chatId + ", message=" + message + ", from=" + from + "]"; - }; - }, - - /** - * Request to invite a player to start a new game. - * @constructor - * @param id The Id of this invite request - * @param name The name of the player being invited - * @param gameType The game type of this invite request - */ - InviteRequest: function(id, name, gameType) { - this.id = id; - this.name = name; - this.gameType = gameType; - }, - - /** - * Response to an InviteRequest message. - * @constructor - * @param inviteId Id of this incoming InviteRequest message - * @param accepted Whether or not the InviteRequest is accepted - */ - InviteResponse: function(inviteId, accepted) { - this.inviteId = inviteId; - this.accepted = accepted; - }, - - /** - * Player configuration for a given game. - * @constructor - * @param gameId This game - * @param modName The mod name for this game - * @param configs Map of player name and applicable player configuration - */ - PlayerConfigMessage: function(gameId, modName, configs) { - this.gameId = gameId; - this.modName = modName; - this.configs = configs; - - this.toString = function() { - return "PlayerConfigMessage{" + - "configs=" + configs + - ", gameId=" + gameId + - ", modName='" + modName + '\'' + - '}'; - }; - } - }, - /** - * Initializes the API for use. - * - * @param server:string -- The server that to be connected to. - * @param isSecure:boolean -- Whether or not the server is being connected to with wss - * - * This sets up all the message types to inherit the main `Message` class, and sets - * up the websocket that will be used to communicate to the server, and to recieve - * information from the server. - * - */ - init: function(server, isSecure, onReady, onError) { - var types = this.messageTypes; - var self = this; // for the events - - types.LoginMessage.prototype = new Message("login"); - types.RequestTargetsMessage.prototype = new Message("requestTargets"); - types.ServerQueryMessage.prototype = new Message("query"); - types.StartGameRequest.prototype = new Message("startgame"); - types.TransformerMessage.prototype = new Message("serial"); - types.UseAbilityMessage.prototype = new Message("use"); - types.ChatMessage.prototype = new Message("chat"); - types.InviteRequest.prototype = new Message("inviteRequest"); - types.InviteResponse.prototype = new Message("inviteResponse"); - types.PlayerConfigMessage.prototype = new Message("playerconfig"); - NotInitializedException.prototype = new Error(); - SocketNotReadyException.prototype = new Error(); - - // secure websocket is wss://, rather than ws:// - var secureAddon = (isSecure ? "s" : ""); - // if the protocol is not found in the string, store the correct protocol (is secure?) - var protocolAddon = (wsProtocolFinder.test(server) ? "" : "ws" + secureAddon + "://"); - var socket = new WebSocket(protocolAddon + server); + /** + * Make a specific type of request to the server. + *

+ * This is used to request an action from the server which requires server-side information. + * @constructor + * @param request This request + * @param message The message accompanying this request + */ + ServerQueryMessage: function(request, message) { + this.request = request; + this.message = message; + + this.toString = function() { + return "ServerQueryMessage: Request" + this.request + " message: " + this.message; + }; + }, + + + /** + * Request to start a new game. + *

+ * This is sent from the Client to the Server when this player invites another player (including AI) to start a new game of a chosen type. + * @constructor + * @param opponent The Id of the player entity being invited by this player + * @param gameType The type / mod of the game chosen by this player + */ + StartGameRequest: function(opponent, gameType) { + this.opponent = opponent; + this.gameType = gameType; + }, + + /** + * Serialize message from JSON to byte. + *

+ * Primarily used for libGDX client. + * Constructor. + * @param type This message type + */ + TransformerMessage: function(type) { + this.type = type; + }, + + /** + * Message for a game entity to use a certain ability. + *

+ * Game entities (e.g., cards, players) may have one or more ability actions that they can perform. + * Certain abilities can have multiple targets, hence the use of an array. + * @constructor. (multiple targets) + *

+ * Used for multiple target actions. + * + * @param gameId This current game + * @param entity This game entity performing an action + * @param action This action + * @param targets The set of multiple targets affected by this action + */ + UseAbilityMessage: function(gameId, id, action, targets) { + this.gameId = gameId; + this.id = id; + this.action = action; + this.targets = targets; + + this.toString = function() { + return "UseAbilityMessage" + + "[id=" + this.id + + ", action=" + this.action + + ", gameId=" + this.gameId + + ", targets=" + this.targets.toString() + + "]"; + }; + }, + + /** + * Chat message in game lobby. + *

+ * These are messages printed to the game lobby which are visible to all users present at the time the message is posted. + * @constructor + * @param message The content of this chat message + */ + ChatMessage: function(message) { + this.chatId = 1; + this.from = "unused"; + this.message = message; - socket.onmessage = function(message) { - self.incomingMessages.push(JSON.parse(message.data)); - } + this.toString = function() { + return "ChatMessage [chatId=" + chatId + ", message=" + message + ", from=" + from + "]"; + }; + }, - socket.onopen = onReady; + /** + * Request to invite a player to start a new game. + * @constructor + * @param id The Id of this invite request + * @param name The name of the player being invited + * @param gameType The game type of this invite request + */ + InviteRequest: function(id, name, gameType) { + this.id = id; + this.name = name; + this.gameType = gameType; + }, - socket.onerror = function() { - onError(); - this.socket = null; - } + /** + * Response to an InviteRequest message. + * @constructor + * @param inviteId Id of this incoming InviteRequest message + * @param accepted Whether or not the InviteRequest is accepted + */ + InviteResponse: function(inviteId, accepted) { + this.inviteId = inviteId; + this.accepted = accepted; + }, - this.socket = socket; - }, - - /** - * Sends a message to the server. - * - * @param message:Message -- The message to send. - * @param onReceive:Function (OPTIONAL) -- A function to run when a message has returned - * @error NotInitializedException -- If the API has not been initialized yet. - * - * This will use websocket setup by `this.init` to send a message to the server. - * - * NOTE: The onReceive function will NOT NECESSARILY be run when the desired request - * is received. However, it is likely. - */ - sendMessage: function(message, onReceive) { - var socket = this.socket; - var self = this; - if(socket) { - if(socket.readyState === SOCKET_OPEN) { - this.socket.send(JSON.stringify(flatten(message))); - if(onReceive) { - this.socket.onmessage = function(msg) { - onReceive(JSON.parse(msg.data)); - this.onmessage = function(msg2) { - self.incomingMessages.push(JSON.parse(msg2.data)); - } - } - } - } else { - throw new SocketNotReadyException("The Websocket is not yet ready to be used", socket.readyState); - } - } else { - throw new NotInitializedException("The API has not yet been initialized."); - } - }, + /** + * Player configuration for a given game. + * @constructor + * @param gameId This game + * @param modName The mod name for this game + * @param configs Map of player name and applicable player configuration + */ + PlayerConfigMessage: function(gameId, modName, configs) { + this.gameId = gameId; + this.modName = modName; + this.configs = configs; - /** - * Gets a message from the recieved message queue. - * - * @return Message -- The first message in the incoming messages queue - * - * This will .shift() the incomingMessages queue and return the value. - * This allows the API to handle the messages from the server so the - * main game code can access the messages as it needs to. - * - * Although the function is very simple, the name make is clear what is - * happening. - */ - getMessage: function() { - return this.incomingMessages.shift(); - } - }; + this.toString = function() { + return "PlayerConfigMessage{" + + "configs=" + configs + + ", gameId=" + gameId + + ", modName='" + modName + '\'' + + '}'; + }; + } + }, + /** + * Initializes the API for use. + * + * @param server:string -- The server that to be connected to. + * @param isSecure:boolean -- Whether or not the server is being connected to with wss + * + * This sets up all the message types to inherit the main `Message` class, and sets + * up the websocket that will be used to communicate to the server, and to recieve + * information from the server. + * + */ + init: function(server, isSecure, onReady, onError) { + var types = this.messageTypes; + var self = this; // for the events + + types.LoginMessage.prototype = new Message("login"); + types.RequestTargetsMessage.prototype = new Message("requestTargets"); + types.ServerQueryMessage.prototype = new Message("query"); + types.StartGameRequest.prototype = new Message("startgame"); + types.TransformerMessage.prototype = new Message("serial"); + types.UseAbilityMessage.prototype = new Message("use"); + types.ChatMessage.prototype = new Message("chat"); + types.InviteRequest.prototype = new Message("inviteRequest"); + types.InviteResponse.prototype = new Message("inviteResponse"); + types.PlayerConfigMessage.prototype = new Message("playerconfig"); + NotInitializedException.prototype = new Error(); + SocketNotReadyException.prototype = new Error(); + + // secure websocket is wss://, rather than ws:// + var secureAddon = (isSecure ? "s" : ""); + // if the protocol is not found in the string, store the correct protocol (is secure?) + var protocolAddon = (wsProtocolFinder.test(server) ? "" : "ws" + secureAddon + "://"); + var socket = new WebSocket(protocolAddon + server); + + socket.onmessage = function(message) { + self.incomingMessages.push(JSON.parse(message.data)); + } + + socket.onopen = onReady; + + socket.onerror = function() { + onError(); + this.socket = null; + } + + this.socket = socket; + }, + + /** + * Sends a message to the server. + * + * @param message:Message -- The message to send. + * @param onReceive:Function (OPTIONAL) -- A function to run when a message has returned + * @error NotInitializedException -- If the API has not been initialized yet. + * + * This will use websocket setup by `this.init` to send a message to the server. + * + * NOTE: The onReceive function will NOT NECESSARILY be run when the desired request + * is received. However, it is likely. + */ + sendMessage: function(message, onReceive) { + var socket = this.socket; + var self = this; + if(socket) { + if(socket.readyState === SOCKET_OPEN) { + this.socket.send(JSON.stringify(flatten(message))); + if(onReceive) { + this.socket.onmessage = function(msg) { + onReceive(JSON.parse(msg.data)); + this.onmessage = function(msg2) { + self.incomingMessages.push(JSON.parse(msg2.data)); + } + } + } + } else { + throw new SocketNotReadyException("The Websocket is not yet ready to be used", socket.readyState); + } + } else { + throw new NotInitializedException("The API has not yet been initialized."); + } + }, + + /** + * Gets a message from the recieved message queue. + * + * @return Message -- The first message in the incoming messages queue + * + * This will .shift() the incomingMessages queue and return the value. + * This allows the API to handle the messages from the server so the + * main game code can access the messages as it needs to. + * + * Although the function is very simple, the name make is clear what is + * happening. + */ + getMessage: function() { + return this.incomingMessages.shift(); + } + }; })(Function("return this")()); \ No newline at end of file