diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a217b34 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: maven + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..407749a --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,19 @@ +name: Java CI + +on: [push] + +jobs: + build_and_test: + strategy: + matrix: + jdkversion: [8, 11, 17] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: ${{ matrix.jdkversion }} + cache: 'maven' + - name: Build with Maven + run: mvn -V -B clean package --file pom.xml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1645036..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -sudo: false - -language: java -jdk: oraclejdk7 - -cache: - directories: - - '$HOME/.m2/repository' - -script: - - mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false - - mvn clean install -B -U - -notifications: - webhooks: - urls: - - https://webhooks.gitter.im/e/952357dbd9d3cea70fd5 - on_success: change # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: false # default: false diff --git a/README.md b/README.md index 6d04cc2..4ea4152 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,27 @@ -# AuthMeBridge - -![AuthMeBridge](http://www.craftfriends.fr/images/AuthMeBridge.png "AuthMeBridge") +# AuthMeBungee This plugin acts like a bridge between your bukkit servers and your BungeeCord instance. To explain simple how it works, bukkit-side plugins send a message to bungee-side on user authentication. If bungee-side doesn't receive this message, the player won't be able to talk in chat and to perform commands, including BungeeCord commands. -Session resume: If you have AuthMe on multiple servers, you can enable autoLogin option that allow you to switch between your servers without having to perform login command again. +**AutoLogin:** If you have AuthMe on multiple servers, you can enable autoLogin option that allow you to switch between your servers without having to perform login command again. + +## Support +- [GitHub issue tracker](https://github.com/AuthMe/AuthMeBungee/issues) +- [Spigot page](https://www.spigotmc.org/resources/authmebungee.50219/) +- [Discord](https://discord.gg/Vn9eCyE) ## Requirements -None +- Java 1.8+ +- BungeeCord/Waterfall/Travertine 1.7+ +- CraftBukkit/Spigot/Paper/Tacospigot 1.7.10+ ## Installation -1. Download AuthMeBridge package -2. Place BungeeAuthMeBridge.jar into your BungeeCord's plugin folder -3. Place AuthMeBridge.jar (or xAuthBridge.jar if you're using xAuth) into your servers' plugin folders +1. Download AuthMeBungee package +2. Place AuthMeBungee.jar into your BungeeCord's plugin folder 4. Restart everything -5. Configure the bungee-side plugin (don't forget to config serversList) -6. Enjoy! +5. Configure the plugin **(don't forget to config authServers)** +6. Enable the **Hooks.bungeecord** option in your **AuthMeReloaded config file** +7. Enjoy! **Please follow these steps and configure the plugin before saying it doesn't work!** diff --git a/authmebridge-authme/pom.xml b/authmebridge-authme/pom.xml deleted file mode 100644 index 8d4f48e..0000000 --- a/authmebridge-authme/pom.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - 4.0.0 - - - com.crylegend - authmebridge-parent - ${project.parent.version} - - - authmebridge-authme - jar - AuthMeBridge - - - ${project.name}-${project.version} - src/main/java - src/test/java - - - - . - false - ../ - - LICENSE - - - - . - true - src/main/resources/ - - * - - - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots - - - - - xephi-repo - http://ci.xephi.fr/plugin/repository/everything/ - - - - - - - org.bukkit - bukkit - ${bukkitVersion} - provided - true - - - junit - junit - - - json-simple - com.googlecode.json-simple - - - gson - com.google.code.gson - - - persistence-api - javax.persistence - - - commons-lang - commons-lang - - - snakeyaml - org.yaml - - - - - - - fr.xephi - authme - 5.2-SNAPSHOT - provided - true - - - diff --git a/authmebridge-authme/src/main/java/com/crylegend/authmebridge/AuthMeBridge.java b/authmebridge-authme/src/main/java/com/crylegend/authmebridge/AuthMeBridge.java deleted file mode 100644 index 99d04c4..0000000 --- a/authmebridge-authme/src/main/java/com/crylegend/authmebridge/AuthMeBridge.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.crylegend.authmebridge; - -import java.util.logging.Logger; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.plugin.messaging.PluginMessageListener; - -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteStreams; - -public class AuthMeBridge extends JavaPlugin implements PluginMessageListener { - Logger log = Logger.getLogger("Minecraft"); - String prefix = "[AuthMeBridge] "; - String incomingChannel = "BAuthMeBridge"; - String outgoingChannel = "AuthMeBridge"; - String autoLoginMessage = ChatColor.GREEN + "Your session has been resumed by the bridge."; - - public void onEnable() { - log.info(prefix + "Hello world"); - - if (!getServer().getPluginManager().isPluginEnabled("AuthMe")) { - log.info(prefix + "AuthMe not found, disabling"); - getServer().getPluginManager().disablePlugin(this); - } - - getServer().getPluginManager().registerEvents(new AuthMeBridgeListener(this), this); - getServer().getMessenger().registerIncomingPluginChannel(this, incomingChannel, this); - getServer().getMessenger().registerOutgoingPluginChannel(this, outgoingChannel); - - autoLoginMessage = getConfig().getString("autoLoginMessage", autoLoginMessage); - getConfig().set("autoLoginMessage", autoLoginMessage); - - saveConfig(); - } - - public void onDisable() { - log.info(prefix + "Goodbye world"); - } - - @Override - public void onPluginMessageReceived(String channel, Player p, byte[] message) { - if (channel.equals(incomingChannel)) { - ByteArrayDataInput in = ByteStreams.newDataInput(message); - String subchannel = in.readUTF(); - - if (subchannel.equals("AutoLogin")) { - Player player = Bukkit.getPlayer(in.readUTF()); - - if (player != null) { - if (!fr.xephi.authme.api.NewAPI.getInstance().isAuthenticated(player)) { - fr.xephi.authme.api.NewAPI.getInstance().forceLogin(player); - if (!autoLoginMessage.isEmpty()) - player.sendMessage(autoLoginMessage); - } - } - } - } - } -} diff --git a/authmebridge-authme/src/main/java/com/crylegend/authmebridge/AuthMeBridgeListener.java b/authmebridge-authme/src/main/java/com/crylegend/authmebridge/AuthMeBridgeListener.java deleted file mode 100644 index 3a3fd0a..0000000 --- a/authmebridge-authme/src/main/java/com/crylegend/authmebridge/AuthMeBridgeListener.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.crylegend.authmebridge; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; - -import fr.xephi.authme.events.LoginEvent; - -public class AuthMeBridgeListener implements Listener{ - AuthMeBridge plugin; - - public AuthMeBridgeListener(AuthMeBridge plugin) { - this.plugin = plugin; - } - - @EventHandler - public void onAuthMeLogin(LoginEvent event) { - if (event.getPlayer() == null) - return; - playerLogin(event.getPlayer()); - } - - @EventHandler - public void onAuthMeSession(PlayerJoinEvent event) { - final Player player = event.getPlayer(); - plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() { - public void run() { - if (fr.xephi.authme.api.NewAPI.getInstance().isAuthenticated(player)) - playerLogin(player); - } - }, 10L); - } - - public void playerLogin(Player player) { - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - try { - out.writeUTF("PlayerLogin"); - out.writeUTF(player.getName()); - new PluginMessageTask(plugin, player, b).runTaskAsynchronously(plugin); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/authmebridge-authme/src/main/java/com/crylegend/authmebridge/PluginMessageTask.java b/authmebridge-authme/src/main/java/com/crylegend/authmebridge/PluginMessageTask.java deleted file mode 100644 index ea42fb3..0000000 --- a/authmebridge-authme/src/main/java/com/crylegend/authmebridge/PluginMessageTask.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.crylegend.authmebridge; - -import java.io.ByteArrayOutputStream; - -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -public class PluginMessageTask extends BukkitRunnable { - private final AuthMeBridge plugin; - private final Player player; - private final ByteArrayOutputStream bytes; - - public PluginMessageTask(AuthMeBridge plugin, Player player, ByteArrayOutputStream bytes) - { - this.plugin = plugin; - this.player = player; - this.bytes = bytes; - } - - public void run() { - player.sendPluginMessage(plugin, plugin.outgoingChannel, bytes.toByteArray()); - } -} diff --git a/authmebridge-authme/src/main/resources/plugin.yml b/authmebridge-authme/src/main/resources/plugin.yml deleted file mode 100644 index 0437fe1..0000000 --- a/authmebridge-authme/src/main/resources/plugin.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: ${project.name} -main: com.crylegend.authmebridge.AuthMeBridge -version: ${project.version} -website: http://www.craftfriends.fr -author: CryLegend -description: The first AuthMe bungeecord addon -depend: [AuthMe] diff --git a/authmebridge-bungee/pom.xml b/authmebridge-bungee/pom.xml deleted file mode 100644 index 53e03ae..0000000 --- a/authmebridge-bungee/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - 4.0.0 - - - com.crylegend - authmebridge-parent - ${project.parent.version} - - - authmebridge-bungeecord - jar - BungeeAuthMeBridge - - - ${project.name}-${project.version} - src/main/java - src/test/java - - - - . - false - ../ - - LICENSE - - - - . - true - src/main/resources/ - - * - - - - - - - - - oss-repo - http://oss.sonatype.org/content/groups/public - - - - - - - net.md-5 - bungeecord-api - ${bungeeVersion} - provided - true - - - diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/BridgeAPI.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/BridgeAPI.java deleted file mode 100644 index 49ccc91..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/BridgeAPI.java +++ /dev/null @@ -1,29 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* BridgeAPI.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:30:37 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:30:40 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge; - -/* - * API class - acts like shortcuts - */ -public class BridgeAPI { - - private BridgeAPI() { } - - public static BungeeAuthMeBridge getPlugin() { - return BungeeAuthMeBridge.getInstance(); - } - - public static PlayersManager getPlayersManager() { - return BungeeAuthMeBridge.getInstance().getPlayersManager(); - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/BungeeAuthMeBridge.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/BungeeAuthMeBridge.java deleted file mode 100644 index c00e289..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/BungeeAuthMeBridge.java +++ /dev/null @@ -1,55 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* BungeeAuthMeBridge.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:30:49 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:30:50 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge; - -import com.crylegend.bungeeauthmebridge.config.Settings; -import com.crylegend.bungeeauthmebridge.listeners.*; - -import net.md_5.bungee.api.plugin.Plugin; - -/* - * Main class - */ -public class BungeeAuthMeBridge extends Plugin { - private static BungeeAuthMeBridge instance; - private PlayersManager playersManager; - - public static BungeeAuthMeBridge getInstance() { - return instance; - } - - public PlayersManager getPlayersManager() { - return playersManager; - } - - public void log(String message) { - getLogger().info(message); - } - - public void onLoad() { - instance = this; - } - - public void onEnable() { - // Registering channels to be able to communicate with bukkit-side - getProxy().registerChannel(Constants.incomingChannel); - getProxy().registerChannel(Constants.outgoingChannel); - - // Registering listeners - getProxy().getPluginManager().registerListener(this, new PlayerListener()); - getProxy().getPluginManager().registerListener(this, new ServerListener()); - - playersManager = new PlayersManager(); - new Settings(); - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/Constants.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/Constants.java deleted file mode 100644 index 8eff660..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/Constants.java +++ /dev/null @@ -1,28 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* Constants.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:30:53 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:30:54 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge; - -import java.util.Arrays; -import java.util.List; - -/* - * Plugin constants - */ -public class Constants { - public static String incomingChannel = "AuthMeBridge"; - public static String outgoingChannel = "BAuthMeBridge"; - public static List authMeCommands = Arrays.asList( - "/login", "/register", "/passpartu", "/l", "/reg", "/email", "/captcha"); - - private Constants() { } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/PlayersManager.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/PlayersManager.java deleted file mode 100644 index baa4244..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/PlayersManager.java +++ /dev/null @@ -1,46 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* PlayersManager.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:30:58 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:30:59 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge; - -import java.util.HashMap; - -import net.md_5.bungee.api.connection.ProxiedPlayer; - -import com.crylegend.bungeeauthmebridge.types.AuthPlayer; - -/* - * Players manager - store all references to AuthPlayer objects through an HashMap - */ -public class PlayersManager { - private HashMap players; - - public PlayersManager() { - players = new HashMap(); - } - - public void addPlayer(AuthPlayer player) { - players.put(player.getName(), player); - } - - public void removePlayer(String name) { - players.remove(name); - } - - public AuthPlayer getPlayer(ProxiedPlayer player) { - return getPlayer(player.getName()); - } - - public AuthPlayer getPlayer(String name) { - return players.get(name); - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/config/Settings.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/config/Settings.java deleted file mode 100644 index 2c6b82f..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/config/Settings.java +++ /dev/null @@ -1,61 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* Settings.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:31:11 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:31:13 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge.config; - -import net.md_5.bungee.config.Configuration; - -import java.util.ArrayList; -import java.util.List; - -import com.crylegend.bungeeauthmebridge.BridgeAPI; - -/* - * Settings class - from AuthMeBungee - * @authors Xephi, CryLegend - */ -public final class Settings { - protected YamlConfig configFile = null; - public static List commandsWhitelist = new ArrayList<>(); - public static List serversList = new ArrayList<>(); - public static boolean commandsRequiresAuth = true; - public static boolean chatRequiresAuth = true; - public static boolean serverSwitchRequiresAuth = false; - public static boolean autoLogin = true; - private Configuration config; - - public Settings() { - try { - this.configFile = new YamlConfig("config.yml", BridgeAPI.getPlugin()); - this.configFile.saveDefaultConfig(); - this.configFile.loadConfig(); - this.config = configFile.getConfig(); - loadConfigOptions(); - } - catch (Exception ex) { - ex.printStackTrace(); - } - } - - public void loadConfigOptions() { - if (configFile == null) { - return; - } - - commandsWhitelist = config.getStringList("commandsWhitelist"); - serversList = config.getStringList("serversList"); - commandsRequiresAuth = config.getBoolean("commandsRequiresAuth", true); - chatRequiresAuth = config.getBoolean("chatRequiresAuth", true); - serverSwitchRequiresAuth = config.getBoolean("serverSwitchRequiresAuth", false); - autoLogin = config.getBoolean("autoLogin", true); - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/config/YamlConfig.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/config/YamlConfig.java deleted file mode 100644 index cd82cf4..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/config/YamlConfig.java +++ /dev/null @@ -1,68 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* YamlConfig.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:31:17 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:31:18 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge.config; - -import java.io.File; -import java.io.IOException; -import java.nio.file.CopyOption; -import java.nio.file.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; - -/* - * YamlConfig class - from AuthMeBungee - * @author Xephi - */ -public class YamlConfig { - - private final File configFile; - private final String fileName; - private final Plugin plugin; - private final File folder; - private static Configuration config; - - public YamlConfig(String fileName, Plugin plugin) { - this.plugin = plugin; - this.fileName = fileName; - this.folder = plugin.getDataFolder(); - this.configFile = new File(this.folder, fileName); - } - - public void saveDefaultConfig() { - if (!this.folder.exists()) { - this.folder.mkdirs(); - } - try { - if (!this.configFile.exists()) { - Files.copy(this.plugin.getResourceAsStream(this.fileName), this.configFile.toPath(), new CopyOption[0]); - } - loadConfig(); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - - public void loadConfig() throws IOException { - config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(this.configFile); - } - - public void saveConfig() throws IOException { - ConfigurationProvider.getProvider(YamlConfiguration.class).save(config, this.configFile); - } - - public Configuration getConfig() { - return config; - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/listeners/PlayerListener.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/listeners/PlayerListener.java deleted file mode 100644 index 3e75737..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/listeners/PlayerListener.java +++ /dev/null @@ -1,134 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* PlayerListener.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:31:32 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:31:34 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge.listeners; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import com.crylegend.bungeeauthmebridge.BridgeAPI; -import com.crylegend.bungeeauthmebridge.Constants; -import com.crylegend.bungeeauthmebridge.config.Settings; -import com.crylegend.bungeeauthmebridge.types.AuthPlayer; -import com.crylegend.bungeeauthmebridge.utils.PluginMessageTask; - -import net.md_5.bungee.api.ChatColor; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.*; -import net.md_5.bungee.api.plugin.Listener; -import net.md_5.bungee.event.EventHandler; -import net.md_5.bungee.event.EventPriority; - -/* - * Player listener - listen to all actions that are related to players - */ -public class PlayerListener implements Listener { - - @EventHandler - public void onPlayerJoin(PostLoginEvent event) { - // Register player in our list - AuthPlayer player = new AuthPlayer(event.getPlayer().getName()); - BridgeAPI.getPlayersManager().addPlayer(player); - } - - @EventHandler - public void onPlayerLeave(PlayerDisconnectEvent event) { - // Remove player from out list - BridgeAPI.getPlayersManager().removePlayer(event.getPlayer().getName()); - } - - // Priority is set to lowest to keep compatibility with some chat plugins - @EventHandler(priority=EventPriority.LOWEST) - public void onChat(ChatEvent event) { - if (event.isCancelled()) - return; - - // Check if it's a player - if (!(event.getSender() instanceof ProxiedPlayer)) - return; - - if (event.isCommand()) { - String command = event.getMessage().split(" ")[0]; - - // Check if command is an AuthMe command - if (Constants.authMeCommands.contains(command)) - return; - - // Check if command is a whitelisted command - if (Settings.commandsWhitelist.contains(command)) - return; - } - - ProxiedPlayer proxiedPlayer = (ProxiedPlayer) event.getSender(); - AuthPlayer player = BridgeAPI.getPlayersManager().getPlayer(proxiedPlayer); - - // If player is not logged in, cancel the event - if (!player.isLoggedIn()) - event.setCancelled(true); - } - - @EventHandler - public void onServerSwitch(ServerSwitchEvent event) { - AuthPlayer player = BridgeAPI.getPlayersManager().getPlayer(event.getPlayer()); - - // Check if player exists (causing NPE, maybe the event is fired on player disconnect?) - if (player == null) - return; - - // Player is trying to switch server (also called on first server player connection) - if (player.isLoggedIn()) { - // If player is logged in and autoLogin is enabled, send login signal to the bukkit side - if (Settings.autoLogin) { - try { - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - - out.writeUTF("AutoLogin"); - - out.writeUTF(player.getName()); - - ProxyServer.getInstance().getScheduler().runAsync(BridgeAPI.getPlugin(), - new PluginMessageTask(event.getPlayer().getServer().getInfo(), b)); - } - catch (IOException e) { - e.printStackTrace(); - } - } - } - else { - // If player is not logged in and serverSwitchRequiresAuth is enabled, kick player - if (Settings.serverSwitchRequiresAuth) { - String server = event.getPlayer().getServer().getInfo().getName(); - - if (!Settings.serversList.contains(server)) { - TextComponent kickReason = new TextComponent("Authentication required."); - kickReason.setColor(ChatColor.RED); - event.getPlayer().disconnect(kickReason); - } - } - } - } - - // I don't remember what it stood for, but I put it again "just in case" - @SuppressWarnings("deprecation") - @EventHandler - public void onPlayerKick(ServerKickEvent event) { - if (event.isCancelled()) - return; - - if (event.getKickReason().equals("You logged in from another location")) - event.setCancelled(true); - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/listeners/ServerListener.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/listeners/ServerListener.java deleted file mode 100644 index 89a5963..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/listeners/ServerListener.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ServerListener.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:31:36 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:31:37 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge.listeners; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import com.crylegend.bungeeauthmebridge.BridgeAPI; -import com.crylegend.bungeeauthmebridge.Constants; -import com.crylegend.bungeeauthmebridge.types.AuthPlayer; - -import net.md_5.bungee.api.connection.Server; -import net.md_5.bungee.api.event.PluginMessageEvent; -import net.md_5.bungee.api.plugin.Listener; -import net.md_5.bungee.event.EventHandler; - -/* - * Server listener - listen to all actions that are related to server, especially plugin messages - */ -public class ServerListener implements Listener { - - @EventHandler - public void onPluginMessage(PluginMessageEvent event) { - if (event.isCancelled()) - return; - - // Check if the message is for us - if (!event.getTag().equalsIgnoreCase(Constants.incomingChannel)) - return; - - // Check if a player is not trying to rip us off sending a fake message - if (!(event.getSender() instanceof Server)) - return; - - // Now that's sure, it's for us, so let's go - event.setCancelled(true); - - try { - // Read the plugin message - DataInputStream in = new DataInputStream(new ByteArrayInputStream(event.getData())); - - // For now that's the only type of message the server is able to receive - String task = in.readUTF(); - if (!task.equals("PlayerLogin")) - return; - - // Gather informations from the plugin message - String name = in.readUTF(); - AuthPlayer player = BridgeAPI.getPlayersManager().getPlayer(name); - - // Set the player status to logged in - player.setLoggedIn(); - } - catch (IOException ex) { - // Something nasty happened - ex.printStackTrace(); - } - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/types/AuthPlayer.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/types/AuthPlayer.java deleted file mode 100644 index 37f3ffe..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/types/AuthPlayer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* AuthPlayer.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:31:50 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:31:52 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge.types; - -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ProxiedPlayer; - -/* - * Auth player - contains name and login status of a player - */ -public class AuthPlayer { - private String name; - private boolean isLoggedIn; - - public AuthPlayer(String name) { - this.name = name; - isLoggedIn = false; - } - - public String getName() { - return name; - } - - public boolean isLoggedIn() { - return isLoggedIn; - } - - public void setLoggedIn() { - isLoggedIn = true; - } - - public boolean isOnline() { - return getProxiedPlayer() != null; - } - - public ProxiedPlayer getProxiedPlayer() { - return ProxyServer.getInstance().getPlayer(name); - } -} diff --git a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/utils/PluginMessageTask.java b/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/utils/PluginMessageTask.java deleted file mode 100644 index 76357e6..0000000 --- a/authmebridge-bungee/src/main/java/com/crylegend/bungeeauthmebridge/utils/PluginMessageTask.java +++ /dev/null @@ -1,36 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* PluginMessageTask.java :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: CryLegend +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2016/03/25 18:31:59 by CryLegend #+# #+# */ -/* Updated: 2016/03/25 18:32:00 by CryLegend ### ########.fr */ -/* */ -/* ************************************************************************** */ - -package com.crylegend.bungeeauthmebridge.utils; - -import java.io.ByteArrayOutputStream; - -import com.crylegend.bungeeauthmebridge.Constants; - -import net.md_5.bungee.api.config.ServerInfo; - -/* - * Plugin message task - used to send plugin messages to bukkit-side - */ -public class PluginMessageTask implements Runnable { - private final ByteArrayOutputStream bytes; - private final ServerInfo server; - - public PluginMessageTask(ServerInfo server, ByteArrayOutputStream bytes) { - this.bytes = bytes; - this.server = server; - } - - public void run() { - server.sendData(Constants.outgoingChannel, bytes.toByteArray()); - } -} diff --git a/authmebridge-bungee/src/main/resources/config.yml b/authmebridge-bungee/src/main/resources/config.yml deleted file mode 100644 index 46ef88f..0000000 --- a/authmebridge-bungee/src/main/resources/config.yml +++ /dev/null @@ -1,15 +0,0 @@ -# List of servers which required to be authenticated -serversList: - - lobby -# Allows or not commands to be performed if user is not logged in -commandsRequiresAuth: true -# List of commands allowed to be perform without being authenticated -commandsWhitelist: - - /glist -# Allows or not user to talk in chat if he is not logged in -chatRequiresAuth: true -# Kick all players who switch servers without being authenticated (eg. plugin teleport) -# Do not set this option to true unless you know what you're doing! -serverSwitchRequiresAuth: false -# Enable session resume between servers (eg. autologin if you change server) -autoLogin: true \ No newline at end of file diff --git a/authmebridge-bungee/src/main/resources/plugin.yml b/authmebridge-bungee/src/main/resources/plugin.yml deleted file mode 100644 index 3b307c5..0000000 --- a/authmebridge-bungee/src/main/resources/plugin.yml +++ /dev/null @@ -1,4 +0,0 @@ -name: ${project.name} -main: com.crylegend.bungeeauthmebridge.BungeeAuthMeBridge -version: ${project.version} -author: CryLegend \ No newline at end of file diff --git a/authmebridge-xauth/pom.xml b/authmebridge-xauth/pom.xml deleted file mode 100644 index 0752731..0000000 --- a/authmebridge-xauth/pom.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - 4.0.0 - - - com.crylegend - authmebridge-parent - ${project.parent.version} - - - authmebridge-xauth - jar - xAuthBridge - - - ${project.name}-${project.version} - src/main/java - src/test/java - - - - . - false - ../ - - LICENSE - - - - . - true - src/main/resources/ - - * - - - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots - - - - - luricos-releases - http://repo.luricos.de/content/repositories/releases - - - - - - - org.bukkit - bukkit - ${bukkitVersion} - provided - true - - - junit - junit - - - json-simple - com.googlecode.json-simple - - - gson - com.google.code.gson - - - persistence-api - javax.persistence - - - commons-lang - commons-lang - - - snakeyaml - org.yaml - - - - - - - de.luricos.bukkit - xAuth - 2.6 - provided - - - org.bukkit - bukkit - - - org.bukkit - craftbukkit - - - updater - net.gravitydevelopment.updater - - - lombok - org.projectlombok - - - EssentialsGroupManager - net.ess3 - - - PermissionsEx - ru.tehkode - - - AccountsClient - com.mojang - - - log4j-core - org.apache.logging.log4j - - - true - - - diff --git a/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/PluginMessageTask.java b/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/PluginMessageTask.java deleted file mode 100644 index 55347f4..0000000 --- a/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/PluginMessageTask.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.crylegend.xauthbridge; - -import java.io.ByteArrayOutputStream; - -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -public class PluginMessageTask extends BukkitRunnable { - private final xAuthBridge plugin; - private final Player player; - private final ByteArrayOutputStream bytes; - - public PluginMessageTask(xAuthBridge plugin, Player player, ByteArrayOutputStream bytes) - { - this.plugin = plugin; - this.player = player; - this.bytes = bytes; - } - - public void run() { - player.sendPluginMessage(plugin, plugin.outgoingChannel, bytes.toByteArray()); - } -} diff --git a/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/xAuthBridge.java b/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/xAuthBridge.java deleted file mode 100644 index 29dd52a..0000000 --- a/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/xAuthBridge.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.crylegend.xauthbridge; - -import java.util.logging.Logger; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.plugin.messaging.PluginMessageListener; - -import com.google.common.io.ByteArrayDataInput; -import com.google.common.io.ByteStreams; - -import de.luricos.bukkit.xAuth.xAuth; - -public class xAuthBridge extends JavaPlugin implements PluginMessageListener { - Logger log = Logger.getLogger("Minecraft"); - String prefix = "[xAuthBridge] "; - String incomingChannel = "BAuthMeBridge"; - String outgoingChannel = "AuthMeBridge"; - String autoLoginMessage = ChatColor.GREEN + "Your session has been resumed by the bridge."; - xAuth xauth; - - public void onEnable() { - log.info(prefix + "Hello world"); - - if (!getServer().getPluginManager().isPluginEnabled("xAuth")) { - log.info(prefix + "xAuth not found, disabling"); - getServer().getPluginManager().disablePlugin(this); - } - - xauth = (xAuth) getServer().getPluginManager().getPlugin("xAuth"); - - getServer().getPluginManager().registerEvents(new xAuthBridgeListener(this), this); - getServer().getMessenger().registerIncomingPluginChannel(this, incomingChannel, this); - getServer().getMessenger().registerOutgoingPluginChannel(this, outgoingChannel); - - autoLoginMessage = getConfig().getString("autoLoginMessage", autoLoginMessage); - getConfig().set("autoLoginMessage", autoLoginMessage); - - saveConfig(); - } - - public void onDisable() { - log.info(prefix + "Goodbye world"); - } - - @Override - public void onPluginMessageReceived(String channel, Player p, byte[] message) { - if (channel.equals(incomingChannel)) { - ByteArrayDataInput in = ByteStreams.newDataInput(message); - String subchannel = in.readUTF(); - - if (subchannel.equals("AutoLogin")) { - Player player = Bukkit.getPlayer(in.readUTF()); - - if (player != null) { - if (!xauth.getPlayerManager().getPlayer(player.getName()).isAuthenticated()) { - xauth.getPlayerManager().doLogin(xauth.getPlayerManager().getPlayer(player)); - if (!autoLoginMessage.isEmpty()) - player.sendMessage(autoLoginMessage); - } - } - } - } - } -} diff --git a/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/xAuthBridgeListener.java b/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/xAuthBridgeListener.java deleted file mode 100644 index 4afaaad..0000000 --- a/authmebridge-xauth/src/main/java/com/crylegend/xauthbridge/xAuthBridgeListener.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.crylegend.xauthbridge; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerJoinEvent; - -public class xAuthBridgeListener implements Listener{ - xAuthBridge plugin; - - public xAuthBridgeListener(xAuthBridge plugin) { - this.plugin = plugin; - } - - @EventHandler - public void onxAuthSession(PlayerJoinEvent event) { - final Player player = event.getPlayer(); - plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() { - public void run() { - playerLogin(player); - } - }, 10L); - } - - @EventHandler - public void onxAuthLogin(PlayerCommandPreprocessEvent event) { - if (event.isCancelled()) - return; - String cmd = event.getMessage().split(" ")[0]; - if (!cmd.equalsIgnoreCase("/register") && !cmd.equalsIgnoreCase("/login")) - return; - final Player player = event.getPlayer(); - plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() { - public void run() { - playerLogin(player); - } - }, 10L); - } - - public void playerLogin(Player player) { - if (!plugin.xauth.getPlayerManager().getPlayer(player.getName()).isAuthenticated()) - return; - ByteArrayOutputStream b = new ByteArrayOutputStream(); - DataOutputStream out = new DataOutputStream(b); - try { - out.writeUTF("PlayerLogin"); - out.writeUTF(player.getName()); - new PluginMessageTask(plugin, player, b).runTaskAsynchronously(plugin); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} diff --git a/authmebridge-xauth/src/main/resources/plugin.yml b/authmebridge-xauth/src/main/resources/plugin.yml deleted file mode 100644 index 3348e22..0000000 --- a/authmebridge-xauth/src/main/resources/plugin.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: ${project.name} -main: com.crylegend.xauthbridge.xAuthBridge -version: ${project.version} -website: http://www.craftfriends.fr -author: CryLegend -description: The first xAuth bungeecord addon -depend: [xAuth] \ No newline at end of file diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 021dcae..0000000 --- a/circle.yml +++ /dev/null @@ -1,14 +0,0 @@ -machine: - java: - version: oraclejdk7 -general: - artifacts: - - "target/AuthMeBridge*.jar" -test: - override: - - mvn clean install -B - post: - - cp ./target/AuthMeBridge*.jar $CIRCLE_ARTIFACTS -notify: - webhooks: - - url: https://webhooks.gitter.im/e/7b92ac1a1741748b26bf diff --git a/pom.xml b/pom.xml index e44b7b8..d120ea1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,37 +4,47 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.crylegend - authmebridge-parent - 1.6.1 - pom + fr.xephi + authmebungee + 2.2.0-SNAPSHOT - AuthMeBridge - Bungeecord addon for AuthMe and xAuth! - 2014 - https://www.spigotmc.org/resources/authmebridge-for-bungeecord.574/ + AuthMeBungee + Bungeecord addon for AuthMe! + 2017 + https://www.spigotmc.org/resources/authmebungee.50219/ AuthMe-Team - https://github.com/AuthMe-Team + https://github.com/AuthMe - scm:git:https://github.com/AuthMe-Team/AuthMeBridge.git - scm:git:git@github.com:Xephi/AuthMe-Team/AuthMeBridge.git - https://github.com/AuthMe-Team/AuthMeBridge.git + scm:git:https://github.com/AuthMe/AuthMeBungee.git + scm:git:git@github.com:AuthMe/AuthMeBungee.git + https://github.com/AuthMe/AuthMeBungee.git jenkins - http://ci.xephi.fr/job/AuthMeBridge/ + http://ci.codemc.org/job/AuthMeBungee/ GitHub - https://github.com/CryLegend/AuthMeBridge/issues + https://github.com/AuthMe/AuthMeBungee/issues + + + codemc-snapshots + https://repo.codemc.org/repository/maven-snapshots/ + + + codemc-releases + https://repo.codemc.org/repository/maven-releases/ + + + The GNU General Public Licence version 3 (GPLv3) @@ -42,39 +52,229 @@ - - 3.3.3 - - - UTF-8 - ${projectEncoding} - ${projectEncoding} - 1.7 - - 1.9-R0.1-SNAPSHOT - 1.9-SNAPSHOT + UTF-8 + UTF-8 - - authmebridge-bungee - authmebridge-authme - authmebridge-xauth - - + clean install + ${project.name}-${project.version}-noshade + + + false + . + + LICENSE + + + + true + src/main/resources + + - + + org.apache.maven.plugins + maven-clean-plugin + 3.2.0 + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + 3.11.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.0 + + false + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.5.0 + + + attach-javadoc + + jar + + + - ${jdkVersion} - ${jdkVersion} + ${project.name}-${project.version} + public + false + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar + + + + + ${project.name}-${project.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + false + true + ${project.name}-${project.version} + + + javax.annotation + fr.xephi.authmebungee.libs.javax.annotation + + + javax.inject + fr.xephi.authmebungee.libs.javax.inject + + + ch.jalu.injector + fr.xephi.authmebungee.libs.jalu.injector + + + org.yaml.snakeyaml + fr.xephi.authmebungee.libs.yaml.snakeyaml + + + ch.jalu.configme + fr.xephi.authmebungee.libs.jalu.configme + + + org.bstats + fr.xephi.authmebungee.libs.org.bstats + + + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.RSA + META-INF/*.MF + META-INF/DEPENDENCIES + META-INF/**/module-info.class + + + + + + + + false + + + + + + + org.apache.maven.plugins + maven-install-plugin + 3.1.1 + + + org.apache.maven.plugins + maven-deploy-plugin + 3.1.1 + + + + + + oss-repo + https://oss.sonatype.org/content/groups/public + + + + codemc-repo + https://repo.codemc.org/repository/maven-public/ + + + + + + + ch.jalu + injector + 1.0 + compile + + + + + ch.jalu + configme + 1.3.0 + compile + + + + + net.md-5 + bungeecord-api + 1.19-R0.1-SNAPSHOT + jar + provided + + + net.md-5 + bungeecord-api + 1.19-R0.1-SNAPSHOT + javadoc + provided + + + + + org.bstats + bstats-bungeecord + 3.0.2 + compile + + diff --git a/src/main/java/fr/xephi/authmebungee/AuthMeBungee.java b/src/main/java/fr/xephi/authmebungee/AuthMeBungee.java new file mode 100644 index 0000000..9b7ed47 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/AuthMeBungee.java @@ -0,0 +1,75 @@ +package fr.xephi.authmebungee; + +import ch.jalu.configme.SettingsManager; +import ch.jalu.injector.Injector; +import ch.jalu.injector.InjectorBuilder; +import fr.xephi.authmebungee.annotations.DataFolder; +import fr.xephi.authmebungee.commands.BungeeReloadCommand; +import fr.xephi.authmebungee.config.BungeeConfigProperties; +import fr.xephi.authmebungee.config.BungeeSettingsProvider; +import fr.xephi.authmebungee.listeners.BungeeMessageListener; +import fr.xephi.authmebungee.listeners.BungeePlayerListener; +import fr.xephi.authmebungee.services.AuthPlayerManager; +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.api.plugin.PluginManager; +import net.md_5.bungee.api.scheduler.TaskScheduler; +import org.bstats.bungeecord.Metrics; + +import java.util.logging.Logger; + +public class AuthMeBungee extends Plugin { + + // Instances + private Injector injector; + private SettingsManager settings; + private AuthPlayerManager authPlayerManager; + + public AuthMeBungee() { + } + + @Override + public void onEnable() { + // Prepare the injector and register stuff + setupInjector(); + + // Get singletons from the injector + settings = injector.getSingleton(SettingsManager.class); + authPlayerManager = injector.getSingleton(AuthPlayerManager.class); + + // Print some config information + getLogger().info("Current auth servers:"); + for (String authServer : settings.getProperty(BungeeConfigProperties.AUTH_SERVERS)) { + getLogger().info("> " + authServer.toLowerCase()); + } + + // Add online players (plugin hotswap, just in case) + for (ProxiedPlayer player : getProxy().getPlayers()) { + authPlayerManager.addAuthPlayer(player); + } + + // Register commands + getProxy().getPluginManager().registerCommand(this, injector.getSingleton(BungeeReloadCommand.class)); + + // Registering event listeners + getProxy().getPluginManager().registerListener(this, injector.getSingleton(BungeeMessageListener.class)); + getProxy().getPluginManager().registerListener(this, injector.getSingleton(BungeePlayerListener.class)); + + // Send metrics data + new Metrics(this, 1880); + } + + private void setupInjector() { + // Setup injector + injector = new InjectorBuilder().addDefaultHandlers("").create(); + injector.register(Logger.class, getLogger()); + injector.register(AuthMeBungee.class, this); + injector.register(ProxyServer.class, getProxy()); + injector.register(PluginManager.class, getProxy().getPluginManager()); + injector.register(TaskScheduler.class, getProxy().getScheduler()); + injector.provide(DataFolder.class, getDataFolder()); + injector.registerProvider(SettingsManager.class, BungeeSettingsProvider.class); + } + +} diff --git a/src/main/java/fr/xephi/authmebungee/annotations/DataFolder.java b/src/main/java/fr/xephi/authmebungee/annotations/DataFolder.java new file mode 100644 index 0000000..69fb6b2 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/annotations/DataFolder.java @@ -0,0 +1,14 @@ +package fr.xephi.authmebungee.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for specifying the plugin's data folder. + */ +@Target({ElementType.PARAMETER, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DataFolder { +} diff --git a/src/main/java/fr/xephi/authmebungee/commands/BungeeReloadCommand.java b/src/main/java/fr/xephi/authmebungee/commands/BungeeReloadCommand.java new file mode 100644 index 0000000..bfd42a7 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/commands/BungeeReloadCommand.java @@ -0,0 +1,33 @@ +package fr.xephi.authmebungee.commands; + +import ch.jalu.configme.SettingsManager; +import ch.jalu.injector.factory.SingletonStore; +import fr.xephi.authmebungee.config.SettingsDependent; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.plugin.Command; + +import javax.inject.Inject; + +public class BungeeReloadCommand extends Command { + + private SettingsManager settings; + private SingletonStore settingsDependentStore; + + @Inject + public BungeeReloadCommand(SettingsManager settings, SingletonStore settingsDependentStore) { + super("abreloadproxy", "authmebungee.reload"); + this.settings = settings; + this.settingsDependentStore = settingsDependentStore; + } + + @Override + public void execute(CommandSender commandSender, String[] strings) { + settings.reload(); + settingsDependentStore.retrieveAllOfType().forEach(settingsDependent -> settingsDependent.reload(settings)); + commandSender.sendMessage( + new ComponentBuilder("AuthMeBungee configuration reloaded!").color(ChatColor.GREEN).create() + ); + } +} diff --git a/src/main/java/fr/xephi/authmebungee/config/BungeeConfigProperties.java b/src/main/java/fr/xephi/authmebungee/config/BungeeConfigProperties.java new file mode 100644 index 0000000..600d447 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/config/BungeeConfigProperties.java @@ -0,0 +1,47 @@ +package fr.xephi.authmebungee.config; + +import ch.jalu.configme.Comment; +import ch.jalu.configme.SettingsHolder; +import ch.jalu.configme.properties.Property; + +import java.util.List; + +import static ch.jalu.configme.properties.PropertyInitializer.newListProperty; +import static ch.jalu.configme.properties.PropertyInitializer.newProperty; + +public class BungeeConfigProperties implements SettingsHolder { + + @Comment("List of servers in the network where authme is installed") + public static final Property> AUTH_SERVERS = + newListProperty("authServers", "lobby"); + @Comment("Consider every server as an auth server") + public static final Property ALL_SERVERS_ARE_AUTH_SERVERS = + newProperty("allServersAreAuthServers", false); + @Comment("Allows or not commands to be performed if user is not logged in") + public static final Property COMMANDS_REQUIRE_AUTH = + newProperty("commands.requireAuth", true); + @Comment("List of commands allowed to be perform without being authenticated") + public static final Property> COMMANDS_WHITELIST = + newListProperty("commands.whitelist", "/login", "/register", "/l", "/reg", "/email", "/captcha", "/2fa", "/totp", "/log"); + @Comment("Allows or not user to talk in chat if he is not logged in") + public static final Property CHAT_REQUIRES_AUTH = + newProperty("chatRequiresAuth", true); + @Comment("Kick all players who switch servers without being authenticated (eg. plugin teleport)") + public static final Property SERVER_SWITCH_REQUIRES_AUTH = + newProperty("serverSwitch.requiresAuth", true); + public static final Property SERVER_SWITCH_KICK_MESSAGE = + newProperty("serverSwitch.kickMessage", "Authentication required."); + @Comment("Enable auto-login between servers") + public static final Property AUTOLOGIN = + newProperty("autoLogin", false); + @Comment("If enabled, unlogged users will be sent to the unloggedUserServer server!") + public static final Property ENABLE_SEND_ON_LOGOUT = + newProperty("sendOnLogout", false); + @Comment("If sendOnLogout is enabled, unlogged users will be sent to this server!") + public static final Property SEND_ON_LOGOUT_TARGET = + newProperty("unloggedUserServer", ""); + + private BungeeConfigProperties() { + } + +} diff --git a/src/main/java/fr/xephi/authmebungee/config/BungeeSettingsProvider.java b/src/main/java/fr/xephi/authmebungee/config/BungeeSettingsProvider.java new file mode 100644 index 0000000..03d5931 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/config/BungeeSettingsProvider.java @@ -0,0 +1,15 @@ +package fr.xephi.authmebungee.config; + +import fr.xephi.authmebungee.annotations.DataFolder; + +import javax.inject.Inject; +import java.io.File; + +public class BungeeSettingsProvider extends SettingsProvider { + + @Inject + public BungeeSettingsProvider(@DataFolder File dataFolder) { + super(dataFolder, BungeeConfigProperties.class); + } + +} diff --git a/src/main/java/fr/xephi/authmebungee/config/SettingsDependent.java b/src/main/java/fr/xephi/authmebungee/config/SettingsDependent.java new file mode 100644 index 0000000..a038f7a --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/config/SettingsDependent.java @@ -0,0 +1,17 @@ +package fr.xephi.authmebungee.config; + +import ch.jalu.configme.SettingsManager; + +/** + * Interface for classes that keep a local copy of certain settings. + */ +public interface SettingsDependent { + + /** + * Performs a reload with the provided settings instance. + * + * @param settings the settings instance + */ + void reload(SettingsManager settings); + +} diff --git a/src/main/java/fr/xephi/authmebungee/config/SettingsProvider.java b/src/main/java/fr/xephi/authmebungee/config/SettingsProvider.java new file mode 100644 index 0000000..f9b5dee --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/config/SettingsProvider.java @@ -0,0 +1,37 @@ +package fr.xephi.authmebungee.config; + +import ch.jalu.configme.SettingsHolder; +import ch.jalu.configme.SettingsManager; +import ch.jalu.configme.SettingsManagerBuilder; + +import javax.inject.Provider; +import java.io.File; + +/** + * Initializes the settings. + */ +public abstract class SettingsProvider implements Provider { + + private File dataFolder; + + private Class properties; + + protected SettingsProvider(File dataFolder, Class properties) { + this.dataFolder = dataFolder; + this.properties = properties; + } + + /** + * Loads the plugin's settings. + * + * @return the settings instance, or null if it could not be constructed + */ + @Override + public SettingsManager get() { + File configFile = new File(dataFolder, "config.yml"); + return SettingsManagerBuilder.withYamlFile(configFile) + .useDefaultMigrationService() + .configurationData(properties) + .create(); + } +} diff --git a/src/main/java/fr/xephi/authmebungee/data/AuthPlayer.java b/src/main/java/fr/xephi/authmebungee/data/AuthPlayer.java new file mode 100644 index 0000000..1eb6680 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/data/AuthPlayer.java @@ -0,0 +1,45 @@ +package fr.xephi.authmebungee.data; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public class AuthPlayer { + + private String name; + private boolean isLogged; + + public AuthPlayer(String name, boolean isLogged) { + this.name = name.toLowerCase(); + this.isLogged = isLogged; + } + + public AuthPlayer(String name) { + this(name, false); + } + + public String getName() { + return name; + } + + public boolean isLogged() { + return isLogged; + } + + public void setLogged(boolean isLogged) { + this.isLogged = isLogged; + } + + public ProxiedPlayer getPlayer() { + for (ProxiedPlayer current : ProxyServer.getInstance().getPlayers()) { + if (current.getName().equalsIgnoreCase(name)) { + return current; + } + } + return null; + } + + public boolean isOnline() { + return getPlayer() != null; + } + +} diff --git a/src/main/java/fr/xephi/authmebungee/listeners/BungeeMessageListener.java b/src/main/java/fr/xephi/authmebungee/listeners/BungeeMessageListener.java new file mode 100644 index 0000000..a0322cf --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/listeners/BungeeMessageListener.java @@ -0,0 +1,110 @@ +package fr.xephi.authmebungee.listeners; + +import ch.jalu.configme.SettingsManager; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; +import fr.xephi.authmebungee.config.BungeeConfigProperties; +import fr.xephi.authmebungee.config.SettingsDependent; +import fr.xephi.authmebungee.data.AuthPlayer; +import fr.xephi.authmebungee.services.AuthPlayerManager; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.connection.Server; +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; + +import javax.inject.Inject; + +public class BungeeMessageListener implements Listener, SettingsDependent { + + // Services + private final AuthPlayerManager authPlayerManager; + + // Settings + private boolean isSendOnLogoutEnabled; + private String sendOnLogoutTarget; + + @Inject + public BungeeMessageListener(final SettingsManager settings, final AuthPlayerManager authPlayerManager) { + this.authPlayerManager = authPlayerManager; + reload(settings); + } + + @Override + public void reload(final SettingsManager settings) { + isSendOnLogoutEnabled = settings.getProperty(BungeeConfigProperties.ENABLE_SEND_ON_LOGOUT); + sendOnLogoutTarget = settings.getProperty(BungeeConfigProperties.SEND_ON_LOGOUT_TARGET); + } + + @EventHandler + public void onPluginMessage(final PluginMessageEvent event) { + if (event.isCancelled()) { + return; + } + + // Check if the message is for a server (ignore client messages) + if (!event.getTag().equals("BungeeCord")) { + return; + } + + // Check if a player is not trying to send us a fake message + if (!(event.getSender() instanceof Server)) { + return; + } + + // Read the plugin message + final ByteArrayDataInput in = ByteStreams.newDataInput(event.getData()); + + // Accept only broadcasts + if(!in.readUTF().equals("Forward")) { + return; + } + in.readUTF(); // Skip ONLINE/ALL parameter + + // Let's check the subchannel + if (!in.readUTF().equals("AuthMe.v2.Broadcast")) { + return; + } + + // Read data byte array + final short dataLength = in.readShort(); + final byte[] dataBytes = new byte[dataLength]; + in.readFully(dataBytes); + final ByteArrayDataInput dataIn = ByteStreams.newDataInput(dataBytes); + + // For now that's the only type of message the server is able to receive + final String type = dataIn.readUTF(); + switch (type) { + case "login": + handleOnLogin(dataIn); + break; + case "logout": + handleOnLogout(dataIn); + break; + } + } + + private void handleOnLogin(final ByteArrayDataInput in) { + final String name = in.readUTF(); + final AuthPlayer authPlayer = authPlayerManager.getAuthPlayer(name); + if (authPlayer != null) { + authPlayer.setLogged(true); + } + } + + private void handleOnLogout(final ByteArrayDataInput in) { + final String name = in.readUTF(); + final AuthPlayer authPlayer = authPlayerManager.getAuthPlayer(name); + if (authPlayer != null) { + authPlayer.setLogged(false); + if (isSendOnLogoutEnabled) { + final ProxiedPlayer player = authPlayer.getPlayer(); + if (player != null) { + player.connect(ProxyServer.getInstance().getServerInfo(sendOnLogoutTarget)); + } + } + } + } + +} diff --git a/src/main/java/fr/xephi/authmebungee/listeners/BungeePlayerListener.java b/src/main/java/fr/xephi/authmebungee/listeners/BungeePlayerListener.java new file mode 100644 index 0000000..b2aae2e --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/listeners/BungeePlayerListener.java @@ -0,0 +1,189 @@ +package fr.xephi.authmebungee.listeners; + +import ch.jalu.configme.SettingsManager; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import fr.xephi.authmebungee.config.BungeeConfigProperties; +import fr.xephi.authmebungee.config.SettingsDependent; +import fr.xephi.authmebungee.data.AuthPlayer; +import fr.xephi.authmebungee.services.AuthPlayerManager; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.config.ServerInfo; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.*; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.event.EventPriority; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +public class BungeePlayerListener implements Listener, SettingsDependent { + + // Services + private final AuthPlayerManager authPlayerManager; + + // Settings + private boolean isAutoLoginEnabled; + private boolean isServerSwitchRequiresAuth; + private String requiresAuthKickMessage; + private List authServers; + private boolean allServersAreAuthServers; + private boolean isCommandsRequireAuth; + private List commandWhitelist; + private boolean chatRequiresAuth; + + @Inject + public BungeePlayerListener(final SettingsManager settings, final AuthPlayerManager authPlayerManager) { + this.authPlayerManager = authPlayerManager; + reload(settings); + } + + @Override + public void reload(final SettingsManager settings) { + isAutoLoginEnabled = settings.getProperty(BungeeConfigProperties.AUTOLOGIN); + isServerSwitchRequiresAuth = settings.getProperty(BungeeConfigProperties.SERVER_SWITCH_REQUIRES_AUTH); + requiresAuthKickMessage = settings.getProperty(BungeeConfigProperties.SERVER_SWITCH_KICK_MESSAGE); + authServers = new ArrayList<>(); + for (final String server : settings.getProperty(BungeeConfigProperties.AUTH_SERVERS)) { + authServers.add(server.toLowerCase()); + } + allServersAreAuthServers = settings.getProperty(BungeeConfigProperties.ALL_SERVERS_ARE_AUTH_SERVERS); + isCommandsRequireAuth = settings.getProperty(BungeeConfigProperties.COMMANDS_REQUIRE_AUTH); + commandWhitelist = new ArrayList<>(); + for (final String command : settings.getProperty(BungeeConfigProperties.COMMANDS_WHITELIST)) { + commandWhitelist.add(command.toLowerCase()); + } + chatRequiresAuth = settings.getProperty(BungeeConfigProperties.CHAT_REQUIRES_AUTH); + } + + @EventHandler + public void onPlayerJoin(final PostLoginEvent event) { + // Register player in our list + authPlayerManager.addAuthPlayer(event.getPlayer()); + } + + @EventHandler + public void onPlayerDisconnect(final PlayerDisconnectEvent event) { + // Remove player from out list + authPlayerManager.removeAuthPlayer(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onCommand(final ChatEvent event) { + if (event.isCancelled() || !event.isCommand() || !isCommandsRequireAuth) { + return; + } + + // Check if it's a player + if (!(event.getSender() instanceof ProxiedPlayer)) { + return; + } + final ProxiedPlayer player = (ProxiedPlayer) event.getSender(); + + // Filter only unauthenticated players + final AuthPlayer authPlayer = authPlayerManager.getAuthPlayer(player); + if (authPlayer != null && authPlayer.isLogged()) { + return; + } + // Only in auth servers + if (!isAuthServer(player.getServer().getInfo())) { + return; + } + // Check if command is whitelisted command + if (commandWhitelist.contains(event.getMessage().split(" ")[0].toLowerCase())) { + return; + } + event.setCancelled(true); + } + + // Priority is set to lowest to keep compatibility with some chat plugins + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerChat(final ChatEvent event) { + if (event.isCancelled() || event.isCommand()) { + return; + } + + // Check if it's a player + if (!(event.getSender() instanceof ProxiedPlayer)) { + return; + } + final ProxiedPlayer player = (ProxiedPlayer) event.getSender(); + + // Filter only unauthenticated players + final AuthPlayer authPlayer = authPlayerManager.getAuthPlayer(player); + if (authPlayer != null && authPlayer.isLogged()) { + return; + } + // Only in auth servers + if (!isAuthServer(player.getServer().getInfo())) { + return; + } + + if (!chatRequiresAuth) { + return; + } + event.setCancelled(true); + } + + private boolean isAuthServer(ServerInfo serverInfo) { + return allServersAreAuthServers || authServers.contains(serverInfo.getName().toLowerCase()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerConnectedToServer(final ServerSwitchEvent event) { + final ProxiedPlayer player = event.getPlayer(); + final ServerInfo server = player.getServer().getInfo(); + final AuthPlayer authPlayer = authPlayerManager.getAuthPlayer(player); + final boolean isAuthenticated = authPlayer != null && authPlayer.isLogged(); + + if (isAuthenticated && isAuthServer(server)) { + // If AutoLogin enabled, notify the server + if (isAutoLoginEnabled) { + final ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("AuthMe.v2"); + out.writeUTF("perform.login"); + out.writeUTF(event.getPlayer().getName()); + server.sendData("BungeeCord", out.toByteArray(), false); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerConnectingToServer(final ServerConnectEvent event) { + if (event.isCancelled()) { + return; + } + + final ProxiedPlayer player = event.getPlayer(); + final AuthPlayer authPlayer = authPlayerManager.getAuthPlayer(player); + final boolean isAuthenticated = authPlayer != null && authPlayer.isLogged(); + + // Skip logged users + if (isAuthenticated) { + return; + } + + // Only check non auth servers + if (isAuthServer(event.getTarget())) { + return; + } + + // If the player is not logged in and serverSwitchRequiresAuth is enabled, cancel the connection + if (isServerSwitchRequiresAuth) { + event.setCancelled(true); + + final TextComponent reasonMessage = new TextComponent(requiresAuthKickMessage); + reasonMessage.setColor(ChatColor.RED); + + // Handle race condition on player join on a misconfigured network + if (player.getServer() == null) { + player.disconnect(reasonMessage); + } else { + player.sendMessage(reasonMessage); + } + } + } +} diff --git a/src/main/java/fr/xephi/authmebungee/services/AuthPlayerManager.java b/src/main/java/fr/xephi/authmebungee/services/AuthPlayerManager.java new file mode 100644 index 0000000..9988a33 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/services/AuthPlayerManager.java @@ -0,0 +1,43 @@ +package fr.xephi.authmebungee.services; + +import fr.xephi.authmebungee.data.AuthPlayer; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.HashMap; +import java.util.Map; + +/* + * Players manager - store all references to AuthPlayer objects through an HashMap + */ +public class AuthPlayerManager { + + private Map players; + + public AuthPlayerManager() { + players = new HashMap<>(); + } + + public void addAuthPlayer(AuthPlayer player) { + players.put(player.getName(), player); + } + + public void addAuthPlayer(ProxiedPlayer player) { + addAuthPlayer(new AuthPlayer(player.getName().toLowerCase())); + } + + public void removeAuthPlayer(String name) { + players.remove(name.toLowerCase()); + } + + public void removeAuthPlayer(ProxiedPlayer player) { + removeAuthPlayer(player.getName()); + } + + public AuthPlayer getAuthPlayer(String name) { + return players.get(name.toLowerCase()); + } + + public AuthPlayer getAuthPlayer(ProxiedPlayer player) { + return getAuthPlayer(player.getName()); + } +} diff --git a/src/main/java/fr/xephi/authmebungee/utils/FileUtils.java b/src/main/java/fr/xephi/authmebungee/utils/FileUtils.java new file mode 100644 index 0000000..51f31c3 --- /dev/null +++ b/src/main/java/fr/xephi/authmebungee/utils/FileUtils.java @@ -0,0 +1,31 @@ +package fr.xephi.authmebungee.utils; + +import java.io.File; +import java.io.IOException; + +/** + * File utilities. + */ +public final class FileUtils { + + // Utility class + private FileUtils() { + } + + /** + * Creates the given file or throws an exception. + * + * @param file the file to create + */ + public static void create(File file) { + try { + file.getParentFile().mkdirs(); + boolean result = file.createNewFile(); + if (!result) { + throw new IllegalStateException("Could not create file '" + file + "'"); + } + } catch (IOException e) { + throw new IllegalStateException("Error while creating file '" + file + "'", e); + } + } +} diff --git a/src/main/resources/bungee.yml b/src/main/resources/bungee.yml new file mode 100644 index 0000000..3ad3771 --- /dev/null +++ b/src/main/resources/bungee.yml @@ -0,0 +1,4 @@ +name: ${project.name} +main: fr.xephi.authmebungee.AuthMeBungee +version: ${project.version} +author: AuthMeTeam