Skip to content

Commit 10b2228

Browse files
Improved MobOwner nullsafety and prevent Mojang rate limits
* Remove unnecessary error logging when requesting PlayerProfile * fix: MobOwner endlessly sending HTTP calls for an invalid/unknown UUID * fix: MobOwner name tags would still be visible after disabling it. feat: prepend the original customNameTag to the stateful one. * Refactor for more abstraction Co-authored-by: Constructor <fractalminds@protonmail.com>
1 parent e9baf54 commit 10b2228

File tree

2 files changed

+58
-34
lines changed

2 files changed

+58
-34
lines changed

src/main/kotlin/com/lambda/client/capeapi/AbstractUUIDManager.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ abstract class AbstractUUIDManager(
7474
val response = if (isUUID) requestProfileFromUUID(nameOrUUID) else requestProfileFromName(nameOrUUID)
7575

7676
return if (response.isNullOrBlank()) {
77-
logger.error("Response is null or blank, internet might be down")
77+
// If there is no player with the given username or UUID an HTTP status code 204 (No Content) is sent without any HTTP body.
7878
null
7979
} else {
8080
try {

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

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ import com.lambda.client.module.Category
66
import com.lambda.client.module.Module
77
import com.lambda.client.util.threads.runSafe
88
import com.lambda.client.util.threads.safeListener
9+
import net.minecraft.entity.Entity
10+
import net.minecraft.entity.EntityLiving
911
import net.minecraft.entity.passive.AbstractHorse
1012
import net.minecraft.entity.passive.EntityTameable
1113
import net.minecraftforge.fml.common.gameevent.TickEvent
14+
import java.util.*
1215
import kotlin.math.pow
1316

17+
private data class EntityData(var originalCustomNameTag: String, var previous: String? = null)
18+
1419
object MobOwner : Module(
1520
name = "MobOwner",
1621
description = "Displays the owner of tamed mobs",
@@ -22,58 +27,77 @@ object MobOwner : Module(
2227

2328
private const val invalidText = "Offline or invalid UUID!"
2429

30+
// nullUUIDs caches all UUID's that returned an empty response from the Mojang API, effectively removing the endless
31+
// HTTP requests and subsequent rate-limit.
32+
private val nullUUIDs = mutableSetOf<UUID>()
33+
34+
// originalCustomNameTags does two things. It stores an EntityData data class for every tamable entity.
35+
// In EntityData the original customNameTag is stored that someone might have applied to the entity, a stateful
36+
// previous variable holds the last customNameTag to keep track when a new customNameTag is applied by a player.
37+
private val originalCustomNameTags = mutableMapOf<UUID, EntityData>()
38+
2539
init {
2640
safeListener<TickEvent.ClientTickEvent> {
27-
for (entity in world.loadedEntityList) {
28-
/* Non Horse types, such as wolves */
29-
if (entity is EntityTameable) {
30-
val ownerUUID = entity.ownerId
31-
if (!entity.isTamed || ownerUUID == null) continue
32-
33-
val ownerName = UUIDManager.getByUUID(ownerUUID)?.name ?: invalidText
34-
entity.alwaysRenderNameTag = true
35-
entity.customNameTag = "Owner: " + ownerName + getHealth(entity)
41+
/* Non Horse types, such as wolves */
42+
world.loadedEntityList.filterIsInstance<EntityTameable>().filter {
43+
it.isTamed
44+
}.forEach { entity ->
45+
entity.ownerId?.let {
46+
changeEntityData(it, entity)
3647
}
48+
}
3749

38-
if (entity is AbstractHorse) {
39-
val ownerUUID = entity.ownerUniqueId
40-
if (!entity.isTame || ownerUUID == null) continue
41-
42-
val ownerName = UUIDManager.getByUUID(ownerUUID)?.name ?: invalidText
43-
entity.alwaysRenderNameTag = true
44-
entity.customNameTag = "Owner: " + ownerName + getSpeed(entity) + getJump(entity) + getHealth(entity)
50+
world.loadedEntityList.filterIsInstance<AbstractHorse>().filter {
51+
it.isTame
52+
}.forEach { entity ->
53+
entity.ownerUniqueId?.let {
54+
changeEntityData(it, entity)
4555
}
4656
}
4757
}
4858

4959
onDisable {
5060
runSafe {
51-
for (entity in world.loadedEntityList) {
52-
if (entity !is AbstractHorse) continue
61+
// Revert customNameTag back to original.
62+
world.loadedEntityList.filterNotNull().forEach {
63+
val entityData = originalCustomNameTags[it.uniqueID]
64+
it.customNameTag = entityData?.originalCustomNameTag ?: it.customNameTag
5365

54-
try {
55-
entity.alwaysRenderNameTag = false
56-
} catch (_: Exception) {
57-
// Ignored
58-
}
66+
it.alwaysRenderNameTag = false
5967
}
68+
69+
originalCustomNameTags.clear()
70+
nullUUIDs.clear()
6071
}
6172
}
6273
}
6374

64-
private fun getSpeed(horse: AbstractHorse): String {
65-
return if (!speed) "" else " S: " + round(43.17 * horse.aiMoveSpeed, 2)
75+
private fun changeEntityData(ownerUUID: UUID, entity: Entity) {
76+
val owner = if (nullUUIDs.contains(ownerUUID)) null else UUIDManager.getByUUID(ownerUUID)
77+
val ownerName = if (owner == null) {
78+
nullUUIDs.add(ownerUUID)
79+
invalidText
80+
} else {
81+
owner.name
82+
}
83+
val entityData = originalCustomNameTags.getOrPut(entity.uniqueID) { EntityData(originalCustomNameTag = entity.customNameTag) }
84+
if (entityData.previous != null && entity.customNameTag != entityData.previous) {
85+
entityData.originalCustomNameTag = entity.customNameTag
86+
}
87+
entity.alwaysRenderNameTag = true
88+
entity.customNameTag = "${if (entityData.originalCustomNameTag != "") "${entityData.originalCustomNameTag} | " else ""}Owner: " + ownerName + getData(entity as EntityLiving)
89+
entityData.previous = entity.customNameTag
6690
}
6791

68-
private fun getJump(horse: AbstractHorse): String {
69-
return if (!jump) "" else " J: " + round(-0.1817584952 * horse.horseJumpStrength.pow(3.0) + 3.689713992 * horse.horseJumpStrength.pow(2.0) + 2.128599134 * horse.horseJumpStrength - 0.343930367, 2)
70-
}
92+
private fun getData(entity: EntityLiving): String {
93+
var data = ""
94+
if (entity is AbstractHorse) {
95+
if (speed) data += " S: " + round(43.17 * entity.aiMoveSpeed, 2)
96+
if (jump) data += " J: " + round(-0.1817584952 * entity.horseJumpStrength.pow(3.0) + 3.689713992 * entity.horseJumpStrength.pow(2.0) + 2.128599134 * entity.horseJumpStrength - 0.343930367, 2)
97+
}
7198

72-
private fun getHealth(horse: AbstractHorse): String {
73-
return if (!hp) "" else " HP: " + round(horse.health, 2)
74-
}
99+
if (hp) data += " HP: " + round(entity.health, 2)
75100

76-
private fun getHealth(tameable: EntityTameable): String {
77-
return if (!hp) "" else " HP: " + round(tameable.health, 2)
101+
return data
78102
}
79103
}

0 commit comments

Comments
 (0)