diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/README.md b/README.md index 2e1d5171d5..f02fca14e3 100644 --- a/README.md +++ b/README.md @@ -27,22 +27,19 @@ 10. Player login logic improvement to reduce lag 11. Automatically purge bot data 12. **Folia support (in active testing)** - 13. Offhand Menu compatibility(Thats amazing) - 14. **Velocity support (See [Velocity Support](./vc-support.md))** - 15. Support Virtual Threads caching - 16. Automatically fix portal stuck issue - 17. Automatically login for Bedrock players(configurable) - 18. Fix shulker box crash bug on legacy versions(MC 1.13-) - 19. **H2 database support** - 20. **100% compatibility with original authme and extensions** - 21. More...... + 13. **Velocity support (See [Velocity Support](./vc-support.md))** + 14. Support Virtual Threads caching + 15. Automatically fix portal stuck issue + 16. Automatically login for Bedrock players(configurable) + 17. Fix shulker box crash bug on legacy versions(MC 1.13-) + 18. **H2 database support** + 19. **100% compatibility with original authme and extensions** + 20. More...... **Download links:** [Releases](https://github.com/HaHaWTH/AuthMeReReloaded/releases/latest) [Actions(Dev builds, use at your own risk!)](https://github.com/HaHaWTH/AuthMeReReloaded/actions/workflows/maven.yml) -If you are using FRP(内网穿透) for your server, this plugin may help [HAProxy-Detector](https://github.com/HaHaWTH/HAProxy-Detector) - **Pull Requests and suggestions are welcome!** ## Building diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 8731693b20..78a19279e4 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -74,9 +74,9 @@ public class AuthMe extends JavaPlugin { private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE; // Version and build number values - private static String pluginVersion = "5.6.0-Fork"; + private static String pluginVersion = "5.7.0-Fork"; private static final String pluginBuild = "b"; - private static String pluginBuildNumber = "50"; + private static String pluginBuildNumber = "53"; // Private instances private EmailService emailService; private CommandHandler commandHandler; diff --git a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java index fd487d6652..81f55863f7 100644 --- a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java +++ b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java @@ -32,6 +32,7 @@ * AuthMeApi authmeApi = AuthMeApi.getInstance(); * */ +@SuppressWarnings("unused") public class AuthMeApi { private static AuthMeApi singleton; diff --git a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java index 83a0e5b2ce..31580db3ac 100644 --- a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java @@ -8,6 +8,7 @@ import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.service.ValidationService.ValidationResult; +import fr.xephi.authme.settings.properties.SecuritySettings; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -42,11 +43,14 @@ public void runCommand(Player player, List arguments) { commonService.send(player, MessageKey.NOT_LOGGED_IN); return; } - // Check if the user has been verified or not - if (codeManager.isVerificationRequired(player)) { - codeManager.codeExistOrGenerateNew(name); - commonService.send(player, MessageKey.VERIFICATION_CODE_REQUIRED); - return; + + if (commonService.getProperty(SecuritySettings.CHANGE_PASSWORD_EMAIL_VERIFICATION_REQUIRED)) { + // Check if the user has been verified or not + if (codeManager.isVerificationRequired(player)) { + codeManager.codeExistOrGenerateNew(name); + commonService.send(player, MessageKey.VERIFICATION_CODE_REQUIRED); + return; + } } String oldPassword = arguments.get(0); diff --git a/src/main/java/fr/xephi/authme/data/VerificationCodeManager.java b/src/main/java/fr/xephi/authme/data/VerificationCodeManager.java index ad1b778da0..1fc1e13b11 100644 --- a/src/main/java/fr/xephi/authme/data/VerificationCodeManager.java +++ b/src/main/java/fr/xephi/authme/data/VerificationCodeManager.java @@ -22,6 +22,8 @@ import java.util.Set; import java.util.concurrent.TimeUnit; +import static fr.xephi.authme.AuthMe.getScheduler; + public class VerificationCodeManager implements SettingsDependent, HasCleanup { private final EmailService emailService; @@ -133,17 +135,19 @@ public void codeExistOrGenerateNew(String name) { * @param name the name of the player to generate a code for */ private void generateCode(String name) { - DataSourceValue emailResult = dataSource.getEmail(name); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'年'MM'月'dd'日' HH:mm:ss"); - Date date = new Date(System.currentTimeMillis()); - if (emailResult.rowExists()) { - final String email = emailResult.getValue(); - if (!Utils.isEmailEmpty(email)) { - String code = RandomStringUtils.generateNum(6); // 6 digits code - verificationCodes.put(name.toLowerCase(Locale.ROOT), code); - emailService.sendVerificationMail(name, email, code, dateFormat.format(date)); + getScheduler().runTaskAsynchronously(() -> { + DataSourceValue emailResult = dataSource.getEmail(name); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy'-'MM'-'dd'-' HH:mm:ss"); + Date date = new Date(System.currentTimeMillis()); + if (emailResult.rowExists()) { + final String email = emailResult.getValue(); + if (!Utils.isEmailEmpty(email)) { + String code = RandomStringUtils.generateNum(6); // 6 digits code + verificationCodes.put(name.toLowerCase(Locale.ROOT), code); + emailService.sendVerificationMail(name, email, code, dateFormat.format(date)); + } } - } + }); } /** diff --git a/src/main/java/fr/xephi/authme/listener/ListenerService.java b/src/main/java/fr/xephi/authme/listener/ListenerService.java index 3d582b0ea6..d90c6f2d99 100644 --- a/src/main/java/fr/xephi/authme/listener/ListenerService.java +++ b/src/main/java/fr/xephi/authme/listener/ListenerService.java @@ -75,9 +75,7 @@ public boolean shouldCancelEvent(PlayerEvent event) { * @param player the player to verify * @return true if the associated event should be canceled, false otherwise */ - public boolean shouldCancelEvent(Player player) { - return player != null && !checkAuth(player.getName()) && !PlayerUtils.isNpc(player); } @Override diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index e435b9c2dc..60aa74015e 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -16,9 +16,11 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.properties.HooksSettings; +import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.util.TeleportUtils; +import fr.xephi.authme.util.message.I18NUtils; import fr.xephi.authme.util.message.MiniMessageUtils; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -93,7 +95,6 @@ public class PlayerListener implements Listener { @Inject private QuickCommandsProtectionManager quickCommandsProtectionManager; - // Lowest priority to apply fast protection checks @EventHandler(priority = EventPriority.LOWEST) public void onAsyncPlayerPreLoginEventLowest(AsyncPlayerPreLoginEvent event) { @@ -248,6 +249,11 @@ public void onPlayerQuit(PlayerQuitEvent event) { } } + // Remove data from locale map when player quit + if (settings.getProperty(PluginSettings.I18N_MESSAGES)) { + I18NUtils.removeLocale(player.getUniqueId()); + } + if (antiBotService.wasPlayerKicked(player.getName())) { return; } @@ -533,12 +539,4 @@ public void onPlayerInventoryClick(InventoryClickEvent event) { event.setCancelled(true); } } -// @EventHandler(priority = EventPriority.LOWEST) -// public void onSwitchHand(PlayerSwapHandItemsEvent event) { -// Player player = event.getPlayer(); -// if (!player.isSneaking() || !player.hasPermission("keybindings.use")) -// return; -// event.setCancelled(true); -// Bukkit.dispatchCommand(event.getPlayer(), "help"); -// } } diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListenerHigherThan18.java b/src/main/java/fr/xephi/authme/listener/PlayerListenerHigherThan18.java index 66c408a185..bd845ce0b1 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListenerHigherThan18.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListenerHigherThan18.java @@ -1,14 +1,10 @@ package fr.xephi.authme.listener; import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.settings.properties.PluginSettings; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPickupItemEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; import javax.inject.Inject; @@ -26,12 +22,4 @@ public void onPlayerPickupItem(EntityPickupItemEvent event) { } } - @EventHandler(priority = EventPriority.LOWEST) - public void onSwitchHand(PlayerSwapHandItemsEvent event) { - Player player = event.getPlayer(); - if (player.isSneaking() && player.hasPermission("keybindings.use") && settings.getProperty(PluginSettings.MENU_UNREGISTER_COMPATIBILITY)) { - event.setCancelled(true); - Bukkit.dispatchCommand(event.getPlayer(), "help"); - } - } } diff --git a/src/main/java/fr/xephi/authme/listener/ServerListener.java b/src/main/java/fr/xephi/authme/listener/ServerListener.java index 97cefa04cd..f5d9612446 100644 --- a/src/main/java/fr/xephi/authme/listener/ServerListener.java +++ b/src/main/java/fr/xephi/authme/listener/ServerListener.java @@ -53,6 +53,9 @@ public void onPluginDisable(PluginDisableEvent event) { } else if ("ProtocolLib".equalsIgnoreCase(pluginName)) { protocolLibService.disable(); logger.warning("ProtocolLib has been disabled, unhooking packet adapters!"); + } else if ("PlaceholderAPI".equalsIgnoreCase(pluginName)) { + pluginHookService.unhookPlaceholderApi(); + logger.info("PlaceholderAPI has been disabled: unhooking placeholders"); } } @@ -74,6 +77,8 @@ public void onPluginEnable(PluginEnableEvent event) { spawnLoader.loadCmiSpawn(); } else if ("ProtocolLib".equalsIgnoreCase(pluginName)) { protocolLibService.setup(); + } else if ("PlaceholderAPI".equalsIgnoreCase(pluginName)) { + pluginHookService.tryHookToPlaceholderApi(); } } } 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 dbfd9df067..424c49896b 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -29,8 +29,6 @@ import org.bukkit.GameMode; import org.bukkit.Server; import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; import javax.inject.Inject; import java.util.Locale; @@ -208,7 +206,7 @@ private void processJoinSync(Player player, boolean isAuthAvailable) { int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout; // AuthMeReReloaded - Fix potion apply on Folia - bukkitService.runTaskIfFolia(player,() -> player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2))); + bukkitService.runTaskIfFolia(player, () -> player.addPotionEffect(bukkitService.createBlindnessEffect(blindTimeOut))); } commandManager.runCommandsOnJoin(player); }); diff --git a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java index 6aeed332cb..96865e21c3 100644 --- a/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/ProcessSyncPlayerLogout.java @@ -14,8 +14,6 @@ import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; import javax.inject.Inject; @@ -75,7 +73,7 @@ private void applyLogoutEffect(Player player) { // Apply Blindness effect if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND; - player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2)); + player.addPotionEffect(bukkitService.createBlindnessEffect(timeout)); } // Set player's data to unauthenticated diff --git a/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java b/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java index 42048ef1ed..41e713e833 100644 --- a/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java +++ b/src/main/java/fr/xephi/authme/process/quit/ProcessSyncPlayerQuit.java @@ -29,7 +29,7 @@ public void processSyncQuit(Player player, boolean wasLoggedIn) { } else { limboService.restoreData(player); if (!UniversalScheduler.isFolia) { // AuthMeReReloaded - Fix #146 (Very stupid solution, but works) - player.saveData(); // #1238: Speed is sometimes not restored properly + // player.saveData(); // #1238: Speed is sometimes not restored properly } } player.leaveVehicle(); 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 b69b993046..caecd295e3 100644 --- a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java +++ b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java @@ -23,8 +23,6 @@ import fr.xephi.authme.settings.properties.RestrictionSettings; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; import javax.inject.Inject; @@ -150,7 +148,7 @@ private void performPostUnregisterActions(String name, Player player) { private void applyBlindEffect(Player player) { if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND; - player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2)); + bukkitService.runTaskIfFolia(player, () -> player.addPotionEffect(bukkitService.createBlindnessEffect(timeout))); } } diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 45008a387c..8a89979558 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -18,6 +18,8 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Event; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; import javax.inject.Inject; import java.util.Collection; @@ -327,6 +329,16 @@ public E createAndCallEvent(Function eventSupplier return event; } + /** + * Creates a PotionEffect with blindness for the given duration in ticks. + * + * @param timeoutInTicks duration of the effect in ticks + * @return blindness potion effect + */ + public PotionEffect createBlindnessEffect(int timeoutInTicks) { + return new PotionEffect(PotionEffectType.BLINDNESS, timeoutInTicks, 2); + } + /** * Gets the world with the given name. * @@ -380,7 +392,11 @@ public void sendBungeeMessage(Player player, byte[] bytes) { * @param bytes the message */ public void sendVelocityMessage(Player player, byte[] bytes) { - player.sendPluginMessage(authMe, "authmevelocity:main", bytes); + if (player != null) { + player.sendPluginMessage(authMe, "authmevelocity:main", bytes); + } else { + Bukkit.getServer().sendPluginMessage(authMe, "authmevelocity:main", bytes); + } } diff --git a/src/main/java/fr/xephi/authme/service/GeoIpService.java b/src/main/java/fr/xephi/authme/service/GeoIpService.java index bf7252ff39..f18a85fa30 100644 --- a/src/main/java/fr/xephi/authme/service/GeoIpService.java +++ b/src/main/java/fr/xephi/authme/service/GeoIpService.java @@ -37,7 +37,7 @@ public class GeoIpService { private volatile boolean downloading; @Inject - GeoIpService(@DataFolder File dataFolder){ + GeoIpService(@DataFolder File dataFolder) { this.dataFile = dataFolder.toPath().resolve(DATABASE_FILE); // Fires download of recent data or the initialization of the look up service diff --git a/src/main/java/fr/xephi/authme/service/PluginHookService.java b/src/main/java/fr/xephi/authme/service/PluginHookService.java index 3615aa7361..df588ee90b 100644 --- a/src/main/java/fr/xephi/authme/service/PluginHookService.java +++ b/src/main/java/fr/xephi/authme/service/PluginHookService.java @@ -6,6 +6,8 @@ import com.onarandombox.MultiverseCore.api.MVWorldManager; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.output.ConsoleLoggerFactory; +import fr.xephi.authme.service.hook.papi.AuthMeExpansion; +import me.clip.placeholderapi.PlaceholderAPIPlugin; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; @@ -26,6 +28,8 @@ public class PluginHookService { private Essentials essentials; private Plugin cmi; private MultiverseCore multiverse; + private PlaceholderAPIPlugin placeholderApi; + private AuthMeExpansion authMeExpansion; /** * Constructor. @@ -38,6 +42,7 @@ public PluginHookService(PluginManager pluginManager) { tryHookToEssentials(); tryHookToCmi(); tryHookToMultiverse(); + tryHookToPlaceholderApi(); } /** @@ -133,6 +138,20 @@ public void tryHookToEssentials() { } } + /** + * Attempts to create a hook into PlaceholderAPI. + */ + public void tryHookToPlaceholderApi() { + try { + placeholderApi = getPlugin(pluginManager, "PlaceholderAPI", PlaceholderAPIPlugin.class); + authMeExpansion = new AuthMeExpansion(); + authMeExpansion.register(); + } catch (Exception | NoClassDefFoundError ignored) { + placeholderApi = null; + authMeExpansion = null; + } + } + /** * Attempts to create a hook into CMI. */ @@ -180,6 +199,16 @@ public void unhookMultiverse() { multiverse = null; } + /** + * Unhooks from PlaceholderAPI. + */ + public void unhookPlaceholderApi() { + if (placeholderApi != null) { + authMeExpansion.unregister(); + placeholderApi = null; + } + } + // ------ // Helpers // ------ diff --git a/src/main/java/fr/xephi/authme/service/TeleportationService.java b/src/main/java/fr/xephi/authme/service/TeleportationService.java index c50b01291f..4693d1fd6b 100644 --- a/src/main/java/fr/xephi/authme/service/TeleportationService.java +++ b/src/main/java/fr/xephi/authme/service/TeleportationService.java @@ -144,7 +144,7 @@ public void teleportOnLogin(final Player player, PlayerAuth auth, LimboPlayer li if (settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) { Location location = buildLocationFromAuth(player, auth); Location playerLoc = player.getLocation(); - if (location.getX() == playerLoc.getX() && location.getY() == location.getY() && location.getZ() == playerLoc.getZ() + if (location.getX() == playerLoc.getX() && location.getY() == playerLoc.getY() && location.getZ() == playerLoc.getZ() && location.getWorld() == playerLoc.getWorld()) return; logger.debug("Teleporting `{0}` after login, based on the player auth", player.getName()); teleportBackFromSpawn(player, location); diff --git a/src/main/java/fr/xephi/authme/service/hook/papi/AuthMeExpansion.java b/src/main/java/fr/xephi/authme/service/hook/papi/AuthMeExpansion.java new file mode 100644 index 0000000000..ce58950d32 --- /dev/null +++ b/src/main/java/fr/xephi/authme/service/hook/papi/AuthMeExpansion.java @@ -0,0 +1,72 @@ +package fr.xephi.authme.service.hook.papi; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.api.v3.AuthMeApi; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.HooksSettings; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +/** + * AuthMe PlaceholderAPI expansion class. + * @author Kobe 8 + */ +public class AuthMeExpansion extends PlaceholderExpansion { + private final Settings settings = AuthMe.settings; + @Override + public @NotNull String getIdentifier() { + return "authme"; + } + + @Override + public @NotNull String getAuthor() { + return "HaHaWTH"; + } + + @Override + public @NotNull String getVersion() { + return AuthMe.getPluginVersion(); + } + + @Override + public boolean persist() { + return true; + } + + @Override + public String onRequest(OfflinePlayer player, @NotNull String params) { + if (!settings.getProperty(HooksSettings.PLACEHOLDER_API)) return null; + AuthMeApi authMeApi = AuthMeApi.getInstance(); + if (authMeApi == null) return null; + if (params.equalsIgnoreCase("version")) { + return getVersion(); + } + if (params.equalsIgnoreCase("is_registered")) { + if (player != null) { + Player onlinePlayer = player.getPlayer(); + if (onlinePlayer != null) { + return String.valueOf(authMeApi.isRegistered(onlinePlayer.getName())); + } + } + } + if (params.equalsIgnoreCase("is_authenticated")) { + if (player != null) { + Player onlinePlayer = player.getPlayer(); + if (onlinePlayer != null) { + return String.valueOf(authMeApi.isAuthenticated(onlinePlayer)); + } + } + } + if (params.equalsIgnoreCase("last_login_time")) { + if (player != null) { + Player onlinePlayer = player.getPlayer(); + if (onlinePlayer != null) { + return authMeApi.getLastLoginTime(onlinePlayer.getName()).toString(); + } + } + } + return null; + } +} diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java index 1018da0a8e..86f06aa8e4 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -129,9 +129,9 @@ private void executeCommands(Player player, List commands if (predicate.test(cmd)) { long delay = cmd.getDelay(); if (delay > 0) { - bukkitService.scheduleSyncDelayedTask(() -> dispatchCommand(player, cmd), delay); + bukkitService.runTaskLater(player, () -> dispatchCommand(player, cmd), delay); } else { - dispatchCommand(player, cmd); + bukkitService.runTaskIfFolia(player, () -> dispatchCommand(player, cmd)); } } } 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 08c91c6a13..32e7a95f05 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java @@ -15,6 +15,10 @@ public final class HooksSettings implements SettingsHolder { public static final Property MULTIVERSE = newProperty("Hooks.multiverse", true); + @Comment("Do we need to hook with PlaceholderAPI for AuthMe placeholders?") + public static final Property PLACEHOLDER_API = + newProperty("Hooks.placeholderapi", false); + @Comment("Do we need to hook with BungeeCord?") public static final Property BUNGEECORD = newProperty("Hooks.bungeecord", false); diff --git a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java index 221496b354..f09e550dd5 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java @@ -11,17 +11,10 @@ import static ch.jalu.configme.properties.PropertyInitializer.newProperty; public final class PluginSettings implements SettingsHolder { - @Comment({ - "Should we execute /help command when unregistered players press Shift+F?", - "This keeps compatibility with some menu plugins", - "If you are using TrMenu, don't enable this because TrMenu already implemented this." - }) - public static final Property MENU_UNREGISTER_COMPATIBILITY = - newProperty("3rdPartyFeature.compatibility.menuPlugins", false); @Comment({ "Send i18n messages to player based on their client settings, this option will override `settings.messagesLanguage`", - "(Requires Protocollib or Packetevents)", + "(Requires ProtocolLib)", "This will not affect language of AuthMe help command." }) public static final Property I18N_MESSAGES = diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 1fc8341fcb..06eb2b55d0 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -173,7 +173,7 @@ public final class RestrictionSettings implements SettingsHolder { @Comment("Regex syntax for allowed chars in email.") public static final Property ALLOWED_EMAIL_REGEX = - newProperty("settings.restrictions.allowedEmailCharacters", "^[A-Za-z0-9_.]{3,20}@(qq|outlook|163|gmail|icloud)\\.com$"); + newProperty("settings.restrictions.allowedEmailCharacters", "^([a-zA-Z0-9_.+-]+)@([a-zA-Z0-9-]+)\\.([a-zA-Z]{2,})$"); @Comment("Force survival gamemode when player joins?") diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index b1d7c4aea2..fc560e3cb7 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -62,6 +62,11 @@ public final class SecuritySettings implements SettingsHolder { public static final Property HAVE_I_BEEN_PWNED_LIMIT = newProperty("Security.account.haveIBeenPwned.limit", 0); + @Comment({"Require email verification when changing password if email feature enabled.", + "Original behavior is true"}) + public static final Property CHANGE_PASSWORD_EMAIL_VERIFICATION_REQUIRED = + newProperty("Security.account.emailVerification.required", true); + @Comment("Enable captcha when a player uses wrong password too many times") public static final Property ENABLE_LOGIN_FAILURE_CAPTCHA = newProperty("Security.captcha.useCaptcha", false); diff --git a/src/main/java/fr/xephi/authme/task/Updater.java b/src/main/java/fr/xephi/authme/task/Updater.java index 5616d88a8a..52750873c7 100644 --- a/src/main/java/fr/xephi/authme/task/Updater.java +++ b/src/main/java/fr/xephi/authme/task/Updater.java @@ -1,10 +1,13 @@ package fr.xephi.authme.task; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + import java.io.IOException; +import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; -import java.util.Scanner; public class Updater { private final String currentVersion; @@ -32,14 +35,16 @@ public boolean isUpdateAvailable() { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(10000); conn.setReadTimeout(10000); - Scanner scanner = new Scanner(conn.getInputStream()); - String response = scanner.useDelimiter("\\Z").next(); - scanner.close(); - String latestVersion = response.substring(response.indexOf("tag_name") + 11); - latestVersion = latestVersion.substring(0, latestVersion.indexOf("\"")); - this.latestVersion = latestVersion; - isUpdateAvailable = !currentVersion.equals(latestVersion); - return isUpdateAvailable; + conn.setRequestMethod("GET"); + conn.setRequestProperty("Accept", "application/vnd.github+json"); + try (InputStreamReader reader = new InputStreamReader(conn.getInputStream())) { + JsonObject jsonObject = new JsonParser().parse(reader).getAsJsonObject(); + String latest = jsonObject.get("tag_name").getAsString(); + latestVersion = latest; + isUpdateAvailable = !currentVersion.equals(latest); + reader.close(); + return isUpdateAvailable; + } } catch (IOException ignored) { this.latestVersion = null; isUpdateAvailable = false; diff --git a/src/main/java/fr/xephi/authme/util/message/I18NUtils.java b/src/main/java/fr/xephi/authme/util/message/I18NUtils.java index ff68b5abb8..da1d6769bc 100644 --- a/src/main/java/fr/xephi/authme/util/message/I18NUtils.java +++ b/src/main/java/fr/xephi/authme/util/message/I18NUtils.java @@ -60,6 +60,10 @@ public static void addLocale(UUID uuid, String locale) { PLAYER_LOCALE.put(uuid, locale); } + public static void removeLocale(UUID uuid) { + PLAYER_LOCALE.remove(uuid); + } + /** * Returns the AuthMe messages file language code, by given locale and settings. * Dreeam - Hard mapping, based on mc1.20.6, 5/29/2024 diff --git a/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java b/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java index 5d7e62168c..36756c6207 100644 --- a/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java +++ b/src/main/java/fr/xephi/authme/util/message/MiniMessageUtils.java @@ -2,9 +2,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import net.md_5.bungee.api.chat.BaseComponent; public class MiniMessageUtils { private static final MiniMessage miniMessage = MiniMessage.miniMessage(); @@ -19,18 +17,6 @@ public static String parseMiniMessageToLegacy(String message) { Component component = miniMessage.deserialize(message); return LegacyComponentSerializer.legacyAmpersand().serialize(component); } - - /** - * Parse a MiniMessage string into a BaseComponent. - * - * @param message The message to parse. - * @return The parsed message. - */ - public static BaseComponent[] parseMiniMessageToBaseComponent(String message) { - Component component = miniMessage.deserialize(message); - return BungeeComponentSerializer.legacy().serialize(component); - } - private MiniMessageUtils() { } } diff --git a/src/main/resources/email.html b/src/main/resources/email.html index 7b9e77faa2..ddadabcd39 100644 --- a/src/main/resources/email.html +++ b/src/main/resources/email.html @@ -104,7 +104,7 @@

Minecraft ·

© 2024 HomoCraft. All rights reserved.

wdsj.in + style="text-decoration: none; font-size: 16px">example.com diff --git a/src/main/resources/new_email.html b/src/main/resources/new_email.html index 74a1a087be..b0da4f0754 100644 --- a/src/main/resources/new_email.html +++ b/src/main/resources/new_email.html @@ -110,7 +110,7 @@

Minecraft ·

© 2024 HomoCraft. All rights reserved.

wdsj.in + style="text-decoration: none; font-size: 16px">example.com diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6414af78ec..7203312c3f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,10 +1,13 @@ -name: AuthMe -authors: [sgdc3, games647, Hex3l, krusic22, DGun Otto] +# noinspection YAMLSchemaValidation +name: ${pluginDescription.name} +# noinspection YAMLSchemaValidation +authors: [${pluginDescription.authors}] website: https://github.com/HaHaWTH/AuthMeReReloaded/ description: A fork of AuthMeReloaded that contains bug fixes -main: fr.xephi.authme.AuthMe +# noinspection YAMLSchemaValidation +main: ${pluginDescription.main} folia-supported: true -version: 5.6.0-FORK-b50 +version: 5.7.0-FORK-b53 api-version: 1.13 softdepend: - Vault @@ -17,6 +20,7 @@ softdepend: - EssentialsSpawn - ProtocolLib - floodgate + - PlaceholderAPI commands: authme: description: AuthMe op commands diff --git a/src/main/resources/recovery_code_email.html b/src/main/resources/recovery_code_email.html index c41c00c9bb..4c665ec7db 100644 --- a/src/main/resources/recovery_code_email.html +++ b/src/main/resources/recovery_code_email.html @@ -103,7 +103,7 @@

Minecraft ·

© 2024 HomoCraft. All rights reserved.

wdsj.in + style="text-decoration: none; font-size: 16px">example.com diff --git a/src/main/resources/shutdown.html b/src/main/resources/shutdown.html index 2819ebfc07..2492193899 100644 --- a/src/main/resources/shutdown.html +++ b/src/main/resources/shutdown.html @@ -101,7 +101,7 @@

Minecraft ·

© 2024 HomoCraft. All rights reserved.

wdsj.in + style="text-decoration: none; font-size: 16px">example.com diff --git a/src/main/resources/verification_code_email.html b/src/main/resources/verification_code_email.html index 0e8d1ddd86..c76d68318b 100644 --- a/src/main/resources/verification_code_email.html +++ b/src/main/resources/verification_code_email.html @@ -103,7 +103,7 @@

Minecraft ·

© 2024 HomoCraft. All rights reserved.

wdsj.in + style="text-decoration: none; font-size: 16px">example.com