mirror of
https://github.com/tribufu/rust-gamedig
synced 2026-06-01 09:42:41 +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.
|
[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.
|
[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
|
# 0.0.4 - 23/10/2022
|
||||||
Queries now support DNS resolve.
|
Queries now support DNS resolve.
|
||||||
|
|
|
||||||
2
GAMES.md
2
GAMES.md
|
|
@ -5,7 +5,7 @@
|
||||||
| TF2 | Team Fortress 2 | Valve Protocol | |
|
| TF2 | Team Fortress 2 | Valve Protocol | |
|
||||||
| TS | The Ship | 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. |
|
| 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 | |
|
| DODS | Day of Defeat: Source | Valve Protocol | |
|
||||||
| L4D | Left 4 Dead | Valve Protocol | |
|
| L4D | Left 4 Dead | Valve Protocol | |
|
||||||
| L4D2 | Left 4 Dead 2 | Valve Protocol | |
|
| L4D2 | Left 4 Dead 2 | Valve Protocol | |
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ struct SplitPacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 mut pos = 0;
|
||||||
|
|
||||||
let header = buffer::get_u32_le(&buf, &mut pos)?;
|
let header = buffer::get_u32_le(&buf, &mut pos)?;
|
||||||
|
|
@ -87,7 +87,10 @@ impl SplitPacket {
|
||||||
App::Source(_) => {
|
App::Source(_) => {
|
||||||
let total = buffer::get_u8(&buf, &mut pos)?;
|
let total = buffer::get_u8(&buf, &mut pos)?;
|
||||||
let number = 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 compressed = ((id >> 31) & 1) == 1;
|
||||||
let (decompressed_size, uncompressed_crc32) = match compressed {
|
let (decompressed_size, uncompressed_crc32) = match compressed {
|
||||||
false => (None, None),
|
false => (None, None),
|
||||||
|
|
@ -166,15 +169,15 @@ impl ValveProtocol {
|
||||||
Ok(buf[..amt].to_vec())
|
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)?;
|
let mut buf = self.receive_raw(buffer_size)?;
|
||||||
|
|
||||||
if buf[0] == 0xFE { //the packet is split
|
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 {
|
for _ in 1..main_packet.total {
|
||||||
buf = self.receive_raw(buffer_size)?;
|
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);
|
main_packet.payload.extend(chunk_packet.payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,11 +189,11 @@ impl ValveProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ask for a specific request only.
|
/// 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();
|
let request_initial_packet = Packet::initial(kind.clone()).to_bytes();
|
||||||
|
|
||||||
self.send(&request_initial_packet)?;
|
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'
|
if packet.kind != 0x41 { //'A'
|
||||||
return Ok(packet.payload.clone());
|
return Ok(packet.payload.clone());
|
||||||
|
|
@ -200,7 +203,7 @@ impl ValveProtocol {
|
||||||
let challenge_packet = Packet::challenge(kind.clone(), challenge).to_bytes();
|
let challenge_packet = Packet::challenge(kind.clone(), challenge).to_bytes();
|
||||||
|
|
||||||
self.send(&challenge_packet)?;
|
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> {
|
fn get_goldsrc_server_info(buf: &[u8]) -> GDResult<ServerInfo> {
|
||||||
|
|
@ -266,7 +269,7 @@ impl ValveProtocol {
|
||||||
|
|
||||||
/// Get the server information's.
|
/// Get the server information's.
|
||||||
fn get_server_info(&self, app: &App) -> GDResult<ServerInfo> {
|
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 let App::GoldSrc(force) = app {
|
||||||
if *force {
|
if *force {
|
||||||
return ValveProtocol::get_goldsrc_server_info(&buf);
|
return ValveProtocol::get_goldsrc_server_info(&buf);
|
||||||
|
|
@ -365,8 +368,8 @@ impl ValveProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the server player's.
|
/// Get the server player's.
|
||||||
fn get_server_players(&self, app: &App) -> GDResult<Vec<ServerPlayer>> {
|
fn get_server_players(&self, app: &App, protocol: u8) -> GDResult<Vec<ServerPlayer>> {
|
||||||
let buf = self.get_request_data(&app, Request::PLAYERS)?;
|
let buf = self.get_request_data(&app, protocol, Request::PLAYERS)?;
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
|
|
||||||
let count = buffer::get_u8(&buf, &mut pos)?;
|
let count = buffer::get_u8(&buf, &mut pos)?;
|
||||||
|
|
@ -393,12 +396,12 @@ impl ValveProtocol {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the server rules's.
|
/// 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
|
if *app == SteamID::CSGO.app() { //cause csgo wont respond to this since feb 21 2014 update
|
||||||
return Ok(None);
|
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 mut pos = 0;
|
||||||
|
|
||||||
let count = buffer::get_u16_le(&buf, &mut pos)?;
|
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 client = ValveProtocol::new(address, port)?;
|
||||||
|
|
||||||
let info = client.get_server_info(&app)?;
|
let info = client.get_server_info(&app)?;
|
||||||
|
let protocol = info.protocol;
|
||||||
|
|
||||||
if let App::Source(x) = &app {
|
if let App::Source(x) = &app {
|
||||||
if let Some(appid) = x {
|
if let Some(appid) = x {
|
||||||
|
|
@ -442,11 +446,11 @@ pub fn query(address: &str, port: u16, app: App, gather_settings: Option<Gatheri
|
||||||
info,
|
info,
|
||||||
players: match gather_players {
|
players: match gather_players {
|
||||||
false => None,
|
false => None,
|
||||||
true => Some(client.get_server_players(&app)?)
|
true => Some(client.get_server_players(&app, protocol)?)
|
||||||
},
|
},
|
||||||
rules: match gather_rules {
|
rules: match gather_rules {
|
||||||
false => None,
|
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