mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 03:49:15 +00:00
尝试添加section注入
This commit is contained in:
@@ -39,10 +39,10 @@ import java.util.*;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent {
|
||||
private static int[] ordinalToIbdID;
|
||||
private final Set<CEChunk> chunksToSave;
|
||||
private final CEWorld ceWorld;
|
||||
private static int[] ordinalToIbdID;
|
||||
private static final Set<ChunkPos> BROKEN_CHUNKS = Collections.synchronizedSet(new HashSet<>());
|
||||
private final Set<ChunkPos> brokenChunks = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
protected FastAsyncWorldEditDelegate(EditSessionEvent event) {
|
||||
super(event.getExtent());
|
||||
@@ -85,7 +85,9 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent {
|
||||
for (int i = 0; i < ceSections.length; i++) {
|
||||
CESection ceSection = ceSections[i];
|
||||
Object section = sections[i];
|
||||
BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z));
|
||||
int finalI = i;
|
||||
BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z),
|
||||
(injected) -> sections[finalI] = injected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,8 +145,8 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent {
|
||||
@Override
|
||||
protected Operation commitBefore() {
|
||||
saveAllChunks();
|
||||
List<ChunkPos> chunks = new ArrayList<>(BROKEN_CHUNKS);
|
||||
BROKEN_CHUNKS.clear();
|
||||
List<ChunkPos> chunks = new ArrayList<>(this.brokenChunks);
|
||||
this.brokenChunks.clear();
|
||||
Object worldServer = this.ceWorld.world().serverWorld();
|
||||
Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer);
|
||||
for (ChunkPos chunk : chunks) {
|
||||
@@ -172,7 +174,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent {
|
||||
int chunkZ = blockZ >> 4;
|
||||
int newStateId = ordinalToIbdID[newBlock.getOrdinal()];
|
||||
int oldStateId = ordinalToIbdID[oldBlock.getOrdinal()];
|
||||
BROKEN_CHUNKS.add(ChunkPos.of(chunkX, chunkZ));
|
||||
this.brokenChunks.add(ChunkPos.of(chunkX, chunkZ));
|
||||
//CraftEngine.instance().debug(() -> "Processing block at " + blockX + ", " + blockY + ", " + blockZ + ": " + oldStateId + " -> " + newStateId);
|
||||
if (BlockStateUtils.isVanillaBlock(newStateId) && BlockStateUtils.isVanillaBlock(oldStateId)) return;
|
||||
try {
|
||||
|
||||
@@ -353,8 +353,15 @@ chunk-system:
|
||||
# 4 = LZ4 | Blazing-Fast Blazing-Fast Low Low |
|
||||
# 5 = ZSTD | Medium-Fast Fast High Medium |
|
||||
compression-method: 4
|
||||
# This might not work for some server forks that modify how Minecraft saves chunks.
|
||||
fast-palette-injection: false
|
||||
# Settings for injection
|
||||
injection:
|
||||
# Requires a restart to apply
|
||||
# SECTION: Inject the LevelChunkSection (Faster, but may conflict with some plugins)
|
||||
# PALETTE: Inject the PalettedContainer
|
||||
target: PALETTE
|
||||
# Enables faster injection method
|
||||
# Note: May not work with certain server forks that alter chunk saving behavior
|
||||
use-fast-method: false
|
||||
# Auto-convert custom blocks -> vanilla blocks when unloading chunks
|
||||
#
|
||||
# - When ENABLED (true):
|
||||
|
||||
@@ -51,7 +51,7 @@ import net.momirealms.craftengine.core.world.CEWorld;
|
||||
import net.momirealms.craftengine.core.world.SectionPos;
|
||||
import net.momirealms.craftengine.core.world.chunk.CEChunk;
|
||||
import net.momirealms.craftengine.core.world.chunk.CESection;
|
||||
import net.momirealms.craftengine.core.world.chunk.InjectedPalettedContainerHolder;
|
||||
import net.momirealms.craftengine.core.world.chunk.InjectedHolder;
|
||||
import net.momirealms.craftengine.shared.ObjectHolder;
|
||||
import net.momirealms.craftengine.shared.block.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -69,12 +69,14 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BukkitInjector {
|
||||
private static final ByteBuddy byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V17);
|
||||
private static final BukkitBlockShape STONE_SHAPE = new BukkitBlockShape(Reflections.instance$Blocks$STONE$defaultState);
|
||||
|
||||
private static Class<?> clazz$InjectedPalettedContainer;
|
||||
private static Class<?> clazz$InjectedLevelChunkSection;
|
||||
|
||||
private static VarHandle varHandle$InjectedPalettedContainer$target;
|
||||
|
||||
@@ -100,17 +102,14 @@ public class BukkitInjector {
|
||||
clazz$InjectedPalettedContainer = byteBuddy
|
||||
.subclass(Reflections.clazz$PalettedContainer)
|
||||
.name("net.minecraft.world.level.chunk.InjectedPalettedContainer")
|
||||
.implement(InjectedPalettedContainerHolder.class)
|
||||
.defineField("target", Reflections.clazz$PalettedContainer, Visibility.PRIVATE)
|
||||
.defineField("ceworld", CEWorld.class, Visibility.PRIVATE)
|
||||
.implement(InjectedHolder.Palette.class)
|
||||
.defineField("target", Reflections.clazz$PalettedContainer, Visibility.PUBLIC)
|
||||
.defineField("cesection", CESection.class, Visibility.PRIVATE)
|
||||
.defineField("cechunk", CEChunk.class, Visibility.PRIVATE)
|
||||
.defineField("cepos", SectionPos.class, Visibility.PRIVATE)
|
||||
.method(ElementMatchers.any()
|
||||
.and(ElementMatchers.not(ElementMatchers.is(Reflections.method$PalettedContainer$getAndSet)))
|
||||
.and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class)))
|
||||
// TODO Requires Paper Patch
|
||||
//.and(ElementMatchers.not(ElementMatchers.named("get").and(ElementMatchers.takesArguments(int.class)).and(ElementMatchers.returns(Object.class))))
|
||||
)
|
||||
.intercept(MethodDelegation.toField("target"))
|
||||
.method(ElementMatchers.is(Reflections.method$PalettedContainer$getAndSet))
|
||||
@@ -121,16 +120,33 @@ public class BukkitInjector {
|
||||
.intercept(FieldAccessor.ofField("cesection"))
|
||||
.method(ElementMatchers.named("ceChunk"))
|
||||
.intercept(FieldAccessor.ofField("cechunk"))
|
||||
.method(ElementMatchers.named("ceWorld"))
|
||||
.intercept(FieldAccessor.ofField("ceworld"))
|
||||
.method(ElementMatchers.named("cePos"))
|
||||
.intercept(FieldAccessor.ofField("cepos"))
|
||||
.make()
|
||||
.load(BukkitInjector.class.getClassLoader())
|
||||
.getLoaded();
|
||||
|
||||
varHandle$InjectedPalettedContainer$target = Objects.requireNonNull(ReflectionUtils.findVarHandle(clazz$InjectedPalettedContainer, "target", Reflections.clazz$PalettedContainer));
|
||||
|
||||
// Level Chunk Section
|
||||
clazz$InjectedLevelChunkSection = byteBuddy
|
||||
.subclass(Reflections.clazz$LevelChunkSection)
|
||||
.name("net.minecraft.world.level.chunk.InjectedLevelChunkSection")
|
||||
.implement(InjectedHolder.Section.class)
|
||||
.defineField("cesection", CESection.class, Visibility.PRIVATE)
|
||||
.defineField("cechunk", CEChunk.class, Visibility.PRIVATE)
|
||||
.defineField("cepos", SectionPos.class, Visibility.PRIVATE)
|
||||
.method(ElementMatchers.is(Reflections.method$LevelChunkSection$setBlockState))
|
||||
.intercept(MethodDelegation.to(SetBlockStateInterceptor.INSTANCE))
|
||||
.method(ElementMatchers.named("ceSection"))
|
||||
.intercept(FieldAccessor.ofField("cesection"))
|
||||
.method(ElementMatchers.named("ceChunk"))
|
||||
.intercept(FieldAccessor.ofField("cechunk"))
|
||||
.method(ElementMatchers.named("cePos"))
|
||||
.intercept(FieldAccessor.ofField("cepos"))
|
||||
.make()
|
||||
.load(BukkitInjector.class.getClassLoader())
|
||||
.getLoaded();
|
||||
|
||||
// State Predicate
|
||||
DynamicType.Unloaded<?> alwaysTrue = byteBuddy
|
||||
.subclass(Reflections.clazz$StatePredicate)
|
||||
@@ -388,23 +404,33 @@ public class BukkitInjector {
|
||||
// }
|
||||
// }
|
||||
|
||||
public synchronized static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEChunk chunk, SectionPos pos) {
|
||||
public synchronized static void injectLevelChunkSection(Object targetSection, CESection ceSection, CEChunk chunk, SectionPos pos, Consumer<Object> callback) {
|
||||
try {
|
||||
Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection);
|
||||
if (!(container instanceof InjectedPalettedContainerHolder)) {
|
||||
InjectedPalettedContainerHolder injectedObject;
|
||||
if (Config.fastPaletteInjection()) {
|
||||
injectedObject = FastNMS.INSTANCE.createInjectedPalettedContainerHolder(container);
|
||||
} else {
|
||||
injectedObject = (InjectedPalettedContainerHolder) Reflections.UNSAFE.allocateInstance(clazz$InjectedPalettedContainer);
|
||||
varHandle$InjectedPalettedContainer$target.set(injectedObject, container);
|
||||
if (Config.injectionTarget()) {
|
||||
Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection);
|
||||
if (!(container instanceof InjectedHolder.Palette)) {
|
||||
InjectedHolder.Palette injectedObject;
|
||||
if (Config.fastInjection()) {
|
||||
injectedObject = FastNMS.INSTANCE.createInjectedPalettedContainerHolder(container);
|
||||
} else {
|
||||
injectedObject = (InjectedHolder.Palette) Reflections.UNSAFE.allocateInstance(clazz$InjectedPalettedContainer);
|
||||
varHandle$InjectedPalettedContainer$target.set(injectedObject, container);
|
||||
}
|
||||
injectedObject.ceChunk(chunk);
|
||||
injectedObject.ceSection(ceSection);
|
||||
injectedObject.cePos(pos);
|
||||
Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container));
|
||||
Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject);
|
||||
}
|
||||
} else {
|
||||
InjectedHolder.Section injectedObject;
|
||||
if (true) {
|
||||
injectedObject = FastNMS.INSTANCE.createInjectedLevelChunkSectionHolder(targetSection);
|
||||
}
|
||||
injectedObject.ceWorld(chunk.world());
|
||||
injectedObject.ceChunk(chunk);
|
||||
injectedObject.ceSection(ceSection);
|
||||
injectedObject.cePos(pos);
|
||||
Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container));
|
||||
Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject);
|
||||
callback.accept(injectedObject);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().severe("Failed to inject chunk section", e);
|
||||
@@ -412,19 +438,30 @@ public class BukkitInjector {
|
||||
}
|
||||
|
||||
public static boolean isSectionInjected(Object section) {
|
||||
Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(section);
|
||||
return container instanceof InjectedPalettedContainerHolder;
|
||||
if (Config.injectionTarget()) {
|
||||
Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(section);
|
||||
return container instanceof InjectedHolder.Palette;
|
||||
} else {
|
||||
return section instanceof InjectedHolder.Section;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static void uninjectLevelChunkSection(Object section) {
|
||||
try {
|
||||
public synchronized static Object uninjectLevelChunkSection(Object section) {
|
||||
if (Config.injectionTarget()) {
|
||||
Object states = FastNMS.INSTANCE.field$LevelChunkSection$states(section);
|
||||
if (states instanceof InjectedPalettedContainerHolder holder) {
|
||||
Reflections.field$LevelChunkSection$states.set(section, holder.target());
|
||||
if (states instanceof InjectedHolder.Palette holder) {
|
||||
try {
|
||||
Reflections.field$LevelChunkSection$states.set(section, holder.target());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().severe("Failed to uninject palette", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (section instanceof InjectedHolder.Section holder) {
|
||||
return FastNMS.INSTANCE.constructor$LevelChunkSection(holder);
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().severe("Failed to inject chunk section", e);
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
public static class GetRecipeForMethodInterceptor1_20 {
|
||||
@@ -682,58 +719,78 @@ public class BukkitInjector {
|
||||
}
|
||||
}
|
||||
|
||||
public static class SetBlockStateInterceptor {
|
||||
public static final SetBlockStateInterceptor INSTANCE = new SetBlockStateInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args, @SuperCall Callable<Object> superMethod) throws Exception {
|
||||
InjectedHolder.Section holder = (InjectedHolder.Section) thisObj;
|
||||
int x = (int) args[0];
|
||||
int y = (int) args[1];
|
||||
int z = (int) args[2];
|
||||
Object newState = args[3];
|
||||
Object previousState = superMethod.call();
|
||||
compareAndUpdateBlockState(x, y, z, newState, previousState, holder);
|
||||
return previousState;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GetAndSetInterceptor {
|
||||
public static final GetAndSetInterceptor INSTANCE = new GetAndSetInterceptor();
|
||||
|
||||
@RuntimeType
|
||||
public Object intercept(@This Object thisObj, @AllArguments Object[] args) {
|
||||
InjectedPalettedContainerHolder holder = (InjectedPalettedContainerHolder) thisObj;
|
||||
InjectedHolder.Palette holder = (InjectedHolder.Palette) thisObj;
|
||||
Object targetStates = holder.target();
|
||||
int x = (int) args[0];
|
||||
int y = (int) args[1];
|
||||
int z = (int) args[2];
|
||||
Object previousState = FastNMS.INSTANCE.method$PalettedContainer$getAndSet(targetStates, x, y, z, args[3]);
|
||||
try {
|
||||
Object newState = args[3];
|
||||
int stateId = BlockStateUtils.blockStateToId(newState);
|
||||
CESection section = holder.ceSection();
|
||||
// 如果是原版方块
|
||||
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
||||
// 那么应该情况自定义块
|
||||
ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE);
|
||||
// 如果先前不是空气则标记
|
||||
if (!previous.isEmpty()) {
|
||||
holder.ceChunk().setDirty(true);
|
||||
}
|
||||
if (Config.enableLightSystem() && Config.forceUpdateLight()) {
|
||||
updateLightIfChanged(holder, previousState, newState, null, y, z, x);
|
||||
}
|
||||
} else {
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
||||
ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState);
|
||||
// 如果之前的自定义块(空气)和当前自定义块不同
|
||||
if (previousImmutableBlockState != immutableBlockState) {
|
||||
holder.ceChunk().setDirty(true);
|
||||
if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) {
|
||||
updateLightIfChanged(holder, previousState, newState, immutableBlockState.vanillaBlockState().handle(), y, z, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to intercept setBlockState", e);
|
||||
}
|
||||
Object newState = args[3];
|
||||
Object previousState = FastNMS.INSTANCE.method$PalettedContainer$getAndSet(targetStates, x, y, z, newState);
|
||||
compareAndUpdateBlockState(x, y, z, newState, previousState, holder);
|
||||
return previousState;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLightIfChanged(@This InjectedPalettedContainerHolder thisObj, Object previousBlockState, Object newState, @Nullable Object clientSideNewState, int y, int z, int x) throws ReflectiveOperationException {
|
||||
int previousLight = BlockStateUtils.getLightEmission(previousBlockState);
|
||||
int newLight = BlockStateUtils.getLightEmission(newState);
|
||||
if (previousLight != newLight || (clientSideNewState != null && (BlockStateUtils.isOcclude(newState) != BlockStateUtils.isOcclude(clientSideNewState)))) {
|
||||
CEWorld world = thisObj.ceWorld();
|
||||
SectionPos sectionPos = thisObj.cePos();
|
||||
Set<SectionPos> posSet = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, Math.max(newLight, previousLight));
|
||||
world.sectionLightUpdated(posSet);
|
||||
protected static void compareAndUpdateBlockState(int x, int y, int z, Object newState, Object previousState, InjectedHolder holder) {
|
||||
try {
|
||||
int stateId = BlockStateUtils.blockStateToId(newState);
|
||||
CESection section = holder.ceSection();
|
||||
// 如果是原版方块
|
||||
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
||||
// 那么应该情况自定义块
|
||||
ImmutableBlockState previous = section.setBlockState(x, y, z, EmptyBlock.STATE);
|
||||
// 如果先前不是空气则标记
|
||||
if (!previous.isEmpty()) {
|
||||
holder.ceChunk().setDirty(true);
|
||||
}
|
||||
if (Config.enableLightSystem() && Config.forceUpdateLight()) {
|
||||
updateLightIfChanged(holder, previousState, newState, null, y, z, x);
|
||||
}
|
||||
} else {
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
||||
ImmutableBlockState previousImmutableBlockState = section.setBlockState(x, y, z, immutableBlockState);
|
||||
// 如果之前的自定义块(空气)和当前自定义块不同
|
||||
if (previousImmutableBlockState != immutableBlockState) {
|
||||
holder.ceChunk().setDirty(true);
|
||||
if (Config.enableLightSystem() && !immutableBlockState.isEmpty()) {
|
||||
updateLightIfChanged(holder, previousState, newState, immutableBlockState.vanillaBlockState().handle(), y, z, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to intercept setBlockState", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void updateLightIfChanged(@This InjectedHolder thisObj, Object previousBlockState, Object newState, @Nullable Object clientSideNewState, int y, int z, int x) throws ReflectiveOperationException {
|
||||
int previousLight = BlockStateUtils.getLightEmission(previousBlockState);
|
||||
int newLight = BlockStateUtils.getLightEmission(newState);
|
||||
if (previousLight != newLight || (clientSideNewState != null && (BlockStateUtils.isOcclude(newState) != BlockStateUtils.isOcclude(clientSideNewState)))) {
|
||||
CEWorld world = thisObj.ceChunk().world();
|
||||
SectionPos sectionPos = thisObj.cePos();
|
||||
Set<SectionPos> posSet = SectionPosUtils.calculateAffectedRegions((sectionPos.x() << 4) + x, (sectionPos.y() << 4) + y, (sectionPos.z() << 4) + z, Math.max(newLight, previousLight));
|
||||
world.sectionLightUpdated(posSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1928,7 +1928,6 @@ public class Reflections {
|
||||
// field$ChunkAccess$blockEntities = targetField;
|
||||
// }
|
||||
|
||||
@Deprecated
|
||||
public static final Method method$LevelChunkSection$setBlockState = requireNonNull(
|
||||
ReflectionUtils.getMethod(
|
||||
clazz$LevelChunkSection, clazz$BlockState, int.class, int.class, int.class, clazz$BlockState, boolean.class
|
||||
|
||||
@@ -282,7 +282,11 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
for (int i = 0; i < ceSections.length; i++) {
|
||||
CESection ceSection = ceSections[i];
|
||||
Object section = sections[i];
|
||||
BukkitInjector.uninjectLevelChunkSection(section);
|
||||
Object uninjectedSection = BukkitInjector.uninjectLevelChunkSection(section);
|
||||
if (uninjectedSection != section) {
|
||||
sections[i] = uninjectedSection;
|
||||
section = uninjectedSection;
|
||||
}
|
||||
if (!ceSection.statesContainer().isEmpty()) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
@@ -383,7 +387,9 @@ public class BukkitWorldManager implements WorldManager, Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z));
|
||||
int finalI = i;
|
||||
BukkitInjector.injectLevelChunkSection(section, ceSection, ceChunk, new SectionPos(pos.x, ceChunk.sectionY(i), pos.z),
|
||||
(injected) -> sections[finalI] = injected);
|
||||
}
|
||||
if (Config.enableRecipeSystem()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -23,6 +23,7 @@ import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
import net.momirealms.craftengine.core.world.InjectionTarget;
|
||||
import net.momirealms.craftengine.core.world.chunk.storage.CompressionMethod;
|
||||
|
||||
import java.io.File;
|
||||
@@ -46,6 +47,7 @@ public class Config {
|
||||
private final String configVersion;
|
||||
private YamlDocument config;
|
||||
|
||||
protected boolean firstTime = true;
|
||||
protected boolean debug;
|
||||
protected boolean checkUpdate;
|
||||
protected boolean metrics;
|
||||
@@ -100,7 +102,8 @@ public class Config {
|
||||
protected boolean chunk_system$restore_custom_blocks_on_chunk_load;
|
||||
protected boolean chunk_system$sync_custom_blocks_on_chunk_load;
|
||||
protected int chunk_system$delay_serialization;
|
||||
protected boolean chunk_system$fast_paletted_injection;
|
||||
protected boolean chunk_system$injection$use_fast_method;
|
||||
protected boolean chunk_system$injection$target;
|
||||
|
||||
protected boolean furniture$handle_invalid_furniture_on_chunk_load$enable;
|
||||
protected Map<String, String> furniture$handle_invalid_furniture_on_chunk_load$mapping;
|
||||
@@ -272,7 +275,10 @@ public class Config {
|
||||
chunk_system$restore_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.restore-custom-blocks-on-chunk-load", true);
|
||||
chunk_system$sync_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.sync-custom-blocks-on-chunk-load", false);
|
||||
chunk_system$delay_serialization = config.getInt("chunk-system.delay-serialization", 20);
|
||||
chunk_system$fast_paletted_injection = config.getBoolean("chunk-system.fast-palette-injection", false);
|
||||
chunk_system$injection$use_fast_method = config.getBoolean("chunk-system.injection.use-fast-method", false);
|
||||
if (firstTime) {
|
||||
chunk_system$injection$target = config.getEnum("chunk-system.injection.target", InjectionTarget.class, InjectionTarget.PALETTE) == InjectionTarget.PALETTE;
|
||||
}
|
||||
|
||||
// furniture
|
||||
furniture$handle_invalid_furniture_on_chunk_load$enable = config.getBoolean("furniture.handle-invalid-furniture-on-chunk-load.enable", false);
|
||||
@@ -342,6 +348,8 @@ public class Config {
|
||||
plugin.logger().warn("Failed to set max chain update", e);
|
||||
}
|
||||
}
|
||||
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
private static float getVersion(String version) {
|
||||
@@ -695,8 +703,12 @@ public class Config {
|
||||
return instance.chunk_system$delay_serialization;
|
||||
}
|
||||
|
||||
public static boolean fastPaletteInjection() {
|
||||
return instance.chunk_system$fast_paletted_injection;
|
||||
public static boolean fastInjection() {
|
||||
return instance.chunk_system$injection$use_fast_method;
|
||||
}
|
||||
|
||||
public static boolean injectionTarget() {
|
||||
return instance.chunk_system$injection$target;
|
||||
}
|
||||
|
||||
public YamlDocument loadOrCreateYamlData(String fileName) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.momirealms.craftengine.core.world;
|
||||
|
||||
public enum InjectionTarget {
|
||||
SECTION,
|
||||
PALETTE
|
||||
}
|
||||
@@ -1,11 +1,8 @@
|
||||
package net.momirealms.craftengine.core.world.chunk;
|
||||
|
||||
import net.momirealms.craftengine.core.world.CEWorld;
|
||||
import net.momirealms.craftengine.core.world.SectionPos;
|
||||
|
||||
public interface InjectedPalettedContainerHolder {
|
||||
|
||||
Object target();
|
||||
public interface InjectedHolder {
|
||||
|
||||
CESection ceSection();
|
||||
|
||||
@@ -15,11 +12,15 @@ public interface InjectedPalettedContainerHolder {
|
||||
|
||||
void ceChunk(CEChunk chunk);
|
||||
|
||||
CEWorld ceWorld();
|
||||
|
||||
void ceWorld(CEWorld world);
|
||||
|
||||
SectionPos cePos();
|
||||
|
||||
void cePos(SectionPos pos);
|
||||
|
||||
interface Section extends InjectedHolder {
|
||||
}
|
||||
|
||||
interface Palette extends InjectedHolder {
|
||||
|
||||
Object target();
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=0.0.53-beta.4
|
||||
config_version=31
|
||||
project_version=0.0.53-beta.6
|
||||
config_version=32
|
||||
lang_version=12
|
||||
project_group=net.momirealms
|
||||
latest_supported_version=1.21.5
|
||||
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.15
|
||||
nms_helper_version=0.64.6
|
||||
nms_helper_version=0.65.11
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.31.23
|
||||
|
||||
Reference in New Issue
Block a user