From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik Date: Tue, 21 Sep 2021 23:54:25 +0100 Subject: [PATCH] Visibility API and Command diff --git a/src/main/java/me/samsuik/sakura/command/SakuraCommands.java b/src/main/java/me/samsuik/sakura/command/SakuraCommands.java index c2651cac1dcf85fb67fe981b97efee4e56431de2..d7d0c49cc5d576c594dee16ddba037cd147e11fa 100644 --- a/src/main/java/me/samsuik/sakura/command/SakuraCommands.java +++ b/src/main/java/me/samsuik/sakura/command/SakuraCommands.java @@ -2,6 +2,9 @@ package me.samsuik.sakura.command; import io.papermc.paper.command.PaperPluginsCommand; import me.samsuik.sakura.command.subcommands.ConfigCommand; +import me.samsuik.sakura.command.subcommands.FPSCommand; +import me.samsuik.sakura.command.subcommands.VisualCommand; +import me.samsuik.sakura.player.visibility.Visibility; import net.minecraft.server.MinecraftServer; import org.bukkit.command.Command; @@ -14,6 +17,10 @@ public class SakuraCommands { static { COMMANDS.put("sakura", new SakuraCommand("sakura")); COMMANDS.put("config", new ConfigCommand("config")); + COMMANDS.put("fps", new FPSCommand("fps")); + COMMANDS.put("tntvisibility", new VisualCommand(Visibility.Setting.TNT_VISIBILITY, "tnttoggle")); + COMMANDS.put("sandvisibility", new VisualCommand(Visibility.Setting.SAND_VISIBILITY, "sandtoggle")); + COMMANDS.put("minimal", new VisualCommand(Visibility.Setting.MINIMAL, "minimaltnt", "tntlag")); } public static void registerCommands(final MinecraftServer server) { diff --git a/src/main/java/me/samsuik/sakura/command/subcommands/FPSCommand.java b/src/main/java/me/samsuik/sakura/command/subcommands/FPSCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..1dc2a98123d671c945e85b97a898f56e527a81f5 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/command/subcommands/FPSCommand.java @@ -0,0 +1,26 @@ +package me.samsuik.sakura.command.subcommands; + +import me.samsuik.sakura.command.BaseSubCommand; +import me.samsuik.sakura.player.visibility.VisibilityGUI; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + +@DefaultQualifier(NonNull.class) +public class FPSCommand extends BaseSubCommand { + + private final VisibilityGUI VISIBILITY_GUI = new VisibilityGUI(); + + public FPSCommand(String name) { + super(name); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (sender instanceof Player player) { + VISIBILITY_GUI.showTo(player); + } + } + +} diff --git a/src/main/java/me/samsuik/sakura/command/subcommands/VisualCommand.java b/src/main/java/me/samsuik/sakura/command/subcommands/VisualCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..6027e4741e2de7c6d3bd7b094c196a212e34e2f5 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/command/subcommands/VisualCommand.java @@ -0,0 +1,45 @@ +package me.samsuik.sakura.command.subcommands; + +import me.samsuik.sakura.command.BaseSubCommand; +import me.samsuik.sakura.configuration.GlobalConfiguration; +import me.samsuik.sakura.player.visibility.Visibility; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; + +import java.util.Arrays; + +@DefaultQualifier(NonNull.class) +public class VisualCommand extends BaseSubCommand { + + private final Visibility.Setting type; + + public VisualCommand(Visibility.Setting type, String... aliases) { + super(type.basicName()); + this.setAliases(Arrays.asList(aliases)); + this.type = type; + } + + @Override + public void execute(CommandSender sender, String[] args) { + if (!(sender instanceof Player player)) { + return; + } + + var visibility = player.getVisibility(); + + // Toggle clicked setting visibility + visibility.toggle(type); + + // Send message to player + var state = visibility.isEnabled(type) ? "Enabled" : "Disabled"; + player.sendMessage(MiniMessage.miniMessage().deserialize(GlobalConfiguration.get().fps.message, + Placeholder.unparsed("name", type.friendlyName()), + Placeholder.unparsed("state", state)) + ); + } + +} diff --git a/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java b/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java new file mode 100644 index 0000000000000000000000000000000000000000..aaffe63cec82e8d89a9b6cd6e1749ca983dc6a13 --- /dev/null +++ b/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java @@ -0,0 +1,120 @@ +package me.samsuik.sakura.player.visibility; + +import me.samsuik.sakura.configuration.GlobalConfiguration; +import me.samsuik.sakura.player.gui.ItemIcon; +import me.samsuik.sakura.player.gui.PlayerGUI; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.function.BiFunction; + +public class VisibilityGUI extends PlayerGUI { + + private static final BiFunction CREATE_INVENTORY = (player, holder) -> { + Inventory inventory = Bukkit.createInventory(holder, 45, Component.text("FPS GUI")); + + for (int i = 0; i < inventory.getSize(); ++i) { + int column = i % 9; + int row = (i + 1) / 9; + + Material background = column > 0 && column < 8 ? (row > 0 && row < 4 || column > 1 && column < 7) + ? Material.matchMaterial(GlobalConfiguration.get().fps.material) + : Material.WHITE_STAINED_GLASS_PANE + : Material.BLACK_STAINED_GLASS_PANE; + + ItemStack itemstack = new ItemStack(background); + ItemMeta meta = itemstack.getItemMeta(); + meta.displayName(Component.space()); + itemstack.setItemMeta(meta); + + inventory.setItem(i, itemstack); + } + + return inventory; + }; + + public VisibilityGUI() { + super(CREATE_INVENTORY); + } + + @Override + protected void register() { + registerFPSIcon(Visibility.Setting.TNT_VISIBILITY, Material.TNT, NamedTextColor.RED, 12); + registerFPSIcon(Visibility.Setting.SAND_VISIBILITY, Material.SAND, NamedTextColor.YELLOW, 14); + registerFPSIcon(Visibility.Setting.MINIMAL, Material.NETHER_BRICK_SLAB, NamedTextColor.GOLD, 13); + registerFPSIcon(Visibility.Setting.SPAWNERS, Material.SPAWNER, NamedTextColor.DARK_GRAY, 20); + registerFPSIcon(Visibility.Setting.FLASHING_TNT, Material.REDSTONE_LAMP, NamedTextColor.RED, 22); + registerFPSIcon(Visibility.Setting.EXPLOSIONS, Material.COBWEB, NamedTextColor.WHITE, 24); + registerFPSIcon(Visibility.Setting.PISTONS, Material.PISTON, NamedTextColor.GOLD, 30); + registerFPSIcon(Visibility.Setting.REDSTONE, Material.REDSTONE, NamedTextColor.DARK_RED, 31); + registerFPSIcon(Visibility.Setting.ENCHANTMENT_GLINT, Material.ENCHANTED_BOOK, NamedTextColor.DARK_PURPLE, 32); + + registerIcon(new ItemIcon( + (player) -> { + ItemStack itemstack = new ItemStack(Material.GREEN_STAINED_GLASS_PANE); + Component title = Component.text("Toggle all", NamedTextColor.GREEN); + + itemstack.editMeta(meta -> meta.displayName(title.decoration(TextDecoration.ITALIC, false))); + return itemstack; + }, + (player) -> { + player.getVisibility().toggleAll(); + + // refresh icons after toggling + this.refresh(player); + }, + 26 + )); + } + + private void registerFPSIcon(Visibility.Setting setting, Material material, TextColor colour, int slot) { + registerIcon(new ItemIcon((player) -> { + Visibility visibility = player.getVisibility(); + ItemStack itemstack = new ItemStack(material); + + itemstack.editMeta(meta -> { + // Get the current state as a string + String state = visibility.isEnabled(setting) ? "Enabled" : "Disabled"; + + // Friendly name as a component + Component title = Component.text(setting.friendlyName(), colour); + + // Display names are italic by default + title = title.decoration(TextDecoration.ITALIC, false); + + // Set the display name + meta.displayName(title.append(Component.space()) + .append(Component.text(state, NamedTextColor.GRAY))); + }); + + return itemstack; + }, (player) -> { + Visibility visibility = player.getVisibility(); + + // Toggle clicked setting visibility + visibility.toggle(setting); + + // Get the current state as a string + String state = visibility.isEnabled(setting) ? "Enabled" : "Disabled"; + + // Send message to player + player.sendMessage(MiniMessage.miniMessage().deserialize(GlobalConfiguration.get().fps.message, + Placeholder.unparsed("name", setting.friendlyName()), + Placeholder.unparsed("state", state) + )); + }, + slot + )); + } + +} diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java index 7c6a6693760638a07b7c7c330aaeffd9fa454845..84299c755d4dd0fe507f57ac86b082d6c7de22a6 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java @@ -16,7 +16,7 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet public private final boolean suppressLightUpdates; public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, ShortSet positions, LevelChunkSection section, boolean noLightingUpdates) { diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 8cb71110c16789a9fbc0b7f76f76f9d4260e62b9..f948882c013afa3df1f55d01eaf1c92f51f96aa0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1574,6 +1574,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop createEntityPacket(Entity entity, ServerPlayer entityplayer) { + if (entity.isPrimedTNT && entityplayer.visibility.isToggled(Visibility.Setting.FLASHING_TNT)) { + return new ClientboundAddEntityPacket(entity.getId(), entity.getUUID(), + entity.getX(), entity.getY(), entity.getZ(), 0, 0, EntityType.FALLING_BLOCK, + Block.getId(Blocks.TNT.defaultBlockState()), entity.getDeltaMovement(), entity.getYHeadRot() + ); + } else { + return entity.getAddEntityPacket(); + } + } + // Sakura end + public void sendPairingData(Consumer> consumer, ServerPlayer entityplayer) { // CraftBukkit - add player if (this.entity.isRemoved()) { // CraftBukkit start - Remove useless error spam, just return @@ -301,12 +321,20 @@ public class ServerEntity { // CraftBukkit end } - Packet packet = this.entity.getAddEntityPacket(); + Packet packet = this.createEntityPacket(this.entity, entityplayer); // Sakura - visibility api this.yHeadRotp = Mth.floor(this.entity.getYHeadRot() * 256.0F / 360.0F); consumer.accept(packet); if (this.trackedDataValues != null) { consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), this.trackedDataValues)); + // Sakura start - visibility api + if (this.entity.isPrimedTNT && entityplayer.visibility.isToggled(Visibility.Setting.FLASHING_TNT)) { + // Could modifying this break something elsewhere? + trackedDataValues.removeIf(data -> data.id() == 8); + } + + consumer.accept(new ClientboundSetEntityDataPacket(this.entity.getId(), trackedDataValues)); + // Sakura end } boolean flag = this.trackDelta; @@ -390,6 +418,32 @@ public class ServerEntity { } } + + // Sakura start - visibility api + private void broadcastEntityData(List> packedValues) { + Packet packet0 = new ClientboundSetEntityDataPacket(this.entity.getId(), packedValues); + Packet packet1 = null; + + if (this.entity.isPrimedTNT) { + var copyOfDirtyItems = Lists.newArrayList(packedValues); + copyOfDirtyItems.removeIf((data) -> data.id() == 8); + + if (!copyOfDirtyItems.isEmpty()) { + packet1 = new ClientboundSetEntityDataPacket(this.entity.getId(), copyOfDirtyItems); + } + } + + for (ServerPlayerConnection connection : trackedPlayers) { + ServerPlayer player = connection.getPlayer(); + + if (!this.entity.isPrimedTNT || !player.visibility.isToggled(Visibility.Setting.FLASHING_TNT)) { + connection.send(packet0); + } else if (packet1 != null) { + connection.send(packet1); + } + } + } + // Sakura end private void sendDirtyEntityData() { SynchedEntityData datawatcher = this.entity.getEntityData(); @@ -397,7 +451,7 @@ public class ServerEntity { if (list != null) { this.trackedDataValues = datawatcher.getNonDefaultValues(); - this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list)); + this.broadcastEntityData(list); // Sakura - visibility api } if (this.entity instanceof LivingEntity) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java index 174802d3ae69cc9a1f0ae16c078dca79be9d6335..93386603037da776a7c6405293aa64f04c99a679 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java @@ -1756,7 +1756,7 @@ public class ServerLevel extends Level implements WorldGenLevel { while (iterator.hasNext()) { ServerPlayer entityplayer = (ServerPlayer) iterator.next(); - if (entityplayer.distanceToSqr(x, y, z) < 4096.0D) { + if (entityplayer.distanceToSqr(x, y, z) < 4096.0D && !entityplayer.visibility.isToggled(me.samsuik.sakura.player.visibility.Visibility.Setting.EXPLOSIONS)) { // Sakura - visibility api entityplayer.connection.send(new ClientboundExplodePacket(x, y, z, power, explosion.getToBlow(), (Vec3) explosion.getHitPlayers().get(entityplayer))); } } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index 98df2463bf41fc736aa6a2b6ddf89e5abde6eb39..acc8be3069f5453701796ba4926d4fee7cfab9aa 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -256,6 +256,7 @@ public class ServerPlayer extends Player { public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper public final com.destroystokyo.paper.util.PooledHashSets.PooledObjectLinkedOpenHashSet cachedSingleMobDistanceMap; // Paper end + public final me.samsuik.sakura.player.visibility.Visibility visibility = new me.samsuik.sakura.player.visibility.Visibility(); // Sakura - visiblity api // CraftBukkit start public String displayName; @@ -514,6 +515,15 @@ public class ServerPlayer extends Player { this.respawnDimension = (ResourceKey) dataresult1.resultOrPartial(logger1::error).orElse(Level.OVERWORLD); } } + // Sakura start - visibility api + CompoundTag tag = nbt.getCompound("Sakura.Visuals"); + + for (me.samsuik.sakura.player.visibility.Visibility.Setting setting : me.samsuik.sakura.player.visibility.Visibility.Setting.values()) { + if (tag.getBoolean(setting.name())) { + visibility.toggle(setting); + } + } + // Sakura end } @@ -580,6 +590,13 @@ public class ServerPlayer extends Player { }); } this.getBukkitEntity().setExtraData(nbt); // CraftBukkit + // Sakura start - visibility api + CompoundTag tag = new CompoundTag(); + for (me.samsuik.sakura.player.visibility.Visibility.Setting setting : me.samsuik.sakura.player.visibility.Visibility.Setting.values()) { + tag.putBoolean(setting.name(), visibility.isToggled(setting)); + } + nbt.put("Sakura.Visuals", tag); + // Sakura end } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index aa287d7f37f38d938d195114408cb6dbda59063d..5b31f47fa33faa9ad7edc3259685d99f544996ab 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -246,6 +246,23 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.SmithingInventory; // CraftBukkit end +// Sakura start +import com.mojang.datafixers.util.Pair; +import me.samsuik.sakura.player.visibility.Visibility.Setting; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundBlockEventPacket; +import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; +import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData.BlockEntityTagOutput; +import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; +import net.minecraft.world.level.block.DiodeBlock; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.RedStoneWireBlock; +import net.minecraft.world.level.block.piston.PistonBaseBlock; +import net.minecraft.world.level.block.piston.PistonHeadBlock; +// Sakura end public class ServerGamePacketListenerImpl implements ServerPlayerConnection, TickablePacketListener, ServerGamePacketListener { @@ -2153,6 +2170,61 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic } else if (packet instanceof ClientboundSetDefaultSpawnPositionPacket) { ClientboundSetDefaultSpawnPositionPacket packet6 = (ClientboundSetDefaultSpawnPositionPacket) packet; this.player.compassTarget = CraftLocation.toBukkit(packet6.pos, this.getCraftPlayer().getWorld()); + // Sakura start - visibility api + } else if (!player.visibility.isModified()) { + // Skip players that haven't modified their settings + } else if (packet instanceof ClientboundSetEquipmentPacket equipment + && player.visibility.isToggled(Setting.ENCHANTMENT_GLINT)) { + var slots = new java.util.ArrayList>(); + + for (int i = 0; i < equipment.getSlots().size(); i++) { + var pair = equipment.getSlots().get(i); + var itemstack = pair.getSecond(); + + if (itemstack.isEnchanted()) { + var copy = itemstack.copy(); + copy.getTag().remove("ench"); + itemstack = copy; + } + + slots.add(new Pair<>(pair.getFirst(), itemstack)); + } + + packet = new ClientboundSetEquipmentPacket(equipment.getEntity(), slots); + } else if (packet instanceof ClientboundBlockEntityDataPacket blockdata + && player.visibility.isToggled(Setting.SPAWNERS) + && player.level.getBlockIfLoaded(blockdata.getPos()) == Blocks.SPAWNER) { + packet = new ClientboundBlockUpdatePacket(blockdata.getPos(), Blocks.BLACK_STAINED_GLASS.defaultBlockState()); + } else if (packet instanceof ClientboundBlockUpdatePacket updatePacket) { + if (player.visibility.isToggled(Setting.SPAWNERS) && updatePacket.blockState.getBlock() == Blocks.SPAWNER) { + packet = new ClientboundBlockUpdatePacket(updatePacket.getPos(), Blocks.BLACK_STAINED_GLASS.defaultBlockState()); + } else if (player.visibility.isToggled(Setting.REDSTONE) + && (updatePacket.blockState.getBlock() instanceof DiodeBlock + || updatePacket.blockState.getBlock() instanceof RedStoneWireBlock)) { + return; + } else if (player.visibility.isToggled(Setting.PISTONS) + && (updatePacket.blockState.getBlock() instanceof PistonBaseBlock + || updatePacket.blockState.getBlock() instanceof PistonHeadBlock)) { + return; + } + } else if (packet instanceof ClientboundSectionBlocksUpdatePacket sectionPacket) { + for (var state : sectionPacket.states) { + if (player.visibility.isToggled(Setting.REDSTONE) + && (state.getBlock() instanceof DiodeBlock + || state.getBlock() instanceof RedStoneWireBlock)) { + return; + } else if (player.visibility.isToggled(Setting.PISTONS) + && (state.getBlock() instanceof PistonBaseBlock + || state.getBlock() instanceof PistonHeadBlock)) { + return; + } + } + } else if (packet instanceof ClientboundBlockEventPacket blockevent + && player.visibility.isToggled(Setting.PISTONS) + && (blockevent.getBlock() instanceof PistonBaseBlock + || blockevent.getBlock() instanceof PistonHeadBlock)) { + return; + // Sakura end } // CraftBukkit end @@ -2162,8 +2234,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic CrashReport crashreport = CrashReport.forThrowable(throwable, "Sending packet"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Packet being sent"); + final Packet finalPacket = packet; // Sakura - this has to be final as we're modifying the packet above crashreportsystemdetails.setDetail("Packet class", () -> { - return packet.getClass().getCanonicalName(); + return finalPacket.getClass().getCanonicalName(); // Sakura }); throw new ReportedException(crashreport); } @@ -3193,6 +3266,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic event.setCancelled(cancelled); AbstractContainerMenu oldContainer = this.player.containerMenu; // SPIGOT-1224 + me.samsuik.sakura.player.gui.PlayerGUI.onWindowClick(event); // Sakura - visibility gui this.cserver.getPluginManager().callEvent(event); if (this.player.containerMenu != oldContainer) { return; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 280ee1838106201f5e3ba7753caced6d030f7e55..038ee401a003cbf0f96eee1f60fbb13bb6622b5b 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -544,6 +544,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { this.teleportTo(worldserver, null); } // Paper end - make end portalling safe + public boolean isPrimedTNT; // Sakura + public boolean isFallingBlock; // Sakura public Entity(EntityType type, Level world) { this.id = Entity.ENTITY_COUNTER.incrementAndGet(); diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java index 536856300da929c101f50da5827677bada5feb50..c7bf257a4c5a36c1a6b54fe23701d7169da13100 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -71,6 +71,7 @@ public class FallingBlockEntity extends Entity { this.blockState = Blocks.SAND.defaultBlockState(); this.dropItem = true; this.fallDamageMax = 40; + this.isFallingBlock = true; // Sakura } public FallingBlockEntity(Level world, double x, double y, double z, BlockState block) { diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java index dfdf7e7fc1070975ec18fd215c724f4fc84d3705..23ba4fc50c0d45f1e5d666ff583b91665cab19f0 100644 --- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java +++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java @@ -28,6 +28,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { public PrimedTnt(EntityType type, Level world) { super(type, world); this.blocksBuilding = true; + this.isPrimedTNT = true; // Sakura } public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java index 4f0b68f33c4fca1fa9f983f966b3899e75b837b8..303c4a47b275e6c53a809c65482ad66734945622 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -287,6 +287,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public abstract ResourceKey getTypeKey(); + public final it.unimi.dsi.fastutil.longs.Long2IntMap minimalTNT = new it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap(); // Sakura - visibility api + protected Level(WritableLevelData worlddatamutable, ResourceKey resourcekey, RegistryAccess iregistrycustom, Holder holder, Supplier supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function paperWorldConfigCreator, Supplier sakuraWorldConfigCreator, java.util.concurrent.Executor executor) { // Sakura // Paper - Async-Anti-Xray - Pass executor this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) worlddatamutable).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index be64633c8bcee96f2ad5247525cac965b7b031b1..a8f7a0a2d4d44fb019ee26ce2b10dc7d33b3db9f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -504,6 +504,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().displayName = name == null ? getName() : name; } + // Sakura start - visiblity api + @Override + public me.samsuik.sakura.player.visibility.Visibility getVisibility() { + return getHandle().visibility; + } + // Sakura end + // Paper start @Override public void playerListName(net.kyori.adventure.text.Component name) {