diff --git a/src/main/java/ptl/ajneb97/PlayerTimeLimit.java b/src/main/java/ptl/ajneb97/PlayerTimeLimit.java index 07a2bbe..928b9fc 100644 --- a/src/main/java/ptl/ajneb97/PlayerTimeLimit.java +++ b/src/main/java/ptl/ajneb97/PlayerTimeLimit.java @@ -17,6 +17,7 @@ import ptl.ajneb97.managers.dependencies.Metrics; import ptl.ajneb97.model.internal.UpdateCheckerResult; import ptl.ajneb97.tasks.*; +import ptl.ajneb97.integrations.AuthMeSupport; import ptl.ajneb97.utils.ServerVersion; @@ -34,6 +35,7 @@ public class PlayerTimeLimit extends JavaPlugin { private DependencyManager dependencyManager; private TimeResetManager timeResetManager; private DatabaseManager databaseManager; + private AuthMeSupport authMeSupport; private PlayerDataSaveTask playerDataSaveTask; private PlayerTimeTask playerTimeTask; @@ -55,6 +57,8 @@ public void onEnable(){ registerEvents(); registerCommands(); + this.authMeSupport = new AuthMeSupport(this); + this.authMeSupport.registerAuthEvents(); playerTimeTask = new PlayerTimeTask(this); playerTimeTask.start(); @@ -185,4 +189,8 @@ public void updateMessage(UpdateCheckerResult result){ public UpdateCheckerManager getUpdateCheckerManager() { return updateCheckerManager; } + + public AuthMeSupport getAuthMeSupport() { + return authMeSupport; + } } diff --git a/src/main/java/ptl/ajneb97/integrations/AuthMeSupport.java b/src/main/java/ptl/ajneb97/integrations/AuthMeSupport.java new file mode 100644 index 0000000..1205e53 --- /dev/null +++ b/src/main/java/ptl/ajneb97/integrations/AuthMeSupport.java @@ -0,0 +1,153 @@ +package ptl.ajneb97.integrations; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.PluginManager; +import ptl.ajneb97.PlayerTimeLimit; +import ptl.ajneb97.configs.MainConfigManager; +import ptl.ajneb97.managers.PlayerDataManager; +import ptl.ajneb97.managers.PlayerTimeManager; + +import java.lang.reflect.Method; + +public class AuthMeSupport { + + private static final String AUTHME_PLUGIN_NAME = "AuthMe"; + private static final String AUTHME_API_CLASS = "fr.xephi.authme.api.v3.AuthMeApi"; + private static final String AUTHME_LOGIN_EVENT = "fr.xephi.authme.events.LoginEvent"; + private static final String AUTHME_RESTORE_SESSION_EVENT = "fr.xephi.authme.events.RestoreSessionEvent"; + private static final String AUTHME_REGISTER_EVENT = "fr.xephi.authme.events.RegisterEvent"; + + private final PlayerTimeLimit plugin; + + private final boolean authMePresent; + private Method apiGetInstanceMethod; + private Method isAuthenticatedMethod; + private Method isRegisteredMethod; + private Object authMeApiInstance; + private boolean apiLoaded; + + public AuthMeSupport(PlayerTimeLimit plugin) { + this.plugin = plugin; + this.authMePresent = Bukkit.getPluginManager().getPlugin(AUTHME_PLUGIN_NAME) != null; + if (authMePresent) { + loadApi(); + } + } + + public boolean isReadyForTimeTracking(Player player) { + if (!authMePresent) { + return true; + } + if (player == null || !player.isOnline()) { + return false; + } + if (!apiLoaded && !loadApi()) { + return false; + } + + try { + boolean authenticated = (boolean) isAuthenticatedMethod.invoke(authMeApiInstance, player); + if (authenticated) { + return true; + } + + boolean registered = (boolean) isRegisteredMethod.invoke(authMeApiInstance, player.getName()); + return !registered; + } catch (ReflectiveOperationException e) { + plugin.getLogger().warning("AuthMe API invocation failed while checking auth state: " + e.getMessage()); + return false; + } + } + + public void registerAuthEvents() { + if (!authMePresent) { + return; + } + + registerAuthEvent(AUTHME_LOGIN_EVENT); + registerAuthEvent(AUTHME_RESTORE_SESSION_EVENT); + registerAuthEvent(AUTHME_REGISTER_EVENT); + } + + private boolean loadApi() { + try { + Class apiClass = Class.forName(AUTHME_API_CLASS); + apiGetInstanceMethod = apiClass.getMethod("getInstance"); + isAuthenticatedMethod = apiClass.getMethod("isAuthenticated", Player.class); + isRegisteredMethod = apiClass.getMethod("isRegistered", String.class); + authMeApiInstance = apiGetInstanceMethod.invoke(null); + apiLoaded = authMeApiInstance != null; + if (!apiLoaded) { + plugin.getLogger().warning("AuthMe API instance is null; delaying auth checks."); + } + return apiLoaded; + } catch (ReflectiveOperationException e) { + plugin.getLogger().warning("Could not load AuthMe API v3 support: " + e.getMessage()); + apiLoaded = false; + return false; + } + } + + @SuppressWarnings("unchecked") + private void registerAuthEvent(String eventClassName) { + try { + Class rawEventClass = Class.forName(eventClassName); + if (!Event.class.isAssignableFrom(rawEventClass)) { + return; + } + + Class eventClass = (Class) rawEventClass; + Listener listener = new Listener() { + }; + + PluginManager pluginManager = Bukkit.getPluginManager(); + pluginManager.registerEvent(eventClass, listener, EventPriority.MONITOR, (registeredListener, event) -> { + Player player = extractPlayer(event); + if (player == null) { + return; + } + runSync(() -> refreshAfterAuthentication(player)); + }, plugin, true); + } catch (ClassNotFoundException ignored) { + // AuthMe variant may not expose all events; this is optional. + } + } + + private Player extractPlayer(Event event) { + try { + Method getPlayer = event.getClass().getMethod("getPlayer"); + Object result = getPlayer.invoke(event); + if (result instanceof Player player) { + return player; + } + } catch (ReflectiveOperationException ignored) { + // Ignore unsupported event signatures. + } + return null; + } + + private void runSync(Runnable action) { + if (Bukkit.isPrimaryThread()) { + action.run(); + } else { + Bukkit.getScheduler().runTask(plugin, action); + } + } + + private void refreshAfterAuthentication(Player player) { + if (player == null || !player.isOnline()) { + return; + } + + PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); + PlayerTimeManager playerTimeManager = plugin.getPlayerTimeManager(); + MainConfigManager mainConfigManager = plugin.getConfigsManager().getMainConfigManager(); + + playerDataManager.updateTimeLimit(player); + playerTimeManager.sendInfoBars(player, playerDataManager, mainConfigManager); + } +} diff --git a/src/main/java/ptl/ajneb97/managers/PlayerDataManager.java b/src/main/java/ptl/ajneb97/managers/PlayerDataManager.java index 5c1457c..12bad94 100644 --- a/src/main/java/ptl/ajneb97/managers/PlayerDataManager.java +++ b/src/main/java/ptl/ajneb97/managers/PlayerDataManager.java @@ -126,7 +126,9 @@ public void manageJoin(Player player){ if(playerData == null){ createPlayer(player); } - updateTimeLimit(player); + if(isReadyForTimeTracking(player)) { + updateTimeLimit(player); + } } public void manageLeave(Player player){ @@ -174,6 +176,13 @@ public void updateTimeLimit(Player player){ } } + public boolean isReadyForTimeTracking(Player player) { + if (player == null || !player.isOnline()) { + return false; + } + return plugin.getAuthMeSupport() == null || plugin.getAuthMeSupport().isReadyForTimeTracking(player); + } + public int getTimeLimit(UUID uuid) { PlayerData playerData = getPlayerByUUID(uuid); Map timeLimits = plugin.getConfigsManager().getMainConfigManager().getTimeLimits(); diff --git a/src/main/java/ptl/ajneb97/tasks/PlayerTimeTask.java b/src/main/java/ptl/ajneb97/tasks/PlayerTimeTask.java index e0ef37b..844ee17 100644 --- a/src/main/java/ptl/ajneb97/tasks/PlayerTimeTask.java +++ b/src/main/java/ptl/ajneb97/tasks/PlayerTimeTask.java @@ -27,8 +27,11 @@ public void run() { public void execute() { MainConfigManager mainConfigManager = plugin.getConfigsManager().getMainConfigManager(); PlayerTimeManager playerTimeManager = plugin.getPlayerTimeManager(); + var playerDataManager = plugin.getPlayerDataManager(); for(Player player : Bukkit.getOnlinePlayers()){ - playerTimeManager.updateTimePlayer(player,mainConfigManager); + if(playerDataManager.isReadyForTimeTracking(player)) { + playerTimeManager.updateTimePlayer(player,mainConfigManager); + } } } diff --git a/src/main/java/ptl/ajneb97/tasks/PlayerUpdateLimitTask.java b/src/main/java/ptl/ajneb97/tasks/PlayerUpdateLimitTask.java index 2ac9a30..ac6a813 100644 --- a/src/main/java/ptl/ajneb97/tasks/PlayerUpdateLimitTask.java +++ b/src/main/java/ptl/ajneb97/tasks/PlayerUpdateLimitTask.java @@ -20,13 +20,15 @@ public void run() { execute(); } - }.runTaskTimerAsynchronously(plugin, 0L, 60L); + }.runTaskTimer(plugin, 0L, 60L); } public void execute() { PlayerDataManager playerDataManager = plugin.getPlayerDataManager(); for(Player player : Bukkit.getOnlinePlayers()){ - playerDataManager.updateTimeLimit(player); + if(playerDataManager.isReadyForTimeTracking(player)) { + playerDataManager.updateTimeLimit(player); + } } } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d4ffb05..165fd25 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ version: ${project.version} name: PlayerTimeLimit api-version: 1.13 author: Ajneb97 -softdepend: [Multiverse-Core,PlaceholderAPI] +softdepend: [Multiverse-Core,PlaceholderAPI,AuthMe] commands: playertimelimit: @@ -20,4 +20,4 @@ permissions: playertimelimit.commands.info: default: true playertimelimit.admin: - default: op \ No newline at end of file + default: op