diff --git a/iclibs/Nukkit-MOT-SNAPSHOT.jar b/iclibs/Nukkit-MOT-SNAPSHOT.jar index 4923dd3e..5bc8834a 100644 Binary files a/iclibs/Nukkit-MOT-SNAPSHOT.jar and b/iclibs/Nukkit-MOT-SNAPSHOT.jar differ diff --git a/src/main/java/com/reider745/InnerCoreServer.java b/src/main/java/com/reider745/InnerCoreServer.java index 1988bd72..91dbe6d4 100644 --- a/src/main/java/com/reider745/InnerCoreServer.java +++ b/src/main/java/com/reider745/InnerCoreServer.java @@ -10,6 +10,7 @@ import com.reider745.block.CustomBlock; import com.reider745.commands.CommandsHelper; import com.reider745.event.EventListener; import com.reider745.event.InnerCorePlugin; +import com.reider745.hooks.BiomesHooks; import com.reider745.hooks.SnowfallEverywhere; import com.reider745.item.CustomItem; @@ -199,6 +200,7 @@ public class InnerCoreServer { final long startupMillis = System.currentTimeMillis(); Thread.currentThread().setPriority(Thread.MAX_PRIORITY); server.getLogger().info("Initiating target directory '" + server.getDataPath() + "'"); + BiomesHooks.init(); dataPath = server.getDataPath(); final File dataFolderFile = new File(dataPath); diff --git a/src/main/java/com/reider745/Main.java b/src/main/java/com/reider745/Main.java index 132f33b5..abe8bcd6 100644 --- a/src/main/java/com/reider745/Main.java +++ b/src/main/java/com/reider745/Main.java @@ -76,6 +76,7 @@ public class Main { loader.registerHooksInitializationForClass(ItemUtils.class); loader.registerHooksInitializationForClass(AndroidHooks.class); loader.registerHooksInitializationForClass(SnowfallEverywhere.class); + loader.registerHooksInitializationForClass(BiomesHooks.class); //bug fix loader.registerHooksInitializationForClass(EntityItemHooks.class); diff --git a/src/main/java/com/reider745/api/pointers/PointersStorage.java b/src/main/java/com/reider745/api/pointers/PointersStorage.java index 7862926c..b37301f6 100644 --- a/src/main/java/com/reider745/api/pointers/PointersStorage.java +++ b/src/main/java/com/reider745/api/pointers/PointersStorage.java @@ -2,6 +2,7 @@ package com.reider745.api.pointers; import com.reider745.api.pointers.pointer_gen.IBasePointerGen; import com.reider745.api.pointers.pointer_gen.PointerGenSlowest; +import com.reider745.world.BiomesMethods; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; @@ -20,17 +21,21 @@ public class PointersStorage { private final INewPointer newPointer; - public PointersStorage(String type, final IBasePointerGen pointerGen, final INewPointer newPointer){ + public PointersStorage(String type, final IBasePointerGen pointerGen, final INewPointer newPointer, boolean clear){ System.out.println("Loaded pointer storage, type - "+type); this.pointerGen = pointerGen; storages.put(type, this); - new ThreadCheckToClear(this); + if(clear) new ThreadCheckToClear(this); this.newPointer = newPointer; } + public PointersStorage(String type, final IBasePointerGen pointerGen, boolean clear){ + this(type, pointerGen, ClassPointer::new, clear); + } + public PointersStorage(String type, final IBasePointerGen pointerGen){ - this(type, pointerGen, ClassPointer::new); + this(type, pointerGen, ClassPointer::new, true); } public PointersStorage(String type){ @@ -38,7 +43,7 @@ public class PointersStorage { } public PointersStorage(String type, final INewPointer newPointer){ - this(type, new PointerGenSlowest(), newPointer); + this(type, new PointerGenSlowest(), newPointer, true); } public final long addPointer(T pointerClass){ diff --git a/src/main/java/com/reider745/hooks/BiomesHooks.java b/src/main/java/com/reider745/hooks/BiomesHooks.java new file mode 100644 index 00000000..1d597d2b --- /dev/null +++ b/src/main/java/com/reider745/hooks/BiomesHooks.java @@ -0,0 +1,37 @@ +package com.reider745.hooks; + +import cn.nukkit.block.Block; +import cn.nukkit.level.biome.Biome; +import cn.nukkit.network.protocol.BiomeDefinitionListPacket; +import com.reider745.api.ReflectHelper; +import com.reider745.api.hooks.HookClass; +import com.reider745.api.hooks.TypeHook; +import com.reider745.api.hooks.annotation.Hooks; +import com.reider745.api.hooks.annotation.Inject; +import com.reider745.world.BiomesMethods; +import javassist.CtClass; +import javassist.CtField; +import javassist.Modifier; + +@Hooks(className = "cn.nukkit.level.biome.Biome") +public class BiomesHooks implements HookClass { + private static final int MAX_ID = 512; + + @Override + public void rebuildField(CtClass ctClass, CtField field) { + String name = field.getName(); + if (name.equals("biomes")) { + field.setModifiers(Modifier.PUBLIC | Modifier.STATIC); + + } + } + + public static void init() { + ReflectHelper.setField(Biome.class, "biomes", new Biome[MAX_ID]); + } + + @Inject(className = "cn.nukkit.network.protocol.BiomeDefinitionListPacket", type = TypeHook.BEFORE_REPLACE) + public static void encode(BiomeDefinitionListPacket self){ + BiomesMethods.encode(self); + } +} diff --git a/src/main/java/com/reider745/world/BiomesMethods.java b/src/main/java/com/reider745/world/BiomesMethods.java new file mode 100644 index 00000000..ad5b57c8 --- /dev/null +++ b/src/main/java/com/reider745/world/BiomesMethods.java @@ -0,0 +1,97 @@ +package com.reider745.world; + +import cn.nukkit.level.biome.Biome; +import cn.nukkit.nbt.NBTIO; +import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.network.protocol.BiomeDefinitionListPacket; +import com.reider745.api.ReflectHelper; +import com.reider745.api.pointers.PointersStorage; +import com.reider745.api.pointers.pointer_gen.PointerGenFastest; +import com.zhekasmirnov.innercore.api.nbt.NativeCompoundTag; +import org.json.JSONObject; + +import java.io.IOException; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.Objects; + +/* +format BiomeDefinitionListPacket +name: { + temperature + downfall +} + */ +public class BiomesMethods { + private static class NukkitCustomBiome extends Biome { + private final String name; + + public NukkitCustomBiome(String name){ + this.name = name; + } + + @Override + public String getName() { + return name; + } + + protected void reg(int id){ + register(id, this); + } + } + + private static final PointersStorage customBiomesPointers = new PointersStorage<>("biomes", new PointerGenFastest(), false); + private static final HashMap customBiomes = new HashMap<>(); + private static final CompoundTag TAG_419; + private static byte[] sendBiomes; + + static { + try { + TAG_419 = NBTIO.read((byte[]) Objects.requireNonNull(ReflectHelper.getField(BiomeDefinitionListPacket.class, "TAG_419")), ByteOrder.LITTLE_ENDIAN, true); + sendBiomes = NBTIO.write(TAG_419, ByteOrder.LITTLE_ENDIAN, true); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static int pre_id = 256; + + public static long nativeRegister(String name) { + NukkitCustomBiome biome = new NukkitCustomBiome(name); + biome.reg(pre_id++); + customBiomes.put(biome.getId(), biome); + try{ + final CompoundTag tag = new CompoundTag(); + tag.putFloat("ash", .0f); + tag.putFloat("blue_spores", .0f); + tag.putFloat("red_spores", .0f); + tag.putFloat("temperature", .5f); + tag.putFloat("downfall", .5f); + tag.putFloat("white_ash", .0f); + + final CompoundTag climate = new CompoundTag(); + climate.putFloat("ash", .0f); + climate.putFloat("downfall", .5f); + climate.putFloat("red_spores", .0f); + climate.putFloat("temperature", .5f); + climate.putFloat("blue_spores", .0f); + climate.putFloat("white_ash", .0f); + tag.put("minecraft:climate", climate); + + TAG_419.put(name, tag); + sendBiomes = NBTIO.write(TAG_419, ByteOrder.LITTLE_ENDIAN, true); + }catch (Exception e){ + throw new RuntimeException(e); + } + return customBiomesPointers.addPointer(biome); + } + + public static int nativeGetId(long pointer) { + return customBiomesPointers.get(pointer).getId(); + } + + public static void encode(BiomeDefinitionListPacket self) { + self.reset(); + self.put(sendBiomes); + } +} diff --git a/src/main/java/com/zhekasmirnov/innercore/api/NativeICRender.java b/src/main/java/com/zhekasmirnov/innercore/api/NativeICRender.java index 2c967591..048dd18c 100644 --- a/src/main/java/com/zhekasmirnov/innercore/api/NativeICRender.java +++ b/src/main/java/com/zhekasmirnov/innercore/api/NativeICRender.java @@ -287,6 +287,31 @@ public class NativeICRender { } } + /* + Условие из будующего обновление иннера + */ + public static class BlockState extends CONDITION { + private int x, y, z, state, value; + + public BlockState(int x, int y, int z, int state, int value){ + super(0); + this.x = x; + this.y = y; + this.z = z; + this.state = state; + this.value = value; + } + + public BlockState(int state, int value){ + this(0, 0, 0, state, value); + } + + @Override + public String toString() { + return "BLOCK ["+ x + " " + y + " " + z + " " + state + " " + value + "]"; + } + } + public static class RANDOM extends CONDITION { private int seed; private int max; diff --git a/src/main/java/com/zhekasmirnov/innercore/api/biomes/CustomBiome.java b/src/main/java/com/zhekasmirnov/innercore/api/biomes/CustomBiome.java index 0f77b67d..41f772ac 100644 --- a/src/main/java/com/zhekasmirnov/innercore/api/biomes/CustomBiome.java +++ b/src/main/java/com/zhekasmirnov/innercore/api/biomes/CustomBiome.java @@ -1,5 +1,6 @@ package com.zhekasmirnov.innercore.api.biomes; +import com.reider745.world.BiomesMethods; import org.json.JSONException; import org.json.JSONObject; @@ -21,7 +22,8 @@ public class CustomBiome { public CustomBiome(String name) { allCustomBiomes.put(name, this); - this.pointer = this.id = 0; + this.pointer = nativeRegister(name); + this.id = nativeGetId(pointer); this.name = name; } @@ -31,7 +33,6 @@ public class CustomBiome { } public CustomBiome setGrassColor(int color) { - InnerCoreServer.useNotCurrentSupport("CustomBiome.setGrassColor(color)"); return this; } @@ -41,7 +42,6 @@ public class CustomBiome { } public CustomBiome setSkyColor(int color) { - InnerCoreServer.useNotCurrentSupport("CustomBiome.setSkyColor(color)"); return this; } @@ -51,7 +51,6 @@ public class CustomBiome { } public CustomBiome setFoliageColor(int color) { - InnerCoreServer.useNotCurrentSupport("CustomBiome.setFoliageColor(color)"); return this; } @@ -61,7 +60,6 @@ public class CustomBiome { } public CustomBiome setWaterColor(int color) { - InnerCoreServer.useNotCurrentSupport("CustomBiome.setWaterColor(color)"); return this; } @@ -121,12 +119,13 @@ public class CustomBiome { } public CustomBiome setClientJson(String json) { - try { - new JSONObject(json); - } catch (JSONException e) { - throw new IllegalArgumentException("failed to parse biome client json: " + e.getMessage(), e); - } - InnerCoreServer.useNotCurrentSupport("CustomBiome.setClientJson(json)"); return this; } + + private static long nativeRegister(String name){ + return BiomesMethods.nativeRegister(name); + } + private static int nativeGetId(long pointer){ + return BiomesMethods.nativeGetId(pointer); + } }