diff --git a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/MojangNames.java b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/MojangNames.java new file mode 100644 index 000000000..1e1b52092 --- /dev/null +++ b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/MojangNames.java @@ -0,0 +1,121 @@ +package vg.civcraft.mc.namelayer; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; +import org.bukkit.Bukkit; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.scheduler.BukkitTask; +import vg.civcraft.mc.civmodcore.serialization.NBTCompound; +import vg.civcraft.mc.civmodcore.util.MapUtils; +import vg.civcraft.mc.namelayer.listeners.AssociationListener; + +public final class MojangNames { + + private static final Map PROFILES = Collections.synchronizedMap( + new TreeMap<>(String.CASE_INSENSITIVE_ORDER)); + private static final String PROFILES_FILE = "mojang.dat"; + private static final long SAVE_DELAY = 20 * 60; // 60 seconds' worth of ticks + private static BukkitTask SAVE_TASK; + + public static void init(final NameLayerPlugin plugin) { + final Path mojangFile = plugin.getResourceFile(PROFILES_FILE).toPath(); + // Load all the profiles that already exist + Bukkit.getScheduler().runTaskAsynchronously( + plugin, () -> load(plugin, mojangFile)); + // Set up a process of saving profiles + SAVE_TASK = Bukkit.getScheduler().runTaskTimerAsynchronously( + plugin, () -> save(plugin, mojangFile), SAVE_DELAY, SAVE_DELAY); + } + + public static void reset(final NameLayerPlugin plugin) { + if (!PROFILES.isEmpty()) { + save(plugin, plugin.getResourceFile(PROFILES_FILE).toPath()); + PROFILES.clear(); + } + if (SAVE_TASK != null) { + SAVE_TASK.cancel(); + SAVE_TASK = null; + } + } + + private static void load(final NameLayerPlugin plugin, final Path file) { + PROFILES.clear(); + try { + final byte[] data = Files.readAllBytes(file); + final NBTCompound nbt = NBTCompound.fromBytes(data); + nbt.getKeys().forEach(key -> PROFILES.put(key, nbt.getUUID(key))); + plugin.info("[MojangNames] Mojang profiles loaded!"); + } + catch (final NoSuchFileException ignored) {} + catch (final IOException exception) { + plugin.warning("[MojangNames] Could not load Mojang profiles!", exception); + } + } + + private static void save(final NameLayerPlugin plugin, final Path file) { + final NBTCompound nbt = new NBTCompound(); + PROFILES.forEach((name, uuid) -> nbt.setUUID(name, uuid)); // Ignore highlighter + final byte[] data = NBTCompound.toBytes(nbt); + try { + Files.write(file, data, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE); + } + catch (final IOException exception) { + plugin.warning("[MojangNames] Could not save Mojang profiles!", exception); + return; + } + plugin.info("[MojangNames] Mojang profiles saved!"); + } + + /** + * Returns the player's uuid based on their Mojang name. + * + * @param name The player's Mojang name. + * @return Returns the player's uuid, or null. + */ + public static UUID getMojangUuid(final String name) { + if (Strings.isNullOrEmpty(name)) { + return null; + } + return PROFILES.get(name); + } + + /** + *

Returns the player's Mojang name based on their uuid.

+ * + *

Note: The name will be lowercase.

+ * + * @param uuid The player's uuid. + * @return Returns the player's Mojang name, or null. + */ + public static String getMojangName(final UUID uuid) { + if (uuid == null) { + return null; + } + return MapUtils.getKeyFromValue(PROFILES, uuid); + } + + /** + * DO NOT USE THIS ANYWHERE OTHER THAN {@link AssociationListener#OnPlayerLogin(PlayerLoginEvent)} + * + * @param uuid The player's uuid. + * @param name The player's Mojang name. + */ + public static void declareMojangName(final UUID uuid, final String name) { + Preconditions.checkNotNull(uuid); + Preconditions.checkArgument(!Strings.isNullOrEmpty(name)); + PROFILES.put(name, uuid); + } + +} diff --git a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/NameLayerPlugin.java b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/NameLayerPlugin.java index c5c160714..3a95d8b4d 100644 --- a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/NameLayerPlugin.java +++ b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/NameLayerPlugin.java @@ -6,12 +6,10 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.logging.Level; - import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; - import vg.civcraft.mc.civmodcore.ACivMod; import vg.civcraft.mc.civmodcore.dao.ManagedDatasource; import vg.civcraft.mc.namelayer.command.CommandHandler; @@ -26,8 +24,8 @@ import vg.civcraft.mc.namelayer.misc.ClassHandler; import vg.civcraft.mc.namelayer.misc.NameCleanser; import vg.civcraft.mc.namelayer.permission.PermissionType; +public class NameLayerPlugin extends ACivMod { -public class NameLayerPlugin extends ACivMod{ private static AssociationList associations; private static BlackList blackList; private static GroupManagerDao groupManagerDao; @@ -55,6 +53,7 @@ public class NameLayerPlugin extends ACivMod{ ClassHandler.Initialize(Bukkit.getServer()); new NameAPI(new GroupManager(), associations); NameCleanser.load(config.getConfigurationSection("name_cleanser")); + MojangNames.init(this); registerListeners(); if (loadGroups){ PermissionType.initialize(); @@ -68,8 +67,8 @@ public class NameLayerPlugin extends ACivMod{ } public void registerListeners(){ - getServer().getPluginManager().registerEvents(new AssociationListener(), this); - getServer().getPluginManager().registerEvents(new PlayerListener(), this); + registerListener(new AssociationListener()); + registerListener(new PlayerListener()); } @Override @@ -88,6 +87,8 @@ public class NameLayerPlugin extends ACivMod{ @Override public void onDisable() { + MojangNames.reset(this); + super.onDisable(); } public static NameLayerPlugin getInstance(){ @@ -229,4 +230,5 @@ public class NameLayerPlugin extends ACivMod{ public static DefaultGroupHandler getDefaultGroupHandler() { return defaultGroupHandler; } + } diff --git a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/gui/PermissionManageGUI.java b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/gui/PermissionManageGUI.java index 3dba28dfc..9a0f94f6c 100644 --- a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/gui/PermissionManageGUI.java +++ b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/gui/PermissionManageGUI.java @@ -1,6 +1,8 @@ package vg.civcraft.mc.namelayer.gui; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.logging.Level; @@ -111,7 +113,10 @@ public class PermissionManageGUI extends AbstractGroupGUI { ClickableInventory ci = new ClickableInventory(54, g.getName()); final List clicks = new ArrayList<>(); final GroupPermission gp = gm.getPermissionforGroup(g); - for (final PermissionType perm : PermissionType.getAllPermissions()) { + + final PermissionType[] permissions = PermissionType.getAllPermissions().toArray(new PermissionType[0]); + Arrays.sort(permissions, Comparator.comparing(PermissionType::getName)); + for (final PermissionType perm : permissions) { ItemStack is = null; Clickable c; final boolean hasPerm = gp.hasPermission(pType, perm); @@ -192,8 +197,8 @@ public class PermissionManageGUI extends AbstractGroupGUI { } clicks.add(c); } - for (int i = 45 * currentPage; i < 45 * (currentPage + 1) - && i < clicks.size(); i++) { + + for (int i = 45 * currentPage; i < 45 * (currentPage + 1) && i < clicks.size(); i++) { ci.setSlot(clicks.get(i), i - (45 * currentPage)); } diff --git a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/listeners/AssociationListener.java b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/listeners/AssociationListener.java index 3ba1e9acc..93741ad0a 100644 --- a/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/listeners/AssociationListener.java +++ b/plugins/namelayer-paper/namelayer-spigot/src/main/java/vg/civcraft/mc/namelayer/listeners/AssociationListener.java @@ -1,15 +1,15 @@ package vg.civcraft.mc.namelayer.listeners; import java.util.UUID; - import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; - +import vg.civcraft.mc.namelayer.MojangNames; import vg.civcraft.mc.namelayer.NameAPI; import vg.civcraft.mc.namelayer.NameLayerPlugin; import vg.civcraft.mc.namelayer.database.AssociationList; @@ -62,14 +62,16 @@ public class AssociationListener implements Listener { @EventHandler(priority = EventPriority.LOWEST) public void OnPlayerLogin(PlayerLoginEvent event) { - String name = associations.getCurrentName(event.getPlayer().getUniqueId()); + final Player player = event.getPlayer(); + MojangNames.declareMojangName(player.getUniqueId(), player.getName()); + String name = associations.getCurrentName(player.getUniqueId()); if (name == null) { - associations.addPlayer(event.getPlayer().getName(), event.getPlayer().getUniqueId()); - name = associations.getCurrentName(event.getPlayer().getUniqueId()); + associations.addPlayer(player.getName(), player.getUniqueId()); + name = associations.getCurrentName(player.getUniqueId()); } if (game != null) - game.setPlayerProfle(event.getPlayer(), name); + game.setPlayerProfle(player, name); } }