Compare commits

...

81 Commits
v2.0 ... main

Author SHA1 Message Date
Carlos
544720331b Fixed colors in MC 1.18 2022-06-08 18:10:36 +02:00
Carlos Mesa
0b8bea51b9
Merge pull request #111 from mesacarlos/dependabot/maven/com.google.code.gson-gson-2.8.9
Bump gson from 2.8.5 to 2.8.9
2022-05-26 17:47:13 +02:00
dependabot[bot]
d2e5bcb293
Bump gson from 2.8.5 to 2.8.9
Bumps [gson](https://github.com/google/gson) from 2.8.5 to 2.8.9.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.8.5...gson-parent-2.8.9)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-26 15:43:58 +00:00
Carlos
dc1ad6d418 Workaround for TPS 2022-04-24 12:00:35 +02:00
Carlos Mesa
c5799af7dc
Merge pull request #107 from Kamillaova/master
Fix tps
2022-04-23 12:35:17 +02:00
Carlos
25ce2f6864 Prepare v2.4 release 2022-04-23 12:29:32 +02:00
Kamillaova
d59fe2c467
I have no words. Fix tps 2022-04-03 06:07:53 +03:00
Carlos
f0f263ebe0 Polskie translation (thanks to gpewojan1) 2022-02-13 15:17:59 +01:00
Carlos Mesa
b284b00a9b
Merge pull request #100 from HttpRafa/master
Added TPS
2022-01-09 15:33:08 +01:00
Carlos
a2c595ccb3 Deleted IDEA files from commit 2022-01-09 15:32:30 +01:00
HttpRafa
045c154f6c Added TPS 2022-01-08 23:32:57 +01:00
Carlos Mesa
b1847debbb
Merge pull request #98 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-core-2.17.1
Bump log4j-core from 2.17.0 to 2.17.1
2022-01-04 19:41:07 +01:00
Carlos Mesa
542448ad0b
Merge pull request #99 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-api-2.17.1
Bump log4j-api from 2.17.0 to 2.17.1
2022-01-04 19:41:00 +01:00
dependabot[bot]
10edee6226
Bump log4j-api from 2.17.0 to 2.17.1
Bumps log4j-api from 2.17.0 to 2.17.1.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 18:39:29 +00:00
dependabot[bot]
d5394144a3
Bump log4j-core from 2.17.0 to 2.17.1
Bumps log4j-core from 2.17.0 to 2.17.1.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-04 18:39:27 +00:00
Carlos Mesa
7d093b4800
Merge pull request #94 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-api-2.17.0
Bump log4j-api from 2.16.0 to 2.17.0
2021-12-18 19:38:32 +01:00
Carlos Mesa
dc3208004f
Merge pull request #95 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-core-2.17.0
Bump log4j-core from 2.16.0 to 2.17.0
2021-12-18 19:38:14 +01:00
dependabot[bot]
c5b959b306
Bump log4j-api from 2.16.0 to 2.17.0
Bumps log4j-api from 2.16.0 to 2.17.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-18 18:37:47 +00:00
dependabot[bot]
8c65a31f1b
Bump log4j-core from 2.16.0 to 2.17.0
Bumps log4j-core from 2.16.0 to 2.17.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-18 18:37:47 +00:00
Carlos Mesa
b60528b824
Merge pull request #93 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-api-2.16.0
Bump log4j-api from 2.15.0 to 2.16.0
2021-12-17 18:56:10 +01:00
dependabot[bot]
f5a11bd7f4
Bump log4j-api from 2.15.0 to 2.16.0
Bumps log4j-api from 2.15.0 to 2.16.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-17 17:55:43 +00:00
Carlos Mesa
820baaca67
Merge pull request #92 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-core-2.16.0
Bump log4j-core from 2.15.0 to 2.16.0
2021-12-17 18:55:21 +01:00
dependabot[bot]
be88747631
Bump log4j-core from 2.15.0 to 2.16.0
Bumps log4j-core from 2.15.0 to 2.16.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-17 17:54:41 +00:00
Carlos
832c801a60 Update readme 2021-12-11 16:26:18 +01:00
Carlos
4dd842286a Added japanese translation and bump to v2.3 2021-12-11 16:20:54 +01:00
Carlos Mesa
b26deceeeb
Merge pull request #90 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-api-2.15.0
Bump log4j-api from 2.12.1 to 2.15.0
2021-12-10 22:09:40 +01:00
dependabot[bot]
01c4c18ef2
Bump log4j-api from 2.12.1 to 2.15.0
Bumps log4j-api from 2.12.1 to 2.15.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-api
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 21:03:18 +00:00
Carlos Mesa
6faf5c3892
Merge pull request #89 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-core-2.15.0
Bump log4j-core from 2.13.2 to 2.15.0
2021-12-10 22:02:17 +01:00
dependabot[bot]
441c8851eb
Bump log4j-core from 2.13.2 to 2.15.0
Bumps log4j-core from 2.13.2 to 2.15.0.

---
updated-dependencies:
- dependency-name: org.apache.logging.log4j:log4j-core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 21:01:10 +00:00
Carlos Mesa
65b3582427
Merge pull request #86 from kuroneko6423/patch-2
Update index.html
2021-11-24 18:19:32 +01:00
Carlos Mesa
6503efb74d
Merge pull request #87 from kuroneko6423/patch-1
Update WebConsoleLanguage.js
2021-11-24 18:19:25 +01:00
kuroneko6423
cc245b8629
Update index.html 2021-11-24 07:40:59 +09:00
kuroneko6423
f4e6b79733
Update WebConsoleLanguage.js 2021-11-24 07:40:03 +09:00
Carlos Mesa
b7ca43284a
Merge pull request #83 from Vinamc/master
Allow save pre-config list of servers (Website)
2021-09-26 15:44:26 +02:00
Alex
8efd97ba75 allow save pre-config list of server 2021-09-25 21:13:32 +07:00
Carlos
211152a70d README fix 2021-08-22 13:42:40 +02:00
Carlos
7ef71ebdd1 Update readme to 2.2 2021-08-21 14:49:56 +02:00
Carlos Mesa
d0929adddd
Merge pull request #80 from awesomemoder316/master
Update to Version 2.2
2021-08-21 14:39:42 +02:00
Carlos
b055b9b248 Fix whitelist not checking some commands 2021-08-21 14:36:24 +02:00
Carlos
e6d230c2d8 Update client and modify configManager to autoupdate old config files 2021-08-21 13:19:39 +02:00
awesomemoder316
896e659e93
Merge pull request #1 from awesomemoder316/feature/command-whitelist&blacklist
Update to Version 2.2
2021-08-18 04:02:26 +00:00
awesomemoder316
05e2706fa9 Improve command whitelist checker. 2021-08-17 21:01:07 -07:00
awesomemoder316
0cb3156186 v2.1 -> v2.2 2021-08-17 19:33:42 -07:00
awesomemoder316
e846ad6441 Added check for whitelisted/blacklisted commands. 2021-08-17 19:33:09 -07:00
awesomemoder316
378d96c504 Added isWhitelistEnabled, isWhitelistActsAsBlacklist, and whitelistedCommands. 2021-08-17 19:32:21 -07:00
awesomemoder316
2cda25e281 viewer-error-console -> no-send-permission-console
Message name changed to better reflect new use case.
2021-08-17 19:30:31 -07:00
Carlos
a6087d13c8 Set setReuseAddr to true 2021-06-09 21:22:36 +02:00
Carlos
d593cf379e Minor fix solving a ConcurrentModificationException 2021-06-02 22:43:10 +02:00
Carlos Mesa
75a505c63f Remove issue templates 2021-01-05 19:45:57 +01:00
Carlos Mesa
55dd139746 Update issue templates 2020-12-24 12:32:21 +01:00
Carlos Mesa
60666d8433 Update issue templates 2020-12-12 23:45:59 +01:00
Carlos
7609179e24 Added wrapper 2020-12-12 13:52:36 +01:00
Carlos
383b0e3420 Changed v2.0 to v2.1 2020-12-05 13:34:17 +01:00
Carlos
dd9003190a Improved security 2020-12-05 13:26:04 +01:00
Carlos
d2696df7bc Edited readme 2020-11-30 12:32:56 +01:00
Carlos
27f769f6ac Fixed ram usage being incorrect 2020-11-28 19:31:58 +01:00
Carlos
7c4286f7df New server form is finally validating data (yay!) 2020-10-31 19:01:15 +01:00
Carlos Mesa
ffe238e977
Create codeql-analysis.yml 2020-10-02 19:17:59 +02:00
Carlos
05e225d507 Updated readme 2020-09-25 19:30:18 +02:00
Carlos
4dadd550a4 Updated footer 2020-09-25 19:16:52 +02:00
Carlos Mesa
613bfa7d6f
Merge pull request #50 from acarnd03/patch-1
changed wrong translations in tr_TR
2020-09-16 10:28:29 +02:00
acarnd03
60e483c3c3
changed wrong translations in tr_TR 2020-09-16 10:14:18 +03:00
Carlos Mesa
06e75e274d
Merge pull request #49 from acarnd03/master
Created phrases_tr.properties and translated client
2020-09-14 14:37:17 +02:00
Carlos
6fca4669e4 Translated client to tr-TR 2020-09-14 14:35:21 +02:00
acarnd03
7a1e5475bb
Created phrases_tr.properties 2020-09-14 13:58:28 +03:00
Carlos
c00ef4a0f5 Some phrases and README changes 2020-08-28 13:57:35 +02:00
Carlos Mesa
deac072d54
Merge pull request #45 from XxPKBxX/master
Modifications to korean translation
2020-08-27 14:00:25 +02:00
XxPKBxX
3316d0e450
Edited location of ko_KR 2020-08-27 13:36:31 +09:00
XxPKBxX
5703b8aa04
Added Korean Translation 2020-08-27 13:35:03 +09:00
Carlos
db61ea7e80 footer edited for v2.0 rev. 1 release 2020-08-26 21:51:16 +02:00
Carlos
4865db233d Added Korean translation 2020-08-26 16:15:00 +02:00
Carlos Mesa
9add265d34
Merge pull request #44 from XxPKBxX/master
Added Korean Translation
2020-08-26 15:44:22 +02:00
Carlos
dfe9851af4 Fixed dropdown link and added serverside translation 2020-08-26 15:43:27 +02:00
XxPKBxX
2c180a4bbf
Added Korean Translation 2020-08-26 20:23:37 +09:00
XxPKBxX
c3451fb6a2
Added Korean Translation 2020-08-26 20:22:44 +09:00
Carlos Mesa
5de27fe76e
Merge pull request #40 from mesacarlos/dependabot/maven/org.apache.logging.log4j-log4j-core-2.13.2
This vulnerability does not affect this plugin
2020-07-01 21:07:19 +02:00
dependabot[bot]
cc65b123ab
Bump log4j-core from 2.12.1 to 2.13.2
Bumps log4j-core from 2.12.1 to 2.13.2.

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-01 19:05:29 +00:00
Carlos
fc4235074b Code cleaning and optimization 2020-06-28 20:05:34 +02:00
Carlos
f177d1fe2d Code refactor 2020-06-25 16:53:10 +02:00
Carlos
45c3584061 Translation updates 2020-06-25 13:07:17 +02:00
Carlos
9680776275 Minor README update 2020-06-24 23:23:23 +02:00
54 changed files with 1591 additions and 356 deletions

71
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,71 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
name: "CodeQL"
on:
push:
branches: [master]
pull_request:
# The branches below must be a subset of the branches above
branches: [master]
schedule:
- cron: '0 6 * * 6'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Override automatic language detection by changing the below list
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
language: ['javascript', 'java']
# Learn more...
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

3
.gitignore vendored
View File

@ -69,3 +69,6 @@ local.properties
.cache-main
.scala_dependencies
.worksheet
#idea
.idea

103
API_js/WebConsoleAPI.js Normal file
View File

@ -0,0 +1,103 @@
/**
WebConsole API for WebConsole
Used to manage active connections
https://github.com/mesacarlos
2019-2020 Carlos Mesa under MIT License.
*/
class WebConsoleAPI {
constructor(serverURI){
this.activeConnection = new WebConsoleConnector(serverURI);
this.activeConnection.subscribe(this.onMsg);
this.activeConnection.connect();
}
/**
* Send password to server
*/
login(pwd){
this.activeConnection.sendToServer({
command: "LOGIN",
params: pwd
});
}
/**
* Send console command to server
*/
sendConsoleCmd(cmd){
this.activeConnection.sendToServer({
command: "EXEC",
token: this.activeConnection.token,
params: cmd
});
this.activeConnection.commands.push(cmd);
}
/**
* Asks server for CPU, RAM and players info
*/
askForInfo(){
this.activeConnection.sendToServer({
command: "PLAYERS",
token: this.activeConnection.token,
});
this.activeConnection.sendToServer({
command: "CPUUSAGE",
token: this.activeConnection.token,
});
this.activeConnection.sendToServer({
command: "RAMUSAGE",
token: this.activeConnection.token,
});
}
/**
* Asks server for full latest.log
*/
askForLogs(){
this.activeConnection.sendToServer({
command: "READLOGFILE",
token: this.activeConnection.token,
});
}
/**
* This function is executed when a message is received from the server
*/
onMsg(message){
//Print JSON to console. You may remove this line:
console.log(message);
//Type your code inside the switch cases:
switch (message.status) {
case 10:
//Console Output
//Info: The weird characters you probably get are the color indicators. Check the link below to learn how the official client parses them
//https://github.com/mesacarlos/WebConsole/blob/383b0e3420a948a61c7935ff84f40ff159fbd466/client/scripts/WebConsole.js#L128
break;
case 200:
//LoggedIn
break;
case 400:
//Unknown Command
break;
case 401:
//Waiting for login...
break;
case 1000:
//Connected players info
break;
case 1001:
//Cpu Usage info
break;
case 1002:
//RAM Usage info
break;
default:
console.log('Unknown server response:');
}
}
}

View File

@ -0,0 +1,96 @@
/**
WebConsole Connector for WebConsole
Used to connect to WebSocketsServer
https://github.com/mesacarlos
2019-2020 Carlos Mesa under MIT License.
*/
class WebConsoleConnector {
constructor(serverURI) {
this.serverURI = serverURI;
this.token;
this.subscribers = []; //List of functions called when a new message arrive
this.messages = []; //All messages retrieved since connection start
this.commands = []; //EXEC Commands sent by user to this server
this.isLogged = false; //Is logged in with valid pasword or not
}
/**
* Connect to WebSocket
*/
connect(){
var connector = this;
this.websocket = new WebSocket(this.serverURI);
this.websocket.onopen = function(evt) { connector.onOpen(evt) };
this.websocket.onclose = function(evt) { connector.onClose(evt) };
this.websocket.onmessage = function(evt) { connector.onMessage(evt) };
this.websocket.onerror = function(evt) { connector.onError(evt) };
}
/**
* Internal function
*/
onOpen(evt){
//Event: Connection opened
}
/**
* Internal function
*/
onClose(evt){
console.log("Closed reason: " + evt.reason); //No reason provided (using chrome at least)
}
/**
* Internal function
*/
onMessage(evt){
var obj = JSON.parse(evt.data);
//Sucessfully connected? Save token
if(obj.status === 200){
this.token = obj.token;
this.isLogged = true;
}
this.notify(obj); //Notify all subscribers
this.messages.push(obj);
}
/**
* Internal function
*/
onError(evt){
//Error occurred on the connection
}
/**
* Notifies a new message to all subscribers
*/
notify(obj){
this.subscribers.forEach(function(fun) {
fun(obj); //Calls function with this object
});
}
/**
* Sends a WebSocket command to Server
*/
sendToServer(message){
this.websocket.send(JSON.stringify(message));
}
/**
* Adds a function to subscriber list
*/
subscribe(func){
this.subscribers.push(func);
}
/**
* Unsubscribe all subscribers
*/
removeSubscribers(){
this.subscribers = [];
}
}

13
API_js/demo.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<script src="WebConsoleAPI.js"></script>
<script src="WebConsoleConnector.js"></script>
</head>
<body>
<h1>API demo</h1>
<p>Open your console (F12) and type: var webconsoleapi = new WebConsoleAPI("ws://localhost:8080");</p>
<p>Replace ws:// with wss:// if your server have SSL enabled, localhost with your server IP and 8080 with your port.</p>
<p>Then call login(pwd) to login, sendConsoleCmd(cmd) to execute a command, etc...</p>
</body>
</html>

View File

@ -4,18 +4,18 @@
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/mesacarlos/WebConsole)](https://github.com/mesacarlos/WebConsole/releases/latest)
![GitHub All Releases](https://img.shields.io/github/downloads/mesacarlos/WebConsole/total?label=total%20downloads)
WebConsole is a Spigot plugin for Minecraft 1.8-1.15+ 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.18+ that allows 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 or security: 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 MC server.
Don't worry about privacy or security: all data is stored in your browser locally and your PC will connect directly to your minecraft server. No intermediary web servers, just you and your MC server.
#### Additional features:
* Multiuser system and View-only user mode: Users with the role "Viewer" can only read console, CPU and RAM usage. Users with role "Admin" can also run commands on the server. Useful if you want your friends to watch the server console but deny them from typing commands and ruining your server.
* Multiuser system and View-only user mode: You can create multiple users and set their role to "Admin" or "Viewer". Users with the role "Viewer" can only read console, CPU and RAM usage. Users with role "Admin" can also run commands on the server. Useful if you want your friends to watch the server console but deny them from typing commands and ruining your server. Also, you can whitelist or blacklist some commands.
* Command history: Use up/down arrow keys to browse the command history, like in the real console.
* Colors supported, for both Windows and Linux hosts. (Colors are represented different in each platform).
* Real-time connected players, machine CPU and server RAM usage information.
* Capable of keeping active connections to more than one server to keep retrieving console log in the background for them all.
* English, Spanish, Chinese (thanks to Neubulae and OPhantomO), Czech (thanks to Tada), Deutsch (thanks to NoNamePro0), Dutch (thanks to Twockx), French (thanks to pickatchou999), Italian (thanks to AlexZap), Portuguese (thanks to AlexandreMuassab and Connect500BR) and Russian (thanks to Stashenko) supported.
* Free, updated regularly, and many more!
* English, Spanish, Chinese (thanks to Neubulae and OPhantomO), Czech (thanks to Tada), Deutsch (thanks to NoNamePro0), Dutch (thanks to Twockx), French (thanks to pickatchou999), Italian (thanks to AlexZap), Japanese (thanks to kuroneko6423), Korean (thanks to XxPKBxX), Portuguese (thanks to AlexandreMuassab and Connect500BR), Russian (thanks to Stashenko) and Turkish (thanks to acarnd03) supported.
* Free!
![Screenshot](https://i.imgur.com/sN1sYju.png)
@ -35,32 +35,39 @@ Dont worry about privacy or security: all data is stored in your browser offline
language: en
passwords:
&nbsp;&nbsp;&nbsp;admin:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user1: mySecurePassword
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user1:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password: mySecurePassword
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;commandWhitelist:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabled: true
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;commandWhitelistActsAsBlacklist: false
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;whitelist:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- whisper
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- gamemode survival
&nbsp;&nbsp;&nbsp;viewer: {}
A explanation of the `host`, `port`, `language` and `passwords` fields follows:
`host`: Leaving it as 0.0.0.0 will do the trick. If you want to listen to a network interface exclusively: If you are in a VPS or dedicated server (or you have a full public IP allocated for your device) type your public IP. If you are at your home (and you dont have a public IP assigned to your device) type your private IP, it should be something like 192.168.xx.xx.
`host`: Leaving it as 0.0.0.0 will do the trick. If you experience issues , you can change this value to your device IP. If you are in a VPS or dedicated server (or you have a full public IP allocated for your device) type your public IP. If you are at your home (and you don't have a public IP assigned to your device) type your private IP, it is probably something like 192.168.xx.xx.
`port`: A port where to run this plugin (cannot be the port you are using for Minecraft).
You can modify `language` to view console and command messages in your preferred language. Valid languages are English (`en`), Spanish (`es`), Chinese (`zh`), Czech (`cs`), Deutsch (`de`), Dutch (`nl`), French (`fr`), Italian (`it`), Portuguese (`pt`) and Russian (`ru`). **IMPORTANT: There is a known issue with Microsoft Windows cmd that shows weird characters when using a language different than English. If you are using Windows to host your server, check [this wiki page](https://github.com/mesacarlos/WebConsole/wiki/Show-local-characters-in-Windows-Console) to solve the problem**.
You can modify `language` to view console and command messages in your preferred language. Valid languages are English (`en`), Spanish (`es`), Chinese (`zh`), Czech (`cs`), Deutsch (`de`), Dutch (`nl`), French (`fr`), Italian (`it`), Japanese (`ja`) Korean (`ko`), Polskie (`pl`), Portuguese (`pt`), Russian (`ru`) and Turkish (`tr`). **IMPORTANT: There is a known issue with Microsoft Windows cmd that shows weird characters when using a language different than English. If you are using Windows to host your server, check [this wiki page](https://github.com/mesacarlos/WebConsole/wiki/Show-local-characters-in-Windows-Console) to solve the problem**.
From version 2.0 you can now create more than one user and set them as admin (Permission for both reading console and executing commands) or viewer (Permission for only reading console and CPU and RAM usage). This is configured using the `passwords` section:
- If you want to create a admin user, type below `admin:` a row like `user: password` replacing user with your desired username and password with your password.
- You can create as many admins as you want repeating this step.
- By default, a user called user1 with password mySecurePassword is created, please replace or remove it as it is only served as an example.
- If you want to create a view-only user, remove the `{}` after `viewer: ` and do the same process as for admin users below `viewer: `.
- If you want to create a view-only user, remove the `{}` after `viewer: ` and type below a row like `user: password` replacing user with your desired username and password with your password.
- You can create as many admins or viewers as needed.
- For all your admin users, you can enable a whitelist of commands under the commandWhitelist section of your user.
The rest of the fields are used for SSL configuration. You can see a tutorial on how to activate SSL [in this link](https://github.com/mesacarlos/WebConsole/wiki/SSL-Configuration). SSL **is not** required for WebConsole to work, you can still use it without encription, unless you are hosting your client in a HTTPS server, in this case is mandatory to enable SSL in all your servers due to web browsers restrictions.
The rest of the fields are used for SSL configuration. You can learn how to activate SSL [here](https://github.com/mesacarlos/WebConsole/wiki/SSL-Configuration). SSL **is not** required for WebConsole to work, you can still use it without encription, unless you are hosting your client in a HTTPS server, in this case is mandatory to enable SSL in all your servers due to web browsers restrictions.
## Using web interface
1. Download web interface (client.zip) from [Releases](https://github.com/mesacarlos/WebConsole/releases).
2. If you want, you can host it in a web server, or use it offline. That's up to you.
1. You can download web interface (client.zip) from [Releases](https://github.com/mesacarlos/WebConsole/releases) or, if you prefer, you can use my [WebConsole Hosted Clients](https://mesacarlos.es/webconsole/) webpage. You can host the client in a web server, or use it offline. That's up to you.
2. Open index.html if you downloaded the client or click on the latest version if you are using my Hosted Clients website.
3. To start adding servers, click on `Your servers`, and then `Add server`. Fill Server name, IP and WebConsole port (the one you placed into config.yml before), and you are ready to go. You will be prompted for password when connecting.
## Check connected WebConsole clients

View File

@ -1,3 +0,0 @@
If you are having issues with client not connecting and throwing random errors after a upgrade,
please force client reload on your browser by pressing Ctrl+F5 to reload the whole page.
This issue happens sometimes due to browsers caching JavaScript code.

View File

@ -47,13 +47,17 @@
<a class="dropdown-item" href="#" onclick="setLanguage('en_US')">English</a>
<a class="dropdown-item" href="#" onclick="setLanguage('es_ES')">Español</a>
<a class="dropdown-item" href="#" onclick="setLanguage('zh_CN')">中文</a>
<a class="dropdown-item" href="#" onclick="setLanguage('ko_KR')">한국어</a>
<a class="dropdown-item" href="#" onclick="setLanguage('cs_CZ')">Czech</a>
<a class="dropdown-item" href="#" onclick="setLanguage('de_DE')">Deutsche</a>
<a class="dropdown-item" href="#" onclick="setLanguage('nl_NL')">Dutch</a>
<a class="dropdown-item" href="#" onclick="setLanguage('fr_FR')">Français</a>
<a class="dropdown-item" href="#" onclick="setLanguage('it_IT')">Italiano</a>
<a class="dropdown-item" href="#" onclick="setLanguage('pt_BR')">Português</a>
<a class="dropdown-item" href="#" onclick="setLanguage('pl_PL')">Polskie</a>
<a class="dropdown-item" href="#" onclick="setLanguage('ru_RU')">русский</a>
<a class="dropdown-item" href="#" onclick="setLanguage('tr_TR')">Türk</a>
<a class="dropdown-item" href="#" onclick="setLanguage('ja_JA')">日本語</a>
</div>
</li>
<li class="nav-item">
@ -76,8 +80,8 @@
<div class="container" id="serverContainer" style="display: none;">
<h1 class="mt-4" id="serverTitle"></h1>
<div class="row p-3">
<div class="col-sm-3 mb-2">
<div class="row p-2">
<div class="col-sm-3">
<div class="card">
<div class="card-body">
<h5 class="card-title" id="players_online">Players Online</h5>
@ -88,7 +92,7 @@
</div>
</div>
</div>
<div class="col-sm-3 mb-2">
<div class="col-sm-3">
<div class="card">
<div class="card-body">
<h5 class="card-title" id="cpu_title">CPU</h5>
@ -99,7 +103,7 @@
</div>
</div>
</div>
<div class="col-sm-3 mb-2">
<div class="col-sm-3">
<div class="card">
<div class="card-body">
<h5 class="card-title" id="ram_title">RAM</h5>
@ -110,19 +114,32 @@
</div>
</div>
</div>
<div class="col-sm-3 mb-2">
<div class="col-sm-3">
<div class="card">
<div class="card-body">
<p class="card-text">
<span id="user_title">Logged as</span>
<span id="loggedUsernameLabel"></span>
(<span id="loggedUserTypeLabel"></span>)
</p>
<button type="button" class="btn btn-danger btn-sm" id="deleteServerButton">Delete server</button>
<h5 class="card-title" id="tps_title">TPS</h5>
<p class="card-text"><span id="tps">0</span> Ticks / <span id="maxTps">0</span> Ticks</p>
<div class="progress flat-progressbar">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%;" id="TpsProgressBar"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row p-2 mb-2">
<div class="col-sm-9">
<div class="card">
<div class="card-body">
<span id="user_title">Logged as</span>&nbsp;<span id="loggedUsernameLabel">Unknown</span>&nbsp;(<span id="loggedUserTypeLabel">Unknown</span>)
</div>
</div>
</div>
<div class="col-sm-3">
<div class="card">
<button type="button" class="btn btn-danger btn-sm" id="deleteServerButton">Delete server</button>
</div>
</div>
</div>
<div class="card mb-2">
<div class="card-body overflow-auto text-light bg-dark console" id="consoleTextArea"></div>
@ -147,7 +164,7 @@
</button>
</div>
<div class="modal-body">
<form>
<form id="addServerForm">
<div class="form-group">
<label for="server-name" class="col-form-label" id="addServerModalSvName">Server name:</label>
<input type="text" class="form-control" id="server-name" required>
@ -158,7 +175,7 @@
</div>
<div class="form-group">
<label for="server-port" class="col-form-label" id="addServerModalSvPort">Server port:</label>
<input type="number" class="form-control" id="server-port" placeholder="8080" required>
<input type="number" class="form-control" id="server-port" placeholder="8080" min="1" max="65535" required>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="server-ssl">
@ -169,7 +186,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal" id="addServerModalClose">Close</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" id="saveAndConnectServerButton">Save and connect</button>
<button type="button" class="btn btn-primary" id="saveAndConnectServerButton">Save and connect</button>
</div>
</div>
</div>
@ -217,8 +234,12 @@
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="disconnectionModalDescription">
Connection was lost with the server you were connected to, probably caused by a server stop.
<div class="modal-body">
<span id="disconnectionModalDescription">Connection was lost with the server. This can be caused by:</span>
<ul>
<li id="disconnectionModalsub1">Server was closed intentionally.</li>
<li id="disconnectionModalsub2">Port is not opened on your host. In this case, troubleshoot using <a href="https://www.yougetsignal.com/tools/open-ports/">this tool</a> and recheck your firewall or router.</li>
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal" id="disconnectionModalCloseButton">Close</button>
@ -258,7 +279,7 @@
<!-- Webpage footer -->
<footer class="footer mt-auto py-3">
<div class="container">
<span class="text-muted">WebConsole v2.0 - <a href="https://github.com/mesacarlos/WebConsole">GitHub</a></span>
<span class="text-muted">WebConsole v2.4 - <a href="https://github.com/mesacarlos/WebConsole">GitHub</a></span>
</div>
</footer>
@ -268,15 +289,15 @@
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<!-- WebConsole JS Objects -->
<script src="scripts/object/Setting.js?v=1.6"></script>
<script src="scripts/object/WSServer.js?v=1.6"></script>
<script src="scripts/object/Setting.js?v=2.4.0"></script>
<script src="scripts/object/WSServer.js?v=2.4.0"></script>
<!-- WebConsole JS Scripts -->
<script src="scripts/WebConsoleLanguage.js?v=1.6"></script>
<script src="scripts/WebConsoleConnector.js?v=1.6"></script>
<script src="scripts/WebConsoleManager.js?v=1.6"></script>
<script src="scripts/WebConsolePersistenceManager.js?v=1.6"></script>
<script src="scripts/WebConsole.js?v=1.6"></script>
<script src="scripts/WebConsoleJqueryHandler.js?v=1.6"></script>
<script src="scripts/WebConsoleLanguage.js?v=2.4.0"></script>
<script src="scripts/WebConsoleConnector.js?v=2.4.0"></script>
<script src="scripts/WebConsoleManager.js?v=2.4.0"></script>
<script src="scripts/WebConsolePersistenceManager.js?v=2.4.0"></script>
<script src="scripts/WebConsole.js?v=2.4.0"></script>
<script src="scripts/WebConsoleJqueryHandler.js?v=2.4.0"></script>
</body>
</html>

View File

@ -5,14 +5,39 @@
*/
/**
* Global variables
*/
var persistenceManager = new WebConsolePersistenceManager();
var connectionManager = new WebConsoleManager();
var lang;
var autoPasswordCompleted = false; //When true, saved password was used. If a 401 is received, then saved password is not correct
var statusCommandsInterval = -1;
var commandHistoryIndex = -1; //Saves current command history index. -1 when not browsing history.
* Global variables
*/
const persistenceManager = new WebConsolePersistenceManager();
const connectionManager = new WebConsoleManager();
let lang;
let autoPasswordCompleted = false; //When true, saved password was used. If a 401 is received, then saved password is not correct
let statusCommandsInterval = -1;
let commandHistoryIndex = -1; //Saves current command history index. -1 when not browsing history.
/**
* Load list of servers in file servers.json
* and auto update in next request when file is changed
*/
function readServerList() {
let hash = persistenceManager.getSetting('server:hash')
/**
* Hash code function used for compare version of file servers.json
* https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript
*/
const hashCode = s => s.split('').reduce((a,b)=>{a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
fetch('servers.json')
.then(res => res.text())
.then(json => {
if (hash !== hashCode(json)) {
persistenceManager.setSetting('server:hash', hashCode(json))
JSON.parse(json).forEach(server => persistenceManager.saveServer(server))
}
})
.then(updateServerList)
.catch(() => console.info('Ignore load new list in file servers.json.'));
}
/**
* Prepare and show server to user
@ -36,10 +61,10 @@ function openServer(serverName){
connectionManager.loadConnection(serverName);
//Load saved messages
var i;
var messages = connectionManager.activeConnection.messages;
let i;
const messages = connectionManager.activeConnection.messages;
for(i = 0; i < messages.length; i++){
if(messages[i].status != 401){
if(messages[i].status !== 401){
onWebSocketsMessage(messages[i]);
}
}
@ -63,7 +88,7 @@ function onWebSocketsMessage(message){
$("#loggedUserTypeLabel").text(message.as);
//Disable command bar if user is viewer
if(message.as.toLowerCase() == "viewer"){
if(message.as.toLowerCase() === "viewer"){
$("#commandInput").prop("disabled", true);
$("#sendCommandButton").prop("disabled", true);
}
@ -81,7 +106,7 @@ function onWebSocketsMessage(message){
break;
case 401:
//Waiting for login. Show password modal or retrieve password
var savedPwd = persistenceManager.getServer(connectionManager.activeConnection.serverName).serverPassword;
const savedPwd = persistenceManager.getServer(connectionManager.activeConnection.serverName).serverPassword;
if(typeof savedPwd !== "undefined" && !autoPasswordCompleted){
connectionManager.sendPassword(savedPwd);
autoPasswordCompleted = true;
@ -102,13 +127,17 @@ function onWebSocketsMessage(message){
//RAM Usage
writeRamInfo(message.free, message.used, message.max);
break;
case 1003:
//Server TPS
writeTpsInfo(message.tps, 20);
break;
default:
console.log('Unknown server response:');
}
console.log(message);
//Add interval for Players, CPU and RAM info, if not set
if(statusCommandsInterval == -1 && message.status !== 401){
if(statusCommandsInterval === -1 && message.status !== 401){
statusCommandsInterval = setInterval(function(){
connectionManager.askForInfo();
}, 2500);
@ -119,7 +148,7 @@ function onWebSocketsMessage(message){
* Write to console
*/
function writeToWebConsole(msg, time){
var isScrolledDown = document.getElementById("consoleTextArea").scrollHeight - document.getElementById("consoleTextArea").scrollTop - 40 == $("#consoleTextArea").height();
const isScrolledDown = document.getElementById("consoleTextArea").scrollHeight - document.getElementById("consoleTextArea").scrollTop - 40 === $("#consoleTextArea").height();
//Write to div, replacing < to &lt; (to avoid XSS) and replacing new line to br.
msg = msg.replace(/</g, "&lt;");
@ -170,6 +199,32 @@ function writeToWebConsole(msg, time){
msg = msg.replace(/§r/g, "</span>"); //&r
//Color filter for MC 1.18 (Also easy :D)
//span may not be closed every time but browsers will do for ourselves
msg = msg.replace(/0/g, "<span style='color: #000000;'>"); //&0
msg = msg.replace(/1/g, "<span style='color: #0000AA;'>"); //&1
msg = msg.replace(/2/g, "<span style='color: #00AA00;'>"); //&2
msg = msg.replace(/3/g, "<span style='color: #00AAAA;'>"); //&3
msg = msg.replace(/4/g, "<span style='color: #AA0000;'>"); //&4
msg = msg.replace(/5/g, "<span style='color: #AA00AA;'>"); //&5
msg = msg.replace(/6/g, "<span style='color: #FFAA00;'>"); //&6
msg = msg.replace(/7/g, "<span style='color: #AAAAAA;'>"); //&7
msg = msg.replace(/8/g, "<span style='color: #555555;'>"); //&8
msg = msg.replace(/9/g, "<span style='color: #5555FF;'>"); //&9
msg = msg.replace(/a/g, "<span style='color: #55FF55;'>"); //&a
msg = msg.replace(/b/g, "<span style='color: #55FFFF;'>"); //&b
msg = msg.replace(/c/g, "<span style='color: #FF5555;'>"); //&c
msg = msg.replace(/d/g, "<span style='color: #FF55FF;'>"); //&d
msg = msg.replace(/e/g, "<span style='color: #FFFF55;'>"); //&e
msg = msg.replace(/f/g, "<span style='color: #FFFFFF;'>"); //&f
msg = msg.replace(/l/g, "<span style='font-weight:bold;'>"); //&l
msg = msg.replace(/m/g, "<span style='text-decoration: line-through;'>"); //&m
msg = msg.replace(/n/g, "<span style='text-decoration: underline;'>"); //&n
msg = msg.replace(/o/g, "<span style='font-style: italic;'>"); //&o
msg = msg.replace(/r/g, "</span>"); //&r
//Append datetime if enabled
if(persistenceManager.getSetting("dateTimePrefix")){
if(typeof time !== 'undefined' && time !== null) //if time is present and not null
@ -184,7 +239,7 @@ function writeToWebConsole(msg, time){
$("#consoleTextArea").append(msg + "<br>");
if(isScrolledDown){
var textarea = document.getElementById('consoleTextArea');
const textarea = document.getElementById('consoleTextArea');
textarea.scrollTop = textarea.scrollHeight;
}
}
@ -196,7 +251,7 @@ function writePlayerInfo(connected, maximum){
$("#connectedPlayers").text(connected);
$("#maxPlayers").text(maximum);
var percent = (connected/maximum)*100;
const percent = (connected / maximum) * 100;
$("#playerProgressBar").width(percent + "%");
}
@ -216,15 +271,29 @@ function writeRamInfo(free, used, total){
$("#usedRam").text(used);
$("#totalRam").text(total);
var percent = (used/total)*100;
const percent = (used / total) * 100;
$("#RamProgressBar").width(percent + "%");
}
/**
* Fill TPS info card
*/
function writeTpsInfo(tps, max){
if(tps > 20) {
tps = 20;
}
$("#tps").text(tps);
$("#maxTps").text(max);
const percent = (tps / max) * 100;
$("#TpsProgressBar").width(percent + "%");
}
/**
* Called from WebConsoleConnector only.
*/
function closedConnection(serverName){
if(connectionManager.activeConnection.serverName == serverName){
if(connectionManager.activeConnection.serverName === serverName){
//Disable command input and button
$("#commandInput").prop("disabled", true);
$("#sendCommandButton").prop("disabled", true);
@ -263,13 +332,13 @@ function updateServerList(){
$('.servermenuitem').remove();
//Add all servers
var servers = persistenceManager.getAllServers();
for(var i = 0; i < servers.length; i++){
const servers = persistenceManager.getAllServers();
for(let i = 0; i < servers.length; i++){
$('#ServerListDropDown').append('<a class="dropdown-item servermenuitem" href="#" onclick="openServer(\'' + servers[i].serverName + '\')">' + servers[i].serverName.replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"").replace(/"/g,"") + '</a>');
}
//Show a "no servers" message when no servers are added
if(servers.length == 0){
if(servers.length === 0){
$('#ServerListDropDown').append('<a class="dropdown-item servermenuitem disabled" href="#" id="noServersAdded">No servers added</a>');
}
}

View File

@ -9,6 +9,7 @@ class WebConsoleConnector {
constructor(serverName, serverURI) {
this.serverName = serverName;
this.serverURI = serverURI;
this.token;
this.subscribers = []; //List of functions called when a new message arrive
this.messages = []; //All messages retrieved since connection start
this.commands = []; //EXEC Commands sent by user to this server
@ -32,7 +33,7 @@ class WebConsoleConnector {
* Internal function
*/
onOpen(evt){
//TODO Check que la version es correcta, y que es un WebSocket del plugin y no de otra cosa
//TODO Check version is correct, and this websocket server is a WebConsole WebSocket
}
/**
@ -48,6 +49,11 @@ class WebConsoleConnector {
*/
onMessage(evt){
var obj = JSON.parse(evt.data);
if(obj.status === 200) //If is a LoggedIn response, save our token
this.token = obj.token;
this.notify(obj); //Notify all subscribers
this.messages.push(obj);
}
@ -63,7 +69,7 @@ class WebConsoleConnector {
* Sends a WebSocket command to Server
*/
sendToServer(message){
this.websocket.send(message);
this.websocket.send(JSON.stringify(message));
}
/**

View File

@ -11,6 +11,7 @@ $(document).ready(function() {
$("#serverContainer").hide();
persistenceManager.initializeSettings();
setLanguage(persistenceManager.getLanguage());
readServerList();
updateServerList();
//Check SSL host
@ -34,6 +35,13 @@ $(document).ready(function() {
* Add server modal button click
*/
$("#saveAndConnectServerButton").click(function() {
//Validate form data
var addServerForm = document.getElementById("addServerForm");
if(!addServerForm.checkValidity()){
addServerForm.classList.add('was-validated');
return;
}
//Save server
var name = $("#server-name").val().replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"").replace(/"/g,"");
var wcIp = $("#server-ip").val();
@ -47,6 +55,10 @@ $("#saveAndConnectServerButton").click(function() {
}
persistenceManager.saveServer(new WSServer(name, uri));
//Close modal
addServerForm.classList.remove('was-validated');
$("#addServerModal").modal('hide');
//Empty all modal values
$("#server-name").val("");
$("#server-ip").val("");

View File

@ -22,8 +22,8 @@ function setLanguage(locale){
"addServerModalSvName": "Server name:",
"addServerModalSvIp": "Server IP:",
"addServerModalSvPort": "WebConsole port:",
"addServerModalSvSsl": "Server is SSL enabled",
"addServerModalSslAdvice": "SSL is required for HTTPS client connections",
"addServerModalSvSsl": "SSL is enabled on the server",
"addServerModalSslAdvice": "SSL is required for connections made from HTTPS websites",
"addServerModalClose": "Close",
"saveAndConnectServerButton": "Save and connect",
"passwordModalLongTitle": "Password required",
@ -32,7 +32,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Close",
"passwordSendButton": "Login",
"disconnectionModalLongTitle": "Disconnected",
"disconnectionModalDescription": "Connection was lost with the server you were connected to, probably caused by a server stop.",
"disconnectionModalDescription": "Connection was lost with the server. This can be caused by:",
"disconnectionModalsub1": "Server was closed intentionally.",
"disconnectionModalsub2": "Port is not opened on your host. In this case, troubleshoot using a port checker and recheck your firewall or router.",
"disconnectionModalCloseButton": "Close",
"disconnectionModalWelcomeScreenButton": "Back to welcome page",
"settingsLink": "Settings",
@ -43,6 +45,7 @@ function setLanguage(locale){
"players_online": "Players Online",
"cpu_title": "CPU",
"ram_title": "RAM usage",
"user_title": "Logged as",
"deleteServerButton": "Delete server",
"sendCommandButton": "Send"
}
@ -70,7 +73,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Cerrar",
"passwordSendButton": "Iniciar sesión",
"disconnectionModalLongTitle": "Desconectado",
"disconnectionModalDescription": "Se ha perdido la conexión con el servidor al que estabas conectado. Esto puede ser debido a que el servidor se ha cerrado.",
"disconnectionModalDescription": "Se perdió la conexión con el servidor. Esto puede deberse a:",
"disconnectionModalsub1": "El servidor se cerró intencionadamente.",
"disconnectionModalsub2": "El puerto no está abierto en el host. Utiliza un port checker para verificar que el puerto está abierto y comprueba tu firewall o router.",
"disconnectionModalCloseButton": "Cerrar",
"disconnectionModalWelcomeScreenButton": "Volver a pagina de inicio",
"settingsLink": "Configuración",
@ -81,6 +86,7 @@ function setLanguage(locale){
"players_online": "Jugadores en línea",
"cpu_title": "CPU",
"ram_title": "RAM en uso",
"user_title": "Iniciado sesion como",
"deleteServerButton": "Borrar servidor",
"sendCommandButton": "Enviar"
}
@ -108,7 +114,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Закрыть",
"passwordSendButton": "Войти",
"disconnectionModalLongTitle": "Отключение!",
"disconnectionModalDescription": "Соединение с сервером, к которому вы подключены, потеряно.",
"disconnectionModalDescription": "Было потеряно соединение с сервером. Это может быть вызвано:",
"disconnectionModalsub1": "Сервер был закрыт намеренно.",
"disconnectionModalsub2": "Порт не открыт на вашем хосте. В этом случае устраните неполадки с помощью средства проверки портов и еще раз проверьте свой брандмауэр или маршрутизатор.",
"disconnectionModalCloseButton": "Закрыть",
"disconnectionModalWelcomeScreenButton": "Вернуться на страницу приветствия",
"settingsLink": "настройки",
@ -119,6 +127,7 @@ function setLanguage(locale){
"players_online": "Игроки",
"cpu_title": "CPU",
"ram_title": "RAM",
"user_title": "Вы вошли как",
"deleteServerButton": "Удалить сервер",
"sendCommandButton": "Отправить"
}
@ -146,7 +155,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Fechar",
"passwordSendButton": "Logar",
"disconnectionModalLongTitle": "desconectado",
"disconnectionModalDescription": "Você foi desconectado, pode ser que o servidor foi fechado/reiniciado ou pode haver algum problema com a sua conexão.",
"disconnectionModalDescription": "A conexão com o servidor foi perdida. Isso pode ser causado por:",
"disconnectionModalsub1": "O servidor foi fechado intencionalmente.",
"disconnectionModalsub2": "A porta não está aberta em seu host. Se for esse o caso, solucione o problema com um testador de porta e verifique seu firewall ou router novamente.",
"disconnectionModalCloseButton": "Fechar",
"disconnectionModalWelcomeScreenButton": "Voltar à página de boas-vindas",
"settingsLink": "Configurações",
@ -157,6 +168,7 @@ function setLanguage(locale){
"players_online": "Jogadores online",
"cpu_title": "Consumo de CPU",
"ram_title": "Consumo de RAM",
"user_title": "Logado como",
"deleteServerButton": "Remover este servidor",
"sendCommandButton": "Enviar"
}
@ -184,7 +196,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "关闭",
"passwordSendButton": "登录",
"disconnectionModalLongTitle": "已断开",
"disconnectionModalDescription": "与服务器的通信中断, 可能是因为服务器停止运行.",
"disconnectionModalDescription": "与服务器的连接丢失。 这可能是由于:",
"disconnectionModalsub1": "服务器是有意关闭的。",
"disconnectionModalsub2": "您的主机上的端口未打开。 如果是这种情况,请使用端口测试仪进行故障排除,然后再次检查防火墙或路由器。",
"disconnectionModalCloseButton": "关闭",
"disconnectionModalWelcomeScreenButton": "返回欢迎页面",
"settingsLink": "设定值",
@ -195,10 +209,52 @@ function setLanguage(locale){
"players_online": "在线人数",
"cpu_title": "CPU",
"ram_title": "内存使用量",
"user_title": "登录为",
"deleteServerButton": "关闭服务器",
"sendCommandButton": "发送"
}
break;
case "ko_KR":
lang = {
"navbarHomeLink": "메인",
"home_header": "메뉴에서 서버를 선택해 주세요",
"home_description": "새 서버를 추가하거나 전에 추가한 서버에 연결하려면 네비게이션 바를 사용하세요.",
"serversDropdown": "서버 목록",
"add_server": "서버 추가하기",
"noServersAdded": "서버 없음",
"lang_dropdown": "언어",
"addServerModalLongTitle": "서버 추가",
"addServerModalSvName": "서버 이름:",
"addServerModalSvIp": "서버 주소:",
"addServerModalSvPort": "WebConsole 포트:",
"addServerModalSvSsl": "서버가 SSL을 사용합니다",
"addServerModalSslAdvice": "SSL은 HTTPS 연결을 위해 필요합니다",
"addServerModalClose": "닫기",
"saveAndConnectServerButton": "저장하고 연결하기",
"passwordModalLongTitle": "비밀번호 필요",
"passwordModalLabel": "비밀번호:",
"passwordModalRememberLabel": "비밀번호 기억",
"passwordModalCloseButton": "닫기",
"passwordSendButton": "로그인",
"disconnectionModalLongTitle": "연결 끊김",
"disconnectionModalDescription": "서버와의 연결이 끊어졌습니다. 원인은 다음과 같습니다.",
"disconnectionModalsub1": "서버가 의도적으로 닫혔습니다.",
"disconnectionModalsub2": "호스트에서 포트가 열려 있지 않습니다. 이 경우 포트 테스터로 문제를 해결하고 방화벽이나 라우터를 다시 확인하십시오.",
"disconnectionModalCloseButton": "닫기",
"disconnectionModalWelcomeScreenButton": "메인으로 돌아가기",
"settingsLink": "설정",
"settingsModalLongTitle": "WebConsole 설정",
"showDateSettingsSwitchLabel": "모든 줄에 시각 표시하기",
"readLogFileSwitchLabel": "로그인 후 전체 로그 파일 읽기",
"settingsModalCloseButton": "완료",
"players_online": "온라인인 플레이어",
"cpu_title": "CPU",
"ram_title": "RAM 사용량",
"user_title": "로그인된 사용자:",
"deleteServerButton": "서버 삭제하기",
"sendCommandButton": "전송"
}
break;
case "fr_FR":
lang = {
"navbarHomeLink": "Page d'accueil",
@ -222,7 +278,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Fermer",
"passwordSendButton": "S'identifier",
"disconnectionModalLongTitle": "Débranché",
"disconnectionModalDescription": "La connexion a été perdue avec le serveur auquel vous étiez connecté, probablement en raison d'un arrêt du serveur.",
"disconnectionModalDescription": "La connexion avec le serveur a été perdue. Cela peut être causé par:",
"disconnectionModalsub1": "Le serveur a été fermé intentionnellement.",
"disconnectionModalsub2": "Le port n'est pas ouvert sur votre hôte. Si tel est le cas, dépannez avec un testeur de port et vérifiez à nouveau votre firewall ou votre router.",
"disconnectionModalCloseButton": "Fermer",
"disconnectionModalWelcomeScreenButton": "Retour à la page d'accueil",
"settingsLink": "Réglages",
@ -233,6 +291,7 @@ function setLanguage(locale){
"players_online": "Joueurs en ligne",
"cpu_title": "Utilisation de la CPU",
"ram_title": "Utilisation de la RAM",
"user_title": "Connecté en tant que",
"deleteServerButton": "Supprimer le serveur",
"sendCommandButton": "Envoyer"
}
@ -260,7 +319,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Zavřít",
"passwordSendButton": "Přihlásit se",
"disconnectionModalLongTitle": "Odpojeno",
"disconnectionModalDescription": "Spojení se serverem s kterým jste byli spojení bylo přerušeno, pravděpodobně z důvodu vypnutí serveru.",
"disconnectionModalDescription": "Připojení bylo ztraceno se serverem. To může být způsobeno:",
"disconnectionModalsub1": "Server byl úmyslně uzavřen.",
"disconnectionModalsub2": "Port není na hostiteli otevřený. Pokud tomu tak je, odstraňte problém s testerem portů a znovu zkontrolujte firewall nebo router.",
"disconnectionModalCloseButton": "Zavřít",
"disconnectionModalWelcomeScreenButton": "Zpět na úvodní stránku",
"settingsLink": "Nastavení",
@ -271,6 +332,7 @@ function setLanguage(locale){
"players_online": "Počet hráčů online",
"cpu_title": "CPU",
"ram_title": "Využití RAM",
"user_title": "Přihlášen jako",
"deleteServerButton": "Odstranit server",
"sendCommandButton": "Odeslat"
}
@ -298,7 +360,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Chiudi",
"passwordSendButton": "Login",
"disconnectionModalLongTitle": "Disconnesso",
"disconnectionModalDescription": "La connessione è stata persa al server al quale eri connesso, probabilmente il server e stato fermato con il comando stop.",
"disconnectionModalDescription": "La connessione con il server è stata persa. Ciò può essere causato da:",
"disconnectionModalsub1": "Il server è stato chiuso intenzionalmente.",
"disconnectionModalsub2": "La porta non è aperta sul tuo host. In tal caso, risolvere i problemi con un tester della porta e controllare nuovamente il firewall o il router.",
"disconnectionModalCloseButton": "Chiudi",
"disconnectionModalWelcomeScreenButton": "Torna alla Home",
"settingsLink": "Impostazioni",
@ -309,6 +373,7 @@ function setLanguage(locale){
"players_online": "Giocatori online",
"cpu_title": "Utilizzo CPU",
"ram_title": "Utilizzo RAM",
"user_title": "Collegato come",
"deleteServerButton": "Cancella il server",
"sendCommandButton": "Invio"
}
@ -336,7 +401,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Sluiten",
"passwordSendButton": "Log in",
"disconnectionModalLongTitle": "Verbinding verbroken",
"disconnectionModalDescription": "De verbinding met de server waarmee u was verbonden is verbroken, waarschijnlijk is dit veroorzaakt door een serverstop.",
"disconnectionModalDescription": "De verbinding met de server is verbroken. Dit kan worden veroorzaakt door:",
"disconnectionModalsub1": "De server is opzettelijk gesloten.",
"disconnectionModalsub2": "De poort is niet open op uw host. Als dit het geval is, lost u het probleem op met een poorttester en controleert u uw firewall of router opnieuw.",
"disconnectionModalCloseButton": "Sluiten",
"disconnectionModalWelcomeScreenButton": "Terug naar homepagina",
"settingsLink": "Instellingen",
@ -347,6 +414,7 @@ function setLanguage(locale){
"players_online": "Spelers online",
"cpu_title": "CPU",
"ram_title": "RAM gebruik",
"user_title": "Aangemeld als",
"deleteServerButton": "Verwijder server",
"sendCommandButton": "Stuur"
}
@ -374,7 +442,9 @@ function setLanguage(locale){
"passwordModalCloseButton": "Schließen",
"passwordSendButton": "Login",
"disconnectionModalLongTitle": "Verbindung getrennt",
"disconnectionModalDescription": "Die Verbindung wurde unterbrochen. Ist vielleicht dein Server gestoppt?",
"disconnectionModalDescription": "Die Verbindung zum Server wurde unterbrochen. Dies kann verursacht werden durch:",
"disconnectionModalsub1": "Server wurde absichtlich geschlossen.",
"disconnectionModalsub2": "Der Port ist auf Ihrem Host nicht geöffnet. Wenn dies der Fall ist, beheben Sie die Fehlerbehebung mit einem Port-Tester und überprüfen Sie Ihre Firewall oder Ihren Router erneut.",
"disconnectionModalCloseButton": "Schließen",
"disconnectionModalWelcomeScreenButton": "Zurück zur Startseite",
"settingsLink": "Einstellungen",
@ -385,10 +455,134 @@ function setLanguage(locale){
"players_online": "Spieler Online",
"cpu_title": "CPU",
"ram_title": "RAM",
"user_title": "Angemeldet als",
"deleteServerButton": "Server entfernen",
"sendCommandButton": "Senden"
}
break;
case "tr_TR": //Credit to acarnd03
lang = {
"navbarHomeLink": "Ev",
"home_header": "Menüden bir sunucu seçin",
"home_description": "Yeni bir Minecraft Sunucusu eklemek veya önceden eklenmiş bir sunucuya bağlanmak için gezinme çubuğunu kullanın.",
"serversDropdown": "Sunucularınız",
"add_server": "Sunucu ekle",
"noServersAdded": "Sunucu eklenmedi",
"lang_dropdown": "Dil",
"addServerModalLongTitle": "Yeni bir sunucu ekleyin",
"addServerModalSvName": "Sunucu adı:",
"addServerModalSvIp": "Sunucu IP'si:",
"addServerModalSvPort": "WebConsole bağlantı noktası:",
"addServerModalSvSsl": "Sunucu SSL etkin",
"addServerModalSslAdvice": "HTTPS istemci bağlantıları için SSL gereklidir",
"addServerModalClose": "Kapat",
"saveAndConnectServerButton": "Kaydet ve bağlan",
"passwordModalLongTitle": "Şifre gereklidir",
"passwordModalLabel": "Parola:",
"passwordModalRememberLabel": "Şifremi hatırla",
"passwordModalCloseButton": "Kapat",
"passwordSendButton": "Oturum aç",
"disconnectionModalLongTitle": "Bağlantı kesildi",
"disconnectionModalDescription": "Sunucuyla bağlantı kesildi. Bunun nedeni şunlar olabilir:",
"disconnectionModalsub1": "Sunucu kasıtlı olarak kapatıldı.",
"disconnectionModalsub2": "Ana makinenizde bağlantı noktasıılmadı. Bu durumda, bir bağlantı noktası denetleyicisi kullanarak sorunu giderin ve güvenlik duvarınızı veya yönlendiricinizi yeniden kontrol edin.",
"disconnectionModalCloseButton": "Kapat",
"disconnectionModalWelcomeScreenButton": "Karşılama sayfasına geri dön",
"settingsLink": "Ayarlar",
"settingsModalLongTitle": "WebConsole Ayarları",
"showDateSettingsSwitchLabel": "Her konsol satırında zamanı göster",
"readLogFileSwitchLabel": "Giriş yaptıktan sonra tam günlük dosyasını sunucudan alın",
"settingsModalCloseButton": "Bitti",
"players_online": "Çevrimiçi Oyuncular",
"cpu_title": "CPU",
"ram_title": "RAM kullanımı",
"user_title": "olarak giriş yapıldı",
"deleteServerButton": "Sunucuyu silin",
"sendCommandButton": "Gönder"
}
break;
case "ja_JA": //Credit to kuroneko6423 | https://kuroneko6423.com
lang = {
"navbarHomeLink": "ホーム",
"home_header": "メニューからサーバーを選択",
"home_description": "ナビゲーションバーを使って、新しいMinecraftサーバーを追加したり、以前に追加したサーバーに接続したりします。",
"serversDropdown": "あなたのサーバー",
"add_server": "サーバー追加",
"noServersAdded": "追加されたサーバーはありません",
"lang_dropdown": "言語",
"addServerModalLongTitle": "新規サーバーの追加",
"addServerModalSvName": "サーバー名:",
"addServerModalSvIp": "サーバーIP:",
"addServerModalSvPort": "WebConsoleポート:",
"addServerModalSvSsl": "サーバーでSSLが有効になっている",
"addServerModalSslAdvice": "HTTPSウェブサイトからの接続にはSSLが必要です。",
"addServerModalClose": "閉じる",
"saveAndConnectServerButton": "保存と接続",
"passwordModalLongTitle": "パスワードが必要です",
"passwordModalLabel": "パスワード:",
"passwordModalRememberLabel": "パスワードの記憶",
"passwordModalCloseButton": "閉じる",
"passwordSendButton": "ログイン",
"disconnectionModalLongTitle": "切断",
"disconnectionModalDescription": "サーバーとの接続が切断されました:",
"disconnectionModalsub1": "サーバーが意図的に閉じられました。",
"disconnectionModalsub2": "ポートがホスト上で開かれていません。この場合、ポートチェッカーを使ってトラブルシューティングを行い、ファイアウォールやルーターを再確認してください。",
"disconnectionModalCloseButton": "閉じる",
"disconnectionModalWelcomeScreenButton": "ホームに戻る",
"settingsLink": "設定",
"settingsModalLongTitle": "WebConsole 設定",
"showDateSettingsSwitchLabel": "各コンソールラインに時間を表示",
"readLogFileSwitchLabel": "ログイン後にサーバーからフルログファイルを取得する",
"settingsModalCloseButton": "了承",
"players_online": "プレイヤーオンライン",
"cpu_title": "CPU",
"ram_title": "RAM",
"user_title": "ログインします。",
"deleteServerButton": "サーバーを削除",
"sendCommandButton": "送信"
}
break;
case "pl_PL": //Credit to gpewojan1
lang = {
"navbarHomeLink": "Strona główna",
"home_header": "Wybierz serwer z menu",
"home_description": "Użyj zakładki \"Twoje serwery\", aby dodać nowy serwer Minecraft lub połączyć się do serwera dodanego wcześniej",
"serversDropdown": "Twoje serwery",
"add_server": "Dodaj Serwer",
"noServersAdded": "Nie dodano żadnych serwerów",
"lang_dropdown": "Język",
"addServerModalLongTitle": "Dodaj nowy serwer",
"addServerModalSvName": "Nazwa serwera:",
"addServerModalSvIp": "IP Serwera:",
"addServerModalSvPort": "Port WebConsole:",
"addServerModalSvSsl": "SSL jest włączony na tym serwerze",
"addServerModalSslAdvice": "SSL jest wymagany do połączeń ze stronami HTTPS",
"addServerModalClose": "Zamknij",
"saveAndConnectServerButton": "Zapisz i połącz",
"passwordModalLongTitle": "Hasło jest wymagane",
"passwordModalLabel": "Hasło:",
"passwordModalRememberLabel": "Zapamiętaj hasło",
"passwordModalCloseButton": "Zamknij",
"passwordSendButton": "Zaloguj się",
"disconnectionModalLongTitle": "Rozłączono",
"disconnectionModalDescription": "Połączenie z serwerem zostało zerwane. Możliwe powody:",
"disconnectionModalsub1": "Serwer został wyłączony intencjonalnie.",
"disconnectionModalsub2": "Port nie jest otworzony przez host. W tym przypadku sprawdź, czy port jest otwarty używając port checkera i sprawdź twój firewall oraz router.",
"disconnectionModalCloseButton": "Zamknij",
"disconnectionModalWelcomeScreenButton": "Strona główna",
"settingsLink": "Ustawienia",
"settingsModalLongTitle": "Ustawienia WebConsole",
"showDateSettingsSwitchLabel": "Pokaż czas na każdej linijce w konsoli",
"readLogFileSwitchLabel": "Pokaż pełny log z serwera po zalogowaniu się",
"settingsModalCloseButton": "Ok",
"players_online": "Gracze Online",
"cpu_title": "Zużycie CPU",
"ram_title": "Zużycie RAM",
"user_title": "Zalogowano jako",
"deleteServerButton": "Usuń serwer",
"sendCommandButton": "Wyślij"
}
break;
default:
console.error("No language set");
}

View File

@ -60,14 +60,22 @@ class WebConsoleManager {
* Send password to server
*/
sendPassword(pwd){
this.activeConnection.sendToServer("LOGIN " + pwd);
this.activeConnection.sendToServer({
command: "LOGIN",
params: pwd
});
}
/**
* Send console command to server
*/
sendConsoleCmd(cmd){
this.activeConnection.sendToServer("EXEC " + cmd);
this.activeConnection.sendToServer({
command: "EXEC",
token: this.activeConnection.token,
params: cmd
});
this.activeConnection.commands.push(cmd);
}
@ -75,16 +83,35 @@ class WebConsoleManager {
* Asks server for CPU, RAM and players info
*/
askForInfo(){
this.activeConnection.sendToServer("PLAYERS");
this.activeConnection.sendToServer("CPUUSAGE");
this.activeConnection.sendToServer("RAMUSAGE");
this.activeConnection.sendToServer({
command: "PLAYERS",
token: this.activeConnection.token,
});
this.activeConnection.sendToServer({
command: "CPUUSAGE",
token: this.activeConnection.token,
});
this.activeConnection.sendToServer({
command: "RAMUSAGE",
token: this.activeConnection.token,
});
this.activeConnection.sendToServer({
command: "TPS",
token: this.activeConnection.token,
});
}
/**
* Asks server for full latest.log
*/
askForLogs(){
this.activeConnection.sendToServer("READLOGFILE");
this.activeConnection.sendToServer({
command: "READLOGFILE",
token: this.activeConnection.token,
});
}
}

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Attempted to send a message to a discon
cpu-usage-message = Usage is {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} tried to run {1} without permission.
no-send-permission-console = [WebConsole] {0} tried to run {1} without permission.
cmd-executed-console = [WebConsole] {0} executed "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Connected {0} players for a maximum of {1}
# RamUsageCommand.java
ram-usage-message = {0} free, {1} used, {2} maximum memory
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole version {0}.
webconsole-no-connections = There are no logged in WebConsole connections now.

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Pokus o odeslání zprávy odpojenému
cpu-usage-message = Využití je {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} se pokusil spustit {1} bez povolení.
no-send-permission-console = [WebConsole] {0} se pokusil spustit {1} bez povolení.
cmd-executed-console = [WebConsole] {0} spustil "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Je připojeno {0} hráčů z maxima {1}
# RamUsageCommand.java
ram-usage-message = {0} volné, {1} použité, {2} maximální paměti
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole verze {0}.
webconsole-no-connections = Nejsou žádné WebConsole připojení.

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Es wurde versucht, eine Nachricht an ei
cpu-usage-message = Die CPU Auslastung liegt bei {0}%.
# ExecCommand.java
viewer-error-console = [WebConsole] {0} hat versucht, {1} ohne Erlaubnis auszuführen.
no-send-permission-console = [WebConsole] {0} hat versucht, {1} ohne Erlaubnis auszuführen.
cmd-executed-console = [WebConsole] {0} hat "{1}" ausgeführt.
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = {0} von {1} Spieler sind verbunden.
# RamUsageCommand.java
ram-usage-message = {0} frei, {1} benutzt, {2} maximal
# TpsCommand.java
tps-message = {0} ticks von {1}
# WebConsoleCommand.java
webconsole-version = Die WebConsole Version ist {0}.
webconsole-no-connections = Aktuell ist niemand mit der WebConsole verbunden

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Attempted to send a message to a discon
cpu-usage-message = Usage is {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} tried to run {1} without permission.
no-send-permission-console = [WebConsole] {0} tried to run {1} without permission.
cmd-executed-console = [WebConsole] {0} executed "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Connected {0} players for a maximum of {1}
# RamUsageCommand.java
ram-usage-message = {0} free, {1} used, {2} maximum memory
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole version {0}.
webconsole-no-connections = There are no logged in WebConsole connections now.

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Se intentó enviar un mensaje a un clie
cpu-usage-message = En uso {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} intentó ejecutar {1} sin permiso.
no-send-permission-console = [WebConsole] {0} intentó ejecutar {1} sin permiso.
cmd-executed-console = [WebConsole] {0} ejecutó "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Actualmente conectados {0} jugadores de un máximo de {1}
# RamUsageCommand.java
ram-usage-message = Memoria: {0} libre, {1} usada, {2} maxima
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole version {0}.
webconsole-no-connections = No hay ninguna conexión activa a WebConsole en este momento.

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Vous avez tenté d'envoyer un message
cpu-usage-message = L'utilisation est {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} a tenté d'exécuter {1} sans autorisation.
no-send-permission-console = [WebConsole] {0} a tenté d'exécuter {1} sans autorisation.
cmd-executed-console = [WebConsole] {0} a exécuté "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Joueurs {0} connectés pour un maximum de {1}
# RamUsageCommand.java
ram-usage-message = {0} gratuit, {1} utilisé, {2} mémoire maximale
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = version WebConsole {0}.
webconsole-no-connections = Aucune connexion WebConsole n'est connectée maintenant.

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Tentativo di inviare un messaggio a un
cpu-usage-message = L''uso è {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} ha provato a eseguire {1} senza autorizzazione.
no-send-permission-console = [WebConsole] {0} ha provato a eseguire {1} senza autorizzazione.
cmd-executed-console = [WebConsole] {0} eseguito "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Connessi {0} players su un massimo di {1}
# RamUsageCommand.java
ram-usage-message = {0} Libera, {1} Usata, {2} Memoria massima
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = Versione WebConsole {0}.
webconsole-no-connections = Non è stata effettuata ancora nessuna connessione tramite WebConsole.

49
phrases_ja.properties Normal file
View File

@ -0,0 +1,49 @@
# WebConsole.java
boot-error = WebSocket Serverの起動時にエラーが発生しました。
# WSServer.java
connection-resumed-message = 接続されています。既にログイン、接続している方を切断してもう一度接続してみてください。
connection-resumed-console = [WebConsole] から接続し、セッションを再開しました。 {0}
connection-login-message = 接続開始、ログイン待ち...
connection-login-console = [WebConsole] 接続され、ログインを待っています... {0}
unknown-command-message = 不明、または存在しないコマンドです
unknown-command-console = [WebConsole] シグナル "{0}" は有効ではないので処理されませんでした。プラグインやウェブインターフェイスは最新のものを使用していますか?
forbidden-message = Forbidden
forbidden-console = [WebConsole] {0} は、ログインしていない状態で "{1}" を実行しようとしました!
closed-connection = [WebConsole] 接続を閉じて、からログアウトしました。 {0}
error-on-connection = [WebConsole] 接続時にエラーが発生しました。 {0}: {1}
started-websocket = [WebConsole] WebSocketサーバが正常に起動しました。
error-disconnected-client = [WebConsole] 切断された WebSocket クライアントにメッセージを送信しようとしました。
# CpuUsageCommand.java
cpu-usage-message = Usage is {0}%
# ExecCommand.java
no-send-permission-console = [WebConsole] {0} は勝手に {1} を実行しようとしましたが権限がないためはじかれました。
cmd-executed-console = [WebConsole] {0} 実行 "{1}".
# LogInCommand.java
login-sucessful-message = ログイン
login-sucessful-console = [WebConsole] {0} ログインに成功しました。
login-failed-message = パスワードが正しくありません、もう一度お試しください。
login-failed-console = [WebConsole] ログイン時にパスワードが正しくないです。 {0}
# PlayersCommand.java
players-message = 接続数 | {0} ,最大接続数 | {1}
# RamUsageCommand.java
ram-usage-message = {0} 空き, {1} 使用済み, {2} 最大メモリ
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsoleのバージョン {0}.
webconsole-no-connections = 現在、WebConsoleのログイン接続はありません。
webconsole-active-connections = WebConsoleに接続しました。:
# ReadLogFileCommand.java
log-read-error = latest.logファイルの読み込みエラーが発生しました
# User.java
user-tostring = User {0} from {1} as {2}

49
phrases_ko.properties Normal file
View File

@ -0,0 +1,49 @@
# WebConsole.java
boot-error = WebSocket 서버를 시작하는 도중 오류가 발생하였습니다.
# WSServer.java
connection-resumed-message = 연결되었습니다. 이미 로그인되어 있습니다. 안녕하세요!
connection-resumed-console = [WebConsole] 연결되었으며 {0}로부터 온 세션을 이어서 시작하였습니다.
connection-login-message = 연결이 시작되었고, 로그인을 기다리는 중입니다
connection-login-console = [WebConsole] 연결되었으며 {0}로부터 로그인을 기다리는 중입니다
unknown-command-message = 알 수 없는 명령어입니다
unknown-command-console = [WebConsole] "{0}" 신호는 알맞지 않기 때문에 처리되지 않았습니다. 플러그인 또는 웹 UI가 최신입니까?
forbidden-message = 제한되었습니다
forbidden-console = [WebConsole] {0}이(가) "{1}"를 로그인되지 않은 상태에서 실행하려고 했습니다!
closed-connection = [WebConsole] 연결을 끊었으며 {0}에서 로그아웃하였습니다
error-on-connection = [WebConsole] {0}에서 오류가 발생하였습니다: {1}
started-websocket = [WebConsole] WebSocket 서버가 성공적으로 시작하였습니다.
error-disconnected-client = [WebConsole] 연결이 끊긴 WebSocket 클라이언트에게 메시지 전송을 시도하였습니다.
# CpuUsageCommand.java
cpu-usage-message = 사용량은 {0}%입니다
# ExecCommand.java
no-send-permission-console = [WebConsole] {0}이(가) {1}을(를) 권한 없이 실행하려고 했습니다.
cmd-executed-console = [WebConsole] {0}이(가) "{1}"을(를) 실행하였습니다.
# LogInCommand.java
login-sucessful-message = 연결되었습니다
login-sucessful-console = [WebConsole] {0}이(가) 성공적으로 로그인하였습니다.
login-failed-message = 알맞지 않은 비밀번호입니다. 다시 시도하세요
login-failed-console = [WebConsole] {0}에서 로그인하는 중 비밀번호가 틀렸습니다
# PlayersCommand.java
players-message = {0}/{1}명의 플레이어를 연결하였습니다
# RamUsageCommand.java
ram-usage-message = {0} 여유, {1} 사용, {2} 최대
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole 버전 {0}.
webconsole-no-connections = 현재 로그인된 사람이 없습니다.
webconsole-active-connections = WebConsole에 연결하였습니다:
# ReadLogFileCommand.java
log-read-error = latest.log 파일을 불러오는 데 오류가 발생하였습니다
# User.java
user-tostring = 유저 {0}, {1}로부터, {2}로서

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Poging om een bericht te sturen naar ee
cpu-usage-message = Verbruik is {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} heeft geprobeerd {1} uit te voeren zonder toestemming.
no-send-permission-console = [WebConsole] {0} heeft geprobeerd {1} uit te voeren zonder toestemming.
cmd-executed-console = [WebConsole] {0} voerde "{1}" uit.
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = {0} spelers verbonden voor een maximum van {1}
# RamUsageCommand.java
ram-usage-message = {0} ongebruikt, {1} gebruikt, {2} maximaal geheugen
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole versie {0}.
webconsole-no-connections = Er zijn nu geen ingelogde Web Console-verbindingen.

46
phrases_pl.properties Normal file
View File

@ -0,0 +1,46 @@
# WebConsole.java
boot-error = Wystąpił błąd podczas włączanie serwera WebSocket.
# WSServer.java
connection-resumed-message = Połączono i zalogowano! Witaj z powrotem!
connection-resumed-console = [WebConsole] Połączono i wznowiono sesję z {0}
connection-login-message = Połączenie rozpoczęte, oczekiwanie na zalogowanie
connection-login-console = [WebConsole] Połączenie rozpoczęte, oczekiwanie na zalogowanie z {0}
unknown-command-message = Nieznana komenda
unknown-command-console = [WebConsole] Sygnał "{0}" nie został przetworzony, ponieważ jest nie poprawny. Czy twój plugin oraz klient są w najnowszej wersji?
forbidden-message = Brak dostępu
forbidden-console = [WebConsole] {0} spróbował uruchomić komendę "{1}" bez zalogowania się!
closed-connection = [WebConsole] Zamknięto połączenie i wylogowano z {0}
error-on-connection = [WebConsole] Wystąpił błąd na połączeniu {0}: {1}
started-websocket = [WebConsole] Serwer WebSocket został uruchomiony pomyślnie.
error-disconnected-client = [WebConsole] Podjęto próbę wysłania wiadomości do rozłączonego klienta WebSocket.
# CpuUsageCommand.java
cpu-usage-message = Zużycie: {0}%
# ExecCommand.java
no-send-permission-console = [WebConsole] {0} podjął próbę uruchominia komendy {1} bez poprawnych uprawnień.
cmd-executed-console = [WebConsole] {0} uruchomił komendę "{1}".
# LogInCommand.java
login-sucessful-message = Zalogowano
login-sucessful-console = [WebConsole] {0} pomyślnie się zalogował.
login-failed-message = Niepoprawne hasło, spróbuj ponownie.
login-failed-console = [WebConsole] Niepoprawne hasło podczas logowania z {0}
# PlayersCommand.java
players-message = Połączono {0}/{1} graczy
# RamUsageCommand.java
ram-usage-message = {0} wolne, {1} w użyciu. Maksymalne zużycie: {2}
# WebConsoleCommand.java
webconsole-version = Wersja WebConsole: {0}.
webconsole-no-connections = W tej chwili nikt nie jest połączony do WebConsole.
webconsole-active-connections = Połączono do WebConsole z:
# ReadLogFileCommand.java
log-read-error = Wystąpił błąd podczas próby przeczytania pliku latest.log
# User.java
user-tostring = Użytkownik {0} z {1} jako {2}

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Tentativa de enviar uma mensagem para u
cpu-usage-message = Consumindo {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} tentou executar o {1} sem permissão.
no-send-permission-console = [WebConsole] {0} tentou executar o {1} sem permissão.
cmd-executed-console = [WebConsole] {0} executou "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Atualmente tem {0} jogador(es) de um total de {1}
# RamUsageCommand.java
ram-usage-message = Disponível: {0}, Consumo de RAM: {1} / {2}
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole versão {0}.
webconsole-no-connections = Atualmente não tem nenhum usuário conectado.

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] Попытка отправить со
cpu-usage-message = Использование {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0} попытался запустить {1} без разрешения.
no-send-permission-console = [WebConsole] {0} попытался запустить {1} без разрешения.
cmd-executed-console = [WebConsole] {0} выполнил "{1}".
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = Подключено {0} игроков из максимум
# RamUsageCommand.java
ram-usage-message = {0} свободно, {1} используется, {2} макс. памяти
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = Версия WebConsole {0}.
webconsole-no-connections = В настоящее время нет подключений к WebConsole.

49
phrases_tr.properties Normal file
View File

@ -0,0 +1,49 @@
# WebConsole.java
boot-error = WebSocket sunucusunu başlatırken hata oluştu.
# WSServer.java
connection-resumed-message = Bağlandı. Zaten giriş yaptın, tekrar hoş geldin!
connection-resumed-console = [WebConsole] Bağlandı ve {0} konumundan gelen oturum devam ettirildi
connection-login-message = Bağlantı başladı, giriş bekleniyor
connection-login-console = [WebConsole] Bağlandı ve {0} konumundan giriş bekleniyor
unknown-command-message = Bilinmeyen komut
unknown-command-console = [WebConsole] "{0}" sinyali geçerli olmadığından işlenilemedi. Eklentin/web arayüzün güncellenmiş mi?
forbidden-message = Forbidden
forbidden-console = [WebConsole] {0}, "{1}" giriş yapmamış olmasına rağmen çalıştırmayı denedi!
closed-connection = [WebConsole] Bağlantı kapatıldı ve {0} konumundan çıkış yapıldı
error-on-connection = [WebConsole] Bağlantıda hata oluştu {0}: {1}
started-websocket = [WebConsole] WebSocket sunucusu başarıyla başlatıldı.
error-disconnected-client = [WebConsole] Bağlantısı kesilmiş bir WebSocket'a bir mesaj gönderilmeye çalışıldı.
# CpuUsageCommand.java
cpu-usage-message = Şuanki kullanım %{0}
# ExecCommand.java
no-send-permission-console = [WebConsole] {0}, {1}'ı yetkisiz olarak çalıştırmayı denedi.
cmd-executed-console = [WebConsole] {0}, "{1}" çalıştırdı.
# LogInCommand.java
login-sucessful-message = Giriş yapıldı
login-sucessful-console = [WebConsole] {0} başarıyla giriş yaptı.
login-failed-message = Yanlış şifre, tekrar deneyin
login-failed-console = [WebConsole] {0} konumundan giriş yapılırken şifre yanlış girildi.
# PlayersCommand.java
players-message = {0} oyuncu bağlandı, toplam {1} oyuncu bağlanabilir.
# RamUsageCommand.java
ram-usage-message = {0} boş, {1} kullanılıyor, {2} maksimum bellek
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = WebConsole sürümü {0}.
webconsole-no-connections = Şuanda oturum açılmış WebSocket bağlantısı yok.
webconsole-active-connections = WebConsole'a buradan bağlanıldı:
# ReadLogFileCommand.java
log-read-error = latest.log dosyasını okumayı denerken hata oluştu
# User.java
user-tostring = {0} isimli kullanıcı {1} konumundan, ayrıca bir {2}

View File

@ -19,7 +19,7 @@ error-disconnected-client = [WebConsole] 尝试向断开连接的WebSocket客户
cpu-usage-message = 已使用 {0}%
# ExecCommand.java
viewer-error-console = [WebConsole] {0}试图未经许可而运行{1}。
no-send-permission-console = [WebConsole] {0}试图未经许可而运行{1}。
cmd-executed-console = [網站控制台] {0} 執行 '{1}'.
# LogInCommand.java
@ -34,6 +34,9 @@ players-message = {0}玩家連接,最多{1}
# RamUsageCommand.java
ram-usage-message = 空閒{0} , 已使用{1} , 最大內存{2}
# TpsCommand.java
tps-message = {0} ticks from {1}
# WebConsoleCommand.java
webconsole-version = 網站控制台版本 {0}.
webconsole-no-connections = 現在沒有連接登錄網站控制台。

View File

@ -1,8 +1,8 @@
name: WebConsole
main: es.mesacarlos.webconsole.WebConsole
api-version: 1.13
version: 2.0
description: WebSockets-based web console
version: 2.4
description: WebSocket-based web console
author: Carlos Mesa
commands:
WebConsole:

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>WebConsole</groupId>
<artifactId>WebConsole</artifactId>
<version>2.0</version>
<version>2.4</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
@ -73,12 +73,12 @@
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
<version>2.17.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
@ -90,7 +90,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<version>2.8.9</version>
</dependency>
</dependencies>
</project>

View File

@ -3,7 +3,6 @@ package es.mesacarlos.webconsole;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
@ -13,29 +12,24 @@ import javax.net.ssl.TrustManagerFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Filter;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.java_websocket.server.DefaultSSLWebSocketServerFactory;
import es.mesacarlos.webconsole.config.ConfigManager;
import es.mesacarlos.webconsole.minecraft.WebConsoleCommand;
import es.mesacarlos.webconsole.util.Internationalization;
import es.mesacarlos.webconsole.util.LogFilter;
import es.mesacarlos.webconsole.websocket.WSServer;
public class WebConsole extends JavaPlugin {
FileConfiguration config = this.getConfig();
// Websocket server and thread
private WSServer server;
private Thread wsThread;
@Override
public void onEnable() {
createConfig();
//Change language to user-specified language.
Internationalization.setCurrentLocale(config.getString("language"));
Internationalization.setCurrentLocale(ConfigManager.getInstance().getLanguage());
//Start WebSocket Server
try {
@ -58,53 +52,24 @@ public class WebConsole extends JavaPlugin {
try {
server.stop();
wsThread = null;
} catch (IOException | InterruptedException e) {
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Creates configuration file
*/
private void createConfig() {
// SSL variables
config.addDefault("useSSL", false);
config.addDefault("StoreType", "JKS");
config.addDefault("KeyStore", "plugins/WebConsole/keystore.jks");
config.addDefault("StorePassword", "storepassword");
config.addDefault("KeyPassword", "keypassword");
// Connection config variables
config.addDefault("host", "0.0.0.0");
config.addDefault("port", 8080);
// Language config
config.addDefault("language", "en");
if(config.getConfigurationSection("passwords") == null) {
ConfigurationSection passwordsSection = config.createSection("passwords");
ConfigurationSection adminPasswordSection = passwordsSection.createSection("admin");
adminPasswordSection.addDefault("user1", "mySecurePassword");
passwordsSection.createSection("viewer");
}
config.options().copyDefaults(true);
saveConfig();
}
/**
* Start WebSocket server
*/
private void startWS() throws Exception {
// Create WebSocket server
server = new WSServer(this, new InetSocketAddress(config.getString("host"), config.getInt("port")));
server = new WSServer(ConfigManager.getInstance().getSocketAdress());
if(config.getBoolean("useSSL")) {
if(ConfigManager.getInstance().isSslEnabled()) {
// Configure SSL
String STORETYPE = config.getString("StoreType");
String KEYSTORE = config.getString("KeyStore");
String STOREPASSWORD = config.getString("StorePassword");
String KEYPASSWORD = config.getString("KeyPassword");
String STORETYPE = ConfigManager.getInstance().getStoreType();
String KEYSTORE = ConfigManager.getInstance().getKeyStore();
String STOREPASSWORD = ConfigManager.getInstance().getStorePassword();
String KEYPASSWORD = ConfigManager.getInstance().getKeyPassword();
KeyStore ks = KeyStore.getInstance(STORETYPE);
File kf = new File(KEYSTORE);
@ -133,6 +98,6 @@ public class WebConsole extends JavaPlugin {
}
public WSServer getWSServer() {
return (WSServer) server;
return server;
}
}

View File

@ -2,25 +2,32 @@ package es.mesacarlos.webconsole.auth;
import java.net.InetSocketAddress;
import es.mesacarlos.webconsole.config.UserType;
import es.mesacarlos.webconsole.util.Internationalization;
public class User {
public class ConnectedUser {
private String username;
private InetSocketAddress socketAddress;
private String token;
private UserType userType;
public User(InetSocketAddress socketAddress, String username, UserType userType) {
public ConnectedUser(InetSocketAddress socketAddress, String username, String token, UserType userType) {
this.socketAddress = socketAddress;
this.username = username;
this.token = token;
this.userType = userType;
}
public String getUsername() {
return username;
}
public InetSocketAddress getSocketAddress() {
return socketAddress;
}
public String getUsername() {
return username;
public String getToken() {
return token;
}
public UserType getUserType() {

View File

@ -4,7 +4,7 @@ import java.net.InetSocketAddress;
import java.util.ArrayList;
public class LoginManager {
private ArrayList<User> loggedInUsers = new ArrayList<User>();
private ArrayList<ConnectedUser> loggedInUsers = new ArrayList<ConnectedUser>();
private static LoginManager instance;
private LoginManager() {}
@ -19,7 +19,7 @@ public class LoginManager {
* Logs user in
* @param user User to login
*/
public void logIn(User user) {
public void logIn(ConnectedUser user) {
loggedInUsers.add(user);
}
@ -28,7 +28,7 @@ public class LoginManager {
* @param address User to logout
*/
public void logOut(InetSocketAddress address) {
for(User user : loggedInUsers)
for(ConnectedUser user : loggedInUsers.toArray(new ConnectedUser[loggedInUsers.size()]))
if(user.getSocketAddress().equals(address))
loggedInUsers.remove(user);
}
@ -38,20 +38,32 @@ public class LoginManager {
* @param address socket of the user
* @return User object, null if no user logged in from that address
*/
public User getUser(InetSocketAddress address) {
for(User user : loggedInUsers)
public ConnectedUser getUser(InetSocketAddress address) {
for(ConnectedUser user : loggedInUsers)
if(user.getSocketAddress().equals(address))
return user;
return null;
}
/**
* Check if user is logged in
* Check if user is logged in. It checks that both the socket adress and the user token corresponds to a logged in user.
* @param address User to check
* @return true if user is logged in, false otherwise
*/
public boolean isLoggedIn(InetSocketAddress address) {
for(User user : loggedInUsers)
public boolean isLoggedIn(InetSocketAddress address, String token) {
for(ConnectedUser user : loggedInUsers)
if(user.getSocketAddress().equals(address) && user.getToken().equals(token))
return true;
return false;
}
/**
* Check if an user is logged in from a given socket address
* @param address User to check
* @return true if user is logged in, false otherwise
*/
public boolean isSocketConnected(InetSocketAddress address) {
for(ConnectedUser user : loggedInUsers)
if(user.getSocketAddress().equals(address))
return true;
return false;
@ -61,7 +73,7 @@ public class LoginManager {
* Retrieve the full logged-in user list
* @return list of logged in users
*/
public ArrayList<User> getLoggedInUsers() {
public ArrayList<ConnectedUser> getLoggedInUsers() {
return loggedInUsers;
}

View File

@ -1,65 +0,0 @@
package es.mesacarlos.webconsole.auth;
import java.util.Map;
import org.bukkit.Bukkit;
import es.mesacarlos.webconsole.WebConsole;
public class PasswordManager {
/**
* Get the user type of a given password
* @param password Password to check
* @return ADMIN if password correspond to a admin user, VIEWER if viewer or UNKNOWN if invalid password
*/
public static UserType isValidUser(String password) {
//Check if is an admin
String username = isValidAdminPassword(password);
if(username != null)
return UserType.ADMIN;
//Check if is a viewer
username = isValidViewerPassword(password);
if(username != null)
return UserType.VIEWER;
//He is nothing
return UserType.UNKNOWN;
}
/**
* Check if the provided password corresponds to any admin
* @param password Provided password
* @return Name of the user if password corresponds to a valid admin, null if is a viewer or an invalid password
*/
public static String isValidAdminPassword(String password) {
WebConsole plugin = (WebConsole)Bukkit.getPluginManager().getPlugin("WebConsole");
Map<String, Object> passwords = plugin.getConfig().getConfigurationSection("passwords").getConfigurationSection("admin").getValues(false);
for(Map.Entry<String, Object> entry : passwords.entrySet()) {
String pwd = (String)entry.getValue();
if(pwd.equals(password))
return entry.getKey();
}
return null;
}
/**
* Check if the provided password corresponds to any viewer
* @param password Provided password
* @return Name of the user if password corresponds to a valid viewer, null if is a admin or invalid password
*/
public static String isValidViewerPassword(String password) {
WebConsole plugin = (WebConsole)Bukkit.getPluginManager().getPlugin("WebConsole");
Map<String, Object> passwords = plugin.getConfig().getConfigurationSection("passwords").getConfigurationSection("viewer").getValues(false);
for(Map.Entry<String, Object> entry : passwords.entrySet()) {
String pwd = (String)entry.getValue();
if(pwd.equals(password))
return entry.getKey();
}
return null;
}
}

View File

@ -1,7 +0,0 @@
package es.mesacarlos.webconsole.auth;
public enum UserType {
ADMIN,
VIEWER,
UNKNOWN
}

View File

@ -0,0 +1,171 @@
package es.mesacarlos.webconsole.config;
import java.net.InetSocketAddress;
import java.util.*;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import es.mesacarlos.webconsole.WebConsole;
public class ConfigManager {
private static ConfigManager instance;
private WebConsole plugin = (WebConsole) Bukkit.getPluginManager().getPlugin("WebConsole");
private FileConfiguration config = plugin.getConfig();
private ConfigManager() {
loadConfig();
}
public static ConfigManager getInstance() {
if(instance == null)
instance = new ConfigManager();
return instance;
}
/**
* Create configuration file or load it if already exist
*/
private void loadConfig() {
// SSL variables
config.addDefault("useSSL", false);
config.addDefault("StoreType", "JKS");
config.addDefault("KeyStore", "plugins/WebConsole/keystore.jks");
config.addDefault("StorePassword", "storepassword");
config.addDefault("KeyPassword", "keypassword");
// Connection config variables
config.addDefault("host", "0.0.0.0");
config.addDefault("port", 8080);
// Language config
config.addDefault("language", "en");
//Create passwords section if it does not exist
ConfigurationSection passwordsSection = config.getConfigurationSection("passwords");
if(passwordsSection == null) {
passwordsSection = config.createSection("passwords");
}
//Create passwords.admin section if it does not exist
ConfigurationSection adminPasswordSection = passwordsSection.getConfigurationSection("admin");
if(adminPasswordSection == null) {
adminPasswordSection = passwordsSection.createSection("admin");
adminPasswordSection.createSection("user1");
}
//For each admin user, create the password value and the commandWhitelist section if it does not exist
Set<String> adminUsersSections = adminPasswordSection.getKeys(false);
for (String adminUserSectionName : adminUsersSections) {
ConfigurationSection userSection = adminPasswordSection.getConfigurationSection(adminUserSectionName);
if(userSection == null) {
//If userSection is null, that means that the config file is prior to v2.2. We need to update the file to v2.2 by replacing the "user:password" value to a new section for each user.
String userPasswordFromOldConfig = adminPasswordSection.getString(adminUserSectionName);
userSection = adminPasswordSection.createSection(adminUserSectionName);
userSection.set("password", userPasswordFromOldConfig);
}
userSection.addDefault("password", "mySecurePassword");
ConfigurationSection commandWhitelist = userSection.getConfigurationSection("commandWhitelist");
if(commandWhitelist == null) {
commandWhitelist = userSection.createSection("commandWhitelist");
commandWhitelist.addDefault("enabled", false);
commandWhitelist.addDefault("commandWhitelistActsAsBlacklist", false);
commandWhitelist.addDefault("whitelist", Arrays.asList("whisper", "gamemode survival"));
}
}
//Create passwords.viewer section if it does not exist
ConfigurationSection viewerPasswordSection = passwordsSection.getConfigurationSection("viewer");
if(viewerPasswordSection == null) {
viewerPasswordSection = passwordsSection.createSection("viewer");
}
config.options().copyDefaults(true);
plugin.saveConfig();
}
public boolean isSslEnabled() {
return config.getBoolean("useSSL");
}
public String getStoreType() {
return config.getString("StoreType");
}
public String getKeyStore() {
return config.getString("KeyStore");
}
public String getStorePassword() {
return config.getString("StorePassword");
}
public String getKeyPassword() {
return config.getString("KeyPassword");
}
/**
* Get host and port fields already as InetSocketAddress
* @return InetSocketAddress created from the fields host and port of config.yml
*/
public InetSocketAddress getSocketAdress() {
return new InetSocketAddress(config.getString("host"), config.getInt("port"));
}
/**
* Language code from config.yml
* @return language code
*/
public String getLanguage() {
return config.getString("language");
}
/**
* Get all admins as a UserData list
* @return list of admin users
*/
private List<UserData> getAdmins() {
Set<String> adminConfig = plugin.getConfig().getConfigurationSection("passwords").getConfigurationSection("admin").getKeys(false);
List<UserData> adminUsers = new ArrayList<>();
for(String username : adminConfig) {
adminUsers.add(new UserData(
username,
plugin.getConfig().getString("passwords.admin." + username + ".password"),
UserType.ADMIN,
plugin.getConfig().getBoolean("passwords.admin." + username + ".commandWhitelist.enabled"),
plugin.getConfig().getBoolean("passwords.admin." + username + ".commandWhitelist.commandWhitelistActsAsBlacklist"),
plugin.getConfig().getStringList("passwords.admin." + username + ".commandWhitelist.whitelist")));
}
return adminUsers;
}
/**
* Get all viewers as a UserData list
* @return list of viewer users
*/
private List<UserData> getViewers() {
Map<String, Object> passwords = plugin.getConfig().getConfigurationSection("passwords").getConfigurationSection("viewer").getValues(false);
List<UserData> viewerUsers = new ArrayList<>();
for(Map.Entry<String, Object> entry : passwords.entrySet())
viewerUsers.add(new UserData(entry.getKey(), entry.getValue().toString(), UserType.VIEWER, false, false, new ArrayList<>()));
return viewerUsers;
}
/**
* Get all registered users
* @return All Admin and Viewer users inside config.yml
*/
public List<UserData> getAllUsers(){
List<UserData> users = getAdmins();
users.addAll(getViewers());
return users;
}
}

View File

@ -0,0 +1,46 @@
package es.mesacarlos.webconsole.config;
import java.util.List;
public class UserData {
private String username;
private String password;
private UserType userType;
private boolean isWhitelistEnabled;
private boolean isWhitelistActsAsBlacklist;
private List<String> whitelistedCommands;
public UserData(String username, String password, UserType userType,
boolean isWhitelistEnabled, boolean isWhitelistActsAsBlacklist, List<String> whitelistedCommands) {
this.username = username;
this.password = password;
this.userType = userType;
this.isWhitelistEnabled = isWhitelistEnabled;
this.isWhitelistActsAsBlacklist = isWhitelistActsAsBlacklist;
this.whitelistedCommands = whitelistedCommands;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public UserType getUserType() {
return userType;
}
public boolean isWhitelistEnabled() {
return isWhitelistEnabled;
}
public boolean isWhitelistActsAsBlacklist() {
return isWhitelistActsAsBlacklist;
}
public List<String> getWhitelistedCommands() {
return whitelistedCommands;
}
}

View File

@ -0,0 +1,6 @@
package es.mesacarlos.webconsole.config;
public enum UserType {
ADMIN,
VIEWER
}

View File

@ -7,7 +7,7 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import es.mesacarlos.webconsole.auth.LoginManager;
import es.mesacarlos.webconsole.auth.User;
import es.mesacarlos.webconsole.auth.ConnectedUser;
import es.mesacarlos.webconsole.util.Internationalization;
public class WebConsoleCommand implements CommandExecutor {
@ -22,14 +22,14 @@ public class WebConsoleCommand implements CommandExecutor {
StringBuilder msg = new StringBuilder();
msg.append(Internationalization.getPhrase("webconsole-version", version) + "\n");
ArrayList<User> users = LoginManager.getInstance().getLoggedInUsers();
ArrayList<ConnectedUser> users = LoginManager.getInstance().getLoggedInUsers();
if (users.isEmpty()) {
msg.append(Internationalization.getPhrase("webconsole-no-connections"));
} else {
msg.append(Internationalization.getPhrase("webconsole-active-connections") + "\n");
for (int i = 0; i < users.size(); i++) {
User user = users.get(i);
ConnectedUser user = users.get(i);
msg.append(user.toString());
if(i+1 < users.size())
msg.append("\n");

View File

@ -0,0 +1,93 @@
package es.mesacarlos.webconsole.util;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class JsonUtils {
/*{
"command": "LOGIN",
"token": "aosduhasiudgasuidgasdgaspid",
"params": ""
}*/
public final static String COMMAND_PROPERTY = "command";
public final static String TOKEN_PROPERTY = "token";
public final static String PARAMS_PROPERTY = "params";
/**
* Check that a given String is a valid JSON
* @param Json JSON to check
* @return true if it is a valid JSON, false otherwise
*/
public static boolean isValidJson(String Json) {
Gson gson = new Gson();
try {
gson.fromJson(Json, Object.class);
Object jsonObjType = gson.fromJson(Json, Object.class).getClass();
if(jsonObjType.equals(String.class)){
return false;
}
return true;
} catch (com.google.gson.JsonSyntaxException ex) {
return false;
}
}
/**
* Check that a given JSON contains some property
* @param JsonString JSON to check
* @param property property to check
* @return true if the JSON string contains that property, false otherwise
*/
public static boolean containsProperty(String JsonString, String property) {
if(!isValidJson(JsonString))
return false;
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(JsonString).getAsJsonObject();
JsonElement elem = obj.get(property);
if(elem == null)
return false;
return true;
}
/**
* Check that a given JSON contains some property, and its type is a String
* @param JsonString JSON to check
* @param property property to check
* @returntrue if the JSON string contains that property and it is a String, false otherwise
*/
public static boolean containsStringProperty(String JsonString, String property) {
if(!isValidJson(JsonString))
return false;
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(JsonString).getAsJsonObject();
JsonElement elem = obj.get(property);
if(elem == null)
return false;
try {
elem.getAsString();
return true;
}catch(Exception e) {
return false;
}
}
/**
* Get a String property from a JSON
* @param JsonString JSON to check
* @param property property to extract from JSON string
* @return the value for that property. If the property is not set, an empty string will be returned
*/
public static String getStringProperty(String JsonString, String property) {
JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(JsonString).getAsJsonObject();
JsonElement result = obj.get(property);
if(result != null)
return result.getAsString();
return "";
}
}

View File

@ -10,10 +10,10 @@ import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import es.mesacarlos.webconsole.WebConsole;
import es.mesacarlos.webconsole.auth.LoginManager;
import es.mesacarlos.webconsole.util.DateTimeUtils;
import es.mesacarlos.webconsole.util.Internationalization;
import es.mesacarlos.webconsole.util.JsonUtils;
import es.mesacarlos.webconsole.websocket.command.WSCommandFactory;
import es.mesacarlos.webconsole.websocket.command.WSCommand;
import es.mesacarlos.webconsole.websocket.response.ConsoleOutput;
@ -23,17 +23,17 @@ import es.mesacarlos.webconsole.websocket.response.LoggedIn;
import es.mesacarlos.webconsole.websocket.response.UnknownCommand;
public class WSServer extends WebSocketServer {
private HashMap<String, WSCommand> commands = WSCommandFactory.getCommandsHashMap();
private WebConsole plugin;
public WSServer(WebConsole plugin, InetSocketAddress address) {
private final HashMap<String, WSCommand> commands = WSCommandFactory.getCommandsHashMap();
public WSServer(InetSocketAddress address) {
super(address);
this.plugin = plugin;
setReuseAddr(true);
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
if (LoginManager.getInstance().isLoggedIn(conn.getRemoteSocketAddress())) {
if (LoginManager.getInstance().isSocketConnected(conn.getRemoteSocketAddress())) {
sendToClient(conn, new LoggedIn(Internationalization.getPhrase("connection-resumed-message")));
Bukkit.getLogger().info(Internationalization.getPhrase("connection-resumed-console", conn.getRemoteSocketAddress()));
} else {
@ -44,11 +44,15 @@ public class WSServer extends WebSocketServer {
@Override
public void onMessage(WebSocket conn, String message) {
if(!JsonUtils.containsStringProperty(message, "command") //Contains a command
|| ( !JsonUtils.containsStringProperty(message, "token") && !JsonUtils.getStringProperty(message, JsonUtils.COMMAND_PROPERTY).equals("LOGIN")) //Contains a token or it is a login command
)
return;
// Get command and params
String wsCommand = message.split(" ")[0];
String wsCommandParams = "";
if (message.contains(" "))
wsCommandParams = message.split(" ", 2)[1];
String wsCommand = JsonUtils.getStringProperty(message, JsonUtils.COMMAND_PROPERTY);
String wsToken = JsonUtils.getStringProperty(message, JsonUtils.TOKEN_PROPERTY);
String wsCommandParams = JsonUtils.getStringProperty(message, JsonUtils.PARAMS_PROPERTY);
// Run command
WSCommand cmd = commands.get(wsCommand);
@ -57,8 +61,8 @@ public class WSServer extends WebSocketServer {
// Command does not exist
sendToClient(conn, new UnknownCommand(Internationalization.getPhrase("unknown-command-message"), message));
Bukkit.getLogger().info(Internationalization.getPhrase("unknown-command-console", message));
} else if (!LoginManager.getInstance().isLoggedIn(conn.getRemoteSocketAddress())
&& !wsCommand.equals("LOGIN")) {
} else if (!wsCommand.equals("LOGIN")
&& !LoginManager.getInstance().isLoggedIn(conn.getRemoteSocketAddress(), wsToken)) {
// User is not authorised. DO NOTHING, IMPORTANT!
sendToClient(conn, new LoginRequired(Internationalization.getPhrase("forbidden-message")));
Bukkit.getLogger().warning(Internationalization.getPhrase("forbidden-console", conn.getRemoteSocketAddress(), message));
@ -83,21 +87,13 @@ public class WSServer extends WebSocketServer {
Bukkit.getLogger().info(Internationalization.getPhrase("started-websocket"));
}
/**
* 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()))
if (LoginManager.getInstance().isSocketConnected(connection.getRemoteSocketAddress()))
sendToClient(connection, new ConsoleOutput(line, DateTimeUtils.getTimeAsString()));
}
}
@ -111,6 +107,7 @@ public class WSServer extends WebSocketServer {
try {
conn.send(content.toJSON());
}catch(WebsocketNotConnectedException e) {
LoginManager.getInstance().logOut(conn.getRemoteSocketAddress());
Bukkit.getLogger().warning(Internationalization.getPhrase("error-disconnected-client"));
}

View File

@ -2,38 +2,94 @@ package es.mesacarlos.webconsole.websocket.command;
import java.util.concurrent.ExecutionException;
import es.mesacarlos.webconsole.config.ConfigManager;
import es.mesacarlos.webconsole.config.UserData;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
import org.java_websocket.WebSocket;
import es.mesacarlos.webconsole.WebConsole;
import es.mesacarlos.webconsole.auth.LoginManager;
import es.mesacarlos.webconsole.auth.User;
import es.mesacarlos.webconsole.auth.UserType;
import es.mesacarlos.webconsole.auth.ConnectedUser;
import es.mesacarlos.webconsole.config.UserType;
import es.mesacarlos.webconsole.util.Internationalization;
import es.mesacarlos.webconsole.websocket.WSServer;
public class ExecCommand implements WSCommand {
LoginManager loginManager = LoginManager.getInstance();
@Override
public void execute(WSServer wsServer, WebSocket conn, String command) {
User u = LoginManager.getInstance().getUser(conn.getRemoteSocketAddress());
ConnectedUser u = LoginManager.getInstance().getUser(conn.getRemoteSocketAddress());
if(u == null || u.getUserType() != UserType.ADMIN) {
if(u != null)
Bukkit.getLogger().warning(Internationalization.getPhrase("viewer-error-console", u, command));
Bukkit.getLogger().warning(Internationalization.getPhrase("no-send-permission-console", u, command));
return;
}
boolean allowCommand = checkWhitelist(conn, command);
if (!allowCommand) {
Bukkit.getLogger().warning(Internationalization.getPhrase("no-send-permission-console", u, command));
return;
}
Bukkit.getLogger().info(Internationalization.getPhrase("cmd-executed-console", conn.getRemoteSocketAddress(), Internationalization.utf8ToIso(command)));
ConsoleCommandSender sender = Bukkit.getServer().getConsoleSender();
WebConsole plugin = (WebConsole) Bukkit.getPluginManager().getPlugin("WebConsole");
try {
@SuppressWarnings("unused")
boolean success = Bukkit.getScheduler()
.callSyncMethod(wsServer.getMainClass(), () -> Bukkit.dispatchCommand(sender, command)).get();
.callSyncMethod(plugin, () -> Bukkit.dispatchCommand(sender, command)).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
private boolean checkWhitelist(WebSocket conn, String command) {
for(UserData ud : ConfigManager.getInstance().getAllUsers()) {
if (ud.getUsername().equals(loginManager.getUser(conn.getRemoteSocketAddress()).getUsername())) {
if (!ud.isWhitelistEnabled()) { //Skip whitelist check.
return true;
}
String[] splitCommand = command.split(" ");
for (String whitelistedCommand : ud.getWhitelistedCommands()) {
String[] splitWhitelistedCommand = whitelistedCommand.split(" ");
if(equalsArray(splitCommand, splitWhitelistedCommand)) {
//Command matches the whitelist
if(ud.isWhitelistActsAsBlacklist())
return false; //If acts as blacklist, do not allow command
else
return true; //If acts as Whitelist, allow command
}
}
//If execution reached this point, then the command is not in the blacklist.
if(ud.isWhitelistActsAsBlacklist())
return true; //If acts as blacklist, allow command
else
return false; //If acts as Whitelist, do not allow command
}
}
throw new RuntimeException("No user matched the whitelist check.");
}
/**
* Check if the user command matches the whitelisted command
*
* @param splitCommand Command sent by user
* @param splitWhitelistedCommand Command in the whitelist
* @return true if the user command matches the whitelist command
*/
private boolean equalsArray(String[] splitCommand, String[] splitWhitelistedCommand) {
for (int i = 0; i < splitWhitelistedCommand.length; i++)
if (!splitCommand[i].equalsIgnoreCase(splitWhitelistedCommand[i]))
return false; //Does not match so far
return true; //Matches the command
}
}

View File

@ -1,12 +1,14 @@
package es.mesacarlos.webconsole.websocket.command;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.java_websocket.WebSocket;
import es.mesacarlos.webconsole.auth.LoginManager;
import es.mesacarlos.webconsole.auth.PasswordManager;
import es.mesacarlos.webconsole.auth.User;
import es.mesacarlos.webconsole.auth.UserType;
import es.mesacarlos.webconsole.auth.ConnectedUser;
import es.mesacarlos.webconsole.config.ConfigManager;
import es.mesacarlos.webconsole.config.UserData;
import es.mesacarlos.webconsole.util.Internationalization;
import es.mesacarlos.webconsole.websocket.WSServer;
import es.mesacarlos.webconsole.websocket.response.LoginRequired;
@ -17,35 +19,22 @@ 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()))
if (LoginManager.getInstance().isSocketConnected(conn.getRemoteSocketAddress()))
return;
//Check user type and login is password is valid
switch(PasswordManager.isValidUser(password)) {
case ADMIN:
login(wsServer, conn, PasswordManager.isValidAdminPassword(password), UserType.ADMIN);
break;
case VIEWER:
login(wsServer, conn, PasswordManager.isValidViewerPassword(password), UserType.VIEWER);
break;
case UNKNOWN:
wsServer.sendToClient(conn, new LoginRequired(Internationalization.getPhrase("login-failed-message")));
Bukkit.getLogger().info(Internationalization.getPhrase("login-failed-console", conn.getRemoteSocketAddress()));
break;
default:
wsServer.sendToClient(conn, new LoginRequired(Internationalization.getPhrase("login-failed-message")));
Bukkit.getLogger().info(Internationalization.getPhrase("login-failed-console", conn.getRemoteSocketAddress()));
break;
//Check if user exists
for(UserData ud : ConfigManager.getInstance().getAllUsers()) {
if(ud.getPassword().equals(password)) {
ConnectedUser user = new ConnectedUser(conn.getRemoteSocketAddress(), ud.getUsername(), UUID.randomUUID().toString(), ud.getUserType());
LoginManager.getInstance().logIn(user);
wsServer.sendToClient(conn, new LoggedIn(Internationalization.getPhrase("login-sucessful-message"), "LOGIN ********", user.getUsername(), user.getUserType(), user.getToken()));
Bukkit.getLogger().info(Internationalization.getPhrase("login-sucessful-console", user.toString()));
return;
}
}
}
private void login(WSServer wsServer, WebSocket conn, String username, UserType as) {
User user = new User(conn.getRemoteSocketAddress(), username, as);
LoginManager.getInstance().logIn(user);
wsServer.sendToClient(conn, new LoggedIn(Internationalization.getPhrase("login-sucessful-message"), "LOGIN ********", user.getUsername(), user.getUserType()));
Bukkit.getLogger().info(Internationalization.getPhrase("login-sucessful-console", user.toString()));
wsServer.sendToClient(conn, new LoginRequired(Internationalization.getPhrase("login-failed-message")));
Bukkit.getLogger().info(Internationalization.getPhrase("login-failed-console", conn.getRemoteSocketAddress()));
}
}

View File

@ -14,7 +14,7 @@ public class RamUsageCommand implements WSCommand {
long free = r.freeMemory() / 1024 / 1024;
long max = r.maxMemory() / 1024 / 1024;
long used = max - free;
long used = r.totalMemory() / 1024 / 1024 - free;
wsServer.sendToClient(conn,
new RamUsage(

View File

@ -0,0 +1,54 @@
package es.mesacarlos.webconsole.websocket.command;
//------------------------------
//
// This class was developed by Rafael K.
// On 1/8/2022 at 10:22 PM
// In the project WebConsole
//
//------------------------------
import es.mesacarlos.webconsole.util.Internationalization;
import es.mesacarlos.webconsole.websocket.WSServer;
import es.mesacarlos.webconsole.websocket.response.Tps;
import org.java_websocket.WebSocket;
import org.bukkit.Bukkit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TpsCommand implements WSCommand {
private static final String mcVer = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
@Override
public void execute(WSServer wsServer, WebSocket conn, String params) {
try {
double tps = getTps()[0];
wsServer.sendToClient(conn, new Tps(Internationalization.getPhrase("tps-message", tps), tps));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @return Current server Tps
*/
public double[] getTps() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
try {
Class<?> minecraftServerClass = Class.forName("net.minecraft.server." + mcVer + ".MinecraftServer");
Method getServerMethod = minecraftServerClass.getDeclaredMethod("getServer");
Object serverInstance = getServerMethod.invoke(null);
Field recentTpsField = serverInstance.getClass().getField("recentTps");
double[] recentTps = (double[]) recentTpsField.get(serverInstance);
for (int i = 0; i < recentTps.length; i++) {
recentTps[i] = Math.round(recentTps[i]);
}
return recentTps;
} catch (Exception e) {
//If an uncaught exception is thrown, maybe it is because this method of getting TPS does not work in the MV version currently running..
return new double[] { 0 };
}
}
}

View File

@ -11,6 +11,7 @@ public class WSCommandFactory {
commands.put("PLAYERS", new PlayersCommand());
commands.put("CPUUSAGE", new CpuUsageCommand());
commands.put("RAMUSAGE", new RamUsageCommand());
commands.put("TPS", new TpsCommand());
commands.put("READLOGFILE", new ReadLogFileCommand());
return commands;
}

View File

@ -2,9 +2,10 @@ package es.mesacarlos.webconsole.websocket.response;
import com.google.gson.JsonObject;
public class ConsoleOutput implements JSONOutput{
private String message;
private String time;
public class ConsoleOutput implements JSONOutput {
private final String message;
private final String time;
public ConsoleOutput(String message, String time) {
this.message = message;

View File

@ -2,9 +2,10 @@ package es.mesacarlos.webconsole.websocket.response;
import com.google.gson.JsonObject;
public class CpuUsage implements JSONOutput{
private String message;
private double usage;
public class CpuUsage implements JSONOutput {
private final String message;
private final double usage;
public CpuUsage(String message, double usage) {
this.message = message;

View File

@ -2,23 +2,26 @@ package es.mesacarlos.webconsole.websocket.response;
import com.google.gson.JsonObject;
import es.mesacarlos.webconsole.auth.UserType;
import es.mesacarlos.webconsole.config.UserType;
public class LoggedIn implements JSONOutput{
private String message;
public class LoggedIn implements JSONOutput {
private final String message;
private String respondsTo;
private String username;
private UserType as;
private String token;
public LoggedIn(String message) {
this.message = message;
}
public LoggedIn(String message, String respondsTo, String username, UserType as) {
public LoggedIn(String message, String respondsTo, String username, UserType as, String token) {
this.message = message;
this.respondsTo = respondsTo;
this.username = username;
this.as = as;
this.token = token;
}
@Override
@ -53,6 +56,10 @@ public class LoggedIn implements JSONOutput{
}
}
private String getToken() {
return token;
}
@Override
public String toJSON() {
JsonObject object = new JsonObject();
@ -61,6 +68,7 @@ public class LoggedIn implements JSONOutput{
object.addProperty("respondsTo", getRespondsTo());
object.addProperty("username", getUsername());
object.addProperty("as", getAs());
object.addProperty("token", getToken());
object.addProperty("message", getMessage());
return object.toString();
}

View File

@ -2,8 +2,9 @@ package es.mesacarlos.webconsole.websocket.response;
import com.google.gson.JsonObject;
public class LoginRequired implements JSONOutput{
private String message;
public class LoginRequired implements JSONOutput {
private final String message;
public LoginRequired(String message) {
this.message = message;

View File

@ -5,11 +5,12 @@ 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 class Players implements JSONOutput {
private final String message;
private final int connectedPlayers;
private final int maxPlayers;
private final List<String> connectedPlayersList;
public Players(String message, int connectedPlayers, int maxPlayers, List<String> connectedPlayersList) {
this.message = message;

View File

@ -3,10 +3,11 @@ package es.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;
private final String message;
private final long free;
private final long used;
private final long max;
public RamUsage(String message, long free, long used, long max) {
this.message = message;

View File

@ -0,0 +1,51 @@
package es.mesacarlos.webconsole.websocket.response;
//------------------------------
//
// This class was developed by Rafael K.
// On 1/8/2022 at 10:23 PM
// In the project WebConsole
//
//------------------------------
import com.google.gson.JsonObject;
public class Tps implements JSONOutput {
private final String message;
private final double tps;
public Tps(String message, double tps) {
this.message = message;
this.tps = tps;
}
@Override
public int getStatusCode() {
return 1003;
}
@Override
public String getMessage() {
return message;
}
/**
* Gets current server TPS
* @return Global Server TPS
*/
public double getTps() {
return tps;
}
@Override
public String toJSON() {
JsonObject object = new JsonObject();
object.addProperty("status", getStatusCode());
object.addProperty("statusDescription", "TPS Usage");
object.addProperty("tps", getTps());
object.addProperty("message", getMessage());
return object.toString();
}
}

View File

@ -2,9 +2,10 @@ package es.mesacarlos.webconsole.websocket.response;
import com.google.gson.JsonObject;
public class UnknownCommand implements JSONOutput{
private String message;
private String respondsTo;
public class UnknownCommand implements JSONOutput {
private final String message;
private final String respondsTo;
public UnknownCommand(String message, String respondsTo) {
this.message = message;