From f7fa08d5e922cd79c63a380eba9757ceb0fb32f6 Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 23 Aug 2016 12:10:11 +0100 Subject: [PATCH] Call #recalculatePermissions on the main thread --- .../main/java/me/lucko/luckperms/BukkitListener.java | 7 ++++--- .../main/java/me/lucko/luckperms/users/BukkitUser.java | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java b/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java index a8fafb59..2d054859 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java +++ b/bukkit/src/main/java/me/lucko/luckperms/BukkitListener.java @@ -76,20 +76,21 @@ class BukkitListener extends AbstractListener implements Listener { u.setAttachment(attachment); } - user.refreshPermissions(); + plugin.doAsync(user::refreshPermissions); } @EventHandler public void onPlayerJoin(PlayerJoinEvent e) { // Refresh permissions again plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName()); - refreshPlayer(e.getPlayer().getUniqueId()); + plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId())); } @EventHandler public void onPlayerChangedWorld(PlayerChangedWorldEvent e) { plugin.getUserManager().getWorldCache().put(e.getPlayer().getUniqueId(), e.getPlayer().getWorld().getName()); - refreshPlayer(e.getPlayer().getUniqueId()); + plugin.doAsync(() -> refreshPlayer(e.getPlayer().getUniqueId())); + } @EventHandler diff --git a/bukkit/src/main/java/me/lucko/luckperms/users/BukkitUser.java b/bukkit/src/main/java/me/lucko/luckperms/users/BukkitUser.java index 13a28ccb..70424741 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/users/BukkitUser.java +++ b/bukkit/src/main/java/me/lucko/luckperms/users/BukkitUser.java @@ -71,11 +71,11 @@ public class BukkitUser extends User { 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 toApply = getLocalPermissions(getPlugin().getConfiguration().getServer(), plugin.getUserManager().getWorldCache().get(getUuid()), null); try { - // Existing is thread-safe, hopefully + // The map in the LP PermissionAttachment is a ConcurrentHashMap. We can modify it's contents async. Map existing = (Map) getPermissionsField().get(attachment); boolean different = false; @@ -93,11 +93,13 @@ public class BukkitUser extends User { if (!different) return; - // Faster than recalculating permissions after each PermissionAttachment#setPermission existing.clear(); 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) { e.printStackTrace();