Compare commits

...

14 Commits

Author SHA1 Message Date
Telesphoreo f734830e12
Merge 162c4a80bb into 704f0aaf9b 2024-05-07 19:43:32 -05:00
Intelli 704f0aaf9b Update build version 2024-05-07 17:51:02 -06:00
Intelli 4daaf6cc02 Fixed lookups on legacy data not matching against legacy materials 2024-05-07 14:18:43 -06:00
Intelli 5426e69fb8 Improved hopper logging to prevent infinite attempts on failed pushes
E.g. when a hopper is repeatedly trying to push into a smoker, but no items are actually being transferred
2024-05-07 14:08:59 -06:00
Intelli 6023c21ba9 Fixed hopper pulls performing container validation on source block 2024-05-06 19:19:48 -06:00
Intelli 3e3496ad12 Corrected version references in API v10 documentation 2024-05-06 18:18:56 -06:00
Telesphoreo 162c4a80bb oops, i can't do it that way 2024-04-25 15:19:33 -05:00
Telesphoreo 28d3f0c45d Remove FAWE toggle entirely 2024-04-25 14:59:44 -05:00
Telesphoreo 9fc56831b6 Add missing `replaceBlocks` method 2024-04-25 14:53:08 -05:00
Telesphoreo 53215be7ab Remove jcenter 2024-04-24 15:59:42 -05:00
Telesphoreo ef0ac61616 Fix registering of FAWE for event bus 2024-04-24 15:53:58 -05:00
Telesphoreo a3d9f6d592 fix regular WE logging 2024-04-21 15:58:49 -05:00
Intelli 1f32d871ec
Merge branch 'master' into fix-fawe-logging 2024-04-21 14:09:45 -06:00
Telesphoreo c4350bb0af Fix FAWE logging on newer builds 2024-04-21 14:50:08 -05:00
13 changed files with 224 additions and 86 deletions

View File

