Skip to content

Commit

Permalink
Add player join/leave messages to Notifier (#4952)
Browse files Browse the repository at this point in the history
Co-authored-by: Wide_Cat <[email protected]>
  • Loading branch information
0xTas and Wide-Cat authored Oct 18, 2024
1 parent 015efc6 commit 42fb908
Showing 1 changed file with 137 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import meteordevelopment.meteorclient.events.entity.EntityAddedEvent;
import meteordevelopment.meteorclient.events.entity.EntityRemovedEvent;
import meteordevelopment.meteorclient.events.game.GameJoinedEvent;
import meteordevelopment.meteorclient.events.game.GameLeftEvent;
import meteordevelopment.meteorclient.events.packets.PacketEvent;
import meteordevelopment.meteorclient.events.world.TickEvent;
import meteordevelopment.meteorclient.settings.*;
Expand All @@ -20,16 +21,20 @@
import meteordevelopment.meteorclient.utils.player.ChatUtils;
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.collection.ArrayListDeque;
import net.minecraft.util.math.Vec3d;

import java.util.*;
Expand All @@ -40,6 +45,7 @@ public class Notifier extends Module {
private final SettingGroup sgTotemPops = settings.createGroup("Totem Pops");
private final SettingGroup sgVisualRange = settings.createGroup("Visual Range");
private final SettingGroup sgPearl = settings.createGroup("Pearl");
private final SettingGroup sgJoinsLeaves = settings.createGroup("Joins/Leaves");

// Totem Pops

Expand Down Expand Up @@ -156,9 +162,37 @@ public class Notifier extends Module {
.build()
);

// Joins/Leaves

private final Setting<JoinLeaveModes> joinsLeavesMode = sgJoinsLeaves.add(new EnumSetting.Builder<JoinLeaveModes>()
.name("player-joins-leaves")
.description("How to handle player join/leave notifications.")
.defaultValue(JoinLeaveModes.None)
.build()
);

private final Setting<Integer> notificationDelay = sgJoinsLeaves.add(new IntSetting.Builder()
.name("notification-delay")
.description("How long to wait in ticks before posting the next join/leave notification in your chat.")
.range(0, 1000)
.sliderRange(0, 100)
.defaultValue(0)
.build()
);

private final Setting<Boolean> simpleNotifications = sgJoinsLeaves.add(new BoolSetting.Builder()
.name("simple-notifications")
.description("Display join/leave notifications without a prefix, to reduce chat clutter.")
.defaultValue(true)
.build()
);

private int timer;
private boolean loginPacket = true;
private final Object2IntMap<UUID> totemPopMap = new Object2IntOpenHashMap<>();
private final Object2IntMap<UUID> chatIdMap = new Object2IntOpenHashMap<>();
private final Map<Integer, Vec3d> pearlStartPosMap = new HashMap<>();
private final ArrayListDeque<Text> messageQueue = new ArrayListDeque<>();

private final Random random = new Random();

Expand Down Expand Up @@ -187,10 +221,8 @@ private void onEntityAdded(EntityAddedEvent event) {
}
}

if (pearl.get()) {
if (event.entity instanceof EnderPearlEntity pearl) {
pearlStartPosMap.put(pearl.getId(), new Vec3d(pearl.getX(), pearl.getY(), pearl.getZ()));
}
if (pearl.get() && event.entity instanceof EnderPearlEntity pearlEntity) {
pearlStartPosMap.put(pearlEntity.getId(), new Vec3d(pearlEntity.getX(), pearlEntity.getY(), pearlEntity.getZ()));
}
}

Expand Down Expand Up @@ -229,7 +261,7 @@ private void onEntityRemoved(EntityRemovedEvent event) {
}
}

// Totem Pops
// Totem Pops && Joins/Leaves

