package org.dynmap.servlet; import static org.dynmap.JSONUtils.s; import static org.dynmap.JSONUtils.g; import java.io.IOException; import java.nio.charset.Charset; import java.util.Date; import java.util.ListIterator; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.dynmap.Client; import org.dynmap.DynmapCore; import org.dynmap.DynmapWorld; import org.dynmap.InternalClientUpdateComponent; import org.dynmap.web.HttpField; import org.json.simple.JSONArray; import org.json.simple.JSONObject; @SuppressWarnings("serial") public class ClientUpdateServlet extends HttpServlet { private DynmapCore core; private Charset cs_utf8 = Charset.forName("UTF-8"); public ClientUpdateServlet(DynmapCore plugin) { this.core = plugin; } Pattern updatePathPattern = Pattern.compile("/([^/]+)/([0-9]*)"); @SuppressWarnings("unchecked") @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { byte[] bytes; HttpSession sess = req.getSession(true); String user = (String) sess.getAttribute(LoginServlet.USERID_ATTRIB); if(user == null) user = LoginServlet.USERID_GUEST; boolean guest = user.equals(LoginServlet.USERID_GUEST); if(core.getLoginRequired() && guest) { JSONObject json = new JSONObject(); s(json, "error", "login-required"); bytes = json.toJSONString().getBytes(cs_utf8); } else { String path = req.getPathInfo(); Matcher match = updatePathPattern.matcher(path); if (!match.matches()) { resp.sendError(404, "World not found"); return; } String worldName = match.group(1); String timeKey = match.group(2); DynmapWorld dynmapWorld = null; if(core.mapManager != null) { dynmapWorld = core.mapManager.getWorld(worldName); } if (dynmapWorld == null) { resp.sendError(404, "World not found"); return; } long since = 0; try { since = Long.parseLong(timeKey); } catch (NumberFormatException e) { } JSONObject u = new JSONObject(); //s(u, "timestamp", current); JSONObject upd = InternalClientUpdateComponent.getWorldUpdate(dynmapWorld.getName()); if(upd != null) u.putAll(upd); boolean see_all = true; if(core.player_info_protected) { if(guest) { see_all = false; } else { see_all = core.getServer().checkPlayerPermission(user, "playermarkers.seeall"); } } if(!see_all) { JSONArray players = (JSONArray)g(u, "players"); JSONArray newplayers = new JSONArray(); u.put("players", newplayers); if(players != null) { for(ListIterator<JSONObject> iter = players.listIterator(); iter.hasNext();) { JSONObject p = iter.next(); JSONObject newp = new JSONObject(); newp.putAll(p); newplayers.add(newp); boolean hide; if(!guest) { hide = !core.testIfPlayerVisibleToPlayer(user, (String)newp.get("name")); } else { hide = true; } if(hide) { s(newp, "world", "-some-other-bogus-world-"); s(newp, "x", 0.0); s(newp, "y", 64.0); s(newp, "z", 0.0); s(newp, "health", 0); s(newp, "armor", 0); } } } } JSONArray updates = (JSONArray)u.get("updates"); JSONArray newupdates = new JSONArray(); u.put("updates", newupdates); if(updates != null) { for(ListIterator<Client.Update> iter = updates.listIterator(); iter.hasNext();) { Client.Update update = iter.next(); if(update.timestamp >= since) { newupdates.add(update); } } } bytes = u.toJSONString().getBytes(cs_utf8); } String dateStr = new Date().toString(); resp.addHeader(HttpField.Date, dateStr); resp.addHeader(HttpField.ContentType, "text/plain; charset=utf-8"); resp.addHeader(HttpField.Expires, "Thu, 01 Dec 1994 16:00:00 GMT"); resp.addHeader(HttpField.LastModified, dateStr); resp.addHeader(HttpField.ContentLength, Integer.toString(bytes.length)); resp.getOutputStream().write(bytes); } }