[Pages] Make directory structure lowercase.
This commit is contained in:
1 parent
3b47a86756
commit
65ca7d7455
96 files changed
+20116
No files matched your search
@@ -0,0 +1,41 @@
|
||||
// instances are basically individual game servers; it is possible to run more than one on the same server.
|
||||
// the connection to the instance should be the first thing the client sends to the websocket server. the client is then bound to this instance for the duration of the connecton.
|
||||
//
|
||||
// normally a race packet exchange goes like this:
|
||||
//
|
||||
// C -> S: join instance. submit (kartInitFormat) (as obj.c) minus flags.
|
||||
// S -> C: send back instance state, type "*". includes mode m (0 = choose course, 1 = race), data d.
|
||||
//
|
||||
// data d for race is in format {c:(courseName), k:(kartInitFormat[]), r:(tickRate in 1/60 tick duration increments), i:(itemConfig), p:(your kart, or -1 if in spectator mode)}
|
||||
|
||||
// kartInitFormat: {
|
||||
// name: (username),
|
||||
// char: (characterID), //physical character id.
|
||||
// kart: (kartID), //physical kart id.
|
||||
// kModel: (kartModelID, undefined normally. if non zero use model sent by server)
|
||||
// cModel: (charModelID, same as above)
|
||||
// customKParam: (same format as kartoffsetdata entry. note that custom characters always use the same offset. may be undefined.)
|
||||
// flags: (info on player, eg if player is an admin, mod, on mobile etc.)
|
||||
// active: boolean //karts are never deleted - they are just set as inactive after disconnect. the karts list is only completely refreshed on course change or restart.
|
||||
// }
|
||||
//
|
||||
// repeatedly:
|
||||
// C -> S: send kart data every tick. positions and checkpoint numbers
|
||||
// S -> C: send array of updated kart data to back to client
|
||||
//
|
||||
// item request:
|
||||
// C -> S: request item packet (hit itembox), type "ri"
|
||||
// S -> C: return which item to select. type "si", sent to all clients so they know what you have.
|
||||
// C -> S: when the user is ready to use their item, they will create the item and send a message to the server to create it on all sides. this is of type "ci", and includes the tick the item was fired on.
|
||||
// S -> C (all others): type "ci" is mirrored to all other clients, server verifies that client has right to send that item first
|
||||
// ---the item is now on all clients at the correct place---
|
||||
// C -> S: when a client gets hit with an item, they send a packet of type "~i" with reason "h" for hit. "~i" is "change item". items that destroy themselves do not need to send this -
|
||||
// they will annihilate automatically on all clients at the same tick if karts do not interfere.
|
||||
//
|
||||
// S -> C: when a spectator connects to a game in progress, they will be sent all item packets in order in an array with type "pi" (packed items).
|
||||
//
|
||||
// win:
|
||||
// C -> S: completed all laps and finished course. type "w", includes finish tick.
|
||||
// S -> C (all other): "w" mirrored to clients.
|
||||
// C (all other) -> S: "wa" (win acknowledge) - ping back to server to confirm win. we wait until all clients agree or the timeout on the clients occurs (usually 2s)
|
||||
// this is to settle win conflicts.
|
||||
@@ -0,0 +1,169 @@
|
||||
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;
|
||||
Reference in new issue
Block a user