[Games] Add timeout settings for proprietary games (#67)

Adding query functions with timeout settings to proprietary games allows
the generic query with timeout function to pass the timeout settings
through.

This does change how the pre-existing FFOW query_with_timeout function
worked: it accepted a non-optional timeout settings, this was changed to
optional to be consistent with other query_with_timeout functions and to
move deciding what to do if the user doesn't provide timeout settings to
a more central location.

Closes #64
This commit is contained in:
Tom 2023-07-10 13:17:49 +00:00 committed by GitHub
parent f3a792e325
commit e207e8dc95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 15 deletions

View file

@ -57,18 +57,16 @@ impl CommonResponse for Response {
fn players_online(&self) -> u64 { self.players_online.into() } fn players_online(&self) -> u64 { self.players_online.into() }
} }
pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { query_with_timeout(address, port, None) }
query_with_timeout(address, port, TimeoutSettings::default())
}
pub fn query_with_timeout( pub fn query_with_timeout(
address: &IpAddr, address: &IpAddr,
port: Option<u16>, port: Option<u16>,
timeout_settings: TimeoutSettings, timeout_settings: Option<TimeoutSettings>,
) -> GDResult<Response> { ) -> GDResult<Response> {
let mut client = ValveProtocol::new( let mut client = ValveProtocol::new(
&SocketAddr::new(*address, port.unwrap_or(5478)), &SocketAddr::new(*address, port.unwrap_or(5478)),
Some(timeout_settings), timeout_settings,
)?; )?;
let mut buffer = client.get_request_data( let mut buffer = client.get_request_data(
&Engine::GoldSrc(true), &Engine::GoldSrc(true),

View file

@ -1,7 +1,7 @@
use crate::bufferer::{Bufferer, Endianess}; use crate::bufferer::{Bufferer, Endianess};
use crate::protocols::gamespy::common::has_password; use crate::protocols::gamespy::common::has_password;
use crate::protocols::gamespy::three::{data_to_map, GameSpy3}; use crate::protocols::gamespy::three::{data_to_map, GameSpy3};
use crate::protocols::types::{CommonPlayer, CommonResponse, GenericPlayer}; use crate::protocols::types::{CommonPlayer, CommonResponse, GenericPlayer, TimeoutSettings};
use crate::protocols::GenericResponse; use crate::protocols::GenericResponse;
use crate::{GDError, GDResult}; use crate::{GDError, GDResult};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@ -75,10 +75,16 @@ fn parse_players_and_teams(packet: Vec<u8>) -> GDResult<Vec<Player>> {
Ok(players) Ok(players)
} }
pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { query_with_timeout(address, port, None) }
pub fn query_with_timeout(
address: &IpAddr,
port: Option<u16>,
timeout_settings: Option<TimeoutSettings>,
) -> GDResult<Response> {
let mut client = GameSpy3::new_custom( let mut client = GameSpy3::new_custom(
&SocketAddr::new(*address, port.unwrap_or(7777)), &SocketAddr::new(*address, port.unwrap_or(7777)),
None, timeout_settings,
[0xFF, 0xFF, 0xFF, 0x02], [0xFF, 0xFF, 0xFF, 0x02],
true, true,
)?; )?;

View file

@ -186,12 +186,15 @@ pub fn query_with_timeout(
QuakeVersion::Three => protocols::quake::three::query(&socket_addr, timeout_settings).map(Box::new)?, QuakeVersion::Three => protocols::quake::three::query(&socket_addr, timeout_settings).map(Box::new)?,
} }
} }
// TODO: No way to query proprietary games with timeout
Protocol::PROPRIETARY(protocol) => { Protocol::PROPRIETARY(protocol) => {
match protocol { match protocol {
ProprietaryProtocol::TheShip => ts::query(address, port).map(Box::new)?, ProprietaryProtocol::TheShip => {
ProprietaryProtocol::FFOW => ffow::query(address, port).map(Box::new)?, ts::query_with_timeout(address, port, timeout_settings).map(Box::new)?
ProprietaryProtocol::JC2MP => jc2mp::query(address, port).map(Box::new)?, }
ProprietaryProtocol::FFOW => ffow::query_with_timeout(address, port, timeout_settings).map(Box::new)?,
ProprietaryProtocol::JC2MP => {
jc2mp::query_with_timeout(address, port, timeout_settings).map(Box::new)?
}
} }
} }
}) })

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
protocols::{ protocols::{
types::{CommonPlayer, CommonResponse, GenericPlayer}, types::{CommonPlayer, CommonResponse, GenericPlayer, TimeoutSettings},
valve::{self, get_optional_extracted_data, Server, ServerPlayer, SteamApp}, valve::{self, get_optional_extracted_data, Server, ServerPlayer, SteamApp},
GenericResponse, GenericResponse,
}, },
@ -126,12 +126,18 @@ impl Response {
} }
} }
pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { pub fn query(address: &IpAddr, port: Option<u16>) -> GDResult<Response> { query_with_timeout(address, port, None) }
pub fn query_with_timeout(
address: &IpAddr,
port: Option<u16>,
timeout_settings: Option<TimeoutSettings>,
) -> GDResult<Response> {
let valve_response = valve::query( let valve_response = valve::query(
&SocketAddr::new(*address, port.unwrap_or(27015)), &SocketAddr::new(*address, port.unwrap_or(27015)),
SteamApp::TS.as_engine(), SteamApp::TS.as_engine(),
None, None,
None, timeout_settings,
)?; )?;
Ok(Response::new_from_valve_response(valve_response)) Ok(Response::new_from_valve_response(valve_response))