1
0
mirror of https://github.com/Zrips/Jobs.git synced 2024-12-01 15:03:36 +01:00

Avoiding memory leaks

This commit is contained in:
Zrips 2022-11-14 14:38:38 +02:00
parent 2bd257b563
commit b79b8a1e9d
3 changed files with 211 additions and 181 deletions

View File

@ -16,6 +16,7 @@ import com.gamingmesh.jobs.container.DBAction;
import net.Zrips.CMILib.Items.CMIMaterial; import net.Zrips.CMILib.Items.CMIMaterial;
import net.Zrips.CMILib.Locale.LC; import net.Zrips.CMILib.Locale.LC;
import net.Zrips.CMILib.Logs.CMIDebug;
import net.Zrips.CMILib.Messages.CMIMessages; import net.Zrips.CMILib.Messages.CMIMessages;
import net.Zrips.CMILib.Version.Version; import net.Zrips.CMILib.Version.Version;
@ -25,73 +26,72 @@ public class bp implements Cmd {
@Override @Override
public boolean perform(Jobs plugin, final CommandSender sender, final String[] args) { public boolean perform(Jobs plugin, final CommandSender sender, final String[] args) {
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
CMIMessages.sendMessage(sender, LC.info_Ingame); CMIMessages.sendMessage(sender, LC.info_Ingame);
return false; return false;
} }
boolean all = false; boolean all = false;
if (args.length > 0 && args[0].equalsIgnoreCase("-a")) if (args.length > 0 && args[0].equalsIgnoreCase("-a"))
all = true; all = true;
final Player player = (Player) sender; final Player player = (Player) sender;
Location loc = player.getLocation(); Location loc = player.getLocation();
final List<Block> changedBlocks = new ArrayList<>(); final List<Block> changedBlocks = new ArrayList<>();
for (int x = -10; x < 10; x++) { for (int x = -10; x < 10; x++) {
for (int y = -10; y < 10; y++) { for (int y = -10; y < 10; y++) {
for (int z = -10; z < 10; z++) { for (int z = -10; z < 10; z++) {
Location l = loc.clone().add(x, y, z); Location l = loc.clone().add(x, y, z);
BlockProtection bp = Jobs.getBpManager().getBp(l); BlockProtection bp = Jobs.getBpManager().getBp(l);
if (bp != null) { if (bp != null) {
Long time = bp.getTime(); Long time = bp.getTime();
if (!all) { if (!all) {
if (bp.getAction() == DBAction.DELETE) if (bp.getAction() == DBAction.DELETE)
continue; continue;
if (time != -1 && time < System.currentTimeMillis()) { if (time != -1 && time < System.currentTimeMillis()) {
Jobs.getBpManager().remove(l); Jobs.getBpManager().remove(l);
continue; continue;
} }
} }
changedBlocks.add(l.getBlock()); changedBlocks.add(l.getBlock());
if (Version.isCurrentEqualOrHigher(Version.v1_15_R1)) { if (Version.isCurrentEqualOrHigher(Version.v1_15_R1)) {
player.sendBlockChange(l, (bp.getAction() == DBAction.DELETE ? player.sendBlockChange(l, (bp.getAction() == DBAction.DELETE ? CMIMaterial.RED_STAINED_GLASS : time == -1 ? CMIMaterial.BLACK_STAINED_GLASS : CMIMaterial.WHITE_STAINED_GLASS)
CMIMaterial.RED_STAINED_GLASS : .getMaterial().createBlockData());
time == -1 ? CMIMaterial.BLACK_STAINED_GLASS : CMIMaterial.WHITE_STAINED_GLASS).getMaterial().createBlockData()); } else {
} else { if (bp.getAction() == DBAction.DELETE)
if (bp.getAction() == DBAction.DELETE) player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 14);
player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 14); else if (time == -1)
else if (time == -1) player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 15);
player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 15); else
else player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 0);
player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 0); }
} }
} }
} }
} }
}
if (changedBlocks.isEmpty()) if (changedBlocks.isEmpty())
sender.sendMessage(Jobs.getLanguage().getMessage("command.bp.output.notFound")); sender.sendMessage(Jobs.getLanguage().getMessage("command.bp.output.notFound"));
else else
sender.sendMessage(Jobs.getLanguage().getMessage("command.bp.output.found", "%amount%", changedBlocks.size())); sender.sendMessage(Jobs.getLanguage().getMessage("command.bp.output.found", "%amount%", changedBlocks.size()));
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
if (Version.isCurrentEqualOrHigher(Version.v1_15_R1)) if (Version.isCurrentEqualOrHigher(Version.v1_15_R1))
for (Block one : changedBlocks) { for (Block one : changedBlocks) {
player.sendBlockChange(one.getLocation(), one.getBlockData()); player.sendBlockChange(one.getLocation(), one.getBlockData());
} }
else else
for (Block one : changedBlocks) { for (Block one : changedBlocks) {
player.sendBlockChange(one.getLocation(), one.getType(), one.getData()); player.sendBlockChange(one.getLocation(), one.getType(), one.getData());
} }
} }
}, 120L); }, 120L);
return true; return true;
} }
} }

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -15,7 +16,6 @@ import com.gamingmesh.jobs.container.DBAction;
import net.Zrips.CMILib.Container.CMIBlock; import net.Zrips.CMILib.Container.CMIBlock;
import net.Zrips.CMILib.Container.CMIBlock.Bisect; import net.Zrips.CMILib.Container.CMIBlock.Bisect;
import net.Zrips.CMILib.Items.CMIMaterial; import net.Zrips.CMILib.Items.CMIMaterial;
import net.Zrips.CMILib.Logs.CMIDebug;
public class BlockProtectionManager { public class BlockProtectionManager {
@ -23,96 +23,108 @@ public class BlockProtectionManager {
private final ConcurrentHashMap<World, ConcurrentHashMap<String, BlockProtection>> tempCache = new ConcurrentHashMap<>(); private final ConcurrentHashMap<World, ConcurrentHashMap<String, BlockProtection>> tempCache = new ConcurrentHashMap<>();
public HashMap<World, HashMap<String, HashMap<String, HashMap<String, BlockProtection>>>> getMap() { public HashMap<World, HashMap<String, HashMap<String, HashMap<String, BlockProtection>>>> getMap() {
return map; return map;
} }
public int getSize() { public int getSize() {
int i = 0; int i = 0;
for (HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> worlds : map.values()) { for (HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> worlds : map.values()) {
for (HashMap<String, HashMap<String, BlockProtection>> regions : worlds.values()) { for (HashMap<String, HashMap<String, BlockProtection>> regions : worlds.values()) {
for (HashMap<String, BlockProtection> chunks : regions.values()) { for (HashMap<String, BlockProtection> chunks : regions.values()) {
i += chunks.size(); i += chunks.size();
} }
} }
} }
return i; return i;
} }
public void add(Block block, Integer cd) { public void add(Block block, Integer cd) {
// Assuming that block is bottom part of flower we will add top part to the record too // Assuming that block is bottom part of flower we will add top part to the record too
CMIMaterial cmat = CMIMaterial.get(block); CMIMaterial cmat = CMIMaterial.get(block);
switch (cmat) { switch (cmat) {
case LILAC: case LILAC:
case SUNFLOWER: case SUNFLOWER:
case ROSE_BUSH: case ROSE_BUSH:
case PEONY: case PEONY:
CMIBlock cmb = new CMIBlock(block); CMIBlock cmb = new CMIBlock(block);
// We are only interested in this being bottom block as this should never trigger for top part of placed block // We are only interested in this being bottom block as this should never trigger for top part of placed block
if (cmb.getBisect().equals(Bisect.BOTTOM)) if (cmb.getBisect().equals(Bisect.BOTTOM))
add(block.getLocation().clone().add(0, 1, 0), cd, true); add(block.getLocation().clone().add(0, 1, 0), cd, true);
break; break;
} }
add(block, cd, true); add(block, cd, true);
} }
public void add(Block block, Integer cd, boolean paid) { public void add(Block block, Integer cd, boolean paid) {
add(block.getLocation(), cd, paid); add(block.getLocation(), cd, paid);
} }
public void add(Location loc, Integer cd) { public void add(Location loc, Integer cd) {
add(loc, cd, true); add(loc, cd, true);
} }
public void add(Location loc, Integer cd, boolean paid) { public void add(Location loc, Integer cd, boolean paid) {
if (cd == null) if (cd == null)
return; return;
if (cd != -1) if (cd != -1)
addP(loc, System.currentTimeMillis() + (cd * 1000), paid, true); addP(loc, System.currentTimeMillis() + (cd * 1000), paid, true);
else else
addP(loc, -1L, paid, true); addP(loc, -1L, paid, true);
} }
public BlockProtection addP(Location loc, Long time, boolean paid, boolean cache) { public BlockProtection addP(Location loc, Long time, boolean paid, boolean cache) {
String v = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> regions = map.getOrDefault(loc.getWorld(), new HashMap<>()); String v = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
String region = locToRegion(loc); HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> regions = map.getOrDefault(loc.getWorld(), new HashMap<>());
HashMap<String, HashMap<String, BlockProtection>> chunks = regions.getOrDefault(region, new HashMap<>());
String chunk = locToChunk(loc); String region = locToRegion(loc);
HashMap<String, BlockProtection> Bpm = chunks.getOrDefault(chunk, new HashMap<>()); HashMap<String, HashMap<String, BlockProtection>> chunks = regions.getOrDefault(region, new HashMap<>());
BlockProtection Bp = Bpm.get(v);
if (Bp == null) String chunk = locToChunk(loc);
Bp = new BlockProtection(DBAction.INSERT, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); HashMap<String, BlockProtection> Bpm = chunks.getOrDefault(chunk, new HashMap<>());
else BlockProtection Bp = Bpm.get(v);
Bp.setAction(DBAction.UPDATE);
Bp.setPaid(paid); if (Bp == null)
Bp.setTime(time); Bp = new BlockProtection(DBAction.INSERT, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
Bpm.put(v, Bp); else {
chunks.put(chunk, Bpm); Bp.setAction(DBAction.UPDATE);
regions.put(region, chunks); if (Bp.getSchedId() > -1)
map.put(loc.getWorld(), regions); Bukkit.getServer().getScheduler().cancelTask(Bp.getSchedId());
if (cache) }
addToCache(loc, Bp);
return Bp; Bp.setPaid(paid);
Bp.setTime(time);
// If timer is under 2 hours, we can run scheduler to remove it when time comes
if ((time - System.currentTimeMillis()) / 1000 < 60 * 60 * 2)
Bp.setSchedId(Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Jobs.getInstance(), () -> {
remove(loc);
}, (time - System.currentTimeMillis()) / 50));
Bpm.put(v, Bp);
chunks.put(chunk, Bpm);
regions.put(region, chunks);
map.put(loc.getWorld(), regions);
// Only saving into save cache if timer is higher than 5 minutes
if (cache && (time - System.currentTimeMillis()) / 1000 > 60 * 5)
addToCache(loc, Bp);
return Bp;
} }
private void addToCache(Location loc, BlockProtection Bp) { private void addToCache(Location loc, BlockProtection Bp) {
if (!Jobs.getGCManager().useBlockProtection) if (!Jobs.getGCManager().useBlockProtection)
return; return;
String v = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ(); String v = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
ConcurrentHashMap<String, BlockProtection> locations = tempCache.get(loc.getWorld()); ConcurrentHashMap<String, BlockProtection> locations = tempCache.get(loc.getWorld());
if (locations == null) { if (locations == null) {
locations = new ConcurrentHashMap<>(); locations = new ConcurrentHashMap<>();
tempCache.put(loc.getWorld(), locations); tempCache.put(loc.getWorld(), locations);
} }
locations.put(v, Bp); locations.put(v, Bp);
// if (locations.size() > 10) { // if (locations.size() > 10) {
// Jobs.getJobsDAO().saveBlockProtection(loc.getWorld().getName(), new HashMap<String, BlockProtection>(locations)); // Jobs.getJobsDAO().saveBlockProtection(loc.getWorld().getName(), new HashMap<String, BlockProtection>(locations));
@ -121,91 +133,100 @@ public class BlockProtectionManager {
} }
public void saveCache() { public void saveCache() {
if (!Jobs.getGCManager().useBlockProtection) if (!Jobs.getGCManager().useBlockProtection)
return; return;
for (Entry<World, ConcurrentHashMap<String, BlockProtection>> one : tempCache.entrySet()) { for (Entry<World, ConcurrentHashMap<String, BlockProtection>> one : tempCache.entrySet()) {
Jobs.getJobsDAO().saveBlockProtection(one.getKey().getName(), one.getValue()); Jobs.getJobsDAO().saveBlockProtection(one.getKey().getName(), one.getValue());
} }
tempCache.clear(); tempCache.clear();
} }
public BlockProtection remove(Block block) { public BlockProtection remove(Block block) {
// In case double plant was destroyed we should remove both blocks from records // In case double plant was destroyed we should remove both blocks from records
CMIMaterial cmat = CMIMaterial.get(block); CMIMaterial cmat = CMIMaterial.get(block);
switch (cmat) { switch (cmat) {
case LILAC: case LILAC:
case SUNFLOWER: case SUNFLOWER:
case ROSE_BUSH: case ROSE_BUSH:
case PEONY: case PEONY:
CMIBlock cmb = new CMIBlock(block); CMIBlock cmb = new CMIBlock(block);
if (cmb.getBisect().equals(Bisect.BOTTOM)) if (cmb.getBisect().equals(Bisect.BOTTOM))
remove(block.getLocation().clone().add(0, 1, 0)); remove(block.getLocation().clone().add(0, 1, 0));
else else
remove(block.getLocation().clone().add(0, -1, 0)); remove(block.getLocation().clone().add(0, -1, 0));
break; break;
} }
return remove(block.getLocation()); return remove(block.getLocation());
} }
public BlockProtection remove(Location loc) { public BlockProtection remove(Location loc) {
HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> world = map.get(loc.getWorld()); HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> world = map.get(loc.getWorld());
if (world == null) if (world == null)
return null; return null;
HashMap<String, HashMap<String, BlockProtection>> region = world.get(locToRegion(loc)); HashMap<String, HashMap<String, BlockProtection>> region = world.get(locToRegion(loc));
if (region == null) if (region == null)
return null; return null;
HashMap<String, BlockProtection> chunk = region.get(locToChunk(loc)); HashMap<String, BlockProtection> chunk = region.get(locToChunk(loc));
if (chunk == null) if (chunk == null)
return null; return null;
String v = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ(); String v = loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ();
BlockProtection bp = chunk.get(v); BlockProtection bp = chunk.get(v);
if (bp != null) if (bp != null)
bp.setAction(DBAction.DELETE); bp.setAction(DBAction.DELETE);
return bp; if (bp != null && bp.getId() < 0) {
chunk.remove(v);
}
if (chunk.isEmpty())
region.remove(locToChunk(loc));
if (region.isEmpty())
world.remove(locToRegion(loc));
return bp;
} }
public Long getTime(Block block) { public Long getTime(Block block) {
return getTime(block.getLocation()); return getTime(block.getLocation());
} }
public Long getTime(Location loc) { public Long getTime(Location loc) {
BlockProtection Bp = getBp(loc); BlockProtection Bp = getBp(loc);
return Bp == null ? null : Bp.getTime(); return Bp == null ? null : Bp.getTime();
} }
public BlockProtection getBp(Location loc) { public BlockProtection getBp(Location loc) {
HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> world = map.get(loc.getWorld()); HashMap<String, HashMap<String, HashMap<String, BlockProtection>>> world = map.get(loc.getWorld());
if (world == null) if (world == null)
return null; return null;
HashMap<String, HashMap<String, BlockProtection>> region = world.get(locToRegion(loc)); HashMap<String, HashMap<String, BlockProtection>> region = world.get(locToRegion(loc));
if (region == null) if (region == null)
return null; return null;
HashMap<String, BlockProtection> chunk = region.get(locToChunk(loc)); HashMap<String, BlockProtection> chunk = region.get(locToChunk(loc));
if (chunk == null) if (chunk == null)
return null; return null;
return chunk.get(loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ()); return chunk.get(loc.getBlockX() + ":" + loc.getBlockY() + ":" + loc.getBlockZ());
} }
private static String locToChunk(Location loc) { private static String locToChunk(Location loc) {
return (int) Math.floor(loc.getBlockX() / 16D) + ":" + (int) Math.floor(loc.getBlockZ() / 16D); return (int) Math.floor(loc.getBlockX() / 16D) + ":" + (int) Math.floor(loc.getBlockZ() / 16D);
} }
private static String locToRegion(Location loc) { private static String locToRegion(Location loc) {
int x = (int) Math.floor(loc.getBlockX() / 16D); int x = (int) Math.floor(loc.getBlockX() / 16D);
int z = (int) Math.floor(loc.getBlockZ() / 16D); int z = (int) Math.floor(loc.getBlockZ() / 16D);
return (int) Math.floor(x / 32D) + ":" + (int) Math.floor(z / 32D); return (int) Math.floor(x / 32D) + ":" + (int) Math.floor(z / 32D);
} }
public Integer getBlockDelayTime(Block block) { public Integer getBlockDelayTime(Block block) {
Integer time = Jobs.getRestrictedBlockManager().restrictedBlocksTimer.get(CMIMaterial.get(block)); Integer time = Jobs.getRestrictedBlockManager().restrictedBlocksTimer.get(CMIMaterial.get(block));
if (time == null && Jobs.getGCManager().useGlobalTimer) { if (time == null && Jobs.getGCManager().useGlobalTimer) {
time = Jobs.getGCManager().globalblocktimer; time = Jobs.getGCManager().globalblocktimer;
} }
return time; return time;
} }
public boolean isInBp(Block block) { public boolean isInBp(Block block) {
return Jobs.getRestrictedBlockManager().restrictedBlocksTimer.containsKey(CMIMaterial.get(block)); return Jobs.getRestrictedBlockManager().restrictedBlocksTimer.containsKey(CMIMaterial.get(block));
} }
} }

View File

@ -6,7 +6,8 @@ public class BlockProtection {
private static long pre = (int) (System.currentTimeMillis() / 10000000000L) * 10000000000L; private static long pre = (int) (System.currentTimeMillis() / 10000000000L) * 10000000000L;
private int id; private int id = -1;
private int schedId = - 1;
private int time = -1; private int time = -1;
private int recorded = -1; private int recorded = -1;
private DBAction action; private DBAction action;
@ -113,4 +114,12 @@ public class BlockProtection {
public int getZ() { public int getZ() {
return z; return z;
} }
public int getSchedId() {
return schedId;
}
public void setSchedId(int schedId) {
this.schedId = schedId;
}
} }