Skip to content

Commit 2a5fefd

Browse files
Nep NepAvanatiker
Nep Nep
andauthored
Add ESP and full Nametag info to LogoutLogger (#281)
* Add LogoutLogger ESP * Add clearing on disable * Make box 2 blocks tall and add outline option * Fix ConcurrentModifcationException, render correct AABB, render metadata * Fix graphic glitches caused by interpolation and clean up Co-authored-by: Constructor <fractalminds@protonmail.com>
1 parent 1519d78 commit 2a5fefd

File tree

2 files changed

+75
-24
lines changed

2 files changed

+75
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,111 @@
11
package com.lambda.client.module.modules.misc
22

33
import com.lambda.client.event.events.ConnectionEvent
4+
import com.lambda.client.event.events.RenderWorldEvent
45
import com.lambda.client.event.listener.asyncListener
6+
import com.lambda.client.event.listener.listener
57
import com.lambda.client.manager.managers.WaypointManager
68
import com.lambda.client.module.Category
79
import com.lambda.client.module.Module
8-
import com.lambda.client.util.EntityUtils.flooredPosition
10+
import com.lambda.client.module.modules.client.GuiColors
911
import com.lambda.client.util.EntityUtils.isFakeOrSelf
1012
import com.lambda.client.util.TickTimer
1113
import com.lambda.client.util.TimeUnit
14+
import com.lambda.client.util.graphics.ESPRenderer
1215
import com.lambda.client.util.math.CoordinateConverter.asString
16+
import com.lambda.client.util.math.VectorUtils.toBlockPos
1317
import com.lambda.client.util.text.MessageSendHelper
1418
import com.lambda.client.util.threads.onMainThread
1519
import com.lambda.client.util.threads.safeListener
1620
import com.mojang.authlib.GameProfile
1721
import net.minecraft.client.entity.EntityOtherPlayerMP
18-
import net.minecraft.util.math.BlockPos
22+
import net.minecraft.util.text.TextFormatting
1923
import net.minecraftforge.fml.common.gameevent.TickEvent
24+
import java.util.concurrent.ConcurrentHashMap
2025

2126
object LogoutLogger : Module(
2227
name = "LogoutLogger",
2328
description = "Logs when a player leaves the game",
2429
category = Category.MISC
2530
) {
26-
private val saveWaypoint by setting("Save Waypoint", true)
31+
private val saveWaypoint by setting("Save Waypoint", false)
2732
private val print by setting("Print To Chat", true)
33+
private val esp by setting("ESP", true)
34+
private val espFilledAlpha by setting("ESP Filled Alpha", 47, 0..255, 1, { esp })
35+
private val espOutlineAlpha by setting("ESP Outline Alpha", 0, 0..255, 1, { esp })
36+
private val espColor by setting("ESP Color", GuiColors.primary, false, { esp })
37+
private val clearEsp by setting("Clear ESP", true, { esp })
2838

29-
private val loggedPlayers = LinkedHashMap<GameProfile, BlockPos>()
30-
private val timer = TickTimer(TimeUnit.SECONDS)
39+
private val loggedPlayers = ConcurrentHashMap<GameProfile, EntityOtherPlayerMP>()
40+
val loggedOutPlayers = ConcurrentHashMap<GameProfile, EntityOtherPlayerMP>()
41+
private val renderer = ESPRenderer()
42+
private val renderTimer = TickTimer(TimeUnit.SECONDS)
3143

3244
init {
3345
asyncListener<ConnectionEvent.Disconnect> {
3446
onMainThread {
3547
loggedPlayers.clear()
48+
if (clearEsp) loggedOutPlayers.clear()
3649
}
3750
}
3851

3952
safeListener<TickEvent.ClientTickEvent> {
4053
if (it.phase != TickEvent.Phase.END) return@safeListener
4154

42-
for (loadedPlayer in world.playerEntities) {
43-
if (loadedPlayer !is EntityOtherPlayerMP) continue
44-
if (loadedPlayer.isFakeOrSelf) continue
55+
world.playerEntities
56+
.filterIsInstance<EntityOtherPlayerMP>()
57+
.filter { entityOtherPlayerMP -> !entityOtherPlayerMP.isFakeOrSelf }
58+
.forEach { entityOtherPlayerMP ->
59+
@Suppress("UNNECESSARY_SAFE_CALL")
60+
connection.getPlayerInfo(entityOtherPlayerMP.gameProfile.id)?.let { networkPlayerInfo ->
61+
loggedPlayers[networkPlayerInfo.gameProfile] = entityOtherPlayerMP
4562

46-
val info = connection.getPlayerInfo(loadedPlayer.gameProfile.id) ?: continue
47-
loggedPlayers[info.gameProfile] = loadedPlayer.flooredPosition
48-
}
49-
50-
if (timer.tick(1L)) {
51-
val toRemove = ArrayList<GameProfile>()
63+
loggedOutPlayers.entries.removeIf { (profile, _) ->
64+
profile.id == networkPlayerInfo.gameProfile.id
65+
}
66+
}
67+
}
5268

53-
loggedPlayers.entries.removeIf { (profile, pos) ->
54-
@Suppress("SENSELESS_COMPARISON")
55-
if (connection.getPlayerInfo(profile.id) == null) {
56-
if (saveWaypoint) WaypointManager.add(pos, "${profile.name} Logout Spot")
57-
if (print) MessageSendHelper.sendChatMessage("${profile.name} logged out at ${pos.asString()}")
58-
true
59-
} else {
60-
false
69+
loggedPlayers.entries.removeIf { (profile, entityOtherPlayerMP) ->
70+
@Suppress("SENSELESS_COMPARISON")
71+
if (connection.getPlayerInfo(profile.id) == null) {
72+
if (saveWaypoint) {
73+
WaypointManager.add(entityOtherPlayerMP.entityBoundingBox.center.toBlockPos(), "${profile.name} Logout Spot")
6174
}
75+
if (print) {
76+
MessageSendHelper.sendChatMessage("$chatName ${TextFormatting.RED}${profile.name}${TextFormatting.RESET} logged out at (${entityOtherPlayerMP.entityBoundingBox.center.toBlockPos().asString()})")
77+
}
78+
79+
// prevent render glitches caused by interpolation
80+
entityOtherPlayerMP.prevPosX = entityOtherPlayerMP.posX
81+
entityOtherPlayerMP.prevPosY = entityOtherPlayerMP.posY
82+
entityOtherPlayerMP.prevPosZ = entityOtherPlayerMP.posZ
83+
84+
loggedOutPlayers[profile] = entityOtherPlayerMP
85+
true
86+
} else {
87+
false
6288
}
89+
}
90+
}
91+
92+
onDisable {
93+
if (clearEsp) loggedOutPlayers.clear()
94+
}
6395

64-
loggedPlayers.keys.removeAll(toRemove.toSet())
96+
listener<RenderWorldEvent> {
97+
if (!esp) return@listener
98+
99+
renderer.aFilled = espFilledAlpha
100+
renderer.aOutline = espOutlineAlpha
101+
102+
if (renderTimer.tick(1)) {
103+
renderer.clear()
104+
loggedOutPlayers.values.forEach {
105+
renderer.add(it, espColor)
106+
}
65107
}
108+
renderer.render(false)
66109
}
67110
}
68111
}

src/main/kotlin/com/lambda/client/module/modules/render/Nametags.kt

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.lambda.client.module.modules.render
22

3+
import com.lambda.client.LambdaMod
34
import com.lambda.client.event.events.RenderOverlayEvent
45
import com.lambda.client.module.Category
56
import com.lambda.client.module.Module
@@ -20,6 +21,7 @@ import com.lambda.client.commons.extension.ceilToInt
2021
import com.lambda.client.commons.extension.floorToInt
2122
import com.lambda.client.commons.utils.MathUtils
2223
import com.lambda.client.event.listener.listener
24+
import com.lambda.client.module.modules.misc.LogoutLogger
2325
import net.minecraft.client.entity.EntityOtherPlayerMP
2426
import net.minecraft.client.renderer.RenderHelper
2527
import net.minecraft.entity.Entity
@@ -113,7 +115,7 @@ object Nametags : Module(
113115

114116
private val line1Settings = arrayOf(line1left, line1center, line1right)
115117
private val line2Settings = arrayOf(line2left, line2center, line2right)
116-
private val entityMap = TreeMap<Entity, TextComponent>(compareByDescending { mc.player.getPositionEyes(1f).distanceTo(it.getPositionEyes(1f)) })
118+
val entityMap = TreeMap<Entity, TextComponent>(compareByDescending { mc.player.getPositionEyes(1f).distanceTo(it.getPositionEyes(1f)) })
117119
private val itemMap = TreeSet<ItemGroup>(compareByDescending { mc.player.getPositionEyes(1f).distanceTo(it.getCenter(1f)) })
118120

119121
private var updateTick = 0
@@ -348,6 +350,12 @@ object Nametags : Module(
348350
if (player.getDistance(entity) > range) continue
349351
entityMap[entity] = TextComponent()
350352
}
353+
354+
LogoutLogger.loggedOutPlayers.values.filter {
355+
player.getDistance(it) <= range
356+
}.forEach {
357+
entityMap[it] = TextComponent()
358+
}
351359
}
352360
2 -> { // Removing items
353361
val loadEntitySet = world.loadedEntityList.toHashSet()

0 commit comments

Comments
 (0)