From bba7e70e8c789089eae7ea52170b74cdbc526546 Mon Sep 17 00:00:00 2001 From: SuperRonanCraft Date: Thu, 23 Sep 2021 23:19:30 -0400 Subject: [PATCH] fixed memory leak - players are loaded as they join/leave --- pom.xml | 6 ++ .../SuperRonanCraft/BetterRTP/BetterRTP.java | 5 ++ .../BetterRTP/player/commands/Commands.java | 2 +- .../BetterRTP/player/events/Join.java | 3 +- .../BetterRTP/player/events/Leave.java | 7 +- .../BetterRTP/player/rtp/RTPCooldown.java | 84 ++++++++++--------- .../BetterRTP/player/rtp/RTPDelay.java | 4 +- .../BetterRTP/player/rtp/RTPPlayer.java | 2 +- .../references/worlds/WorldPlayer.java | 8 +- 9 files changed, 71 insertions(+), 50 deletions(-) diff --git a/pom.xml b/pom.xml index 5c3c629..7e431ae 100644 --- a/pom.xml +++ b/pom.xml @@ -291,5 +291,11 @@ particle 1.5.1 + + org.projectlombok + lombok + RELEASE + compile + \ No newline at end of file diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java b/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java index affed12..1bc119c 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java @@ -12,8 +12,10 @@ import me.SuperRonanCraft.BetterRTP.references.invs.RTPInventories; import me.SuperRonanCraft.BetterRTP.references.settings.Settings; import me.SuperRonanCraft.BetterRTP.references.web.Metrics; import me.SuperRonanCraft.BetterRTP.references.Updater; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import java.util.List; @@ -95,6 +97,9 @@ public class BetterRTP extends JavaPlugin { invs.closeAll(); loadAll(); text.getReload(sendi); + //Reload all players cooldowns + for (Player p : Bukkit.getOnlinePlayers()) + getCmd().cooldowns.loadPlayer(p.getUniqueId()); } public RTPInventories getInvs() { diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/Commands.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/Commands.java index 8ad7af9..10a060f 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/Commands.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/Commands.java @@ -173,7 +173,7 @@ public class Commands { private boolean checkCooldown(CommandSender sendi, Player player) { if (sendi != player || pl.getPerms().getBypassCooldown(player)) { //Bypassing/Forced? return true; - } else if (cooldowns.enabled) { //Cooling down? + } else if (cooldowns.isEnabled()) { //Cooling down? UUID id = player.getUniqueId(); if (cooldowns.exists(id)) { if (cooldowns.locked(id)) { //Infinite cooldown (locked) diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Join.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Join.java index 164d261..2e8e161 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Join.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Join.java @@ -1,9 +1,9 @@ package me.SuperRonanCraft.BetterRTP.player.events; +import me.SuperRonanCraft.BetterRTP.BetterRTP; import me.SuperRonanCraft.BetterRTP.player.rtp.RTP_TYPE; import me.SuperRonanCraft.BetterRTP.references.Updater; import me.SuperRonanCraft.BetterRTP.references.file.FileBasics; -import me.SuperRonanCraft.BetterRTP.BetterRTP; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerJoinEvent; @@ -13,6 +13,7 @@ public class Join { void event(PlayerJoinEvent e) { Player p = e.getPlayer(); updater(p); + getPl().getCmd().cooldowns.loadPlayer(p.getUniqueId()); rtpOnFirstJoin(p); } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Leave.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Leave.java index 9d51da1..03ad393 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Leave.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/events/Leave.java @@ -3,9 +3,14 @@ package me.SuperRonanCraft.BetterRTP.player.events; import me.SuperRonanCraft.BetterRTP.BetterRTP; import org.bukkit.event.player.PlayerQuitEvent; +import java.util.UUID; + class Leave { void event(PlayerQuitEvent e) { - BetterRTP.getInstance().getCmd().rtping.remove(e.getPlayer().getUniqueId()); + BetterRTP pl = BetterRTP.getInstance(); + UUID id = e.getPlayer().getUniqueId(); + pl.getCmd().rtping.remove(id); + pl.getCmd().cooldowns.unloadPlayer(id); } } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPCooldown.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPCooldown.java index 031ec6d..4d641b3 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPCooldown.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPCooldown.java @@ -1,5 +1,6 @@ package me.SuperRonanCraft.BetterRTP.player.rtp; +import lombok.Getter; import me.SuperRonanCraft.BetterRTP.references.file.FileBasics; import me.SuperRonanCraft.BetterRTP.BetterRTP; import org.bukkit.configuration.InvalidConfigurationException; @@ -14,12 +15,13 @@ public class RTPCooldown { private final HashMap cooldowns = new HashMap<>(); //Cooldown timer for each player private HashMap locked = null; //Players locked from rtp'ing ever again - public boolean enabled; + @Getter boolean enabled; private int timer, //Cooldown timer lockedAfter; //Rtp's before being locked public void load() { + configfile = new File(BetterRTP.getInstance().getDataFolder(), "data/cooldowns.yml"); cooldowns.clear(); if (locked != null) locked.clear(); @@ -30,7 +32,6 @@ public class RTPCooldown { lockedAfter = config.getInt("Settings.Cooldown.LockAfter"); if (lockedAfter > 0) locked = new HashMap<>(); - loadFile(); } } @@ -62,7 +63,7 @@ public class RTPCooldown { return false; } - public void remove(UUID id) { + public void removeCooldown(UUID id) { if (!enabled) return; if (lockedAfter > 0) { locked.put(id, locked.getOrDefault(id, 1) - 1); @@ -80,7 +81,11 @@ public class RTPCooldown { private void savePlayer(UUID id, boolean adding, long time, int attempts) { YamlConfiguration config = getFile(); - if (config == null) return; + if (config == null) { + BetterRTP.getInstance().getLogger().severe("Unabled to save cooldown for the players UUID " + id + + ". Cooldown file might have been compromised!"); + return; + } if (adding) { //Add player to file config.set(id.toString() + ".Time", time); if (attempts > 0) @@ -95,50 +100,49 @@ public class RTPCooldown { } } - private YamlConfiguration config; private File configfile; private YamlConfiguration getFile() { - if (config != null) { - return config; - } else { - if (!configfile.exists()) { - try { - configfile.getParentFile().mkdir(); - configfile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } + if (!configfile.exists()) { try { - config = new YamlConfiguration(); - config.load(configfile); - return config; - } catch (IOException | InvalidConfigurationException e) { + configfile.getParentFile().mkdir(); + configfile.createNewFile(); + } catch (IOException e) { e.printStackTrace(); } - return null; + } + try { + YamlConfiguration config = new YamlConfiguration(); + config.load(configfile); + return config; + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + return null; + } + + public void loadPlayer(UUID uuid) { + if (isEnabled()) { + String id = uuid.toString(); + YamlConfiguration config = getFile(); + if (config != null && config.isConfigurationSection(id)) + try { + Long time = config.getLong(id + ".Time"); + cooldowns.put(uuid, time); + if (lockedAfter > 0) { + int attempts = config.getInt(id + ".Attempts"); + locked.put(uuid, attempts); + } + } catch (IllegalArgumentException e) { + BetterRTP.getInstance().getLogger().info("UUID of `" + id + "` is invalid, please delete this!"); + //Bad uuid + } } } - private void loadFile() { - config = null; - configfile = new File(BetterRTP.getInstance().getDataFolder(), "data/cooldowns.yml"); - YamlConfiguration config = getFile(); - if (config != null) - for (String id : config.getKeys(false)) { - try { - UUID uuid = UUID.fromString(id); - Long time = config.getLong(id + ".Time"); - cooldowns.put(uuid, time); - if (lockedAfter > 0) { - int attempts = config.getInt(id + ".Attempts"); - locked.put(uuid, attempts); - } - } catch (IllegalArgumentException e) { - BetterRTP.getInstance().getLogger().info("UUID of `" + id + "` is invalid, please delete this!"); - //Bad uuid - } - } + public void unloadPlayer(UUID uuid) { + cooldowns.remove(uuid); + if (locked != null) + locked.remove(uuid); } } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPDelay.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPDelay.java index d892ef9..b633d10 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPDelay.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPDelay.java @@ -25,7 +25,7 @@ class RTPDelay implements Listener { private void delay(CommandSender sendi, int delay) { getPl().getRTP().getTeleport().beforeTeleportDelay(rtp.getPlayer(), delay); - run = Bukkit.getScheduler().scheduleSyncDelayedTask(BetterRTP.getInstance(), run(sendi, this), delay * 20); + run = Bukkit.getScheduler().scheduleSyncDelayedTask(BetterRTP.getInstance(), run(sendi, this), delay * 20L); if (cancelOnMove || cancelOnDamage) Bukkit.getPluginManager().registerEvents(this, BetterRTP.getInstance()); } @@ -60,7 +60,7 @@ class RTPDelay implements Listener { HandlerList.unregisterAll(this); getPl().getRTP().getTeleport().cancelledTeleport(rtp.getPlayer()); //getPl().getEco().unCharge(rtp.getPlayer(), rtp.pWorld); - getPl().getCmd().cooldowns.remove(rtp.getPlayer().getUniqueId()); + getPl().getCmd().cooldowns.removeCooldown(rtp.getPlayer().getUniqueId()); getPl().getCmd().rtping.put(rtp.getPlayer().getUniqueId(), false); Bukkit.getServer().getPluginManager().callEvent(new RTP_CancelledEvent(rtp.getPlayer())); } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java index 4a35667..d45dccf 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java @@ -75,7 +75,7 @@ public class RTPPlayer { getPl().getText().getFailedNotSafe(sendi, settings.maxAttempts); else getPl().getText().getOtherNotSafe(sendi, settings.maxAttempts, p.getName());*/ - getPl().getCmd().cooldowns.remove(p.getUniqueId()); + getPl().getCmd().cooldowns.removeCooldown(p.getUniqueId()); //getPl().getEco().unCharge(p, pWorld); getPl().getCmd().rtping.put(p.getUniqueId(), false); } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/worlds/WorldPlayer.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/worlds/WorldPlayer.java index 6bbb7f6..407a4a5 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/worlds/WorldPlayer.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/worlds/WorldPlayer.java @@ -126,9 +126,9 @@ public class WorldPlayer implements RTPWorld { } public Location generateLocation() { - Location loc = null; + Location loc; switch (shape) { - case CIRCLE: //DISABLED UNTIL NEXT PATCH + case CIRCLE: loc = generateRound(getMaxRad(), getMinRad()); break; default: loc = generateSquare(getMaxRad(), getMinRad()); break; @@ -171,8 +171,8 @@ public class WorldPlayer implements RTPWorld { double area = Math.PI * (max - min) * (max + min); //of all the area in this donut double subArea = area * new Random().nextDouble(); //pick a random subset of that area - Double r = Math.sqrt(subArea/Math.PI + min*min); //convert area to radius - double theta = (r - r.intValue()) * 2 * Math.PI; //use the remainder as an angle + double r = Math.sqrt(subArea/Math.PI + min*min); //convert area to radius + double theta = (r - (int) r) * 2 * Math.PI; //use the remainder as an angle // polar to cartesian x = (int) (r * Math.cos(theta));