From d221d0aa8dc442f1599d98380068bff282eaaf10 Mon Sep 17 00:00:00 2001 From: LossyDragon Date: Sun, 19 Oct 2025 00:54:10 -0500 Subject: [PATCH 1/2] Update PersonaStateCallback with all current values from its protobuf. --- .../_020_friends/SampleFriends.java | 2 +- .../steam/handlers/steamfriends/ClanData.kt | 9 ++ .../steam/handlers/steamfriends/KV.kt | 9 ++ .../handlers/steamfriends/OtherGameData.kt | 9 ++ .../callback/PersonaStateCallback.kt | 150 ++++++++++++++---- .../steammessages_clientserver_friends.proto | 1 + .../steamfriends/SteamFriendsTest.java | 4 +- 7 files changed, 150 insertions(+), 34 deletions(-) create mode 100644 src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/ClanData.kt create mode 100644 src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/KV.kt create mode 100644 src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/OtherGameData.kt diff --git a/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java b/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java index ffc82cb3..ee1419e8 100644 --- a/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java +++ b/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java @@ -207,6 +207,6 @@ private void onPersonaState(PersonaStateCallback callback) { // this callback is received when the persona state (friend information) of a friend changes // for this sample we'll simply display the names of the friends - System.out.println("State change: " + callback.getName() + " | " + callback.getState() + " | " + callback.getStatusFlags()); + System.out.println("State change: " + callback.getPlayerName() + " | " + callback.getPersonaState() + " | " + callback.getStatusFlags()); } } diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/ClanData.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/ClanData.kt new file mode 100644 index 00000000..84e318f0 --- /dev/null +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/ClanData.kt @@ -0,0 +1,9 @@ +package `in`.dragonbra.javasteam.steam.handlers.steamfriends + +/** + * Represents clan-related data for a friend. + * + * @property oggAppId The app ID associated with the clan. + * @property chatGroupID The chat group ID for the clan. + */ +data class ClanData(val oggAppId: Int, val chatGroupID: Long) diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/KV.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/KV.kt new file mode 100644 index 00000000..ee3a3b6e --- /dev/null +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/KV.kt @@ -0,0 +1,9 @@ +package `in`.dragonbra.javasteam.steam.handlers.steamfriends + +/** + * Represents a key-value pair, typically used for rich presence data. + * + * @property key The key identifier. + * @property value The value associated with the key. + */ +data class KV(val key: String, val value: String) diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/OtherGameData.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/OtherGameData.kt new file mode 100644 index 00000000..c7bba84b --- /dev/null +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/OtherGameData.kt @@ -0,0 +1,9 @@ +package `in`.dragonbra.javasteam.steam.handlers.steamfriends + +/** + * Represents game data for other games a user is playing or has played. + * + * @property gameId The game ID. + * @property richPresence The list of rich presence key-value pairs for the game. + */ +data class OtherGameData(val gameId: Long, val richPresence: List) diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt index 09cad511..deba17ec 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt @@ -4,6 +4,9 @@ import `in`.dragonbra.javasteam.enums.EClientPersonaStateFlag import `in`.dragonbra.javasteam.enums.EPersonaState import `in`.dragonbra.javasteam.enums.EPersonaStateFlag import `in`.dragonbra.javasteam.protobufs.steamclient.SteammessagesClientserverFriends.CMsgClientPersonaState +import `in`.dragonbra.javasteam.steam.handlers.steamfriends.ClanData +import `in`.dragonbra.javasteam.steam.handlers.steamfriends.KV +import `in`.dragonbra.javasteam.steam.handlers.steamfriends.OtherGameData import `in`.dragonbra.javasteam.steam.steamclient.callbackmgr.CallbackMsg import `in`.dragonbra.javasteam.types.GameID import `in`.dragonbra.javasteam.types.SteamID @@ -26,44 +29,49 @@ class PersonaStateCallback( val statusFlags: EnumSet = statusFlags /** - * Gets the friend's [SteamID] + * Gets the friend's [SteamID]. */ - val friendID: SteamID = SteamID(friend.friendid) + val friendId: SteamID = SteamID(friend.friendid) /** - * Gets the state. + * Gets the persona state. */ - val state: EPersonaState = EPersonaState.from(friend.personaState) ?: EPersonaState.Offline + val personaState: EPersonaState = EPersonaState.from(friend.personaState) ?: EPersonaState.Offline /** - * Gets the state flags. + * Gets the game app ID being played. */ - val stateFlags: EnumSet = EPersonaStateFlag.from(friend.personaStateFlags) + val gamePlayedAppId: Int = friend.gamePlayedAppId /** - * Gets the game app ID. + * Gets the game server IP address. */ - val gameAppID: Int = friend.gamePlayedAppId + val gameServerIp: InetAddress = NetHelpers.getIPAddress(friend.gameServerIp) /** - * Gets the game ID. + * Gets the game server port. */ - val gameID: GameID = GameID(friend.gameid) + val gameServerPort: Int = friend.gameServerPort /** - * Gets the name of the game. + * Gets the persona state flags. */ - val gameName: String = friend.gameName + val personaStateFlags: EnumSet = EPersonaStateFlag.from(friend.personaStateFlags) /** - * Gets the game server IP. + * Gets the number of online session instances. */ - val gameServerIP: InetAddress = NetHelpers.getIPAddress(friend.gameServerIp) + val onlineSessionInstances: Int = friend.onlineSessionInstances /** - * Gets the game server port. + * Gets whether the persona was set by the user. */ - val gameServerPort: Int = friend.gameServerPort + val personaSetByUser: Boolean = friend.personaSetByUser + + /** + * Gets the player name. + */ + val playerName: String = friend.playerName /** * Gets the query port. @@ -73,37 +81,52 @@ class PersonaStateCallback( /** * Gets the source [SteamID]. */ - val sourceSteamID: SteamID = SteamID(friend.steamidSource) + val steamIdSource: SteamID = SteamID(friend.steamidSource) /** - * Gets the game data blob. + * Gets the avatar hash. */ - val gameDataBlob: ByteArray = friend.gameDataBlob.toByteArray() + val avatarHash: ByteArray = friend.avatarHash.toByteArray() /** - * Gets the name. + * Gets the last logoff time. */ - val name: String = friend.playerName + val lastLogoff: Date = Date(friend.lastLogoff * 1000L) /** - * Gets the avatar hash. + * Gets the last logon time. */ - val avatarHash: ByteArray = friend.avatarHash.toByteArray() + val lastLogon: Date = Date(friend.lastLogon * 1000L) + + /** + * Gets the last seen online time. + */ + val lastSeenOnline: Date = Date(friend.lastSeenOnline * 1000L) /** - * Gets the last log off. + * Gets the clan rank. */ - val lastLogOff: Date = Date(friend.lastLogoff * 1000L) + val clanRank: Int = friend.clanRank /** - * Gets the last log on. + * Gets the name of the game. */ - val lastLogOn: Date = Date(friend.lastLogon * 1000L) + val gameName: String = friend.gameName /** - * Gets the clan rank. + * Gets the game ID. */ - val clanRank: Int = friend.clanRank + val gameId: GameID = GameID(friend.gameid) + + /** + * Gets the game data blob. + */ + val gameDataBlob: ByteArray = friend.gameDataBlob.toByteArray() + + /** + * Gets the clan data. + */ + val clanData: ClanData = ClanData(friend.clanData.oggAppId, friend.clanData.chatGroupId) /** * Gets the clan tag. @@ -111,7 +134,72 @@ class PersonaStateCallback( val clanTag: String = friend.clanTag /** - * Gets the online session instance. + * Gets the rich presence key-value pairs. */ - val onlineSessionInstances: Int = friend.onlineSessionInstances + val richPresence: List = friend.richPresenceList.map { KV(key = it.key, value = it.value) } + + /** + * Gets the broadcast ID. + */ + val broadcastId: Long = friend.broadcastId + + /** + * Gets the game lobby ID. + */ + val gameLobbyId: Long = friend.gameLobbyId + + /** + * Gets the account ID of the broadcast being watched. + */ + val watchingBroadcastAccountId: Int = friend.watchingBroadcastAccountid + + /** + * Gets the app ID of the broadcast being watched. + */ + val watchingBroadcastAppId: Int = friend.watchingBroadcastAppid + + /** + * Gets the number of viewers watching the broadcast. + */ + val watchingBroadcastViewers: Int = friend.watchingBroadcastViewers + + /** + * Gets the title of the broadcast being watched. + */ + val watchingBroadcastTitle: String = friend.watchingBroadcastTitle + + /** + * Gets whether the user is community banned. + */ + val isCommunityBanned: Boolean = friend.isCommunityBanned + + /** + * Gets whether the player name is pending review. + */ + val playerNamePendingReview: Boolean = friend.playerNamePendingReview + + /** + * Gets whether the avatar is pending review. + */ + val avatarPendingReview: Boolean = friend.avatarPendingReview + + /** + * Gets whether the user is on Steam Deck. + */ + val onSteamDeck: Boolean = friend.onSteamDeck + + /** + * Gets the other game data. + */ + val otherGameData: List = friend.otherGameDataList.map { gameData -> + OtherGameData( + gameId = gameData.gameid, + richPresence = gameData.richPresenceList.map { KV(key = it.key, value = it.value) } + ) + } + + /** + * Gets the gaming device type. + */ + val gamingDeviceType: Int = friend.gamingDeviceType } diff --git a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientserver_friends.proto b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientserver_friends.proto index b473620b..9756a44c 100644 --- a/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientserver_friends.proto +++ b/src/main/proto/in/dragonbra/javasteam/protobufs/steamclient/steammessages_clientserver_friends.proto @@ -162,6 +162,7 @@ message CMsgClientPersonaState { optional bool avatar_pending_review = 80; optional bool on_steam_deck = 81; repeated .CMsgClientPersonaState.Friend.OtherGameData other_game_data = 82; + optional uint32 gaming_device_type = 83; } optional uint32 status_flags = 1; diff --git a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java index 4601ef3c..a0667289 100644 --- a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java +++ b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java @@ -330,8 +330,8 @@ public void handlePersonaState() { PersonaStateCallback callback = verifyCallback(); //assertEquals(1, callback.getPersonaStates().size()); - assertEquals(EPersonaState.Offline, callback.getState()); - assertEquals("klay", callback.getName()); + assertEquals(EPersonaState.Offline, callback.getPersonaState()); + assertEquals("klay", callback.getPlayerName()); } @Test From 597aea5c680db5492d92b0889d3b2685798e0428 Mon Sep 17 00:00:00 2001 From: LossyDragon Date: Sun, 19 Oct 2025 01:44:17 -0500 Subject: [PATCH 2/2] Add JvmName annotation to keep getter names the same in java. --- .../javasteamsamples/_020_friends/SampleFriends.java | 2 +- .../handlers/steamfriends/callback/PersonaStateCallback.kt | 3 +++ .../steam/handlers/steamfriends/SteamFriendsTest.java | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java b/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java index ee1419e8..ffc82cb3 100644 --- a/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java +++ b/javasteam-samples/src/main/java/in/dragonbra/javasteamsamples/_020_friends/SampleFriends.java @@ -207,6 +207,6 @@ private void onPersonaState(PersonaStateCallback callback) { // this callback is received when the persona state (friend information) of a friend changes // for this sample we'll simply display the names of the friends - System.out.println("State change: " + callback.getPlayerName() + " | " + callback.getPersonaState() + " | " + callback.getStatusFlags()); + System.out.println("State change: " + callback.getName() + " | " + callback.getState() + " | " + callback.getStatusFlags()); } } diff --git a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt index deba17ec..e2957ab0 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt +++ b/src/main/java/in/dragonbra/javasteam/steam/handlers/steamfriends/callback/PersonaStateCallback.kt @@ -36,11 +36,13 @@ class PersonaStateCallback( /** * Gets the persona state. */ + @get:JvmName("getState") val personaState: EPersonaState = EPersonaState.from(friend.personaState) ?: EPersonaState.Offline /** * Gets the game app ID being played. */ + @get:JvmName("getGameAppID") val gamePlayedAppId: Int = friend.gamePlayedAppId /** @@ -71,6 +73,7 @@ class PersonaStateCallback( /** * Gets the player name. */ + @get:JvmName("getName") val playerName: String = friend.playerName /** diff --git a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java index a0667289..4601ef3c 100644 --- a/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java +++ b/src/test/java/in/dragonbra/javasteam/steam/handlers/steamfriends/SteamFriendsTest.java @@ -330,8 +330,8 @@ public void handlePersonaState() { PersonaStateCallback callback = verifyCallback(); //assertEquals(1, callback.getPersonaStates().size()); - assertEquals(EPersonaState.Offline, callback.getPersonaState()); - assertEquals("klay", callback.getPlayerName()); + assertEquals(EPersonaState.Offline, callback.getState()); + assertEquals("klay", callback.getName()); } @Test