diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index fcc3ce61..4632e065 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -29,6 +29,7 @@ import fr.xephi.authme.command.executable.authme.TotpViewStatusCommand; import fr.xephi.authme.command.executable.authme.UnregisterAdminCommand; import fr.xephi.authme.command.executable.authme.UpdateHelpMessagesCommand; import fr.xephi.authme.command.executable.authme.VersionCommand; +import fr.xephi.authme.command.executable.authme.WhitelistCommand; import fr.xephi.authme.command.executable.authme.debug.DebugCommand; import fr.xephi.authme.command.executable.captcha.CaptchaCommand; import fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand; @@ -420,6 +421,16 @@ public class CommandInitializer { .executableCommand(SwitchAntiBotCommand.class) .register(); + CommandDescription.builder() + .parent(authmeBase) + .labels("whitelist") + .description("Switch whitelist mode") + .detailedDescription("Switch or toggle the whitelist mode to the specified state.") + .withArgument("mode", "ON / OFF", OPTIONAL) + .permission(AdminPermission.SWITCH_ANTIBOT) + .executableCommand(WhitelistCommand.class) + .register(); + // Register the reload command CommandDescription.builder() .parent(authmeBase) diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/WhitelistCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/WhitelistCommand.java new file mode 100644 index 00000000..f6c436c9 --- /dev/null +++ b/src/main/java/fr/xephi/authme/command/executable/authme/WhitelistCommand.java @@ -0,0 +1,40 @@ +package fr.xephi.authme.command.executable.authme; + +import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.service.WhiteListService; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import javax.inject.Inject; +import java.util.List; + +/** + * Display or change the status of the antibot mod. + */ +public class WhitelistCommand implements ExecutableCommand { + + @Inject + private WhiteListService whiteListService; + + + @Override + public void executeCommand(final CommandSender sender, List arguments) { + if (arguments.isEmpty()) { + sender.sendMessage("[AuthMe] WhiteList: " + whiteListService.getWhiteListStatus().name()); + return; + } + + String newState = arguments.get(0); + + // Enable or disable the mod + if ("ON".equalsIgnoreCase(newState)) { + whiteListService.overrideWhiteListStatus(true); + sender.sendMessage("[AuthMe] WhiteList enabled!"); + } else if ("OFF".equalsIgnoreCase(newState)) { + sender.sendMessage("[AuthMe] WhiteList disabled!"); + whiteListService.overrideWhiteListStatus(false); + } else { + sender.sendMessage(ChatColor.GOLD + "Detailed help: " + ChatColor.WHITE + "/authme help whitelist"); + } + } +} diff --git a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java index 08224841..6258f9c4 100644 --- a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java +++ b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java @@ -7,11 +7,13 @@ import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; import fr.xephi.authme.output.ConsoleLoggerFactory; +import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.service.AntiBotService; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.ValidationService; +import fr.xephi.authme.service.WhiteListService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ProtectionSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; @@ -46,6 +48,8 @@ public class OnJoinVerifier implements Reloadable { @Inject private AntiBotService antiBotService; @Inject + private WhiteListService whiteListService; + @Inject private ValidationService validationService; @Inject private BukkitService bukkitService; @@ -81,6 +85,18 @@ public class OnJoinVerifier implements Reloadable { throw new FailedVerificationException(MessageKey.KICK_ANTIBOT); } } + public void checkWhitelist(String name, boolean isAuthAvailable) throws FailedVerificationException { + if (isAuthAvailable || permissionsManager.hasPermissionOffline(name, PlayerStatePermission.WHITELIST)) { + return; + } else { + bukkitService.getOnlinePlayers().stream() + .filter(player -> permissionsManager.hasPermission(player, AdminPermission.WHITELIST_MESSAGE)) + .forEach(player -> messages.send(player, MessageKey.WHITELIST_KICK, name)); + } + if (whiteListService.shouldKick()) { + throw new FailedVerificationException(MessageKey.KICK_WHITELIST); + } + } /** * Checks whether non-registered players should be kicked, and if so, whether the player should be kicked. diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index 95f0685c..e998a69f 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -148,6 +148,7 @@ public class PlayerListener implements Listener { final PlayerAuth auth = dataSource.getAuth(name); final boolean isAuthAvailable = auth != null; onJoinVerifier.checkKickNonRegistered(isAuthAvailable); + onJoinVerifier.checkWhitelist(name, isAuthAvailable); onJoinVerifier.checkAntibot(name, isAuthAvailable); onJoinVerifier.checkNameCasing(name, auth); final String ip = event.getAddress().getHostAddress(); diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java index a9ee9b78..21344157 100644 --- a/src/main/java/fr/xephi/authme/message/MessageKey.java +++ b/src/main/java/fr/xephi/authme/message/MessageKey.java @@ -16,6 +16,9 @@ public enum MessageKey { /** AntiBot protection mode is enabled! You have to wait some minutes before joining the server. */ KICK_ANTIBOT("antibot.kick_antibot"), + KICK_WHITELIST("on_join_validation.kick_whitelist"), + WHITELIST_ENABLED_MESSAGE("misc.whitelist_enabled"), + WHITELIST_DISABLED_MESSAGE("misc.whitelist_disabled"), /** This user isn't registered! */ UNKNOWN_USER("error.unregistered_user"), @@ -196,6 +199,7 @@ public enum MessageKey { /** [AntiBotService] AntiBot disabled after %m minutes! */ ANTIBOT_AUTO_DISABLED_MESSAGE("antibot.auto_disabled", "%m"), + WHITELIST_KICK("misc.whitelist_kick", "%p"), /** The email address is already being used */ EMAIL_ALREADY_USED_ERROR("email.already_used"), diff --git a/src/main/java/fr/xephi/authme/permission/AdminPermission.java b/src/main/java/fr/xephi/authme/permission/AdminPermission.java index 20e27f2f..ce9ab1d2 100644 --- a/src/main/java/fr/xephi/authme/permission/AdminPermission.java +++ b/src/main/java/fr/xephi/authme/permission/AdminPermission.java @@ -124,6 +124,7 @@ public enum AdminPermission implements PermissionNode { * Permission to see Antibot messages. */ ANTIBOT_MESSAGES("authme.admin.antibotmessages"), + WHITELIST_MESSAGE("authme.admin.whitelistmessage"), /** * Permission to use the update messages command. diff --git a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java index b9fe17e7..4e48cb79 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java @@ -10,6 +10,7 @@ public enum PlayerStatePermission implements PermissionNode { * Permission node to bypass AntiBot protection. */ BYPASS_ANTIBOT("authme.bypassantibot", DefaultPermission.OP_ONLY), + WHITELIST("authme.whitelist", DefaultPermission.OP_ONLY), /** * Permission node to bypass BungeeCord server teleportation. diff --git a/src/main/java/fr/xephi/authme/service/WhiteListService.java b/src/main/java/fr/xephi/authme/service/WhiteListService.java new file mode 100644 index 00000000..73728e80 --- /dev/null +++ b/src/main/java/fr/xephi/authme/service/WhiteListService.java @@ -0,0 +1,82 @@ +package fr.xephi.authme.service; + +import fr.xephi.authme.initialization.SettingsDependent; +import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.message.Messages; +import fr.xephi.authme.permission.AdminPermission; +import fr.xephi.authme.permission.PermissionsManager; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.ProtectionSettings; +import org.bukkit.scheduler.BukkitTask; + +import javax.inject.Inject; +import java.util.Locale; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * The AntiBot Service Management class. + */ +public class WhiteListService implements SettingsDependent { + + private final PermissionsManager permissionsManager; + private final Messages messages; + private final BukkitService bukkitService; + private WhiteListStatus whiteListStatus; + + @Inject + WhiteListService(Settings settings, Messages messages, PermissionsManager permissionsManager, + BukkitService bukkitService) { + // Instances + this.messages = messages; + this.permissionsManager = permissionsManager; + this.bukkitService = bukkitService; + // Initial status + whiteListStatus = WhiteListStatus.DISABLED; + // Load settings and start if required + reload(settings); + } + + @Override + public void reload(Settings settings) { + } + + private void startProtection() { + if (whiteListStatus == WhiteListStatus.ACTIVE) { + return; + } + whiteListStatus = WhiteListStatus.ACTIVE; + bukkitService.getOnlinePlayers().stream() + .filter(player -> permissionsManager.hasPermission(player, AdminPermission.WHITELIST_MESSAGE)) + .forEach(player -> messages.send(player, MessageKey.WHITELIST_ENABLED_MESSAGE)); + + } + + private void stopProtection() { + if (whiteListStatus == WhiteListStatus.DISABLED) { + return; + } + whiteListStatus = WhiteListStatus.DISABLED; + bukkitService.getOnlinePlayers().stream() + .filter(player -> permissionsManager.hasPermission(player, AdminPermission.WHITELIST_MESSAGE)) + .forEach(player -> messages.send(player, MessageKey.WHITELIST_DISABLED_MESSAGE)); + } + public WhiteListStatus getWhiteListStatus() { + return whiteListStatus; + } + + public void overrideWhiteListStatus(boolean started) { + if (started) { + startProtection(); + } else { + stopProtection(); + } + } + public boolean shouldKick() { + return whiteListStatus != WhiteListStatus.DISABLED; + } + + public enum WhiteListStatus { + DISABLED, + ACTIVE + } +} diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java index 84c6fabf..f52f0bcf 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java @@ -19,7 +19,9 @@ public final class ProtectionSettings implements SettingsHolder { @Comment("Apply the protection also to registered usernames") public static final Property ENABLE_PROTECTION_REGISTERED = newProperty("Protection.enableProtectionRegistered", true); - + @Comment("Only allow registed usernames join server") + public static final Property ENABLE_WHITELIST = + newProperty("Protection.enableWhiteList", true); @Comment({ "Countries allowed to join the server and register. For country codes, see", "https://dev.maxmind.com/geoip/legacy/codes/iso3166/", diff --git a/src/main/resources/messages/messages_zhcn.yml b/src/main/resources/messages/messages_zhcn.yml index 710f9825..ee3bc03c 100644 --- a/src/main/resources/messages/messages_zhcn.yml +++ b/src/main/resources/messages/messages_zhcn.yml @@ -65,6 +65,9 @@ misc: usage_change_password: '&a正确用法:“/changepassword 旧密码 新密码”' accounts_owned_self: '您拥有 %count 个账户:' accounts_owned_other: '玩家 %name 拥有 %count 个账户:' + whitelist_enabled: '&c*** 服务器已暂停注册 ***' + whitelist_disabled: '&a*** 服务器已开放注册 ***' + whitelist_kick: '&7玩家 &c%p &7请求加入服务器,但是被拒绝了.' # Session messages session: @@ -87,7 +90,10 @@ on_join_validation: &c如果您并不知情,请更换您的用户名重新加入该服务器. invalid_name_case: '&c您应该使用 %valid 登录服务器,当前名字: %invalid .' quick_command: '&c您发送命令的速度太快了,请重新加入服务器等待一会后再使用命令' - + kick_whitelist: |- + &6[&b&lAccount Security System&6] + &c本服务器已经暂停注册,请用下面的联系方式了解详细情况. + &cQQ群聊号码: 550984860 &b| &c QQ: 2125368097 &b| &cTelegram: @Stabrinai # Email email: add_email_request: '' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1e7fdeed..55e8fa3e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -184,6 +184,9 @@ permissions: authme.bypassantibot: description: Permission node to bypass AntiBot protection. default: op + authme.whitelist: + description: Permission node to whitelist. + default: op authme.bypasscountrycheck: description: Permission to bypass the GeoIp country code check. default: false