move common parsing into its own function

This commit is contained in:
2023-11-25 09:04:10 -06:00
parent 60de1632eb
commit dcefef69e8
+142 -223
View File
@@ -1,12 +1,23 @@
class Console { class Console {
constructor() { constructor() {
this.sportInitialized = false; this.sportInitialized = false;
this.state = {
time: {},
auxTime: {},
home: {},
guest: {},
};
} }
reset() { reset() {
this.sportInitialized = false; this.sportInitialized = false;
delete this.sport; delete this.sport;
delete this.state; this.state = {
time: {},
auxTime: {},
home: {},
guest: {},
};
} }
/** /**
@@ -14,22 +25,28 @@ class Console {
* @param {Buffer} buffer * @param {Buffer} buffer
*/ */
update(buffer) { update(buffer) {
switch (buffer.at(2)) { if (buffer.at(0) === 0xfc && buffer.at(1) === 0xfc) {
this.currentBuffer = {
hex: buffer.toString('hex'),
buffer,
};
this.parseCommon();
switch (this.currentBuffer.buffer.at(2)) {
case 0x51: case 0x51:
this.sport = 'basketball'; this.sport = 'basketball';
this.parseBasketball(buffer); this.parseBasketball();
break; break;
case 0x61: case 0x61:
this.sport = 'football'; this.sport = 'football';
this.parseFootball(buffer); this.parseFootball();
break; break;
case 0x70: case 0x70:
this.sport = 'volleyball'; this.sport = 'volleyball';
this.parseVolleyball(buffer); this.parseVolleyball();
break; break;
case 0x71: case 0x71:
this.sport = 'baseball'; this.sport = 'baseball';
this.parseBaseball(buffer); this.parseBaseball();
break; break;
case 0x16: case 0x16:
this.sport = 'soccer'; this.sport = 'soccer';
@@ -40,28 +57,92 @@ class Console {
case 0x40: case 0x40:
this.sport = 'hockey'; this.sport = 'hockey';
throw new Error('Hockey is not implemented'); throw new Error('Hockey is not implemented');
case 0x85:
this.sport = 'auto_racing';
throw new Error('Auto racing is not implemented');
case 0x82:
this.sport = 'track';
throw new Error('Track is not implemented');
case 0x59:
this.sport = 'whirley';
throw new Error('Whirley is not implemented');
case 0x67:
this.sport = 'segment';
throw new Error('Segment is not implemented');
default: default:
console.log(`unidentified sport data: ${buffer.toString('hex')}`); console.log(`unidentified sport data: ${buffer.toString('hex')}`);
break; break;
} }
} }
}
/** parseCommon() {
* this.state.time.minutes = this.currentBuffer.buffer.subarray(5, 6).toString('hex');
* @param {Buffer} buffer this.state.time.seconds = this.currentBuffer.buffer.subarray(6, 7).toString('hex');
*/ this.state.time.tenths = this.currentBuffer.hex.substring(15, 16);
parseBaseball(buffer) {
this.state.time.showTenths = this.currentBuffer.hex.at(8) === '1';
this.state.time.display = `${this.state.time.minutes}:${this.state.time.seconds}`;
if (this.state.time.showTenths) {
this.state.time.display += `.${this.state.time.tenths}`;
}
this.state.auxTime.seconds = this.currentBuffer.hex.substring(16, 18);
if (this.state.auxTime.seconds === 'aa') {
this.state.auxTime.seconds = '00';
}
this.state.auxTime.tenths = this.currentBuffer.hex.substring(19, 20);
if (this.state.auxTime.tenths === 'a') {
this.state.auxTime.tenths = '0';
}
this.state.auxTime.display = `${this.state.auxTime.seconds}.${this.state.auxTime.tenths}`;
const hornBinaryFlags = this.currentBuffer.buffer.at(4).toString(2).padStart(8, '0');
this.state.horn = hornBinaryFlags[0] === '1';
this.state.auxHorn = hornBinaryFlags[1] === '1';
this.state.showTimeOfDay = this.currentBuffer.buffer.at(5) === 0xff && this.currentBuffer.buffer.at(6) === 0xff;
if (this.currentBuffer.buffer.at(10) === 0x11) {
const homeBinaryInfo = this.currentBuffer.buffer.at(12).toString(2).padStart(8, '0');
const guestBinaryInfo = this.currentBuffer.buffer.at(14).toString(2).padStart(8, '0');
this.state.home.score = parseInt(this.currentBuffer.hex.substring(22, 24), 10);
if (homeBinaryInfo[0] === '1') {
this.state.home.score += 100;
}
this.state.guest.score = parseInt(this.currentBuffer.hex.substring(26, 28), 10);
if (guestBinaryInfo[0] === '1') {
this.state.guest.score += 100;
}
this.state.home.poss = homeBinaryInfo[7] === '1';
this.state.guest.poss = guestBinaryInfo[7] === '1';
this.state.home.doubleBonus = homeBinaryInfo[3] === '1';
this.state.home.bonus = homeBinaryInfo[4] === '1';
this.state.guest.doubleBonus = guestBinaryInfo[3] === '1';
this.state.guest.bonus = guestBinaryInfo[4] === '1';
this.state.period = parseInt(this.currentBuffer.hex.substring(31, 32), 10);
this.state.home.timeouts = parseInt(this.currentBuffer.hex.substring(40, 41), 10);
this.state.guest.timeouts = parseInt(this.currentBuffer.hex.substring(41, 42), 10);
}
}
parseBaseball() {
if (!this.sportInitialized) { if (!this.sportInitialized) {
this.state = { this.state.bases = {
time: {},
home: {},
guest: {},
bases: {
first: false, first: false,
second: false, second: false,
third: false, third: false,
}, };
innings: {
this.state.innings = {
1: { 1: {
home: { home: {
score: 0, score: 0,
@@ -151,69 +232,46 @@ class Console {
score: 0, score: 0,
}, },
}, },
},
}; };
this.sportInitialized = true; this.sportInitialized = true;
} }
const bufferHex = buffer.toString('hex'); const seqNum = this.currentBuffer.buffer.at(10);
if (seqNum === 0x11) {
this.state.guest.hits = parseInt(this.currentBuffer.buffer.subarray(23, 24).toString('hex'), 10);
this.state.home.hits = parseInt(this.currentBuffer.buffer.subarray(22, 23).toString('hex'), 10);
this.state.time.minutes = buffer.subarray(5, 6).toString('hex'); this.state.batter = this.currentBuffer.buffer.subarray(21, 22).toString('hex');
this.state.time.seconds = buffer.subarray(6, 7).toString('hex');
this.state.time.tenths = bufferHex.substring(15, 16);
this.state.time.showTenths = bufferHex.at(8) === '1';
this.state.time.display = `${this.state.time.minutes}:${this.state.time.seconds}`;
const hornBinaryFlags = buffer.at(4).toString(2).padStart(8, '0');
this.state.horn = hornBinaryFlags[0] === '1';
const seqNum = bufferHex.substring(20, 22);
if (seqNum === '11') {
const homeBinaryInfo = buffer.at(12).toString(2).padStart(8, '0');
const guestBinaryInfo = buffer.at(14).toString(2).padStart(8, '0');
this.state.home.score = parseInt(bufferHex.substring(22, 24), 10);
if (homeBinaryInfo[0] === '1') {
this.state.home.score += 100;
}
this.state.guest.score = parseInt(bufferHex.substring(26, 28), 10);
if (guestBinaryInfo[0] === '1') {
this.state.guest.score += 100;
}
this.state.guest.hits = parseInt(buffer.subarray(23, 24).toString('hex'), 10);
this.state.home.hits = parseInt(buffer.subarray(22, 23).toString('hex'), 10);
this.state.batter = buffer.subarray(21, 22).toString('hex');
if (this.state.batter === 'aa') { if (this.state.batter === 'aa') {
this.state.batter = ''; this.state.batter = '';
} }
this.state.home.pitcher = parseInt(buffer.subarray(26, 27).toString('hex'), 10); this.state.home.pitcher = parseInt(this.currentBuffer.buffer.subarray(26, 27).toString('hex'), 10);
this.state.guest.pitcher = parseInt(buffer.subarray(24, 25).toString('hex'), 10); this.state.guest.pitcher = parseInt(this.currentBuffer.buffer.subarray(24, 25).toString('hex'), 10);
const baseBinaryInfo = buffer.at(19).toString(2).padStart(8, '0'); const baseBinaryInfo = this.currentBuffer.buffer.at(19).toString(2).padStart(8, '0');
this.state.bases.first = baseBinaryInfo[3] === '1'; this.state.bases.first = baseBinaryInfo[3] === '1';
this.state.bases.second = baseBinaryInfo[2] === '1'; this.state.bases.second = baseBinaryInfo[2] === '1';
this.state.bases.third = baseBinaryInfo[1] === '1'; this.state.bases.third = baseBinaryInfo[1] === '1';
this.state.outs = parseInt(bufferHex.substring(37, 38), 10); this.state.outs = parseInt(this.currentBuffer.hex.substring(37, 38), 10);
this.state.strikes = parseInt(bufferHex.substring(36, 37), 10); this.state.strikes = parseInt(this.currentBuffer.hex.substring(36, 37), 10);
this.state.balls = parseInt(bufferHex.substring(39, 40), 10); this.state.balls = parseInt(this.currentBuffer.hex.substring(39, 40), 10);
const binaryFlags = buffer.at(12).toString(2).padStart(8, '0'); const binaryFlags = this.currentBuffer.buffer.at(12).toString(2).padStart(8, '0');
this.state.hit = binaryFlags[4] === '1'; this.state.hit = binaryFlags[4] === '1';
} else if (seqNum === '22') { } else if (seqNum === 0x22) {
const guestInningStartIndex = 11; const guestInningStartIndex = 11;
const homeInningStartIndex = 21; const homeInningStartIndex = 21;
for (let i = 0; i < 10; i += 1) { for (let i = 0; i < 10; i += 1) {
const guestInningScore = buffer const guestInningScore = this.currentBuffer.buffer
.subarray(guestInningStartIndex + i, guestInningStartIndex + i + 1) .subarray(guestInningStartIndex + i, guestInningStartIndex + i + 1)
.toString('hex'); .toString('hex');
if (guestInningScore !== '0a') { if (guestInningScore !== '0a') {
this.state.innings[i + 1].guest.score = parseInt(guestInningScore, 10); this.state.innings[i + 1].guest.score = parseInt(guestInningScore, 10);
} }
const homeInningScore = buffer.subarray(homeInningStartIndex + i, homeInningStartIndex + i + 1).toString('hex'); const homeInningScore = this.currentBuffer.buffer
.subarray(homeInningStartIndex + i, homeInningStartIndex + i + 1)
.toString('hex');
if (homeInningScore !== '0a') { if (homeInningScore !== '0a') {
this.state.innings[i + 1].home.score = parseInt(homeInningScore, 10); this.state.innings[i + 1].home.score = parseInt(homeInningScore, 10);
} }
@@ -225,182 +283,43 @@ class Console {
* *
* @param {Buffer} buffer * @param {Buffer} buffer
*/ */
parseFootball(buffer) { parseFootball() {
if (!this.sportInitialized) { if (!this.sportInitialized) {
this.state = {
time: {},
playClock: {},
home: {},
guest: {},
};
this.sportInitialized = true; this.sportInitialized = true;
} }
const bufferHex = buffer.toString('hex'); const seqNum = this.currentBuffer.buffer.at(10);
if (seqNum === 0x11) {
this.state.time.minutes = buffer.subarray(5, 6).toString('hex'); this.state.quarter = parseInt(this.currentBuffer.hex.substring(31, 32), 10);
this.state.time.seconds = buffer.subarray(6, 7).toString('hex'); this.state.down = parseInt(this.currentBuffer.hex.substring(39, 40), 10);
this.state.time.tenths = bufferHex.substring(15, 16); this.state.yardsToGo = parseInt(this.currentBuffer.buffer.subarray(18, 19).toString('hex'), 10);
this.state.ballOn = parseInt(this.currentBuffer.buffer.subarray(21, 22).toString('hex'), 10);
this.state.time.showTenths = bufferHex.at(8) === '1';
this.state.time.display = `${this.state.time.minutes}:${this.state.time.seconds}`;
this.state.playClock.seconds = bufferHex.substring(16, 18);
const hornBinaryFlags = buffer.at(4).toString(2).padStart(8, '0');
this.state.horn = hornBinaryFlags[0] === '1';
const seqNum = bufferHex.substring(20, 22);
if (seqNum === '11') {
const homeBinaryInfo = buffer.at(12).toString(2).padStart(8, '0');
const guestBinaryInfo = buffer.at(14).toString(2).padStart(8, '0');
this.state.home.score = parseInt(bufferHex.substring(22, 24), 10);
if (homeBinaryInfo[0] === '1') {
this.state.home.score += 100;
}
this.state.guest.score = parseInt(bufferHex.substring(26, 28), 10);
if (guestBinaryInfo[0] === '1') {
this.state.guest.score += 100;
}
this.state.home.poss = homeBinaryInfo[7] === '1';
this.state.guest.poss = guestBinaryInfo[7] === '1';
this.state.home.timeouts = parseInt(bufferHex.substring(40, 41), 10);
this.state.guest.timeouts = parseInt(bufferHex.substring(41, 42), 10);
this.state.quarter = parseInt(bufferHex.substring(31, 32), 10);
this.state.down = parseInt(bufferHex.substring(39, 40), 10);
this.state.yardsToGo = parseInt(buffer.subarray(18, 19).toString('hex'), 10);
this.state.ballOn = parseInt(buffer.subarray(21, 22).toString('hex'), 10);
} }
} }
/** parseVolleyball() {
* if (!this.sportInitialized) {
* @param {Buffer} buffer this.sportInitialized = true;
*/ }
parseVolleyball(buffer) { const seqNum = this.currentBuffer.buffer.at(10);
const bufferHex = buffer.toString('hex'); if (seqNum === 0x11) {
this.state.home.gamesWon = parseInt(this.currentBuffer.buffer.subarray(16, 17).toString('hex'), 10);
this.state.guest.gamesWon = parseInt(this.currentBuffer.buffer.subarray(17, 18).toString('hex'), 10);
this.state.game = parseInt(this.currentBuffer.hex.substring(31, 32), 10);
}
}
parseBasketball() {
if (!this.sportInitialized) { if (!this.sportInitialized) {
this.state = {
time: {},
home: {},
guest: {},
};
this.sportInitialized = true; this.sportInitialized = true;
} }
this.state.time.minutes = bufferHex.substring(10, 12); const seqNum = this.currentBuffer.buffer.at(10);
this.state.time.seconds = bufferHex.substring(12, 14); if (seqNum === 0x11) {
this.state.time.tenths = bufferHex.substring(15, 16); this.state.home.fouls = parseInt(this.currentBuffer.hex.substring(32, 34), 10);
this.state.guest.fouls = parseInt(this.currentBuffer.hex.substring(34, 36), 10);
this.state.time.showTenths = bufferHex.at(8) === '1'; this.state.period = parseInt(this.currentBuffer.hex.substring(31, 32), 10);
this.state.time.display = `${this.state.time.minutes}:${this.state.time.seconds}`;
const hornBinaryFlags = buffer.at(4).toString(2).padStart(8, '0');
this.state.horn = hornBinaryFlags[0] === '1';
const seqNum = bufferHex.substring(20, 22);
if (seqNum === '11') {
const homeBinaryInfo = buffer.at(12).toString(2).padStart(8, '0');
const guestBinaryInfo = buffer.at(14).toString(2).padStart(8, '0');
this.state.home.score = parseInt(bufferHex.substring(22, 24), 10);
if (homeBinaryInfo[0] === '1') {
this.state.home.score += 100;
}
this.state.guest.score = parseInt(bufferHex.substring(26, 28), 10);
if (guestBinaryInfo[0] === '1') {
this.state.guest.score += 100;
}
this.state.home.serve = homeBinaryInfo[7] === '1';
this.state.guest.serve = guestBinaryInfo[7] === '1';
this.state.home.gamesWon = parseInt(buffer.subarray(16, 17).toString('hex'), 10);
this.state.guest.gamesWon = parseInt(buffer.subarray(17, 18).toString('hex'), 10);
this.state.home.timeouts = parseInt(bufferHex.substring(40, 41), 10);
this.state.guest.timeouts = parseInt(bufferHex.substring(41, 42), 10);
this.state.game = parseInt(bufferHex.substring(31, 32), 10);
}
}
/**
*
* @param {Buffer} buffer
*/
parseBasketball(buffer) {
const bufferHex = buffer.toString('hex');
if (!this.sportInitialized) {
this.state = {
time: {},
shotClock: {},
home: {},
guest: {},
};
this.sportInitialized = true;
}
this.state.time.minutes = bufferHex.substring(10, 12);
this.state.time.seconds = bufferHex.substring(12, 14);
this.state.time.tenths = bufferHex.substring(15, 16);
this.state.time.showTenths = bufferHex.at(8) === '1';
this.state.time.display = `${this.state.time.minutes}:${this.state.time.seconds}`;
if (this.state.time.showTenths) {
this.state.time.display += `.${this.state.time.tenths}`;
}
this.state.shotClock.seconds = bufferHex.substring(16, 18);
if (this.state.shotClock.seconds === 'aa') {
this.state.shotClock.seconds = '00';
}
this.state.shotClock.tenths = bufferHex.substring(19, 20);
if (this.state.shotClock.tenths === 'a') {
this.state.shotClock.tenths = '0';
}
this.state.shotClock.display = `${this.state.shotClock.seconds}.${this.state.shotClock.tenths}`;
const seqNum = bufferHex.substring(20, 22);
const hornBinaryFlags = buffer.at(4).toString(2).padStart(8, '0');
this.state.horn = hornBinaryFlags[0] === '1';
if (seqNum === '11') {
const homeBinaryInfo = buffer.at(12).toString(2).padStart(8, '0');
const guestBinaryInfo = buffer.at(14).toString(2).padStart(8, '0');
this.state.home.score = parseInt(bufferHex.substring(22, 24), 10);
if (homeBinaryInfo[0] === '1') {
this.state.home.score += 100;
}
this.state.guest.score = parseInt(bufferHex.substring(26, 28), 10);
if (guestBinaryInfo[0] === '1') {
this.state.guest.score += 100;
}
this.state.home.poss = homeBinaryInfo[7] === '1';
this.state.guest.poss = guestBinaryInfo[7] === '1';
this.state.home.doubleBonus = homeBinaryInfo[3] === '1';
this.state.home.bonus = homeBinaryInfo[4] === '1';
this.state.guest.doubleBonus = guestBinaryInfo[3] === '1';
this.state.guest.bonus = guestBinaryInfo[4] === '1';
this.state.home.fouls = parseInt(bufferHex.substring(32, 34), 10);
this.state.guest.fouls = parseInt(bufferHex.substring(34, 36), 10);
this.state.home.timeouts = parseInt(bufferHex.substring(40, 41), 10);
this.state.guest.timeouts = parseInt(bufferHex.substring(41, 42), 10);
this.state.period = parseInt(bufferHex.substring(31, 32), 10);
} }
// TODO(jwetzell): decode player stats in seqNum >= 22 // TODO(jwetzell): decode player stats in seqNum >= 22