From 5b8ff4732f9a4c83c605209070e6c122c9bff8ea Mon Sep 17 00:00:00 2001 From: Reider745 <70357814+Reider745@users.noreply.github.com> Date: Thu, 9 May 2024 15:39:57 +0300 Subject: [PATCH] =?UTF-8?q?Fixed:=20=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D0=B5=20ChangeBlock(=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20?= =?UTF-8?q?=D0=BE=D0=BD=D0=BE=20=D1=80=D0=B5=D0=B0=D0=B3=D0=B8=D1=80=D1=83?= =?UTF-8?q?=D0=B5=D1=82=20=D0=BD=D0=B0=20=D0=B2=D1=81=D0=B5=20=D0=B1=D0=BB?= =?UTF-8?q?=D0=BE=D0=BA=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/reider745/api/ReflectHelper.java | 11 +++ .../com/reider745/event/EventListener.java | 4 +- .../java/com/reider745/hooks/LevelHooks.java | 83 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/reider745/api/ReflectHelper.java b/src/main/java/com/reider745/api/ReflectHelper.java index 341ed800c..13c3be16d 100644 --- a/src/main/java/com/reider745/api/ReflectHelper.java +++ b/src/main/java/com/reider745/api/ReflectHelper.java @@ -1,6 +1,7 @@ package com.reider745.api; import java.lang.reflect.Field; +import java.lang.reflect.Method; public class ReflectHelper { @@ -49,4 +50,14 @@ public static void setField(Class self, String name, Object v) { e.printStackTrace(); } } + + public static void invokeVoid(Object self, String name, Object[] args, Class... classes){ + try { + Method method = self.getClass().getDeclaredMethod(name, classes); + method.setAccessible(true); + method.invoke(self, args); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/src/main/java/com/reider745/event/EventListener.java b/src/main/java/com/reider745/event/EventListener.java index 4f3d4b2fb..31b877fd2 100644 --- a/src/main/java/com/reider745/event/EventListener.java +++ b/src/main/java/com/reider745/event/EventListener.java @@ -396,7 +396,7 @@ public void onPickupItem(InventoryPickupItemEvent event) { consumeEvent(event, () -> NativeCallback.onEntityPickUpDrop(entity, dropEntity, count)); } - @EventHandler(priority = EventPriority.HIGHEST) + /*@EventHandler(priority = EventPriority.HIGHEST) public void onBlockUpdate(BlockGrowEvent event) { final Block block = event.getBlock(); final Block newBlock = event.getNewState(); @@ -406,7 +406,7 @@ public void onBlockUpdate(BlockGrowEvent event) { () -> NativeCallback.onBlockChanged((int) block.x, (int) block.y, (int) block.z, block.getId(), block.getDamage(), newBlock.getId(), newBlock.getDamage(), FakeDimensions.getFakeIdForLevel(level), newBlock.getFullId(), block.getLevel())); - } + }*/ @EventHandler(priority = EventPriority.HIGHEST) public void onEntityTeleport(EntityTeleportEvent event) { diff --git a/src/main/java/com/reider745/hooks/LevelHooks.java b/src/main/java/com/reider745/hooks/LevelHooks.java index 6b92fd62b..545c5ffff 100644 --- a/src/main/java/com/reider745/hooks/LevelHooks.java +++ b/src/main/java/com/reider745/hooks/LevelHooks.java @@ -9,13 +9,16 @@ import cn.nukkit.entity.Entity; import cn.nukkit.entity.item.EntityPrimedTNT; import cn.nukkit.event.block.BlockBreakEvent; +import cn.nukkit.event.block.BlockUpdateEvent; import cn.nukkit.item.Item; import cn.nukkit.item.ItemBlock; import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.lang.TranslationContainer; +import cn.nukkit.level.ChunkLoader; import cn.nukkit.level.GameRule; import cn.nukkit.level.Level; import cn.nukkit.level.Position; +import cn.nukkit.level.format.generic.BaseFullChunk; import cn.nukkit.level.format.generic.BaseLevelProvider; import cn.nukkit.level.particle.DestroyBlockParticle; import cn.nukkit.level.particle.ItemBreakParticle; @@ -24,6 +27,7 @@ import cn.nukkit.math.SimpleAxisAlignedBB; import cn.nukkit.math.Vector3; import cn.nukkit.nbt.tag.*; +import cn.nukkit.network.protocol.UpdateBlockPacket; import cn.nukkit.potion.Effect; import cn.nukkit.utils.TextFormat; import cn.nukkit.utils.Utils; @@ -33,16 +37,20 @@ import com.reider745.api.hooks.annotation.Hooks; import com.reider745.api.hooks.annotation.Inject; import com.reider745.event.EventListener; +import com.reider745.world.FakeDimensions; import com.reider745.world.dimensions.DimensionsMethods; +import com.zhekasmirnov.innercore.api.NativeCallback; import com.zhekasmirnov.innercore.api.dimensions.CustomDimension; import com.zhekasmirnov.innercore.api.unlimited.IDRegistry; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import javassist.CtClass; import javassist.CtField; import javassist.Modifier; import java.util.HashMap; import java.util.Map; +import java.util.function.Consumer; @Hooks(className = "cn.nukkit.level.Level") public class LevelHooks implements HookClass { @@ -345,4 +353,79 @@ public static Map getGeneratorOptions(BaseLevelProvider provider } }; } + + @Inject + public static boolean setBlock(Level self, int x, int y, int z, int layer, Block block, boolean direct, boolean update){ + if (!self.isYInRange(y) || layer < 0 || layer > self.requireProvider().getMaximumLayer()) { + return false; + } + BaseFullChunk chunk = self.getChunk(x >> 4, z >> 4, true); + Block blockPrevious; + blockPrevious = chunk.getAndSetBlock(x & 0xF, y, z & 0xF, layer, block); + if (blockPrevious.getFullId() == block.getFullId()) { + return false; + } + block.x = x; + block.y = y; + block.z = z; + block.level = self; + block.layer = layer; + + try { + final Int2ObjectMap> callbackBlockSet = ReflectHelper.getField(self, "callbackBlockSet"); + for (Consumer callback : callbackBlockSet.values()) { + callback.accept(block); + } + } catch (Exception e) { + Server.getInstance().getLogger().error("Error while calling block set callback", e); + } + + int cx = x >> 4; + int cz = z >> 4; + + if (direct) { + self.sendBlocks(self.getChunkPlayers(cx, cz).values().toArray(Player.EMPTY_ARRAY), new Block[]{block}, UpdateBlockPacket.FLAG_ALL_PRIORITY, block.layer); + } else { + ReflectHelper.invokeVoid(self, "addBlockChange", new Object[]{ + Level.chunkHash(cx, cz), x, y, z + }, long.class, int.class, int.class, int.class); + } + + for (ChunkLoader loader : self.getChunkLoaders(cx, cz)) { + loader.onBlockChanged(block); + } + if (update) { + if (blockPrevious.isTransparent() != block.isTransparent() || blockPrevious.getLightLevel() != block.getLightLevel()) { + self.addLightUpdate(x, y, z); + } + //TODO: Молимся бакам что-бы тут нечего не сломалось, при первойже возможности переписать этот участок + try { + NativeCallback.onBlockChanged(x, y, z, + blockPrevious.getId(), blockPrevious.getDamage(), + block.getId(), blockPrevious.getDamage(), + FakeDimensions.getFakeIdForLevel(self), + 0, + self + ); + }catch (Exception ignore){ + ignore.printStackTrace(); + } + + BlockUpdateEvent ev = new BlockUpdateEvent(block); + self.getServer().getPluginManager().callEvent(ev); + if (!ev.isCancelled()) { + for (Entity entity : self.getNearbyEntities(new SimpleAxisAlignedBB(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1))) { + entity.scheduleUpdate(); + } + block = ev.getBlock(); + block.onUpdate(Level.BLOCK_UPDATE_NORMAL); + block.getLevelBlockAtLayer(layer == 0 ? 1 : 0).onUpdate(Level.BLOCK_UPDATE_NORMAL); + if (block.isTransparent()) { + self.antiXrayOnBlockChange(null, block, 1); + } + self.updateAround(new Vector3(x, y, z)); + } + } + return true; + } }