make player list show vanished players

not really a much of work because i already have a working players module
This commit is contained in:
Chayapak 2023-06-11 10:56:14 +07:00
parent e51eae558c
commit 29ef3324fc
9 changed files with 91 additions and 34 deletions

View file

@ -6,7 +6,7 @@ import net.minecraft.text.Text;
public class Listener {
public void chatMessageReceived (Text message) {}
public void packetReceived (Packet packet) {}
public void packetReceived (Packet<?> packet) {}
public void packetSent (Packet packet) {}
public void packetSent (Packet<?> packet) {}
}

View file

@ -1,11 +1,22 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.network.PlayerListEntry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.text.Text;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
public interface ClientPlayNetworkHandlerAccessor {
@Accessor("CHAT_VALIDATION_FAILED_TEXT")
public static Text chatValidationFailedText () { throw new AssertionError(); }
static Text chatValidationFailedText () { throw new AssertionError(); }
@Accessor("playerListEntries")
Map<UUID, PlayerListEntry> playerListEntries();
@Accessor("listedPlayerListEntries")
Set<PlayerListEntry> listedPlayerListEntries();
}

View file

@ -0,0 +1,11 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(ClientPlayNetworkHandler.class)
public interface ClientPlayNetworkHandlerInvoker {
@Invoker("isSecureChatEnforced")
public boolean isSecureChatEnforced();
}

View file

@ -1,18 +1,19 @@
package land.chipmunk.chipmunkmod.mixin;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.modules.*;
import net.minecraft.client.network.ClientDynamicRegistryType;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
import net.minecraft.registry.CombinedDynamicRegistries;
import net.minecraft.resource.featuretoggle.FeatureSet;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.registry.CombinedDynamicRegistries;
import net.minecraft.client.network.ClientDynamicRegistryType;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
@ -34,4 +35,9 @@ public class ClientPlayNetworkHandlerMixin {
private void onGameJoinHead (GameJoinS2CPacket packet, CallbackInfo ci) {
Players.INSTANCE.init();
}
@Inject(method = "onPlayerRemove", at = @At("HEAD"), cancellable = true)
private void onPlayerRemove (PlayerRemoveS2CPacket packet, CallbackInfo ci) {
ci.cancel();
}
}

View file

