@vaitosoi/minejs 0.5.1 → 0.6.1

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 (77) hide show
  1. package/README.md +25 -9
  2. package/assets/minecraft/26.2/components.json +113 -0
  3. package/assets/minecraft/26.2/packets.json +8 -28
  4. package/assets/minecraft/26.3/packets.json +4957 -0
  5. package/assets/minecraft/versionMapping.json +16 -0
  6. package/dist/binary/decoder.d.ts +35 -0
  7. package/dist/binary/decoder.d.ts.map +1 -1
  8. package/dist/binary/decoder.js +665 -2
  9. package/dist/binary/decoder.js.map +1 -1
  10. package/dist/binary/encoder.d.ts +3 -3
  11. package/dist/binary/encoder.d.ts.map +1 -1
  12. package/dist/binary/encoder.js +4 -4
  13. package/dist/binary/encoder.js.map +1 -1
  14. package/dist/client/client.d.ts +178 -22
  15. package/dist/client/client.d.ts.map +1 -1
  16. package/dist/client/client.js +132 -13
  17. package/dist/client/client.js.map +1 -1
  18. package/dist/net/tcp.d.ts +6 -9
  19. package/dist/net/tcp.d.ts.map +1 -1
  20. package/dist/net/tcp.js +16 -19
  21. package/dist/net/tcp.js.map +1 -1
  22. package/dist/packet/listener.d.ts +6 -1
  23. package/dist/packet/listener.d.ts.map +1 -1
  24. package/dist/packet/listener.js +220 -60
  25. package/dist/packet/listener.js.map +1 -1
  26. package/dist/packet/sender.d.ts +4 -1
  27. package/dist/packet/sender.d.ts.map +1 -1
  28. package/dist/packet/sender.js +30 -4
  29. package/dist/packet/sender.js.map +1 -1
  30. package/dist/physics/aabb.d.ts.map +1 -1
  31. package/dist/physics/aabb.js +17 -9
  32. package/dist/physics/aabb.js.map +1 -1
  33. package/dist/physics/direction.js +2 -2
  34. package/dist/physics/direction.js.map +1 -1
  35. package/dist/physics/player.js +1 -5
  36. package/dist/physics/player.js.map +1 -1
  37. package/dist/version/codec.d.ts.map +1 -1
  38. package/dist/version/codec.js +63 -14
  39. package/dist/version/codec.js.map +1 -1
  40. package/dist/version/registry.d.ts +26 -5
  41. package/dist/version/registry.d.ts.map +1 -1
  42. package/dist/version/registry.js +78 -18
  43. package/dist/version/registry.js.map +1 -1
  44. package/dist/world/block.d.ts +54 -10
  45. package/dist/world/block.d.ts.map +1 -1
  46. package/dist/world/block.js +78 -32
  47. package/dist/world/block.js.map +1 -1
  48. package/dist/world/container.d.ts +106 -0
  49. package/dist/world/container.d.ts.map +1 -0
  50. package/dist/world/container.js +240 -0
  51. package/dist/world/container.js.map +1 -0
  52. package/dist/world/entity.d.ts +3 -0
  53. package/dist/world/entity.d.ts.map +1 -1
  54. package/dist/world/entity.js +3 -0
  55. package/dist/world/entity.js.map +1 -1
  56. package/dist/world/state.d.ts +11 -5
  57. package/dist/world/state.d.ts.map +1 -1
  58. package/dist/world/state.js +11 -0
  59. package/dist/world/state.js.map +1 -1
  60. package/package.json +2 -2
  61. package/src/binary/decoder.ts +691 -2
  62. package/src/binary/encoder.ts +8 -9
  63. package/src/client/client.ts +234 -34
  64. package/src/net/tcp.ts +27 -22
  65. package/src/packet/listener.ts +275 -76
  66. package/src/packet/sender.ts +42 -7
  67. package/src/physics/aabb.ts +18 -9
  68. package/src/physics/direction.ts +2 -2
  69. package/src/physics/player.ts +5 -5
  70. package/src/version/codec.ts +56 -14
  71. package/src/version/registry.ts +92 -18
  72. package/src/world/block.ts +83 -39
  73. package/src/world/container.ts +180 -0
  74. package/src/world/entity.ts +3 -0
  75. package/src/world/state.ts +21 -6
  76. package/test/client/index.ts +56 -21
  77. package/test/client/registry.json +1735 -0
