-
Notifications
You must be signed in to change notification settings - Fork 4
Fix unvanish skin layers and mod crashes by using vanilla entity trac… #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,12 @@ | |
| import net.kyori.adventure.text.Component; | ||
| import net.minecraft.item.ItemStack; | ||
| import net.minecraft.item.Items; | ||
| import net.minecraft.network.listener.ClientPlayPacketListener; | ||
| import net.minecraft.network.packet.Packet; | ||
| import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; | ||
| import net.minecraft.registry.Registries; | ||
| import net.minecraft.server.MinecraftServer; | ||
| import net.minecraft.server.network.EntityTrackerEntry; | ||
| import net.minecraft.server.network.ServerPlayerEntity; | ||
| import net.minecraft.text.Text; | ||
| import net.minecraft.util.Identifier; | ||
|
|
@@ -26,6 +30,7 @@ | |
| import java.time.format.DateTimeFormatter; | ||
| import java.util.*; | ||
| import java.util.concurrent.*; | ||
| import java.util.function.Predicate; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| import static gg.modl.minecraft.core.util.Java8Collections.*; | ||
|
|
@@ -184,47 +189,36 @@ private void hidePlayerFrom(ServerPlayerEntity toHide, ServerPlayerEntity viewer | |
| } | ||
|
|
||
| private void showPlayerTo(ServerPlayerEntity toShow, ServerPlayerEntity viewer) { | ||
| var peApi = PacketEvents.getAPI(); | ||
| if (peApi == null) return; | ||
|
|
||
| com.mojang.authlib.GameProfile mojangProfile = toShow.getGameProfile(); | ||
| List<TextureProperty> textureProperties = new ArrayList<>(); | ||
| for (com.mojang.authlib.properties.Property prop : mojangProfile.properties().get("textures")) { | ||
| textureProperties.add(new TextureProperty("textures", prop.value(), prop.signature())); | ||
| if (toShow == null || viewer == null || toShow == viewer) { | ||
| return; | ||
| } | ||
| UserProfile profile = new UserProfile(toShow.getUuid(), mojangProfile.name(), textureProperties); | ||
|
|
||
| com.github.retrooper.packetevents.protocol.player.GameMode peGameMode = | ||
| com.github.retrooper.packetevents.protocol.player.GameMode.values()[toShow.interactionManager.getGameMode().ordinal()]; | ||
| viewer.networkHandler.sendPacket(PlayerListS2CPacket.entryFromPlayer(List.of(toShow))); | ||
|
|
||
| WrapperPlayServerPlayerInfoUpdate.PlayerInfo info = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( | ||
| profile, true, toShow.networkHandler.getLatency(), peGameMode, | ||
| net.kyori.adventure.text.Component.text(toShow.getName().getString()), null | ||
| ); | ||
| EntityTrackerEntry trackerEntry = new EntityTrackerEntry( | ||
| toShow.getEntityWorld(), | ||
| toShow, | ||
| toShow.getType().getTrackTickInterval(), | ||
| toShow.getType().alwaysUpdateVelocity(), | ||
| new EntityTrackerEntry.TrackerPacketSender() { | ||
| @Override | ||
| public void sendToListeners(Packet<? super ClientPlayPacketListener> packet) { | ||
| } | ||
|
|
||
| peApi.getPlayerManager().sendPacket(viewer, | ||
| new WrapperPlayServerPlayerInfoUpdate( | ||
| EnumSet.of( | ||
| WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE | ||
| ), | ||
| info | ||
| )); | ||
| @Override | ||
| public void sendToSelfAndListeners(Packet<? super ClientPlayPacketListener> packet) { | ||
| } | ||
|
|
||
| peApi.getPlayerManager().sendPacket(viewer, | ||
| new WrapperPlayServerSpawnEntity( | ||
| toShow.getId(), | ||
| Optional.of(toShow.getUuid()), | ||
| EntityTypes.PLAYER, | ||
| new Vector3d(toShow.getX(), toShow.getY(), toShow.getZ()), | ||
| toShow.getPitch(), | ||
| toShow.getYaw(), | ||
| toShow.getYaw(), | ||
| 0, | ||
| Optional.of(new Vector3d(0, 0, 0)) | ||
| )); | ||
| @Override | ||
| public void sendToListenersIf( | ||
| Packet<? super ClientPlayPacketListener> packet, | ||
| Predicate<ServerPlayerEntity> predicate | ||
| ) { | ||
| } | ||
| } | ||
| ); | ||
|
|
||
| trackerEntry.sendPackets(viewer, packet -> viewer.networkHandler.sendPacket(packet)); | ||
|
Comment on lines
+196
to
+221
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Rule Used: THE CENTRAL RULE everything else serves: maintain ... (source) Prompt To Fix With AIThis is a comment left during a code review.
Path: platforms/fabric-12111/src/main/java/gg/modl/minecraft/fabric/v1_21_11/handler/FabricStaffModeHandler.java
Line: 196-221
Comment:
**Unconditional tracker pairing**
`unvanish()` calls this for every online player, but this new vanilla-packet path sends player-list and tracker pairing data without checking that the viewer is in the same world or inside the normal tracking range. If a vanished staff member unvanishes in another dimension or far away, this can spawn a ghost player entity for viewers who vanilla tracking would not pair with at all. Gate this send through the same world/range conditions, or use the real server tracker’s pairing decision instead of sending a fresh tracker entry to every viewer.
**Rule Used:** THE CENTRAL RULE everything else serves: maintain ... ([source](https://app.greptile.com/review/custom-context?memory=21719055-65fa-440f-b434-eba8d358d917))
How can I resolve this? If you propose a fix, please make it concise. |
||
| } | ||
|
|
||
| private void updateVanishHotbarItem(ServerPlayerEntity player, boolean isVanished) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,10 @@ | |
| import net.kyori.adventure.text.Component; | ||
| import net.minecraft.item.ItemStack; | ||
| import net.minecraft.item.Items; | ||
| import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; | ||
| import net.minecraft.registry.Registries; | ||
| import net.minecraft.server.MinecraftServer; | ||
| import net.minecraft.server.network.EntityTrackerEntry; | ||
| import net.minecraft.server.network.ServerPlayerEntity; | ||
| import net.minecraft.text.Text; | ||
| import net.minecraft.util.Identifier; | ||
|
|
@@ -183,48 +185,24 @@ private void hidePlayerFrom(ServerPlayerEntity toHide, ServerPlayerEntity viewer | |
| new WrapperPlayServerDestroyEntities(toHide.getId())); | ||
| } | ||
|
|
||
| private void showPlayerTo(ServerPlayerEntity toShow, ServerPlayerEntity viewer) { | ||
| var peApi = PacketEvents.getAPI(); | ||
| if (peApi == null) return; | ||
|
|
||
| com.mojang.authlib.GameProfile mojangProfile = toShow.getGameProfile(); | ||
| List<TextureProperty> textureProperties = new ArrayList<>(); | ||
| for (com.mojang.authlib.properties.Property prop : mojangProfile.getProperties().get("textures")) { | ||
| textureProperties.add(new TextureProperty("textures", prop.value(), prop.signature())); | ||
| private void showPlayerTo(ServerPlayerEntity toShow, ServerPlayerEntity viewer) { | ||
| if (toShow == null || viewer == null || toShow == viewer) { | ||
| return; | ||
| } | ||
| UserProfile profile = new UserProfile(toShow.getUuid(), mojangProfile.getName(), textureProperties); | ||
|
|
||
| com.github.retrooper.packetevents.protocol.player.GameMode peGameMode = | ||
| com.github.retrooper.packetevents.protocol.player.GameMode.values()[toShow.interactionManager.getGameMode().ordinal()]; | ||
| viewer.networkHandler.sendPacket(PlayerListS2CPacket.entryFromPlayer(List.of(toShow))); | ||
|
|
||
| WrapperPlayServerPlayerInfoUpdate.PlayerInfo info = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( | ||
| profile, true, toShow.networkHandler.getLatency(), peGameMode, | ||
| net.kyori.adventure.text.Component.text(toShow.getName().getString()), null | ||
| EntityTrackerEntry trackerEntry = new EntityTrackerEntry( | ||
| toShow.getServerWorld(), | ||
| toShow, | ||
| toShow.getType().getTrackTickInterval(), | ||
| toShow.getType().alwaysUpdateVelocity(), | ||
| packet -> { | ||
| } | ||
| ); | ||
|
|
||
| peApi.getPlayerManager().sendPacket(viewer, | ||
| new WrapperPlayServerPlayerInfoUpdate( | ||
| EnumSet.of( | ||
| WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE | ||
| ), | ||
| info | ||
| )); | ||
|
|
||
| peApi.getPlayerManager().sendPacket(viewer, | ||
| new WrapperPlayServerSpawnEntity( | ||
| toShow.getId(), | ||
| Optional.of(toShow.getUuid()), | ||
| EntityTypes.PLAYER, | ||
| new Vector3d(toShow.getX(), toShow.getY(), toShow.getZ()), | ||
| toShow.getPitch(), | ||
| toShow.getYaw(), | ||
| toShow.getYaw(), | ||
| 0, | ||
| Optional.of(new Vector3d(0, 0, 0)) | ||
| )); | ||
| trackerEntry.sendPackets(viewer, packet -> viewer.networkHandler.sendPacket(packet)); | ||
|
Comment on lines
+194
to
+205
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Rule Used: THE CENTRAL RULE everything else serves: maintain ... (source) Prompt To Fix With AIThis is a comment left during a code review.
Path: platforms/fabric-1214/src/main/java/gg/modl/minecraft/fabric/v1_21_4/handler/FabricStaffModeHandler.java
Line: 194-205
Comment:
**Unconditional tracker pairing**
`unvanish()` calls this for every online player, but this new vanilla-packet path sends player-list and tracker pairing data without checking that the viewer is in the same world or inside the normal tracking range. If a vanished staff member unvanishes in another dimension or far away, this can spawn a ghost player entity for viewers who vanilla tracking would not pair with at all. Gate this send through the same world/range conditions, or use the real server tracker’s pairing decision instead of sending a fresh tracker entry to every viewer.
**Rule Used:** THE CENTRAL RULE everything else serves: maintain ... ([source](https://app.greptile.com/review/custom-context?memory=21719055-65fa-440f-b434-eba8d358d917))
How can I resolve this? If you propose a fix, please make it concise. |
||
| } | ||
|
|
||
| private void updateVanishHotbarItem(ServerPlayerEntity player, boolean isVanished) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,8 +15,10 @@ | |
| import net.kyori.adventure.text.Component; | ||
| import net.minecraft.item.ItemStack; | ||
| import net.minecraft.item.Items; | ||
| import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket; | ||
| import net.minecraft.registry.Registries; | ||
| import net.minecraft.server.MinecraftServer; | ||
| import net.minecraft.server.network.EntityTrackerEntry; | ||
| import net.minecraft.server.network.ServerPlayerEntity; | ||
| import net.minecraft.text.Text; | ||
| import net.minecraft.util.Identifier; | ||
|
|
@@ -183,49 +185,72 @@ private void hidePlayerFrom(ServerPlayerEntity toHide, ServerPlayerEntity viewer | |
| new WrapperPlayServerDestroyEntities(toHide.getId())); | ||
| } | ||
|
|
||
| private void showPlayerTo(ServerPlayerEntity toShow, ServerPlayerEntity viewer) { | ||
| var peApi = PacketEvents.getAPI(); | ||
| if (peApi == null) return; | ||
|
|
||
| com.mojang.authlib.GameProfile mojangProfile = toShow.getGameProfile(); | ||
| List<TextureProperty> textureProperties = new ArrayList<>(); | ||
| for (com.mojang.authlib.properties.Property prop : mojangProfile.getProperties().get("textures")) { | ||
| textureProperties.add(new TextureProperty("textures", prop.value(), prop.signature())); | ||
|
|
||
| private void showPlayerTo(ServerPlayerEntity toShow, ServerPlayerEntity viewer) { | ||
| if (toShow == null || viewer == null || toShow == viewer) { | ||
| return; | ||
| } | ||
| UserProfile profile = new UserProfile(toShow.getUuid(), mojangProfile.getName(), textureProperties); | ||
|
|
||
| com.github.retrooper.packetevents.protocol.player.GameMode peGameMode = | ||
| com.github.retrooper.packetevents.protocol.player.GameMode.values()[toShow.interactionManager.getGameMode().ordinal()]; | ||
| viewer.networkHandler.sendPacket(PlayerListS2CPacket.entryFromPlayer(List.of(toShow))); | ||
|
|
||
| WrapperPlayServerPlayerInfoUpdate.PlayerInfo info = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( | ||
| profile, true, toShow.networkHandler.getLatency(), peGameMode, | ||
| net.kyori.adventure.text.Component.text(toShow.getName().getString()), null | ||
| ); | ||
| EntityTrackerEntry trackerEntry = new EntityTrackerEntry( | ||
| toShow.getWorld(), | ||
| toShow, | ||
| toShow.getType().getTrackTickInterval(), | ||
| toShow.getType().alwaysUpdateVelocity(), | ||
| packet -> {}, | ||
| (packet, excludedPlayers) -> { | ||
|
|
||
| peApi.getPlayerManager().sendPacket(viewer, | ||
| new WrapperPlayServerPlayerInfoUpdate( | ||
| EnumSet.of( | ||
| WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY, | ||
| WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE | ||
| ), | ||
| info | ||
| )); | ||
| } | ||
| ); | ||
|
|
||
| peApi.getPlayerManager().sendPacket(viewer, | ||
| new WrapperPlayServerSpawnEntity( | ||
| toShow.getId(), | ||
| Optional.of(toShow.getUuid()), | ||
| EntityTypes.PLAYER, | ||
| new Vector3d(toShow.getX(), toShow.getY(), toShow.getZ()), | ||
| toShow.getPitch(), | ||
| toShow.getYaw(), | ||
| toShow.getYaw(), | ||
| 0, | ||
| Optional.of(new Vector3d(0, 0, 0)) | ||
| )); | ||
| } | ||
| trackerEntry.sendPackets(viewer, packet -> viewer.networkHandler.sendPacket(packet)); | ||
|
Comment on lines
+195
to
+208
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Rule Used: THE CENTRAL RULE everything else serves: maintain ... (source) Prompt To Fix With AIThis is a comment left during a code review.
Path: platforms/fabric-1218/src/main/java/gg/modl/minecraft/fabric/v1_21_8/handler/FabricStaffModeHandler.java
Line: 195-208
Comment:
**Unconditional tracker pairing**
`unvanish()` calls this for every online player, but this new vanilla-packet path sends player-list and tracker pairing data without checking that the viewer is in the same world or inside the normal tracking range. If a vanished staff member unvanishes in another dimension or far away, this can spawn a ghost player entity for viewers who vanilla tracking would not pair with at all. Gate this send through the same world/range conditions, or use the real server tracker’s pairing decision instead of sending a fresh tracker entry to every viewer.
**Rule Used:** THE CENTRAL RULE everything else serves: maintain ... ([source](https://app.greptile.com/review/custom-context?memory=21719055-65fa-440f-b434-eba8d358d917))
How can I resolve this? If you propose a fix, please make it concise. |
||
| } | ||
|
|
||
| // private void showPlayerTo(ServerPlayerEntity toShow, ServerPlayerEntity viewer) { | ||
| // var peApi = PacketEvents.getAPI(); | ||
| // if (peApi == null) return; | ||
| // | ||
| // com.mojang.authlib.GameProfile mojangProfile = toShow.getGameProfile(); | ||
| // List<TextureProperty> textureProperties = new ArrayList<>(); | ||
| // for (com.mojang.authlib.properties.Property prop : mojangProfile.getProperties().get("textures")) { | ||
| // textureProperties.add(new TextureProperty("textures", prop.value(), prop.signature())); | ||
| // } | ||
| // UserProfile profile = new UserProfile(toShow.getUuid(), mojangProfile.getName(), textureProperties); | ||
| // | ||
| // com.github.retrooper.packetevents.protocol.player.GameMode peGameMode = | ||
| // com.github.retrooper.packetevents.protocol.player.GameMode.values()[toShow.interactionManager.getGameMode().ordinal()]; | ||
| // | ||
| // WrapperPlayServerPlayerInfoUpdate.PlayerInfo info = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo( | ||
| // profile, true, toShow.networkHandler.getLatency(), peGameMode, | ||
| // net.kyori.adventure.text.Component.text(toShow.getName().getString()), null | ||
| // ); | ||
| // | ||
| // peApi.getPlayerManager().sendPacket(viewer, | ||
| // new WrapperPlayServerPlayerInfoUpdate( | ||
| // EnumSet.of( | ||
| // WrapperPlayServerPlayerInfoUpdate.Action.ADD_PLAYER, | ||
| // WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LISTED, | ||
| // WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_LATENCY, | ||
| // WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE | ||
| // ), | ||
| // info | ||
| // )); | ||
| // | ||
| // peApi.getPlayerManager().sendPacket(viewer, | ||
| // new WrapperPlayServerSpawnEntity( | ||
| // toShow.getId(), | ||
| // Optional.of(toShow.getUuid()), | ||
| // EntityTypes.PLAYER, | ||
| // new Vector3d(toShow.getX(), toShow.getY(), toShow.getZ()), | ||
| // toShow.getPitch(), | ||
| // toShow.getYaw(), | ||
| // toShow.getYaw(), | ||
| // 0, | ||
| // Optional.of(new Vector3d(0, 0, 0)) | ||
| // )); | ||
| // } | ||
|
|
||
| private void updateVanishHotbarItem(ServerPlayerEntity player, boolean isVanished) { | ||
| Map<Integer, StaffModeConfig.HotbarItem> hotbar = getActiveHotbar(player.getUuid()); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unvanish()calls this for every online player, but this new vanilla-packet path sends player-list and tracker pairing data without checking that the viewer is in the same world or inside the normal tracking range. If a vanished staff member unvanishes in another dimension or far away, this can spawn a ghost player entity for viewers who vanilla tracking would not pair with at all. Gate this send through the same world/range conditions, or use the real server tracker’s pairing decision instead of sending a fresh tracker entry to every viewer.Rule Used: THE CENTRAL RULE everything else serves: maintain ... (source)
Prompt To Fix With AI