@@ -29,13 +29,11 @@ import com.lambda.network.mojang.getProfile
2929import com.lambda.threading.onShutdown
3030import com.lambda.util.Timer
3131import com.lambda.util.player.FakePlayerId
32- import com.lambda.util.player.spawnFakePlayer
3332import com.mojang.authlib.GameProfile
3433import com.mojang.datafixers.util.Either
3534import net.minecraft.client.network.OtherClientPlayerEntity
3635import net.minecraft.client.network.PlayerListEntry
3736import java.util.*
38- import kotlin.jvm.optionals.getOrElse
3937import kotlin.jvm.optionals.getOrNull
4038import kotlin.time.Duration.Companion.seconds
4139
@@ -59,16 +57,16 @@ object FakePlayer : Module(
5957
6058 init {
6159 listen<TickEvent .Pre > {
62- fakePlayer = cachedProfiles[playerName]
63- ?.let { spawnFakePlayer(it, fakePlayer ? : player, addToWorld = false ) }
64- ?.takeUnless { it == fakePlayer?.gameProfile }
65- ? : fakePlayer?.takeIf { playerName == it.gameProfile.name }
66- ? : spawnFakePlayer(nilProfile, fakePlayer ? : player, addToWorld = false )
60+ val newFakePlayer = cachedProfiles[playerName]
61+ ?.let { newFakePlayer(it) }
62+ ?.takeUnless { it.gameProfile == fakePlayer?.gameProfile } // If the current profile equals the current fake player's profile, stop.
63+
64+ fakePlayer = newFakePlayer
65+ ? : return @listen
6766 }
6867
6968 listenConcurrently<TickEvent .Pre >(priority = 1000 ) {
7069 if (! fetchTimer.timePassed(2 .seconds)) return @listenConcurrently
71-
7270 cachedProfiles.getOrPut(playerName) { fetchProfile(playerName) }
7371 }
7472
@@ -77,24 +75,33 @@ object FakePlayer : Module(
7775 }
7876
7977 listen<ConnectionEvent .Connect .Pre > { disable() }
80- onShutdown { disable() }
78+
79+ onShutdown { disable() } // FixMe: This doesn't work because the hook triggers after the modules are saved.
80+
8181 onDisable { fakePlayer?.discard(); fakePlayer = null }
8282 }
8383
84+ fun SafeContext.newFakePlayer (profile : GameProfile ) =
85+ OtherClientPlayerEntity (world, profile).apply {
86+ copyFrom(player)
87+ id = FakePlayerId
88+ }
89+
8490 suspend fun SafeContext.fetchProfile (user : String ): GameProfile {
85- val requestedProfile = getProfile(user).getOrElse { return nilProfile }
91+ val requestedProfile = getProfile(user)
92+ .getOrElse { return nilProfile }
8693
8794 // Fetch the skin properties from mojang
8895 val properties = mc.apiServices.profileResolver
89- .getProfile(Either .right(requestedProfile.id)).getOrNull()?.properties
96+ .getProfile(Either .right(requestedProfile.id))
97+ .getOrNull()
98+ ?.properties
99+ ? : return nilProfile
90100
91- // We use the nil profile to avoid the nil username if something wrong happens
92- // Check the GameProfile deserializer you'll understand
93- val profile = nilProfile
94- properties?.let { profile.properties.putAll(it) }
101+ val profile = GameProfile (requestedProfile.id, requestedProfile.name, properties)
95102
96- mc.networkHandler?. playerListEntries?.put( profile.id, PlayerListEntry (profile, false ) )
103+ connection. playerListEntries[ profile.id] = PlayerListEntry (profile, false )
97104
98- return profile
105+ return profile
99106 }
100107}
0 commit comments