diff options
| author | Matthew Collins <[email protected]> | 2018-05-05 15:46:12 +0100 |
|---|---|---|
| committer | Matthew Collins <[email protected]> | 2018-05-05 15:46:12 +0100 |
| commit | 5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d (patch) | |
| tree | e667ed1dccc3d3ac0df83e8c66b76dd5dc0771e8 /src | |
| parent | Minor bump due to slight mistake with last publish (diff) | |
| download | steamworks-rs-5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d.tar.xz 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/callback.rs | 55 | ||||
| -rw-r--r-- | src/error.rs | 228 | ||||
| -rw-r--r-- | src/friends.rs | 43 | ||||
| -rw-r--r-- | src/matchmaking.rs | 77 | ||||
| -rw-r--r-- | src/server.rs | 19 | ||||
| -rw-r--r-- | src/user.rs | 50 | ||||
| -rw-r--r-- | src/utils.rs | 8 |
7 files changed, 291 insertions, 189 deletions
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); } |