@bloopjs/bloop 0.0.80 → 0.0.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bloop.d.ts.map +1 -1
- package/dist/mod.js +297 -83
- package/dist/mod.js.map +6 -7
- package/dist/sim.d.ts +45 -17
- package/dist/sim.d.ts.map +1 -1
- package/dist/system.d.ts +5 -0
- package/dist/system.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/bloop.ts +64 -3
- package/src/sim.ts +158 -26
- package/src/system.ts +8 -0
- package/dist/net.d.ts +0 -60
- package/dist/net.d.ts.map +0 -1
- package/src/net.ts +0 -138
package/dist/bloop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bloop.d.ts","sourceRoot":"","sources":["../src/bloop.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bloop.d.ts","sourceRoot":"","sources":["../src/bloop.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,GAAG,IAAI;IACrC,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IAEH;;OAEG;IAEH;;;OAGG;IACH,GAAG,CAAC,EAAE,CAAC,CAAC;CAET,CAAC;AAEF,qBAAa,KAAK,CAAC,EAAE,SAAS,WAAW;;IAKvC;;OAEG;IACH,MAAM,CAAC,MAAM,CAGX,CAAC,SAAS,GAAG,EAGb,IAAI,GAAE,SAAS,CAAC,CAAC,CAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAI5C;;OAEG;gBACS,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,YAAK,EAAE,kBAAkB,EAAE,MAAM;IAoBrE;;OAEG;IACH,IAAI,GAAG,IAAI,EAAE,CAAC,GAAG,CAAC,CAEjB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAEnC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM;IAMjD;;OAEG;IACH,KAAK,EAAE,WAAW,CAmNhB;CACH;AAUD,KAAK,MAAM,CAAC,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/mod.js
CHANGED
|
@@ -104,6 +104,7 @@ var __export2 = (target, all) => {
|
|
|
104
104
|
};
|
|
105
105
|
var exports_enums = {};
|
|
106
106
|
__export2(exports_enums, {
|
|
107
|
+
NetJoinFailReason: () => NetJoinFailReason,
|
|
107
108
|
MouseButton: () => MouseButton,
|
|
108
109
|
Key: () => Key,
|
|
109
110
|
InputSource: () => InputSource,
|
|
@@ -119,11 +120,13 @@ var EventType;
|
|
|
119
120
|
EventType2[EventType2["MouseUp"] = 5] = "MouseUp";
|
|
120
121
|
EventType2[EventType2["MouseWheel"] = 6] = "MouseWheel";
|
|
121
122
|
EventType2[EventType2["FrameStart"] = 7] = "FrameStart";
|
|
122
|
-
EventType2[EventType2["
|
|
123
|
-
EventType2[EventType2["
|
|
124
|
-
EventType2[EventType2["
|
|
125
|
-
EventType2[EventType2["
|
|
126
|
-
EventType2[EventType2["
|
|
123
|
+
EventType2[EventType2["NetJoinOk"] = 8] = "NetJoinOk";
|
|
124
|
+
EventType2[EventType2["NetJoinFail"] = 9] = "NetJoinFail";
|
|
125
|
+
EventType2[EventType2["NetPeerJoin"] = 10] = "NetPeerJoin";
|
|
126
|
+
EventType2[EventType2["NetPeerLeave"] = 11] = "NetPeerLeave";
|
|
127
|
+
EventType2[EventType2["NetPeerAssignLocalId"] = 12] = "NetPeerAssignLocalId";
|
|
128
|
+
EventType2[EventType2["NetPacketReceived"] = 13] = "NetPacketReceived";
|
|
129
|
+
EventType2[EventType2["NetSessionInit"] = 14] = "NetSessionInit";
|
|
127
130
|
})(EventType ||= {});
|
|
128
131
|
var MouseButton;
|
|
129
132
|
((MouseButton2) => {
|
|
@@ -367,6 +370,14 @@ var InputSource;
|
|
|
367
370
|
InputSource2[InputSource2["RemotePeer11"] = 139] = "RemotePeer11";
|
|
368
371
|
InputSource2[InputSource2["Unmapped"] = 255] = "Unmapped";
|
|
369
372
|
})(InputSource ||= {});
|
|
373
|
+
var NetJoinFailReason;
|
|
374
|
+
((NetJoinFailReason2) => {
|
|
375
|
+
NetJoinFailReason2[NetJoinFailReason2["unknown"] = 0] = "unknown";
|
|
376
|
+
NetJoinFailReason2[NetJoinFailReason2["timeout"] = 1] = "timeout";
|
|
377
|
+
NetJoinFailReason2[NetJoinFailReason2["room_full"] = 2] = "room_full";
|
|
378
|
+
NetJoinFailReason2[NetJoinFailReason2["room_not_found"] = 3] = "room_not_found";
|
|
379
|
+
NetJoinFailReason2[NetJoinFailReason2["already_in_room"] = 4] = "already_in_room";
|
|
380
|
+
})(NetJoinFailReason ||= {});
|
|
370
381
|
var MAX_PLAYERS = 12;
|
|
371
382
|
var KEYBOARD_OFFSET = 0;
|
|
372
383
|
var KEYBOARD_SIZE = 256;
|
|
@@ -1120,30 +1131,171 @@ class KeyboardContext {
|
|
|
1120
1131
|
return state;
|
|
1121
1132
|
}
|
|
1122
1133
|
}
|
|
1134
|
+
var MAX_PEERS = 12;
|
|
1135
|
+
var PEERS_ARRAY_OFFSET = 32;
|
|
1136
|
+
var PEER_CTX_SIZE = 8;
|
|
1137
|
+
var PEER_CONNECTED_OFFSET = 0;
|
|
1138
|
+
var PEER_PACKET_COUNT_OFFSET = 1;
|
|
1139
|
+
var PEER_SEQ_OFFSET = 2;
|
|
1140
|
+
var PEER_ACK_OFFSET = 4;
|
|
1141
|
+
var PEER_ACK_COUNT_OFFSET = 6;
|
|
1142
|
+
var STATUS_MAP = {
|
|
1143
|
+
0: "offline",
|
|
1144
|
+
1: "local",
|
|
1145
|
+
2: "join:pending",
|
|
1146
|
+
3: "connected",
|
|
1147
|
+
4: "disconnected"
|
|
1148
|
+
};
|
|
1123
1149
|
|
|
1124
1150
|
class NetContext {
|
|
1125
1151
|
dataView;
|
|
1152
|
+
#peers = Array.from({ length: MAX_PEERS }, () => ({
|
|
1153
|
+
isLocal: false,
|
|
1154
|
+
seq: -1,
|
|
1155
|
+
ack: -1
|
|
1156
|
+
}));
|
|
1157
|
+
#peersResult = [];
|
|
1126
1158
|
constructor(dataView) {
|
|
1127
1159
|
this.dataView = dataView;
|
|
1128
1160
|
}
|
|
1161
|
+
#hasValidBuffer() {
|
|
1162
|
+
if (!this.dataView)
|
|
1163
|
+
return false;
|
|
1164
|
+
return this.dataView.buffer.byteLength > 0;
|
|
1165
|
+
}
|
|
1129
1166
|
get peerCount() {
|
|
1130
|
-
if (!this
|
|
1131
|
-
throw new Error("NetContext
|
|
1167
|
+
if (!this.#hasValidBuffer()) {
|
|
1168
|
+
throw new Error("NetContext dataView is not valid");
|
|
1132
1169
|
}
|
|
1133
1170
|
return this.dataView.getUint8(0);
|
|
1134
1171
|
}
|
|
1172
|
+
get localPeerId() {
|
|
1173
|
+
if (!this.#hasValidBuffer()) {
|
|
1174
|
+
throw new Error("NetContext dataView is not valid");
|
|
1175
|
+
}
|
|
1176
|
+
return this.dataView.getUint8(1);
|
|
1177
|
+
}
|
|
1135
1178
|
get isInSession() {
|
|
1136
|
-
if (!this
|
|
1137
|
-
throw new Error("NetContext
|
|
1179
|
+
if (!this.#hasValidBuffer()) {
|
|
1180
|
+
throw new Error("NetContext dataView is not valid");
|
|
1138
1181
|
}
|
|
1139
1182
|
return this.dataView.getUint8(2) !== 0;
|
|
1140
1183
|
}
|
|
1184
|
+
get status() {
|
|
1185
|
+
if (!this.#hasValidBuffer()) {
|
|
1186
|
+
throw new Error("NetContext dataView is not valid");
|
|
1187
|
+
}
|
|
1188
|
+
const statusByte = this.dataView.getUint8(3);
|
|
1189
|
+
return STATUS_MAP[statusByte] ?? "local";
|
|
1190
|
+
}
|
|
1141
1191
|
get matchFrame() {
|
|
1142
|
-
if (!this
|
|
1143
|
-
throw new Error("NetContext
|
|
1192
|
+
if (!this.#hasValidBuffer()) {
|
|
1193
|
+
throw new Error("NetContext dataView is not valid");
|
|
1144
1194
|
}
|
|
1145
1195
|
return this.dataView.getUint32(4, true);
|
|
1146
1196
|
}
|
|
1197
|
+
get sessionStartFrame() {
|
|
1198
|
+
if (!this.#hasValidBuffer()) {
|
|
1199
|
+
throw new Error("NetContext dataView is not valid");
|
|
1200
|
+
}
|
|
1201
|
+
return this.dataView.getUint32(8, true);
|
|
1202
|
+
}
|
|
1203
|
+
get roomCode() {
|
|
1204
|
+
if (!this.#hasValidBuffer()) {
|
|
1205
|
+
throw new Error("NetContext dataView is not valid");
|
|
1206
|
+
}
|
|
1207
|
+
const bytes = [];
|
|
1208
|
+
for (let i = 0;i < 8; i++) {
|
|
1209
|
+
const byte = this.dataView.getUint8(12 + i);
|
|
1210
|
+
if (byte === 0)
|
|
1211
|
+
break;
|
|
1212
|
+
bytes.push(byte);
|
|
1213
|
+
}
|
|
1214
|
+
return String.fromCharCode(...bytes);
|
|
1215
|
+
}
|
|
1216
|
+
get wantsRoomCode() {
|
|
1217
|
+
if (!this.#hasValidBuffer()) {
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
const bytes = [];
|
|
1221
|
+
for (let i = 0;i < 8; i++) {
|
|
1222
|
+
const byte = this.dataView.getUint8(20 + i);
|
|
1223
|
+
if (byte === 0)
|
|
1224
|
+
break;
|
|
1225
|
+
bytes.push(byte);
|
|
1226
|
+
}
|
|
1227
|
+
return bytes.length > 0 ? String.fromCharCode(...bytes) : undefined;
|
|
1228
|
+
}
|
|
1229
|
+
set wantsRoomCode(code) {
|
|
1230
|
+
if (!this.#hasValidBuffer()) {
|
|
1231
|
+
throw new Error("NetContext dataView is not valid");
|
|
1232
|
+
}
|
|
1233
|
+
for (let i = 0;i < 8; i++) {
|
|
1234
|
+
this.dataView.setUint8(20 + i, 0);
|
|
1235
|
+
}
|
|
1236
|
+
if (code) {
|
|
1237
|
+
for (let i = 0;i < Math.min(code.length, 7); i++) {
|
|
1238
|
+
this.dataView.setUint8(20 + i, code.charCodeAt(i));
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
get wantsDisconnect() {
|
|
1243
|
+
if (!this.#hasValidBuffer()) {
|
|
1244
|
+
return false;
|
|
1245
|
+
}
|
|
1246
|
+
return this.dataView.getUint8(28) !== 0;
|
|
1247
|
+
}
|
|
1248
|
+
set wantsDisconnect(value) {
|
|
1249
|
+
if (!this.#hasValidBuffer()) {
|
|
1250
|
+
throw new Error("NetContext dataView is not valid");
|
|
1251
|
+
}
|
|
1252
|
+
this.dataView.setUint8(28, value ? 1 : 0);
|
|
1253
|
+
}
|
|
1254
|
+
get peers() {
|
|
1255
|
+
if (!this.#hasValidBuffer()) {
|
|
1256
|
+
throw new Error("NetContext dataView is not valid");
|
|
1257
|
+
}
|
|
1258
|
+
const dv = this.dataView;
|
|
1259
|
+
const localPeerId = this.localPeerId;
|
|
1260
|
+
const matchFrame = this.matchFrame;
|
|
1261
|
+
let minRemoteSeq = -1;
|
|
1262
|
+
for (let i = 0;i < MAX_PEERS; i++) {
|
|
1263
|
+
if (i === localPeerId)
|
|
1264
|
+
continue;
|
|
1265
|
+
const peerOffset = PEERS_ARRAY_OFFSET + i * PEER_CTX_SIZE;
|
|
1266
|
+
if (dv.getUint8(peerOffset + PEER_CONNECTED_OFFSET) !== 1)
|
|
1267
|
+
continue;
|
|
1268
|
+
if (dv.getUint8(peerOffset + PEER_PACKET_COUNT_OFFSET) === 0)
|
|
1269
|
+
continue;
|
|
1270
|
+
const seq = dv.getUint16(peerOffset + PEER_SEQ_OFFSET, true);
|
|
1271
|
+
if (minRemoteSeq === -1 || seq < minRemoteSeq) {
|
|
1272
|
+
minRemoteSeq = seq;
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
this.#peersResult.length = 0;
|
|
1276
|
+
for (let i = 0;i < MAX_PEERS; i++) {
|
|
1277
|
+
const peerOffset = PEERS_ARRAY_OFFSET + i * PEER_CTX_SIZE;
|
|
1278
|
+
if (dv.getUint8(peerOffset + PEER_CONNECTED_OFFSET) !== 1)
|
|
1279
|
+
continue;
|
|
1280
|
+
const peer = this.#peers[i];
|
|
1281
|
+
if (!peer) {
|
|
1282
|
+
throw new Error(`Unexpected missing peer object at index ${i}`);
|
|
1283
|
+
}
|
|
1284
|
+
const isLocal = i === localPeerId;
|
|
1285
|
+
peer.isLocal = isLocal;
|
|
1286
|
+
if (isLocal) {
|
|
1287
|
+
peer.seq = matchFrame;
|
|
1288
|
+
peer.ack = minRemoteSeq;
|
|
1289
|
+
} else {
|
|
1290
|
+
const packetCount = dv.getUint8(peerOffset + PEER_PACKET_COUNT_OFFSET);
|
|
1291
|
+
const ackCount = dv.getUint8(peerOffset + PEER_ACK_COUNT_OFFSET);
|
|
1292
|
+
peer.seq = packetCount === 0 ? -1 : dv.getUint16(peerOffset + PEER_SEQ_OFFSET, true);
|
|
1293
|
+
peer.ack = ackCount === 0 ? -1 : dv.getUint16(peerOffset + PEER_ACK_OFFSET, true);
|
|
1294
|
+
}
|
|
1295
|
+
this.#peersResult.push(peer);
|
|
1296
|
+
}
|
|
1297
|
+
return this.#peersResult;
|
|
1298
|
+
}
|
|
1147
1299
|
}
|
|
1148
1300
|
|
|
1149
1301
|
class TimeContext {
|
|
@@ -1185,7 +1337,7 @@ function readTapeHeader(tape) {
|
|
|
1185
1337
|
eventCount: view.getUint16(14, true)
|
|
1186
1338
|
};
|
|
1187
1339
|
}
|
|
1188
|
-
var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.
|
|
1340
|
+
var DEFAULT_WASM_URL = new URL("https://unpkg.com/@bloopjs/engine@0.0.82/wasm/bloop.wasm");
|
|
1189
1341
|
var MAX_ROLLBACK_FRAMES = 500;
|
|
1190
1342
|
var TIME_CTX_OFFSET = 0;
|
|
1191
1343
|
var INPUT_CTX_OFFSET = TIME_CTX_OFFSET + 4;
|
|
@@ -1194,64 +1346,6 @@ var NET_CTX_OFFSET = EVENTS_OFFSET + 4;
|
|
|
1194
1346
|
var SNAPSHOT_HEADER_LEN = 16;
|
|
1195
1347
|
var SNAPSHOT_HEADER_USER_LEN_OFFSET = 4;
|
|
1196
1348
|
var SNAPSHOT_HEADER_ENGINE_LEN_OFFSET = 8;
|
|
1197
|
-
// src/net.ts
|
|
1198
|
-
class Net {
|
|
1199
|
-
#wasm;
|
|
1200
|
-
#memory;
|
|
1201
|
-
constructor(wasm, memory) {
|
|
1202
|
-
this.#wasm = wasm;
|
|
1203
|
-
this.#memory = memory;
|
|
1204
|
-
}
|
|
1205
|
-
setLocalPeer(peerId) {
|
|
1206
|
-
this.#wasm.session_set_local_peer(peerId);
|
|
1207
|
-
}
|
|
1208
|
-
connectPeer(peerId) {
|
|
1209
|
-
this.#wasm.session_peer_connect(peerId);
|
|
1210
|
-
}
|
|
1211
|
-
disconnectPeer(peerId) {
|
|
1212
|
-
this.#wasm.session_peer_disconnect(peerId);
|
|
1213
|
-
}
|
|
1214
|
-
getOutboundPacket(targetPeer) {
|
|
1215
|
-
this.#wasm.build_outbound_packet(targetPeer);
|
|
1216
|
-
const len = this.#wasm.get_outbound_packet_len();
|
|
1217
|
-
if (len === 0) {
|
|
1218
|
-
return null;
|
|
1219
|
-
}
|
|
1220
|
-
const ptr = this.#wasm.get_outbound_packet();
|
|
1221
|
-
assert(ptr > 0, `Invalid outbound packet pointer: ${ptr}`);
|
|
1222
|
-
const memoryView = new Uint8Array(this.#memory.buffer, ptr, len);
|
|
1223
|
-
const copy = new Uint8Array(len);
|
|
1224
|
-
copy.set(memoryView);
|
|
1225
|
-
return copy;
|
|
1226
|
-
}
|
|
1227
|
-
receivePacket(data) {
|
|
1228
|
-
if (data.length === 0) {
|
|
1229
|
-
return;
|
|
1230
|
-
}
|
|
1231
|
-
const ptr = this.#wasm.alloc(data.byteLength);
|
|
1232
|
-
assert(ptr > 0, `Failed to allocate ${data.byteLength} bytes for received packet`);
|
|
1233
|
-
const memoryView = new Uint8Array(this.#memory.buffer, ptr, data.byteLength);
|
|
1234
|
-
memoryView.set(data);
|
|
1235
|
-
const result = this.#wasm.receive_packet(ptr, data.byteLength);
|
|
1236
|
-
this.#wasm.free(ptr, data.byteLength);
|
|
1237
|
-
if (result !== 0) {
|
|
1238
|
-
const errorMessages = {
|
|
1239
|
-
1: "No active session",
|
|
1240
|
-
2: "Buffer too small",
|
|
1241
|
-
3: "Unsupported packet version",
|
|
1242
|
-
4: "Invalid event count"
|
|
1243
|
-
};
|
|
1244
|
-
throw new Error(errorMessages[result] ?? `Unknown packet error: ${result}`);
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
getPeerState(peer) {
|
|
1248
|
-
return {
|
|
1249
|
-
seq: this.#wasm.get_peer_seq(peer),
|
|
1250
|
-
ack: this.#wasm.get_peer_ack(peer)
|
|
1251
|
-
};
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
1349
|
// src/sim.ts
|
|
1256
1350
|
var originalConsole = globalThis.console;
|
|
1257
1351
|
var noop = () => {};
|
|
@@ -1270,7 +1364,7 @@ class Sim {
|
|
|
1270
1364
|
#time;
|
|
1271
1365
|
#serialize;
|
|
1272
1366
|
#isPaused = false;
|
|
1273
|
-
net;
|
|
1367
|
+
#net;
|
|
1274
1368
|
onTapeFull;
|
|
1275
1369
|
constructor(wasm, memory, opts) {
|
|
1276
1370
|
this.wasm = wasm;
|
|
@@ -1278,7 +1372,7 @@ class Sim {
|
|
|
1278
1372
|
this.#time = new TimeContext(new DataView(this.#memory.buffer, this.wasm.get_time_ctx()));
|
|
1279
1373
|
this.id = `${Math.floor(Math.random() * 1e6)}`;
|
|
1280
1374
|
this.#serialize = opts?.serialize;
|
|
1281
|
-
this
|
|
1375
|
+
this.#net = new NetContext;
|
|
1282
1376
|
}
|
|
1283
1377
|
step(ms) {
|
|
1284
1378
|
if (this.#isPaused) {
|
|
@@ -1359,7 +1453,9 @@ class Sim {
|
|
|
1359
1453
|
assert(tapePtr > 0, `failed to allocate ${tape.byteLength} bytes for tape load, pointer=${tapePtr}`);
|
|
1360
1454
|
const memoryView = new Uint8Array(this.#memory.buffer, tapePtr, tape.byteLength);
|
|
1361
1455
|
memoryView.set(tape);
|
|
1362
|
-
this.
|
|
1456
|
+
if (this.isRecording) {
|
|
1457
|
+
this.wasm.stop_recording();
|
|
1458
|
+
}
|
|
1363
1459
|
const result = this.wasm.load_tape(tapePtr, tape.byteLength);
|
|
1364
1460
|
assert(result === 0, `failed to load tape, error code=${result}`);
|
|
1365
1461
|
this.wasm.free(tapePtr, tape.byteLength);
|
|
@@ -1381,6 +1477,12 @@ class Sim {
|
|
|
1381
1477
|
}
|
|
1382
1478
|
return this.#time;
|
|
1383
1479
|
}
|
|
1480
|
+
get net() {
|
|
1481
|
+
if (!this.#net.dataView || this.#net.dataView.buffer !== this.#memory.buffer) {
|
|
1482
|
+
this.#net.dataView = new DataView(this.#memory.buffer, this.wasm.get_net_ctx());
|
|
1483
|
+
}
|
|
1484
|
+
return this.#net;
|
|
1485
|
+
}
|
|
1384
1486
|
get buffer() {
|
|
1385
1487
|
return this.#memory.buffer;
|
|
1386
1488
|
}
|
|
@@ -1411,16 +1513,77 @@ class Sim {
|
|
|
1411
1513
|
},
|
|
1412
1514
|
mousewheel: (x, y, peerId = 0) => {
|
|
1413
1515
|
this.wasm.emit_mousewheel(x, y, peerId);
|
|
1516
|
+
},
|
|
1517
|
+
network: (type, data) => {
|
|
1518
|
+
switch (type) {
|
|
1519
|
+
case "join:ok": {
|
|
1520
|
+
const roomCode = data.roomCode;
|
|
1521
|
+
const encoded = new TextEncoder().encode(roomCode);
|
|
1522
|
+
const ptr = this.wasm.alloc(encoded.length);
|
|
1523
|
+
new Uint8Array(this.#memory.buffer, ptr, encoded.length).set(encoded);
|
|
1524
|
+
this.wasm.emit_net_join_ok(ptr, encoded.length);
|
|
1525
|
+
this.wasm.free(ptr, encoded.length);
|
|
1526
|
+
break;
|
|
1527
|
+
}
|
|
1528
|
+
case "join:fail":
|
|
1529
|
+
this.wasm.emit_net_join_fail(0);
|
|
1530
|
+
break;
|
|
1531
|
+
case "peer:join": {
|
|
1532
|
+
const peerId = data.peerId;
|
|
1533
|
+
this.wasm.emit_net_peer_join(peerId);
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
case "peer:leave": {
|
|
1537
|
+
const peerId = data.peerId;
|
|
1538
|
+
this.wasm.emit_net_peer_leave(peerId);
|
|
1539
|
+
break;
|
|
1540
|
+
}
|
|
1541
|
+
case "peer:assign_local_id": {
|
|
1542
|
+
const peerId = data.peerId;
|
|
1543
|
+
this.wasm.emit_net_peer_assign_local_id(peerId);
|
|
1544
|
+
break;
|
|
1545
|
+
}
|
|
1546
|
+
case "session:start":
|
|
1547
|
+
this.wasm.emit_net_session_init();
|
|
1548
|
+
break;
|
|
1549
|
+
case "session:end":
|
|
1550
|
+
this.wasm.emit_net_session_end();
|
|
1551
|
+
break;
|
|
1552
|
+
}
|
|
1553
|
+
},
|
|
1554
|
+
packet: (data) => {
|
|
1555
|
+
if (data.length === 0) {
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
const ptr = this.wasm.alloc(data.byteLength);
|
|
1559
|
+
assert(ptr > 0, `Failed to allocate ${data.byteLength} bytes for received packet`);
|
|
1560
|
+
const memoryView = new Uint8Array(this.#memory.buffer, ptr, data.byteLength);
|
|
1561
|
+
memoryView.set(data);
|
|
1562
|
+
const result = this.wasm.emit_receive_packet(ptr, data.byteLength);
|
|
1563
|
+
this.wasm.free(ptr, data.byteLength);
|
|
1564
|
+
if (result !== 0) {
|
|
1565
|
+
const errorMessages = {
|
|
1566
|
+
1: "No active session",
|
|
1567
|
+
2: "Buffer too small",
|
|
1568
|
+
3: "Unsupported packet version",
|
|
1569
|
+
4: "Invalid event count"
|
|
1570
|
+
};
|
|
1571
|
+
throw new Error(errorMessages[result] ?? `Unknown packet error: ${result}`);
|
|
1572
|
+
}
|
|
1414
1573
|
}
|
|
1415
1574
|
};
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
const
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1575
|
+
getOutboundPacket(targetPeer) {
|
|
1576
|
+
this.wasm.build_outbound_packet(targetPeer);
|
|
1577
|
+
const len = this.wasm.get_outbound_packet_len();
|
|
1578
|
+
if (len === 0) {
|
|
1579
|
+
throw new Error(`No outbound packet available for peer ${targetPeer}`);
|
|
1580
|
+
}
|
|
1581
|
+
const ptr = this.wasm.get_outbound_packet();
|
|
1582
|
+
assert(ptr > 0, `Invalid outbound packet pointer: ${ptr}`);
|
|
1583
|
+
const memoryView = new Uint8Array(this.#memory.buffer, ptr, len);
|
|
1584
|
+
const copy = new Uint8Array(len);
|
|
1585
|
+
copy.set(memoryView);
|
|
1586
|
+
return copy;
|
|
1424
1587
|
}
|
|
1425
1588
|
}
|
|
1426
1589
|
|
|
@@ -1641,8 +1804,59 @@ class Bloop {
|
|
|
1641
1804
|
y: payloadVec2.y
|
|
1642
1805
|
}));
|
|
1643
1806
|
break;
|
|
1807
|
+
case exports_enums.EventType.NetJoinOk: {
|
|
1808
|
+
const roomCodeBytes = [];
|
|
1809
|
+
for (let j = 0;j < 8; j++) {
|
|
1810
|
+
const byte = eventsDataView.getUint8(payloadOffset + j);
|
|
1811
|
+
if (byte === 0)
|
|
1812
|
+
break;
|
|
1813
|
+
roomCodeBytes.push(byte);
|
|
1814
|
+
}
|
|
1815
|
+
const roomCode = String.fromCharCode(...roomCodeBytes);
|
|
1816
|
+
this.#context.event = {
|
|
1817
|
+
type: "join:ok",
|
|
1818
|
+
data: { roomCode }
|
|
1819
|
+
};
|
|
1820
|
+
system.netcode?.(this.#context);
|
|
1821
|
+
break;
|
|
1822
|
+
}
|
|
1823
|
+
case exports_enums.EventType.NetJoinFail: {
|
|
1824
|
+
const reasonCode = eventsDataView.getUint8(payloadOffset);
|
|
1825
|
+
const reasons = [
|
|
1826
|
+
"unknown",
|
|
1827
|
+
"timeout",
|
|
1828
|
+
"room_full",
|
|
1829
|
+
"room_not_found",
|
|
1830
|
+
"already_in_room"
|
|
1831
|
+
];
|
|
1832
|
+
const reason = reasons[reasonCode] ?? "unknown";
|
|
1833
|
+
this.#context.event = {
|
|
1834
|
+
type: "join:fail",
|
|
1835
|
+
data: { reason }
|
|
1836
|
+
};
|
|
1837
|
+
system.netcode?.(this.#context);
|
|
1838
|
+
break;
|
|
1839
|
+
}
|
|
1840
|
+
case exports_enums.EventType.NetPeerJoin: {
|
|
1841
|
+
const peerId = eventsDataView.getUint8(payloadOffset);
|
|
1842
|
+
this.#context.event = {
|
|
1843
|
+
type: "peer:join",
|
|
1844
|
+
data: { peerId }
|
|
1845
|
+
};
|
|
1846
|
+
system.netcode?.(this.#context);
|
|
1847
|
+
break;
|
|
1848
|
+
}
|
|
1849
|
+
case exports_enums.EventType.NetPeerLeave: {
|
|
1850
|
+
const peerId = eventsDataView.getUint8(payloadOffset);
|
|
1851
|
+
this.#context.event = {
|
|
1852
|
+
type: "peer:leave",
|
|
1853
|
+
data: { peerId }
|
|
1854
|
+
};
|
|
1855
|
+
system.netcode?.(this.#context);
|
|
1856
|
+
break;
|
|
1857
|
+
}
|
|
1644
1858
|
default:
|
|
1645
|
-
|
|
1859
|
+
break;
|
|
1646
1860
|
}
|
|
1647
1861
|
offset += 12;
|
|
1648
1862
|
}
|
|
@@ -1665,5 +1879,5 @@ export {
|
|
|
1665
1879
|
Bloop
|
|
1666
1880
|
};
|
|
1667
1881
|
|
|
1668
|
-
//# debugId=
|
|
1882
|
+
//# debugId=D5243D77F62CBF8A64756E2164756E21
|
|
1669
1883
|
//# sourceMappingURL=mod.js.map
|