Call #recalculatePermissions on the main thread

This commit is contained in:
Luck 2016-08-23 12:10:11 +01:00
parent 7a4135319f
commit f7fa08d5e9
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
2 changed files with 10 additions and 7 deletions

View File

@ -76,20 +76,21 @@ class BukkitListener extends AbstractListener implements Listener {
u.setAttachment(attachment); u.setAttachment(attachment);
} }
user.refreshPermissions(); plugin.doAsync(user::refreshPermissions);
} }
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent e) { public void onPlayerJoin(PlayerJoinEvent e) {
// Refresh permissions again // Refresh permissions again
plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName()); plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName());
refreshPlayer(e.getPlayer().getUniqueId()); plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId()));
} }
@EventHandler @EventHandler
public void onPlayerChangedWorld(PlayerChangedWorldEvent e) { public void onPlayerChangedWorld(PlayerChangedWorldEvent e) {
plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName()); plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName());
refreshPlayer(e.getPlayer().getUniqueId()); plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId()));
} }
@EventHandler @EventHandler

View File

@ -71,11 +71,11 @@ public class BukkitUser extends User {
getPlugin().getLog().severe("User " + getName() + " does not have a permissions attachment defined."); getPlugin().getLog().severe("User " + getName() + " does not have a permissions attachment defined.");
} }
// Calculate the permissions that should be applied // Calculate the permissions that should be applied. This is done async, who cares about how long it takes or how often it's done.
Map<String, Boolean> toApply = getLocalPermissions(getPlugin().getConfiguration().getServer(), plugin.getUserManager().getWorldCache().get(getUuid()), null); Map<String, Boolean> toApply = getLocalPermissions(getPlugin().getConfiguration().getServer(), plugin.getUserManager().getWorldCache().get(getUuid()), null);
try { try {
// Existing is thread-safe, hopefully // The map in the LP PermissionAttachment is a ConcurrentHashMap. We can modify it's contents async.
Map<String, Boolean> existing = (Map<String, Boolean>) getPermissionsField().get(attachment); Map<String, Boolean> existing = (Map<String, Boolean>) getPermissionsField().get(attachment);
boolean different = false; boolean different = false;
@ -93,11 +93,13 @@ public class BukkitUser extends User {
if (!different) return; if (!different) return;
// Faster than recalculating permissions after each PermissionAttachment#setPermission
existing.clear(); existing.clear();
existing.putAll(toApply); existing.putAll(toApply);
attachment.getPermissible().recalculatePermissions(); /* Must be called sync, as #recalculatePermissions is an unmodified Bukkit API call that is absolutely not thread safe.
Shouldn't be too taxing on the server. This only gets called when permissions have actually changed,
which is like once per user per login, assuming their permissions don't get modified. */
plugin.doSync(() -> attachment.getPermissible().recalculatePermissions());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();