@Override
public void onActivate() {
Expand All @@ -238,42 +270,76 @@ public void onActivate() {
pearlStartPosMap.clear();
}

@Override
public void onDeactivate() {
timer = 0;
messageQueue.clear();
}

@EventHandler
private void onGameJoin(GameJoinedEvent event) {
timer = 0;
totemPopMap.clear();
chatIdMap.clear();
messageQueue.clear();
pearlStartPosMap.clear();
}

@EventHandler
private void onReceivePacket(PacketEvent.Receive event) {
if (!totemPops.get()) return;
if (!(event.packet instanceof EntityStatusS2CPacket p)) return;

if (p.getStatus() != 35) return;
private void onGameLeave(GameLeftEvent event) {
loginPacket = true;
}

Entity entity = p.getEntity(mc.world);
@EventHandler
private void onReceivePacket(PacketEvent.Receive event) {
switch (event.packet) {
case PlayerListS2CPacket packet when joinsLeavesMode.get().equals(JoinLeaveModes.Both) || joinsLeavesMode.get().equals(JoinLeaveModes.Joins) -> {
if (loginPacket) {
loginPacket = false;
return;
}

if (!(entity instanceof PlayerEntity)) return;
if (packet.getActions().contains(PlayerListS2CPacket.Action.ADD_PLAYER)) {
createJoinNotifications(packet);
}
}
case PlayerRemoveS2CPacket packet when joinsLeavesMode.get().equals(JoinLeaveModes.Both) || joinsLeavesMode.get().equals(JoinLeaveModes.Leaves) ->
createLeaveNotification(packet);

if ((entity.equals(mc.player) && totemsIgnoreOwn.get())
|| (Friends.get().isFriend(((PlayerEntity) entity)) && totemsIgnoreOthers.get())
|| (!Friends.get().isFriend(((PlayerEntity) entity)) && totemsIgnoreFriends.get())
) return;
case EntityStatusS2CPacket packet when totemPops.get() && packet.getStatus() == 35 && packet.getEntity(mc.world) instanceof PlayerEntity entity -> {
if ((entity.equals(mc.player) && totemsIgnoreOwn.get())
|| (Friends.get().isFriend(entity) && totemsIgnoreOthers.get())
|| (!Friends.get().isFriend(entity) && totemsIgnoreFriends.get())
) return;

synchronized (totemPopMap) {
int pops = totemPopMap.getOrDefault(entity.getUuid(), 0);
totemPopMap.put(entity.getUuid(), ++pops);
synchronized (totemPopMap) {
int pops = totemPopMap.getOrDefault(entity.getUuid(), 0);
totemPopMap.put(entity.getUuid(), ++pops);

double distance = PlayerUtils.distanceTo(entity);
if (totemsDistanceCheck.get() && distance > totemsDistance.get()) return;
double distance = PlayerUtils.distanceTo(entity);
if (totemsDistanceCheck.get() && distance > totemsDistance.get()) return;

ChatUtils.sendMsg(getChatId(entity), Formatting.GRAY, "(highlight)%s (default)popped (highlight)%d (default)%s.", entity.getName().getString(), pops, pops == 1 ? "totem" : "totems");
ChatUtils.sendMsg(getChatId(entity), Formatting.GRAY, "(highlight)%s (default)popped (highlight)%d (default)%s.", entity.getName().getString(), pops, pops == 1 ? "totem" : "totems");
}
}
default -> {}
}
}

@EventHandler
private void onTick(TickEvent.Post event) {
if (joinsLeavesMode.get() != JoinLeaveModes.None) {
timer++;
while (timer >= notificationDelay.get() && !messageQueue.isEmpty()) {
timer = 0;
if (simpleNotifications.get()) {
mc.player.sendMessage(messageQueue.removeFirst());
} else {
ChatUtils.sendMsg(messageQueue.removeFirst());
}
}
}

if (!totemPops.get()) return;
synchronized (totemPopMap) {
for (PlayerEntity player : mc.world.getPlayers()) {
Expand All @@ -293,9 +359,58 @@ private int getChatId(Entity entity) {
return chatIdMap.computeIfAbsent(entity.getUuid(), value -> random.nextInt());
}

private void createJoinNotifications(PlayerListS2CPacket packet) {
for (PlayerListS2CPacket.Entry entry : packet.getPlayerAdditionEntries()) {
if (entry.profile() == null) continue;

if (simpleNotifications.get()) {
messageQueue.addLast(Text.literal(
Formatting.GRAY + "["
+ Formatting.GREEN + "+"
+ Formatting.GRAY + "] "
+ entry.profile().getName()
));
} else {
messageQueue.addLast(Text.literal(
Formatting.WHITE
+ entry.profile().getName()
+ Formatting.GRAY + " joined."
));
}
}
}

private void createLeaveNotification(PlayerRemoveS2CPacket packet) {
if (mc.getNetworkHandler() == null) return;

for (UUID id : packet.profileIds()) {
PlayerListEntry toRemove = mc.getNetworkHandler().getPlayerListEntry(id);
if (toRemove == null) continue;

if (simpleNotifications.get()) {
messageQueue.addLast(Text.literal(
Formatting.GRAY + "["
+ Formatting.RED + "-"
+ Formatting.GRAY + "] "
+ toRemove.getProfile().getName()
));
} else {
messageQueue.addLast(Text.literal(
Formatting.WHITE
+ toRemove.getProfile().getName()
+ Formatting.GRAY + " left."
));
}
}
}

public enum Event {
Spawn,
Despawn,
Both
}

public enum JoinLeaveModes {
None, Joins, Leaves, Both
}
}

0 comments on commit 42fb908

Please sign in to comment.