mirror of
https://github.com/Xiao-MoMi/Custom-Crops.git
synced 2025-12-19 15:09:25 +00:00
WorldEdit support
This commit is contained in:
@@ -412,4 +412,10 @@ public abstract class AbstractCustomEventListener implements Listener {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onBurn(BlockBurnEvent event) {
|
||||
Block block = event.getBlock();
|
||||
itemManager.handlePhysicsBreak(block.getLocation(), block.getBlockData().getAsString(), event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,8 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
|
||||
protected HashSet<Material> overriddenCrops = new HashSet<>();
|
||||
|
||||
protected boolean worldeditSupport = false;
|
||||
|
||||
public ConfigManager(BukkitCustomCropsPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
instance = this;
|
||||
@@ -188,6 +190,10 @@ public abstract class ConfigManager implements ConfigLoader, Reloadable {
|
||||
return instance.overriddenCrops;
|
||||
}
|
||||
|
||||
public static boolean worldeditSupport() {
|
||||
return instance.worldeditSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public YamlDocument loadConfig(String filePath) {
|
||||
return loadConfig(filePath, '.');
|
||||
|
||||
@@ -18,7 +18,10 @@
|
||||
package net.momirealms.customcrops.api.core.world;
|
||||
|
||||
import com.flowpowered.nbt.CompoundMap;
|
||||
import com.flowpowered.nbt.CompoundTag;
|
||||
import net.momirealms.customcrops.api.core.block.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.util.TagUtils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -44,4 +47,12 @@ public interface CustomCropsBlockState extends DataBlock {
|
||||
static CustomCropsBlockState create(CustomCropsBlock owner, CompoundMap compoundMap) {
|
||||
return new CustomCropsBlockStateImpl(owner, compoundMap);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
static CustomCropsBlockState create(CustomCropsBlock owner, byte[] nbtBytes) {
|
||||
return new CustomCropsBlockStateImpl(owner, ((CompoundTag) TagUtils.fromBytes(nbtBytes)).getValue());
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
byte[] getNBTDataAsBytes();
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
package net.momirealms.customcrops.api.core.world;
|
||||
|
||||
import com.flowpowered.nbt.CompoundMap;
|
||||
import com.flowpowered.nbt.CompoundTag;
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import net.momirealms.customcrops.api.core.SynchronizedCompoundMap;
|
||||
import net.momirealms.customcrops.api.core.block.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.util.TagUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CustomCropsBlockStateImpl implements CustomCropsBlockState {
|
||||
@@ -39,6 +41,11 @@ public class CustomCropsBlockStateImpl implements CustomCropsBlockState {
|
||||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getNBTDataAsBytes() {
|
||||
return TagUtils.toBytes(new CompoundTag("data", compoundMap.originalMap()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag<?> set(String key, Tag<?> tag) {
|
||||
return compoundMap.put(key, tag);
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.api.util;
|
||||
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import com.flowpowered.nbt.stream.NBTInputStream;
|
||||
import com.flowpowered.nbt.stream.NBTOutputStream;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class TagUtils {
|
||||
|
||||
public static Tag<?> fromBytes(byte[] bytes) {
|
||||
try {
|
||||
NBTInputStream nbtInputStream = new NBTInputStream(
|
||||
new ByteArrayInputStream(bytes),
|
||||
NBTInputStream.NO_COMPRESSION,
|
||||
ByteOrder.BIG_ENDIAN
|
||||
);
|
||||
return nbtInputStream.readTag();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toBytes(Tag<?> tag) {
|
||||
try {
|
||||
ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
|
||||
NBTOutputStream outStream = new NBTOutputStream(
|
||||
outByteStream,
|
||||
NBTInputStream.NO_COMPRESSION,
|
||||
ByteOrder.BIG_ENDIAN
|
||||
);
|
||||
outStream.writeTag(tag);
|
||||
return outByteStream.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,14 @@ repositories {
|
||||
maven("https://nexus.betonquest.org/repository/betonquest/") // betonquest
|
||||
maven("https://repo.dmulloy2.net/repository/public/") // betonquest needs packet wrapper?
|
||||
maven("https://oss.sonatype.org/content/repositories/snapshots")
|
||||
maven("https://repo.rapture.pw/repository/maven-releases/") // flow nbt
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":common"))
|
||||
compileOnly(project(":api"))
|
||||
compileOnly("dev.dejvokep:boosted-yaml:${rootProject.properties["boosted_yaml_version"]}")
|
||||
compileOnly("com.flowpowered:flow-nbt:${rootProject.properties["flow_nbt_version"]}")
|
||||
compileOnly("net.kyori:adventure-api:${rootProject.properties["adventure_bundle_version"]}") {
|
||||
exclude(module = "adventure-bom")
|
||||
exclude(module = "checker-qual")
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.bukkit.integration.worldedit;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.core.InternalRegistries;
|
||||
import net.momirealms.customcrops.api.core.block.CustomCropsBlock;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.common.util.Key;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class CustomCropsDelegateExtent extends AbstractDelegateExtent {
|
||||
|
||||
private CustomCropsWorld<?> world = null;
|
||||
|
||||
protected CustomCropsDelegateExtent(EditSessionEvent editSessionEvent) {
|
||||
super(editSessionEvent.getExtent());
|
||||
World weWorld = editSessionEvent.getWorld();
|
||||
if (weWorld == null) return;
|
||||
Optional<CustomCropsWorld<?>> optionalWorld = BukkitCustomCropsPlugin.getInstance().getWorldManager().getWorld(weWorld.getName());
|
||||
optionalWorld.ifPresent(customCropsWorld -> this.world = customCropsWorld);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
|
||||
if (world != null) {
|
||||
BaseBlock baseBlock = block.toBaseBlock();
|
||||
Pos3 pos3 = new Pos3(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
world.removeBlockState(pos3);
|
||||
CompoundTag tag = baseBlock.getNbtData();
|
||||
if (tag != null) {
|
||||
String type = tag.getString("cc_type");
|
||||
if (type != null) {
|
||||
Key key = Key.key(type);
|
||||
CustomCropsBlock customCropsBlock = InternalRegistries.BLOCK.get(key);
|
||||
if (customCropsBlock != null) {
|
||||
byte[] bytes = tag.getByteArray("cc_data");
|
||||
if (bytes != null) {
|
||||
CustomCropsBlockState state = CustomCropsBlockState.create(customCropsBlock, bytes);
|
||||
world.addBlockState(pos3, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.setBlock(location, block);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.bukkit.integration.worldedit;
|
||||
|
||||
public class WorldEditHook {
|
||||
|
||||
private static WorldEditListener listener;
|
||||
private static boolean registered;
|
||||
|
||||
public static void register() {
|
||||
if (registered) return;
|
||||
try {
|
||||
if (listener == null) {
|
||||
listener = new WorldEditListener();
|
||||
}
|
||||
listener.load();
|
||||
registered= true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void unregister() {
|
||||
if (!registered) return;
|
||||
try {
|
||||
if (listener != null) {
|
||||
listener.unload();
|
||||
registered = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) <2024> <XiaoMoMi>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.momirealms.customcrops.bukkit.integration.worldedit;
|
||||
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
import com.sk89q.worldedit.session.SessionManager;
|
||||
import com.sk89q.worldedit.util.eventbus.EventHandler;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import net.momirealms.customcrops.api.BukkitCustomCropsPlugin;
|
||||
import net.momirealms.customcrops.api.core.ConfigManager;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsBlockState;
|
||||
import net.momirealms.customcrops.api.core.world.CustomCropsWorld;
|
||||
import net.momirealms.customcrops.api.core.world.Pos3;
|
||||
import net.momirealms.customcrops.api.util.PluginUtils;
|
||||
import net.momirealms.customcrops.common.plugin.feature.Reloadable;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WorldEditListener implements Reloadable, Listener {
|
||||
|
||||
private Constructor<?> baseBlockConstructor;
|
||||
|
||||
public WorldEditListener() {
|
||||
try {
|
||||
baseBlockConstructor = BaseBlock.class.getDeclaredConstructor(BlockState.class, CompoundTag.class);
|
||||
baseBlockConstructor.setAccessible(true);
|
||||
// if (PluginUtils.isEnabled("FastAsyncWorldEdit")) {
|
||||
// BukkitCustomCropsPlugin.getInstance().getPluginLogger().info("FastAsyncWorldEdit detected. Don't forget to add `" + CustomCropsDelegateExtent.class.getCanonicalName() + "` to allowed-plugins.");
|
||||
// }
|
||||
} catch (ReflectiveOperationException e) {
|
||||
BukkitCustomCropsPlugin.getInstance().getPluginLogger().warn("Not a supported WorldEdit version", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
WorldEdit.getInstance().getEventBus().unregister(this);
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
WorldEdit.getInstance().getEventBus().register(this);
|
||||
Bukkit.getPluginManager().registerEvents(this, BukkitCustomCropsPlugin.getInstance().getBoostrap());
|
||||
}
|
||||
|
||||
@Subscribe(priority = EventHandler.Priority.LATE)
|
||||
public void onEditSession(EditSessionEvent event) {
|
||||
if (!ConfigManager.worldeditSupport()) return;
|
||||
if (event.getStage() != EditSession.Stage.BEFORE_CHANGE) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
event.setExtent(new CustomCropsDelegateExtent(event));
|
||||
} catch (Exception e) {
|
||||
BukkitCustomCropsPlugin.getInstance().debug(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@org.bukkit.event.EventHandler(ignoreCancelled = true)
|
||||
private void onCommand(PlayerCommandPreprocessEvent event) {
|
||||
if (!ConfigManager.worldeditSupport()) return;
|
||||
String string = event.getMessage();
|
||||
if (string.startsWith("//copy")) {
|
||||
Player player = event.getPlayer();
|
||||
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().runLater(() ->
|
||||
updateCopyClipBoard(player), 1, player.getLocation());
|
||||
}
|
||||
|
||||
if (string.startsWith("//cut")) {
|
||||
updateCutClipBoard(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCutClipBoard(Player player) {
|
||||
com.sk89q.worldedit.entity.Player actor = BukkitAdapter.adapt(player);
|
||||
SessionManager manager = WorldEdit.getInstance().getSessionManager();
|
||||
LocalSession localSession = manager.get(actor);
|
||||
World world = actor.getWorld();
|
||||
Region region;
|
||||
try {
|
||||
region = localSession.getRegionSelector(world).getRegion();
|
||||
} catch (IncompleteRegionException e) {
|
||||
return;
|
||||
}
|
||||
Optional<CustomCropsWorld<?>> optionalWorld = BukkitCustomCropsPlugin.getInstance().getWorldManager().getWorld(world.getName());
|
||||
if (optionalWorld.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
CustomCropsWorld<?> customWorld = optionalWorld.get();
|
||||
|
||||
HashMap<BlockVector3, CustomCropsBlockState> tempMap = new HashMap<>();
|
||||
|
||||
BlockVector3 maxPoint = region.getMaximumPoint();
|
||||
BlockVector3 minPoint = region.getMinimumPoint();
|
||||
int minX = Math.min(minPoint.getBlockX(), maxPoint.getBlockX());
|
||||
int minY = Math.min(minPoint.getBlockY(), maxPoint.getBlockY());
|
||||
int minZ = Math.min(minPoint.getBlockZ(), maxPoint.getBlockZ());
|
||||
int maxX = Math.max(maxPoint.getBlockX(), minPoint.getBlockX());
|
||||
int maxY = Math.max(maxPoint.getBlockY(), minPoint.getBlockY());
|
||||
int maxZ = Math.max(maxPoint.getBlockZ(), minPoint.getBlockZ());
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
Pos3 pos3 = new Pos3(x, y, z);
|
||||
BlockVector3 vector3 = BlockVector3.at(x, y, z);
|
||||
Optional<CustomCropsBlockState> optionalState = customWorld.getBlockState(pos3);
|
||||
optionalState.ifPresent(customCropsBlockState -> tempMap.put(vector3, customCropsBlockState));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BukkitCustomCropsPlugin.getInstance().getScheduler().sync().runLater(() -> {
|
||||
ClipboardHolder holder;
|
||||
try {
|
||||
holder = localSession.getClipboard();
|
||||
} catch (EmptyClipboardException e) {
|
||||
return;
|
||||
}
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
for (Map.Entry<BlockVector3, CustomCropsBlockState> entry : tempMap.entrySet()) {
|
||||
BaseBlock baseBlock = clipboard.getFullBlock(entry.getKey());
|
||||
CustomCropsBlockState state = entry.getValue();
|
||||
CompoundTag tag = baseBlock.getNbtData();
|
||||
if (tag != null) {
|
||||
Map<String, Tag> map = tag.getValue();
|
||||
map.put("cc_type", new StringTag(state.type().type().asString()));
|
||||
map.put("cc_data", new ByteArrayTag(state.getNBTDataAsBytes()));
|
||||
} else {
|
||||
try {
|
||||
clipboard.setBlock(entry.getKey(), (BaseBlock) baseBlockConstructor.newInstance(
|
||||
baseBlock.toImmutableState(),
|
||||
new CompoundTag(
|
||||
new HashMap<>(
|
||||
Map.of(
|
||||
"cc_type", new StringTag(state.type().type().asString()),
|
||||
"cc_data", new ByteArrayTag(state.getNBTDataAsBytes())
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
} catch (WorldEditException | InvocationTargetException |
|
||||
InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 1, player.getLocation());
|
||||
}
|
||||
|
||||
public void updateCopyClipBoard(Player player) {
|
||||
com.sk89q.worldedit.entity.Player actor = BukkitAdapter.adapt(player);
|
||||
SessionManager manager = WorldEdit.getInstance().getSessionManager();
|
||||
LocalSession localSession = manager.get(actor);
|
||||
ClipboardHolder holder;
|
||||
try {
|
||||
holder = localSession.getClipboard();
|
||||
} catch (EmptyClipboardException e) {
|
||||
return;
|
||||
}
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
|
||||
Region region = clipboard.getRegion();
|
||||
World world = region.getWorld();
|
||||
if (world == null) return;
|
||||
|
||||
BukkitCustomCropsPlugin.getInstance().getWorldManager().getWorld(world.getName())
|
||||
.ifPresent(customWorld -> {
|
||||
BukkitCustomCropsPlugin.getInstance().getScheduler().async().execute(() -> {
|
||||
BlockVector3 maxPoint = region.getMaximumPoint();
|
||||
BlockVector3 minPoint = region.getMinimumPoint();
|
||||
int minX = Math.min(minPoint.getBlockX(), maxPoint.getBlockX());
|
||||
int minY = Math.min(minPoint.getBlockY(), maxPoint.getBlockY());
|
||||
int minZ = Math.min(minPoint.getBlockZ(), maxPoint.getBlockZ());
|
||||
int maxX = Math.max(maxPoint.getBlockX(), minPoint.getBlockX());
|
||||
int maxY = Math.max(maxPoint.getBlockY(), minPoint.getBlockY());
|
||||
int maxZ = Math.max(maxPoint.getBlockZ(), minPoint.getBlockZ());
|
||||
for (int x = minX; x <= maxX; x++) {
|
||||
for (int y = minY; y <= maxY; y++) {
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
Pos3 pos3 = new Pos3(x, y, z);
|
||||
BlockVector3 vector3 = BlockVector3.at(x, y, z);
|
||||
Optional<CustomCropsBlockState> optionalState = customWorld.getBlockState(pos3);
|
||||
if (optionalState.isPresent()) {
|
||||
BaseBlock baseBlock = clipboard.getFullBlock(vector3);
|
||||
CustomCropsBlockState state = optionalState.get();
|
||||
CompoundTag tag = baseBlock.getNbtData();
|
||||
if (tag != null) {
|
||||
Map<String, Tag> map = tag.getValue();
|
||||
map.put("cc_type", new StringTag(state.type().type().asString()));
|
||||
map.put("cc_data", new ByteArrayTag(state.getNBTDataAsBytes()));
|
||||
} else {
|
||||
try {
|
||||
clipboard.setBlock(vector3, (BaseBlock) baseBlockConstructor.newInstance(
|
||||
baseBlock.toImmutableState(),
|
||||
new CompoundTag(
|
||||
new HashMap<>(
|
||||
Map.of(
|
||||
"cc_type", new StringTag(state.type().type().asString()),
|
||||
"cc_data", new ByteArrayTag(state.getNBTDataAsBytes())
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
} catch (WorldEditException | InvocationTargetException |
|
||||
InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=3.6.4
|
||||
config_version=38
|
||||
project_version=3.6.5
|
||||
config_version=39
|
||||
project_group=net.momirealms
|
||||
|
||||
# Dependency settings
|
||||
|
||||
@@ -33,11 +33,14 @@ import net.momirealms.customcrops.api.misc.HologramManager;
|
||||
import net.momirealms.customcrops.api.misc.cooldown.CoolDownManager;
|
||||
import net.momirealms.customcrops.api.misc.placeholder.BukkitPlaceholderManager;
|
||||
import net.momirealms.customcrops.api.util.EventUtils;
|
||||
import net.momirealms.customcrops.api.util.PluginUtils;
|
||||
import net.momirealms.customcrops.bukkit.action.BlockActionManager;
|
||||
import net.momirealms.customcrops.bukkit.action.PlayerActionManager;
|
||||
import net.momirealms.customcrops.bukkit.command.BukkitCommandManager;
|
||||
import net.momirealms.customcrops.bukkit.config.BukkitConfigManager;
|
||||
import net.momirealms.customcrops.bukkit.integration.BukkitIntegrationManager;
|
||||
import net.momirealms.customcrops.bukkit.integration.worldedit.CustomCropsDelegateExtent;
|
||||
import net.momirealms.customcrops.bukkit.integration.worldedit.WorldEditHook;
|
||||
import net.momirealms.customcrops.bukkit.item.BukkitItemManager;
|
||||
import net.momirealms.customcrops.bukkit.requirement.BlockRequirementManager;
|
||||
import net.momirealms.customcrops.bukkit.requirement.PlayerRequirementManager;
|
||||
@@ -191,21 +194,18 @@ public class BukkitCustomCropsPluginImpl extends BukkitCustomCropsPlugin {
|
||||
});
|
||||
}
|
||||
|
||||
Runnable delayedInitTask = () -> {
|
||||
((SimpleRegistryAccess) registryAccess).freeze();
|
||||
logger.info("Registry access has been frozen");
|
||||
((BukkitItemManager) itemManager).setAntiGriefLib(AntiGriefLib.builder((JavaPlugin) getBoostrap()).silentLogs(true).ignoreOP(true).build());
|
||||
EventUtils.fireAndForget(new CustomCropsReloadEvent(this));
|
||||
};
|
||||
|
||||
// delayed init task
|
||||
if (VersionHelper.isFolia()) {
|
||||
Bukkit.getGlobalRegionScheduler().run(getBoostrap(), (scheduledTask) -> {
|
||||
((SimpleRegistryAccess) registryAccess).freeze();
|
||||
logger.info("Registry access has been frozen");
|
||||
((BukkitItemManager) itemManager).setAntiGriefLib(AntiGriefLib.builder((JavaPlugin) getBoostrap()).silentLogs(true).ignoreOP(true).build());
|
||||
EventUtils.fireAndForget(new CustomCropsReloadEvent(this));
|
||||
});
|
||||
Bukkit.getGlobalRegionScheduler().run(getBoostrap(), (scheduledTask) -> delayedInitTask.run());
|
||||
} else {
|
||||
Bukkit.getScheduler().runTask(getBoostrap(), () -> {
|
||||
((SimpleRegistryAccess) registryAccess).freeze();
|
||||
logger.info("Registry access has been frozen");
|
||||
((BukkitItemManager) itemManager).setAntiGriefLib(AntiGriefLib.builder((JavaPlugin) getBoostrap()).silentLogs(false).ignoreOP(true).build());
|
||||
EventUtils.fireAndForget(new CustomCropsReloadEvent(this));
|
||||
});
|
||||
Bukkit.getScheduler().runTask(getBoostrap(), delayedInitTask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,6 +236,11 @@ public class BukkitCustomCropsPluginImpl extends BukkitCustomCropsPlugin {
|
||||
|
||||
this.worldManager.load();
|
||||
|
||||
if (ConfigManager.worldeditSupport() && PluginUtils.isEnabled("WorldEdit")) {
|
||||
WorldEditHook.register();
|
||||
} else {
|
||||
WorldEditHook.unregister();
|
||||
}
|
||||
EventUtils.fireAndForget(new CustomCropsReloadEvent(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,8 @@ public class BukkitConfigManager extends ConfigManager {
|
||||
preventTrampling = config.getBoolean("mechanics.vanilla-farmland.prevent-trampling", false);
|
||||
disableMoistureMechanic = config.getBoolean("mechanics.vanilla-farmland.disable-moisture-mechanic", false);
|
||||
|
||||
worldeditSupport = config.getBoolean("other-settings.worldedit-support", false);
|
||||
|
||||
offsets.clear();
|
||||
Section section = config.getSection("mechanics.hologram-offset-correction");
|
||||
if (section != null) {
|
||||
|
||||
@@ -57,6 +57,7 @@ public class BukkitIntegrationManager implements IntegrationManager {
|
||||
@Override
|
||||
public void disable() {
|
||||
this.levelerProviders.clear();
|
||||
this.entityProviders.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,6 +127,24 @@ public class BukkitIntegrationManager implements IntegrationManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doesPluginExists(String hooked) {
|
||||
return Bukkit.getPluginManager().getPlugin(hooked) != null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean doesPluginExists(String hooked, String... versionPrefix) {
|
||||
Plugin p = Bukkit.getPluginManager().getPlugin(hooked);
|
||||
if (p != null) {
|
||||
String ver = p.getDescription().getVersion();
|
||||
for (String prefix : versionPrefix) {
|
||||
if (ver.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isHooked(String hooked) {
|
||||
if (Bukkit.getPluginManager().getPlugin(hooked) != null) {
|
||||
plugin.getPluginLogger().info(hooked + " hooked!");
|
||||
|
||||
@@ -141,3 +141,5 @@ other-settings:
|
||||
# Whether to verify if a block/furniture matches the data in CustomCrops
|
||||
# Enable this if using Oraxen, as its API is more reliable
|
||||
double-check: false
|
||||
# Enable WorldEdit support (Experimental)
|
||||
worldedit-support: false
|
||||
|
||||
@@ -16,4 +16,5 @@ softdepend:
|
||||
- RealisticSeasons
|
||||
- AdvancedSeasons
|
||||
- SlimeWorldManager
|
||||
- MythicMobs
|
||||
- MythicMobs
|
||||
- WorldEdit
|
||||
Reference in New Issue
Block a user