Added parameter on 1000 response, added MC info cmd and more changes
This commit is contained in:
113
src/com/mesacarlos/webconsole/websocket/WSServer.java
Normal file
113
src/com/mesacarlos/webconsole/websocket/WSServer.java
Normal file
@ -0,0 +1,113 @@
|
||||
package com.mesacarlos.webconsole.websocket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
|
||||
import com.mesacarlos.webconsole.WebConsole;
|
||||
import com.mesacarlos.webconsole.util.LoginManager;
|
||||
import com.mesacarlos.webconsole.websocket.command.CommandFactory;
|
||||
import com.mesacarlos.webconsole.websocket.command.WSCommand;
|
||||
import com.mesacarlos.webconsole.websocket.response.ConsoleOutput;
|
||||
import com.mesacarlos.webconsole.websocket.response.JSONOutput;
|
||||
import com.mesacarlos.webconsole.websocket.response.LoginRequired;
|
||||
import com.mesacarlos.webconsole.websocket.response.Processed;
|
||||
import com.mesacarlos.webconsole.websocket.response.UnknownCommand;
|
||||
|
||||
public class WSServer extends WebSocketServer {
|
||||
private HashMap<String, WSCommand> commands = CommandFactory.getCommandsHashMap();
|
||||
private WebConsole plugin;
|
||||
|
||||
public WSServer(WebConsole plugin, InetSocketAddress address) {
|
||||
super(address);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket conn, ClientHandshake handshake) {
|
||||
if(LoginManager.getInstance().isLoggedIn(conn.getRemoteSocketAddress()))
|
||||
sendToClient(conn, new Processed("Connected. Already logged in, welcome back!"));
|
||||
else
|
||||
sendToClient(conn, new LoginRequired("Connection started, waiting login"));
|
||||
Bukkit.getLogger().info("[WebConsole] Connected and waiting login from " + conn.getRemoteSocketAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket conn, String message) {
|
||||
// Get command and params
|
||||
String wsCommand = message.split(" ")[0];
|
||||
String wsCommandParams = "";
|
||||
if (message.contains(" "))
|
||||
wsCommandParams = message.split(" ", 2)[1];
|
||||
|
||||
// Run command
|
||||
WSCommand cmd = commands.get(wsCommand);
|
||||
|
||||
if (cmd == null) {
|
||||
//Command does not exist
|
||||
sendToClient(conn, new UnknownCommand("Unknown command", message));
|
||||
Bukkit.getLogger().info(
|
||||
"[WebConsole] Signal '" + message + "' was not processed since is not valid. Is your plugin/web interface up to date?");
|
||||
} else if (!LoginManager.getInstance().isLoggedIn(conn.getRemoteSocketAddress())
|
||||
&& !wsCommand.equals("LOGIN")) {
|
||||
//User is not authorised. DO NOTHING, IMPORTANT!
|
||||
sendToClient(conn, new LoginRequired("Forbidden"));
|
||||
Bukkit.getLogger().warning("[WebConsole] " + conn.getRemoteSocketAddress()
|
||||
+ " tried to run '" + message + "' while not logged in!");
|
||||
} else {
|
||||
cmd.execute(this, conn, wsCommandParams);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
|
||||
LoginManager.getInstance().logOut(conn.getRemoteSocketAddress());
|
||||
Bukkit.getLogger()
|
||||
.info("[WebConsole] Closed WS connection " + conn.getRemoteSocketAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket conn, Exception ex) {
|
||||
Bukkit.getLogger()
|
||||
.warning("[WebConsole] Error occured on connection " + conn.getRemoteSocketAddress() + ":" + ex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
Bukkit.getLogger().info("[WebConsole] WebSocket Server started successfully");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns main class
|
||||
* @return Main plugin class
|
||||
*/
|
||||
public WebConsole getMainClass() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the message to all connected AND logged-in users
|
||||
*/
|
||||
public void onNewConsoleLinePrinted(String line) {
|
||||
Collection<WebSocket> connections = getConnections();
|
||||
for (WebSocket connection : connections) {
|
||||
if (LoginManager.getInstance().isLoggedIn(connection.getRemoteSocketAddress()))
|
||||
sendToClient(connection, new ConsoleOutput(line));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this JSONOutput to client
|
||||
* @param conn Connection to client
|
||||
* @param content JSONOutput object
|
||||
*/
|
||||
public void sendToClient(WebSocket conn, JSONOutput content) {
|
||||
conn.send(content.toJSON());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CommandFactory {
|
||||
|
||||
public static HashMap<String, WSCommand> getCommandsHashMap() {
|
||||
HashMap<String, WSCommand> commands = new HashMap<String, WSCommand>();
|
||||
commands.put("LOGIN", new LogInCommand());
|
||||
commands.put("EXEC", new ExecCommand());
|
||||
commands.put("PLAYERS", new PlayersCommand());
|
||||
commands.put("CPUUSAGE", new CpuUsageCommand());
|
||||
commands.put("RAMUSAGE", new RamUsageCommand());
|
||||
return commands;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
import javax.management.Attribute;
|
||||
import javax.management.AttributeList;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import com.mesacarlos.webconsole.websocket.WSServer;
|
||||
import com.mesacarlos.webconsole.websocket.response.CpuUsage;
|
||||
|
||||
public class CpuUsageCommand implements WSCommand {
|
||||
|
||||
@Override
|
||||
public void execute(WSServer wsServer, WebSocket conn, String params) {
|
||||
try {
|
||||
double usage = getProcessCpuLoad();
|
||||
wsServer.sendToClient(conn, new CpuUsage("Usage is " + usage + "%", usage));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check out usage for the whole system
|
||||
* Got from https://stackoverflow.com/questions/18489273/how-to-get-percentage-of-cpu-usage-of-os-from-java
|
||||
* @return CPU Usage for the whole system
|
||||
* @throws Exception Something went wrong
|
||||
*/
|
||||
public double getProcessCpuLoad() throws Exception {
|
||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
ObjectName name = ObjectName.getInstance("java.lang:type=OperatingSystem");
|
||||
AttributeList list = mbs.getAttributes(name, new String[] {"SystemCpuLoad"});
|
||||
|
||||
if (list.isEmpty())
|
||||
return Double.NaN;
|
||||
|
||||
Attribute att = (Attribute) list.get(0);
|
||||
Double value = (Double) att.getValue();
|
||||
|
||||
// usually takes a couple of seconds before we get real values
|
||||
if (value == -1.0)
|
||||
return Double.NaN;
|
||||
// returns a percentage value with 1 decimal point precision
|
||||
return ((int) (value * 1000) / 10.0);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import com.mesacarlos.webconsole.websocket.WSServer;
|
||||
|
||||
public class ExecCommand implements WSCommand {
|
||||
|
||||
@Override
|
||||
public void execute(WSServer wsServer, WebSocket conn, String command) {
|
||||
|
||||
Bukkit.getLogger().info("[WebConsole] " + conn.getRemoteSocketAddress() + " executed '" + command + "'");
|
||||
ConsoleCommandSender sender = Bukkit.getServer().getConsoleSender();
|
||||
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
boolean success = Bukkit.getScheduler()
|
||||
.callSyncMethod(wsServer.getMainClass(), () -> Bukkit.dispatchCommand(sender, command)).get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import com.mesacarlos.webconsole.util.LoginManager;
|
||||
import com.mesacarlos.webconsole.websocket.WSServer;
|
||||
import com.mesacarlos.webconsole.websocket.response.LoginRequired;
|
||||
import com.mesacarlos.webconsole.websocket.response.Processed;
|
||||
|
||||
public class LogInCommand implements WSCommand {
|
||||
|
||||
@Override
|
||||
public void execute(WSServer wsServer, WebSocket conn, String password) {
|
||||
// If user is logged in, then return.
|
||||
if (LoginManager.getInstance().isLoggedIn(conn.getRemoteSocketAddress()))
|
||||
return;
|
||||
|
||||
// Get password from config files
|
||||
String receivedPassword = wsServer.getMainClass().getConfig().getString("password");
|
||||
|
||||
if (receivedPassword.equals(password)) {
|
||||
// Password is correct, logging in
|
||||
LoginManager.getInstance().logIn(conn.getRemoteSocketAddress());
|
||||
wsServer.sendToClient(conn, new Processed("Logged In", "LOGIN ********"));
|
||||
Bukkit.getLogger().info("[WebConsole] Successfully logged in from " + conn.getRemoteSocketAddress());
|
||||
} else {
|
||||
wsServer.sendToClient(conn, new LoginRequired("Incorrect password, try again"));
|
||||
Bukkit.getLogger()
|
||||
.info("[WebConsole] Password incorrect while login from " + conn.getRemoteSocketAddress());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import com.mesacarlos.webconsole.websocket.WSServer;
|
||||
import com.mesacarlos.webconsole.websocket.response.Players;
|
||||
|
||||
public class PlayersCommand implements WSCommand{
|
||||
|
||||
@Override
|
||||
public void execute(WSServer wsServer, WebSocket conn, String params) {
|
||||
List<String> connectedPlayersList = new ArrayList<String>();
|
||||
for(Player player : Bukkit.getOnlinePlayers()) {
|
||||
connectedPlayersList.add(player.getName());
|
||||
}
|
||||
int connectedPlayers = Bukkit.getOnlinePlayers().size();
|
||||
int maxPlayers = Bukkit.getMaxPlayers();
|
||||
|
||||
wsServer.sendToClient(conn, new Players("Currently " + connectedPlayers + " connected players for a maximum of " + maxPlayers, connectedPlayers, maxPlayers, connectedPlayersList));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import com.mesacarlos.webconsole.websocket.WSServer;
|
||||
import com.mesacarlos.webconsole.websocket.response.RamUsage;
|
||||
|
||||
public class RamUsageCommand implements WSCommand {
|
||||
|
||||
@Override
|
||||
public void execute(WSServer wsServer, WebSocket conn, String params) {
|
||||
Runtime r = Runtime.getRuntime();
|
||||
|
||||
long free = r.freeMemory() / 1024 / 1024;
|
||||
long max = r.maxMemory() / 1024 / 1024;
|
||||
long used = max - free;
|
||||
|
||||
wsServer.sendToClient(conn,
|
||||
new RamUsage(free + " free, " + used + " used, " + max + " maximum memory", free, used, max));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.mesacarlos.webconsole.websocket.command;
|
||||
|
||||
import org.java_websocket.WebSocket;
|
||||
|
||||
import com.mesacarlos.webconsole.websocket.WSServer;
|
||||
|
||||
public interface WSCommand {
|
||||
void execute(WSServer wsServer, WebSocket conn, String params);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class ConsoleOutput implements JSONOutput{
|
||||
private String message;
|
||||
|
||||
public ConsoleOutput(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "Console Output");
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class CpuUsage implements JSONOutput{
|
||||
private String message;
|
||||
private double usage;
|
||||
|
||||
public CpuUsage(String message, double usage) {
|
||||
this.message = message;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 1001;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets system CPU Usage
|
||||
* @return Global CPU Usage
|
||||
*/
|
||||
public double getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "CPU Usage");
|
||||
object.addProperty("usage", getUsage());
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
public interface JSONOutput {
|
||||
/**
|
||||
* Gets status code representing this message. See docs for code meanings.
|
||||
* @return Status code representing this message
|
||||
*/
|
||||
int getStatusCode();
|
||||
|
||||
/**
|
||||
* Explanatory message of this response
|
||||
* @return Explanatory message of this response
|
||||
*/
|
||||
String getMessage();
|
||||
|
||||
/**
|
||||
* Coverts this object into JSON, ready to send it over WS
|
||||
* @return JSON Object Stringified
|
||||
*/
|
||||
String toJSON();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class LoginRequired implements JSONOutput{
|
||||
private String message;
|
||||
|
||||
public LoginRequired(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 401;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "Login Required");
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class Players implements JSONOutput{
|
||||
private String message;
|
||||
private int connectedPlayers;
|
||||
private int maxPlayers;
|
||||
private List<String> connectedPlayersList;
|
||||
|
||||
public Players(String message, int connectedPlayers, int maxPlayers, List<String> connectedPlayersList) {
|
||||
this.message = message;
|
||||
this.connectedPlayers = connectedPlayers;
|
||||
this.maxPlayers = maxPlayers;
|
||||
this.connectedPlayersList = connectedPlayersList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getConnectedPlayers() {
|
||||
return connectedPlayers;
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return maxPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "Players");
|
||||
object.addProperty("connectedPlayers", getConnectedPlayers());
|
||||
object.addProperty("maxPlayers", getMaxPlayers());
|
||||
object.addProperty("players", new Gson().toJson(connectedPlayersList));
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class Processed implements JSONOutput{
|
||||
private String message;
|
||||
private String respondsTo;
|
||||
|
||||
public Processed(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Processed(String message, String respondsTo) {
|
||||
this.message = message;
|
||||
this.respondsTo = respondsTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* The command that originated this response
|
||||
* @return WebSockets full command and parameters
|
||||
*/
|
||||
private String getRespondsTo() {
|
||||
return respondsTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "Processed");
|
||||
object.addProperty("respondsTo", getRespondsTo());
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class RamUsage implements JSONOutput {
|
||||
private String message;
|
||||
private long free;
|
||||
private long used;
|
||||
private long max;
|
||||
|
||||
public RamUsage(String message, long free, long used, long max) {
|
||||
this.message = message;
|
||||
this.free = free;
|
||||
this.used = used;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 1002;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free amount of RAM, in MB
|
||||
* @return
|
||||
*/
|
||||
public long getFree() {
|
||||
return free;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used amount of RAM, in MB
|
||||
* @return
|
||||
*/
|
||||
public long getUsed() {
|
||||
return used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Max amount of RAM, in MB
|
||||
* @return
|
||||
*/
|
||||
public long getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "RAM Usage");
|
||||
object.addProperty("free", getFree());
|
||||
object.addProperty("used", getUsed());
|
||||
object.addProperty("max", getMax());
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.mesacarlos.webconsole.websocket.response;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public class UnknownCommand implements JSONOutput{
|
||||
private String message;
|
||||
private String respondsTo;
|
||||
|
||||
public UnknownCommand(String message, String respondsTo) {
|
||||
this.message = message;
|
||||
this.respondsTo = respondsTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusCode() {
|
||||
return 400;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* The command that originated this response
|
||||
* @return WebSockets full command and parameters
|
||||
*/
|
||||
public String getRespondsTo() {
|
||||
return respondsTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("status", getStatusCode());
|
||||
object.addProperty("statusDescription", "Unknown Command");
|
||||
object.addProperty("respondsTo", getRespondsTo());
|
||||
object.addProperty("message", getMessage());
|
||||
return object.toString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user