diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 18464fe5..67e2beb9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -47,8 +47,10 @@ body: description: Which server implementation are you using? multiple: false options: - - Standalone server (no proxy) + - Standalone(Spigot) + - Standalone(Folia) - BungeeCord + - Velocity validations: required: true @@ -60,6 +62,9 @@ body: options: - SQLite - MySQL + - H2 + - MariaDB + - PostgreSQL validations: required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index cbb688c0..df46beec 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,6 @@ name: Feature request description: Suggest an idea for AuthMe -labels: 'Type: enhancement' +labels: 'enhancement' body: - type: markdown diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 06408062..ac8b4818 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -25,7 +25,7 @@ jobs: uses: actions/upload-artifact@v3.1.2 with: name: Download - path: ./target/AuthMe-5.6.0-FORK-Spigot-Universal.jar + path: ./target/AuthMe-5.6.0-FORK-Universal.jar runtime-test: name: Plugin Runtime Test needs: [Build] @@ -37,8 +37,8 @@ jobs: javaVersion: '8' - mcVersion: '1.12.2' javaVersion: '8' - - mcVersion: '1.20.2' - javaVersion: '20' + - mcVersion: '1.20.1' + javaVersion: '17' steps: - uses: HaHaWTH/minecraft-plugin-runtime-test@paper with: diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 00000000..df5376b2 --- /dev/null +++ b/README-zh.md @@ -0,0 +1,51 @@ +# AuthMeReReloaded +**"Bukkit 的最佳身份验证插件的分支!"** + +![Graph](https://bstats.org/signatures/bukkit/AuthMeReloaded-Fork.svg) +

+ Code size + GitHub repo size + CodeFactor + Downloads +

