Skip to content

Commit a3c5dfc

Browse files
committed
feat(api): enhance friends API with persona state and game info
1 parent 0bd985d commit a3c5dfc

3 files changed

Lines changed: 103 additions & 24 deletions

File tree

client.d.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,29 @@ export declare namespace cloud {
7979
}
8080
}
8181
export declare namespace friends {
82+
export const enum PersonaState {
83+
Offline = 0,
84+
Online = 1,
85+
Busy = 2,
86+
Away = 3,
87+
Snooze = 4,
88+
LookingToTrade = 5,
89+
LookingToPlay = 6,
90+
Invisible = 7
91+
}
92+
export interface FriendGameInfo {
93+
gameId: bigint
94+
gameIp: string
95+
gamePort: number
96+
queryPort: number
97+
lobbyId: bigint
98+
}
8299
export interface Friend {
83100
steamId: bigint
84101
name: string
102+
nickname?: string
103+
state: PersonaState
104+
gamePlayed?: FriendGameInfo
85105
}
86106
export const enum FriendFlags {
87107
None = 0,
@@ -98,33 +118,28 @@ export declare namespace friends {
98118
* Get an array of friends matching the provided flags.
99119
*
100120
* @param flags - The flags to filter friends by.
101-
* @returns An array of friend objects containing steamId and name.
121+
* @returns An array of friend objects containing steamId, name, nickname, state and gamePlayed.
102122
*
103123
* @example
104124
* ```js
105125
* const friends = client.friends.getFriends(client.friends.FriendFlags.Immediate)
106126
* console.log(friends)
107-
* // Output:
108-
* // [
109-
* // { steamId: 76561197985341433n, name: 'MaD_SpY' },
110-
* // { steamId: 76561198034399293n, name: 'BladeSmith' },
111-
* // ]
112127
* ```
113128
*/
114129
export function getFriends(flags: number): Array<Friend>
115130
/**
116-
* Get the persona name of a friend.
131+
* Get the name of a friend.
117132
*
118133
* @param steam_id64 - The Steam ID of the friend.
119134
* @returns The name of the friend.
120135
*
121136
* @example
122137
* ```js
123-
* const name = client.friends.getFriendPersonaName(76561197985341433n)
124-
* console.log(name) // 'MaD_SpY'
138+
* const name = client.friends.getFriendName(76561197985341433n)
139+
* console.log(name)
125140
* ```
126141
*/
127-
export function getFriendPersonaName(steamId64: bigint): string
142+
export function getFriendName(steamId64: bigint): string
128143
}
129144
export declare namespace input {
130145
export const enum InputType {

src/api/friends.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,34 @@ pub mod friends {
55
use napi::bindgen_prelude::BigInt;
66
use steamworks::SteamId;
77

8+
#[napi]
9+
pub enum PersonaState {
10+
Offline = 0,
11+
Online = 1,
12+
Busy = 2,
13+
Away = 3,
14+
Snooze = 4,
15+
LookingToTrade = 5,
16+
LookingToPlay = 6,
17+
Invisible = 7,
18+
}
19+
20+
#[napi(object)]
21+
pub struct FriendGameInfo {
22+
pub game_id: BigInt,
23+
pub game_ip: String,
24+
pub game_port: u32,
25+
pub query_port: u32,
26+
pub lobby_id: BigInt,
27+
}
28+
829
#[napi(object)]
930
pub struct Friend {
1031
pub steam_id: BigInt,
1132
pub name: String,
33+
pub nickname: Option<String>,
34+
pub state: PersonaState,
35+
pub game_played: Option<FriendGameInfo>,
1236
}
1337

1438
#[napi]
@@ -27,17 +51,12 @@ pub mod friends {
2751
/// Get an array of friends matching the provided flags.
2852
///
2953
/// @param flags - The flags to filter friends by.
30-
/// @returns An array of friend objects containing steamId and name.
54+
/// @returns An array of friend objects containing steamId, name, nickname, state and gamePlayed.
3155
///
3256
/// @example
3357
/// ```js
3458
/// const friends = client.friends.getFriends(client.friends.FriendFlags.Immediate)
3559
/// console.log(friends)
36-
/// // Output:
37-
/// // [
38-
/// // { steamId: 76561197985341433n, name: 'XXX' },
39-
/// // { steamId: 76561198034399293n, name: 'YYY' },
40-
/// // ]
4160
/// ```
4261
#[napi]
4362
pub fn get_friends(flags: i32) -> Vec<Friend> {
@@ -50,11 +69,28 @@ pub mod friends {
5069
.map(|f| Friend {
5170
steam_id: BigInt::from(f.id().raw()),
5271
name: f.name(),
72+
nickname: f.nick_name(),
73+
state: match f.state() {
74+
steamworks::FriendState::Offline => PersonaState::Offline,
75+
steamworks::FriendState::Online => PersonaState::Online,
76+
steamworks::FriendState::Busy => PersonaState::Busy,
77+
steamworks::FriendState::Away => PersonaState::Away,
78+
steamworks::FriendState::Snooze => PersonaState::Snooze,
79+
steamworks::FriendState::LookingToTrade => PersonaState::LookingToTrade,
80+
steamworks::FriendState::LookingToPlay => PersonaState::LookingToPlay,
81+
},
82+
game_played: f.game_played().map(|g| FriendGameInfo {
83+
game_id: BigInt::from(g.game.raw()),
84+
game_ip: g.game_address.to_string(),
85+
game_port: g.game_port as u32,
86+
query_port: g.query_port as u32,
87+
lobby_id: BigInt::from(g.lobby.raw()),
88+
}),
5389
})
5490
.collect()
5591
}
5692

57-
/// Get the persona name of a friend.
93+
/// Get the name of a friend.
5894
///
5995
/// @param steam_id64 - The Steam ID of the friend.
6096
/// @returns The name of the friend.

test/friends.js

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,60 @@ try {
55
const friends = client.friends
66

77
console.log('Testing Friends API...')
8-
8+
99
// Test FriendFlags existence
1010
if (!friends.FriendFlags) {
1111
throw new Error('FriendFlags is missing')
1212
}
1313
console.log('✓ FriendFlags found')
1414

15+
16+
// Test PersonaState existence
17+
if (!friends.PersonaState) {
18+
throw new Error('PersonaState is missing')
19+
}
20+
console.log('✓ PersonaState found')
21+
1522
// Test getFriends
1623
const friendList = friends.getFriends(friends.FriendFlags.Immediate)
1724
console.log(`✓ getFriends returned ${friendList.length} friends`)
1825

1926
if (friendList.length > 0) {
2027
const firstFriend = friendList[0]
21-
28+
2229
// Test Friend object structure
2330
if (typeof firstFriend.steamId !== 'bigint' || typeof firstFriend.name !== 'string') {
2431
throw new Error('Invalid Friend object structure')
2532
}
33+
34+
if (typeof firstFriend.state !== 'number') {
35+
throw new Error('New Friend object property (state) is invalid or missing')
36+
}
37+
38+
// nickname is optional
39+
if (firstFriend.nickname !== undefined && firstFriend.nickname !== null) {
40+
if (typeof firstFriend.nickname !== 'string') {
41+
throw new Error('Invalid nickname type')
42+
}
43+
console.log(`✓ Friend has a nickname: ${firstFriend.nickname}`)
44+
}
45+
46+
// gamePlayed is optional
47+
if (firstFriend.gamePlayed !== undefined && firstFriend.gamePlayed !== null) {
48+
if (typeof firstFriend.gamePlayed.gameId !== 'bigint' || typeof firstFriend.gamePlayed.gameIp !== 'string') {
49+
throw new Error('Invalid FriendGameInfo structure in gamePlayed')
50+
}
51+
console.log('✓ Friend is in-game, gamePlayed structure is valid')
52+
}
53+
2654
console.log('✓ Friend object structure is valid')
2755

28-
// Test getFriendPersonaName
29-
const personaName = friends.getFriendPersonaName(firstFriend.steamId)
30-
if (personaName !== firstFriend.name) {
31-
throw new Error(`Persona name mismatch: expected ${firstFriend.name}, got ${personaName}`)
56+
// Test getFriendName
57+
const name = friends.getFriendName(firstFriend.steamId)
58+
if (name !== firstFriend.name) {
59+
throw new Error(`Name mismatch: expected ${firstFriend.name}, got ${name}`)
3260
}
33-
console.log(`✓ getFriendPersonaName returned correct name: ${personaName}`)
61+
console.log(`✓ getFriendName returned correct name: ${name}`)
3462
} else {
3563
console.log('! No friends found to test individual properties, but getFriends call succeeded.')
3664
}

0 commit comments

Comments
 (0)