@@ -12,6 +12,7 @@ import { AuthRelatedNotFound, HaveSignatureButNotIndex, MessageLinkNotFound, Not
12
12
  import { uuidToBuffer } from "../base/math";
13
13
  import { MessageLink } from "../message/link";
14
14
  import { Sender } from "./sender";
15
+ import { Container, Slot } from "../world/container";
15
16
 
16
17
  function zodParse<Type extends zod.ZodType>(data: object, zod: Type): zod.infer<Type> {
17
18
  return zod.parse(data);
@@ -55,13 +56,20 @@ export class Listener {
55
56
  "play:add_entity": this.handleSpawnEntity,
56
57
  "play:move_entity_pos": this.handleUpdateEntityPosition,
57
58
  "play:move_entity_pos_rot": this.handleUpdateEntityPositionRotation,
58
- "play:entity_position_sync": this.handleTeleportEntity,
59
+ "play:entity_position_sync": this.handleEntityPositionSync,
59
60
  "play:player_position": this.handleSynchronizePlayerPosition,
60
61
  "play:update_mob_effect": this.handleUpdateMobEffect,
61
62
  "play:remove_entities": this.handleRemoveEntity,
62
63
  "play:remove_mob_effect": this.handleRemoveMobEffect,
63
64
  // "play:rotate_head": ,
64
65
  "play:set_entity_motion": this.handleSetEntityVelocity,
66
+
67
+ "play:open_screen": this.handleOpenScreen,
68
+ "play:container_close": this.handleCloseContainer,
69
+ "play:container_set_content": this.handleContainerContent,
70
+ "play:container_set_data": this.handleContainerProperty,
71
+
72
+ "play:tab_list": this.handleSetTablist
65
73
  };
66
74
  }
67
75
 
@@ -76,7 +84,11 @@ export class Listener {
76
84
  // Login
77
85
 
78
86
  private handleLoginDisconnect(data: object) {
79
- const { reason } = zodParse(data, zod.object({ reason: zod.record(zod.string(), zod.any()) }));
87
+ const { reason } = zodParse(data, zod.object({ reason: zod.record(zod.string(), zod.any()).or(zod.string()) }));
88
+
89
+ if (typeof reason === "string")
90
+ return this.disconnect(reason);
91
+
80
92
  const text = getTextFromTextComponent(reason);
81
93
 
82
94
  this.disconnect(text, reason);
@@ -146,7 +158,9 @@ export class Listener {
146
158
  yaw: 0,
147
159
  pitch: 0,
148
160
  },
149
- effects: {}
161
+ effects: {},
162
+ inventory: new Container(0, -1, {}),
163
+ carryingItem: undefined
150
164
  } satisfies ClientPlayer as any;
151
165
  this.sender.sendLoginAck();
152
166
  }
@@ -301,8 +315,8 @@ export class Listener {
301
315
  angle: newAngle,
302
316
  } satisfies ClientPlayer as any
303
317
  );
