mirror of
https://github.com/Samsuik/Sakura.git
synced 2025-12-28 19:29:07 +00:00
The player velocity was not being talied correctly, and velocity was not sent when explosion effects were disabled in fps settings.
579 lines
31 KiB
Diff
579 lines
31 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Samsuik <kfian294ma4@gmail.com>
|
|
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 3e85c19db0655034c203eaab8d2e6b5504da5da8..9b550fad76a45fb6ea8d07f75c2ff901d56ae514 100644
|
|
--- a/src/main/java/me/samsuik/sakura/command/SakuraCommands.java
|
|
+++ b/src/main/java/me/samsuik/sakura/command/SakuraCommands.java
|
|
@@ -1,6 +1,9 @@
|
|
package me.samsuik.sakura.command;
|
|
|
|
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;
|
|
|
|
@@ -12,6 +15,10 @@ public final 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(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..65f7f7dee78e352bdc88ff42714d10585aa25e21
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/samsuik/sakura/command/subcommands/FPSCommand.java
|
|
@@ -0,0 +1,24 @@
|
|
+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 final class FPSCommand extends BaseSubCommand {
|
|
+ private final VisibilityGUI gui = new VisibilityGUI();
|
|
+
|
|
+ public FPSCommand(String name) {
|
|
+ super(name);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void execute(CommandSender sender, String[] args) {
|
|
+ if (sender instanceof Player player) {
|
|
+ this.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..2931294d1063eb78b43f637269b27c257726b0ff
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/samsuik/sakura/command/subcommands/VisualCommand.java
|
|
@@ -0,0 +1,43 @@
|
|
+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 final 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;
|
|
+ }
|
|
+
|
|
+ Visibility visibility = player.getVisibility();
|
|
+
|
|
+ // Toggle clicked setting visibility
|
|
+ visibility.toggle(this.type);
|
|
+
|
|
+ // Send message to player
|
|
+ String state = visibility.isEnabled(this.type) ? "Enabled" : "Disabled";
|
|
+ player.sendRichMessage(GlobalConfiguration.get().messages.fpsSettingChange,
|
|
+ Placeholder.unparsed("name", this.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..049befac3219413be44c0a56f7b930a2eb55cee9
|
|
--- /dev/null
|
|
+++ b/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGUI.java
|
|
@@ -0,0 +1,123 @@
|
|
+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.TextDecoration;
|
|
+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 final class VisibilityGUI extends PlayerGUI {
|
|
+
|
|
+ private static final BiFunction<Player, Holder, Inventory> 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)
|
|
+ ? 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, 12);
|
|
+ registerFPSIcon(Visibility.Setting.SAND_VISIBILITY, 14);
|
|
+ registerFPSIcon(Visibility.Setting.MINIMAL, 13);
|
|
+ registerFPSIcon(Visibility.Setting.SPAWNERS, 20);
|
|
+ // ...22
|
|
+ registerFPSIcon(Visibility.Setting.EXPLOSIONS, 24);
|
|
+ registerFPSIcon(Visibility.Setting.PISTONS, 30);
|
|
+ registerFPSIcon(Visibility.Setting.REDSTONE, 31);
|
|
+ registerFPSIcon(Visibility.Setting.ENCHANTMENT_GLINT, 32);
|
|
+
|
|
+ registerIcon(new ItemIcon(player -> {
|
|
+ Visibility.State state = player.getVisibility().getState();
|
|
+ ItemStack itemstack = new ItemStack(state.material());
|
|
+
|
|
+ itemstack.editMeta(meta -> {
|
|
+ Component title = Component.text("Toggle all", state.colour());
|
|
+
|
|
+ // italic is default
|
|
+ title = title.decoration(TextDecoration.ITALIC, false);
|
|
+
|
|
+ meta.displayName(title.append(Component.space())
|
|
+ .append(Component.text(state.title(), NamedTextColor.GRAY)));
|
|
+ });
|
|
+
|
|
+ return itemstack;
|
|
+ }, player -> {
|
|
+ player.getVisibility().toggleAll();
|
|
+ // refresh icons after toggling
|
|
+ this.refresh(player);
|
|
+ }, 26));
|
|
+ }
|
|
+
|
|
+ private void registerFPSIcon(Visibility.Setting setting, int slot) {
|
|
+ registerIcon(new ItemIcon(player -> {
|
|
+ Visibility visibility = player.getVisibility();
|
|
+ ItemStack itemstack = new ItemStack(setting.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(), setting.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.sendRichMessage(GlobalConfiguration.get().messages.fpsSettingChange,
|
|
+ Placeholder.unparsed("name", setting.friendlyName()),
|
|
+ Placeholder.unparsed("state", state)
|
|
+ );
|
|
+
|
|
+ // Update toggle all icon
|
|
+ this.refreshSlot(player, 26);
|
|
+ }, 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 1a37654aff9a9c86c9f7af10a1cf721371f0c5ec..82644b34a77dc5e5af38260b7b07b3ec9aceae33 100644
|
|
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
|
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
|
@@ -19,7 +19,7 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet<ClientGamePa
|
|
private static final int POS_IN_SECTION_BITS = 12;
|
|
private final SectionPos sectionPos;
|
|
private final short[] positions;
|
|
- private final BlockState[] states;
|
|
+ public final BlockState[] states; // Sakura - private -> public
|
|
|
|
public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, ShortSet positions, LevelChunkSection section) {
|
|
this.sectionPos = sectionPos;
|
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
index af8cb316ac169aa8d98a88765b85bb013b9ba961..7e77a384855904a36c717c311db7cf24566774b9 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
@@ -172,6 +172,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
return null; // Paper - rewrite chunk system
|
|
}
|
|
// Paper end
|
|
+ private final it.unimi.dsi.fastutil.longs.Long2IntMap minimalEntities; // Sakura - visibility api; minimal tnt/sand
|
|
|
|
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
|
|
super(new RegionStorageInfo(session.getLevelId(), world.dimension(), "chunk"), session.getDimensionPath(world.dimension()).resolve("region"), dataFixer, dsync);
|
|
@@ -220,6 +221,10 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
this.poiManager = new PoiManager(new RegionStorageInfo(session.getLevelId(), world.dimension(), "poi"), path.resolve("poi"), dataFixer, dsync, iregistrycustom, world.getServer(), world);
|
|
this.setServerViewDistance(viewDistance);
|
|
this.worldGenContext = new WorldGenContext(world, chunkGenerator, structureTemplateManager, this.lightEngine, null); // Paper - rewrite chunk system
|
|
+ // Sakura start - visibility api; minimal tnt/sand
|
|
+ this.minimalEntities = new it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap();
|
|
+ this.minimalEntities.defaultReturnValue(Integer.MIN_VALUE);
|
|
+ // Sakura end - visibility api; minimal tnt/sand
|
|
}
|
|
|
|
// Paper start
|
|
@@ -943,6 +948,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
}
|
|
((ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerTrackedEntity)tracker).moonrise$clearPlayers();
|
|
}
|
|
+
|
|
+ this.minimalEntities.clear(); // Sakura - visibility api and command
|
|
}
|
|
// Paper end - optimise entity tracker
|
|
|
|
@@ -1179,6 +1186,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
}
|
|
}
|
|
// Paper end - optimise entity tracker
|
|
+ // Sakura start - visibility api and command
|
|
+ private boolean checkEntityVisibility(ServerPlayer player) {
|
|
+ if (!player.visibility.isModified() || !(this.entity.isPrimedTNT || this.entity.isFallingBlock)) {
|
|
+ return true;
|
|
+ }
|
|
+ if (this.entity.isPrimedTNT && player.visibility.isToggled(me.samsuik.sakura.player.visibility.Visibility.Setting.TNT_VISIBILITY)) {
|
|
+ return false;
|
|
+ }
|
|
+ if (this.entity.isFallingBlock && player.visibility.isToggled(me.samsuik.sakura.player.visibility.Visibility.Setting.SAND_VISIBILITY)) {
|
|
+ return false;
|
|
+ }
|
|
+ if (player.visibility.isToggled(me.samsuik.sakura.player.visibility.Visibility.Setting.MINIMAL)) {
|
|
+ final long key = this.entity.blockPosition().asLong() ^ this.entity.getType().hashCode();
|
|
+ final long visibleEntity = ChunkMap.this.minimalEntities.get(key);
|
|
+ if (visibleEntity != Integer.MIN_VALUE) {
|
|
+ return this.entity.getId() == visibleEntity;
|
|
+ } else {
|
|
+ ChunkMap.this.minimalEntities.put(key, this.entity.getId());
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+ // Sakura end - visibility api and command
|
|
|
|
public TrackedEntity(final Entity entity, final int i, final int j, final boolean flag) {
|
|
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
|
|
@@ -1256,6 +1286,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
}
|
|
flag = flag && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z);
|
|
// Paper end - Configurable entity tracking range by Y
|
|
+ flag = flag && this.checkEntityVisibility(player); // Sakura start - visibility api and command
|
|
|
|
// CraftBukkit start - respect vanish API
|
|
if (flag && !player.getBukkitEntity().canSee(this.entity.getBukkitEntity())) { // Paper - only consider hits
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
index 1a0819301e0ce05c60b6cb961202a5c60697f6c1..274404085e685e58bfa1cd0ff85ec966fd948538 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1794,7 +1794,19 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
|
|
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
|
|
|
|
if (entityplayer.distanceToSqr(x, y, z) < 4096.0D) {
|
|
- entityplayer.connection.send(new ClientboundExplodePacket(x, y, z, power, explosion.getToBlow(), (Vec3) explosion.getHitPlayers().get(entityplayer), explosion.getBlockInteraction(), explosion.getSmallExplosionParticles(), explosion.getLargeExplosionParticles(), explosion.getExplosionSound()));
|
|
+ // Sakura start - visibility api; let players toggle explosion particles
|
|
+ ParticleOptions smallParticle = explosion.getSmallExplosionParticles();
|
|
+ ParticleOptions largeParticle = explosion.getLargeExplosionParticles();
|
|
+ Vec3 position = new Vec3(x, y, z);
|
|
+ // In 1.22 and later this should be replaced with sending the motion through a PlayerPositionPacket.
|
|
+ // The problem here is SetEntityMotion is capped to 3.9 b/pt and the only other alternate mean was
|
|
+ // implemented in 1.21.3. I believe it's best to just wait on this issue and deal with this hack.
|
|
+ if (entityplayer.visibility.isToggled(me.samsuik.sakura.player.visibility.Visibility.Setting.EXPLOSIONS)) {
|
|
+ position = new Vec3(0.0, -1024.0, 0.0);
|
|
+ smallParticle = largeParticle = net.minecraft.core.particles.ParticleTypes.SMOKE;
|
|
+ }
|
|
+ entityplayer.connection.send(new ClientboundExplodePacket(position.x(), position.y(), position.z(), power, explosion.getToBlow(), (Vec3) explosion.getHitPlayers().get(entityplayer), explosion.getBlockInteraction(), smallParticle, largeParticle, explosion.getExplosionSound()));
|
|
+ // Sakura end - visibility api; let players toggle explosion particles
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index c396580a9cfd86ff261bed439bb4662ae88010b5..007bc568d3fb23f08790044aa3171727996927dc 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -282,6 +282,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
|
|
public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper
|
|
// Paper end - Optional per player mob spawns
|
|
public final int[] mobBackoffCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper - per player mob count backoff
|
|
+ public final me.samsuik.sakura.player.visibility.Visibility visibility = new me.samsuik.sakura.player.visibility.Visibility(); // Sakura - visiblity api
|
|
|
|
// CraftBukkit start
|
|
public CraftPlayer.TransferCookieConnection transferCookieConnection;
|
|
@@ -586,6 +587,15 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
|
|
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 - visibility api
|
|
|
|
this.spawnExtraParticlesOnFall = nbt.getBoolean("spawn_extra_particles_on_fall");
|
|
Tag nbtbase = nbt.get("raid_omen_position");
|
|
@@ -664,6 +674,13 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
|
|
});
|
|
}
|
|
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 - visibility api
|
|
|
|
nbt.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall);
|
|
if (this.raidOmenPosition != null) {
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
|
index 7174f8c89a7cdcf40ff28f6636ecfb23b13ccdaa..208a71435d9be5fa6f6612c0e6d5a843f6442685 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
|
@@ -43,6 +43,23 @@ import org.bukkit.craftbukkit.util.CraftLocation;
|
|
import org.bukkit.craftbukkit.util.Waitable;
|
|
import org.bukkit.event.player.PlayerKickEvent;
|
|
import org.bukkit.event.player.PlayerResourcePackStatusEvent;
|
|
+// Sakura start
|
|
+import com.mojang.datafixers.util.Pair;
|
|
+import me.samsuik.sakura.player.visibility.Visibility.Setting;
|
|
+import net.minecraft.core.component.DataComponents;
|
|
+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.ClientboundSectionBlocksUpdatePacket;
|
|
+import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
|
|
+import net.minecraft.world.entity.EquipmentSlot;
|
|
+import net.minecraft.world.item.ItemStack;
|
|
+import net.minecraft.world.level.block.Blocks;
|
|
+import net.minecraft.world.level.block.DiodeBlock;
|
|
+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 abstract class ServerCommonPacketListenerImpl implements ServerCommonPacketListener, CraftPlayer.TransferCookieConnection {
|
|
|
|
@@ -100,6 +117,65 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
|
protected final org.bukkit.craftbukkit.CraftServer cserver;
|
|
public boolean processedDisconnect;
|
|
|
|
+ // Sakura start - visibility api
|
|
+ private @Nullable Packet<?> recreatePacket(Packet<?> packet) {
|
|
+ me.samsuik.sakura.player.visibility.Visibility visibility = this.player.visibility;
|
|
+ if (packet instanceof ClientboundSetEquipmentPacket equipment && visibility.isToggled(Setting.ENCHANTMENT_GLINT)) {
|
|
+ java.util.List<Pair<EquipmentSlot, ItemStack>> slots = new java.util.ArrayList<>();
|
|
+
|
|
+ for (int i = 0; i < equipment.getSlots().size(); i++) {
|
|
+ Pair<EquipmentSlot, ItemStack> pair = equipment.getSlots().get(i);
|
|
+ ItemStack itemstack = pair.getSecond();
|
|
+
|
|
+ if (itemstack.isEnchanted()) {
|
|
+ ItemStack copy = itemstack.copy();
|
|
+ copy.remove(DataComponents.ENCHANTMENTS);
|
|
+ itemstack = copy;
|
|
+ }
|
|
+
|
|
+ slots.add(new Pair<>(pair.getFirst(), itemstack));
|
|
+ }
|
|
+
|
|
+ packet = new ClientboundSetEquipmentPacket(equipment.getEntity(), slots);
|
|
+ } else if (packet instanceof ClientboundBlockEntityDataPacket blockdata
|
|
+ && visibility.isToggled(Setting.SPAWNERS)
|
|
+ && this.player.level().getBlockIfLoaded(blockdata.getPos()) == Blocks.SPAWNER) {
|
|
+ packet = new ClientboundBlockUpdatePacket(blockdata.getPos(), Blocks.BLACK_STAINED_GLASS.defaultBlockState());
|
|
+ } else if (packet instanceof ClientboundBlockUpdatePacket updatePacket) {
|
|
+ if (visibility.isToggled(Setting.SPAWNERS) && updatePacket.blockState.getBlock() == Blocks.SPAWNER) {
|
|
+ packet = new ClientboundBlockUpdatePacket(updatePacket.getPos(), Blocks.BLACK_STAINED_GLASS.defaultBlockState());
|
|
+ } else if (visibility.isToggled(Setting.REDSTONE)
|
|
+ && (updatePacket.blockState.getBlock() instanceof DiodeBlock
|
|
+ || updatePacket.blockState.getBlock() instanceof RedStoneWireBlock)) {
|
|
+ return null;
|
|
+ } else if (visibility.isToggled(Setting.PISTONS)
|
|
+ && (updatePacket.blockState.getBlock() instanceof PistonBaseBlock
|
|
+ || updatePacket.blockState.getBlock() instanceof PistonHeadBlock)) {
|
|
+ return null;
|
|
+ }
|
|
+ } else if (packet instanceof ClientboundSectionBlocksUpdatePacket sectionPacket) {
|
|
+ for (net.minecraft.world.level.block.state.BlockState state : sectionPacket.states) {
|
|
+ if (visibility.isToggled(Setting.REDSTONE)
|
|
+ && (state.getBlock() instanceof DiodeBlock
|
|
+ || state.getBlock() instanceof RedStoneWireBlock)) {
|
|
+ return null;
|
|
+ } else if (visibility.isToggled(Setting.PISTONS)
|
|
+ && (state.getBlock() instanceof PistonBaseBlock
|
|
+ || state.getBlock() instanceof PistonHeadBlock)) {
|
|
+ return null;
|
|
+ }
|
|
+ }
|
|
+ } else if (packet instanceof ClientboundBlockEventPacket blockevent
|
|
+ && visibility.isToggled(Setting.PISTONS)
|
|
+ && (blockevent.getBlock() instanceof PistonBaseBlock
|
|
+ || blockevent.getBlock() instanceof PistonHeadBlock)) {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ return packet;
|
|
+ }
|
|
+ // Sakura end - visibility api
|
|
+
|
|
public CraftPlayer getCraftPlayer() {
|
|
return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
|
|
// CraftBukkit end
|
|
@@ -302,6 +378,12 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
|
ClientboundSetDefaultSpawnPositionPacket packet6 = (ClientboundSetDefaultSpawnPositionPacket) packet;
|
|
this.player.compassTarget = CraftLocation.toBukkit(packet6.pos, this.getCraftPlayer().getWorld());
|
|
}
|
|
+ // Sakura start - visibility api
|
|
+ if (this.player.visibility.isModified()) {
|
|
+ packet = this.recreatePacket(packet);
|
|
+ if (packet == null) return;
|
|
+ }
|
|
+ // Sakura end - visibility api
|
|
// CraftBukkit end
|
|
if (packet.isTerminal()) {
|
|
this.close();
|
|
@@ -315,8 +397,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
|
CrashReport crashreport = CrashReport.forThrowable(throwable, "Sending packet");
|
|
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Packet being sent");
|
|
|
|
+ // Sakura start - this has to be effectively final as we're modifying the packet above
|
|
+ var packetFinal = packet;
|
|
crashreportsystemdetails.setDetail("Packet class", () -> {
|
|
- return packet.getClass().getCanonicalName();
|
|
+ return packetFinal.getClass().getCanonicalName();
|
|
+ // Sakura end
|
|
});
|
|
throw new ReportedException(crashreport);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index 064d52d4479727c6a32bf357be8da32d1760e7fc..b0b6bd0fe9c50a237d889e7bdcab290c8424af42 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -3221,6 +3221,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
|
|
|
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 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..d2e91843df93753a78bb9bd6839de287dc2ce4e5 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
|
@@ -549,6 +549,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
|
}
|
|
}
|
|
// Paper end - optimise entity tracker
|
|
+ // Sakura start - visibility api and command
|
|
+ public boolean isPrimedTNT;
|
|
+ public boolean isFallingBlock;
|
|
+ // Sakura end - visibility api and command
|
|
|
|
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 b83be9bbb9f348da83c0fd1ecc7f65c8a58b45b9..1bfdebe6c1057ee19fb96d8f0f571c9d20d14cc6 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
|
@@ -78,6 +78,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 42bd2d9a1528b6210e4dfb56233062fd97c9743b..28a15f612239614c6c56974da5855ce3bfd7c89e 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
|
@@ -57,6 +57,7 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
|
public PrimedTnt(EntityType<? extends PrimedTnt> 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/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index 42d7660efe5baa6f796f2a7606686c765b6f2478..71f9c53cb3a3130adcbbf92a081fbe2b32efd626 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -547,6 +547,13 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
this.getHandle().displayName = name == null ? this.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) {
|