package com.mrkayjaydee.playhours.permissions; import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.server.ServerLifecycleHooks; import java.util.UUID; import java.util.concurrent.TimeUnit; /** * Handles LuckPerms integration for permission checking. * Separates LuckPerms-specific logic from general permission checking. */ public final class LuckPermsIntegration { private LuckPermsIntegration() {} // LuckPerms soft integration - detected at startup private static net.luckperms.api.LuckPerms luckPerms; static { try { luckPerms = net.luckperms.api.LuckPermsProvider.get(); } catch (Throwable ignored) { // LuckPerms not present, will use vanilla fallback luckPerms = null; } } /** * Checks if LuckPerms is available. * * @return true if LuckPerms is loaded and available */ public static boolean isAvailable() { return luckPerms != null; } /** * Checks a permission for an online player using LuckPerms. * * @param player the player to check * @param permission the permission node * @return true if the player has the permission */ public static boolean hasPermission(ServerPlayer player, String permission) { if (!isAvailable()) return false; var user = luckPerms.getUserManager().getUser(player.getUUID()); if (user == null) return false; var data = user.getCachedData().getPermissionData(); var result = data.checkPermission(permission); return result.asBoolean(); } /** * Checks a permission for an offline player by UUID using LuckPerms. * Uses a timeout to prevent blocking indefinitely. * * @param uuid the player UUID * @param permission the permission node * @return true if the player has the permission, false otherwise or on timeout */ public static boolean hasPermissionOffline(UUID uuid, String permission) { if (!isAvailable()) return false; // Check if player is online first var server = ServerLifecycleHooks.getCurrentServer(); ServerPlayer online = server.getPlayerList().getPlayer(uuid); if (online != null) { return hasPermission(online, permission); } // Offline LP check (best-effort with timeout to avoid blocking) try { var future = luckPerms.getUserManager().loadUser(uuid); var user = future.get(PermissionConstants.LUCKPERMS_TIMEOUT_SECONDS, TimeUnit.SECONDS); if (user != null) { var result = user.getCachedData().getPermissionData().checkPermission(permission); return result.asBoolean(); } } catch (Throwable t) { // Timeout, interrupted, or other error - log and continue // This is acceptable as it's best-effort for offline checks } return false; } }