diff --git a/Plan Advanced/src/com/djrapitops/plan/Plan.java b/Plan Advanced/src/com/djrapitops/plan/Plan.java index 9506af685..9433503cb 100644 --- a/Plan Advanced/src/com/djrapitops/plan/Plan.java +++ b/Plan Advanced/src/com/djrapitops/plan/Plan.java @@ -2,6 +2,7 @@ package com.djrapitops.plan; import com.djrapitops.plan.command.PlanCommand; import com.djrapitops.plan.api.API; +import com.djrapitops.plan.data.cache.AnalysisCacheHandler; import com.djrapitops.planlite.api.Hook; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.database.Database; @@ -10,6 +11,7 @@ import com.djrapitops.plan.database.databases.SQLiteDB; import com.djrapitops.plan.data.cache.DataCacheHandler; import com.djrapitops.plan.data.cache.InspectCacheHandler; import com.djrapitops.plan.data.listeners.*; +import com.djrapitops.plan.ui.WebSocketServer; import org.bukkit.plugin.java.JavaPlugin; import java.util.ArrayList; @@ -30,8 +32,10 @@ public class Plan extends JavaPlugin { private PlanLiteHook planLiteHook; private DataCacheHandler handler; private InspectCacheHandler inspectCache; + private AnalysisCacheHandler analysisCache; private Database db; private HashSet databases; + private WebSocketServer uiServer; @Override public void onEnable() { @@ -73,6 +77,7 @@ public class Plan extends JavaPlugin { hookPlanLite(); this.handler = new DataCacheHandler(this); this.inspectCache = new InspectCacheHandler(this); + this.analysisCache = new AnalysisCacheHandler(this); registerListeners(); log(MiscUtils.checkVersion()); @@ -81,6 +86,9 @@ public class Plan extends JavaPlugin { this.api = new API(this); handler.handleReload(); + + uiServer = new WebSocketServer(this); + uiServer.initServer(); log("Player Analytics Enabled."); } @@ -102,6 +110,7 @@ public class Plan extends JavaPlugin { @Override public void onDisable() { + uiServer.stop(); Bukkit.getScheduler().cancelTasks(this); log("Saving cached data.."); ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); @@ -193,6 +202,10 @@ public class Plan extends JavaPlugin { return true; } + public AnalysisCacheHandler getAnalysisCache() { + return analysisCache; + } + public InspectCacheHandler getInspectCache() { return inspectCache; } diff --git a/Plan Advanced/src/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java b/Plan Advanced/src/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java new file mode 100644 index 000000000..8c8d70271 --- /dev/null +++ b/Plan Advanced/src/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java @@ -0,0 +1,22 @@ + +package com.djrapitops.plan.data.cache; + +import com.djrapitops.plan.Plan; + +/** + * + * @author Rsl1122 + */ +public class AnalysisCacheHandler { + private Plan plugin; + private InspectCacheHandler inspectCache; + + public AnalysisCacheHandler(Plan plugin) { + this.plugin = plugin; + this.inspectCache = plugin.getInspectCache(); + } + + public boolean isCached() { + return true; + } +} diff --git a/Plan Advanced/src/com/djrapitops/plan/ui/DataRequestHandler.java b/Plan Advanced/src/com/djrapitops/plan/ui/DataRequestHandler.java new file mode 100644 index 000000000..9e7af7dda --- /dev/null +++ b/Plan Advanced/src/com/djrapitops/plan/ui/DataRequestHandler.java @@ -0,0 +1,44 @@ + +package com.djrapitops.plan.ui; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.data.UserData; +import com.djrapitops.plan.data.cache.AnalysisCacheHandler; +import com.djrapitops.plan.data.cache.InspectCacheHandler; +import java.util.UUID; + +/** + * + * @author Rsl1122 + */ +public class DataRequestHandler { + private Plan plugin; + private InspectCacheHandler inspectCache; + private AnalysisCacheHandler analysisCache; + + public DataRequestHandler(Plan plugin) { + this.plugin = plugin; + this.inspectCache = plugin.getInspectCache(); + this.analysisCache = plugin.getAnalysisCache(); + } + + public boolean checkIfCached(UUID uuid) { + return inspectCache.getCache().containsKey(uuid); + } + + public String getDataHtml(UUID uuid) { + UserData data = inspectCache.getFromCache(uuid); + if (data == null) { + return "

404 Data was not found in cache

"; + } + return "Test Successful"; + } + + public String getAnalysisHtml() { + return "Test Successful"; + } + + public boolean checkIfAnalysisIsCached() { + return analysisCache.isCached(); + } +} diff --git a/Plan Advanced/src/com/djrapitops/plan/ui/WebSocketServer.java b/Plan Advanced/src/com/djrapitops/plan/ui/WebSocketServer.java new file mode 100644 index 000000000..c3ec9f6da --- /dev/null +++ b/Plan Advanced/src/com/djrapitops/plan/ui/WebSocketServer.java @@ -0,0 +1,97 @@ +package com.djrapitops.plan.ui; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.data.cache.AnalysisCacheHandler; +import com.djrapitops.plan.data.cache.InspectCacheHandler; +import com.djrapitops.plan.ui.webserver.Request; +import com.djrapitops.plan.ui.webserver.Response; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * + * @author Rsl1122 + */ +public class WebSocketServer { + + private int PORT; + private boolean ENABLED = false; + private ServerSocket server; + + private Plan plugin; + private InspectCacheHandler inspectHandler; + private AnalysisCacheHandler analysisHandler; + private DataRequestHandler dataReqHandler; + + private boolean shutdown; + + public WebSocketServer(Plan plugin) { + this.plugin = plugin; + this.inspectHandler = plugin.getInspectCache(); + this.PORT = plugin.getConfig().getInt("WebServer.Port"); + shutdown = false; + dataReqHandler = new DataRequestHandler(plugin); + } + + public void initServer() { + //Server is already enabled stop code + if (ENABLED) { + return; + } + plugin.log("Initializing Webserver.."); + try { + //Setup server + try { + server = new ServerSocket(PORT, 1, InetAddress.getByName("127.0.0.1")); + } catch (IOException e) { + System.exit(1); + } + //Run server in seperate thread + (new BukkitRunnable() { + @Override + public void run() { + while (!shutdown) { + Socket socket; + InputStream input; + OutputStream output; + try { + socket = server.accept(); + input = socket.getInputStream(); + output = socket.getOutputStream(); + plugin.log("Connected: " + socket.getRemoteSocketAddress().toString()); + Request request = new Request(input); + request.parse(); + + Response response = new Response(output, dataReqHandler); + response.setRequest(request); + response.sendStaticResource(); + } catch (IOException e) { + } + } + this.cancel(); + } + }).runTaskAsynchronously(plugin); + + ENABLED = true; + + plugin.log("Webserver running: " + server.getInetAddress().getHostAddress() + ":" + server.getLocalPort()); + } catch (Exception e) { + ENABLED = false; + } + } + + public void stop() { + plugin.log("Shutting down Webserver.."); + shutdown = true; + try { + server.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/Plan Advanced/src/com/djrapitops/plan/ui/webserver/Request.java b/Plan Advanced/src/com/djrapitops/plan/ui/webserver/Request.java new file mode 100644 index 000000000..498971dd8 --- /dev/null +++ b/Plan Advanced/src/com/djrapitops/plan/ui/webserver/Request.java @@ -0,0 +1,56 @@ +package com.djrapitops.plan.ui.webserver; + +import java.io.IOException; +import java.io.InputStream; + +/** + * + * @author Rsl1122 + */ +public class Request { + + private InputStream input; + private String uri; + + public Request(InputStream input) { + this.input = input; + } + + public void parse() { + // Read a set of characters from the socket + StringBuffer request = new StringBuffer(2048); + int i; + byte[] buffer = new byte[2048]; + + try { + i = input.read(buffer); + } catch (IOException e) { + e.printStackTrace(); + i = -1; + } + + for (int j = 0; j < i; j++) { + request.append((char) buffer[j]); + } + + System.out.print(request.toString()); + uri = parseUri(request.toString()); + } + + private String parseUri(String requestString) { + int index1, index2; + index1 = requestString.indexOf(' '); + + if (index1 != -1) { + index2 = requestString.indexOf(' ', index1 + 1); + if (index2 > index1) { + return requestString.substring(index1 + 1, index2); + } + } + return null; + } + + public String getUri() { + return uri; + } +} diff --git a/Plan Advanced/src/com/djrapitops/plan/ui/webserver/Response.java b/Plan Advanced/src/com/djrapitops/plan/ui/webserver/Response.java new file mode 100644 index 000000000..2b671ed43 --- /dev/null +++ b/Plan Advanced/src/com/djrapitops/plan/ui/webserver/Response.java @@ -0,0 +1,95 @@ +package com.djrapitops.plan.ui.webserver; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.ui.DataRequestHandler; +import com.djrapitops.plan.utilities.UUIDFetcher; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.UUID; +import static org.bukkit.plugin.java.JavaPlugin.getPlugin; + +/** + * + * @author Rsl1122 + */ +public class Response { + + private OutputStream output; + private Request request; + + private DataRequestHandler handler; + + public Response(OutputStream output, DataRequestHandler h) { + this.output = output; + handler = h; + } + + public void sendStaticResource() throws IOException { + try { + if (request == null) { + return; + } + if (request.getUri() == null) { + return; + } + String[] requestArgs = request.getUri().split("/"); + if (requestArgs.length < 1) { + String errorMessage = "HTTP/1.1 403 Forbidden\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: 45\r\n" + + "\r\n" + + "

403 Forbidden - Direct access not allowed

"; + output.write(errorMessage.getBytes()); + return; + } + String command = requestArgs[1].toLowerCase(); + if (command.equals("player")) { + if (requestArgs.length >= 3) { + UUID uuid = UUIDFetcher.getUUIDOf(requestArgs[2].trim()); + if (uuid == null) { + String errorMessage = "HTTP/1.1 404 UUID not Found\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: 30\r\n" + + "\r\n" + + "

404 - Player doesn't exist

"; + output.write(errorMessage.getBytes()); + return; + } + if (handler.checkIfCached(uuid)) { + String dataHtml = handler.getDataHtml(uuid); + String htmlDef = "HTTP/1.1 Analysis\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: " + dataHtml.length() + "\r\n" + + "\r\n"; + output.write((htmlDef + dataHtml).getBytes()); + return; + } + } + } else if (command.equals("server")) { + if (handler.checkIfAnalysisIsCached()) { + String analysisHtml = handler.getAnalysisHtml(); + String htmlDef = "HTTP/1.1 Analysis\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: " + analysisHtml.length() + "\r\n" + + "\r\n"; + output.write((htmlDef + analysisHtml).getBytes()); + return; + } + } + String errorMessage = "HTTP/1.1 404 UserData not Found\r\n" + + "Content-Type: text/html\r\n" + + "Content-Length: 35\r\n" + + "\r\n" + + "

404 Data was not found in cache

"; + output.write(errorMessage.getBytes()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void setRequest(Request request) { + this.request = request; + } +} diff --git a/Plan Advanced/src/config.yml b/Plan Advanced/src/config.yml index 3c2a29eaa..281878a81 100644 --- a/Plan Advanced/src/config.yml +++ b/Plan Advanced/src/config.yml @@ -2,7 +2,10 @@ debug: true saveEveryXMinutes: 5 database: - type: sqlite + type: sqlite + +WebServer: + Port: 8804 enabledData: planLite: