tsinsim
Version:
An InSim library for Node.js (JavaScript runtime environment) with TypeScript support.
82 lines (81 loc) • 3.01 kB
JavaScript
import net from 'net';
import { Packets } from "./packets/utilities/decorators.js";
import { PacketType } from './packets/types/index.js';
import { IS_ISI, IS_TINY } from './packets/structs/index.js';
import { Events } from './utilities/events.js';
export class InSim extends Events {
InSimOptions;
stream = null;
buffer = Buffer.alloc(0);
connected = false;
constructor(InSimOptions) {
super();
this.InSimOptions = InSimOptions;
}
connect(connectionOptions) {
this.stream = net.connect(connectionOptions.Port, connectionOptions.Host);
this.stream.on('connect', () => {
this.sendPacket(new IS_ISI({ ...this.InSimOptions }));
for (const value of [6, 7, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 22, 23, 25, 27, 29]) {
this.sendPacket(new IS_TINY({ ReqI: 1, SubT: value }));
}
this.on(PacketType.ISP_TINY, () => {
this.sendPacket(new IS_TINY({ ReqI: 1 }));
});
this.fire('connect');
});
this.stream.on('data', (data) => {
this.buffer = Buffer.concat([this.buffer, data]);
var size = this.peekByte();
while ((this.buffer.length > 0) && (size <= this.buffer.length)) {
if (size > 0) {
this.deserializePacket(this.buffer.subarray(0, size));
this.buffer = this.buffer.subarray(size, this.buffer.length);
}
size = this.peekByte();
}
});
this.stream.on('close', () => {
console.log('[InSim] Disconnected.');
this.disconnect();
});
this.stream.on('error', (err) => {
console.log('[InSim] Error: ' + err);
this.disconnect();
});
}
peekByte(offset = 0) {
return offset >= this.buffer.length ? 0 : this.buffer.subarray(0, 1).readUInt8(offset) * 4;
}
disconnect() {
if (this.stream) {
this.stream.end();
this.stream = null;
}
this.connected = false;
this.fire('disconnect');
}
sendPacket(packet) {
if (this.stream === null)
return;
this.stream.write(packet.pack());
}
deserializePacket(data) {
if (this.stream === null)
return;
if (!this.connected) {
this.connected = true;
this.fire('connected');
}
const packetId = data.readUInt8(1);
const packetType = PacketType[packetId];
if (!packetType) {
return console.log('[InSim:deserializePacket] packetType with packetId: ' + packetId + ' unknown!');
}
const packetClass = Packets.get(packetType);
if (!packetClass) {
return console.log('[InSim:deserializePacket] packetClass for packetType: ' + packetType + ' ID: ' + packetId + ' unknown!');
}
this.fire(packetId, (new packetClass).unpack(data));
}
}