4.0.2 Fix counter strike 1.5

This commit is contained in:
Michael Morrison 2022-02-19 06:23:21 -06:00
parent 343e23c4ad
commit 07c7eca262
5 changed files with 69 additions and 48 deletions

View file

@ -1,3 +1,6 @@
### 4.0.2
* Counter-Strike 1.5 - Fixed support
### 4.0.1
* Rust - Fixed maxplayers >255
* dayZ - Fixed tag info not parsing when queryRules wasn't set

View file

@ -62,7 +62,7 @@ conanexiles|Conan Exiles (2018)|valve|port=7777,port_query=27015
contagion|Contagion (2011)|valve|port=27015
contactjack|Contract J.A.C.K. (2003)|gamespy1|port_query=27888
cs15|Counter-Strike 1.5 (2002)|valve|port=27015
cs15|Counter-Strike 1.5 (2002)|goldsrc|port=27015
cs16|Counter-Strike 1.6 (2003)|valve|port=27015
cs2d|Counter-Strike: 2D (2004)|cs2d|port=36963
cscz|Counter-Strike: Condition Zero (2004)|valve|port=27015

View file

@ -24,7 +24,7 @@
],
"main": "lib/index.js",
"author": "GameDig Contributors",
"version": "4.0.1",
"version": "4.0.2",
"repository": {
"type": "git",
"url": "https://github.com/gamedig/node-gamedig.git"

10
protocols/goldsrc.js Normal file
View file

@ -0,0 +1,10 @@
const Valve = require('./valve');
class GoldSrc extends Valve {
constructor() {
super();
this.goldsrcInfo = true;
}
}
module.exports = GoldSrc;

View file

@ -47,8 +47,8 @@ class Valve extends Core {
async queryInfo(/** Results */ state) {
this.debugLog("Requesting info ...");
const b = await this.sendPacket(
0x54,
'Source Engine Query\0',
this.goldsrcInfo ? undefined : 0x54,
this.goldsrcInfo ? 'details' : 'Source Engine Query\0',
this.goldsrcInfo ? 0x6D : 0x49,
false
);
@ -62,19 +62,15 @@ class Valve extends Core {
state.map = reader.string();
state.raw.folder = reader.string();
state.raw.game = reader.string();
state.raw.appId = reader.uint(2);
if(!this.goldsrcInfo) state.raw.appId = reader.uint(2);
state.raw.numplayers = reader.uint(1);
state.maxplayers = reader.uint(1);
if(this.goldsrcInfo) state.raw.protocol = reader.uint(1);
else state.raw.numbots = reader.uint(1);
state.raw.listentype = reader.uint(1);
state.raw.environment = reader.uint(1);
if(!this.goldsrcInfo) {
state.raw.listentype = String.fromCharCode(state.raw.listentype);
state.raw.environment = String.fromCharCode(state.raw.environment);
}
state.raw.listentype = String.fromCharCode(reader.uint(1));
state.raw.environment = String.fromCharCode(reader.uint(1));
state.password = !!reader.uint(1);
if(this.goldsrcInfo) {
@ -88,12 +84,8 @@ class Valve extends Core {
state.raw.modtype = reader.uint(1);
state.raw.moddll = reader.uint(1);
}
}
state.raw.secure = reader.uint(1);
if(this.goldsrcInfo) {
state.raw.numbots = reader.uint(1);
} else {
state.raw.secure = reader.uint(1);
if(state.raw.appId === AppId.Ship) {
state.raw.shipmode = reader.uint(1);
state.raw.shipwitnesses = reader.uint(1);
@ -206,8 +198,8 @@ class Valve extends Core {
this.debugLog("Requesting player list ...");
const b = await this.sendPacket(
0x55,
null,
this.goldsrcInfo ? undefined : 0x55,
this.goldsrcInfo ? 'players' : null,
0x44,
true
);
@ -254,36 +246,49 @@ class Valve extends Core {
const rules = {};
state.raw.rules = rules;
this.debugLog("Requesting rules ...");
const b = await this.sendPacket(0x56,null,0x45,true);
if (b === null) return; // timed out - the server probably has rules disabled
const dayZPayload = [];
let dayZPayloadEnded = false;
const reader = this.reader(b);
const num = reader.uint(2);
for(let i = 0; i < num; i++) {
if (appId === AppId.DayZ && !dayZPayloadEnded) {
const one = reader.uint(1);
const two = reader.uint(1);
const three = reader.uint(1);
if (one !== 0 && two !== 0 && three === 0) {
while (true) {
const byte = reader.uint(1);
if (byte === 0) break;
dayZPayload.push(byte);
}
continue;
} else {
reader.skip(-3);
dayZPayloadEnded = true;
}
this.debugLog("Requesting rules ...");
if (this.goldsrcInfo) {
const b = await this.udpSend('\xff\xff\xff\xffrules', b=>b, ()=>null);
if (b === null) return; // timed out - the server probably has rules disabled
const reader = this.reader(b);
while (!reader.done()) {
const key = reader.string();
const value = reader.string();
rules[key] = value;
}
} else {
const b = await this.sendPacket(0x56,null,0x45,true);
if (b === null) return; // timed out - the server probably has rules disabled
const key = reader.string();
const value = reader.string();
rules[key] = value;
let dayZPayloadEnded = false;
const reader = this.reader(b);
const num = reader.uint(2);
for (let i = 0; i < num; i++) {
if (appId === AppId.DayZ && !dayZPayloadEnded) {
const one = reader.uint(1);
const two = reader.uint(1);
const three = reader.uint(1);
if (one !== 0 && two !== 0 && three === 0) {
while (true) {
const byte = reader.uint(1);
if (byte === 0) break;
dayZPayload.push(byte);
}
continue;
} else {
reader.skip(-3);
dayZPayloadEnded = true;
}
}
const key = reader.string();
const value = reader.string();
rules[key] = value;
}
}
// Battalion 1944 puts its info into rules fields for some reason
@ -413,7 +418,7 @@ class Valve extends Core {
return botProbability(a) - botProbability(b);
});
delete state.raw.players;
const numBots = state.raw.numbots;
const numBots = state.raw.numbots || 0;
const numPlayers = state.raw.numplayers - numBots;
while(state.bots.length < numBots) {
if (sortedPlayers.length) state.bots.push(sortedPlayers.pop());
@ -492,7 +497,8 @@ class Valve extends Core {
if (typeof payload === 'string') payload = Buffer.from(payload, 'binary');
const b = Buffer.alloc(5
const b = Buffer.alloc(4
+ (type !== undefined ? 1 : 0)
+ (challengeAtBeginning ? 4 : 0)
+ (challengeAtEnd ? 4 : 0)
+ (payload ? payload.length : 0)
@ -505,8 +511,10 @@ class Valve extends Core {
b.writeInt32LE(-1, offset);
offset += 4;
b.writeUInt8(type, offset);
offset += 1;
if (type !== undefined) {
b.writeUInt8(type, offset);
offset += 1;
}
if (challengeAtBeginning) {
if (this.byteorder === 'le') b.writeUInt32LE(challenge, offset);