Implemented Players, CpuUsage, RamUsage Commands. Updated README

This commit is contained in:
Carlos
2019-08-13 19:38:37 +02:00
parent 59fa012a18
commit 7f170f15b6
18 changed files with 266 additions and 66 deletions

View File

@ -2,7 +2,7 @@
# WebConsole
WebConsole is a Spigot plugin for Minecraft 1.14 that enables you to view your server console and manage your server from anywhere. It creates a WebSocket server in the background used by the web interface to send commands, receive your console log and manage your server.
WebConsole is a Spigot plugin for Minecraft 1.8-1.14 that enables you to view your server console and manage your server from anywhere. It creates a WebSocket server in the background used by the web interface to send commands, receive your console log and manage your server.
Dont worry about privacy: all data is stored in your browser offline and your PC will connect directly to your minecraft server. No intermediary web servers, just you and your server.
@ -67,34 +67,5 @@ WebConsole does not support PEM certificates, so you will need to convert it to
## Technical information
### WebSocket commands
You can find how client and server comunicate [here](https://github.com/mesacarlos/WebConsole/wiki/WebSocket-commands-and-responses)
The following tables represent how server communicates with the client(s), something like a language between them.
#### Websocket Server -> Client
Server communicate with all connected clients using JSON. The following table shows all possible JSON variables.
| Variable |Meaning |
|---------------------|-----------------------------------------------------------------------------|
| status |Status code (as integer), representing response type. See listing below* |
| statusDescription |Status description (as String) describing response type. |
| respondsTo |`(Optional)` Original command sent by client which triggered this response|
| message |Response content |
*Status codes are listed below:
- **010**: Console output.
- **200**: Ok/Processed.
- **400**: Unknown command.
- **401**: Login required/Not logged in.
#### Client -> Websocket Server
Clients can communicate with server using commands. The following table shows existing commands.
| Code |Meaning |Extra info |
|---------------------|-----------------------------------------|--------------|
|LOGIN *(password)* |Login to start communication with server | |
|EXEC *(command)* |Run desired command in Minecraft Server |Login required|

View File

@ -1,7 +1,6 @@
name: WebConsole
main: com.mesacarlos.webconsole.WebConsole
version: 1.0
version: 1.1
description: WebSockets-based web console
api-version: 1.14
author: Carlos Mesa
commands:

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>WebConsole</groupId>
<artifactId>WebConsole</artifactId>
<version>1.0</version>
<version>1.1</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
@ -59,7 +59,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.14.2-R0.1-SNAPSHOT</version>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- WebSockets Server Dependency -->

View File

@ -4,10 +4,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
@ -78,8 +75,7 @@ public class WebConsole extends JavaPlugin {
/**
* Start WebSocket server
*/
private void startWS() throws Exception,
KeyStoreException, UnrecoverableKeyException, KeyManagementException {
private void startWS() throws Exception {
// Create WebSocket server
server = new WSServer(this, new InetSocketAddress(config.getString("host"), config.getInt("port")));

View File

@ -7,7 +7,10 @@ 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 ExecuteCmdCommand());
commands.put("EXEC", new ExecCommand());
commands.put("PLAYERS", new PlayersCommand());
commands.put("CPUUSAGE", new CpuUsageCommand());
commands.put("RAMUSAGE", new RamUsageCommand());
return commands;
}
}

View File

@ -0,0 +1,51 @@
package com.mesacarlos.webconsole.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.json.CpuUsage;
import com.mesacarlos.webconsole.websockets.WSServer;
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);
}
}

View File

