quake2ts 0.0.254 → 0.0.256

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.
Files changed (42) hide show
  1. package/package.json +1 -1
  2. package/packages/client/dist/browser/index.global.js +13 -13
  3. package/packages/client/dist/browser/index.global.js.map +1 -1
  4. package/packages/client/dist/cjs/index.cjs +754 -36
  5. package/packages/client/dist/cjs/index.cjs.map +1 -1
  6. package/packages/client/dist/esm/index.js +754 -36
  7. package/packages/client/dist/esm/index.js.map +1 -1
  8. package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
  9. package/packages/client/dist/types/index.d.ts +3 -1
  10. package/packages/client/dist/types/index.d.ts.map +1 -1
  11. package/packages/client/dist/types/net/connection.d.ts +60 -0
  12. package/packages/client/dist/types/net/connection.d.ts.map +1 -0
  13. package/packages/client/dist/types/ui/menu/main.d.ts +2 -0
  14. package/packages/client/dist/types/ui/menu/main.d.ts.map +1 -1
  15. package/packages/client/dist/types/ui/menu/multiplayer.d.ts +11 -0
  16. package/packages/client/dist/types/ui/menu/multiplayer.d.ts.map +1 -0
  17. package/packages/engine/dist/browser/index.global.js +14 -14
  18. package/packages/engine/dist/browser/index.global.js.map +1 -1
  19. package/packages/engine/dist/cjs/index.cjs +2 -0
  20. package/packages/engine/dist/cjs/index.cjs.map +1 -1
  21. package/packages/engine/dist/esm/index.js +1 -0
  22. package/packages/engine/dist/esm/index.js.map +1 -1
  23. package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
  24. package/packages/engine/dist/types/index.d.ts +1 -1
  25. package/packages/engine/dist/types/index.d.ts.map +1 -1
  26. package/packages/game/dist/browser/index.global.js +2 -2
  27. package/packages/game/dist/browser/index.global.js.map +1 -1
  28. package/packages/game/dist/cjs/index.cjs.map +1 -1
  29. package/packages/game/dist/esm/index.js.map +1 -1
  30. package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
  31. package/packages/shared/dist/browser/index.global.js +1 -1
  32. package/packages/shared/dist/browser/index.global.js.map +1 -1
  33. package/packages/shared/dist/cjs/index.cjs +94 -0
  34. package/packages/shared/dist/cjs/index.cjs.map +1 -1
  35. package/packages/shared/dist/esm/index.js +93 -0
  36. package/packages/shared/dist/esm/index.js.map +1 -1
  37. package/packages/shared/dist/tsconfig.tsbuildinfo +1 -1
  38. package/packages/shared/dist/types/io/index.d.ts +1 -0
  39. package/packages/shared/dist/types/io/index.d.ts.map +1 -1
  40. package/packages/shared/dist/types/io/messageBuilder.d.ts +21 -0
  41. package/packages/shared/dist/types/io/messageBuilder.d.ts.map +1 -0
  42. package/packages/tools/dist/tsconfig.tsbuildinfo +1 -1
@@ -2029,42 +2029,42 @@ function addReplayFrame(session, cmd, serverFrame, startTime) {
2029
2029
  });
2030
2030
  }
2031
2031
  var WATERJUMP_CLEAR = 8 | 16 | 32 | 1024;