@ -6,8 +6,11 @@ import com.mojang.brigadier.suggestion.Suggestions;
import land.chipmunk.chipmunkmod.data.MutablePlayerListEntry;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import land.chipmunk.chipmunkmod.mixin.ClientPlayNetworkHandlerAccessor;
import land.chipmunk.chipmunkmod.mixin.ClientPlayNetworkHandlerInvoker;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
@ -17,6 +20,8 @@ import net.minecraft.text.Text;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
public class Players extends Listener {
public List<MutablePlayerListEntry> list = new ArrayList<>();
@ -63,7 +68,7 @@ public class Players extends Listener {
}
@Override
public void packetReceived (Packet packet) {
public void packetReceived (Packet<?> packet) {
if (packet instanceof PlayerListS2CPacket) packetReceived((PlayerListS2CPacket) packet);
else if (packet instanceof PlayerRemoveS2CPacket) packetReceived((PlayerRemoveS2CPacket) packet);
}
@ -136,7 +141,10 @@ public class Players extends Listener {
private void addPlayer (PlayerListS2CPacket.Entry newEntry) {
try {
final MutablePlayerListEntry duplicate = getEntry(newEntry);
if (duplicate != null) list.remove(duplicate);
if (duplicate != null) {
removeFromPlayerList(duplicate.profile().getId());
list.remove(duplicate);
}
list.add(new MutablePlayerListEntry(newEntry));
} catch (Exception e) {
@ -174,6 +182,11 @@ public class Players extends Listener {
final MutablePlayerListEntry target = getEntry(uuid);
if (target == null) return;
if (!serverHasCommand("scoreboard")) {
removeFromPlayerList(uuid);
return;
}
final CompletableFuture<CommandSuggestionsS2CPacket> future = TabComplete.INSTANCE.complete("/scoreboard players add ");
if (future == null) return;
@ -187,9 +200,12 @@ public class Players extends Listener {
final Message tooltip = suggestion.getTooltip();
if (tooltip != null || !suggestion.getText().equals(username)) continue;
return packet;
}
removeFromPlayerList(uuid);
list.remove(target);
return packet;
});
@ -197,4 +213,12 @@ public class Players extends Listener {
e.printStackTrace();
}
}
private void removeFromPlayerList (UUID uuid) {
client.getSocialInteractionsManager().setPlayerOffline(uuid);
final PlayerListEntry playerListEntry = ((ClientPlayNetworkHandlerAccessor) MinecraftClient.getInstance().getNetworkHandler()).playerListEntries().remove(uuid);
if (playerListEntry != null) {
((ClientPlayNetworkHandlerAccessor) MinecraftClient.getInstance().getNetworkHandler()).listedPlayerListEntries().remove(playerListEntry);
}
}
}

View file

@ -7,14 +7,14 @@ import lombok.Setter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import lombok.Getter;
import net.minecraft.text.Text;
import java.util.Timer;
import java.util.TimerTask;
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
public class SelfCare extends Listener {
private final MinecraftClient client;
@Getter private final long interval;
@ -114,19 +114,4 @@ public class SelfCare extends Listener {
if (!cspy && cspyEnabled) { if (serverHasCommand("c")) networkHandler.sendChatCommand("c on"); }
else if (!hasSkin && !skin.equals("off")) { if (serverHasCommand("skin")) networkHandler.sendChatCommand("skin " + skin); }
}
// TODO: Move this into a separate class related to server info gathering (and yes, I plan on making this d y n a m i c and require little to no configuration for most servers)
private boolean serverHasCommand (String name) {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
if (networkHandler == null) return false;
for (CommandNode node : networkHandler.getCommandDispatcher().getRoot().getChildren()) {
if (!(node instanceof LiteralCommandNode literal)) continue;
if (literal.getLiteral().equals(name)) return true;
}
return false;
}
}

View file

@ -2,7 +2,6 @@ package land.chipmunk.chipmunkmod.modules;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import lombok.Getter;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.ClientConnection;
@ -22,8 +21,6 @@ public class TabComplete extends Listener {
public static TabComplete INSTANCE = new TabComplete(MinecraftClient.getInstance());
@Getter private boolean loggedIn = false;
public TabComplete (MinecraftClient client) {
this.client = client;
ListenerManager.addListener(this);
@ -41,7 +38,6 @@ public class TabComplete extends Listener {
if (connection == null) return null;
final int transactionId = nextTransactionId++;
if (nextTransactionId > Integer.MAX_VALUE) nextTransactionId = 0; // ? Can and should I use negative numbers too?
connection.send(new RequestCommandCompletionsC2SPacket(transactionId, command));
final CompletableFuture<CommandSuggestionsS2CPacket> future = new CompletableFuture<>();
@ -50,7 +46,7 @@ public class TabComplete extends Listener {
}
@Override
public void packetReceived (Packet packet) {
public void packetReceived (Packet<?> packet) {
if (packet instanceof CommandSuggestionsS2CPacket) packetReceived((CommandSuggestionsS2CPacket) packet);
}

View file

@ -0,0 +1,23 @@
package land.chipmunk.chipmunkmod.util;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
public class ServerUtilities {
public static boolean serverHasCommand (String name) {
final MinecraftClient client = MinecraftClient.getInstance();
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
if (networkHandler == null) return false;
for (CommandNode node : networkHandler.getCommandDispatcher().getRoot().getChildren()) {
if (!(node instanceof LiteralCommandNode literal)) continue;
if (literal.getLiteral().equals(name)) return true;
}
return false;
}
}

View file

@ -11,6 +11,7 @@
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerAccessor",
"ClientPlayNetworkHandlerMixin",
"ClientPlayNetworkHandlerInvoker",
"MinecraftClientAccessor",
"LightmapTextureManagerMixin",
"DecoderHandlerMixin",