use constants for long poll events, ajax request operation names, ajax response field names, and error codes

This commit is contained in:
Andy Janata 2012-01-12 21:36:31 -08:00
parent f33070ab7e
commit 9a281cd38f
15 changed files with 269 additions and 79 deletions

View File

@ -12,6 +12,25 @@ cah.$.AjaxOperation.REGISTER = "register";
cah.$.AjaxOperation.CHAT = "chat"; cah.$.AjaxOperation.CHAT = "chat";
cah.$.AjaxOperation.NAMES = "names"; cah.$.AjaxOperation.NAMES = "names";
cah.$.AjaxRequest = function() {
// pass
};
cah.$.AjaxRequest.prototype.dummy = undefined;
cah.$.AjaxRequest.SERIAL = "serial";
cah.$.AjaxResponse = function() {
// pass
};
cah.$.AjaxResponse.prototype.dummy = undefined;
cah.$.AjaxResponse.NEXT = "next";
cah.$.AjaxResponse.ERROR = "error";
cah.$.AjaxResponse.ERROR_CODE = "error_code";
cah.$.AjaxResponse.SERIAL = "serial";
cah.$.AjaxResponse.ERROR_MESSAGE = "error_message";
cah.$.AjaxResponse.IN_PROGRESS = "in_progress";
cah.$.AjaxResponse.NICKNAME = "nickname";
cah.$.AjaxResponse.NAMES = "names";
cah.$.DisconnectReason = function() { cah.$.DisconnectReason = function() {
// pass // pass
}; };
@ -20,3 +39,35 @@ cah.$.DisconnectReason.PING_TIMEOUT = "ping_timeout";
cah.$.DisconnectReason.KICKED = "kicked"; cah.$.DisconnectReason.KICKED = "kicked";
cah.$.DisconnectReason.MANUAL = "manual"; cah.$.DisconnectReason.MANUAL = "manual";
cah.$.ErrorCode = function() {
// pass
};
cah.$.ErrorCode.prototype.dummy = undefined;
cah.$.ErrorCode.NO_SESSION = "no_session";
cah.$.ErrorCode.NOT_REGISTERED = "not_registered";
cah.$.ErrorCode.BAD_REQUEST = "bad_req";
cah.$.ErrorCode.OP_NOT_SPECIFIED = "op_not_spec";
cah.$.ErrorCode.SESSION_EXPIRED = "session_expired";
cah.$.ErrorCode.BAD_OP = "bad_op";
cah.$.LongPollEvent = function() {
// pass
};
cah.$.LongPollEvent.prototype.dummy = undefined;
cah.$.LongPollEvent.NOOP = "noop";
cah.$.LongPollEvent.NEW_PLAYER = "new_player";
cah.$.LongPollEvent.PLAYER_LEAVE = "player_leave";
cah.$.LongPollEvent.CHAT = "chat";
cah.$.LongPollResponse = function() {
// pass
};
cah.$.LongPollResponse.prototype.dummy = undefined;
cah.$.LongPollResponse.MESSAGE = "message";
cah.$.LongPollResponse.REASON = "reason";
cah.$.LongPollResponse.GAME_ID = "game_id";
cah.$.LongPollResponse.FROM = "from";
cah.$.LongPollResponse.EVENT = "event";
cah.$.LongPollResponse.TIMESTAMP = "timestamp";
cah.$.LongPollResponse.NICKNAME = "nickname";

View File

