Clean up reader.string

This commit is contained in:
mmorrison 2019-02-04 19:58:28 -06:00
parent 6189d2fa62
commit fc5975bf0c
12 changed files with 58 additions and 61 deletions

View file

@ -21,7 +21,9 @@ class Reader {
* @param {Buffer} buffer * @param {Buffer} buffer
**/ **/
constructor(query,buffer) { constructor(query,buffer) {
this.query = query; this.defaultEncoding = query.options.encoding || query.encoding;
this.defaultDelimiter = query.delimiter;
this.defaultByteOrder = query.byteorder;
this.buffer = buffer; this.buffer = buffer;
this.i = 0; this.i = 0;
} }
@ -34,56 +36,64 @@ class Reader {
this.i += i; this.i += i;
} }
string(...args) { pascalString(bytesForSize, adjustment=0) {
let options = {}; const length = this.uint(bytesForSize) + adjustment;
if(args.length === 0) { return this.string(length);
options = {}; }
} else if(args.length === 1) {
if(typeof args[0] === 'string') options = { delimiter: args[0] }; string(arg) {
else if(typeof args[0] === 'number') options = { length: args[0] }; let encoding = this.defaultEncoding;
else options = args[0]; let length = null;
let delimiter = this.defaultDelimiter;
if(typeof arg === 'string') delimiter = arg;
else if(typeof arg === 'number') length = arg;
else if(typeof arg === 'object') {
if ('encoding' in arg) encoding = arg.encoding;
if ('length' in arg) length = arg.length;
if ('delimiter' in arg) delimiter = arg.delimiter;
} }
options.encoding = options.encoding || this.query.options.encoding || this.query.encoding; if(encoding === 'latin1') encoding = 'win1252';
if(options.encoding === 'latin1') options.encoding = 'win1252';
const start = this.i+0; const start = this.i;
let end = start; let end = start;
if(!('length' in options)) { if(length === null) {
// terminated by the delimiter // terminated by the delimiter
let delim = options.delimiter || this.query.delimiter; let delim = delimiter;
if(typeof delim === 'string') delim = delim.charCodeAt(0); if (typeof delim === 'string') delim = delim.charCodeAt(0);
while(true) { while (true) {
if(end >= this.buffer.length) { if (end >= this.buffer.length) {
end = this.buffer.length; end = this.buffer.length;
break; break;
} }
if(this.buffer.readUInt8(end) === delim) break; if (this.buffer.readUInt8(end) === delim) break;
end++; end++;
} }
this.i = end+1; this.i = end + 1;
} else if (length <= 0) {
return '';
} else { } else {
end = start+options.length; end = start+length;
if(end >= this.buffer.length) { if(end >= this.buffer.length) {
end = this.buffer.length; end = this.buffer.length;
} }
this.i = end; this.i = end;
} }
let out = this.buffer.slice(start, end); const slice = this.buffer.slice(start, end);
const enc = options.encoding; const enc = encoding;
if(enc === 'utf8' || enc === 'ucs2' || enc === 'binary') { if(enc === 'utf8' || enc === 'ucs2' || enc === 'binary') {
out = out.toString(enc); return slice.toString(enc);
} else { } else {
out = Iconv.decode(out,enc); return Iconv.decode(slice,enc);
} }
return out;
} }
int(bytes) { int(bytes) {
let r = 0; let r = 0;
if(this.remaining() >= bytes) { if(this.remaining() >= bytes) {
if(this.query.byteorder === 'be') { if(this.defaultByteOrder === 'be') {
if(bytes === 1) r = this.buffer.readInt8(this.i); if(bytes === 1) r = this.buffer.readInt8(this.i);
else if(bytes === 2) r = this.buffer.readInt16BE(this.i); else if(bytes === 2) r = this.buffer.readInt16BE(this.i);
else if(bytes === 4) r = this.buffer.readInt32BE(this.i); else if(bytes === 4) r = this.buffer.readInt32BE(this.i);
@ -101,7 +111,7 @@ class Reader {
uint(bytes) { uint(bytes) {
let r = 0; let r = 0;
if(this.remaining() >= bytes) { if(this.remaining() >= bytes) {
if(this.query.byteorder === 'be') { if(this.defaultByteOrder === 'be') {
if(bytes === 1) r = this.buffer.readUInt8(this.i); if(bytes === 1) r = this.buffer.readUInt8(this.i);
else if(bytes === 2) r = this.buffer.readUInt16BE(this.i); else if(bytes === 2) r = this.buffer.readUInt16BE(this.i);
else if(bytes === 4) r = this.buffer.readUInt32BE(this.i); else if(bytes === 4) r = this.buffer.readUInt32BE(this.i);
@ -120,7 +130,7 @@ class Reader {
float() { float() {
let r = 0; let r = 0;
if(this.remaining() >= 4) { if(this.remaining() >= 4) {
if(this.query.byteorder === 'be') r = this.buffer.readFloatBE(this.i); if(this.defaultByteOrder === 'be') r = this.buffer.readFloatBE(this.i);
else r = this.buffer.readFloatLE(this.i); else r = this.buffer.readFloatLE(this.i);
} }
this.i += 4; this.i += 4;

View file

@ -4,7 +4,7 @@ class Ase extends Core {
async run(state) { async run(state) {
const buffer = await this.udpSend('s',(buffer) => { const buffer = await this.udpSend('s',(buffer) => {
const reader = this.reader(buffer); const reader = this.reader(buffer);
const header = reader.string({length: 4}); const header = reader.string(4);
if (header === 'EYE1') return reader.rest(); if (header === 'EYE1') return reader.rest();
}); });
@ -40,8 +40,7 @@ class Ase extends Core {
} }
readString(reader) { readString(reader) {
const len = reader.uint(1); return reader.pascalString(1, -1);
return reader.string({length:len-1});
} }
} }

View file

@ -153,8 +153,7 @@ class Battlefield extends Core {
const paramCount = reader.uint(4); const paramCount = reader.uint(4);
const params = []; const params = [];
for(let i = 0; i < paramCount; i++) { for(let i = 0; i < paramCount; i++) {
const len = reader.uint(4); params.push(reader.pascalString(4));
params.push(reader.string({length:len}));
const strNull = reader.uint(1); const strNull = reader.uint(1);
} }
return params; return params;

View file

@ -66,8 +66,7 @@ class Cs2d extends Core {
} }
readString(reader) { readString(reader) {
const length = reader.uint(1); return reader.pascalString(1);
return reader.string({length:length});
} }
} }

View file

@ -16,10 +16,10 @@ class Doom3 extends Core {
if(header !== 0xffff) return; if(header !== 0xffff) return;
const header2 = reader.string(); const header2 = reader.string();
if(header2 !== 'infoResponse') return; if(header2 !== 'infoResponse') return;
const challengePart1 = reader.string({length:4}); const challengePart1 = reader.string(4);
if (challengePart1 !== "PiNG") return; if (challengePart1 !== "PiNG") return;
// some doom3 implementations only return the first 4 bytes of the challenge // some doom3 implementations only return the first 4 bytes of the challenge
const challengePart2 = reader.string({length:4}); const challengePart2 = reader.string(4);
if (challengePart2 !== 'PoNg') reader.skip(-4); if (challengePart2 !== 'PoNg') reader.skip(-4);
return reader.rest(); return reader.rest();
}); });

View file

@ -102,7 +102,7 @@ class Gamespy1 extends Core {
return await this.udpSend('\\'+type+'\\', buffer => { return await this.udpSend('\\'+type+'\\', buffer => {
const reader = this.reader(buffer); const reader = this.reader(buffer);
const str = reader.string({length:buffer.length}); const str = reader.string(buffer.length);
const split = str.split('\\'); const split = str.split('\\');
split.shift(); split.shift();
const data = {}; const data = {};

View file

@ -9,7 +9,7 @@ class M2mp extends Core {
async run(state) { async run(state) {
const body = await this.udpSend('M2MP',(buffer) => { const body = await this.udpSend('M2MP',(buffer) => {
const reader = this.reader(buffer); const reader = this.reader(buffer);
const header = reader.string({length: 4}); const header = reader.string(4);
if (header !== 'M2MP') return; if (header !== 'M2MP') return;
return reader.rest(); return reader.rest();
}); });
@ -32,8 +32,7 @@ class M2mp extends Core {
} }
readString(reader) { readString(reader) {
const length = reader.uint(1); return reader.pascalString(1,-1);
return reader.string({length:length-1});
} }
} }

View file

@ -17,7 +17,7 @@ class Quake2 extends Core {
if (header !== '\xff\xff\xff\xff') return; if (header !== '\xff\xff\xff\xff') return;
let type; let type;
if (this.isQuake1) { if (this.isQuake1) {
type = reader.string({length: this.responseHeader.length}); type = reader.string(this.responseHeader.length);
} else { } else {
type = reader.string({encoding: 'latin1'}); type = reader.string({encoding: 'latin1'});
} }

View file

@ -20,9 +20,9 @@ class Samp extends Core {
state.password = !!reader.uint(1); state.password = !!reader.uint(1);
state.raw.numplayers = reader.uint(2); state.raw.numplayers = reader.uint(2);
state.maxplayers = reader.uint(2); state.maxplayers = reader.uint(2);
state.name = this.readString(reader,4); state.name = reader.pascalString(4);
state.raw.gamemode = this.readString(reader,4); state.raw.gamemode = reader.pascalString(4);
state.raw.map = this.readString(reader,4); state.raw.map = reader.pascalString(4);
} }
// read rules // read rules
@ -31,8 +31,8 @@ class Samp extends Core {
const ruleCount = reader.uint(2); const ruleCount = reader.uint(2);
state.raw.rules = {}; state.raw.rules = {};
for(let i = 0; i < ruleCount; i++) { for(let i = 0; i < ruleCount; i++) {
const key = this.readString(reader,1); const key = reader.pascalString(1);
const value = this.readString(reader,1); const value = reader.pascalString(1);
state.raw.rules[key] = value; state.raw.rules[key] = value;
} }
} }
@ -48,7 +48,7 @@ class Samp extends Core {
const playerCount = reader.uint(2); const playerCount = reader.uint(2);
for(let i = 0; i < playerCount; i++) { for(let i = 0; i < playerCount; i++) {
const player = {}; const player = {};
player.name = this.readString(reader,1); player.name = reader.pascalString(1);
state.players.push(player); state.players.push(player);
} }
} }
@ -60,7 +60,7 @@ class Samp extends Core {
for(let i = 0; i < playerCount; i++) { for(let i = 0; i < playerCount; i++) {
const player = {}; const player = {};
player.id = reader.uint(1); player.id = reader.uint(1);
player.name = this.readString(reader,1); player.name = reader.pascalString(1);
player.score = reader.int(4); player.score = reader.int(4);
player.ping = reader.uint(4); player.ping = reader.uint(4);
state.players.push(player); state.players.push(player);
@ -72,11 +72,6 @@ class Samp extends Core {
state.players = state.raw.numplayers; state.players = state.raw.numplayers;
} }
} }
readString(reader,lenBytes) {
const length = reader.uint(lenBytes);
if(!length) return '';
return reader.string({length:length});
}
async sendPacket(type,allowTimeout) { async sendPacket(type,allowTimeout) {
const outBuffer = Buffer.alloc(11); const outBuffer = Buffer.alloc(11);
outBuffer.write(this.magicHeader,0, 4); outBuffer.write(this.magicHeader,0, 4);

View file

@ -145,9 +145,7 @@ class Tribes1 extends Core {
.map((a) => a.trim()); .map((a) => a.trim());
} }
readString(reader) { readString(reader) {
const length = reader.uint(1); return reader.pascalString(1);
if(!length) return '';
return reader.string({length:length});
} }
} }

View file

@ -74,9 +74,7 @@ class Tribes1Master extends Core {
} }
} }
readString(reader) { readString(reader) {
const length = reader.uint(1); return reader.pascalString(1);
if(!length) return '';
return reader.string({length:length});
} }
} }

View file

@ -89,7 +89,7 @@ class Unreal2 extends Core {
let length = reader.uint(1); let length = reader.uint(1);
let out; let out;
if(length < 0x80) { if(length < 0x80) {
//out = reader.string({length:length}); //out = reader.string(length);
out = ''; out = '';
if(length > 0) out = reader.string(); if(length > 0) out = reader.string();
} else { } else {