1
0
mirror of https://github.com/Zrips/Jobs.git synced 2024-11-22 10:36:10 +01:00

Second pass for block protection

Separation of block place and breaking when it comes to global timers
This commit is contained in:
Zrips 2024-06-27 16:41:47 +03:00
parent 48e67d0426
commit 06c714b363
7 changed files with 215 additions and 70 deletions

Binary file not shown.

View File

@ -295,6 +295,7 @@ public final class Jobs extends JavaPlugin {
return loging;
}
@Deprecated
public static BlockProtectionManager getBpManager() {
if (bpManager == null)
bpManager = new BlockProtectionManager();
@ -1043,8 +1044,12 @@ public final class Jobs extends JavaPlugin {
List<JobProgression> progression = jPlayer.getJobProgression();
int numjobs = progression.size();
if (!Jobs.getGCManager().useBlockProtectionBlockTracker && !Jobs.getExploitManager().isProtectionValidAddIfNotExists(jPlayer, info, block, true))
CMIDebug.it();
if (!Jobs.getGCManager().useBlockProtectionBlockTracker && !Jobs.getExploitManager().isProtectionValidAddIfNotExists(jPlayer, info, block, true)) {
CMIDebug.d(CMIDebug.getIT(), "ms");
return;
}
CMIDebug.d(CMIDebug.getIT(), "ms");
// no job
if (numjobs == 0) {

View File

@ -3,7 +3,6 @@ package com.gamingmesh.jobs.commands.list;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
@ -15,8 +14,10 @@ import com.gamingmesh.jobs.container.BlockProtection;
import com.gamingmesh.jobs.container.DBAction;
import com.gamingmesh.jobs.i18n.Language;
import net.Zrips.CMILib.Container.CMINumber;
import net.Zrips.CMILib.Items.CMIMaterial;
import net.Zrips.CMILib.Locale.LC;
import net.Zrips.CMILib.Logs.CMIDebug;
import net.Zrips.CMILib.Messages.CMIMessages;
import net.Zrips.CMILib.Version.Version;
import net.Zrips.CMILib.Version.Schedulers.CMIScheduler;
@ -42,6 +43,19 @@ public class bp implements Cmd {
final List<Block> changedBlocks = new ArrayList<>();
if (Jobs.getGCManager().useNewBlockProtection) {
// if (Version.isTestServer()) {
// CMIDebug.d("Filling test blocks");
// for (int x = 0; x < 16; x++) {
// for (int y = 72; y < 150; y++) {
// for (int z = 0; z < 16; z++) {
// Block block = loc.getChunk().getBlock(x, y, z);
// Jobs.getExploitManager().addProtection(block, CMINumber.random(1, 10));
// }
// }
// }
// }
for (int x = -10; x < 10; x++) {
for (int y = -10; y < 10; y++) {
for (int z = -10; z < 10; z++) {
@ -58,10 +72,9 @@ public class bp implements Cmd {
changedBlocks.add(l.getBlock());
if (Version.isCurrentEqualOrHigher(Version.v1_15_R1)) {
player.sendBlockChange(l, (time == -1 ? CMIMaterial.BLACK_STAINED_GLASS : CMIMaterial.WHITE_STAINED_GLASS)
.getMaterial().createBlockData());
player.sendBlockChange(l, (time == -1 ? CMIMaterial.BLACK_STAINED_GLASS : CMIMaterial.WHITE_STAINED_GLASS).getMaterial().createBlockData());
} else {
if (time == -1)
if (time == -1)
player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 15);
else
player.sendBlockChange(l, CMIMaterial.RED_STAINED_GLASS.getMaterial(), (byte) 0);

View File

@ -222,19 +222,16 @@ public class BlockProtectionManager {
return (int) Math.floor(x / 32D) + ":" + (int) Math.floor(z / 32D);
}
@Deprecated
public Integer getBlockDelayTime(Block block) {
Integer time = Jobs.getRestrictedBlockManager().restrictedBlocksTimer.get(CMIMaterial.get(block));
if (time == null && Jobs.getGCManager().useGlobalTimer) {
time = Jobs.getGCManager().globalblocktimer;
}
return time;
return Jobs.getExploitManager().getBlockProtectionTime(block);
}
@Deprecated
public boolean isInBp(Block block) {
return Jobs.getRestrictedBlockManager().restrictedBlocksTimer.containsKey(CMIMaterial.get(block));
}
public boolean isBpOk(JobsPlayer player, ActionInfo info, Block block, boolean inform) {
if (block == null || !Jobs.getGCManager().useBlockProtection)
return true;
@ -248,7 +245,7 @@ public class BlockProtectionManager {
BlockProtection bp = getBp(block.getLocation());
if (bp != null) {
long time = bp.getTime();
Integer cd = getBlockDelayTime(block);
Integer cd = Jobs.getExploitManager().getBlockProtectionTime(info.getType(), block);
if (time == -1L) {
remove(block);
@ -271,18 +268,14 @@ public class BlockProtectionManager {
add(block, cd);
if ((cd == null || cd == 0) && Jobs.getGCManager().useGlobalTimer) {
add(block, Jobs.getGCManager().globalblocktimer);
}
} else
add(block, Jobs.getExploitManager().getBlockProtectionTime(info.getType(), block));
} else if (Jobs.getGCManager().useGlobalTimer) {
add(block, Jobs.getGCManager().globalblocktimer);
}
} else if (info.getType() == ActionType.PLACE) {
BlockProtection bp = getBp(block.getLocation());
if (bp != null) {
Long time = bp.getTime();
Integer cd = getBlockDelayTime(block);
Integer cd = Jobs.getExploitManager().getBlockProtectionTime(info.getType(), block);
if (time != -1L) {
if (time < System.currentTimeMillis() && bp.getAction() != DBAction.DELETE) {
add(block, cd);
@ -307,7 +300,7 @@ public class BlockProtectionManager {
} else
add(block, cd);
} else
add(block, getBlockDelayTime(block));
add(block, Jobs.getExploitManager().getBlockProtectionTime(info.getType(), block));
}
return true;

View File

@ -1,7 +1,13 @@
package com.gamingmesh.jobs.config;
import java.util.HashMap;
import java.util.Set;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.util.Vector;
import com.gamingmesh.jobs.Jobs;
import com.gamingmesh.jobs.container.ActionInfo;
@ -15,12 +21,37 @@ import net.Zrips.CMILib.Container.CMIBlock;
import net.Zrips.CMILib.Container.CMIBlock.Bisect;
import net.Zrips.CMILib.Items.CMIMaterial;
import net.Zrips.CMILib.Logs.CMIDebug;
import net.Zrips.CMILib.PersistentData.CMIBlockPersistentDataContainer;
import net.Zrips.CMILib.PersistentData.CMIChunkPersistentDataContainer;
public class ExploitProtectionManager {
private static final String NAMEGENERAL = "JobsExploitProtection";
private static final String NAMEPAID = "JobsPaidProtection";
private static final String NAMETIME = "Time";
private static final String NAMEPAID = "Paid";
private HashMap<String, HashMap<String, CMIChunkPersistentDataContainer>> map = new HashMap<>();
private CMIChunkPersistentDataContainer getPDC(Block block) {
if (block == null)
return null;
return getPDC(block.getChunk());
}
private CMIChunkPersistentDataContainer getPDC(Chunk chunk) {
if (chunk == null)
return null;
HashMap<String, CMIChunkPersistentDataContainer> world = map.computeIfAbsent(chunk.getWorld().getName(), x -> new HashMap<>());
return world.computeIfAbsent(chunk.getX() + ":" + chunk.getZ(), x -> new CMIChunkPersistentDataContainer(NAMEGENERAL, chunk));
}
public void removePDC(Chunk chunk) {
if (!Jobs.getGCManager().useNewBlockProtection)
return;
HashMap<String, CMIChunkPersistentDataContainer> world = map.get(chunk.getWorld().getName());
if (world == null)
return;
world.remove(chunk.getX() + ":" + chunk.getZ());
}
public void addProtection(Block block, Integer cd) {
@ -50,8 +81,30 @@ public class ExploitProtectionManager {
addProtection(block, cd != -1 ? System.currentTimeMillis() + (cd * 1000) : -1, paid);
}
public ExploitProtection addProtection(Block block, Long protectedUntil, boolean paid) {
private String convertLoc(Location loc) {
return convertLoc(loc.toVector());
}
private String convertLoc(Vector loc) {
return loc.getBlockX() + "." + loc.getBlockY() + "." + loc.getBlockZ();
}
private int shortenLong(long value) {
if (value == -1)
return -1;
return (int) (value / 1000) - 2147483647;
}
private Long deconvertLong(Integer value) {
if (value == null)
return null;
if (value == -1)
return -1L;
return (value + 2147483647L) * 1000L;
}
public ExploitProtection addProtection(Block block, Long protectedUntil, boolean paid) {
// CMIDebug.c("Adding protection ", block.getLocation().toVector());
if (!Jobs.getGCManager().useNewBlockProtection) {
BlockProtection protection = Jobs.getBpManager().addP(block.getLocation(), protectedUntil, paid, true);
@ -64,9 +117,21 @@ public class ExploitProtectionManager {
if (protectedUntil == null || protectedUntil == 0)
return null;
CMIBlockPersistentDataContainer pdc = new CMIBlockPersistentDataContainer(block);
pdc.set(NAMEGENERAL, protectedUntil);
pdc.set(NAMEPAID, paid);
if (block == null)
return null;
CMIChunkPersistentDataContainer pdc = getPDC(block);
if (pdc == null)
return null;
String locString = convertLoc(block.getLocation());
pdc.set(locString, NAMETIME, shortenLong(protectedUntil));
if (!paid)
pdc.set(locString, NAMEPAID, paid);
else
pdc.remove(locString, NAMEPAID);
pdc.save();
ExploitProtection ep = new ExploitProtection(block.getLocation().toVector());
@ -77,7 +142,11 @@ public class ExploitProtectionManager {
}
public void remove(Block block) {
CMIDebug.d("remove protection", block.getType());
if (!Jobs.getGCManager().useNewBlockProtection) {
Jobs.getBpManager().remove(block);
return;
}
// In case double plant was destroyed we should remove both blocks from records
CMIMaterial cmat = CMIMaterial.get(block);
switch (cmat) {
@ -94,9 +163,9 @@ CMIDebug.d("remove protection", block.getType());
return;
}
CMIBlockPersistentDataContainer pdc = new CMIBlockPersistentDataContainer(block);
pdc.remove(NAMEGENERAL);
pdc.remove(NAMEPAID);
CMIChunkPersistentDataContainer pdc = getPDC(block);
String locString = convertLoc(block.getLocation());
pdc.remove(locString);
pdc.save();
}
@ -105,20 +174,35 @@ CMIDebug.d("remove protection", block.getType());
if (!Jobs.getGCManager().useNewBlockProtection)
return Jobs.getBpManager().getTime(block);
CMIBlockPersistentDataContainer pdc = new CMIBlockPersistentDataContainer(block);
return pdc.getLong(NAMEGENERAL);
CMIChunkPersistentDataContainer pdc = getPDC(block);
String locString = convertLoc(block.getLocation());
return deconvertLong(pdc.getInt(locString, NAMETIME));
}
public Long getTime(Location loc) {
return getTime(loc.getBlock());
}
@Deprecated
public Integer getBlockProtectionTime(Block block) {
Integer time = Jobs.getRestrictedBlockManager().restrictedBlocksTimer.get(CMIMaterial.get(block));
if (time == null && Jobs.getGCManager().useGlobalTimer) {
time = Jobs.getGCManager().globalblocktimer;
return getBlockProtectionTime(ActionType.PLACE, block);
}
public Integer getBlockProtectionTime(ActionType action, Block block) {
switch (action) {
case BREAK:
if (Jobs.getGCManager().useGlobalBreakTimer)
return Jobs.getGCManager().globalBlockBreakTimer;
break;
case PLACE:
Integer time = Jobs.getRestrictedBlockManager().restrictedBlocksTimer.get(CMIMaterial.get(block));
if (time == null && Jobs.getGCManager().useGlobalTimer)
return Jobs.getGCManager().globalblocktimer;
return time == null ? 0 : time;
}
return time;
return 0;
}
public boolean isInProtection(Block block) {
@ -126,8 +210,13 @@ CMIDebug.d("remove protection", block.getType());
}
public void setPaid(Block block, boolean paid) {
CMIBlockPersistentDataContainer pdc = new CMIBlockPersistentDataContainer(block);
pdc.set(NAMEPAID, paid);
// CMIDebug.d("Setting to paid", block.getLocation().toVector());
CMIChunkPersistentDataContainer pdc = getPDC(block);
String locString = convertLoc(block.getLocation());
if (!paid)
pdc.set(locString, NAMEPAID, paid);
else
pdc.remove(locString, NAMEPAID);
pdc.save();
}
@ -135,17 +224,16 @@ CMIDebug.d("remove protection", block.getType());
ExploitProtection ep = new ExploitProtection(block.getLocation().toVector());
CMIBlockPersistentDataContainer pdc = new CMIBlockPersistentDataContainer(block);
ep.setPaid(pdc.getBoolean(NAMEPAID));
ep.setProtectedUntil(pdc.getLong(NAMEGENERAL));
CMIChunkPersistentDataContainer pdc = getPDC(block);
String locString = convertLoc(block.getLocation());
Boolean paidValue = pdc.getBoolean(locString, NAMEPAID);
ep.setPaid(paidValue == null ? true : paidValue);
ep.setProtectedUntil(deconvertLong(pdc.getInt(locString, NAMETIME)));
return ep;
}
public boolean isProtectionValidAddIfNotExists(JobsPlayer player, ActionInfo info, Block block, boolean inform) {
if (!Jobs.getGCManager().useNewBlockProtection)
return Jobs.getBpManager().isBpOk(player, info, block, inform);
@ -178,17 +266,10 @@ CMIDebug.d("remove protection", block.getType());
return false;
}
Integer cd = getBlockProtectionTime(block);
addProtection(block, getBlockProtectionTime(info.getType(), block));
if ((cd == null || cd == 0) && Jobs.getGCManager().useGlobalTimer) {
addProtection(block, Jobs.getGCManager().globalblocktimer);
return true;
}
addProtection(block, cd);
} else if (Jobs.getGCManager().useGlobalTimer) {
addProtection(block, Jobs.getGCManager().globalblocktimer);
} else {
addProtection(block, getBlockProtectionTime(info.getType(), block));
}
} else if (info.getType() == ActionType.PLACE) {
ExploitProtection exploitProtection = getProtection(block);
@ -196,7 +277,7 @@ CMIDebug.d("remove protection", block.getType());
long time = exploitProtection.getProtectedUntil();
Integer cd = getBlockProtectionTime(block);
Integer cd = getBlockProtectionTime(info.getType(), block);
if (time != -1L) {
if (time < System.currentTimeMillis()) {
addProtection(block, cd);
@ -218,9 +299,38 @@ CMIDebug.d("remove protection", block.getType());
} else
addProtection(block, cd);
} else
addProtection(block, getBlockProtectionTime(block));
addProtection(block, getBlockProtectionTime(info.getType(), block));
}
return true;
}
public void cleanChunk(Chunk chunk) {
if (!Jobs.getGCManager().useNewBlockProtection)
return;
// CompletableFuture.supplyAsync(() -> {
try {
CMIDebug.it();
CMIChunkPersistentDataContainer pdc = getPDC(chunk);
Set<NamespacedKey> keys = pdc.getKeys();
for (NamespacedKey one : keys) {
Long time = deconvertLong(pdc.getInt(one.getKey(), NAMETIME));
if (time != null && time < System.currentTimeMillis()) {
pdc.remove(one.getKey());
}
}
pdc.save();
CMIDebug.c(CMIDebug.getIT(), "ms chunk cleanup");
} catch (Throwable e) {
e.printStackTrace();
}
// return null;
// });
}
}

View File

@ -74,7 +74,7 @@ public class GeneralConfigManager {
private String getSelectionTool, DecimalPlacesMoney, DecimalPlacesExp, DecimalPlacesPoints;
public int jobExpiryTime, BlockProtectionDays, FireworkPower, ShootTime, blockOwnershipRange,
globalblocktimer, CowMilkingTimer, InfoUpdateInterval, JobsTopAmount, PlaceholdersPage, ConfirmExpiryTime,
globalblocktimer, globalBlockBreakTimer, CowMilkingTimer, InfoUpdateInterval, JobsTopAmount, PlaceholdersPage, ConfirmExpiryTime,
SegmentCount, BossBarTimer, AutoJobJoinDelay, DBCleaningJobsLvl, DBCleaningUsersDays, BlastFurnacesMaxDefault, SmokersMaxDefault,
levelLossPercentageFromMax, levelLossPercentage, SoundLevelupVolume, SoundLevelupPitch, SoundTitleChangeVolume,
SoundTitleChangePitch, ToplistInScoreboardInterval;
@ -95,7 +95,7 @@ public class GeneralConfigManager {
public boolean ignoreOreGenerators, useBlockProtection, useNewBlockProtection, useNewExploration, useBlockProtectionBlockTracker, enableSchedule, PayForRenaming, PayForEnchantingOnAnvil,
PayForEachCraft, SignsEnabled,
SignsColorizeJobName, ShowToplistInScoreboard, useGlobalTimer, useSilkTouchProtection, UseCustomNames,
SignsColorizeJobName, ShowToplistInScoreboard, useGlobalTimer, useGlobalBreakTimer, useSilkTouchProtection, UseCustomNames,
PreventSlimeSplit, PreventMagmaCubeSplit, PreventHopperFillUps, PreventBrewingStandFillUps, informOnPaymentDisable,
BrowseUseNewLook, payExploringWhenGliding = false, resetExploringData = false, disablePaymentIfMaxLevelReached, disablePaymentIfRiding,
boostedItemsInOffHand = false, boostedItemsInMainHand, boostedArmorItems, boostedItemsSlotSpecific, multiplyBoostedExtraValues, addPermissionBoost,
@ -918,11 +918,19 @@ public class GeneralConfigManager {
+ " once you have broken the block in one place.");
allowBreakPaymentForOreGenerators = c.get("ExploitProtections.General.AllowBreakPaymentForOreGenerators", false);*/
c.addComment("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer", "All blocks will be protected X seconds after player places/breaks it");
useGlobalTimer = c.get("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Use", true);
c.addComment("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Timer", "Time in seconds. This can only be positive number");
globalblocktimer = c.get("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Timer", 3);
globalblocktimer = CMINumber.clamp(globalblocktimer, 1, 99999);
c.addComment("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Place", "All blocks will be protected X seconds after player places it");
useGlobalTimer = c.get("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Place.Use", c.getC().getBoolean("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Use", true));
c.addComment("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Place.Timer",
"Time in seconds. This can only be positive number and no higher than 900",
"If higher timers are needed then it can be defined in restrictedBlocks.yml file for each specific block");
globalblocktimer = c.get("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Place.Timer", c.getC().getInt("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Timer", 3));
globalblocktimer = CMINumber.clamp(globalblocktimer, 1, 900);
useGlobalBreakTimer = c.get("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Break.Use", true);
c.addComment("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Break.Timer",
"Time in seconds. This can only be positive number and no higher than 60",
"This is only to prevent player from placing blocks into same place and getting paid once more");
globalBlockBreakTimer = c.get("ExploitProtections.General.PlaceAndBreak.GlobalBlockTimer.Break.Timer", 3);
globalBlockBreakTimer = CMINumber.clamp(globalBlockBreakTimer, 1, 60);
c.addComment("ExploitProtections.General.PlaceAndBreak.SilkTouchProtection", "Enable silk touch protection.",
"With this enabled players wont get paid for broken blocks from restrictedblocks list with silk touch tool.");

View File

@ -58,6 +58,7 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.StructureGrowEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.inventory.EquipmentSlot;
@ -118,23 +119,38 @@ public class JobsListener implements Listener {
return time > 100;
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onChunkUnload(ChunkUnloadEvent event) {
Jobs.getExploitManager().removePDC(event.getChunk());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onChunkUnload(JobsChunkChangeEvent event) {
Jobs.getExploitManager().cleanChunk(event.getOldChunk());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockFromToEvent(BlockFromToEvent event) {
if (!Jobs.getGCManager().useBlockProtection)
return;
if (!Jobs.getGCManager().ignoreOreGenerators)
return;
if (!Jobs.getGCManager().canPerformActionInWorld(event.getBlock().getWorld()))
return;
// Ignoring air blocks
if (CMIMaterial.isAir(event.getToBlock().getType()))
return;
if (CMIMaterial.isWater(event.getBlock().getType()))
return;
if (Jobs.getGCManager().useNewBlockProtection) {
Jobs.getExploitManager().remove(event.getToBlock());
} else
Jobs.getBpManager().remove(event.getToBlock());
CMIDebug.d(event.getBlock().getType(), event.getToBlock().getType());
Jobs.getExploitManager().remove(event.getToBlock());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)