304
- this.state.enqueueEvent("playerPosition", { x: newPosX, y: newPosY, z: newPosZ });
305
- this.sender.sendConfirmTeleportation(teleport_id);
318
+ this.state.enqueueEvent("playerPosition", newPosition);
319
+ this.sender.sendConfirmTeleportation(teleport_id, newPosition, newAngle);
306
320
  this.sender.sendPacket("move_player_pos_rot", {
307
321
  x: newPosition.x,
308
322
  feet_y: newPosition.y,
@@ -509,89 +523,191 @@ export class Listener {
509
523
  this.state.enqueueEvent("spawnEntity", entity);
510
524
  }
511
525
 
512
- private handleTeleportEntity(data: object) {
513
- const {
514
- entity_id,
515
- x,
516
- y,
517
- z,
518
- velocity_x,
519
- velocity_y,
520
- velocity_z,
521
- pitch,
522
- yaw
523
- } = zodParse(data, zod.object({
524
- entity_id: zod.int(),
525
- x: zod.number(),
526
- y: zod.number(),
527
- z: zod.number(),
528
- velocity_x: zod.number(),
529
- velocity_y: zod.number(),
530
- velocity_z: zod.number(),
531
- pitch: zod.number(),
532
- yaw: zod.number(),
533
- }));
526
+ private handleEntityPositionSync(data: object) {
527
+ if (this.state.getProtocolId() > 776) {
534
528
 
535
- if (entity_id in this.state.world!.entities) this.state.enqueueMutation(state => {
536
- state.world!.entities[entity_id]!.position = { x, y, z };
537
- state.world!.entities[entity_id]!.velocity = { x: velocity_x, y: velocity_y, z: velocity_z };
538
- state.world!.entities[entity_id]!.angle = { pitch, yaw };
539
- });
540
- this.state.enqueueEvent("updateEntity", entity_id);
529
+ const {
530
+ entity_id,
531
+ linear,
532
+ stepped,
533
+ pitch,
534
+ yaw
535
+ } = zodParse(data, zod.object({
536
+ entity_id: zod.int(),
537
+ linear: zod.object({
538
+ x: zod.number(),
539
+ y: zod.number(),
540
+ z: zod.number(),
541
+ }).nullable(),
542
+ stepped: zod.object({
543
+ x: zod.number(),
544
+ y: zod.number(),
545
+ z: zod.number(),
546
+ tick_offset: zod.number()
547
+ }).array().nullable(),
548
+ pitch: zod.number(),
549
+ yaw: zod.number(),
550
+ }));
551
+ const { x, y, z } = linear ? linear : stepped![stepped!.length - 1]!;
552
+
553
+ if (entity_id in this.state.world!.entities) this.state.enqueueMutation(state => {
554
+ state.world!.entities[entity_id]!.position = { x, y, z };
555
+ state.world!.entities[entity_id]!.angle = { pitch, yaw };
556
+ });
557
+ this.state.enqueueEvent("updateEntity", entity_id);
558
+ } else {
559
+ const {
560
+ entity_id,
561
+ x,
562
+ y,
563
+ z,
564
+ velocity_x,
565
+ velocity_y,
566
+ velocity_z,
567
+ pitch,
568
+ yaw
569
+ } = zodParse(data, zod.object({
570
+ entity_id: zod.int(),
571
+ x: zod.number(),
572
+ y: zod.number(),
573
+ z: zod.number(),
574
+ velocity_x: zod.number(),
575
+ velocity_y: zod.number(),
576
+ velocity_z: zod.number(),
577
+ pitch: zod.number(),
578
+ yaw: zod.number(),
579
+ }));
580
+
581
+ if (entity_id in this.state.world!.entities) this.state.enqueueMutation(state => {
582
+ state.world!.entities[entity_id]!.position = { x, y, z };
583
+ state.world!.entities[entity_id]!.velocity = { x: velocity_x, y: velocity_y, z: velocity_z };
584
+ state.world!.entities[entity_id]!.angle = { pitch, yaw };
585
+ });
586
+ this.state.enqueueEvent("updateEntity", entity_id);
587
+ }
541
588
  }
542
589
 
543
590
  private handleUpdateEntityPosition(data: object) {
544
- const {
545
- entity_id,
546
- delta_x,
547
- delta_y,
548
- delta_z
549
- } = zodParse(data, zod.object({
550
- entity_id: zod.number(),
551
- delta_x: zod.number(),
552
- delta_y: zod.number(),
553
- delta_z: zod.number(),
554
- }));
591
+ if (this.state.getProtocolId() <= 776) { // Before 26.3
592
+ const {
593
+ entity_id,
594
+ delta_x,
595
+ delta_y,
596
+ delta_z
597
+ } = zodParse(data, zod.object({
598
+ entity_id: zod.number(),
599
+ delta_x: zod.number(),
600
+ delta_y: zod.number(),
601
+ delta_z: zod.number(),
602
+ }));
555
603
 
556
- if (entity_id in this.state.world!.entities) this.state.enqueueMutation(state => {
557
- let { x, y, z } = state.world!.entities[entity_id]!.position;
558
- x += delta_x;
559
- y += delta_y;
560
- z += delta_z;
561
- state.world!.entities[entity_id]!.position = { x, y, z };
562
- });
563
- this.state.enqueueEvent("updateEntity", entity_id);
564
- }
604
+ if (entity_id in this.state.world!.entities) this.state.enqueueMutation(state => {
605
+ let { x, y, z } = state.world!.entities[entity_id]!.position;
606
+ x += delta_x;
607
+ y += delta_y;
608
+ z += delta_z;
609
+ state.world!.entities[entity_id]!.position = { x, y, z };
610
+ });
611
+ this.state.enqueueEvent("updateEntity", entity_id);
612
+ } else {
613
+ const {
614
+ entity_id,
615
+ step,
616
+ steps
617
+ } = zodParse(data, zod.object({
618
+ entity_id: zod.number(),
619
+ step: zod.object({
620
+ delta_x: zod.number(),
621
+ delta_y: zod.number(),
622
+ delta_z: zod.number(),
623
+ }).nullable(),
624
+ steps: zod.object({
625
+ tick_offset: zod.number(),
626
+ delta_x: zod.number(),
627
+ delta_y: zod.number(),
628
+ delta_z: zod.number(),
629
+ }).array().nullable()
630
+ }));
631
+ const { delta_x, delta_y, delta_z } = step ? step : steps![steps!.length - 1]!;
565
632
 
566
- private handleUpdateEntityPositionRotation(data: object) {
567
- const {
568
- entity_id,
569
- delta_x,
570
- delta_y,
571
- delta_z,
572
- pitch,
573
- yaw
574
- } = zodParse(data, zod.object({
575
- entity_id: zod.number(),
576
- delta_x: zod.number(),
577
- delta_y: zod.number(),
578
- delta_z: zod.number(),
579
- pitch: zod.number(),
580
- yaw: zod.number(),
581
- }));
582
- if (entity_id in this.state.world!.entities) {
583
- this.state.enqueueMutation(state => {
633
+ if (entity_id in this.state.world!.entities) this.state.enqueueMutation(state => {
584
634
  let { x, y, z } = state.world!.entities[entity_id]!.position;
585
635
  x += delta_x;
586
636
  y += delta_y;
587
637
  z += delta_z;
588
638
  state.world!.entities[entity_id]!.position = { x, y, z };
589
- state.world!.entities[entity_id]!.angle = { yaw, pitch };
590
639
  });
591
640
  this.state.enqueueEvent("updateEntity", entity_id);
592
641
  }
593
642
  }
594
643
 
644
+ private handleUpdateEntityPositionRotation(data: object) {
645
+ if (this.state.getProtocolId() <= 776) { // Before 26.3
646
+ const {
647
+ entity_id,
648
+ delta_x,
649
+ delta_y,
650
+ delta_z,
651
+ pitch,
652
+ yaw
653
+ } = zodParse(data, zod.object({
654
+ entity_id: zod.number(),
655
+ delta_x: zod.number(),
656
+ delta_y: zod.number(),
657
+ delta_z: zod.number(),
658
+ pitch: zod.number(),
659
+ yaw: zod.number(),
660
+ }));
661
+ if (entity_id in this.state.world!.entities) {
662
+ this.state.enqueueMutation(state => {
663
+ let { x, y, z } = state.world!.entities[entity_id]!.position;
664
+ x += delta_x;
665
+ y += delta_y;
666
+ z += delta_z;
667
+ state.world!.entities[entity_id]!.position = { x, y, z };
668
+ state.world!.entities[entity_id]!.angle = { yaw, pitch };
669
+ });
670
+ this.state.enqueueEvent("updateEntity", entity_id);
671
+ }
672
+ } else {
673
+ const {
674
+ entity_id,
675
+ step,
676
+ steps,
677
+ pitch,
678
+ yaw
679
+ } = zodParse(data, zod.object({
680
+ entity_id: zod.number(),
681
+ step: zod.object({
682
+ delta_x: zod.number(),
683
+ delta_y: zod.number(),
684
+ delta_z: zod.number(),
685
+ }).nullable(),
686
+ steps: zod.object({
687
+ tick_offset: zod.number(),
688
+ delta_x: zod.number(),
689
+ delta_y: zod.number(),
690
+ delta_z: zod.number(),
691
+ }).array().nullable(),
692
+ pitch: zod.number(),
693
+ yaw: zod.number(),
694
+ }));
695
+ const { delta_x, delta_y, delta_z } = step ? step : steps![steps!.length - 1]!;
696
+
697
+ if (entity_id in this.state.world!.entities) {
698
+ this.state.enqueueMutation(state => {
699
+ let { x, y, z } = state.world!.entities[entity_id]!.position;
700
+ x += delta_x;
701
+ y += delta_y;
702
+ z += delta_z;
703
+ state.world!.entities[entity_id]!.position = { x, y, z };
704
+ state.world!.entities[entity_id]!.angle = { yaw, pitch };
705
+ });
706
+ this.state.enqueueEvent("updateEntity", entity_id);
707
+ }
708
+ }
709
+ }
710
+
595
711
  private handleSetEntityVelocity(data: object) {
596
712
  const { entity_id, velocity } = zodParse(data, zod.object({
597
713
  entity_id: zod.number(),
@@ -693,12 +809,16 @@ export class Listener {
693
809
  filter_type: zod.int(),
694
810
  filter_type_bits: zod.array(zod.bigint()).nullable(),
695
811
  chat_type: zod.int().or(zod.record(zod.string(), zod.any())),
696
- sender_name: zod.record(zod.string(), zod.any()),
697
- target_name: zod.record(zod.string(), zod.any()).nullable()
812
+ sender_name: zod.record(zod.string(), zod.any()).or(zod.string()),
813
+ target_name: zod.record(zod.string(), zod.any()).or(zod.string()).nullable()
698
814
  }));
699
815
 
700
- const senderNameText = getTextFromTextComponent(sender_name).toString(),
701
- targetNameText = target_name ? getTextFromTextComponent(target_name).toString() : undefined;
816
+ const senderNameText = typeof sender_name === "string" ? sender_name : getTextFromTextComponent(sender_name).toString(),
817
+ targetNameText = target_name
818
+ ? typeof target_name === "string"
819
+ ? target_name
820
+ : getTextFromTextComponent(target_name).toString()
821
+ : undefined;
702
822
 
703
823
  const emitObject = {
704
824
  sender: senderNameText,
@@ -834,4 +954,83 @@ export class Listener {
834
954
  }
835
955
  });
836
956
  }
957
+
958
+ // Container
959
+ private handleOpenScreen(data: object) {
960
+ const {
961
+ window_id,
962
+ window_type,
963
+ window_title
964
+ } = zodParse(data, zod.object({
965
+ window_id: zod.int(),
966
+ window_type: zod.int(),
967
+ window_title: zod.record(zod.string(), zod.any())
968
+ }));
969
+ this.state.enqueueMutation(state => {
970
+ state.openingContainer = new Container(window_id, window_type, window_title);
971
+ this.emit("openContainer", this.state.openingContainer!);
972
+ });
973
+ }
974
+
975
+ private handleCloseContainer(data: object) {
976
+ // Not used by vanilla client
977
+ const { window_id } = zodParse(data, zod.object({ window_id: zod.int() }));
978
+
979
+ this.state.enqueueMutation(state => {
980
+ state.openingContainer = undefined;
981
+ this.emit("closeContainer");
982
+ });
983
+ }
984
+
985
+ private handleContainerContent(data: object) {
986
+ const {
987
+ window_id,
988
+ state_id,
989
+ slot_data,
990
+ carried_item
991
+ } = zodParse(data, zod.object({
992
+ window_id: zod.int(),
993
+ state_id: zod.int(),
994
+ slot_data: zod.array(zod.any() as zod.ZodType<Slot>),
995
+ carried_item: zod.any() as zod.ZodType<Slot>,
996
+ }));
997
+ this.state.enqueueMutation(state => {
998
+ if (!state.openingContainer) return;
999
+ state.openingContainer.stateId = state_id;
1000
+ state.openingContainer.slots = slot_data;
1001
+ state.player!.carryingItem = carried_item;
1002
+ this.emit("containerContent", state.openingContainer, state.player!.carryingItem);
1003
+ });
1004
+ }
1005
+
1006
+ private handleContainerProperty(data: object) {
1007
+ const {
1008
+ window_id,
1009
+ property,
1010
+ value
1011
+ } = zodParse(data, zod.object({
1012
+ window_id: zod.number(),
1013
+ property: zod.number(),
1014
+ value: zod.number(),
1015
+ }));
1016
+ this.state.enqueueMutation(state => {
1017
+ if (!state.openingContainer) return;
1018
+ state.openingContainer.setProperty(property, value);
1019
+ this.emit("containerProperty", state.openingContainer);
1020
+ });
1021
+ }
1022
+
1023
+ private handleSetTablist(data: object) {
1024
+ const { header, footer } = zodParse(data, zod.object({
1025
+ header: zod.record(zod.string(), zod.any()),
1026
+ footer: zod.record(zod.string(), zod.any()),
1027
+ }));
1028
+ this.emit(
1029
+ "tablist",
1030
+ {
1031
+ header: { text: getTextFromTextComponent(header), raw: header },
1032
+ footer: { text: getTextFromTextComponent(footer), raw: footer },
1033
+ }
1034
+ );
1035
+ }
837
1036
  }
@@ -1,14 +1,15 @@
1
- import { createPublicKey, publicEncrypt, constants as crypto_constants, randomBytes } from "node:crypto";
1
+ import { createPublicKey, publicEncrypt, constants as crypto_constants, randomBytes, randomInt } from "node:crypto";
2
2
  import { TypedEmmiter } from "../base/event";
3
3
  import { ClientEvents } from "../client/client";
4
4
  import { ProtocolVersionMapping } from "../version/registry";
5
5
  import { ClientStatus, ConnectionState, ServerKnownPack, SharedState } from "../world/state";
6
6
  import { sliceBuffer } from "../base/buffer";
7
7
  import { randomUUIDBytes } from "../base/math";
8
- import { Angle, BaseVec3 } from "../physics/direction";
9
- import { MessageTooLong, NotImplemented } from "../base/error";
8
+ import { Angle, BaseVec3, Direction } from "../physics/direction";
9
+ import { MessageTooLong, MissingField, NotImplemented } from "../base/error";
10
10
  import BitSet from "../base/bitset";
11
11
  import { makeMovementFlag } from "../binary/encoder";
12
+ import { BlockFace } from "../world/block";
12
13
 
13
14
  /**
14
15
  * Packet sender
@@ -97,10 +98,22 @@ export class Sender {
97
98
  });
98
99
  }
99
100
 
100
- public sendConfirmTeleportation(teleportId: number) {
101
- this.sendPacket("accept_teleportation", {
102
- teleport_id: teleportId
103
- });
101
+ public sendConfirmTeleportation(teleportId: number): void;
102
+ public sendConfirmTeleportation(teleportId: number, newPos: BaseVec3, newAngle: Angle): void;
103
+ public sendConfirmTeleportation(teleportId: number, newPos?: BaseVec3, newAngle?: Angle) {
104
+ if (this.state.getProtocolId() > 776) {
105
+ if (!newPos || !newAngle) throw new MissingField("newPos or newAngle", "confirm_teleportation packet on version 26.3 or over");
106
+ const { x, y, z } = newPos,
107
+ { yaw, pitch } = newAngle;
108
+ this.sendPacket("accept_teleportation", {
109
+ teleport_id: teleportId,
110
+ x, y, z,
111
+ yaw, pitch
112
+ });
113
+ } else
114
+ this.sendPacket("accept_teleportation", {
115
+ teleport_id: teleportId
116
+ });
104
117
  }
105
118
 
106
119
  public sendKeepAlive(id: bigint) {
@@ -176,4 +189,26 @@ export class Sender {
176
189
  });
177
190
  this.state.messageCount = 0;
178
191
  }
192
+
193
+ public sendUseItemOn(
194
+ hand: "main" | "off",
195
+ position: BaseVec3,
196
+ face: BlockFace | Direction,
197
+ cursorPositionOnBlock: BaseVec3,
198
+ isInsideBlock: boolean,
199
+ worldBorderHit: boolean,
200
+ ) {
201
+ const face_ = (face instanceof Direction ? face.index3D : face) as number;
202
+ this.sendPacket("use_item_on", {
203
+ hand: hand === "off" ? 1 : 0,
204
+ location: position,
205
+ face: face_,
206
+ cursor_position_x: cursorPositionOnBlock.x,
207
+ cursor_position_y: cursorPositionOnBlock.y,
208
+ cursor_position_z: cursorPositionOnBlock.z,
209
+ inside_block: isInsideBlock,
210
+ world_border_hit: worldBorderHit,
211
+ sequence: this.state.nextSequence()
212
+ });
213
+ }
179
214
  }
@@ -209,7 +209,7 @@ export class AABB implements BaseAABB {
209
209
  * Cliping math. Find smallest distance to reach a face of this AABB.
210
210
  */
211
211
  public static getDirection(aabb: BaseAABB, from: BaseVec3, delta: BaseVec3, direction_: Direction | null, scaleRef: [number]) {
212
- let direction = structuredClone(direction_);
212
+ let direction = direction_;
213
213
  const { minX, maxX, minY, maxY, minZ, maxZ } = aabb;
214
214
  if (delta.x > Epsilon)
215
215
  direction = this.clipPoint(
@@ -217,7 +217,7 @@ export class AABB implements BaseAABB {
217
217
  scaleRef,
218
218
  { a: delta.x, b: delta.y, c: delta.z },
219
219
  minX,
220
- minY, maxX,
220
+ minY, maxY,
221
221
  minZ, maxZ,
222
222
  from.x, from.y, from.z
223
223
  );
@@ -227,7 +227,7 @@ export class AABB implements BaseAABB {
227
227
  scaleRef,
228
228
  { a: delta.x, b: delta.y, c: delta.z },
229
229
  maxX,
230
- minY, maxX,
230
+ minY, maxY,
231
231
  minZ, maxZ,
232
232
  from.x, from.y, from.z
233
233
  );
@@ -292,7 +292,7 @@ export class AABB implements BaseAABB {
292
292
  /**
293
293
  * `s` come from this equation:
294
294
  * ```
295
- * fromA + s * deltaA = minA (or point here)
295
+ * fromA + s * deltaA = minA (or `point` here)
296
296
  * ```
297
297
  * Which find "how far the ray travels to reach a face of this bounding box".
298
298
  *
@@ -305,7 +305,7 @@ export class AABB implements BaseAABB {
305
305
  pb = fromB + s * delta.b,
306
306
  pc = fromC + s * delta.c;
307
307
  if (
308
- 0 < s && s < scaleRef[0] &&
308
+ 0 < s && s < scaleRef[0] + Epsilon &&
309
309
  minB - Epsilon < pb && pb < maxB + Epsilon &&
310
310
  minC - Epsilon < pc && pc < maxC + Epsilon
311
311
  ) {
@@ -585,13 +585,22 @@ export class VoxelShape {
585
585
  }
586
586
  private forAllBoxes(consumer: (bb: BaseAABB) => void, mergeNeighbor: boolean) {
587
587
  const shape = this.copy();
588
+ const consumerWithRawInd = (bb: BaseAABB) =>
589
+ consumer({
590
+ minX: shape.xs[bb.minX]!,
591
+ maxX: shape.xs[bb.maxX]!,
592
+ minY: shape.ys[bb.minY]!,
593
+ maxY: shape.ys[bb.maxY]!,
594
+ minZ: shape.zs[bb.minZ]!,
595
+ maxZ: shape.zs[bb.maxZ]!
596
+ });
588
597
  for (let y = 0; y < shape.getSize(BaseAxis.Y); y++)
589
598
  for (let x = 0; x < shape.getSize(BaseAxis.X); x++) {
590
599
  let lastStartZ = -1;
591
600
  for (let z = 0; z <= shape.getSize(BaseAxis.Z); z++) {
592
601
  if (shape.isFullWide(x, y, z)) {
593
602
  if (!mergeNeighbor)
594
- consumer({
603
+ consumerWithRawInd({
595
604
  minX: x,
596
605
  maxX: x + 1,
597
606
  minY: y,
@@ -599,9 +608,9 @@ export class VoxelShape {
599
608
  minZ: z,
600
609
  maxZ: z + 1
601
610
  });
602
- else if (lastStartZ !== -1)
611
+ else if (lastStartZ === -1)
603
612
  lastStartZ = z;
604
- } else if (lastStartZ === -1) {
613
+ } else if (lastStartZ !== -1) {
605
614
  let endX = x,
606
615
  endY = y;
607
616
  shape.clearZStrip(lastStartZ, z, endX, endY);
@@ -615,7 +624,7 @@ export class VoxelShape {
615
624
  }
616
625
  endY++;
617
626
  }
618
- consumer({
627
+ consumerWithRawInd({
619
628
  minX: x,
620
629
  maxX: endX + 1,
621
630
  minY: y,
@@ -17,7 +17,7 @@ export class Vec3 implements BaseVec3 {
17
17
  * Helper function for loading vec3 args
18
18
  */
19
19
  static loadArgs(a: BaseVec3 | number, b?: number, c?: number): BaseVec3 {
20
- let x = 1, y = 1, z = 1;
20
+ let x = 0, y = 0, z = 0;
21
21
  if (typeof a === "object" && "x" in a) {
22
22
  x = a.x;
23
23
  y = a.y;
@@ -114,7 +114,7 @@ export class Vec3 implements BaseVec3 {
114
114
  public multiply(x: number, y: number, z: number): Vec3;
115
115
  public multiply(a: BaseVec3 | number, b?: number, c?: number) {
116
116
  let vec: BaseVec3;
117
- if ((a && b && c) || (typeof a === "object" && "x" in a)) vec = Vec3.loadArgs(a, b, c);
117
+ if ((a !== undefined && b !== undefined && c !== undefined) || (typeof a === "object" && "x" in a)) vec = Vec3.loadArgs(a, b, c);
118
118
  else vec = { x: a, y: a, z: a };
119
119
  const x = this.x * vec.x;
120
120
  const y = this.y * vec.y;
@@ -473,11 +473,11 @@ export class Player {
473
473
  if (this.fallDistance != 0 && movement.length() >= 1) {
474
474
  const checkDistance = Math.min(movement.length(), 8);
475
475
  const checkTo = this.getPos().add(movement.normalize().scale(checkDistance));
476
- const hitResult = BlockGetter.clip(this.getPos(), checkTo, {
477
- from: this.getPos(),
478
- to: checkTo,
479
- getBlockState: (position) => this.blocks.at(position)!.shape
480
- });
476
+ const hitResult = BlockGetter.clip(
477
+ this.getPos(),
478
+ checkTo,
479
+ (position) => this.blocks.at(position)!.shape
480
+ );
481
481
  if (hitResult?.miss !== false)
482
482
  this.fallDistance = 0;
483
483
  }