Skip to content

Commit

Permalink
Add built-in HTTP server for instant commands
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMicky-FR committed Dec 28, 2019
1 parent b68d4f1 commit 2a922f0
Show file tree
Hide file tree
Showing 20 changed files with 393 additions and 64 deletions.
6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ subprojects {
sourceCompatibility = 1.8
targetCompatibility = 1.8

tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}

repositories {
mavenCentral()

maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

dependencies {
Expand Down
3 changes: 2 additions & 1 deletion bukkit/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
repositories {
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

dependencies {
compileOnly 'org.spigotmc:spigot-api:1.14.4-R0.1-SNAPSHOT'
compile project(':azlink-common')
compileOnly 'org.spigotmc:spigot-api:1.15.1-R0.1-SNAPSHOT'
}

processResources {
Expand Down
2 changes: 1 addition & 1 deletion bukkit/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ api-version: 1.13
commands:
azlink:
description: Manage the AzLink plugin.
usage: /<command> [status|setup]
usage: /<command> [status|setup|fetch|port]
aliases: [azuriomlink]
6 changes: 5 additions & 1 deletion bungee/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
repositories {
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}

dependencies {
compileOnly 'net.md-5:bungeecord-api:1.14-SNAPSHOT'
compile project(':azlink-common')
compileOnly 'net.md-5:bungeecord-api:1.15-SNAPSHOT'
}

processResources {
Expand Down
1 change: 1 addition & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dependencies {
compileOnly 'org.slf4j:slf4j-api:1.7.28'
compileOnly 'io.netty:netty-all:4.1.25.Final'
compile 'com.squareup.okhttp3:okhttp:3.14.3'
}
67 changes: 42 additions & 25 deletions common/src/main/java/com/azuriom/azlink/common/AzLinkPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@
import com.azuriom.azlink.common.data.ServerData;
import com.azuriom.azlink.common.data.SystemData;
import com.azuriom.azlink.common.data.WorldData;
import com.azuriom.azlink.common.http.HttpClient;
import com.azuriom.azlink.common.http.client.HttpClient;
import com.azuriom.azlink.common.http.server.HttpServer;
import com.azuriom.azlink.common.logger.LoggerAdapter;
import com.azuriom.azlink.common.scheduler.ThreadBuilder;
import com.azuriom.azlink.common.tasks.FetcherTask;
import com.azuriom.azlink.common.utils.SystemUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
Expand All @@ -35,6 +37,7 @@ public class AzLinkPlugin {
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(r -> new ThreadBuilder(r).name("azlink-thread").daemon().build());

private final HttpClient httpClient = new HttpClient(this);
private HttpServer httpServer = new HttpServer(this);

private final Gson gson = new Gson();
private final Gson gsonPrettyPrint = new GsonBuilder().setPrettyPrinting().create();
Expand All @@ -46,7 +49,7 @@ public class AzLinkPlugin {
private final AzLinkPlatform platform;

private Path configFile;
private PluginConfig config = new PluginConfig(null, null);
private PluginConfig config = new PluginConfig(null, null, true, HttpServer.DEFAULT_PORT);

private boolean logCpuError = true;

Expand All @@ -62,31 +65,47 @@ public void init() {
} catch (NoSuchFileException e) {
// ignore, not setup yet
} catch (IOException e) {
platform.getLoggerAdapter().error("Error while loading configuration", e);
getLogger().error("Error while loading configuration", e);
return;
}

LocalDateTime start = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES).plusMinutes(1);
long startDelay = Duration.between(LocalDateTime.now(), start).toMillis();
long startDelay = Duration.between(LocalDateTime.now(), start).toMillis() + 500; // Add 0.5s to ensure we are not in the previous hour

scheduler.scheduleAtFixedRate(fetcherTask, startDelay, TimeUnit.MINUTES.toMillis(1), TimeUnit.MILLISECONDS);

if (!config.isValid()) {
platform.getLoggerAdapter().warn("Invalid configuration, you can use '/azlink' to setup the plugin.");
getLogger().warn("Invalid configuration, you can use '/azlink' to setup the plugin.");
return;
}

platform.executeAsync(() -> {
try {
httpClient.verifyStatus();

getLogger().info("Successful connected to " + config.getSiteUrl());
} catch (IOException e) {
platform.getLoggerAdapter().warn("Unable to connect", e);
getLogger().warn("Unable to verify website connection: " + e.getMessage() + " - " + e.getClass().getName());
}
});

if (config.hasInstantCommands()) {
platform.executeAsync(httpServer::startSafe);
}
}

public void restartHttpServer() throws Exception {
httpServer.stopSafe();

httpServer = new HttpServer(this);

httpServer.start();
}

public void shutdown() {
scheduler.shutdown();

httpServer.stopSafe();
}

public void setConfig(PluginConfig config) {
Expand Down Expand Up @@ -115,33 +134,18 @@ public ServerData getServerData(boolean fullData) {

PlatformData platformData = platform.getPlatformData();

SystemData system = fullData ? new SystemData(getMemoryUsage(), getCpuUsage()) : null;
SystemData system = fullData ? new SystemData(getCpuUsage(), SystemUtils.getMemoryUsage()) : null;
WorldData world = fullData ? platform.getWorldData().orElse(null) : null;

return new ServerData(platformData, platform.getPluginVersion(), players, max, system, world, fullData);
}

private double getCpuUsage() {
try {
if (ManagementFactory.getOperatingSystemMXBean() instanceof com.sun.management.OperatingSystemMXBean) {
return ((com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean()).getProcessCpuLoad() * 100.0;
}
} catch (Throwable t) {
if (logCpuError) {
logCpuError = false;

platform.getLoggerAdapter().warn("Error while retrieving cpu usage", t);
}
}
return -1;
}

public void fetchNow() {
platform.executeAsync(fetcherTask);
}

private double getMemoryUsage() {
return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024.0 / 1024.0;
public LoggerAdapter getLogger() {
return platform.getLoggerAdapter();
}

public PluginConfig getConfig() {
Expand All @@ -163,4 +167,17 @@ public Gson getGson() {
public Gson getGsonPrettyPrint() {
return gsonPrettyPrint;
}

private double getCpuUsage() {
try {
return SystemUtils.getCpuUsage();
} catch (Throwable t) {
if (logCpuError) {
logCpuError = false;

getLogger().warn("Error while retrieving cpu usage", t);
}
}
return -1;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.azuriom.azlink.common.command;

import com.azuriom.azlink.common.AzLinkPlugin;
import com.azuriom.azlink.common.config.PluginConfig;

import java.io.IOException;
import java.util.Collections;
Expand All @@ -11,7 +10,7 @@

public class AzLinkCommand {

private static final String[] COMPLETIONS = {"status", "setup", "key", "site"};
private static final String[] COMPLETIONS = {"status", "setup", "fetch", "port"};

private final AzLinkPlugin plugin;

Expand Down Expand Up @@ -52,6 +51,37 @@ public void execute(CommandSender sender, String[] args) {
return;
}

if (args[0].equalsIgnoreCase("port")) {
if (args.length < 2) {
sender.sendMessage("§cUsage: /azlink port <port>");
return;
}

int port;

try {
port = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
sender.sendMessage("§c'" + args[1] + "' is not a valid port !");
return;
}

plugin.getConfig().setHttpPort(port);

plugin.getPlatform().executeAsync(() -> {
try {
plugin.restartHttpServer();

sender.sendMessage("§aHTTP server started on port " + port);
} catch (Exception e) {
sender.sendMessage("§cAn error occurred while starting the HTTP server: " + e.getMessage() + " - " + e.getClass().getName());
plugin.getLogger().error("Error while starting the HTTP server", e);
}
});

return;
}

sendUsage(sender);
}

Expand All @@ -67,22 +97,28 @@ public List<String> tabComplete(CommandSender sender, String[] args) {
return Collections.emptyList();
}

public String getUsage() {
return "Usage: /azlink [" + String.join("|", COMPLETIONS) + "]";
}

private void sendUsage(CommandSender sender) {
String version = plugin.getPlatform().getPluginVersion();
sender.sendMessage("§9AzLink v" + version + "§7. Website: §9https://azuriom.com");
sender.sendMessage("§8- /azlink setup <url> <key>");
sender.sendMessage("§8- /azlink port <port>");
sender.sendMessage("§8- /azlink status");
}

private void setup(CommandSender sender, String url, String key) {
plugin.setConfig(new PluginConfig(key, url));
plugin.getConfig().setSiteKey(key);
plugin.getConfig().setSiteUrl(url);

if (showStatus(sender)) {
try {
plugin.saveConfig();
} catch (IOException e) {
sender.sendMessage(cError while saving config: " + e.getMessage() + " - " + e.getClass().getName());
plugin.getPlatform().getLoggerAdapter().error("Error while saving config", e);
sender.sendMessage(cAn error occurred while saving config: " + e.getMessage() + " - " + e.getClass().getName());
plugin.getLogger().error("Error while saving config", e);
}
}
}
Expand All @@ -96,8 +132,8 @@ private boolean showStatus(CommandSender sender) {
plugin.fetchNow();

return true;
} catch (IOException e) {
sender.sendMessage("§cUnable to connect to the server: " + e.getMessage());
} catch (Exception e) {
sender.sendMessage("§cUnable to connect to the website: " + e.getMessage() + " - " + e.getClass().getName());

return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,56 @@

public class PluginConfig {

private final String siteKey;
private final String siteUrl;
private String siteKey;
private String siteUrl;
private boolean instantCommands;
private int httpPort;

public PluginConfig(String siteKey, String siteUrl) {
public PluginConfig(String siteKey, String siteUrl, boolean instantCommands, int httpPort) {
this.siteKey = siteKey;
this.siteUrl = siteUrl;
this.instantCommands = instantCommands;
this.httpPort = httpPort;
}

public String getSiteKey() {
return siteKey;
}

public void setSiteKey(String siteKey) {
this.siteKey = siteKey;
}

public String getSiteUrl() {
return siteUrl;
}

public void setSiteUrl(String siteUrl) {
this.siteUrl = siteUrl;
}

public boolean hasInstantCommands() {
return instantCommands;
}

public void setInstantCommands(boolean instantCommands) {
this.instantCommands = instantCommands;
}

public int getHttpPort() {
return httpPort;
}

public void setHttpPort(int httpPort) {
this.httpPort = httpPort;
}

public boolean isValid() {
return siteKey != null && !siteKey.isEmpty() && siteUrl != null && !siteUrl.isEmpty();
}

@Override
public String toString() {
return "PluginConfig{siteKey='" + siteKey + "', siteUrl='" + siteUrl + "', httpPort=" + httpPort + '}';
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.azuriom.azlink.common.http;
package com.azuriom.azlink.common.http.client;

import com.azuriom.azlink.common.AzLinkPlugin;
import com.azuriom.azlink.common.data.ServerData;
Expand Down Expand Up @@ -52,8 +52,8 @@ public WebsiteResponse postData(ServerData data) throws IOException {
throw new RuntimeException("No body in response");
}

try (InputStream is = body.byteStream()) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
try (InputStream in = body.byteStream()) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
return plugin.getGson().fromJson(reader, WebsiteResponse.class);
}
}
Expand Down Expand Up @@ -82,6 +82,6 @@ private Request addHeadersToRequest(Request request) {
}

private String getSiteUrl() {
return plugin.getConfig().getSiteUrl() + "/api/v1/azlink";
return plugin.getConfig().getSiteUrl() + "/api/azlink";
}
}
Loading

0 comments on commit 2a922f0

Please sign in to comment.