diff --git a/WebContent/admin.jsp b/WebContent/admin.jsp index 8d72147..8000315 100644 --- a/WebContent/admin.jsp +++ b/WebContent/admin.jsp @@ -2,19 +2,33 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="com.google.inject.Injector" %> +<%@ page import="net.socialgamer.cah.Constants.DisconnectReason" %> +<%@ page import="net.socialgamer.cah.Constants.LongPollEvent" %> +<%@ page import="net.socialgamer.cah.Constants.LongPollResponse" %> +<%@ page import="net.socialgamer.cah.Constants.ReturnableData" %> <%@ page import="net.socialgamer.cah.StartupUtils" %> <%@ page import="net.socialgamer.cah.data.ConnectedUsers" %> +<%@ page import="net.socialgamer.cah.data.QueuedMessage" %> +<%@ page import="net.socialgamer.cah.data.QueuedMessage.MessageType" %> <%@ page import="net.socialgamer.cah.data.User" %> <%@ page import="java.util.Collection" %> <%@ page import="java.util.Date" %> +<%@ page import="java.util.HashMap" %> +<%@ page import="java.util.Map" %> <% String remoteAddr = request.getRemoteAddr(); -if (!(remoteAddr.equals("0:0:0:0:0:0:0:1") || remoteAddr.equals("127.0.0.1"))) { +// TODO better access control than hard-coding IP addresses. +if (!(remoteAddr.equals("0:0:0:0:0:0:0:1") || remoteAddr.equals("127.0.0.1") || + remoteAddr.equals("98.248.33.90"))) { response.sendError(403, "Access is restricted to known hosts"); + return; } ServletContext servletContext = pageContext.getServletContext(); +Injector injector = (Injector) servletContext.getAttribute(StartupUtils.INJECTOR); + +ConnectedUsers connectedUsers = injector.getInstance(ConnectedUsers.class); // process verbose toggle String verboseParam = request.getParameter("verbose"); @@ -24,11 +38,29 @@ if (verboseParam != null) { } else { servletContext.setAttribute(StartupUtils.VERBOSE_DEBUG, Boolean.FALSE); } + response.sendRedirect("admin.jsp"); + return; +} + +// process kick +String kickParam = request.getParameter("kick"); +if (kickParam != null) { + User user = connectedUsers.getUser(kickParam); + if (user != null) { + Map data = new HashMap(); + data.put(LongPollResponse.EVENT, LongPollEvent.KICKED.toString()); + QueuedMessage qm = new QueuedMessage(MessageType.KICKED, data); + user.enqueueMessage(qm); + + connectedUsers.removeUser(user, DisconnectReason.KICKED); + } + response.sendRedirect("admin.jsp"); + return; } %> - - + @@ -45,20 +77,16 @@ th, td { -<% -Injector injector = (Injector) servletContext.getAttribute(StartupUtils.INJECTOR); -%> -

Server up since <% Date startedDate = (Date) servletContext.getAttribute(StartupUtils.DATE_NAME); long uptime = System.currentTimeMillis() - startedDate.getTime(); - uptime /= 1000l; - long seconds = uptime % 60l; - long minutes = (uptime / 60l) % 60l; - long hours = (uptime / 60l / 60l) % 24l; - long days = (uptime / 60l / 60l / 24l); + uptime /= 1000L; + long seconds = uptime % 60L; + long minutes = (uptime / 60L) % 60L; + long hours = (uptime / 60L / 60L) % 24L; + long days = (uptime / 60L / 60L / 24L); out.print(String.format("%s (%d hours, %02d:%02d:%02d)", startedDate.toString(), days, hours, minutes, seconds)); %> @@ -72,38 +100,37 @@ Injector injector = (Injector) servletContext.getAttribute(StartupUtils.INJECTOR In Use <% out.print((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) - / 1024 / 1024); %> + / 1024L / 1024L); %> Free - <% out.print(Runtime.getRuntime().freeMemory() / 1024 / 1024); %> + <% out.print(Runtime.getRuntime().freeMemory() / 1024L / 1024L); %> JVM Allocated - <% out.print(Runtime.getRuntime().totalMemory() / 1024 / 1024); %> + <% out.print(Runtime.getRuntime().totalMemory() / 1024L / 1024L); %> JVM Max - <% out.print(Runtime.getRuntime().maxMemory() / 1024 / 1024); %> + <% out.print(Runtime.getRuntime().maxMemory() / 1024L / 1024L); %> - -<% -ConnectedUsers connectedUsers = injector.getInstance(ConnectedUsers.class); -Collection users = connectedUsers.getUsers(); -%>
+ <% + Collection users = connectedUsers.getUsers(); for (User u : users) { + // TODO have a ban system. would need to store them somewhere. %> + <% } diff --git a/WebContent/js/cah.constants.js b/WebContent/js/cah.constants.js index d31f565..9896591 100644 --- a/WebContent/js/cah.constants.js +++ b/WebContent/js/cah.constants.js @@ -193,13 +193,14 @@ cah.$.LongPollEvent = function() { // Dummy constructor to make Eclipse auto-complete. }; cah.$.LongPollEvent.prototype.dummyForAutocomplete = undefined; +cah.$.LongPollEvent.KICKED = "kicked"; cah.$.LongPollEvent.GAME_PLAYER_LEAVE = "game_player_leave"; cah.$.LongPollEvent.NEW_PLAYER = "new_player"; cah.$.LongPollEvent.GAME_PLAYER_JOIN = "game_player_join"; cah.$.LongPollEvent.GAME_LIST_REFRESH = "game_list_refresh"; cah.$.LongPollEvent.GAME_ROUND_COMPLETE = "game_round_complete"; -cah.$.LongPollEvent.GAME_PLAYER_INFO_CHANGE = "game_player_info_change"; cah.$.LongPollEvent.NOOP = "noop"; +cah.$.LongPollEvent.GAME_PLAYER_INFO_CHANGE = "game_player_info_change"; cah.$.LongPollEvent.GAME_BLACK_RESHUFFLE = "game_black_reshuffle"; cah.$.LongPollEvent.GAME_WHITE_RESHUFFLE = "game_white_reshuffle"; cah.$.LongPollEvent.GAME_STATE_CHANGE = "game_state_change"; diff --git a/WebContent/js/cah.longpoll.handlers.js b/WebContent/js/cah.longpoll.handlers.js index 2a290a0..8a51be6 100644 --- a/WebContent/js/cah.longpoll.handlers.js +++ b/WebContent/js/cah.longpoll.handlers.js @@ -38,6 +38,15 @@ cah.longpoll.EventHandlers[cah.$.LongPollEvent.NOOP] = function(data) { // pass }; +cah.longpoll.EventHandlers[cah.$.LongPollEvent.KICKED] = function() { + cah.log.status("You have been kicked by the server administrator."); + cah.longpoll.Resume = false; + $("input").attr("disabled", "disabled"); + $("#menubar_left").empty(); + $("#main").empty(); + $("#info_area").empty(); +}; + cah.longpoll.EventHandlers[cah.$.LongPollEvent.CHAT] = function(data) { // TODO deal with multiple channels eventually // don't display our own chat diff --git a/src/net/socialgamer/cah/Constants.java b/src/net/socialgamer/cah/Constants.java index 3fe4119..5862901 100644 --- a/src/net/socialgamer/cah/Constants.java +++ b/src/net/socialgamer/cah/Constants.java @@ -210,6 +210,7 @@ public class Constants { GAME_STATE_CHANGE("game_state_change"), GAME_WHITE_RESHUFFLE("game_white_reshuffle"), HAND_DEAL("hand_deal"), + KICKED("kicked"), NEW_PLAYER("new_player"), NOOP("noop"), PLAYER_LEAVE("player_leave"); diff --git a/src/net/socialgamer/cah/data/ConnectedUsers.java b/src/net/socialgamer/cah/data/ConnectedUsers.java index 736a75a..c37579c 100644 --- a/src/net/socialgamer/cah/data/ConnectedUsers.java +++ b/src/net/socialgamer/cah/data/ConnectedUsers.java @@ -12,6 +12,7 @@ import net.socialgamer.cah.Constants.ReturnableData; import net.socialgamer.cah.data.QueuedMessage.MessageType; import com.google.inject.Singleton; +import com.sun.istack.internal.Nullable; /** @@ -47,11 +48,25 @@ public class ConnectedUsers { public void removeUser(final User user, final DisconnectReason reason) { synchronized (users) { - users.remove(user.getNickname()); - notifyRemoveUser(user, reason); + if (users.containsValue(user)) { + user.noLongerVaild(); + users.remove(user.getNickname()); + notifyRemoveUser(user, reason); + } } } + /** + * Get the User for the specified nickname, or null if no such user exists. + * + * @param nickname + * @return User, or null. + */ + @Nullable + public User getUser(final String nickname) { + return users.get(nickname); + } + private void notifyRemoveUser(final User user, final DisconnectReason reason) { // We might also have to tell games about this directly, probably with a listener system. final HashMap data = new HashMap(); diff --git a/src/net/socialgamer/cah/data/QueuedMessage.java b/src/net/socialgamer/cah/data/QueuedMessage.java index f9e75dc..8df2316 100644 --- a/src/net/socialgamer/cah/data/QueuedMessage.java +++ b/src/net/socialgamer/cah/data/QueuedMessage.java @@ -44,7 +44,7 @@ public class QueuedMessage implements Comparable { * @author ajanata */ public enum MessageType { - PLAYER_EVENT(3), GAME_EVENT(3), GAME_PLAYER_EVENT(4), CHAT(5); + KICKED(1), PLAYER_EVENT(3), GAME_EVENT(3), GAME_PLAYER_EVENT(4), CHAT(5); private final int weight;
Username HostActions
<% out.print(u.getNickname()); %> <% out.print(u.getHostName()); %>Kick