mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-05-06 15:27:28 +00:00
Fixed multipacket response when protocol = 7 with certain apps
This commit is contained in:
parent
d3a1dba3c1
commit
ac9d385fb6
3 changed files with 22 additions and 17 deletions
|
|
@ -10,7 +10,8 @@ It is now an enum of:
|
|||
|
||||
[Counter-Strike: Condition Zero](https://store.steampowered.com/app/80/CounterStrike_Condition_Zero/) implementation.
|
||||
[Day of Defeat](https://store.steampowered.com/app/30/Day_of_Defeat/) implementation.
|
||||
Games besides CSGO and TS now have the same response structure.
|
||||
Games besides CSGO and TS now have the same response structure.
|
||||
Fixed Source multipacket response crash due to when a certain app with a certain protocol doesnt have the Size field.
|
||||
|
||||
# 0.0.4 - 23/10/2022
|
||||
Queries now support DNS resolve.
|
||||
|
|
|
|||
2
GAMES.md
2
GAMES.md
|
|
@ -5,7 +5,7 @@
|
|||
| TF2 | Team Fortress 2 | Valve Protocol | |
|
||||
| TS | The Ship | Valve Protocol | |
|
||||
| CSGO | Counter-Strike: Global Offensive | Valve Protocol | The server wouldn't respond the to Rules query since the 21 Feb 2014 update. |
|
||||
| CSS | Counter-Strike: Source | Valve Protocol | If protocol is 7, queries with multi-packet responses will crash. |
|
||||
| CSS | Counter-Strike: Source | Valve Protocol | |
|
||||
| DODS | Day of Defeat: Source | Valve Protocol | |
|
||||
| L4D | Left 4 Dead | Valve Protocol | |
|
||||
| L4D2 | Left 4 Dead 2 | Valve Protocol | |
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ struct SplitPacket {
|
|||
}
|
||||
|
||||
impl SplitPacket {
|
||||
fn new(app: &App, buf: &[u8]) -> GDResult<Self> {
|
||||
fn new(app: &App, protocol: u8, buf: &[u8]) -> GDResult<Self> {
|
||||
let mut pos = 0;
|
||||
|
||||
let header = buffer::get_u32_le(&buf, &mut pos)?;
|
||||
|
|
@ -87,7 +87,10 @@ impl SplitPacket {
|
|||
App::Source(_) => {
|
||||
let total = buffer::get_u8(&buf, &mut pos)?;
|
||||
let number = buffer::get_u8(&buf, &mut pos)?;
|
||||
let size = buffer::get_u16_le(&buf, &mut pos)?; //if game is CSS and if protocol is 7, queries with multi-packet responses will crash
|
||||
let size = match protocol == 7 && (*app == SteamID::CSS.app()) { //certain apps with protocol = 7 doesnt have this field
|
||||
false => buffer::get_u16_le(&buf, &mut pos)?,
|
||||
true => 1248
|
||||
};
|
||||
let compressed = ((id >> 31) & 1) == 1;
|
||||
let (decompressed_size, uncompressed_crc32) = match compressed {
|
||||
false => (None, None),
|
||||
|
|
@ -166,15 +169,15 @@ impl ValveProtocol {
|
|||
Ok(buf[..amt].to_vec())
|
||||
}
|
||||
|
||||
fn receive(&self, app: &App, buffer_size: usize) -> GDResult<Packet> {
|
||||
fn receive(&self, app: &App, protocol: u8, buffer_size: usize) -> GDResult<Packet> {
|
||||
let mut buf = self.receive_raw(buffer_size)?;
|
||||
|
||||
if buf[0] == 0xFE { //the packet is split
|
||||
let mut main_packet = SplitPacket::new(&app, &buf)?;
|
||||
let mut main_packet = SplitPacket::new(&app, protocol, &buf)?;
|
||||
|
||||
for _ in 1..main_packet.total {
|
||||
buf = self.receive_raw(buffer_size)?;
|
||||
let chunk_packet = SplitPacket::new(&app, &buf)?;
|
||||
let chunk_packet = SplitPacket::new(&app, protocol, &buf)?;
|
||||
main_packet.payload.extend(chunk_packet.payload);
|
||||
}
|
||||
|
||||
|
|
@ -186,11 +189,11 @@ impl ValveProtocol {
|
|||
}
|
||||
|
||||
/// Ask for a specific request only.
|
||||
fn get_request_data(&self, app: &App, kind: Request) -> GDResult<Vec<u8>> {
|
||||
fn get_request_data(&self, app: &App, protocol: u8, kind: Request) -> GDResult<Vec<u8>> {
|
||||
let request_initial_packet = Packet::initial(kind.clone()).to_bytes();
|
||||
|
||||
self.send(&request_initial_packet)?;
|
||||
let packet = self.receive(app, DEFAULT_PACKET_SIZE)?;
|
||||
let packet = self.receive(app, protocol, DEFAULT_PACKET_SIZE)?;
|
||||
|
||||
if packet.kind != 0x41 { //'A'
|
||||
return Ok(packet.payload.clone());
|
||||
|
|
@ -200,7 +203,7 @@ impl ValveProtocol {
|
|||
let challenge_packet = Packet::challenge(kind.clone(), challenge).to_bytes();
|
||||
|
||||
self.send(&challenge_packet)?;
|
||||
Ok(self.receive(app, DEFAULT_PACKET_SIZE)?.payload)
|
||||
Ok(self.receive(app, protocol, DEFAULT_PACKET_SIZE)?.payload)
|
||||
}
|
||||
|
||||
fn get_goldsrc_server_info(buf: &[u8]) -> GDResult<ServerInfo> {
|
||||
|
|
@ -266,7 +269,7 @@ impl ValveProtocol {
|
|||
|
||||
/// Get the server information's.
|
||||
fn get_server_info(&self, app: &App) -> GDResult<ServerInfo> {
|
||||
let buf = self.get_request_data(&app, Request::INFO)?;
|
||||
let buf = self.get_request_data(&app, 0, Request::INFO)?;
|
||||
if let App::GoldSrc(force) = app {
|
||||
if *force {
|
||||
return ValveProtocol::get_goldsrc_server_info(&buf);
|
||||
|
|
@ -365,8 +368,8 @@ impl ValveProtocol {
|
|||
}
|
||||
|
||||
/// Get the server player's.
|
||||
fn get_server_players(&self, app: &App) -> GDResult<Vec<ServerPlayer>> {
|
||||
let buf = self.get_request_data(&app, Request::PLAYERS)?;
|
||||
fn get_server_players(&self, app: &App, protocol: u8) -> GDResult<Vec<ServerPlayer>> {
|
||||
let buf = self.get_request_data(&app, protocol, Request::PLAYERS)?;
|
||||
let mut pos = 0;
|
||||
|
||||
let count = buffer::get_u8(&buf, &mut pos)?;
|
||||
|
|
@ -393,12 +396,12 @@ impl ValveProtocol {
|
|||
}
|
||||
|
||||
/// Get the server rules's.
|
||||
fn get_server_rules(&self, app: &App) -> GDResult<Option<Vec<ServerRule>>> {
|
||||
fn get_server_rules(&self, app: &App, protocol: u8) -> GDResult<Option<Vec<ServerRule>>> {
|
||||
if *app == SteamID::CSGO.app() { //cause csgo wont respond to this since feb 21 2014 update
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let buf = self.get_request_data(&app, Request::RULES)?;
|
||||
let buf = self.get_request_data(&app, protocol, Request::RULES)?;
|
||||
let mut pos = 0;
|
||||
|
||||
let count = buffer::get_u16_le(&buf, &mut pos)?;
|
||||
|
|
@ -421,6 +424,7 @@ pub fn query(address: &str, port: u16, app: App, gather_settings: Option<Gatheri
|
|||
let client = ValveProtocol::new(address, port)?;
|
||||
|
||||
let info = client.get_server_info(&app)?;
|
||||
let protocol = info.protocol;
|
||||
|
||||
if let App::Source(x) = &app {
|
||||
if let Some(appid) = x {
|
||||
|
|
@ -442,11 +446,11 @@ pub fn query(address: &str, port: u16, app: App, gather_settings: Option<Gatheri
|
|||
info,
|
||||
players: match gather_players {
|
||||
false => None,
|
||||
true => Some(client.get_server_players(&app)?)
|
||||
true => Some(client.get_server_players(&app, protocol)?)
|
||||
},
|
||||
rules: match gather_rules {
|
||||
false => None,
|
||||
true => client.get_server_rules(&app)?
|
||||
true => client.get_server_rules(&app, protocol)?
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue