SubServers-2/SubServers.Client/Bukkit/src/net/ME1312/SubServers/Client/Bukkit/SubPlugin.java

270 lines
13 KiB
Java
Raw Normal View History

2016-12-20 00:31:01 +01:00
package net.ME1312.SubServers.Client.Bukkit;
2022-03-17 05:18:34 +01:00
import net.ME1312.Galaxi.Library.Access;
2020-11-16 21:34:59 +01:00
import net.ME1312.Galaxi.Library.Config.YAMLConfig;
import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.Galaxi.Library.Container.Pair;
2019-04-18 16:02:09 +02:00
import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Try;
2020-11-16 21:34:59 +01:00
import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubData.Client.DataClient;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubData.Client.Encryption.AES;
import net.ME1312.SubData.Client.Encryption.DHE;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubData.Client.Encryption.RSA;
2019-05-10 04:43:34 +02:00
import net.ME1312.SubData.Client.Library.DisconnectReason;
2020-11-16 21:34:59 +01:00
import net.ME1312.SubData.Client.SubDataClient;
import net.ME1312.SubServers.Client.Bukkit.Graphic.DefaultUIHandler;
2017-01-21 17:49:37 +01:00
import net.ME1312.SubServers.Client.Bukkit.Graphic.UIHandler;
2022-03-17 05:18:34 +01:00
import net.ME1312.SubServers.Client.Bukkit.Library.Compatibility.PlaceholderImpl;
import net.ME1312.SubServers.Client.Bukkit.Library.Placeholders;
import net.ME1312.SubServers.Client.Bukkit.Library.ConfigUpdater;
2020-11-16 21:34:59 +01:00
import net.ME1312.SubServers.Client.Bukkit.Library.Metrics;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubServers.Client.Bukkit.Network.SubProtocol;
2020-11-16 21:34:59 +01:00
2016-12-20 00:31:01 +01:00
import org.bukkit.Bukkit;
2019-04-29 17:05:06 +02:00
import org.bukkit.command.CommandMap;
import org.bukkit.entity.Player;
2016-12-20 00:31:01 +01:00
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
2022-03-17 05:18:34 +01:00
import java.lang.invoke.MethodHandle;
import java.lang.reflect.InvocationTargetException;
2016-12-20 00:31:01 +01:00
import java.net.InetAddress;
2017-11-22 22:58:33 +01:00
import java.net.URL;
import java.nio.charset.Charset;
2016-12-20 00:31:01 +01:00
import java.nio.file.Files;
2017-05-25 21:55:47 +02:00
import java.nio.file.StandardCopyOption;
2019-05-10 04:43:34 +02:00
import java.util.*;
2017-11-22 22:58:33 +01:00
import java.util.concurrent.TimeUnit;
2016-12-20 00:31:01 +01:00
import static net.ME1312.SubServers.Client.Bukkit.Library.AccessMode.NO_COMMANDS;
import static net.ME1312.SubServers.Client.Bukkit.Library.AccessMode.NO_INTEGRATIONS;
2021-06-06 23:01:28 +02:00
2017-01-08 20:42:40 +01:00
/**
* SubServers Client Plugin Class
*/
2016-12-20 00:31:01 +01:00
public final class SubPlugin extends JavaPlugin {
2019-05-17 00:36:41 +02:00
HashMap<Integer, SubDataClient> subdata = new HashMap<Integer, SubDataClient>();
2020-11-14 08:07:25 +01:00
Pair<Long, Map<String, Map<String, String>>> lang = null;
private File dir;
2017-01-26 23:19:48 +01:00
public YAMLConfig config;
2019-04-29 17:05:06 +02:00
public SubProtocol subprotocol;
2016-12-20 00:31:01 +01:00
2017-01-21 17:49:37 +01:00
public UIHandler gui = null;
2017-01-08 20:42:40 +01:00
public final Version version;
2017-01-21 17:49:37 +01:00
public final SubAPI api = new SubAPI(this);
2022-03-17 05:18:34 +01:00
public final Placeholders phi = new Placeholders(this);
public String server_address;
2016-12-20 00:31:01 +01:00
2022-03-17 05:18:34 +01:00
private MethodHandle gson;
private long resetDate = 0;
2019-05-10 04:43:34 +02:00
private boolean reconnect = false;
2022-03-17 05:18:34 +01:00
@SuppressWarnings("ConstantConditions")
public SubPlugin() throws Throwable {
2017-01-08 20:42:40 +01:00
super();
2022-03-17 05:18:34 +01:00
Class<?> gson = Class.forName(((Try.all.get(() -> Class.forName("com.google.gson.Gson") != null, false)?"":"org.bukkit.craftbukkit.libs.")) + "com.google.gson.Gson");
this.gson = Access.shared.type(gson).method("fromJson").instance(gson.newInstance()).parameters(String.class, Class.class).returns(Object.class).handle();
version = Version.fromString(getDescription().getVersion());
2019-05-10 06:04:10 +02:00
subdata.put(0, null);
2017-01-08 20:42:40 +01:00
}
/**
* Enable Plugin
*/
2016-12-20 00:31:01 +01:00
@Override
public void onEnable() {
try {
Bukkit.getLogger().info("SubServers > Loading SubServers.Client.Bukkit v" + version.toString() + " Libraries (for Minecraft " + api.getGameVersion() + ")");
dir = new File(getDataFolder().getParentFile(), "SubServers-Client");
2021-06-12 21:27:51 +02:00
if (getDataFolder().exists()) {
Files.move(getDataFolder().toPath(), dir.toPath(), StandardCopyOption.REPLACE_EXISTING);
} else dir.mkdirs();
ConfigUpdater.updateConfig(new File(dir, "config.yml"));
config = new YAMLConfig(new File(dir, "config.yml"));
if (new File(new File(System.getProperty("user.dir")), "subdata.json").exists()) {
FileReader reader = new FileReader(new File(new File(System.getProperty("user.dir")), "subdata.json"));
2019-04-18 16:02:09 +02:00
config.get().getMap("Settings").set("SubData", new YAMLSection(parseJSON(Util.readAll(reader))));
config.save();
reader.close();
new File(new File(System.getProperty("user.dir")), "subdata.json").delete();
2019-04-18 16:02:09 +02:00
}
if (new File(new File(System.getProperty("user.dir")), "subdata.rsa.key").exists()) {
if (new File(dir, "subdata.rsa.key").exists()) new File(dir, "subdata.rsa.key").delete();
Files.move(new File(new File(System.getProperty("user.dir")), "subdata.rsa.key").toPath(), new File(dir, "subdata.rsa.key").toPath());
}
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
reload(false);
2019-04-18 16:02:09 +02:00
subprotocol = SubProtocol.get();
subprotocol.registerCipher("DHE", DHE.get(128));
subprotocol.registerCipher("DHE-128", DHE.get(128));
subprotocol.registerCipher("DHE-192", DHE.get(192));
subprotocol.registerCipher("DHE-256", DHE.get(256));
api.name = config.get().getMap("Settings").getMap("SubData").getString("Name", System.getenv("name"));
server_address = config.get().getMap("Settings").getString("Connect-Address", System.getenv("address"));
if (config.get().getMap("Settings").getMap("SubData").getString("Password", "").length() > 0) {
subprotocol.registerCipher("AES", new AES(128, config.get().getMap("Settings").getMap("SubData").getString("Password")));
subprotocol.registerCipher("AES-128", new AES(128, config.get().getMap("Settings").getMap("SubData").getString("Password")));
subprotocol.registerCipher("AES-192", new AES(192, config.get().getMap("Settings").getMap("SubData").getString("Password")));
subprotocol.registerCipher("AES-256", new AES(256, config.get().getMap("Settings").getMap("SubData").getString("Password")));
2021-09-15 04:05:56 +02:00
Bukkit.getLogger().info("SubData > AES Encryption Available");
}
if (new File(dir, "subdata.rsa.key").exists()) {
try {
subprotocol.registerCipher("RSA", new RSA(new File(dir, "subdata.rsa.key")));
2021-09-15 04:05:56 +02:00
Bukkit.getLogger().info("SubData > RSA Encryption Available");
} catch (Exception e) {
e.printStackTrace();
}
}
reconnect = true;
2021-09-15 04:05:56 +02:00
Bukkit.getLogger().info("SubData > ");
Bukkit.getLogger().info("SubData > Connecting to /" + config.get().getMap("Settings").getMap("SubData").getString("Address", "127.0.0.1:4391"));
connect(null);
2016-12-20 00:31:01 +01:00
2021-06-06 23:01:28 +02:00
gui = new DefaultUIHandler(this);
if (api.access.value > NO_COMMANDS.value && !config.get().getMap("Settings").getBoolean("API-Only-Mode", false)) {
2022-03-17 05:18:34 +01:00
Bukkit.getPluginManager().registerEvents(new SubSigns(this, new File(dir, "signs.dat")), this);
2019-04-29 17:05:06 +02:00
CommandMap cmd = Util.reflect(Bukkit.getServer().getClass().getDeclaredField("commandMap"), Bukkit.getServer());
cmd.register("subservers", new SubCommand(this, "subservers"));
cmd.register("subservers", new SubCommand(this, "subserver"));
cmd.register("subservers", new SubCommand(this, "sub"));
2019-04-18 16:02:09 +02:00
}
2017-11-22 22:58:33 +01:00
2022-03-17 05:18:34 +01:00
if (api.access.value > NO_INTEGRATIONS.value) {
if (config.get().getMap("Settings").getBoolean("PlaceholderAPI-Ready", false)) phi.start();
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) new PlaceholderImpl(this).register();
}
new Metrics(this, 2334);
2017-11-22 22:58:33 +01:00
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
try {
2018-08-04 02:43:02 +02:00
YAMLSection tags = new YAMLSection(parseJSON("{\"tags\":" + Util.readAll(new BufferedReader(new InputStreamReader(new URL("https://api.github.com/repos/ME1312/SubServers-2/git/refs/tags").openStream(), Charset.forName("UTF-8")))) + '}'));
List<Version> versions = new LinkedList<Version>();
2017-11-22 22:58:33 +01:00
Version updversion = version;
2018-03-14 22:50:15 +01:00
int updcount = 0;
2019-04-18 16:02:09 +02:00
for (ObjectMap<String> tag : tags.getMapList("tags")) versions.add(Version.fromString(tag.getString("ref").substring(10)));
Collections.sort(versions);
for (Version version : versions) {
2018-07-29 05:02:47 +02:00
if (version.compareTo(updversion) > 0) {
2018-07-27 21:36:51 +02:00
updversion = version;
updcount++;
2017-11-22 22:58:33 +01:00
}
}
if (updcount > 0) Bukkit.getLogger().info("SubServers > SubServers.Client.Bukkit v" + updversion + " is available. You are " + updcount + " version" + ((updcount == 1)?"":"s") + " behind.");
2022-03-17 05:18:34 +01:00
} catch (Throwable e) {}
2017-11-22 22:58:33 +01:00
}, 0, TimeUnit.DAYS.toSeconds(2) * 20);
2022-03-17 05:18:34 +01:00
} catch (Throwable e) {
2016-12-20 00:31:01 +01:00
e.printStackTrace();
}
}
public void reload(boolean notifyPlugins) throws IOException {
resetDate = Calendar.getInstance().getTime().getTime();
ConfigUpdater.updateConfig(new File(dir, "config.yml"));
config.reload();
if (notifyPlugins) {
List<Runnable> listeners = api.reloadListeners;
if (listeners.size() > 0) {
for (Object obj : listeners) {
try {
((Runnable) obj).run();
} catch (Throwable e) {
new InvocationTargetException(e, "Problem reloading plugin").printStackTrace();
}
}
}
}
}
2020-11-14 08:07:25 +01:00
private void connect(Pair<DisconnectReason, DataClient> disconnect) throws IOException {
2020-11-11 22:07:22 +01:00
int reconnect = config.get().getMap("Settings").getMap("SubData").getInt("Reconnect", 60);
2020-11-14 08:07:25 +01:00
if (disconnect == null || (this.reconnect && reconnect > 0 && disconnect.key() != DisconnectReason.PROTOCOL_MISMATCH && disconnect.key() != DisconnectReason.ENCRYPTION_MISMATCH)) {
long reset = resetDate;
if (disconnect != null) Bukkit.getLogger().info("SubData > Attempting reconnect in " + reconnect + " seconds");
Bukkit.getScheduler().runTaskLaterAsynchronously(this, new Runnable() {
@Override
public void run() {
try {
2019-10-19 22:38:44 +02:00
if (reset == resetDate && (subdata.getOrDefault(0, null) == null || subdata.get(0).isClosed())) {
SubDataClient open = subprotocol.open(InetAddress.getByName(config.get().getMap("Settings").getMap("SubData").getString("Address", "127.0.0.1:4391").split(":")[0]),
Integer.parseInt(config.get().getMap("Settings").getMap("SubData").getString("Address", "127.0.0.1:4391").split(":")[1]));
2019-10-19 00:24:58 +02:00
if (subdata.getOrDefault(0, null) != null) subdata.get(0).reconnect(open);
subdata.put(0, open);
}
} catch (IOException e) {
Bukkit.getLogger().info("SubData > Connection was unsuccessful, retrying in " + reconnect + " seconds");
Bukkit.getScheduler().runTaskLater(SubPlugin.this, this, reconnect * 20);
}
}
}, (disconnect == null)?0:reconnect * 20);
}
2019-05-10 04:43:34 +02:00
}
2017-01-08 20:42:40 +01:00
/**
* Disable Plugin
*/
2016-12-20 00:31:01 +01:00
@Override
public void onDisable() {
2017-01-21 17:49:37 +01:00
if (subdata != null) try {
2019-04-29 17:05:06 +02:00
setEnabled(false);
2019-05-10 04:43:34 +02:00
reconnect = false;
ArrayList<SubDataClient> temp = new ArrayList<SubDataClient>();
temp.addAll(subdata.values());
2019-05-11 23:23:31 +02:00
for (SubDataClient client : temp) if (client != null) {
2019-05-10 04:43:34 +02:00
client.close();
client.waitFor();
}
subdata.clear();
2019-05-11 23:23:31 +02:00
subdata.put(0, null);
2022-03-17 05:18:34 +01:00
SubSigns.save();
} catch (IOException | InterruptedException e) {
2017-01-21 17:49:37 +01:00
e.printStackTrace();
}
2016-12-20 00:31:01 +01:00
}
2018-08-04 02:43:02 +02:00
/**
* Use reflection to access Gson for parsing
*
* @param json JSON to parse
* @return JSON as a map
*/
@SuppressWarnings("unchecked")
2022-03-17 05:18:34 +01:00
public Map<String, ?> parseJSON(String json) throws Throwable {
return (Map<String, ?>) (Object) gson.invokeExact(json, Map.class);
2018-08-04 02:43:02 +02:00
}
/**
* Send a message to the BungeeCord Plugin Messaging Channel
*
* @param player Player that will send
* @param message Message contents
*/
public void pmc(Player player, String... message) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(stream);
try {
for (String m : message) data.writeUTF(m);
data.flush();
} catch (IOException e) {
e.printStackTrace();
}
player.sendPluginMessage(this, "BungeeCord", stream.toByteArray());
}
2016-12-20 00:31:01 +01:00
}