Compare commits
No commits in common. "master" and "2.13.2b" have entirely different histories.
|
@ -0,0 +1,63 @@
|
|||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
|
@ -11,7 +11,7 @@ Paste in the version information from the SubServers app in question here. To ge
|
|||
Here you can write about what happened that shouldn't have. If you have any errors in your console related to what happened, you should also paste those here.
|
||||
|
||||
### How It Happened
|
||||
Tell us step-by-step how to recreate the problem. This step is vital for us to determine whether the problem happens to everyone else too.
|
||||
Tell us step-by-step how to recreate the problem. This step is vital for us to determine whether or not the problem happens to everyone else too.
|
||||
|
||||
### Additional Information
|
||||
Here you can provide any extra details you may think useful for solving the problem.
|
||||
|
|
|
@ -1,17 +1,48 @@
|
|||
# Hide System and IDE Generated Files
|
||||
/out/
|
||||
.idea/
|
||||
# SubServers 2 Ignored Files
|
||||
|
||||
*.iml
|
||||
.DS_STORE
|
||||
|
||||
# Hide Unfinished Projects
|
||||
/SubServers.Test/
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.userprefs
|
||||
|
||||
# Hide Compiled Artifacts
|
||||
/Artifacts/*
|
||||
/BungeeCord/
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
|
||||
# Hide Unfinished Project Files
|
||||
/SubServers.Client/Windows/
|
||||
/Artifacts/SubServers.Web.jar
|
||||
/SubServers.Velocity/
|
||||
/SubServers.Web/
|
||||
|
||||
# Hide Others
|
||||
/Artifacts/-Maven/
|
||||
/Artifacts/-History/
|
||||
/Artifacts/-Icon/
|
||||
/Artifacts/*.jar
|
||||
/Javadoc/
|
||||
|
||||
# Show Interpreted Artifacts
|
||||
!/Artifacts/Download/
|
||||
!/Artifacts/SubServers.Patcher.sh
|
||||
/SubServers.Test/
|
||||
/build.ant
|
||||
/build.log
|
||||
.DS_STORE
|
||||
|
|
|
@ -321,14 +321,14 @@
|
|||
switch (a.attr("href").toLowerCase()) {
|
||||
case "%adfly_app_download%":
|
||||
if (hash.hasOwnProperty("build")) {
|
||||
a.attr("href", "https://adf.ly/18562515/https://dev.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
||||
a.attr("href", "https://adf.ly/18562515/https://src.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
||||
} else {
|
||||
a.attr("href", "https://adf.ly/18562515/https://raw.githubusercontent.com/ME1312/SubServers-2/" + hash.commit.toLowerCase() + "/Artifacts/" + hash.app);
|
||||
}
|
||||
break;
|
||||
case "%app_download%":
|
||||
if (hash.hasOwnProperty("build")) {
|
||||
a.attr("href", "https://dev.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
||||
a.attr("href", "https://src.me1312.net/maven/net/ME1312/SubServers/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "/" + hash.build + "/" + hash.app.replace(/^(.+?)\.([^.]*)$/, '$1') + "-" + hash.build + ".jar");
|
||||
} else {
|
||||
a.attr("href", "https://raw.githubusercontent.com/ME1312/SubServers-2/" + hash.commit.toLowerCase() + "/Artifacts/" + hash.app);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ if [ $__RETURN -eq 0 ]
|
|||
rm -Rf LICENSE
|
||||
fi
|
||||
if [ -f "META-INF/MANIFEST.MF" ]; then
|
||||
cat META-INF/MANIFEST.MF | sed 's/\r$//' | sed ':a;N;$!ba;s/\n //g' | sed -e "/^\s*$/d" -e "/^Main-Class:.*$/d" -e "/^Implementation-Title:.*$/d" -e "/^Specification-Title:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" > ../MANIFEST.MF
|
||||
cat META-INF/MANIFEST.MF | sed -e "/^\s*$/d" -e "/^Main-Class:.*$/d" -e "/^Implementation-Title:.*$/d" -e "/^Specification-Title:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" > ../MANIFEST.MF
|
||||
else
|
||||
printf "Manifest-Version: 1.0\n" > ../MANIFEST.MF
|
||||
fi
|
||||
|
@ -67,8 +67,8 @@ if [ $__RETURN -eq 0 ]
|
|||
then
|
||||
echo ">> Writing Changes..."
|
||||
if [ -f "META-INF/MANIFEST.MF" ]
|
||||
then # (Read File) (Convert to LF) (Rejoin Split Lines) (Omit Empty, Duplicate, and Unnecessary Properties)
|
||||
cat META-INF/MANIFEST.MF | sed 's/\r$//' | sed ':a;N;$!ba;s/\n //g' | sed -e "/^\s*$/d" -e "/^Manifest-Version:.*$/d" -e "/^Class-Path:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" >> ../MANIFEST.MF
|
||||
then
|
||||
cat META-INF/MANIFEST.MF | sed -e "/^\s*$/d" -e "/^Manifest-Version:.*$/d" -e "/^Class-Path:.*$/d" -e "/^Build-Jdk:.*$/d" -e "/^Created-By:.*$/d" -e "/^Built-By:.*$/d" >> ../MANIFEST.MF
|
||||
else
|
||||
if [ ! -d "META-INF" ]; then
|
||||
mkdir META-INF
|
||||
|
@ -79,13 +79,13 @@ if [ $__RETURN -eq 0 ]
|
|||
fi
|
||||
yes | cp -rf . ../Patched.jar
|
||||
cd ../
|
||||
printf "Built-By: SubServers.Patcher\n" >> MANIFEST.MF
|
||||
printf "Built-By: SubServers.Bungee.Patcher\n" >> MANIFEST.MF
|
||||
cp -f MANIFEST.MF Patched.jar/META-INF
|
||||
if [ -f "Patched.jar/bungee.yml" ]; then
|
||||
rm -Rf Patched.jar/bungee.yml
|
||||
fi
|
||||
if [ ! -f "MODIFICATIONS" ]; then
|
||||
printf "# SubServers.Patcher generated difference list (may be empty if git is not installed)\n#\n" > MODIFICATIONS
|
||||
printf "# SubServers.Bungee.Patcher generated difference list (may be empty if git is not installed)\n#\n" > MODIFICATIONS
|
||||
fi
|
||||
printf "@ `date`\n> git --no-pager diff --no-index --name-status SubServers.Patcher/Original.jar SubServers.Patcher/Patched.jar\n" >> MODIFICATIONS
|
||||
git --no-pager diff --no-index --name-status Original.jar Patched.jar | sed -e "s/\tOriginal.jar\//\t\//" -e "s/\tPatched.jar\//\t\//" >> MODIFICATIONS
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -186,7 +186,7 @@
|
|||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (C) 2015-2023 ME1312
|
||||
Copyright (C) 2015-2019 ME1312
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
23
README.md
23
README.md
|
@ -1,6 +1,6 @@
|
|||
# ![https://s3.postimg.cc/dikyxlz5v/Sub_Banner.png](https://s3.postimg.cc/dikyxlz5v/Sub_Banner.png)
|
||||
[![Build Status](https://dev.me1312.net/jenkins/job/SubServers%20Platform/badge/icon)](https://dev.me1312.net/jenkins/job/SubServers%20Platform/)
|
||||
[![Release Verison](https://img.shields.io/github/release/ME1312/SubServers-2/all.svg)](https://github.com/ME1312/SubServers-2/releases) [![Snapshot Verison](https://img.shields.io/badge/dynamic/xml.svg?label=snapshot&url=https%3A%2F%2Fdev.me1312.net%2Fmaven%2Fnet%2FME1312%2FSubServers%2FSubServers.Bungee%2Fmaven-metadata.xml&query=%2F%2Fversioning%2Frelease&colorB=blue)](https://dev.me1312.net/jenkins/job/SubServers%20Platform/) [![Discord](https://img.shields.io/discord/526520424880930867.svg)](https://discord.gg/zWupnVn)<br><br>
|
||||
[![Build Status](https://src.me1312.net/jenkins/job/SubServers%20Platform/badge/icon)](https://src.me1312.net/jenkins/job/SubServers%20Platform/)
|
||||
[![Release Verison](https://img.shields.io/github/release/ME1312/SubServers-2/all.svg)](https://github.com/ME1312/SubServers-2/releases) [![Snapshot Verison](https://img.shields.io/badge/dynamic/xml.svg?label=snapshot&url=https%3A%2F%2Fsrc.me1312.net%2Fmaven%2Fnet%2FME1312%2FSubServers%2FSubServers.Bungee%2Fmaven-metadata.xml&query=%2F%2Fversioning%2Frelease&colorB=blue)](https://src.me1312.net/jenkins/job/SubServers%20Platform/)<br><br>
|
||||
SubServers 2 is a rewrite of SubServers, the Server Management Platform.<br>
|
||||
> [https://www.spigotmc.org/resources/subservers-bungee.11264/](https://www.spigotmc.org/resources/subservers-bungee.11264/)<br>
|
||||
> [https://www.spigotmc.org/resources/subservers-host.38833/](https://www.spigotmc.org/resources/subservers-host.38833/)<br>
|
||||
|
@ -12,26 +12,21 @@ SubServers 2 is a rewrite of SubServers, the Server Management Platform.<br>
|
|||
These are some quick links for common resources of SubServers 2.
|
||||
|
||||
### How to Install
|
||||
> [https://github.com/ME1312/SubServers-2/wiki/Install](https://github.com/ME1312/SubServers-2/wiki/Installation)
|
||||
> [https://github.com/ME1312/SubServers-2/wiki/Install](https://github.com/ME1312/SubServers-2/wiki/Install)
|
||||
|
||||
### Snapshot Downloads
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform](https://dev.me1312.net/jenkins/job/SubServers%20Platform)
|
||||
> [https://src.me1312.net/jenkins/job/SubServers Platform](https://src.me1312.net/jenkins/job/SubServers%20Platform)
|
||||
|
||||
### Javadocs for Developers
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee.Common](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee.Common)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Host](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Host)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync.Velocity](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync.Velocity)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Bukkit](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Bukkit)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Common](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Common)<br>
|
||||
> [https://dev.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Sponge](https://dev.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Sponge)
|
||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Bungee/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Bungee/)<br>
|
||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Host/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Host/)<br>
|
||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Sync/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Sync/)<br>
|
||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Bukkit/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Bukkit/)<br>
|
||||
> [https://src.me1312.net/jenkins/job/SubServers Platform/javadoc/SubServers.Client.Sponge/](https://src.me1312.net/jenkins/job/SubServers%20Platform/javadoc/SubServers.Client.Sponge/)
|
||||
|
||||
### Stats for nerds
|
||||
> [https://bstats.org/plugin/bungeecord/SubServers_Bungee](https://bstats.org/plugin/bungeecord/SubServers%202)<br>
|
||||
> [https://bstats.org/plugin/other/SubServers_Host](https://bstats.org/plugin/other/SubServers%20Host)<br>
|
||||
> [https://bstats.org/plugin/bungeecord/SubServers_Sync](https://bstats.org/plugin/bungeecord/SubServers%20Sync)<br>
|
||||
> [https://bstats.org/plugin/velocity/SubServers_Sync](https://bstats.org/plugin/velocity/SubServers%20Sync)<br>
|
||||
> [https://bstats.org/plugin/bungeecord/SubServers_Console](https://bstats.org/plugin/bungeecord/SubServers%20Console)<br>
|
||||
> [https://bstats.org/plugin/bukkit/SubServers_Client](https://bstats.org/plugin/bukkit/SubServers%20Client)<br>
|
||||
> [https://bstats.org/plugin/sponge/SubServers_Client](https://bstats.org/plugin/sponge/SubServers%20Client)
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.ME1312.SubServers</groupId>
|
||||
<artifactId>SubServers.Bungee.Common</artifactId>
|
||||
<version>-PLACEHOLDER</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>md_5-repo</id>
|
||||
<url>http://repo.md-5.net/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>me1312-repo</id>
|
||||
<url>https://dev.me1312.net/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.md_5</groupId>
|
||||
<artifactId>bungeecord-internal</artifactId>
|
||||
<version>1.15-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ME1312.Galaxi</groupId>
|
||||
<artifactId>GalaxiBase</artifactId>
|
||||
<version>23w51a</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<directory>../../out/compile/target/SubServers.Bungee.Common</directory>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src</directory>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<mkdir dir="${project.build.directory}" />
|
||||
<copy file="${basedir}/../../LICENSE" todir="${project.build.directory}/classes" />
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<finalName>SubServers.Bungee.Common</finalName>
|
||||
<outputDirectory>../../Artifacts/Maven</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>javadoc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<windowtitle>SubServers.Bungee.Common</windowtitle>
|
||||
<doctitle>SubServers.Bungee.Common ${project.version}</doctitle>
|
||||
<show>protected</show>
|
||||
<destDir>./</destDir>
|
||||
<outputDirectory>${basedir}/../../Javadoc/SubServers.Bungee.Common</outputDirectory>
|
||||
<reportOutputDirectory>${basedir}/../../Javadoc/SubServers.Bungee.Common</reportOutputDirectory>
|
||||
<additionalOptions>-Xdoclint:none</additionalOptions>
|
||||
<links>
|
||||
<link>https://dev.me1312.net/jenkins/job/GalaxiEngine/javadoc/GalaxiBase/</link>
|
||||
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
|
||||
</links>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -1,137 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* SubAPI BungeeCord Common Class
|
||||
*/
|
||||
public interface BungeeAPI {
|
||||
|
||||
/**
|
||||
* Gets the SubAPI BungeeCord Common Methods
|
||||
*
|
||||
* @return SubAPI BungeeCord Common
|
||||
*/
|
||||
static BungeeAPI getInstance() {
|
||||
return ((BungeeCommon) ProxyServer.getInstance()).api.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the BungeeCommon Internals
|
||||
*
|
||||
* @deprecated Use BungeeAPI Methods when available
|
||||
* @return BungeeCommon Internals
|
||||
*/
|
||||
@Deprecated
|
||||
BungeeCommon getInternals();
|
||||
|
||||
/**
|
||||
* Get the number of players on this network across all known proxies
|
||||
*
|
||||
* @return Remote Player Collection
|
||||
*/
|
||||
int getRemotePlayerCount();
|
||||
|
||||
/**
|
||||
* Get players on this server across all known proxies
|
||||
*
|
||||
* @param server Server to search
|
||||
* @return Remote Player Map
|
||||
*/
|
||||
Map<UUID, ? extends RemotePlayer> getRemotePlayers(ServerInfo server);
|
||||
|
||||
/**
|
||||
* Get players on this network across all known proxies
|
||||
*
|
||||
* @return Remote Player Map
|
||||
*/
|
||||
Map<UUID, ? extends RemotePlayer> getRemotePlayers();
|
||||
|
||||
/**
|
||||
* Get a player on this network by searching across all known proxies
|
||||
*
|
||||
* @param name Player name
|
||||
* @return Remote Player
|
||||
*/
|
||||
RemotePlayer getRemotePlayer(String name);
|
||||
|
||||
/**
|
||||
* Get a player on this network by searching across all known proxies
|
||||
*
|
||||
* @param id Player UUID
|
||||
* @return Remote Player
|
||||
*/
|
||||
RemotePlayer getRemotePlayer(UUID id);
|
||||
|
||||
/**
|
||||
* Gets the current SubServers Lang Channels
|
||||
*
|
||||
* @return SubServers Lang Channel list
|
||||
*/
|
||||
Collection<String> getLangChannels();
|
||||
|
||||
/**
|
||||
* Gets values from the SubServers Lang
|
||||
*
|
||||
* @param channel Lang Channel
|
||||
* @return Lang Value
|
||||
*/
|
||||
Map<String, String> getLang(String channel);
|
||||
|
||||
/**
|
||||
* Gets a value from the SubServers Lang
|
||||
*
|
||||
* @param channel Lang Channel
|
||||
* @param key Key
|
||||
* @return Lang Values
|
||||
*/
|
||||
default String getLang(String channel, String key) {
|
||||
Util.nullpo(channel, key);
|
||||
return getLang(channel).get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Runtime Directory
|
||||
*
|
||||
* @return Directory
|
||||
*/
|
||||
File getRuntimeDirectory();
|
||||
|
||||
/**
|
||||
* Gets the SubServers Version
|
||||
*
|
||||
* @return SubServers Version
|
||||
*/
|
||||
Version getWrapperVersion();
|
||||
|
||||
/**
|
||||
* Gets the SubServers Build Version
|
||||
*
|
||||
* @return SubServers Build Version (or null if unsigned)
|
||||
*/
|
||||
Version getWrapperBuild();
|
||||
|
||||
/**
|
||||
* Gets the BungeeCord Version
|
||||
*
|
||||
* @return BungeeCord Version
|
||||
*/
|
||||
Version getProxyVersion();
|
||||
|
||||
/**
|
||||
* Get an array of compatible Minecraft Versions
|
||||
*
|
||||
* @return Minecraft Versions
|
||||
*/
|
||||
Version[] getGameVersion();
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* BungeeCord Common Layout Class
|
||||
*/
|
||||
public abstract class BungeeCommon extends BungeeCord {
|
||||
private static BungeeCommon instance;
|
||||
final Supplier<BungeeAPI> api;
|
||||
protected final Collection<Channel> listeners;
|
||||
|
||||
protected BungeeCommon(Supplier<BungeeAPI> api) throws Exception {
|
||||
listeners= Util.reflect(BungeeCord.class.getDeclaredField("listeners"), this);
|
||||
this.api = api;
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name from BungeeCord's original signature (for determining which fork is being used)
|
||||
*
|
||||
* @return BungeeCord Software Name
|
||||
*/
|
||||
public abstract String getBungeeName();
|
||||
|
||||
/**
|
||||
* Waterfall's getServersCopy()
|
||||
*
|
||||
* @return Server Map Copy
|
||||
*/
|
||||
public abstract Map<String, ServerInfo> getServersCopy();
|
||||
|
||||
/**
|
||||
* Gets the ProxyServer Common Object
|
||||
*
|
||||
* @return ProxyServer Common
|
||||
*/
|
||||
public static BungeeCommon getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.BungeeCommon;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
* Logger Compatibility Class
|
||||
*/
|
||||
public class Logger {
|
||||
private static final HashMap<String, java.util.logging.Logger> existing = new HashMap<String, java.util.logging.Logger>();
|
||||
|
||||
/**
|
||||
* Get a logger
|
||||
*
|
||||
* @param prefix Prefix
|
||||
* @return Logger
|
||||
*/
|
||||
public static java.util.logging.Logger get(String prefix) {
|
||||
if (!existing.containsKey(prefix)) {
|
||||
java.util.logging.Logger log = java.util.logging.Logger.getAnonymousLogger();
|
||||
log.setUseParentHandlers(false);
|
||||
log.addHandler(new Handler() {
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
BungeeCommon.getInstance().getLogger().log(record.getLevel(), prefix + " > " + record.getMessage(), record.getParameters());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {}
|
||||
public void close() {}
|
||||
});
|
||||
existing.put(prefix, log);
|
||||
}
|
||||
return existing.get(prefix);
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
/**
|
||||
* RemotePlayer Static Implementation Layout Class
|
||||
*/
|
||||
public abstract class RPSI {
|
||||
protected static RPSI instance;
|
||||
protected RPSI() {
|
||||
if (instance == null) instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to this player
|
||||
*
|
||||
* @param players Players to send to
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
protected abstract void sendMessage(UUID[] players, String[] messages, IntConsumer response);
|
||||
|
||||
/**
|
||||
* Sends messages to this player
|
||||
*
|
||||
* @param players Players to send to
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
protected abstract void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response);
|
||||
|
||||
/**
|
||||
* Transfers this player to another server
|
||||
*
|
||||
* @param players Players to send to
|
||||
* @param server Target server
|
||||
* @param response Success Status
|
||||
*/
|
||||
protected abstract void transfer(UUID[] players, String server, IntConsumer response);
|
||||
|
||||
/**
|
||||
* Disconnects this player from the network
|
||||
*
|
||||
* @param players Players to send to
|
||||
* @param reason Disconnect Reason
|
||||
* @param response Success status
|
||||
*/
|
||||
protected abstract void disconnect(UUID[] players, String reason, IntConsumer response);
|
||||
}
|
|
@ -1,460 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
import static net.ME1312.SubServers.Bungee.Library.Compatibility.RPSI.instance;
|
||||
|
||||
/**
|
||||
* RemotePlayer Layout Class
|
||||
*/
|
||||
public interface RemotePlayer {
|
||||
|
||||
/**
|
||||
* Get Local Player
|
||||
*
|
||||
* @return Local Player (or null when not local)
|
||||
*/
|
||||
ProxiedPlayer get();
|
||||
|
||||
/**
|
||||
* Get the UUID of this player.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
UUID getUniqueId();
|
||||
|
||||
/**
|
||||
* Get the unique name of this player.
|
||||
*
|
||||
* @return the player's username
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Gets the remote address of this connection.
|
||||
*
|
||||
* @return the remote address
|
||||
*/
|
||||
InetSocketAddress getAddress();
|
||||
|
||||
/**
|
||||
* Gets the name of the proxy this player is connected to.
|
||||
*
|
||||
* @return the name of the proxy this player is connected to
|
||||
*/
|
||||
String getProxyName();
|
||||
|
||||
/**
|
||||
* Gets the name of the server this player is connected to.
|
||||
*
|
||||
* @return the name of the server this player is connected to
|
||||
*/
|
||||
String getServerName();
|
||||
|
||||
/**
|
||||
* Gets the server this player is connected to.
|
||||
*
|
||||
* @return the server this player is connected to
|
||||
*/
|
||||
ServerInfo getServer();
|
||||
|
||||
/**
|
||||
* Sends messages to all players
|
||||
*
|
||||
* @param messages Messages to send
|
||||
*/
|
||||
static void broadcastMessage(String... messages) {
|
||||
broadcastMessage(messages, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to all players
|
||||
*
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void broadcastMessage(String message, IntConsumer response) {
|
||||
broadcastMessage(new String[]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to all players
|
||||
*
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void broadcastMessage(String[] messages, IntConsumer response) {
|
||||
sendMessage(null, messages, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to this player
|
||||
*
|
||||
* @param messages Messages to send
|
||||
*/
|
||||
default void sendMessage(String... messages) {
|
||||
sendMessage(messages, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this player
|
||||
*
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
default void sendMessage(String message, IntConsumer response) {
|
||||
sendMessage(new String[]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to this player
|
||||
*
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
default void sendMessage(String[] messages, IntConsumer response) {
|
||||
sendMessage(new UUID[]{ getUniqueId() }, messages, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param messages Messages to send
|
||||
*/
|
||||
static void sendMessage(UUID[] players, String... messages) {
|
||||
sendMessage(players, messages, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void sendMessage(UUID[] players, String message, IntConsumer response) {
|
||||
sendMessage(players, new String[]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void sendMessage(UUID[] players, String[] messages, IntConsumer response) {
|
||||
instance.sendMessage(players, messages, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to all players
|
||||
*
|
||||
* @param message Message to send
|
||||
*/
|
||||
static void broadcastMessage(BaseComponent... message) {
|
||||
broadcastMessage(message, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to all players
|
||||
*
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void broadcastMessage(BaseComponent message, IntConsumer response) {
|
||||
broadcastMessage(new BaseComponent[]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a messages to all players
|
||||
*
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void broadcastMessage(BaseComponent[] message, IntConsumer response) {
|
||||
broadcastMessage(new BaseComponent[][]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to all players
|
||||
*
|
||||
* @param messages Messages to send
|
||||
*/
|
||||
static void broadcastMessage(BaseComponent[]... messages) {
|
||||
broadcastMessage(messages, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to all players
|
||||
*
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void broadcastMessage(BaseComponent[][] messages, IntConsumer response) {
|
||||
sendMessage(null, messages, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this player
|
||||
*
|
||||
* @param message Message to send
|
||||
*/
|
||||
default void sendMessage(BaseComponent... message) {
|
||||
sendMessage(message, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this player
|
||||
*
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
default void sendMessage(BaseComponent message, IntConsumer response) {
|
||||
sendMessage(new BaseComponent[]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to this player
|
||||
*
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
default void sendMessage(BaseComponent[] message, IntConsumer response) {
|
||||
sendMessage(new BaseComponent[][]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to this player
|
||||
*
|
||||
* @param messages Messages to send
|
||||
*/
|
||||
default void sendMessage(BaseComponent[]... messages) {
|
||||
sendMessage(messages, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to this player
|
||||
*
|
||||
* @param messages Messages to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
default void sendMessage(BaseComponent[][] messages, IntConsumer response) {
|
||||
sendMessage(new UUID[]{ getUniqueId() }, messages, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param message Message to send
|
||||
*/
|
||||
static void sendMessage(UUID[] players, BaseComponent... message) {
|
||||
sendMessage(players, message, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void sendMessage(UUID[] players, BaseComponent message, IntConsumer response) {
|
||||
sendMessage(players, new BaseComponent[]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param message Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void sendMessage(UUID[] players, BaseComponent[] message, IntConsumer response) {
|
||||
sendMessage(players, new BaseComponent[][]{ message }, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param messages Messages to send
|
||||
*/
|
||||
static void sendMessage(UUID[] players, BaseComponent[]... messages) {
|
||||
sendMessage(players, messages, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends messages to these players
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param messages Message to send
|
||||
* @param response Success Status
|
||||
*/
|
||||
static void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response) {
|
||||
instance.sendMessage(players, messages, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers this player to another server
|
||||
*
|
||||
* @param server Target server
|
||||
*/
|
||||
default void transfer(String server) {
|
||||
transfer(server, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers this player to another server
|
||||
*
|
||||
* @param server Target server
|
||||
* @param response Success status
|
||||
*/
|
||||
default void transfer(String server, IntConsumer response) {
|
||||
transfer(new UUID[]{ getUniqueId() }, server, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers these players to another server
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param server Target server
|
||||
*/
|
||||
static void transfer(UUID[] players, String server) {
|
||||
transfer(players, server, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers these players to another server
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param server Target server
|
||||
* @param response Success status
|
||||
*/
|
||||
static void transfer(UUID[] players, String server, IntConsumer response) {
|
||||
instance.transfer(players, server, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers this player to another server
|
||||
*
|
||||
* @param server Target server
|
||||
*/
|
||||
default void transfer(ServerInfo server) {
|
||||
transfer(server, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers this player to another server
|
||||
*
|
||||
* @param server Target server
|
||||
* @param response Success status
|
||||
*/
|
||||
default void transfer(ServerInfo server, IntConsumer response) {
|
||||
transfer(new UUID[]{ getUniqueId() }, server, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers these players to another server
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param server Target server
|
||||
*/
|
||||
static void transfer(UUID[] players, ServerInfo server) {
|
||||
transfer(players, server, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers these players to another server
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param server Target server
|
||||
* @param response Success status
|
||||
*/
|
||||
static void transfer(UUID[] players, ServerInfo server, IntConsumer response) {
|
||||
instance.transfer(players, server.getName(), response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects this player from the network
|
||||
*/
|
||||
default void disconnect() {
|
||||
disconnect((String) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects this player from the network
|
||||
*
|
||||
* @param response Success status
|
||||
*/
|
||||
default void disconnect(IntConsumer response) {
|
||||
disconnect((String) null, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects this player from the network
|
||||
*
|
||||
* @param reason Disconnect Reason
|
||||
*/
|
||||
default void disconnect(String reason) {
|
||||
disconnect(reason, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects this player from the network
|
||||
*
|
||||
* @param reason Disconnect Reason
|
||||
* @param response Success status
|
||||
*/
|
||||
default void disconnect(String reason, IntConsumer response) {
|
||||
disconnect(new UUID[]{ getUniqueId() }, reason, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects these players from the network
|
||||
*
|
||||
* @param players Players to select
|
||||
*/
|
||||
static void disconnect(UUID... players) {
|
||||
disconnect(players, (String) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects these players from the network
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param response Success status
|
||||
*/
|
||||
static void disconnect(UUID[] players, IntConsumer response) {
|
||||
disconnect(players, null, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects these players from the network
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param reason Disconnect Reason
|
||||
*/
|
||||
static void disconnect(UUID[] players, String reason) {
|
||||
disconnect(players, reason, i -> {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects these players from the network
|
||||
*
|
||||
* @param players Players to select
|
||||
* @param reason Disconnect Reason
|
||||
* @param response Success status
|
||||
*/
|
||||
static void disconnect(UUID[] players, String reason, IntConsumer response) {
|
||||
instance.disconnect(players, reason, response);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Fallback;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
/**
|
||||
* Fallback Server Inspector Layout Class
|
||||
*/
|
||||
public interface FallbackInspector {
|
||||
|
||||
/**
|
||||
* Inspect a fallback server and modify its confidence score
|
||||
*
|
||||
* @param player Player that requested (may be null)
|
||||
* @param server Server to inspect
|
||||
* @return A Positive Value to add points, a Negative Value to subtract points, a Null Value to invalidate the server, or a Zero Value to do nothing
|
||||
*/
|
||||
Double inspect(ProxiedPlayer player, ServerInfo server);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Fallback;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Fallback Player State Class
|
||||
*/
|
||||
public class FallbackState {
|
||||
public final UUID player;
|
||||
public final LinkedList<String> names;
|
||||
public final LinkedList<ServerInfo> servers;
|
||||
public final BaseComponent[] reason;
|
||||
private Map<String, ServerInfo> map;
|
||||
private Timer finish;
|
||||
|
||||
/**
|
||||
* Smart Fallback State Container
|
||||
*
|
||||
* @param player Player
|
||||
* @param servers Fallback Servers
|
||||
* @param reason Original Disconnect Reason
|
||||
*/
|
||||
public FallbackState(UUID player, Map<String, ServerInfo> servers, BaseComponent... reason) {
|
||||
this.player = player;
|
||||
this.map = servers;
|
||||
this.names = new LinkedList<>(servers.keySet());
|
||||
this.servers = new LinkedList<>(servers.values());
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Use</i> a server
|
||||
*
|
||||
* @param name Server name to remove
|
||||
*/
|
||||
public void remove(String name) {
|
||||
servers.remove(map.get(name));
|
||||
names.remove(name);
|
||||
map.remove(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* <i>Use</i> a server
|
||||
*
|
||||
* @param server Server to remove
|
||||
*/
|
||||
public void remove(ServerInfo server) {
|
||||
map.remove(server.getName());
|
||||
names.remove(server.getName());
|
||||
servers.remove(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the process
|
||||
*
|
||||
* @param callback Finishing callback
|
||||
* @param delay Delay for determining stability
|
||||
*/
|
||||
public void done(Runnable callback, long delay) {
|
||||
if (finish != null) finish.cancel();
|
||||
(finish = new Timer("SubServers.Bungee::Fallback_Limbo_Timer(" + player + ')')).schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (callback != null) callback.run();
|
||||
finish.cancel();
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
}
|
|
@ -1,209 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Fallback;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.BungeeCommon;
|
||||
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.api.AbstractReconnectHandler;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.ReconnectHandler;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* Smart Fallback Handler Class
|
||||
*/
|
||||
public class SmartFallback implements ReconnectHandler {
|
||||
private static List<FallbackInspector> inspectors = new CopyOnWriteArrayList<FallbackInspector>();
|
||||
private static ReconnectHandler reconnect;
|
||||
public static boolean dns_forward = false;
|
||||
|
||||
public SmartFallback(ObjectMap<String> settings) {
|
||||
dns_forward = settings.getBoolean("DNS-Forward", false);
|
||||
if (reconnect == null && settings.getBoolean("Reconnect", false))
|
||||
reconnect = Try.all.get(() -> Util.reflect(ProxyServer.getInstance().getPluginManager().getPlugin("reconnect_yaml").getClass().getClassLoader().loadClass("net.md_5.bungee.module.reconnect.yaml.YamlReconnectHandler").getConstructor()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerInfo getServer(ProxiedPlayer player) {
|
||||
return getServer(player, player instanceof UserConnection);
|
||||
}
|
||||
|
||||
protected ServerInfo getServer(ProxiedPlayer player, boolean queue) {
|
||||
ServerInfo override;
|
||||
if ((override = getForcedHost(player.getPendingConnection())) != null
|
||||
|| (override = getDNS(player.getPendingConnection())) != null) {
|
||||
if (queue) ((UserConnection) player).setServerJoinQueue(new LinkedList<>());
|
||||
return override;
|
||||
} else {
|
||||
Map<String, ServerInfo> fallbacks = getFallbackServers(player.getPendingConnection().getListener(), player);
|
||||
|
||||
if ((override = getReconnectServer(player)) != null || !fallbacks.isEmpty()) {
|
||||
if (queue) ((UserConnection) player).setServerJoinQueue(new LinkedList<>(fallbacks.keySet()));
|
||||
return (override != null)? override : new LinkedList<>(fallbacks.values()).getFirst();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the Forced Host Server for this connection
|
||||
*
|
||||
* @see AbstractReconnectHandler#getForcedHost(PendingConnection) Essentially the same method, but more ambigous
|
||||
* @param connection Connection to check
|
||||
* @return Forced Host Server (or null if there is none)
|
||||
*/
|
||||
public static ServerInfo getForcedHost(PendingConnection connection) {
|
||||
if (connection.getVirtualHost() == null) {
|
||||
return null;
|
||||
} else {
|
||||
String forced = connection.getListener().getForcedHosts().get(connection.getVirtualHost().getHostString());
|
||||
//if (forced == null && con.getListener().isForceDefault()) { // This is the part of the method that made it ambiguous
|
||||
// forced = con.getListener().getDefaultServer(); // Aside from that, everything else was fine
|
||||
//} // :(
|
||||
|
||||
return ProxyServer.getInstance().getServerInfo(forced);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the Server that a connection's DNS matches
|
||||
*
|
||||
* @param connection Connection to check
|
||||
* @return DNS Forward Server
|
||||
*/
|
||||
public static ServerInfo getDNS(PendingConnection connection) {
|
||||
if (connection.getVirtualHost() == null || !dns_forward) {
|
||||
return null;
|
||||
} else {
|
||||
Map.Entry<String, ServerInfo> server = null;
|
||||
String dns = connection.getVirtualHost().getHostString().toLowerCase();
|
||||
for (Map.Entry<String, ServerInfo> s : ((BungeeCommon) ProxyServer.getInstance()).getServersCopy().entrySet()) {
|
||||
if (dns.startsWith(s.getKey().toLowerCase() + '.'))
|
||||
if (server == null || server.getKey().length() < s.getKey().length())
|
||||
server = s;
|
||||
}
|
||||
|
||||
return (server == null)?null:server.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the Server that a player was last connected to
|
||||
*
|
||||
* @param player Player
|
||||
* @return Reconnect Server
|
||||
*/
|
||||
public static ServerInfo getReconnectServer(ProxiedPlayer player) {
|
||||
if (reconnect == null) {
|
||||
return null;
|
||||
} else try {
|
||||
return Util.reflect(reconnect.getClass().getDeclaredMethod("getStoredServer", ProxiedPlayer.class), reconnect, player);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
|
||||
*
|
||||
* @param listener Listener to grab fallback servers from
|
||||
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
|
||||
*/
|
||||
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener) {
|
||||
return getFallbackServers(listener, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a <i>smart</i> sorted map of fallback servers using a generated confidence score
|
||||
*
|
||||
* @param listener Listener to grab fallback servers from
|
||||
* @param player Player that is requesting fallback servers
|
||||
* @return Fallback Server Map (with legacy bungee case-sensitive keys)
|
||||
*/
|
||||
public static Map<String, ServerInfo> getFallbackServers(ListenerInfo listener, ProxiedPlayer player) {
|
||||
TreeMap<Double, List<ServerInfo>> score = new TreeMap<Double, List<ServerInfo>>(Collections.reverseOrder());
|
||||
for (String name : listener.getServerPriority()) {
|
||||
ServerInfo server = ProxyServer.getInstance().getServerInfo(name);
|
||||
if (server != null) {
|
||||
boolean valid = true;
|
||||
double confidence = 0;
|
||||
|
||||
List<FallbackInspector> inspectors = new ArrayList<FallbackInspector>();
|
||||
inspectors.addAll(SmartFallback.inspectors);
|
||||
for (FallbackInspector inspector : inspectors) try {
|
||||
Double response = inspector.inspect(player, server);
|
||||
if (response == null) {
|
||||
valid = false;
|
||||
} else {
|
||||
confidence += response;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running inspecting fallback server: " + server.getName()).printStackTrace();
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
List<ServerInfo> servers = (score.containsKey(confidence))?score.get(confidence):new LinkedList<ServerInfo>();
|
||||
servers.add(server);
|
||||
score.put(confidence, servers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Random random = new Random();
|
||||
LinkedHashMap<String, ServerInfo> map = new LinkedHashMap<String, ServerInfo>();
|
||||
for (List<ServerInfo> servers : score.values()) {
|
||||
while (!servers.isEmpty()) {
|
||||
ServerInfo next = servers.get(random.nextInt(servers.size()));
|
||||
map.put(next.getName(), next);
|
||||
servers.remove(next);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Fallback Server Inspector
|
||||
*
|
||||
* @param inspector Inspector
|
||||
*/
|
||||
public static void addInspector(FallbackInspector inspector) {
|
||||
Util.nullpo(inspector);
|
||||
inspectors.add(inspector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a Fallback Server Inspector
|
||||
*
|
||||
* @param inspector Inspector
|
||||
*/
|
||||
public static void removeInspector(FallbackInspector inspector) {
|
||||
Util.nullpo(inspector);
|
||||
Try.all.run(() -> inspectors.remove(inspector));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServer(ProxiedPlayer player) {
|
||||
if (reconnect != null) reconnect.setServer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
if (reconnect != null) reconnect.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (reconnect != null) reconnect.close();
|
||||
}
|
||||
}
|
|
@ -1,909 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.BungeeAPI;
|
||||
import net.ME1312.SubServers.Bungee.BungeeCommon;
|
||||
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
import net.md_5.bungee.config.YamlConfiguration;
|
||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* SubServers BStats Metrics Implementation
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
private final Plugin plugin;
|
||||
|
||||
private final MetricsBase metricsBase;
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
private String serverUUID;
|
||||
|
||||
private boolean logErrors = false;
|
||||
|
||||
private boolean logSentData;
|
||||
|
||||
private boolean logResponseStatusText;
|
||||
|
||||
/**
|
||||
* Creates a new Metrics instance.
|
||||
*
|
||||
* @param plugin Your plugin instance.
|
||||
* @param serviceId The id of the service. It can be found at <a
|
||||
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
||||
*/
|
||||
public Metrics(Plugin plugin, int serviceId) {
|
||||
this.plugin = plugin;
|
||||
try {
|
||||
loadConfig();
|
||||
} catch (IOException e) {
|
||||
// Failed to load configuration
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to load bStats config!", e);
|
||||
metricsBase = null;
|
||||
return;
|
||||
}
|
||||
metricsBase =
|
||||
new MetricsBase(
|
||||
"bungeecord",
|
||||
serverUUID,
|
||||
serviceId,
|
||||
enabled,
|
||||
this::appendPlatformData,
|
||||
this::appendServiceData,
|
||||
null,
|
||||
() -> true,
|
||||
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
|
||||
(message) -> this.plugin.getLogger().log(Level.INFO, message),
|
||||
logErrors,
|
||||
logSentData,
|
||||
logResponseStatusText);
|
||||
}
|
||||
|
||||
/** Loads the bStats configuration. */
|
||||
private void loadConfig() throws IOException {
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
bStatsFolder.mkdirs();
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
if (!configFile.exists()) {
|
||||
writeFile(
|
||||
configFile,
|
||||
"# bStats (https://bStats.org) collects some basic information for plugin authors, like how",
|
||||
"# many people use their plugin and their total player count. It's recommended to keep bStats",
|
||||
"# enabled, but if you're not comfortable with this, you can turn this setting off. There is no",
|
||||
"# performance penalty associated with having metrics enabled, and data sent to bStats is fully",
|
||||
"# anonymous.",
|
||||
"enabled: true",
|
||||
"serverUuid: \"" + UUID.randomUUID() + "\"",
|
||||
"logFailedRequests: false",
|
||||
"logSentData: false",
|
||||
"logResponseStatusText: false");
|
||||
}
|
||||
Configuration configuration =
|
||||
ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
||||
// Load configuration
|
||||
enabled = configuration.getBoolean("enabled", true);
|
||||
serverUUID = configuration.getString("serverUuid");
|
||||
logErrors = configuration.getBoolean("logFailedRequests", false);
|
||||
logSentData = configuration.getBoolean("logSentData", false);
|
||||
logResponseStatusText = configuration.getBoolean("logResponseStatusText", false);
|
||||
}
|
||||
|
||||
private void writeFile(File file, String... lines) throws IOException {
|
||||
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
|
||||
for (String line : lines) {
|
||||
bufferedWriter.write(line);
|
||||
bufferedWriter.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final AdvancedPie PLAYER_VERSIONS;
|
||||
static {
|
||||
final int[] PROTOCOL_VERSIONS;
|
||||
final String[] PROTOCOL_NAMES;
|
||||
{
|
||||
TIntObjectHashMap<String> protocols = new TIntObjectHashMap<String>();
|
||||
try {
|
||||
for (Field f : ProtocolConstants.class.getDeclaredFields()) {
|
||||
int fm = f.getModifiers();
|
||||
if (Modifier.isPublic(fm) && Modifier.isStatic(fm) && Modifier.isFinal(fm) && f.getType() == int.class && f.getName().startsWith("MINECRAFT_")) {
|
||||
protocols.put(f.getInt(null), f.getName().substring(10).replace('_', '.'));
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
PROTOCOL_VERSIONS = protocols.keys();
|
||||
PROTOCOL_NAMES = new String[PROTOCOL_VERSIONS.length];
|
||||
|
||||
Arrays.sort(PROTOCOL_VERSIONS);
|
||||
for (int i = 0; i < PROTOCOL_VERSIONS.length; ++i) {
|
||||
PROTOCOL_NAMES[i] = protocols.get(PROTOCOL_VERSIONS[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PLAYER_VERSIONS = new AdvancedPie("player_versions", () -> {
|
||||
int[] players = new int[PROTOCOL_VERSIONS.length];
|
||||
for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) {
|
||||
int i = Arrays.binarySearch(PROTOCOL_VERSIONS, player.getPendingConnection().getVersion());
|
||||
if (i != -1) {
|
||||
++players[i];
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<String, Integer> map = new HashMap<String, Integer>();
|
||||
for (int i = 0; i < PROTOCOL_NAMES.length; ++i) if (players[i] != 0) {
|
||||
map.put(PROTOCOL_NAMES[i], players[i]);
|
||||
}
|
||||
return map;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subservers platform information as custom charts
|
||||
*/
|
||||
public Metrics addPlatformCharts() {
|
||||
return addCustomChart(new SimplePie("subservers_version", () -> BungeeAPI.getInstance().getWrapperVersion().toString())).addCustomChart(PLAYER_VERSIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public Metrics addCustomChart(CustomChart chart) {
|
||||
metricsBase.addCustomChart(chart);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void appendPlatformData(JsonObjectBuilder builder) {
|
||||
builder.appendField("playerAmount", plugin.getProxy().getOnlineCount());
|
||||
builder.appendField("managedServers", ((BungeeCommon) plugin.getProxy()).getServersCopy().size());
|
||||
builder.appendField("onlineMode", plugin.getProxy().getConfig().isOnlineMode() ? 1 : 0);
|
||||
builder.appendField("bungeecordVersion", plugin.getProxy().getVersion());
|
||||
builder.appendField("javaVersion", System.getProperty("java.version"));
|
||||
builder.appendField("osName", System.getProperty("os.name"));
|
||||
builder.appendField("osArch", System.getProperty("os.arch"));
|
||||
builder.appendField("osVersion", System.getProperty("os.version"));
|
||||
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
|
||||
}
|
||||
|
||||
private void appendServiceData(JsonObjectBuilder builder) {
|
||||
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
|
||||
}
|
||||
|
||||
public static class MetricsBase {
|
||||
|
||||
/** The version of the Metrics class. */
|
||||
public static final String METRICS_VERSION = "3.0.0";
|
||||
|
||||
private static final ScheduledExecutorService scheduler =
|
||||
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
|
||||
|
||||
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
|
||||
|
||||
private final String platform;
|
||||
|
||||
private final String serverUuid;
|
||||
|
||||
private final int serviceId;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
|
||||
|
||||
private final Consumer<Runnable> submitTaskConsumer;
|
||||
|
||||
private final Supplier<Boolean> checkServiceEnabledSupplier;
|
||||
|
||||
private final BiConsumer<String, Throwable> errorLogger;
|
||||
|
||||
private final Consumer<String> infoLogger;
|
||||
|
||||
private final boolean logErrors;
|
||||
|
||||
private final boolean logSentData;
|
||||
|
||||
private final boolean logResponseStatusText;
|
||||
|
||||
private final Set<CustomChart> customCharts = new HashSet<>();
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Creates a new MetricsBase class instance.
|
||||
*
|
||||
* @param platform The platform of the service.
|
||||
* @param serviceId The id of the service.
|
||||
* @param serverUuid The server uuid.
|
||||
* @param enabled Whether or not data sending is enabled.
|
||||
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all platform-specific data.
|
||||
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all service-specific data.
|
||||
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
|
||||
* used to delegate the data collection to a another thread to prevent errors caused by
|
||||
* concurrency. Can be {@code null}.
|
||||
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
|
||||
* @param errorLogger A consumer that accepts log message and an error.
|
||||
* @param infoLogger A consumer that accepts info log messages.
|
||||
* @param logErrors Whether or not errors should be logged.
|
||||
* @param logSentData Whether or not the sent data should be logged.
|
||||
* @param logResponseStatusText Whether or not the response status text should be logged.
|
||||
*/
|
||||
public MetricsBase(
|
||||
String platform,
|
||||
String serverUuid,
|
||||
int serviceId,
|
||||
boolean enabled,
|
||||
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
|
||||
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
|
||||
Consumer<Runnable> submitTaskConsumer,
|
||||
Supplier<Boolean> checkServiceEnabledSupplier,
|
||||
BiConsumer<String, Throwable> errorLogger,
|
||||
Consumer<String> infoLogger,
|
||||
boolean logErrors,
|
||||
boolean logSentData,
|
||||
boolean logResponseStatusText) {
|
||||
this.platform = platform;
|
||||
this.serverUuid = serverUuid;
|
||||
this.serviceId = serviceId;
|
||||
this.enabled = enabled;
|
||||
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
|
||||
this.appendServiceDataConsumer = appendServiceDataConsumer;
|
||||
this.submitTaskConsumer = submitTaskConsumer;
|
||||
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
|
||||
this.errorLogger = errorLogger;
|
||||
this.infoLogger = infoLogger;
|
||||
this.logErrors = logErrors;
|
||||
this.logSentData = logSentData;
|
||||
this.logResponseStatusText = logResponseStatusText;
|
||||
checkRelocation();
|
||||
if (enabled) {
|
||||
// WARNING: Removing the option to opt-out will get your plugin banned from bStats
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
this.customCharts.add(chart);
|
||||
}
|
||||
|
||||
private void startSubmitting() {
|
||||
final Runnable submitTask =
|
||||
() -> {
|
||||
if (!enabled || !checkServiceEnabledSupplier.get()) {
|
||||
// Submitting data or service is disabled
|
||||
scheduler.shutdown();
|
||||
return;
|
||||
}
|
||||
if (submitTaskConsumer != null) {
|
||||
submitTaskConsumer.accept(this::submitData);
|
||||
} else {
|
||||
this.submitData();
|
||||
}
|
||||
};
|
||||
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
|
||||
// of requests on the
|
||||
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
|
||||
// and second delay.
|
||||
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
|
||||
// frequency!
|
||||
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
|
||||
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
|
||||
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
|
||||
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
|
||||
scheduler.scheduleAtFixedRate(
|
||||
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void submitData() {
|
||||
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
|
||||
appendPlatformDataConsumer.accept(baseJsonBuilder);
|
||||
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
|
||||
appendServiceDataConsumer.accept(serviceJsonBuilder);
|
||||
JsonObjectBuilder.JsonObject[] chartData =
|
||||
customCharts.stream()
|
||||
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(JsonObjectBuilder.JsonObject[]::new);
|
||||
serviceJsonBuilder.appendField("id", serviceId);
|
||||
serviceJsonBuilder.appendField("customCharts", chartData);
|
||||
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
|
||||
baseJsonBuilder.appendField("serverUUID", serverUuid);
|
||||
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
|
||||
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
|
||||
scheduler.execute(
|
||||
() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Could not submit bStats metrics data", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
|
||||
if (logSentData) {
|
||||
infoLogger.accept("Sent bStats metrics data: " + data.toString());
|
||||
}
|
||||
String url = String.format(REPORT_URL, platform);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
|
||||
connection.setDoOutput(true);
|
||||
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
|
||||
outputStream.write(compressedData);
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try (BufferedReader bufferedReader =
|
||||
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
}
|
||||
if (logResponseStatusText) {
|
||||
infoLogger.accept("Sent data to bStats and received response: " + builder);
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks that the class was properly relocated. */
|
||||
private void checkRelocation() {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null
|
||||
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little
|
||||
// "trick" ... :D
|
||||
final String defaultPackage =
|
||||
new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
|
||||
final String examplePackage =
|
||||
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure no one just copy & pastes the example and uses the wrong package
|
||||
// names
|
||||
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|
||||
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given string.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped string.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class CustomChart {
|
||||
|
||||
private final String chartId;
|
||||
|
||||
protected CustomChart(String chartId) {
|
||||
if (chartId == null) {
|
||||
throw new IllegalArgumentException("chartId must not be null");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder.JsonObject getRequestJsonObject(
|
||||
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
|
||||
JsonObjectBuilder builder = new JsonObjectBuilder();
|
||||
builder.appendField("chartId", chartId);
|
||||
try {
|
||||
JsonObjectBuilder.JsonObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
builder.appendField("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
|
||||
}
|
||||
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extremely simple JSON builder.
|
||||
*
|
||||
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
|
||||
* for its use-case.
|
||||
*/
|
||||
public static class JsonObjectBuilder {
|
||||
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
private boolean hasAtLeastOneField = false;
|
||||
|
||||
public JsonObjectBuilder() {
|
||||
builder.append("{");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a null field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendNull(String key) {
|
||||
appendFieldUnescaped(key, "null");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String value) {
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("JSON value must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int value) {
|
||||
appendFieldUnescaped(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param object The object.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject object) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException("JSON object must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, object.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The string array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values)
|
||||
.map(value -> "\"" + escape(value) + "\"")
|
||||
.collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a field to the object.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param escapedValue The escaped value of the field.
|
||||
*/
|
||||
private void appendFieldUnescaped(String key, String escapedValue) {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("JSON key must not be null");
|
||||
}
|
||||
if (hasAtLeastOneField) {
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
|
||||
hasAtLeastOneField = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JSON string and invalidates this builder.
|
||||
*
|
||||
* @return The built JSON string.
|
||||
*/
|
||||
public JsonObject build() {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
JsonObject object = new JsonObject(builder.append("}").toString());
|
||||
builder = null;
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
|
||||
*
|
||||
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
|
||||
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
|
||||
*
|
||||
* @param value The value to escape.
|
||||
* @return The escaped value.
|
||||
*/
|
||||
private static String escape(String value) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char c = value.charAt(i);
|
||||
if (c == '"') {
|
||||
builder.append("\\\"");
|
||||
} else if (c == '\\') {
|
||||
builder.append("\\\\");
|
||||
} else if (c <= '\u000F') {
|
||||
builder.append("\\u000").append(Integer.toHexString(c));
|
||||
} else if (c <= '\u001F') {
|
||||
builder.append("\\u00").append(Integer.toHexString(c));
|
||||
} else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A super simple representation of a JSON object.
|
||||
*
|
||||
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
|
||||
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
|
||||
* JsonObject)}.
|
||||
*/
|
||||
public static class JsonObject {
|
||||
|
||||
private final String value;
|
||||
|
||||
private JsonObject(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>net.ME1312.SubServers</groupId>
|
||||
|
@ -14,7 +16,7 @@
|
|||
</repository>
|
||||
<repository>
|
||||
<id>me1312-repo</id>
|
||||
<url>https://dev.me1312.net/maven</url>
|
||||
<url>https://src.me1312.net/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
@ -22,19 +24,13 @@
|
|||
<dependency>
|
||||
<groupId>net.md_5</groupId>
|
||||
<artifactId>bungeecord-internal</artifactId>
|
||||
<version>1.15-SNAPSHOT</version>
|
||||
<version>1.9-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ME1312.SubServers</groupId>
|
||||
<artifactId>SubServers.Bungee.Common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ME1312.SubData</groupId>
|
||||
<artifactId>Server</artifactId>
|
||||
<version>23w08b</version>
|
||||
<groupId>org.msgpack</groupId>
|
||||
<artifactId>msgpack-core</artifactId>
|
||||
<version>0.8.16</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -43,6 +39,12 @@
|
|||
<version>1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.imaginarycode.minecraft</groupId>
|
||||
<artifactId>RedisBungee</artifactId>
|
||||
<version>0.3.8-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -71,7 +73,6 @@
|
|||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>process</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
|
@ -80,42 +81,17 @@
|
|||
<tasks>
|
||||
<mkdir dir="${project.build.directory}" />
|
||||
<copy file="${basedir}/../LICENSE" todir="${project.build.directory}/classes" />
|
||||
<mkdir dir="${basedir}/../Artifacts/Modulized" />
|
||||
<copy file="${basedir}/../Artifacts/SubServers.Client.Universal.jar" tofile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/client.jar" />
|
||||
<copy file="${basedir}/../Artifacts/SubServers.Client.jar" tofile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/client.jar" />
|
||||
<mkdir dir="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip" includes="Forge/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/purpur.zip" includes="Purpur/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip" includes="Spigot/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip" includes="Sponge/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip" includes="Vanilla/**" />
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>verify</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks> <!-- Dependency Stripped Jar for Testing -->
|
||||
<jar destfile="${basedir}/../Artifacts/Modulized/SubServers.Bungee.jar" manifest="src/META-INF/MANIFEST.MOD.MF">
|
||||
<zipfileset src="${basedir}/../Artifacts/SubServers.Bungee.jar" excludes="net/ME1312/Galaxi/** net/ME1312/SubData/**" />
|
||||
</jar>
|
||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip" includes="Forge/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip" includes="Spigot/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip" includes="Sponge/**" />
|
||||
<zip basedir="${basedir}/../SubServers.Creator/src" destfile="${project.build.directory}/classes/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip" includes="Vanilla/**" />
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<finalName>SubServers.Bungee</finalName>
|
||||
<outputDirectory>../Artifacts/Maven</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
|
@ -126,9 +102,9 @@
|
|||
<archive>
|
||||
<manifestFile>src/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
<descriptors>
|
||||
<descriptor>../SubServers.Client/Common/jar-with-some-dependencies.xml</descriptor>
|
||||
</descriptors>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
<executions>
|
||||
|
@ -152,22 +128,13 @@
|
|||
<goal>javadoc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<windowtitle>SubServers.Bungee</windowtitle>
|
||||
<doctitle>SubServers.Bungee ${project.version}</doctitle>
|
||||
<show>protected</show>
|
||||
<windowtitle>SubServers.Bungee Javadoc</windowtitle>
|
||||
<doctitle>SubServers.Bungee Javadoc</doctitle>
|
||||
<show>public</show>
|
||||
<destDir>./</destDir>
|
||||
<outputDirectory>${basedir}/../Javadoc/SubServers.Bungee</outputDirectory>
|
||||
<reportOutputDirectory>${basedir}/../Javadoc/SubServers.Bungee</reportOutputDirectory>
|
||||
<additionalOptions>-Xdoclint:none</additionalOptions>
|
||||
<links>
|
||||
<link>https://dev.me1312.net/jenkins/job/GalaxiEngine/javadoc/GalaxiBase/</link>
|
||||
<link>https://dev.me1312.net/jenkins/job/SubData/javadoc/Server/</link>
|
||||
<link>https://ci.md-5.net/job/BungeeCord/ws/api/target/apidocs/</link>
|
||||
</links>
|
||||
<includeDependencySources>true</includeDependencySources>
|
||||
<dependencySourceIncludes>
|
||||
<dependencySourceInclude>net.ME1312.SubServers:SubServers.Bungee.Common:*</dependencySourceInclude>
|
||||
</dependencySourceIncludes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Class-Path: libraries/GalaxiBase.jar libraries/SubDataServer.jar libraries/BungeeCord.jar
|
||||
Main-Class: net.ME1312.SubServers.Bungee.Launch
|
||||
Implementation-Title: SubServers.Bungee
|
|
@ -1,9 +1,9 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class SubAddHostEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param host Host Being Added
|
||||
*/
|
||||
public SubAddHostEvent(UUID player, Host host) {
|
||||
Util.nullpo(host);
|
||||
if (Util.isNull(host)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.host = host;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +17,7 @@ public class SubAddProxyEvent extends Event implements SubEvent {
|
|||
* @param proxy Host Being Added
|
||||
*/
|
||||
public SubAddProxyEvent(Proxy proxy) {
|
||||
Util.nullpo(proxy);
|
||||
if (Util.isNull(proxy)) throw new NullPointerException();
|
||||
this.proxy = proxy;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -27,7 +26,7 @@ public class SubAddServerEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param server Server Starting
|
||||
*/
|
||||
public SubAddServerEvent(UUID player, Host host, Server server) {
|
||||
Util.nullpo(server);
|
||||
if (Util.isNull(server)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.host = host;
|
||||
this.server = server;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -18,7 +16,6 @@ import java.util.UUID;
|
|||
public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
||||
private boolean cancelled = false;
|
||||
private UUID player;
|
||||
private SubServer update;
|
||||
private Host host;
|
||||
private String name;
|
||||
private SubCreator.ServerTemplate template;
|
||||
|
@ -36,7 +33,7 @@ public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param port Server Port Number
|
||||
*/
|
||||
public SubCreateEvent(UUID player, Host host, String name, SubCreator.ServerTemplate template, Version version, int port) {
|
||||
Util.nullpo(host, name, template);
|
||||
if (Util.isNull(host, name, template, version, port)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.host = host;
|
||||
this.name = name;
|
||||
|
@ -45,25 +42,6 @@ public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
|||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Server Create Event (as an Update)
|
||||
*
|
||||
* @param player Player Updating
|
||||
* @param server Server to be Updated
|
||||
* @param template Server Template
|
||||
* @param version Server Version
|
||||
*/
|
||||
public SubCreateEvent(UUID player, SubServer server, SubCreator.ServerTemplate template, Version version) {
|
||||
Util.nullpo(server);
|
||||
this.player = player;
|
||||
this.update = server;
|
||||
this.name = server.getName();
|
||||
this.host = server.getHost();
|
||||
this.template = template;
|
||||
this.version = version;
|
||||
this.port = server.getAddress().getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Host the SubServer will run on
|
||||
*
|
||||
|
@ -73,24 +51,6 @@ public class SubCreateEvent extends Event implements SubEvent, Cancellable {
|
|||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if SubCreator is being run in update mode
|
||||
*
|
||||
* @return Update Mode Status
|
||||
*/
|
||||
public boolean isUpdate() {
|
||||
return update != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Server that's being updated
|
||||
*
|
||||
* @return Updating Server
|
||||
*/
|
||||
public SubServer getUpdatingServer() {
|
||||
return update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name the SubServer will use
|
||||
*
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Server Created Event
|
||||
*/
|
||||
public class SubCreatedEvent extends Event implements SubEvent {
|
||||
private UUID player;
|
||||
private SubServer server;
|
||||
private boolean success;
|
||||
private boolean update;
|
||||
private Host host;
|
||||
private String name;
|
||||
private SubCreator.ServerTemplate template;
|
||||
private Version version;
|
||||
private int port;
|
||||
|
||||
/**
|
||||
* Server Created Event
|
||||
*
|
||||
* @param player Player Creating
|
||||
* @param host Potential Host
|
||||
* @param name Server Name
|
||||
* @param template Server Template
|
||||
* @param version Server Version
|
||||
* @param port Server Port Number
|
||||
* @param server Server Object
|
||||
* @param update Update Mode Status
|
||||
* @param success Success Status
|
||||
*/
|
||||
public SubCreatedEvent(UUID player, Host host, String name, SubCreator.ServerTemplate template, Version version, int port, SubServer server, boolean update, boolean success) {
|
||||
Util.nullpo(host, name, template);
|
||||
this.player = player;
|
||||
this.host = host;
|
||||
this.name = name;
|
||||
this.template = template;
|
||||
this.version = version;
|
||||
this.port = port;
|
||||
this.server = server;
|
||||
this.update = update;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Host the SubServer runs on
|
||||
*
|
||||
* @return Host
|
||||
*/
|
||||
public Host getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if SubCreator was being run in update mode
|
||||
*
|
||||
* @return Update Mode Status
|
||||
*/
|
||||
public boolean wasUpdate() {
|
||||
return update;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the operation was a success
|
||||
*
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean wasSuccessful() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Server that was created/updated
|
||||
*
|
||||
* @return Finished Server
|
||||
*/
|
||||
public SubServer getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name the SubServer used
|
||||
*
|
||||
* @return SubServer Name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Template that was used
|
||||
*
|
||||
* @return Server Template
|
||||
*/
|
||||
public SubCreator.ServerTemplate getTemplate() {
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Version the Server used
|
||||
*
|
||||
* @return Server Version
|
||||
*/
|
||||
public Version getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Port the Server used
|
||||
*
|
||||
* @return Port Number
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player that triggered the Event
|
||||
*
|
||||
* @return The Player that triggered this Event or null if Console
|
||||
*/
|
||||
public UUID getPlayer() { return player; }
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -20,7 +18,8 @@ public class SubEditServerEvent extends Event implements SubEvent, Cancellable {
|
|||
private boolean cancelled = false;
|
||||
private UUID player;
|
||||
private Server server;
|
||||
private Pair<String, ObjectMapValue> edit;
|
||||
private NamedContainer<String, YAMLValue> edit;
|
||||
private boolean perm;
|
||||
|
||||
/**
|
||||
* Server Edit Event
|
||||
|
@ -28,14 +27,16 @@ public class SubEditServerEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param player Player Adding Server
|
||||
* @param server Server to be Edited
|
||||
* @param edit Edit to make
|
||||
* @param permanent If the change is permanent
|
||||
*/
|
||||
public SubEditServerEvent(UUID player, Server server, Pair<String, ?> edit) {
|
||||
Util.nullpo(server, edit);
|
||||
ObjectMap<String> section = new ObjectMap<String>();
|
||||
section.set(".", edit.value());
|
||||
public SubEditServerEvent(UUID player, Server server, NamedContainer<String, ?> edit, boolean permanent) {
|
||||
if (Util.isNull(server, edit)) throw new NullPointerException();
|
||||
YAMLSection section = new YAMLSection();
|
||||
section.set(".", edit.get());
|
||||
this.player = player;
|
||||
this.server = server;
|
||||
this.edit = new ContainedPair<String, ObjectMapValue>(edit.key(), section.get("."));
|
||||
this.edit = new NamedContainer<String, YAMLValue>(edit.name(), section.get("."));
|
||||
this.perm = permanent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,10 +58,19 @@ public class SubEditServerEvent extends Event implements SubEvent, Cancellable {
|
|||
*
|
||||
* @return Edit to be made
|
||||
*/
|
||||
public Pair<String, ObjectMapValue> getEdit() {
|
||||
public NamedContainer<String, YAMLValue> getEdit() {
|
||||
return edit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the edit is permanent
|
||||
*
|
||||
* @return Permanent Status
|
||||
*/
|
||||
public boolean isPermanent() {
|
||||
return perm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Cancelled Status
|
||||
*
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
import net.ME1312.SubData.Server.DataServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* SubData Network Connect Event
|
||||
*/
|
||||
public class SubNetworkConnectEvent extends Event implements SubEvent, Cancellable {
|
||||
private boolean cancelled = false;
|
||||
private DataServer network;
|
||||
private DataClient client;
|
||||
private SubDataServer network;
|
||||
private InetAddress address;
|
||||
|
||||
/**
|
||||
* SubData Network Connect Event
|
||||
*/
|
||||
public SubNetworkConnectEvent(DataServer network, DataClient client) {
|
||||
Util.nullpo(network, client);
|
||||
public SubNetworkConnectEvent(SubDataServer network, InetAddress address) {
|
||||
if (Util.isNull(network, address)) throw new NullPointerException();
|
||||
this.network = network;
|
||||
this.client = client;
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,17 +30,17 @@ public class SubNetworkConnectEvent extends Event implements SubEvent, Cancellab
|
|||
*
|
||||
* @return SubData Network
|
||||
*/
|
||||
public DataServer getNetwork() {
|
||||
public SubDataServer getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connecting client
|
||||
* Get the address of the connecting client
|
||||
*
|
||||
* @return Client
|
||||
* @return Client address
|
||||
*/
|
||||
public DataClient getClient() {
|
||||
return client;
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,29 +1,25 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
import net.ME1312.SubData.Server.DataServer;
|
||||
import net.ME1312.SubData.Server.Library.DisconnectReason;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* SubData Network Disconnect Event
|
||||
*/
|
||||
public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
||||
private DataServer network;
|
||||
private DataClient client;
|
||||
private DisconnectReason reason;
|
||||
private SubDataServer network;
|
||||
private Client client;
|
||||
|
||||
/**
|
||||
* SubData Network Disconnect Event
|
||||
*/
|
||||
public SubNetworkDisconnectEvent(DataServer network, DataClient client, DisconnectReason reason) {
|
||||
Util.nullpo(network, client, reason);
|
||||
public SubNetworkDisconnectEvent(SubDataServer network, Client client) {
|
||||
if (Util.isNull(network, client)) throw new NullPointerException();
|
||||
this.network = network;
|
||||
this.client = client;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,7 +27,7 @@ public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
|||
*
|
||||
* @return SubData Network
|
||||
*/
|
||||
public DataServer getNetwork() {
|
||||
public SubDataServer getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
|
@ -40,16 +36,8 @@ public class SubNetworkDisconnectEvent extends Event implements SubEvent {
|
|||
*
|
||||
* @return Client
|
||||
*/
|
||||
public DataClient getClient() {
|
||||
public Client getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reason the client disconnected
|
||||
*
|
||||
* @return Disconnect Reason
|
||||
*/
|
||||
public DisconnectReason getReason() {
|
||||
return reason;
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
import net.ME1312.SubData.Server.DataServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* SubData Network Login Event
|
||||
*/
|
||||
public class SubNetworkLoginEvent extends Event implements SubEvent {
|
||||
private DataServer network;
|
||||
private DataClient client;
|
||||
|
||||
/**
|
||||
* SubData Network Login Event
|
||||
*/
|
||||
public SubNetworkLoginEvent(DataServer network, DataClient client) {
|
||||
Util.nullpo(network, client);
|
||||
this.network = network;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the network the client is connected to
|
||||
*
|
||||
* @return SubData Network
|
||||
*/
|
||||
public DataServer getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the connecting client
|
||||
*
|
||||
* @return Client
|
||||
*/
|
||||
public DataClient getClient() {
|
||||
return client;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class SubRemoveHostEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param host Host to be added
|
||||
*/
|
||||
public SubRemoveHostEvent(UUID player, Host host) {
|
||||
Util.nullpo(host);
|
||||
if (Util.isNull(host)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.host = host;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +17,7 @@ public class SubRemoveProxyEvent extends Event implements SubEvent {
|
|||
* @param proxy Host Being Added
|
||||
*/
|
||||
public SubRemoveProxyEvent(Proxy proxy) {
|
||||
Util.nullpo(proxy);
|
||||
if (Util.isNull(proxy)) throw new NullPointerException();
|
||||
this.proxy = proxy;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -27,7 +26,7 @@ public class SubRemoveServerEvent extends Event implements SubEvent, Cancellable
|
|||
* @param server Server Starting
|
||||
*/
|
||||
public SubRemoveServerEvent(UUID player, Host host, Server server) {
|
||||
Util.nullpo(server);
|
||||
if (Util.isNull(server)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.host = host;
|
||||
this.server = server;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -15,24 +14,20 @@ import java.util.UUID;
|
|||
public class SubSendCommandEvent extends Event implements SubEvent, Cancellable {
|
||||
private boolean cancelled = false;
|
||||
private UUID player;
|
||||
private Server server;
|
||||
private SubServer server;
|
||||
private String command;
|
||||
private UUID target;
|
||||
|
||||
/**
|
||||
* Server Command Event
|
||||
*
|
||||
* @param player Player Commanding
|
||||
* @param server Target Server
|
||||
* @param command Command to Send
|
||||
* @param target Player that will send
|
||||
* @param player Player Commanding Server
|
||||
* @param server Server being Commanded
|
||||
*/
|
||||
public SubSendCommandEvent(UUID player, Server server, String command, UUID target) {
|
||||
Util.nullpo(server, command);
|
||||
public SubSendCommandEvent(UUID player, SubServer server, String command) {
|
||||
if (Util.isNull(server, command)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.server = server;
|
||||
this.command = command;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +35,7 @@ public class SubSendCommandEvent extends Event implements SubEvent, Cancellable
|
|||
*
|
||||
* @return The Server Effected
|
||||
*/
|
||||
public Server getServer() { return server; }
|
||||
public SubServer getServer() { return server; }
|
||||
|
||||
/**
|
||||
* Gets the player that triggered the Event
|
||||
|
@ -67,15 +62,6 @@ public class SubSendCommandEvent extends Event implements SubEvent, Cancellable
|
|||
command = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Player that will be forced to send the Command
|
||||
*
|
||||
* @return Target Player or null if Console
|
||||
*/
|
||||
public UUID getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Cancelled Status
|
||||
*
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -24,7 +23,7 @@ public class SubStartEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param server Server Starting
|
||||
*/
|
||||
public SubStartEvent(UUID player, SubServer server) {
|
||||
Util.nullpo(server);
|
||||
if (Util.isNull(server)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.server = server;
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Server Started Event
|
||||
*/
|
||||
public class SubStartedEvent extends Event implements SubEvent {
|
||||
private SubServer server;
|
||||
|
||||
/**
|
||||
* Server Started Event<br>
|
||||
* <b>This event can only be called when a SubData connection is made!</b>
|
||||
*
|
||||
* @param server Server Starting
|
||||
*/
|
||||
public SubStartedEvent(SubServer server) {
|
||||
Util.nullpo(server);
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Server Effected
|
||||
*
|
||||
* @return The Server Effected
|
||||
*/
|
||||
public SubServer getServer() { return server; }
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
|
@ -26,7 +25,7 @@ public class SubStopEvent extends Event implements SubEvent, Cancellable {
|
|||
* @param force If it was a Forced Shutdown
|
||||
*/
|
||||
public SubStopEvent(UUID player, SubServer server, boolean force) {
|
||||
Util.nullpo(server, force);
|
||||
if (Util.isNull(server, force)) throw new NullPointerException();
|
||||
this.player = player;
|
||||
this.server = server;
|
||||
this.force = force;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Event;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.SubEvent;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +17,7 @@ public class SubStoppedEvent extends Event implements SubEvent {
|
|||
* @param server Server that Stopped
|
||||
*/
|
||||
public SubStoppedEvent(SubServer server) {
|
||||
Util.nullpo(server);
|
||||
if (Util.isNull(server)) throw new NullPointerException();
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,121 +1,75 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Platform;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.JNA;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.stream.Stream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Executable Handler Class
|
||||
* Executable Variable Class
|
||||
*/
|
||||
public class Executable {
|
||||
private Executable() {}
|
||||
private static final boolean USE_SESSION_TRACKING;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class Executable implements Serializable {
|
||||
private boolean isFile;
|
||||
private File File;
|
||||
private String Str;
|
||||
/**
|
||||
* Format a command to be executed
|
||||
* New Executable
|
||||
*
|
||||
* @param gitbash Git Bash location (optional)
|
||||
* @param exec Executable String
|
||||
* @return Formatted Executable
|
||||
* @param exe Executable String or File Path
|
||||
*/
|
||||
public static String[] parse(String gitbash, String exec) {
|
||||
if (exec.startsWith("java "))
|
||||
exec = '\"' + System.getProperty("java.home") + File.separator + "bin" + File.separator + "java" + '\"' + exec.substring(4);
|
||||
|
||||
String[] cmd;
|
||||
if (Platform.getSystem() == Platform.WINDOWS) {
|
||||
if (gitbash != null && (exec.toLowerCase().startsWith("bash ") || exec.toLowerCase().startsWith("sh ")))
|
||||
exec = '"' + gitbash + ((gitbash.endsWith(File.separator))?"":File.separator) + "bin" + File.separatorChar + "sh.exe\" -lc \"" +
|
||||
exec.replace("\\", "/\\").replace("\"", "\\\"").replace("^", "^^").replace("%", "^%").replace("&", "^&").replace("<", "^<").replace(">", "^>").replace("|", "^|") + '"';
|
||||
cmd = new String[]{"cmd.exe", "/q", "/c", '"'+exec+'"'};
|
||||
} else if (USE_SESSION_TRACKING) {
|
||||
cmd = new String[]{"setsid", "sh", "-lc", exec};
|
||||
public Executable(String exe) {
|
||||
if (Util.isNull(exe)) throw new NullPointerException();
|
||||
if (new File(exe).exists()) {
|
||||
isFile = true;
|
||||
File = new File(exe);
|
||||
Str = exe;
|
||||
} else {
|
||||
cmd = new String[]{"sh", "-lc", exec};
|
||||
isFile = false;
|
||||
File = null;
|
||||
Str = exe;
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static {
|
||||
USE_SESSION_TRACKING = Platform.getSystem() != Platform.WINDOWS && Try.all.get(() -> {
|
||||
Process test = Runtime.getRuntime().exec(new String[]{"setsid", "bash", "-c", "exit 0"});
|
||||
test.waitFor(); // The purpose of this block is to test for the 'setsid' command
|
||||
return test.exitValue() == 0;
|
||||
}, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PID of a currently running process
|
||||
* New Executable
|
||||
*
|
||||
* @param process Process
|
||||
* @return Process ID (null if unknown)
|
||||
* @param path File Path
|
||||
*/
|
||||
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||
public static Long pid(Process process) {
|
||||
if (process.isAlive()) {
|
||||
try { // Java 9 Standard
|
||||
return (long) Process.class.getMethod("pid").invoke(process);
|
||||
} catch (Throwable e) {
|
||||
try { // Java 8 Not-so-standard
|
||||
Object response = Util.reflect(process.getClass().getDeclaredField("pid"), process);
|
||||
public Executable(File path) {
|
||||
if (Util.isNull(path)) throw new NullPointerException();
|
||||
isFile = true;
|
||||
File = path;
|
||||
Str = path.toString();
|
||||
}
|
||||
|
||||
if (response instanceof Number) {
|
||||
return ((Number) response).longValue();
|
||||
} else throw e;
|
||||
} catch (Throwable e2) {
|
||||
if (Platform.getSystem() == Platform.WINDOWS) try {
|
||||
long handle = Util.reflect(process.getClass().getDeclaredField("handle"), process);
|
||||
|
||||
ClassLoader jna = JNA.get();
|
||||
Class<?> pc = jna.loadClass("com.sun.jna.Pointer"),
|
||||
ntc = jna.loadClass("com.sun.jna.platform.win32.WinNT$HANDLE"),
|
||||
k32c = jna.loadClass("com.sun.jna.platform.win32.Kernel32");
|
||||
Object k32 = k32c.getField("INSTANCE").get(null),
|
||||
nt = ntc.getConstructor().newInstance();
|
||||
ntc.getMethod("setPointer", pc).invoke(nt, pc.getMethod("createConstant", long.class).invoke(null, handle));
|
||||
return ((Number) k32c.getMethod("GetProcessId", ntc).invoke(k32, nt)).longValue();
|
||||
} catch (Throwable e3) {
|
||||
// No way to find pid, I suppose.
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
String String;
|
||||
if (isFile) {
|
||||
String = File.toString();
|
||||
} else {
|
||||
String = Str;
|
||||
}
|
||||
return null;
|
||||
return String;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate a currently running process
|
||||
* Check if the Executable String is a file
|
||||
*
|
||||
* @param process Process
|
||||
* @return File Status
|
||||
*/
|
||||
public static void terminate(Process process) {
|
||||
if (process.isAlive()) {
|
||||
Long pid;
|
||||
if (Platform.getSystem() == Platform.WINDOWS) {
|
||||
if ((pid = pid(process)) != null) Try.all.run(() -> Runtime.getRuntime().exec(new String[]{"taskkill.exe", "/T", "/F", "/PID", pid.toString()}).waitFor());
|
||||
} else if (USE_SESSION_TRACKING) {
|
||||
if ((pid = pid(process)) != null) Try.all.run(() -> Runtime.getRuntime().exec(new String[]{"bash", "-c", "kill -9 $(ps -s " + pid + " -o pid=)"}).waitFor());
|
||||
}
|
||||
|
||||
if (process.isAlive() && terminate9(process)) {
|
||||
process.destroyForcibly();
|
||||
}
|
||||
}
|
||||
public boolean isFile() {
|
||||
return isFile;
|
||||
}
|
||||
|
||||
private static boolean terminate9(Object handle) {
|
||||
try { // Attempt iteration over Java 9 ProcessHandle objects
|
||||
Class<?> clazz = handle.getClass();
|
||||
Stream<?> children = (Stream<?>) clazz.getMethod("children").invoke(handle);
|
||||
clazz.getMethod("destroyForcibly").invoke(handle);
|
||||
children.forEach(Executable::terminate9);
|
||||
return false;
|
||||
} catch (Throwable e) {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Get Executable File
|
||||
*
|
||||
* @return File or Null if Executable isn't a file
|
||||
*/
|
||||
public File toFile() {
|
||||
return File;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.External;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.ClientHandler;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
||||
import net.ME1312.SubServers.Bungee.Host.Executable;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Callback;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExAddServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDeleteServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExRemoveServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExReset;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutReset;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
|
@ -29,111 +27,79 @@ import java.util.*;
|
|||
* External Host Class
|
||||
*/
|
||||
public class ExternalHost extends Host implements ClientHandler {
|
||||
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
||||
private HashMap<String, SubServer> servers = new HashMap<String, SubServer>();
|
||||
private String name;
|
||||
boolean available;
|
||||
private boolean enabled;
|
||||
private InetAddress address;
|
||||
private SubCreator creator;
|
||||
private String directory;
|
||||
protected NamedContainer<Integer, Integer> range;
|
||||
protected NamedContainer<Boolean, Client> client;
|
||||
private LinkedList<PacketOut> queue;
|
||||
private boolean clean;
|
||||
SubProxy plugin;
|
||||
protected SubPlugin plugin;
|
||||
|
||||
/**
|
||||
* Creates an External Host
|
||||
*
|
||||
* @param plugin SubServers Internals
|
||||
* @param name The Name of your Host
|
||||
* @param ports The range of ports to auto-select from
|
||||
* @param log Whether apps like SubCreator should log to console (does not apply to servers)
|
||||
* @param enabled If your host is Enabled
|
||||
* @param address The address of your Host
|
||||
* @param directory The runtime directory of your Host
|
||||
* @param gitBash The Git Bash directory
|
||||
* @param plugin Plugin
|
||||
* @param name Name
|
||||
* @param enabled Enabled Status
|
||||
* @param address Address
|
||||
* @param directory Directory
|
||||
* @param gitBash Git Bash Location
|
||||
*/
|
||||
public ExternalHost(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
||||
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
||||
public ExternalHost(SubPlugin plugin, String name, Boolean enabled, InetAddress address, String directory, NamedContainer<Integer, Integer> range, String gitBash) {
|
||||
super(plugin, name, enabled, address, directory, range, gitBash);
|
||||
if (Util.isNull(plugin, name, enabled, address, directory, gitBash)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.available = false;
|
||||
this.enabled = enabled;
|
||||
this.address = address;
|
||||
this.creator = new ExternalSubCreator(this, ports, log, gitBash);
|
||||
this.client = new NamedContainer<Boolean, Client>(false, null);
|
||||
this.creator = new ExternalSubCreator(this, gitBash);
|
||||
this.directory = directory;
|
||||
this.range = range;
|
||||
this.queue = new LinkedList<PacketOut>();
|
||||
this.clean = false;
|
||||
|
||||
subdata.put(0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataClient[] getSubData() {
|
||||
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
||||
DataClient[] channels = new DataClient[keys.length];
|
||||
Arrays.sort(keys);
|
||||
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
||||
return channels;
|
||||
}
|
||||
|
||||
public void setSubData(DataClient client, int channel) {
|
||||
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
||||
if (client == null && channel == 0) available = false;
|
||||
if (client != null || channel == 0) {
|
||||
if (!subdata.containsKey(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
||||
subdata.put(channel, (SubDataClient) client);
|
||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) ((SubDataClient) client).setHandler(this);
|
||||
}
|
||||
} else {
|
||||
subdata.remove(channel);
|
||||
}
|
||||
public Client getSubData() {
|
||||
return client.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubData(DataClient client) {
|
||||
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
||||
public void setSubData(Client client) {
|
||||
this.client = new NamedContainer<Boolean, Client>(false, client);
|
||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
||||
}
|
||||
|
||||
void queue(PacketOut... packet) {
|
||||
for (PacketOut p : packet) if (getSubData()[0] == null || !available) {
|
||||
protected void queue(PacketOut... packet) {
|
||||
for (PacketOut p : packet) if (client.get() == null || client.name() == false) {
|
||||
queue.add(p);
|
||||
} else {
|
||||
((SubDataClient) getSubData()[0]).sendPacket(p);
|
||||
client.get().sendPacket(p);
|
||||
}
|
||||
}
|
||||
private void requeue() {
|
||||
SubDataClient client = (SubDataClient) getSubData()[0];
|
||||
if (!clean) {
|
||||
client.sendPacket(new PacketOutExReset("Prevent Desync"));
|
||||
client.get().sendPacket(new PacketOutReset("Prevent Desync"));
|
||||
clean = true;
|
||||
}
|
||||
HashSet<String> served = new HashSet<String>();
|
||||
LinkedList<PacketOut> queue = this.queue; this.queue = new LinkedList<PacketOut>();
|
||||
PacketOut[] payload = new PacketOut[queue.size()];
|
||||
for (int i = 0; i < payload.length; ++i) {
|
||||
PacketOut packet = queue.get(i);
|
||||
if (packet instanceof PacketExAddServer) served.add(((PacketExAddServer) packet).peek());
|
||||
payload[i] = packet;
|
||||
}
|
||||
for (SubServer server : servers.values()) {
|
||||
if (!served.contains(server.getName())) {
|
||||
client.sendPacket(new PacketExAddServer((ExternalSubServer) server, (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null, data -> {
|
||||
if (data.contains(0x0002)) ((ExternalSubServer) server).started(data.getUUID(0x0002));
|
||||
else if (server.isRunning()) ((ExternalSubServer) server).stopped(false);
|
||||
}));
|
||||
}
|
||||
client.get().sendPacket(new PacketExAddServer(server.getName(), server.isEnabled(), server.getAddress().getPort(), server.isLogging(), server.getPath(), ((ExternalSubServer) server).exec, server.getStopCommand(), (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null));
|
||||
}
|
||||
client.sendPacket(payload);
|
||||
available = true;
|
||||
while (this.queue.size() != 0) {
|
||||
client.sendPacket(this.queue.remove(0));
|
||||
while (queue.size() != 0) {
|
||||
client.get().sendPacket(queue.get(0));
|
||||
queue.remove(0);
|
||||
}
|
||||
client.rename(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return available;
|
||||
return this.client.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,136 +139,40 @@ public class ExternalHost extends Host implements ClientHandler {
|
|||
|
||||
@Override
|
||||
public SubServer getSubServer(String name) {
|
||||
if (Util.isNull(name)) return null;
|
||||
return servers.get(name.toLowerCase());
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
return getSubServers().get(name.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
return ExternalSubServer.construct(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addSubServer(UUID player, SubServer server) throws InvalidServerException {
|
||||
if (server.getHost() != this) throw new IllegalArgumentException("That Server does not belong to this Host!");
|
||||
if (plugin.api.getServers().containsKey(server.getName().toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
||||
public SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, Executable executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
if (plugin.api.getServers().keySet().contains(name.toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
||||
SubServer server = new ExternalSubServer(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
queue(new PacketExAddServer(((ExternalSubServer) server), (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null, data -> {
|
||||
if (data.contains(0x0002)) ((ExternalSubServer) server).started(data.getUUID(0x0002));
|
||||
((ExternalSubServer) server).registered(true);
|
||||
}));
|
||||
servers.put(server.getName().toLowerCase(), server);
|
||||
return true;
|
||||
queue(new PacketExAddServer(name, enabled, port, log, directory, executable, stopcmd, (server.isRunning())?((ExternalSubLogger) server.getLogger()).getExternalAddress():null));
|
||||
servers.put(name.toLowerCase(), server);
|
||||
return server;
|
||||
} else {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||
Util.nullpo(name);
|
||||
ExternalSubServer server = (ExternalSubServer) servers.get(name.toLowerCase());
|
||||
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (forced || !event.isCancelled()) {
|
||||
server.registered(false);
|
||||
if (server.isRunning()) {
|
||||
server.stop();
|
||||
server.waitFor();
|
||||
}
|
||||
|
||||
servers.remove(name.toLowerCase());
|
||||
queue(new PacketExRemoveServer(name.toLowerCase(), data -> {
|
||||
if (data.getInt(0x0001) != 0 && data.getInt(0x0001) != 1) {
|
||||
server.registered(true);
|
||||
servers.put(name.toLowerCase(), server);
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||
Util.nullpo(name);
|
||||
ExternalSubServer s = (ExternalSubServer) servers.get(name.toLowerCase());
|
||||
String server = s.getName();
|
||||
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, s);
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (forced || !event.isCancelled()) {
|
||||
s.registered(false);
|
||||
if (s.isRunning()) {
|
||||
s.stop();
|
||||
s.waitFor();
|
||||
}
|
||||
|
||||
Logger.get("SubServers").info("Saving...");
|
||||
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
|
||||
info.set("Name", server);
|
||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||
try {
|
||||
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||
plugin.servers.get().getMap("Servers").remove(server);
|
||||
plugin.servers.save();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Logger.get("SubServers").info("Moving Files...");
|
||||
queue(new PacketExDeleteServer(server, info, true, data -> {
|
||||
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
|
||||
servers.remove(server.toLowerCase());
|
||||
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||
} else {
|
||||
s.registered(true);
|
||||
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||
Util.nullpo(name);
|
||||
ExternalSubServer s = (ExternalSubServer) servers.get(name.toLowerCase());
|
||||
String server = s.getName();
|
||||
public boolean removeSubServer(UUID player, String name) throws InterruptedException {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (forced || !event.isCancelled()) {
|
||||
s.registered(false);
|
||||
if (s.isRunning()) {
|
||||
s.stop();
|
||||
s.waitFor();
|
||||
if (!event.isCancelled()) {
|
||||
if (getSubServer(server).isRunning()) {
|
||||
getSubServer(server).stop();
|
||||
getSubServer(server).waitFor();
|
||||
}
|
||||
|
||||
Logger.get("SubServers").info("Saving...");
|
||||
ObjectMap<String> info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?plugin.servers.get().getMap("Servers").getMap(server).clone():new ObjectMap<String>();
|
||||
info.set("Name", server);
|
||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||
try {
|
||||
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||
plugin.servers.get().getMap("Servers").remove(server);
|
||||
plugin.servers.save();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Logger.get("SubServers").info("Removing Files...");
|
||||
queue(new PacketExDeleteServer(server, info, false, data -> {
|
||||
if (data.getInt(0x0001) == 0 || data.getInt(0x0001) == 1) {
|
||||
queue(new PacketExRemoveServer(server, data -> {
|
||||
if (data.getInt("r") == 0) {
|
||||
servers.remove(server.toLowerCase());
|
||||
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||
} else {
|
||||
s.registered(true);
|
||||
Logger.get("SubServers").info("Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
|
@ -310,19 +180,96 @@ public class ExternalHost extends Host implements ClientHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean destroy() {
|
||||
if (Try.all.get(() -> Util.reflect(SubProxy.class.getDeclaredField("running"), plugin), true)) {
|
||||
return super.destroy();
|
||||
public boolean forceRemoveSubServer(UUID player, String name) {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (getSubServer(server).isRunning()) {
|
||||
getSubServer(server).terminate();
|
||||
}
|
||||
queue(new PacketExRemoveServer(server, data -> {
|
||||
if (data.getInt("r") == 0) {
|
||||
servers.remove(server.toLowerCase());
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> hinfo = super.forSubData();
|
||||
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
||||
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
||||
hinfo.set("subdata", subdata);
|
||||
return hinfo;
|
||||
public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
if (getSubServer(server).isRunning()) {
|
||||
getSubServer(server).stop();
|
||||
getSubServer(server).waitFor();
|
||||
}
|
||||
|
||||
System.out.println("SubServers > Saving...");
|
||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
||||
info.set("Name", server);
|
||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||
try {
|
||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
||||
plugin.config.get().getSection("Servers").remove(server);
|
||||
plugin.config.save();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("SubServers > Removing Files...");
|
||||
queue(new PacketExDeleteServer(server, info, data -> {
|
||||
if (data.getInt("r") == 0) {
|
||||
servers.remove(server.toLowerCase());
|
||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
||||
} else {
|
||||
System.out.println("SubServers > Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (getSubServer(server).isRunning()) {
|
||||
getSubServer(server).terminate();
|
||||
}
|
||||
|
||||
System.out.println("SubServers > Saving...");
|
||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
||||
info.set("Name", server);
|
||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||
try {
|
||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
||||
plugin.config.get().getSection("Servers").remove(server);
|
||||
plugin.config.save();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.out.println("SubServers > Removing Files...");
|
||||
queue(new PacketExDeleteServer(server, info, data -> {
|
||||
if (data.getInt("r") == 0) {
|
||||
for (String group : getSubServer(server).getGroups()) getSubServer(server).removeGroup(group);
|
||||
servers.remove(server.toLowerCase());
|
||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
||||
} else {
|
||||
System.out.println("SubServers > Couldn't remove " + server + " from memory. See " + getName() + " console for more details");
|
||||
}
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,20 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.External;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Container.Container;
|
||||
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||
import net.ME1312.Galaxi.Library.Container.Value;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubCreatedEvent;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer.StopAction;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Host.*;
|
||||
import net.ME1312.SubServers.Bungee.Host.Internal.InternalSubCreator;
|
||||
import net.ME1312.SubServers.Bungee.Library.*;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLConfig;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExConfigureHost;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExCreateServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDownloadTemplates;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExUploadTemplates;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* External SubCreator Class
|
||||
|
@ -40,84 +22,120 @@ import java.util.function.Consumer;
|
|||
@SuppressWarnings("unchecked")
|
||||
public class ExternalSubCreator extends SubCreator {
|
||||
private HashMap<String, ServerTemplate> templates = new HashMap<String, ServerTemplate>();
|
||||
private HashMap<String, ServerTemplate> templatesR = new HashMap<String, ServerTemplate>();
|
||||
private Boolean enableRT = false;
|
||||
private ExternalHost host;
|
||||
private Range<Integer> ports;
|
||||
private Value<Boolean> log;
|
||||
private String gitBash;
|
||||
private TreeMap<String, Pair<Integer, ExternalSubLogger>> thread;
|
||||
private TreeMap<String, NamedContainer<Integer, ExternalSubLogger>> thread;
|
||||
|
||||
/**
|
||||
* Creates an External SubCreator
|
||||
*
|
||||
* @param host Host
|
||||
* @param ports The range of ports to auto-select from
|
||||
* @param log Whether SubCreator should log to console
|
||||
* @param gitBash The Git Bash directory
|
||||
* @param gitBash Git Bash
|
||||
*/
|
||||
public ExternalSubCreator(ExternalHost host, Range<Integer> ports, boolean log, String gitBash) {
|
||||
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
||||
Util.nullpo(host, ports, log, gitBash);
|
||||
public ExternalSubCreator(ExternalHost host, String gitBash) {
|
||||
if (Util.isNull(host, gitBash)) throw new NullPointerException();
|
||||
this.host = host;
|
||||
this.ports = ports;
|
||||
this.log = new Container<Boolean>(log);
|
||||
this.gitBash = gitBash;
|
||||
this.thread = new TreeMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||
this.thread = new TreeMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
templatesR.clear();
|
||||
if (new File(host.plugin.dir, "SubServers/Templates").exists()) for (File file : new File(host.plugin.dir, "SubServers/Templates").listFiles()) {
|
||||
templates.clear();
|
||||
if (new UniversalFile(host.plugin.dir, "SubServers:Templates").exists()) for (File file : new UniversalFile(host.plugin.dir, "SubServers:Templates").listFiles()) {
|
||||
try {
|
||||
if (file.isDirectory() && !file.getName().endsWith(".x")) {
|
||||
ObjectMap<String> config = (new File(file, "template.yml").exists())? new YAMLConfig(new File(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()) : new ObjectMap<String>();
|
||||
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
|
||||
templatesR.put(file.getName().toLowerCase(), template);
|
||||
if (config.getKeys().contains("Display")) template.setDisplayName(Util.unescapeJavaString(config.getString("Display")));
|
||||
if (file.isDirectory()) {
|
||||
YAMLSection config = (new UniversalFile(file, "template.yml").exists())?new YAMLConfig(new UniversalFile(file, "template.yml")).get().getSection("Template", new YAMLSection()):new YAMLSection();
|
||||
ServerTemplate template = new ServerTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getSection("Build", new YAMLSection()), config.getSection("Settings", new YAMLSection()));
|
||||
templates.put(file.getName().toLowerCase(), template);
|
||||
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.get(host.getName()).severe("Couldn't load template: " + file.getName());
|
||||
System.out.println(host.getName() + "/Creator > Couldn't load template: " + file.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (host.available && !Try.all.get(() -> Util.reflect(SubProxy.class.getDeclaredField("reloading"), host.plugin), false)) {
|
||||
host.queue(new PacketExConfigureHost(host.plugin, host), new PacketExUploadTemplates(host.plugin, () -> {
|
||||
if (enableRT == null || enableRT) host.queue(new PacketExDownloadTemplates(host.plugin, host));
|
||||
}));
|
||||
}
|
||||
if (host.client.name()) host.queue(new PacketExConfigureHost(host.plugin, host));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback) {
|
||||
Util.nullpo(name, template);
|
||||
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().containsKey(name.toLowerCase()) && !SubCreator.isReserved(name) && (version != null || !template.requiresVersion())) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback) {
|
||||
if (Util.isNull(name, template, version)) throw new NullPointerException();
|
||||
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().keySet().contains(name.toLowerCase()) && !SubCreator.isReserved(name)) {
|
||||
StackTraceElement[] origin = new Exception().getStackTrace();
|
||||
|
||||
if (port == null) {
|
||||
Container<Integer> i = new Container<Integer>(ports.lowerEndpoint() - 1);
|
||||
Container<Integer> i = new Container<Integer>(host.range.name() - 1);
|
||||
port = Util.getNew(getAllReservedAddresses(), () -> {
|
||||
do {
|
||||
++i.value;
|
||||
if (i.value > ports.upperEndpoint()) throw new IllegalStateException("There are no more ports available in range: " + ports.toString());
|
||||
} while (!ports.contains(i.value));
|
||||
return new InetSocketAddress(host.getAddress(), i.value);
|
||||
i.set(i.get() + 1);
|
||||
if (i.get() > host.range.get()) throw new IllegalStateException("There are no more ports available between " + host.range.name() + " and " + host.range.get());
|
||||
return new InetSocketAddress(host.getAddress(), i.get());
|
||||
}).getPort();
|
||||
}
|
||||
String prefix = name + File.separator + "Creator";
|
||||
ExternalSubLogger logger = new ExternalSubLogger(this, prefix, log, null);
|
||||
thread.put(name.toLowerCase(), new ContainedPair<>(port, logger));
|
||||
ExternalSubLogger logger = new ExternalSubLogger(this, name + File.separator + "Creator", new Container<Boolean>(host.plugin.config.get().getSection("Settings").getBoolean("Log-Creator")), null);
|
||||
thread.put(name.toLowerCase(), new NamedContainer<>(port, logger));
|
||||
|
||||
final int fport = port;
|
||||
final SubCreateEvent event = new SubCreateEvent(player, host, name, template, version, port);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
logger.start();
|
||||
host.queue(new PacketExCreateServer(player, name, template, version, port, logger.getExternalAddress(), data -> {
|
||||
finish(player, null, name, template, version, fport, prefix, origin, data, callback);
|
||||
host.queue(new PacketExCreateServer(name, template, version, port, logger.getExternalAddress(), data -> {
|
||||
try {
|
||||
if (data.getInt("r") == 0) {
|
||||
System.out.println(name + "/Creator > Saving...");
|
||||
if (host.plugin.exServers.keySet().contains(name.toLowerCase()))
|
||||
host.plugin.exServers.remove(name.toLowerCase());
|
||||
|
||||
YAMLSection server = new YAMLSection();
|
||||
YAMLSection config = new YAMLSection((Map<String, ?>) convert(data.getSection("c").get(), new NamedContainer<>("$player$", (player == null)?"":player.toString()), new NamedContainer<>("$name$", name),
|
||||
new NamedContainer<>("$template$", template.getName()), new NamedContainer<>("$type$", template.getType().toString()), new NamedContainer<>("$version$", version.toString().replace(" ", "@")), new NamedContainer<>("$port$", Integer.toString(fport))));
|
||||
|
||||
server.set("Enabled", true);
|
||||
server.set("Display", "");
|
||||
server.set("Host", host.getName());
|
||||
server.set("Group", new ArrayList<String>());
|
||||
server.set("Port", fport);
|
||||
server.set("Motd", "Some SubServer");
|
||||
server.set("Log", true);
|
||||
server.set("Directory", "." + File.separatorChar + name);
|
||||
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
||||
server.set("Stop-Command", "stop");
|
||||
server.set("Stop-Action", "NONE");
|
||||
server.set("Run-On-Launch", false);
|
||||
server.set("Restricted", false);
|
||||
server.set("Incompatible", new ArrayList<String>());
|
||||
server.set("Hidden", false);
|
||||
server.setAll(config);
|
||||
|
||||
SubServer subserver = host.addSubServer(player, name, server.getBoolean("Enabled"), fport, server.getColoredString("Motd", '&'), server.getBoolean("Log"), server.getRawString("Directory"),
|
||||
new Executable(server.getRawString("Executable")), server.getRawString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
||||
if (server.getString("Display").length() > 0) subserver.setDisplayName(server.getString("Display"));
|
||||
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
||||
SubServer.StopAction action = Util.getDespiteException(() -> SubServer.StopAction.valueOf(server.getRawString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
||||
if (action != null) subserver.setStopAction(action);
|
||||
if (server.contains("Extra")) for (String extra : server.getSection("Extra").getKeys())
|
||||
subserver.addExtra(extra, server.getSection("Extra").getObject(extra));
|
||||
host.plugin.config.get().getSection("Servers").set(name, server);
|
||||
host.plugin.config.save();
|
||||
if (template.getBuildOptions().getBoolean("Run-On-Finish", true))
|
||||
subserver.start();
|
||||
|
||||
if (callback != null) try {
|
||||
callback.run(subserver);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
System.out.println(name + "/Creator > " + data.getString("m"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.stop();
|
||||
this.thread.remove(name.toLowerCase());
|
||||
}));
|
||||
return true;
|
||||
|
@ -126,129 +144,33 @@ public class ExternalSubCreator extends SubCreator {
|
|||
return false;
|
||||
}
|
||||
} else return false;
|
||||
} private <T> void callback(StackTraceElement[] origin, Consumer<T> callback, T value) {
|
||||
if (callback != null) try {
|
||||
callback.accept(value);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback) {
|
||||
Util.nullpo(server);
|
||||
final ServerTemplate ft = (template == null)?server.getTemplate():template;
|
||||
if (host.isAvailable() && host.isEnabled() && host == server.getHost() && server.isAvailable() && !server.isRunning() && ft != null && ft.isEnabled() && ft.canUpdate() && (version != null || !ft.requiresVersion())) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
|
||||
String name = server.getName();
|
||||
String prefix = name + File.separator + "Updater";
|
||||
((ExternalSubServer) server).updating(true);
|
||||
ExternalSubLogger logger = new ExternalSubLogger(this, prefix, log, null);
|
||||
thread.put(name.toLowerCase(), new ContainedPair<>(server.getAddress().getPort(), logger));
|
||||
|
||||
final SubCreateEvent event = new SubCreateEvent(player, server, ft, version);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
logger.start();
|
||||
host.queue(new PacketExCreateServer(player, server, ft, version, logger.getExternalAddress(), data -> {
|
||||
finish(player, server, server.getName(), ft, version, server.getAddress().getPort(), prefix, origin, data, s -> {
|
||||
((ExternalSubServer) server).updating(false);
|
||||
if (callback != null) callback.accept(s != null);
|
||||
});
|
||||
this.thread.remove(name.toLowerCase());
|
||||
}));
|
||||
return true;
|
||||
} else {
|
||||
thread.remove(name.toLowerCase());
|
||||
return false;
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
|
||||
private void finish(UUID player, SubServer update, String name, ServerTemplate template, Version version, int port, String prefix, StackTraceElement[] origin, ObjectMap<Integer> data, Consumer<SubServer> callback) {
|
||||
try {
|
||||
if (data.getInt(0x0001) == 0) {
|
||||
Logger.get(prefix).info("Saving...");
|
||||
SubServer subserver = update;
|
||||
if (update == null || update.getTemplate() != template || template.getBuildOptions().getBoolean("Update-Settings", false)) {
|
||||
if (host.plugin.exServers.containsKey(name.toLowerCase()))
|
||||
host.plugin.exServers.remove(name.toLowerCase());
|
||||
|
||||
ObjectMap<String> server = new ObjectMap<String>();
|
||||
ObjectMap<String> config = new ObjectMap<String>((Map<String, ?>) data.getObject(0x0002));
|
||||
if (config.contains("Directory") && (update != null || !template.getConfigOptions().contains("Directory"))) config.remove("Directory");
|
||||
|
||||
if (update == null) {
|
||||
server.set("Enabled", true);
|
||||
server.set("Display", "");
|
||||
server.set("Host", host.getName());
|
||||
server.set("Template", template.getName());
|
||||
server.set("Group", new ArrayList<String>());
|
||||
server.set("Port", port);
|
||||
server.set("Motd", "Some SubServer");
|
||||
server.set("Log", true);
|
||||
server.set("Directory", "./" + name);
|
||||
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
||||
server.set("Stop-Command", "stop");
|
||||
server.set("Stop-Action", "NONE");
|
||||
server.set("Run-On-Launch", false);
|
||||
server.set("Restricted", false);
|
||||
server.set("Incompatible", new ArrayList<String>());
|
||||
server.set("Hidden", false);
|
||||
} else {
|
||||
server.setAll(host.plugin.servers.get().getMap("Servers").getMap(name, new HashMap<>()));
|
||||
server.set("Template", template.getName());
|
||||
}
|
||||
server.setAll(config);
|
||||
|
||||
if (update != null) Try.all.run(() -> update.getHost().forceRemoveSubServer(name));
|
||||
subserver = host.constructSubServer(name, server.getBoolean("Enabled"), port, ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(server.getString("Motd"))), server.getBoolean("Log"),
|
||||
server.getString("Directory"), server.getString("Executable"), server.getString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
||||
|
||||
if (server.getString("Display").length() > 0) subserver.setDisplayName(Util.unescapeJavaString(server.getString("Display")));
|
||||
subserver.setTemplate(server.getString("Template"));
|
||||
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
||||
SubServer.StopAction action = Try.all.get(() -> SubServer.StopAction.valueOf(server.getString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||
if (action != null) subserver.setStopAction(action);
|
||||
if (server.contains("Extra")) for (String extra : server.getMap("Extra").getKeys())
|
||||
subserver.addExtra(extra, server.getMap("Extra").getObject(extra));
|
||||
|
||||
if ((update != null && host.plugin.servers.get().getMap("Servers").contains(name)) ||
|
||||
!(subserver.getStopAction() == StopAction.REMOVE_SERVER || subserver.getStopAction() == StopAction.RECYCLE_SERVER || subserver.getStopAction() == StopAction.DELETE_SERVER)) {
|
||||
host.plugin.servers.get().getMap("Servers").set(name, server);
|
||||
host.plugin.servers.save();
|
||||
}
|
||||
|
||||
host.addSubServer(subserver);
|
||||
if (update == null && template.getBuildOptions().getBoolean("Run-On-Finish", true)) {
|
||||
while (!subserver.isAvailable() && host.isAvailable()) {
|
||||
Thread.sleep(250);
|
||||
}
|
||||
if (subserver.isAvailable()) {
|
||||
subserver.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, subserver, update != null, true));
|
||||
callback(origin, callback, subserver);
|
||||
} else {
|
||||
Logger.get(prefix).info(data.getString(0x0003));
|
||||
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, update, update != null, false));
|
||||
callback(origin, callback, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
callback(origin, callback, null);
|
||||
} private Object convert(Object value, NamedContainer<String, String>... replacements) {
|
||||
if (value instanceof Map) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.addAll(((Map<String, Object>) value).keySet());
|
||||
for (String key : list) ((Map<String, Object>) value).put(key, convert(((Map<String, Object>) value).get(key), replacements));
|
||||
return value;
|
||||
} else if (value instanceof Collection) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Object val : (Collection<Object>) value) list.add(convert(val, replacements));
|
||||
return list;
|
||||
} else if (value.getClass().isArray()) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (int i = 0; i < ((Object[]) value).length; i++) list.add(convert(((Object[]) value)[i], replacements));
|
||||
return list;
|
||||
} else if (value instanceof String) {
|
||||
return replace((String) value, replacements);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
} private String replace(String string, NamedContainer<String, String>... replacements) {
|
||||
for (NamedContainer<String, String> replacement : replacements) string = string.replace(replacement.name(), replacement.get());
|
||||
return string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void terminate() {
|
||||
HashMap<String, Pair<Integer, ExternalSubLogger>> thread = new HashMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||
HashMap<String, NamedContainer<Integer, ExternalSubLogger>> thread = new HashMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
||||
thread.putAll(this.thread);
|
||||
for (String i : thread.keySet()) {
|
||||
terminate(i);
|
||||
|
@ -257,15 +179,15 @@ public class ExternalSubCreator extends SubCreator {
|
|||
|
||||
@Override
|
||||
public void terminate(String name) {
|
||||
if (this.thread.containsKey(name.toLowerCase())) {
|
||||
((SubDataClient) host.getSubData()[0]).sendPacket(new PacketExCreateServer(name.toLowerCase()));
|
||||
if (this.thread.keySet().contains(name.toLowerCase())) {
|
||||
host.getSubData().sendPacket(new PacketExCreateServer(name.toLowerCase()));
|
||||
thread.remove(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitFor() throws InterruptedException {
|
||||
HashMap<String, Pair<Integer, ExternalSubLogger>> thread = new HashMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||
HashMap<String, NamedContainer<Integer, ExternalSubLogger>> thread = new HashMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
||||
thread.putAll(this.thread);
|
||||
for (String i : thread.keySet()) {
|
||||
waitFor(i);
|
||||
|
@ -274,7 +196,7 @@ public class ExternalSubCreator extends SubCreator {
|
|||
|
||||
@Override
|
||||
public void waitFor(String name) throws InterruptedException {
|
||||
while (this.thread.containsKey(name.toLowerCase()) && host.getSubData()[0] != null) {
|
||||
while (this.thread.keySet().contains(name.toLowerCase()) && host.client.get() != null) {
|
||||
Thread.sleep(250);
|
||||
}
|
||||
}
|
||||
|
@ -284,17 +206,6 @@ public class ExternalSubCreator extends SubCreator {
|
|||
return host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Range getPortRange() {
|
||||
return ports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPortRange(Range<Integer> value) {
|
||||
if (!value.hasLowerBound() || !value.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
||||
ports = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBashDirectory() {
|
||||
return gitBash;
|
||||
|
@ -303,7 +214,7 @@ public class ExternalSubCreator extends SubCreator {
|
|||
@Override
|
||||
public List<SubLogger> getLoggers() {
|
||||
List<SubLogger> loggers = new ArrayList<SubLogger>();
|
||||
HashMap<String, Pair<Integer, ExternalSubLogger>> temp = new HashMap<String, Pair<Integer, ExternalSubLogger>>();
|
||||
HashMap<String, NamedContainer<Integer, ExternalSubLogger>> temp = new HashMap<String, NamedContainer<Integer, ExternalSubLogger>>();
|
||||
temp.putAll(thread);
|
||||
for (String i : temp.keySet()) {
|
||||
loggers.add(getLogger(i));
|
||||
|
@ -313,18 +224,7 @@ public class ExternalSubCreator extends SubCreator {
|
|||
|
||||
@Override
|
||||
public SubLogger getLogger(String name) {
|
||||
return this.thread.get(name.toLowerCase()).value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return log.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogging(boolean value) {
|
||||
Util.nullpo(value);
|
||||
log.value(value);
|
||||
return this.thread.get(name.toLowerCase()).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -335,33 +235,18 @@ public class ExternalSubCreator extends SubCreator {
|
|||
@Override
|
||||
public List<Integer> getReservedPorts() {
|
||||
List<Integer> ports = new ArrayList<Integer>();
|
||||
for (Pair<Integer, ExternalSubLogger> task : thread.values()) ports.add(task.key());
|
||||
for (NamedContainer<Integer, ExternalSubLogger> task : thread.values()) ports.add(task.name());
|
||||
return ports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ServerTemplate> getTemplates() {
|
||||
TreeMap<String, ServerTemplate> map = new TreeMap<String, ServerTemplate>();
|
||||
if (enableRT != null && enableRT) for (Map.Entry<String, ServerTemplate> template : templatesR.entrySet()) {
|
||||
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
|
||||
}
|
||||
for (Map.Entry<String, ServerTemplate> template : templates.entrySet()) {
|
||||
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
|
||||
}
|
||||
return map;
|
||||
return new TreeMap<String, ServerTemplate>(templates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerTemplate getTemplate(String name) {
|
||||
Util.nullpo(name);
|
||||
name = name.toLowerCase();
|
||||
|
||||
ServerTemplate template = templates.getOrDefault(name, null);
|
||||
if (template == null && enableRT != null && enableRT) template = templatesR.getOrDefault(name, null);
|
||||
if (template == null || template.isInternal()) {
|
||||
return null;
|
||||
} else {
|
||||
return template;
|
||||
}
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
return getTemplates().get(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.External;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.Value;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubLogFilter;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketInExLogMessage;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* External Process Logger Class
|
||||
*/
|
||||
public class ExternalSubLogger extends SubLogger {
|
||||
private Object handle;
|
||||
UUID id = null;
|
||||
String name;
|
||||
Value<Boolean> log;
|
||||
private List<SubLogFilter> filters = new CopyOnWriteArrayList<>();
|
||||
File file;
|
||||
protected UUID id = null;
|
||||
protected String name;
|
||||
protected Container<Boolean> log;
|
||||
private List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
private List<LogMessage> messages = new LinkedList<LogMessage>();
|
||||
protected File file;
|
||||
private PrintWriter writer = null;
|
||||
private boolean started = false;
|
||||
|
||||
|
@ -43,7 +43,7 @@ public class ExternalSubLogger extends SubLogger {
|
|||
* @param log Console Logging Status
|
||||
* @param file File to log to (or null for disabled)
|
||||
*/
|
||||
ExternalSubLogger(Object user, String name, Value<Boolean> log, File file) {
|
||||
protected ExternalSubLogger(Object user, String name, Container<Boolean> log, File file) {
|
||||
this.handle = user;
|
||||
this.name = name;
|
||||
this.log = log;
|
||||
|
@ -72,21 +72,44 @@ public class ExternalSubLogger extends SubLogger {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the External Logger Address
|
||||
*
|
||||
* @return External Address
|
||||
*/
|
||||
public UUID getExternalAddress() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a Message
|
||||
*
|
||||
* @param line Message
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void log(int type, String msg) {
|
||||
public void log(String line) {
|
||||
if (started) {
|
||||
String msg = line;
|
||||
Level level;
|
||||
|
||||
// REGEX Formatting
|
||||
String type = "";
|
||||
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
|
||||
while (matcher.find()) {
|
||||
type = matcher.group(3).toUpperCase();
|
||||
}
|
||||
|
||||
msg = msg.substring(msg.length() - msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "").length());
|
||||
|
||||
// Determine LOG LEVEL
|
||||
switch (type) {
|
||||
case 80:
|
||||
level = Level.FINE;
|
||||
break;
|
||||
case 40:
|
||||
case "WARNING":
|
||||
case "WARN":
|
||||
level = Level.WARNING;
|
||||
break;
|
||||
case 30:
|
||||
case 20:
|
||||
case "SEVERE":
|
||||
case "ERROR":
|
||||
case "ERR":
|
||||
level = Level.SEVERE;
|
||||
break;
|
||||
default:
|
||||
|
@ -94,7 +117,7 @@ public class ExternalSubLogger extends SubLogger {
|
|||
}
|
||||
|
||||
// Filter Message
|
||||
boolean allow = (SubAPI.getInstance().getInternals().sudo == getHandler() && SubAPI.getInstance().getInternals().canSudo) || (log.value() && (SubAPI.getInstance().getInternals().sudo == null || !SubAPI.getInstance().getInternals().canSudo));
|
||||
boolean allow = log.get() && (!SubAPI.getInstance().getInternals().canSudo || SubAPI.getInstance().getInternals().sudo == null || SubAPI.getInstance().getInternals().sudo == getHandler());
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters)
|
||||
|
@ -105,40 +128,35 @@ public class ExternalSubLogger extends SubLogger {
|
|||
}
|
||||
|
||||
// Log to CONSOLE
|
||||
if (allow) Logger.get(name).log(level, msg);
|
||||
if (allow) ProxyServer.getInstance().getLogger().log(level, name + " > " + msg);
|
||||
|
||||
// Log to MEMORY
|
||||
messages.add(new LogMessage(level, msg));
|
||||
|
||||
// Log to FILE
|
||||
if (writer != null) {
|
||||
writer.println('[' + new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()) + "] [" + level + "] > " + msg);
|
||||
writer.println(line);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the External Logger Address
|
||||
*
|
||||
* @return External Address
|
||||
*/
|
||||
public UUID getExternalAddress() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFilter(SubLogFilter filter) {
|
||||
Util.nullpo(filter);
|
||||
if (Util.isNull(filter)) throw new NullPointerException();
|
||||
filters.add(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFilter(SubLogFilter filter) {
|
||||
Util.nullpo(filter);
|
||||
Try.all.run(() -> filters.remove(filter));
|
||||
if (Util.isNull(filter)) throw new NullPointerException();
|
||||
filters.remove(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (started) {
|
||||
PacketInExLogMessage.unregister(id);
|
||||
id = null;
|
||||
started = false;
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
|
@ -148,10 +166,11 @@ public class ExternalSubLogger extends SubLogger {
|
|||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
messages.clear();
|
||||
if (writer != null) {
|
||||
PrintWriter writer = this.writer;
|
||||
this.writer = null;
|
||||
int l = (("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2;
|
||||
int l = (int) Math.floor((("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2);
|
||||
String s = "";
|
||||
while (s.length() < l) s += '-';
|
||||
writer.println(s + " LOG END " + s);
|
||||
|
@ -172,6 +191,11 @@ public class ExternalSubLogger extends SubLogger {
|
|||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return log.value();
|
||||
return log.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LogMessage> getMessageHistory() {
|
||||
return new LinkedList<LogMessage>(messages);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,34 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.External;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Container.Container;
|
||||
import net.ME1312.Galaxi.Library.Container.Value;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Event.*;
|
||||
import net.ME1312.SubServers.Bungee.Host.*;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlServer.Action;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExUpdateServer;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.md_5.bungee.BungeeServerInfo;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* External SubServer Class
|
||||
*/
|
||||
public class ExternalSubServer extends SubServerImpl {
|
||||
public class ExternalSubServer extends SubServerContainer {
|
||||
private ExternalHost host;
|
||||
private boolean enabled;
|
||||
private Value<Boolean> log;
|
||||
private Container<Boolean> log;
|
||||
private String dir;
|
||||
String exec;
|
||||
protected Executable exec;
|
||||
private String stopcmd;
|
||||
private StopAction stopaction;
|
||||
private LinkedList<LoggedCommand> history;
|
||||
|
@ -59,34 +52,9 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
* @param restricted Restricted Status
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public static ExternalSubServer construct(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
try {
|
||||
return new ExternalSubServer(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
} catch (NoSuchMethodError e) {
|
||||
return new ExternalSubServer(host, name, enabled, (Integer) port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Super Method 2 (newest)
|
||||
* @see #construct(ExternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||
*/
|
||||
protected ExternalSubServer(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
public ExternalSubServer(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, Executable executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(host, name, port, motd, hidden, restricted);
|
||||
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Super Method 1 (oldest)
|
||||
* @see #construct(ExternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||
*/
|
||||
protected ExternalSubServer(ExternalHost host, String name, boolean enabled, Integer port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(host, name, port, motd, hidden, restricted);
|
||||
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
private void init(ExternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
Util.nullpo(host, name, enabled, port, motd, log, stopcmd, hidden, restricted);
|
||||
if (Util.isNull(host, name, enabled, port, motd, log, stopcmd, hidden, restricted)) throw new NullPointerException();
|
||||
this.host = host;
|
||||
this.enabled = enabled;
|
||||
this.log = new Container<Boolean>(log);
|
||||
|
@ -101,46 +69,24 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
this.lock = false;
|
||||
}
|
||||
|
||||
void registered(boolean value) {
|
||||
registered = value;
|
||||
}
|
||||
|
||||
void updating(boolean value) {
|
||||
updating = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start(UUID player) {
|
||||
if (!lock && isAvailable() && isEnabled() && !running && getCurrentIncompatibilities().size() == 0) {
|
||||
if (!lock && isEnabled() && !running && getCurrentIncompatibilities().size() == 0) {
|
||||
lock = true;
|
||||
SubStartEvent event = new SubStartEvent(player, this);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
lock = false;
|
||||
if (!event.isCancelled()) {
|
||||
Logger.get("SubServers").info("Now starting " + getName());
|
||||
started(null);
|
||||
host.queue(new PacketExControlServer(this, Action.START, logger.getExternalAddress().toString()));
|
||||
System.out.println("SubServers > Now starting " + getName());
|
||||
running = true;
|
||||
logger.start();
|
||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.START, logger.getExternalAddress().toString()));
|
||||
return true;
|
||||
} else {
|
||||
lock = false;
|
||||
return false;
|
||||
}
|
||||
} else return false;
|
||||
} else return false;
|
||||
}
|
||||
void started(UUID address) {
|
||||
if (!running) {
|
||||
stopping = false;
|
||||
started = false;
|
||||
running = true;
|
||||
lock = false;
|
||||
logger.start();
|
||||
if (address != null) {
|
||||
if (address != logger.getExternalAddress()) host.queue(new PacketExControlServer(this, Action.SET_LOGGING_ADDRESS, logger.getExternalAddress().toString()));
|
||||
host.plugin.getPluginManager().callEvent(new SubStartEvent(null, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
private void falsestart() {
|
||||
Logger.get("SubServers").info("Couldn't start " + getName() + " - See the " + host.getName() + " console for more details");
|
||||
System.out.println("SubServers > Couldn't start " + getName() + " - See the " + host.getName() + " console for more details");
|
||||
running = false;
|
||||
logger.stop();
|
||||
}
|
||||
|
@ -152,33 +98,28 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
history.add(new LoggedCommand(player, stopcmd));
|
||||
host.queue(new PacketExControlServer(this, Action.STOP));
|
||||
stopping = true;
|
||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.STOP));
|
||||
return true;
|
||||
} else return false;
|
||||
} else return false;
|
||||
}
|
||||
void stopped(Boolean allowrestart) {
|
||||
logger.stop();
|
||||
history.clear();
|
||||
started = false;
|
||||
running = false;
|
||||
stopping = false;
|
||||
private void stopped(Boolean allowrestart) {
|
||||
SubStoppedEvent event = new SubStoppedEvent(this);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
Logger.get("SubServers").info(getName() + " has stopped");
|
||||
System.out.println("SubServers > " + getName() + " has stopped");
|
||||
logger.stop();
|
||||
history.clear();
|
||||
running = false;
|
||||
|
||||
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.RECYCLE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
||||
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
||||
try {
|
||||
if (stopaction == StopAction.RECYCLE_SERVER) {
|
||||
host.recycleSubServer(getName());
|
||||
} else if (stopaction == StopAction.DELETE_SERVER) {
|
||||
if (stopaction == StopAction.DELETE_SERVER) {
|
||||
host.deleteSubServer(getName());
|
||||
} else {
|
||||
try {
|
||||
if (host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||
host.plugin.servers.save();
|
||||
if (host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
host.plugin.config.get().getSection("Servers").remove(getName());
|
||||
host.plugin.config.save();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -197,7 +138,7 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, "SubServers.Bungee::External_Server_Restart_Handler(" + getName() + ')').start();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,8 +149,7 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
SubStopEvent event = new SubStopEvent(player, this, true);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
host.queue(new PacketExControlServer(this, Action.TERMINATE));
|
||||
stopping = true;
|
||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.TERMINATE));
|
||||
return true;
|
||||
} else return false;
|
||||
} else return false;
|
||||
|
@ -217,317 +157,306 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public boolean command(UUID player, String command) {
|
||||
Util.nullpo(command);
|
||||
if (Util.isNull(command)) throw new NullPointerException();
|
||||
if (running) {
|
||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command, null);
|
||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) {
|
||||
if (!event.isCancelled()) {
|
||||
history.add(new LoggedCommand(player, event.getCommand()));
|
||||
if (event.getCommand().equalsIgnoreCase(stopcmd)) {
|
||||
host.queue(new PacketExControlServer(this, Action.STOP));
|
||||
stopping = true;
|
||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.STOP));
|
||||
} else {
|
||||
host.queue(new PacketExControlServer(this, Action.COMMAND, event.getCommand()));
|
||||
host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.COMMAND, event.getCommand()));
|
||||
}
|
||||
return true;
|
||||
} else return false;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
@Override
|
||||
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||
if (isAvailable()) {
|
||||
int c = 0;
|
||||
boolean state = isRunning();
|
||||
SubServer forward = null;
|
||||
ObjectMap<String> pending = edit.clone();
|
||||
for (String key : edit.getKeys()) {
|
||||
pending.remove(key);
|
||||
ObjectMapValue value = edit.get(key);
|
||||
boolean allowed = true;
|
||||
if (perma) {
|
||||
SubEditServerEvent event = new SubEditServerEvent(player, this, new ContainedPair<String, ObjectMapValue>(key, value));
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
allowed = !event.isCancelled();
|
||||
}
|
||||
if (allowed) {
|
||||
try {
|
||||
switch (key.toLowerCase()) {
|
||||
case "name":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = host.constructSubServer(value.asString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
ObjectMap<String> config = this.host.plugin.servers.get().getMap("Servers").getMap(getName());
|
||||
this.host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||
this.host.plugin.servers.get().getMap("Servers").set(server.getName(), config);
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "display":
|
||||
if (value.isString()) {
|
||||
setDisplayName(value.asString());
|
||||
logger.name = getDisplayName();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
if (getName().equals(getDisplayName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).remove("Display");
|
||||
} else {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Display", getDisplayName());
|
||||
}
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "enabled":
|
||||
if (value.isBoolean()) {
|
||||
if (enabled != value.asBoolean()) host.queue(new PacketExControlServer(this, Action.SET_ENABLED, (Boolean) value.asBoolean()));
|
||||
enabled = value.asBoolean();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Enabled", isEnabled());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "group":
|
||||
if (value.isList()) {
|
||||
Util.reflect(ServerImpl.class.getDeclaredField("groups"), this, value.asStringList());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Group", value.asStringList());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "host":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = this.host.plugin.api.getHost(value.asString()).constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Host", server.getHost().getName());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "template":
|
||||
if (value.isString()) {
|
||||
setTemplate(value.asString());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Template", value.asString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "port":
|
||||
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = host.constructSubServer(getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Port", server.getAddress().getPort());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "motd":
|
||||
if (value.isString()) {
|
||||
setMotd(ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(value.asString())));
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Motd", value.asString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "log":
|
||||
if (value.isBoolean()) {
|
||||
if (log.value() != value.asBoolean()) host.queue(new PacketExControlServer(this, Action.SET_LOGGING, (Boolean) value.asBoolean()));
|
||||
log.value(value.asBoolean());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Log", isLogging());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "dir":
|
||||
case "directory":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = host.constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), value.asString(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Directory", server.getPath());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "exec":
|
||||
case "executable":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = host.constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), value.asString(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Executable", value.asString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "state":
|
||||
if (value.isBoolean()) {
|
||||
state = value.asBoolean();
|
||||
}
|
||||
break;
|
||||
case "stop-cmd":
|
||||
case "stop-command":
|
||||
if (value.isString()) {
|
||||
if (!stopcmd.equals(value.asString())) host.queue(new PacketExControlServer(this, Action.SET_STOP_COMMAND, value.asString()));
|
||||
stopcmd = value.asString();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Command", getStopCommand());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "stop-action":
|
||||
if (value.isString()) {
|
||||
StopAction action = Try.all.get(() -> StopAction.valueOf(value.asString().toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||
if (action != null) {
|
||||
stopaction = action;
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Action", getStopAction().toString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "auto-run":
|
||||
case "run-on-launch":
|
||||
if (value.isBoolean()) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Run-On-Launch", value.asBoolean());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "incompatible":
|
||||
if (value.isList()) {
|
||||
for (SubServer oserver : getIncompatibilities()) toggleCompatibility(oserver);
|
||||
for (String oname : (List<String>) value.asStringList()) {
|
||||
SubServer oserver = host.plugin.api.getSubServer(oname);
|
||||
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
||||
}
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Incompatible", value.asStringList());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "restricted":
|
||||
if (value.isBoolean()) {
|
||||
setRestricted(value.asBoolean());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Restricted", isRestricted());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "hidden":
|
||||
if (value.isBoolean()) {
|
||||
setHidden(value.asBoolean());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Hidden", isHidden());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "whitelist":
|
||||
if (value.isList()) {
|
||||
Util.reflect(ServerImpl.class.getDeclaredField("whitelist"), this, value.asUUIDList());
|
||||
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_SET, value.asUUIDList()));
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (forward != null) {
|
||||
forward.setStopAction(getStopAction());
|
||||
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
||||
List<String> groups = new ArrayList<String>();
|
||||
forward.setTemplate(getTemplate());
|
||||
groups.addAll(getGroups());
|
||||
for (String group : groups) {
|
||||
removeGroup(group);
|
||||
forward.addGroup(group);
|
||||
}
|
||||
for (SubServer server : getIncompatibilities()) {
|
||||
toggleCompatibility(server);
|
||||
forward.toggleCompatibility(server);
|
||||
}
|
||||
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
||||
|
||||
if (state) pending.set("state", true);
|
||||
c += (perma)?forward.permaEdit(player, pending):forward.edit(player, pending);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public int edit(UUID player, YAMLSection edit) {
|
||||
int c = 0;
|
||||
boolean state = isRunning();
|
||||
SubServer forward = null;
|
||||
YAMLSection pending = edit.clone();
|
||||
for (String key : edit.getKeys()) {
|
||||
pending.remove(key);
|
||||
YAMLValue value = edit.get(key);
|
||||
SubEditServerEvent event = new SubEditServerEvent(player, this, new NamedContainer<String, YAMLValue>(key, value), true);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
try {
|
||||
switch (key) {
|
||||
case "name":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = host.addSubServer(player, value.asRawString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
YAMLSection config = this.host.plugin.config.get().getSection("Servers").getSection(getName());
|
||||
this.host.plugin.config.get().getSection("Servers").remove(getName());
|
||||
this.host.plugin.config.get().getSection("Servers").set(server.getName(), config);
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "display":
|
||||
if (value.isString()) {
|
||||
Field f = ServerContainer.class.getDeclaredField("nick");
|
||||
f.setAccessible(true);
|
||||
if (value == null || value.asString().length() == 0 || getName().equals(value)) {
|
||||
f.set(this, null);
|
||||
} else {
|
||||
f.set(this, value.asString());
|
||||
}
|
||||
f.setAccessible(false);
|
||||
logger.name = getDisplayName();
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
if (getName().equals(getDisplayName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).remove("Display");
|
||||
} else {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Display", getDisplayName());
|
||||
}
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "enabled":
|
||||
if (value.isBoolean()) {
|
||||
if (enabled != value.asBoolean()) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_ENABLED, (Boolean) value.asBoolean()));
|
||||
enabled = value.asBoolean();
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Enabled", isEnabled());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "group":
|
||||
if (value.isList()) {
|
||||
Field f = ServerContainer.class.getDeclaredField("groups");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asStringList());
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Group", value.asStringList());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "host":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = this.host.plugin.api.getHost(value.asRawString()).addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Host", server.getHost().getName());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "port":
|
||||
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Port", server.getAddress().getPort());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "motd":
|
||||
if (value.isString()) {
|
||||
Field f = BungeeServerInfo.class.getDeclaredField("motd");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asColoredString('&'));
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Motd", value.asString());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "log":
|
||||
if (value.isBoolean()) {
|
||||
if (log.get() != value.asBoolean()) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_LOGGING, (Boolean) value.asBoolean()));
|
||||
log.set(value.asBoolean());
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Log", isLogging());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "dir":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), value.asRawString(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Directory", server.getPath());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "exec":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
waitFor(() -> host.getSubServer(getName()), null);
|
||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), new Executable(value.asRawString()), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Executable", value.asRawString());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "state":
|
||||
if (value.isBoolean()) {
|
||||
state = value.asBoolean();
|
||||
}
|
||||
break;
|
||||
case "stop-cmd":
|
||||
if (value.isString()) {
|
||||
if (!stopcmd.equals(value)) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_STOP_COMMAND, value.asRawString()));
|
||||
stopcmd = value.asRawString();
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Command", getStopCommand());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "stop-action":
|
||||
if (value.isString()) {
|
||||
StopAction action = Util.getDespiteException(() -> StopAction.valueOf(value.asRawString().toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
||||
if (action != null) {
|
||||
stopaction = action;
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Action", getStopAction().toString());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "auto-run":
|
||||
if (value.isBoolean()) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Run-On-Launch", value.asBoolean());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "incompatible":
|
||||
if (value.isList()) {
|
||||
for (String oname : value.asStringList()) {
|
||||
SubServer oserver = host.plugin.api.getSubServer(oname);
|
||||
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
||||
}
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Incompatible", value.asStringList());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "restricted":
|
||||
if (value.isBoolean()) {
|
||||
Field f = BungeeServerInfo.class.getDeclaredField("restricted");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asBoolean());
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Restricted", isRestricted());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "hidden":
|
||||
if (value.isBoolean()) {
|
||||
Field f = ServerContainer.class.getDeclaredField("hidden");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asBoolean());
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Hidden", isHidden());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (forward != null) {
|
||||
forward.setStopAction(getStopAction());
|
||||
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
||||
List<String> groups = new ArrayList<String>();
|
||||
groups.addAll(getGroups());
|
||||
for (String group : groups) {
|
||||
removeGroup(group);
|
||||
forward.addGroup(group);
|
||||
}
|
||||
for (SubServer server : getIncompatibilities()) {
|
||||
toggleCompatibility(server);
|
||||
forward.toggleCompatibility(server);
|
||||
}
|
||||
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
||||
|
||||
if (state) pending.set("state", true);
|
||||
c += forward.edit(player, pending);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (!isRunning() && forward == null && state) start(player);
|
||||
return c;
|
||||
} else return -1;
|
||||
} private <V> void waitFor(Supplier<V> method, V value) throws InterruptedException {
|
||||
while (method.get() != value) {
|
||||
}
|
||||
if (!isRunning() && forward == null && state) start(player);
|
||||
return c;
|
||||
} private <V> void waitFor(Util.ReturnRunnable<V> method, V value) throws InterruptedException {
|
||||
while (method.run() != value) {
|
||||
Thread.sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitFor() throws InterruptedException {
|
||||
while (running && host.getSubData()[0] != null) {
|
||||
while (running && host.client.get() != null) {
|
||||
Thread.sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return running || lock;
|
||||
return running;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayName(String value) {
|
||||
super.setDisplayName(value);
|
||||
logger.name = getDisplayName();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("display", value), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -537,26 +466,28 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled && host.isEnabled();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
Util.nullpo(value);
|
||||
if (enabled != value) host.queue(new PacketExControlServer(this, Action.SET_ENABLED, (Boolean) value));
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("enabled", value), false));
|
||||
if (enabled != value) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_ENABLED, (Boolean) value));
|
||||
enabled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return log.value();
|
||||
return log.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogging(boolean value) {
|
||||
Util.nullpo(value);
|
||||
if (log.value() != value) host.queue(new PacketExControlServer(this, Action.SET_LOGGING, (Boolean) value));
|
||||
log.value(value);
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("log", value), false));
|
||||
if (log.get() != value) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_LOGGING, (Boolean) value));
|
||||
log.set(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -575,7 +506,7 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getExecutable() {
|
||||
public Executable getExecutable() {
|
||||
return exec;
|
||||
}
|
||||
|
||||
|
@ -586,8 +517,9 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public void setStopCommand(String value) {
|
||||
Util.nullpo(value);
|
||||
if (!stopcmd.equals(value)) host.queue(new PacketExControlServer(this, Action.SET_STOP_COMMAND, value));
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-cmd", value), false));
|
||||
if (!stopcmd.equals(value)) host.queue(new PacketExUpdateServer(this, PacketExUpdateServer.UpdateType.SET_STOP_COMMAND, value));
|
||||
stopcmd = value;
|
||||
}
|
||||
|
||||
|
@ -598,7 +530,8 @@ public class ExternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public void setStopAction(StopAction action) {
|
||||
Util.nullpo(action);
|
||||
if (Util.isNull(action)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-action", action), false));
|
||||
stopaction = action;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.ExtraDataHandler;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidHostException;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.ME1312.SubServers.Bungee.Library.ExtraDataHandler;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Host Layout Class
|
||||
*/
|
||||
public abstract class Host implements ExtraDataHandler<String> {
|
||||
private final ObjectMap<String> extra = new ObjectMap<String>();
|
||||
public abstract class Host implements ExtraDataHandler {
|
||||
private YAMLSection extra = new YAMLSection();
|
||||
private final String signature;
|
||||
private String nick = null;
|
||||
|
||||
|
@ -32,20 +29,16 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
*
|
||||
* @param plugin SubServers Internals
|
||||
* @param name The Name of your Host
|
||||
* @param ports The range of ports to auto-select from
|
||||
* @param log Whether apps like SubCreator should log to console (does not apply to servers)
|
||||
* @param enabled If your host is Enabled
|
||||
* @param address The address of your Host
|
||||
* @param directory The runtime directory of your Host
|
||||
* @param range The range of ports to auto-select from
|
||||
* @param gitBash The Git Bash directory
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public Host(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
||||
public Host(SubPlugin plugin, String name, Boolean enabled, InetAddress address, String directory, NamedContainer<Integer, Integer> range, String gitBash) {
|
||||
if (name.contains(" ")) throw new InvalidHostException("Host names cannot have spaces: " + name);
|
||||
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new InvalidHostException("Port range is not bound");
|
||||
Util.nullpo(plugin, name, enabled, ports, log, address, directory, gitBash);
|
||||
signature = plugin.api.signAnonymousObject();
|
||||
SubAPI.getInstance().getInternals().subprotocol.whitelist(address.getHostAddress());
|
||||
SubDataServer.allowConnection(address.getHostAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,32 +107,6 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get players on servers provided by this host
|
||||
*
|
||||
* @return Local Player Collection
|
||||
*/
|
||||
public Collection<ProxiedPlayer> getPlayers() {
|
||||
LinkedList<ProxiedPlayer> players = new LinkedList<ProxiedPlayer>();
|
||||
for (SubServer server : getSubServers().values()) {
|
||||
players.addAll(server.getPlayers());
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get players on servers provided by this host across all known proxies
|
||||
*
|
||||
* @return Remote Player Collection
|
||||
*/
|
||||
public Collection<RemotePlayer> getRemotePlayers() {
|
||||
LinkedList<RemotePlayer> players = new LinkedList<RemotePlayer>();
|
||||
for (SubServer server : getSubServers().values()) {
|
||||
players.addAll(server.getRemotePlayers());
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Servers Specified
|
||||
*
|
||||
|
@ -264,44 +231,6 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
*/
|
||||
public abstract SubServer getSubServer(String name);
|
||||
|
||||
/**
|
||||
* Constructs a SubServer (but doesn't add it to the server manager)
|
||||
*
|
||||
* @param name Name of Server
|
||||
* @param enabled Enabled Status
|
||||
* @param port Port Number
|
||||
* @param motd Motd of the Server
|
||||
* @param log Logging Status
|
||||
* @param directory Directory
|
||||
* @param executable Executable String
|
||||
* @param stopcmd Command to Stop the Server
|
||||
* @param hidden if the server should be hidden from players
|
||||
* @param restricted Players will need a permission to join if true
|
||||
* @return The SubServer
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public abstract SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException;
|
||||
|
||||
/**
|
||||
* Adds a SubServer
|
||||
*
|
||||
* @param name Name of Server
|
||||
* @param enabled Enabled Status
|
||||
* @param port Port Number
|
||||
* @param motd Motd of the Server
|
||||
* @param log Logging Status
|
||||
* @param directory Directory
|
||||
* @param executable Executable String
|
||||
* @param stopcmd Command to Stop the Server
|
||||
* @param hidden if the server should be hidden from players
|
||||
* @param restricted Players will need a permission to join if true
|
||||
* @return The SubServer
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public SubServer addSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
return addSubServer(null, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a SubServer
|
||||
*
|
||||
|
@ -312,37 +241,35 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
* @param motd Motd of the Server
|
||||
* @param log Logging Status
|
||||
* @param directory Directory
|
||||
* @param executable Executable String
|
||||
* @param executable Executable
|
||||
* @param stopcmd Command to Stop the Server
|
||||
* @param hidden if the server should be hidden from players
|
||||
* @param restricted Players will need a permission to join if true
|
||||
* @return The SubServer
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
SubServer server = constructSubServer(name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
return (addSubServer(player, server))?server:null;
|
||||
}
|
||||
public abstract SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, Executable executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException;
|
||||
|
||||
/**
|
||||
* Adds a SubServer
|
||||
*
|
||||
* @param server SubServer to add
|
||||
* @return Success status
|
||||
* @param name Name of Server
|
||||
* @param enabled Enabled Status
|
||||
* @param port Port Number
|
||||
* @param motd Motd of the Server
|
||||
* @param log Logging Status
|
||||
* @param directory Directory
|
||||
* @param executable Executable
|
||||
* @param stopcmd Command to Stop the Server
|
||||
* @param hidden if the server should be hidden from players
|
||||
* @param restricted Players will need a permission to join if true
|
||||
* @return The SubServer
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public boolean addSubServer(SubServer server) throws InvalidServerException {
|
||||
return addSubServer(null, server);
|
||||
public SubServer addSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, Executable executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
return addSubServer(null, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a SubServer
|
||||
*
|
||||
* @param player Player who added
|
||||
* @param server SubServer to add
|
||||
* @return Success status
|
||||
*/
|
||||
public abstract boolean addSubServer(UUID player, SubServer server) throws InvalidServerException;
|
||||
|
||||
/**
|
||||
* Removes a SubServer
|
||||
*
|
||||
|
@ -352,7 +279,7 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
*/
|
||||
public boolean removeSubServer(String name) throws InterruptedException {
|
||||
return removeSubServer(null, name);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a SubServer
|
||||
|
@ -362,26 +289,12 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
* @throws InterruptedException
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean removeSubServer(UUID player, String name) throws InterruptedException {
|
||||
return removeSubServer(player, name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a SubServer
|
||||
*
|
||||
* @param player Player Removing
|
||||
* @param name SubServer Name
|
||||
* @param forced Forces the Removal
|
||||
* @throws InterruptedException
|
||||
* @return Success Status
|
||||
*/
|
||||
protected abstract boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException;
|
||||
public abstract boolean removeSubServer(UUID player, String name) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Forces the Removal of a SubServer
|
||||
*
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean forceRemoveSubServer(String name) throws InterruptedException {
|
||||
return forceRemoveSubServer(null, name);
|
||||
|
@ -392,66 +305,11 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
*
|
||||
* @param player Player Removing
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException {
|
||||
return removeSubServer(player, name, true);
|
||||
}
|
||||
public abstract boolean forceRemoveSubServer(UUID player, String name) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||
*
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean recycleSubServer(String name) throws InterruptedException {
|
||||
return recycleSubServer(null, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean recycleSubServer(UUID player, String name) throws InterruptedException {
|
||||
return recycleSubServer(player, name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @param forced Forces the Deletion
|
||||
* @return Success Status
|
||||
*/
|
||||
protected abstract boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Forces the Deletion of a SubServer (will move to 'Recently Deleted')
|
||||
*
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean forceRecycleSubServer(String name) throws InterruptedException {
|
||||
return forceRecycleSubServer(null, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the Deletion of a SubServer (will move to 'Recently Deleted')
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean forceRecycleSubServer(UUID player, String name) throws InterruptedException {
|
||||
return recycleSubServer(player, name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a SubServer
|
||||
* Delete a SubServer
|
||||
*
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
|
@ -461,34 +319,22 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Deletes a SubServer
|
||||
* Delete a SubServer
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
|
||||
return deleteSubServer(player, name, false);
|
||||
}
|
||||
public abstract boolean deleteSubServer(UUID player, String name) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Deletes a SubServer
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @param forced Forces the Deletion
|
||||
* @return Success Status
|
||||
*/
|
||||
protected abstract boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Forces the Deletion of a SubServer
|
||||
* Forced the Deletion of a SubServer
|
||||
*
|
||||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean forceDeleteSubServer(String name) throws InterruptedException {
|
||||
return forceDeleteSubServer(null, name);
|
||||
return deleteSubServer(null, name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -498,32 +344,7 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
* @param name SubServer Name
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
|
||||
return deleteSubServer(player, name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this Host object
|
||||
*
|
||||
* @return Success Status
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean destroy() {
|
||||
try {
|
||||
Map.Entry<String, SubServer>[] subservers = getSubServers().entrySet().toArray(new Map.Entry[0]);
|
||||
|
||||
for (Map.Entry<String, SubServer> entry : subservers) {
|
||||
if (entry.getValue().isRunning()) Logger.get("SubServers").info("Stopping " + entry.getValue().getName());
|
||||
forceRemoveSubServer(entry.getKey());
|
||||
}
|
||||
getCreator().terminate();
|
||||
getCreator().waitFor();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public abstract boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Get the Signature of this Object
|
||||
|
@ -534,42 +355,39 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Host && signature.equals(((Host) obj).signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtra(String handle, Object value) {
|
||||
Util.nullpo(handle, value);
|
||||
if (Util.isNull(handle, value)) throw new NullPointerException();
|
||||
extra.set(handle, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
return extra.getKeys().contains(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapValue getExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
public YAMLValue getExtra(String handle) {
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
return extra.get(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> getExtra() {
|
||||
public YAMLSection getExtra() {
|
||||
return extra.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
extra.remove(handle);
|
||||
}
|
||||
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> hinfo = new ObjectMap<String>();
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public String toString() {
|
||||
YAMLSection hinfo = new YAMLSection();
|
||||
hinfo.set("type", "Host");
|
||||
hinfo.set("name", getName());
|
||||
hinfo.set("display", getDisplayName());
|
||||
|
@ -578,20 +396,21 @@ public abstract class Host implements ExtraDataHandler<String> {
|
|||
hinfo.set("address", getAddress().getHostAddress());
|
||||
hinfo.set("dir", getPath());
|
||||
|
||||
ObjectMap<String> cinfo = new ObjectMap<String>();
|
||||
ObjectMap<String> templates = new ObjectMap<String>();
|
||||
YAMLSection cinfo = new YAMLSection();
|
||||
YAMLSection templates = new YAMLSection();
|
||||
for (SubCreator.ServerTemplate template : getCreator().getTemplates().values())
|
||||
templates.set(template.getName(), template.forSubData());
|
||||
templates.set(template.getName(), new YAMLSection(new Gson().fromJson(template.toString(), Map.class)));
|
||||
cinfo.set("templates", templates);
|
||||
hinfo.set("creator", cinfo);
|
||||
|
||||
ObjectMap<String> servers = new ObjectMap<String>();
|
||||
YAMLSection servers = new YAMLSection();
|
||||
for (SubServer server : getSubServers().values()) {
|
||||
servers.set(server.getName(), server.forSubData());
|
||||
servers.set(server.getName(), new YAMLSection(new Gson().fromJson(server.toString(), Map.class)));
|
||||
}
|
||||
hinfo.set("servers", servers);
|
||||
if (this instanceof ClientHandler && ((ClientHandler) this).getSubData() != null) hinfo.set("subdata", ((ClientHandler) this).getSubData().getAddress().toString());
|
||||
hinfo.set("signature", signature);
|
||||
hinfo.set("extra", getExtra());
|
||||
return hinfo;
|
||||
return hinfo.toJSON();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Config.YAMLSection;
|
||||
import net.ME1312.Galaxi.Library.Directories;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import com.dosse.upnp.UPnP;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubAddServerEvent;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubRemoveServerEvent;
|
||||
import net.ME1312.SubServers.Bungee.Host.Executable;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import com.dosse.upnp.UPnP;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.UniversalFile;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
@ -33,29 +30,30 @@ public class InternalHost extends Host {
|
|||
private InetAddress address;
|
||||
private SubCreator creator;
|
||||
private String directory;
|
||||
SubProxy plugin;
|
||||
protected NamedContainer<Integer, Integer> range;
|
||||
protected SubPlugin plugin;
|
||||
|
||||
/**
|
||||
* Creates an Internal Host
|
||||
*
|
||||
* @param plugin SubServers Internals
|
||||
* @param name The Name of your Host
|
||||
* @param ports The range of ports to auto-select from
|
||||
* @param log Whether apps like SubCreator should log to console (does not apply to servers)
|
||||
* @param enabled If your host is Enabled
|
||||
* @param address The address of your Host
|
||||
* @param directory The runtime directory of your Host
|
||||
* @param gitBash The Git Bash directory
|
||||
* @param plugin Plugin
|
||||
* @param name Name
|
||||
* @param enabled Enabled Status
|
||||
* @param address Address
|
||||
* @param directory Directory
|
||||
* @param gitBash Git Bash Location
|
||||
*/
|
||||
public InternalHost(SubProxy plugin, String name, boolean enabled, Range<Integer> ports, boolean log, InetAddress address, String directory, String gitBash) {
|
||||
super(plugin, name, enabled, ports, log, address, directory, gitBash);
|
||||
public InternalHost(SubPlugin plugin, String name, Boolean enabled, InetAddress address, String directory, NamedContainer<Integer, Integer> range, String gitBash) {
|
||||
super(plugin, name, enabled, address, directory, range, gitBash);
|
||||
if (!DRM_ALLOW) throw new IllegalStateException("SubServers' hosting capabilities have been disabled by your provider");
|
||||
if (Util.isNull(plugin, name, enabled, address, directory, gitBash)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.enabled = enabled;
|
||||
this.address = address;
|
||||
this.creator = new InternalSubCreator(this, ports, log, gitBash);
|
||||
this.creator = new InternalSubCreator(this, gitBash);
|
||||
this.directory = directory;
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -95,156 +93,144 @@ public class InternalHost extends Host {
|
|||
|
||||
@Override
|
||||
public SubServer getSubServer(String name) {
|
||||
if (Util.isNull(name)) return null;
|
||||
return servers.get(name.toLowerCase());
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
return getSubServers().get(name.toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubServer constructSubServer(String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
return InternalSubServer.construct(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addSubServer(UUID player, SubServer server) throws InvalidServerException {
|
||||
if (server.getHost() != this) throw new IllegalArgumentException("That Server does not belong to this Host!");
|
||||
if (plugin.api.getServers().containsKey(server.getName().toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
||||
public SubServer addSubServer(UUID player, String name, boolean enabled, int port, String motd, boolean log, String directory, Executable executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
if (plugin.api.getServers().keySet().contains(name.toLowerCase())) throw new InvalidServerException("A Server already exists with this name!");
|
||||
SubServer server = new InternalSubServer(this, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
SubAddServerEvent event = new SubAddServerEvent(player, this, server);
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
((InternalSubServer) server).registered(true);
|
||||
servers.put(server.getName().toLowerCase(), server);
|
||||
if (UPnP.isUPnPAvailable() && plugin.config.get().getMap("Settings").getMap("UPnP", new ObjectMap<String>()).getBoolean("Forward-Servers", false)) UPnP.openPortTCP(server.getAddress().getPort());
|
||||
return true;
|
||||
servers.put(name.toLowerCase(), server);
|
||||
if (UPnP.isUPnPAvailable() && plugin.config.get().getSection("Settings").getSection("UPnP", new YAMLSection()).getBoolean("Forward-Servers", false)) UPnP.openPortTCP(port);
|
||||
return server;
|
||||
} else {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||
Util.nullpo(name);
|
||||
InternalSubServer server = (InternalSubServer) servers.get(name.toLowerCase());
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, server);
|
||||
public boolean removeSubServer(UUID player, String name) throws InterruptedException {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (forced || !event.isCancelled()) {
|
||||
server.registered(false);
|
||||
if (server.isRunning()) {
|
||||
server.stop();
|
||||
server.waitFor();
|
||||
if (!event.isCancelled()) {
|
||||
if (getSubServer(server).isRunning()) {
|
||||
getSubServer(server).stop();
|
||||
getSubServer(server).waitFor();
|
||||
}
|
||||
servers.remove(name.toLowerCase());
|
||||
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(server.getAddress().getPort()))
|
||||
UPnP.closePortTCP(server.getAddress().getPort());
|
||||
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(getSubServer(server).getAddress().getPort()))
|
||||
UPnP.closePortTCP(getSubServer(server).getAddress().getPort());
|
||||
servers.remove(server.toLowerCase());
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean recycleSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||
return recycleSubServer(player, name, forced, true);
|
||||
public boolean forceRemoveSubServer(UUID player, String name) {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
SubRemoveServerEvent event = new SubRemoveServerEvent(player, this, getSubServer(server));
|
||||
plugin.getPluginManager().callEvent(event);
|
||||
if (getSubServer(server).isRunning()) {
|
||||
getSubServer(server).terminate();
|
||||
}
|
||||
if (UPnP.isUPnPAvailable() && UPnP.isMappedTCP(getSubServer(server).getAddress().getPort()))
|
||||
UPnP.closePortTCP(getSubServer(server).getAddress().getPort());
|
||||
servers.remove(server.toLowerCase());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a SubServer (will move to 'Recently Deleted')
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @param forced Forces the Deletion
|
||||
* @param multithreading Uses Multithreading for I/O
|
||||
* @return Success Status
|
||||
*/
|
||||
protected boolean recycleSubServer(UUID player, String name, boolean forced, boolean multithreading) throws InterruptedException {
|
||||
Util.nullpo(name);
|
||||
@Override
|
||||
public boolean deleteSubServer(UUID player, String name) throws InterruptedException {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
|
||||
if (removeSubServer(player, server, forced)) {
|
||||
Runnable method = () -> {
|
||||
File to = new File(plugin.dir, "SubServers/Recently Deleted/" + server.toLowerCase());
|
||||
if (removeSubServer(player, server)) {
|
||||
new Thread(() -> {
|
||||
UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase());
|
||||
try {
|
||||
if (from.exists()) {
|
||||
Logger.get("SubServers").info("Moving Files...");
|
||||
System.out.println("SubServers > Removing Files...");
|
||||
if (to.exists()) {
|
||||
if (to.isDirectory()) Directories.delete(to);
|
||||
if (to.isDirectory()) Util.deleteDirectory(to);
|
||||
else to.delete();
|
||||
}
|
||||
to.mkdirs();
|
||||
Directories.copy(from, to);
|
||||
Directories.delete(from);
|
||||
Util.copyDirectory(from, to);
|
||||
Util.deleteDirectory(from);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Logger.get("SubServers").info("Saving...");
|
||||
YAMLSection info = (plugin.servers.get().getMap("Servers").getKeys().contains(server))?new YAMLSection(plugin.servers.get().getMap("Servers").getMap(server).get()):new YAMLSection();
|
||||
System.out.println("SubServers > Saving...");
|
||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
||||
info.set("Name", server);
|
||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||
try {
|
||||
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||
plugin.servers.get().getMap("Servers").remove(server);
|
||||
plugin.servers.save();
|
||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
||||
plugin.config.get().getSection("Servers").remove(server);
|
||||
plugin.config.save();
|
||||
}
|
||||
if (!to.exists()) to.mkdirs();
|
||||
FileWriter writer = new FileWriter(new File(to, "info.json"), false);
|
||||
writer.write(new Gson().toJson(info.get()));
|
||||
FileWriter writer = new FileWriter(new File(to, "info.json"));
|
||||
writer.write(info.toJSON());
|
||||
writer.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||
};
|
||||
|
||||
if (multithreading) {
|
||||
new Thread(method, "SubServers.Bungee::Internal_Server_Recycler(" + name + ')').start();
|
||||
} else method.run();
|
||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
||||
}).start();
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean deleteSubServer(UUID player, String name, boolean forced) throws InterruptedException {
|
||||
return deleteSubServer(player, name, forced, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a SubServer
|
||||
*
|
||||
* @param player Player Deleting
|
||||
* @param name SubServer Name
|
||||
* @param forced Forces the Deletion
|
||||
* @param multithreading Uses Multithreading for I/O
|
||||
* @return Success Status
|
||||
*/
|
||||
protected boolean deleteSubServer(UUID player, String name, boolean forced, boolean multithreading) throws InterruptedException {
|
||||
Util.nullpo(name);
|
||||
public boolean forceDeleteSubServer(UUID player, String name) throws InterruptedException {
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
String server = servers.get(name.toLowerCase()).getName();
|
||||
File from = new File(getPath(), servers.get(server.toLowerCase()).getPath());
|
||||
if (removeSubServer(player, server, forced)) {
|
||||
Runnable method = () -> {
|
||||
if (forceRemoveSubServer(player, server)) {
|
||||
new Thread(() -> {
|
||||
UniversalFile to = new UniversalFile(plugin.dir, "SubServers:Recently Deleted:" + server.toLowerCase());
|
||||
try {
|
||||
if (from.exists()) {
|
||||
Logger.get("SubServers").info("Removing Files...");
|
||||
Directories.delete(from);
|
||||
System.out.println("SubServers > Removing Files...");
|
||||
if (to.exists()) {
|
||||
if (to.isDirectory()) Util.deleteDirectory(to);
|
||||
else to.delete();
|
||||
}
|
||||
to.mkdirs();
|
||||
Util.copyDirectory(from, to);
|
||||
Util.deleteDirectory(from);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Logger.get("SubServers").info("Saving...");
|
||||
System.out.println("SubServers > Saving...");
|
||||
YAMLSection info = (plugin.config.get().getSection("Servers").getKeys().contains(server))?plugin.config.get().getSection("Servers").getSection(server).clone():new YAMLSection();
|
||||
info.set("Name", server);
|
||||
info.set("Timestamp", Calendar.getInstance().getTime().getTime());
|
||||
try {
|
||||
if (plugin.servers.get().getMap("Servers").getKeys().contains(server)) {
|
||||
plugin.servers.get().getMap("Servers").remove(server);
|
||||
plugin.servers.save();
|
||||
if (plugin.config.get().getSection("Servers").getKeys().contains(server)) {
|
||||
plugin.config.get().getSection("Servers").remove(server);
|
||||
plugin.config.save();
|
||||
}
|
||||
if (!to.exists()) to.mkdirs();
|
||||
FileWriter writer = new FileWriter(new File(to, "info.json"), false);
|
||||
writer.write(info.toJSON());
|
||||
writer.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Logger.get("SubServers").info("Deleted SubServer: " + server);
|
||||
};
|
||||
|
||||
if (multithreading) {
|
||||
new Thread(method, "SubServers.Bungee::Internal_Server_Deletion(" + name + ')').start();
|
||||
} else method.run();
|
||||
System.out.println("SubServers > Deleted SubServer: " + server);
|
||||
}).start();
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
|
|
@ -1,48 +1,30 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
|
||||
import net.ME1312.Galaxi.Library.Config.YAMLSection;
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Container.Container;
|
||||
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||
import net.ME1312.Galaxi.Library.Container.Value;
|
||||
import net.ME1312.Galaxi.Library.Directories;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubCreatedEvent;
|
||||
import net.ME1312.SubServers.Bungee.Host.*;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer.StopAction;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.*;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLConfig;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.SubCreatorException;
|
||||
import net.ME1312.SubServers.Bungee.Library.ReplacementScanner;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.gson.Gson;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.LinkOption;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
/**
|
||||
* Internal SubCreator Class
|
||||
*/
|
||||
|
@ -50,166 +32,114 @@ import static java.util.logging.Level.WARNING;
|
|||
public class InternalSubCreator extends SubCreator {
|
||||
private HashMap<String, ServerTemplate> templates = new HashMap<String, ServerTemplate>();
|
||||
private InternalHost host;
|
||||
private Range<Integer> ports;
|
||||
private Value<Boolean> log;
|
||||
private String gitBash;
|
||||
private TreeMap<String, CreatorTask> thread;
|
||||
|
||||
private class CreatorTask extends Thread {
|
||||
private final UUID player;
|
||||
private final SubServer update;
|
||||
private final String name;
|
||||
private final ServerTemplate template;
|
||||
private final Version version;
|
||||
private final int port;
|
||||
private final String prefix;
|
||||
private final InternalSubLogger log;
|
||||
private final LinkedList<String> replace;
|
||||
private final HashMap<String, String> replacements;
|
||||
private final Consumer<SubServer> callback;
|
||||
private boolean install;
|
||||
private final Callback<SubServer> callback;
|
||||
private Process process;
|
||||
|
||||
private CreatorTask(UUID player, String name, ServerTemplate template, Version version, int port, Consumer<SubServer> callback) {
|
||||
super("SubServers.Bungee::Internal_SubCreator_Process_Handler(" + name + ')');
|
||||
private CreatorTask(UUID player, String name, ServerTemplate template, Version version, int port, Callback<SubServer> callback) {
|
||||
this.player = player;
|
||||
this.update = null;
|
||||
this.name = name;
|
||||
this.template = template;
|
||||
this.version = version;
|
||||
this.port = port;
|
||||
this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Creator", InternalSubCreator.this.log, null);
|
||||
(this.replace = new LinkedList<String>()).add("/server.properties");
|
||||
this.replacements = new HashMap<String, String>();
|
||||
this.log = new InternalSubLogger(null, this, name + File.separator + "Creator", new Container<Boolean>(false), null);
|
||||
this.callback = callback;
|
||||
this.install = true;
|
||||
}
|
||||
|
||||
private CreatorTask(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<SubServer> callback) {
|
||||
super("SubServers.Bungee::Internal_SubCreator_Process_Handler(" + server.getName() + ')');
|
||||
this.player = player;
|
||||
this.update = server;
|
||||
this.name = server.getName();
|
||||
this.template = template;
|
||||
this.version = version;
|
||||
this.port = server.getAddress().getPort();
|
||||
this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Updater", InternalSubCreator.this.log, null);
|
||||
(this.replace = new LinkedList<String>()).add("/server.properties");
|
||||
this.replacements = new HashMap<String, String>();
|
||||
this.callback = callback;
|
||||
this.install = true;
|
||||
}
|
||||
|
||||
private ObjectMap<String> build(File dir, ServerTemplate template, List<ServerTemplate> history, List<ServerTemplate> stack) throws SubCreatorException {
|
||||
ObjectMap<String> server = new ObjectMap<String>();
|
||||
private YAMLSection build(File dir, ServerTemplate template, List<ServerTemplate> history) throws SubCreatorException {
|
||||
YAMLSection server = new YAMLSection();
|
||||
Version version = this.version;
|
||||
HashMap<String, String> var = new HashMap<String, String>();
|
||||
boolean error = false;
|
||||
if (stack.contains(template)) throw new IllegalStateException("Infinite template import loop detected");
|
||||
stack.add(template);
|
||||
if (history.contains(template)) throw new IllegalStateException("Template Import loop detected");
|
||||
history.add(template);
|
||||
for (String other : template.getBuildOptions().getStringList("Import", new ArrayList<String>())) {
|
||||
if (templates.containsKey(other.toLowerCase())) {
|
||||
final ServerTemplate ot = templates.get(other.toLowerCase());
|
||||
if (ot.isEnabled()) {
|
||||
if (version != null || !ot.requiresVersion()) {
|
||||
if (update == null || ot.canUpdate()) {
|
||||
if (!history.contains(ot)) {
|
||||
server.setAll(this.build(dir, ot, history, stack));
|
||||
} else {
|
||||
log.log(WARNING, "Skipping template that is already loaded: " + other);
|
||||
}
|
||||
} else {
|
||||
log.log(WARNING, "Skipping template that cannot be run in update mode: " + other);
|
||||
}
|
||||
if (templates.keySet().contains(other.toLowerCase())) {
|
||||
if (templates.get(other.toLowerCase()).isEnabled()) {
|
||||
YAMLSection config = build(dir, templates.get(other.toLowerCase()), history);
|
||||
if (config == null) {
|
||||
throw new SubCreatorException();
|
||||
} else {
|
||||
log.log(WARNING, "Skipping template that requires extra versioning information: " + other);
|
||||
server.setAll(config);
|
||||
}
|
||||
} else {
|
||||
log.log(WARNING, "Skipping disabled template: " + other);
|
||||
System.out.println(name + File.separator + "Creator > Skipping disabled template: " + other);
|
||||
}
|
||||
} else {
|
||||
log.log(WARNING, "Skipping missing template: " + other);
|
||||
System.out.println(name + File.separator + "Creator > Skipping missing template: " + other);
|
||||
}
|
||||
}
|
||||
history.add(template);
|
||||
stack.remove(template);
|
||||
server.setAll(template.getConfigOptions());
|
||||
try {
|
||||
log.log(INFO, "Loading" + ((template.isDynamic())?" Dynamic":"") + " Template: " + template.getDisplayName());
|
||||
updateDirectory(template.getDirectory(), dir, template.getBuildOptions().getBoolean("Update-Files", false));
|
||||
System.out.println(name + File.separator + "Creator > Loading Template: " + template.getDisplayName());
|
||||
Util.copyDirectory(template.getDirectory(), dir);
|
||||
if (template.getType() == ServerType.FORGE || template.getType() == ServerType.SPONGE) {
|
||||
System.out.println(name + File.separator + "Creator > Searching Versions...");
|
||||
YAMLSection spversionmanifest = new YAMLSection(new Gson().fromJson("{\"versions\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://dl-api.spongepowered.org/v1/org.spongepowered/sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "/downloads?type=stable&minecraft=" + version).openStream(), Charset.forName("UTF-8")))) + '}', Map.class));
|
||||
|
||||
install = template.getBuildOptions().getBoolean("Install-Client", install);
|
||||
replace.addAll(template.getBuildOptions().getStringList("Replace", Collections.emptyList()));
|
||||
for (ObjectMapValue<String> replacement : template.getBuildOptions().getMap("Replacements", new ObjectMap<>()).getValues()) if (!replacement.isNull()) {
|
||||
replacements.put(replacement.getHandle().toLowerCase().replace('-', '_').replace(' ', '_'), replacement.asString());
|
||||
}
|
||||
|
||||
var.putAll(replacements);
|
||||
var.put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
|
||||
var.put("mode", (update == null)? "CREATE" : ((CreatorTask.this.template.equals(update.getTemplate()))?"UPDATE":"SWITCH"));
|
||||
if (player != null) var.put("player", player.toString().toUpperCase());
|
||||
else var.remove("player");
|
||||
var.put("name", name);
|
||||
var.put("host", host.getName());
|
||||
var.put("template", template.getName());
|
||||
var.put("type", template.getType().toString().toUpperCase());
|
||||
if (version != null) var.put("version", version.toString());
|
||||
else var.remove("version");
|
||||
var.put("address", host.getAddress().getHostAddress());
|
||||
var.put("port", Integer.toString(port));
|
||||
switch (template.getType()) {
|
||||
case SPONGE:
|
||||
case FORGE:
|
||||
if (version != null) {
|
||||
log.log(INFO, "Searching Versions...");
|
||||
ObjectMap<String> spversionmanifest = new ObjectMap<String>(new Gson().fromJson("{\"versions\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://dl-api.spongepowered.org/v1/org.spongepowered/sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "/downloads?type=stable&minecraft=" + version).openStream(), Charset.forName("UTF-8")))) + '}', Map.class));
|
||||
|
||||
ObjectMap<String> spprofile = null;
|
||||
Version spversion = null;
|
||||
for (ObjectMap<String> profile : spversionmanifest.getMapList("versions")) {
|
||||
if (profile.getMap("dependencies").getString("minecraft").equalsIgnoreCase(version.toString()) && (spversion == null || new Version(profile.getString("version")).compareTo(spversion) >= 0)) {
|
||||
spprofile = profile;
|
||||
spversion = new Version(profile.getString("version"));
|
||||
}
|
||||
}
|
||||
if (spversion == null)
|
||||
throw new InvalidServerException("Cannot find Sponge version for Minecraft " + version.toString());
|
||||
log.log(INFO, "Found \"sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "-" + spversion.toString() + '"');
|
||||
|
||||
if (template.getType() == ServerType.FORGE) {
|
||||
Version mcfversion = new Version(((spprofile.getMap("dependencies").getString("forge").contains("-"))?"":spprofile.getMap("dependencies").getString("minecraft") + '-') + spprofile.getMap("dependencies").getString("forge"));
|
||||
log.log(INFO, "Found \"forge-" + mcfversion.toString() + '"');
|
||||
|
||||
var.put("mcf_version", mcfversion.toString());
|
||||
}
|
||||
var.put("sp_version", spversion.toString());
|
||||
YAMLSection spprofile = null;
|
||||
Version spversion = null;
|
||||
for (YAMLSection profile : spversionmanifest.getSectionList("versions")) {
|
||||
if (profile.getSection("dependencies").getRawString("minecraft").equalsIgnoreCase(version.toString()) && (spversion == null || new Version(profile.getRawString("version")).compareTo(spversion) >= 0)) {
|
||||
spprofile = profile;
|
||||
spversion = new Version(profile.getRawString("version"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (spversion == null)
|
||||
throw new InvalidServerException("Cannot find Sponge version for Minecraft " + version.toString());
|
||||
System.out.println(name + File.separator + "Creator > Found \"sponge" + ((template.getType() == ServerType.FORGE)?"forge":"vanilla") + "-" + spversion.toString() + '"');
|
||||
|
||||
if (template.getType() == ServerType.FORGE) {
|
||||
Version mcfversion = new Version(spprofile.getSection("dependencies").getRawString("minecraft") + '-' + spprofile.getSection("dependencies").getRawString("forge"));
|
||||
System.out.println(name + File.separator + "Creator > Found \"forge-" + mcfversion.toString() + '"');
|
||||
|
||||
version = new Version(mcfversion.toString() + " " + spversion.toString());
|
||||
} else version = new Version(spversion.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (template.getBuildOptions().contains("Executable")) {
|
||||
File cache = null;
|
||||
if (template.getBuildOptions().contains("Shell-Location")) {
|
||||
String gitBash = InternalSubCreator.this.gitBash + ((InternalSubCreator.this.gitBash.endsWith(File.separator)) ? "" : File.separator) + "bin" + File.separatorChar + "bash.exe";
|
||||
File cache;
|
||||
if (template.getBuildOptions().getBoolean("Use-Cache", true)) {
|
||||
cache = new File(host.plugin.dir, "SubServers/Cache/Templates/" + template.getName());
|
||||
cache = new UniversalFile(host.plugin.dir, "SubServers:Cache:Templates:" + template.getName());
|
||||
cache.mkdirs();
|
||||
var.put("cache", cache.getAbsolutePath());
|
||||
} else {
|
||||
cache = null;
|
||||
}
|
||||
if (!(System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) && template.getBuildOptions().contains("Permission")) {
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("chmod " + template.getBuildOptions().getRawString("Permission") + ' ' + template.getBuildOptions().getRawString("Shell-Location"), null, dir);
|
||||
Thread.sleep(500);
|
||||
if (process.exitValue() != 0) {
|
||||
System.out.println(name + File.separator + "Creator > Couldn't set " + template.getBuildOptions().getRawString("Permission") + " permissions to " + template.getBuildOptions().getRawString("Shell-Location"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(name + File.separator + "Creator > Couldn't set " + template.getBuildOptions().getRawString("Permission") + " permissions to " + template.getBuildOptions().getRawString("Shell-Location"));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
var.put("source", dir.getAbsolutePath());
|
||||
|
||||
try {
|
||||
log.log(INFO, "Launching Build Script...");
|
||||
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(gitBash, template.getBuildOptions().getString("Executable"))).directory(dir);
|
||||
pb.environment().putAll(var);
|
||||
log.file = new File(dir, "SubCreator-" + template.getName() + ((version != null)?"-"+version.toString():"") + ".log");
|
||||
process = pb.start();
|
||||
System.out.println(name + File.separator + "Creator > Launching " + template.getBuildOptions().getRawString("Shell-Location"));
|
||||
process = Runtime.getRuntime().exec((System.getProperty("os.name").toLowerCase().indexOf("win") >= 0)?"cmd.exe /c \"\"" + gitBash + "\" --login -i -c \"bash " + template.getBuildOptions().getRawString("Shell-Location") + ' ' + version.toString() + ' ' + ((cache == null)?':':cache.toString().replace('\\', '/').replace(" ", "\\ ")) + "\"\"":("bash " + template.getBuildOptions().getRawString("Shell-Location") + ' ' + version.toString() + ' ' + ((cache == null)?':':cache.toString().replace(" ", "\\ "))), null, dir);
|
||||
log.log.set(host.plugin.config.get().getSection("Settings").getBoolean("Log-Creator"));
|
||||
log.file = new File(dir, "SubCreator-" + template.getName() + "-" + version.toString().replace(" ", "@") + ".log");
|
||||
log.process = process;
|
||||
log.start();
|
||||
|
||||
process.waitFor();
|
||||
Thread.sleep(250);
|
||||
Thread.sleep(500);
|
||||
|
||||
if (process.exitValue() != 0) error = true;
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -221,132 +151,104 @@ public class InternalSubCreator extends SubCreator {
|
|||
|
||||
if (cache != null) {
|
||||
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
||||
cache = new File(host.plugin.dir, "SubServers/Cache/Templates");
|
||||
cache = new UniversalFile(host.plugin.dir, "SubServers:Cache:Templates");
|
||||
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
||||
cache = new File(host.plugin.dir, "SubServers/Cache");
|
||||
cache = new UniversalFile(host.plugin.dir, "SubServers:Cache");
|
||||
if (cache.isDirectory() && cache.listFiles().length == 0) cache.delete();
|
||||
}
|
||||
}
|
||||
|
||||
new File(dir, "template.yml").delete();
|
||||
new UniversalFile(dir, "template.yml").delete();
|
||||
if (error) throw new SubCreatorException();
|
||||
return server;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Runnable declaration = () -> {
|
||||
replacements.put("player", (player == null)?"":player.toString());
|
||||
replacements.put("name", name);
|
||||
replacements.put("host", host.getName());
|
||||
replacements.put("template", template.getName());
|
||||
replacements.put("type", template.getType().toString());
|
||||
replacements.put("version", (version != null)?version.toString():"");
|
||||
replacements.put("address", host.getAddress().getHostAddress());
|
||||
replacements.put("port", Integer.toString(port));
|
||||
};
|
||||
|
||||
declaration.run();
|
||||
File dir = (update != null)?new File(update.getFullPath()):new File(host.getPath(),
|
||||
(template.getConfigOptions().contains("Directory"))?new ReplacementScanner(replacements).replace(template.getConfigOptions().getString("Directory")).toString():name);
|
||||
|
||||
ObjectMap<String> server = new ObjectMap<String>();
|
||||
ObjectMap<String> config;
|
||||
UniversalFile dir = new UniversalFile(new File(host.getPath()), name);
|
||||
dir.mkdirs();
|
||||
YAMLSection server = new YAMLSection();
|
||||
YAMLSection config;
|
||||
try {
|
||||
log.init();
|
||||
config = build(dir, template, new LinkedList<>(), new LinkedList<>());
|
||||
config = build(dir, template, new LinkedList<>());
|
||||
generateProperties(dir, port);
|
||||
generateClient(dir, template.getType(), name);
|
||||
} catch (SubCreatorException e) {
|
||||
config = null;
|
||||
} catch (Exception e) {
|
||||
config = null;
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
log.destroy();
|
||||
}
|
||||
|
||||
declaration.run();
|
||||
ReplacementScanner replacements = new ReplacementScanner(this.replacements);
|
||||
if (config != null) {
|
||||
try {
|
||||
if (install) generateClient(dir, template.getType(), name);
|
||||
replacements.replace(dir, replace.toArray(new String[0]));
|
||||
} catch (Exception e) {
|
||||
config = null;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (config != null) {
|
||||
try {
|
||||
Logger.get(prefix).info("Saving...");
|
||||
SubServer subserver = update;
|
||||
if (update == null || update.getTemplate() != template || template.getBuildOptions().getBoolean("Update-Settings", false)) {
|
||||
if (host.plugin.exServers.containsKey(name.toLowerCase()))
|
||||
host.plugin.exServers.remove(name.toLowerCase());
|
||||
System.out.println(name + File.separator + "Creator > Saving...");
|
||||
if (host.plugin.exServers.keySet().contains(name.toLowerCase()))
|
||||
host.plugin.exServers.remove(name.toLowerCase());
|
||||
|
||||
config = new ObjectMap<String>((Map<String, ?>) replacements.replace(config.get()));
|
||||
if (config.contains("Directory") && (update != null || !template.getConfigOptions().contains("Directory"))) config.remove("Directory");
|
||||
config = new YAMLSection((Map<String, ?>) convert(config.get(), new NamedContainer<>("$player$", (player == null)?"":player.toString()), new NamedContainer<>("$name$", name), new NamedContainer<>("$template$", template.getName()),
|
||||
new NamedContainer<>("$type$", template.getType().toString()), new NamedContainer<>("$version$", version.toString().replace(" ", "@")), new NamedContainer<>("$port$", Integer.toString(port))));
|
||||
|
||||
if (update == null) {
|
||||
server.set("Enabled", true);
|
||||
server.set("Display", "");
|
||||
server.set("Host", host.getName());
|
||||
server.set("Template", template.getName());
|
||||
server.set("Group", new ArrayList<String>());
|
||||
server.set("Port", port);
|
||||
server.set("Motd", "Some SubServer");
|
||||
server.set("Log", true);
|
||||
server.set("Directory", "./" + name);
|
||||
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
||||
server.set("Stop-Command", "stop");
|
||||
server.set("Stop-Action", "NONE");
|
||||
server.set("Run-On-Launch", false);
|
||||
server.set("Restricted", false);
|
||||
server.set("Incompatible", new ArrayList<String>());
|
||||
server.set("Hidden", false);
|
||||
} else {
|
||||
server.setAll(host.plugin.servers.get().getMap("Servers").getMap(name, new HashMap<>()));
|
||||
server.set("Template", template.getName());
|
||||
}
|
||||
server.setAll(config);
|
||||
server.set("Enabled", true);
|
||||
server.set("Display", "");
|
||||
server.set("Host", host.getName());
|
||||
server.set("Group", new ArrayList<String>());
|
||||
server.set("Port", port);
|
||||
server.set("Motd", "Some SubServer");
|
||||
server.set("Log", true);
|
||||
server.set("Directory", "." + File.separatorChar + name);
|
||||
server.set("Executable", "java -Xmx1024M -jar " + template.getType().toString() + ".jar");
|
||||
server.set("Stop-Command", "stop");
|
||||
server.set("Stop-Action", "NONE");
|
||||
server.set("Run-On-Launch", false);
|
||||
server.set("Restricted", false);
|
||||
server.set("Incompatible", new ArrayList<String>());
|
||||
server.set("Hidden", false);
|
||||
server.setAll(config);
|
||||
|
||||
if (update != null) Try.all.run(() -> update.getHost().forceRemoveSubServer(name));
|
||||
subserver = host.constructSubServer(name, server.getBoolean("Enabled"), port, ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(server.getString("Motd"))), server.getBoolean("Log"),
|
||||
server.getString("Directory"), server.getString("Executable"), server.getString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
||||
|
||||
if (server.getString("Display").length() > 0) subserver.setDisplayName(Util.unescapeJavaString(server.getString("Display")));
|
||||
subserver.setTemplate(server.getString("Template"));
|
||||
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
||||
SubServer.StopAction action = Try.all.get(() -> SubServer.StopAction.valueOf(server.getString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||
if (action != null) subserver.setStopAction(action);
|
||||
if (server.contains("Extra")) for (String extra : server.getMap("Extra").getKeys())
|
||||
subserver.addExtra(extra, server.getMap("Extra").getObject(extra));
|
||||
|
||||
if ((update != null && host.plugin.servers.get().getMap("Servers").contains(name)) ||
|
||||
!(subserver.getStopAction() == StopAction.REMOVE_SERVER || subserver.getStopAction() == StopAction.RECYCLE_SERVER || subserver.getStopAction() == StopAction.DELETE_SERVER)) {
|
||||
host.plugin.servers.get().getMap("Servers").set(name, server);
|
||||
host.plugin.servers.save();
|
||||
}
|
||||
|
||||
host.addSubServer(subserver);
|
||||
if (update == null && template.getBuildOptions().getBoolean("Run-On-Finish", true))
|
||||
subserver.start();
|
||||
}
|
||||
SubServer subserver = host.addSubServer(player, name, server.getBoolean("Enabled"), port, server.getColoredString("Motd", '&'), server.getBoolean("Log"), server.getRawString("Directory"),
|
||||
new Executable(server.getRawString("Executable")), server.getRawString("Stop-Command"), server.getBoolean("Hidden"), server.getBoolean("Restricted"));
|
||||
if (server.getString("Display").length() > 0) subserver.setDisplayName(server.getString("Display"));
|
||||
for (String group : server.getStringList("Group")) subserver.addGroup(group);
|
||||
SubServer.StopAction action = Util.getDespiteException(() -> SubServer.StopAction.valueOf(server.getRawString("Stop-Action").toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
||||
if (action != null) subserver.setStopAction(action);
|
||||
if (server.contains("Extra")) for (String extra : server.getSection("Extra").getKeys())
|
||||
subserver.addExtra(extra, server.getSection("Extra").getObject(extra));
|
||||
host.plugin.config.get().getSection("Servers").set(name, server);
|
||||
host.plugin.config.save();
|
||||
if (template.getBuildOptions().getBoolean("Run-On-Finish", true))
|
||||
subserver.start();
|
||||
|
||||
InternalSubCreator.this.thread.remove(name.toLowerCase());
|
||||
|
||||
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, subserver, update != null, true));
|
||||
callback.accept(subserver);
|
||||
callback.run(subserver);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, update, update != null, false));
|
||||
callback.accept(null);
|
||||
}
|
||||
} else {
|
||||
Logger.get(prefix).info("Couldn't build the server jar. Check the SubCreator logs for more detail.");
|
||||
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, port, update, update != null, false));
|
||||
callback.accept(null);
|
||||
System.out.println(name + File.separator + "Creator > Couldn't build the server jar. Check the SubCreator logs for more detail.");
|
||||
}
|
||||
InternalSubCreator.this.thread.remove(name.toLowerCase());
|
||||
} private Object convert(Object value, NamedContainer<String, String>... replacements) {
|
||||
if (value instanceof Map) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.addAll(((Map<String, Object>) value).keySet());
|
||||
for (String key : list) ((Map<String, Object>) value).put(key, convert(((Map<String, Object>) value).get(key), replacements));
|
||||
return value;
|
||||
} else if (value instanceof Collection) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Object val : (Collection<Object>) value) list.add(convert(val, replacements));
|
||||
return list;
|
||||
} else if (value.getClass().isArray()) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (int i = 0; i < ((Object[]) value).length; i++) list.add(convert(((Object[]) value)[i], replacements));
|
||||
return list;
|
||||
} else if (value instanceof String) {
|
||||
return replace((String) value, replacements);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
} private String replace(String string, NamedContainer<String, String>... replacements) {
|
||||
for (NamedContainer<String, String> replacement : replacements) string = string.replace(replacement.name(), replacement.get());
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,18 +256,12 @@ public class InternalSubCreator extends SubCreator {
|
|||
* Creates an Internal SubCreator
|
||||
*
|
||||
* @param host Host
|
||||
* @param ports The range of ports to auto-select from
|
||||
* @param log Whether SubCreator should log to console
|
||||
* @param gitBash The Git Bash directory
|
||||
* @param gitBash Git Bash
|
||||
*/
|
||||
public InternalSubCreator(InternalHost host, Range<Integer> ports, boolean log, String gitBash) {
|
||||
if (!ports.hasLowerBound() || !ports.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
||||
Util.nullpo(host, ports, log, gitBash);
|
||||
public InternalSubCreator(InternalHost host, String gitBash) {
|
||||
if (Util.isNull(host, gitBash)) throw new NullPointerException();
|
||||
this.host = host;
|
||||
this.ports = ports;
|
||||
this.log = new Container<Boolean>(log);
|
||||
this.gitBash = (System.getenv("ProgramFiles(x86)") == null)?Pattern.compile("%(ProgramFiles)\\(x86\\)%", Pattern.CASE_INSENSITIVE).matcher(gitBash).replaceAll("%$1%"):gitBash;
|
||||
if (this.gitBash.endsWith(File.pathSeparator)) this.gitBash = this.gitBash.substring(0, this.gitBash.length() - 1);
|
||||
this.thread = new TreeMap<String, CreatorTask>();
|
||||
reload();
|
||||
}
|
||||
|
@ -373,17 +269,17 @@ public class InternalSubCreator extends SubCreator {
|
|||
@Override
|
||||
public void reload() {
|
||||
templates.clear();
|
||||
if (new File(host.plugin.dir, "SubServers/Templates").exists())
|
||||
for (File file : new File(host.plugin.dir, "SubServers/Templates").listFiles()) {
|
||||
if (new UniversalFile(host.plugin.dir, "SubServers:Templates").exists())
|
||||
for (File file : new UniversalFile(host.plugin.dir, "SubServers:Templates").listFiles()) {
|
||||
try {
|
||||
if (file.isDirectory() && !file.getName().endsWith(".x")) {
|
||||
ObjectMap<String> config = (new File(file, "template.yml").exists())? new YAMLConfig(new File(file, "template.yml")).get().getMap("Template", new ObjectMap<String>()) : new ObjectMap<String>();
|
||||
ServerTemplate template = loadTemplate(file.getName(), config.getBoolean("Enabled", true), config.getBoolean("Internal", false), config.getString("Icon", "::NULL::"), file, config.getMap("Build", new ObjectMap<String>()), config.getMap("Settings", new ObjectMap<String>()));
|
||||
if (file.isDirectory()) {
|
||||
YAMLSection config = (new UniversalFile(file, "template.yml").exists()) ? new YAMLConfig(new UniversalFile(file, "template.yml")).get().getSection("Template", new YAMLSection()) : new YAMLSection();
|
||||
ServerTemplate template = new ServerTemplate(file.getName(), config.getBoolean("Enabled", true), config.getRawString("Icon", "::NULL::"), file, config.getSection("Build", new YAMLSection()), config.getSection("Settings", new YAMLSection()));
|
||||
templates.put(file.getName().toLowerCase(), template);
|
||||
if (config.getKeys().contains("Display")) template.setDisplayName(Util.unescapeJavaString(config.getString("Display")));
|
||||
if (config.getKeys().contains("Display")) template.setDisplayName(config.getString("Display"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.get(host.getName()).severe("Couldn't load template: " + file.getName());
|
||||
System.out.println(host.getName() + File.separator + "Creator > Couldn't load template: " + file.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -391,36 +287,33 @@ public class InternalSubCreator extends SubCreator {
|
|||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback) {
|
||||
Util.nullpo(name, template);
|
||||
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().containsKey(name.toLowerCase()) && !SubCreator.isReserved(name) && (version != null || !template.requiresVersion())) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
public boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback) {
|
||||
if (Util.isNull(name, template, version)) throw new NullPointerException();
|
||||
if (host.isAvailable() && host.isEnabled() && template.isEnabled() && !SubAPI.getInstance().getSubServers().keySet().contains(name.toLowerCase()) && !SubCreator.isReserved(name)) {
|
||||
StackTraceElement[] origin = new Exception().getStackTrace();
|
||||
|
||||
if (port == null) {
|
||||
Value<Integer> i = new Container<Integer>(ports.lowerEndpoint() - 1);
|
||||
Container<Integer> i = new Container<Integer>(host.range.name() - 1);
|
||||
port = Util.getNew(getAllReservedAddresses(), () -> {
|
||||
do {
|
||||
i.value(i.value() + 1);
|
||||
if (i.value() > ports.upperEndpoint()) throw new IllegalStateException("There are no more ports available in range: " + ports.toString());
|
||||
} while (!ports.contains(i.value()));
|
||||
return new InetSocketAddress(host.getAddress(), i.value());
|
||||
i.set(i.get() + 1);
|
||||
if (i.get() > host.range.get()) throw new IllegalStateException("There are no more ports available between " + host.range.name() + " and " + host.range.get());
|
||||
return new InetSocketAddress(host.getAddress(), i.get());
|
||||
}).getPort();
|
||||
}
|
||||
|
||||
CreatorTask task = new CreatorTask(player, name, template, version, port, server -> {
|
||||
if (callback != null) try {
|
||||
callback.accept(server);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
this.thread.put(name.toLowerCase(), task);
|
||||
|
||||
final SubCreateEvent event = new SubCreateEvent(player, host, name, template, version, port);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
CreatorTask task = new CreatorTask(player, name, template, version, port, server -> {
|
||||
if (callback != null && server != null) try {
|
||||
callback.run(server);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
this.thread.put(name.toLowerCase(), task);
|
||||
task.start();
|
||||
return true;
|
||||
} else {
|
||||
|
@ -430,39 +323,6 @@ public class InternalSubCreator extends SubCreator {
|
|||
} else return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean update(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback) {
|
||||
Util.nullpo(server);
|
||||
final ServerTemplate ft = (template == null)?server.getTemplate():template;
|
||||
if (host.isAvailable() && host.isEnabled() && host == server.getHost() && server.isAvailable() && !server.isRunning() && ft != null && ft.isEnabled() && ft.canUpdate() && (version != null || !ft.requiresVersion())) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
|
||||
((InternalSubServer) server).updating(true);
|
||||
CreatorTask task = new CreatorTask(player, server, ft, version, x -> {
|
||||
((InternalSubServer) server).updating(false);
|
||||
if (callback != null) try {
|
||||
callback.accept(x != null);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
this.thread.put(server.getName().toLowerCase(), task);
|
||||
|
||||
final SubCreateEvent event = new SubCreateEvent(player, server, ft, version);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
task.start();
|
||||
return true;
|
||||
} else {
|
||||
this.thread.remove(server.getName().toLowerCase());
|
||||
return false;
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void terminate() {
|
||||
HashMap<String, CreatorTask> temp = new HashMap<String, CreatorTask>();
|
||||
|
@ -474,9 +334,9 @@ public class InternalSubCreator extends SubCreator {
|
|||
|
||||
@Override
|
||||
public void terminate(String name) {
|
||||
if (this.thread.containsKey(name.toLowerCase())) {
|
||||
if (this.thread.keySet().contains(name.toLowerCase())) {
|
||||
if (this.thread.get(name.toLowerCase()).process != null && this.thread.get(name.toLowerCase()).process.isAlive()) {
|
||||
Executable.terminate(this.thread.get(name.toLowerCase()).process);
|
||||
this.thread.get(name.toLowerCase()).process.destroyForcibly();
|
||||
} else if (this.thread.get(name.toLowerCase()).isAlive()) {
|
||||
this.thread.get(name.toLowerCase()).interrupt();
|
||||
this.thread.remove(name.toLowerCase());
|
||||
|
@ -495,7 +355,7 @@ public class InternalSubCreator extends SubCreator {
|
|||
|
||||
@Override
|
||||
public void waitFor(String name) throws InterruptedException {
|
||||
while (this.thread.containsKey(name.toLowerCase()) && this.thread.get(name.toLowerCase()).isAlive()) {
|
||||
while (this.thread.keySet().contains(name.toLowerCase()) && this.thread.get(name.toLowerCase()).isAlive()) {
|
||||
Thread.sleep(250);
|
||||
}
|
||||
}
|
||||
|
@ -505,17 +365,6 @@ public class InternalSubCreator extends SubCreator {
|
|||
return host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Range getPortRange() {
|
||||
return ports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPortRange(Range<Integer> value) {
|
||||
if (!value.hasLowerBound() || !value.hasUpperBound()) throw new IllegalArgumentException("Port range is not bound");
|
||||
ports = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBashDirectory() {
|
||||
return gitBash;
|
||||
|
@ -537,17 +386,6 @@ public class InternalSubCreator extends SubCreator {
|
|||
return this.thread.get(name.toLowerCase()).log;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return log.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogging(boolean value) {
|
||||
Util.nullpo(value);
|
||||
log.value(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getReservedNames() {
|
||||
return new ArrayList<String>(thread.keySet());
|
||||
|
@ -562,100 +400,43 @@ public class InternalSubCreator extends SubCreator {
|
|||
|
||||
@Override
|
||||
public Map<String, ServerTemplate> getTemplates() {
|
||||
TreeMap<String, ServerTemplate> map = new TreeMap<String, ServerTemplate>();
|
||||
for (Map.Entry<String, ServerTemplate> template : templates.entrySet()) {
|
||||
if (!template.getValue().isInternal()) map.put(template.getKey(), template.getValue());
|
||||
}
|
||||
return map;
|
||||
return new TreeMap<String, ServerTemplate>(templates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerTemplate getTemplate(String name) {
|
||||
Util.nullpo(name);
|
||||
|
||||
ServerTemplate template = templates.getOrDefault(name.toLowerCase(), null);
|
||||
if (template == null || template.isInternal()) {
|
||||
return null;
|
||||
} else {
|
||||
return template;
|
||||
}
|
||||
}
|
||||
|
||||
private static Pair<YAMLSection, Map<String, Object>> subdata = null;
|
||||
private Map<String, Object> getSubData() {
|
||||
if (subdata == null || host.plugin.config.get() != subdata.key()) {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
map.put("Address", host.plugin.config.get().getMap("Settings").getMap("SubData").getString("Address", "127.0.0.1").replace("0.0.0.0", "127.0.0.1"));
|
||||
if (host.plugin.config.get().getMap("Settings").getMap("SubData").getString("Password", "").length() > 0) map.put("Password", host.plugin.config.get().getMap("Settings").getMap("SubData").getString("Password"));
|
||||
subdata = new ContainedPair<>(host.plugin.config.get(), map);
|
||||
}
|
||||
return subdata.value();
|
||||
if (Util.isNull(name)) throw new NullPointerException();
|
||||
return getTemplates().get(name.toLowerCase());
|
||||
}
|
||||
|
||||
private void generateClient(File dir, ServerType type, String name) throws IOException {
|
||||
boolean installed = false;
|
||||
if (type == ServerType.SPIGOT) {
|
||||
installed = true;
|
||||
if (!new File(dir, "plugins").exists()) new File(dir, "plugins").mkdirs();
|
||||
if (!new File(dir, "plugins/SubServers.Client.jar").exists())
|
||||
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new File(dir, "plugins/SubServers.Client.jar").getPath());
|
||||
} else if (type == ServerType.FORGE || type == ServerType.SPONGE) {
|
||||
installed = true;
|
||||
if (!new File(dir, "mods").exists()) new File(dir, "mods").mkdirs();
|
||||
if (!new File(dir, "mods/SubServers.Client.jar").exists())
|
||||
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new File(dir, "mods/SubServers.Client.jar").getPath());
|
||||
}
|
||||
|
||||
if (installed) {
|
||||
YAMLSection config = new YAMLSection();
|
||||
FileWriter writer = new FileWriter(new File(dir, "subdata.json"), false);
|
||||
config.setAll(getSubData());
|
||||
writer.write(new Gson().toJson(config.get()));
|
||||
writer.close();
|
||||
|
||||
if (!new File(dir, "subdata.rsa.key").exists() && new File("SubServers/subdata.rsa.key").exists()) {
|
||||
Files.copy(new File("SubServers/subdata.rsa.key").toPath(), new File(dir, "subdata.rsa.key").toPath());
|
||||
if (new UniversalFile(dir, "subservers.client").exists()) {
|
||||
if (type == ServerType.SPIGOT) {
|
||||
if (!new UniversalFile(dir, "plugins").exists()) new UniversalFile(dir, "plugins").mkdirs();
|
||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "plugins:SubServers.Client.jar").getPath());
|
||||
} else if (type == ServerType.FORGE || type == ServerType.SPONGE) {
|
||||
if (!new UniversalFile(dir, "mods").exists()) new UniversalFile(dir, "mods").mkdirs();
|
||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "mods:SubServers.Client.jar").getPath());
|
||||
}
|
||||
YAMLSection config = new YAMLSection();
|
||||
FileWriter writer = new FileWriter(new UniversalFile(dir, "subservers.client"), false);
|
||||
config.set("Name", name);
|
||||
config.set("Address", host.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Address", "127.0.0.1").replace("0.0.0.0", "127.0.0.1"));
|
||||
config.set("Password", host.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password", ""));
|
||||
config.set("Encryption", host.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Encryption", "NONE"));
|
||||
writer.write(config.toJSON());
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDirectory(File from, File to, boolean overwrite) {
|
||||
if (!to.exists()) {
|
||||
Directories.copy(from, to);
|
||||
} else if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
|
||||
String files[] = from.list();
|
||||
|
||||
for (String file : files) {
|
||||
File srcFile = new File(from, file);
|
||||
File destFile = new File(to, file);
|
||||
|
||||
updateDirectory(srcFile, destFile, overwrite);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (overwrite && (from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from)))) {
|
||||
if (to.exists()) {
|
||||
if (to.isDirectory()) Directories.delete(to);
|
||||
else to.delete();
|
||||
}
|
||||
Files.copy(from.toPath(), to.toPath(), LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} private byte[] generateSHA256(File file) throws Exception {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] dataBytes = new byte[4096];
|
||||
|
||||
int nread;
|
||||
|
||||
while ((nread = fis.read(dataBytes)) != -1) {
|
||||
md.update(dataBytes, 0, nread);
|
||||
}
|
||||
|
||||
fis.close();
|
||||
return md.digest();
|
||||
private void generateProperties(File dir, int port) throws IOException {
|
||||
File file = new File(dir, "server.properties");
|
||||
if (!file.exists()) file.createNewFile();
|
||||
InputStream stream = new FileInputStream(file);
|
||||
String content = Util.readAll(new BufferedReader(new InputStreamReader(stream))).replaceAll("server-port=.*(\r?\n)", "server-port=" + port + "$1").replaceAll("server-ip=.*(\r?\n)", "server-ip=" + host.getAddress().getHostAddress() + "$1");
|
||||
stream.close();
|
||||
file.delete();
|
||||
PrintWriter writer = new PrintWriter(file, "UTF-8");
|
||||
writer.write(content);
|
||||
writer.close();
|
||||
}
|
||||
}
|
|
@ -1,18 +1,18 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.Value;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubLogFilter;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubLogger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -21,12 +21,13 @@ import java.util.regex.Pattern;
|
|||
* Internal Process Logger Class
|
||||
*/
|
||||
public class InternalSubLogger extends SubLogger {
|
||||
Process process;
|
||||
protected Process process;
|
||||
private Object handle;
|
||||
String name;
|
||||
Value<Boolean> log;
|
||||
private List<SubLogFilter> filters = new CopyOnWriteArrayList<>();
|
||||
File file;
|
||||
protected String name;
|
||||
protected Container<Boolean> log;
|
||||
private List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
private List<LogMessage> messages = new LinkedList<LogMessage>();
|
||||
protected File file;
|
||||
private PrintWriter writer = null;
|
||||
private boolean started = false;
|
||||
private Thread out = null;
|
||||
|
@ -41,7 +42,7 @@ public class InternalSubLogger extends SubLogger {
|
|||
* @param log Console Logging Status
|
||||
* @param file File to log to (or null for disabled)
|
||||
*/
|
||||
InternalSubLogger(Process process, Object user, String name, Value<Boolean> log, File file) {
|
||||
protected InternalSubLogger(Process process, Object user, String name, Container<Boolean> log, File file) {
|
||||
this.process = process;
|
||||
this.handle = user;
|
||||
this.name = name;
|
||||
|
@ -49,16 +50,6 @@ public class InternalSubLogger extends SubLogger {
|
|||
this.file = file;
|
||||
}
|
||||
|
||||
void init() {
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters) try {
|
||||
filter.start();
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
started = true;
|
||||
|
@ -71,8 +62,15 @@ public class InternalSubLogger extends SubLogger {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (out == null) (out = new Thread(() -> start(process.getInputStream(), false), "SubServers.Bungee::Internal_Log_Spooler(" + name + ')')).start();
|
||||
if (err == null) (err = new Thread(() -> start(process.getErrorStream(), true), "SubServers.Bungee::Internal_Error_Spooler(" + name + ')')).start();
|
||||
if (out == null) (out = new Thread(() -> start(process.getInputStream(), false))).start();
|
||||
if (err == null) (err = new Thread(() -> start(process.getErrorStream(), true))).start();
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters) try {
|
||||
filter.start();
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
@ -81,7 +79,57 @@ public class InternalSubLogger extends SubLogger {
|
|||
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
log(line);
|
||||
if (!line.startsWith(">")) {
|
||||
String msg = line;
|
||||
Level level;
|
||||
|
||||
// REGEX Formatting
|
||||
String type = "";
|
||||
Matcher matcher = Pattern.compile("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)").matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
|
||||
while (matcher.find()) {
|
||||
type = matcher.group(3).toUpperCase();
|
||||
}
|
||||
|
||||
msg = msg.replaceAll("^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(MESSAGE|INFO|WARNING|WARN|ERROR|ERR|SEVERE)\\]?:?(?:\\s*>)?\\s*)", "");
|
||||
|
||||
// Determine LOG LEVEL
|
||||
switch (type) {
|
||||
case "WARNING":
|
||||
case "WARN":
|
||||
level = Level.WARNING;
|
||||
break;
|
||||
case "SEVERE":
|
||||
case "ERROR":
|
||||
case "ERR":
|
||||
level = Level.SEVERE;
|
||||
break;
|
||||
default:
|
||||
level = Level.INFO;
|
||||
}
|
||||
|
||||
// Filter Message
|
||||
boolean allow = log.get() && (!SubAPI.getInstance().getInternals().canSudo || SubAPI.getInstance().getInternals().sudo == null || SubAPI.getInstance().getInternals().sudo == getHandler());
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters)
|
||||
try {
|
||||
allow = (filter.log(level, msg) && allow);
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
|
||||
// Log to CONSOLE
|
||||
if (allow) ProxyServer.getInstance().getLogger().log(level, name + " > " + msg);
|
||||
|
||||
// Log to MEMORY
|
||||
messages.add(new LogMessage(level, msg));
|
||||
|
||||
// Log to FILE
|
||||
if (writer != null) {
|
||||
writer.println(line);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {} finally {
|
||||
if (isErr) {
|
||||
|
@ -94,117 +142,46 @@ public class InternalSubLogger extends SubLogger {
|
|||
}
|
||||
}
|
||||
|
||||
private Level level = Level.INFO;
|
||||
private static final String PATTERN = "^((?:\\s*\\[?([0-9]{2}:[0-9]{2}:[0-9]{2})]?)?[\\s\\/\\\\\\|]*(?:\\[|\\[.*\\/)?(DEBUG|MESSAGE|MSG|" + Pattern.quote(Level.INFO.getLocalizedName()) + "|INFO|" + Pattern.quote(Level.WARNING.getLocalizedName()) + "|WARNING|WARN|ERROR|ERR|" + Pattern.quote(Level.SEVERE.getLocalizedName()) + "|SEVERE)\\]?(?::|\\s*>)?\\s*)";
|
||||
private void log(String line) {
|
||||
if (!line.startsWith(">")) {
|
||||
String msg = line;
|
||||
|
||||
// REGEX Formatting
|
||||
String type = null;
|
||||
Matcher matcher = Pattern.compile(PATTERN).matcher(msg.replaceAll("\u001B\\[[;\\d]*m", ""));
|
||||
if (matcher.find()) {
|
||||
type = matcher.group(3).toUpperCase();
|
||||
}
|
||||
|
||||
msg = msg.replaceAll(PATTERN, "");
|
||||
|
||||
// Determine LOG LEVEL
|
||||
if (type != null) {
|
||||
if (type.equalsIgnoreCase(Level.INFO.getLocalizedName())) {
|
||||
level = Level.INFO;
|
||||
} else if (type.equalsIgnoreCase(Level.WARNING.getLocalizedName())) {
|
||||
level = Level.WARNING;
|
||||
} else if (type.equalsIgnoreCase(Level.SEVERE.getLocalizedName())) {
|
||||
level = Level.SEVERE;
|
||||
} else switch (type) {
|
||||
case "WARNING":
|
||||
case "WARN":
|
||||
level = Level.WARNING;
|
||||
break;
|
||||
case "SEVERE":
|
||||
case "ERROR":
|
||||
case "ERR":
|
||||
level = Level.SEVERE;
|
||||
break;
|
||||
default:
|
||||
level = Level.INFO;
|
||||
}
|
||||
}
|
||||
|
||||
// Log to FILTER
|
||||
log(level, msg);
|
||||
|
||||
// Log to FILE
|
||||
if (writer != null) {
|
||||
writer.println(line);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void log(Level level, String message) {
|
||||
// Filter Message
|
||||
boolean allow = (SubAPI.getInstance().getInternals().sudo == getHandler() && SubAPI.getInstance().getInternals().canSudo) || (log.value() && (SubAPI.getInstance().getInternals().sudo == null || !SubAPI.getInstance().getInternals().canSudo));
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters) {
|
||||
try {
|
||||
allow = (filter.log(level, message) && allow);
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Log to CONSOLE
|
||||
if (allow || !started) {
|
||||
Logger.get(name).log(level, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
try {
|
||||
if (out != null) out.interrupt();
|
||||
if (err != null) err.interrupt();
|
||||
level = Level.INFO;
|
||||
|
||||
if (started) {
|
||||
started = false;
|
||||
if (writer != null) {
|
||||
PrintWriter writer = this.writer;
|
||||
this.writer = null;
|
||||
int l = (("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2;
|
||||
String s = "";
|
||||
while (s.length() < l) s += '-';
|
||||
if (writer != null) {
|
||||
writer.println(s + " LOG END " + s);
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {}
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters) try {
|
||||
filter.stop();
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
if (out != null) out.interrupt();
|
||||
if (err != null) err.interrupt();
|
||||
destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFilter(SubLogFilter filter) {
|
||||
Util.nullpo(filter);
|
||||
if (Util.isNull(filter)) throw new NullPointerException();
|
||||
filters.add(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterFilter(SubLogFilter filter) {
|
||||
Util.nullpo(filter);
|
||||
Try.all.run(() -> filters.remove(filter));
|
||||
if (Util.isNull(filter)) throw new NullPointerException();
|
||||
filters.remove(filter);
|
||||
}
|
||||
|
||||
private void destroy() {
|
||||
if (started) {
|
||||
started = false;
|
||||
List<SubLogFilter> filters = new ArrayList<SubLogFilter>();
|
||||
filters.addAll(this.filters);
|
||||
for (SubLogFilter filter : filters) try {
|
||||
filter.stop();
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, "Exception while running SubLogger Event").printStackTrace();
|
||||
}
|
||||
messages.clear();
|
||||
if (writer != null) {
|
||||
PrintWriter writer = this.writer;
|
||||
this.writer = null;
|
||||
int l = (int) Math.floor((("---------- LOG START \u2014 " + name + " ----------").length() - 9) / 2);
|
||||
String s = "";
|
||||
while (s.length() < l) s += '-';
|
||||
writer.println(s + " LOG END " + s);
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -219,6 +196,11 @@ public class InternalSubLogger extends SubLogger {
|
|||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return log.value();
|
||||
return log.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LogMessage> getMessageHistory() {
|
||||
return new LinkedList<LogMessage>(messages);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,20 @@
|
|||
package net.ME1312.SubServers.Bungee.Host.Internal;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Container.Container;
|
||||
import net.ME1312.Galaxi.Library.Container.Value;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Event.*;
|
||||
import net.ME1312.SubServers.Bungee.Host.*;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.UniversalFile;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
import net.md_5.bungee.BungeeServerInfo;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -34,13 +25,13 @@ import java.util.jar.JarInputStream;
|
|||
/**
|
||||
* Internal SubServer Class
|
||||
*/
|
||||
public class InternalSubServer extends SubServerImpl {
|
||||
public class InternalSubServer extends SubServerContainer {
|
||||
private InternalHost host;
|
||||
private boolean enabled;
|
||||
private Value<Boolean> log;
|
||||
private Container<Boolean> log;
|
||||
private String dir;
|
||||
private File directory;
|
||||
private String executable;
|
||||
private Executable executable;
|
||||
private String stopcmd;
|
||||
private StopAction stopaction;
|
||||
private LinkedList<LoggedCommand> history;
|
||||
|
@ -67,34 +58,9 @@ public class InternalSubServer extends SubServerImpl {
|
|||
* @param restricted Restricted Status
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public static InternalSubServer construct(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
try {
|
||||
return new InternalSubServer(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
} catch (NoSuchMethodError e) {
|
||||
return new InternalSubServer(host, name, enabled, (Integer) port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Super Method 2 (newest)
|
||||
* @see #construct(InternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||
*/
|
||||
protected InternalSubServer(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
public InternalSubServer(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, Executable executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(host, name, port, motd, hidden, restricted);
|
||||
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Super Method 1 (oldest)
|
||||
* @see #construct(InternalHost, String, boolean, int, String, boolean, String, String, String, boolean, boolean) for method details
|
||||
*/
|
||||
protected InternalSubServer(InternalHost host, String name, boolean enabled, Integer port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(host, name, port, motd, hidden, restricted);
|
||||
init(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
}
|
||||
|
||||
private void init(InternalHost host, String name, boolean enabled, int port, String motd, boolean log, String directory, String executable, String stopcmd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
Util.nullpo(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted);
|
||||
if (Util.isNull(host, name, enabled, port, motd, log, directory, executable, stopcmd, hidden, restricted)) throw new NullPointerException();
|
||||
this.host = host;
|
||||
this.enabled = enabled;
|
||||
this.log = new Container<Boolean>(log);
|
||||
|
@ -108,62 +74,54 @@ public class InternalSubServer extends SubServerImpl {
|
|||
this.logger = new InternalSubLogger(null, this, getName(), this.log, null);
|
||||
this.thread = null;
|
||||
this.command = null;
|
||||
final File[] locations = new File[] {
|
||||
new File(this.directory, "plugins/SubServers.Client.jar"),
|
||||
new File(this.directory, "mods/SubServers.Client.jar")
|
||||
};
|
||||
|
||||
for (File location : locations) {
|
||||
if (location.exists()) {
|
||||
try {
|
||||
JarInputStream updated = new JarInputStream(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
|
||||
JarFile existing = new JarFile(location);
|
||||
if (new UniversalFile(this.directory, "plugins:SubServers.Client.jar").exists()) {
|
||||
try {
|
||||
JarInputStream updated = new JarInputStream(SubPlugin.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
|
||||
JarFile existing = new JarFile(new UniversalFile(this.directory, "plugins:SubServers.Client.jar"));
|
||||
|
||||
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
|
||||
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
|
||||
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
|
||||
location.delete();
|
||||
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", location.getPath());
|
||||
}
|
||||
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
|
||||
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
|
||||
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
|
||||
new UniversalFile(this.directory, "plugins:SubServers.Client.jar").delete();
|
||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(this.directory, "plugins:SubServers.Client.jar").getPath());
|
||||
}
|
||||
existing.close();
|
||||
updated.close();
|
||||
} catch (Throwable e) {
|
||||
System.out.println("Couldn't auto-update SubServers.Client for subserver: " + name);
|
||||
e.printStackTrace();
|
||||
}
|
||||
existing.close();
|
||||
updated.close();
|
||||
} catch (Throwable e) {
|
||||
System.out.println("Couldn't auto-update SubServers.Client.jar for " + name);
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (new UniversalFile(this.directory, "mods:SubServers.Client.jar").exists()) {
|
||||
try {
|
||||
JarInputStream updated = new JarInputStream(SubPlugin.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/client.jar"));
|
||||
JarFile existing = new JarFile(new UniversalFile(this.directory, "mods:SubServers.Client.jar"));
|
||||
|
||||
if (existing.getManifest().getMainAttributes().getValue("Implementation-Title") != null && existing.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && existing.getManifest().getMainAttributes().getValue("Specification-Title") != null &&
|
||||
updated.getManifest().getMainAttributes().getValue("Implementation-Title") != null && updated.getManifest().getMainAttributes().getValue("Implementation-Title").startsWith("SubServers.Client") && updated.getManifest().getMainAttributes().getValue("Specification-Title") != null) {
|
||||
if (new Version(existing.getManifest().getMainAttributes().getValue("Specification-Title")).compareTo(new Version(updated.getManifest().getMainAttributes().getValue("Specification-Title"))) < 0) {
|
||||
new UniversalFile(this.directory, "mods:SubServers.Client.jar").delete();
|
||||
Util.copyFromJar(SubPlugin.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(this.directory, "mods:SubServers.Client.jar").getPath());
|
||||
}
|
||||
}
|
||||
existing.close();
|
||||
updated.close();
|
||||
} catch (Throwable e) {
|
||||
System.out.println("Couldn't auto-update SubServers.Client.jar for " + name);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
this.lock = false;
|
||||
}
|
||||
|
||||
void registered(boolean value) {
|
||||
registered = value;
|
||||
}
|
||||
|
||||
void updating(boolean value) {
|
||||
updating = value;
|
||||
}
|
||||
|
||||
private void run() {
|
||||
boolean locked = lock;
|
||||
allowrestart = true;
|
||||
stopping = false;
|
||||
started = false;
|
||||
try {
|
||||
ProcessBuilder pb = new ProcessBuilder().command(Executable.parse(host.getCreator().getBashDirectory(), executable)).directory(directory);
|
||||
pb.environment().put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
|
||||
pb.environment().put("name", getName());
|
||||
pb.environment().put("host", host.getName());
|
||||
pb.environment().put("address", host.getAddress().getHostAddress());
|
||||
pb.environment().put("port", Integer.toString(getAddress().getPort()));
|
||||
logger.init();
|
||||
process = pb.start();
|
||||
Logger.get("SubServers").info("Now starting " + getName());
|
||||
process = Runtime.getRuntime().exec(executable.toString(), null, directory);
|
||||
System.out.println("SubServers > Now starting " + getName());
|
||||
logger.process = process;
|
||||
logger.start();
|
||||
lock = locked = false;
|
||||
command = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
|
||||
for (LoggedCommand command : history) if (process.isAlive()) {
|
||||
this.command.write(command.getCommand());
|
||||
|
@ -174,32 +132,25 @@ public class InternalSubServer extends SubServerImpl {
|
|||
if (process.isAlive()) process.waitFor();
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
if (locked) lock = false;
|
||||
allowrestart = false;
|
||||
}
|
||||
|
||||
logger.destroy();
|
||||
Logger.get("SubServers").info(getName() + " has stopped");
|
||||
process = null;
|
||||
command = null;
|
||||
started = false;
|
||||
stopping = false;
|
||||
history.clear();
|
||||
|
||||
SubStoppedEvent event = new SubStoppedEvent(this);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
System.out.println("SubServers > " + getName() + " has stopped");
|
||||
process = null;
|
||||
command = null;
|
||||
history.clear();
|
||||
|
||||
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.RECYCLE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
||||
if (stopaction == StopAction.REMOVE_SERVER || stopaction == StopAction.DELETE_SERVER) {
|
||||
try {
|
||||
if (stopaction == StopAction.RECYCLE_SERVER) {
|
||||
host.recycleSubServer(null, getName(), false, false);
|
||||
} else if (stopaction == StopAction.DELETE_SERVER) {
|
||||
host.deleteSubServer(null, getName(), false, false);
|
||||
if (stopaction == StopAction.DELETE_SERVER) {
|
||||
host.deleteSubServer(getName());
|
||||
} else {
|
||||
try {
|
||||
if (host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||
host.plugin.servers.save();
|
||||
if (host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
host.plugin.config.get().getSection("Servers").remove(getName());
|
||||
host.plugin.config.save();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -220,24 +171,22 @@ public class InternalSubServer extends SubServerImpl {
|
|||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, "SubServers.Bungee::Internal_Server_Restart_Handler(" + getName() + ')').start();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start(UUID player) {
|
||||
if (!lock && isAvailable() && isEnabled() && !(thread != null && thread.isAlive()) && getCurrentIncompatibilities().size() == 0) {
|
||||
if (!lock && isEnabled() && !(thread != null && thread.isAlive()) && getCurrentIncompatibilities().size() == 0) {
|
||||
lock = true;
|
||||
SubStartEvent event = new SubStartEvent(player, this);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
lock = false;
|
||||
if (!event.isCancelled()) {
|
||||
(thread = new Thread(this::run, "SubServers.Bungee::Internal_Server_Process_Handler(" + getName() + ')')).start();
|
||||
(thread = new Thread(this::run)).start();
|
||||
return true;
|
||||
} else {
|
||||
lock = false;
|
||||
return false;
|
||||
}
|
||||
} else return false;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
|
@ -248,7 +197,6 @@ public class InternalSubServer extends SubServerImpl {
|
|||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
try {
|
||||
stopping = true;
|
||||
allowrestart = false;
|
||||
history.add(new LoggedCommand(player, stopcmd));
|
||||
if (process != null && process.isAlive()) {
|
||||
|
@ -271,9 +219,8 @@ public class InternalSubServer extends SubServerImpl {
|
|||
SubStopEvent event = new SubStopEvent(player, this, true);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
stopping = true;
|
||||
allowrestart = false;
|
||||
if (process != null && process.isAlive()) Executable.terminate(process);
|
||||
if (process != null && process.isAlive()) process.destroyForcibly();
|
||||
return true;
|
||||
} else return false;
|
||||
} else return false;
|
||||
|
@ -281,16 +228,13 @@ public class InternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public boolean command(UUID player, String command) {
|
||||
Util.nullpo(command);
|
||||
if (Util.isNull(command)) throw new NullPointerException();
|
||||
if (thread != null && thread.isAlive()) {
|
||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command, null);
|
||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled() && (player == null || !DISALLOWED_COMMANDS.matcher(command).find())) {
|
||||
if (!event.isCancelled()) {
|
||||
try {
|
||||
if (event.getCommand().equalsIgnoreCase(stopcmd)) {
|
||||
stopping = true;
|
||||
allowrestart = false;
|
||||
}
|
||||
if (event.getCommand().equalsIgnoreCase(stopcmd)) allowrestart = false;
|
||||
history.add(new LoggedCommand(player, event.getCommand()));
|
||||
if (process != null && process.isAlive()) {
|
||||
this.command.write(event.getCommand());
|
||||
|
@ -306,275 +250,261 @@ public class InternalSubServer extends SubServerImpl {
|
|||
} else return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
@Override
|
||||
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||
if (isAvailable()) {
|
||||
int c = 0;
|
||||
boolean state = isRunning();
|
||||
SubServer forward = null;
|
||||
ObjectMap<String> pending = edit.clone();
|
||||
for (String key : edit.getKeys()) {
|
||||
pending.remove(key);
|
||||
ObjectMapValue value = edit.get(key);
|
||||
boolean allowed = true;
|
||||
if (perma) {
|
||||
SubEditServerEvent event = new SubEditServerEvent(player, this, new ContainedPair<String, ObjectMapValue>(key, value));
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
allowed = !event.isCancelled();
|
||||
}
|
||||
if (allowed) {
|
||||
try {
|
||||
switch (key.toLowerCase()) {
|
||||
case "name":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = host.constructSubServer(value.asString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
ObjectMap<String> config = this.host.plugin.servers.get().getMap("Servers").getMap(getName());
|
||||
this.host.plugin.servers.get().getMap("Servers").remove(getName());
|
||||
this.host.plugin.servers.get().getMap("Servers").set(server.getName(), config);
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "display":
|
||||
if (value.isString()) {
|
||||
setDisplayName(value.asString());
|
||||
logger.name = getDisplayName();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
if (getName().equals(getDisplayName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).remove("Display");
|
||||
} else {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Display", getDisplayName());
|
||||
}
|
||||
this.host.plugin.servers.save();
|
||||
@SuppressWarnings("deprecation")
|
||||
public int edit(UUID player, YAMLSection edit) {
|
||||
int c = 0;
|
||||
boolean state = isRunning();
|
||||
SubServer forward = null;
|
||||
YAMLSection pending = edit.clone();
|
||||
for (String key : edit.getKeys()) {
|
||||
pending.remove(key);
|
||||
YAMLValue value = edit.get(key);
|
||||
SubEditServerEvent event = new SubEditServerEvent(player, this, new NamedContainer<String, YAMLValue>(key, value), true);
|
||||
host.plugin.getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
try {
|
||||
switch (key) {
|
||||
case "name":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = host.addSubServer(player, value.asRawString(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
YAMLSection config = this.host.plugin.config.get().getSection("Servers").getSection(getName());
|
||||
this.host.plugin.config.get().getSection("Servers").remove(getName());
|
||||
this.host.plugin.config.get().getSection("Servers").set(server.getName(), config);
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "enabled":
|
||||
if (value.isBoolean()) {
|
||||
enabled = value.asBoolean();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Enabled", isEnabled());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "group":
|
||||
if (value.isList()) {
|
||||
Util.reflect(ServerImpl.class.getDeclaredField("groups"), this, value.asStringList());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Group", value.asStringList());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "host":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = this.host.plugin.api.getHost(value.asString()).constructSubServer(getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Host", server.getHost().getName());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "template":
|
||||
if (value.isString()) {
|
||||
setTemplate(value.asString());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Template", value.asString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "port":
|
||||
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = host.constructSubServer(getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Port", server.getAddress().getPort());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "motd":
|
||||
if (value.isString()) {
|
||||
setMotd(ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(value.asString())));
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Motd", value.asString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "log":
|
||||
if (value.isBoolean()) {
|
||||
log.value(value.asBoolean());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Log", isLogging());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "dir":
|
||||
case "directory":
|
||||
if (value.isString()) {
|
||||
if (isRunning()) {
|
||||
stop(player);
|
||||
waitFor();
|
||||
}
|
||||
dir = value.asString();
|
||||
directory = new File(getHost().getPath(), value.asString());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Directory", getPath());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "exec":
|
||||
case "executable":
|
||||
if (value.isString()) {
|
||||
if (isRunning()) {
|
||||
stop(player);
|
||||
waitFor();
|
||||
}
|
||||
executable = value.asString();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Executable", value.asString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "stop-cmd":
|
||||
case "stop-command":
|
||||
if (value.isString()) {
|
||||
stopcmd = value.asString();
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Command", getStopCommand());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "stop-action":
|
||||
if (value.isString()) {
|
||||
StopAction action = Try.all.get(() -> StopAction.valueOf(value.asString().toUpperCase().replace('-', '_').replace(' ', '_')));
|
||||
if (action != null) {
|
||||
stopaction = action;
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Stop-Action", getStopAction().toString());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "state":
|
||||
if (value.isBoolean()) {
|
||||
state = value.asBoolean();
|
||||
}
|
||||
break;
|
||||
case "auto-run":
|
||||
case "run-on-launch":
|
||||
if (value.isBoolean()) {
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Run-On-Launch", value.asBoolean());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "incompatible":
|
||||
if (value.isList()) {
|
||||
for (SubServer oserver : getIncompatibilities()) toggleCompatibility(oserver);
|
||||
for (String oname : (List<String>) value.asStringList()) {
|
||||
SubServer oserver = host.plugin.api.getSubServer(oname);
|
||||
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
||||
}
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Incompatible", value.asStringList());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "restricted":
|
||||
if (value.isBoolean()) {
|
||||
setRestricted(value.asBoolean());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Restricted", isRestricted());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "hidden":
|
||||
if (value.isBoolean()) {
|
||||
setHidden(value.asBoolean());
|
||||
if (perma && this.host.plugin.servers.get().getMap("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.servers.get().getMap("Servers").getMap(getName()).set("Hidden", isHidden());
|
||||
this.host.plugin.servers.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "whitelist":
|
||||
if (value.isList()) {
|
||||
Util.reflect(ServerImpl.class.getDeclaredField("whitelist"), this, value.asUUIDList());
|
||||
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_SET, value.asUUIDList()));
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (forward != null) {
|
||||
forward.setStopAction(getStopAction());
|
||||
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
||||
forward.setTemplate(getTemplate());
|
||||
List<String> groups = new ArrayList<String>();
|
||||
groups.addAll(getGroups());
|
||||
for (String group : groups) {
|
||||
removeGroup(group);
|
||||
forward.addGroup(group);
|
||||
}
|
||||
for (SubServer server : getIncompatibilities()) {
|
||||
toggleCompatibility(server);
|
||||
forward.toggleCompatibility(server);
|
||||
}
|
||||
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
||||
forward.getHost().addSubServer(player, forward);
|
||||
|
||||
if (state) pending.set("state", true);
|
||||
c += (perma)?forward.permaEdit(player, pending):forward.edit(player, pending);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
case "display":
|
||||
if (value.isString()) {
|
||||
Field f = ServerContainer.class.getDeclaredField("nick");
|
||||
f.setAccessible(true);
|
||||
if (value == null || value.asString().length() == 0 || getName().equals(value)) {
|
||||
f.set(this, null);
|
||||
} else {
|
||||
f.set(this, value.asString());
|
||||
}
|
||||
f.setAccessible(false);
|
||||
logger.name = getDisplayName();
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
if (getName().equals(getDisplayName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).remove("Display");
|
||||
} else {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Display", getDisplayName());
|
||||
}
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "enabled":
|
||||
if (value.isBoolean()) {
|
||||
enabled = value.asBoolean();
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Enabled", isEnabled());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "group":
|
||||
if (value.isList()) {
|
||||
Field f = ServerContainer.class.getDeclaredField("groups");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asStringList());
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Group", value.asStringList());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "host":
|
||||
if (value.isString() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = this.host.plugin.api.getHost(value.asRawString()).addSubServer(player, getName(), isEnabled(), getAddress().getPort(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Host", server.getHost().getName());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "port":
|
||||
if (value.isNumber() && host.removeSubServer(player, getName())) {
|
||||
SubServer server = host.addSubServer(player, getName(), isEnabled(), value.asInt(), getMotd(), isLogging(), getPath(), getExecutable(), getStopCommand(), isHidden(), isRestricted());
|
||||
if (server != null) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Port", server.getAddress().getPort());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
forward = server;
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "motd":
|
||||
if (value.isString()) {
|
||||
Field f = BungeeServerInfo.class.getDeclaredField("motd");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asColoredString('&'));
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Motd", value.asString());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "log":
|
||||
if (value.isBoolean()) {
|
||||
log.set(value.asBoolean());
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Log", isLogging());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "dir":
|
||||
if (value.isString()) {
|
||||
if (isRunning()) {
|
||||
stop(player);
|
||||
waitFor();
|
||||
}
|
||||
dir = value.asRawString();
|
||||
directory = new File(getHost().getPath(), value.asRawString());
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Directory", getPath());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "exec":
|
||||
if (value.isString()) {
|
||||
if (isRunning()) {
|
||||
stop(player);
|
||||
waitFor();
|
||||
}
|
||||
executable = new Executable(value.asRawString());
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Executable", value.asRawString());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "stop-cmd":
|
||||
if (value.isString()) {
|
||||
stopcmd = value.asRawString();
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Command", getStopCommand());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "stop-action":
|
||||
if (value.isString()) {
|
||||
StopAction action = Util.getDespiteException(() -> StopAction.valueOf(value.asRawString().toUpperCase().replace('-', '_').replace(' ', '_')), null);
|
||||
if (action != null) {
|
||||
stopaction = action;
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Stop-Action", getStopAction().toString());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "state":
|
||||
if (value.isBoolean()) {
|
||||
state = value.asBoolean();
|
||||
}
|
||||
break;
|
||||
case "auto-run":
|
||||
if (value.isBoolean()) {
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Run-On-Launch", value.asBoolean());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "incompatible":
|
||||
if (value.isList()) {
|
||||
for (String oname : value.asStringList()) {
|
||||
SubServer oserver = host.plugin.api.getSubServer(oname);
|
||||
if (oserver != null && isCompatible(oserver)) toggleCompatibility(oserver);
|
||||
}
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Incompatible", value.asStringList());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "restricted":
|
||||
if (value.isBoolean()) {
|
||||
Field f = BungeeServerInfo.class.getDeclaredField("restricted");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asBoolean());
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Restricted", isRestricted());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
case "hidden":
|
||||
if (value.isBoolean()) {
|
||||
Field f = ServerContainer.class.getDeclaredField("hidden");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value.asBoolean());
|
||||
f.setAccessible(false);
|
||||
if (this.host.plugin.config.get().getSection("Servers").getKeys().contains(getName())) {
|
||||
this.host.plugin.config.get().getSection("Servers").getSection(getName()).set("Hidden", isHidden());
|
||||
this.host.plugin.config.save();
|
||||
}
|
||||
c++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (forward != null) {
|
||||
forward.setStopAction(getStopAction());
|
||||
if (!getName().equals(getDisplayName())) forward.setDisplayName(getDisplayName());
|
||||
List<String> groups = new ArrayList<String>();
|
||||
groups.addAll(getGroups());
|
||||
for (String group : groups) {
|
||||
removeGroup(group);
|
||||
forward.addGroup(group);
|
||||
}
|
||||
for (SubServer server : getIncompatibilities()) {
|
||||
toggleCompatibility(server);
|
||||
forward.toggleCompatibility(server);
|
||||
}
|
||||
for (String extra : getExtra().getKeys()) forward.addExtra(extra, getExtra(extra));
|
||||
|
||||
if (state) pending.set("state", true);
|
||||
c += forward.edit(player, pending);
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (!isRunning() && forward == null && state) start(player);
|
||||
return c;
|
||||
} else return -1;
|
||||
}
|
||||
if (!isRunning() && forward == null && state) start(player);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -586,7 +516,7 @@ public class InternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return (process != null && process.isAlive()) || lock;
|
||||
return process != null && process.isAlive();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -602,24 +532,26 @@ public class InternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled && host.isEnabled();
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
Util.nullpo(value);
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("enabled", value), false));
|
||||
enabled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return log.value();
|
||||
return log.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogging(boolean value) {
|
||||
Util.nullpo(value);
|
||||
log.value(value);
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("log", value), false));
|
||||
log.set(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -638,7 +570,7 @@ public class InternalSubServer extends SubServerImpl {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getExecutable() {
|
||||
public Executable getExecutable() {
|
||||
return executable;
|
||||
}
|
||||
|
||||
|
@ -649,7 +581,8 @@ public class InternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public void setStopCommand(String value) {
|
||||
Util.nullpo(value);
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-cmd", value), false));
|
||||
stopcmd = value;
|
||||
}
|
||||
|
||||
|
@ -660,7 +593,8 @@ public class InternalSubServer extends SubServerImpl {
|
|||
|
||||
@Override
|
||||
public void setStopAction(StopAction action) {
|
||||
Util.nullpo(action);
|
||||
if (Util.isNull(action)) throw new NullPointerException();
|
||||
host.plugin.getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("stop-action", action), false));
|
||||
stopaction = action;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.ExtraDataHandler;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.ClientHandler;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubRemoveProxyEvent;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExSyncPlayer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
import net.ME1312.SubServers.Bungee.Library.ExtraDataHandler;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -19,70 +17,39 @@ import java.util.*;
|
|||
/**
|
||||
* Proxy Class
|
||||
*/
|
||||
public class Proxy implements ClientHandler, ExtraDataHandler<String> {
|
||||
private final HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
||||
private final ObjectMap<String> extra = new ObjectMap<String>();
|
||||
public class Proxy implements ClientHandler, ExtraDataHandler {
|
||||
private YAMLSection extra = new YAMLSection();
|
||||
private final String signature;
|
||||
private boolean persistent = false;
|
||||
private boolean persistent = true;
|
||||
private Client client = null;
|
||||
private String nick = null;
|
||||
private final String name;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public Proxy(String name) throws IllegalArgumentException {
|
||||
if (name == null) name = Util.getNew(SubAPI.getInstance().getInternals().proxies.keySet(), () -> UUID.randomUUID().toString());
|
||||
if (name == null) {
|
||||
name = Util.getNew(SubAPI.getInstance().getInternals().proxies.keySet(), () -> UUID.randomUUID().toString());
|
||||
persistent = false;
|
||||
}
|
||||
if (name.contains(" ")) throw new IllegalArgumentException("Proxy names cannot have spaces: " + name);
|
||||
this.name = name;
|
||||
this.signature = SubAPI.getInstance().signAnonymousObject();
|
||||
|
||||
subdata.put(0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataClient[] getSubData() {
|
||||
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
||||
DataClient[] channels = new DataClient[keys.length];
|
||||
Arrays.sort(keys);
|
||||
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
||||
return channels;
|
||||
public Client getSubData() {
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setSubData(SubDataClient client, int channel) {
|
||||
boolean update = false;
|
||||
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
||||
if (client != null || channel == 0) {
|
||||
if (!subdata.containsKey(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
||||
update = true;
|
||||
subdata.put(channel, client);
|
||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
||||
}
|
||||
} else {
|
||||
update = true;
|
||||
subdata.remove(channel);
|
||||
public void setSubData(Client client) {
|
||||
this.client = client;
|
||||
if (client == null && !persistent) {
|
||||
ProxyServer.getInstance().getPluginManager().callEvent(new SubRemoveProxyEvent(this));
|
||||
SubAPI.getInstance().getInternals().proxies.remove(getName().toLowerCase());
|
||||
}
|
||||
|
||||
if (update) {
|
||||
DataClient[] subdata = getSubData();
|
||||
if (subdata[0] == null && subdata.length <= 1) {
|
||||
SubProxy plugin = SubAPI.getInstance().getInternals();
|
||||
for (UUID id : Util.getBackwards(plugin.rPlayerLinkP, this)) {
|
||||
plugin.rPlayerLinkS.remove(id);
|
||||
plugin.rPlayerLinkP.remove(id);
|
||||
plugin.rPlayers.remove(id);
|
||||
}
|
||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null && proxy != this) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketExSyncPlayer(getName(), null, (RemotePlayer[]) null));
|
||||
}
|
||||
if (!persistent) {
|
||||
ProxyServer.getInstance().getPluginManager().callEvent(new SubRemoveProxyEvent(this));
|
||||
SubAPI.getInstance().getInternals().proxies.remove(getName().toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubData(DataClient client) {
|
||||
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,36 +84,34 @@ public class Proxy implements ClientHandler, ExtraDataHandler<String> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determine if the proxy is the Master Proxy
|
||||
* Test if the proxy is connected to RedisBungee's server
|
||||
*
|
||||
* @return Master Proxy Status
|
||||
* @return Redis Status
|
||||
*/
|
||||
public boolean isMaster() {
|
||||
return SubAPI.getInstance().getMasterProxy() == this;
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
public boolean isRedis() {
|
||||
SubPlugin plugin = SubAPI.getInstance().getInternals();
|
||||
return plugin.redis != null && Util.getDespiteException(() -> plugin.redis("getPlayersOnProxy", new NamedContainer<>(String.class, getName())) != null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the players on this proxy
|
||||
* Get the players on this proxy (via RedisBungee)
|
||||
*
|
||||
* @return Remote Player Collection
|
||||
* @return Player Collection
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public Collection<RemotePlayer> getPlayers() {
|
||||
SubProxy plugin = SubAPI.getInstance().getInternals();
|
||||
ArrayList<RemotePlayer> players = new ArrayList<RemotePlayer>();
|
||||
for (UUID id : Util.getBackwards(plugin.rPlayerLinkP, this)) {
|
||||
players.add(plugin.rPlayers.get(id));
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
public Collection<NamedContainer<String, UUID>> getPlayers() {
|
||||
List<NamedContainer<String, UUID>> players = new ArrayList<NamedContainer<String, UUID>>();
|
||||
SubPlugin plugin = SubAPI.getInstance().getInternals();
|
||||
if (plugin.redis != null) {
|
||||
try {
|
||||
for (UUID player : (Set<UUID>) plugin.redis("getPlayersOnProxy", new NamedContainer<>(String.class, getName())))
|
||||
players.add(new NamedContainer<>((String) plugin.redis("getNameFromUuid", new NamedContainer<>(UUID.class, player)), player));
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes it so the proxy object will still exist within the server manager even if it is disconnected
|
||||
*/
|
||||
public final void persist() {
|
||||
persistent = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Signature of this Object
|
||||
*
|
||||
|
@ -156,56 +121,52 @@ public class Proxy implements ClientHandler, ExtraDataHandler<String> {
|
|||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof Proxy && signature.equals(((Proxy) obj).signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtra(String handle, Object value) {
|
||||
Util.nullpo(handle, value);
|
||||
if (Util.isNull(handle, value)) throw new NullPointerException();
|
||||
extra.set(handle, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
return extra.getKeys().contains(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapValue getExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
public YAMLValue getExtra(String handle) {
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
return extra.get(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> getExtra() {
|
||||
public YAMLSection getExtra() {
|
||||
return extra.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
extra.remove(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> info = new ObjectMap<String>();
|
||||
public String toString() {
|
||||
YAMLSection info = new YAMLSection();
|
||||
info.set("type", "Proxy");
|
||||
info.set("name", getName());
|
||||
info.set("display", getDisplayName());
|
||||
ObjectMap<String> players = new ObjectMap<String>();
|
||||
for (RemotePlayer player : getPlayers())
|
||||
players.set(player.getUniqueId().toString(), player.getName());
|
||||
YAMLSection players = new YAMLSection();
|
||||
for (NamedContainer<String, UUID> player : getPlayers()) {
|
||||
YAMLSection pinfo = new YAMLSection();
|
||||
pinfo.set("name", player.name());
|
||||
players.set(player.get().toString(), pinfo);
|
||||
}
|
||||
info.set("players", players);
|
||||
info.set("master", isMaster());
|
||||
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
||||
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
||||
info.set("subdata", subdata);
|
||||
info.set("redis", isRedis());
|
||||
if (getSubData() != null) info.set("subdata", getSubData().getAddress().toString());
|
||||
info.set("signature", signature);
|
||||
info.set("extra", getExtra());
|
||||
return info;
|
||||
return info.toJSON();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,314 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubData.Server.SubDataSerializable;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.RPSI;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketDisconnectPlayer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketMessagePlayer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketTransferPlayer;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
/**
|
||||
* Remote Player Class
|
||||
*/
|
||||
public class RemotePlayer implements net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer, SubDataSerializable {
|
||||
private ProxiedPlayer local;
|
||||
private UUID id;
|
||||
private String name;
|
||||
private InetSocketAddress ip;
|
||||
private Proxy proxy;
|
||||
private Server server;
|
||||
|
||||
/**
|
||||
* Translate a Local Player to a Remote Player
|
||||
*
|
||||
* @param player Local Player
|
||||
*/
|
||||
public RemotePlayer(ProxiedPlayer player) {
|
||||
this(player, player.getServer().getInfo());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate a Local Player to a Remote Player
|
||||
*
|
||||
* @param player Local Player
|
||||
* @param server Server the player is on
|
||||
*/
|
||||
public RemotePlayer(ProxiedPlayer player, ServerInfo server) {
|
||||
Util.nullpo(player);
|
||||
this.local = player;
|
||||
this.id = player.getUniqueId();
|
||||
this.server = (server instanceof Server)? (Server) server : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a Remote Player using their ID
|
||||
*
|
||||
* @param name Player Name
|
||||
* @param id Player UUID
|
||||
* @param proxy Proxy the player is on
|
||||
* @param server Server the player is on
|
||||
* @param ip Player IP Address
|
||||
*/
|
||||
public RemotePlayer(String name, UUID id, Proxy proxy, ServerInfo server, InetSocketAddress ip) {
|
||||
Util.nullpo(name, id, proxy, ip);
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.ip = ip;
|
||||
this.proxy = proxy;
|
||||
this.server = (server instanceof Server)? (Server) server : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxiedPlayer get() {
|
||||
return local;
|
||||
}
|
||||
|
||||
private static ProxiedPlayer get(UUID player) {
|
||||
return ProxyServer.getInstance().getPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUniqueId() {
|
||||
if (local != null) {
|
||||
return local.getUniqueId();
|
||||
} else return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (local != null) {
|
||||
return local.getName();
|
||||
} else return name;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public InetSocketAddress getAddress() {
|
||||
if (local != null) {
|
||||
return local.getAddress();
|
||||
} else return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the proxy this player is connected to.
|
||||
*
|
||||
* @return the proxy this player is connected to
|
||||
*/
|
||||
public Proxy getProxy() {
|
||||
if (local != null) {
|
||||
return SubAPI.getInstance().getMasterProxy();
|
||||
} else return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProxyName() {
|
||||
Proxy proxy = getProxy();
|
||||
return (proxy == null)? null : proxy.getName();
|
||||
}
|
||||
|
||||
private SubDataClient getProxyConnection() {
|
||||
Proxy proxy = getProxy();
|
||||
return (proxy == null)? null : (SubDataClient) proxy.getSubData()[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server getServer() {
|
||||
return server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerName() {
|
||||
Server server = getServer();
|
||||
return (server == null)? null : server.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof RemotePlayer && getUniqueId().equals(((RemotePlayer) obj).getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> pinfo = new ObjectMap<String>();
|
||||
pinfo.set("name", getName());
|
||||
pinfo.set("id", getUniqueId());
|
||||
pinfo.set("address", getAddress().getAddress().getHostAddress() + ':' + getAddress().getPort());
|
||||
if (getServer() != null) pinfo.set("server", getServer().getName());
|
||||
if (getProxy() != null) pinfo.set("proxy", getProxy().getName());
|
||||
return pinfo;
|
||||
}
|
||||
|
||||
static {
|
||||
// These overrides provide for the static methods in BungeeCommon
|
||||
new RPSI() {
|
||||
@Override
|
||||
protected void sendMessage(UUID[] players, String[] messages, IntConsumer response) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
PacketMessagePlayer.run(Arrays.asList(players), new ContainedPair<>(messages, null), null, i -> {
|
||||
try {
|
||||
response.accept(i);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
PacketMessagePlayer.run(Arrays.asList(players), new ContainedPair<>(null, messages), null, i -> {
|
||||
try {
|
||||
response.accept(i);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void transfer(UUID[] players, String server, IntConsumer response) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
PacketTransferPlayer.run(Arrays.asList(players), server, i -> {
|
||||
try {
|
||||
response.accept(i);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disconnect(UUID[] players, String reason, IntConsumer response) {
|
||||
StackTraceElement[] origin = new Throwable().getStackTrace();
|
||||
PacketDisconnectPlayer.run(Arrays.asList(players), reason, i -> {
|
||||
try {
|
||||
response.accept(i);
|
||||
} catch (Throwable e) {
|
||||
Throwable ew = new InvocationTargetException(e);
|
||||
ew.setStackTrace(origin);
|
||||
ew.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// The following methods all redirect to their BungeeCommon counterparts
|
||||
public static void broadcastMessage(String... messages) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(String message, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message, response);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(String[] messages, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages, response);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, String... messages) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, String message, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message, response);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, String[] messages, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages, response);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(BaseComponent... message) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(BaseComponent message, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message, response);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(BaseComponent[] message, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(message, response);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(BaseComponent[]... messages) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages);
|
||||
}
|
||||
|
||||
public static void broadcastMessage(BaseComponent[][] messages, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.broadcastMessage(messages, response);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, BaseComponent... message) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, BaseComponent message, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message, response);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, BaseComponent[] message, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, message, response);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, BaseComponent[]... messages) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages);
|
||||
}
|
||||
|
||||
public static void sendMessage(UUID[] players, BaseComponent[][] messages, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.sendMessage(players, messages, response);
|
||||
}
|
||||
|
||||
public static void transfer(UUID[] players, String server) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server);
|
||||
}
|
||||
|
||||
public static void transfer(UUID[] players, String server, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server, response);
|
||||
}
|
||||
|
||||
public static void transfer(UUID[] players, ServerInfo server) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server);
|
||||
}
|
||||
|
||||
public static void transfer(UUID[] players, ServerInfo server, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.transfer(players, server, response);
|
||||
}
|
||||
|
||||
public static void disconnect(UUID... players) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players);
|
||||
}
|
||||
|
||||
public static void disconnect(UUID[] players, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players, response);
|
||||
}
|
||||
|
||||
public static void disconnect(UUID[] players, String reason) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players, reason);
|
||||
}
|
||||
|
||||
public static void disconnect(UUID[] players, String reason, IntConsumer response) {
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.RemotePlayer.disconnect(players, reason, response);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.ExtraDataHandler;
|
||||
import net.ME1312.SubData.Server.ClientHandler;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.ExtraDataHandler;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Network.ClientHandler;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -13,15 +12,7 @@ import java.util.UUID;
|
|||
/**
|
||||
* Server Interface
|
||||
*/
|
||||
public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler<String> {
|
||||
|
||||
/**
|
||||
* Link a SubData Client to this Object
|
||||
*
|
||||
* @param client Client to Link
|
||||
* @param channel Channel ID
|
||||
*/
|
||||
void setSubData(DataClient client, int channel);
|
||||
public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler {
|
||||
|
||||
/**
|
||||
* Get the Display Name of this Server
|
||||
|
@ -58,40 +49,12 @@ public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler<Stri
|
|||
*/
|
||||
void removeGroup(String value);
|
||||
|
||||
/**
|
||||
* Commands the Server
|
||||
*
|
||||
* @param player Player who's Commanding
|
||||
* @param target Player who will Send
|
||||
* @param command Command to Send
|
||||
*/
|
||||
boolean command(UUID player, UUID target, String command);
|
||||
|
||||
/**
|
||||
* Commands the Server
|
||||
*
|
||||
* @param player Player who's Commanding
|
||||
* @param command Command to Send
|
||||
*/
|
||||
default boolean command(UUID player, String command) {
|
||||
return command(player, null, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commands the Server
|
||||
*
|
||||
* @param command Command to Send
|
||||
*/
|
||||
default boolean command(String command) {
|
||||
return command(null, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get players on this server across all known proxies
|
||||
*
|
||||
* @return Remote Player Collection
|
||||
* @return Player Collection
|
||||
*/
|
||||
Collection<RemotePlayer> getRemotePlayers();
|
||||
Collection<NamedContainer<String, UUID>> getGlobalPlayers();
|
||||
|
||||
/**
|
||||
* If the server is hidden from players
|
||||
|
@ -135,40 +98,6 @@ public interface Server extends ServerInfo, ClientHandler, ExtraDataHandler<Stri
|
|||
*/
|
||||
void setRestricted(boolean value);
|
||||
|
||||
/**
|
||||
* Get a copy of the current whitelist
|
||||
*
|
||||
* @return Player Whitelist
|
||||
*/
|
||||
Collection<UUID> getWhitelist();
|
||||
|
||||
/**
|
||||
* See if a player is whitelisted
|
||||
*
|
||||
* @param player Player to check
|
||||
* @return Whitelisted Status
|
||||
*/
|
||||
boolean isWhitelisted(UUID player);
|
||||
|
||||
/**
|
||||
* Add a player to the whitelist (for use with restricted servers)
|
||||
*
|
||||
* @param player Player to add
|
||||
*/
|
||||
void whitelist(UUID player);
|
||||
|
||||
/**
|
||||
* Remove a player to the whitelist
|
||||
*
|
||||
* @param player Player to remove
|
||||
*/
|
||||
void unwhitelist(UUID player);
|
||||
|
||||
/**
|
||||
* Makes it so the server object will still exist within the server manager even if it is disconnected
|
||||
*/
|
||||
void persist();
|
||||
|
||||
/**
|
||||
* Get the Signature of this Object
|
||||
*
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Event.SubEditServerEvent;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubNetworkConnectEvent;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubNetworkDisconnectEvent;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutRunEvent;
|
||||
import net.ME1312.SubServers.Bungee.Network.SubDataServer;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
import net.md_5.bungee.BungeeServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Server Class
|
||||
*/
|
||||
public class ServerContainer extends BungeeServerInfo implements Server {
|
||||
private YAMLSection extra = new YAMLSection();
|
||||
private final String signature;
|
||||
private Client client = null;
|
||||
private List<String> groups = new ArrayList<String>();
|
||||
private String nick = null;
|
||||
private boolean hidden;
|
||||
|
||||
public ServerContainer(String name, InetSocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(name, address, motd, restricted);
|
||||
if (Util.isNull(name, address, motd, hidden, restricted)) throw new NullPointerException();
|
||||
if (name.contains(" ")) throw new InvalidServerException("Server names cannot have spaces: " + name);
|
||||
signature = SubAPI.getInstance().signAnonymousObject();
|
||||
SubDataServer.allowConnection(getAddress().getAddress().getHostAddress());
|
||||
this.hidden = hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Client getSubData() {
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSubData(Client client) {
|
||||
this.client = client;
|
||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData() != null) {
|
||||
YAMLSection args = new YAMLSection();
|
||||
args.set("server", getName());
|
||||
if (client != null) args.set("address", client.getAddress().toString());
|
||||
proxy.getSubData().sendPacket(new PacketOutRunEvent((client != null)?SubNetworkConnectEvent.class:SubNetworkDisconnectEvent.class, args));
|
||||
}
|
||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) client.setHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return (nick == null)?getName():nick;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setDisplayName(String value) {
|
||||
if (value == null || value.length() == 0 || getName().equals(value)) {
|
||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("display", getName()), false));
|
||||
this.nick = null;
|
||||
} else {
|
||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("display", value), false));
|
||||
this.nick = value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addGroup(String value) {
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
if (value.length() > 0 && !groups.contains(value)) {
|
||||
groups.add(value);
|
||||
Collections.sort(groups);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void removeGroup(String value) {
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
groups.remove(value);
|
||||
Collections.sort(groups);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
@Override
|
||||
public Collection<NamedContainer<String, UUID>> getGlobalPlayers() {
|
||||
List<NamedContainer<String, UUID>> players = new ArrayList<NamedContainer<String, UUID>>();
|
||||
SubPlugin plugin = SubAPI.getInstance().getInternals();
|
||||
if (plugin.redis != null) {
|
||||
try {
|
||||
for (UUID player : (Set<UUID>) plugin.redis("getPlayersOnServer", new NamedContainer<>(String.class, getName()))) players.add(new NamedContainer<>((String) plugin.redis("getNameFromUuid", new NamedContainer<>(UUID.class, player)), player));
|
||||
} catch (Exception e) {}
|
||||
} else {
|
||||
for (ProxiedPlayer player : getPlayers()) players.add(new NamedContainer<>(player.getName(), player.getUniqueId()));
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setHidden(boolean value) {
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("hidden", value), false));
|
||||
this.hidden = value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setMotd(String value) {
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("motd", value), false));
|
||||
try {
|
||||
Field f = BungeeServerInfo.class.getDeclaredField("motd");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value);
|
||||
f.setAccessible(false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setRestricted(boolean value) {
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
SubAPI.getInstance().getInternals().getPluginManager().callEvent(new SubEditServerEvent(null, this, new NamedContainer<String, Object>("restricted", value), false));
|
||||
try {
|
||||
Field f = BungeeServerInfo.class.getDeclaredField("restricted");
|
||||
f.setAccessible(true);
|
||||
f.set(this, value);
|
||||
f.setAccessible(false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtra(String handle, Object value) {
|
||||
if (Util.isNull(handle, value)) throw new NullPointerException();
|
||||
extra.set(handle, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasExtra(String handle) {
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
return extra.getKeys().contains(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YAMLValue getExtra(String handle) {
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
return extra.get(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YAMLSection getExtra() {
|
||||
return extra.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtra(String handle) {
|
||||
if (Util.isNull(handle)) throw new NullPointerException();
|
||||
extra.remove(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
YAMLSection info = new YAMLSection();
|
||||
info.set("type", "Server");
|
||||
info.set("name", getName());
|
||||
info.set("display", getDisplayName());
|
||||
info.set("group", getGroups());
|
||||
info.set("address", getAddress().getAddress().getHostAddress() + ':' + getAddress().getPort());
|
||||
info.set("motd", getMotd());
|
||||
info.set("restricted", isRestricted());
|
||||
info.set("hidden", isHidden());
|
||||
if (getSubData() != null) info.set("subdata", getSubData().getAddress().toString());
|
||||
YAMLSection players = new YAMLSection();
|
||||
for (NamedContainer<String, UUID> player : getGlobalPlayers()) {
|
||||
YAMLSection pinfo = new YAMLSection();
|
||||
pinfo.set("name", player.name());
|
||||
players.set(player.get().toString(), pinfo);
|
||||
}
|
||||
info.set("players", players);
|
||||
if (getSubData() != null) info.set("subdata", getSubData().getAddress().toString());
|
||||
info.set("signature", signature);
|
||||
info.set("extra", getExtra());
|
||||
return info.toJSON();
|
||||
}
|
||||
}
|
|
@ -1,344 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.DataClient;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Event.SubSendCommandEvent;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer.LoggedCommand;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExControlPlayer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExEditServer.Edit;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import net.md_5.bungee.BungeeServerInfo;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Server Class
|
||||
*/
|
||||
public class ServerImpl extends BungeeServerInfo implements Server {
|
||||
private HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
|
||||
private ObjectMap<String> extra = new ObjectMap<String>();
|
||||
private String nick = null;
|
||||
private List<String> groups = new ArrayList<String>();
|
||||
private List<UUID> whitelist = new ArrayList<UUID>();
|
||||
private boolean hidden;
|
||||
private final String signature = SubAPI.getInstance().signAnonymousObject();
|
||||
private volatile boolean persistent = true;
|
||||
|
||||
/**
|
||||
* Construct a new Server data type
|
||||
*
|
||||
* @param name Server name
|
||||
* @param address Server Address
|
||||
* @param motd Server MOTD
|
||||
* @param hidden Hidden Status
|
||||
* @param restricted Restricted Status
|
||||
* @return
|
||||
*/
|
||||
public static ServerImpl construct(String name, SocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
try {
|
||||
return new ServerImpl(name, address, motd, hidden, restricted);
|
||||
} catch (NoSuchMethodError e) {
|
||||
return new ServerImpl(name, (InetSocketAddress) address, motd, hidden, restricted);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Super Method 2 (newest)
|
||||
* @see #construct(String, SocketAddress, String, boolean, boolean) for method details
|
||||
*/
|
||||
protected ServerImpl(String name, SocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(name, address, motd, restricted);
|
||||
init(name, address, motd, hidden, restricted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Super Method 1 (oldest)
|
||||
* @see #construct(String, SocketAddress, String, boolean, boolean) for method details
|
||||
*/
|
||||
protected ServerImpl(String name, InetSocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(name, address, motd, restricted);
|
||||
init(name, address, motd, hidden, restricted);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void init(String name, SocketAddress address, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
Util.nullpo(name, address, motd, hidden, restricted);
|
||||
if (name.contains(" ")) throw new InvalidServerException("Server names cannot have spaces: " + name);
|
||||
SubAPI.getInstance().getInternals().subprotocol.whitelist(getAddress().getAddress().getHostAddress());
|
||||
this.hidden = hidden;
|
||||
|
||||
subdata.put(0, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if this server has been registered
|
||||
*
|
||||
* @return Registered status
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
protected boolean isRegistered() {
|
||||
return SubAPI.getInstance().getInternals().exServers.containsKey(getName().toLowerCase());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataClient[] getSubData() {
|
||||
Integer[] keys = subdata.keySet().toArray(new Integer[0]);
|
||||
DataClient[] channels = new DataClient[keys.length];
|
||||
Arrays.sort(keys);
|
||||
for (int i = 0; i < keys.length; ++i) channels[i] = subdata.get(keys[i]);
|
||||
return channels;
|
||||
}
|
||||
|
||||
public void setSubData(DataClient client, int channel) {
|
||||
boolean update = false;
|
||||
if (channel < 0) throw new IllegalArgumentException("Subchannel ID cannot be less than zero");
|
||||
if (client != null || channel == 0) {
|
||||
if (!subdata.containsKey(channel) || (channel == 0 && (client == null || subdata.get(channel) == null))) {
|
||||
update = true;
|
||||
subdata.put(channel, (SubDataClient) client);
|
||||
if (client != null && (client.getHandler() == null || !equals(client.getHandler()))) ((SubDataClient) client).setHandler(this);
|
||||
}
|
||||
} else {
|
||||
update = true;
|
||||
subdata.remove(channel);
|
||||
}
|
||||
|
||||
if (update) {
|
||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
if (client != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.CONNECTED, channel, client.getID()));
|
||||
} else {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.DISCONNECTED, channel));
|
||||
}
|
||||
}
|
||||
if (!persistent) {
|
||||
DataClient[] subdata = getSubData();
|
||||
if (subdata[0] == null && subdata.length <= 1) {
|
||||
SubAPI.getInstance().removeServer(getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubData(DataClient client) {
|
||||
for (Integer channel : Util.getBackwards(subdata, (SubDataClient) client)) setSubData(null, channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return (nick == null)?getName():nick;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setDisplayName(String value) {
|
||||
if (value == null || value.length() == 0 || getName().equals(value)) {
|
||||
this.nick = null;
|
||||
} else {
|
||||
this.nick = value;
|
||||
}
|
||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.DISPLAY_NAME, getDisplayName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addGroup(String value) {
|
||||
Util.nullpo(value);
|
||||
if (value.length() > 0 && !groups.contains(value)) {
|
||||
groups.add(value);
|
||||
Collections.sort(groups);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public void removeGroup(String value) {
|
||||
Util.nullpo(value);
|
||||
groups.remove(value);
|
||||
Collections.sort(groups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean command(UUID player, UUID target, String command) {
|
||||
Util.nullpo(command);
|
||||
SubDataClient channel = (SubDataClient) getSubData()[0];
|
||||
if (channel != null) {
|
||||
SubSendCommandEvent event = new SubSendCommandEvent(player, this, command, target);
|
||||
ProxyServer.getInstance().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled() && (player == null || !SubServerImpl.DISALLOWED_COMMANDS.matcher(command).find())) {
|
||||
channel.sendPacket(new PacketExControlPlayer(target, command));
|
||||
return true;
|
||||
} else return false;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<RemotePlayer> getRemotePlayers() {
|
||||
return SubAPI.getInstance().getRemotePlayers(this).values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHidden(boolean value) {
|
||||
this.hidden = value;
|
||||
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.HIDDEN, isHidden()));
|
||||
}
|
||||
}
|
||||
|
||||
public void setMotd(String value) {
|
||||
Util.nullpo(value);
|
||||
try {
|
||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("motd"), this, value);
|
||||
for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.MOTD, getMotd()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRestricted(boolean value) {
|
||||
Util.nullpo(value);
|
||||
try {
|
||||
Util.reflect(BungeeServerInfo.class.getDeclaredField("restricted"), this, value);
|
||||
|
||||
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.RESTRICTED, isRestricted()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if a player can access this server
|
||||
*
|
||||
* @param player Player
|
||||
* @return Whitelisted Status
|
||||
*/
|
||||
@Override
|
||||
public boolean canAccess(CommandSender player) {
|
||||
return super.canAccess(player) || (player instanceof ProxiedPlayer && whitelist.contains(((ProxiedPlayer) player).getUniqueId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<UUID> getWhitelist() {
|
||||
return new ArrayList<UUID>(whitelist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(UUID player) {
|
||||
return whitelist.contains(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whitelist(UUID player) {
|
||||
Util.nullpo(player);
|
||||
if (!whitelist.contains(player)) whitelist.add(player);
|
||||
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_ADD, player));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unwhitelist(UUID player) {
|
||||
Util.nullpo(player);
|
||||
whitelist.remove(player);
|
||||
if (isRegistered()) for (Proxy proxy : SubAPI.getInstance().getProxies().values()) if (proxy.getSubData()[0] != null) {
|
||||
((SubDataClient) proxy.getSubData()[0]).sendPacket(new PacketOutExEditServer(this, Edit.WHITELIST_REMOVE, player));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void persist() {
|
||||
persistent = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof ServerImpl && signature.equals(((ServerImpl) obj).signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addExtra(String handle, Object value) {
|
||||
Util.nullpo(handle, value);
|
||||
extra.set(handle, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
return extra.getKeys().contains(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapValue getExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
return extra.get(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> getExtra() {
|
||||
return extra.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeExtra(String handle) {
|
||||
Util.nullpo(handle);
|
||||
extra.remove(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> info = new ObjectMap<String>();
|
||||
info.set("type", "Server");
|
||||
info.set("name", getName());
|
||||
info.set("display", getDisplayName());
|
||||
info.set("group", getGroups());
|
||||
info.set("address", getAddress().getAddress().getHostAddress() + ':' + getAddress().getPort());
|
||||
info.set("motd", getMotd());
|
||||
info.set("whitelist", getWhitelist());
|
||||
info.set("restricted", isRestricted());
|
||||
info.set("hidden", isHidden());
|
||||
ObjectMap<String> players = new ObjectMap<String>();
|
||||
for (RemotePlayer player : getRemotePlayers())
|
||||
players.set(player.getUniqueId().toString(), player.getName());
|
||||
info.set("players", players);
|
||||
ObjectMap<Integer> subdata = new ObjectMap<Integer>();
|
||||
for (int channel : this.subdata.keySet()) subdata.set(channel, (this.subdata.get(channel) == null)?null:this.subdata.get(channel).getID());
|
||||
info.set("subdata", subdata);
|
||||
info.set("signature", signature);
|
||||
info.set("extra", getExtra());
|
||||
return info;
|
||||
}
|
||||
}
|
|
@ -1,60 +1,49 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Library.Callback;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidTemplateException;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* SubCreator Layout Class
|
||||
*/
|
||||
public abstract class SubCreator {
|
||||
public static class ServerTemplate {
|
||||
private final boolean dynamic;
|
||||
private String name;
|
||||
private String nick = null;
|
||||
private boolean enabled;
|
||||
private boolean internal;
|
||||
private String icon;
|
||||
private File directory;
|
||||
private ServerType type;
|
||||
private ObjectMap<String> build;
|
||||
private ObjectMap<String> options;
|
||||
private YAMLSection build;
|
||||
private YAMLSection options;
|
||||
|
||||
/**
|
||||
* Create a SubCreator Template
|
||||
*
|
||||
* @param name Template Name
|
||||
* @param enabled Template Enabled Status
|
||||
* @param icon Template Item Icon Name
|
||||
* @param directory Template Directory
|
||||
* @param build Build Options
|
||||
* @param options Configuration Options
|
||||
*/
|
||||
public ServerTemplate(String name, boolean enabled, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
|
||||
this(name, enabled, false, icon, directory, build, options, true);
|
||||
}
|
||||
|
||||
private ServerTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options, boolean dynamic) {
|
||||
Util.nullpo(name, enabled, directory, build, options);
|
||||
public ServerTemplate(String name, boolean enabled, String icon, File directory, YAMLSection build, YAMLSection options) {
|
||||
if (Util.isNull(name, enabled, directory, build, options)) throw new NullPointerException();
|
||||
if (name.contains(" ")) throw new InvalidTemplateException("Template names cannot have spaces: " + name);
|
||||
this.name = name;
|
||||
this.enabled = enabled;
|
||||
this.internal = internal;
|
||||
this.icon = icon;
|
||||
this.directory = directory;
|
||||
this.type = (build.contains("Server-Type"))?ServerType.valueOf(build.getString("Server-Type").toUpperCase()):ServerType.CUSTOM;
|
||||
this.type = (build.contains("Server-Type"))?ServerType.valueOf(build.getRawString("Server-Type").toUpperCase()):ServerType.CUSTOM;
|
||||
this.build = build;
|
||||
this.options = options;
|
||||
this.dynamic = dynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,15 +95,6 @@ public abstract class SubCreator {
|
|||
enabled = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if this Template is for Internal use only
|
||||
*
|
||||
* @return Internal Status
|
||||
*/
|
||||
public boolean isInternal() {
|
||||
return internal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Item Icon for this Template
|
||||
*
|
||||
|
@ -151,39 +131,12 @@ public abstract class SubCreator {
|
|||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this Template requires the Version argument
|
||||
*
|
||||
* @return Version Requirement
|
||||
*/
|
||||
public boolean requiresVersion() {
|
||||
return getBuildOptions().getBoolean("Require-Version", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this Template can be used to update it's servers
|
||||
*
|
||||
* @return Updatable Status
|
||||
*/
|
||||
public boolean canUpdate() {
|
||||
return getBuildOptions().getBoolean("Can-Update", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this Template was generated by a SubCreator instance
|
||||
*
|
||||
* @return Dynamic Status
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Build Options for this Template
|
||||
*
|
||||
* @return Build Options
|
||||
*/
|
||||
public ObjectMap<String> getBuildOptions() {
|
||||
public YAMLSection getBuildOptions() {
|
||||
return build;
|
||||
}
|
||||
|
||||
|
@ -192,21 +145,19 @@ public abstract class SubCreator {
|
|||
*
|
||||
* @return Configuration Options
|
||||
*/
|
||||
public ObjectMap<String> getConfigOptions() {
|
||||
public YAMLSection getConfigOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> tinfo = new ObjectMap<String>();
|
||||
@Override
|
||||
public String toString() {
|
||||
YAMLSection tinfo = new YAMLSection();
|
||||
tinfo.set("enabled", isEnabled());
|
||||
tinfo.set("name", getName());
|
||||
tinfo.set("display", getDisplayName());
|
||||
tinfo.set("icon", getIcon());
|
||||
tinfo.set("type", getType().toString());
|
||||
tinfo.set("version-req", requiresVersion());
|
||||
tinfo.set("can-update", canUpdate());
|
||||
return tinfo;
|
||||
return tinfo.toJSON();
|
||||
}
|
||||
}
|
||||
public enum ServerType {
|
||||
|
@ -228,12 +179,11 @@ public abstract class SubCreator {
|
|||
* @param player Player Creating
|
||||
* @param name Server Name
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @param version Server Version
|
||||
* @param port Server Port Number (null to auto-select)
|
||||
* @param callback Callback
|
||||
* @return Success Status
|
||||
*/
|
||||
public abstract boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback);
|
||||
public abstract boolean create(UUID player, String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback);
|
||||
|
||||
/**
|
||||
* Create a SubServer
|
||||
|
@ -241,7 +191,7 @@ public abstract class SubCreator {
|
|||
* @param player Player Creating
|
||||
* @param name Server Name
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @param version Server Version
|
||||
* @param port Server Port Number (null to auto-select)
|
||||
* @return Success Status
|
||||
*/
|
||||
|
@ -254,12 +204,11 @@ public abstract class SubCreator {
|
|||
*
|
||||
* @param name Server Name
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @param version Server Version
|
||||
* @param port Server Port Number (null to auto-select)
|
||||
* @param callback Callback
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean create(String name, ServerTemplate template, Version version, Integer port, Consumer<SubServer> callback) {
|
||||
public boolean create(String name, ServerTemplate template, Version version, Integer port, Callback<SubServer> callback) {
|
||||
return create(null, name, template, version, port, callback);
|
||||
}
|
||||
|
||||
|
@ -268,7 +217,7 @@ public abstract class SubCreator {
|
|||
*
|
||||
* @param name Server Name
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @param version Server Version
|
||||
* @param port Server Port Number (null to auto-select)
|
||||
* @return Success Status
|
||||
*/
|
||||
|
@ -276,79 +225,6 @@ public abstract class SubCreator {
|
|||
return create(null, name, template, version, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a SubServer
|
||||
*
|
||||
* @param player Player Updating
|
||||
* @param server Server to Update
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @param callback Callback
|
||||
* @return Success Status
|
||||
*/
|
||||
public abstract boolean update(UUID player, SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback);
|
||||
|
||||
/**
|
||||
* Update a SubServer
|
||||
*
|
||||
* @param player Player Updating
|
||||
* @param server Server to Update
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean update(UUID player, SubServer server, ServerTemplate template, Version version) {
|
||||
return update(player, server, template, version, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a SubServer
|
||||
*
|
||||
* @param server Server to Update
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @param callback Callback
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean update(SubServer server, ServerTemplate template, Version version, Consumer<Boolean> callback) {
|
||||
return update(null, server, template, version, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a SubServer
|
||||
*
|
||||
* @param server Server to Update
|
||||
* @param template Server Template
|
||||
* @param version Server Version (may be null)
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean update(SubServer server, ServerTemplate template, Version version) {
|
||||
return update(null, server, template, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a SubServer
|
||||
*
|
||||
* @param player Player Updating
|
||||
* @param server Server to Update
|
||||
* @param version Server Version (may be null)
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean update(UUID player, SubServer server, Version version) {
|
||||
return update(player, server, null, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a SubServer
|
||||
*
|
||||
* @param server Server to Update
|
||||
* @param version Server Version (may be null)
|
||||
* @return Success Status
|
||||
*/
|
||||
public boolean update(SubServer server, Version version) {
|
||||
return update(null, server, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate All SubCreator Instances on this host
|
||||
*/
|
||||
|
@ -383,20 +259,6 @@ public abstract class SubCreator {
|
|||
*/
|
||||
public abstract Host getHost();
|
||||
|
||||
/**
|
||||
* Get the range of available port numbers
|
||||
*
|
||||
* @return Port Range
|
||||
*/
|
||||
public abstract Range getPortRange();
|
||||
|
||||
/**
|
||||
* Get the range of available port numbers
|
||||
*
|
||||
* @param value Value
|
||||
*/
|
||||
public abstract void setPortRange(Range<Integer> value);
|
||||
|
||||
/**
|
||||
* Gets the Git Bash install directory
|
||||
*
|
||||
|
@ -419,20 +281,6 @@ public abstract class SubCreator {
|
|||
*/
|
||||
public abstract SubLogger getLogger(String thread);
|
||||
|
||||
/**
|
||||
* If the Creator is Logging to console
|
||||
*
|
||||
* @return Logging Status
|
||||
*/
|
||||
public abstract boolean isLogging();
|
||||
|
||||
/**
|
||||
* Set if the Creator is Logging
|
||||
*
|
||||
* @param value Value
|
||||
*/
|
||||
public abstract void setLogging(boolean value);
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of currently reserved Server names
|
||||
|
@ -518,28 +366,8 @@ public abstract class SubCreator {
|
|||
*/
|
||||
public abstract ServerTemplate getTemplate(String name);
|
||||
|
||||
/**
|
||||
* Create a SubCreator Template
|
||||
*
|
||||
* @param name Template Name
|
||||
* @param enabled Template Enabled Status
|
||||
* @param internal Template Internal Status
|
||||
* @param icon Template Item Icon Name
|
||||
* @param directory Template Directory
|
||||
* @param build Build Options
|
||||
* @param options Configuration Options
|
||||
*/
|
||||
protected ServerTemplate loadTemplate(String name, boolean enabled, boolean internal, String icon, File directory, ObjectMap<String> build, ObjectMap<String> options) {
|
||||
return new ServerTemplate(name, enabled, internal, icon, directory, build, options, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload SubCreator
|
||||
*/
|
||||
public abstract void reload();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof SubCreator && getHost().getSignature().equals(((SubCreator) obj).getHost().getSignature());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,91 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* SubLogger Layout Class
|
||||
*/
|
||||
public abstract class SubLogger {
|
||||
/**
|
||||
* Log Message Storage Class
|
||||
*/
|
||||
public static class LogMessage {
|
||||
private Date date;
|
||||
private Level level;
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* Store a Message
|
||||
*
|
||||
* @param message Message
|
||||
*/
|
||||
public LogMessage(String message) {
|
||||
if (Util.isNull(message)) throw new NullPointerException();
|
||||
this.date = Calendar.getInstance().getTime();
|
||||
this.level = Level.INFO;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a Message
|
||||
*
|
||||
* @param level Log Level
|
||||
* @param message Message
|
||||
*/
|
||||
public LogMessage(Level level, String message) {
|
||||
if (Util.isNull(level, message)) throw new NullPointerException();
|
||||
this.date = Calendar.getInstance().getTime();
|
||||
this.level = level;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a Message
|
||||
*
|
||||
* @param date Date
|
||||
* @param level Log Level
|
||||
* @param message Message
|
||||
*/
|
||||
public LogMessage(Date date, Level level, String message) {
|
||||
if (Util.isNull(date, level, message)) throw new NullPointerException();
|
||||
this.date = date;
|
||||
this.level = level;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date this message was logged
|
||||
*
|
||||
* @return Date
|
||||
*/
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the level this message was logged on
|
||||
*
|
||||
* @return Log Level
|
||||
*/
|
||||
public Level getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message
|
||||
*
|
||||
* @return Message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the Name of the task logging
|
||||
|
@ -36,6 +118,13 @@ public abstract class SubLogger {
|
|||
*/
|
||||
public abstract boolean isLogging();
|
||||
|
||||
/**
|
||||
* Gets a list of all the messages logged by this logger
|
||||
*
|
||||
* @return Log Messages (named by log level)
|
||||
*/
|
||||
public abstract List<LogMessage> getMessageHistory();
|
||||
|
||||
/**
|
||||
* Register Filter
|
||||
*
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -18,7 +17,6 @@ public interface SubServer extends Server {
|
|||
NONE,
|
||||
RESTART,
|
||||
REMOVE_SERVER,
|
||||
RECYCLE_SERVER,
|
||||
DELETE_SERVER;
|
||||
|
||||
@Override
|
||||
|
@ -41,7 +39,7 @@ public interface SubServer extends Server {
|
|||
* @param command Command
|
||||
*/
|
||||
public LoggedCommand(String command) {
|
||||
Util.nullpo(command);
|
||||
if (Util.isNull(command)) throw new NullPointerException();
|
||||
this.date = Calendar.getInstance().getTime();
|
||||
this.sender = null;
|
||||
this.command = command;
|
||||
|
@ -54,7 +52,7 @@ public interface SubServer extends Server {
|
|||
* @param command Command
|
||||
*/
|
||||
public LoggedCommand(UUID sender, String command) {
|
||||
Util.nullpo(command);
|
||||
if (Util.isNull(command)) throw new NullPointerException();
|
||||
this.date = Calendar.getInstance().getTime();
|
||||
this.sender = sender;
|
||||
this.command = command;
|
||||
|
@ -68,7 +66,7 @@ public interface SubServer extends Server {
|
|||
* @param command Command
|
||||
*/
|
||||
public LoggedCommand(Date date, UUID sender, String command) {
|
||||
Util.nullpo(date, command);
|
||||
if (Util.isNull(date, command)) throw new NullPointerException();
|
||||
this.date = date;
|
||||
this.sender = sender;
|
||||
this.command = command;
|
||||
|
@ -115,9 +113,7 @@ public interface SubServer extends Server {
|
|||
*
|
||||
* @return Success Status
|
||||
*/
|
||||
default boolean start() {
|
||||
return start(null);
|
||||
}
|
||||
boolean start();
|
||||
|
||||
/**
|
||||
* Stops the Server
|
||||
|
@ -132,9 +128,7 @@ public interface SubServer extends Server {
|
|||
*
|
||||
* @return Success Status
|
||||
*/
|
||||
default boolean stop() {
|
||||
return stop(null);
|
||||
}
|
||||
boolean stop();
|
||||
|
||||
/**
|
||||
* Terminates the Server
|
||||
|
@ -149,9 +143,24 @@ public interface SubServer extends Server {
|
|||
*
|
||||
* @return Success Status
|
||||
*/
|
||||
default boolean terminate() {
|
||||
return terminate(null);
|
||||
}
|
||||
boolean terminate();
|
||||
|
||||
/**
|
||||
* Commands the Server
|
||||
*
|
||||
* @param player Player who Commanded
|
||||
* @param command Command to Send
|
||||
* @return Success Status
|
||||
*/
|
||||
boolean command(UUID player, String command);
|
||||
|
||||
/**
|
||||
* Commands the Server
|
||||
*
|
||||
* @param command Command to Send
|
||||
* @return Success Status
|
||||
*/
|
||||
boolean command(String command);
|
||||
|
||||
/**
|
||||
* Edits the Server
|
||||
|
@ -160,7 +169,7 @@ public interface SubServer extends Server {
|
|||
* @param edit Edits
|
||||
* @return Success Status
|
||||
*/
|
||||
default int edit(UUID player, ObjectMap<String> edit) {
|
||||
default int edit(UUID player, YAMLSection edit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -170,31 +179,10 @@ public interface SubServer extends Server {
|
|||
* @param edit Edits
|
||||
* @return Success Status
|
||||
*/
|
||||
default int edit(ObjectMap<String> edit) {
|
||||
return edit(null, edit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the Server (& Saves Changes)
|
||||
*
|
||||
* @param player Player Editing
|
||||
* @param edit Edits
|
||||
* @return Success Status
|
||||
*/
|
||||
default int permaEdit(UUID player, ObjectMap<String> edit) {
|
||||
default int edit(YAMLSection edit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the Server (& Saves Changes)
|
||||
*
|
||||
* @param edit Edits
|
||||
* @return Success Status
|
||||
*/
|
||||
default int permaEdit(ObjectMap<String> edit) {
|
||||
return permaEdit(null, edit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the Server to Stop
|
||||
*
|
||||
|
@ -209,22 +197,6 @@ public interface SubServer extends Server {
|
|||
*/
|
||||
boolean isRunning();
|
||||
|
||||
/**
|
||||
* If the Server is Online<br>
|
||||
* <b>This method can only be true when a SubData connection is made!</b>
|
||||
*
|
||||
* @return Online Status
|
||||
*/
|
||||
boolean isOnline();
|
||||
|
||||
/**
|
||||
* If the Server is Stopping<br>
|
||||
* <b>This method can only be true when the server is stopped through the server manager!</b>
|
||||
*
|
||||
* @return Stopping Status
|
||||
*/
|
||||
boolean isStopping();
|
||||
|
||||
/**
|
||||
* Grabs the Host of the Server
|
||||
*
|
||||
|
@ -232,34 +204,6 @@ public interface SubServer extends Server {
|
|||
*/
|
||||
Host getHost();
|
||||
|
||||
/**
|
||||
* Grabs the Template this Server was created from
|
||||
*
|
||||
* @return The Template
|
||||
*/
|
||||
SubCreator.ServerTemplate getTemplate();
|
||||
|
||||
/**
|
||||
* Sets the Template this Server was created from
|
||||
*
|
||||
* @param value Value
|
||||
*/
|
||||
void setTemplate(SubCreator.ServerTemplate value);
|
||||
|
||||
/**
|
||||
* Sets the Template this Server was created from
|
||||
*
|
||||
* @param value Value
|
||||
*/
|
||||
void setTemplate(String value);
|
||||
|
||||
/**
|
||||
* Is this Host Available?
|
||||
*
|
||||
* @return Availability Status
|
||||
*/
|
||||
boolean isAvailable();
|
||||
|
||||
/**
|
||||
* If the Server is Enabled
|
||||
*
|
||||
|
@ -277,12 +221,12 @@ public interface SubServer extends Server {
|
|||
/**
|
||||
* If the Server is accepting requests to edit()
|
||||
*
|
||||
* @see #permaEdit(ObjectMap<String>)
|
||||
* @see #permaEdit(UUID, ObjectMap<String>)
|
||||
* @see #edit(YAMLSection)
|
||||
* @see #edit(UUID, YAMLSection)
|
||||
* @return Edit Status
|
||||
*/
|
||||
default boolean isEditable() {
|
||||
return permaEdit(new ObjectMap<String>()) >= 0;
|
||||
return edit(new YAMLSection()) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,16 +267,14 @@ public interface SubServer extends Server {
|
|||
*
|
||||
* @return Full Server Directory Path
|
||||
*/
|
||||
default String getFullPath() {
|
||||
return new File(getHost().getPath(), getPath()).getPath();
|
||||
}
|
||||
String getFullPath();
|
||||
|
||||
/**
|
||||
* Get the Server's Executable String
|
||||
*
|
||||
* @return Executable String
|
||||
*/
|
||||
String getExecutable();
|
||||
Executable getExecutable();
|
||||
|
||||
/**
|
||||
* Grab the Command to Stop the Server
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* SubServer Layout Class
|
||||
*/
|
||||
public abstract class SubServerContainer extends ServerContainer implements SubServer {
|
||||
private List<NamedContainer<String, String>> incompatibilities = new ArrayList<NamedContainer<String, String>>();
|
||||
|
||||
/**
|
||||
* Creates a SubServer
|
||||
*
|
||||
* @param host Host
|
||||
* @param name Server Name
|
||||
* @param port Port Number
|
||||
* @param motd Server MOTD
|
||||
* @param restricted Players will need a permission to join if true
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
public SubServerContainer(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(name, new InetSocketAddress(host.getAddress().getHostAddress(), port), motd, hidden, restricted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return start(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return stop(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean terminate() {
|
||||
return terminate(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean command(String command) {
|
||||
return command(null, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int edit(YAMLSection edit) {
|
||||
return edit(null, edit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullPath() {
|
||||
return new File(getHost().getPath(), getPath()).getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleCompatibility(SubServer... server) {
|
||||
for (SubServer s : server) {
|
||||
if (!equals(s)) {
|
||||
NamedContainer<String, String> info = new NamedContainer<String, String>(s.getHost().getName(), s.getName());
|
||||
if (isCompatible(s)) {
|
||||
incompatibilities.add(info);
|
||||
if (s.isCompatible(this)) toggleCompatibility(this);
|
||||
} else {
|
||||
incompatibilities.remove(info);
|
||||
if (!s.isCompatible(this)) toggleCompatibility(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatible(SubServer server) {
|
||||
return !incompatibilities.contains(new NamedContainer<String, String>(server.getHost().getName(), server.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubServer> getIncompatibilities() {
|
||||
List<SubServer> servers = new ArrayList<SubServer>();
|
||||
List<NamedContainer<String, String>> temp = new ArrayList<NamedContainer<String, String>>();
|
||||
temp.addAll(incompatibilities);
|
||||
for (NamedContainer<String, String> info : temp) {
|
||||
try {
|
||||
SubServer server = SubAPI.getInstance().getHost(info.name()).getSubServer(info.get());
|
||||
if (server == null) throw new NullPointerException();
|
||||
servers.add(server);
|
||||
} catch (Throwable e) {
|
||||
incompatibilities.remove(info);
|
||||
}
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubServer> getCurrentIncompatibilities() {
|
||||
List<SubServer> servers = new ArrayList<SubServer>();
|
||||
for (SubServer server : getIncompatibilities()) {
|
||||
if (server.isRunning()) servers.add(server);
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
@Override
|
||||
public String toString() {
|
||||
YAMLSection sinfo = new YAMLSection(new Gson().fromJson(super.toString(), Map.class));
|
||||
sinfo.set("type", "SubServer");
|
||||
sinfo.set("host", getHost().getName());
|
||||
sinfo.set("enabled", isEnabled());
|
||||
sinfo.set("editable", isEditable());
|
||||
sinfo.set("log", isLogging());
|
||||
sinfo.set("dir", getPath());
|
||||
sinfo.set("exec", getExecutable());
|
||||
sinfo.set("running", isRunning());
|
||||
sinfo.set("stop-cmd", getStopCommand());
|
||||
sinfo.set("stop-action", getStopAction().toString());
|
||||
sinfo.set("auto-run", SubAPI.getInstance().getInternals().config.get().getSection("Servers").getSection(getName(), new YAMLSection()).getBoolean("Run-On-Launch", false));
|
||||
List<String> incompatibleCurrent = new ArrayList<String>();
|
||||
List<String> incompatible = new ArrayList<String>();
|
||||
for (SubServer server : getCurrentIncompatibilities()) incompatibleCurrent.add(server.getName());
|
||||
for (SubServer server : getIncompatibilities()) incompatible.add(server.getName());
|
||||
sinfo.set("incompatible", incompatibleCurrent);
|
||||
sinfo.set("incompatible-list", incompatible);
|
||||
return sinfo.toJSON();
|
||||
}
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* API-Safe SubServer Layout Class
|
||||
*/
|
||||
public abstract class SubServerController {
|
||||
private final SubServerImpl control;
|
||||
private final SubServerContainer control;
|
||||
|
||||
/**
|
||||
* Creates a SubServer
|
||||
|
@ -23,149 +22,132 @@ public abstract class SubServerController {
|
|||
* @throws InvalidServerException
|
||||
*/
|
||||
public SubServerController(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
SubServerImpl control;
|
||||
try {
|
||||
control = new ControlledSubServer(host, name, port, motd, hidden, restricted);
|
||||
} catch (NoSuchMethodError e) {
|
||||
control = new ControlledSubServer(host, name, (Integer) port, motd, hidden, restricted);
|
||||
}
|
||||
this.control = control;
|
||||
}
|
||||
control = new SubServerContainer(host, name, port, motd, hidden, restricted) {
|
||||
@Override
|
||||
public boolean start() {
|
||||
return SubServerController.this.start();
|
||||
}
|
||||
|
||||
private final class ControlledSubServer extends SubServerImpl {
|
||||
public ControlledSubServer(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(host, name, port, motd, hidden, restricted);
|
||||
}
|
||||
@Override
|
||||
public boolean start(UUID player) {
|
||||
return SubServerController.this.start(player);
|
||||
}
|
||||
|
||||
public ControlledSubServer(Host host, String name, Integer port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(host, name, port, motd, hidden, restricted);
|
||||
}
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return SubServerController.this.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
if (SubServerController.this.start()) {
|
||||
started = false;
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
@Override
|
||||
public boolean stop(UUID player) {
|
||||
return SubServerController.this.stop(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start(UUID player) {
|
||||
if (SubServerController.this.start(player)) {
|
||||
started = false;
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
@Override
|
||||
public boolean terminate() {
|
||||
return SubServerController.this.terminate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return SubServerController.this.stop();
|
||||
}
|
||||
@Override
|
||||
public boolean terminate(UUID player) {
|
||||
return SubServerController.this.terminate(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop(UUID player) {
|
||||
return SubServerController.this.stop(player);
|
||||
}
|
||||
@Override
|
||||
public boolean command(String command) {
|
||||
return SubServerController.this.command(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean terminate() {
|
||||
return SubServerController.this.terminate();
|
||||
}
|
||||
@Override
|
||||
public boolean command(UUID player, String command) {
|
||||
return SubServerController.this.command(player, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean terminate(UUID player) {
|
||||
return SubServerController.this.terminate(player);
|
||||
}
|
||||
@Override
|
||||
public int edit(YAMLSection edit) {
|
||||
return SubServerController.this.edit(edit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean command(String command) {
|
||||
return SubServerController.this.command(command);
|
||||
}
|
||||
@Override
|
||||
public int edit(UUID player, YAMLSection edit) {
|
||||
return SubServerController.this.edit(player, edit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean command(UUID player, String command) {
|
||||
return SubServerController.this.command(player, command);
|
||||
}
|
||||
@Override
|
||||
public void waitFor() throws InterruptedException {
|
||||
SubServerController.this.waitFor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||
return SubServerController.this.edit(player, edit, perma);
|
||||
}
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return SubServerController.this.isRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitFor() throws InterruptedException {
|
||||
SubServerController.this.waitFor();
|
||||
}
|
||||
@Override
|
||||
public Host getHost() {
|
||||
return SubServerController.this.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return SubServerController.this.isRunning();
|
||||
}
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return SubServerController.this.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Host getHost() {
|
||||
return SubServerController.this.getHost();
|
||||
}
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
SubServerController.this.setEnabled(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return SubServerController.this.isEnabled();
|
||||
}
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return SubServerController.this.isLogging();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean value) {
|
||||
SubServerController.this.setEnabled(value);
|
||||
}
|
||||
@Override
|
||||
public void setLogging(boolean value) {
|
||||
SubServerController.this.setLogging(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogging() {
|
||||
return SubServerController.this.isLogging();
|
||||
}
|
||||
@Override
|
||||
public SubLogger getLogger() {
|
||||
return SubServerController.this.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogging(boolean value) {
|
||||
SubServerController.this.setLogging(value);
|
||||
}
|
||||
@Override
|
||||
public LinkedList<LoggedCommand> getCommandHistory() {
|
||||
return SubServerController.this.getCommandHistory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubLogger getLogger() {
|
||||
return SubServerController.this.getLogger();
|
||||
}
|
||||
@Override
|
||||
public String getPath() {
|
||||
return SubServerController.this.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedList<LoggedCommand> getCommandHistory() {
|
||||
return SubServerController.this.getCommandHistory();
|
||||
}
|
||||
@Override
|
||||
public Executable getExecutable() {
|
||||
return SubServerController.this.getExecutable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return SubServerController.this.getPath();
|
||||
}
|
||||
@Override
|
||||
public String getStopCommand() {
|
||||
return SubServerController.this.getStopCommand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExecutable() {
|
||||
return SubServerController.this.getExecutable();
|
||||
}
|
||||
@Override
|
||||
public void setStopCommand(String value) {
|
||||
SubServerController.this.setStopCommand(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStopCommand() {
|
||||
return SubServerController.this.getStopCommand();
|
||||
}
|
||||
@Override
|
||||
public StopAction getStopAction() {
|
||||
return SubServerController.this.getStopAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStopCommand(String value) {
|
||||
SubServerController.this.setStopCommand(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StopAction getStopAction() {
|
||||
return SubServerController.this.getStopAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStopAction(StopAction action) {
|
||||
SubServerController.this.setStopAction(action);
|
||||
}
|
||||
@Override
|
||||
public void setStopAction(StopAction action) {
|
||||
SubServerController.this.setStopAction(action);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -231,7 +213,7 @@ public abstract class SubServerController {
|
|||
/**
|
||||
* Commands the Server
|
||||
*
|
||||
* @param player Player who's Commanding
|
||||
* @param player Player who Commanded
|
||||
* @param command Command to Send
|
||||
* @return Success Status
|
||||
*/
|
||||
|
@ -252,10 +234,19 @@ public abstract class SubServerController {
|
|||
*
|
||||
* @param player Player Editing
|
||||
* @param edit Edits
|
||||
* @param perma Saves Changes
|
||||
* @return Success Status
|
||||
*/
|
||||
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||
public int edit(UUID player, YAMLSection edit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the Server
|
||||
*
|
||||
* @param edit Edits
|
||||
* @return Success Status
|
||||
*/
|
||||
public int edit(YAMLSection edit) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -332,7 +323,7 @@ public abstract class SubServerController {
|
|||
*
|
||||
* @return Executable String
|
||||
*/
|
||||
public abstract String getExecutable();
|
||||
public abstract Executable getExecutable();
|
||||
|
||||
/**
|
||||
* Grab the Command to Stop the Server
|
||||
|
@ -361,4 +352,9 @@ public abstract class SubServerController {
|
|||
* @param action Stop Action
|
||||
*/
|
||||
public abstract void setStopAction(SubServer.StopAction action);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return control.toString();
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Host;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.ContainedPair;
|
||||
import net.ME1312.Galaxi.Library.Container.Pair;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* SubServer Layout Class
|
||||
*/
|
||||
public abstract class SubServerImpl extends ServerImpl implements SubServer {
|
||||
protected static final Pattern DISALLOWED_COMMANDS = Pattern.compile("^/?(?:[^\\s]+:)?sub(?:servers?)?(?:\\s|$)", Pattern.CASE_INSENSITIVE & Pattern.UNICODE_CASE);
|
||||
private List<Pair<String, String>> incompatibilities = new ArrayList<Pair<String, String>>();
|
||||
private SubCreator.ServerTemplate templateV = null;
|
||||
private String templateS = null;
|
||||
protected boolean registered, started, stopping, updating;
|
||||
|
||||
/**
|
||||
* Creates a SubServer
|
||||
*
|
||||
* @param host Host
|
||||
* @param name Server Name
|
||||
* @param port Port Number
|
||||
* @param motd Server MOTD
|
||||
* @param hidden Hidden Status
|
||||
* @param restricted Restricted Status
|
||||
*
|
||||
* @see ServerImpl#ServerImpl(String, SocketAddress, String, boolean, boolean) Super Method 2
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
protected SubServerImpl(Host host, String name, int port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(name, (SocketAddress) new InetSocketAddress(host.getAddress().getHostAddress(), port), motd, hidden, restricted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a SubServer
|
||||
*
|
||||
* @param host Host
|
||||
* @param name Server Name
|
||||
* @param port Port Number
|
||||
* @param motd Server MOTD
|
||||
* @param hidden Hidden Status
|
||||
* @param restricted Restricted Status
|
||||
*
|
||||
* @see ServerImpl#ServerImpl(String, InetSocketAddress, String, boolean, boolean) Super Method 1
|
||||
* @throws InvalidServerException
|
||||
*/
|
||||
protected SubServerImpl(Host host, String name, Integer port, String motd, boolean hidden, boolean restricted) throws InvalidServerException {
|
||||
super(name, new InetSocketAddress(host.getAddress().getHostAddress(), port), motd, hidden, restricted);
|
||||
}
|
||||
|
||||
public int edit(UUID player, ObjectMap<String> edit) {
|
||||
return edit(player, edit, false);
|
||||
}
|
||||
|
||||
public int permaEdit(UUID player, ObjectMap<String> edit) {
|
||||
return edit(player, edit, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the Server
|
||||
*
|
||||
* @param player Player Editing
|
||||
* @param edit Edits
|
||||
* @param perma Saves Changes
|
||||
* @return Success Status
|
||||
*/
|
||||
protected int edit(UUID player, ObjectMap<String> edit, boolean perma) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean isRegistered() {
|
||||
return registered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return registered && !updating && getHost().isAvailable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline() {
|
||||
return isRunning() && started;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStopping() {
|
||||
return isRunning() && stopping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemplate(String template) {
|
||||
this.templateV = null;
|
||||
this.templateS = template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTemplate(SubCreator.ServerTemplate template) {
|
||||
this.templateV = template;
|
||||
this.templateS = (template != null)?template.getName():null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubCreator.ServerTemplate getTemplate() {
|
||||
if (templateV != null) {
|
||||
return templateV;
|
||||
} else if (templateS != null && getHost().getCreator().getTemplates().containsKey(templateS.toLowerCase())) {
|
||||
return getHost().getCreator().getTemplate(templateS.toLowerCase());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggleCompatibility(SubServer... server) {
|
||||
for (SubServer s : server) {
|
||||
if (!equals(s)) {
|
||||
Pair<String, String> info = new ContainedPair<String, String>(s.getHost().getName(), s.getName());
|
||||
if (isCompatible(s)) {
|
||||
incompatibilities.add(info);
|
||||
if (s.isCompatible(this)) toggleCompatibility(this);
|
||||
} else {
|
||||
incompatibilities.remove(info);
|
||||
if (!s.isCompatible(this)) toggleCompatibility(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatible(SubServer server) {
|
||||
return !incompatibilities.contains(new ContainedPair<String, String>(server.getHost().getName(), server.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubServer> getIncompatibilities() {
|
||||
List<SubServer> servers = new ArrayList<SubServer>();
|
||||
List<Pair<String, String>> temp = new ArrayList<Pair<String, String>>();
|
||||
temp.addAll(incompatibilities);
|
||||
for (Pair<String, String> info : temp) {
|
||||
try {
|
||||
SubServer server = SubAPI.getInstance().getHost(info.key()).getSubServer(info.value());
|
||||
if (server == null) throw new NullPointerException();
|
||||
servers.add(server);
|
||||
} catch (Throwable e) {
|
||||
incompatibilities.remove(info);
|
||||
}
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubServer> getCurrentIncompatibilities() {
|
||||
List<SubServer> servers = new ArrayList<SubServer>();
|
||||
for (SubServer server : getIncompatibilities()) {
|
||||
if (server.isRunning()) servers.add(server);
|
||||
}
|
||||
return servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof SubServerImpl && super.equals(obj);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ObjectMap<String> forSubData() {
|
||||
ObjectMap<String> sinfo = super.forSubData();
|
||||
sinfo.set("type", "SubServer");
|
||||
sinfo.set("host", getHost().getName());
|
||||
sinfo.set("template", (getTemplate() != null)?getTemplate().getName():null);
|
||||
sinfo.set("available", isAvailable());
|
||||
sinfo.set("enabled", isEnabled());
|
||||
sinfo.set("editable", isEditable());
|
||||
sinfo.set("log", isLogging());
|
||||
sinfo.set("dir", getPath());
|
||||
sinfo.set("exec", getExecutable());
|
||||
sinfo.set("running", isRunning());
|
||||
sinfo.set("online", isOnline());
|
||||
sinfo.set("stopping", isStopping());
|
||||
sinfo.set("stop-cmd", getStopCommand());
|
||||
sinfo.set("stop-action", getStopAction().toString());
|
||||
sinfo.set("auto-run", SubAPI.getInstance().getInternals().servers.get().getMap("Servers").getMap(getName(), new ObjectMap<String>()).getBoolean("Run-On-Launch", false));
|
||||
List<String> incompatibleCurrent = new ArrayList<String>();
|
||||
List<String> incompatible = new ArrayList<String>();
|
||||
for (SubServer server : getCurrentIncompatibilities()) incompatibleCurrent.add(server.getName());
|
||||
for (SubServer server : getIncompatibilities()) incompatible.add(server.getName());
|
||||
sinfo.set("incompatible", incompatibleCurrent);
|
||||
sinfo.set("incompatible-list", incompatible);
|
||||
return sinfo;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
package net.ME1312.SubServers.Bungee;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Platform;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.SubServers.Bungee.Library.Container;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.VersionType;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.Security;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
|
@ -21,11 +24,9 @@ public final class Launch {
|
|||
*/
|
||||
@SuppressWarnings({"deprecation", "unchecked"})
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.setProperty("jdk.lang.Process.allowAmbiguousCommands", "true");
|
||||
System.setProperty("jdk.util.jar.enableMultiRelease", "force");
|
||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||
|
||||
if (Try.all.get(() -> Class.forName("net.md_5.bungee.BungeeCord") == null, true)) {
|
||||
if (Util.getDespiteException(() -> Class.forName("net.md_5.bungee.BungeeCord") == null, true)) {
|
||||
System.out.println("");
|
||||
System.out.println("*******************************************");
|
||||
System.out.println("*** Error: BungeeCord.jar Doesn't Exist ***");
|
||||
|
@ -47,11 +48,38 @@ public final class Launch {
|
|||
parser.accepts("noconsole");
|
||||
joptsimple.OptionSet options = parser.parse(args);
|
||||
if(options.has("version") || options.has("v")) {
|
||||
String osarch;
|
||||
if (System.getProperty("os.name").toLowerCase().startsWith("windows")) {
|
||||
String arch = System.getenv("PROCESSOR_ARCHITECTURE");
|
||||
String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432");
|
||||
|
||||
osarch = arch != null && arch.endsWith("64") || wow64Arch != null && wow64Arch.endsWith("64")?"x64":"x86";
|
||||
} else if (System.getProperty("os.arch").endsWith("86")) {
|
||||
osarch = "x86";
|
||||
} else if (System.getProperty("os.arch").endsWith("64")) {
|
||||
osarch = "x64";
|
||||
} else {
|
||||
osarch = System.getProperty("os.arch");
|
||||
}
|
||||
|
||||
String javaarch = null;
|
||||
switch (System.getProperty("sun.arch.data.model")) {
|
||||
case "32":
|
||||
javaarch = "x86";
|
||||
break;
|
||||
case "64":
|
||||
javaarch = "x64";
|
||||
break;
|
||||
default:
|
||||
if (!System.getProperty("sun.arch.data.model").equalsIgnoreCase("unknown"))
|
||||
javaarch = System.getProperty("sun.arch.data.model");
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
System.out.println(Platform.getSystemName() + ' ' + Platform.getSystemVersion() + ((Platform.getSystemBuild() != null)?" (" + Platform.getSystemBuild() + ')':"") + ((!Platform.getSystemArchitecture().equals("unknown"))?" [" + Platform.getSystemArchitecture() + ']':"") + ',');
|
||||
System.out.println("Java " + Platform.getJavaVersion() + ((!Platform.getJavaArchitecture().equals("unknown"))?" [" + Platform.getJavaArchitecture() + ']':"") + ',');
|
||||
System.out.println("BungeeCord " + net.md_5.bungee.Bootstrap.class.getPackage().getImplementationVersion() + ((patched)?" [Patched]":"") + ',');
|
||||
System.out.println("SubServers.Bungee v" + SubProxy.version.toExtendedString() + ((SubProxy.class.getPackage().getSpecificationTitle() != null)?" (" + SubProxy.class.getPackage().getSpecificationTitle() + ')':""));
|
||||
System.out.println(System.getProperty("os.name") + ((!System.getProperty("os.name").toLowerCase().startsWith("windows"))?' ' + System.getProperty("os.version"):"") + ((osarch != null)?" [" + osarch + ']':"") + ',');
|
||||
System.out.println("Java " + System.getProperty("java.version") + ((javaarch != null)?" [" + javaarch + ']':"") + ',');
|
||||
System.out.println("BungeeCord" + ((patched)?" [Patched] ":" ") + net.md_5.bungee.Bootstrap.class.getPackage().getImplementationVersion() + ',');
|
||||
System.out.println("SubServers.Bungee v" + SubPlugin.version.toExtendedString() + ((SubPlugin.class.getPackage().getSpecificationTitle() != null)?" (" + SubPlugin.class.getPackage().getSpecificationTitle() + ')':""));
|
||||
System.out.println("");
|
||||
} else {
|
||||
System.out.println("");
|
||||
|
@ -65,7 +93,7 @@ public final class Launch {
|
|||
if (net.md_5.bungee.BungeeCord.class.getPackage().getSpecificationVersion() != null) {
|
||||
Date date = (new SimpleDateFormat("yyyyMMdd")).parse(net.md_5.bungee.BungeeCord.class.getPackage().getSpecificationVersion());
|
||||
Calendar line = Calendar.getInstance();
|
||||
line.add(Calendar.WEEK_OF_YEAR, -8);
|
||||
line.add(3, -4);
|
||||
if (date.before(line.getTime())) {
|
||||
System.out.println("*** Warning: BungeeCord is outdated ***");
|
||||
System.out.println("*** Please download a new build from: ***");
|
||||
|
@ -83,16 +111,16 @@ public final class Launch {
|
|||
}
|
||||
System.out.println("");
|
||||
|
||||
SubProxy plugin = new SubProxy(System.out, patched);
|
||||
SubPlugin plugin = new SubPlugin(System.out, patched);
|
||||
net.md_5.bungee.api.ProxyServer.class.getMethod("setInstance", net.md_5.bungee.api.ProxyServer.class).invoke(null, plugin);
|
||||
plugin.getLogger().info("Enabled " + plugin.getBungeeName() + " version " + plugin.getVersion());
|
||||
plugin.start();
|
||||
|
||||
if (!options.has("noconsole")) {
|
||||
try {
|
||||
if (Try.all.get(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands") != null, false)) { // Waterfall Setup
|
||||
if (Util.getDespiteException(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands") != null, false)) {
|
||||
Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("readCommands").invoke(null);
|
||||
} else if (Try.all.get(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("start") != null, false)) {
|
||||
} else if (Util.getDespiteException(() -> Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole").getMethod("start") != null, false)) {
|
||||
Class console = Class.forName("io.github.waterfallmc.waterfall.console.WaterfallConsole");
|
||||
console.getMethod("start").invoke(console.getConstructor().newInstance());
|
||||
} else {
|
||||
|
@ -105,7 +133,7 @@ public final class Launch {
|
|||
}
|
||||
} else if (line.equalsIgnoreCase("exit")) {
|
||||
plugin.sudo = null;
|
||||
net.ME1312.SubServers.Bungee.Library.Compatibility.Logger.get("SubServers").info("Reverting to the BungeeCord Console");
|
||||
System.out.println("SubServers > Reverting to the BungeeCord Console");
|
||||
} else {
|
||||
plugin.sudo.command(line);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
/**
|
||||
* Callback Class
|
||||
*/
|
||||
public interface Callback<T> {
|
||||
/**
|
||||
* Run the Callback
|
||||
*
|
||||
* @param obj Object
|
||||
*/
|
||||
void run(T obj);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Command Layout Class that implements all possible features (Base Version)
|
||||
*/
|
||||
public abstract class CommandX extends Command implements TabExecutor {
|
||||
|
||||
/**
|
||||
* Create a Command
|
||||
*
|
||||
* @param name Command Name
|
||||
*/
|
||||
public CommandX(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Command
|
||||
*
|
||||
* @param name Command Name
|
||||
* @param permission Command Permission
|
||||
* @param aliases Command Aliases
|
||||
*/
|
||||
public CommandX(String name, String permission, String... aliases) {
|
||||
super(name, permission, aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggest Arguments
|
||||
*
|
||||
* @param sender Sender
|
||||
* @param args Arguments (including the final unfinished one)
|
||||
* @return An Error Message (if there was one, otherwise null) and a List of Suggestions
|
||||
*/
|
||||
public abstract NamedContainer<String, List<String>> suggestArguments(CommandSender sender, String[] args);
|
||||
|
||||
/**
|
||||
* Override the BungeeCord Method of {@link #suggestArguments(CommandSender, String[])}
|
||||
*
|
||||
* @param sender Sender
|
||||
* @param args Arguments (including the final unfinished one)
|
||||
* @return A Collection of Suggestions
|
||||
*/
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
|
||||
return suggestArguments(sender, args).get();
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.SEVERE;
|
||||
|
||||
/**
|
||||
* JNA Library Loader Class
|
||||
*/
|
||||
public class JNA {
|
||||
private JNA() {}
|
||||
private static ClassLoader JNA = null;
|
||||
private static final String JNA_VERSION = "5.2.0";
|
||||
private static final String JNA_DOWNLOAD = "https://oss.sonatype.org/service/local/repositories/releases/content/net/java/dev/jna/$1/" + JNA_VERSION + "/$1-" + JNA_VERSION + ".jar";
|
||||
|
||||
/**
|
||||
* Get/Load JNA Library
|
||||
*
|
||||
* @return JNA ClassLoader
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public static ClassLoader get() {
|
||||
if (JNA == null) {
|
||||
boolean announced = false;
|
||||
Logger log = ProxyServer.getInstance().getLogger();
|
||||
File library = new File(SubAPI.getInstance().getInternals().dir, "SubServers/Cache/Libraries");
|
||||
File jna = new File(library, "jna-" + JNA_VERSION + ".jar");
|
||||
jna.getParentFile().mkdirs();
|
||||
if (!jna.exists()) {
|
||||
announced = true;
|
||||
log.info(">> Downloading JNA v" + JNA_VERSION);
|
||||
try (FileOutputStream fin = new FileOutputStream(jna)) {
|
||||
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna")), fin);
|
||||
} catch (Throwable e) {
|
||||
jna.delete();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
File platform = new File(library, "jna-platform-" + JNA_VERSION + ".jar");
|
||||
platform.getParentFile().mkdirs();
|
||||
if (!platform.exists()) {
|
||||
if (!announced) log.info(">> Downloading JNA platform v" + JNA_VERSION);
|
||||
announced = true;
|
||||
try (FileOutputStream fin = new FileOutputStream(platform)) {
|
||||
Resources.copy(new URL(JNA_DOWNLOAD.replace("$1", "jna-platform")), fin);
|
||||
} catch (Throwable e) {
|
||||
platform.delete();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (jna.exists() && platform.exists()) {
|
||||
if (announced) log.info(">> JNA download complete");
|
||||
try {
|
||||
JNA = new URLClassLoader(new URL[]{jna.toURI().toURL(), platform.toURI().toURL()});
|
||||
} catch (Throwable e) {
|
||||
log.log(SEVERE, ">> Couldn't load JNA:", e);
|
||||
}
|
||||
} else {
|
||||
log.log(SEVERE, ">> Couldn't load JNA:", new FileNotFoundException());
|
||||
}
|
||||
}
|
||||
return JNA;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.util.CaseInsensitiveMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Legacy Server Map Translation Class
|
||||
*/
|
||||
public class LegacyServerMap extends CaseInsensitiveMap<ServerInfo> {
|
||||
public LegacyServerMap() {
|
||||
|
||||
}
|
||||
|
||||
public LegacyServerMap(Map<String, ServerInfo> map) {
|
||||
for (Entry<String, ServerInfo> e : map.entrySet()) super.put(e.getKey(), e.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ServerInfo put(String key, ServerInfo value) {
|
||||
if (value == null) throw new NullPointerException();
|
||||
ServerInfo n = SubAPI.getInstance().addServer(value.getName(), value.getAddress().getAddress(), value.getAddress().getPort(), value.getMotd(), false, value.isRestricted()),
|
||||
s = getOrDefault(key, null);
|
||||
|
||||
if (n != null)
|
||||
super.put(n.getName(), n);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerInfo remove(Object key) {
|
||||
if (key instanceof String) {
|
||||
ServerInfo s = getOrDefault(key, null);
|
||||
if (s != null) {
|
||||
if (SubAPI.getInstance().removeServer((String) key))
|
||||
super.remove(key);
|
||||
return s;
|
||||
} else return null;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
// Disallow removing all servers
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility;
|
||||
|
||||
public final class Plugin extends net.md_5.bungee.api.plugin.Plugin {
|
||||
public class Plugin extends net.md_5.bungee.api.plugin.Plugin {
|
||||
|
||||
@Deprecated
|
||||
public Plugin() {
|
||||
throw new IllegalStateException("SubServers.Bungee does not run as a plugin, but a wrapper. For more information on how to install, please visit this page: https://github.com/ME1312/SubServers-2/wiki/Installation");
|
||||
@Override
|
||||
public void onEnable() {
|
||||
throw new IllegalStateException("SubServers.Bungee does not run as a plugin, but a wrapper. For more information on how to install, visit this page: https://github.com/ME1312/SubServers-2/wiki/Install");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Compatibility.v1_13;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.NamedContainer;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Command Layout Class that implements all possible features (1.13 Version)
|
||||
*/
|
||||
public class CommandX extends net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX/* implements TabValidator */ {
|
||||
public final net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX command;
|
||||
|
||||
/**
|
||||
* Create a Command
|
||||
*
|
||||
* @param other CommandX from previous version
|
||||
*/
|
||||
public CommandX(net.ME1312.SubServers.Bungee.Library.Compatibility.CommandX other) {
|
||||
super(other.getName());
|
||||
command = other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override BungeeCord Method for the previously used one
|
||||
*
|
||||
* @param sender Sender
|
||||
* @param args Arguments
|
||||
*/
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
command.execute(sender, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamedContainer<String, List<String>> suggestArguments(CommandSender sender, String[] args) {
|
||||
return command.suggestArguments(sender, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a Command (Override for custom)
|
||||
*
|
||||
* @param sender Sender
|
||||
* @param command Command to validate
|
||||
* @return NamedContainer with a String error message and a Integer that represents where the command was deemed invalid
|
||||
*/
|
||||
public NamedContainer<String, Integer> validateCommand(CommandSender sender, String command) {
|
||||
List<NamedContainer<String, Integer>> split = new LinkedList<NamedContainer<String, Integer>>();
|
||||
String cmd = command;
|
||||
int i;
|
||||
while ((i = cmd.indexOf((int) ' ')) < 0) {
|
||||
i++;
|
||||
String arg = cmd.substring(i);
|
||||
split.add(new NamedContainer<>(arg.contains(" ")?arg.substring(0, arg.indexOf((int) ' ')):arg, i));
|
||||
cmd = arg;
|
||||
}
|
||||
|
||||
List<String> args = new LinkedList<String>();
|
||||
NamedContainer<String, Integer> response = null;
|
||||
i = 0;
|
||||
for (NamedContainer<String, Integer> arg : split) {
|
||||
if (i > 0) {
|
||||
args.add(arg.name());
|
||||
NamedContainer<String, List<String>> suggestions = suggestArguments(sender, args.toArray(new String[args.size() - 1]));
|
||||
if (suggestions.name() != null) response = new NamedContainer<>(suggestions.name(), arg.get());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
// TODO Override the original validator method
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Config;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* YAML Config Class
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class YAMLConfig {
|
||||
private File file;
|
||||
private Yaml yaml;
|
||||
private YAMLSection config;
|
||||
|
||||
/**
|
||||
* Creates/Loads a YAML Formatted Config
|
||||
*
|
||||
* @param file
|
||||
* @throws IOException
|
||||
* @throws YAMLException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public YAMLConfig(File file) throws IOException, YAMLException {
|
||||
if (Util.isNull(file)) throw new NullPointerException();
|
||||
this.file = file;
|
||||
this.yaml = new Yaml(getDumperOptions());
|
||||
if (file.exists()) {
|
||||
InputStream stream = new FileInputStream(file);
|
||||
this.config = new YAMLSection((LinkedHashMap<String, ?>) yaml.loadAs(stream, LinkedHashMap.class), null, null, yaml);
|
||||
stream.close();
|
||||
} else {
|
||||
this.config = new YAMLSection(null, null, null, yaml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Config Contents
|
||||
*
|
||||
* @return Config Contents
|
||||
*/
|
||||
public YAMLSection get() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Config Contents
|
||||
*
|
||||
* @param value Value
|
||||
*/
|
||||
public void set(YAMLSection value) {
|
||||
if (Util.isNull(value)) throw new NullPointerException();
|
||||
config = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload Config Contents
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void reload() throws IOException {
|
||||
if (file.exists()) {
|
||||
InputStream stream = new FileInputStream(file);
|
||||
this.config = new YAMLSection((LinkedHashMap<String, ?>) yaml.loadAs(stream, LinkedHashMap.class), null, null, yaml);
|
||||
stream.close();
|
||||
} else {
|
||||
this.config = new YAMLSection(null, null, null, yaml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Config Contents
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
if (!file.exists()) file.createNewFile();
|
||||
FileWriter writer = new FileWriter(file);
|
||||
yaml.dump(config.map, writer);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof YAMLConfig) {
|
||||
return get().equals(((YAMLConfig) object).get());
|
||||
} else {
|
||||
return super.equals(object);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return yaml.dump(config.map);
|
||||
}
|
||||
|
||||
protected static DumperOptions getDumperOptions() {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setAllowUnicode(false);
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setIndent(2);
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,372 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Config;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* YAML Value Class
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "unused"})
|
||||
public class YAMLValue {
|
||||
protected Object obj;
|
||||
protected String label;
|
||||
protected YAMLSection up;
|
||||
private Yaml yaml;
|
||||
|
||||
protected YAMLValue(Object obj, YAMLSection up, String label, Yaml yaml) {
|
||||
this.obj = obj;
|
||||
this.label = label;
|
||||
this.yaml = yaml;
|
||||
this.up = up;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the YAML Section this Object was defined in
|
||||
*
|
||||
* @return YAML Section
|
||||
*/
|
||||
public YAMLSection getDefiningSection() {
|
||||
return up;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object
|
||||
*
|
||||
* @return Object
|
||||
*/
|
||||
public Object asObject() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as List
|
||||
*
|
||||
* @return List
|
||||
*/
|
||||
public List<?> asObjectList() {
|
||||
return (List<?>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Boolean
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public Boolean asBoolean() {
|
||||
return (Boolean) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as List
|
||||
*
|
||||
* @return List
|
||||
*/
|
||||
public List<Boolean> asBooleanList() {
|
||||
return (List<Boolean>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as YAML Section
|
||||
*
|
||||
* @return YAML Section
|
||||
*/
|
||||
public YAMLSection asSection() {
|
||||
if (obj != null) return new YAMLSection((Map<String, ?>) obj, up, label, yaml);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as YAML Section List
|
||||
*
|
||||
* @return YAML Section List
|
||||
*/
|
||||
public List<YAMLSection> asSectionList() {
|
||||
if (obj != null) {
|
||||
List<YAMLSection> values = new ArrayList<YAMLSection>();
|
||||
for (Map<String, ?> value : (List<? extends Map<String, ?>>) obj) {
|
||||
values.add(new YAMLSection(value, null, null, yaml));
|
||||
}
|
||||
return values;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Double
|
||||
*
|
||||
* @return Double
|
||||
*/
|
||||
public Double asDouble() {
|
||||
return ((Number) obj).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Double List
|
||||
*
|
||||
* @return Double List
|
||||
*/
|
||||
public List<Double> asDoubleList() {
|
||||
return (List<Double>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Float
|
||||
*
|
||||
* @return Float
|
||||
*/
|
||||
public Float asFloat() {
|
||||
return ((Number) obj).floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Float List
|
||||
*
|
||||
* @return Float List
|
||||
*/
|
||||
public List<Float> asFloatList() {
|
||||
return (List<Float>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Integer
|
||||
*
|
||||
* @return Integer
|
||||
*/
|
||||
public Integer asInt() {
|
||||
return ((Number) obj).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Integer List
|
||||
*
|
||||
* @return Integer List
|
||||
*/
|
||||
public List<Integer> asIntList() {
|
||||
return (List<Integer>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Long
|
||||
*
|
||||
* @return Long
|
||||
*/
|
||||
public Long asLong() {
|
||||
return ((Number) obj).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Long List
|
||||
*
|
||||
* @return Long List
|
||||
*/
|
||||
public List<Long> asLongList() {
|
||||
return (List<Long>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Short by Handle
|
||||
*
|
||||
* @return Short
|
||||
*/
|
||||
public Short asShort() {
|
||||
return ((Number) obj).shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Short List by Handle
|
||||
*
|
||||
* @return Short List
|
||||
*/
|
||||
public List<Short> asShortList() {
|
||||
return (List<Short>) obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Unparsed String
|
||||
*
|
||||
* @return Unparsed String
|
||||
*/
|
||||
public String asRawString() {
|
||||
if (obj != null) return obj.toString();
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Unparsed String List
|
||||
*
|
||||
* @return Unparsed String List
|
||||
*/
|
||||
public List<String> asRawStringList() {
|
||||
if (obj != null) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
for (Object value : (List<?>) obj) {
|
||||
values.add(value.toString());
|
||||
}
|
||||
return values;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as String
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String asString() {
|
||||
if (obj != null) return Util.unescapeJavaString(asRawString());
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as String List
|
||||
*
|
||||
* @return String List
|
||||
*/
|
||||
public List<String> asStringList() {
|
||||
if (obj != null) {
|
||||
List<String> values = new ArrayList<String>();
|
||||
for (String value : asRawStringList()) {
|
||||
values.add(Util.unescapeJavaString(value));
|
||||
}
|
||||
return values;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Colored String
|
||||
*
|
||||
* @param color Color Char to parse
|
||||
* @return Colored String
|
||||
*/
|
||||
public String asColoredString(char color) {
|
||||
if (Util.isNull(color)) throw new NullPointerException();
|
||||
if (obj != null) return ChatColor.translateAlternateColorCodes(color, asString());
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as Colored String List
|
||||
*
|
||||
* @param color Color Char to parse
|
||||
* @return Colored String List
|
||||
*/
|
||||
public List<String> asColoredStringList(char color) {
|
||||
if (obj != null) {
|
||||
if (Util.isNull(color)) throw new NullPointerException();
|
||||
List<String> values = new ArrayList<String>();
|
||||
for (String value : asStringList()) {
|
||||
values.add(ChatColor.translateAlternateColorCodes(color, value));
|
||||
}
|
||||
return values;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as UUID
|
||||
*
|
||||
* @return UUID
|
||||
*/
|
||||
public UUID asUUID() {
|
||||
if (obj != null) return UUID.fromString((String) obj);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Object as UUID List
|
||||
*
|
||||
* @return UUID List
|
||||
*/
|
||||
public List<UUID> asUUIDList() {
|
||||
if (obj != null) {
|
||||
List<UUID> values = new ArrayList<UUID>();
|
||||
for (String value : (List<String>) obj) {
|
||||
values.add(UUID.fromString(value));
|
||||
}
|
||||
return values;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if object is Null
|
||||
*
|
||||
* @return Null Status
|
||||
*/
|
||||
public boolean isNull() {
|
||||
return obj == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is a Boolean
|
||||
*
|
||||
* @return Boolean Status
|
||||
*/
|
||||
public boolean isBoolean() {
|
||||
return (obj instanceof Boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is a YAML Section
|
||||
*
|
||||
* @return YAML Section Status
|
||||
*/
|
||||
public boolean isSection() {
|
||||
return (obj instanceof Map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is a List
|
||||
*
|
||||
* @return List Status
|
||||
*/
|
||||
public boolean isList() {
|
||||
return (obj instanceof List);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is a Number
|
||||
*
|
||||
* @return Number Status
|
||||
*/
|
||||
public boolean isNumber() {
|
||||
return (obj instanceof Number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is a String
|
||||
*
|
||||
* @return String Status
|
||||
*/
|
||||
public boolean isString() {
|
||||
return (obj instanceof String);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if object is a UUID
|
||||
*
|
||||
* @return UUID Status
|
||||
*/
|
||||
public boolean isUUID() {
|
||||
return (obj instanceof String && !Util.isException(() -> UUID.fromString((String) obj)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (obj == null) {
|
||||
return object == null;
|
||||
} else {
|
||||
if (object instanceof YAMLValue) {
|
||||
return obj.equals(((YAMLValue) object).obj);
|
||||
} else {
|
||||
return obj.equals(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (obj != null) return obj.toString();
|
||||
else return "null";
|
||||
}
|
||||
}
|
|
@ -1,562 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
|
||||
import net.ME1312.Galaxi.Library.Config.YAMLSection;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* SubServers Configuration Updater
|
||||
*/
|
||||
public class ConfigUpdater {
|
||||
private static final Version UNSIGNED = new Version(new SimpleDateFormat("yy'w'ww'zz'").format(Calendar.getInstance().getTime()));
|
||||
|
||||
/**
|
||||
* Update SubServers' config.yml
|
||||
*
|
||||
* @param file File to bring up-to-date
|
||||
*/
|
||||
public static void updateConfig(File file) throws IOException {
|
||||
YAMLConfig config = new YAMLConfig(file);
|
||||
YAMLSection existing = config.get().clone();
|
||||
YAMLSection updated = existing.clone();
|
||||
YAMLSection rewritten = new YAMLSection();
|
||||
|
||||
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
|
||||
Version now = SubAPI.getInstance().getWrapperBuild();
|
||||
|
||||
int i = 0;
|
||||
if (now == null) now = UNSIGNED;
|
||||
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
|
||||
YAMLSection hosts = new YAMLSection();
|
||||
YAMLSection host = new YAMLSection();
|
||||
host.set("Enabled", true);
|
||||
host.set("Display", "Default");
|
||||
hosts.set("~", host);
|
||||
updated.set("Hosts", hosts);
|
||||
|
||||
i++;
|
||||
Logger.get("SubServers").info("Created ./SubServers/config.yml");
|
||||
} else {
|
||||
if (was.compareTo(new Version("19w17a")) <= 0) {
|
||||
if (existing.getMap("Settings", new YAMLSection()).contains("Log-Creator")) for (String name : existing.getMap("Hosts", new YAMLSection()).getKeys())
|
||||
updated.getMap("Hosts").getMap(name).safeSet("Log-Creator", existing.getMap("Settings").getBoolean("Log-Creator"));
|
||||
|
||||
if (existing.getMap("Settings", new YAMLSection()).contains("SubData") && !existing.getMap("Settings", new YAMLSection()).getMap("SubData").contains("Encryption"))
|
||||
updated.getMap("Settings").getMap("SubData").set("Encryption", "NONE");
|
||||
|
||||
if (existing.contains("Servers")) {
|
||||
YAMLConfig sc = new YAMLConfig(new File(file.getParentFile(), "servers.yml"));
|
||||
YAMLSection settings = new YAMLSection();
|
||||
settings.set("Version", was.toString());
|
||||
settings.set("Run-On-Launch-Timeout", (existing.getMap("Settings", new YAMLSection()).contains("Run-On-Launch-Timeout"))?existing.getMap("Settings").getInt("Run-On-Launch-Timeout"):0);
|
||||
sc.get().safeSet("Settings", settings);
|
||||
|
||||
sc.get().safeSet("Servers", new YAMLSection());
|
||||
sc.get().getMap("Servers").safeSetAll(existing.getMap("Servers"));
|
||||
Logger.get("SubServers").info("Created ./SubServers/servers.yml (using existing data)");
|
||||
sc.save();
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
} if (was.compareTo(new Version("19w35c")) <= 0) {
|
||||
if (existing.getMap("Settings", new YAMLSection()).contains("SubData")) {
|
||||
LinkedList<String> whitelist = new LinkedList<>();
|
||||
LinkedList<String> newWhitelist = new LinkedList<>();
|
||||
whitelist.addAll(existing.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getStringList("Allowed-Connections", Collections.emptyList()));
|
||||
whitelist.addAll(existing.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getStringList("Whitelist", Collections.emptyList()));
|
||||
|
||||
boolean warnPls = false;
|
||||
for (String address : whitelist) {
|
||||
Matcher regAddress = Pattern.compile("^(\\d{1,3}|%)\\.(\\d{1,3}|%)\\.(\\d{1,3}|%)\\.(\\d{1,3}|%)$").matcher(address);
|
||||
if (regAddress.find()) {
|
||||
StringBuilder newAddress = new StringBuilder();
|
||||
int subnet = -1;
|
||||
boolean warn = false;
|
||||
for (int o = 1; o <= 4; o++) {
|
||||
if (o > 1) newAddress.append('.');
|
||||
if (subnet == -1) {
|
||||
if (!regAddress.group(o).equals("%")) {
|
||||
newAddress.append(regAddress.group(o));
|
||||
} else {
|
||||
subnet = 8 * (o - 1);
|
||||
newAddress.append('0');
|
||||
}
|
||||
} else {
|
||||
if (!regAddress.group(o).equals("%")) warn = warnPls = true;
|
||||
newAddress.append('0');
|
||||
}
|
||||
}
|
||||
if (subnet < 0) subnet = 32;
|
||||
if (warn) Logger.get("SubServers").warning("Updating non-standard mask: " + address);
|
||||
newAddress.append('/');
|
||||
newAddress.append(subnet);
|
||||
newWhitelist.add(newAddress.toString());
|
||||
}
|
||||
}
|
||||
updated.getMap("Settings").getMap("SubData").set("Whitelist", newWhitelist);
|
||||
if (warnPls) Logger.get("SubServers").warning("Non-standard masks have been updated. This may expose SubData to unintended networks!");
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
} if (was.compareTo(new Version("20w08d")) <= 0) {
|
||||
if (existing.contains("Hosts")) {
|
||||
for (String name : existing.getMap("Hosts", new YAMLSection()).getKeys()) {
|
||||
if (existing.getMap("Hosts").getMap(name).getString("Driver", "BUILT_IN").replace('-', '_').replace(' ', '_').equalsIgnoreCase("BUILT_IN"))
|
||||
updated.getMap("Hosts").getMap(name).set("Driver", "VIRTUAL");
|
||||
}
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
} if (was.compareTo(new Version("20w34a")) <= 0) {
|
||||
if (existing.getMap("Settings", new YAMLSection()).contains("Smart-Fallback") && existing.getMap("Settings").isBoolean("Smart-Fallback")) {
|
||||
YAMLSection smart_fallback = new YAMLSection();
|
||||
smart_fallback.set("Enabled", existing.getMap("Settings").getBoolean("Smart-Fallback"));
|
||||
smart_fallback.set("Fallback", existing.getMap("Settings").getBoolean("Smart-Fallback"));
|
||||
updated.getMap("Settings").set("Smart-Fallback", smart_fallback);
|
||||
}
|
||||
if (existing.getMap("Settings", new YAMLSection()).contains("Override-Bungee-Commands") && existing.getMap("Settings").isBoolean("Override-Bungee-Commands")) {
|
||||
List<String> overrides = new LinkedList<>();
|
||||
if (!existing.getMap("Settings").getBoolean("Override-Bungee-Commands")) {
|
||||
overrides.add("/server");
|
||||
overrides.add("/glist");
|
||||
}
|
||||
updated.getMap("Settings").set("Disabled-Overrides", overrides);
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
} else if (was.compareTo(new Version("21w27b")) <= 0) {
|
||||
|
||||
//existing = updated.clone();
|
||||
i++;
|
||||
|
||||
}// if (was.compareTo(new Version("99w99a")) <= 0) {
|
||||
// // do something
|
||||
// existing = updated.clone();
|
||||
// i++
|
||||
//}
|
||||
|
||||
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/config.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
YAMLSection settings = new YAMLSection();
|
||||
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
|
||||
if (updated.getMap("Settings", new YAMLSection()).contains("RPEC-Check-Interval")) settings.set("RPEC-Check-Interval", updated.getMap("Settings").getString("RPEC-Check-Interval"));
|
||||
settings.set("Strict-Server-Linking", updated.getMap("Settings", new YAMLSection()).getBoolean("Strict-Server-Linking", true));
|
||||
settings.set("Disabled-Overrides", updated.getMap("Settings", new YAMLSection()).getStringList("Disabled-Overrides", Collections.emptyList()));
|
||||
|
||||
YAMLSection smart_fallback = new YAMLSection();
|
||||
smart_fallback.set("Enabled", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Enabled", true));
|
||||
smart_fallback.set("Fallback", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Fallback", true));
|
||||
smart_fallback.set("Reconnect", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("Reconnect", false));
|
||||
smart_fallback.set("DNS-Forward", updated.getMap("Settings", new YAMLSection()).getMap("Smart-Fallback", new YAMLSection()).getBoolean("DNS-Forward", false));
|
||||
settings.set("Smart-Fallback", smart_fallback);
|
||||
|
||||
YAMLSection upnp = new YAMLSection();
|
||||
upnp.set("Forward-Proxy", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-Proxy", true));
|
||||
upnp.set("Forward-SubData", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-SubData", false));
|
||||
upnp.set("Forward-Servers", updated.getMap("Settings", new YAMLSection()).getMap("UPnP", new YAMLSection()).getBoolean("Forward-Servers", false));
|
||||
settings.set("UPnP", upnp);
|
||||
|
||||
YAMLSection subdata = new YAMLSection();
|
||||
subdata.set("Address", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getString("Address", "127.0.0.1:4391"));
|
||||
if (updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).contains("Password")) subdata.set("Password", updated.getMap("Settings").getMap("SubData").getString("Password"));
|
||||
subdata.set("Encryption", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getString("Encryption", "RSA/AES"));
|
||||
subdata.set("Whitelist", updated.getMap("Settings", new YAMLSection()).getMap("SubData", new YAMLSection()).getStringList("Whitelist", Collections.emptyList()));
|
||||
settings.set("SubData", subdata);
|
||||
|
||||
rewritten.set("Settings", settings);
|
||||
|
||||
|
||||
YAMLSection hosts = new YAMLSection();
|
||||
for (String name : updated.getMap("Hosts", new YAMLSection()).getKeys()) {
|
||||
YAMLSection host = new YAMLSection();
|
||||
host.set("Enabled", updated.getMap("Hosts").getMap(name).getBoolean("Enabled", false));
|
||||
host.set("Display", updated.getMap("Hosts").getMap(name).getString("Display", ""));
|
||||
host.set("Driver", updated.getMap("Hosts").getMap(name).getString("Driver", "VIRTUAL"));
|
||||
host.set("Address", updated.getMap("Hosts").getMap(name).getString("Address", "127.0.0.1"));
|
||||
host.set("Port-Range", updated.getMap("Hosts").getMap(name).getString("Port-Range", "25500-25559"));
|
||||
host.set("Directory", updated.getMap("Hosts").getMap(name).getString("Directory", (host.getString("Driver").equalsIgnoreCase("VIRTUAL"))?"./SubServers/Servers":"./Servers"));
|
||||
host.set("Git-Bash", updated.getMap("Hosts").getMap(name).getString("Git-Bash", "%ProgramFiles%\\Git"));
|
||||
host.set("Log-Creator", updated.getMap("Hosts").getMap(name).getBoolean("Log-Creator", true));
|
||||
if (updated.getMap("Hosts").getMap(name).contains("Extra")) host.set("Extra", updated.getMap("Hosts").getMap(name).getMap("Extra"));
|
||||
hosts.set(name, host);
|
||||
}
|
||||
rewritten.set("Hosts", hosts);
|
||||
|
||||
config.set(rewritten);
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update SubServers' servers.yml
|
||||
*
|
||||
* @param file File to bring up-to-date
|
||||
*/
|
||||
public static void updateServers(File file) throws IOException {
|
||||
YAMLConfig config = new YAMLConfig(file);
|
||||
YAMLSection existing = config.get().clone();
|
||||
YAMLSection updated = existing.clone();
|
||||
YAMLSection rewritten = new YAMLSection();
|
||||
|
||||
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
|
||||
Version now = SubAPI.getInstance().getWrapperBuild();
|
||||
|
||||
int i = 0;
|
||||
if (now == null) now = UNSIGNED;
|
||||
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
|
||||
YAMLSection servers = new YAMLSection();
|
||||
servers.set("Example", new YAMLSection());
|
||||
updated.set("Servers", servers);
|
||||
|
||||
i++;
|
||||
Logger.get("SubServers").info("Created ./SubServers/servers.yml");
|
||||
} else {
|
||||
if (was.compareTo(new Version("19w17a")) <= 0) {
|
||||
if (existing.contains("Servers")) {
|
||||
for (String name : existing.getMap("Servers", new YAMLSection()).getKeys()) {
|
||||
if (existing.getMap("Servers").getMap(name).getBoolean("Auto-Restart", true))
|
||||
updated.getMap("Servers").getMap(name).safeSet("Stop-Action", "RESTART");
|
||||
|
||||
if (existing.getMap("Servers").getMap(name).getString("Stop-Action", "NONE").equalsIgnoreCase("DELETE_SERVER"))
|
||||
updated.getMap("Servers").getMap(name).set("Stop-Action", "RECYCLE_SERVER");
|
||||
}
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
}// if (was.compareTo(new Version("99w99a")) <= 0) {
|
||||
// // do something
|
||||
// i++
|
||||
//}
|
||||
|
||||
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/servers.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
YAMLSection settings = new YAMLSection();
|
||||
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
|
||||
settings.set("Run-On-Launch-Timeout", updated.getMap("Settings", new YAMLSection()).getInt("Run-On-Launch-Timeout", 0));
|
||||
|
||||
rewritten.set("Settings", settings);
|
||||
|
||||
|
||||
YAMLSection servers = new YAMLSection();
|
||||
for (String name : updated.getMap("Servers", new YAMLSection()).getKeys()) {
|
||||
YAMLSection server = new YAMLSection();
|
||||
server.set("Enabled", updated.getMap("Servers").getMap(name).getBoolean("Enabled", false));
|
||||
server.set("Display", updated.getMap("Servers").getMap(name).getString("Display", ""));
|
||||
server.set("Host", updated.getMap("Servers").getMap(name).getString("Host", "~"));
|
||||
if (updated.getMap("Servers").getMap(name).contains("Template")) server.set("Template", updated.getMap("Servers").getMap(name).getString("Template"));
|
||||
server.set("Group", updated.getMap("Servers").getMap(name).getStringList("Groups", Collections.emptyList()));
|
||||
server.set("Port", updated.getMap("Servers").getMap(name).getInt("Port", 25567));
|
||||
server.set("Motd", updated.getMap("Servers").getMap(name).getString("Motd", "Some SubServer"));
|
||||
server.set("Log", updated.getMap("Servers").getMap(name).getBoolean("Log", true));
|
||||
server.set("Directory", updated.getMap("Servers").getMap(name).getString("Directory", "." + File.separatorChar));
|
||||
server.set("Executable", updated.getMap("Servers").getMap(name).getString("Executable", "java -Xmx1024M -Djline.terminal=jline.UnsupportedTerminal -jar Spigot.jar"));
|
||||
server.set("Stop-Command", updated.getMap("Servers").getMap(name).getString("Stop-Command", "stop"));
|
||||
server.set("Stop-Action", updated.getMap("Servers").getMap(name).getString("Stop-Action", "NONE"));
|
||||
server.set("Run-On-Launch", updated.getMap("Servers").getMap(name).getBoolean("Run-On-Launch", false));
|
||||
server.set("Restricted", updated.getMap("Servers").getMap(name).getBoolean("Restricted", false));
|
||||
server.set("Incompatible", updated.getMap("Servers").getMap(name).getStringList("Incompatible", Collections.emptyList()));
|
||||
server.set("Hidden", updated.getMap("Servers").getMap(name).getBoolean("Hidden", false));
|
||||
if (updated.getMap("Servers").getMap(name).contains("Extra")) server.set("Extra", updated.getMap("Servers").getMap(name).getMap("Extra"));
|
||||
servers.set(name, server);
|
||||
}
|
||||
rewritten.set("Servers", servers);
|
||||
|
||||
config.set(rewritten);
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update SubServers' lang.yml
|
||||
*
|
||||
* @param file File to bring up-to-date
|
||||
*/
|
||||
public static void updateLang(File file) throws IOException {
|
||||
YAMLConfig config = new YAMLConfig(file);
|
||||
YAMLSection existing = config.get().clone();
|
||||
YAMLSection updated = existing.clone();
|
||||
YAMLSection rewritten = new YAMLSection();
|
||||
|
||||
Version was = existing.getMap("Settings", new ObjectMap<>()).getVersion("Version", new Version(0));
|
||||
Version now = SubAPI.getInstance().getWrapperBuild();
|
||||
|
||||
int i = 0;
|
||||
if (now == null) now = UNSIGNED;
|
||||
if (!existing.contains("Settings") || !existing.getMap("Settings").contains("Version")) {
|
||||
|
||||
i++;
|
||||
Logger.get("SubServers").info("Created ./SubServers/lang.yml");
|
||||
} else {
|
||||
if (was.compareTo(new Version("19w22b")) <= 0) {
|
||||
if (existing.contains("Lang")) {
|
||||
updated.getMap("Lang").remove("Interface.Host-Admin.SubServers");
|
||||
updated.getMap("Lang").remove("Interface.Server-Admin.Command");
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
} if (was.compareTo(new Version("20w08d")) <= 0) {
|
||||
if (existing.contains("Lang")) {
|
||||
LinkedList<String> keys = new LinkedList<>(existing.getMap("Lang").getKeys());
|
||||
for (String key : keys) if (key.startsWith("Command.")) {
|
||||
updated.getMap("Lang").remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
} if (was.compareTo(new Version("22w07c")) <= 0) {
|
||||
if (existing.contains("Lang")) {
|
||||
updated.getMap("Lang").remove("Command.Teleport");
|
||||
}
|
||||
|
||||
existing = updated.clone();
|
||||
i++;
|
||||
}// if (was.compareTo(new Version("99w99a")) <= 0) {
|
||||
// // do something
|
||||
// i++
|
||||
//}
|
||||
|
||||
if (i > 0) Logger.get("SubServers").info("Updated ./SubServers/lang.yml (" + i + " pass" + ((i != 1)?"es":"") + ")");
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
YAMLSection settings = new YAMLSection();
|
||||
settings.set("Version", ((now.compareTo(was) <= 0)?was:now).toString());
|
||||
|
||||
rewritten.set("Settings", settings);
|
||||
|
||||
LinkedHashMap<String, String> def = new LinkedHashMap<String, String>();
|
||||
def.put("Bungee.Feature.Smart-Fallback", "&6Returning from $str$: &r$msg$");
|
||||
def.put("Bungee.Feature.Smart-Fallback.Result", "&6You are now on $str$.");
|
||||
def.put("Bungee.Restricted", "&cYou don't have permission to access this server.");
|
||||
def.put("Bungee.Ping.Offline", "&6&l[&e&lWarning&6&l] &7Backend server(s) are not running");
|
||||
def.put("Bungee.Server.Current", "&6You are currently connected to $str$");
|
||||
def.put("Bungee.Server.Available", "&6You may connect to the following servers at this time:");
|
||||
def.put("Bungee.Server.List", "&6$str$");
|
||||
def.put("Bungee.Server.Hover", "$int$ player(s)\\n&oClick to connect to the server");
|
||||
def.put("Bungee.Server.Divider", "&6, ");
|
||||
def.put("Bungee.Server.Offline", "&cThe specified server is not currently running.");
|
||||
def.put("Bungee.Server.Invalid", "&cThe specified server does not exist.");
|
||||
def.put("Bungee.List.Format", "&a[$str$] &e($int$)&r: ");
|
||||
def.put("Bungee.List.List", "&f$str$");
|
||||
def.put("Bungee.List.Divider", "&f, ");
|
||||
def.put("Bungee.List.Total", "Total players online: $int$");
|
||||
def.put("Signs.Create", "&aSubServers &2&l\\u00BB&a Server sign activated");
|
||||
def.put("Signs.Delete", "&aSubServers &2&l\\u00BB&a Server sign removed");
|
||||
def.put("Signs.Text.Unknown", "&f&oSubServers\\n&3$str$\\n&7Unknown Status\\n&8\\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022");
|
||||
def.put("Signs.Text.Offline", "&c&oSubServers\\n&3$str$\\n&4Offline\\n&7Click to Start");
|
||||
def.put("Signs.Text.Starting", "&e&oSubServers\\n&3$str$\\n&6Starting\\n&8\\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022");
|
||||
def.put("Signs.Text.Online", "&a&oSubServers\\n&3$str$\\n&2$int$ Online\\n&7Click to Join");
|
||||
def.put("Signs.Text.Stopping", "&e&oSubServers\\n&3$str$\\n&6Stopping\\n&8\\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022 \\u2022");
|
||||
def.put("Command.Generic.Player-Only", "&cSubServers &4&l\\u00BB&c The console cannot perform this command");
|
||||
def.put("Command.Generic.Console-Only", "&cSubServers &4&l\\u00BB&c This command is for console use only");
|
||||
def.put("Command.Generic.Usage", "&7SubServers &8&l\\u00BB&7 Usage: &f$str$");
|
||||
def.put("Command.Generic.Exception", "&cSubServers &4&l\\u00BB&c An unexpected exception has occurred while parsing this command");
|
||||
def.put("Command.Generic.Invalid-Subcommand", "&cSubServers &4&l\\u00BB&c Unknown sub-command: &4$str$");
|
||||
def.put("Command.Generic.Invalid-Permission", "&cSubServers &4&l\\u00BB&c You need &4&n$str$&c to use this command");
|
||||
def.put("Command.Generic.Invalid-Select-Permission", "&cSubServers &4&l\\u00BB&c You don't have permission to select &4$str$");
|
||||
def.put("Command.Generic.Unknown-Proxy", "&cSubServers &4&l\\u00BB&c There is no proxy named &4$str$");
|
||||
def.put("Command.Generic.Unknown-Host", "&cSubServers &4&l\\u00BB&c There is no host named &4$str$");
|
||||
def.put("Command.Generic.Unknown-Group", "&cSubServers &4&l\\u00BB&c There is no group named &4$str$");
|
||||
def.put("Command.Generic.Unknown-Server", "&cSubServers &4&l\\u00BB&c There is no server named &4$str$");
|
||||
def.put("Command.Generic.Unknown-SubServer", "&cSubServers &4&l\\u00BB&c There is no subserver named &4$str$");
|
||||
def.put("Command.Generic.Unknown-Player", "&cSubServers &4&l\\u00BB&c There is no player named &4$str$");
|
||||
def.put("Command.Generic.No-Servers-On-Host", "&7SubServers &8&l\\u00BB&7 There are no servers on host &f$str$");
|
||||
def.put("Command.Generic.No-SubServers-On-Host", "&7SubServers &8&l\\u00BB&7 There are no subservers on host &f$str$");
|
||||
def.put("Command.Generic.No-Servers-In-Group", "&7SubServers &8&l\\u00BB&7 There are no servers in group &f$str$");
|
||||
def.put("Command.Generic.No-SubServers-In-Group", "&7SubServers &8&l\\u00BB&7 There are no subservers in group &f$str$");
|
||||
def.put("Command.Generic.No-Servers-Selected", "&cSubServers &4&l\\u00BB&c No servers were selected");
|
||||
def.put("Command.Generic.No-SubServers-Selected", "&cSubServers &4&l\\u00BB&c No subservers were selected");
|
||||
def.put("Command.Help.Header", "&7SubServers &8&l\\u00BB&7 Command Help:");
|
||||
def.put("Command.Help.Help", " &7Help:&f $str$");
|
||||
def.put("Command.Help.List", " &7List:&f $str$");
|
||||
def.put("Command.Help.Version", " &7Version:&f $str$");
|
||||
def.put("Command.Help.Info", " &7Info:&f $str$");
|
||||
def.put("Command.Help.Host.Create", " &7Create Server:&f $str$");
|
||||
def.put("Command.Help.SubServer.Start", " &7Start Server:&f $str$");
|
||||
def.put("Command.Help.SubServer.Restart", " &7Restart Server:&f $str$");
|
||||
def.put("Command.Help.SubServer.Stop", " &7Stop Server:&f $str$");
|
||||
def.put("Command.Help.SubServer.Terminate", " &7Terminate Server:&f $str$");
|
||||
def.put("Command.Help.SubServer.Command", " &7Command Server:&f $str$");
|
||||
def.put("Command.Help.SubServer.Update", " &7Update Server:&f $str$");
|
||||
def.put("Command.Version", "&7SubServers &8&l\\u00BB&7 These are the platforms and versions that are running &f$str$&7:");
|
||||
def.put("Command.Version.Outdated", "&7$name$ &f$str$ &7is available. You are $int$ version(s) behind.");
|
||||
def.put("Command.Version.Latest", "&7You are on the latest version.");
|
||||
def.put("Command.List.Group-Header", "&7SubServers &8&l\\u00BB&7 Group/Server List:");
|
||||
def.put("Command.List.Host-Header", "&7SubServers &8&l\\u00BB&7 Host/SubServer List:");
|
||||
def.put("Command.List.Server-Header", "&7SubServers &8&l\\u00BB&7 Server List:");
|
||||
def.put("Command.List.Proxy-Header", "&7SubServers &8&l\\u00BB&7 Proxy List:");
|
||||
def.put("Command.List.Header", "&7: ");
|
||||
def.put("Command.List.Divider", "&7, ");
|
||||
def.put("Command.List.Empty", "&7(none)");
|
||||
def.put("Command.Info", "&7SubServers &8&l\\u00BB&7 Info on $str$: &r");
|
||||
def.put("Command.Info.Unknown", "&cSubServers &4&l\\u00BB&c There is no object with that name");
|
||||
def.put("Command.Info.Unknown-Type", "&cSubServers &4&l\\u00BB&c There is no object type with that name");
|
||||
def.put("Command.Info.Unknown-Proxy", "&cSubServers &4&l\\u00BB&c There is no proxy with that name");
|
||||
def.put("Command.Info.Unknown-Host", "&cSubServers &4&l\\u00BB&c There is no host with that name");
|
||||
def.put("Command.Info.Unknown-Group", "&cSubServers &4&l\\u00BB&c There is no group with that name");
|
||||
def.put("Command.Info.Unknown-Server", "&cSubServers &4&l\\u00BB&c There is no server with that name");
|
||||
def.put("Command.Info.Unknown-Player", "&cSubServers &4&l\\u00BB&c There is no player with that name");
|
||||
def.put("Command.Info.Format", " -> &7$str$&7: &r");
|
||||
def.put("Command.Info.List", " - ");
|
||||
def.put("Command.Start", "&aSubServers &2&l\\u00BB&a Started &2$int$&a subserver(s)");
|
||||
def.put("Command.Start.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||
def.put("Command.Start.Host-Unavailable", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not available");
|
||||
def.put("Command.Start.Host-Disabled", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not enabled");
|
||||
def.put("Command.Start.Server-Unavailable", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not available");
|
||||
def.put("Command.Start.Server-Disabled", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not enabled");
|
||||
def.put("Command.Start.Server-Incompatible", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c cannot start while incompatible server(s) are running");
|
||||
def.put("Command.Start.Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 subserver(s) were already running");
|
||||
def.put("Command.Restart", "&aSubServers &2&l\\u00BB&a Restarting &2$int$&a subserver(s)");
|
||||
def.put("Command.Restart.Disappeared", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c has disappeared");
|
||||
def.put("Command.Restart.Host-Unavailable", "&cSubServers &4&l\\u00BB&c Could not restart server: The host for &4$str$&c is no longer available");
|
||||
def.put("Command.Restart.Host-Disabled", "&cSubServers &4&l\\u00BB&c Could not restart server: The host for &4$str$&c is no longer enabled");
|
||||
def.put("Command.Restart.Server-Unavailable", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c is no longer available");
|
||||
def.put("Command.Restart.Server-Disabled", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c is no longer enabled");
|
||||
def.put("Command.Restart.Server-Incompatible", "&cSubServers &4&l\\u00BB&c Could not restart server: Subserver &4$str$&c cannot start while incompatible server(s) are running");
|
||||
def.put("Command.Stop", "&aSubServers &2&l\\u00BB&a Stopping &2$int$&a subserver(s)");
|
||||
def.put("Command.Stop.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||
def.put("Command.Stop.Not-Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 subserver(s) were already offline");
|
||||
def.put("Command.Terminate", "&aSubServers &2&l\\u00BB&a Terminated &2$int$&a subserver(s)");
|
||||
def.put("Command.Terminate.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||
def.put("Command.Terminate.Not-Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 subserver(s) were already offline");
|
||||
def.put("Command.Command", "&aSubServers &2&l\\u00BB&a Sent command to &2$int$&a server(s)");
|
||||
def.put("Command.Command.Disappeared", "&cSubServers &4&l\\u00BB&c Server &4$str$&c has disappeared");
|
||||
def.put("Command.Command.No-Command", "&cSubServers &4&l\\u00BB&c No command was entered");
|
||||
def.put("Command.Command.Not-Running", "&7SubServers &8&l\\u00BB&7 &f$int$&7 server(s) were unavailable");
|
||||
def.put("Command.Creator", "&aSubServers &2&l\\u00BB&a Creating subserver &2$str$&a");
|
||||
def.put("Command.Creator.Exists", "&cSubServers &4&l\\u00BB&c There is already a subserver with that name");
|
||||
def.put("Command.Creator.Unknown-Host", "&cSubServers &4&l\\u00BB&c There is no host with that name");
|
||||
def.put("Command.Creator.Host-Unavailable", "&cSubServers &4&l\\u00BB&c That host is not available");
|
||||
def.put("Command.Creator.Host-Disabled", "&cSubServers &4&l\\u00BB&c That host is not enabled");
|
||||
def.put("Command.Creator.Unknown-Template", "&cSubServers &4&l\\u00BB&c There is no template with that name");
|
||||
def.put("Command.Creator.Template-Disabled", "&cSubServers &4&l\\u00BB&c That template is not enabled");
|
||||
def.put("Command.Creator.Template-Invalid", "&cSubServers &4&l\\u00BB&c That template does not support subserver updating");
|
||||
def.put("Command.Creator.Version-Required", "&cSubServers &4&l\\u00BB&c That template requires a Minecraft version to be specified");
|
||||
def.put("Command.Creator.Invalid-Port", "&cSubServers &4&l\\u00BB&c Invalid port number");
|
||||
def.put("Command.Update", "&aSubServers &2&l\\u00BB&a Updating &2$int$&a subserver(s)");
|
||||
def.put("Command.Update.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||
def.put("Command.Update.Host-Unavailable", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not available");
|
||||
def.put("Command.Update.Host-Disabled", "&cSubServers &4&l\\u00BB&c The host for &4$str$&c is not enabled");
|
||||
def.put("Command.Update.Server-Unavailable", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not available");
|
||||
def.put("Command.Update.Running", "&cSubServers &4&l\\u00BB&c Cannot update &4$str$&c while it is still running");
|
||||
def.put("Command.Update.Unknown-Template", "&cSubServers &4&l\\u00BB&c We don't know which template created &4$str$");
|
||||
def.put("Command.Update.Template-Disabled", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c is not enabled");
|
||||
def.put("Command.Update.Template-Invalid", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c does not support subserver updating");
|
||||
def.put("Command.Update.Version-Required", "&cSubServers &4&l\\u00BB&c The template that created &4$str$&c requires a Minecraft version to be specified");
|
||||
def.put("Command.Delete.Disappeared", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c has disappeared");
|
||||
def.put("Command.Delete.Running", "&cSubServers &4&l\\u00BB&c Cannot delete &4$str$&c while it is still running");
|
||||
def.put("Command.Delete", "&aSubServers &2&l\\u00BB&a Deleting &2$int$&a subserver(s)");
|
||||
def.put("Command.Teleport", "&aSubServers &2&l\\u00BB&a Teleporting to &2$str$");
|
||||
def.put("Command.Teleport.Others", "&aSubServers &2&l\\u00BB&a Teleporting &2$name$&a to &2$str$");
|
||||
def.put("Command.Teleport.Not-Running", "&cSubServers &4&l\\u00BB&c Subserver &4$str$&c is not running");
|
||||
def.put("Interface.Generic.Back", "&cBack");
|
||||
def.put("Interface.Generic.Back-Arrow", "&e&l<--");
|
||||
def.put("Interface.Generic.Next-Arrow", "&e&l-->");
|
||||
def.put("Interface.Generic.Undo", "&6Undo");
|
||||
def.put("Interface.Generic.Downloading", "&7SubServers &8&l\\u00BB&7 Downloading:&f $str$");
|
||||
def.put("Interface.Generic.Downloading.Title", "Downloading...");
|
||||
def.put("Interface.Generic.Downloading.Title-Color", "&b");
|
||||
def.put("Interface.Generic.Downloading.Title-Color-Alt", "&3");
|
||||
def.put("Interface.Generic.Downloading.Response", "&eWaiting for response");
|
||||
def.put("Interface.Generic.Invalid-Permission", "&4You need &n$str$");
|
||||
def.put("Interface.Proxy-Menu.Proxy-Player-Count", "&2$int$ Player(s) Online");
|
||||
def.put("Interface.Proxy-Menu.Proxy-Master", "&8Master Proxy");
|
||||
def.put("Interface.Proxy-Menu.Proxy-Disconnected", "&4Disconnected");
|
||||
def.put("Interface.Host-Menu.Title", "Host Menu");
|
||||
def.put("Interface.Host-Menu.Host-Unavailable", "&4Unavailable");
|
||||
def.put("Interface.Host-Menu.Host-Disabled", "&4Disabled");
|
||||
def.put("Interface.Host-Menu.Host-Server-Count", "&9$int$ Server(s)");
|
||||
def.put("Interface.Host-Menu.No-Hosts", "&c&oThere are No Hosts");
|
||||
def.put("Interface.Host-Menu.Group-Menu", "&6&lView Servers by Group");
|
||||
def.put("Interface.Host-Menu.Server-Menu", "&a&lView Servers");
|
||||
def.put("Interface.Host-Admin.Title", "Host/$str$");
|
||||
def.put("Interface.Host-Admin.Creator", "&eCreate a SubServer");
|
||||
def.put("Interface.Host-Admin.SubServers", "&bView SubServers");
|
||||
def.put("Interface.Host-Admin.Plugins", "&bPlugins...");
|
||||
def.put("Interface.Host-Creator.Title", "Host/$str$/Create");
|
||||
def.put("Interface.Host-Creator.Edit-Name", "Change Name");
|
||||
def.put("Interface.Host-Creator.Edit-Name.Title", "&eSubCreator\\n&6Enter a Name for this Server");
|
||||
def.put("Interface.Host-Creator.Edit-Name.Message", "&eSubCreator &6&l\\u00BB&e Enter a Name for this Server via Chat");
|
||||
def.put("Interface.Host-Creator.Edit-Name.Exists", "&cSubCreator &4&l\\u00BB&c There is already a SubServer with that name");
|
||||
def.put("Interface.Host-Creator.Edit-Name.Exists-Title", "&eSubCreator\\n&cThere is already a SubServer with that name");
|
||||
def.put("Interface.Host-Creator.Edit-Name.Invalid", "&cSubCreator &4&l\\u00BB&c Invalid Server Name");
|
||||
def.put("Interface.Host-Creator.Edit-Name.Invalid-Title", "&eSubCreator\\n&cInvalid Server Name");
|
||||
def.put("Interface.Host-Creator.Edit-Template", "Change Server Template");
|
||||
def.put("Interface.Host-Creator.Edit-Template.Title", "Host/$str$/Templates");
|
||||
def.put("Interface.Host-Creator.Edit-Template.No-Templates", "&c&oThere are No Templates");
|
||||
def.put("Interface.Host-Creator.Edit-Version", "Change Server Version");
|
||||
def.put("Interface.Host-Creator.Edit-Version.Title", "&eSubCreator\\n&6Enter a Server Version");
|
||||
def.put("Interface.Host-Creator.Edit-Version.Message", "&eSubCreator &6&l\\u00BB&e Enter a Server Version via Chat");
|
||||
def.put("Interface.Host-Creator.Edit-Port", "Change Server Port");
|
||||
def.put("Interface.Host-Creator.Edit-Port.Title", "&eSubCreator\\n&6Enter a Port Number");
|
||||
def.put("Interface.Host-Creator.Edit-Port.Message", "&eSubCreator &6&l\\u00BB&e Enter a Port Number via Chat");
|
||||
def.put("Interface.Host-Creator.Edit-Port.Invalid", "&cSubCreator &4&l\\u00BB&c Invalid Port Number");
|
||||
def.put("Interface.Host-Creator.Edit-Port.Invalid-Title", "&eSubCreator\\n&cInvalid Port Number");
|
||||
def.put("Interface.Host-Creator.Submit", "&eCreate SubServer");
|
||||
def.put("Interface.Host-Creator.Form-Incomplete", "&4Buttons above must be green");
|
||||
def.put("Interface.Host-Plugin.Title", "Host/$str$/Plugins");
|
||||
def.put("Interface.Host-Plugin.No-Plugins", "&c&oThere are No Plugins Available");
|
||||
def.put("Interface.Host-SubServer.Title", "Host/$str$/SubServers");
|
||||
def.put("Interface.Group-Menu.Title", "Group Menu");
|
||||
def.put("Interface.Group-Menu.Group-Server-Count", "&9$int$ Server(s)");
|
||||
def.put("Interface.Group-Menu.Ungrouped", "&7(ungrouped)");
|
||||
def.put("Interface.Group-Menu.Server-Menu", "&a&lView All Servers");
|
||||
def.put("Interface.Group-SubServer.Title", "Group/$str$/Servers");
|
||||
def.put("Interface.Group-SubServer.Title-Ungrouped", "Ungrouped Server Menu");
|
||||
def.put("Interface.Server-Menu.Title", "Server Menu");
|
||||
def.put("Interface.Server-Menu.Server-Player-Count", "&2$int$ Player(s) Online");
|
||||
def.put("Interface.Server-Menu.Server-External", "&7External Server");
|
||||
def.put("Interface.Server-Menu.SubServer-Temporary", "&9Temporary");
|
||||
def.put("Interface.Server-Menu.SubServer-Offline", "&6Offline");
|
||||
def.put("Interface.Server-Menu.SubServer-Incompatible", "&4Incompatible with $str$");
|
||||
def.put("Interface.Server-Menu.SubServer-Unavailable", "&4Unavailable");
|
||||
def.put("Interface.Server-Menu.SubServer-Disabled", "&4Disabled");
|
||||
def.put("Interface.Server-Menu.No-Servers", "&c&oThere are No Servers");
|
||||
def.put("Interface.Server-Menu.Host-Menu", "&b&lView Hosts");
|
||||
def.put("Interface.Server-Admin.Title", "Server/$str$");
|
||||
def.put("Interface.Server-Admin.Start", "&aStart SubServer");
|
||||
def.put("Interface.Server-Admin.Start.Title", "&aStarting SubServer");
|
||||
def.put("Interface.Server-Admin.Stop", "&cStop SubServer");
|
||||
def.put("Interface.Server-Admin.Stop.Title", "&cStopping $str$");
|
||||
def.put("Interface.Server-Admin.Terminate", "&4Terminate SubServer");
|
||||
def.put("Interface.Server-Admin.Terminate.Title", "&cTerminating $str$");
|
||||
def.put("Interface.Server-Admin.Command", "&bSend a Command to the Server");
|
||||
def.put("Interface.Server-Admin.Command.Title", "&eSubServers\\n&6Enter a Command to send via Chat");
|
||||
def.put("Interface.Server-Admin.Command.Message", "&eSubServers &6&l\\u00BB&e Enter a Command to send via Chat");
|
||||
def.put("Interface.Server-Admin.Update", "&eUpdate SubServer");
|
||||
def.put("Interface.Server-Admin.Update.Title", "&eSubServers\\n&6Enter a Server Version to update to");
|
||||
def.put("Interface.Server-Admin.Update.Message", "&eSubServers &6&l\\u00BB&e Enter a Server Version to update to via Chat");
|
||||
def.put("Interface.Server-Admin.Plugins", "&bPlugins...");
|
||||
def.put("Interface.SubServer-Plugin.Title", "Server/$str$/Plugins");
|
||||
def.put("Interface.SubServer-Plugin.No-Plugins", "&c&oThere are No Plugins Available");
|
||||
|
||||
YAMLSection lang = new YAMLSection();
|
||||
for (String key : def.keySet()) lang.set(key, updated.getMap("Lang", new YAMLSection()).getString(key, def.get(key)));
|
||||
rewritten.set("Lang", lang);
|
||||
|
||||
config.set(rewritten);
|
||||
config.save();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
/**
|
||||
* Container Class
|
||||
*
|
||||
* @param <V> Item
|
||||
*/
|
||||
public class Container<V> {
|
||||
private V obj;
|
||||
|
||||
/**
|
||||
* Creates a Container
|
||||
*
|
||||
* @param item Object to Store
|
||||
*/
|
||||
public Container(V item) {
|
||||
obj = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the Object
|
||||
*
|
||||
* @return The Object
|
||||
*/
|
||||
public V get() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite the Object
|
||||
*
|
||||
* @param value Object to Store
|
||||
*/
|
||||
public void set(V value) {
|
||||
obj = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof Container) {
|
||||
if (obj == null || ((Container) object).get() == null) {
|
||||
return obj == ((Container) object).get();
|
||||
} else {
|
||||
return obj.equals(((Container) object).get());
|
||||
}
|
||||
} else {
|
||||
return super.equals(object);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLValue;
|
||||
|
||||
/**
|
||||
* Extra Data Handler Layout Class
|
||||
*/
|
||||
public interface ExtraDataHandler {
|
||||
/**
|
||||
* Add an extra value to this Object
|
||||
*
|
||||
* @param handle Handle
|
||||
* @param value Value
|
||||
*/
|
||||
void addExtra(String handle, Object value);
|
||||
|
||||
/**
|
||||
* Determine if an extra value exists
|
||||
*
|
||||
* @param handle Handle
|
||||
* @return Value Status
|
||||
*/
|
||||
boolean hasExtra(String handle);
|
||||
|
||||
/**
|
||||
* Get an extra value
|
||||
*
|
||||
* @param handle Handle
|
||||
* @return Value
|
||||
*/
|
||||
YAMLValue getExtra(String handle);
|
||||
|
||||
/**
|
||||
* Get the extra value section
|
||||
*
|
||||
* @return Extra Value Section
|
||||
*/
|
||||
YAMLSection getExtra();
|
||||
|
||||
/**
|
||||
* Remove an extra value from this Object
|
||||
*
|
||||
* @param handle Handle
|
||||
*/
|
||||
void removeExtra(String handle);
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Directories;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* File Scanner Base Class
|
||||
*/
|
||||
public abstract class FileScanner {
|
||||
|
||||
/**
|
||||
* Scan a Directory
|
||||
*
|
||||
* @param dir Directory
|
||||
* @param whitelist File Whitelist
|
||||
*/
|
||||
protected void scan(File dir, String... whitelist) throws IOException {
|
||||
List<String> files = Directories.search(dir);
|
||||
if (files.size() <= 0 || whitelist.length <= 0)
|
||||
return;
|
||||
|
||||
boolean csfs = false;
|
||||
{
|
||||
long stamp = Math.round(Math.random() * 100000);
|
||||
File test1 = new File(dir, '.' + stamp + ".ss_fsc");
|
||||
File test2 = new File(dir, '.' + stamp + ".SS_FSC");
|
||||
|
||||
test1.createNewFile();
|
||||
if (test2.createNewFile()) {
|
||||
csfs = true;
|
||||
test2.delete();
|
||||
}
|
||||
test1.delete();
|
||||
}
|
||||
|
||||
LinkedHashMap<Pattern, Boolean> rules = new LinkedHashMap<Pattern, Boolean>();
|
||||
for (String entry : whitelist) {
|
||||
boolean mode = !entry.startsWith("!");
|
||||
if (!mode) entry = entry.substring(1);
|
||||
|
||||
String pattern;
|
||||
if (!entry.startsWith("%")) {
|
||||
if (entry.startsWith("./"))
|
||||
entry = entry.substring(1);
|
||||
|
||||
StringBuilder rule = new StringBuilder();
|
||||
if (entry.startsWith("**")) {
|
||||
entry = entry.substring(2);
|
||||
rule.append("^.*");
|
||||
} else if (entry.startsWith("/")) {
|
||||
rule.append("^");
|
||||
}
|
||||
|
||||
boolean greedyEnding = false;
|
||||
if (entry.endsWith("**")) {
|
||||
entry = entry.substring(0, entry.length() - 2);
|
||||
greedyEnding = true;
|
||||
} else if (entry.endsWith("/")) {
|
||||
greedyEnding = true;
|
||||
}
|
||||
|
||||
StringBuilder literal = new StringBuilder();
|
||||
for (PrimitiveIterator.OfInt i = entry.codePoints().iterator(); i.hasNext(); ) {
|
||||
int c = i.next();
|
||||
if ((c == '*' || c == '?' || c == '[') && literal.length() > 0) {
|
||||
rule.append(Pattern.quote(literal.toString()));
|
||||
literal = new StringBuilder();
|
||||
}
|
||||
switch (c) {
|
||||
case '[':
|
||||
for (boolean escaped = false; i.hasNext() && (c != ']' || escaped); c = i.next()) {
|
||||
if (c == '\\') escaped = !escaped;
|
||||
else escaped = false;
|
||||
literal.appendCodePoint(c);
|
||||
}
|
||||
if (c == ']' && literal.length() > 1) {
|
||||
literal.appendCodePoint(c);
|
||||
rule.append(literal.toString());
|
||||
}
|
||||
literal = new StringBuilder();
|
||||
break;
|
||||
case '*':
|
||||
rule.append("[^/]+");
|
||||
break;
|
||||
case '?':
|
||||
rule.append("[^/]");
|
||||
break;
|
||||
case '\\':
|
||||
if (i.hasNext()) c = i.next();
|
||||
default:
|
||||
literal.appendCodePoint(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (literal.length() > 0)
|
||||
rule.append(Pattern.quote(literal.toString()));
|
||||
|
||||
if (greedyEnding)
|
||||
rule.append(".*");
|
||||
rule.append("$");
|
||||
pattern = rule.toString();
|
||||
} else {
|
||||
pattern = entry.substring(1);
|
||||
}
|
||||
|
||||
if (csfs) rules.put(Pattern.compile(pattern), mode);
|
||||
else rules.put(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE), mode);
|
||||
}
|
||||
|
||||
for (String file : files) {
|
||||
boolean act = false;
|
||||
|
||||
for (Map.Entry<Pattern, Boolean> rule : rules.entrySet()) {
|
||||
if (rule.getKey().matcher('/' + file.replace(File.separatorChar, '/')).find()) act = rule.getValue();
|
||||
}
|
||||
|
||||
if (act) act(dir, file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform an action on an included file
|
||||
*
|
||||
* @param dir Parent Directory
|
||||
* @param name File Name
|
||||
*/
|
||||
protected abstract void act(File dir, String name) throws IOException;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
Settings:
|
||||
Version: '2.11.2a+'
|
||||
Log-Creator: true
|
||||
Override-Bungee-Commands: true
|
||||
UPnP:
|
||||
Forward-Proxy: true
|
||||
Forward-SubData: false
|
||||
Forward-Servers: false
|
||||
SubData:
|
||||
Address: '127.0.0.1:4391'
|
||||
Password: 'default'
|
||||
Encryption: 'AES'
|
||||
Allowed-Connections: []
|
||||
|
||||
Hosts:
|
||||
'~':
|
||||
Enabled: true
|
||||
Display: 'Default'
|
||||
Driver: 'BUILT-IN'
|
||||
Address: '127.0.0.1'
|
||||
Port-Range: '25500-25559'
|
||||
Directory: './SubServers/Servers'
|
||||
Git-Bash: '%ProgramFiles%\Git'
|
||||
|
||||
Servers:
|
||||
'Example':
|
||||
Enabled: false
|
||||
Display: ''
|
||||
Host: '~'
|
||||
Group: []
|
||||
Port: 25567
|
||||
Motd: '&aThis is a SubServer'
|
||||
Log: true
|
||||
Directory: './Example'
|
||||
Executable: 'java -Djline.terminal=jline.UnsupportedTerminal -jar Spigot.jar'
|
||||
Stop-Command: 'stop'
|
||||
Stop-Action: 'NONE'
|
||||
Run-On-Launch: false
|
||||
Restricted: false
|
||||
Incompatible: []
|
||||
Hidden: false
|
|
@ -0,0 +1,163 @@
|
|||
Version: '2.13.1a+'
|
||||
Lang:
|
||||
'Bungee.Feature.Return': '&6Returning to $str$: &r$msg$'
|
||||
'Bungee.Server.Current': '&6You are currently connected to $str$'
|
||||
'Bungee.Server.Available': '&6You may connect to the following servers at this time:'
|
||||
'Bungee.Server.List': '&6$str$'
|
||||
'Bungee.Server.Hover': '$int$ player(s)\n&oClick to connect to the server'
|
||||
'Bungee.Server.Divider': '&6, '
|
||||
'Bungee.Server.Invalid': '&cThe specified server does not exist.'
|
||||
'Bungee.List.Format': '&a[$str$] &e($int$)&r: '
|
||||
'Bungee.List.List': '&f$str$'
|
||||
'Bungee.List.Divider': '&f, '
|
||||
'Bungee.List.Total': 'Total players online: $int$'
|
||||
'Command.Generic.Player-Only': '&cSubServers &4&l\u00BB&c Console cannot run this command'
|
||||
'Command.Generic.Console-Only': '&cSubServers &4&l\u00BB&c This command is for console use only'
|
||||
'Command.Generic.Usage': '&7SubServers &8&l\u00BB&7 Usage: &f$str$'
|
||||
'Command.Generic.Exception': '&cSubServers &4&l\u00BB&c An unexpected exception has occurred while parsing this command'
|
||||
'Command.Generic.Invalid-Subcommand': '&cSubServers &4&l\u00BB&c Unknown sub-command: $str$'
|
||||
'Command.Generic.Invalid-Permission': '&cSubServers &4&l\u00BB&c You need &4&n$str$&c to use this command'
|
||||
'Command.Generic.Unknown-Proxy': '&cSubServers &4&l\u00BB&c There is no proxy with that name'
|
||||
'Command.Generic.Unknown-Host': '&cSubServers &4&l\u00BB&c There is no host with that name'
|
||||
'Command.Generic.Unknown-Group': '&cSubServers &4&l\u00BB&c There is no group with that name'
|
||||
'Command.Generic.Unknown-Server': '&cSubServers &4&l\u00BB&c There is no server with that name'
|
||||
'Command.Generic.Unknown-SubServer': '&cSubServers &4&l\u00BB&c There is no subserver with that name'
|
||||
'Command.Help.Header': '&7SubServers &8&l\u00BB&7 Command Help:'
|
||||
'Command.Help.Help': ' &7Help:&f $str$'
|
||||
'Command.Help.List': ' &7List:&f $str$'
|
||||
'Command.Help.Version': ' &7Version:&f $str$'
|
||||
'Command.Help.Info': ' &7Info:&f $str$'
|
||||
'Command.Help.Terminate': ' &7Teleport to Server:&f $str$'
|
||||
'Command.Help.Host.Create': ' &7Create Server:&f $str$'
|
||||
'Command.Help.SubServer.Start': ' &7Start Server:&f $str$'
|
||||
'Command.Help.SubServer.Stop': ' &7Stop Server:&f $str$'
|
||||
'Command.Help.SubServer.Terminate': ' &7Terminate Server:&f $str$'
|
||||
'Command.Help.SubServer.Command': ' &7Command Server:&f $str$'
|
||||
'Command.Version': '&7SubServers &8&l\u00BB&7 These are the platforms and versions that are running &f$str$&7:'
|
||||
'Command.Version.Outdated': '&7$name$ &f$str$ &7is available. You are $int$ version(s) behind.'
|
||||
'Command.Version.Latest': '&7You are on the latest version.'
|
||||
'Command.List.Group-Header': '&7SubServers &8&l\u00BB&7 Group/Server List:'
|
||||
'Command.List.Host-Header': '&7SubServers &8&l\u00BB&7 Host/SubServer List:'
|
||||
'Command.List.Server-Header': '&7SubServers &8&l\u00BB&7 Server List:'
|
||||
'Command.List.Proxy-Header': '&7SubServers &8&l\u00BB&7 Proxy List:'
|
||||
'Command.List.Header': '&7: '
|
||||
'Command.List.Divider': '&7, '
|
||||
'Command.List.Empty': '&7(none)'
|
||||
'Command.Info': '&7SubServers &8&l\u00BB&7 Info on $str$&7: &r'
|
||||
'Command.Info.Unknown': '&cSubServers &4&l\u00BB&c There is no object with that name'
|
||||
'Command.Info.Unknown-Type': '&cSubServers &4&l\u00BB&c There is no object type with that name'
|
||||
'Command.Info.Unknown-Proxy': '&cSubServers &4&l\u00BB&c There is no proxy with that name'
|
||||
'Command.Info.Unknown-Host': '&cSubServers &4&l\u00BB&c There is no host with that name'
|
||||
'Command.Info.Unknown-Group': '&cSubServers &4&l\u00BB&c There is no group with that name'
|
||||
'Command.Info.Unknown-Server': '&cSubServers &4&l\u00BB&c There is no server with that name'
|
||||
'Command.Info.Format': ' -> &7$str$&7: &r'
|
||||
'Command.Info.List': ' - '
|
||||
'Command.Start': '&aSubServers &2&l\u00BB&a Starting SubServer'
|
||||
'Command.Start.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
||||
'Command.Start.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
||||
'Command.Start.Host-Unavailable': '&cSubServers &4&l\u00BB&c That SubServer\u0027s Host is not available'
|
||||
'Command.Start.Host-Disabled': '&cSubServers &4&l\u00BB&c That SubServer\u0027s Host is not enabled'
|
||||
'Command.Start.Server-Disabled': '&cSubServers &4&l\u00BB&c That SubServer is not enabled'
|
||||
'Command.Start.Server-Incompatible': '&cSubServers &4&l\u00BB&c That SubServer cannot start while these server(s) are running: &4$str$'
|
||||
'Command.Start.Running': '&cSubServers &4&l\u00BB&c That SubServer is already running'
|
||||
'Command.Stop': '&aSubServers &2&l\u00BB&a Stopping SubServer'
|
||||
'Command.Stop.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
||||
'Command.Stop.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
||||
'Command.Stop.Not-Running': '&cSubServers &4&l\u00BB&c That SubServer is not running'
|
||||
'Command.Terminate': '&aSubServers &2&l\u00BB&a Stopping SubServer'
|
||||
'Command.Terminate.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
||||
'Command.Terminate.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
||||
'Command.Terminate.Not-Running': '&cSubServers &4&l\u00BB&c That SubServer is not running'
|
||||
'Command.Command': '&aSubServers &2&l\u00BB&a Sending command to SubServer'
|
||||
'Command.Command.Unknown': '&cSubServers &4&l\u00BB&c There is no Server with that name'
|
||||
'Command.Command.Invalid': '&cSubServers &4&l\u00BB&c That Server is not a SubServer'
|
||||
'Command.Command.Not-Running': '&cSubServers &4&l\u00BB&c That SubServer is not running'
|
||||
'Command.Creator': '&aSubServers &2&l\u00BB&a Creating SubServer'
|
||||
'Command.Creator.Exists': '&cSubServers &4&l\u00BB&c There is already a SubServer with that name'
|
||||
'Command.Creator.Unknown-Host': '&cSubServers &4&l\u00BB&c There is no Host with that name'
|
||||
'Command.Creator.Host-Unavailable': '&cSubServers &4&l\u00BB&c That Host is not available'
|
||||
'Command.Creator.Host-Disabled': '&cSubServers &4&l\u00BB&c That Host is not enabled'
|
||||
'Command.Creator.Unknown-Template': '&cSubServers &4&l\u00BB&c There is no Template with that name'
|
||||
'Command.Creator.Template-Disabled': '&cSubServers &4&l\u00BB&c That Template is not enabled'
|
||||
'Command.Creator.Invalid-Version': '&cSubServers &4&l\u00BB&c SubCreator cannot create servers before Minecraft 1.8'
|
||||
'Command.Creator.Invalid-Port': '&cSubServers &4&l\u00BB&c Invalid Port Number'
|
||||
'Interface.Generic.Back': '&cBack'
|
||||
'Interface.Generic.Back-Arrow': '&e&l<--'
|
||||
'Interface.Generic.Next-Arrow': '&e&l-->'
|
||||
'Interface.Generic.Undo': '&6Undo'
|
||||
'Interface.Generic.Downloading': '&7SubServers &8&l\u00BB&7 Downloading:&f $str$'
|
||||
'Interface.Generic.Downloading.Title': 'Downloading...'
|
||||
'Interface.Generic.Downloading.Title-Color': '&b'
|
||||
'Interface.Generic.Downloading.Title-Color-Alt': '&3'
|
||||
'Interface.Generic.Downloading.Response': '&eWaiting for response'
|
||||
'Interface.Generic.Invalid-Permission': '&4You need &n$str$'
|
||||
'Interface.Proxy-Menu.Proxy-Player-Count': '&2$int$ Player(s) Online'
|
||||
'Interface.Proxy-Menu.Proxy-Master': '&8Master Proxy'
|
||||
'Interface.Proxy-Menu.Proxy-SubData': '&9SubData Only'
|
||||
'Interface.Proxy-Menu.Proxy-Redis': '&7Redis Only'
|
||||
'Interface.Proxy-Menu.Proxy-Disconnected': '&4Disconnected'
|
||||
'Interface.Host-Menu.Title': 'Host Menu'
|
||||
'Interface.Host-Menu.Host-Unavailable': '&4Unavailable'
|
||||
'Interface.Host-Menu.Host-Disabled': '&4Disabled'
|
||||
'Interface.Host-Menu.Host-Server-Count': '&9$int$ Server(s)'
|
||||
'Interface.Host-Menu.No-Hosts': '&c&oThere are No Hosts'
|
||||
'Interface.Host-Menu.Group-Menu': '&6&lView Servers by Group'
|
||||
'Interface.Host-Menu.Server-Menu': '&a&lView Servers'
|
||||
'Interface.Host-Admin.Title': 'Host/$str$'
|
||||
'Interface.Host-Admin.Creator': '&eCreate a SubServer'
|
||||
'Interface.Host-Admin.SubServers': '&aView SubServers'
|
||||
'Interface.Host-Admin.Plugins': '&bPlugins...'
|
||||
'Interface.Host-Creator.Title': 'Host/$str$/Create'
|
||||
'Interface.Host-Creator.Edit-Name': 'Change Name'
|
||||
'Interface.Host-Creator.Edit-Name.Title': '&eSubCreator\n&6Enter a Name for this Server'
|
||||
'Interface.Host-Creator.Edit-Name.Message': '&eSubCreator &6&l\u00BB&e Enter a Name for this Server via Chat'
|
||||
'Interface.Host-Creator.Edit-Name.Exists': '&cSubCreator &4&l\u00BB&c There is already a SubServer with that name'
|
||||
'Interface.Host-Creator.Edit-Name.Exists-Title': '&eSubCreator\n&cThere is already a SubServer with that name'
|
||||
'Interface.Host-Creator.Edit-Name.Invalid': '&cSubCreator &4&l\u00BB&c Invalid Server Name'
|
||||
'Interface.Host-Creator.Edit-Name.Invalid-Title': '&eSubCreator\n&cInvalid Server Name'
|
||||
'Interface.Host-Creator.Edit-Template': 'Change Server Template'
|
||||
'Interface.Host-Creator.Edit-Template.Title': 'Host/$str$/Templates'
|
||||
'Interface.Host-Creator.Edit-Template.No-Templates': '&c&oThere are No Templates'
|
||||
'Interface.Host-Creator.Edit-Version': 'Change Server Version'
|
||||
'Interface.Host-Creator.Edit-Version.Title': '&eSubCreator\n&6Enter a Server Version'
|
||||
'Interface.Host-Creator.Edit-Version.Message': '&eSubCreator &6&l\u00BB&e Enter a Server Version via Chat'
|
||||
'Interface.Host-Creator.Edit-Version.Unavailable': '&cSubCreator &4&l\u00BB&c SubCreator cannot create servers before Minecraft 1.8'
|
||||
'Interface.Host-Creator.Edit-Version.Unavailable-Title': '&eSubCreator\n&cCannot create servers before MC 1.8'
|
||||
'Interface.Host-Creator.Edit-Port': 'Change Server Port'
|
||||
'Interface.Host-Creator.Edit-Port.Title': '&eSubCreator\n&6Enter a Port Number'
|
||||
'Interface.Host-Creator.Edit-Port.Message': '&eSubCreator &6&l\u00BB&e Enter a Port Number via Chat'
|
||||
'Interface.Host-Creator.Edit-Port.Invalid': '&cSubCreator &4&l\u00BB&c Invalid Port Number'
|
||||
'Interface.Host-Creator.Edit-Port.Invalid-Title': '&eSubCreator\n&cInvalid Port Number'
|
||||
'Interface.Host-Creator.Submit': '&eCreate SubServer'
|
||||
'Interface.Host-Creator.Form-Incomplete': '&4Buttons above must be green'
|
||||
'Interface.Host-Plugin.Title': 'Host/$str$/Plugins'
|
||||
'Interface.Host-Plugin.No-Plugins': '&c&oThere are No Plugins Available'
|
||||
'Interface.Host-SubServer.Title': 'Host/$str$/SubServers'
|
||||
'Interface.Group-Menu.Title': 'Group Menu'
|
||||
'Interface.Group-Menu.Group-Server-Count': '&9$int$ Server(s)'
|
||||
'Interface.Group-Menu.No-Groups': '&c&oThere are No Groups'
|
||||
'Interface.Group-Menu.Server-Menu': '&a&lView All Servers'
|
||||
'Interface.Group-SubServer.Title': 'Group/$str$/Servers'
|
||||
'Interface.Server-Menu.Title': 'Server Menu'
|
||||
'Interface.Server-Menu.Server-Player-Count': '&2$int$ Player(s) Online'
|
||||
'Interface.Server-Menu.Server-External': '&7External Server'
|
||||
'Interface.Server-Menu.SubServer-Temporary': '&9Temporary'
|
||||
'Interface.Server-Menu.SubServer-Offline': '&6Offline'
|
||||
'Interface.Server-Menu.SubServer-Incompatible': '&4Incompatible with $str$'
|
||||
'Interface.Server-Menu.SubServer-Disabled': '&4Disabled'
|
||||
'Interface.Server-Menu.SubServer-Invalid': '&4Cannot be managed by SubServers'
|
||||
'Interface.Server-Menu.No-Servers': '&c&oThere are No Servers'
|
||||
'Interface.Server-Menu.Host-Menu': '&b&lView Hosts'
|
||||
'Interface.SubServer-Admin.Title': 'SubServer/$str$'
|
||||
'Interface.SubServer-Admin.Start': '&aStart SubServer'
|
||||
'Interface.SubServer-Admin.Start.Title': '&aStarting SubServer'
|
||||
'Interface.SubServer-Admin.Stop': '&cStop SubServer'
|
||||
'Interface.SubServer-Admin.Stop.Title': '&cStopping $str$'
|
||||
'Interface.SubServer-Admin.Terminate': '&4Terminate SubServer'
|
||||
'Interface.SubServer-Admin.Terminate.Title': '&cTerminating $str$'
|
||||
'Interface.SubServer-Admin.Command': '&eSend a Command to the SubServer'
|
||||
'Interface.SubServer-Admin.Command.Title': '&eSubServers\n&6Enter a Command to send via Chat'
|
||||
'Interface.SubServer-Admin.Command.Message': '&eSubServers &6&l\u00BB&e Enter a Command to send via Chat'
|
||||
'Interface.SubServer-Admin.Plugins': '&bPlugins...'
|
||||
'Interface.SubServer-Plugin.Title': 'SubServer/$str$/Plugins'
|
||||
'Interface.SubServer-Plugin.No-Plugins': '&c&oThere are No Plugins Available'
|
|
@ -0,0 +1,457 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
import net.md_5.bungee.config.ConfigurationProvider;
|
||||
import net.md_5.bungee.config.YamlConfiguration;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
*
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'n', 'g', 'e', 'e', 'c', 'o', 'r', 'd'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bungeecord";
|
||||
|
||||
// The plugin
|
||||
private final SubPlugin plugin;
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// The uuid of the server
|
||||
private String serverUUID;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private boolean logFailedRequests = false;
|
||||
|
||||
// A list with all known metrics class objects including this one
|
||||
private static final List<Object> knownMetricsInstances = new ArrayList<>();
|
||||
|
||||
public Metrics(SubPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
try {
|
||||
loadConfig();
|
||||
} catch (IOException e) {
|
||||
// Failed to load configuration
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to load bStats config!", e);
|
||||
return;
|
||||
}
|
||||
|
||||
// We are not allowed to send data about this server :(
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> usedMetricsClass = getFirstBStatsClass();
|
||||
if (usedMetricsClass == null) {
|
||||
// Failed to get first metrics class
|
||||
return;
|
||||
}
|
||||
if (usedMetricsClass == getClass()) {
|
||||
// We are the first! :)
|
||||
linkMetrics(this);
|
||||
startSubmitting();
|
||||
} else {
|
||||
// We aren't the first so we link to the first metrics class
|
||||
try {
|
||||
usedMetricsClass.getMethod("linkMetrics", Object.class).invoke(null,this);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to link to first metrics class " + usedMetricsClass.getName() + "!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Links an other metrics class with this class.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @param metrics An object of the metrics class to link.
|
||||
*/
|
||||
public static void linkMetrics(Object metrics) {
|
||||
knownMetricsInstances.add(metrics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
String pluginName = "SubServers 2";
|
||||
String pluginVersion = plugin.version.toString();
|
||||
|
||||
data.addProperty("pluginName", pluginName);
|
||||
data.addProperty("pluginVersion", pluginVersion);
|
||||
|
||||
JsonArray customCharts = new JsonArray();
|
||||
customCharts.add(new SingleLineChart("managed_hosts", new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
return plugin.api.getHosts().size();
|
||||
}
|
||||
}).getRequestJsonObject(plugin.getLogger(), logFailedRequests));
|
||||
customCharts.add(new SingleLineChart("subdata_connected", new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
return (plugin.subdata != null)?plugin.subdata.getClients().size():0;
|
||||
}
|
||||
}).getRequestJsonObject(plugin.getLogger(), logFailedRequests));
|
||||
data.add("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private void startSubmitting() {
|
||||
new Timer().schedule( new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// The data collection is async, as well as sending the data
|
||||
// Bungeecord does not have a main thread, everything is async
|
||||
submitData();
|
||||
}
|
||||
}, TimeUnit.MINUTES.toMillis(2), TimeUnit.MINUTES.toMillis(30));
|
||||
// Submit the data every 30 minutes, first time after 2 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount = plugin.getOnlineCount();
|
||||
playerAmount = playerAmount > 500 ? 500 : playerAmount;
|
||||
int onlineMode = plugin.getConfig().isOnlineMode() ? 1 : 0;
|
||||
String bungeecordVersion = (plugin.getName().equals("SubServers Platform"))?"SubServers-Bungee-Patched":plugin.getVersion();
|
||||
int managedServers = plugin.getServers().size();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("managedServers", managedServers);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bungeecordVersion", bungeecordVersion);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JsonObject data = getServerData();
|
||||
|
||||
final JsonArray pluginData = new JsonArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Object metrics : knownMetricsInstances) {
|
||||
try {
|
||||
Object plugin = metrics.getClass().getMethod("getPluginData").invoke(metrics);
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the bStats configuration.
|
||||
*
|
||||
* @throws IOException If something did not work :(
|
||||
*/
|
||||
private void loadConfig() throws IOException {
|
||||
Path configPath = new File(plugin.dir, "plugins").toPath().resolve("bStats");
|
||||
configPath.toFile().mkdirs();
|
||||
File configFile = new File(configPath.toFile(), "config.yml");
|
||||
if (!configFile.exists()) {
|
||||
writeFile(configFile,
|
||||
"#bStats collects some data for plugin authors like how many servers are using their plugins.",
|
||||
"#To honor their work, you should not disable it.",
|
||||
"#This has nearly no effect on the server performance!",
|
||||
"#Check out https://bStats.org/ to learn more :)",
|
||||
"enabled: true",
|
||||
"serverUuid: \"" + UUID.randomUUID().toString() + "\"",
|
||||
"logFailedRequests: false");
|
||||
}
|
||||
|
||||
Configuration configuration = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
|
||||
|
||||
// Load configuration
|
||||
enabled = configuration.getBoolean("enabled", true);
|
||||
serverUUID = configuration.getString("serverUuid");
|
||||
logFailedRequests = configuration.getBoolean("logFailedRequests", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first bStat Metrics class.
|
||||
*
|
||||
* @return The first bStats metrics class.
|
||||
*/
|
||||
private Class<?> getFirstBStatsClass() {
|
||||
Path configPath = new File(plugin.dir, "plugins").toPath().resolve("bStats");
|
||||
configPath.toFile().mkdirs();
|
||||
File tempFile = new File(configPath.toFile(), "temp.txt");
|
||||
|
||||
try {
|
||||
String className = readFile(tempFile);
|
||||
if (className != null) {
|
||||
try {
|
||||
// Let's check if a class with the given name exists.
|
||||
return Class.forName(className);
|
||||
} catch (ClassNotFoundException ignored) { }
|
||||
}
|
||||
writeFile(tempFile, getClass().getName());
|
||||
return getClass();
|
||||
} catch (IOException e) {
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to get first bStats class!", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the first line of the file.
|
||||
*
|
||||
* @param file The file to read. Cannot be null.
|
||||
* @return The first line of the file or <code>null</code> if the file does not exist or is empty.
|
||||
* @throws IOException If something did not work :(
|
||||
*/
|
||||
private String readFile(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
try (
|
||||
FileReader fileReader = new FileReader(file);
|
||||
BufferedReader bufferedReader = new BufferedReader(fileReader);
|
||||
) {
|
||||
return bufferedReader.readLine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a String to a file. It also adds a note for the user,
|
||||
*
|
||||
* @param file The file to write to. Cannot be null.
|
||||
* @param lines The lines to write.
|
||||
* @throws IOException If something did not work :(
|
||||
*/
|
||||
private void writeFile(File file, String... lines) throws IOException {
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
try (
|
||||
FileWriter fileWriter = new FileWriter(file);
|
||||
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)
|
||||
) {
|
||||
for (String line : lines) {
|
||||
bufferedWriter.write(line);
|
||||
bufferedWriter.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(JsonObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null");
|
||||
}
|
||||
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes("UTF-8"));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
private static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
private final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId) {
|
||||
if (chartId == null || chartId.isEmpty()) {
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
JsonObject getRequestJsonObject(Logger logger, boolean logFailedRequests) {
|
||||
JsonObject chart = new JsonObject();
|
||||
chart.addProperty("chartId", chartId);
|
||||
try {
|
||||
JsonObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.add("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
logger.log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JsonObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
private static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
/**
|
||||
* Named Container Class
|
||||
* @param <T> Name
|
||||
* @param <V> Item
|
||||
*/
|
||||
public class NamedContainer<T, V> extends Container<V> {
|
||||
private T name;
|
||||
|
||||
/**
|
||||
* Creates a TaggedContainer
|
||||
*
|
||||
* @param name Tag to Bind
|
||||
* @param item Object to Store
|
||||
*/
|
||||
public NamedContainer(T name, V item) {
|
||||
super(item);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the Container
|
||||
*
|
||||
* @return Container name
|
||||
*/
|
||||
public T name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames the Container
|
||||
*
|
||||
* @param name New Container Name
|
||||
*/
|
||||
public void rename(T name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof NamedContainer) {
|
||||
if (name == null || ((NamedContainer) object).name() == null) {
|
||||
return name == ((NamedContainer) object).name() && super.equals(object);
|
||||
} else {
|
||||
return name.equals(((NamedContainer) object).name()) && super.equals(object);
|
||||
}
|
||||
} else {
|
||||
return super.equals(object);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* File Replacement Scanner
|
||||
*/
|
||||
public class ReplacementScanner extends FileScanner {
|
||||
private final Map<String, String> replacements = new LinkedHashMap<>();
|
||||
|
||||
public ReplacementScanner(Map<String, String> replacements) {
|
||||
TreeMap<Integer, LinkedList<String>> order = new TreeMap<Integer, LinkedList<String>>(Comparator.reverseOrder());
|
||||
for (String key : replacements.keySet()) {
|
||||
int length = key.length();
|
||||
if (!order.containsKey(length)) order.put(length, new LinkedList<>());
|
||||
order.get(length).add(key);
|
||||
}
|
||||
|
||||
for (Integer length : order.keySet()) {
|
||||
for (String key : order.get(length)) {
|
||||
this.replacements.put(key, replacements.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the replacements
|
||||
*
|
||||
* @return Replacement Map
|
||||
*/
|
||||
public Map<String, String> getReplacements() {
|
||||
return new HashMap<>(replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make replacements in a File or Directory
|
||||
*
|
||||
* @param dir File or Directory
|
||||
* @param whitelist File Whitelist
|
||||
*/
|
||||
public void replace(File dir, String... whitelist) throws IOException {
|
||||
super.scan(dir, whitelist);
|
||||
}
|
||||
|
||||
protected void act(File dir, String name) throws IOException {
|
||||
File file = new File(dir, name);
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
String string = Util.readAll(new InputStreamReader(stream));
|
||||
stream.close();
|
||||
|
||||
boolean update = false;
|
||||
for (Map.Entry<String, String> replacement : replacements.entrySet()) {
|
||||
String placeholder = "SubServers::" + replacement.getKey();
|
||||
if (string.contains(placeholder)) {
|
||||
string = string.replace(placeholder, replacement.getValue());
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (update) {
|
||||
FileWriter writer = new FileWriter(file, false);
|
||||
writer.write(string);
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make replacements in an Object
|
||||
*
|
||||
* @param value Map, Collection, Array, or String
|
||||
* @return Object with replaced variables
|
||||
*/
|
||||
public Object replace(Object value) {
|
||||
if (value instanceof Map) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.addAll(((Map<String, Object>) value).keySet());
|
||||
for (String key : list) ((Map<String, Object>) value).put(key, replace(((Map<String, Object>) value).get(key)));
|
||||
return value;
|
||||
} else if (value instanceof Collection) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Object val : (Collection<Object>) value) list.add(replace(val));
|
||||
return list;
|
||||
} else if (value.getClass().isArray()) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (int i = 0; i < ((Object[]) value).length; i++) list.add(replace(((Object[]) value)[i]));
|
||||
return list;
|
||||
} else if (value instanceof String) {
|
||||
return replaceObj((String) value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
} private String replaceObj(String string) {
|
||||
for (Map.Entry<String, String> replacement : replacements.entrySet()) string = string.replace('$' + replacement.getKey() + '$', replacement.getValue());
|
||||
return string;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Universal File Class
|
||||
*/
|
||||
public class UniversalFile extends File {
|
||||
|
||||
/**
|
||||
* Creates a File Link. Path names are separated by ':'
|
||||
*
|
||||
* @param pathname Path name
|
||||
*/
|
||||
public UniversalFile(String pathname) {
|
||||
super(pathname.replace(".:", System.getProperty("user.dir") + ":").replace(':', File.separatorChar));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a File Link. Path names are separated by the divider
|
||||
*
|
||||
* @param pathname Path name
|
||||
* @param divider Divider to use
|
||||
*/
|
||||
public UniversalFile(String pathname, char divider) {
|
||||
super(pathname.replace("." + divider, System.getProperty("user.dir") + divider).replace(divider, File.separatorChar));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a File Link.
|
||||
*
|
||||
* @see File
|
||||
* @param file File
|
||||
*/
|
||||
public UniversalFile(File file) {
|
||||
super(file.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a File. Path names are separated by the ':'
|
||||
*
|
||||
* @see File
|
||||
* @param parent Parent File
|
||||
* @param child Path name
|
||||
*/
|
||||
public UniversalFile(File parent, String child) {
|
||||
super(parent, child.replace(':', File.separatorChar));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a File. Path names are separated by the divider
|
||||
*
|
||||
* @see File
|
||||
* @param parent Parent File
|
||||
* @param child Path name
|
||||
* @param divider Divider to use
|
||||
*/
|
||||
public UniversalFile(File parent, String child, char divider) {
|
||||
super(parent, child.replace(divider, File.separatorChar));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Universal File Path (separated by ':')
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUniversalPath() {
|
||||
return getPath().replace(File.separatorChar, ':');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,423 @@
|
|||
package net.ME1312.SubServers.Bungee.Library;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* SubServers Utility Class
|
||||
*/
|
||||
public final class Util {
|
||||
private Util(){}
|
||||
public interface ExceptionReturnRunnable<R> {
|
||||
R run() throws Throwable;
|
||||
}
|
||||
public interface ExceptionRunnable {
|
||||
void run() throws Throwable;
|
||||
}
|
||||
public interface ReturnRunnable<R> {
|
||||
R run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks values to make sure they're not null
|
||||
*
|
||||
* @param values Values to check
|
||||
* @return If any are null
|
||||
*/
|
||||
public static boolean isNull(Object... values) {
|
||||
boolean ret = false;
|
||||
for (Object value : values) {
|
||||
if (value == null) ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keys by value from map
|
||||
*
|
||||
* @param map Map to search
|
||||
* @param value Value to search for
|
||||
* @param <K> Key
|
||||
* @param <V> Value
|
||||
* @return Search results
|
||||
*/
|
||||
public static <K, V> List<K> getBackwards(Map<K, V> map, V value) {
|
||||
List<K> values = new ArrayList<K>();
|
||||
|
||||
for (K key : map.keySet()) {
|
||||
if (map.get(key).equals(value)) {
|
||||
values.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item from a map ignoring case
|
||||
*
|
||||
* @param map Map to search
|
||||
* @param key Key to search with
|
||||
* @param <V> Value
|
||||
* @return Search Result
|
||||
*/
|
||||
public static <V> V getCaseInsensitively(Map<String, V> map, String key) {
|
||||
HashMap<String, String> insensitivity = new HashMap<String, String>();
|
||||
for (String item : map.keySet()) if (!insensitivity.keySet().contains(item.toLowerCase())) insensitivity.put(item.toLowerCase(), item);
|
||||
if (insensitivity.keySet().contains(key.toLowerCase())) {
|
||||
return map.get(insensitivity.get(key.toLowerCase()));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new Variable that doesn't match the existing Variables
|
||||
*
|
||||
* @param existing Existing Variables
|
||||
* @param generator Variable Generator
|
||||
* @param <V> Variable Type
|
||||
* @return Variable
|
||||
*/
|
||||
public static <V> V getNew(Collection<? extends V> existing, ReturnRunnable<V> generator) {
|
||||
V result = null;
|
||||
while (result == null) {
|
||||
V tmp = generator.run();
|
||||
if (!existing.contains(tmp)) result = tmp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Everything from Reader
|
||||
*
|
||||
* @param rd Reader
|
||||
* @return Reader Contents
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String readAll(Reader rd) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int cp;
|
||||
while ((cp = rd.read()) != -1) {
|
||||
sb.append((char) cp);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy from the Class Loader
|
||||
*
|
||||
* @param loader ClassLoader
|
||||
* @param resource Location From
|
||||
* @param destination Location To
|
||||
*/
|
||||
public static void copyFromJar(ClassLoader loader, String resource, String destination) {
|
||||
InputStream resStreamIn = loader.getResourceAsStream(resource);
|
||||
File resDestFile = new File(destination);
|
||||
try {
|
||||
OutputStream resStreamOut = new FileOutputStream(resDestFile);
|
||||
int readBytes;
|
||||
byte[] buffer = new byte[4096];
|
||||
while ((readBytes = resStreamIn.read(buffer)) > 0) {
|
||||
resStreamOut.write(buffer, 0, readBytes);
|
||||
}
|
||||
resStreamOut.close();
|
||||
resStreamIn.close();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a variable from a method which may throw an exception
|
||||
*
|
||||
* @param runnable Runnable
|
||||
* @param def Default value when an exception is thrown
|
||||
* @param <R> Variable Type
|
||||
* @return Returns value or default depending on if an exception is thrown
|
||||
*/
|
||||
public static <R> R getDespiteException(ExceptionReturnRunnable<R> runnable, R def) {
|
||||
try {
|
||||
return runnable.run();
|
||||
} catch (Throwable e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if an Exception will occur
|
||||
*
|
||||
* @param runnable Runnable
|
||||
* @return If an Exception occured
|
||||
*/
|
||||
public static boolean isException(ExceptionRunnable runnable) {
|
||||
try {
|
||||
runnable.run();
|
||||
return false;
|
||||
} catch (Throwable e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Directory
|
||||
*
|
||||
* @param folder Location
|
||||
*/
|
||||
public static void deleteDirectory(File folder) {
|
||||
File[] files = folder.listFiles();
|
||||
if(files!=null) {
|
||||
for(File f: files) {
|
||||
if(f.isDirectory()) {
|
||||
deleteDirectory(f);
|
||||
} else {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
folder.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a Directory
|
||||
*
|
||||
* @param from Source
|
||||
* @param to Destination
|
||||
*/
|
||||
public static void copyDirectory(File from, File to) {
|
||||
if (from.isDirectory()) {
|
||||
if (!to.exists()) {
|
||||
to.mkdirs();
|
||||
}
|
||||
|
||||
String files[] = from.list();
|
||||
|
||||
for (String file : files) {
|
||||
File srcFile = new File(from, file);
|
||||
File destFile = new File(to, file);
|
||||
|
||||
copyDirectory(srcFile, destFile);
|
||||
}
|
||||
} else {
|
||||
if (to.exists()) {
|
||||
to.delete();
|
||||
}
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
|
||||
try {
|
||||
in = new FileInputStream(from);
|
||||
out = new FileOutputStream(to, false);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
int length;
|
||||
while ((length = in.read(buffer)) > 0) {
|
||||
out.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
if (in != null) in.close();
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
if (out != null) out.close();
|
||||
} catch (IOException e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> zipsearch(File origin, File file) {
|
||||
List<String> list = new LinkedList<String>();
|
||||
if (file.isFile()) {
|
||||
list.add(file.getAbsoluteFile().toString().substring(origin.getAbsoluteFile().toString().length()+1, file.getAbsoluteFile().toString().length()));
|
||||
}
|
||||
if (file.isDirectory()) for (File next : file.listFiles()) {
|
||||
list.addAll(zipsearch(origin, next));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void zip(File file, OutputStream zip) {
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
try{
|
||||
ZipOutputStream zos = new ZipOutputStream(zip);
|
||||
|
||||
for(String next : zipsearch(file, file)){
|
||||
ZipEntry ze= new ZipEntry(next);
|
||||
zos.putNextEntry(ze);
|
||||
|
||||
FileInputStream in = new FileInputStream(file.getAbsolutePath() + File.separator + next);
|
||||
|
||||
int len;
|
||||
while ((len = in.read(buffer)) > 0) {
|
||||
zos.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
in.close();
|
||||
}
|
||||
|
||||
zos.closeEntry();
|
||||
zos.close();
|
||||
} catch(IOException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void unzip(InputStream zip, File dir) {
|
||||
byte[] buffer = new byte[1024];
|
||||
try{
|
||||
ZipInputStream zis = new ZipInputStream(zip);
|
||||
ZipEntry ze;
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
File newFile = new File(dir + File.separator + ze.getName());
|
||||
if (newFile.exists()) {
|
||||
if (newFile.isDirectory()) {
|
||||
Util.deleteDirectory(newFile);
|
||||
} else {
|
||||
newFile.delete();
|
||||
}
|
||||
}
|
||||
if (ze.isDirectory()) {
|
||||
newFile.mkdirs();
|
||||
continue;
|
||||
} else if (!newFile.getParentFile().exists()) {
|
||||
newFile.getParentFile().mkdirs();
|
||||
}
|
||||
FileOutputStream fos = new FileOutputStream(newFile);
|
||||
int len;
|
||||
while ((len = zis.read(buffer)) > 0) {
|
||||
fos.write(buffer, 0, len);
|
||||
}
|
||||
|
||||
fos.close();
|
||||
}
|
||||
zis.closeEntry();
|
||||
zis.close();
|
||||
} catch(IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Random Integer
|
||||
*
|
||||
* @param min Minimum Value
|
||||
* @param max Maximum Value
|
||||
* @return Random Integer
|
||||
*/
|
||||
public static int random(int min, int max) {
|
||||
return new Random().nextInt((max - min) + 1) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse escapes in a Java String
|
||||
*
|
||||
* @param str String
|
||||
* @return Unescaped String
|
||||
*/
|
||||
public static String unescapeJavaString(String str) {
|
||||
StringBuilder sb = new StringBuilder(str.length());
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
int ch = str.codePointAt(i);
|
||||
if (ch == '\\') {
|
||||
int nextChar = (i == str.length() - 1) ? '\\' : str
|
||||
.codePointAt(i + 1);
|
||||
// Octal escape?
|
||||
if (nextChar >= '0' && nextChar <= '7') {
|
||||
StringBuilder code = new StringBuilder();
|
||||
code.appendCodePoint(nextChar);
|
||||
i++;
|
||||
if ((i < str.length() - 1) && str.codePointAt(i + 1) >= '0'
|
||||
&& str.codePointAt(i + 1) <= '7') {
|
||||
code.appendCodePoint(str.codePointAt(i + 1));
|
||||
i++;
|
||||
if ((i < str.length() - 1) && str.codePointAt(i + 1) >= '0'
|
||||
&& str.codePointAt(i + 1) <= '7') {
|
||||
code.appendCodePoint(str.codePointAt(i + 1));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
sb.append((char) Integer.parseInt(code.toString(), 8));
|
||||
continue;
|
||||
}
|
||||
switch (nextChar) {
|
||||
case '\\':
|
||||
ch = '\\';
|
||||
break;
|
||||
case 'b':
|
||||
ch = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
ch = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
ch = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
ch = '\r';
|
||||
break;
|
||||
case 't':
|
||||
ch = '\t';
|
||||
break;
|
||||
case '\"':
|
||||
ch = '\"';
|
||||
break;
|
||||
case '\'':
|
||||
ch = '\'';
|
||||
break;
|
||||
// Hex Unicode Char: u????
|
||||
// Hex Unicode Codepoint: u{??????}
|
||||
case 'u':
|
||||
try {
|
||||
if (i >= str.length() - 4) throw new IllegalStateException();
|
||||
StringBuilder escape = new StringBuilder();
|
||||
int offset = 2;
|
||||
|
||||
if (str.codePointAt(i + 2) != '{') {
|
||||
if (i >= str.length() - 5) throw new IllegalStateException();
|
||||
while (offset <= 5) {
|
||||
Integer.toString(str.codePointAt(i + offset), 16);
|
||||
escape.appendCodePoint(str.codePointAt(i + offset));
|
||||
offset++;
|
||||
}
|
||||
offset--;
|
||||
} else {
|
||||
offset++;
|
||||
while (str.codePointAt(i + offset) != '}') {
|
||||
Integer.toString(str.codePointAt(i + offset), 16);
|
||||
escape.appendCodePoint(str.codePointAt(i + offset));
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
sb.append(new String(new int[]{
|
||||
Integer.parseInt(escape.toString(), 16)
|
||||
}, 0, 1));
|
||||
|
||||
i += offset;
|
||||
continue;
|
||||
} catch (Throwable e){
|
||||
sb.append('\\');
|
||||
ch = 'u';
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
sb.appendCodePoint(ch);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,411 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Version;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Version Class
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class Version implements Serializable, Comparable<Version> {
|
||||
private final Version parent;
|
||||
private final VersionType type;
|
||||
private final String string;
|
||||
|
||||
/**
|
||||
* Creates a Version
|
||||
*
|
||||
* @param string Version String
|
||||
*/
|
||||
public Version(String string) {
|
||||
this(VersionType.RELEASE, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version
|
||||
*
|
||||
* @param type Version Type
|
||||
* @param string Version String
|
||||
*/
|
||||
public Version(VersionType type, String string) {
|
||||
this(null, type, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version (Appending the parent)
|
||||
*
|
||||
* @param parent Parent Version
|
||||
* @param string Version String
|
||||
*/
|
||||
public Version(Version parent, String string) {
|
||||
this(parent, VersionType.RELEASE, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version (Appending the parent)
|
||||
*
|
||||
* @param parent Parent Version
|
||||
* @param type Version Type
|
||||
* @param string Version String
|
||||
*/
|
||||
public Version(Version parent, VersionType type, String string) {
|
||||
if (Util.isNull(string, type)) throw new NullPointerException();
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version
|
||||
*
|
||||
* @param ints Version Numbers (Will be separated with dots)
|
||||
*/
|
||||
public Version(int... ints) {
|
||||
this(VersionType.RELEASE, ints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version
|
||||
*
|
||||
* @param type Version Type
|
||||
* @param ints Version Numbers (Will be separated with dots)
|
||||
*/
|
||||
public Version(VersionType type, int... ints) {
|
||||
this(null, type, ints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version (Appending the parent)
|
||||
*
|
||||
* @param parent Parent Version
|
||||
* @param ints Version Numbers (Will be separated with dots)
|
||||
*/
|
||||
public Version(Version parent, int... ints) {
|
||||
this(parent, VersionType.RELEASE, ints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Version (Appending the parent)
|
||||
*
|
||||
* @param parent Parent Version
|
||||
* @param type Version Type
|
||||
* @param ints Version Numbers (Will be separated with dots)
|
||||
*/
|
||||
public Version(Version parent, VersionType type, int... ints) {
|
||||
if (Util.isNull(type)) throw new NullPointerException();
|
||||
this.parent = parent;
|
||||
this.type = type;
|
||||
String string = Integer.toString(ints[0]);
|
||||
int i = 0;
|
||||
if (ints.length != 1) {
|
||||
do {
|
||||
i++;
|
||||
string = string + "." + ints[i];
|
||||
} while ((i + 1) != ints.length);
|
||||
}
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a Version from a string
|
||||
*
|
||||
* @param string String to parse
|
||||
* @see #toFullString() <b>#toFullString()</b> returns a valid string
|
||||
* @see #toFullString() <b>#toString()</b> returns a valid string
|
||||
*/
|
||||
public static Version fromString(String string) {
|
||||
Matcher regex = Pattern.compile("(rv|p?[abrv]|[su])?([^/]+)", Pattern.CASE_INSENSITIVE).matcher(string);
|
||||
Version current = null;
|
||||
while (regex.find()) {
|
||||
try {
|
||||
VersionType type = VersionType.VERSION;
|
||||
if (regex.group(1) != null) switch (regex.group(1).toLowerCase()) {
|
||||
case "pa":
|
||||
type = VersionType.PRE_ALPHA;
|
||||
break;
|
||||
case "a":
|
||||
type = VersionType.ALPHA;
|
||||
break;
|
||||
case "pv":
|
||||
type = VersionType.PREVIEW;
|
||||
break;
|
||||
case "pb":
|
||||
type = VersionType.PRE_BETA;
|
||||
break;
|
||||
case "b":
|
||||
type = VersionType.BETA;
|
||||
break;
|
||||
case "s":
|
||||
type = VersionType.SNAPSHOT;
|
||||
break;
|
||||
case "pr":
|
||||
type = VersionType.PRE_RELEASE;
|
||||
break;
|
||||
case "r":
|
||||
type = VersionType.RELEASE;
|
||||
break;
|
||||
case "rv":
|
||||
type = VersionType.REVISION;
|
||||
break;
|
||||
case "u":
|
||||
type = VersionType.UPDATE;
|
||||
break;
|
||||
}
|
||||
current = new Version(current, type, regex.group(2));
|
||||
} catch (Throwable e) {}
|
||||
}
|
||||
if (current == null) throw new IllegalArgumentException("Could not find version in string: " + string);
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default toString() method<br>
|
||||
* <br>
|
||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
||||
* <b style="font-family: consolas">1.0.0/pa7</b>
|
||||
*
|
||||
* @return Version as a String
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return ((parent == null)?"":parent.toString()+'/'+type.shortname) + string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The full toString() method<br>
|
||||
* <br>
|
||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
||||
* <b style="font-family: consolas">r1.0.0/pa7</b>
|
||||
*
|
||||
* @return Version as a String
|
||||
*/
|
||||
public String toFullString() {
|
||||
return ((parent == null)?"":parent.toFullString()+'/') + type.shortname + string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The extended toString() method<br>
|
||||
* <br>
|
||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
||||
* <b style="font-family: consolas">1.0.0 pre-alpha 7</b>
|
||||
*
|
||||
* @return Version as a String
|
||||
*/
|
||||
public String toExtendedString() {
|
||||
return ((parent == null)?"":parent.toExtendedString()+' '+type.longname+' ') + string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The full extended toString() method<br>
|
||||
* <br>
|
||||
* <b style="font-family: consolas">new Version(new Version("1.0.0"), VersionType.PRE_ALPHA, "7")</b> would return:<br>
|
||||
* <b style="font-family: consolas">release 1.0.0 pre-alpha 7</b>
|
||||
*
|
||||
* @return Version as a String
|
||||
*/
|
||||
public String toFullExtendedString() {
|
||||
return ((parent == null)?"":parent.toFullExtendedString()+' ') + type.longname + ' ' + string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object instanceof Version) {
|
||||
return equals((Version) object);
|
||||
} else {
|
||||
return super.equals(object);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See if Versions are Equal
|
||||
*
|
||||
* @param version Version to Compare to
|
||||
* @return
|
||||
*/
|
||||
public boolean equals(Version version) {
|
||||
return compareTo(version) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if Greater than
|
||||
* Returns 0 if Equal
|
||||
* Returns -1 if Less than
|
||||
*//**
|
||||
*
|
||||
* Compare Versions
|
||||
*
|
||||
* @param version Version to Compare to
|
||||
*/
|
||||
public int compareTo(Version version) {
|
||||
return compare(this, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* See if Versions are Equal
|
||||
*
|
||||
* @param ver1 Version to Compare
|
||||
* @param ver2 Version to Compare
|
||||
* @return
|
||||
*/
|
||||
public static boolean equals(Version ver1, Version ver2) {
|
||||
return compare(ver1, ver2) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if Greater than
|
||||
* Returns 0 if Equal
|
||||
* Returns -1 if Less than
|
||||
*//**
|
||||
* Compare Versions
|
||||
*
|
||||
* @param ver1 Version to Compare
|
||||
* @param ver2 Version to Compare
|
||||
*/
|
||||
public static int compare(Version ver1, Version ver2) {
|
||||
if (ver1 == null && ver2 == null) {
|
||||
// Both versions are null
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ver1 == null) {
|
||||
// Version one is null
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ver2 == null) {
|
||||
// Version two is null
|
||||
return 1;
|
||||
}
|
||||
|
||||
LinkedList<Version> stack1 = new LinkedList<Version>();
|
||||
stack1.add(ver1);
|
||||
while (ver1.parent != null) {
|
||||
ver1 = ver1.parent;
|
||||
stack1.add(ver1);
|
||||
}
|
||||
Collections.reverse(stack1);
|
||||
|
||||
LinkedList<Version> stack2 = new LinkedList<Version>();
|
||||
stack2.add(ver2);
|
||||
while (ver2.parent != null) {
|
||||
ver2 = ver2.parent;
|
||||
stack2.add(ver2);
|
||||
}
|
||||
Collections.reverse(stack2);
|
||||
|
||||
int id;
|
||||
for (id = 0; id < stack1.size(); id++) {
|
||||
if (id >= stack2.size()) {
|
||||
// Version one still has children when version two does not...
|
||||
if (stack1.get(id).type.stageid < 0) {
|
||||
// ...making version two the official version
|
||||
return -1;
|
||||
} else {
|
||||
// ...however the direct child of version one has a stageid higher than or equal to a release
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int result = stack1.get(id).compare(stack2.get(id));
|
||||
if (result != 0) {
|
||||
// Versions are not the same, return the result
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (id < stack2.size()) {
|
||||
// Version one does not children when version two still does...
|
||||
if (stack2.get(id).type.stageid < 0) {
|
||||
// ...making version one the official version
|
||||
return 1;
|
||||
} else {
|
||||
// ...however the direct child of version two has a stageid higher than or equal to a release
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares versions ignoring parent/child relationships
|
||||
*/
|
||||
private int compare(Version version) {
|
||||
if (this.type.stageid > version.type.stageid) {
|
||||
// Version one has a type of a later stage than version two
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (this.type.stageid < version.type.stageid) {
|
||||
// Version one has a type of an earlier stage than version two
|
||||
return -1;
|
||||
}
|
||||
|
||||
VersionTokenizer tokenizer1 = new VersionTokenizer(string);
|
||||
VersionTokenizer tokenizer2 = new VersionTokenizer(version.string);
|
||||
|
||||
int number1, number2;
|
||||
String suffix1, suffix2;
|
||||
|
||||
while (tokenizer1.MoveNext()) {
|
||||
if (!tokenizer2.MoveNext()) {
|
||||
do {
|
||||
number1 = tokenizer1.getNumber();
|
||||
suffix1 = tokenizer1.getSuffix();
|
||||
if (number1 != 0 || suffix1.length() != 0) {
|
||||
// Version one is longer than number two, and non-zero
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
while (tokenizer1.MoveNext());
|
||||
|
||||
// Version one is longer than version two, but zero
|
||||
return 0;
|
||||
}
|
||||
|
||||
number1 = tokenizer1.getNumber();
|
||||
suffix1 = tokenizer1.getSuffix();
|
||||
number2 = tokenizer2.getNumber();
|
||||
suffix2 = tokenizer2.getSuffix();
|
||||
|
||||
if (number1 < number2) {
|
||||
// Number one is less than number two
|
||||
return -1;
|
||||
}
|
||||
if (number1 > number2) {
|
||||
// Number one is greater than number two
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean empty1 = suffix1.length() == 0;
|
||||
boolean empty2 = suffix2.length() == 0;
|
||||
|
||||
if (empty1 && empty2) continue; // No suffixes
|
||||
if (empty1) return 1; // First suffix is empty (1.2 > 1.2b)
|
||||
if (empty2) return -1; // Second suffix is empty (1.2a < 1.2)
|
||||
|
||||
// Lexical comparison of suffixes
|
||||
int result = suffix1.compareTo(suffix2);
|
||||
if (result != 0) return result;
|
||||
|
||||
}
|
||||
if (tokenizer2.MoveNext()) {
|
||||
do {
|
||||
number2 = tokenizer2.getNumber();
|
||||
suffix2 = tokenizer2.getSuffix();
|
||||
if (number2 != 0 || suffix2.length() != 0) {
|
||||
// Version one is longer than version two, and non-zero
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while (tokenizer2.MoveNext());
|
||||
|
||||
// Version two is longer than version one, but zero
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Version;
|
||||
|
||||
final class VersionTokenizer {
|
||||
private final String _versionString;
|
||||
private final int _length;
|
||||
|
||||
private int _position;
|
||||
private int _number;
|
||||
private String _suffix;
|
||||
private boolean _hasValue;
|
||||
|
||||
protected int getNumber() {
|
||||
return _number;
|
||||
}
|
||||
|
||||
protected String getSuffix() {
|
||||
return _suffix;
|
||||
}
|
||||
|
||||
protected boolean hasValue() {
|
||||
return _hasValue;
|
||||
}
|
||||
|
||||
protected VersionTokenizer(String versionString) {
|
||||
if (versionString == null)
|
||||
throw new IllegalArgumentException("versionString is null");
|
||||
|
||||
_versionString = versionString;
|
||||
_length = versionString.length();
|
||||
}
|
||||
|
||||
protected boolean MoveNext() {
|
||||
_number = 0;
|
||||
_suffix = "";
|
||||
_hasValue = false;
|
||||
|
||||
// No more characters
|
||||
if (_position >= _length)
|
||||
return false;
|
||||
|
||||
_hasValue = true;
|
||||
|
||||
while (_position < _length) {
|
||||
char c = _versionString.charAt(_position);
|
||||
if (c < '0' || c > '9') break;
|
||||
_number = _number * 10 + (c - '0');
|
||||
_position++;
|
||||
}
|
||||
|
||||
int suffixStart = _position;
|
||||
|
||||
while (_position < _length) {
|
||||
char c = _versionString.charAt(_position);
|
||||
if (c == '.') break;
|
||||
_position++;
|
||||
}
|
||||
|
||||
_suffix = _versionString.substring(suffixStart, _position);
|
||||
|
||||
if (_position < _length) _position++;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package net.ME1312.SubServers.Bungee.Library.Version;
|
||||
|
||||
public enum VersionType {
|
||||
PRE_ALPHA(-6, "pa", "pre-alpha"),
|
||||
ALPHA(-5, "a", "alpha"),
|
||||
PREVIEW(-4, "pv", "preview"),
|
||||
PRE_BETA(-4, "pb", "pre-beta"),
|
||||
BETA(-3, "b", "beta"),
|
||||
SNAPSHOT(-2, "s", "snapshot"),
|
||||
PRE_RELEASE(-1, "pr", "pre-release"),
|
||||
RELEASE(0, "r", "release"),
|
||||
REVISION(0, "rv", "revision"),
|
||||
VERSION(0, "v", "version"),
|
||||
UPDATE(0, "u", "update"),
|
||||
;
|
||||
final short stageid;
|
||||
final String shortname, longname;
|
||||
VersionType(int stageid, String shortname, String longname) {
|
||||
this.stageid = (short) stageid;
|
||||
this.shortname = shortname;
|
||||
this.longname = longname;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.ME1312.SubServers.Bungee.Network;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import org.msgpack.value.Value;
|
||||
|
||||
/**
|
||||
* SubData Cipher Layout Class
|
||||
*/
|
||||
public interface Cipher {
|
||||
/**
|
||||
* Get the name of this Cipher
|
||||
*
|
||||
* @return Cipher Name
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Encrypt JSON Data
|
||||
*
|
||||
* @param key Key to Encrypt Data with
|
||||
* @param data Data to Encrypt
|
||||
* @return Encrypted Data Array
|
||||
*/
|
||||
Value encrypt(String key, YAMLSection data) throws Exception;
|
||||
|
||||
/**
|
||||
* Decrypt Encrypted JSON Data
|
||||
*
|
||||
* @param key Key to Decrypt Data with
|
||||
* @param data Encrypted Data Array
|
||||
* @return JSON Data
|
||||
*/
|
||||
YAMLSection decrypt(String key, Value data) throws Exception;
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package net.ME1312.SubServers.Bungee.Network;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Exception.IllegalPacketException;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Network.Packet.PacketAuthorization;
|
||||
import org.msgpack.core.MessageInsufficientBufferException;
|
||||
import org.msgpack.core.MessagePack;
|
||||
import org.msgpack.core.MessagePacker;
|
||||
import org.msgpack.core.MessageUnpacker;
|
||||
import org.msgpack.value.Value;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Network Client Class
|
||||
*/
|
||||
public class Client {
|
||||
private Socket socket;
|
||||
private InetSocketAddress address;
|
||||
private ClientHandler handler;
|
||||
private MessagePacker out;
|
||||
private Timer authorized;
|
||||
private SubDataServer subdata;
|
||||
boolean closed;
|
||||
|
||||
/**
|
||||
* Network Client
|
||||
*
|
||||
* @param subdata SubData Direct Server
|
||||
* @param client Socket to Bind
|
||||
*/
|
||||
public Client(SubDataServer subdata, Socket client) throws IOException {
|
||||
if (Util.isNull(subdata, client)) throw new NullPointerException();
|
||||
this.subdata = subdata;
|
||||
closed = false;
|
||||
socket = client;
|
||||
out = MessagePack.newDefaultPacker(client.getOutputStream());
|
||||
address = new InetSocketAddress(client.getInetAddress(), client.getPort());
|
||||
authorized = new Timer();
|
||||
authorized.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!socket.isClosed()) try {
|
||||
subdata.removeClient(Client.this);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, 15000);
|
||||
loop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Network Loop
|
||||
*/
|
||||
private void loop() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
MessageUnpacker in = MessagePack.newDefaultUnpacker(socket.getInputStream());
|
||||
Value input;
|
||||
while ((input = in.unpackValue()) != null) {
|
||||
try {
|
||||
YAMLSection data = subdata.getCipher().decrypt(subdata.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"), input);
|
||||
for (PacketIn packet : SubDataServer.decodePacket(this, data)) {
|
||||
boolean auth = authorized == null;
|
||||
if (auth || packet instanceof PacketAuthorization) {
|
||||
try {
|
||||
if (data.contains("f")) {
|
||||
if (data.getString("f").length() <= 0) {
|
||||
List<Client> clients = new ArrayList<Client>();
|
||||
clients.addAll(subdata.getClients());
|
||||
for (Client client : clients) {
|
||||
client.out.packValue(input);
|
||||
}
|
||||
} else {
|
||||
Client client = subdata.getClient(data.getString("f"));
|
||||
if (client != null) {
|
||||
client.out.packValue(input);
|
||||
} else {
|
||||
throw new IllegalPacketException(getAddress().toString() + ": Unknown Forward Address: " + data.getString("f"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
packet.execute(Client.this, (data.contains("c")) ? data.getSection("c") : null);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
new InvocationTargetException(e, getAddress().toString() + ": Exception while executing PacketIn").printStackTrace();
|
||||
}
|
||||
} else {
|
||||
sendPacket(new PacketAuthorization(-1, "Unauthorized"));
|
||||
throw new IllegalPacketException(getAddress().toString() + ": Unauthorized call to packet type: " + data.getSection("h"));
|
||||
}
|
||||
}
|
||||
} catch (YAMLException e) { // TODO
|
||||
new IllegalPacketException(getAddress().toString() + ": Unknown Packet Format: " + input).printStackTrace();
|
||||
} catch (IllegalPacketException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
new InvocationTargetException(e, getAddress().toString() + ": Exception while decoding packet").printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
subdata.removeClient(Client.this);
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (!(e instanceof SocketException || e instanceof MessageInsufficientBufferException)) e.printStackTrace();
|
||||
try {
|
||||
subdata.removeClient(Client.this);
|
||||
} catch (IOException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize Connection
|
||||
*/
|
||||
public void authorize() {
|
||||
if (authorized != null) {
|
||||
authorized.cancel();
|
||||
System.out.println("SubData > " + socket.getRemoteSocketAddress().toString() + " logged in");
|
||||
}
|
||||
authorized = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Packet to Client
|
||||
*
|
||||
* @param packet Packet to send
|
||||
*/
|
||||
public void sendPacket(PacketOut packet) {
|
||||
if (Util.isNull(packet)) throw new NullPointerException();
|
||||
try {
|
||||
out.packValue(subdata.getCipher().encrypt(subdata.plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"), SubDataServer.encodePacket(this, packet)));
|
||||
out.flush();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Raw Connection
|
||||
*
|
||||
* @return Socket
|
||||
*/
|
||||
public Socket getConnection() {
|
||||
return socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the connection has been closed
|
||||
*
|
||||
* @return Closed Stauts
|
||||
*/
|
||||
public boolean isClosed() {
|
||||
return closed && socket.isClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Remote Address
|
||||
*
|
||||
* @return Address
|
||||
*/
|
||||
public InetSocketAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the connection is authorized
|
||||
*
|
||||
* @return Authorization Status
|
||||
*/
|
||||
public boolean isAuthorized() {
|
||||
return authorized == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Linked Handler
|
||||
*
|
||||
* @return Handler
|
||||
*/
|
||||
public ClientHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Handler
|
||||
*
|
||||
* @param obj Handler
|
||||
*/
|
||||
public void setHandler(ClientHandler obj) {
|
||||
if (handler != null && handler.getSubData() != null && equals(handler.getSubData())) handler.setSubData(null);
|
||||
handler = obj;
|
||||
if (handler != null && (handler.getSubData() == null || !equals(handler.getSubData()))) handler.setSubData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the Client
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void disconnect() throws IOException {
|
||||
if (!socket.isClosed()) getConnection().close();
|
||||
if (handler != null) {
|
||||
setHandler(null);
|
||||
handler = null;
|
||||
}
|
||||
closed = true;
|
||||
if (subdata.getClients().contains(this)) subdata.removeClient(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package net.ME1312.SubServers.Bungee.Network;
|
||||
|
||||
/**
|
||||
* Client Handler Layout Class
|
||||
*/
|
||||
public interface ClientHandler {
|
||||
/**
|
||||
* Gets the SubData Client
|
||||
*
|
||||
* @return SubData Client (or null if not linked)
|
||||
*/
|
||||
Client getSubData();
|
||||
|
||||
/**
|
||||
* Link a SubData Client to this Object
|
||||
*
|
||||
* @see Client#setHandler(ClientHandler)
|
||||
* @param client Client to Link
|
||||
*/
|
||||
void setSubData(Client client);
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Encryption;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import org.msgpack.core.MessageBufferPacker;
|
||||
import org.msgpack.core.MessagePack;
|
||||
import org.msgpack.core.MessagePacker;
|
||||
import org.msgpack.value.Value;
|
||||
import org.msgpack.value.ValueFactory;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* A class to perform password-based AES encryption and decryption in CBC mode.
|
||||
* 128, 192, and 256-bit encryption are supported, provided that the latter two
|
||||
* are permitted by the Java runtime's jurisdiction policy files.
|
||||
* <br/>
|
||||
* The public interface for this class consists of the static methods
|
||||
* {@link #encrypt} and {@link #decrypt}, which encrypt and decrypt arbitrary
|
||||
* streams of data, respectively.
|
||||
*
|
||||
* @author dweymouth@gmail.com
|
||||
*/
|
||||
public final class AES implements net.ME1312.SubServers.Bungee.Network.Cipher {
|
||||
|
||||
// AES specification
|
||||
private static final String CIPHER_SPEC = "AES/CBC/PKCS5Padding";
|
||||
|
||||
// Key derivation specification
|
||||
private static final String KEYGEN_SPEC = "PBKDF2WithHmacSHA1";
|
||||
private static final int SALT_LENGTH = 16; // in bytes
|
||||
private static final int AUTH_KEY_LENGTH = 8; // in bytes
|
||||
private static final int ITERATIONS = 32768;
|
||||
|
||||
// Process input/output streams in chunks
|
||||
private static final int BUFFER_SIZE = 1024;
|
||||
|
||||
// Hold Data for use by SubData Cipher methods
|
||||
private final int keyLength;
|
||||
|
||||
/**
|
||||
* Constructor for use as a SubData Cipher
|
||||
*/
|
||||
public AES(int keyLength) {
|
||||
this.keyLength = keyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new pseudorandom salt of the specified length
|
||||
*/
|
||||
private static byte[] generateSalt(int length) {
|
||||
Random r = new SecureRandom();
|
||||
byte[] salt = new byte[length];
|
||||
r.nextBytes(salt);
|
||||
return salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive an AES encryption key and authentication key from given password and salt,
|
||||
* using PBKDF2 key stretching. The authentication key is 64 bits long.
|
||||
* @param keyLength
|
||||
* length of the AES key in bits (128, 192, or 256)
|
||||
* @param password
|
||||
* the password from which to derive the keys
|
||||
* @param salt
|
||||
* the salt from which to derive the keys
|
||||
* @return a Keys object containing the two generated keys
|
||||
*/
|
||||
private static Keys keygen(int keyLength, char[] password, byte[] salt) {
|
||||
SecretKeyFactory factory;
|
||||
try {
|
||||
factory = SecretKeyFactory.getInstance(KEYGEN_SPEC);
|
||||
} catch (NoSuchAlgorithmException impossible) { return null; }
|
||||
// derive a longer key, then split into AES key and authentication key
|
||||
KeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, keyLength + AUTH_KEY_LENGTH * 8);
|
||||
SecretKey tmp = null;
|
||||
try {
|
||||
tmp = factory.generateSecret(spec);
|
||||
} catch (InvalidKeySpecException impossible) { }
|
||||
byte[] fullKey = tmp.getEncoded();
|
||||
SecretKey authKey = new SecretKeySpec( // key for password authentication
|
||||
Arrays.copyOfRange(fullKey, 0, AUTH_KEY_LENGTH), "AES");
|
||||
SecretKey encKey = new SecretKeySpec( // key for AES encryption
|
||||
Arrays.copyOfRange(fullKey, AUTH_KEY_LENGTH, fullKey.length), "AES");
|
||||
return new Keys(encKey, authKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a stream of data. The encrypted stream consists of a header
|
||||
* followed by the raw AES data. The header is broken down as follows:<br/>
|
||||
* <ul>
|
||||
* <li><b>keyLength</b>: AES key length in bytes (valid for 16, 24, 32) (1 byte)</li>
|
||||
* <li><b>salt</b>: pseudorandom salt used to derive keys from password (16 bytes)</li>
|
||||
* <li><b>authentication key</b> (derived from password and salt, used to
|
||||
* check validity of password upon decryption) (8 bytes)</li>
|
||||
* <li><b>IV</b>: pseudorandom AES initialization vector (16 bytes)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param keyLength
|
||||
* key length to use for AES encryption (must be 128, 192, or 256)
|
||||
* @param password
|
||||
* password to use for encryption
|
||||
* @param input
|
||||
* an arbitrary byte stream to encrypt
|
||||
* @param output
|
||||
* stream to which encrypted data will be written
|
||||
* @throws AES.InvalidKeyLengthException
|
||||
* if keyLength is not 128, 192, or 256
|
||||
* @throws AES.StrongEncryptionNotAvailableException
|
||||
* if keyLength is 192 or 256, but the Java runtime's jurisdiction
|
||||
* policy files do not allow 192- or 256-bit encryption
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void encrypt(int keyLength, String password, InputStream input, OutputStream output)
|
||||
throws InvalidKeyLengthException, StrongEncryptionNotAvailableException, IOException {
|
||||
// Check validity of key length
|
||||
if (keyLength != 128 && keyLength != 192 && keyLength != 256) {
|
||||
throw new InvalidKeyLengthException(keyLength);
|
||||
}
|
||||
|
||||
// generate salt and derive keys for authentication and encryption
|
||||
byte[] salt = generateSalt(SALT_LENGTH);
|
||||
Keys keys = keygen(keyLength, password.toCharArray(), salt);
|
||||
|
||||
// initialize AES encryption
|
||||
Cipher encrypt = null;
|
||||
try {
|
||||
encrypt = Cipher.getInstance(CIPHER_SPEC);
|
||||
encrypt.init(Cipher.ENCRYPT_MODE, keys.encryption);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException impossible) { }
|
||||
catch (InvalidKeyException e) { // 192 or 256-bit AES not available
|
||||
throw new StrongEncryptionNotAvailableException(keyLength);
|
||||
}
|
||||
|
||||
// get initialization vector
|
||||
byte[] iv = null;
|
||||
try {
|
||||
iv = encrypt.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
|
||||
} catch (InvalidParameterSpecException impossible) { }
|
||||
|
||||
// write authentication and AES initialization data
|
||||
output.write(keyLength / 8);
|
||||
output.write(salt);
|
||||
output.write(keys.authentication.getEncoded());
|
||||
output.write(iv);
|
||||
|
||||
// read data from input into buffer, encrypt and write to output
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int numRead;
|
||||
byte[] encrypted = null;
|
||||
while ((numRead = input.read(buffer)) > 0) {
|
||||
encrypted = encrypt.update(buffer, 0, numRead);
|
||||
if (encrypted != null) {
|
||||
output.write(encrypted);
|
||||
}
|
||||
}
|
||||
try { // finish encryption - do final block
|
||||
encrypted = encrypt.doFinal();
|
||||
} catch (IllegalBlockSizeException | BadPaddingException impossible) { }
|
||||
if (encrypted != null) {
|
||||
output.write(encrypted);
|
||||
}
|
||||
output.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calls to {@link #encrypt(int, String, InputStream, OutputStream)}, simplified for the {@link net.ME1312.SubServers.Bungee.Network.Cipher} interface.
|
||||
*
|
||||
* @param key Key to Encrypt Data with
|
||||
* @param data Data to Encrypt
|
||||
* @return Encrypted Data Array
|
||||
*/
|
||||
public Value encrypt(String key, YAMLSection data) throws Exception {
|
||||
ByteArrayOutputStream unencrypted = new ByteArrayOutputStream();
|
||||
MessagePacker packer = MessagePack.newDefaultPacker(unencrypted);
|
||||
packer.packValue(data.msgPack());
|
||||
packer.close();
|
||||
|
||||
ByteArrayOutputStream encrypted = new ByteArrayOutputStream();
|
||||
encrypt(keyLength, key, new ByteArrayInputStream(unencrypted.toByteArray()), encrypted);
|
||||
return ValueFactory.newBinary(encrypted.toByteArray(), true);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "AES_" + keyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a stream of data that was encrypted by {@link #encrypt}.
|
||||
* @param password
|
||||
* the password used to encrypt/decrypt the stream
|
||||
* @param input
|
||||
* stream of encrypted data to be decrypted
|
||||
* @param output
|
||||
* stream to which decrypted data will be written
|
||||
* @return the key length for the decrypted stream (128, 192, or 256)
|
||||
* @throws AES.InvalidPasswordException
|
||||
* if the given password was not used to encrypt the data
|
||||
* @throws AES.InvalidAESStreamException
|
||||
* if the given input stream is not a valid AES-encrypted stream
|
||||
* @throws AES.StrongEncryptionNotAvailableException
|
||||
* if the stream is 192 or 256-bit encrypted, and the Java runtime's
|
||||
* jurisdiction policy files do not allow for AES-192 or 256
|
||||
* @throws IOException
|
||||
*/
|
||||
public static int decrypt(String password, InputStream input, OutputStream output)
|
||||
throws InvalidPasswordException, InvalidAESStreamException, IOException,
|
||||
StrongEncryptionNotAvailableException {
|
||||
int keyLength = input.read() * 8;
|
||||
// Check validity of key length
|
||||
if (keyLength != 128 && keyLength != 192 && keyLength != 256) {
|
||||
throw new InvalidAESStreamException();
|
||||
}
|
||||
|
||||
// read salt, generate keys, and authenticate password
|
||||
byte[] salt = new byte[SALT_LENGTH];
|
||||
input.read(salt);
|
||||
Keys keys = keygen(keyLength, password.toCharArray(), salt);
|
||||
byte[] authRead = new byte[AUTH_KEY_LENGTH];
|
||||
input.read(authRead);
|
||||
if (!Arrays.equals(keys.authentication.getEncoded(), authRead)) {
|
||||
throw new InvalidPasswordException();
|
||||
}
|
||||
|
||||
// initialize AES decryption
|
||||
byte[] iv = new byte[16]; // 16-byte I.V. regardless of key size
|
||||
input.read(iv);
|
||||
Cipher decrypt = null;
|
||||
try {
|
||||
decrypt = Cipher.getInstance(CIPHER_SPEC);
|
||||
decrypt.init(Cipher.DECRYPT_MODE, keys.encryption, new IvParameterSpec(iv));
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException
|
||||
| InvalidAlgorithmParameterException impossible) { }
|
||||
catch (InvalidKeyException e) { // 192 or 256-bit AES not available
|
||||
throw new StrongEncryptionNotAvailableException(keyLength);
|
||||
}
|
||||
|
||||
// read data from input into buffer, decrypt and write to output
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int numRead;
|
||||
byte[] decrypted;
|
||||
while ((numRead = input.read(buffer)) > 0) {
|
||||
decrypted = decrypt.update(buffer, 0, numRead);
|
||||
if (decrypted != null) {
|
||||
output.write(decrypted);
|
||||
}
|
||||
}
|
||||
try { // finish decryption - do final block
|
||||
decrypted = decrypt.doFinal();
|
||||
} catch (IllegalBlockSizeException | BadPaddingException e) {
|
||||
throw new InvalidAESStreamException(e);
|
||||
}
|
||||
if (decrypted != null) {
|
||||
output.write(decrypted);
|
||||
}
|
||||
|
||||
output.flush();
|
||||
return keyLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calls to {@link #decrypt(String, InputStream, OutputStream)}), simplified for the {@link net.ME1312.SubServers.Bungee.Network.Cipher} interface.
|
||||
*
|
||||
* @param key Key to Decrypt Data with
|
||||
* @param data Encrypted Data Array
|
||||
* @return JSON Data
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public YAMLSection decrypt(String key, Value data) throws Exception {
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
decrypt(key, new ByteArrayInputStream(data.asBinaryValue().asByteArray()), bytes);
|
||||
return new YAMLSection(MessagePack.newDefaultUnpacker(bytes.toByteArray()).unpackValue().asMapValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* A tuple of encryption and authentication keys returned by {@link #keygen}
|
||||
*/
|
||||
private static class Keys {
|
||||
public final SecretKey encryption, authentication;
|
||||
public Keys(SecretKey encryption, SecretKey authentication) {
|
||||
this.encryption = encryption;
|
||||
this.authentication = authentication;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if an attempt is made to decrypt a stream with an incorrect password.
|
||||
*/
|
||||
public static class InvalidPasswordException extends Exception { }
|
||||
|
||||
/**
|
||||
* Thrown if an attempt is made to encrypt a stream with an invalid AES key length.
|
||||
*/
|
||||
public static class InvalidKeyLengthException extends Exception {
|
||||
InvalidKeyLengthException(int length) {
|
||||
super("Invalid AES key length: " + length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if 192- or 256-bit AES encryption or decryption is attempted,
|
||||
* but not available on the particular Java platform.
|
||||
*/
|
||||
public static class StrongEncryptionNotAvailableException extends Exception {
|
||||
public StrongEncryptionNotAvailableException(int keySize) {
|
||||
super(keySize + "-bit AES encryption is not available on this Java platform.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown if an attempt is made to decrypt an invalid AES stream.
|
||||
*/
|
||||
public static class InvalidAESStreamException extends Exception {
|
||||
public InvalidAESStreamException() { super(); };
|
||||
public InvalidAESStreamException(Exception e) { super(e); }
|
||||
}
|
||||
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Add Server Packet
|
||||
*/
|
||||
public class PacketAddServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
private int response;
|
||||
private int status;
|
||||
private UUID tracker;
|
||||
|
||||
/**
|
||||
* New PacketAddServer (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketAddServer(SubProxy plugin) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketEditServer (Out)
|
||||
*
|
||||
* @param response Response ID
|
||||
* @param tracker Receiver ID
|
||||
*/
|
||||
public PacketAddServer(int response, UUID tracker) {
|
||||
this.response = response;
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> json = new ObjectMap<Integer>();
|
||||
if (tracker != null) json.set(0x0000, tracker);
|
||||
json.set(0x0001, response);
|
||||
json.set(0x0002, status);
|
||||
return json;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||
try {
|
||||
String name = data.getString(0x0001);
|
||||
boolean subserver = data.getBoolean(0x0002);
|
||||
ObjectMap<String> opt = new ObjectMap<>((Map<String, ?>)data.getObject(0x0003));
|
||||
UUID player = (data.contains(0x0004)?data.getUUID(0x0004):null);
|
||||
|
||||
if (plugin.api.getServers().containsKey(name.toLowerCase())) {
|
||||
client.sendPacket(new PacketAddServer(3, tracker));
|
||||
} else {
|
||||
if (!subserver) {
|
||||
if (plugin.api.addServer(player, name, InetAddress.getByName(opt.getString("address").split(":")[0]), Integer.parseInt(opt.getString("address").split(":")[1]),
|
||||
ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(opt.getString("motd"))), opt.getBoolean("hidden"), opt.getBoolean("restricted")) != null) {
|
||||
client.sendPacket(new PacketAddServer(0, tracker));
|
||||
} else {
|
||||
client.sendPacket(new PacketAddServer(1, tracker));
|
||||
}
|
||||
} else if (!plugin.api.getHosts().containsKey(opt.getString("host").toLowerCase())) {
|
||||
client.sendPacket(new PacketAddServer(4, tracker));
|
||||
} else {
|
||||
if (plugin.api.getHost(opt.getString("host")).addSubServer(player, name, opt.getBoolean("enabled"), opt.getInt("port"), ChatColor.translateAlternateColorCodes('&', Util.unescapeJavaString(opt.getString("motd"))),
|
||||
opt.getBoolean("log"), opt.getString("dir"), opt.getString("exec"), opt.getString("stop-cmd"), opt.getBoolean("hidden"), opt.getBoolean("restricted")) != null) {
|
||||
client.sendPacket(new PacketAddServer(0, tracker));
|
||||
} else {
|
||||
client.sendPacket(new PacketAddServer(1, tracker));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
client.sendPacket(new PacketAddServer(2, tracker));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
/**
|
||||
* Authorization Packet
|
||||
*/
|
||||
public final class PacketAuthorization implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private int response;
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* New PacketAuthorization (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketAuthorization(SubPlugin plugin) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketAuthorization (Out)
|
||||
*
|
||||
* @param response Response ID
|
||||
* @param message Message
|
||||
*/
|
||||
public PacketAuthorization(int response, String message) {
|
||||
if (Util.isNull(response, message)) throw new NullPointerException();
|
||||
this.response = response;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
data.set("r", response);
|
||||
data.set("m", message);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
try {
|
||||
if (data.getRawString("password").equals(plugin.config.get().getSection("Settings").getSection("SubData").getRawString("Password"))) {
|
||||
client.authorize();
|
||||
client.sendPacket(new PacketAuthorization(0, "Successfully Logged in"));
|
||||
} else {
|
||||
client.sendPacket(new PacketAuthorization(2, "Invalid Password"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
client.sendPacket(new PacketAuthorization(1, e.getClass().getCanonicalName() + ": " + e.getMessage()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.11.0a");
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Check Permission Packet
|
||||
*/
|
||||
public class PacketCheckPermission implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
static HashMap<UUID, Consumer<Boolean>[]> callbacks = new HashMap<UUID, Consumer<Boolean>[]>();
|
||||
private UUID player;
|
||||
private String permission;
|
||||
private UUID tracker;
|
||||
|
||||
/**
|
||||
* New PacketCheckPermission (In)
|
||||
*/
|
||||
public PacketCheckPermission() {}
|
||||
|
||||
/**
|
||||
* New PacketCheckPermission (Out)
|
||||
*
|
||||
* @param player Player to check on
|
||||
* @param permission Permission to check
|
||||
* @param callback Callbacks
|
||||
*/
|
||||
@SafeVarargs
|
||||
public PacketCheckPermission(UUID player, String permission, Consumer<Boolean>... callback) {
|
||||
this.player = player;
|
||||
this.permission = permission;
|
||||
this.tracker = Util.getNew(callbacks.keySet(), UUID::randomUUID);
|
||||
callbacks.put(tracker, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) throws Throwable {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
data.set(0x0000, tracker);
|
||||
data.set(0x0001, player);
|
||||
data.set(0x0002, permission);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) throws Throwable {
|
||||
client.sendPacket(new PacketCheckPermissionResponse(data.getUUID(0x0001), data.getString(0x0002), (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Try;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static net.ME1312.SubServers.Bungee.Network.Packet.PacketCheckPermission.callbacks;
|
||||
|
||||
|
||||
/**
|
||||
* Check Permission Response Packet
|
||||
*/
|
||||
public class PacketCheckPermissionResponse implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private boolean result;
|
||||
private UUID tracker;
|
||||
|
||||
/**
|
||||
* New PacketCheckPermissionResponse (In)
|
||||
*/
|
||||
public PacketCheckPermissionResponse() {}
|
||||
|
||||
/**
|
||||
* New PacketCheckPermissionResponse (Out)
|
||||
*
|
||||
* @param player Player to check on
|
||||
* @param permission Permission to check
|
||||
* @param tracker Receiver ID
|
||||
*/
|
||||
public PacketCheckPermissionResponse(UUID player, String permission, UUID tracker) {
|
||||
this.result = Try.all.get(() -> ProxyServer.getInstance().getPlayer(player).hasPermission(permission), false);
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) throws Throwable {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
data.set(0x0000, tracker);
|
||||
data.set(0x0001, result);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) throws Throwable {
|
||||
for (Consumer<Boolean> callback : callbacks.remove(data.getUUID(0x0000))) callback.accept(data.getBoolean(0x0001));
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
@ -15,81 +16,86 @@ import java.util.UUID;
|
|||
/**
|
||||
* Server Command Packet
|
||||
*/
|
||||
public class PacketCommandServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
public class PacketCommandServer implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private int response;
|
||||
private UUID tracker;
|
||||
private String message;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketCommandServer (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketCommandServer(SubProxy plugin) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
public PacketCommandServer(SubPlugin plugin) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketCommandServer (Out)
|
||||
*
|
||||
* @param response Response ID
|
||||
* @param tracker Tracker ID
|
||||
* @param message Message
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketCommandServer(int response, UUID tracker) {
|
||||
public PacketCommandServer(int response, String message, String id) {
|
||||
if (Util.isNull(response, message)) throw new NullPointerException();
|
||||
this.response = response;
|
||||
this.tracker = tracker;
|
||||
this.message = message;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
if (tracker != null) data.set(0x0000, tracker);
|
||||
data.set(0x0001, response);
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
if (id != null) data.set("id", id);
|
||||
data.set("r", response);
|
||||
data.set("m", message);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
try {
|
||||
String server = data.getString(0x0001);
|
||||
String command = data.getString(0x0002);
|
||||
UUID player = (data.contains(0x0003)?data.getUUID(0x0003):null);
|
||||
UUID target = (data.contains(0x0004)?data.getUUID(0x0004):null);
|
||||
|
||||
Map<String, Server> servers = plugin.api.getServers();
|
||||
if (!server.equals("*") && !servers.containsKey(server.toLowerCase())) {
|
||||
client.sendPacket(new PacketCommandServer(3, tracker));
|
||||
} else if (!server.equals("*") && !(target == null && servers.get(server.toLowerCase()) instanceof SubServer) && servers.get(server.toLowerCase()).getSubData()[0] == null) {
|
||||
client.sendPacket(new PacketCommandServer(4, tracker));
|
||||
} else if (!server.equals("*") && servers.get(server.toLowerCase()) instanceof SubServer && !((SubServer) servers.get(server.toLowerCase())).isRunning()) {
|
||||
client.sendPacket(new PacketCommandServer(5, tracker));
|
||||
if (!data.getRawString("server").equals("*") && !servers.keySet().contains(data.getRawString("server").toLowerCase())) {
|
||||
client.sendPacket(new PacketCommandServer(3, "There is no server with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (!data.getRawString("server").equals("*") && !(servers.get(data.getRawString("server").toLowerCase()) instanceof SubServer)) {
|
||||
client.sendPacket(new PacketCommandServer(4, "That Server is not a SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (!data.getRawString("server").equals("*") && !((SubServer) servers.get(data.getRawString("server").toLowerCase())).isRunning()) {
|
||||
client.sendPacket(new PacketCommandServer(5, "That SubServer is not running", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else {
|
||||
if (server.equals("*")) {
|
||||
if (data.getRawString("server").equals("*")) {
|
||||
boolean sent = false;
|
||||
for (Server next : servers.values()) {
|
||||
if (target == null) {
|
||||
sent |= next.command(player, command);
|
||||
} else {
|
||||
sent |= next.command(player, target, command);
|
||||
for (Server server : servers.values()) {
|
||||
if (server instanceof SubServer && ((SubServer) server).isRunning()) {
|
||||
if (((SubServer) server).command((data.contains("player"))?UUID.fromString(data.getRawString("player")):null, data.getRawString("command"))) {
|
||||
sent = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sent) {
|
||||
client.sendPacket(new PacketCommandServer(0, tracker));
|
||||
client.sendPacket(new PacketCommandServer(0, "Sending Command", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else {
|
||||
client.sendPacket(new PacketCommandServer(1, tracker));
|
||||
client.sendPacket(new PacketCommandServer(1, "Couldn't send command", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
}
|
||||
} else {
|
||||
if (target == null) {
|
||||
client.sendPacket(new PacketCommandServer((servers.get(server.toLowerCase()).command(player, command))? 0 : 1, tracker));
|
||||
if (((SubServer) servers.get(data.getRawString("server").toLowerCase())).command((data.contains("player")) ? UUID.fromString(data.getRawString("player")) : null, data.getRawString("command"))) {
|
||||
client.sendPacket(new PacketCommandServer(0, "Sending Command", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else {
|
||||
client.sendPacket(new PacketCommandServer((servers.get(server.toLowerCase()).command(player, target, command))? 0 : 1, tracker));
|
||||
client.sendPacket(new PacketCommandServer(1, "Couldn't send command", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
client.sendPacket(new PacketCommandServer(2, tracker));
|
||||
client.sendPacket(new PacketCommandServer(2, e.getClass().getCanonicalName() + ": " + e.getMessage(), (data.contains("id")) ? data.getRawString("id") : null));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.11.0a");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubCreator;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Create Server Packet
|
||||
*/
|
||||
public class PacketCreateServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
public class PacketCreateServer implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private int response;
|
||||
private UUID tracker;
|
||||
private String message;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketCreateServer (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketCreateServer(SubProxy plugin) {
|
||||
public PacketCreateServer(SubPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
@ -31,64 +33,72 @@ public class PacketCreateServer implements PacketObjectIn<Integer>, PacketObject
|
|||
* New PacketCreateServer (Out)
|
||||
*
|
||||
* @param response Response ID
|
||||
* @param message Message
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketCreateServer(int response, UUID id) {
|
||||
public PacketCreateServer(int response, String message, String id) {
|
||||
this.response = response;
|
||||
this.tracker = id;
|
||||
this.message = message;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
if (tracker != null) data.set(0x0000, tracker);
|
||||
data.set(0x0001, response);
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
if (id != null) data.set("id", id);
|
||||
data.set("r", response);
|
||||
data.set("m", message);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
try {
|
||||
String name = data.getString(0x0001);
|
||||
String host = data.getString(0x0002);
|
||||
String template = data.getString(0x0003);
|
||||
Version version = (data.contains(0x0004)?data.getVersion(0x0004):null);
|
||||
Integer port = (data.contains(0x0005)?data.getInt(0x0005):null);
|
||||
UUID player = (data.contains(0x0006)?data.getUUID(0x0006):null);
|
||||
boolean waitfor = (data.contains(0x0007)?data.getBoolean(0x0007):false);
|
||||
|
||||
if (name.contains(" ")) {
|
||||
client.sendPacket(new PacketCreateServer(3, tracker));
|
||||
} else if (plugin.api.getSubServers().containsKey(name.toLowerCase()) || SubCreator.isReserved(name)) {
|
||||
client.sendPacket(new PacketCreateServer(4, tracker));
|
||||
} else if (!plugin.hosts.containsKey(host.toLowerCase())) {
|
||||
client.sendPacket(new PacketCreateServer(5, tracker));
|
||||
} else if (!plugin.hosts.get(host.toLowerCase()).isAvailable()) {
|
||||
client.sendPacket(new PacketCreateServer(6, tracker));
|
||||
} else if (!plugin.hosts.get(host.toLowerCase()).isEnabled()) {
|
||||
client.sendPacket(new PacketCreateServer(7, tracker));
|
||||
} else if (!plugin.hosts.get(host.toLowerCase()).getCreator().getTemplates().containsKey(template.toLowerCase())) {
|
||||
client.sendPacket(new PacketCreateServer(8, tracker));
|
||||
} else if (!plugin.hosts.get(host.toLowerCase()).getCreator().getTemplate(template).isEnabled()) {
|
||||
client.sendPacket(new PacketCreateServer(9, tracker));
|
||||
} else if (version == null && plugin.hosts.get(host.toLowerCase()).getCreator().getTemplate(template).requiresVersion()) {
|
||||
client.sendPacket(new PacketCreateServer(10, tracker));
|
||||
} else if (port != null && (port <= 0 || port > 65535)) {
|
||||
client.sendPacket(new PacketCreateServer(11, tracker));
|
||||
if (data.getSection("creator").getString("name").contains(" ")) {
|
||||
client.sendPacket(new PacketCreateServer(3, "Server names cannot have spaces", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (plugin.api.getSubServers().keySet().contains(data.getSection("creator").getString("name").toLowerCase()) || SubCreator.isReserved(data.getSection("creator").getString("name"))) {
|
||||
client.sendPacket(new PacketCreateServer(4, "There is already a subserver with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (!plugin.hosts.keySet().contains(data.getSection("creator").getString("host").toLowerCase())) {
|
||||
client.sendPacket(new PacketCreateServer(5, "There is no Host with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).isAvailable()) {
|
||||
client.sendPacket(new PacketStartServer(6, "That SubServer's Host is not available", (data.contains("id"))?data.getRawString("id"):null));
|
||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).isEnabled()) {
|
||||
client.sendPacket(new PacketStartServer(7, "That SubServer's Host is not enabled", (data.contains("id"))?data.getRawString("id"):null));
|
||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().getTemplates().keySet().contains(data.getSection("creator").getString("template").toLowerCase())) {
|
||||
client.sendPacket(new PacketCreateServer(8, "There is no template with that name", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (!plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().getTemplate(data.getSection("creator").getString("template")).isEnabled()) {
|
||||
client.sendPacket(new PacketCreateServer(8, "That Template is not enabled", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (new Version("1.8").compareTo(new Version(data.getSection("creator").getString("version"))) > 0) {
|
||||
client.sendPacket(new PacketCreateServer(10, "SubCreator cannot create servers before Minecraft 1.8", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else if (data.getSection("creator").contains("port") && (data.getSection("creator").getInt("port") <= 0 || data.getSection("creator").getInt("port") > 65535)) {
|
||||
client.sendPacket(new PacketCreateServer(11, "Invalid Port Number", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} else {
|
||||
if (plugin.hosts.get(host.toLowerCase()).getCreator().create(player, name, plugin.hosts.get(host.toLowerCase()).getCreator().getTemplate(template), version, port, server -> {
|
||||
if (waitfor) client.sendPacket(new PacketCreateServer((server == null)?12:0, tracker));
|
||||
})) {
|
||||
if (!waitfor) client.sendPacket(new PacketCreateServer(0, tracker));
|
||||
if (plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().create((data.contains("player"))?UUID.fromString(data.getRawString("player")):null, data.getSection("creator").getString("name"), plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().getTemplate(data.getSection("creator").getString("template")), new Version(data.getSection("creator").getString("version")), (data.getSection("creator").contains("port"))?data.getSection("creator").getInt("port"):null)) {
|
||||
if (data.contains("wait") && data.getBoolean("wait")) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
plugin.hosts.get(data.getSection("creator").getString("host").toLowerCase()).getCreator().waitFor();
|
||||
client.sendPacket(new PacketCreateServer(0, "Created SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
client.sendPacket(new PacketCreateServer(0, "Creating SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
}
|
||||
} else {
|
||||
client.sendPacket(new PacketCreateServer(1, tracker));
|
||||
client.sendPacket(new PacketCreateServer(1, "Couldn't create SubServer", (data.contains("id")) ? data.getRawString("id") : null));
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
client.sendPacket(new PacketCreateServer(2, tracker));
|
||||
client.sendPacket(new PacketCreateServer(2, e.getClass().getCanonicalName() + ": " + e.getMessage(), (data.contains("id")) ? data.getRawString("id") : null));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.13b");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.Host.SubServer;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Delete Server Packet
|
||||
*/
|
||||
public class PacketDeleteServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
private int response;
|
||||
private UUID tracker;
|
||||
|
||||
/**
|
||||
* New PacketDeleteServer (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketDeleteServer(SubProxy plugin) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketDeleteServer (Out)
|
||||
*
|
||||
* @param response Response ID
|
||||
* @param tracker Receiver ID
|
||||
*/
|
||||
public PacketDeleteServer(int response, UUID tracker) {
|
||||
this.response = response;
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> json = new ObjectMap<Integer>();
|
||||
if (tracker != null) json.set(0x0000, tracker);
|
||||
json.set(0x0001, response);
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||
try {
|
||||
String name = data.getString(0x0001);
|
||||
boolean recycle = data.getBoolean(0x0002);
|
||||
boolean force = data.getBoolean(0x0003);
|
||||
UUID player = (data.contains(0x0004)?data.getUUID(0x0004):null);
|
||||
|
||||
Map<String, Server> servers = plugin.api.getServers();
|
||||
if (!servers.containsKey(name.toLowerCase())) {
|
||||
client.sendPacket(new PacketDeleteServer(3, tracker));
|
||||
} else if (!(servers.get(name.toLowerCase()) instanceof SubServer)) {
|
||||
client.sendPacket(new PacketDeleteServer(4, tracker));
|
||||
} else {
|
||||
if (recycle) {
|
||||
if (force) {
|
||||
if (((SubServer) servers.get(name.toLowerCase())).getHost().forceRecycleSubServer(player, name.toLowerCase())) {
|
||||
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||
} else {
|
||||
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||
}
|
||||
} else {
|
||||
if (((SubServer) servers.get(name.toLowerCase())).getHost().recycleSubServer(player, name.toLowerCase())) {
|
||||
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||
} else {
|
||||
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (force) {
|
||||
if (((SubServer) servers.get(name.toLowerCase())).getHost().forceDeleteSubServer(player, name.toLowerCase())) {
|
||||
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||
} else {
|
||||
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||
}
|
||||
} else {
|
||||
if (((SubServer) servers.get(name.toLowerCase())).getHost().deleteSubServer(player, name.toLowerCase())) {
|
||||
client.sendPacket(new PacketDeleteServer(0, tracker));
|
||||
} else {
|
||||
client.sendPacket(new PacketDeleteServer(1, tracker));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
client.sendPacket(new PacketDeleteServer(2, tracker));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Container.Container;
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Merger;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||
import net.ME1312.SubServers.Bungee.Host.RemotePlayer;
|
||||
import net.ME1312.SubServers.Bungee.SubAPI;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
/**
|
||||
* Disconnect Player Packet
|
||||
*/
|
||||
public class PacketDisconnectPlayer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private int response;
|
||||
private UUID tracker;
|
||||
|
||||
/**
|
||||
* New PacketDisconnectPlayer (In)
|
||||
*/
|
||||
public PacketDisconnectPlayer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketDisconnectPlayer (Out)
|
||||
*
|
||||
* @param response Response ID
|
||||
* @param tracker Receiver ID
|
||||
*/
|
||||
public PacketDisconnectPlayer(int response, UUID tracker) {
|
||||
this.response = response;
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> json = new ObjectMap<Integer>();
|
||||
if (tracker != null) json.set(0x0000, tracker);
|
||||
json.set(0x0001, response);
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
UUID tracker = (data.contains(0x0000)?data.getUUID(0x0000):null);
|
||||
run(data.getUUIDList(0x0001), data.contains(0x0002)?data.getString(0x0002):null, i -> {
|
||||
client.sendPacket(new PacketDisconnectPlayer(i, tracker));
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void run(List<UUID> ids, String reason, IntConsumer callback) {
|
||||
try {
|
||||
Container<Integer> failures = new Container<>(0);
|
||||
HashMap<Proxy, List<UUID>> requests = new HashMap<Proxy, List<UUID>>();
|
||||
for (UUID id : ids) {
|
||||
ProxiedPlayer local;
|
||||
RemotePlayer remote;
|
||||
if ((local = ProxyServer.getInstance().getPlayer(id)) != null) {
|
||||
if (reason != null) {
|
||||
local.disconnect(reason);
|
||||
} else local.disconnect();
|
||||
} else if ((remote = SubAPI.getInstance().getRemotePlayer(id)) != null && remote.getProxy().getSubData()[0] != null) {
|
||||
Proxy proxy = remote.getProxy();
|
||||
List<UUID> list = requests.getOrDefault(proxy, new ArrayList<>());
|
||||
list.add(id);
|
||||
requests.put(proxy, list);
|
||||
} else {
|
||||
++failures.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (requests.size() == 0) {
|
||||
callback.accept(failures.value);
|
||||
} else {
|
||||
Merger merge = new Merger(() -> {
|
||||
callback.accept(failures.value);
|
||||
});
|
||||
for (Map.Entry<Proxy, List<UUID>> entry : requests.entrySet()) {
|
||||
merge.reserve();
|
||||
((SubDataClient) entry.getKey().getSubData()[0]).sendPacket(new PacketExDisconnectPlayer(entry.getValue(), reason, r -> {
|
||||
failures.value += r.getInt(0x0001);
|
||||
merge.release();
|
||||
}));
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
callback.accept(-1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,81 +1,80 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.Host.Proxy;
|
||||
import net.ME1312.SubServers.Bungee.Host.Server;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Download Group Info Packet
|
||||
*/
|
||||
public class PacketDownloadGroupInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
private String[] groups;
|
||||
private UUID tracker;
|
||||
public class PacketDownloadGroupInfo implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private String host;
|
||||
private String group;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketDownloadGroupInfo (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketDownloadGroupInfo(SubProxy plugin) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
public PacketDownloadGroupInfo(SubPlugin plugin) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketDownloadGroupInfo (Out)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
* @param groups Groups (or null for all)
|
||||
* @param tracker Receiver ID
|
||||
* @param group Group (or null for all)
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketDownloadGroupInfo(SubProxy plugin, List<String> groups, UUID tracker) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
this.tracker = tracker;
|
||||
|
||||
if (groups != null) {
|
||||
this.groups = new String[groups.size()];
|
||||
for (int i = 0; i < this.groups.length; ++i) this.groups[i] = groups.get(i).toLowerCase();
|
||||
Arrays.sort(this.groups);
|
||||
}
|
||||
public PacketDownloadGroupInfo(SubPlugin plugin, String group, String id) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
this.host = host;
|
||||
this.group = group;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
if (tracker != null) data.set(0x0000, tracker);
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
if (id != null) data.set("id", id);
|
||||
|
||||
if (this.groups == null || this.groups.length > 0) {
|
||||
ObjectMap<String> groups = new ObjectMap<String>();
|
||||
for (Map.Entry<String, List<Server>> group : plugin.api.getGroups().entrySet()) {
|
||||
if (this.groups == null || Arrays.binarySearch(this.groups, group.getKey().toLowerCase()) >= 0) {
|
||||
ObjectMap<String> servers = new ObjectMap<String>();
|
||||
for (Server server : group.getValue()) {
|
||||
servers.set(server.getName(), server.forSubData());
|
||||
}
|
||||
groups.set(group.getKey(), servers);
|
||||
YAMLSection groups = new YAMLSection();
|
||||
for (String group : plugin.api.getGroups().keySet()) {
|
||||
if (this.group == null || this.group.length() <= 0 || this.group.equalsIgnoreCase(group)) {
|
||||
YAMLSection servers = new YAMLSection();
|
||||
for (Server server : plugin.api.getGroup(group)) {
|
||||
servers.set(server.getName(), new YAMLSection(new Gson().fromJson(server.toString(), Map.class)));
|
||||
}
|
||||
groups.set(group, servers);
|
||||
}
|
||||
data.set(0x0001, groups);
|
||||
} else {
|
||||
ObjectMap<String> ungrouped = new ObjectMap<String>();
|
||||
for (Server server : plugin.api.getServers().values()) {
|
||||
if (server.getGroups().size() <= 0) ungrouped.set(server.getName(), server.forSubData());
|
||||
}
|
||||
|
||||
data.set(0x0001, Collections.emptyMap());
|
||||
data.set(0x0002, ungrouped);
|
||||
}
|
||||
data.set("groups", groups);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
client.sendPacket(new PacketDownloadGroupInfo(plugin, (data.contains(0x0001))?data.getStringList(0x0001):null, (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
client.sendPacket(new PacketDownloadGroupInfo(plugin, (data.contains("group"))?data.getRawString("group"):null, (data.contains("id"))?data.getRawString("id"):null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.13b");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +1,72 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Util;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import com.google.gson.Gson;
|
||||
import net.ME1312.SubServers.Bungee.Host.Host;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Download Host Info Packet
|
||||
*/
|
||||
public class PacketDownloadHostInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
private String[] hosts;
|
||||
private UUID tracker;
|
||||
public class PacketDownloadHostInfo implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private String host;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketDownloadHostInfo (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketDownloadHostInfo(SubProxy plugin) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
public PacketDownloadHostInfo(SubPlugin plugin) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketDownloadHostInfo (Out)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
* @param hosts Hosts (or null for all)
|
||||
* @param tracker Receiver ID
|
||||
* @param host Host (or null for all)
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketDownloadHostInfo(SubProxy plugin, List<String> hosts, UUID tracker) {
|
||||
this.plugin = Util.nullpo(plugin);
|
||||
this.tracker = tracker;
|
||||
|
||||
if (hosts != null) {
|
||||
this.hosts = new String[hosts.size()];
|
||||
for (int i = 0; i < this.hosts.length; ++i) this.hosts[i] = hosts.get(i).toLowerCase();
|
||||
Arrays.sort(this.hosts);
|
||||
}
|
||||
public PacketDownloadHostInfo(SubPlugin plugin, String host, String id) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
this.host = host;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
if (tracker != null) data.set(0x0000, tracker);
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
if (id != null) data.set("id", id);
|
||||
|
||||
ObjectMap<String> hosts = new ObjectMap<String>();
|
||||
YAMLSection hosts = new YAMLSection();
|
||||
for (Host host : plugin.api.getHosts().values()) {
|
||||
if (this.hosts == null || this.hosts.length <= 0 || Arrays.binarySearch(this.hosts, host.getName().toLowerCase()) >= 0) {
|
||||
hosts.set(host.getName(), host.forSubData());
|
||||
if (this.host == null || this.host.length() <= 0 || this.host.equalsIgnoreCase(host.getName())) {
|
||||
hosts.set(host.getName(), new YAMLSection(new Gson().fromJson(host.toString(), Map.class)));
|
||||
}
|
||||
}
|
||||
data.set(0x0001, hosts);
|
||||
data.set("hosts", hosts);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
client.sendPacket(new PacketDownloadHostInfo(plugin, (data.contains(0x0001))?data.getStringList(0x0001):null, (data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
client.sendPacket(new PacketDownloadHostInfo(plugin, (data.contains("host"))?data.getRawString("host"):null, (data.contains("id"))?data.getRawString("id"):null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.13b");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Download Lang Packet
|
||||
*/
|
||||
public class PacketDownloadLang implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
private UUID tracker;
|
||||
public class PacketDownloadLang implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketDownloadLang (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketDownloadLang(SubProxy plugin) {
|
||||
public PacketDownloadLang(SubPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
@ -30,26 +30,31 @@ public class PacketDownloadLang implements PacketObjectIn<Integer>, PacketObject
|
|||
* New PacketDownloadLang (Out)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
* @param tracker Receiver ID
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketDownloadLang(SubProxy plugin, UUID tracker) {
|
||||
public PacketDownloadLang(SubPlugin plugin, String id) {
|
||||
this.plugin = plugin;
|
||||
this.tracker = tracker;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
if (tracker != null) data.set(0x0000, tracker);
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
if (id != null) data.set("id", id);
|
||||
LinkedHashMap<String, Map<String, String>> full = new LinkedHashMap<>();
|
||||
for (String channel : plugin.api.getLangChannels())
|
||||
full.put(channel, plugin.api.getLang(channel));
|
||||
data.set(0x0001, full);
|
||||
data.set("Lang", full);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
client.sendPacket(new PacketDownloadLang(plugin, (data != null && data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
client.sendPacket(new PacketDownloadLang(plugin, (data != null && data.contains("id"))?data.getRawString("id"):null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.11.0a");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Util;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Download Network List Packet
|
||||
*/
|
||||
public class PacketDownloadNetworkList implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketDownloadNetworkList (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketDownloadNetworkList(SubPlugin plugin) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* New PacketDownloadNetworkList (Out)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketDownloadNetworkList(SubPlugin plugin, String id) {
|
||||
if (Util.isNull(plugin)) throw new NullPointerException();
|
||||
this.plugin = plugin;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public YAMLSection generate() {
|
||||
YAMLSection json = new YAMLSection();
|
||||
if (id != null) json.set("id", id);
|
||||
YAMLSection clients = new YAMLSection();
|
||||
for (Client client : plugin.subdata.getClients()) {
|
||||
try {
|
||||
clients.set(client.getAddress().toString(), new YAMLSection(new Gson().fromJson(client.getHandler().toString(), Map.class)));
|
||||
} catch (JsonParseException | NullPointerException e) {
|
||||
clients.set(client.getAddress().toString(), new YAMLSection());
|
||||
}
|
||||
}
|
||||
json.set("clients", clients);
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
client.sendPacket(new PacketDownloadNetworkList(plugin, (data.contains("id"))?data.getRawString("id"):null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.11.0a");
|
||||
}
|
||||
}
|
|
@ -1,30 +1,28 @@
|
|||
package net.ME1312.SubServers.Bungee.Network.Packet;
|
||||
|
||||
import net.ME1312.Galaxi.Library.Map.ObjectMap;
|
||||
import net.ME1312.Galaxi.Library.Version.Version;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectIn;
|
||||
import net.ME1312.SubData.Server.Protocol.PacketObjectOut;
|
||||
import net.ME1312.SubData.Server.SubDataClient;
|
||||
import net.ME1312.SubServers.Bungee.SubProxy;
|
||||
|
||||
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection;
|
||||
import net.ME1312.SubServers.Bungee.Library.Version.Version;
|
||||
import net.ME1312.SubServers.Bungee.Network.Client;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketIn;
|
||||
import net.ME1312.SubServers.Bungee.Network.PacketOut;
|
||||
import net.ME1312.SubServers.Bungee.SubPlugin;
|
||||
import net.md_5.bungee.api.config.ListenerInfo;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Download Proxy Info Packet
|
||||
*/
|
||||
public class PacketDownloadPlatformInfo implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
|
||||
private SubProxy plugin;
|
||||
private UUID tracker;
|
||||
public class PacketDownloadPlatformInfo implements PacketIn, PacketOut {
|
||||
private SubPlugin plugin;
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* New PacketDownloadPlatformInfo (In)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
*/
|
||||
public PacketDownloadPlatformInfo(SubProxy plugin) {
|
||||
public PacketDownloadPlatformInfo(SubPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
@ -32,73 +30,65 @@ public class PacketDownloadPlatformInfo implements PacketObjectIn<Integer>, Pack
|
|||
* New PacketDownloadPlatformInfo (Out)
|
||||
*
|
||||
* @param plugin SubPlugin
|
||||
* @param tracker Receiver ID
|
||||
* @param id Receiver ID
|
||||
*/
|
||||
public PacketDownloadPlatformInfo(SubProxy plugin, UUID tracker) {
|
||||
public PacketDownloadPlatformInfo(SubPlugin plugin, String id) {
|
||||
this.plugin = plugin;
|
||||
this.tracker = tracker;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMap<Integer> send(SubDataClient client) {
|
||||
ObjectMap<Integer> data = new ObjectMap<Integer>();
|
||||
if (tracker != null) data.set(0x0000, tracker);
|
||||
ObjectMap<String> info = new ObjectMap<String>();
|
||||
|
||||
|
||||
ObjectMap<String> subservers = new ObjectMap<String>();
|
||||
public YAMLSection generate() {
|
||||
YAMLSection data = new YAMLSection();
|
||||
if (id != null) data.set("id", id);
|
||||
YAMLSection subservers = new YAMLSection();
|
||||
subservers.set("version", plugin.api.getWrapperVersion().toString());
|
||||
if (plugin.api.getWrapperBuild() != null) subservers.set("build", plugin.api.getWrapperBuild().toString());
|
||||
subservers.set("last-reload", plugin.resetDate);
|
||||
subservers.set("proxies", plugin.api.getProxies().size());
|
||||
subservers.set("hosts", plugin.api.getHosts().size());
|
||||
subservers.set("subservers", plugin.api.getSubServers().size());
|
||||
info.set("subservers", subservers);
|
||||
|
||||
|
||||
ObjectMap<String> bungee = new ObjectMap<String>();
|
||||
data.set("subservers", subservers);
|
||||
YAMLSection bungee = new YAMLSection();
|
||||
bungee.set("version", plugin.api.getProxyVersion().toString());
|
||||
bungee.set("disabled-cmds", plugin.getConfig().getDisabledCommands());
|
||||
bungee.set("player-limit", plugin.getConfig().getPlayerLimit());
|
||||
bungee.set("servers", plugin.api.getServers().size());
|
||||
LinkedList<ObjectMap<String>> listeners = new LinkedList<ObjectMap<String>>();
|
||||
for (ListenerInfo next : plugin.getConfig().getListeners()) {
|
||||
ObjectMap<String> listener = new ObjectMap<String>();
|
||||
listener.set("forced-hosts", next.getForcedHosts());
|
||||
listener.set("motd", next.getMotd());
|
||||
listener.set("priorities", next.getServerPriority());
|
||||
listener.set("player-limit", next.getMaxPlayers());
|
||||
LinkedList<YAMLSection> listeners = new LinkedList<YAMLSection>();
|
||||
for (ListenerInfo info : plugin.getConfig().getListeners()) {
|
||||
YAMLSection listener = new YAMLSection();
|
||||
listener.set("forced-hosts", info.getForcedHosts());
|
||||
listener.set("motd", info.getMotd());
|
||||
listener.set("priorities", info.getServerPriority());
|
||||
listener.set("player-limit", info.getMaxPlayers());
|
||||
listeners.add(listener);
|
||||
}
|
||||
bungee.set("listeners", listeners);
|
||||
info.set("bungee", bungee);
|
||||
|
||||
|
||||
ObjectMap<String> minecraft = new ObjectMap<String>();
|
||||
data.set("bungee", bungee);
|
||||
YAMLSection minecraft = new YAMLSection();
|
||||
LinkedList<String> mcversions = new LinkedList<String>();
|
||||
for (Version version : plugin.api.getGameVersion()) mcversions.add(version.toString());
|
||||
minecraft.set("version", mcversions);
|
||||
minecraft.set("players", plugin.api.getRemotePlayers().size());
|
||||
info.set("minecraft", minecraft);
|
||||
|
||||
|
||||
ObjectMap<String> system = new ObjectMap<String>();
|
||||
ObjectMap<String> os = new ObjectMap<String>();
|
||||
minecraft.set("players", plugin.api.getGlobalPlayers().size());
|
||||
data.set("minecraft", minecraft);
|
||||
YAMLSection system = new YAMLSection();
|
||||
YAMLSection os = new YAMLSection();
|
||||
os.set("name", System.getProperty("os.name"));
|
||||
os.set("version", System.getProperty("os.version"));
|
||||
system.set("os", os);
|
||||
ObjectMap<String> java = new ObjectMap<String>();
|
||||
YAMLSection java = new YAMLSection();
|
||||
java.set("version", System.getProperty("java.version"));
|
||||
system.set("java", java);
|
||||
info.set("system", system);
|
||||
|
||||
|
||||
data.set(0x0001, info);
|
||||
data.set("system", system);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(SubDataClient client, ObjectMap<Integer> data) {
|
||||
client.sendPacket(new PacketDownloadPlatformInfo(plugin, (data != null && data.contains(0x0000))?data.getUUID(0x0000):null));
|
||||
public void execute(Client client, YAMLSection data) {
|
||||
client.sendPacket(new PacketDownloadPlatformInfo(plugin, (data != null && data.contains("id"))?data.getRawString("id"):null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version getVersion() {
|
||||
return new Version("2.11.0a");
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue