1
1
package com.lambda.client.module.modules.misc
2
2
3
3
import com.lambda.client.event.events.ConnectionEvent
4
+ import com.lambda.client.event.events.RenderWorldEvent
4
5
import com.lambda.client.event.listener.asyncListener
6
+ import com.lambda.client.event.listener.listener
5
7
import com.lambda.client.manager.managers.WaypointManager
6
8
import com.lambda.client.module.Category
7
9
import com.lambda.client.module.Module
8
- import com.lambda.client.util.EntityUtils.flooredPosition
10
+ import com.lambda.client.module.modules.client.GuiColors
9
11
import com.lambda.client.util.EntityUtils.isFakeOrSelf
10
12
import com.lambda.client.util.TickTimer
11
13
import com.lambda.client.util.TimeUnit
14
+ import com.lambda.client.util.graphics.ESPRenderer
12
15
import com.lambda.client.util.math.CoordinateConverter.asString
16
+ import com.lambda.client.util.math.VectorUtils.toBlockPos
13
17
import com.lambda.client.util.text.MessageSendHelper
14
18
import com.lambda.client.util.threads.onMainThread
15
19
import com.lambda.client.util.threads.safeListener
16
20
import com.mojang.authlib.GameProfile
17
21
import net.minecraft.client.entity.EntityOtherPlayerMP
18
- import net.minecraft.util.math.BlockPos
22
+ import net.minecraft.util.text.TextFormatting
19
23
import net.minecraftforge.fml.common.gameevent.TickEvent
24
+ import java.util.concurrent.ConcurrentHashMap
20
25
21
26
object LogoutLogger : Module(
22
27
name = " LogoutLogger" ,
23
28
description = " Logs when a player leaves the game" ,
24
29
category = Category .MISC
25
30
) {
26
- private val saveWaypoint by setting(" Save Waypoint" , true )
31
+ private val saveWaypoint by setting(" Save Waypoint" , false )
27
32
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 })
28
38
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 )
31
43
32
44
init {
33
45
asyncListener<ConnectionEvent .Disconnect > {
34
46
onMainThread {
35
47
loggedPlayers.clear()
48
+ if (clearEsp) loggedOutPlayers.clear()
36
49
}
37
50
}
38
51
39
52
safeListener<TickEvent .ClientTickEvent > {
40
53
if (it.phase != TickEvent .Phase .END ) return @safeListener
41
54
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
45
62
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
+ }
52
68
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" )
61
74
}
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
62
88
}
89
+ }
90
+ }
91
+
92
+ onDisable {
93
+ if (clearEsp) loggedOutPlayers.clear()
94
+ }
63
95
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
+ }
65
107
}
108
+ renderer.render(false )
66
109
}
67
110
}
68
111
}
0 commit comments