169 lines
4.0 KiB
JavaScript
169 lines
4.0 KiB
JavaScript
|
function mkjsInstance(config, instanceConfig, wss) {
|
||
|
var userID = 0;
|
||
|
var sockets = [];
|
||
|
var kartInf = [];
|
||
|
var relkDat = [];
|
||
|
var t = this;
|
||
|
|
||
|
var upInt = setInterval(update, 16.667);
|
||
|
|
||
|
function update() {
|
||
|
|
||
|
//generate and send kart dat packet
|
||
|
if (relkDat.length != 0) {
|
||
|
var d = new ArrayBuffer(3+relkDat.length*0x62);
|
||
|
var arr = new Uint8Array(d);
|
||
|
var view = new DataView(d);
|
||
|
arr[0] = 32;
|
||
|
view.setUint16(1, relkDat.length, true);
|
||
|
var off = 3;
|
||
|
for (var i=0; i<relkDat.length; i++) {
|
||
|
view.setUint16(off, relkDat[i].k, true)
|
||
|
var cpy = new Uint8Array(relkDat[i].d);
|
||
|
arr.set(cpy, off+2);
|
||
|
off += 0x62;
|
||
|
}
|
||
|
|
||
|
for (var i=0; i<sockets.length; i++) {
|
||
|
sockets[i].send(d)
|
||
|
}
|
||
|
relkDat = [];
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//HANDLERS BELOW
|
||
|
|
||
|
function addKart(cli) {
|
||
|
var c = JSON.parse(JSON.stringify(cli.credentials));
|
||
|
c.active = true;
|
||
|
cli.kartID = kartInf.length;
|
||
|
kartInf.push(c);
|
||
|
|
||
|
for (var i=0; i<sockets.length; i++) {
|
||
|
if (sockets[i] != cli) sockets[i].send(JSON.stringify({
|
||
|
t:"+",
|
||
|
k:c
|
||
|
}))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.addClient = function(clientSocket) {
|
||
|
console.log("added client")
|
||
|
sockets.push(clientSocket);
|
||
|
clientSocket.credentials.userID = userID++;
|
||
|
|
||
|
addKart(clientSocket);
|
||
|
|
||
|
sendInstanceInfo(clientSocket);
|
||
|
|
||
|
//sendClientID(clientSocket);
|
||
|
}
|
||
|
|
||
|
function sendInstanceInfo(clientSocket) {
|
||
|
clientSocket.send(JSON.stringify({
|
||
|
t:"*",
|
||
|
k:kartInf,
|
||
|
p:clientSocket.kartID,
|
||
|
c:"mkds/"+Math.floor(Math.random()*36),
|
||
|
r: 1,
|
||
|
m: 1
|
||
|
}))
|
||
|
}
|
||
|
|
||
|
function sendToClient(cli, dat) {
|
||
|
//this function is just here to double check if the client socket hasn't mysteriously closed yet.
|
||
|
//occasionally a socket can close and we will still be sending data before the "onclose" event for that socket fires.
|
||
|
//todo: check if there is a reliable way to determine if a socket has closed
|
||
|
|
||
|
try {
|
||
|
cli.send(dat);
|
||
|
} catch(err) {
|
||
|
console.warn("WARN: failed to send packet to a client. They may have already disconnected.")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.removeClient = function(clientSocket) {
|
||
|
//attempt to remove client -- may not be in this instance!
|
||
|
var ind = sockets.indexOf(clientSocket);
|
||
|
if (ind != -1) sockets.splice(ind, 1); //shouldn't cause any problems.
|
||
|
|
||
|
if (clientSocket.kartID != null) {
|
||
|
//tell all other clients that this client's kart is now inactive.
|
||
|
var dat = JSON.stringify({
|
||
|
t:"-",
|
||
|
k:clientSocket.kartID
|
||
|
});
|
||
|
kartInf[clientSocket.kartID].active = false;
|
||
|
for (var i=0; i<sockets.length; i++) sockets[i].send(dat)
|
||
|
}
|
||
|
|
||
|
if (sockets.length == 0) t.resetInstance();
|
||
|
}
|
||
|
|
||
|
function toArrayBuffer(buffer) { //why are you making my life so difficult :(
|
||
|
var ab = new ArrayBuffer(buffer.length);
|
||
|
var view = new Uint8Array(ab);
|
||
|
for (var i = 0; i < buffer.length; ++i) {
|
||
|
view[i] = buffer[i];
|
||
|
}
|
||
|
return ab;
|
||
|
}
|
||
|
|
||
|
this.handleMessage = function(cli, data, flags) {
|
||
|
if (sockets.indexOf(cli) == null) {
|
||
|
socket.send(JSON.stringify(
|
||
|
{
|
||
|
t: "!",
|
||
|
m: "FATAL ERROR: Server does not recognise client! Are you connecting to the wrong instance?"
|
||
|
}
|
||
|
));
|
||
|
} else {
|
||
|
var d = toArrayBuffer(data);
|
||
|
if (flags.binary) {
|
||
|
//binary data
|
||
|
var view = new DataView(d);
|
||
|
var handler = binH[view.getUint8(0)];
|
||
|
if (handler != null) handler(cli, view);
|
||
|
} else {
|
||
|
//JSON string
|
||
|
var obj;
|
||
|
try {
|
||
|
obj = JSON.parse(d);
|
||
|
} catch (err) {
|
||
|
debugger; //packet recieved from server is bullshit
|
||
|
return;
|
||
|
}
|
||
|
var handler = wsH["$"+obj.t];
|
||
|
if (handler != null) handler(cli, obj);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var binH = [];
|
||
|
binH[32] = function(cli, view) {
|
||
|
if (cli.kartID != null) relkDat.push({k:cli.kartID, d:view.buffer.slice(1)});
|
||
|
}
|
||
|
|
||
|
this.resetInstance = function() {
|
||
|
console.log("instance reset")
|
||
|
userID = 0;
|
||
|
kartInf = [];
|
||
|
relkDat = [];
|
||
|
for (var i=0; i<sockets.length; i++) {
|
||
|
sockets[i].credentials.userID = userID++; //reassign user IDs to clients.
|
||
|
sendClientID(sockets[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function sendClientID(socket) {
|
||
|
socket.send(JSON.stringify(
|
||
|
{
|
||
|
t: "#",
|
||
|
i: socket.credentials.userID
|
||
|
}
|
||
|
));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exports.mkjsInstance = mkjsInstance;
|