+ +**详细改动:** + 1. 改进邮件发送逻辑,支持更多邮件 + 2. 关闭邮件发送(当服务器关闭时,向您发送邮件) + 3. 原有漏洞修复 + 4. 反幽灵玩家(重复登录错误) + 5. 按服务器分支使用最佳性能方法 + 6. 基岩兼容性(需要Floodgate)(基于 UUID) + 7. 更新检查器 + 8. 集成 GUI 验证码功能(需要 Bedrock 兼容性和 ProtocolLib)(70% 异步) + 9. 改进监听器 + 10. 改进玩家登录逻辑以减少延迟 + 11. 自动清除机器人数据 + 12. 支持**Folia(正在测试中)** + 13. F键菜单兼容 + 14. 自动修复传送卡传送门/地底问题 + 15. **Velocity支持 (详见 [Velocity Support](./vc-support.md))** + 16. 基岩版玩家自动登录(可配置) + 17. 修复旧版本(MC 1.13-)中的 "潜影盒 "崩溃问题 + 18. 支持 **H2 数据库** + 19. 虚拟线程支持 + 20. **100% 兼容原版 authme 和扩展** + 21. 更多...... + +**下载链接:** +[Release](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest) +[Actions(开发版,使用风险自负!)](https://github.com/HaHaWTH/AuthMeReReloaded/actions/workflows/maven.yml) + +如果您的服务器使用 FRP(内网穿透),此插件可能会有所帮助 [HAProxy-Detector](https://github.com/HaHaWTH/HAProxy-Detector) + +**欢迎提出请求和建议!** + + + + Star History Chart + diff --git a/README.md b/README.md index 6690c483..62ba15d2 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -**This branch adds MultiPaper support, requires Java 17 or higher** \ No newline at end of file +**This branch adds Multipaper support, requires Java17 or higher** \ No newline at end of file diff --git a/pom.xml b/pom.xml index ff001c9b..7c59d410 100644 --- a/pom.xml +++ b/pom.xml @@ -82,54 +82,11 @@ sgdc3, games647, Hex3l, krusic22 - - - - - jenkins - - - env.BUILD_NUMBER - - - - ${env.BUILD_NUMBER} - - - - - skipLongHashTests - - - skipLongHashTests - - - - true - - - - - skipJavadocGeneration - - - - org.apache.maven.plugins - maven-javadoc-plugin - - true - - - - - - clean package ${project.finalNameBase}-noshade - . @@ -222,7 +179,7 @@ org.jacoco jacoco-maven-plugin - 0.8.11 + 0.8.12 pre-unit-test @@ -282,7 +239,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 ${project.finalNameBase} @@ -308,6 +265,7 @@ shade + ${project.finalNameBase}-Lite @@ -318,7 +276,7 @@ com.google.j2objc:j2objc-annotations com.google.code.gson:gson - + @@ -366,6 +324,16 @@ fr.xephi.authme.libs.com.github.benmanes.caffeine + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + @@ -375,7 +343,7 @@ shade - ${project.finalNameBase}-Spigot-Universal + ${project.finalNameBase}-Universal com.google.common diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 6c944738..4d3acdd5 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -35,6 +35,7 @@ import fr.xephi.authme.service.BackupService; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.MigrationService; import fr.xephi.authme.service.bungeecord.BungeeReceiver; +import fr.xephi.authme.service.velocity.VelocityReceiver; import fr.xephi.authme.service.yaml.YamlParseException; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.SettingsWarner; @@ -79,7 +80,7 @@ public class AuthMe extends JavaPlugin { // Version and build number values private static String pluginVersion = "5.6.0-Fork"; private static final String pluginBuild = "b"; - private static String pluginBuildNumber = "45"; + private static String pluginBuildNumber = "47"; // Private instances private EmailService emailService; private CommandHandler commandHandler; @@ -300,6 +301,7 @@ public class AuthMe extends JavaPlugin { // Trigger instantiation (class not used elsewhere) injector.getSingleton(BungeeReceiver.class); + injector.getSingleton(VelocityReceiver.class); // Trigger construction of API classes; they will keep track of the singleton injector.getSingleton(AuthMeApi.class); diff --git a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java index d2185491..29e98333 100644 --- a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java @@ -15,6 +15,7 @@ import fr.xephi.authme.process.register.executors.PasswordRegisterParams; import fr.xephi.authme.process.register.executors.RegistrationMethod; import fr.xephi.authme.process.register.executors.TwoFactorRegisterParams; import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.EmailSettings; @@ -24,8 +25,6 @@ import org.bukkit.entity.Player; import javax.inject.Inject; import java.util.List; -import java.util.Timer; -import java.util.TimerTask; import static fr.xephi.authme.process.register.RegisterSecondaryArgument.CONFIRMATION; import static fr.xephi.authme.process.register.RegisterSecondaryArgument.EMAIL_MANDATORY; @@ -46,6 +45,9 @@ public class RegisterCommand extends PlayerCommand { @Inject private CommonService commonService; + @Inject + private BukkitService bukkitService; + @Inject private DataSource dataSource; @@ -175,20 +177,15 @@ public class RegisterCommand extends PlayerCommand { } else if (isSecondArgValidForEmailRegistration(player, arguments)) { management.performRegister(RegistrationMethod.EMAIL_REGISTRATION, EmailRegisterParams.of(player, email)); - Timer timer = new Timer(); - timer.schedule(new TimerTask() { - @Override - public void run() { + if (commonService.getProperty(RegistrationSettings.UNREGISTER_ON_EMAIL_VERIFICATION_FAILURE) && commonService.getProperty(RegistrationSettings.UNREGISTER_AFTER_MINUTES) > 0) { + bukkitService.runTaskLater(player, () -> { if (dataSource.getAuth(player.getName()) != null) { if (dataSource.getAuth(player.getName()).getLastLogin() == null) { management.performUnregisterByAdmin(null, player.getName(), player); - timer.cancel(); } - } else { - timer.cancel(); } - } - }, 600000); + }, 60 * 20 * commonService.getProperty(RegistrationSettings.UNREGISTER_AFTER_MINUTES)); + } } } diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 0a3fcd43..9a1cf216 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -41,6 +41,7 @@ public class MySQL extends AbstractSqlDataSource { private boolean useSsl; private boolean serverCertificateVerification; private boolean allowPublicKeyRetrieval; + private String mariaDbSslMode; private String host; private String port; private String username; @@ -121,6 +122,7 @@ public class MySQL extends AbstractSqlDataSource { this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL); this.serverCertificateVerification = settings.getProperty(DatabaseSettings.MYSQL_CHECK_SERVER_CERTIFICATE); this.allowPublicKeyRetrieval = settings.getProperty(DatabaseSettings.MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL); + this.mariaDbSslMode = settings.getProperty(DatabaseSettings.MARIADB_SSL_MODE); } /** @@ -145,12 +147,19 @@ public class MySQL extends AbstractSqlDataSource { ds.setDriverClassName(this.getDriverClassName()); // Request mysql over SSL - ds.addDataSourceProperty("useSSL", String.valueOf(useSsl)); + if (this instanceof MariaDB) { + ds.addDataSourceProperty("sslMode", mariaDbSslMode); + } else { + ds.addDataSourceProperty("useSSL", String.valueOf(useSsl)); + + // Disabling server certificate verification on need + if (!serverCertificateVerification) { + ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false)); + } + } + // Disabling server certificate verification on need - if (!serverCertificateVerification) { - ds.addDataSourceProperty("verifyServerCertificate", String.valueOf(false)); - } // Disabling server certificate verification on need if (allowPublicKeyRetrieval) { ds.addDataSourceProperty("allowPublicKeyRetrieval", String.valueOf(true)); } diff --git a/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java b/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java index 3593e7ea..07211ef2 100644 --- a/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java +++ b/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java @@ -79,6 +79,7 @@ public class DataSourceProvider implements Provider { break; case H2: dataSource = new H2(settings, dataFolder); + logger.warning("You are using H2 database, which is still in development!\nMake sure to backup and report any issues you encounter on GitHub!"); break; default: throw new UnsupportedOperationException("Unknown data source type '" + dataSourceType + "'"); diff --git a/src/main/java/fr/xephi/authme/listener/BedrockAutoLoginListener.java b/src/main/java/fr/xephi/authme/listener/BedrockAutoLoginListener.java index 52d39daa..9a0adfb3 100644 --- a/src/main/java/fr/xephi/authme/listener/BedrockAutoLoginListener.java +++ b/src/main/java/fr/xephi/authme/listener/BedrockAutoLoginListener.java @@ -39,14 +39,16 @@ public class BedrockAutoLoginListener implements Listener { return settings.getProperty(HooksSettings.HOOK_FLOODGATE_PLAYER) && settings.getProperty(SecuritySettings.FORCE_LOGIN_BEDROCK) && org.geysermc.floodgate.api.FloodgateApi.getInstance().isFloodgateId(uuid) && getServer().getPluginManager().getPlugin("floodgate") != null; } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); String name = event.getPlayer().getName(); UUID uuid = event.getPlayer().getUniqueId(); - if (isBedrockPlayer(uuid) && !authmeApi.isAuthenticated(player) && authmeApi.isRegistered(name)) { - authmeApi.forceLogin(player); - messages.send(player, MessageKey.BEDROCK_AUTO_LOGGED_IN); - } + bukkitService.runTaskLater(player, () -> { + if (isBedrockPlayer(uuid) && !authmeApi.isAuthenticated(player) && authmeApi.isRegistered(name)) { + authmeApi.forceLogin(player); + messages.send(player, MessageKey.BEDROCK_AUTO_LOGGED_IN); + } + },20L); } } diff --git a/src/main/java/fr/xephi/authme/listener/PurgeListener.java b/src/main/java/fr/xephi/authme/listener/PurgeListener.java index 03f8a6ff..dcc3db4e 100644 --- a/src/main/java/fr/xephi/authme/listener/PurgeListener.java +++ b/src/main/java/fr/xephi/authme/listener/PurgeListener.java @@ -52,11 +52,15 @@ public class PurgeListener implements Listener { // 构建玩家数据文件路径 File playerDataFile = new File(playerDataFolder, File.separator + playerUUID + ".dat"); + File playerDataOldFile = new File(playerDataFolder, File.separator + playerUUID + ".dat_old"); // 删除玩家数据文件 if (playerDataFile.exists()) { playerDataFile.delete(); } + if (playerDataOldFile.exists()) { + playerDataOldFile.delete(); + } } private void deleteAuthMePlayerData(UUID playerUUID) { diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index aca8d306..ed723f7b 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -17,6 +17,9 @@ import fr.xephi.authme.service.SessionService; import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.service.bungeecord.BungeeSender; import fr.xephi.authme.service.bungeecord.MessageType; +import fr.xephi.authme.service.velocity.VMessageType; +import fr.xephi.authme.service.velocity.VelocitySender; +import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; @@ -45,6 +48,9 @@ public class AsynchronousJoin implements AsynchronousProcess { @Inject private Server server; + @Inject + private Settings settings; + @Inject private DataSource database; @@ -75,6 +81,9 @@ public class AsynchronousJoin implements AsynchronousProcess { @Inject private BungeeSender bungeeSender; + @Inject + private VelocitySender velocitySender; + @Inject private ProxySessionManager proxySessionManager; @@ -152,7 +161,11 @@ public class AsynchronousJoin implements AsynchronousProcess { // As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/ // "Keep in mind that you can't send plugin messages directly after a player joins." bukkitService.scheduleSyncDelayedTask(() -> - bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L); + bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY)); + } + if (velocitySender.isEnabled()) { + bukkitService.scheduleSyncDelayedTask(() -> + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY)); } return; } diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index b9ebbdb7..12ed97a0 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -26,6 +26,9 @@ import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.SessionService; import fr.xephi.authme.service.bungeecord.BungeeSender; import fr.xephi.authme.service.bungeecord.MessageType; +import fr.xephi.authme.service.velocity.VMessageType; +import fr.xephi.authme.service.velocity.VelocitySender; +import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.HooksSettings; @@ -81,9 +84,12 @@ public class AsynchronousLogin implements AsynchronousProcess { @Inject private SessionService sessionService; - + @Inject + private Settings settings; @Inject private BungeeSender bungeeSender; + @Inject + private VelocitySender velocitySender; AsynchronousLogin() { } @@ -306,7 +312,11 @@ public class AsynchronousLogin implements AsynchronousProcess { // As described at https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/ // "Keep in mind that you can't send plugin messages directly after a player joins." bukkitService.scheduleSyncDelayedTask(() -> - bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), 5L); + bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY)); + } + if (velocitySender.isEnabled()) { + bukkitService.scheduleSyncDelayedTask(() -> + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGIN), settings.getProperty(HooksSettings.PROXY_SEND_DELAY)); } // As the scheduling executes the Task most likely after the current diff --git a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java index 2e5bd87c..5e6f953f 100644 --- a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java @@ -11,6 +11,8 @@ import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.SessionService; import fr.xephi.authme.service.bungeecord.BungeeSender; import fr.xephi.authme.service.bungeecord.MessageType; +import fr.xephi.authme.service.velocity.VMessageType; +import fr.xephi.authme.service.velocity.VelocitySender; import fr.xephi.authme.settings.properties.RestrictionSettings; import org.bukkit.entity.Player; @@ -42,6 +44,8 @@ public class AsynchronousLogout implements AsynchronousProcess { @Inject private BungeeSender bungeeSender; + @Inject + private VelocitySender velocitySender; AsynchronousLogout() { } @@ -72,6 +76,7 @@ public class AsynchronousLogout implements AsynchronousProcess { database.setUnlogged(name); sessionService.revokeSession(name); bungeeSender.sendAuthMeBungeecordMessage(player, MessageType.LOGOUT); + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.LOGOUT); syncProcessManager.processSyncPlayerLogout(player); } } diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java index c1fae36c..0fe19acf 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java @@ -8,6 +8,8 @@ import fr.xephi.authme.output.ConsoleLoggerFactory; import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.velocity.VMessageType; +import fr.xephi.authme.service.velocity.VelocitySender; import fr.xephi.authme.util.PlayerUtils; import org.bukkit.entity.Player; @@ -28,6 +30,8 @@ public class ProcessSyncEmailRegister implements SynchronousProcess { @Inject private LimboService limboService; + @Inject + private VelocitySender velocitySender; ProcessSyncEmailRegister() { } @@ -40,7 +44,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess { public void processEmailRegister(Player player) { service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED); limboService.replaceTasksAfterRegistration(player); - + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.REGISTER); bukkitService.callEvent(new RegisterEvent(player)); logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player)); } diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java index ceed84ca..f68ba015 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java @@ -9,6 +9,8 @@ import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.bungeecord.BungeeSender; +import fr.xephi.authme.service.velocity.VMessageType; +import fr.xephi.authme.service.velocity.VelocitySender; import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; @@ -27,6 +29,9 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess { @Inject private BungeeSender bungeeSender; + @Inject + private VelocitySender velocitySender; + @Inject private CommonService service; @@ -66,7 +71,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess { if (!service.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) { service.send(player, MessageKey.ADD_EMAIL_MESSAGE); } - + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.REGISTER); bukkitService.callEvent(new RegisterEvent(player)); logger.fine(player.getName() + " registered " + PlayerUtils.getPlayerIp(player)); diff --git a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java index b26fb93f..c7537236 100644 --- a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java +++ b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java @@ -16,6 +16,8 @@ import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.TeleportationService; import fr.xephi.authme.service.bungeecord.BungeeSender; import fr.xephi.authme.service.bungeecord.MessageType; +import fr.xephi.authme.service.velocity.VMessageType; +import fr.xephi.authme.service.velocity.VelocitySender; import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; @@ -56,6 +58,9 @@ public class AsynchronousUnregister implements AsynchronousProcess { @Inject private CommandManager commandManager; + @Inject + private VelocitySender velocitySender; + @Inject private BungeeSender bungeeSender; @@ -76,6 +81,7 @@ public class AsynchronousUnregister implements AsynchronousProcess { if (dataSource.removeAuth(name)) { performPostUnregisterActions(name, player); logger.info(name + " unregistered himself"); + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.UNREGISTER); bukkitService.createAndCallEvent(isAsync -> new UnregisterByPlayerEvent(player, isAsync)); } else { service.send(player, MessageKey.ERROR); @@ -97,8 +103,8 @@ public class AsynchronousUnregister implements AsynchronousProcess { public void adminUnregister(CommandSender initiator, String name, Player player) { if (dataSource.removeAuth(name)) { performPostUnregisterActions(name, player); + velocitySender.sendAuthMeVelocityMessage(player, VMessageType.FORCE_UNREGISTER); bukkitService.createAndCallEvent(isAsync -> new UnregisterByAdminEvent(player, name, isAsync, initiator)); - if (initiator == null) { logger.info(name + " was unregistered"); } else { diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 05e32d7a..002ca9fa 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -167,6 +167,10 @@ public class BukkitService implements SettingsDependent { return getScheduler().runTaskLater(task, delay); } + public MyScheduledTask runTaskLater(Entity entity, Runnable task, long delay) { + return getScheduler().runTaskLater(entity, task, delay); + } + /** * Schedules this task to run asynchronously or immediately executes it based on * AuthMe's configuration. @@ -369,6 +373,17 @@ public class BukkitService implements SettingsDependent { player.sendPluginMessage(authMe, "BungeeCord", bytes); } + /** + * Send the specified bytes to bungeecord using the specified player connection. + * + * @param player the player + * @param bytes the message + */ + public void sendVelocityMessage(Player player, byte[] bytes) { + player.sendPluginMessage(authMe, "authmevelocity:main", bytes); + } + + /** * Adds a ban to the list. If a previous ban exists, this will * update the previous entry. diff --git a/src/main/java/fr/xephi/authme/service/velocity/VMessageType.java b/src/main/java/fr/xephi/authme/service/velocity/VMessageType.java new file mode 100644 index 00000000..0e65db42 --- /dev/null +++ b/src/main/java/fr/xephi/authme/service/velocity/VMessageType.java @@ -0,0 +1,5 @@ +package fr.xephi.authme.service.velocity; + +public enum VMessageType { + LOGIN, REGISTER, LOGOUT, FORCE_UNREGISTER, UNREGISTER +} diff --git a/src/main/java/fr/xephi/authme/service/velocity/VelocityReceiver.java b/src/main/java/fr/xephi/authme/service/velocity/VelocityReceiver.java new file mode 100644 index 00000000..caa04e5f --- /dev/null +++ b/src/main/java/fr/xephi/authme/service/velocity/VelocityReceiver.java @@ -0,0 +1,89 @@ +package fr.xephi.authme.service.velocity; + +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.data.ProxySessionManager; +import fr.xephi.authme.initialization.SettingsDependent; +import fr.xephi.authme.output.ConsoleLoggerFactory; +import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.HooksSettings; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import javax.inject.Inject; + +public class VelocityReceiver implements PluginMessageListener, SettingsDependent { + + private final ConsoleLogger logger = ConsoleLoggerFactory.get(VelocityReceiver.class); + + private final AuthMe plugin; + private final BukkitService bukkitService; + private final ProxySessionManager proxySessionManager; + private final Management management; + + private boolean isEnabled; + + @Inject + VelocityReceiver(AuthMe plugin, BukkitService bukkitService, ProxySessionManager proxySessionManager, + Management management, Settings settings) { + this.plugin = plugin; + this.bukkitService = bukkitService; + this.proxySessionManager = proxySessionManager; + this.management = management; + reload(settings); + } + + @Override + public void reload(Settings settings) { + this.isEnabled = settings.getProperty(HooksSettings.VELOCITY); + if (this.isEnabled) { + final Messenger messenger = plugin.getServer().getMessenger(); + if (!messenger.isIncomingChannelRegistered(plugin, "authmevelocity:main")) { + messenger.registerIncomingPluginChannel(plugin, "authmevelocity:main", this); + } + } + } + + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] bytes) { + if (!isEnabled) { + return; + } + + if (channel.equals("authmevelocity:main")) { + final ByteArrayDataInput in = ByteStreams.newDataInput(bytes); + + final String data = in.readUTF(); + final String username = in.readUTF(); + processData(username, data); + logger.debug("PluginMessage | AuthMeVelocity identifier processed"); + } + } + + private void processData(String username, String data) { + if (VMessageType.LOGIN.toString().equals(data)) { + performLogin(username); + } + } + + private void performLogin(String name) { + Player player = bukkitService.getPlayerExact(name); + if (player != null && player.isOnline()) { + management.forceLogin(player, true); + logger.info("The user " + player.getName() + " has been automatically logged in, " + + "as requested via plugin messaging."); + } else { + proxySessionManager.processProxySessionMessage(name); + logger.info("The user " + name + " should be automatically logged in, " + + "as requested via plugin messaging but has not been detected, nickname has been" + + " added to autologin queue."); + } + } + +} diff --git a/src/main/java/fr/xephi/authme/service/velocity/VelocitySender.java b/src/main/java/fr/xephi/authme/service/velocity/VelocitySender.java new file mode 100644 index 00000000..16a0f2cb --- /dev/null +++ b/src/main/java/fr/xephi/authme/service/velocity/VelocitySender.java @@ -0,0 +1,76 @@ +package fr.xephi.authme.service.velocity; + +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.initialization.SettingsDependent; +import fr.xephi.authme.output.ConsoleLoggerFactory; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.bungeecord.MessageType; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.HooksSettings; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.Messenger; + +import javax.inject.Inject; + +public class VelocitySender implements SettingsDependent { + + private final ConsoleLogger logger = ConsoleLoggerFactory.get(VelocitySender.class); + private final AuthMe plugin; + private final BukkitService bukkitService; + + private boolean isEnabled; + + /* + * Constructor. + */ + @Inject + VelocitySender(AuthMe plugin, BukkitService bukkitService, Settings settings) { + this.plugin = plugin; + this.bukkitService = bukkitService; + reload(settings); + } + + @Override + public void reload(Settings settings) { + this.isEnabled = settings.getProperty(HooksSettings.VELOCITY); + + if (this.isEnabled) { + Messenger messenger = plugin.getServer().getMessenger(); + if (!messenger.isOutgoingChannelRegistered(plugin, "authmevelocity:main")) { + messenger.registerOutgoingPluginChannel(plugin, "authmevelocity:main"); + } + } + } + + public boolean isEnabled() { + return isEnabled; + } + + private void sendForwardedVelocityMessage(Player player, VMessageType type, String playerName) { + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF(type.toString()); + out.writeUTF(playerName); + bukkitService.sendVelocityMessage(player, out.toByteArray()); + } + + /** + * Sends a message to the AuthMe plugin messaging channel, if enabled. + * + * @param player The player related to the message + * @param type The message type, See {@link MessageType} + */ + public void sendAuthMeVelocityMessage(Player player, VMessageType type) { + if (!isEnabled) { + return; + } + if (!plugin.isEnabled()) { + logger.debug("Tried to send a " + type + " velocity message but the plugin was disabled!"); + return; + } + sendForwardedVelocityMessage(player, type, player.getName()); + } + +} diff --git a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java b/src/main/java/fr/xephi/authme/settings/SettingsWarner.java index b12f84ef..c63ffe71 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsWarner.java @@ -61,7 +61,7 @@ public class SettingsWarner { // Warn if spigot.yml has settings.bungeecord set to true but config.yml has Hooks.bungeecord set to false if (isTrue(bukkitService.isBungeeCordConfiguredForSpigot()) - && !settings.getProperty(HooksSettings.BUNGEECORD)) { + && !settings.getProperty(HooksSettings.BUNGEECORD) && !settings.getProperty(HooksSettings.VELOCITY)) { logger.warning("Note: Hooks.bungeecord is set to false but your server appears to be running in" + " bungeecord mode (see your spigot.yml). In order to allow the datasource caching and the" + " AuthMeBungee add-on to work properly you have to enable this option!"); diff --git a/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java b/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java index 3b799b3a..6103183d 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/DatabaseSettings.java @@ -31,7 +31,17 @@ public final class DatabaseSettings implements SettingsHolder { public static final Property MYSQL_PORT = newProperty("DataSource.mySQLPort", "3306"); - @Comment("Connect to MySQL database over SSL") + @Comment({"Replacement of Mysql's useSsl (for MariaDB only).", + "- disable: No SSL", + "- trust: Trust blindly (no validation)", + "- verify_ca: Encryption, certificates validation, BUT no hostname verification", + "- verify_full: Encryption, certificate validation and hostname validation", + "Read more: https://bit.ly/mariadb-sslmode"}) + public static final Property MARIADB_SSL_MODE = + newProperty("DataSource.MariaDbSslMode", "disabled"); + + @Comment({"Connect to MySQL database over SSL", + "If you're using MariaDB, use sslMode instead"}) public static final Property MYSQL_USE_SSL = newProperty("DataSource.mySQLUseSSL", true); @@ -39,12 +49,13 @@ public final class DatabaseSettings implements SettingsHolder { "We would not recommend to set this option to false.", "Set this option to false at your own risk if and only if you know what you're doing"}) public static final Property MYSQL_CHECK_SERVER_CERTIFICATE = - newProperty( "DataSource.mySQLCheckServerCertificate", true ); + newProperty( "DataSource.mySQLCheckServerCertificate", true); @Comment({"Authorize client to retrieve RSA server public key.", - "Advanced option, ignore if you don't know what it means."}) + "Advanced option, ignore if you don't know what it means.", + "If you are using MariaDB, use MariaDbSslMode instead."}) public static final Property MYSQL_ALLOW_PUBLIC_KEY_RETRIEVAL = - newProperty( "DataSource.mySQLAllowPublicKeyRetrieval", true ); + newProperty( "DataSource.mySQLAllowPublicKeyRetrieval", true); @Comment("Username to connect to the MySQL database") public static final Property MYSQL_USERNAME = diff --git a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java index 5d27c052..08c91c6a 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java @@ -18,6 +18,15 @@ public final class HooksSettings implements SettingsHolder { @Comment("Do we need to hook with BungeeCord?") public static final Property BUNGEECORD = newProperty("Hooks.bungeecord", false); + @Comment("Do we need to hook with Velocity?") + public static final Property VELOCITY = + newProperty("Hooks.velocity", false); + + @Comment({"How many ticks should we wait before sending login info to proxy?", + "Change this to higher if your player has high ping.", + "See: https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/"}) + public static final Property PROXY_SEND_DELAY = + newProperty("Hooks.proxySendDelay", 10L); @Comment({"Hook into floodgate.", "This must be true if you want to use other bedrock features." diff --git a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java index ccf83cda..b15132d5 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java @@ -46,6 +46,16 @@ public final class RegistrationSettings implements SettingsHolder { newProperty(RegisterSecondaryArgument.class, "settings.registration.secondArg", RegisterSecondaryArgument.CONFIRMATION); + @Comment({ + "Should we unregister the player when he didn't verify the email?", + "This only works if you enabled email registration."}) + public static final Property UNREGISTER_ON_EMAIL_VERIFICATION_FAILURE = + newProperty("settings.registration.email.unregisterOnEmailVerificationFailure", false); + + @Comment({"How many minutes should we wait before unregister the player", + "when he didn't verify the email?"}) + public static final Property UNREGISTER_AFTER_MINUTES = + newProperty("settings.registration.email.unregisterAfterMinutes", 10L); @Comment({ "Do we force kick a player after a successful registration?", "Do not use with login feature below"}) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a80a6371..b043c435 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,7 +4,7 @@ website: http://github.com/HaHaWTH/AuthMeReReloaded/ description: A fork of AuthMeReloaded that contains bug fixes main: ${pluginDescription.main} folia-supported: true -version: 5.6.0-FORK-b45 +version: 5.6.0-FORK-b47 api-version: 1.13 softdepend: - Vault diff --git a/vc-support.md b/vc-support.md new file mode 100644 index 00000000..4b840e0a --- /dev/null +++ b/vc-support.md @@ -0,0 +1,27 @@ +## About Velocity support + +**AuthMeReReloaded offers integrated support for Velocity since b46, in order to use, please follow the instructions below.** + + +### Step 1: Enable Velocity hook in config.yml + +```yaml +Hooks: + # Do we need to hook with Velocity? + velocity: true # Set this to true +``` +**Then restart your server if you have done so.** + +### Step 2: Configure backend server and proxy + +**Before we can continue, you need to configure your Velocity proxy forwarding method following [PaperMC's instructions](https://docs.papermc.io/velocity/player-information-forwarding#configuring-modern-forwarding).** + +### Step 3: Install AuthMeVelocity on the Proxy + +AuthMeVelocity is a plugin that allows Velocity to forward player information to AuthMeReloaded. + +**Only install it on the proxy, not on the backend server.** + +**You can download it from [Modrinth](https://modrinth.com/plugin/authmevelocity).** + +**Then configure follow its instructions.**