You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
7.5 KiB
219 lines
7.5 KiB
package ru.simsonic.rscPermissions.Bukkit; |
|
|
|
import java.util.Arrays; |
|
import java.util.Collections; |
|
import java.util.HashMap; |
|
import java.util.HashSet; |
|
import java.util.Map; |
|
import java.util.Set; |
|
import java.util.concurrent.ConcurrentHashMap; |
|
import java.util.concurrent.LinkedBlockingQueue; |
|
import org.bukkit.OfflinePlayer; |
|
import org.bukkit.command.CommandSender; |
|
import org.bukkit.entity.Player; |
|
import org.bukkit.permissions.PermissionAttachment; |
|
import ru.simsonic.rscCommonsLibrary.RestartableThread; |
|
import ru.simsonic.rscMinecraftLibrary.Bukkit.GenericChatCodes; |
|
import ru.simsonic.rscMinecraftLibrary.Bukkit.Tools; |
|
import ru.simsonic.rscPermissions.API.Settings; |
|
import ru.simsonic.rscPermissions.BukkitPluginMain; |
|
import ru.simsonic.rscPermissions.Engine.Phrases; |
|
import ru.simsonic.rscPermissions.Engine.ResolutionParams; |
|
import ru.simsonic.rscPermissions.Engine.ResolutionResult; |
|
|
|
public class BukkitPermissionManager extends RestartableThread |
|
{ |
|
private final BukkitPluginMain rscp; |
|
public BukkitPermissionManager(BukkitPluginMain plugin) |
|
{ |
|
this.rscp = plugin; |
|
} |
|
private final LinkedBlockingQueue<Player> updateQueue = new LinkedBlockingQueue<>(); |
|
private final Map<String, ResolutionResult> resolutions = new ConcurrentHashMap<>(); |
|
private final Map<Player, PermissionAttachment> attachments = new HashMap<>(); |
|
private final Map<Player, Map<String, Boolean>> persistent = new HashMap<>(); |
|
// private final Map<Player, Map<String, Boolean>> temporary = new HashMap<>(); |
|
private final Set<CommandSender> debug = new HashSet<>(); |
|
public void recalculateOnlinePlayers() |
|
{ |
|
resolutions.clear(); |
|
updateQueue.addAll(Tools.getOnlinePlayers()); |
|
rscp.scheduleAutoUpdate(); |
|
} |
|
public void recalculatePlayer(Player player) |
|
{ |
|
try |
|
{ |
|
updateQueue.put(player); |
|
} catch(InterruptedException ex) { |
|
} |
|
} |
|
public ResolutionResult getResult(String playerIdentifier) |
|
{ |
|
return resolutions.containsKey(playerIdentifier) |
|
? resolutions.get(playerIdentifier) |
|
: resolvePlayerIdentifier(playerIdentifier); |
|
} |
|
public ResolutionResult getResult(OfflinePlayer offline) |
|
{ |
|
final String key = offline.toString(); |
|
return resolutions.containsKey(key) |
|
? resolutions.get(key) |
|
: resolveOfflinePlayer(offline); |
|
} |
|
public ResolutionResult getResult(Player player) |
|
{ |
|
final String key = player.toString(); |
|
return resolutions.containsKey(key) |
|
? resolutions.get(key) |
|
: resolvePlayer(player); |
|
} |
|
public Map<String, Boolean> listPlayerPermissions(Player player) |
|
{ |
|
final PermissionAttachment attachment = rscp.permissionManager.attachments.get(player); |
|
if(attachment != null) |
|
return attachment.getPermissions(); |
|
return Collections.EMPTY_MAP; |
|
} |
|
public void removePlayer(Player player) |
|
{ |
|
updateQueue.remove(player); |
|
attachments.remove(player); |
|
persistent.remove(player); |
|
// temporary.remove(player); |
|
synchronized(debug) |
|
{ |
|
debug.remove(player); |
|
} |
|
} |
|
@Override |
|
public void run() |
|
{ |
|
Thread.currentThread().setName("rscp:" + this.getClass().getSimpleName()); |
|
Thread.currentThread().setPriority(Thread.MIN_PRIORITY); |
|
try |
|
{ |
|
for(Player current = updateQueue.take(); current != null; current = updateQueue.take()) |
|
{ |
|
final ResolutionResult result = rscp.permissionManager.resolvePlayer(current); |
|
persistent.put(current, result.getPermissions()); |
|
final Player player = current; |
|
rscp.getServer().getScheduler().runTask(rscp, new Runnable() |
|
{ |
|
@Override |
|
public void run() |
|
{ |
|
// Remove old |
|
if(attachments.containsKey(player)) |
|
attachments.remove(player).remove(); |
|
// Create new and fill with permissions |
|
final PermissionAttachment attachment = player.addAttachment(rscp); |
|
attachments.put(player, attachment); |
|
final Map<String, Boolean> pp = persistent.get(player); |
|
if(pp != null && !pp.isEmpty()) |
|
for(Map.Entry<String, Boolean> row : pp.entrySet()) |
|
attachment.setPermission(row.getKey(), row.getValue()); |
|
/* |
|
final Map<String, Boolean> tp = temporary.get(player); |
|
if(tp != null && !tp.isEmpty()) |
|
for(Map.Entry<String, Boolean> row : tp.entrySet()) |
|
attachment.setPermission(row.getKey(), row.getValue()); |
|
*/ |
|
// Set/reset Server Operator status |
|
final Boolean asterisk = attachment.getPermissions().get("*"); |
|
if(rscp.settings.isAsteriskOP()) |
|
player.setOp(asterisk != null ? asterisk : false); |
|
// Show debugging information |
|
if(isDebugging(player)) |
|
{ |
|
final String groupList = "{_LG}" + GenericChatCodes.glue(result.getDeorderedGroups(), "{_LS}, {_LG}") + "{_LS}"; |
|
final String permsSize = String.valueOf(attachment.getPermissions().size()); |
|
final String[] lines = new String[] |
|
{ |
|
Phrases.DEBUG_INGAME_1.toString().replace("{:PARENTS}", groupList), |
|
Phrases.DEBUG_INGAME_2.toString().replace("{:PERMISSIONS}", permsSize), |
|
}; |
|
for(String line : lines) |
|
player.sendMessage(GenericChatCodes.processStringStatic(Settings.CHAT_PREFIX + line)); |
|
} |
|
} |
|
}); |
|
} |
|
} catch(InterruptedException ex) { |
|
} |
|
updateQueue.clear(); |
|
} |
|
public synchronized ResolutionResult resolvePlayerIdentifier(String playerIdentifier) |
|
{ |
|
final ResolutionParams params = new ResolutionParams(); |
|
params.applicableIdentifiers = new String[] { playerIdentifier }; |
|
final ResolutionResult result = rscp.internalCache.resolvePlayer(params); |
|
resolutions.put(playerIdentifier, result); |
|
return result; |
|
} |
|
public synchronized ResolutionResult resolveOfflinePlayer(OfflinePlayer offline) |
|
{ |
|
final ResolutionParams params = new ResolutionParams(); |
|
params.applicableIdentifiers = BukkitUtilities.getOfflinePlayerIdentifiers(offline); |
|
final ResolutionResult result = rscp.internalCache.resolvePlayer(params); |
|
for(String id : params.applicableIdentifiers) |
|
resolutions.put(id, result); |
|
resolutions.put(offline.toString(), result); |
|
return result; |
|
} |
|
public synchronized ResolutionResult resolvePlayer(Player player) |
|
{ |
|
final ResolutionParams params = new ResolutionParams(); |
|
params.applicableIdentifiers = BukkitUtilities.getPlayerIdentifiers(player); |
|
if(rscp.regionListProvider != null) |
|
{ |
|
Set<String> regionSet = rscp.regionListProvider.getPlayerRegions(player); |
|
params.destRegions = regionSet.toArray(new String[regionSet.size()]); |
|
} |
|
params.destWorld = player.getLocation().getWorld().getName(); |
|
params.expirience = player.getLevel(); |
|
final ResolutionResult result = rscp.internalCache.resolvePlayer(params); |
|
for(String id : params.applicableIdentifiers) |
|
resolutions.put(id, result); |
|
resolutions.put(player.toString(), result); |
|
return result; |
|
} |
|
public synchronized void forgetOfflinePlayer(OfflinePlayer offline) |
|
{ |
|
for(String id : BukkitUtilities.getOfflinePlayerIdentifiers(offline)) |
|
resolutions.remove(id); |
|
} |
|
public synchronized void forgetPlayer(Player player) |
|
{ |
|
for(String id : BukkitUtilities.getPlayerIdentifiers(player)) |
|
resolutions.remove(id); |
|
} |
|
public Set<CommandSender> getDebuggers() |
|
{ |
|
synchronized(debug) |
|
{ |
|
return new HashSet<>(debug); |
|
} |
|
} |
|
public boolean isConsoleDebugging() |
|
{ |
|
return isDebugging(rscp.getServer().getConsoleSender()); |
|
} |
|
public boolean isDebugging(CommandSender target) |
|
{ |
|
synchronized(debug) |
|
{ |
|
return debug.contains(target); |
|
} |
|
} |
|
public void setDebugging(CommandSender target, boolean value) |
|
{ |
|
synchronized(debug) |
|
{ |
|
if(value) |
|
debug.add(target); |
|
else |
|
debug.remove(target); |
|
} |
|
} |
|
}
|
|
|