mudb
Version:
Real-time database for multiplayer games
197 lines • 6.33 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const stream_1 = require("../../stream");
const logger_1 = require("../../logger");
class MuBufferWrapper {
constructor(bytes) {
this._buffer = stream_1.allocBuffer(bytes.length);
this.bytes = this._buffer.uint8.subarray(0, bytes.length);
this.bytes.set(bytes);
}
free() {
stream_1.freeBuffer(this._buffer);
}
}
function calcDelay(latency, jitter) {
return latency + Math.floor(Math.random() * jitter);
}
function drain(pendingMessages, handler) {
const message = pendingMessages.shift();
if (typeof message === 'string') {
handler(message);
}
else if (message) {
handler(message.bytes);
message.free();
}
}
class MuDebugSocket {
constructor(spec) {
this.inLatency = 0;
this.inJitter = 0;
this.inPacketLoss = 0;
this.outLatency = 0;
this.outJitter = 0;
this.outPacketLoss = 0;
this._inbox = [];
this._outbox = [];
this.socket = spec.socket;
this.sessionId = this.socket.sessionId;
if (typeof spec.inLatency === 'number') {
this.inLatency = Math.max(0, spec.inLatency);
}
if (typeof spec.inJitter === 'number') {
this.inJitter = Math.max(0, spec.inJitter);
}
if (typeof spec.inPacketLoss === 'number') {
this.inPacketLoss = Math.min(100, Math.max(0, spec.inPacketLoss));
}
if (typeof spec.outLatency === 'number') {
this.outLatency = Math.max(0, spec.outLatency);
}
if (typeof spec.outJitter === 'number') {
this.outJitter = Math.max(0, spec.outJitter);
}
if (typeof spec.outPacketLoss === 'number') {
this.outPacketLoss = Math.min(100, Math.max(0, spec.outPacketLoss));
}
this.logger = spec.logger || logger_1.MuDefaultLogger;
}
state() {
return this.socket.state();
}
open(spec) {
this.socket.open({
ready: () => {
try {
spec.ready();
}
catch (e) {
this.logger.exception(e);
}
},
message: (data, unreliable) => {
if (unreliable) {
if (Math.random() * 100 < this.inPacketLoss) {
return;
}
setTimeout(() => {
try {
spec.message(data, true);
}
catch (e) {
this.logger.exception(e);
}
}, calcDelay(this.inLatency, this.inJitter));
}
else {
const message = typeof data === 'string' ? data : new MuBufferWrapper(data);
this._inbox.push(message);
setTimeout(() => {
try {
drain(this._inbox, (data_) => spec.message(data_, false));
}
catch (e) {
this.logger.exception(e);
}
}, calcDelay(this.inLatency, this.inJitter));
}
},
close: () => {
try {
spec.close();
}
catch (e) {
this.logger.exception(e);
}
},
});
}
send(data, unreliable) {
const message = typeof data === 'string' ? data : new MuBufferWrapper(data);
this._outbox.push(message);
const unreliable_ = !!unreliable;
if (unreliable_) {
if (Math.random() * 100 < this.outPacketLoss) {
return;
}
}
setTimeout(() => drain(this._outbox, (data_) => {
try {
this.socket.send(data_, unreliable_);
}
catch (e) {
this.logger.exception(e);
}
}), calcDelay(this.outLatency, this.outJitter));
}
close() {
this.socket.close();
}
reliableBufferedAmount() {
return this.socket.reliableBufferedAmount();
}
unreliableBufferedAmount() {
return this.socket.unreliableBufferedAmount();
}
}
exports.MuDebugSocket = MuDebugSocket;
class MuDebugServer {
constructor(spec) {
this.clients = [];
this.socketServer = spec.socketServer;
this.inLatency = spec.inLatency || 0;
this.inJitter = spec.inJitter || 0;
this.inPacketLoss = spec.inPacketLoss || 0;
this.outLatency = spec.outLatency || 0;
this.outJitter = spec.outJitter || 0;
this.outPacketLoss = spec.outPacketLoss || 0;
this.logger = spec.logger || logger_1.MuDefaultLogger;
}
state() {
return this.socketServer.state();
}
start(spec) {
this.socketServer.start({
ready: () => {
try {
spec.ready();
}
catch (e) {
this.logger.exception(e);
}
},
connection: (socket) => {
const client = new MuDebugSocket({
socket,
inLatency: this.inLatency,
inJitter: this.inJitter,
inPacketLoss: this.inPacketLoss,
outLatency: this.outLatency,
outJitter: this.outJitter,
outPacketLoss: this.outPacketLoss,
});
this.clients.push(client);
try {
spec.connection(client);
}
catch (e) {
this.logger.exception(e);
}
},
close: () => {
try {
spec.close();
}
catch (e) {
this.logger.exception(e);
}
},
});
}
close() {
this.socketServer.close();
}
}
exports.MuDebugServer = MuDebugServer;
//# sourceMappingURL=index.js.map