package net.cubespace.dynmap.multiserver.HTTP.Handler; import com.google.gson.Gson; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaders; import net.cubespace.dynmap.multiserver.Config.Main; import net.cubespace.dynmap.multiserver.DynmapServer; import net.cubespace.dynmap.multiserver.GSON.Component; import net.cubespace.dynmap.multiserver.GSON.DynmapConfig; import net.cubespace.dynmap.multiserver.GSON.DynmapWorld; import net.cubespace.dynmap.multiserver.HTTP.HandlerUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import static io.netty.handler.codec.http.HttpHeaders.Names.*; import static io.netty.handler.codec.http.HttpResponseStatus.OK; import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; /** * @author geNAZt (fabian.fassbender42@googlemail.com) */ public class DynmapConfigJSONHandler implements IHandler { static Logger logger = LoggerFactory.getLogger(DynmapConfigJSONHandler.class); private static DynmapConfigJSONUpdater dynmapConfigJSONUpdater; private static String responseStr; private static DynmapConfig config; private static Gson gson; private static long start = 0; private class DynmapConfigJSONUpdater extends Thread { public DynmapConfigJSONUpdater() { setName("DynmapConfigJSONUpdater"); } public void run() { while (true) { try { updateJson(); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public DynmapConfigJSONHandler(Main mainConfig) { if (gson == null) gson = new Gson(); if (config == null) { config = new DynmapConfig(); config.setDefaultmap("flat"); config.setDefaultworld("world"); config.setConfighash(0); config.setTitle(mainConfig.Webserver_Title); responseStr = gson.toJson(config); } if (start == 0) start = System.currentTimeMillis(); if (dynmapConfigJSONUpdater == null) { dynmapConfigJSONUpdater = new DynmapConfigJSONUpdater(); dynmapConfigJSONUpdater.start(); } } private void updateJson() { //Worlds List<DynmapWorld> dynmapWorlds = new ArrayList<>(); List<Component> components = new ArrayList<>(); ArrayList<String> addedComponents = new ArrayList<>(); config.setConfighash(0); String temp = gson.toJson(config); for (DynmapServer dynmapServer : net.cubespace.dynmap.multiserver.Main.getDynmapServers()) { dynmapWorlds.addAll(dynmapServer.getWorlds()); for (Component component : dynmapServer.getComponents()) { if (component != null) { if (!addedComponents.contains(component.type)) { addedComponents.add(component.type); components.add(component); } } } } config.setWorlds(dynmapWorlds); config.setComponents(components); config.setCoreversion(net.cubespace.dynmap.multiserver.Main.getCoreVersion()); config.setDynmapversion(net.cubespace.dynmap.multiserver.Main.getDynmapVersion()); if (!responseStr.equals(temp)) { config.setConfighash(0); responseStr = gson.toJson(config); start = System.currentTimeMillis(); } } @Override public void handle(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { // Cache Validation String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE); if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HandlerUtil.HTTP_DATE_FORMAT, Locale.US); Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); // Only compare up to the second because the datetime format we send to the client // does not have milliseconds long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000; long fileLastModifiedSeconds = start / 1000; if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { HandlerUtil.sendNotModified(ctx); return; } } FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(responseStr.getBytes())); HandlerUtil.setDateAndCacheHeaders(response, start); response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8"); response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); response.headers().set(CONNECTION, HttpHeaders.Values.CLOSE); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }