mirror of
https://github.com/d07RiV/diabloweb.git
synced 2026-07-04 12:11:42 +00:00
websocket mode
This commit is contained in:
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "diabloweb",
|
"name": "diabloweb",
|
||||||
"version": "1.0.29",
|
"version": "1.0.30",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "diabloweb",
|
"name": "diabloweb",
|
||||||
"version": "1.0.29",
|
"version": "1.0.30",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "7.4.3",
|
"@babel/core": "7.4.3",
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export class buffer_reader {
|
|||||||
this.pos += length;
|
this.pos += length;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
rest() {
|
read_buf() {
|
||||||
const size = this.read32();
|
const size = this.read32();
|
||||||
const result = this.buffer.subarray(this.pos, this.pos + size);
|
const result = this.buffer.subarray(this.pos, this.pos + size);
|
||||||
this.pos += size;
|
this.pos += size;
|
||||||
@@ -86,11 +86,15 @@ export class buffer_writer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
rest(value) {
|
rest(value) {
|
||||||
this.write32(value.byteLength);
|
|
||||||
this.buffer.set(value, this.pos);
|
this.buffer.set(value, this.pos);
|
||||||
this.pos += value.byteLength;
|
this.pos += value.byteLength;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
write_buf(value) {
|
||||||
|
this.write32(value.byteLength);
|
||||||
|
this.rest(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RejectionReason = {
|
export const RejectionReason = {
|
||||||
@@ -194,9 +198,9 @@ export const server_packet = {
|
|||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
code: 0x01,
|
code: 0x01,
|
||||||
read: reader => ({id: reader.read8(), payload: reader.rest()}),
|
read: reader => ({id: reader.read8(), payload: reader.read_buf()}),
|
||||||
size: ({payload}) => 5 + payload.byteLength,
|
size: ({payload}) => 5 + payload.byteLength,
|
||||||
write: (writer, {id, payload}) => writer.write8(id).rest(payload),
|
write: (writer, {id, payload}) => writer.write8(id).write_buf(payload),
|
||||||
},
|
},
|
||||||
turn: {
|
turn: {
|
||||||
code: 0x02,
|
code: 0x02,
|
||||||
@@ -246,9 +250,9 @@ export const client_packet = {
|
|||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
code: 0x01,
|
code: 0x01,
|
||||||
read: reader => ({id: reader.read8(), payload: reader.rest()}),
|
read: reader => ({id: reader.read8(), payload: reader.read_buf()}),
|
||||||
size: ({payload}) => 5 + payload.byteLength,
|
size: ({payload}) => 5 + payload.byteLength,
|
||||||
write: (writer, {id, payload}) => writer.write8(id).rest(payload),
|
write: (writer, {id, payload}) => writer.write8(id).write_buf(payload),
|
||||||
},
|
},
|
||||||
turn: {
|
turn: {
|
||||||
code: 0x02,
|
code: 0x02,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class webrtc_server {
|
|||||||
this.seed = Math.floor(Math.random() * Math.pow(2, 32));
|
this.seed = Math.floor(Math.random() * Math.pow(2, 32));
|
||||||
|
|
||||||
const onError = () => {
|
const onError = () => {
|
||||||
onMessage(server_packet.join_reject.write({cookie, reason: RejectionReason.CREATE_GAME_EXISTS}));
|
onMessage(write_packet(server_packet.join_reject, {cookie, reason: RejectionReason.CREATE_GAME_EXISTS}));
|
||||||
onClose();
|
onClose();
|
||||||
this.peer.off('error', onError);
|
this.peer.off('error', onError);
|
||||||
this.peer.off('open', onOpen);
|
this.peer.off('open', onOpen);
|
||||||
@@ -39,8 +39,8 @@ class webrtc_server {
|
|||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
//console.log('peer open');
|
//console.log('peer open');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
onMessage(server_packet.join_accept.write({cookie, index: 0, seed: this.seed, difficulty}));
|
onMessage(write_packet(server_packet.join_accept, {cookie, index: 0, seed: this.seed, difficulty}));
|
||||||
onMessage(server_packet.connect.write({id: 0}));
|
onMessage(write_packet(server_packet.connect, {id: 0}));
|
||||||
}, 0);
|
}, 0);
|
||||||
this.peer.off('error', onError);
|
this.peer.off('error', onError);
|
||||||
this.peer.off('open', onOpen);
|
this.peer.off('open', onOpen);
|
||||||
@@ -64,23 +64,23 @@ class webrtc_server {
|
|||||||
break;
|
break;
|
||||||
case client_packet.join_game.code:
|
case client_packet.join_game.code:
|
||||||
if (peer.version !== this.version) {
|
if (peer.version !== this.version) {
|
||||||
conn.send(server_packet.join_reject.write({cookie: pkt.cookie, reason: RejectionReason.JOIN_VERSION_MISMATCH}));
|
conn.send(write_packet(server_packet.join_reject, {cookie: pkt.cookie, reason: RejectionReason.JOIN_VERSION_MISMATCH}));
|
||||||
} else if (pkt.name !== this.name) {
|
} else if (pkt.name !== this.name) {
|
||||||
conn.send(server_packet.join_reject.write({cookie: pkt.cookie, reason: RejectionReason.JOIN_GAME_NOT_FOUND}));
|
conn.send(write_packet(server_packet.join_reject, {cookie: pkt.cookie, reason: RejectionReason.JOIN_GAME_NOT_FOUND}));
|
||||||
} else if (pkt.password !== this.password) {
|
} else if (pkt.password !== this.password) {
|
||||||
conn.send(server_packet.join_reject.write({cookie: pkt.cookie, reason: RejectionReason.JOIN_INCORRECT_PASSWORD}));
|
conn.send(write_packet(server_packet.join_reject, {cookie: pkt.cookie, reason: RejectionReason.JOIN_INCORRECT_PASSWORD}));
|
||||||
} else {
|
} else {
|
||||||
let i = 1;
|
let i = 1;
|
||||||
while (i < MAX_PLRS && this.players[i]) {
|
while (i < MAX_PLRS && this.players[i]) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
if (i >= MAX_PLRS) {
|
if (i >= MAX_PLRS) {
|
||||||
conn.send(server_packet.join_reject.write({cookie: pkt.cookie, reason: RejectionReason.JOIN_GAME_FULL}));
|
conn.send(write_packet(server_packet.join_reject, {cookie: pkt.cookie, reason: RejectionReason.JOIN_GAME_FULL}));
|
||||||
} else {
|
} else {
|
||||||
this.players[i] = peer;
|
this.players[i] = peer;
|
||||||
peer.id = i;
|
peer.id = i;
|
||||||
conn.send(server_packet.join_accept.write({cookie: pkt.cookie, index: i, seed: this.seed, difficulty: this.difficulty}));
|
conn.send(write_packet(server_packet.join_accept, {cookie: pkt.cookie, index: i, seed: this.seed, difficulty: this.difficulty}));
|
||||||
this.send(0xFF, server_packet.connect.write({id: i}));
|
this.send(0xFF, write_packet(server_packet.connect, {id: i}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -122,11 +122,11 @@ class webrtc_server {
|
|||||||
for (let i = 1; i < MAX_PLRS; ++i) {
|
for (let i = 1; i < MAX_PLRS; ++i) {
|
||||||
this.drop(i, 0x40000006);
|
this.drop(i, 0x40000006);
|
||||||
}
|
}
|
||||||
this.onMessage(server_packet.disconnect.write({id, reason}));
|
this.onMessage(write_packet(server_packet.disconnect, {id, reason}));
|
||||||
this.peer.destroy();
|
this.peer.destroy();
|
||||||
this.onClose();
|
this.onClose();
|
||||||
} else if (this.players[id]) {
|
} else if (this.players[id]) {
|
||||||
this.send(0xFF, server_packet.disconnect.write({id, reason}));
|
this.send(0xFF, write_packet(server_packet.disconnect, {id, reason}));
|
||||||
this.players[id].id = null;
|
this.players[id].id = null;
|
||||||
if (this.players[id].conn) {
|
if (this.players[id].conn) {
|
||||||
this.players[id].conn.close();
|
this.players[id].conn.close();
|
||||||
@@ -144,10 +144,10 @@ class webrtc_server {
|
|||||||
this.drop(pkt.id, pkt.reason);
|
this.drop(pkt.id, pkt.reason);
|
||||||
break;
|
break;
|
||||||
case client_packet.message.code:
|
case client_packet.message.code:
|
||||||
this.send(pkt.id === 0xFF ? ~(1 << id) : (1 << pkt.id), server_packet.message.write({id, payload: pkt.payload}));
|
this.send(pkt.id === 0xFF ? ~(1 << id) : (1 << pkt.id), write_packet(server_packet.message, {id, payload: pkt.payload}));
|
||||||
break;
|
break;
|
||||||
case client_packet.turn.code:
|
case client_packet.turn.code:
|
||||||
this.send(~(1 << id), server_packet.turn.write({id, turn: pkt.turn}));
|
this.send(~(1 << id), write_packet(server_packet.turn, {id, turn: pkt.turn}));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw Error(`invalid packet ${code}`);
|
throw Error(`invalid packet ${code}`);
|
||||||
@@ -174,13 +174,13 @@ class webrtc_client {
|
|||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
};
|
};
|
||||||
const onError = () => {
|
const onError = () => {
|
||||||
onMessage(server_packet.join_reject.write({cookie, reason: RejectionReason.JOIN_GAME_NOT_FOUND}));
|
onMessage(write_packet(server_packet.join_reject, {cookie, reason: RejectionReason.JOIN_GAME_NOT_FOUND}));
|
||||||
onClose();
|
onClose();
|
||||||
unreg();
|
unreg();
|
||||||
};
|
};
|
||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
this.conn.send(client_packet.info.write({version}));
|
this.conn.send(write_packet(client_packet.info, {version}));
|
||||||
this.conn.send(client_packet.join_game.write({cookie, name, password}));
|
this.conn.send(write_packet(client_packet.join_game, {cookie, name, password}));
|
||||||
for (let pkt of this.pending) {
|
for (let pkt of this.pending) {
|
||||||
this.conn.send(pkt);
|
this.conn.send(pkt);
|
||||||
}
|
}
|
||||||
@@ -251,14 +251,14 @@ export default function webrtc_open(onMessage) {
|
|||||||
break;
|
break;
|
||||||
case client_packet.create_game.code:
|
case client_packet.create_game.code:
|
||||||
if (server || client) {
|
if (server || client) {
|
||||||
onMessage(server_packet.join_reject.write({cookie: pkt.cookie, reason: RejectionReason.JOIN_ALREADY_IN_GAME}));
|
onMessage(write_packet(server_packet.join_reject, {cookie: pkt.cookie, reason: RejectionReason.JOIN_ALREADY_IN_GAME}));
|
||||||
} else {
|
} else {
|
||||||
server = new webrtc_server(version, pkt, onMessage, () => server = null);
|
server = new webrtc_server(version, pkt, onMessage, () => server = null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case client_packet.join_game.code:
|
case client_packet.join_game.code:
|
||||||
if (server || client) {
|
if (server || client) {
|
||||||
onMessage(server_packet.join_reject.write({cookie: pkt.cookie, reason: RejectionReason.JOIN_ALREADY_IN_GAME}));
|
onMessage(write_packet(server_packet.join_reject, {cookie: pkt.cookie, reason: RejectionReason.JOIN_ALREADY_IN_GAME}));
|
||||||
} else {
|
} else {
|
||||||
client = new webrtc_client(version, pkt, onMessage, () => client = null);
|
client = new webrtc_client(version, pkt, onMessage, () => client = null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,32 +48,46 @@ async function do_websocket_open(url, handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function websocket_open(url, handler, finisher) {
|
export default function websocket_open(url, handler, finisher) {
|
||||||
let ws = null, pending = [];
|
let ws = null, batch = [], intr = null;
|
||||||
const proxy = {
|
const proxy = {
|
||||||
get readyState() {
|
get readyState() {
|
||||||
return ws ? ws.readyState : 0;
|
return ws ? ws.readyState : 0;
|
||||||
},
|
},
|
||||||
send(msg) {
|
send(msg) {
|
||||||
if (ws) {
|
batch.push(msg.slice());
|
||||||
ws.send(msg);
|
|
||||||
} else {
|
|
||||||
pending.push(msg.slice());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
|
if (intr) {
|
||||||
|
clearInterval(intr);
|
||||||
|
intr = null;
|
||||||
|
}
|
||||||
if (ws) {
|
if (ws) {
|
||||||
ws.close();
|
ws.close();
|
||||||
} else {
|
} else {
|
||||||
pending = null;
|
batch = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
do_websocket_open(url, handler).then(sock => {
|
do_websocket_open(url, handler).then(sock => {
|
||||||
ws = sock;
|
ws = sock;
|
||||||
if (pending) {
|
if (batch) {
|
||||||
for (let msg of pending) {
|
intr = setInterval(() => {
|
||||||
ws.send(msg);
|
if (!batch.length) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
const size = batch.reduce((sum, msg) => sum + msg.byteLength, 3);
|
||||||
|
const buffer = new Uint8Array(size);
|
||||||
|
buffer[0] = 0;
|
||||||
|
buffer[1] = (batch.length & 0xFF);
|
||||||
|
buffer[2] = batch.length >> 8;
|
||||||
|
let pos = 3;
|
||||||
|
for (let msg of batch) {
|
||||||
|
buffer.set(msg, pos);
|
||||||
|
pos += msg.byteLength;
|
||||||
|
}
|
||||||
|
ws.send(buffer);
|
||||||
|
batch.length = 0;
|
||||||
|
}, 100);
|
||||||
} else {
|
} else {
|
||||||
ws.close();
|
ws.close();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user