aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Collins <[email protected]>2018-05-07 01:02:44 +0100
committerMatthew Collins <[email protected]>2018-05-07 01:02:44 +0100
commit63f96e3eb579cd53b4a7bee84ef173add5f888e8 (patch)
tree8badd7acdc85a70f141f3750bbf047c586cffd44
parentFix building with older steam sdks (diff)
downloadsteamworks-rs-63f96e3eb579cd53b4a7bee84ef173add5f888e8.tar.xz
steamworks-rs-63f96e3eb579cd53b4a7bee84ef173add5f888e8.zip
Steam networking support + other improvements
-rw-r--r--src/callback.rs33
-rw-r--r--src/friends.rs96
-rw-r--r--src/lib.rs67
-rw-r--r--src/matchmaking.rs60
-rw-r--r--src/networking.rs109
-rw-r--r--src/server.rs8
-rw-r--r--src/user.rs4
-rw-r--r--steamworks-sys/src/lib.cpp25
-rw-r--r--steamworks-sys/src/lib.rs24
9 files changed, 412 insertions, 14 deletions
diff --git a/src/callback.rs b/src/callback.rs
index 18c1db0..d8e186d 100644
--- a/src/callback.rs
+++ b/src/callback.rs
@@ -5,8 +5,11 @@ use sys;
use std::mem;
use std::sync::{ Arc, Weak };
+#[cfg(debug_assertions)]
use std::panic::*;
+#[cfg(debug_assertions)]
use std::any::Any;
+#[cfg(debug_assertions)]
use std::process::abort;
pub unsafe trait Callback {
@@ -15,6 +18,29 @@ pub unsafe trait Callback {
unsafe fn from_raw(raw: *mut c_void) -> Self;
}
+/// A handled that can be used to remove a callback
+/// at a later point.
+///
+/// Removes the callback when dropped
+pub struct CallbackHandle<Manager = ClientManager> {
+ handle: *mut c_void,
+ inner: Weak<Inner<Manager>>,
+}
+unsafe impl <Manager> Send for CallbackHandle<Manager> {}
+
+impl <Manager> Drop for CallbackHandle<Manager> {
+ fn drop(&mut self) {
+ if let Some(inner) = self.inner.upgrade() {
+ let mut cb = inner.callbacks.lock().unwrap();
+ if let Some(pos) = cb.callbacks.iter().position(|v| *v == self.handle) {
+ cb.callbacks.swap_remove(pos);
+ unsafe { sys::delete_rust_callback(self.handle); }
+ }
+ }
+ }
+}
+
+#[cfg(debug_assertions)]
fn print_err(err: Box<Any>) {
if let Some(err) = err.downcast_ref::<&str>() {
println!("Steam callback paniced: {}", err);
@@ -25,7 +51,7 @@ fn print_err(err: Box<Any>) {
}
}
-pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>>, f: F, game_server: bool)
+pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>>, f: F, game_server: bool) -> CallbackHandle<Manager>
where C: Callback,
F: FnMut(C) + Send + 'static
{
@@ -70,6 +96,11 @@ pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>
let mut cbs = inner.callbacks.lock().unwrap();
cbs.callbacks.push(ptr);
+
+ CallbackHandle {
+ handle: ptr,
+ inner: Arc::downgrade(inner),
+ }
}
pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manager>>, api_call: sys::SteamAPICall, callback_id: i32, f: F)
diff --git a/src/friends.rs b/src/friends.rs
index f0fe66e..68cbe6d 100644
--- a/src/friends.rs
+++ b/src/friends.rs
@@ -1,5 +1,6 @@
use super::*;
+use std::net::Ipv4Addr;
const CALLBACK_BASE_ID: i32 = 300;
@@ -78,6 +79,14 @@ impl <Manager> Friends<Manager> {
}
}
+ pub fn get_friend(&self, friend: SteamId) -> Friend<Manager> {
+ Friend {
+ id: friend,
+ friends: self.friends,
+ _inner: self.inner.clone(),
+ }
+ }
+
pub fn request_user_information(&self, user: SteamId, name_only: bool) {
unsafe {
sys::SteamAPI_ISteamFriends_RequestUserInformation(self.friends, user.0, name_only as u8);
@@ -91,6 +100,29 @@ impl <Manager> Friends<Manager> {
sys::SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage(self.friends, url.as_ptr() as *const _);
}
}
+
+ /// Opens up an invite dialog for the given lobby
+ pub fn activate_invite_dialog(&self, lobby: LobbyId) {
+ unsafe {
+ sys::SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialog(self.friends, lobby.0);
+ }
+ }
+}
+
+/// Information about a friend's current state in a game
+#[derive(Debug)]
+pub struct FriendGame {
+ /// The id of the game that the friend is
+ /// playing
+ pub game: GameId,
+ /// The address of the server the player is in
+ pub game_address: Ipv4Addr,
+ /// The game port of the server the player is in
+ pub game_port: u16,
+ /// The query port of the server the player is in
+ pub query_port: u16,
+ /// Optional id of the lobby the player is in
+ pub lobby: LobbyId,
}
#[derive(Debug)]
@@ -171,6 +203,70 @@ impl <Manager> Friend<Manager> {
}
}
}
+
+ /// Returns information about the game the player is current playing if any
+ pub fn game_played(&self) -> Option<FriendGame> {
+ unsafe {
+ let mut info = sys::create_empty_FriendGameInfo_t();
+ if sys::SteamAPI_ISteamFriends_GetFriendGamePlayed(self.friends, self.id.0, &mut info) != 0 {
+ Some(FriendGame {
+ game: GameId(info.get_m_gameID()),
+ game_address: info.get_m_unGameIP().into(),
+ game_port: info.get_m_usGamePort(),
+ query_port: info.get_m_usQueryPort(),
+ lobby: LobbyId(info.get_m_steamIDLobby()),
+ })
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Returns a small (32x32) avatar for the user
+ pub fn small_avatar(&self) -> Option<Vec<u8>> {
+ unsafe {
+ let utils = sys::steam_rust_get_utils();
+ let img = sys::SteamAPI_ISteamFriends_GetSmallFriendAvatar(self.friends, self.id.0);
+ if img == 0 {
+ return None;
+ }
+ let mut width = 0;
+ let mut height = 0;
+ if sys::SteamAPI_ISteamUtils_GetImageSize(utils, img, &mut width, &mut height) == 0 {
+ return None;
+ }
+ assert_eq!(width, 32);
+ assert_eq!(height, 32);
+ let mut dest = vec![0; 32 * 32 * 4];
+ if sys::SteamAPI_ISteamUtils_GetImageRGBA(utils, img, dest.as_mut_ptr(), 32 * 32 * 4) == 0 {
+ return None;
+ }
+ Some(dest)
+ }
+ }
+
+ /// Returns a small (64x64) avatar for the user
+ pub fn medium_avatar(&self) -> Option<Vec<u8>> {
+ unsafe {
+ let utils = sys::steam_rust_get_utils();
+ let img = sys::SteamAPI_ISteamFriends_GetMediumFriendAvatar(self.friends, self.id.0);
+ if img == 0 {
+ return None;
+ }
+ let mut width = 0;
+ let mut height = 0;
+ if sys::SteamAPI_ISteamUtils_GetImageSize(utils, img, &mut width, &mut height) == 0 {
+ return None;
+ }
+ assert_eq!(width, 64);
+ assert_eq!(height, 64);
+ let mut dest = vec![0; 64 * 64 * 4];
+ if sys::SteamAPI_ISteamUtils_GetImageRGBA(utils, img, dest.as_mut_ptr(), 64 * 64 * 4) == 0 {
+ return None;
+ }
+ Some(dest)
+ }
+ }
}
#[derive(Clone, Copy, Debug)]
diff --git a/src/lib.rs b/src/lib.rs
index 5884eb4..00f8f08 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -21,6 +21,8 @@ mod friends;
pub use friends::*;
mod matchmaking;
pub use matchmaking::*;
+mod networking;
+pub use networking::*;
mod user;
pub use user::*;
@@ -160,12 +162,12 @@ impl <Manager> Client<Manager> {
///
/// The callback will be run on the thread that `run_callbacks`
/// is called when the event arrives.
- pub fn register_callback<C, F>(&self, f: F)
+ pub fn register_callback<C, F>(&self, f: F) -> CallbackHandle<Manager>
where C: Callback,
F: FnMut(C) + 'static + Send
{
unsafe {
- register_callback(&self.inner, f, false);
+ register_callback(&self.inner, f, false)
}
}
@@ -193,6 +195,18 @@ impl <Manager> Client<Manager> {
}
}
+ /// Returns an accessor to the steam networking interface
+ pub fn networking(&self) -> Networking<Manager> {
+ unsafe {
+ let net = sys::steam_rust_get_networking();
+ debug_assert!(!net.is_null());
+ Networking {
+ net: net,
+ _inner: self.inner.clone(),
+ }
+ }
+ }
+
/// Returns an accessor to the steam apps interface
pub fn apps(&self) -> Apps<Manager> {
unsafe {
@@ -273,7 +287,7 @@ impl Drop for ClientManager {
}
/// A user's steam id
-#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
+#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct SteamId(pub(crate) u64);
impl SteamId {
@@ -292,6 +306,51 @@ impl SteamId {
pub fn raw(&self) -> u64 {
self.0
}
+
+ /// Returns whether this id is valid or not
+ pub fn is_valid(&self) -> bool {
+ unsafe {
+ sys::steam_rust_is_steam_id_valid(self.0) != 0
+ }
+ }
+}
+
+/// A game id
+///
+/// Combines `AppId` and other information
+#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
+pub struct GameId(pub(crate) u64);
+
+impl GameId {
+ /// Creates a `GameId` from a raw 64 bit value.
+ ///
+ /// May be useful for deserializing game ids from
+ /// a network or save format.
+ pub fn from_raw(id: u64) -> GameId {
+ GameId(id)
+ }
+
+ /// Returns the raw 64 bit value of the game id
+ ///
+ /// May be useful for serializing game ids over a
+ /// network or to a save format.
+ pub fn raw(&self) -> u64 {
+ self.0
+ }
+
+ /// Returns the app id of this game
+ pub fn app_id(&self) -> AppId {
+ unsafe {
+ AppId(sys::steam_rust_get_game_id_app(self.0))
+ }
+ }
+
+ /// Returns whether this id is valid or not
+ pub fn is_valid(&self) -> bool {
+ unsafe {
+ sys::steam_rust_is_game_id_valid(self.0) != 0
+ }
+ }
}
#[cfg(test)]
@@ -301,7 +360,7 @@ mod tests {
fn basic_test() {
let (client, single) = Client::init().unwrap();
- client.register_callback(|p: PersonaStateChange| {
+ let _cb = client.register_callback(|p: PersonaStateChange| {
println!("Got callback: {:?}", p);
});
diff --git a/src/matchmaking.rs b/src/matchmaking.rs
index f219381..0f3c17b 100644
--- a/src/matchmaking.rs
+++ b/src/matchmaking.rs
@@ -17,8 +17,33 @@ pub enum LobbyType {
Invisible,
}
-#[derive(Debug)]
-pub struct LobbyId(pub u64);
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct LobbyId(pub(crate) u64);
+
+impl LobbyId {
+ /// Creates a `LobbyId` from a raw 64 bit value.
+ ///
+ /// May be useful for deserializing lobby ids from
+ /// a network or save format.
+ pub fn from_raw(id: u64) -> LobbyId {
+ LobbyId(id)
+ }
+
+ /// Returns the raw 64 bit value of the lobby id
+ ///
+ /// May be useful for serializing lobby ids over a
+ /// network or to a save format.
+ pub fn raw(&self) -> u64 {
+ self.0
+ }
+
+ /// Returns whether this id is valid or not
+ pub fn is_valid(&self) -> bool {
+ unsafe {
+ sys::steam_rust_is_steam_id_valid(self.0) != 0
+ }
+ }
+}
impl <Manager> Matchmaking<Manager> {
@@ -105,6 +130,37 @@ impl <Manager> Matchmaking<Manager> {
sys::SteamAPI_ISteamMatchmaking_LeaveLobby(self.mm, lobby.0);
}
}
+
+ /// Returns the steam id of the current owner of the passed lobby
+ pub fn lobby_owner(&self, lobby: LobbyId) -> SteamId {
+ unsafe {
+ SteamId(sys::SteamAPI_ISteamMatchmaking_GetLobbyOwner(self.mm, lobby.0))
+ }
+ }
+
+ /// Returns the number of players in a lobby.
+ ///
+ /// Useful if you are not currently in the lobby
+ pub fn lobby_member_count(&self, lobby: LobbyId) -> usize {
+ unsafe {
+ let count = sys::SteamAPI_ISteamMatchmaking_GetNumLobbyMembers(self.mm, lobby.0);
+ count as usize
+ }
+ }
+
+ /// Returns a list of members currently in the lobby
+ pub fn lobby_members(&self, lobby: LobbyId) -> Vec<SteamId> {
+ unsafe {
+ let count = sys::SteamAPI_ISteamMatchmaking_GetNumLobbyMembers(self.mm, lobby.0);
+ let mut members = Vec::with_capacity(count as usize);
+ for idx in 0 .. count {
+ members.push(SteamId(
+ sys::SteamAPI_ISteamMatchmaking_GetLobbyMemberByIndex(self.mm, lobby.0, idx)
+ ))
+ }
+ members
+ }
+ }
}
#[test]
diff --git a/src/networking.rs b/src/networking.rs
new file mode 100644
index 0000000..258abda
--- /dev/null
+++ b/src/networking.rs
@@ -0,0 +1,109 @@
+use super::*;
+
+/// Access to the steam networking interface
+pub struct Networking<Manager> {
+ pub(crate) net: *mut sys::ISteamNetworking,
+ pub(crate) _inner: Arc<Inner<Manager>>,
+}
+
+/// The method used to send a packet
+#[derive(Debug)]
+pub enum SendType {
+ /// Send the packet directly over udp.
+ ///
+ /// Can't be larger than 1200 bytes
+ Unreliable,
+ /// Like `Unreliable` but doesn't buffer packets
+ /// sent before the connection has started.
+ UnreliableNoDelay,
+ /// Reliable packet sending.
+ ///
+ /// Can't be larger than 1 megabyte.
+ Reliable,
+ /// Like `Reliable` but applies the nagle
+ /// algorithm to packets being sent
+ ReliableWithBuffering,
+}
+
+impl <Manager> Networking<Manager> {
+ /// Accepts incoming packets from the given user
+ ///
+ /// Should only be called in response to a `P2PSessionRequest`.
+ pub fn accept_p2p_session(&self, user: SteamId) {
+ unsafe {
+ sys::SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser(self.net, user.0);
+ }
+ }
+
+ /// Closes the p2p connection between the given user
+ pub fn close_p2p_session(&self, user: SteamId) {
+ unsafe {
+ sys::SteamAPI_ISteamNetworking_CloseP2PSessionWithUser(self.net, user.0);
+ }
+ }
+
+ /// Sends a packet to the start user starting the
+ /// connection if it isn't started already
+ pub fn send_p2p_packet(&self, remote: SteamId, send_type: SendType, data: &[u8]) -> bool {
+ unsafe {
+ let send_type = match send_type {
+ SendType::Unreliable => sys::EP2PSend_k_EP2PSendUnreliable,
+ SendType::UnreliableNoDelay => sys::EP2PSend_k_EP2PSendUnreliableNoDelay,
+ SendType::Reliable => sys::EP2PSend_k_EP2PSendReliable,
+ SendType::ReliableWithBuffering => sys::EP2PSend_k_EP2PSendReliableWithBuffering,
+ };
+ sys::SteamAPI_ISteamNetworking_SendP2PPacket(self.net, remote.0, data.as_ptr() as *const _, data.len() as u32, send_type, 0) != 0
+ }
+ }
+
+ /// Returns whether there is a packet queued that can be read.
+ ///
+ /// Returns the size of the queued packet if any.
+ pub fn is_p2p_packet_available(&self) -> Option<usize> {
+ unsafe {
+ let mut size = 0;
+ if sys::SteamAPI_ISteamNetworking_IsP2PPacketAvailable(self.net, &mut size, 0) != 0 {
+ Some(size as usize)
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Attempts to read a queued packet into the buffer
+ /// if there are any.
+ ///
+ /// Returns the steam id of the sender and the size of the
+ /// packet.
+ pub fn read_p2p_packet(&self, buf: &mut [u8]) -> Option<(SteamId, usize)> {
+ unsafe {
+ let mut size = 0;
+ let mut remote = 0;
+ if sys::SteamAPI_ISteamNetworking_ReadP2PPacket(self.net, buf.as_mut_ptr() as *mut _, buf.len() as _, &mut size, &mut remote, 0) != 0 {
+ Some((SteamId(remote), size as usize))
+ } else {
+ None
+ }
+ }
+ }
+}
+
+/// Called when a user wants to communicate via p2p
+#[derive(Debug)]
+pub struct P2PSessionRequest {
+ /// The steam ID of the user requesting a p2p
+ /// session
+ pub remote: SteamId,
+}
+
+unsafe impl Callback for P2PSessionRequest {
+ const ID: i32 = sys::P2PSessionRequest_t_k_iCallback as i32;
+ const SIZE: i32 = ::std::mem::size_of::<sys::P2PSessionRequest_t>() as i32;
+
+ unsafe fn from_raw(raw: *mut libc::c_void) -> Self {
+ let val = &mut *(raw as *mut sys::P2PSessionRequest_t);
+ P2PSessionRequest {
+ remote: SteamId(val.get_m_steamIDRemote()),
+ }
+ }
+}
diff --git a/src/server.rs b/src/server.rs
index ee67742..6a01b7f 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -97,12 +97,12 @@ impl Server {
///
/// The callback will be run on the thread that `run_callbacks`
/// is called when the event arrives.
- pub fn register_callback<C, F>(&self, f: F)
+ pub fn register_callback<C, F>(&self, f: F) -> CallbackHandle<ServerManager>
where C: Callback,
F: FnMut(C) + 'static + Send + Sync
{
unsafe {
- register_callback(&self.inner, f, true);
+ register_callback(&self.inner, f, true)
}
}
@@ -251,8 +251,8 @@ fn test() {
println!("{:?}", server.steam_id());
- server.register_callback(|v: AuthSessionTicketResponse| println!("{:?}", v));
- server.register_callback(|v: ValidateAuthTicketResponse| println!("{:?}", v));
+ let _cb = server.register_callback(|v: AuthSessionTicketResponse| println!("{:?}", v));
+ let _cb = server.register_callback(|v: ValidateAuthTicketResponse| println!("{:?}", v));
let id = server.steam_id();
let (auth, ticket) = server.authentication_session_ticket();
diff --git a/src/user.rs b/src/user.rs
index 8298656..3263ba6 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -111,8 +111,8 @@ fn test() {
let (client, single) = Client::init().unwrap();
let user = client.user();
- client.register_callback(|v: AuthSessionTicketResponse| println!("{:?}", v));
- client.register_callback(|v: ValidateAuthTicketResponse| println!("{:?}", v));
+ let _cb = client.register_callback(|v: AuthSessionTicketResponse| println!("{:?}", v));
+ let _cb = client.register_callback(|v: ValidateAuthTicketResponse| println!("{:?}", v));
let id = user.steam_id();
let (auth, ticket) = user.authentication_session_ticket();
diff --git a/steamworks-sys/src/lib.cpp b/steamworks-sys/src/lib.cpp
index 38701da..655eaf4 100644
--- a/steamworks-sys/src/lib.cpp
+++ b/steamworks-sys/src/lib.cpp
@@ -52,8 +52,33 @@ extern "C" {
return SteamGameServer_Init(ip, steam_port, game_port, query_port, server_mode, version);
}
+ int steam_rust_is_steam_id_valid(uint64_t steam_id) {
+ CSteamID id = CSteamID();
+ id.SetFromUint64(steam_id);
+ return id.IsValid();
+ }
+
+ int steam_rust_is_game_id_valid(uint64_t game_id) {
+ CGameID id = CGameID();
+ id.Set(game_id);
+ return id.IsValid();
+ }
+
+ uint32_t steam_rust_get_game_id_mod(uint64_t game_id) {
+ CGameID id = CGameID();
+ id.Set(game_id);
+ return id.ModID();
+ }
+
+ uint32_t steam_rust_get_game_id_app(uint64_t game_id) {
+ CGameID id = CGameID();
+ id.Set(game_id);
+ return id.AppID();
+ }
+
ISteamClient* steam_rust_get_client() { return SteamClient(); }
ISteamMatchmaking* steam_rust_get_matchmaking() { return SteamMatchmaking(); }
+ ISteamNetworking* steam_rust_get_networking() { return SteamNetworking(); }
ISteamUtils* steam_rust_get_utils() { return SteamUtils(); }
ISteamApps* steam_rust_get_apps() { return SteamApps(); }
ISteamFriends* steam_rust_get_friends() { return SteamFriends(); }
diff --git a/steamworks-sys/src/lib.rs b/steamworks-sys/src/lib.rs
index 7d6ebae..a89a14d 100644
--- a/steamworks-sys/src/lib.rs
+++ b/steamworks-sys/src/lib.rs
@@ -26,6 +26,8 @@ pub struct ISteamMatchmaking(c_void);
pub struct ISteamUser(c_void);
#[repr(C)]
pub struct ISteamGameServer(c_void);
+#[repr(C)]
+pub struct ISteamNetworking(c_void);
pub type HSteamPipe = i32;
pub type AppId = u32;
@@ -53,8 +55,13 @@ extern "C" {
pub fn steam_rust_get_user() -> *mut ISteamUser;
pub fn steam_rust_get_server() -> *mut ISteamGameServer;
pub fn steam_rust_get_server_apps() -> *mut ISteamApps;
+ pub fn steam_rust_get_networking() -> *mut ISteamNetworking;
pub fn steam_rust_game_server_init(ip: u32, steam_port: u16, game_port: u16, query_port: u16, server_mode: EServerMode, version: *const c_char) -> c_int;
+ pub fn steam_rust_is_steam_id_valid(id: u64) -> c_int;
+ pub fn steam_rust_is_game_id_valid(id: u64) -> c_int;
+ pub fn steam_rust_get_game_id_mod(id: u64) -> u32;
+ pub fn steam_rust_get_game_id_app(id: u64) -> u32;
//
@@ -76,8 +83,10 @@ extern "C" {
pub fn SteamAPI_ISteamUtils_GetAppID(instance: *mut ISteamUtils) -> u32;
pub fn SteamAPI_ISteamUtils_GetSteamUILanguage(instance: *mut ISteamUtils) -> *const c_char;
- pub fn SteamAPI_ISteamUtils_IsAPICallCompleted(instance: *mut ISteamUtils, api_call: SteamAPICall, failed: *mut bool) -> bool;
+ pub fn SteamAPI_ISteamUtils_IsAPICallCompleted(instance: *mut ISteamUtils, api_call: SteamAPICall, failed: *mut bool) -> u8;
pub fn SteamAPI_ISteamUtils_SetOverlayNotificationPosition(instance: *mut ISteamUtils, position: ENotificationPosition);
+ pub fn SteamAPI_ISteamUtils_GetImageSize(instance: *mut ISteamUtils, image: c_int, width: *mut u32, height: *mut u32) -> u8;
+ pub fn SteamAPI_ISteamUtils_GetImageRGBA(instance: *mut ISteamUtils, image: c_int, dest: *mut u8, dest_size: c_int) -> u8;
pub fn SteamAPI_ISteamApps_BIsAppInstalled(instance: *mut ISteamApps, app_id: AppId) -> u8;
pub fn SteamAPI_ISteamApps_BIsDlcInstalled(instance: *mut ISteamApps, app_id: AppId) -> u8;
@@ -101,12 +110,25 @@ extern "C" {
pub fn SteamAPI_ISteamFriends_RequestUserInformation(instance: *mut ISteamFriends, user_id: u64, name_only: u8) -> u8;
pub fn SteamAPI_ISteamFriends_ActivateGameOverlayToWebPage(instance: *mut ISteamFriends, url: *const c_char);
pub fn SteamAPI_ISteamFriends_GetPersonaName(instance: *mut ISteamFriends) -> *const c_char;
+ pub fn SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialog(instance: *mut ISteamFriends, lobby: u64);
+ pub fn SteamAPI_ISteamFriends_GetSmallFriendAvatar(instance: *mut ISteamFriends, friend: u64) -> c_int;
+ pub fn SteamAPI_ISteamFriends_GetMediumFriendAvatar(instance: *mut ISteamFriends, friend: u64) -> c_int;
+ pub fn SteamAPI_ISteamFriends_GetFriendGamePlayed(instance: *mut ISteamFriends, friend: u64, game_info: *mut FriendGameInfo_t) -> u8;
pub fn SteamAPI_ISteamMatchmaking_CreateLobby(instance: *mut ISteamMatchmaking, lobby_ty: ELobbyType, max_members: c_int) -> SteamAPICall;
pub fn SteamAPI_ISteamMatchmaking_RequestLobbyList(instance: *mut ISteamMatchmaking) -> SteamAPICall;
pub fn SteamAPI_ISteamMatchmaking_GetLobbyByIndex(instance: *mut ISteamMatchmaking, lobby: c_int) -> u64;
pub fn SteamAPI_ISteamMatchmaking_LeaveLobby(instance: *mut ISteamMatchmaking, lobby: u64);
pub fn SteamAPI_ISteamMatchmaking_JoinLobby(instance: *mut ISteamMatchmaking, lobby: u64) -> SteamAPICall;
+ pub fn SteamAPI_ISteamMatchmaking_GetLobbyOwner(instance: *mut ISteamMatchmaking, lobby: u64) -> u64;
+ pub fn SteamAPI_ISteamMatchmaking_GetNumLobbyMembers(instance: *mut ISteamMatchmaking, lobby: u64) -> c_int;
+ pub fn SteamAPI_ISteamMatchmaking_GetLobbyMemberByIndex(instance: *mut ISteamMatchmaking, lobby: u64, member: c_int) -> u64;
+
+ pub fn SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser(instance: *mut ISteamNetworking, remote: u64) -> u8;
+ pub fn SteamAPI_ISteamNetworking_CloseP2PSessionWithUser(instance: *mut ISteamNetworking, remote: u64) -> u8;
+ pub fn SteamAPI_ISteamNetworking_SendP2PPacket(instance: *mut ISteamNetworking, remote: u64, data: *const c_void, data_len: u32, send_type: EP2PSend, channel: c_int) -> u8;
+ pub fn SteamAPI_ISteamNetworking_IsP2PPacketAvailable(instance: *mut ISteamNetworking, msg_size: *mut u32, channel: c_int) -> u8;
+ pub fn SteamAPI_ISteamNetworking_ReadP2PPacket(instance: *mut ISteamNetworking, data: *mut c_void, data_len: u32, msg_size: *mut u32, remote: *mut u64, channel: c_int) -> u8;
pub fn SteamAPI_ISteamUser_GetSteamID(instance: *mut ISteamUser) -> u64;
pub fn SteamAPI_ISteamUser_GetAuthSessionTicket(instance: *mut ISteamUser, ticket: *mut c_void, max_ticket: c_int, ticket_size: *mut u32) -> HAuthTicket;