mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2026-01-04 15:41:38 +00:00
0.0.48
This commit is contained in:
@@ -148,6 +148,8 @@ block:
|
|||||||
# - Use `client-bound-item-data` to safely sync custom block data to clients.
|
# - Use `client-bound-item-data` to safely sync custom block data to clients.
|
||||||
# Documentation: https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/add-new-contents/items/item-data/client-bound-item-data
|
# Documentation: https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/add-new-contents/items/item-data/client-bound-item-data
|
||||||
simplify-adventure-break-check: false
|
simplify-adventure-break-check: false
|
||||||
|
# Similar to the option above, but designed for block placement
|
||||||
|
simplify-adventure-place-check: false
|
||||||
# Whether plugin should predict the next block to break
|
# Whether plugin should predict the next block to break
|
||||||
# This can help improve mining experience to some extent at the cost of performance
|
# This can help improve mining experience to some extent at the cost of performance
|
||||||
predict-breaking:
|
predict-breaking:
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class BlockEventListener implements Listener {
|
|||||||
Location location = block.getLocation();
|
Location location = block.getLocation();
|
||||||
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
|
BukkitServerPlayer serverPlayer = this.plugin.adapt(player);
|
||||||
// double check adventure mode to prevent dupe
|
// double check adventure mode to prevent dupe
|
||||||
if (!FastNMS.INSTANCE.mayBuild(serverPlayer.serverPlayer()) && !serverPlayer.canBreak(LocationUtils.toBlockPos(location))) {
|
if (!FastNMS.INSTANCE.mayBuild(serverPlayer.serverPlayer()) && !serverPlayer.canBreak(LocationUtils.toBlockPos(location), null)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ public class BukkitCustomItem implements CustomItem<ItemStack> {
|
|||||||
private Key id;
|
private Key id;
|
||||||
private Material material;
|
private Material material;
|
||||||
private Key materialKey;
|
private Key materialKey;
|
||||||
|
private ItemSettings settings;
|
||||||
private final List<ItemBehavior> behaviors = new ArrayList<>();
|
private final List<ItemBehavior> behaviors = new ArrayList<>();
|
||||||
private ItemSettings settings = ItemSettings.of();
|
|
||||||
private final List<ItemDataModifier<ItemStack>> modifiers = new ArrayList<>();
|
private final List<ItemDataModifier<ItemStack>> modifiers = new ArrayList<>();
|
||||||
private final List<ItemDataModifier<ItemStack>> clientBoundModifiers = new ArrayList<>();
|
private final List<ItemDataModifier<ItemStack>> clientBoundModifiers = new ArrayList<>();
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ public class BukkitCustomItem implements CustomItem<ItemStack> {
|
|||||||
@Override
|
@Override
|
||||||
public CustomItem<ItemStack> build() {
|
public CustomItem<ItemStack> build() {
|
||||||
this.modifiers.addAll(this.settings.modifiers());
|
this.modifiers.addAll(this.settings.modifiers());
|
||||||
return new BukkitCustomItem(id, materialKey, material, modifiers, clientBoundModifiers, behaviors, settings);
|
return new BukkitCustomItem(this.id, this.materialKey, this.material, this.modifiers, this.clientBoundModifiers, this.behaviors, this.settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,12 +76,12 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
this.debugStickListener = new DebugStickListener(plugin);
|
this.debugStickListener = new DebugStickListener(plugin);
|
||||||
this.itemParser = new ItemParser();
|
this.itemParser = new ItemParser();
|
||||||
this.registerAllVanillaItems();
|
this.registerAllVanillaItems();
|
||||||
if (plugin.hasMod()) {
|
if (plugin.hasMod() && VersionHelper.isVersionNewerThan1_20_5()) {
|
||||||
Class<?> clazz$CustomStreamCodec = ReflectionUtils.getClazz("net.momirealms.craftengine.mod.item.CustomStreamCodec");
|
Class<?> clazz$CustomStreamCodec = ReflectionUtils.getClazz("net.momirealms.craftengine.mod.item.CustomStreamCodec");
|
||||||
if (clazz$CustomStreamCodec != null) {
|
if (clazz$CustomStreamCodec != null) {
|
||||||
Field cProcessor = ReflectionUtils.getDeclaredField(clazz$CustomStreamCodec, Function.class, 0);
|
Field s2cProcessor = ReflectionUtils.getDeclaredField(clazz$CustomStreamCodec, Function.class, 0);
|
||||||
Field sProcessor = ReflectionUtils.getDeclaredField(clazz$CustomStreamCodec, Function.class, 1);
|
Field c2sProcessor = ReflectionUtils.getDeclaredField(clazz$CustomStreamCodec, Function.class, 1);
|
||||||
Function<Object, Object> c = (raw) -> {
|
Function<Object, Object> s2c = (raw) -> {
|
||||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(raw);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(raw);
|
||||||
Item<ItemStack> wrapped = this.wrap(itemStack.clone());
|
Item<ItemStack> wrapped = this.wrap(itemStack.clone());
|
||||||
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
|
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
|
||||||
@@ -99,7 +99,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
return wrapped.getLiteralObject();
|
return wrapped.getLiteralObject();
|
||||||
};
|
};
|
||||||
|
|
||||||
Function<Object, Object> s = (raw) -> {
|
Function<Object, Object> c2s = (raw) -> {
|
||||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(raw);
|
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(raw);
|
||||||
Item<ItemStack> wrapped = this.wrap(itemStack);
|
Item<ItemStack> wrapped = this.wrap(itemStack);
|
||||||
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
|
Optional<CustomItem<ItemStack>> customItem = wrapped.getCustomItem();
|
||||||
@@ -117,10 +117,10 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
return wrapped.getLiteralObject();
|
return wrapped.getLiteralObject();
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
assert cProcessor != null;
|
assert s2cProcessor != null;
|
||||||
cProcessor.set(null, c);
|
s2cProcessor.set(null, s2c);
|
||||||
assert sProcessor != null;
|
assert c2sProcessor != null;
|
||||||
sProcessor.set(null, s);
|
c2sProcessor.set(null, c2s);
|
||||||
} catch (ReflectiveOperationException e) {
|
} catch (ReflectiveOperationException e) {
|
||||||
plugin.logger().warn("Failed to load custom stream codec", e);
|
plugin.logger().warn("Failed to load custom stream codec", e);
|
||||||
}
|
}
|
||||||
@@ -267,7 +267,10 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
|
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
|
||||||
.register(new ResourceKey<>(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
|
.register(new ResourceKey<>(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
|
||||||
|
|
||||||
|
boolean isVanillaItem = id.namespace().equals("minecraft") && Registry.MATERIAL.get(new NamespacedKey(id.namespace(), id.value())) != null;
|
||||||
String materialStringId = (String) section.get("material");
|
String materialStringId = (String) section.get("material");
|
||||||
|
if (isVanillaItem)
|
||||||
|
materialStringId = id.value();
|
||||||
if (materialStringId == null) {
|
if (materialStringId == null) {
|
||||||
TranslationManager.instance().log("warning.config.item.lack_material", path.toString(), id.toString());
|
TranslationManager.instance().log("warning.config.item.lack_material", path.toString(), id.toString());
|
||||||
return;
|
return;
|
||||||
@@ -284,8 +287,6 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
Key itemModelKey = null;
|
Key itemModelKey = null;
|
||||||
|
|
||||||
CustomItem.Builder<ItemStack> itemBuilder = BukkitCustomItem.builder().id(id).material(materialId);
|
CustomItem.Builder<ItemStack> itemBuilder = BukkitCustomItem.builder().id(id).material(materialId);
|
||||||
itemBuilder.dataModifier(new IdModifier<>(id));
|
|
||||||
|
|
||||||
boolean hasItemModelSection = section.containsKey("item-model");
|
boolean hasItemModelSection = section.containsKey("item-model");
|
||||||
|
|
||||||
// To get at least one model provider
|
// To get at least one model provider
|
||||||
@@ -341,6 +342,10 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add it here to make sure that ce id is always applied
|
||||||
|
if (!isVanillaItem)
|
||||||
|
itemBuilder.dataModifier(new IdModifier<>(id));
|
||||||
|
|
||||||
// Get item data
|
// Get item data
|
||||||
Map<String, Object> clientSideDataSection = MiscUtils.castToMap(section.get("client-bound-data"), true);
|
Map<String, Object> clientSideDataSection = MiscUtils.castToMap(section.get("client-bound-data"), true);
|
||||||
if (clientSideDataSection != null) {
|
if (clientSideDataSection != null) {
|
||||||
@@ -355,10 +360,17 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemSettings itemSettings;
|
||||||
if (section.containsKey("settings")) {
|
if (section.containsKey("settings")) {
|
||||||
Map<String, Object> settings = MiscUtils.castToMap(section.get("settings"), false);
|
Map<String, Object> settings = MiscUtils.castToMap(section.get("settings"), false);
|
||||||
itemBuilder.settings(ItemSettings.fromMap(settings));
|
itemSettings = ItemSettings.fromMap(settings);
|
||||||
|
} else {
|
||||||
|
itemSettings = ItemSettings.of();
|
||||||
}
|
}
|
||||||
|
if (isVanillaItem) {
|
||||||
|
itemSettings.canPlaceRelatedVanillaBlock(true);
|
||||||
|
}
|
||||||
|
itemBuilder.settings(itemSettings);
|
||||||
|
|
||||||
CustomItem<ItemStack> customItem = itemBuilder.build();
|
CustomItem<ItemStack> customItem = itemBuilder.build();
|
||||||
customItems.put(id, customItem);
|
customItems.put(id, customItem);
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ import net.momirealms.craftengine.bukkit.api.event.CustomBlockAttemptPlaceEvent;
|
|||||||
import net.momirealms.craftengine.bukkit.api.event.CustomBlockPlaceEvent;
|
import net.momirealms.craftengine.bukkit.api.event.CustomBlockPlaceEvent;
|
||||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
import net.momirealms.craftengine.bukkit.util.*;
|
||||||
import net.momirealms.craftengine.bukkit.util.EventUtils;
|
|
||||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
|
||||||
import net.momirealms.craftengine.bukkit.util.Reflections;
|
|
||||||
import net.momirealms.craftengine.core.block.CustomBlock;
|
import net.momirealms.craftengine.core.block.CustomBlock;
|
||||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||||
import net.momirealms.craftengine.core.block.UpdateOption;
|
import net.momirealms.craftengine.core.block.UpdateOption;
|
||||||
@@ -22,6 +19,7 @@ import net.momirealms.craftengine.core.item.context.BlockPlaceContext;
|
|||||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||||
import net.momirealms.craftengine.core.pack.Pack;
|
import net.momirealms.craftengine.core.pack.Pack;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||||
import net.momirealms.craftengine.core.world.BlockPos;
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
@@ -81,11 +79,6 @@ public class BlockItemBehavior extends ItemBehavior {
|
|||||||
World world = (World) placeContext.getLevel().platformWorld();
|
World world = (World) placeContext.getLevel().platformWorld();
|
||||||
Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z());
|
Location placeLocation = new Location(world, pos.x(), pos.y(), pos.z());
|
||||||
|
|
||||||
// todo adventure check
|
|
||||||
if (player.isAdventureMode()) {
|
|
||||||
return InteractionResult.FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int gameTicks = player.gameTicks();
|
int gameTicks = player.gameTicks();
|
||||||
if (!player.updateLastSuccessfulInteractionTick(gameTicks)) {
|
if (!player.updateLastSuccessfulInteractionTick(gameTicks)) {
|
||||||
return InteractionResult.FAIL;
|
return InteractionResult.FAIL;
|
||||||
@@ -95,6 +88,22 @@ public class BlockItemBehavior extends ItemBehavior {
|
|||||||
Block againstBlock = world.getBlockAt(againstPos.x(), againstPos.y(), againstPos.z());
|
Block againstBlock = world.getBlockAt(againstPos.x(), againstPos.y(), againstPos.z());
|
||||||
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
|
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) player.platformPlayer();
|
||||||
|
|
||||||
|
if (player.isAdventureMode()) {
|
||||||
|
Object againstBlockState = BlockStateUtils.blockDataToBlockState(againstBlock.getBlockData());
|
||||||
|
int stateId = BlockStateUtils.blockStateToId(againstBlockState);
|
||||||
|
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
||||||
|
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, againstBlockState)) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImmutableBlockState customState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
||||||
|
// custom block
|
||||||
|
if (!AdventureModeUtils.canPlace(context.getItem(), context.getLevel(), againstPos, Config.simplifyAdventurePlaceCheck() ? customState.vanillaBlockState().handle() : againstBlockState)) {
|
||||||
|
return InteractionResult.FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// trigger event
|
// trigger event
|
||||||
CustomBlockAttemptPlaceEvent attemptPlaceEvent = new CustomBlockAttemptPlaceEvent(bukkitPlayer, placeLocation.clone(), blockStateToPlace,
|
CustomBlockAttemptPlaceEvent attemptPlaceEvent = new CustomBlockAttemptPlaceEvent(bukkitPlayer, placeLocation.clone(), blockStateToPlace,
|
||||||
DirectionUtils.toBlockFace(context.getClickedFace()), bukkitBlock, context.getHand());
|
DirectionUtils.toBlockFace(context.getClickedFace()), bukkitBlock, context.getHand());
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.momirealms.craftengine.core.item.ItemWrapper;
|
|||||||
import net.momirealms.craftengine.core.item.modifier.IdModifier;
|
import net.momirealms.craftengine.core.item.modifier.IdModifier;
|
||||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
import net.momirealms.craftengine.core.util.Key;
|
import net.momirealms.craftengine.core.util.Key;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -43,7 +44,10 @@ public abstract class BukkitItemFactory extends ItemFactory<CraftEngine, RTagIte
|
|||||||
@Override
|
@Override
|
||||||
protected Key id(ItemWrapper<ItemStack> item) {
|
protected Key id(ItemWrapper<ItemStack> item) {
|
||||||
Object id = item.get(IdModifier.CRAFT_ENGINE_ID);
|
Object id = item.get(IdModifier.CRAFT_ENGINE_ID);
|
||||||
if (id == null) return Key.of(item.getItem().getType().getKey().asString());
|
if (id == null) {
|
||||||
|
NamespacedKey key = item.getItem().getType().getKey();
|
||||||
|
return Key.of(key.getNamespace(), key.getKey());
|
||||||
|
}
|
||||||
return Key.of(id.toString());
|
return Key.of(id.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1131,14 +1131,14 @@ public class PacketConsumers {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (player.isAdventureMode()) {
|
if (player.isAdventureMode()) {
|
||||||
if (Config.simplifyAdventureCheck()) {
|
if (Config.simplifyAdventureBreakCheck()) {
|
||||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
||||||
if (!player.canBreak(pos, state.vanillaBlockState().handle())) {
|
if (!player.canBreak(pos, state.vanillaBlockState().handle())) {
|
||||||
player.preventMiningBlock();
|
player.preventMiningBlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!player.canBreak(pos)) {
|
if (!player.canBreak(pos, null)) {
|
||||||
player.preventMiningBlock();
|
player.preventMiningBlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,49 +157,13 @@ public class BukkitServerPlayer extends Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBreak(BlockPos pos) {
|
public boolean canBreak(BlockPos pos, @Nullable Object state) {
|
||||||
Item<ItemStack> stackItem = getItemInHand(InteractionHand.MAIN_HAND);
|
return AdventureModeUtils.canBreak(platformPlayer().getInventory().getItemInMainHand(), new Location(platformPlayer().getWorld(), pos.x(), pos.y(), pos.z()), state);
|
||||||
Object itemStack = stackItem == null ? Reflections.instance$ItemStack$EMPTY : stackItem.getLiteralObject();
|
|
||||||
Object blockPos = LocationUtils.toBlockPos(pos);
|
|
||||||
try {
|
|
||||||
Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(level().serverWorld(), blockPos, false);
|
|
||||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
|
||||||
if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
this.plugin.logger().warn("Failed to run canBreak check", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBreak(BlockPos pos, Object state) {
|
@Override
|
||||||
Item<ItemStack> stackItem = getItemInHand(InteractionHand.MAIN_HAND);
|
public boolean canPlace(BlockPos pos, @Nullable Object state) {
|
||||||
Object itemStack = stackItem == null ? Reflections.instance$ItemStack$EMPTY : stackItem.getLiteralObject();
|
return AdventureModeUtils.canPlace(platformPlayer().getInventory().getItemInMainHand(), new Location(platformPlayer().getWorld(), pos.x(), pos.y(), pos.z()), state);
|
||||||
Object blockPos = LocationUtils.toBlockPos(pos);
|
|
||||||
try {
|
|
||||||
Object blockInWorld = Reflections.constructor$BlockInWorld.newInstance(level().serverWorld(), blockPos, false);
|
|
||||||
Reflections.field$BlockInWorld$state.set(blockInWorld, state);
|
|
||||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
|
||||||
if (Reflections.method$ItemStack$canBreakBlockInAdventureMode != null && !(boolean) Reflections.method$ItemStack$canBreakBlockInAdventureMode.invoke(itemStack, blockInWorld)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Reflections.method$ItemStack$canDestroy != null && !(boolean) Reflections.method$ItemStack$canDestroy.invoke(itemStack, Reflections.instance$BuiltInRegistries$BLOCK, blockInWorld)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ReflectiveOperationException e) {
|
|
||||||
this.plugin.logger().warn("Failed to run canBreak check", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -569,7 +533,7 @@ public class BukkitServerPlayer extends Player {
|
|||||||
// can break now
|
// can break now
|
||||||
if (this.miningProgress >= 1f) {
|
if (this.miningProgress >= 1f) {
|
||||||
// for simplified adventure break, switch mayBuild temporarily
|
// for simplified adventure break, switch mayBuild temporarily
|
||||||
if (isAdventureMode() && Config.simplifyAdventureCheck()) {
|
if (isAdventureMode() && Config.simplifyAdventureBreakCheck()) {
|
||||||
// check the appearance state
|
// check the appearance state
|
||||||
if (canBreak(hitPos, customState.vanillaBlockState().handle())) {
|
if (canBreak(hitPos, customState.vanillaBlockState().handle())) {
|
||||||
// Error might occur so we use try here
|
// Error might occur so we use try here
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package net.momirealms.craftengine.bukkit.util;
|
||||||
|
|
||||||
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
|
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||||
|
import net.momirealms.craftengine.core.world.BlockPos;
|
||||||
|
import net.momirealms.craftengine.core.world.World;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
@SuppressWarnings("DuplicatedCode")
|
||||||
|
public class AdventureModeUtils {
|
||||||
|
|
||||||
|
private AdventureModeUtils() {}
|
||||||
|
|
||||||
|
public static boolean canBreak(ItemStack itemStack, Location pos) {
|
||||||
|
return canPlace(itemStack, pos, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canBreak(ItemStack itemStack, Location pos, Object state) {
|
||||||
|
Object blockPos = LocationUtils.toBlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||||
|
Object blockInWorld = FastNMS.INSTANCE.constructor$BlockInWorld(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(pos.getWorld()), blockPos, false);
|
||||||
|
if (state != null) {
|
||||||
|
try {
|
||||||
|
Reflections.field$BlockInWorld$state.set(blockInWorld, state);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to set field$BlockInWorld$state", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FastNMS.INSTANCE.canBreakInAdventureMode(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack), blockInWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canPlace(Item<?> itemStack, World world, BlockPos pos, Object state) {
|
||||||
|
Object blockPos = LocationUtils.toBlockPos(pos);
|
||||||
|
Object item = itemStack == null ? Reflections.instance$ItemStack$Air : itemStack.getLiteralObject();
|
||||||
|
Object blockInWorld = FastNMS.INSTANCE.constructor$BlockInWorld(FastNMS.INSTANCE.field$CraftWorld$ServerLevel((org.bukkit.World) world.platformWorld()), blockPos, false);
|
||||||
|
if (state != null) {
|
||||||
|
try {
|
||||||
|
Reflections.field$BlockInWorld$state.set(blockInWorld, state);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to set field$BlockInWorld$state", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FastNMS.INSTANCE.canPlaceInAdventureMode(item, blockInWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canPlace(ItemStack itemStack, Location pos, Object state) {
|
||||||
|
Object blockPos = LocationUtils.toBlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||||
|
Object blockInWorld = FastNMS.INSTANCE.constructor$BlockInWorld(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(pos.getWorld()), blockPos, false);
|
||||||
|
if (state != null) {
|
||||||
|
try {
|
||||||
|
Reflections.field$BlockInWorld$state.set(blockInWorld, state);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
CraftEngine.instance().logger().warn("Failed to set field$BlockInWorld$state", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FastNMS.INSTANCE.canPlaceInAdventureMode(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack), blockInWorld);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,17 +14,12 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.HumanEntity;
|
import org.bukkit.entity.HumanEntity;
|
||||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
||||||
import org.bukkit.inventory.*;
|
import org.bukkit.inventory.*;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import sun.misc.Unsafe;
|
import sun.misc.Unsafe;
|
||||||
@@ -5780,24 +5775,24 @@ public class Reflections {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final Constructor<?> constructor$BlockInWorld = requireNonNull(
|
// public static final Constructor<?> constructor$BlockInWorld = requireNonNull(
|
||||||
ReflectionUtils.getConstructor(
|
// ReflectionUtils.getConstructor(
|
||||||
clazz$BlockInWorld, 0
|
// clazz$BlockInWorld, 0
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
|
|
||||||
// 1.20.5+
|
// // 1.20.5+
|
||||||
public static final Method method$ItemStack$canBreakBlockInAdventureMode =
|
// public static final Method method$ItemStack$canBreakBlockInAdventureMode =
|
||||||
ReflectionUtils.getMethod(
|
// ReflectionUtils.getMethod(
|
||||||
clazz$ItemStack, new String[]{"canBreakBlockInAdventureMode"}, clazz$BlockInWorld
|
// clazz$ItemStack, new String[]{"canBreakBlockInAdventureMode"}, clazz$BlockInWorld
|
||||||
);
|
// );
|
||||||
|
|
||||||
// 1.20 ~ 1.20.4
|
// // 1.20 ~ 1.20.4
|
||||||
// instance$BuiltInRegistries$BLOCK
|
// // instance$BuiltInRegistries$BLOCK
|
||||||
public static final Method method$ItemStack$canDestroy =
|
// public static final Method method$ItemStack$canDestroy =
|
||||||
ReflectionUtils.getMethod(
|
// ReflectionUtils.getMethod(
|
||||||
clazz$ItemStack,new String[]{"b"}, clazz$Registry, clazz$BlockInWorld
|
// clazz$ItemStack,new String[]{"b"}, clazz$Registry, clazz$BlockInWorld
|
||||||
);
|
// );
|
||||||
|
|
||||||
public static final Method method$BlockStateBase$getBlock = requireNonNull(
|
public static final Method method$BlockStateBase$getBlock = requireNonNull(
|
||||||
ReflectionUtils.getMethod(
|
ReflectionUtils.getMethod(
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ public abstract class Player extends Entity implements NetWorkUser {
|
|||||||
|
|
||||||
public abstract boolean isAdventureMode();
|
public abstract boolean isAdventureMode();
|
||||||
|
|
||||||
public abstract boolean canBreak(BlockPos pos);
|
public abstract boolean canBreak(BlockPos pos, Object state);
|
||||||
|
|
||||||
|
public abstract boolean canPlace(BlockPos pos, Object state);
|
||||||
|
|
||||||
public abstract void sendActionBar(Component text);
|
public abstract void sendActionBar(Component text);
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ public class ComponentModifier<I> implements ItemDataModifier<I> {
|
|||||||
this.arguments = pairs;
|
this.arguments = pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Pair<Key, Object>> arguments() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
private Object parseValue(Object value) {
|
private Object parseValue(Object value) {
|
||||||
if (value instanceof String string) {
|
if (value instanceof String string) {
|
||||||
if (string.startsWith("(json) ")) {
|
if (string.startsWith("(json) ")) {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package net.momirealms.craftengine.core.item.modifier;
|
package net.momirealms.craftengine.core.item.modifier;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
import net.momirealms.craftengine.core.item.ComponentKeys;
|
import net.momirealms.craftengine.core.item.ComponentKeys;
|
||||||
import net.momirealms.craftengine.core.item.Item;
|
import net.momirealms.craftengine.core.item.Item;
|
||||||
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
import net.momirealms.craftengine.core.item.ItemBuildContext;
|
||||||
@@ -7,9 +10,20 @@ import net.momirealms.craftengine.core.util.Key;
|
|||||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
public class IdModifier<I> implements ItemDataModifier<I> {
|
public class IdModifier<I> implements ItemDataModifier<I> {
|
||||||
public static final String CRAFT_ENGINE_ID = "craftengine:id";
|
public static final String CRAFT_ENGINE_ID = "craftengine:id";
|
||||||
|
private static final BiConsumer<Item<?>, String> ID_SETTER = VersionHelper.isVersionNewerThan1_20_5() ?
|
||||||
|
((item, id) -> {
|
||||||
|
JsonElement element = item.getJsonTypeComponent(ComponentKeys.CUSTOM_DATA);
|
||||||
|
if (element instanceof JsonObject jo) {
|
||||||
|
jo.add(CRAFT_ENGINE_ID, new JsonPrimitive(id));
|
||||||
|
item.setComponent(ComponentKeys.CUSTOM_DATA, jo);
|
||||||
|
} else {
|
||||||
|
item.setComponent(ComponentKeys.CUSTOM_DATA, Map.of(CRAFT_ENGINE_ID, id));
|
||||||
|
}
|
||||||
|
}) : ((item, id) -> item.setTag(id, CRAFT_ENGINE_ID));
|
||||||
private final Key argument;
|
private final Key argument;
|
||||||
|
|
||||||
public IdModifier(Key argument) {
|
public IdModifier(Key argument) {
|
||||||
@@ -23,11 +37,7 @@ public class IdModifier<I> implements ItemDataModifier<I> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(Item<I> item, ItemBuildContext context) {
|
public void apply(Item<I> item, ItemBuildContext context) {
|
||||||
if (VersionHelper.isVersionNewerThan1_20_5()) {
|
ID_SETTER.accept(item, argument.toString());
|
||||||
item.setComponent(ComponentKeys.CUSTOM_DATA, Map.of(CRAFT_ENGINE_ID, argument.toString()));
|
|
||||||
} else {
|
|
||||||
item.setTag(argument.toString(), CRAFT_ENGINE_ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ public class TagsModifier<I> implements ItemDataModifier<I> {
|
|||||||
this.arguments = mapToMap(arguments);
|
this.arguments = mapToMap(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> arguments() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String name() {
|
||||||
return "tags";
|
return "tags";
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ public class Config {
|
|||||||
|
|
||||||
protected boolean block$sound_system$enable;
|
protected boolean block$sound_system$enable;
|
||||||
protected boolean block$simplify_adventure_break_check;
|
protected boolean block$simplify_adventure_break_check;
|
||||||
|
protected boolean block$simplify_adventure_place_check;
|
||||||
protected boolean block$predict_breaking;
|
protected boolean block$predict_breaking;
|
||||||
protected int block$predict_breaking_interval;
|
protected int block$predict_breaking_interval;
|
||||||
protected double block$extended_interaction_range;
|
protected double block$extended_interaction_range;
|
||||||
@@ -286,6 +287,7 @@ public class Config {
|
|||||||
// block
|
// block
|
||||||
block$sound_system$enable = config.getBoolean("block.sound-system.enable", true);
|
block$sound_system$enable = config.getBoolean("block.sound-system.enable", true);
|
||||||
block$simplify_adventure_break_check = config.getBoolean("block.simplify-adventure-break-check", false);
|
block$simplify_adventure_break_check = config.getBoolean("block.simplify-adventure-break-check", false);
|
||||||
|
block$simplify_adventure_place_check = config.getBoolean("block.simplify-adventure-place-check", false);
|
||||||
block$predict_breaking = config.getBoolean("block.predict-breaking.enable", true);
|
block$predict_breaking = config.getBoolean("block.predict-breaking.enable", true);
|
||||||
block$predict_breaking_interval = Math.max(config.getInt("block.predict-breaking.interval", 10), 1);
|
block$predict_breaking_interval = Math.max(config.getInt("block.predict-breaking.interval", 10), 1);
|
||||||
block$extended_interaction_range = Math.max(config.getDouble("block.predict-breaking.extended-interaction-range", 0.5), 0.0);
|
block$extended_interaction_range = Math.max(config.getDouble("block.predict-breaking.extended-interaction-range", 0.5), 0.0);
|
||||||
@@ -398,10 +400,14 @@ public class Config {
|
|||||||
return instance.block$sound_system$enable;
|
return instance.block$sound_system$enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean simplifyAdventureCheck() {
|
public static boolean simplifyAdventureBreakCheck() {
|
||||||
return instance.block$simplify_adventure_break_check;
|
return instance.block$simplify_adventure_break_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean simplifyAdventurePlaceCheck() {
|
||||||
|
return instance.block$simplify_adventure_place_check;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean enableRecipeSystem() {
|
public static boolean enableRecipeSystem() {
|
||||||
return instance.recipe$enable;
|
return instance.recipe$enable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Project settings
|
# Project settings
|
||||||
# Rule: [major update].[feature update].[bug fix]
|
# Rule: [major update].[feature update].[bug fix]
|
||||||
project_version=0.0.47.6
|
project_version=0.0.48
|
||||||
config_version=26
|
config_version=26
|
||||||
lang_version=4
|
lang_version=4
|
||||||
project_group=net.momirealms
|
project_group=net.momirealms
|
||||||
@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
|
|||||||
ahocorasick_version=0.6.3
|
ahocorasick_version=0.6.3
|
||||||
snake_yaml_version=2.4
|
snake_yaml_version=2.4
|
||||||
anti_grief_version=0.13
|
anti_grief_version=0.13
|
||||||
nms_helper_version=0.58.7
|
nms_helper_version=0.58.8
|
||||||
# Ignite Dependencies
|
# Ignite Dependencies
|
||||||
mixinextras_version=0.4.1
|
mixinextras_version=0.4.1
|
||||||
mixin_version=0.15.2+mixin.0.8.7
|
mixin_version=0.15.2+mixin.0.8.7
|
||||||
@@ -65,9 +65,9 @@ modmenu_version=13.0.3
|
|||||||
cloth_version=17.0.144
|
cloth_version=17.0.144
|
||||||
|
|
||||||
# Proxy settings
|
# Proxy settings
|
||||||
systemProp.socks.proxyHost=127.0.0.1
|
#systemProp.socks.proxyHost=127.0.0.1
|
||||||
systemProp.socks.proxyPort=7890
|
#systemProp.socks.proxyPort=7890
|
||||||
systemProp.http.proxyHost=127.0.0.1
|
#systemProp.http.proxyHost=127.0.0.1
|
||||||
systemProp.http.proxyPort=7890
|
#systemProp.http.proxyPort=7890
|
||||||
systemProp.https.proxyHost=127.0.0.1
|
#systemProp.https.proxyHost=127.0.0.1
|
||||||
systemProp.https.proxyPort=7890
|
#systemProp.https.proxyPort=7890
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package net.momirealms.craftengine.mod;
|
package net.momirealms.craftengine.mod;
|
||||||
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|||||||
Reference in New Issue
Block a user