@ -11,16 +11,15 @@ cah.longpoll.ErrorCodeHandlers.not_registered = function(data) {
cah.log.error("You will need to refresh the page to start a new game."); cah.log.error("You will need to refresh the page to start a new game.");
}; };
cah.longpoll.EventHandlers.new_player = function(data) { cah.longpoll.EventHandlers[cah.$.LongPollEvent.NEW_PLAYER] = function(data) {
// don't display our own join // don't display our own join
if (data.nickname != cah.nickname) { if (data.nickname != cah.nickname) {
cah.log.status(data.nickname + " has connected."); cah.log.status(data.nickname + " has connected.");
} }
}; };
cah.longpoll.EventHandlers.player_leave = function(data) { cah.longpoll.EventHandlers[cah.$.LongPollEvent.PLAYER_LEAVE] = function(data) {
var friendly_reason = "Leaving"; var friendly_reason = "Leaving";
// see net.socialgamer.cah.data.User.DisconnectReason
switch (data.reason) { switch (data.reason) {
case cah.$.DisconnectReason.KICKED: case cah.$.DisconnectReason.KICKED:
friendly_reason = "Kicked by server"; friendly_reason = "Kicked by server";
@ -35,11 +34,11 @@ cah.longpoll.EventHandlers.player_leave = function(data) {
cah.log.status(data.nickname + " has disconnected (" + friendly_reason + ")."); cah.log.status(data.nickname + " has disconnected (" + friendly_reason + ").");
}; };
cah.longpoll.EventHandlers.noop = function(data) { cah.longpoll.EventHandlers[cah.$.LongPollEvent.NOOP] = function(data) {
// pass // pass
}; };
cah.longpoll.EventHandlers.chat = function(data) { cah.longpoll.EventHandlers[cah.$.LongPollEvent.CHAT] = function(data) {
// TODO deal with multiple channels eventually // TODO deal with multiple channels eventually
// don't display our own chat // don't display our own chat
if (data.from != cah.nickname) { if (data.from != cah.nickname) {

View File

@ -10,6 +10,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ErrorCode;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.handlers.Handler; import net.socialgamer.cah.handlers.Handler;
import net.socialgamer.cah.handlers.Handlers; import net.socialgamer.cah.handlers.Handlers;
@ -37,7 +40,7 @@ public class AjaxServlet extends CahServlet {
try { try {
serial = Integer.parseInt(request.getParameter("serial")); serial = Integer.parseInt(request.getParameter("serial"));
} catch (final NumberFormatException nfe) { } catch (final NumberFormatException nfe) {
returnError(out, "bad_req", "Bad request"); returnError(out, ErrorCode.BAD_REQUEST, "Bad request");
return; return;
} }
} }
@ -45,7 +48,7 @@ public class AjaxServlet extends CahServlet {
final String op = request.getParameter("op"); final String op = request.getParameter("op");
// !Handlers.LIST.containsKey(op) // !Handlers.LIST.containsKey(op)
if (op == null || op.equals("")) { if (op == null || op.equals("")) {
returnError(out, "op_not_spec", "Operation not specified.", serial); returnError(out, ErrorCode.OP_NOT_SPECIFIED, "Operation not specified.", serial);
return; return;
} }
@ -53,11 +56,11 @@ public class AjaxServlet extends CahServlet {
try { try {
handler = getInjector().getInstance(Handlers.LIST.get(op)); handler = getInjector().getInstance(Handlers.LIST.get(op));
} catch (final Exception e) { } catch (final Exception e) {
returnError(out, "bad_op", "Invalid operation.", serial); returnError(out, ErrorCode.BAD_OP, "Invalid operation.", serial);
return; return;
} }
final Map<String, Object> data = handler.handle(request.getParameterMap(), hSession); final Map<ReturnableData, Object> data = handler.handle(request.getParameterMap(), hSession);
data.put("serial", serial); data.put(AjaxResponse.SERIAL, serial);
returnData(out, data); returnData(out, data);
return; return;
} }

View File

@ -11,6 +11,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ErrorCode;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.data.User; import net.socialgamer.cah.data.User;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
@ -45,19 +49,21 @@ public abstract class CahServlet extends HttpServlet {
final HttpSession hSession = request.getSession(true); final HttpSession hSession = request.getSession(true);
final String op = request.getParameter("op"); final String op = request.getParameter("op");
final boolean skipSessionUserCheck = op != null final boolean skipSessionUserCheck = op != null
&& (op.equals("register") || op.equals("firstload")); && (op.equals(AjaxOperation.REGISTER.toString())
|| op.equals(AjaxOperation.FIRST_LOAD.toString()));
if (hSession.isNew()) { if (hSession.isNew()) {
// they should have gotten a session from the index page. // they should have gotten a session from the index page.
// they probably don't have cookies on. // they probably don't have cookies on.
returnError(response.getWriter(), "no_session", returnError(response.getWriter(), ErrorCode.NO_SESSION,
"Session not detected. Make sure you have cookies enabled."); "Session not detected. Make sure you have cookies enabled.");
} else if (!skipSessionUserCheck && hSession.getAttribute("user") == null) { } else if (!skipSessionUserCheck && hSession.getAttribute("user") == null) {
returnError(response.getWriter(), "not_registered", "Not registered. Refresh the page."); returnError(response.getWriter(), ErrorCode.NOT_REGISTERED,
"Not registered. Refresh the page.");
} else if (hSession.getAttribute("user") != null } else if (hSession.getAttribute("user") != null
&& !(((User) hSession.getAttribute("user")).isValid())) { && !(((User) hSession.getAttribute("user")).isValid())) {
// user probably pinged out // user probably pinged out
hSession.invalidate(); hSession.invalidate();
returnError(response.getWriter(), "session_expired", returnError(response.getWriter(), ErrorCode.SESSION_EXPIRED,
"Your session has expired. Refresh the page."); "Your session has expired. Refresh the page.");
} else { } else {
handleRequest(request, response, hSession); handleRequest(request, response, hSession);
@ -87,7 +93,7 @@ public abstract class CahServlet extends HttpServlet {
* @param message * @param message
* User-visible error message. * User-visible error message.
*/ */
protected void returnError(final PrintWriter writer, final String code, final String message) { protected void returnError(final PrintWriter writer, final ErrorCode code, final String message) {
returnError(writer, code, message, -1); returnError(writer, code, message, -1);
} }
@ -99,12 +105,12 @@ public abstract class CahServlet extends HttpServlet {
* @param serial * @param serial
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected void returnError(final PrintWriter writer, final String code, final String message, protected void returnError(final PrintWriter writer, final ErrorCode code, final String message,
final int serial) { final int serial) {
final JSONObject ret = new JSONObject(); final JSONObject ret = new JSONObject();
ret.put("error", Boolean.TRUE); ret.put(AjaxResponse.ERROR, Boolean.TRUE);
ret.put("error_code", code); ret.put(AjaxResponse.ERROR_CODE, code.toString());
ret.put("error_message", message); ret.put(AjaxResponse.ERROR_MESSAGE, message);
writer.println(ret.toJSONString()); writer.println(ret.toJSONString());
} }
@ -116,7 +122,7 @@ public abstract class CahServlet extends HttpServlet {
* @param data * @param data
* Key-value data to return as the response. * Key-value data to return as the response.
*/ */
protected void returnData(final PrintWriter writer, final Map<String, Object> data) { protected void returnData(final PrintWriter writer, final Map<ReturnableData, Object> data) {
returnObject(writer, data); returnObject(writer, data);
} }
@ -128,7 +134,8 @@ public abstract class CahServlet extends HttpServlet {
* @param data_list * @param data_list
* List of key-value data to return as the response. * List of key-value data to return as the response.
*/ */
protected void returnArray(final PrintWriter writer, final List<Map<String, Object>> data_list) { protected void returnArray(final PrintWriter writer,
final List<Map<ReturnableData, Object>> data_list) {
returnObject(writer, data_list); returnObject(writer, data_list);
} }

View File

@ -1,8 +1,13 @@
package net.socialgamer.cah; package net.socialgamer.cah;
public class Constants { public class Constants {
public interface ReturnableData {
}
public enum DisconnectReason { public enum DisconnectReason {
KICKED("kicked"), MANUAL("manual"), PING_TIMEOUT("ping_timeout"); KICKED("kicked"),
MANUAL("manual"),
PING_TIMEOUT("ping_timeout");
private final String reason; private final String reason;
@ -17,7 +22,11 @@ public class Constants {
} }
public enum AjaxOperation { public enum AjaxOperation {
CHAT("chat"), FIRST_LOAD("firstload"), LOG_OUT("logout"), NAMES("names"), REGISTER("register"); CHAT("chat"),
FIRST_LOAD("firstload"),
LOG_OUT("logout"),
NAMES("names"),
REGISTER("register");
private final String op; private final String op;
@ -30,4 +39,100 @@ public class Constants {
return op; return op;
} }
} }
public enum AjaxRequest {
SERIAL("serial");
private final String field;
AjaxRequest(final String field) {
this.field = field;
}
@Override
public String toString() {
return field;
}
}
public enum AjaxResponse implements ReturnableData {
ERROR("error"),
ERROR_CODE("error_code"),
ERROR_MESSAGE("error_message"),
IN_PROGRESS("in_progress"),
NAMES("names"),
NEXT("next"),
NICKNAME("nickname"),
SERIAL("serial");
private final String field;
AjaxResponse(final String field) {
this.field = field;
}
@Override
public String toString() {
return field;
}
}
public enum ErrorCode {
BAD_OP("bad_op"),
BAD_REQUEST("bad_req"),
NO_SESSION("no_session"),
NOT_REGISTERED("not_registered"),
OP_NOT_SPECIFIED("op_not_spec"),
SESSION_EXPIRED("session_expired");
private final String code;
ErrorCode(final String code) {
this.code = code;
}
@Override
public String toString() {
return code;
}
}
public enum LongPollEvent {
CHAT("chat"),
NEW_PLAYER("new_player"),
NOOP("noop"),
PLAYER_LEAVE("player_leave");
private final String event;
LongPollEvent(final String event) {
this.event = event;
}
@Override
public String toString() {
return event;
}
}
public enum LongPollResponse implements ReturnableData {
EVENT("event"),
FROM("from"),
GAME_ID("game_id"),
MESSAGE("message"),
NICKNAME("nickname"),
REASON("reason"),
TIMESTAMP("timestamp");
private final String field;
LongPollResponse(final String field) {
this.field = field;
}
@Override
public String toString() {
return field;
}
}
} }

View File

@ -15,6 +15,9 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.LongPollEvent;
import net.socialgamer.cah.Constants.LongPollResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.data.QueuedMessage; import net.socialgamer.cah.data.QueuedMessage;
import net.socialgamer.cah.data.User; import net.socialgamer.cah.data.User;
@ -37,6 +40,7 @@ public class LongPollServlet extends CahServlet {
* will be TIMEOUT_BASE + TIMEOUT_RANDOMNESS. * will be TIMEOUT_BASE + TIMEOUT_RANDOMNESS.
*/ */
private static final double TIMEOUT_RANDOMNESS = 20 * 1000 * 1000; private static final double TIMEOUT_RANDOMNESS = 20 * 1000 * 1000;
// private static final double TIMEOUT_RANDOMNESS = 0;
/** /**
* The maximum number of messages which will be returned to a client during a single poll * The maximum number of messages which will be returned to a client during a single poll
@ -72,7 +76,8 @@ public class LongPollServlet extends CahServlet {
final Collection<QueuedMessage> msgs = user.getNextQueuedMessages(MAX_MESSAGES_PER_POLL); final Collection<QueuedMessage> msgs = user.getNextQueuedMessages(MAX_MESSAGES_PER_POLL);
// just in case... // just in case...
if (msgs.size() > 0) { if (msgs.size() > 0) {
final List<Map<String, Object>> data = new ArrayList<Map<String, Object>>(msgs.size()); final List<Map<ReturnableData, Object>> data = new ArrayList<Map<ReturnableData, Object>>(
msgs.size());
for (final QueuedMessage qm : msgs) { for (final QueuedMessage qm : msgs) {
data.add(qm.getData()); data.add(qm.getData());
} }
@ -81,11 +86,9 @@ public class LongPollServlet extends CahServlet {
} }
} }
// otherwise, return that there is no new data // otherwise, return that there is no new data
final Map<String, Object> data = new HashMap<String, Object>(); final Map<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put("event", "noop"); data.put(LongPollResponse.EVENT, LongPollEvent.NOOP.toString());
data.put("timestamp", System.currentTimeMillis()); data.put(LongPollResponse.TIMESTAMP, System.currentTimeMillis());
final List<Map<String, Object>> data_list = new ArrayList<Map<String, Object>>(1); returnData(out, data);
data_list.add(data);
returnArray(out, data_list);
} }
} }

View File

@ -7,6 +7,8 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import net.socialgamer.cah.Constants.DisconnectReason; import net.socialgamer.cah.Constants.DisconnectReason;
import net.socialgamer.cah.Constants.LongPollResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.data.QueuedMessage.MessageType; import net.socialgamer.cah.data.QueuedMessage.MessageType;
@ -34,9 +36,9 @@ public class ConnectedUsers {
public void newUser(final User user) { public void newUser(final User user) {
synchronized (users) { synchronized (users) {
users.put(user.getNickname(), user); users.put(user.getNickname(), user);
final HashMap<String, Object> data = new HashMap<String, Object>(); final HashMap<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put("event", "new_player"); data.put(LongPollResponse.EVENT, "new_player");
data.put("nickname", user.getNickname()); data.put(LongPollResponse.NICKNAME, user.getNickname());
broadcastToAll(MessageType.PLAYER_EVENT, data); broadcastToAll(MessageType.PLAYER_EVENT, data);
} }
} }
@ -50,10 +52,10 @@ public class ConnectedUsers {
private void notifyRemoveUser(final User user, final DisconnectReason reason) { private void notifyRemoveUser(final User user, final DisconnectReason reason) {
// We might also have to tell games about this directly, probably with a listener system. // We might also have to tell games about this directly, probably with a listener system.
final HashMap<String, Object> data = new HashMap<String, Object>(); final HashMap<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put("event", "player_leave"); data.put(LongPollResponse.EVENT, "player_leave");
data.put("nickname", user.getNickname()); data.put(LongPollResponse.NICKNAME, user.getNickname());
data.put("reason", reason.toString()); data.put(LongPollResponse.REASON, reason.toString());
broadcastToAll(MessageType.PLAYER_EVENT, data); broadcastToAll(MessageType.PLAYER_EVENT, data);
} }
@ -77,7 +79,8 @@ public class ConnectedUsers {
* @param type * @param type
* @param masterData * @param masterData
*/ */
public void broadcastToAll(final MessageType type, final HashMap<String, Object> masterData) { public void broadcastToAll(final MessageType type,
final HashMap<ReturnableData, Object> masterData) {
broadcastToList(users.values(), type, masterData); broadcastToList(users.values(), type, masterData);
} }
@ -89,12 +92,12 @@ public class ConnectedUsers {
* @param masterData * @param masterData
*/ */
public void broadcastToList(final Collection<User> broadcastTo, final MessageType type, public void broadcastToList(final Collection<User> broadcastTo, final MessageType type,
final HashMap<String, Object> masterData) { final HashMap<ReturnableData, Object> masterData) {
synchronized (users) { synchronized (users) {
for (final User u : broadcastTo) { for (final User u : broadcastTo) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final Map<String, Object> data = (Map<String, Object>) masterData.clone(); final Map<ReturnableData, Object> data = (Map<ReturnableData, Object>) masterData.clone();
data.put("timestamp", System.currentTimeMillis()); data.put(LongPollResponse.TIMESTAMP, System.currentTimeMillis());
final QueuedMessage qm = new QueuedMessage(type, data); final QueuedMessage qm = new QueuedMessage(type, data);
u.enqueueMessage(qm); u.enqueueMessage(qm);
} }

View File

@ -5,6 +5,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import net.socialgamer.cah.Constants.LongPollResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.data.QueuedMessage.MessageType; import net.socialgamer.cah.data.QueuedMessage.MessageType;
@ -37,10 +39,10 @@ public class Game {
} }
} }
final HashMap<String, Object> data = new HashMap<String, Object>(); final HashMap<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put("event", "game_player_join"); data.put(LongPollResponse.EVENT, "game_player_join");
data.put("game_id", id); data.put(LongPollResponse.GAME_ID, id);
data.put("nickname", user.getNickname()); data.put(LongPollResponse.NICKNAME, user.getNickname());
broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data); broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data);
} }
@ -56,10 +58,10 @@ public class Game {
final Player player = iterator.next(); final Player player = iterator.next();
if (player.getUser() == user) { if (player.getUser() == user) {
iterator.remove(); iterator.remove();
final HashMap<String, Object> data = new HashMap<String, Object>(); final HashMap<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put("event", "game_player_leave"); data.put(LongPollResponse.EVENT, "game_player_leave");
data.put("game_id", id); data.put(LongPollResponse.GAME_ID, id);
data.put("nickname", user.getNickname()); data.put(LongPollResponse.NICKNAME, user.getNickname());
broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data); broadcastToPlayers(MessageType.GAME_PLAYER_EVENT, data);
if (host == player) { if (host == player) {
if (players.size() > 0) { if (players.size() > 0) {
@ -75,7 +77,8 @@ public class Game {
} }
} }
public void broadcastToPlayers(final MessageType type, final HashMap<String, Object> masterData) { public void broadcastToPlayers(final MessageType type,
final HashMap<ReturnableData, Object> masterData) {
connectedUsers.broadcastToList(playersToUsers(), type, masterData); connectedUsers.broadcastToList(playersToUsers(), type, masterData);
} }

View File

@ -2,13 +2,15 @@ package net.socialgamer.cah.data;
import java.util.Map; import java.util.Map;
import net.socialgamer.cah.Constants.ReturnableData;
public class QueuedMessage implements Comparable<QueuedMessage> { public class QueuedMessage implements Comparable<QueuedMessage> {
private final MessageType messageType; private final MessageType messageType;
private final Map<String, Object> data; private final Map<ReturnableData, Object> data;
public QueuedMessage(final MessageType messageType, final Map<String, Object> data) { public QueuedMessage(final MessageType messageType, final Map<ReturnableData, Object> data) {
this.messageType = messageType; this.messageType = messageType;
this.data = data; this.data = data;
} }
@ -17,7 +19,7 @@ public class QueuedMessage implements Comparable<QueuedMessage> {
return messageType; return messageType;
} }
public Map<String, Object> getData() { public Map<ReturnableData, Object> getData() {
return data; return data;
} }

View File

@ -6,6 +6,9 @@ import java.util.Map;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation; import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.LongPollEvent;
import net.socialgamer.cah.Constants.LongPollResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.Server; import net.socialgamer.cah.Server;
import net.socialgamer.cah.data.ConnectedUsers; import net.socialgamer.cah.data.ConnectedUsers;
import net.socialgamer.cah.data.QueuedMessage.MessageType; import net.socialgamer.cah.data.QueuedMessage.MessageType;
@ -26,9 +29,9 @@ public class ChatHandler extends Handler {
} }
@Override @Override
public Map<String, Object> handle(final Map<String, String[]> parameters, public Map<ReturnableData, Object> handle(final Map<String, String[]> parameters,
final HttpSession session) { final HttpSession session) {
final Map<String, Object> data = new HashMap<String, Object>(); final Map<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
final User user = (User) session.getAttribute("user"); final User user = (User) session.getAttribute("user");
assert (user != null); assert (user != null);
@ -40,10 +43,10 @@ public class ChatHandler extends Handler {
if (message.length() > 200) { if (message.length() > 200) {
return error("Messages cannot be longer than 200 characters."); return error("Messages cannot be longer than 200 characters.");
} else { } else {
final HashMap<String, Object> broadcastData = new HashMap<String, Object>(); final HashMap<ReturnableData, Object> broadcastData = new HashMap<ReturnableData, Object>();
broadcastData.put("event", "chat"); broadcastData.put(LongPollResponse.EVENT, LongPollEvent.CHAT.toString());
broadcastData.put("from", user.getNickname()); broadcastData.put(LongPollResponse.FROM, user.getNickname());
broadcastData.put("message", message); broadcastData.put(LongPollResponse.MESSAGE, message);
// TODO once there are multiple chat channels, put the destination here // TODO once there are multiple chat channels, put the destination here
// TODO once there are games and they have their own chat, make it only send to participants // TODO once there are games and they have their own chat, make it only send to participants
users.broadcastToAll(MessageType.CHAT, broadcastData); users.broadcastToAll(MessageType.CHAT, broadcastData);

View File

@ -6,6 +6,8 @@ import java.util.Map;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation; import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.data.User; import net.socialgamer.cah.data.User;
@ -21,21 +23,21 @@ public class FirstLoadHandler extends Handler {
public static final String OP = AjaxOperation.FIRST_LOAD.toString(); public static final String OP = AjaxOperation.FIRST_LOAD.toString();
@Override @Override
public Map<String, Object> handle(final Map<String, String[]> parameters, public Map<ReturnableData, Object> handle(final Map<String, String[]> parameters,
final HttpSession session) { final HttpSession session) {
final HashMap<String, Object> ret = new HashMap<String, Object>(); final HashMap<ReturnableData, Object> ret = new HashMap<ReturnableData, Object>();
final User user = (User) session.getAttribute("user"); final User user = (User) session.getAttribute("user");
if (user == null) { if (user == null) {
ret.put("in_progress", Boolean.FALSE); ret.put(AjaxResponse.IN_PROGRESS, Boolean.FALSE);
ret.put("next", "register"); ret.put(AjaxResponse.NEXT, "register");
} else { } else {
// They already have a session in progress, we need to figure out what they were doing // They already have a session in progress, we need to figure out what they were doing
// and tell the client where to continue from. // and tell the client where to continue from.
// Right now we just tell them what their name is. // Right now we just tell them what their name is.
ret.put("in_progress", Boolean.TRUE); ret.put(AjaxResponse.IN_PROGRESS, Boolean.TRUE);
ret.put("next", ""); // TODO ret.put(AjaxResponse.NEXT, ""); // TODO
ret.put("nickname", user.getNickname()); ret.put(AjaxResponse.NICKNAME, user.getNickname());
} }
return ret; return ret;

View File

@ -5,6 +5,9 @@ import java.util.Map;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ReturnableData;
/** /**
* Implementations of this interface MUST also have a public static final String OP. * Implementations of this interface MUST also have a public static final String OP.
@ -13,12 +16,13 @@ import javax.servlet.http.HttpSession;
* *
*/ */
public abstract class Handler { public abstract class Handler {
public abstract Map<String, Object> handle(Map<String, String[]> parameters, HttpSession session); public abstract Map<ReturnableData, Object> handle(Map<String, String[]> parameters,
HttpSession session);
protected Map<String, Object> error(final String message) { protected Map<ReturnableData, Object> error(final String message) {
final Map<String, Object> data = new HashMap<String, Object>(); final Map<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
data.put("error", Boolean.TRUE); data.put(AjaxResponse.ERROR, Boolean.TRUE);
data.put("error_message", message); data.put(AjaxResponse.ERROR_MESSAGE, message);
return data; return data;
} }
} }

View File

@ -7,6 +7,7 @@ import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation; import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.DisconnectReason; import net.socialgamer.cah.Constants.DisconnectReason;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.Server; import net.socialgamer.cah.Server;
import net.socialgamer.cah.data.ConnectedUsers; import net.socialgamer.cah.data.ConnectedUsers;
import net.socialgamer.cah.data.User; import net.socialgamer.cah.data.User;
@ -26,9 +27,9 @@ public class LogoutHandler extends Handler {
} }
@Override @Override
public Map<String, Object> handle(final Map<String, String[]> parameters, public Map<ReturnableData, Object> handle(final Map<String, String[]> parameters,
final HttpSession session) { final HttpSession session) {
final Map<String, Object> data = new HashMap<String, Object>(); final Map<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
final User user = (User) session.getAttribute("user"); final User user = (User) session.getAttribute("user");
assert (user != null); assert (user != null);

View File

@ -9,6 +9,8 @@ import java.util.Map;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation; import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.Server; import net.socialgamer.cah.Server;
import net.socialgamer.cah.data.ConnectedUsers; import net.socialgamer.cah.data.ConnectedUsers;
import net.socialgamer.cah.data.User; import net.socialgamer.cah.data.User;
@ -28,16 +30,16 @@ public class NamesHandler extends Handler {
} }
@Override @Override
public Map<String, Object> handle(final Map<String, String[]> parameters, public Map<ReturnableData, Object> handle(final Map<String, String[]> parameters,
final HttpSession session) { final HttpSession session) {
final HashMap<String, Object> ret = new HashMap<String, Object>(); final Map<ReturnableData, Object> ret = new HashMap<ReturnableData, Object>();
// TODO once there are multiple rooms, we needCollection<E>hich one was asked for // TODO once there are multiple rooms, we needCollection<E>hich one was asked for
final Collection<User> userList = users.getUsers(); final Collection<User> userList = users.getUsers();
final List<String> names = new ArrayList<String>(userList.size()); final List<String> names = new ArrayList<String>(userList.size());
for (final User u : userList) { for (final User u : userList) {
names.add(u.getNickname()); names.add(u.getNickname());
} }
ret.put("names", names); ret.put(AjaxResponse.NAMES, names);
return ret; return ret;
} }
} }

View File

@ -7,6 +7,8 @@ import java.util.regex.Pattern;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation; import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import net.socialgamer.cah.Server; import net.socialgamer.cah.Server;
import net.socialgamer.cah.data.ConnectedUsers; import net.socialgamer.cah.data.ConnectedUsers;
import net.socialgamer.cah.data.User; import net.socialgamer.cah.data.User;
@ -34,9 +36,9 @@ public class RegisterHandler extends Handler {
} }
@Override @Override
public Map<String, Object> handle(final Map<String, String[]> parameters, public Map<ReturnableData, Object> handle(final Map<String, String[]> parameters,
final HttpSession session) { final HttpSession session) {
final Map<String, Object> data = new HashMap<String, Object>(); final Map<ReturnableData, Object> data = new HashMap<ReturnableData, Object>();
if (!parameters.containsKey("nickname") || parameters.get("nickname").length != 1) { if (!parameters.containsKey("nickname") || parameters.get("nickname").length != 1) {
return error("No nickname specified."); return error("No nickname specified.");
@ -52,7 +54,7 @@ public class RegisterHandler extends Handler {
users.newUser(user); users.newUser(user);
session.setAttribute("user", user); session.setAttribute("user", user);
data.put("nickname", nick); data.put(AjaxResponse.NICKNAME, nick);
} }
} }
return data; return data;