2032
- var ServerCommand = /* @__PURE__ */ ((ServerCommand2) => {
2033
- ServerCommand2[ServerCommand2["bad"] = 0] = "bad";
2034
- ServerCommand2[ServerCommand2["muzzleflash"] = 1] = "muzzleflash";
2035
- ServerCommand2[ServerCommand2["muzzleflash2"] = 2] = "muzzleflash2";
2036
- ServerCommand2[ServerCommand2["temp_entity"] = 3] = "temp_entity";
2037
- ServerCommand2[ServerCommand2["layout"] = 4] = "layout";
2038
- ServerCommand2[ServerCommand2["inventory"] = 5] = "inventory";
2039
- ServerCommand2[ServerCommand2["nop"] = 6] = "nop";
2040
- ServerCommand2[ServerCommand2["disconnect"] = 7] = "disconnect";
2041
- ServerCommand2[ServerCommand2["reconnect"] = 8] = "reconnect";
2042
- ServerCommand2[ServerCommand2["sound"] = 9] = "sound";
2043
- ServerCommand2[ServerCommand2["print"] = 10] = "print";
2044
- ServerCommand2[ServerCommand2["stufftext"] = 11] = "stufftext";
2045
- ServerCommand2[ServerCommand2["serverdata"] = 12] = "serverdata";
2046
- ServerCommand2[ServerCommand2["configstring"] = 13] = "configstring";
2047
- ServerCommand2[ServerCommand2["spawnbaseline"] = 14] = "spawnbaseline";
2048
- ServerCommand2[ServerCommand2["centerprint"] = 15] = "centerprint";
2049
- ServerCommand2[ServerCommand2["download"] = 16] = "download";
2050
- ServerCommand2[ServerCommand2["playerinfo"] = 17] = "playerinfo";
2051
- ServerCommand2[ServerCommand2["packetentities"] = 18] = "packetentities";
2052
- ServerCommand2[ServerCommand2["deltapacketentities"] = 19] = "deltapacketentities";
2053
- ServerCommand2[ServerCommand2["frame"] = 20] = "frame";
2054
- ServerCommand2[ServerCommand2["splitclient"] = 21] = "splitclient";
2055
- ServerCommand2[ServerCommand2["configblast"] = 22] = "configblast";
2056
- ServerCommand2[ServerCommand2["spawnbaselineblast"] = 23] = "spawnbaselineblast";
2057
- ServerCommand2[ServerCommand2["level_restart"] = 24] = "level_restart";
2058
- ServerCommand2[ServerCommand2["damage"] = 25] = "damage";
2059
- ServerCommand2[ServerCommand2["locprint"] = 26] = "locprint";
2060
- ServerCommand2[ServerCommand2["fog"] = 27] = "fog";
2061
- ServerCommand2[ServerCommand2["waitingforplayers"] = 28] = "waitingforplayers";
2062
- ServerCommand2[ServerCommand2["bot_chat"] = 29] = "bot_chat";
2063
- ServerCommand2[ServerCommand2["poi"] = 30] = "poi";
2064
- ServerCommand2[ServerCommand2["help_path"] = 31] = "help_path";
2065
- ServerCommand2[ServerCommand2["muzzleflash3"] = 32] = "muzzleflash3";
2066
- ServerCommand2[ServerCommand2["achievement"] = 33] = "achievement";
2067
- return ServerCommand2;
2032
+ var ServerCommand = /* @__PURE__ */ ((ServerCommand22) => {
2033
+ ServerCommand22[ServerCommand22["bad"] = 0] = "bad";
2034
+ ServerCommand22[ServerCommand22["muzzleflash"] = 1] = "muzzleflash";
2035
+ ServerCommand22[ServerCommand22["muzzleflash2"] = 2] = "muzzleflash2";
2036
+ ServerCommand22[ServerCommand22["temp_entity"] = 3] = "temp_entity";
2037
+ ServerCommand22[ServerCommand22["layout"] = 4] = "layout";
2038
+ ServerCommand22[ServerCommand22["inventory"] = 5] = "inventory";
2039
+ ServerCommand22[ServerCommand22["nop"] = 6] = "nop";
2040
+ ServerCommand22[ServerCommand22["disconnect"] = 7] = "disconnect";
2041
+ ServerCommand22[ServerCommand22["reconnect"] = 8] = "reconnect";
2042
+ ServerCommand22[ServerCommand22["sound"] = 9] = "sound";
2043
+ ServerCommand22[ServerCommand22["print"] = 10] = "print";
2044
+ ServerCommand22[ServerCommand22["stufftext"] = 11] = "stufftext";
2045
+ ServerCommand22[ServerCommand22["serverdata"] = 12] = "serverdata";
2046
+ ServerCommand22[ServerCommand22["configstring"] = 13] = "configstring";
2047
+ ServerCommand22[ServerCommand22["spawnbaseline"] = 14] = "spawnbaseline";
2048
+ ServerCommand22[ServerCommand22["centerprint"] = 15] = "centerprint";
2049
+ ServerCommand22[ServerCommand22["download"] = 16] = "download";
2050
+ ServerCommand22[ServerCommand22["playerinfo"] = 17] = "playerinfo";
2051
+ ServerCommand22[ServerCommand22["packetentities"] = 18] = "packetentities";
2052
+ ServerCommand22[ServerCommand22["deltapacketentities"] = 19] = "deltapacketentities";
2053
+ ServerCommand22[ServerCommand22["frame"] = 20] = "frame";
2054
+ ServerCommand22[ServerCommand22["splitclient"] = 21] = "splitclient";
2055
+ ServerCommand22[ServerCommand22["configblast"] = 22] = "configblast";
2056
+ ServerCommand22[ServerCommand22["spawnbaselineblast"] = 23] = "spawnbaselineblast";
2057
+ ServerCommand22[ServerCommand22["level_restart"] = 24] = "level_restart";
2058
+ ServerCommand22[ServerCommand22["damage"] = 25] = "damage";
2059
+ ServerCommand22[ServerCommand22["locprint"] = 26] = "locprint";
2060
+ ServerCommand22[ServerCommand22["fog"] = 27] = "fog";
2061
+ ServerCommand22[ServerCommand22["waitingforplayers"] = 28] = "waitingforplayers";
2062
+ ServerCommand22[ServerCommand22["bot_chat"] = 29] = "bot_chat";
2063
+ ServerCommand22[ServerCommand22["poi"] = 30] = "poi";
2064
+ ServerCommand22[ServerCommand22["help_path"] = 31] = "help_path";
2065
+ ServerCommand22[ServerCommand22["muzzleflash3"] = 32] = "muzzleflash3";
2066
+ ServerCommand22[ServerCommand22["achievement"] = 33] = "achievement";
2067
+ return ServerCommand22;
2068
2068
  })(ServerCommand || {});
2069
2069
  var TempEntity = /* @__PURE__ */ ((TempEntity2) => {
2070
2070
  TempEntity2[TempEntity2["GUNSHOT"] = 0] = "GUNSHOT";
@@ -8047,6 +8047,170 @@ function angleMod(angle2) {
8047
8047
  const value = angle2 % 360;
8048
8048
  return value < 0 ? 360 + value : value;
8049
8049
  }
8050
+ var ANORMS2 = [
8051
+ [-0.525731, 0, 0.850651],
8052
+ [-0.442863, 0.238856, 0.864188],
8053
+ [-0.295242, 0, 0.955423],
8054
+ [-0.309017, 0.5, 0.809017],
8055
+ [-0.16246, 0.262866, 0.951056],
8056
+ [0, 0, 1],
8057
+ [0, 0.850651, 0.525731],
8058
+ [-0.147621, 0.716567, 0.681718],
8059
+ [0.147621, 0.716567, 0.681718],
8060
+ [0, 0.525731, 0.850651],
8061
+ [0.309017, 0.5, 0.809017],
8062
+ [0.525731, 0, 0.850651],
8063
+ [0.295242, 0, 0.955423],
8064
+ [0.442863, 0.238856, 0.864188],
8065
+ [0.16246, 0.262866, 0.951056],
8066
+ [-0.681718, 0.147621, 0.716567],
8067
+ [-0.809017, 0.309017, 0.5],
8068
+ [-0.587785, 0.425325, 0.688191],
8069
+ [-0.850651, 0.525731, 0],
8070
+ [-0.864188, 0.442863, 0.238856],
8071
+ [-0.716567, 0.681718, 0.147621],
8072
+ [-0.688191, 0.587785, 0.425325],
8073
+ [-0.5, 0.809017, 0.309017],
8074
+ [-0.238856, 0.864188, 0.442863],
8075
+ [-0.425325, 0.688191, 0.587785],
8076
+ [-0.716567, 0.681718, -0.147621],
8077
+ [-0.5, 0.809017, -0.309017],
8078
+ [-0.525731, 0.850651, 0],
8079
+ [0, 0.850651, -0.525731],
8080
+ [-0.238856, 0.864188, -0.442863],
8081
+ [0, 0.955423, -0.295242],
8082
+ [-0.262866, 0.951056, -0.16246],
8083
+ [0, 1, 0],
8084
+ [0, 0.955423, 0.295242],
8085
+ [-0.262866, 0.951056, 0.16246],
8086
+ [0.238856, 0.864188, 0.442863],
8087
+ [0.262866, 0.951056, 0.16246],
8088
+ [0.5, 0.809017, 0.309017],
8089
+ [0.238856, 0.864188, -0.442863],
8090
+ [0.262866, 0.951056, -0.16246],
8091
+ [0.5, 0.809017, -0.309017],
8092
+ [0.850651, 0.525731, 0],
8093
+ [0.716567, 0.681718, 0.147621],
8094
+ [0.716567, 0.681718, -0.147621],
8095
+ [0.525731, 0.850651, 0],
8096
+ [0.425325, 0.688191, 0.587785],
8097
+ [0.864188, 0.442863, 0.238856],
8098
+ [0.688191, 0.587785, 0.425325],
8099
+ [0.809017, 0.309017, 0.5],
8100
+ [0.681718, 0.147621, 0.716567],
8101
+ [0.587785, 0.425325, 0.688191],
8102
+ [0.955423, 0.295242, 0],
8103
+ [1, 0, 0],
8104
+ [0.951056, 0.16246, 0.262866],
8105
+ [0.850651, -0.525731, 0],
8106
+ [0.955423, -0.295242, 0],
8107
+ [0.864188, -0.442863, 0.238856],
8108
+ [0.951056, -0.16246, 0.262866],
8109
+ [0.809017, -0.309017, 0.5],
8110
+ [0.681718, -0.147621, 0.716567],
8111
+ [0.850651, 0, 0.525731],
8112
+ [0.864188, 0.442863, -0.238856],
8113
+ [0.809017, 0.309017, -0.5],
8114
+ [0.951056, 0.16246, -0.262866],
8115
+ [0.525731, 0, -0.850651],
8116
+ [0.681718, 0.147621, -0.716567],
8117
+ [0.681718, -0.147621, -0.716567],
8118
+ [0.850651, 0, -0.525731],
8119
+ [0.809017, -0.309017, -0.5],
8120
+ [0.864188, -0.442863, -0.238856],
8121
+ [0.951056, -0.16246, -0.262866],
8122
+ [0.147621, 0.716567, -0.681718],
8123
+ [0.309017, 0.5, -0.809017],
8124
+ [0.425325, 0.688191, -0.587785],
8125
+ [0.442863, 0.238856, -0.864188],
8126
+ [0.587785, 0.425325, -0.688191],
8127
+ [0.688191, 0.587785, -0.425325],
8128
+ [-0.147621, 0.716567, -0.681718],
8129
+ [-0.309017, 0.5, -0.809017],
8130
+ [0, 0.525731, -0.850651],
8131
+ [-0.525731, 0, -0.850651],
8132
+ [-0.442863, 0.238856, -0.864188],
8133
+ [-0.295242, 0, -0.955423],
8134
+ [-0.16246, 0.262866, -0.951056],
8135
+ [0, 0, -1],
8136
+ [0.295242, 0, -0.955423],
8137
+ [0.16246, 0.262866, -0.951056],
8138
+ [-0.442863, -0.238856, -0.864188],
8139
+ [-0.309017, -0.5, -0.809017],
8140
+ [-0.16246, -0.262866, -0.951056],
8141
+ [0, -0.850651, -0.525731],
8142
+ [-0.147621, -0.716567, -0.681718],
8143
+ [0.147621, -0.716567, -0.681718],
8144
+ [0, -0.525731, -0.850651],
8145
+ [0.309017, -0.5, -0.809017],
8146
+ [0.442863, -0.238856, -0.864188],
8147
+ [0.16246, -0.262866, -0.951056],
8148
+ [0.238856, -0.864188, -0.442863],
8149
+ [0.5, -0.809017, -0.309017],
8150
+ [0.425325, -0.688191, -0.587785],
8151
+ [0.716567, -0.681718, -0.147621],
8152
+ [0.688191, -0.587785, -0.425325],
8153
+ [0.587785, -0.425325, -0.688191],
8154
+ [0, -0.955423, -0.295242],
8155
+ [0, -1, 0],
8156
+ [0.262866, -0.951056, -0.16246],
8157
+ [0, -0.850651, 0.525731],
8158
+ [0, -0.955423, 0.295242],
8159
+ [0.238856, -0.864188, 0.442863],
8160
+ [0.262866, -0.951056, 0.16246],
8161
+ [0.5, -0.809017, 0.309017],
8162
+ [0.716567, -0.681718, 0.147621],
8163
+ [0.525731, -0.850651, 0],
8164
+ [-0.238856, -0.864188, -0.442863],
8165
+ [-0.5, -0.809017, -0.309017],
8166
+ [-0.262866, -0.951056, -0.16246],
8167
+ [-0.850651, -0.525731, 0],
8168
+ [-0.716567, -0.681718, -0.147621],
8169
+ [-0.716567, -0.681718, 0.147621],
8170
+ [-0.525731, -0.850651, 0],
8171
+ [-0.5, -0.809017, 0.309017],
8172
+ [-0.238856, -0.864188, 0.442863],
8173
+ [-0.262866, -0.951056, 0.16246],
8174
+ [-0.864188, -0.442863, 0.238856],
8175
+ [-0.809017, -0.309017, 0.5],
8176
+ [-0.688191, -0.587785, 0.425325],
8177
+ [-0.681718, -0.147621, 0.716567],
8178
+ [-0.442863, -0.238856, 0.864188],
8179
+ [-0.587785, -0.425325, 0.688191],
8180
+ [-0.309017, -0.5, 0.809017],
8181
+ [-0.147621, -0.716567, 0.681718],
8182
+ [-0.425325, -0.688191, 0.587785],
8183
+ [-0.16246, -0.262866, 0.951056],
8184
+ [0.442863, -0.238856, 0.864188],
8185
+ [0.16246, -0.262866, 0.951056],
8186
+ [0.309017, -0.5, 0.809017],
8187
+ [0.147621, -0.716567, 0.681718],
8188
+ [0, -0.525731, 0.850651],
8189
+ [0.425325, -0.688191, 0.587785],
8190
+ [0.587785, -0.425325, 0.688191],
8191
+ [0.688191, -0.587785, 0.425325],
8192
+ [-0.955423, 0.295242, 0],
8193
+ [-0.951056, 0.16246, 0.262866],
8194
+ [-1, 0, 0],
8195
+ [-0.850651, 0, 0.525731],
8196
+ [-0.955423, -0.295242, 0],
8197
+ [-0.951056, -0.16246, 0.262866],
8198
+ [-0.864188, 0.442863, -0.238856],
8199
+ [-0.951056, 0.16246, -0.262866],
8200
+ [-0.809017, 0.309017, -0.5],
8201
+ [-0.864188, -0.442863, -0.238856],
8202
+ [-0.951056, -0.16246, -0.262866],
8203
+ [-0.809017, -0.309017, -0.5],
8204
+ [-0.681718, 0.147621, -0.716567],
8205
+ [-0.681718, -0.147621, -0.716567],
8206
+ [-0.850651, 0, -0.525731],
8207
+ [-0.688191, 0.587785, -0.425325],
8208
+ [-0.587785, 0.425325, -0.688191],
8209
+ [-0.425325, 0.688191, -0.587785],
8210
+ [-0.425325, -0.688191, -0.587785],
8211
+ [-0.587785, -0.425325, -0.688191],
8212
+ [-0.688191, -0.587785, -0.425325]
8213
+ ];
8050
8214
  var CONTENTS_SOLID2 = 1 << 0;
8051
8215
  var CONTENTS_WINDOW2 = 1 << 1;
8052
8216
  var CONTENTS_AUX2 = 1 << 2;
@@ -8246,6 +8410,14 @@ function mouseDeltaToViewDelta(delta, options) {
8246
8410
  z: 0
8247
8411
  };
8248
8412
  }
8413
+ var ClientCommand = /* @__PURE__ */ ((ClientCommand2) => {
8414
+ ClientCommand2[ClientCommand2["bad"] = 0] = "bad";
8415
+ ClientCommand2[ClientCommand2["nop"] = 1] = "nop";
8416
+ ClientCommand2[ClientCommand2["move"] = 2] = "move";
8417
+ ClientCommand2[ClientCommand2["userinfo"] = 3] = "userinfo";
8418
+ ClientCommand2[ClientCommand2["stringcmd"] = 4] = "stringcmd";
8419
+ return ClientCommand2;
8420
+ })(ClientCommand || {});
8249
8421
  var MZ_BLASTER = 0;
8250
8422
  var MZ_MACHINEGUN = 1;
8251
8423
  var MZ_SHOTGUN = 2;
@@ -8504,6 +8676,211 @@ var U_MODEL23 = 1 << 0;
8504
8676
  var U_MODEL33 = 1 << 1;
8505
8677
  var U_MODEL43 = 1 << 2;
8506
8678
  var U_REMOVE3 = 32768;
8679
+ var BinaryStream2 = class {
8680
+ constructor(buffer) {
8681
+ if (buffer instanceof Uint8Array) {
8682
+ this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
8683
+ } else {
8684
+ this.view = new DataView(buffer);
8685
+ }
8686
+ this.offset = 0;
8687
+ this.length = this.view.byteLength;
8688
+ }
8689
+ getPosition() {
8690
+ return this.offset;
8691
+ }
8692
+ seek(position) {
8693
+ if (position < 0 || position > this.length) {
8694
+ throw new Error(`Seek out of bounds: ${position} (length: ${this.length})`);
8695
+ }
8696
+ this.offset = position;
8697
+ }
8698
+ hasMore() {
8699
+ return this.offset < this.length;
8700
+ }
8701
+ readChar() {
8702
+ const value = this.view.getInt8(this.offset);
8703
+ this.offset += 1;
8704
+ return value;
8705
+ }
8706
+ readByte() {
8707
+ const value = this.view.getUint8(this.offset);
8708
+ this.offset += 1;
8709
+ return value;
8710
+ }
8711
+ readShort() {
8712
+ const value = this.view.getInt16(this.offset, true);
8713
+ this.offset += 2;
8714
+ return value;
8715
+ }
8716
+ readUShort() {
8717
+ const value = this.view.getUint16(this.offset, true);
8718
+ this.offset += 2;
8719
+ return value;
8720
+ }
8721
+ readLong() {
8722
+ const value = this.view.getInt32(this.offset, true);
8723
+ this.offset += 4;
8724
+ return value;
8725
+ }
8726
+ readULong() {
8727
+ const value = this.view.getUint32(this.offset, true);
8728
+ this.offset += 4;
8729
+ return value;
8730
+ }
8731
+ readFloat() {
8732
+ const value = this.view.getFloat32(this.offset, true);
8733
+ this.offset += 4;
8734
+ return value;
8735
+ }
8736
+ readString() {
8737
+ let str3 = "";
8738
+ while (this.offset < this.length) {
8739
+ const charCode = this.readChar();
8740
+ if (charCode === -1 || charCode === 0) {
8741
+ break;
8742
+ }
8743
+ str3 += String.fromCharCode(charCode);
8744
+ }
8745
+ return str3;
8746
+ }
8747
+ readStringLine() {
8748
+ let str3 = "";
8749
+ while (this.offset < this.length) {
8750
+ const charCode = this.readChar();
8751
+ if (charCode === -1 || charCode === 0 || charCode === 10) {
8752
+ break;
8753
+ }
8754
+ str3 += String.fromCharCode(charCode);
8755
+ }
8756
+ return str3;
8757
+ }
8758
+ readCoord() {
8759
+ return this.readShort() * (1 / 8);
8760
+ }
8761
+ readAngle() {
8762
+ return this.readChar() * (360 / 256);
8763
+ }
8764
+ readAngle16() {
8765
+ return this.readShort() * 360 / 65536;
8766
+ }
8767
+ readData(length2) {
8768
+ if (this.offset + length2 > this.length) {
8769
+ throw new Error(`Read out of bounds: ${this.offset + length2} (length: ${this.length})`);
8770
+ }
8771
+ const data = new Uint8Array(this.view.buffer, this.view.byteOffset + this.offset, length2);
8772
+ this.offset += length2;
8773
+ return new Uint8Array(data);
8774
+ }
8775
+ readPos(out) {
8776
+ out.x = this.readCoord();
8777
+ out.y = this.readCoord();
8778
+ out.z = this.readCoord();
8779
+ }
8780
+ readDir(out) {
8781
+ const b = this.readByte();
8782
+ if (b >= 162) {
8783
+ out.x = 0;
8784
+ out.y = 0;
8785
+ out.z = 0;
8786
+ return;
8787
+ }
8788
+ const norm = ANORMS2[b];
8789
+ out.x = norm[0];
8790
+ out.y = norm[1];
8791
+ out.z = norm[2];
8792
+ }
8793
+ };
8794
+ var NetworkMessageBuilder = class {
8795
+ constructor(initialSize = 1024) {
8796
+ this.buffer = new Uint8Array(initialSize);
8797
+ this.view = new DataView(this.buffer.buffer);
8798
+ this.offset = 0;
8799
+ }
8800
+ ensureCapacity(needed) {
8801
+ if (this.offset + needed > this.buffer.length) {
8802
+ const newSize = Math.max(this.buffer.length * 2, this.offset + needed);
8803
+ const newBuffer = new Uint8Array(newSize);
8804
+ newBuffer.set(this.buffer);
8805
+ this.buffer = newBuffer;
8806
+ this.view = new DataView(this.buffer.buffer);
8807
+ }
8808
+ }
8809
+ getData() {
8810
+ return this.buffer.slice(0, this.offset);
8811
+ }
8812
+ writeByte(value) {
8813
+ this.ensureCapacity(1);
8814
+ this.view.setUint8(this.offset, value);
8815
+ this.offset += 1;
8816
+ }
8817
+ writeChar(value) {
8818
+ this.ensureCapacity(1);
8819
+ this.view.setInt8(this.offset, value);
8820
+ this.offset += 1;
8821
+ }
8822
+ writeShort(value) {
8823
+ this.ensureCapacity(2);
8824
+ this.view.setInt16(this.offset, value, true);
8825
+ this.offset += 2;
8826
+ }
8827
+ writeUShort(value) {
8828
+ this.ensureCapacity(2);
8829
+ this.view.setUint16(this.offset, value, true);
8830
+ this.offset += 2;
8831
+ }
8832
+ writeLong(value) {
8833
+ this.ensureCapacity(4);
8834
+ this.view.setInt32(this.offset, value, true);
8835
+ this.offset += 4;
8836
+ }
8837
+ writeFloat(value) {
8838
+ this.ensureCapacity(4);
8839
+ this.view.setFloat32(this.offset, value, true);
8840
+ this.offset += 4;
8841
+ }
8842
+ writeString(value) {
8843
+ const len2 = value.length + 1;
8844
+ this.ensureCapacity(len2);
8845
+ for (let i = 0; i < value.length; i++) {
8846
+ this.view.setUint8(this.offset + i, value.charCodeAt(i));
8847
+ }
8848
+ this.view.setUint8(this.offset + value.length, 0);
8849
+ this.offset += len2;
8850
+ }
8851
+ writeData(data) {
8852
+ this.ensureCapacity(data.length);
8853
+ this.buffer.set(data, this.offset);
8854
+ this.offset += data.length;
8855
+ }
8856
+ writeCoord(value) {
8857
+ this.writeShort(Math.round(value * 8));
8858
+ }
8859
+ writeAngle(value) {
8860
+ this.writeByte(Math.round(value * 256 / 360) & 255);
8861
+ }
8862
+ writeAngle16(value) {
8863
+ this.writeShort(Math.round(value * 65536 / 360));
8864
+ }
8865
+ writeDir(x, y, z) {
8866
+ let best = 0;
8867
+ let bestDot = -999999;
8868
+ const len2 = Math.sqrt(x * x + y * y + z * z);
8869
+ if (len2 > 0) {
8870
+ x /= len2;
8871
+ y /= len2;
8872
+ z /= len2;
8873
+ for (let i = 0; i < 162; i++) {
8874
+ const dot2 = x * ANORMS2[i][0] + y * ANORMS2[i][1] + z * ANORMS2[i][2];
8875
+ if (dot2 > bestDot) {
8876
+ bestDot = dot2;
8877
+ best = i;
8878
+ }
8879
+ }
8880
+ }
8881
+ this.writeByte(best);
8882
+ }
8883
+ };
8507
8884
  var AmmoType2 = /* @__PURE__ */ ((AmmoType22) => {
8508
8885
  AmmoType22[AmmoType22["Bullets"] = 0] = "Bullets";
8509
8886
  AmmoType22[AmmoType22["Shells"] = 1] = "Shells";
@@ -9473,6 +9850,16 @@ var MainMenuFactory = class {
9473
9850
  this.menuSystem.pushMenu(this.createDifficultyMenu());
9474
9851
  }
9475
9852
  },
9853
+ {
9854
+ label: "Multiplayer",
9855
+ action: () => {
9856
+ if (this.options.multiplayerFactory) {
9857
+ this.menuSystem.pushMenu(this.options.multiplayerFactory.createMultiplayerMenu());
9858
+ } else {
9859
+ console.warn("Multiplayer factory not configured");
9860
+ }
9861
+ }
9862
+ },
9476
9863
  {
9477
9864
  label: "Load Game",
9478
9865
  action: () => {
@@ -10047,6 +10434,74 @@ var PauseMenuFactory = class {
10047
10434
  }
10048
10435
  };
10049
10436
 
10437
+ // src/ui/menu/multiplayer.ts
10438
+ var MultiplayerMenuFactory = class {
10439
+ constructor(menuSystem, connection) {
10440
+ this.menuSystem = menuSystem;
10441
+ this.connection = connection;
10442
+ }
10443
+ createMultiplayerMenu(initialAddress = "localhost:27910", status = "") {
10444
+ let address = initialAddress;
10445
+ const items = [];
10446
+ if (status) {
10447
+ items.push({
10448
+ label: status,
10449
+ action: () => {
10450
+ }
10451
+ // No-op
10452
+ });
10453
+ }
10454
+ items.push(
10455
+ {
10456
+ label: "Address: " + address,
10457
+ action: () => {
10458
+ if (typeof window !== "undefined") {
10459
+ const newAddr = window.prompt("Enter Server Address", address);
10460
+ if (newAddr) {
10461
+ address = newAddr;
10462
+ this.refreshMenu(address);
10463
+ }
10464
+ }
10465
+ }
10466
+ },
10467
+ {
10468
+ label: "Connect",
10469
+ action: () => {
10470
+ this.refreshMenu(address, "Connecting...");
10471
+ this.connection.connect("ws://" + address).then(() => {
10472
+ this.menuSystem.closeAll();
10473
+ }).catch((err2) => {
10474
+ console.error(err2);
10475
+ const failStatus = "Failed: " + (err2.message || "Unknown error");
10476
+ this.refreshMenu(address, failStatus);
10477
+ });
10478
+ }
10479
+ },
10480
+ {
10481
+ label: "Disconnect",
10482
+ action: () => {
10483
+ this.connection.disconnect();
10484
+ this.refreshMenu(address, "Disconnected");
10485
+ }
10486
+ },
10487
+ {
10488
+ label: "Back",
10489
+ action: () => {
10490
+ this.menuSystem.popMenu();
10491
+ }
10492
+ }
10493
+ );
10494
+ return {
10495
+ title: "Multiplayer",
10496
+ items
10497
+ };
10498
+ }
10499
+ refreshMenu(address, status = "") {
10500
+ this.menuSystem.popMenu();
10501
+ this.menuSystem.pushMenu(this.createMultiplayerMenu(address, status));
10502
+ }
10503
+ };
10504
+
10050
10505
  // src/ui/menu/render.ts
10051
10506
  function Draw_Menu(renderer, state, width, height) {
10052
10507
  if (!state.activeMenu) {
@@ -10325,6 +10780,233 @@ function buildRenderableEntities(latestEntities, previousEntities, alpha, config
10325
10780
  return renderables;
10326
10781
  }
10327
10782
 
10783
+ // src/net/browserWsDriver.ts
10784
+ var BrowserWebSocketNetDriver = class {
10785
+ constructor() {
10786
+ this.socket = null;
10787
+ this.messageCallback = null;
10788
+ this.closeCallback = null;
10789
+ this.errorCallback = null;
10790
+ }
10791
+ async connect(url) {
10792
+ return new Promise((resolve, reject) => {
10793
+ try {
10794
+ this.socket = new WebSocket(url);
10795
+ this.socket.binaryType = "arraybuffer";
10796
+ this.socket.onopen = () => {
10797
+ resolve();
10798
+ };
10799
+ this.socket.onerror = (event) => {
10800
+ const error = new Error("WebSocket connection error");
10801
+ if (this.errorCallback) {
10802
+ this.errorCallback(error);
10803
+ }
10804
+ reject(error);
10805
+ };
10806
+ this.socket.onclose = () => {
10807
+ if (this.closeCallback) {
10808
+ this.closeCallback();
10809
+ }
10810
+ this.socket = null;
10811
+ };
10812
+ this.socket.onmessage = (event) => {
10813
+ if (this.messageCallback) {
10814
+ if (event.data instanceof ArrayBuffer) {
10815
+ this.messageCallback(new Uint8Array(event.data));
10816
+ } else {
10817
+ console.warn("Received non-binary message from server");
10818
+ }
10819
+ }
10820
+ };
10821
+ } catch (e) {
10822
+ reject(e);
10823
+ }
10824
+ });
10825
+ }
10826
+ disconnect() {
10827
+ if (this.socket) {
10828
+ this.socket.close();
10829
+ this.socket = null;
10830
+ }
10831
+ }
10832
+ send(data) {
10833
+ if (this.socket && this.socket.readyState === WebSocket.OPEN) {
10834
+ this.socket.send(data);
10835
+ } else {
10836
+ console.warn("Attempted to send data on closed or connecting socket");
10837
+ }
10838
+ }
10839
+ onMessage(callback) {
10840
+ this.messageCallback = callback;
10841
+ }
10842
+ onClose(callback) {
10843
+ this.closeCallback = callback;
10844
+ }
10845
+ onError(callback) {
10846
+ this.errorCallback = callback;
10847
+ }
10848
+ isConnected() {
10849
+ return this.socket !== null && this.socket.readyState === WebSocket.OPEN;
10850
+ }
10851
+ };
10852
+
10853
+ // src/net/connection.ts
10854
+ var MultiplayerConnection = class {
10855
+ constructor(options) {
10856
+ this.state = 0 /* Disconnected */;
10857
+ this.parser = null;
10858
+ // Game State
10859
+ this.serverProtocol = 0;
10860
+ this.serverCount = 0;
10861
+ this.gameDir = "";
10862
+ this.playerNum = 0;
10863
+ this.levelName = "";
10864
+ this.configStrings = /* @__PURE__ */ new Map();
10865
+ this.baselines = /* @__PURE__ */ new Map();
10866
+ this.challenge = 0;
10867
+ this.connectPacketCount = 0;
10868
+ this.connectPacketTime = 0;
10869
+ this.driver = new BrowserWebSocketNetDriver();
10870
+ this.options = options;
10871
+ this.driver.onMessage((data) => this.handleMessage(data));
10872
+ this.driver.onClose(() => this.handleDisconnect());
10873
+ this.driver.onError((err2) => console.error("Network Error:", err2));
10874
+ }
10875
+ async connect(url) {
10876
+ if (this.state !== 0 /* Disconnected */) {
10877
+ this.disconnect();
10878
+ }
10879
+ console.log(`Connecting to ${url}...`);
10880
+ this.state = 1 /* Connecting */;
10881
+ try {
10882
+ await this.driver.connect(url);
10883
+ console.log("WebSocket connected.");
10884
+ this.state = 2 /* Challenge */;
10885
+ this.sendChallenge();
10886
+ } catch (e) {
10887
+ console.error("Connection failed:", e);
10888
+ this.state = 0 /* Disconnected */;
10889
+ throw e;
10890
+ }
10891
+ }
10892
+ disconnect() {
10893
+ if (this.state === 0 /* Disconnected */) return;
10894
+ this.driver.disconnect();
10895
+ this.state = 0 /* Disconnected */;
10896
+ this.configStrings.clear();
10897
+ this.baselines.clear();
10898
+ }
10899
+ sendCommand(cmd) {
10900
+ if (this.state !== 5 /* Active */) return;
10901
+ const builder = new NetworkMessageBuilder();
10902
+ builder.writeByte(ClientCommand.nop);
10903
+ this.driver.send(builder.getData());
10904
+ }
10905
+ handleMessage(data) {
10906
+ let buffer = data.buffer;
10907
+ if (buffer instanceof SharedArrayBuffer) {
10908
+ const newBuffer = new ArrayBuffer(data.byteLength);
10909
+ new Uint8Array(newBuffer).set(data);
10910
+ buffer = newBuffer;
10911
+ }
10912
+ const stream = new BinaryStream2(buffer);
10913
+ const sequence = stream.readLong();
10914
+ const sequenceAck = stream.readLong();
10915
+ this.parser = new NetworkMessageParser(stream, this);
10916
+ this.parser.parseMessage();
10917
+ }
10918
+ handleDisconnect() {
10919
+ console.log("Disconnected from server.");
10920
+ this.state = 0 /* Disconnected */;
10921
+ }
10922
+ sendChallenge() {
10923
+ const builder = new NetworkMessageBuilder();
10924
+ builder.writeByte(ClientCommand.stringcmd);
10925
+ builder.writeString("getchallenge");
10926
+ this.driver.send(builder.getData());
10927
+ }
10928
+ sendConnect(challenge) {
10929
+ const builder = new NetworkMessageBuilder();
10930
+ builder.writeByte(ClientCommand.stringcmd);
10931
+ const userinfo = `\\name\\${this.options.username}\\model\\${this.options.model}\\skin\\${this.options.skin}\\hand\\${this.options.hand ?? 0}\\fov\\${this.options.fov ?? 90}`;
10932
+ builder.writeString(`connect ${PROTOCOL_VERSION_RERELEASE} ${challenge} ${userinfo}`);
10933
+ this.driver.send(builder.getData());
10934
+ }
10935
+ isConnected() {
10936
+ return this.state === 5 /* Active */;
10937
+ }
10938
+ // ==================================================================================
10939
+ // NetworkMessageHandler Implementation
10940
+ // ==================================================================================
10941
+ onServerData(protocol, serverCount, attractLoop, gameDir, playerNum, levelName) {
10942
+ console.log(`Server Data: Protocol ${protocol}, Level ${levelName}`);
10943
+ this.serverProtocol = protocol;
10944
+ this.serverCount = serverCount;
10945
+ this.gameDir = gameDir;
10946
+ this.playerNum = playerNum;
10947
+ this.levelName = levelName;
10948
+ this.state = 3 /* Connected */;
10949
+ const builder = new NetworkMessageBuilder();
10950
+ builder.writeByte(ClientCommand.stringcmd);
10951
+ builder.writeString("new");
10952
+ this.driver.send(builder.getData());
10953
+ this.state = 4 /* Loading */;
10954
+ }
10955
+ onConfigString(index, str3) {
10956
+ this.configStrings.set(index, str3);
10957
+ }
10958
+ onSpawnBaseline(entity) {
10959
+ this.baselines.set(entity.number, entity);
10960
+ }
10961
+ onStuffText(msg) {
10962
+ console.log(`Server StuffText: ${msg}`);
10963
+ if (msg.startsWith("precache")) {
10964
+ this.finishLoading();
10965
+ }
10966
+ if (msg.startsWith("challenge ")) {
10967
+ const parts = msg.split(" ");
10968
+ if (parts.length > 1) {
10969
+ this.challenge = parseInt(parts[1], 10);
10970
+ this.sendConnect(this.challenge);
10971
+ }
10972
+ }
10973
+ }
10974
+ finishLoading() {
10975
+ console.log("Finished loading, sending begin...");
10976
+ const builder = new NetworkMessageBuilder();
10977
+ builder.writeByte(ClientCommand.stringcmd);
10978
+ builder.writeString("begin");
10979
+ this.driver.send(builder.getData());
10980
+ this.state = 5 /* Active */;
10981
+ }
10982
+ // Stubs for other handlers
10983
+ onFrame(frame) {
10984
+ }
10985
+ onCenterPrint(msg) {
10986
+ }
10987
+ onPrint(level, msg) {
10988
+ }
10989
+ onSound(flags, soundNum, volume, attenuation, offset, ent, pos) {
10990
+ }
10991
+ onTempEntity(type, pos, pos2, dir, cnt, color, ent, srcEnt, destEnt) {
10992
+ }
10993
+ onLayout(layout) {
10994
+ }
10995
+ onInventory(inventory) {
10996
+ }
10997
+ onMuzzleFlash(ent, weapon) {
10998
+ }
10999
+ onMuzzleFlash2(ent, weapon) {
11000
+ }
11001
+ onDisconnect() {
11002
+ this.disconnect();
11003
+ }
11004
+ onReconnect() {
11005
+ }
11006
+ onDownload(size, percent, data) {
11007
+ }
11008
+ };
11009
+
10328
11010
  // src/input/bindings.ts
10329
11011
  var DEFAULT_BINDINGS = [
10330
11012
  { code: "KeyW", command: "+forward" },
@@ -10861,6 +11543,21 @@ function createClient(imports) {
10861
11543
  };
10862
11544
  const cgameImport = createCGameImport(imports, stateProvider);
10863
11545
  const cg = GetCGameAPI(cgameImport);
11546
+ const multiplayer = new MultiplayerConnection({
11547
+ get username() {
11548
+ return imports.host?.cvars?.get("name")?.string || "Player";
11549
+ },
11550
+ get model() {
11551
+ return imports.host?.cvars?.get("model")?.string || "male";
11552
+ },
11553
+ get skin() {
11554
+ return imports.host?.cvars?.get("skin")?.string || "grunt";
11555
+ },
11556
+ get fov() {
11557
+ return fovValue;
11558
+ }
11559
+ });
11560
+ const multiplayerFactory = new MultiplayerMenuFactory(menuSystem, multiplayer);
10864
11561
  demoHandler.setCallbacks({
10865
11562
  onCenterPrint: (msg) => cg.ParseCenterPrint(msg, 0, false),
10866
11563
  onPrint: (level, msg) => cg.NotifyMessage(0, msg, false),
@@ -10923,6 +11620,22 @@ function createClient(imports) {
10923
11620
  menuSystem.pushMenu(pauseMenuFactory.createPauseMenu());
10924
11621
  }
10925
11622
  }, "Toggle the main/pause menu");
11623
+ imports.host.commands.register("connect", (args) => {
11624
+ if (args.length < 1) {
11625
+ console.log("usage: connect <address>");
11626
+ return;
11627
+ }
11628
+ const address = args[0];
11629
+ console.log(`Connecting to ${address}...`);
11630
+ multiplayer.connect(address).catch((e) => {
11631
+ console.error("Failed to connect:", e);
11632
+ errorDialog.show("Connection Failed", e instanceof Error ? e.message : "Unknown error");
11633
+ });
11634
+ }, "Connect to a multiplayer server");
11635
+ imports.host.commands.register("disconnect", () => {
11636
+ multiplayer.disconnect();
11637
+ console.log("Disconnected.");
11638
+ }, "Disconnect from server");
10926
11639
  if (imports.host.cvars) {
10927
11640
  imports.host.cvars.register({
10928
11641
  name: "fov",
@@ -10977,6 +11690,9 @@ function createClient(imports) {
10977
11690
  predict(command) {
10978
11691
  if (menuSystem.isActive()) {
10979
11692
  }
11693
+ if (multiplayer.isConnected()) {
11694
+ multiplayer.sendCommand(command);
11695
+ }
10980
11696
  return prediction.enqueueCommand(command);
10981
11697
  },
10982
11698
  handleInput(key, down) {
@@ -11041,6 +11757,7 @@ function createClient(imports) {
11041
11757
  ...options,
11042
11758
  optionsFactory: optsFactory,
11043
11759
  mapsFactory,
11760
+ multiplayerFactory,
11044
11761
  onSetDifficulty: (skill) => {
11045
11762
  if (imports.host?.cvars) {
11046
11763
  imports.host.cvars.setValue("skill", skill.toString());
@@ -11246,6 +11963,7 @@ function createClient(imports) {
11246
11963
  cg.ParseConfigString(index, value);
11247
11964
  },
11248
11965
  demoHandler,
11966
+ multiplayer,
11249
11967
  configStrings
11250
11968
  };
11251
11969
  return clientExports;