Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/ptl/ajneb97/PlayerTimeLimit.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;


Expand All @@ -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;
Expand All @@ -55,6 +57,8 @@ public void onEnable(){

registerEvents();
registerCommands();
this.authMeSupport = new AuthMeSupport(this);
this.authMeSupport.registerAuthEvents();

playerTimeTask = new PlayerTimeTask(this);
playerTimeTask.start();
Expand Down Expand Up @@ -185,4 +189,8 @@ public void updateMessage(UpdateCheckerResult result){
public UpdateCheckerManager getUpdateCheckerManager() {
return updateCheckerManager;
}

public AuthMeSupport getAuthMeSupport() {
return authMeSupport;
}
}
153 changes: 153 additions & 0 deletions src/main/java/ptl/ajneb97/integrations/AuthMeSupport.java
Original file line number Diff line number Diff line change
@@ -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<? extends Event> eventClass = (Class<? extends Event>) 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);
}
}
11 changes: 10 additions & 1 deletion src/main/java/ptl/ajneb97/managers/PlayerDataManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -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){
Expand Down Expand Up @@ -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<String,Integer> timeLimits = plugin.getConfigsManager().getMainConfigManager().getTimeLimits();
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/ptl/ajneb97/tasks/PlayerTimeTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/java/ptl/ajneb97/tasks/PlayerUpdateLimitTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
4 changes: 2 additions & 2 deletions src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -20,4 +20,4 @@ permissions:
playertimelimit.commands.info:
default: true
playertimelimit.admin:
default: op
default: op