@ -41,7 +41,7 @@ Maven
<dependency>
<groupId>net.coreprotect</groupId>
<artifactId>coreprotect</artifactId>
<version>22.2</version>
<version>22.3</version>
<scope>provided</scope>
</dependency>
```

View File

@ -2,12 +2,12 @@ import org.apache.tools.ant.filters.ReplaceTokens
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'com.palantir.git-version' version '0.13.0'
}
group = 'net.coreprotect'
String projectVersion = '22.2'
String projectVersion = '22.3'
String projectBranch = ''
version = projectVersion // `version` might be modified, we don't always want that (e.g. plugin.yml)
description = 'Provides block protection for your server.'
@ -23,17 +23,15 @@ if (System.getenv("BUILD_NUMBER") != null) {
logger.info("Building version $version")
repositories {
jcenter()
maven { url = 'https://hub.spigotmc.org/nexus/content/groups/public/' }
maven { url = 'https://papermc.io/repo/repository/maven-public/' }
maven { url = 'https://repo.papermc.io/repository/maven-public/' }
maven { url = 'https://repo.codemc.org/repository/maven-public/' }
maven { url = 'https://maven.enginehub.org/repo/' }
}
dependencies {
compileOnly('com.sk89q.worldedit:worldedit-bukkit:7.0.0-SNAPSHOT') {
exclude group: 'org.bukkit'
}
implementation(platform("com.intellectualsites.bom:bom-newest:1.44")) // Ref: https://github.com/IntellectualSites/bom
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core")
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit")
compileOnly 'io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT'
implementation 'org.bstats:bstats-bukkit-lite:1.8'
implementation 'com.zaxxer:HikariCP:5.0.1'

View File

@ -25,8 +25,8 @@ logRemoval(String user, BlockState blockState)
## Getting Started
Ensure you're using CoreProtect 21.0 or higher. Add it as an external jar to your plugin in your IDE.
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 21.0).
Ensure you're using CoreProtect 23.0 or higher. Add it as an external jar to your plugin in your IDE.
Alternatively, if using Maven, you can add it via the repository [https://maven.playpro.com](https://maven.playpro.com) (net.coreprotect, 23.0).
The first thing you need to do is get access to CoreProtect. You can do this by using code similar to the following:
@ -49,7 +49,7 @@ private CoreProtectAPI getCoreProtect() {
}
// Check that a compatible version of the API is loaded
if (CoreProtect.APIVersion() < 9) {
if (CoreProtect.APIVersion() < 10) {
return null;
}

31
pom.xml
View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.coreprotect</groupId>
<artifactId>CoreProtect</artifactId>
<version>22.2</version>
<version>22.3</version>
<properties>
<project.branch></project.branch>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -88,11 +88,18 @@
<id>codemc-repo</id>
<url>https://repo.codemc.org/repository/maven-public/</url>
</repository>
<repository>
<id>enginehub-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.intellectualsites.bom</groupId>
<artifactId>bom-newest</artifactId> <!-- Ref: https://github.com/IntellectualSites/bom -->
<version>1.44</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--
paper-api: io.papermc.paper
@ -113,14 +120,18 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.0.0-SNAPSHOT</version>
<groupId>com.fastasyncworldedit</groupId>
<artifactId>FastAsyncWorldEdit-Core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fastasyncworldedit</groupId>
<artifactId>FastAsyncWorldEdit-Bukkit</artifactId>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<artifactId>FastAsyncWorldEdit-Core</artifactId>
<groupId>*</groupId>
</exclusion>
</exclusions>
</dependency>

View File

@ -41,7 +41,6 @@ public class Config extends Language {
public String MYSQL_USERNAME;
public String MYSQL_PASSWORD;
public String LANGUAGE;
public boolean ENABLE_AWE;
public boolean ENABLE_SSL;
public boolean DISABLE_WAL;
public boolean HOVER_EVENTS;
@ -189,7 +188,6 @@ public class Config extends Language {
}
private void readValues() {
this.ENABLE_AWE = this.getBoolean("enable-awe", false);
this.ENABLE_SSL = this.getBoolean("enable-ssl", false);
this.DISABLE_WAL = this.getBoolean("disable-wal", false);
this.HOVER_EVENTS = this.getBoolean("hover-events", true);

View File

@ -101,6 +101,7 @@ public class ConfigHandler extends Queue {
public static ConcurrentHashMap<String, List<ItemStack>> itemsSell = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsBuy = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Object[]> hopperAbort = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Object[]> hopperSuccess = new ConcurrentHashMap<>();
public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
public static Map<String, Integer> lookupType = syncMap();
public static Map<String, Object[]> lookupThrottle = syncMap();

View File

@ -1,12 +1,16 @@
package net.coreprotect.consumer.process;
import java.sql.PreparedStatement;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import net.coreprotect.config.ConfigHandler;
@ -41,6 +45,41 @@ class ContainerTransactionProcess {
ConfigHandler.transactingChest.remove(transactingChestId);
}
}
else if (loggingChestId.startsWith("#hopper")) {
if (force_size == 0 && ConfigHandler.oldContainer.get(loggingChestId).size() == 1 && ConfigHandler.transactingChest.get(transactingChestId).isEmpty()) {
int loopCount = ConfigHandler.loggingChest.get(loggingChestId);
int maxInventorySize = (99 * 54);
try {
Inventory checkInventory = (Inventory) inventory;
maxInventorySize = checkInventory.getSize() * checkInventory.getMaxStackSize();
}
catch (Exception e) {
// use default of 5,346
}
if (loopCount > maxInventorySize) {
ItemStack[] destinationContents = null;
ItemStack movedItem = null;
String hopperPush = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
Object[] hopperPushData = ConfigHandler.hopperSuccess.remove(hopperPush);
if (hopperPushData != null) {
destinationContents = (ItemStack[]) hopperPushData[0];
movedItem = (ItemStack) hopperPushData[1];
}
if (destinationContents != null) {
Set<ItemStack> movedItems = new HashSet<>();
Object[] lastAbort = ConfigHandler.hopperAbort.get(hopperPush);
if (lastAbort != null && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) {
((Set<?>) lastAbort[0]).forEach(itemStack -> movedItems.add((ItemStack) itemStack));
}
movedItems.add(movedItem);
ConfigHandler.hopperAbort.put(hopperPush, new Object[] { movedItems, destinationContents });
}
}
}
}
}
inventories.remove(id);
}

View File

@ -161,6 +161,7 @@ public class ContainerLogger extends Queue {
if (ConfigHandler.blacklist.get(user.toLowerCase(Locale.ROOT)) != null) {
return;
}
boolean success = false;
int slot = 0;
for (ItemStack item : items) {
if (item != null) {
@ -190,10 +191,17 @@ public class ContainerLogger extends Queue {
int data = 0;
int amount = item.getAmount();
ContainerStatement.insert(preparedStmt, batchCount, time, userId, wid, x, y, z, typeId, data, amount, metadata, action, 0);
success = true;
}
}
slot++;
}
if (success && user.equals("#hopper")) {
String hopperPush = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
ConfigHandler.hopperSuccess.remove(hopperPush);
ConfigHandler.hopperAbort.remove(hopperPush);
}
}
catch (Exception e) {
e.printStackTrace();

View File

@ -28,7 +28,7 @@ public final class HopperPullListener {
}
}
ItemStack[] sourceContainer = Util.getContainerState(sourceHolder.getInventory().getContents());
ItemStack[] destinationContainer = Util.getContainerState(destinationHolder.getInventory().getContents());
ItemStack movedItem = item.clone();
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
@ -39,7 +39,7 @@ public final class HopperPullListener {
}
boolean abort = false;
boolean addedInventory = Util.canAddContainer(sourceContainer, movedItem, sourceHolder.getInventory().getMaxStackSize());
boolean addedInventory = Util.canAddContainer(destinationContainer, movedItem, destinationHolder.getInventory().getMaxStackSize());
if (!addedInventory) {
abort = true;
}

View File

@ -19,7 +19,8 @@ import net.coreprotect.utility.Util;
public final class HopperPushListener {
static void processHopperPush(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item) {
String loggingChestId = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ();
Location destinationLocation = destinationHolder.getInventory().getLocation();
String loggingChestId = "#hopper-push." + destinationLocation.getBlockX() + "." + destinationLocation.getBlockY() + "." + destinationLocation.getBlockZ();
Object[] lastAbort = ConfigHandler.hopperAbort.get(loggingChestId);
if (lastAbort != null) {
ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
@ -55,6 +56,9 @@ public final class HopperPushListener {
ConfigHandler.hopperAbort.put(loggingChestId, new Object[] { movedItems, Util.getContainerState(destinationContents) });
return;
}
else {
ConfigHandler.hopperSuccess.put(loggingChestId, new Object[] { destinationContainer, movedItem });
}
List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
if (list != null) {

View File

@ -1039,6 +1039,10 @@ public class Util extends Queue {
name = BukkitAdapter.ADAPTER.parseLegacyName(name);
material = Material.getMaterial(name);
if (material == null) {
material = Material.getMaterial(name, true);
}
}
return material;

View File

@ -1,90 +1,99 @@
package net.coreprotect.worldedit;
import org.bukkit.Bukkit;
import com.sk89q.worldedit.EditSession.Stage;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.eventbus.Subscribe;
import com.sk89q.worldedit.world.World;
import net.coreprotect.CoreProtect;
import net.coreprotect.config.Config;
import net.coreprotect.config.ConfigHandler;
import net.coreprotect.language.Phrase;
import net.coreprotect.language.Selector;
import net.coreprotect.thread.Scheduler;
import net.coreprotect.utility.Chat;
import org.bukkit.Bukkit;
public class CoreProtectEditSessionEvent {
public class CoreProtectEditSessionEvent
{
private static boolean initialized = false;
private static boolean isFAWE = false;
private static CoreProtectEditSessionEvent event = new CoreProtectEditSessionEvent();
public static boolean isInitialized() {
public static boolean isInitialized()
{
return initialized;
}
public static boolean isFAWE() {
public static boolean isFAWE()
{
return isFAWE;
}
public static void register() {
if (isInitialized()) {
public static void register()
{
if (isInitialized())
{
return;
}
try {
if (Bukkit.getServer().getPluginManager().getPlugin("AsyncWorldEdit") == null || Config.getGlobal().ENABLE_AWE) {
WorldEdit.getInstance().getEventBus().register(event);
initialized = true;
ConfigHandler.worldeditEnabled = true;
isFAWE = (Bukkit.getServer().getPluginManager().getPlugin("FastAsyncWorldEdit") != null);
}
try
{
WorldEdit.getInstance().getEventBus().register(new Object()
{
@Subscribe
public void onEditSessionEvent(EditSessionEvent event)
{
if (event.getActor() != null && event.getStage() == Stage.BEFORE_CHANGE)
{
event.setExtent(new CoreProtectLogger(event.getActor(), event.getWorld(), event.getExtent()));
}
}
});
initialized = true;
ConfigHandler.worldeditEnabled = true;
isFAWE = (Bukkit.getServer().getPluginManager().getPlugin("FastAsyncWorldEdit") != null);
}
catch (Exception e) {
catch (Exception e)
{
// Failed to initialize WorldEdit logging
}
Scheduler.runTask(CoreProtect.getInstance(), () -> {
try {
if (isInitialized()) {
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, "WorldEdit", Selector.FIRST));
Scheduler.runTask(CoreProtect.getInstance(), () ->
{
try
{
if (isInitialized())
{
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.FIRST));
}
else {
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, "WorldEdit", Selector.FIRST));
else
{
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.FIRST));
}
}
catch (Exception e) {
catch (Exception e)
{
e.printStackTrace();
}
});
}
public static void unregister() {
if (!isInitialized()) {
public static void unregister()
{
if (!isInitialized())
{
return;
}
try {
try
{
WorldEdit.getInstance().getEventBus().unregister(event);
initialized = false;
ConfigHandler.worldeditEnabled = false;
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, "WorldEdit", Selector.SECOND));
Chat.console(Phrase.build(Phrase.INTEGRATION_SUCCESS, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.SECOND));
}
catch (Exception e) {
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, "WorldEdit", Selector.SECOND));
}
}
@Subscribe
public void wrapForLogging(EditSessionEvent event) {
Actor actor = event.getActor();
World world = event.getWorld();
if (actor != null && event.getStage() == (isFAWE ? Stage.BEFORE_HISTORY : Stage.BEFORE_CHANGE)) {
event.setExtent(new CoreProtectLogger(actor, world, event.getExtent()));
catch (Exception e)
{
Chat.console(Phrase.build(Phrase.INTEGRATION_ERROR, isFAWE() ? "FastAsyncWorldEdit" : "WorldEdit", Selector.SECOND));
}
}
}

View File

@ -1,30 +1,33 @@
package net.coreprotect.worldedit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import net.coreprotect.config.Config;
import net.coreprotect.utility.Util;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
public class CoreProtectLogger extends AbstractDelegateExtent {
public class CoreProtectLogger extends AbstractDelegateExtent
{
private final Actor eventActor;
private final World eventWorld;
private final Extent eventExtent;
protected CoreProtectLogger(Actor actor, World world, Extent extent) {
protected CoreProtectLogger(Actor actor, World world, Extent extent)
{
super(extent);
this.eventActor = actor;
this.eventWorld = world;
@ -32,10 +35,19 @@ public class CoreProtectLogger extends AbstractDelegateExtent {
}
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException
{
org.bukkit.World world = BukkitAdapter.adapt(eventWorld);
if (!Config.getConfig(world).WORLDEDIT) {
return eventExtent.setBlock(position, block);
if (!Config.getConfig(world).WORLDEDIT)
{
if (CoreProtectEditSessionEvent.isFAWE())
{
return eventExtent.setBlock(position.getX(), position.getY(), position.getZ(), block);
}
else
{
return eventExtent.setBlock(position, block);
}
}
BlockState oldBlock = eventExtent.getBlock(position);
@ -48,16 +60,70 @@ public class CoreProtectLogger extends AbstractDelegateExtent {
// e.g. BaseBlock block = eventWorld.getBlock(position);
ItemStack[] containerData = CoreProtectEditSessionEvent.isFAWE() ? null : Util.getContainerContents(oldType, null, location);
if (eventExtent.setBlock(position, block)) {
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
return true;
if (CoreProtectEditSessionEvent.isFAWE())
{
if (eventExtent.setBlock(position.getX(), position.getY(), position.getZ(), block))
{
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
return true;
}
}
else
{
if (eventExtent.setBlock(position, block))
{
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, block, baseBlock, oldType, oldBlock, containerData);
return true;
}
}
return false;
}
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException {
return setBlock(BlockVector3.at(x,y,z), block);
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block) throws WorldEditException
{
return this.setBlock(BlockVector3.at(x, y, z), block);
}
}
@Override
public int replaceBlocks(final Region region, final Mask mask, final Pattern pattern) throws MaxChangedBlocksException
{
org.bukkit.World world = BukkitAdapter.adapt(eventWorld);
if (!Config.getConfig(world).WORLDEDIT)
{
return eventExtent.replaceBlocks(region, mask, pattern);
}
processPatternToBlocks(world, region, pattern);
return eventExtent.replaceBlocks(region, mask, pattern);
}
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException
{
org.bukkit.World world = BukkitAdapter.adapt(eventWorld);
if (!Config.getConfig(world).WORLDEDIT)
{
return eventExtent.setBlocks(region, pattern);
}
processPatternToBlocks(world, region, pattern);
return eventExtent.setBlocks(region, pattern);
}
private void processPatternToBlocks(org.bukkit.World world, Region region, Pattern pattern)
{
for (BlockVector3 position : region.clone())
{
BlockState oldBlock = eventExtent.getBlock(position);
Material oldType = BukkitAdapter.adapt(oldBlock.getBlockType());
Location location = new Location(world, position.getBlockX(), position.getBlockY(), position.getBlockZ());
BaseBlock baseBlock = WorldEditLogger.getBaseBlock(eventExtent, position, location, oldType, oldBlock);
// No clear way to get container content data from within the WorldEdit API
// Data may be available by converting oldBlock.toBaseBlock().getNbtData()
// e.g. BaseBlock block = eventWorld.getBlock(position);
ItemStack[] containerData = CoreProtectEditSessionEvent.isFAWE() ? null : Util.getContainerContents(oldType, null, location);
WorldEditLogger.postProcess(eventExtent, eventActor, position, location, pattern.applyBlock(position), baseBlock, oldType, oldBlock, containerData);
}
}
}