90 lines
3.6 KiB
Java
90 lines
3.6 KiB
Java
package tc.oc.commons.bukkit.nick;
|
|
|
|
import com.google.common.cache.LoadingCache;
|
|
import com.google.common.collect.ComparisonChain;
|
|
import com.google.common.eventbus.Subscribe;
|
|
import java.lang.ref.WeakReference;
|
|
import javax.inject.Inject;
|
|
import javax.inject.Singleton;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.player.PlayerQuitEvent;
|
|
import tc.oc.api.bukkit.users.BukkitUserStore;
|
|
import tc.oc.api.minecraft.MinecraftService;
|
|
import tc.oc.api.minecraft.servers.LocalServerReconfigureEvent;
|
|
import tc.oc.commons.core.plugin.PluginFacet;
|
|
import tc.oc.commons.core.util.CacheUtils;
|
|
|
|
@Singleton
|
|
public class PlayerOrderCache implements PlayerOrder.Factory, PluginFacet {
|
|
|
|
private final LoadingCache<Player, Integer> prioritiesByPlayer;
|
|
private final LoadingCache<CommandSender, PlayerOrder> comparatorsByViewer;
|
|
|
|
@Inject PlayerOrderCache(IdentityProvider identityProvider, BukkitUserStore userStore, MinecraftService minecraftService) {
|
|
|
|
prioritiesByPlayer = CacheUtils.newWeakKeyCache(player -> userStore
|
|
.getUser(player)
|
|
.minecraft_flair()
|
|
.stream()
|
|
.filter(flair -> minecraftService.getLocalServer().realms().contains(flair.realm))
|
|
.map(flair -> flair.priority)
|
|
.min(Integer::compare)
|
|
.orElse(Integer.MAX_VALUE)
|
|
);
|
|
|
|
comparatorsByViewer = CacheUtils.newWeakKeyCache(strongViewer -> {
|
|
final WeakReference<CommandSender> weakViewer = new WeakReference<>(strongViewer);
|
|
return (a, b) -> {
|
|
// Do not reference strongViewer in here
|
|
final CommandSender viewer = weakViewer.get();
|
|
if(viewer == null) return 0;
|
|
|
|
final Identity aIdentity = identityProvider.currentIdentity(a);
|
|
final Identity bIdentity = identityProvider.currentIdentity(b);
|
|
return ComparisonChain.start()
|
|
.compareTrueFirst(a == viewer, b == viewer)
|
|
.compareTrueFirst(aIdentity.isFriend(viewer), bIdentity.isFriend(viewer))
|
|
.compare(priority(a, aIdentity, viewer), priority(b, bIdentity, viewer))
|
|
.compare(aIdentity.getName(viewer), bIdentity.getName(viewer), String::compareToIgnoreCase)
|
|
.result();
|
|
};
|
|
});
|
|
}
|
|
|
|
private int priority(Player player, Identity identity, CommandSender viewer) {
|
|
if(identity.isDisguised(viewer)) return Integer.MAX_VALUE;
|
|
|
|
final Integer priority = prioritiesByPlayer.getUnchecked(player);
|
|
if(!player.willBeOnline()) {
|
|
prioritiesByPlayer.invalidate(player);
|
|
}
|
|
return priority;
|
|
}
|
|
|
|
@Override
|
|
public PlayerOrder apply(CommandSender viewer) {
|
|
final PlayerOrder order = comparatorsByViewer.getUnchecked(viewer);
|
|
if(viewer instanceof Player && !((Player) viewer).willBeOnline()) {
|
|
comparatorsByViewer.invalidate(viewer);
|
|
}
|
|
return order;
|
|
}
|
|
|
|
@Subscribe
|
|
public void onReconfigure(LocalServerReconfigureEvent event) {
|
|
// Invalidate everything if local realms change
|
|
if(event.getOldConfig() != null && !event.getOldConfig().realms().equals(event.getNewConfig().realms())) {
|
|
prioritiesByPlayer.invalidateAll();
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.MONITOR)
|
|
private void onQuit(PlayerQuitEvent event) {
|
|
prioritiesByPlayer.invalidate(event.getPlayer());
|
|
comparatorsByViewer.invalidate(event.getPlayer());
|
|
}
|
|
}
|