aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Collins <[email protected]>2018-05-05 15:46:12 +0100
committerMatthew Collins <[email protected]>2018-05-05 15:46:12 +0100
commit5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d (patch)
treee667ed1dccc3d3ac0df83e8c66b76dd5dc0771e8
parentMinor bump due to slight mistake with last publish (diff)
downloadarchived-steamworks-rs-5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d.tar.xz
archived-steamworks-rs-5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d.zip
Rework how the sys crate is generated
Due to packing issues with steam's structs we use wrapper methods to access the fields and create the structs.
-rw-r--r--Cargo.toml4
-rw-r--r--src/callback.rs55
-rw-r--r--src/error.rs228
-rw-r--r--src/friends.rs43
-rw-r--r--src/matchmaking.rs77
-rw-r--r--src/server.rs19
-rw-r--r--src/user.rs50
-rw-r--r--src/utils.rs8
-rw-r--r--steamworks-sys/Cargo.toml11
-rw-r--r--steamworks-sys/build.rs209
-rw-r--r--steamworks-sys/src/lib.cpp4
-rw-r--r--steamworks-sys/src/lib.rs229
-rw-r--r--steamworks-sys/wrapper.hpp3
13 files changed, 527 insertions, 413 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 768049e..f044a13 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "steamworks"
-version = "0.3.2"
+version = "0.4.0"
authors = ["Thinkofname"]
description = "Provides rust friendly bindings to the steamworks sdk"
license = "MIT / Apache-2.0"
@@ -20,7 +20,7 @@ members = [
]
[dependencies]
-steamworks-sys = {path = "./steamworks-sys", version = "0.2.1"}
+steamworks-sys = {path = "./steamworks-sys", version = "0.3.0"}
failure = "0.1.1"
bitflags = "1.0.1"
libc = "0.2.36"
diff --git a/src/callback.rs b/src/callback.rs
index d249207..6808a45 100644
--- a/src/callback.rs
+++ b/src/callback.rs
@@ -5,6 +5,9 @@ use sys;
use std::mem;
use std::sync::{ Arc, Weak };
+use std::panic::*;
+use std::any::Any;
+use std::process::abort;
pub unsafe trait Callback {
const ID: i32;
@@ -12,6 +15,16 @@ pub unsafe trait Callback {
unsafe fn from_raw(raw: *mut c_void) -> Self;
}
+fn print_err(err: Box<Any>) {
+ if let Some(err) = err.downcast_ref::<&str>() {
+ println!("Steam callback paniced: {}", err);
+ } else if let Some(err) = err.downcast_ref::<String>() {
+ println!("Steam callback paniced: {}", err);
+ } else {
+ println!("Steam callback paniced");
+ }
+}
+
pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>>, f: F, game_server: bool)
where C: Callback,
F: FnMut(C) + Send + Sync + 'static
@@ -25,7 +38,7 @@ pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>
func(param);
}
- unsafe extern "C" fn run_extra<C, F>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, _: bool, _: sys::SteamAPICall)
+ unsafe extern "C" fn run_extra<C, F>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, _: u8, _: sys::SteamAPICall)
where C: Callback,
F: FnMut(C) + Send + Sync + 'static
{
@@ -72,18 +85,46 @@ pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manag
where F: for<'a> FnMut(&'a C, bool) + Send + Sync + 'static
{
let data: &mut CallData<F, Manager> = &mut *(userdata as *mut CallData<F, Manager>);
- (data.func)(&*(param as *const _), false);
-
+ #[cfg(debug_assertions)]
+ {
+ let res = catch_unwind(AssertUnwindSafe(||
+ (data.func)(&*(param as *const _), false)
+ ));
+ if let Err(err) = res {
+ print_err(err);
+ abort();
+ }
+
+ }
+ #[cfg(not(debug_assertions))]
+ {
+ (data.func)(&*(param as *const _), false);
+ }
+
sys::delete_rust_callback(cb);
}
- unsafe extern "C" fn run_extra<C, F, Manager>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, io_error: bool, api_call: sys::SteamAPICall)
+ unsafe extern "C" fn run_extra<C, F, Manager>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, io_error: u8, api_call: sys::SteamAPICall)
where F: for<'a> FnMut(&'a C, bool) + Send + Sync + 'static
{
let data: &mut CallData<F, Manager> = &mut *(userdata as *mut CallData<F, Manager>);
if api_call == data.api_call {
- (data.func)(&*(param as *const _), io_error);
+ #[cfg(debug_assertions)]
+ {
+ let res = catch_unwind(AssertUnwindSafe(||
+ (data.func)(&*(param as *const _), io_error != 0)
+ ));
+ if let Err(err) = res {
+ print_err(err);
+ abort();
+ }
+
+ }
+ #[cfg(not(debug_assertions))]
+ {
+ (data.func)(&*(param as *const _), io_error != 0);
+ }
sys::delete_rust_callback(cb);
}
}
@@ -94,8 +135,6 @@ pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manag
let data: Box<CallData<F, Manager>> = Box::from_raw(userdata as _);
if let Some(inner) = data.inner.upgrade() {
- sys::SteamAPI_UnregisterCallResult(cb, data.api_call);
-
let mut cbs = inner.callbacks.lock().unwrap();
cbs.call_results.remove(&data.api_call);
}
@@ -110,7 +149,7 @@ pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manag
};
let data = sys::CallbackData {
- param_size: mem::size_of::<C> as _,
+ param_size: mem::size_of::<C>() as _,
userdata: Box::into_raw(Box::new(userdata)) as _,
run: run::<C, F, Manager>,
run_extra: run_extra::<C, F, Manager>,
diff --git a/src/error.rs b/src/error.rs
index c641392..683b2c6 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -385,121 +385,121 @@ pub enum SteamError {
LimitedUserAccount,
}
-impl From<sys::SResult> for SteamError {
- fn from(r: sys::SResult) -> Self {
- use sys::SResult;
+impl From<sys::EResult> for SteamError {
+ fn from(r: sys::EResult) -> Self {
match r {
- SResult::Ok => panic!("SResult::Ok isn't an error"),
- SResult::Fail => SteamError::Generic,
- SResult::NoConnection => SteamError::NoConnection,
- SResult::InvalidPassword => SteamError::InvalidPassword,
- SResult::LoggedInElsewhere => SteamError::LoggedInElsewhere,
- SResult::InvalidProtocolVer => SteamError::InvalidProtocolVersion,
- SResult::InvalidParam => SteamError::InvalidParameter,
- SResult::FileNotFound => SteamError::FileNotFound,
- SResult::Busy => SteamError::Busy,
- SResult::InvalidState => SteamError::InvalidState,
- SResult::InvalidName => SteamError::InvalidName,
- SResult::InvalidEmail => SteamError::InvalidEmail,
- SResult::DuplicateName => SteamError::DuplicateName,
- SResult::AccessDenied => SteamError::AccessDenied,
- SResult::Timeout => SteamError::Timeout,
- SResult::Banned => SteamError::Banned,
- SResult::AccountNotFound => SteamError::AccountNotFound,
- SResult::InvalidSteamID => SteamError::InvalidSteamID,
- SResult::ServiceUnavailable => SteamError::ServiceUnavailable,
- SResult::NotLoggedOn => SteamError::NotLoggedOn,
- SResult::Pending => SteamError::Pending,
- SResult::EncryptionFailure => SteamError::EncryptionFailure,
- SResult::InsufficientPrivilege => SteamError::InsufficientPrivilege,
- SResult::LimitExceeded => SteamError::LimitExceeded,
- SResult::Revoked => SteamError::Revoked,
- SResult::Expired => SteamError::Expired,
- SResult::AlreadyRedeemed => SteamError::AlreadyRedeemed,
- SResult::DuplicateRequest => SteamError::DuplicateRequest,
- SResult::AlreadyOwned => SteamError::AlreadyOwned,
- SResult::IPNotFound => SteamError::IPNotFound,
- SResult::PersistFailed => SteamError::PersistFailed,
- SResult::LockingFailed => SteamError::LockingFailed,
- SResult::LogonSessionReplaced => SteamError::LogonSessionReplaced,
- SResult::ConnectFailed => SteamError::ConnectFailed,
- SResult::HandshakeFailed => SteamError::HandshakeFailed,
- SResult::IOFailure => SteamError::IOFailure,
- SResult::RemoteDisconnect => SteamError::RemoteDisconnect,
- SResult::ShoppingCartNotFound => SteamError::ShoppingCartNotFound,
- SResult::Blocked => SteamError::Blocked,
- SResult::Ignored => SteamError::Ignored,
- SResult::NoMatch => SteamError::NoMatch,
- SResult::AccountDisabled => SteamError::AccountDisabled,
- SResult::ServiceReadOnly => SteamError::ServiceReadOnly,
- SResult::AccountNotFeatured => SteamError::AccountNotFeatured,
- SResult::AdministratorOK => SteamError::AdministratorOK,
- SResult::ContentVersion => SteamError::ContentVersion,
- SResult::TryAnotherCM => SteamError::TryAnotherCM,
- SResult::PasswordRequiredToKickSession => SteamError::PasswordRequiredToKickSession,
- SResult::AlreadyLoggedInElsewhere => SteamError::AlreadyLoggedInElsewhere,
- SResult::Suspended => SteamError::Suspended,
- SResult::Cancelled => SteamError::Cancelled,
- SResult::DataCorruption => SteamError::DataCorruption,
- SResult::DiskFull => SteamError::DiskFull,
- SResult::RemoteCallFailed => SteamError::RemoteCallFailed,
- SResult::PasswordUnset => SteamError::PasswordUnset,
- SResult::ExternalAccountUnlinked => SteamError::ExternalAccountUnlinked,
- SResult::PSNTicketInvalid => SteamError::PSNTicketInvalid,
- SResult::ExternalAccountAlreadyLinked => SteamError::ExternalAccountAlreadyLinked,
- SResult::RemoteFileConflict => SteamError::RemoteFileConflict,
- SResult::IllegalPassword => SteamError::IllegalPassword,
- SResult::SameAsPreviousValue => SteamError::SameAsPreviousValue,
- SResult::AccountLogonDenied => SteamError::AccountLogonDenied,
- SResult::CannotUseOldPassword => SteamError::CannotUseOldPassword,
- SResult::InvalidLoginAuthCode => SteamError::InvalidLoginAuthCode,
- SResult::AccountLogonDeniedNoMail => SteamError::AccountLogonDeniedNoMail,
- SResult::HardwareNotCapableOfIPT => SteamError::HardwareNotCapableOfIPT,
- SResult::IPTInitError => SteamError::IPTInitError,
- SResult::ParentalControlRestricted => SteamError::ParentalControlRestricted,
- SResult::FacebookQueryError => SteamError::FacebookQueryError,
- SResult::ExpiredLoginAuthCode => SteamError::ExpiredLoginAuthCode,
- SResult::IPLoginRestrictionFailed => SteamError::IPLoginRestrictionFailed,
- SResult::AccountLockedDown => SteamError::AccountLockedDown,
- SResult::AccountLogonDeniedVerifiedEmailRequired => SteamError::AccountLogonDeniedVerifiedEmailRequired,
- SResult::NoMatchingURL => SteamError::NoMatchingURL,
- SResult::BadResponse => SteamError::BadResponse,
- SResult::RequirePasswordReEntry => SteamError::RequirePasswordReEntry,
- SResult::ValueOutOfRange => SteamError::ValueOutOfRange,
- SResult::UnexpectedError => SteamError::UnexpectedError,
- SResult::Disabled => SteamError::Disabled,
- SResult::InvalidCEGSubmission => SteamError::InvalidCEGSubmission,
- SResult::RestrictedDevice => SteamError::RestrictedDevice,
- SResult::RegionLocked => SteamError::RegionLocked,
- SResult::RateLimitExceeded => SteamError::RateLimitExceeded,
- SResult::AccountLoginDeniedNeedTwoFactor => SteamError::AccountLoginDeniedNeedTwoFactor,
- SResult::ItemDeleted => SteamError::ItemDeleted,
- SResult::AccountLoginDeniedThrottle => SteamError::AccountLoginDeniedThrottle,
- SResult::TwoFactorCodeMismatch => SteamError::TwoFactorCodeMismatch,
- SResult::TwoFactorActivationCodeMismatch => SteamError::TwoFactorActivationCodeMismatch,
- SResult::AccountAssociatedToMultiplePartners => SteamError::AccountAssociatedToMultiplePartners,
- SResult::NotModified => SteamError::NotModified,
- SResult::NoMobileDevice => SteamError::NoMobileDevice,
- SResult::TimeNotSynced => SteamError::TimeNotSynced,
- SResult::SmsCodeFailed => SteamError::SmsCodeFailed,
- SResult::AccountLimitExceeded => SteamError::AccountLimitExceeded,
- SResult::AccountActivityLimitExceeded => SteamError::AccountActivityLimitExceeded,
- SResult::PhoneActivityLimitExceeded => SteamError::PhoneActivityLimitExceeded,
- SResult::RefundToWallet => SteamError::RefundToWallet,
- SResult::EmailSendFailure => SteamError::EmailSendFailure,
- SResult::NotSettled => SteamError::NotSettled,
- SResult::NeedCaptcha => SteamError::NeedCaptcha,
- SResult::GSLTDenied => SteamError::GSLTDenied,
- SResult::GSOwnerDenied => SteamError::GSOwnerDenied,
- SResult::InvalidItemType => SteamError::InvalidItemType,
- SResult::IPBanned => SteamError::IPBanned,
- SResult::GSLTExpired => SteamError::GSLTExpired,
- SResult::InsufficientFunds => SteamError::InsufficientFunds,
- SResult::TooManyPending => SteamError::TooManyPending,
- SResult::NoSiteLicensesFound => SteamError::NoSiteLicensesFound,
- SResult::WGNetworkSendExceeded => SteamError::WGNetworkSendExceeded,
- SResult::AccountNotFriends => SteamError::AccountNotFriends,
- SResult::LimitedUserAccount => SteamError::LimitedUserAccount,
+ sys::EResult_k_EResultOK => panic!("EResult_k_EResultOK isn't an error"),
+ sys::EResult_k_EResultFail => SteamError::Generic,
+ sys::EResult_k_EResultNoConnection => SteamError::NoConnection,
+ sys::EResult_k_EResultInvalidPassword => SteamError::InvalidPassword,
+ sys::EResult_k_EResultLoggedInElsewhere => SteamError::LoggedInElsewhere,
+ sys::EResult_k_EResultInvalidProtocolVer => SteamError::InvalidProtocolVersion,
+ sys::EResult_k_EResultInvalidParam => SteamError::InvalidParameter,
+ sys::EResult_k_EResultFileNotFound => SteamError::FileNotFound,
+ sys::EResult_k_EResultBusy => SteamError::Busy,
+ sys::EResult_k_EResultInvalidState => SteamError::InvalidState,
+ sys::EResult_k_EResultInvalidName => SteamError::InvalidName,
+ sys::EResult_k_EResultInvalidEmail => SteamError::InvalidEmail,
+ sys::EResult_k_EResultDuplicateName => SteamError::DuplicateName,
+ sys::EResult_k_EResultAccessDenied => SteamError::AccessDenied,
+ sys::EResult_k_EResultTimeout => SteamError::Timeout,
+ sys::EResult_k_EResultBanned => SteamError::Banned,
+ sys::EResult_k_EResultAccountNotFound => SteamError::AccountNotFound,
+ sys::EResult_k_EResultInvalidSteamID => SteamError::InvalidSteamID,
+ sys::EResult_k_EResultServiceUnavailable => SteamError::ServiceUnavailable,
+ sys::EResult_k_EResultNotLoggedOn => SteamError::NotLoggedOn,
+ sys::EResult_k_EResultPending => SteamError::Pending,
+ sys::EResult_k_EResultEncryptionFailure => SteamError::EncryptionFailure,
+ sys::EResult_k_EResultInsufficientPrivilege => SteamError::InsufficientPrivilege,
+ sys::EResult_k_EResultLimitExceeded => SteamError::LimitExceeded,
+ sys::EResult_k_EResultRevoked => SteamError::Revoked,
+ sys::EResult_k_EResultExpired => SteamError::Expired,
+ sys::EResult_k_EResultAlreadyRedeemed => SteamError::AlreadyRedeemed,
+ sys::EResult_k_EResultDuplicateRequest => SteamError::DuplicateRequest,
+ sys::EResult_k_EResultAlreadyOwned => SteamError::AlreadyOwned,
+ sys::EResult_k_EResultIPNotFound => SteamError::IPNotFound,
+ sys::EResult_k_EResultPersistFailed => SteamError::PersistFailed,
+ sys::EResult_k_EResultLockingFailed => SteamError::LockingFailed,
+ sys::EResult_k_EResultLogonSessionReplaced => SteamError::LogonSessionReplaced,
+ sys::EResult_k_EResultConnectFailed => SteamError::ConnectFailed,
+ sys::EResult_k_EResultHandshakeFailed => SteamError::HandshakeFailed,
+ sys::EResult_k_EResultIOFailure => SteamError::IOFailure,
+ sys::EResult_k_EResultRemoteDisconnect => SteamError::RemoteDisconnect,
+ sys::EResult_k_EResultShoppingCartNotFound => SteamError::ShoppingCartNotFound,
+ sys::EResult_k_EResultBlocked => SteamError::Blocked,
+ sys::EResult_k_EResultIgnored => SteamError::Ignored,
+ sys::EResult_k_EResultNoMatch => SteamError::NoMatch,
+ sys::EResult_k_EResultAccountDisabled => SteamError::AccountDisabled,
+ sys::EResult_k_EResultServiceReadOnly => SteamError::ServiceReadOnly,
+ sys::EResult_k_EResultAccountNotFeatured => SteamError::AccountNotFeatured,
+ sys::EResult_k_EResultAdministratorOK => SteamError::AdministratorOK,
+ sys::EResult_k_EResultContentVersion => SteamError::ContentVersion,
+ sys::EResult_k_EResultTryAnotherCM => SteamError::TryAnotherCM,
+ sys::EResult_k_EResultPasswordRequiredToKickSession => SteamError::PasswordRequiredToKickSession,
+ sys::EResult_k_EResultAlreadyLoggedInElsewhere => SteamError::AlreadyLoggedInElsewhere,
+ sys::EResult_k_EResultSuspended => SteamError::Suspended,
+ sys::EResult_k_EResultCancelled => SteamError::Cancelled,
+ sys::EResult_k_EResultDataCorruption => SteamError::DataCorruption,
+ sys::EResult_k_EResultDiskFull => SteamError::DiskFull,
+ sys::EResult_k_EResultRemoteCallFailed => SteamError::RemoteCallFailed,
+ sys::EResult_k_EResultPasswordUnset => SteamError::PasswordUnset,
+ sys::EResult_k_EResultExternalAccountUnlinked => SteamError::ExternalAccountUnlinked,
+ sys::EResult_k_EResultPSNTicketInvalid => SteamError::PSNTicketInvalid,
+ sys::EResult_k_EResultExternalAccountAlreadyLinked => SteamError::ExternalAccountAlreadyLinked,
+ sys::EResult_k_EResultRemoteFileConflict => SteamError::RemoteFileConflict,
+ sys::EResult_k_EResultIllegalPassword => SteamError::IllegalPassword,
+ sys::EResult_k_EResultSameAsPreviousValue => SteamError::SameAsPreviousValue,
+ sys::EResult_k_EResultAccountLogonDenied => SteamError::AccountLogonDenied,
+ sys::EResult_k_EResultCannotUseOldPassword => SteamError::CannotUseOldPassword,
+ sys::EResult_k_EResultInvalidLoginAuthCode => SteamError::InvalidLoginAuthCode,
+ sys::EResult_k_EResultAccountLogonDeniedNoMail => SteamError::AccountLogonDeniedNoMail,
+ sys::EResult_k_EResultHardwareNotCapableOfIPT => SteamError::HardwareNotCapableOfIPT,
+ sys::EResult_k_EResultIPTInitError => SteamError::IPTInitError,
+ sys::EResult_k_EResultParentalControlRestricted => SteamError::ParentalControlRestricted,
+ sys::EResult_k_EResultFacebookQueryError => SteamError::FacebookQueryError,
+ sys::EResult_k_EResultExpiredLoginAuthCode => SteamError::ExpiredLoginAuthCode,
+ sys::EResult_k_EResultIPLoginRestrictionFailed => SteamError::IPLoginRestrictionFailed,
+ sys::EResult_k_EResultAccountLockedDown => SteamError::AccountLockedDown,
+ sys::EResult_k_EResultAccountLogonDeniedVerifiedEmailRequired => SteamError::AccountLogonDeniedVerifiedEmailRequired,
+ sys::EResult_k_EResultNoMatchingURL => SteamError::NoMatchingURL,
+ sys::EResult_k_EResultBadResponse => SteamError::BadResponse,
+ sys::EResult_k_EResultRequirePasswordReEntry => SteamError::RequirePasswordReEntry,
+ sys::EResult_k_EResultValueOutOfRange => SteamError::ValueOutOfRange,
+ sys::EResult_k_EResultUnexpectedError => SteamError::UnexpectedError,
+ sys::EResult_k_EResultDisabled => SteamError::Disabled,
+ sys::EResult_k_EResultInvalidCEGSubmission => SteamError::InvalidCEGSubmission,
+ sys::EResult_k_EResultRestrictedDevice => SteamError::RestrictedDevice,
+ sys::EResult_k_EResultRegionLocked => SteamError::RegionLocked,
+ sys::EResult_k_EResultRateLimitExceeded => SteamError::RateLimitExceeded,
+ sys::EResult_k_EResultAccountLoginDeniedNeedTwoFactor => SteamError::AccountLoginDeniedNeedTwoFactor,
+ sys::EResult_k_EResultItemDeleted => SteamError::ItemDeleted,
+ sys::EResult_k_EResultAccountLoginDeniedThrottle => SteamError::AccountLoginDeniedThrottle,
+ sys::EResult_k_EResultTwoFactorCodeMismatch => SteamError::TwoFactorCodeMismatch,
+ sys::EResult_k_EResultTwoFactorActivationCodeMismatch => SteamError::TwoFactorActivationCodeMismatch,
+ sys::EResult_k_EResultAccountAssociatedToMultiplePartners => SteamError::AccountAssociatedToMultiplePartners,
+ sys::EResult_k_EResultNotModified => SteamError::NotModified,
+ sys::EResult_k_EResultNoMobileDevice => SteamError::NoMobileDevice,
+ sys::EResult_k_EResultTimeNotSynced => SteamError::TimeNotSynced,
+ sys::EResult_k_EResultSmsCodeFailed => SteamError::SmsCodeFailed,
+ sys::EResult_k_EResultAccountLimitExceeded => SteamError::AccountLimitExceeded,
+ sys::EResult_k_EResultAccountActivityLimitExceeded => SteamError::AccountActivityLimitExceeded,
+ sys::EResult_k_EResultPhoneActivityLimitExceeded => SteamError::PhoneActivityLimitExceeded,
+ sys::EResult_k_EResultRefundToWallet => SteamError::RefundToWallet,
+ sys::EResult_k_EResultEmailSendFailure => SteamError::EmailSendFailure,
+ sys::EResult_k_EResultNotSettled => SteamError::NotSettled,
+ sys::EResult_k_EResultNeedCaptcha => SteamError::NeedCaptcha,
+ sys::EResult_k_EResultGSLTDenied => SteamError::GSLTDenied,
+ sys::EResult_k_EResultGSOwnerDenied => SteamError::GSOwnerDenied,
+ sys::EResult_k_EResultInvalidItemType => SteamError::InvalidItemType,
+ sys::EResult_k_EResultIPBanned => SteamError::IPBanned,
+ sys::EResult_k_EResultGSLTExpired => SteamError::GSLTExpired,
+ sys::EResult_k_EResultInsufficientFunds => SteamError::InsufficientFunds,
+ sys::EResult_k_EResultTooManyPending => SteamError::TooManyPending,
+ sys::EResult_k_EResultNoSiteLicensesFound => SteamError::NoSiteLicensesFound,
+ sys::EResult_k_EResultWGNetworkSendExceeded => SteamError::WGNetworkSendExceeded,
+ sys::EResult_k_EResultAccountNotFriends => SteamError::AccountNotFriends,
+ sys::EResult_k_EResultLimitedUserAccount => SteamError::LimitedUserAccount,
+ _ => unreachable!(),
}
}
} \ No newline at end of file
diff --git a/src/friends.rs b/src/friends.rs
index 1d993ed..f0fe66e 100644
--- a/src/friends.rs
+++ b/src/friends.rs
@@ -1,6 +1,8 @@
use super::*;
+const CALLBACK_BASE_ID: i32 = 300;
+
bitflags! {
#[repr(C)]
pub struct FriendFlags: u16 {
@@ -98,14 +100,33 @@ pub struct PersonaStateChange {
}
unsafe impl Callback for PersonaStateChange {
- const ID: i32 = 304;
+ const ID: i32 = CALLBACK_BASE_ID + 4;
const SIZE: i32 = ::std::mem::size_of::<sys::PersonaStateChange_t>() as i32;
unsafe fn from_raw(raw: *mut libc::c_void) -> Self {
let val = &mut *(raw as *mut sys::PersonaStateChange_t);
PersonaStateChange {
- steam_id: SteamId(val.steam_id),
- flags: PersonaChange::from_bits_truncate(val.flags as i32),
+ steam_id: SteamId(val.get_m_ulSteamID()),
+ flags: PersonaChange::from_bits_truncate(val.get_m_nChangeFlags() as i32),
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct GameLobbyJoinRequested {
+ pub lobby_steam_id: LobbyId,
+ pub friend_steam_id: SteamId,
+}
+
+unsafe impl Callback for GameLobbyJoinRequested {
+ const ID: i32 = CALLBACK_BASE_ID + 33;
+ const SIZE: i32 = ::std::mem::size_of::<sys::GameLobbyJoinRequested_t>() as i32;
+
+ unsafe fn from_raw(raw: *mut libc::c_void) -> Self {
+ let val = &mut *(raw as *mut sys::GameLobbyJoinRequested_t);
+ GameLobbyJoinRequested {
+ lobby_steam_id: LobbyId(val.get_m_steamIDLobby()),
+ friend_steam_id: SteamId(val.get_m_steamIDFriend()),
}
}
}
@@ -139,14 +160,14 @@ impl <Manager> Friend<Manager> {
unsafe {
let state = sys::SteamAPI_ISteamFriends_GetFriendPersonaState(self.friends, self.id.0);
match state {
- sys::PersonaState::Offline => FriendState::Offline,
- sys::PersonaState::Online => FriendState::Online,
- sys::PersonaState::Busy => FriendState::Busy,
- sys::PersonaState::Away => FriendState::Away,
- sys::PersonaState::Snooze => FriendState::Snooze,
- sys::PersonaState::LookingToPlay => FriendState::LookingToPlay,
- sys::PersonaState::LookingToTrade => FriendState::LookingToTrade,
- sys::PersonaState::Max => unreachable!(),
+ sys::EPersonaState_k_EPersonaStateOffline => FriendState::Offline,
+ sys::EPersonaState_k_EPersonaStateOnline => FriendState::Online,
+ sys::EPersonaState_k_EPersonaStateBusy => FriendState::Busy,
+ sys::EPersonaState_k_EPersonaStateAway => FriendState::Away,
+ sys::EPersonaState_k_EPersonaStateSnooze => FriendState::Snooze,
+ sys::EPersonaState_k_EPersonaStateLookingToPlay => FriendState::LookingToPlay,
+ sys::EPersonaState_k_EPersonaStateLookingToTrade => FriendState::LookingToTrade,
+ _ => unreachable!(),
}
}
}
diff --git a/src/matchmaking.rs b/src/matchmaking.rs
index 9ed8f8f..177cb8e 100644
--- a/src/matchmaking.rs
+++ b/src/matchmaking.rs
@@ -9,6 +9,7 @@ pub struct Matchmaking<Manager> {
const CALLBACK_BASE_ID: i32 = 500;
+/// The visibility of a lobby
pub enum LobbyType {
Private,
FriendsOnly,
@@ -17,7 +18,7 @@ pub enum LobbyType {
}
#[derive(Debug)]
-pub struct LobbyId(u64);
+pub struct LobbyId(pub u64);
impl <Manager> Matchmaking<Manager> {
@@ -26,46 +27,84 @@ impl <Manager> Matchmaking<Manager> {
{
unsafe {
let api_call = sys::SteamAPI_ISteamMatchmaking_RequestLobbyList(self.mm);
- register_call_result::<sys::LobbyMatchList, _, _>(
+ register_call_result::<sys::LobbyMatchList_t, _, _>(
&self.inner, api_call, CALLBACK_BASE_ID + 10,
move |v, io_error| {
- cb(if io_error {
- Err(SteamError::IOFailure)
- } else {
- let mut out = Vec::with_capacity(v.lobbies_matching as usize);
- for idx in 0 .. v.lobbies_matching {
- out.push(LobbyId(sys::SteamAPI_ISteamMatchmaking_GetLobbyByIndex(sys::steam_rust_get_matchmaking(), idx as _)));
- }
- Ok(out)
- })
+ cb(if io_error {
+ Err(SteamError::IOFailure)
+ } else {
+ let mut out = Vec::with_capacity(v.get_m_nLobbiesMatching() as usize);
+ for idx in 0 .. v.get_m_nLobbiesMatching() {
+ out.push(LobbyId(sys::SteamAPI_ISteamMatchmaking_GetLobbyByIndex(sys::steam_rust_get_matchmaking(), idx as _)));
+ }
+ Ok(out)
+ })
});
}
}
+ /// Attempts to create a new matchmaking lobby
+ ///
+ /// The lobby with have the visibility of the of the passed
+ /// `LobbyType` and a limit of `max_members` inside it.
+ /// The `max_members` may not be higher than 250.
+ ///
+ /// # Triggers
+ ///
+ /// * `LobbyEnter`
+ /// * `LobbyCreated`
pub fn create_lobby<F>(&self, ty: LobbyType, max_members: u32, mut cb: F)
where F: FnMut(Result<LobbyId, SteamError>) + 'static + Send + Sync
{
+ assert!(max_members <= 250); // Steam API limits
unsafe {
let ty = match ty {
- LobbyType::Private => sys::LobbyType::Private,
- LobbyType::FriendsOnly => sys::LobbyType::FriendsOnly,
- LobbyType::Public => sys::LobbyType::Public,
- LobbyType::Invisible => sys::LobbyType::Invisible,
+ LobbyType::Private => sys::ELobbyType_k_ELobbyTypePrivate,
+ LobbyType::FriendsOnly => sys::ELobbyType_k_ELobbyTypeFriendsOnly,
+ LobbyType::Public => sys::ELobbyType_k_ELobbyTypePublic,
+ LobbyType::Invisible => sys::ELobbyType_k_ELobbyTypeInvisible,
};
let api_call = sys::SteamAPI_ISteamMatchmaking_CreateLobby(self.mm, ty, max_members as _);
- register_call_result::<sys::LobbyCreated, _, _>(
+ register_call_result::<sys::LobbyCreated_t, _, _>(
&self.inner, api_call, CALLBACK_BASE_ID + 13,
move |v, io_error| {
cb(if io_error {
Err(SteamError::IOFailure)
- } else if v.result != sys::SResult::Ok {
- Err(v.result.into())
+ } else if v.get_m_eResult() != sys::EResult_k_EResultOK {
+ Err(v.get_m_eResult().into())
+ } else {
+ Ok(LobbyId(v.get_m_ulSteamIDLobby()))
+ })
+ });
+ }
+ }
+
+ /// Tries to join the lobby with the given ID
+ pub fn join_lobby<F>(&self, lobby: LobbyId, mut cb: F)
+ where F: FnMut(Result<LobbyId, ()>) + 'static + Send + Sync
+ {
+ unsafe {
+ let api_call = sys::SteamAPI_ISteamMatchmaking_JoinLobby(self.mm, lobby.0);
+ register_call_result::<sys::LobbyEnter_t, _, _>(
+ &self.inner, api_call, CALLBACK_BASE_ID + 4,
+ move |v, io_error| {
+ cb(if io_error {
+ Err(())
+ } else if v.get_m_EChatRoomEnterResponse() != 1 {
+ Err(())
} else {
- Ok(LobbyId(v.lobby_steam_id))
+ Ok(LobbyId(v.get_m_ulSteamIDLobby()))
})
});
}
}
+
+ /// Exits the passed lobby
+ pub fn leave_lobby(&self, lobby: LobbyId) {
+ unsafe {
+ sys::SteamAPI_ISteamMatchmaking_LeaveLobby(self.mm, lobby.0);
+ }
+ }
}
#[test]
diff --git a/src/server.rs b/src/server.rs
index ee37cac..fc1f6e8 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -62,9 +62,9 @@ impl Server {
let version = CString::new(version).unwrap();
let raw_ip: u32 = ip.into();
let server_mode = match server_mode {
- ServerMode::NoAuthentication => sys::ServerMode::NoAuthentication,
- ServerMode::Authentication => sys::ServerMode::Authentication,
- ServerMode::AuthenticationAndSecure => sys::ServerMode::AuthenticationAndSecure,
+ ServerMode::NoAuthentication => sys::EServerMode_eServerModeNoAuthentication,
+ ServerMode::Authentication => sys::EServerMode_eServerModeAuthentication,
+ ServerMode::AuthenticationAndSecure => sys::EServerMode_eServerModeAuthenticationAndSecure,
};
if sys::steam_rust_game_server_init(
raw_ip, steam_port,
@@ -170,12 +170,13 @@ impl Server {
user.0
);
Err(match res {
- sys::BeginAuthSessionResult::Ok => return Ok(()),
- sys::BeginAuthSessionResult::InvalidTicket => AuthSessionError::InvalidTicket,
- sys::BeginAuthSessionResult::DuplicateRequest => AuthSessionError::DuplicateRequest,
- sys::BeginAuthSessionResult::InvalidVersion => AuthSessionError::InvalidVersion,
- sys::BeginAuthSessionResult::GameMismatch => AuthSessionError::GameMismatch,
- sys::BeginAuthSessionResult::ExpiredTicket => AuthSessionError::ExpiredTicket,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultOK => return Ok(()),
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultInvalidTicket => AuthSessionError::InvalidTicket,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultDuplicateRequest => AuthSessionError::DuplicateRequest,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultInvalidVersion => AuthSessionError::InvalidVersion,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultGameMismatch => AuthSessionError::GameMismatch,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultExpiredTicket => AuthSessionError::ExpiredTicket,
+ _ => unreachable!(),
})
}
}
diff --git a/src/user.rs b/src/user.rs
index ec2c768..b21ac5f 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -63,12 +63,13 @@ impl <Manager> User<Manager> {
user.0
);
Err(match res {
- sys::BeginAuthSessionResult::Ok => return Ok(()),
- sys::BeginAuthSessionResult::InvalidTicket => AuthSessionError::InvalidTicket,
- sys::BeginAuthSessionResult::DuplicateRequest => AuthSessionError::DuplicateRequest,
- sys::BeginAuthSessionResult::InvalidVersion => AuthSessionError::InvalidVersion,
- sys::BeginAuthSessionResult::GameMismatch => AuthSessionError::GameMismatch,
- sys::BeginAuthSessionResult::ExpiredTicket => AuthSessionError::ExpiredTicket,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultOK => return Ok(()),
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultInvalidTicket => AuthSessionError::InvalidTicket,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultDuplicateRequest => AuthSessionError::DuplicateRequest,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultInvalidVersion => AuthSessionError::InvalidVersion,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultGameMismatch => AuthSessionError::GameMismatch,
+ sys::EBeginAuthSessionResult_k_EBeginAuthSessionResultExpiredTicket => AuthSessionError::ExpiredTicket,
+ _ => unreachable!(),
})
}
}
@@ -154,15 +155,15 @@ pub struct AuthSessionTicketResponse {
unsafe impl Callback for AuthSessionTicketResponse {
const ID: i32 = 163;
const SIZE: i32 = ::std::mem::size_of::<sys::GetAuthSessionTicketResponse_t>() as i32;
-
+
unsafe fn from_raw(raw: *mut libc::c_void) -> Self {
let val = &mut *(raw as *mut sys::GetAuthSessionTicketResponse_t);
AuthSessionTicketResponse {
- ticket: AuthTicket(val.auth_ticket),
- result: if val.result == sys::SResult::Ok {
+ ticket: AuthTicket(val.get_m_hAuthTicket()),
+ result: if val.get_m_eResult() == sys::EResult_k_EResultOK {
Ok(())
} else {
- Err(val.result.into())
+ Err(val.get_m_eResult().into())
}
}
}
@@ -185,23 +186,24 @@ pub struct ValidateAuthTicketResponse {
unsafe impl Callback for ValidateAuthTicketResponse {
const ID: i32 = 143;
const SIZE: i32 = ::std::mem::size_of::<sys::ValidateAuthTicketResponse_t>() as i32;
-
+
unsafe fn from_raw(raw: *mut libc::c_void) -> Self {
let val = &mut *(raw as *mut sys::ValidateAuthTicketResponse_t);
ValidateAuthTicketResponse {
- steam_id: SteamId(val.steam_id),
- owner_steam_id: SteamId(val.owner_steam_id),
- response: match val.response {
- sys::AuthSessionResponse::Ok => Ok(()),
- sys::AuthSessionResponse::UserNotConnectedToSteam => Err(AuthSessionValidateError::UserNotConnectedToSteam),
- sys::AuthSessionResponse::NoLicenseOrExpired => Err(AuthSessionValidateError::NoLicenseOrExpired),
- sys::AuthSessionResponse::VACBanned => Err(AuthSessionValidateError::VACBanned),
- sys::AuthSessionResponse::LoggedInElseWhere => Err(AuthSessionValidateError::LoggedInElseWhere),
- sys::AuthSessionResponse::VACCheckTimedOut => Err(AuthSessionValidateError::VACCheckTimedOut),
- sys::AuthSessionResponse::AuthTicketCancelled => Err(AuthSessionValidateError::AuthTicketCancelled),
- sys::AuthSessionResponse::AuthTicketInvalidAlreadyUsed => Err(AuthSessionValidateError::AuthTicketInvalidAlreadyUsed),
- sys::AuthSessionResponse::AuthTicketInvalid => Err(AuthSessionValidateError::AuthTicketInvalid),
- sys::AuthSessionResponse::PublisherIssuedBan => Err(AuthSessionValidateError::PublisherIssuedBan),
+ steam_id: SteamId(val.get_m_SteamID()),
+ owner_steam_id: SteamId(val.get_m_OwnerSteamID()),
+ response: match val.get_m_eAuthSessionResponse() {
+ sys::EAuthSessionResponse_k_EAuthSessionResponseOK => Ok(()),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseUserNotConnectedToSteam => Err(AuthSessionValidateError::UserNotConnectedToSteam),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseNoLicenseOrExpired => Err(AuthSessionValidateError::NoLicenseOrExpired),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseVACBanned => Err(AuthSessionValidateError::VACBanned),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseLoggedInElseWhere => Err(AuthSessionValidateError::LoggedInElseWhere),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseVACCheckTimedOut => Err(AuthSessionValidateError::VACCheckTimedOut),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseAuthTicketCanceled => Err(AuthSessionValidateError::AuthTicketCancelled),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseAuthTicketInvalidAlreadyUsed => Err(AuthSessionValidateError::AuthTicketInvalidAlreadyUsed),
+ sys::EAuthSessionResponse_k_EAuthSessionResponseAuthTicketInvalid => Err(AuthSessionValidateError::AuthTicketInvalid),
+ sys::EAuthSessionResponse_k_EAuthSessionResponsePublisherIssuedBan => Err(AuthSessionValidateError::PublisherIssuedBan),
+ _ => unreachable!(),
}
}
}
diff --git a/src/utils.rs b/src/utils.rs
index 5c5ae10..43e167b 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -39,10 +39,10 @@ impl <Manager> Utils<Manager> {
pub fn set_overlay_notification_position(&self, position: NotificationPosition) {
unsafe {
let position = match position {
- NotificationPosition::TopLeft => sys::NotificationPosition::TopLeft,
- NotificationPosition::TopRight => sys::NotificationPosition::TopRight,
- NotificationPosition::BottomLeft => sys::NotificationPosition::BottomLeft,
- NotificationPosition::BottomRight => sys::NotificationPosition::BottomRight,
+ NotificationPosition::TopLeft => sys::ENotificationPosition_k_EPositionTopLeft,
+ NotificationPosition::TopRight => sys::ENotificationPosition_k_EPositionTopRight,
+ NotificationPosition::BottomLeft => sys::ENotificationPosition_k_EPositionBottomLeft,
+ NotificationPosition::BottomRight => sys::ENotificationPosition_k_EPositionBottomRight,
};
sys::SteamAPI_ISteamUtils_SetOverlayNotificationPosition(self.utils, position);
}
diff --git a/steamworks-sys/Cargo.toml b/steamworks-sys/Cargo.toml
index 96edbe7..9b4960e 100644
--- a/steamworks-sys/Cargo.toml
+++ b/steamworks-sys/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "steamworks-sys"
-version = "0.2.3"
+version = "0.3.0"
authors = ["Thinkofname"]
build = "build.rs"
description = "Provides raw bindings to the steamworks sdk"
@@ -8,6 +8,9 @@ license = "MIT / Apache-2.0"
repository = "https://github.com/Thinkofname/steamworks-rs"
documentation = "https://docs.rs/steamworks-sys"
+[package.metadata.docs.rs]
+features = [ "docs-only" ]
+
[features]
default = []
@@ -20,6 +23,8 @@ libc = "0.2.36"
[build-dependencies]
cc = "1.0.4"
+bindgen = "0.36.0"
+serde = "1.0.37"
+serde_derive = "1.0.37"
+serde_json = "1.0.14"
-[package.metadata.docs.rs]
-features = [ "docs-only" ] \ No newline at end of file
diff --git a/steamworks-sys/build.rs b/steamworks-sys/build.rs
index 8dbf861..2aa6c42 100644
--- a/steamworks-sys/build.rs
+++ b/steamworks-sys/build.rs
@@ -1,6 +1,32 @@
-
+extern crate bindgen;
extern crate cc;
+extern crate serde_json;
+#[macro_use]
+extern crate serde_derive;
+
+#[derive(Deserialize)]
+struct SteamApi {
+ structs: Vec<SteamStruct>,
+ enums: Vec<SteamEnum>,
+}
+
+#[derive(Deserialize)]
+struct SteamEnum {
+ enumname: String,
+}
+
+#[derive(Deserialize)]
+struct SteamStruct {
+ #[serde(rename = "struct")]
+ struct_: String,
+ fields: Vec<SteamField>,
+}
+#[derive(Deserialize)]
+struct SteamField {
+ fieldname: String,
+ fieldtype: String,
+}
#[cfg(feature = "docs-only")]
fn main() {}
@@ -8,8 +34,12 @@ fn main() {}
#[cfg(not(feature = "docs-only"))]
fn main() {
use std::env;
- use std::path::Path;
+ use std::path::{Path, PathBuf};
+ use std::io::Write;
+ use std::fmt::Write as FWrite;
+ use std::fs::File;
+ let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let sdk_loc = env::var("STEAM_SDK_LOCATION")
.expect("STEAM_SDK_LOCATION must be set");
let sdk_loc = Path::new(&sdk_loc);
@@ -37,9 +67,184 @@ fn main() {
println!("cargo:rustc-link-search={}", path.display());
println!("cargo:rustc-link-lib=dylib={}", lib);
+ let mut builder = bindgen::builder()
+ .header("wrapper.hpp")
+ .clang_arg(format!("-I{}", sdk_loc.join("public/steam").display()))
+ .ctypes_prefix("libc")
+ .rustfmt_bindings(false);
+
+ // Steamworks uses packed structs making them hard to work
+ // with normally
+ let steam_api: SteamApi = serde_json::from_reader(File::open(sdk_loc.join("public/steam/steam_api.json")).unwrap())
+ .unwrap();
+
+ let mut cpp_wrapper = String::from(r#"
+#include <steam_api.h>
+#include <steam_gameserver.h>
+#include <stdint.h>
+extern "C" {
+ "#);
+
+ fn field_type_fix(fty: &str) -> (&str, String){
+ let fty = {
+ if fty.contains("enum") {
+ fty.trim_left_matches("enum ")
+ } else if fty.contains("struct") {
+ fty.trim_left_matches("struct ")
+ } else if fty == "_Bool" {
+ "bool"
+ } else {
+ fty
+ }
+ };
+ let fty_rust = if fty == "const char*" || fty == "*const char" || fty == "const char *" {
+ "*const libc::c_char".to_owned()
+ } else if fty == "char*" {
+ "*mut libc::c_char".to_owned()
+ } else if fty == "const char **" {
+ "*mut *const libc::c_char".to_owned()
+ }else if fty.ends_with("*") {
+ if fty.starts_with("const") {
+ let trimmed = fty.trim_left_matches("const ").trim_right_matches("*");
+ format!("*const {}", trimmed)
+ } else {
+ let trimmed = fty.trim_right_matches("*");
+ format!("*mut {}", trimmed)
+ }
+ } else if fty.contains("[") {
+ panic!("Unsupported field type array")
+ } else if fty == "class CSteamID" {
+ "u64".to_owned()
+ } else if fty == "class CGameID" {
+ "u64".to_owned()
+ } else if fty == "int" {
+ "libc::c_int".to_owned()
+ } else if fty == "float" {
+ "libc::c_float".to_owned()
+ } else if fty == "double" {
+ "libc::c_double".to_owned()
+ } else {
+ fty.to_owned()
+ };
+ (fty, fty_rust)
+ }
+
+ for SteamStruct{struct_: ref ty, ref fields} in &steam_api.structs {
+ if ty.contains("::") || !ty.ends_with("_t") || fields.iter().any(|v| v.fieldtype.contains('['))
+ || ty.chars().next().map_or(true, |v| v.is_lowercase())
+ || ty.starts_with("GSStats")
+ {
+ continue;
+ }
+ builder = builder.whitelist_type(ty);
+
+ // Make a raw constructor
+ writeln!(cpp_wrapper, r#"{ty} __rust_helper_raw__{ty}() {{
+ {ty} created_type = {{}};
+ return created_type;
+ }}"#, ty = ty).unwrap();
+ builder = builder.raw_line(format!(r#"
+ extern "C" {{
+ fn __rust_helper_raw__{ty}() -> {ty};
+ }}
+ pub unsafe fn create_empty_{ty}() -> {ty} {{
+ __rust_helper_raw__{ty}()
+ }}
+ "#, ty = ty));
+
+ // Make a typed constructor
+ let mut typed_constr_extern = String::new();
+ let mut typed_constr_wrap = String::new();
+ write!(cpp_wrapper, r#"{ty} __rust_helper_typed__{ty}("#, ty = ty).unwrap();
+ write!(typed_constr_extern, r#"extern "C" {{
+ fn __rust_helper_typed__{ty}("#, ty = ty).unwrap();
+ write!(typed_constr_wrap, r#"pub unsafe fn create_{ty}("#, ty = ty).unwrap();
+ for (idx, SteamField{fieldname: ref fname, fieldtype: ref fty}) in fields.iter().enumerate() {
+ let (fty, fty_rust) = field_type_fix(fty);
+ write!(cpp_wrapper, "{} {}", fty, fname).unwrap();
+ write!(typed_constr_extern, "{}: {},", fname, fty_rust).unwrap();
+ write!(typed_constr_wrap, "{}: {},", fname, fty_rust).unwrap();
+ if idx != fields.len() - 1 {
+ cpp_wrapper.push(',');
+ }
+ }
+
+ write!(cpp_wrapper, r#") {{
+ {ty} created_type = {{}};
+ "#, ty = ty).unwrap();
+ write!(typed_constr_extern, r#") -> {ty};
+ }}"#, ty = ty).unwrap();
+ write!(typed_constr_wrap, r#") -> {ty} {{
+ __rust_helper_typed__{ty}("#, ty = ty).unwrap();
+ for SteamField{fieldname: ref fname, ..} in fields.iter() {
+ write!(cpp_wrapper, "created_type.{fname} = {fname};", fname = fname).unwrap();
+ write!(typed_constr_wrap, "{},", fname).unwrap();
+ }
+ writeln!(cpp_wrapper, r#"
+ return created_type;
+ }}"#).unwrap();
+ writeln!(typed_constr_wrap, r#")
+ }}"#).unwrap();
+
+ builder = builder.raw_line(typed_constr_extern);
+ builder = builder.raw_line(typed_constr_wrap);
+
+
+ for SteamField{fieldname: ref fname, fieldtype: ref fty} in fields.iter() {
+ let (fty, fty_rust) = field_type_fix(fty);
+ builder = builder.whitelist_type(fty);
+ // Generate getters/setters for fields
+
+ writeln!(cpp_wrapper, r#"
+ {fty} __rust_helper_getter__{ty}_{fname}(const {ty}* from) {{
+ return from->{fname};
+ }}
+ void __rust_helper_setter__{ty}_{fname}({ty}* to, {fty} val) {{
+ to->{fname} = val;
+ }}
+ "#, ty = ty, fty = fty, fname = fname).unwrap();
+
+ builder = builder.raw_line(format!(r#"
+ extern "C" {{
+ fn __rust_helper_getter__{ty}_{fname}(from: *const {ty}) -> {fty_rust};
+ fn __rust_helper_setter__{ty}_{fname}(from: *mut {ty}, val: {fty_rust});
+ }}
+ impl {ty} {{
+ pub unsafe fn get_{fname}(&self) -> {fty_rust} {{
+ __rust_helper_getter__{ty}_{fname}(self)
+ }}
+ pub unsafe fn set_{fname}(&mut self, val: {fty_rust}) {{
+ __rust_helper_setter__{ty}_{fname}(self, val)
+ }}
+ }}
+ "#, ty = ty, fty_rust = fty_rust, fname = fname))
+ }
+ }
+ for e in steam_api.enums {
+ builder = builder.whitelist_type(e.enumname);
+ }
+ builder = builder.whitelist_type("EServerMode");
+
+ cpp_wrapper.push_str("}");
+
+ File::create(out_path.join("steam_gen.cpp"))
+ .unwrap()
+ .write_all(cpp_wrapper.as_bytes())
+ .unwrap();
+
+ // panic!("{}", out_path.join("steam_gen.cpp").display());
cc::Build::new()
.cpp(true)
.include(sdk_loc.join("public/steam"))
.file("src/lib.cpp")
+ .file(out_path.join("steam_gen.cpp"))
.compile("steamrust");
+
+ let bindings = builder
+ .generate()
+ .unwrap();
+ // panic!("{}", bindings.to_string());
+ bindings
+ .write_to_file(out_path.join("bindings.rs"))
+ .expect("Couldn't write bindings!");
} \ No newline at end of file
diff --git a/steamworks-sys/src/lib.cpp b/steamworks-sys/src/lib.cpp
index 226c31a..38701da 100644
--- a/steamworks-sys/src/lib.cpp
+++ b/steamworks-sys/src/lib.cpp
@@ -6,7 +6,7 @@ struct CallbackData {
int param_size;
void* userdata;
void (*run)(void*, void*, void*);
- void (*run_extra)(void*, void*, void*, bool, SteamAPICall_t);
+ void (*run_extra)(void*, void*, void*, uint8_t, SteamAPICall_t);
void (*dealloc)(void*, void*);
};
@@ -26,7 +26,7 @@ public:
}
void Run(void* pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall) {
- data.run_extra(this, data.userdata, pvParam, bIOFailure, hSteamAPICall);
+ data.run_extra(this, data.userdata, pvParam, bIOFailure ? 1 : 0, hSteamAPICall);
}
int GetCallbackSizeBytes() {
diff --git a/steamworks-sys/src/lib.rs b/steamworks-sys/src/lib.rs
index 5fbb565..7d6ebae 100644
--- a/steamworks-sys/src/lib.rs
+++ b/steamworks-sys/src/lib.rs
@@ -1,7 +1,11 @@
#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
extern crate libc;
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
use libc::{
c_char,
c_void,
@@ -24,222 +28,15 @@ pub struct ISteamUser(c_void);
pub struct ISteamGameServer(c_void);
pub type HSteamPipe = i32;
-pub type HSteamUser = i32;
-pub type HAuthTicket = u32;
pub type AppId = u32;
pub type SteamAPICall = u64;
#[repr(C)]
-pub enum PersonaState {
- Offline = 0,
- Online = 1,
- Busy = 2,
- Away = 3,
- Snooze = 4,
- LookingToTrade = 5,
- LookingToPlay = 6,
- Max,
-}
-
-#[repr(C)]
-pub enum LobbyType {
- Private = 0,
- FriendsOnly = 1,
- Public = 2,
- Invisible = 3,
-}
-
-#[repr(C)]
-pub struct PersonaStateChange_t {
- pub steam_id: u64,
- pub flags: c_int,
-}
-
-#[repr(C)]
-pub struct GetAuthSessionTicketResponse_t {
- pub auth_ticket: HAuthTicket,
- pub result: SResult,
-}
-
-#[repr(C)]
-pub struct ValidateAuthTicketResponse_t {
- pub steam_id: u64,
- pub response: AuthSessionResponse,
- pub owner_steam_id: u64,
-}
-
-#[repr(C)]
-pub struct LobbyCreated {
- pub result: SResult,
- pub lobby_steam_id: u64,
-}
-#[repr(C)]
-pub struct LobbyMatchList {
- pub lobbies_matching: u32,
-}
-
-#[repr(C)]
-pub enum NotificationPosition {
- TopLeft = 0,
- TopRight = 1,
- BottomLeft = 2,
- BottomRight = 3,
-}
-
-#[repr(C)]
-pub enum BeginAuthSessionResult {
- Ok = 0,
- InvalidTicket = 1,
- DuplicateRequest = 2,
- InvalidVersion = 3,
- GameMismatch = 4,
- ExpiredTicket = 5,
-}
-
-#[repr(C)]
-pub enum AuthSessionResponse {
- Ok = 0,
- UserNotConnectedToSteam = 1,
- NoLicenseOrExpired = 2,
- VACBanned = 3,
- LoggedInElseWhere = 4,
- VACCheckTimedOut = 5,
- AuthTicketCancelled = 6,
- AuthTicketInvalidAlreadyUsed = 7,
- AuthTicketInvalid = 8,
- PublisherIssuedBan = 9,
-}
-
-#[repr(C)]
-pub enum ServerMode {
- Invalid = 0,
- NoAuthentication = 1,
- Authentication = 2,
- AuthenticationAndSecure = 3,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug, Ord, PartialOrd, Eq, PartialEq)]
-pub enum SResult {
- Ok = 1,
- Fail = 2,
- NoConnection = 3,
- InvalidPassword = 5,
- LoggedInElsewhere = 6,
- InvalidProtocolVer = 7,
- InvalidParam = 8,
- FileNotFound = 9,
- Busy = 10,
- InvalidState = 11,
- InvalidName = 12,
- InvalidEmail = 13,
- DuplicateName = 14,
- AccessDenied = 15,
- Timeout = 16,
- Banned = 17,
- AccountNotFound = 18,
- InvalidSteamID = 19,
- ServiceUnavailable = 20,
- NotLoggedOn = 21,
- Pending = 22,
- EncryptionFailure = 23,
- InsufficientPrivilege = 24,
- LimitExceeded = 25,
- Revoked = 26,
- Expired = 27,
- AlreadyRedeemed = 28,
- DuplicateRequest = 29,
- AlreadyOwned = 30,
- IPNotFound = 31,
- PersistFailed = 32,
- LockingFailed = 33,
- LogonSessionReplaced = 34,
- ConnectFailed = 35,
- HandshakeFailed = 36,
- IOFailure = 37,
- RemoteDisconnect = 38,
- ShoppingCartNotFound = 39,
- Blocked = 40,
- Ignored = 41,
- NoMatch = 42,
- AccountDisabled = 43,
- ServiceReadOnly = 44,
- AccountNotFeatured = 45,
- AdministratorOK = 46,
- ContentVersion = 47,
- TryAnotherCM = 48,
- PasswordRequiredToKickSession = 49,
- AlreadyLoggedInElsewhere = 50,
- Suspended = 51,
- Cancelled = 52,
- DataCorruption = 53,
- DiskFull = 54,
- RemoteCallFailed = 55,
- PasswordUnset = 56,
- ExternalAccountUnlinked = 57,
- PSNTicketInvalid = 58,
- ExternalAccountAlreadyLinked = 59,
- RemoteFileConflict = 60,
- IllegalPassword = 61,
- SameAsPreviousValue = 62,
- AccountLogonDenied = 63,
- CannotUseOldPassword = 64,
- InvalidLoginAuthCode = 65,
- AccountLogonDeniedNoMail = 66,
- HardwareNotCapableOfIPT = 67,
- IPTInitError = 68,
- ParentalControlRestricted = 69,
- FacebookQueryError = 70,
- ExpiredLoginAuthCode = 71,
- IPLoginRestrictionFailed = 72,
- AccountLockedDown = 73,
- AccountLogonDeniedVerifiedEmailRequired = 74,
- NoMatchingURL = 75,
- BadResponse = 76,
- RequirePasswordReEntry = 77,
- ValueOutOfRange = 78,
- UnexpectedError = 79,
- Disabled = 80,
- InvalidCEGSubmission = 81,
- RestrictedDevice = 82,
- RegionLocked = 83,
- RateLimitExceeded = 84,
- AccountLoginDeniedNeedTwoFactor = 85,
- ItemDeleted = 86,
- AccountLoginDeniedThrottle = 87,
- TwoFactorCodeMismatch = 88,
- TwoFactorActivationCodeMismatch = 89,
- AccountAssociatedToMultiplePartners = 90,
- NotModified = 91,
- NoMobileDevice = 92,
- TimeNotSynced = 93,
- SmsCodeFailed = 94,
- AccountLimitExceeded = 95,
- AccountActivityLimitExceeded = 96,
- PhoneActivityLimitExceeded = 97,
- RefundToWallet = 98,
- EmailSendFailure = 99,
- NotSettled = 100,
- NeedCaptcha = 101,
- GSLTDenied = 102,
- GSOwnerDenied = 103,
- InvalidItemType = 104,
- IPBanned = 105,
- GSLTExpired = 106,
- InsufficientFunds = 107,
- TooManyPending = 108,
- NoSiteLicensesFound = 109,
- WGNetworkSendExceeded = 110,
- AccountNotFriends = 111,
- LimitedUserAccount = 112,
-}
-
-#[repr(C)]
pub struct CallbackData {
pub param_size: c_int,
pub userdata: *mut c_void,
pub run: unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void),
- pub run_extra: unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void, bool, SteamAPICall),
+ pub run_extra: unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void, u8, SteamAPICall),
pub dealloc: unsafe extern "C" fn(*mut c_void, *mut c_void),
}
@@ -257,7 +54,7 @@ extern "C" {
pub fn steam_rust_get_server() -> *mut ISteamGameServer;
pub fn steam_rust_get_server_apps() -> *mut ISteamApps;
- pub fn steam_rust_game_server_init(ip: u32, steam_port: u16, game_port: u16, query_port: u16, server_mode: ServerMode, version: *const c_char) -> c_int;
+ 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;
//
@@ -280,11 +77,11 @@ 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_SetOverlayNotificationPosition(instance: *mut ISteamUtils, position: NotificationPosition);
+ pub fn SteamAPI_ISteamUtils_SetOverlayNotificationPosition(instance: *mut ISteamUtils, position: ENotificationPosition);
pub fn SteamAPI_ISteamApps_BIsAppInstalled(instance: *mut ISteamApps, app_id: AppId) -> u8;
pub fn SteamAPI_ISteamApps_BIsDlcInstalled(instance: *mut ISteamApps, app_id: AppId) -> u8;
- pub fn SteamAPI_ISteamApps_BIsSubscribedApp(instace: *mut ISteamApps, app_id: AppId) -> u8;
+ pub fn SteamAPI_ISteamApps_BIsSubscribedApp(instance: *mut ISteamApps, app_id: AppId) -> u8;
pub fn SteamAPI_ISteamApps_BIsSubscribedFromFreeWeekend(instance: *mut ISteamApps) -> u8;
pub fn SteamAPI_ISteamApps_BIsVACBanned(instance: *mut ISteamApps) -> u8;
pub fn SteamAPI_ISteamApps_BIsCybercafe(instance: *mut ISteamApps) -> u8;
@@ -300,18 +97,20 @@ extern "C" {
pub fn SteamAPI_ISteamFriends_GetFriendCount(instance: *mut ISteamFriends, flags: c_int) -> c_int;
pub fn SteamAPI_ISteamFriends_GetFriendByIndex(instance: *mut ISteamFriends, friend: c_int, flags: c_int) -> u64;
pub fn SteamAPI_ISteamFriends_GetFriendPersonaName(instance: *mut ISteamFriends, friend: u64) -> *const c_char;
- pub fn SteamAPI_ISteamFriends_GetFriendPersonaState(instance: *mut ISteamFriends, friend: u64) -> PersonaState;
+ pub fn SteamAPI_ISteamFriends_GetFriendPersonaState(instance: *mut ISteamFriends, friend: u64) -> EPersonaState;
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_ISteamMatchmaking_CreateLobby(instance: *mut ISteamMatchmaking, lobby_ty: LobbyType, max_members: c_int) -> SteamAPICall;
+ 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_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;
- pub fn SteamAPI_ISteamUser_BeginAuthSession(instance: *mut ISteamUser, ticket: *const c_void, ticket_size: *mut u32, steam_id: u64) -> BeginAuthSessionResult;
+ pub fn SteamAPI_ISteamUser_BeginAuthSession(instance: *mut ISteamUser, ticket: *const c_void, ticket_size: *mut u32, steam_id: u64) -> EBeginAuthSessionResult;
pub fn SteamAPI_ISteamUser_EndAuthSession(instance: *mut ISteamUser, steam_id: u64);
pub fn SteamAPI_ISteamUser_CancelAuthTicket(instance: *mut ISteamUser, auth_ticket: HAuthTicket);
@@ -321,7 +120,7 @@ extern "C" {
pub fn SteamAPI_ISteamGameServer_SetDedicatedServer(instance: *mut ISteamGameServer, dedicated: u8);
pub fn SteamAPI_ISteamGameServer_GetSteamID(instance: *mut ISteamGameServer) -> u64;
pub fn SteamAPI_ISteamGameServer_GetAuthSessionTicket(instance: *mut ISteamGameServer, ticket: *mut c_void, max_ticket: c_int, ticket_size: *mut u32) -> HAuthTicket;
- pub fn SteamAPI_ISteamGameServer_BeginAuthSession(instance: *mut ISteamGameServer, ticket: *const c_void, ticket_size: *mut u32, steam_id: u64) -> BeginAuthSessionResult;
+ pub fn SteamAPI_ISteamGameServer_BeginAuthSession(instance: *mut ISteamGameServer, ticket: *const c_void, ticket_size: *mut u32, steam_id: u64) -> EBeginAuthSessionResult;
pub fn SteamAPI_ISteamGameServer_EndAuthSession(instance: *mut ISteamGameServer, steam_id: u64);
pub fn SteamAPI_ISteamGameServer_CancelAuthTicket(instance: *mut ISteamGameServer, auth_ticket: HAuthTicket);
}
diff --git a/steamworks-sys/wrapper.hpp b/steamworks-sys/wrapper.hpp
new file mode 100644
index 0000000..27c4619
--- /dev/null
+++ b/steamworks-sys/wrapper.hpp
@@ -0,0 +1,3 @@
+#include <steam_api.h>
+#include <steam_gameserver.h>
+#include <stdint.h> \ No newline at end of file