Skip to content

Commit

Permalink
move filters from function to macro & other little changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ymo-4 committed Jul 25, 2024
1 parent 7848fab commit b099e51
Showing 1 changed file with 86 additions and 106 deletions.
192 changes: 86 additions & 106 deletions src/matchmaking_servers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ macro_rules! matchmaking_servers_callback {
) => {
paste::item! {
$(
#[allow(unused_variables)]
extern fn [<$name:lower _ $fn_name _virtual>]($self: *mut [<$name CallbacksReal>] $(, $fn_arg_name: $cpp_fn_arg)*) {
unsafe {
$(
Expand Down Expand Up @@ -110,31 +111,60 @@ macro_rules! gen_server_list_fn {
filters: &HashMap<&str, &str>,
callbacks: ServerListCallbacks,
) -> Option<Arc<Mutex<ServerListRequest>>> {
unsafe {
let app_id = app_id.into().0;
let app_id = app_id.into().0;
let mut filters = {
let mut vec = Vec::with_capacity(filters.len());
for i in filters {
let key_bytes = i.0.as_bytes();
let value_bytes = i.1.as_bytes();

// Max length is 255, so 256th byte will always be nul-terminator
if key_bytes.len() >= 256 || value_bytes.len() >= 256 {
return None;
}

let mut key = [0i8; 256];
let mut value = [0i8; 256];

unsafe {
key.as_mut_ptr()
.copy_from(key_bytes.as_ptr().cast(), key_bytes.len());
value
.as_mut_ptr()
.copy_from(value_bytes.as_ptr().cast(), value_bytes.len());
}

let mut filters = create_filters(filters)?;
vec.push(steamworks_sys::MatchMakingKeyValuePair_t {
m_szKey: key,
m_szValue: value,
});
}
vec.shrink_to_fit();

vec
};

unsafe {
let callbacks = create_serverlist(callbacks);

let arc = Arc::clone(&(*(*callbacks).rust_callbacks).req);
let mut req = arc.lock().unwrap();
let request_arc = ServerListRequest::get(callbacks);
let mut request = request_arc.lock().unwrap();

let handle = steamworks_sys::$sys_method(
self.mms,
app_id,
&mut filters.0,
filters.1.try_into().unwrap(),
&mut filters.as_mut_ptr() as *mut *mut _,
filters.len().try_into().unwrap(),
callbacks.cast(),
);

req.mms = self.mms;
req.real = callbacks;
req.filters = filters;
req.h_req = handle;
request.mms = self.mms;
request.real = callbacks;
request.h_req = handle;

drop(req);
drop(request);

Some(arc)
Some(request_arc)
}
}
};
Expand Down Expand Up @@ -164,45 +194,43 @@ pub struct GameServerItem {
}

impl GameServerItem {
fn from_ptr(raw: *const steamworks_sys::gameserveritem_t) -> Self {
unsafe {
let raw = *raw;
Self {
appid: raw.m_nAppID,
players: raw.m_nPlayers,
bot_players: raw.m_nBotPlayers,
ping: raw.m_nPing,
max_players: raw.m_nMaxPlayers,
server_version: raw.m_nServerVersion,
steamid: raw.m_steamID.m_steamid.m_unAll64Bits,

do_not_refresh: raw.m_bDoNotRefresh,
successful_response: raw.m_bHadSuccessfulResponse,
have_password: raw.m_bPassword,
secure: raw.m_bSecure,

addr: Ipv4Addr::from(raw.m_NetAdr.m_unIP),
query_port: raw.m_NetAdr.m_usQueryPort,
connection_port: raw.m_NetAdr.m_usConnectionPort,

game_description: CStr::from_ptr(raw.m_szGameDescription.as_ptr())
.to_string_lossy()
.into_owned(),
server_name: CStr::from_ptr(raw.m_szServerName.as_ptr())
.to_string_lossy()
.into_owned(),
game_dir: CStr::from_ptr(raw.m_szGameDir.as_ptr())
.to_string_lossy()
.into_owned(),
map: CStr::from_ptr(raw.m_szMap.as_ptr())
.to_string_lossy()
.into_owned(),
tags: CStr::from_ptr(raw.m_szGameTags.as_ptr())
.to_string_lossy()
.into_owned(),

last_time_played: Duration::from_secs(raw.m_ulTimeLastPlayed.into()),
}
unsafe fn from_ptr(raw: *const steamworks_sys::gameserveritem_t) -> Self {
let raw = *raw;
Self {
appid: raw.m_nAppID,
players: raw.m_nPlayers,
bot_players: raw.m_nBotPlayers,
ping: raw.m_nPing,
max_players: raw.m_nMaxPlayers,
server_version: raw.m_nServerVersion,
steamid: raw.m_steamID.m_steamid.m_unAll64Bits,

do_not_refresh: raw.m_bDoNotRefresh,
successful_response: raw.m_bHadSuccessfulResponse,
have_password: raw.m_bPassword,
secure: raw.m_bSecure,

addr: Ipv4Addr::from(raw.m_NetAdr.m_unIP),
query_port: raw.m_NetAdr.m_usQueryPort,
connection_port: raw.m_NetAdr.m_usConnectionPort,

game_description: CStr::from_ptr(raw.m_szGameDescription.as_ptr())
.to_string_lossy()
.into_owned(),
server_name: CStr::from_ptr(raw.m_szServerName.as_ptr())
.to_string_lossy()
.into_owned(),
game_dir: CStr::from_ptr(raw.m_szGameDir.as_ptr())
.to_string_lossy()
.into_owned(),
map: CStr::from_ptr(raw.m_szMap.as_ptr())
.to_string_lossy()
.into_owned(),
tags: CStr::from_ptr(raw.m_szGameTags.as_ptr())
.to_string_lossy()
.into_owned(),

last_time_played: Duration::from_secs(raw.m_ulTimeLastPlayed.into()),
}
}
}
Expand Down Expand Up @@ -250,20 +278,19 @@ matchmaking_servers_callback!(
released: false,
mms: ptr::null_mut(),
real: ptr::null_mut(),
filters: (std::ptr::null_mut(), 0),
}))
}
);
responded({}): (
request: steamworks_sys::HServerListRequest => Arc<Mutex<ServerListRequest>> where { ServerListRequest::get(_self, request) },
request: steamworks_sys::HServerListRequest => Arc<Mutex<ServerListRequest>> where { ServerListRequest::get(_self) },
server: i32 => i32 where {server}
),
failed({}): (
request: steamworks_sys::HServerListRequest => Arc<Mutex<ServerListRequest>> where { ServerListRequest::get(_self, request) },
request: steamworks_sys::HServerListRequest => Arc<Mutex<ServerListRequest>> where { ServerListRequest::get(_self) },
server: i32 => i32 where {server}
),
refresh_complete({}): (
request: steamworks_sys::HServerListRequest => Arc<Mutex<ServerListRequest>> where { ServerListRequest::get(_self, request) },
request: steamworks_sys::HServerListRequest => Arc<Mutex<ServerListRequest>> where { ServerListRequest::get(_self) },
response: ServerResponse => ServerResponse where {response}
)
);
Expand All @@ -281,14 +308,10 @@ pub struct ServerListRequest {
pub(self) released: bool,
pub(self) mms: *mut sys::ISteamMatchmakingServers,
pub(self) real: *mut ServerListCallbacksReal,
pub(self) filters: (*mut steamworks_sys::MatchMakingKeyValuePair_t, usize),
}

impl ServerListRequest {
pub(self) unsafe fn get(
_self: *mut ServerListCallbacksReal,
_request: steamworks_sys::HServerListRequest,
) -> Arc<Mutex<Self>> {
pub(self) unsafe fn get(_self: *mut ServerListCallbacksReal) -> Arc<Mutex<Self>> {
let rust_callbacks = &*(*_self).rust_callbacks;
Arc::clone(&rust_callbacks.req)
}
Expand All @@ -311,10 +334,6 @@ impl ServerListRequest {
self.released = true;
steamworks_sys::SteamAPI_ISteamMatchmakingServers_ReleaseRequest(self.mms, self.h_req);

if !self.filters.0.is_null() {
free_filters(self.filters.0, self.filters.1);
}

free_serverlist(self.real);
}
}
Expand Down Expand Up @@ -402,44 +421,6 @@ impl ServerListRequest {
}
}

unsafe fn create_filters(
map: &HashMap<&str, &str>,
) -> Option<(*mut steamworks_sys::MatchMakingKeyValuePair_t, usize)> {
let mut vec = Vec::with_capacity(map.len());
for i in map {
let key_bytes = i.0.as_bytes();
let value_bytes = i.1.as_bytes();

// Max length is 255, so 256th byte will always be nul-terminator
if key_bytes.len() >= 256 || value_bytes.len() >= 256 {
return None;
}

let mut key = [0i8; 256];
let mut value = [0i8; 256];

key.as_mut_ptr()
.copy_from(key_bytes.as_ptr().cast(), key_bytes.len());
value
.as_mut_ptr()
.copy_from(value_bytes.as_ptr().cast(), value_bytes.len());

vec.push(steamworks_sys::MatchMakingKeyValuePair_t {
m_szKey: key,
m_szValue: value,
});
}
vec.shrink_to_fit();
let filters = (vec.as_mut_ptr(), vec.len());
std::mem::forget(vec);

Some(filters)
}

unsafe fn free_filters(ptr: *mut steamworks_sys::MatchMakingKeyValuePair_t, count: usize) {
drop(Vec::from_raw_parts(ptr, count, count))
}

/// Access to the steam MatchmakingServers interface
pub struct MatchmakingServers<Manager> {
pub(crate) mms: *mut sys::ISteamMatchmakingServers,
Expand Down Expand Up @@ -519,8 +500,6 @@ impl<Manager> MatchmakingServers<Manager> {

req.mms = self.mms;
req.real = callbacks;
// No filters here, leaving defaults. Then check its in ServerListRequest::release
// req.filters = filters;
req.h_req = handle;

drop(req);
Expand Down Expand Up @@ -573,7 +552,8 @@ fn test_internet_servers() {
map.insert("map", "PEI");
let _ = client
.matchmaking_servers()
.internet_server_list(304930, &map, callbacks);
.internet_server_list(304930, &map, callbacks)
.unwrap();

for _ in 0..2000 {
single.run_callbacks();
Expand Down

0 comments on commit b099e51

Please sign in to comment.