@ -8,7 +8,7 @@ import org.java_websocket.WebSocket;
import com.mesacarlos.webconsole.websockets.WSServer;
public class ExecuteCmdCommand implements WSCommand {
public class ExecCommand implements WSCommand {
@Override
public void execute(WSServer wsServer, WebSocket conn, String command) {

View File

@ -0,0 +1,19 @@
package com.mesacarlos.webconsole.command;
import org.bukkit.Bukkit;
import org.java_websocket.WebSocket;
import com.mesacarlos.webconsole.json.Players;
import com.mesacarlos.webconsole.websockets.WSServer;
public class PlayersCommand implements WSCommand{
@Override
public void execute(WSServer wsServer, WebSocket conn, String params) {
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));
}
}

View File

@ -0,0 +1,21 @@
package com.mesacarlos.webconsole.command;
import org.java_websocket.WebSocket;
import com.mesacarlos.webconsole.json.RamUsage;
import com.mesacarlos.webconsole.websockets.WSServer;
public class RamUsageCommand implements WSCommand {
@Override
public void execute(WSServer wsServer, WebSocket conn, String params) {
Runtime r = Runtime.getRuntime();
int free = (int) r.freeMemory()/1024/1024;
int max = (int) r.maxMemory()/1024/1024;
int used = max - free;
wsServer.sendToClient(conn, new RamUsage(free + "free, " + used + " used," + max + " maximum memmory", free, used, max));
}
}

View File

@ -18,11 +18,6 @@ public class ConsoleOutput implements JSONOutput{
public String getMessage() {
return message;
}
@Override
public String getRespondsTo() {
return null;
}
@Override
public String toJSON() {

View File

@ -0,0 +1,42 @@
package com.mesacarlos.webconsole.json;
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();
}
}

View File

@ -7,13 +7,6 @@ public interface JSONOutput {
*/
int getStatusCode();
/**
* Returns the command sended by client who created this response.
* In case of a server-generated response (like ConsoleOutput), this will be null
* @return
*/
String getRespondsTo();
/**
* Explanatory message of this response
* @return Explanatory message of this response

View File

@ -18,11 +18,6 @@ public class LoginRequired implements JSONOutput{
public String getMessage() {
return message;
}
@Override
public String getRespondsTo() {
return null;
}
@Override
public String toJSON() {

View File

@ -0,0 +1,45 @@
package com.mesacarlos.webconsole.json;
import com.google.gson.JsonObject;
public class Players implements JSONOutput{
private String message;
private int connectedPlayers;
private int maxPlayers;
public Players(String message, int connectedPlayers, int maxPlayers) {
this.message = message;
this.connectedPlayers = connectedPlayers;
this.maxPlayers = maxPlayers;
}
@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("message", getMessage());
return object.toString();
}
}

View File

@ -25,8 +25,11 @@ public class Processed implements JSONOutput{
return message;
}
@Override
public String getRespondsTo() {
/**
* The command that originated this response
* @return WebSockets full command and parameters
*/
private String getRespondsTo() {
return respondsTo;
}

View File

@ -0,0 +1,64 @@
package com.mesacarlos.webconsole.json;
import com.google.gson.JsonObject;
public class RamUsage implements JSONOutput {
private String message;
private int free;
private int used;
private int max;
public RamUsage(String message, int free, int used, int 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 int getFree() {
return free;
}
/**
* Used amount of RAM, in MB
* @return
*/
public int getUsed() {
return used;
}
/**
* Max amount of RAM, in MB
* @return
*/
public int 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("total", getUsed());
object.addProperty("max", getMax());
object.addProperty("message", getMessage());
return object.toString();
}
}

View File

@ -2,11 +2,11 @@ package com.mesacarlos.webconsole.json;
import com.google.gson.JsonObject;
public class UnknownWSCmd implements JSONOutput{
public class UnknownCommand implements JSONOutput{
private String message;
private String respondsTo;
public UnknownWSCmd(String message, String respondsTo) {
public UnknownCommand(String message, String respondsTo) {
this.message = message;
this.respondsTo = respondsTo;
}
@ -21,7 +21,10 @@ public class UnknownWSCmd implements JSONOutput{
return message;
}
@Override
/**
* The command that originated this response
* @return WebSockets full command and parameters
*/
public String getRespondsTo() {
return respondsTo;
}

View File

@ -16,7 +16,7 @@ import com.mesacarlos.webconsole.json.ConsoleOutput;
import com.mesacarlos.webconsole.json.JSONOutput;
import com.mesacarlos.webconsole.json.LoginRequired;
import com.mesacarlos.webconsole.json.Processed;
import com.mesacarlos.webconsole.json.UnknownWSCmd;
import com.mesacarlos.webconsole.json.UnknownCommand;
import com.mesacarlos.webconsole.util.LoginManager;
public class WSServer extends WebSocketServer {
@ -50,7 +50,7 @@ public class WSServer extends WebSocketServer {
if (cmd == null) {
//Command does not exist
sendToClient(conn, new UnknownWSCmd("Unknown command", message));
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())