Skip to content

Commit ff29527

Browse files
committed
get cosmetics of users in lobby
1 parent 989f6f6 commit ff29527

File tree

7 files changed

+97
-19
lines changed

7 files changed

+97
-19
lines changed

src/main/kotlin/org/polyfrost/polyplus/client/PolyPlusClient.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import kotlinx.coroutines.SupervisorJob
1414
import kotlinx.coroutines.launch
1515
import kotlinx.serialization.json.Json
1616
import org.apache.logging.log4j.LogManager
17+
import org.polyfrost.oneconfig.api.event.v1.EventManager
1718
import org.polyfrost.oneconfig.utils.v1.dsl.addDefaultCommand
1819
import org.polyfrost.polyplus.PolyPlusConstants
20+
import org.polyfrost.polyplus.client.cosmetics.ApplyCosmetics
1921
import org.polyfrost.polyplus.client.cosmetics.CosmeticManager
2022
import org.polyfrost.polyplus.client.discord.DiscordPresence
2123
import org.polyfrost.polyplus.client.network.http.PolyAuthorization
@@ -47,6 +49,13 @@ object PolyPlusClient {
4749

4850
fun initialize() {
4951
PolyPlusConfig.preload()
52+
53+
listOf(
54+
ApplyCosmetics
55+
).forEach {
56+
EventManager.INSTANCE.register(it)
57+
}
58+
5059
DiscordPresence.initialize()
5160
PolyConnection.initialize {
5261
LOGGER.info("Connected to PolyPlus WebSocket server.")
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package org.polyfrost.polyplus.client.cosmetics
2+
3+
import net.minecraft.network.play.server.S38PacketPlayerListItem
4+
import net.minecraftforge.event.world.WorldEvent
5+
import org.apache.logging.log4j.LogManager
6+
import org.polyfrost.oneconfig.api.event.v1.events.PacketEvent
7+
import org.polyfrost.oneconfig.api.event.v1.invoke.impl.Subscribe
8+
import org.polyfrost.polyplus.client.network.http.PolyCosmetics
9+
import org.polyfrost.polyplus.client.network.websocket.ClientboundPacket
10+
import org.polyfrost.polyplus.client.network.websocket.PolyConnection
11+
import org.polyfrost.polyplus.client.network.websocket.ServerboundPacket
12+
import org.polyfrost.polyplus.events.WebSocketMessage
13+
import java.util.UUID
14+
import kotlin.collections.component1
15+
import kotlin.collections.component2
16+
import kotlin.collections.iterator
17+
18+
object ApplyCosmetics {
19+
private val LOGGER = LogManager.getLogger()
20+
21+
@Subscribe
22+
fun onWorldLoad(event: WorldEvent.Load) {
23+
PolyCosmetics.reset()
24+
}
25+
26+
@Subscribe
27+
fun onPlayerList(event: PacketEvent.Receive) {
28+
val packet = try { event.getPacket<S38PacketPlayerListItem>() ?: return } catch (e: Exception) { return }
29+
when (packet.action) {
30+
S38PacketPlayerListItem.Action.ADD_PLAYER -> {
31+
val players = packet.entries.mapNotNull { it.profile.id.takeUnless { it.version() == 2 }?.toString() } // mojang only uses UUIDv2 so if its not, its a bot and wont have a cape.
32+
PolyConnection.sendPacket(ServerboundPacket.GetActiveCosmetics(players))
33+
LOGGER.info("Requested cosmetics for players: $players")
34+
}
35+
36+
S38PacketPlayerListItem.Action.REMOVE_PLAYER -> {
37+
for (entry in packet.entries) {
38+
PolyCosmetics.removeFromCache(entry.profile.id)
39+
}
40+
}
41+
42+
else -> return
43+
}
44+
}
45+
46+
@Subscribe
47+
fun onRecieveCosmetics(event: WebSocketMessage) {
48+
val cosmeticInfo = event.packet as? ClientboundPacket.CosmeticsInfo ?: return
49+
// todo: have a map of type to valid ids? or ask ty to include type in the returned info. for now theyre all capes.
50+
for ((uuid, active) in cosmeticInfo.all) {
51+
active.forEach {
52+
PolyCosmetics.cacheActive(UUID.fromString(uuid), "cape", it)
53+
LOGGER.info("Cached cosmetic for player $uuid: cape -> $it")
54+
}
55+
}
56+
}
57+
}

src/main/kotlin/org/polyfrost/polyplus/client/network/http/PolyCosmetics.kt

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,22 @@ import kotlinx.coroutines.async
88
import org.apache.logging.log4j.LogManager
99
import org.polyfrost.polyplus.client.PolyPlusClient
1010
import org.polyfrost.polyplus.client.PolyPlusConfig
11+
import org.polyfrost.polyplus.client.network.http.responses.Cosmetic
1112
import org.polyfrost.polyplus.client.network.http.responses.CosmeticList
1213
import org.polyfrost.polyplus.client.network.http.responses.PlayerCosmetics
1314
import java.util.UUID
1415

1516
object PolyCosmetics {
1617
private val LOGGER = LogManager.getLogger()
18+
private var OWNED: List<Cosmetic> = emptyList()
1719
private val CACHE = HashMap<UUID, HashMap<String, Int>>()
1820

1921
suspend fun updateOwned() {
20-
val cosmetics = PolyPlusClient.HTTP
22+
val playerCosmetics = PolyPlusClient.HTTP
2123
.getBodyAuthorized<PlayerCosmetics>("${PolyPlusConfig.apiUrl}/cosmetics/player")
2224
.onFailure { LOGGER.error("Failed to fetch owned cosmetics", it) }
2325
.getOrElse { return LOGGER.warn("Could not fetch owned cosmetics for player $playerUuid") }
24-
.owned
25-
for (cosmetic in cosmetics) {
26-
CACHE[playerUuid] = CACHE.getOrPut(playerUuid) {
27-
HashMap()
28-
}.apply {
29-
set(cosmetic.type, cosmetic.id)
30-
}
31-
}
26+
OWNED = playerCosmetics.owned
3227
}
3328

3429
fun getAll(): Deferred<Result<CosmeticList>> = PolyPlusClient.SCOPE.async {
@@ -42,10 +37,19 @@ object PolyCosmetics {
4237
}
4338

4439
fun reset() {
40+
LOGGER.info("Resetting cosmetics cache: Size before reset: ${CACHE.size}")
4541
CACHE.clear()
4642
}
4743

4844
fun getFor(uuid: UUID): HashMap<String, Int>? {
4945
return CACHE[uuid]
5046
}
47+
48+
fun cacheActive(uuid: UUID, type: String, id: Int) {
49+
CACHE.getOrPut(uuid) { HashMap() }[type] = id
50+
}
51+
52+
fun removeFromCache(uuid: UUID) {
53+
CACHE.remove(uuid)
54+
}
5155
}

src/main/kotlin/org/polyfrost/polyplus/client/network/http/responses/ActiveCosmetics.kt

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/main/kotlin/org/polyfrost/polyplus/client/network/http/responses/PlayerCosmetics.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ import kotlinx.serialization.SerialName
44
import kotlinx.serialization.Serializable
55

66
@Serializable
7-
data class PlayerCosmetics(val active: ActiveCosmetics, @SerialName("cosmetics") val owned: List<Cosmetic>)
7+
data class PlayerCosmetics(val active: HashMap<String, Int?>, @SerialName("cosmetics") val owned: List<Cosmetic>)

src/main/kotlin/org/polyfrost/polyplus/client/network/websocket/PolyConnection.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@ import kotlinx.coroutines.channels.Channel
1010
import kotlinx.coroutines.launch
1111
import kotlinx.serialization.serializer
1212
import org.apache.logging.log4j.LogManager
13+
import org.polyfrost.oneconfig.api.event.v1.EventManager
1314
import org.polyfrost.polyplus.client.PolyPlusClient
1415
import org.polyfrost.polyplus.client.PolyPlusConfig
16+
import org.polyfrost.polyplus.client.cosmetics.CosmeticManager
17+
import org.polyfrost.polyplus.client.network.http.PolyCosmetics
18+
import org.polyfrost.polyplus.events.WebSocketMessage
19+
import java.util.UUID
1520

1621
object PolyConnection {
1722
private val LOGGER = LogManager.getLogger()
@@ -99,12 +104,15 @@ object PolyConnection {
99104
}
100105

101106
private fun process(scope: CoroutineScope, message: String) {
102-
println("Received message: $message")
103107
val packet = PolyPlusClient.JSON.decodeFromString<ClientboundPacket>(message)
104-
println("Decoded packet: $packet")
108+
if (packet is ClientboundPacket.Error) {
109+
LOGGER.error("Error packet received: ${packet.message}")
110+
}
111+
112+
EventManager.INSTANCE.post(WebSocketMessage(packet))
105113
}
106114

107115
private inline fun <reified T : ServerboundPacket> T.string(): String {
108-
return PolyPlusClient.JSON.encodeToString(serializer(), this)
116+
return PolyPlusClient.JSON.encodeToString(ServerboundPacket.serializer(), this)
109117
}
110118
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.polyfrost.polyplus.events
2+
3+
import org.polyfrost.oneconfig.api.event.v1.events.Event
4+
import org.polyfrost.polyplus.client.network.websocket.ClientboundPacket
5+
6+
class WebSocketMessage(val packet: ClientboundPacket) : Event

0 commit comments

Comments
 (0)