commit a075059739fde5c447375ac3affd67d87d3ed729 Author: Ruakij Date: Sun Mar 7 21:30:57 2021 +0100 Initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bd405af --- /dev/null +++ b/LICENSE @@ -0,0 +1,163 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the terms +and conditions of version 3 of the GNU General Public License, supplemented +by the additional permissions listed below. + + 0. Additional Definitions. + + + +As used herein, "this License" refers to version 3 of the GNU Lesser General +Public License, and the "GNU GPL" refers to version 3 of the GNU General Public +License. + + + +"The Library" refers to a covered work governed by this License, other than +an Application or a Combined Work as defined below. + + + +An "Application" is any work that makes use of an interface provided by the +Library, but which is not otherwise based on the Library. Defining a subclass +of a class defined by the Library is deemed a mode of using an interface provided +by the Library. + + + +A "Combined Work" is a work produced by combining or linking an Application +with the Library. The particular version of the Library with which the Combined +Work was made is also called the "Linked Version". + + + +The "Minimal Corresponding Source" for a Combined Work means the Corresponding +Source for the Combined Work, excluding any source code for portions of the +Combined Work that, considered in isolation, are based on the Application, +and not on the Linked Version. + + + +The "Corresponding Application Code" for a Combined Work means the object +code and/or source code for the Application, including any data and utility +programs needed for reproducing the Combined Work from the Application, but +excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License without +being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a facility +refers to a function or data to be supplied by an Application that uses the +facility (other than as an argument passed when the facility is invoked), +then you may convey a copy of the modified version: + +a) under this License, provided that you make a good faith effort to ensure +that, in the event an Application does not supply the function or data, the +facility still operates, and performs whatever part of its purpose remains +meaningful, or + +b) under the GNU GPL, with none of the additional permissions of this License +applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from a header +file that is part of the Library. You may convey such object code under terms +of your choice, provided that, if the incorporated material is not limited +to numerical parameters, data structure layouts and accessors, or small macros, +inline functions and templates (ten or fewer lines in length), you do both +of the following: + +a) Give prominent notice with each copy of the object code that the Library +is used in it and that the Library and its use are covered by this License. + +b) Accompany the object code with a copy of the GNU GPL and this license document. + + 4. Combined Works. + +You may convey a Combined Work under terms of your choice that, taken together, +effectively do not restrict modification of the portions of the Library contained +in the Combined Work and reverse engineering for debugging such modifications, +if you also do each of the following: + +a) Give prominent notice with each copy of the Combined Work that the Library +is used in it and that the Library and its use are covered by this License. + +b) Accompany the Combined Work with a copy of the GNU GPL and this license +document. + +c) For a Combined Work that displays copyright notices during execution, include +the copyright notice for the Library among these notices, as well as a reference +directing the user to the copies of the GNU GPL and this license document. + + d) Do one of the following: + +0) Convey the Minimal Corresponding Source under the terms of this License, +and the Corresponding Application Code in a form suitable for, and under terms +that permit, the user to recombine or relink the Application with a modified +version of the Linked Version to produce a modified Combined Work, in the +manner specified by section 6 of the GNU GPL for conveying Corresponding Source. + +1) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (a) uses at run time a copy of the Library +already present on the user's computer system, and (b) will operate properly +with a modified version of the Library that is interface-compatible with the +Linked Version. + +e) Provide Installation Information, but only if you would otherwise be required +to provide such information under section 6 of the GNU GPL, and only to the +extent that such information is necessary to install and execute a modified +version of the Combined Work produced by recombining or relinking the Application +with a modified version of the Linked Version. (If you use option 4d0, the +Installation Information must accompany the Minimal Corresponding Source and +Corresponding Application Code. If you use option 4d1, you must provide the +Installation Information in the manner specified by section 6 of the GNU GPL +for conveying Corresponding Source.) + + 5. Combined Libraries. + +You may place library facilities that are a work based on the Library side +by side in a single library together with other library facilities that are +not Applications and are not covered by this License, and convey such a combined +library under terms of your choice, if you do both of the following: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities, conveyed under the +terms of this License. + +b) Give prominent notice with the combined library that part of it is a work +based on the Library, and explaining where to find the accompanying uncombined +form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions of the +GNU Lesser General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address +new problems or concerns. + +Each version is given a distinguishing version number. If the Library as you +received it specifies that a certain numbered version of the GNU Lesser General +Public License "or any later version" applies to it, you have the option of +following the terms and conditions either of that published version or of +any later version published by the Free Software Foundation. If the Library +as you received it does not specify a version number of the GNU Lesser General +Public License, you may choose any version of the GNU Lesser General Public +License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide whether +future versions of the GNU Lesser General Public License shall apply, that +proxy's public statement of acceptance of any version is permanent authorization +for you to choose that version for the Library. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cdf12e3 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# ForceServer + +Bungeecord-Plugin that can force players to join specific servers by default based on +- UUID +- Name +- Permission diff --git a/src/config.yml b/src/config.yml new file mode 100755 index 0000000..d848f03 --- /dev/null +++ b/src/config.yml @@ -0,0 +1,11 @@ + + +# Force default-join-server for players that match the following attributes +# More specific attributes are preferred (UUID > Name > Permission) +forceServer: + byUUID: + '25282767-426d-446a-99ab-5554b354ac59': Server1 + byName: + 'ABCDE': Server1 + byPermission: + 'forceServer.server1': Server1 diff --git a/src/eu/ruekov/ruakij/forceServer/ConfigHelper.java b/src/eu/ruekov/ruakij/forceServer/ConfigHelper.java new file mode 100755 index 0000000..6327e75 --- /dev/null +++ b/src/eu/ruekov/ruakij/forceServer/ConfigHelper.java @@ -0,0 +1,89 @@ +package eu.ruekov.ruakij.forceServer; + +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +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 java.io.*; +import java.util.Random; +import java.util.logging.Logger; + +public class ConfigHelper { + public static Configuration loadOrRecreateConfig(Plugin plugin, String resource) throws IOException { + return loadOrRecreateConfig(plugin, resource, null); + } + public static Configuration loadOrRecreateConfig(Plugin plugin, String resource, Logger log) throws IOException { + + for(int i=0; i<2; i++) { + try { + // Copy default config if not existing + ConfigHelper.loadAndSaveResource(plugin, "config.yml"); + } catch (IOException e) { + + if(log!=null)log.severe("Could not load plugin-resource!"); + throw e; + } + + try { + // Read config + return ConfigurationProvider.getProvider(YamlConfiguration.class).load(new File(plugin.getDataFolder(), resource)); + + } catch (IOException e) { + + if(i == 0) { + if(log!=null)log.severe("Could not load configuration-file!"); + e.printStackTrace(); + + if(log!=null)log.info("Backing-up config and creating a new one"); + backupAndDisableConfig(resource); + } + else + throw e; + + } + } + + // We should not end up here.. + throw new IOException("Could not create/load configuration-file!"); + } + + public static void backupAndDisableConfig(String resource) throws IOException { + + // Rename the old config to a new-one, so settings are not lost + Random rand = new Random(); + String newResource = resource + rand.nextInt(); + + Files.move(new File(resource), new File(newResource)); + } + + public static File loadAndSaveResource(Plugin plugin, String resource) throws IOException { + File folder = plugin.getDataFolder(); + if (!folder.exists()) + folder.mkdir(); + File resourceFile = new File(folder, resource); + if (!resourceFile.exists()) { + resourceFile.createNewFile(); + try (InputStream in = plugin.getResourceAsStream(resource); + OutputStream out = new FileOutputStream(resourceFile)) { + ByteStreams.copy(in, out); + } + } + return resourceFile; + } + + public static boolean validateEntry(String entry, String[] allowed) { + return validateEntry(entry, allowed, false); + } + public static boolean validateEntry(String entry, String[] allowed, boolean caseSensetive) { + + for(String allow : allowed) { + + if(entry.equalsIgnoreCase(allow)) + return true; + } + return false; + } +} diff --git a/src/eu/ruekov/ruakij/forceServer/Main.java b/src/eu/ruekov/ruakij/forceServer/Main.java new file mode 100755 index 0000000..dccdda0 --- /dev/null +++ b/src/eu/ruekov/ruakij/forceServer/Main.java @@ -0,0 +1,85 @@ +package eu.ruekov.ruakij.forceServer; + +import eu.ruekov.ruakij.forceServer.command.forceServer; +import eu.ruekov.ruakij.forceServer.listener.PostLogin; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.api.plugin.PluginDescription; +import net.md_5.bungee.config.Configuration; + + +import java.io.IOException; +import java.util.HashMap; +import java.util.logging.Logger; + +public class Main extends Plugin { + + public static Main plugin; + public static PluginDescription pInfo; + + public static Logger log; + + public static Configuration config; + + public static HashMap forceServerByUUID; + public static HashMap forceServerByName; + public static HashMap forceServerByPermission; + + public void onEnable() { + log = getLogger(); // Get logger + plugin = this; // Get plugin + pInfo = this.getDescription(); // Get plugin-info + + log.info("Loading config.."); + try { + loadConfig(); + } catch (IOException ex) { + log.severe("Loading config failed!"); + ex.printStackTrace(); + + // Disable plugin + onDisable(); + return; + } + + log.info("Registering commands.."); + this.getProxy().getPluginManager().registerCommand(this, new forceServer("forceserver")); + + log.info("Registering events.."); + this.getProxy().getPluginManager().registerListener(this, new PostLogin()); + } + + @Override + public void onDisable() { + + log.info("Version: " + pInfo.getVersion() + " is now disabled!"); + } + + public void loadConfig() throws IOException { + config = ConfigHelper.loadOrRecreateConfig(this, "config.yml"); + + // Load UUID-List into memory + forceServerByUUID = new HashMap<>(); + Configuration byUuidSection = config.getSection("forceServer.byUUID"); + for(String uuid : byUuidSection.getKeys()) { + String targetServer = byUuidSection.getString(uuid); + forceServerByUUID.put(uuid, targetServer); + } + log.info(forceServerByUUID.size() +" UUID's"); + + forceServerByName = new HashMap<>(); + Configuration byNameSection = config.getSection("forceServer.byName"); + for(String uuid : byNameSection.getKeys()) { + String targetServer = byNameSection.getString(uuid); + forceServerByName.put(uuid, targetServer); + } + log.info(forceServerByName.size() +" Names"); + + forceServerByPermission = new HashMap<>(); + Configuration byPermissionSection = config.getSection("forceServer.byPermission"); + for(String uuid : byPermissionSection.getKeys()) { + String targetServer = byPermissionSection.getString(uuid); + forceServerByPermission.put(uuid, targetServer); + } + log.info(forceServerByPermission.size() +" Permission-Nodes"); + } +} diff --git a/src/eu/ruekov/ruakij/forceServer/command/forceServer.java b/src/eu/ruekov/ruakij/forceServer/command/forceServer.java new file mode 100644 index 0000000..815c536 --- /dev/null +++ b/src/eu/ruekov/ruakij/forceServer/command/forceServer.java @@ -0,0 +1,39 @@ +package eu.ruekov.ruakij.forceServer.command; + +import eu.ruekov.ruakij.forceServer.Main; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; + +import java.io.IOException; + +public class forceServer extends Command { + public forceServer(String name) { super(name); } + + @Override + public void execute(CommandSender sender, String[] args) { + + // Permission check if sender is player + if(sender instanceof ProxiedPlayer){ + ProxiedPlayer p = (ProxiedPlayer)sender; + + if(!p.hasPermission("forceServer.cmd")){ + p.sendMessage("§cNo Permission!"); + return; + } + } + + Main.log.info("Reloading config.."); + sender.sendMessage("§eReloading.."); + try { + Main.plugin.loadConfig(); + } catch (IOException ex) { + Main.log.severe("Reloading config failed!"); + ex.printStackTrace(); + + sender.sendMessage("§cFailed! See config for details"); + return; + } + sender.sendMessage("§aDone"); + } +} diff --git a/src/eu/ruekov/ruakij/forceServer/listener/PostLogin.java b/src/eu/ruekov/ruakij/forceServer/listener/PostLogin.java new file mode 100644 index 0000000..91bddea --- /dev/null +++ b/src/eu/ruekov/ruakij/forceServer/listener/PostLogin.java @@ -0,0 +1,43 @@ +package eu.ruekov.ruakij.forceServer.listener; + +import eu.ruekov.ruakij.forceServer.Main; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import java.util.logging.Logger; + +public class PostLogin implements Listener { + + @EventHandler + public void onPostLogin(PostLoginEvent e) { + + ProxiedPlayer p = e.getPlayer(); + + // byUUID + String forcedTargetServer = Main.forceServerByUUID.get(p.getUniqueId().toString()); + // byName + if(forcedTargetServer == null) Main.forceServerByName.get(p.getName()); + // byPermission + if(forcedTargetServer == null) { + for(String permission : Main.forceServerByPermission.keySet()) { + if(p.hasPermission(permission)){ + forcedTargetServer = Main.forceServerByPermission.get(permission); + } + } + Main.forceServerByPermission.get(p); + } + if(forcedTargetServer == null) return; + + ServerInfo sInfo = BungeeCord.getInstance().getServerInfo(forcedTargetServer); + if(sInfo == null) { + Main.log.severe("TargetServer '"+ forcedTargetServer +"' not found!"); + return; + } + + p.connect(sInfo); + } +} diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100755 index 0000000..a3df3ee --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,5 @@ +name: ForceServer +version: 1.0.0 +author: Ruakij + +main: eu.ruekov.ruakij.forceServer.Main