ygopro-msg-encode 1.1.0 → 1.1.2

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/index.cjs CHANGED
@@ -39,6 +39,7 @@ var index_exports = {};
39
39
  __export(index_exports, {
40
40
  BattleCmdType: () => BattleCmdType,
41
41
  BinaryField: () => BinaryField,
42
+ CardData: () => CardData,
42
43
  CardQuery: () => CardQuery,
43
44
  CardQuery_CardLocation: () => CardQuery_CardLocation,
44
45
  CardQuery_Counter: () => CardQuery_Counter,
@@ -486,10 +487,14 @@ var toBinaryFields = (obj, useClass) => {
486
487
  const length = resolveLength(obj, info.length, key);
487
488
  let currentOffset = offset;
488
489
  for (let i = 0; i < length; i++) {
489
- if (value[i]) {
490
+ if (value && i < value.length && value[i]) {
490
491
  const itemData = toBinaryFields(value[i], Constructor);
491
492
  data.set(itemData, currentOffset);
492
493
  currentOffset += itemData.length;
494
+ } else {
495
+ const emptyInstance = new Constructor();
496
+ const itemData = toBinaryFields(emptyInstance, Constructor);
497
+ currentOffset += itemData.length;
493
498
  }
494
499
  }
495
500
  } else {
@@ -508,7 +513,7 @@ var toBinaryFields = (obj, useClass) => {
508
513
  if (info.length != null) {
509
514
  const length = resolveLength(obj, info.length, key);
510
515
  for (let i = 0; i < length; i++) {
511
- if (value[i] !== void 0 && value[i] !== null) {
516
+ if (value && i < value.length && value[i] !== void 0 && value[i] !== null) {
512
517
  writeValue(typeStr, offset + i * typeSize, value[i]);
513
518
  }
514
519
  }
@@ -582,449 +587,6 @@ var PayloadBase = class {
582
587
  };
583
588
  PayloadBase.identifier = 0;
584
589
 
585
- // src/protos/ctos/base.ts
586
- var YGOProCtosBase = class extends PayloadBase {
587
- /**
588
- * Serialize to full payload including header (length + identifier + body)
589
- * Format: [length 2 bytes LE][identifier 1 byte][body]
590
- * Length = 1 (identifier) + body.length
591
- */
592
- toFullPayload() {
593
- const body = this.toPayload();
594
- const length = 1 + body.length;
595
- const fullPayload = new Uint8Array(3 + body.length);
596
- fullPayload[0] = length & 255;
597
- fullPayload[1] = length >> 8 & 255;
598
- fullPayload[2] = this.identifier;
599
- fullPayload.set(body, 3);
600
- return fullPayload;
601
- }
602
- /**
603
- * Deserialize from full payload including header (length + identifier + body)
604
- * Format: [length 2 bytes LE][identifier 1 byte][body]
605
- * @param data - Full payload data
606
- * @returns this instance
607
- * @throws Error if data is too short or identifier mismatch
608
- */
609
- fromFullPayload(data) {
610
- if (data.length < 3) {
611
- throw new Error(
612
- `CTOS payload too short: expected at least 3 bytes, got ${data.length}`
613
- );
614
- }
615
- const declaredLength = data[0] | data[1] << 8;
616
- const identifier = data[2];
617
- if (identifier !== this.identifier) {
618
- throw new Error(
619
- `CTOS identifier mismatch: expected 0x${this.identifier.toString(16)}, got 0x${identifier.toString(16)}`
620
- );
621
- }
622
- const expectedTotalLength = 3 + declaredLength - 1;
623
- if (data.length < expectedTotalLength) {
624
- throw new Error(
625
- `CTOS payload too short: declared length ${declaredLength} requires ${expectedTotalLength} bytes total, got ${data.length}`
626
- );
627
- }
628
- const bodyData = data.length > expectedTotalLength ? data.slice(3, expectedTotalLength) : data.slice(3);
629
- return this.fromPayload(bodyData);
630
- }
631
- };
632
-
633
- // src/proto-base/registry-base.ts
634
- var RegistryBase = class {
635
- constructor(payloadClass, options = {}) {
636
- this.payloadClass = payloadClass;
637
- this.options = options;
638
- this.protos = /* @__PURE__ */ new Map();
639
- }
640
- register(proto) {
641
- const identifier = proto.identifier;
642
- this.protos.set(identifier, proto);
643
- }
644
- get(identifier) {
645
- return this.protos.get(identifier);
646
- }
647
- getInstanceFromPayload(data) {
648
- const identifier = data[this.options.identifierOffset ?? 0];
649
- const proto = this.get(identifier);
650
- if (!proto) {
651
- return void 0;
652
- }
653
- return new proto().fromPayload(
654
- data.slice(this.options.dataOffset ?? 0)
655
- );
656
- }
657
- };
658
-
659
- // src/protos/ctos/proto/response.ts
660
- var YGOProCtosResponse = class extends YGOProCtosBase {
661
- fromPayload(data) {
662
- this.response = data;
663
- return this;
664
- }
665
- toPayload() {
666
- return this.response || new Uint8Array(0);
667
- }
668
- };
669
- YGOProCtosResponse.identifier = 1;
670
-
671
- // src/protos/ctos/proto/update-deck.ts
672
- var import_ygopro_deck_encode = __toESM(require("ygopro-deck-encode"));
673
- var YGOProCtosUpdateDeck = class extends YGOProCtosBase {
674
- constructor() {
675
- super();
676
- this.deck = new import_ygopro_deck_encode.default();
677
- }
678
- fromPayload(data) {
679
- this.deck = import_ygopro_deck_encode.default.fromUpdateDeckPayload(data);
680
- return this;
681
- }
682
- toPayload() {
683
- return this.deck.toUpdateDeckPayload();
684
- }
685
- fromPartial(data) {
686
- if (data.deck) {
687
- this.deck = new import_ygopro_deck_encode.default(data.deck);
688
- }
689
- return this;
690
- }
691
- copy() {
692
- const copied = new this.constructor();
693
- copied.deck = new import_ygopro_deck_encode.default(this.deck);
694
- return copied;
695
- }
696
- };
697
- YGOProCtosUpdateDeck.identifier = 2;
698
-
699
- // src/protos/ctos/proto/hand-result.ts
700
- var YGOProCtosHandResult = class extends YGOProCtosBase {
701
- };
702
- YGOProCtosHandResult.identifier = 3;
703
- __decorateClass([
704
- BinaryField("u8", 0)
705
- ], YGOProCtosHandResult.prototype, "res", 2);
706
-
707
- // src/protos/ctos/proto/tp-result.ts
708
- var YGOProCtosTpResult = class extends YGOProCtosBase {
709
- };
710
- YGOProCtosTpResult.identifier = 4;
711
- __decorateClass([
712
- BinaryField("u8", 0)
713
- ], YGOProCtosTpResult.prototype, "res", 2);
714
-
715
- // src/protos/ctos/proto/player-info.ts
716
- var YGOProCtosPlayerInfo = class extends YGOProCtosBase {
717
- };
718
- YGOProCtosPlayerInfo.identifier = 16;
719
- __decorateClass([
720
- BinaryField("utf16", 0, 20)
721
- ], YGOProCtosPlayerInfo.prototype, "name", 2);
722
-
723
- // src/protos/ctos/proto/create-game.ts
724
- var YGOProCtosCreateGame = class extends YGOProCtosBase {
725
- };
726
- YGOProCtosCreateGame.identifier = 17;
727
- __decorateClass([
728
- BinaryField(() => HostInfo, 0)
729
- ], YGOProCtosCreateGame.prototype, "info", 2);
730
- __decorateClass([
731
- BinaryField("utf16", 20, 20)
732
- ], YGOProCtosCreateGame.prototype, "name", 2);
733
- __decorateClass([
734
- BinaryField("utf16", 60, 20)
735
- ], YGOProCtosCreateGame.prototype, "pass", 2);
736
-
737
- // src/protos/ctos/proto/join-game.ts
738
- var YGOProCtosJoinGame = class extends YGOProCtosBase {
739
- };
740
- YGOProCtosJoinGame.identifier = 18;
741
- __decorateClass([
742
- BinaryField("u16", 0)
743
- ], YGOProCtosJoinGame.prototype, "version", 2);
744
- __decorateClass([
745
- BinaryField("u32", 4)
746
- ], YGOProCtosJoinGame.prototype, "gameid", 2);
747
- __decorateClass([
748
- BinaryField("utf16", 8, 20)
749
- ], YGOProCtosJoinGame.prototype, "pass", 2);
750
-
751
- // src/protos/ctos/proto/leave-game.ts
752
- var YGOProCtosLeaveGame = class extends YGOProCtosBase {
753
- };
754
- YGOProCtosLeaveGame.identifier = 19;
755
-
756
- // src/protos/ctos/proto/surrender.ts
757
- var YGOProCtosSurrender = class extends YGOProCtosBase {
758
- };
759
- YGOProCtosSurrender.identifier = 20;
760
-
761
- // src/protos/ctos/proto/time-confirm.ts
762
- var YGOProCtosTimeConfirm = class extends YGOProCtosBase {
763
- };
764
- YGOProCtosTimeConfirm.identifier = 21;
765
-
766
- // src/protos/ctos/proto/chat.ts
767
- var YGOProCtosChat = class extends YGOProCtosBase {
768
- constructor() {
769
- super();
770
- this.msg = "";
771
- }
772
- fromPayload(data) {
773
- const decoder = new TextDecoder("utf-16le");
774
- this.msg = decoder.decode(data).replace(/\0+$/, "");
775
- return this;
776
- }
777
- toPayload() {
778
- const encoder = new TextEncoder();
779
- const utf8 = encoder.encode(this.msg);
780
- const decoder = new TextDecoder("utf-8");
781
- const text = decoder.decode(utf8);
782
- const utf16 = new Uint16Array(text.length + 1);
783
- for (let i = 0; i < text.length; i++) {
784
- utf16[i] = text.charCodeAt(i);
785
- }
786
- utf16[text.length] = 0;
787
- const result = new Uint8Array(utf16.buffer);
788
- return result;
789
- }
790
- fromPartial(data) {
791
- if (data.msg !== void 0) {
792
- this.msg = data.msg;
793
- }
794
- return this;
795
- }
796
- };
797
- YGOProCtosChat.identifier = 22;
798
-
799
- // src/protos/ctos/proto/external-address.ts
800
- var YGOProCtosExternalAddress = class extends YGOProCtosBase {
801
- constructor() {
802
- super();
803
- this.real_ip = "0.0.0.0";
804
- this.hostname = "";
805
- }
806
- // Convert IPv4 string to uint32 (network byte order / big endian)
807
- ipToUint32(ip) {
808
- let ipv4 = ip;
809
- if (ip.startsWith("::ffff:")) {
810
- ipv4 = ip.substring(7);
811
- }
812
- const parts = ipv4.split(".");
813
- if (parts.length !== 4) {
814
- return 0;
815
- }
816
- const bytes = parts.map((p) => parseInt(p, 10));
817
- if (bytes.some((b) => isNaN(b) || b < 0 || b > 255)) {
818
- return 0;
819
- }
820
- return bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3];
821
- }
822
- // Convert uint32 (network byte order / big endian) to IPv4 string
823
- uint32ToIp(value) {
824
- const byte1 = value >>> 24 & 255;
825
- const byte2 = value >>> 16 & 255;
826
- const byte3 = value >>> 8 & 255;
827
- const byte4 = value & 255;
828
- return `${byte1}.${byte2}.${byte3}.${byte4}`;
829
- }
830
- fromPayload(data) {
831
- if (data.length < 4) {
832
- throw new Error("CTOS_EXTERNAL_ADDRESS data too short");
833
- }
834
- const ipUint32 = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
835
- this.real_ip = this.uint32ToIp(ipUint32);
836
- if (data.length > 4) {
837
- const decoder = new TextDecoder("utf-16le");
838
- this.hostname = decoder.decode(data.slice(4)).replace(/\0+$/, "");
839
- } else {
840
- this.hostname = "";
841
- }
842
- return this;
843
- }
844
- toPayload() {
845
- const encoder = new TextEncoder();
846
- const utf8 = encoder.encode(this.hostname);
847
- const decoder = new TextDecoder("utf-8");
848
- const text = decoder.decode(utf8);
849
- const utf16 = new Uint16Array(text.length + 1);
850
- for (let i = 0; i < text.length; i++) {
851
- utf16[i] = text.charCodeAt(i);
852
- }
853
- utf16[text.length] = 0;
854
- const result = new Uint8Array(4 + utf16.byteLength);
855
- const ipUint32 = this.ipToUint32(this.real_ip);
856
- result[0] = ipUint32 >>> 24 & 255;
857
- result[1] = ipUint32 >>> 16 & 255;
858
- result[2] = ipUint32 >>> 8 & 255;
859
- result[3] = ipUint32 & 255;
860
- result.set(new Uint8Array(utf16.buffer), 4);
861
- return result;
862
- }
863
- fromPartial(data) {
864
- if (data.real_ip !== void 0) {
865
- this.real_ip = data.real_ip;
866
- }
867
- if (data.hostname !== void 0) {
868
- this.hostname = data.hostname;
869
- }
870
- return this;
871
- }
872
- };
873
- YGOProCtosExternalAddress.identifier = 23;
874
-
875
- // src/protos/ctos/proto/hs-toduelist.ts
876
- var YGOProCtosHsToDuelist = class extends YGOProCtosBase {
877
- };
878
- YGOProCtosHsToDuelist.identifier = 32;
879
-
880
- // src/protos/ctos/proto/hs-toobserver.ts
881
- var YGOProCtosHsToObserver = class extends YGOProCtosBase {
882
- };
883
- YGOProCtosHsToObserver.identifier = 33;
884
-
885
- // src/protos/ctos/proto/hs-ready.ts
886
- var YGOProCtosHsReady = class extends YGOProCtosBase {
887
- };
888
- YGOProCtosHsReady.identifier = 34;
889
-
890
- // src/protos/ctos/proto/hs-notready.ts
891
- var YGOProCtosHsNotReady = class extends YGOProCtosBase {
892
- };
893
- YGOProCtosHsNotReady.identifier = 35;
894
-
895
- // src/protos/ctos/proto/kick.ts
896
- var YGOProCtosKick = class extends YGOProCtosBase {
897
- };
898
- YGOProCtosKick.identifier = 36;
899
- __decorateClass([
900
- BinaryField("u8", 0)
901
- ], YGOProCtosKick.prototype, "pos", 2);
902
-
903
- // src/protos/ctos/proto/hs-start.ts
904
- var YGOProCtosHsStart = class extends YGOProCtosBase {
905
- };
906
- YGOProCtosHsStart.identifier = 37;
907
-
908
- // src/protos/ctos/proto/request-field.ts
909
- var YGOProCtosRequestField = class extends YGOProCtosBase {
910
- };
911
- YGOProCtosRequestField.identifier = 48;
912
-
913
- // src/protos/ctos/registry.ts
914
- var YGOProCtos = new RegistryBase(YGOProCtosBase, {
915
- identifierOffset: 2,
916
- dataOffset: 3
917
- });
918
- YGOProCtos.register(YGOProCtosResponse);
919
- YGOProCtos.register(YGOProCtosUpdateDeck);
920
- YGOProCtos.register(YGOProCtosHandResult);
921
- YGOProCtos.register(YGOProCtosTpResult);
922
- YGOProCtos.register(YGOProCtosPlayerInfo);
923
- YGOProCtos.register(YGOProCtosCreateGame);
924
- YGOProCtos.register(YGOProCtosJoinGame);
925
- YGOProCtos.register(YGOProCtosLeaveGame);
926
- YGOProCtos.register(YGOProCtosSurrender);
927
- YGOProCtos.register(YGOProCtosTimeConfirm);
928
- YGOProCtos.register(YGOProCtosChat);
929
- YGOProCtos.register(YGOProCtosExternalAddress);
930
- YGOProCtos.register(YGOProCtosHsToDuelist);
931
- YGOProCtos.register(YGOProCtosHsToObserver);
932
- YGOProCtos.register(YGOProCtosHsReady);
933
- YGOProCtos.register(YGOProCtosHsNotReady);
934
- YGOProCtos.register(YGOProCtosKick);
935
- YGOProCtos.register(YGOProCtosHsStart);
936
- YGOProCtos.register(YGOProCtosRequestField);
937
-
938
- // src/protos/stoc/base.ts
939
- var YGOProStocBase = class extends PayloadBase {
940
- /**
941
- * Serialize to full payload including header (length + identifier + body)
942
- * Format: [length 2 bytes LE][identifier 1 byte][body]
943
- * Length = 1 (identifier) + body.length
944
- */
945
- toFullPayload() {
946
- const body = this.toPayload();
947
- const length = 1 + body.length;
948
- const fullPayload = new Uint8Array(3 + body.length);
949
- fullPayload[0] = length & 255;
950
- fullPayload[1] = length >> 8 & 255;
951
- fullPayload[2] = this.identifier;
952
- fullPayload.set(body, 3);
953
- return fullPayload;
954
- }
955
- /**
956
- * Deserialize from full payload including header (length + identifier + body)
957
- * Format: [length 2 bytes LE][identifier 1 byte][body]
958
- * @param data - Full payload data
959
- * @returns this instance
960
- * @throws Error if data is too short or identifier mismatch
961
- */
962
- fromFullPayload(data) {
963
- if (data.length < 3) {
964
- throw new Error(
965
- `STOC payload too short: expected at least 3 bytes, got ${data.length}`
966
- );
967
- }
968
- const declaredLength = data[0] | data[1] << 8;
969
- const identifier = data[2];
970
- if (identifier !== this.identifier) {
971
- throw new Error(
972
- `STOC identifier mismatch: expected 0x${this.identifier.toString(16)}, got 0x${identifier.toString(16)}`
973
- );
974
- }
975
- const expectedTotalLength = 3 + declaredLength - 1;
976
- if (data.length < expectedTotalLength) {
977
- throw new Error(
978
- `STOC payload too short: declared length ${declaredLength} requires ${expectedTotalLength} bytes total, got ${data.length}`
979
- );
980
- }
981
- const bodyData = data.length > expectedTotalLength ? data.slice(3, expectedTotalLength) : data.slice(3);
982
- return this.fromPayload(bodyData);
983
- }
984
- };
985
-
986
- // src/protos/msg/base.ts
987
- var YGOProMsgBase = class extends PayloadBase {
988
- fromPayload(data) {
989
- if (data.length < 1) {
990
- throw new Error("MSG data too short");
991
- }
992
- const msgType = data[0];
993
- if (msgType !== this.identifier) {
994
- throw new Error(
995
- `MSG type mismatch: expected ${this.identifier}, got ${msgType}`
996
- );
997
- }
998
- return super.fromPayload(data.slice(1));
999
- }
1000
- toPayload() {
1001
- const payload = super.toPayload();
1002
- const result = new Uint8Array(1 + payload.length);
1003
- result[0] = this.identifier;
1004
- result.set(payload, 1);
1005
- return result;
1006
- }
1007
- opponentView() {
1008
- return this.copy();
1009
- }
1010
- teammateView() {
1011
- return this.copy();
1012
- }
1013
- observerView() {
1014
- return this.opponentView();
1015
- }
1016
- playerView(playerId) {
1017
- if (typeof this["player"] === "number") {
1018
- const selfPlayerId = this["player"];
1019
- if (selfPlayerId === playerId) {
1020
- return this.copy();
1021
- }
1022
- return this.opponentView();
1023
- }
1024
- return this.copy();
1025
- }
1026
- };
1027
-
1028
590
  // src/vendor/ocgcore-constants.ts
1029
591
  var OcgcoreCommonConstants = {
1030
592
  ACTIVITY_ATTACK: 5,
@@ -1387,6 +949,645 @@ var OcgcoreCommonConstants = {
1387
949
  TYPE_XYZ: 8388608
1388
950
  };
1389
951
 
952
+ // src/protos/common/card-data.ts
953
+ var CARD_ARTWORK_VERSIONS_OFFSET = 20;
954
+ var CARD_BLACK_LUSTER_SOLDIER2 = 5405695;
955
+ var CARD_MARINE_DOLPHIN = 78734254;
956
+ var CARD_TWINKLE_MOSS = 13857930;
957
+ function checkSetcode(setcode, value) {
958
+ const settype = value & 4095;
959
+ const setsubtype = value & 61440;
960
+ return setcode && (setcode & 4095) === settype && (setcode & setsubtype) === setsubtype;
961
+ }
962
+ function isAlternative(code, alias) {
963
+ if (code === CARD_BLACK_LUSTER_SOLDIER2) {
964
+ return false;
965
+ }
966
+ return alias && alias < code + CARD_ARTWORK_VERSIONS_OFFSET && code < alias + CARD_ARTWORK_VERSIONS_OFFSET;
967
+ }
968
+ var CardData = class extends PayloadBase {
969
+ /**
970
+ * Check if this card belongs to a specific setcode
971
+ * @param value The setcode value to check against
972
+ * @returns true if the card belongs to the setcode
973
+ */
974
+ isSetCard(value) {
975
+ for (const x of this.setcode) {
976
+ if (!x) {
977
+ return false;
978
+ }
979
+ if (checkSetcode(x, value)) {
980
+ return true;
981
+ }
982
+ }
983
+ return false;
984
+ }
985
+ /**
986
+ * Get the original code of this card (handles alternate artworks)
987
+ * @returns The original card code
988
+ */
989
+ getOriginalCode() {
990
+ return isAlternative(this.code, this.alias) ? this.alias : this.code;
991
+ }
992
+ /**
993
+ * Check if this card can be declared with the given opcode filter
994
+ * @param opcode Array of opcodes that define the filter expression
995
+ * @returns true if the card can be declared
996
+ */
997
+ isDeclarable(opcode) {
998
+ const stack = [];
999
+ for (const it of opcode) {
1000
+ switch (it) {
1001
+ case OcgcoreCommonConstants.OPCODE_ADD: {
1002
+ if (stack.length >= 2) {
1003
+ const rhs = stack.pop();
1004
+ const lhs = stack.pop();
1005
+ stack.push(lhs + rhs);
1006
+ }
1007
+ break;
1008
+ }
1009
+ case OcgcoreCommonConstants.OPCODE_SUB: {
1010
+ if (stack.length >= 2) {
1011
+ const rhs = stack.pop();
1012
+ const lhs = stack.pop();
1013
+ stack.push(lhs - rhs);
1014
+ }
1015
+ break;
1016
+ }
1017
+ case OcgcoreCommonConstants.OPCODE_MUL: {
1018
+ if (stack.length >= 2) {
1019
+ const rhs = stack.pop();
1020
+ const lhs = stack.pop();
1021
+ stack.push(lhs * rhs);
1022
+ }
1023
+ break;
1024
+ }
1025
+ case OcgcoreCommonConstants.OPCODE_DIV: {
1026
+ if (stack.length >= 2) {
1027
+ const rhs = stack.pop();
1028
+ const lhs = stack.pop();
1029
+ stack.push(Math.floor(lhs / rhs));
1030
+ }
1031
+ break;
1032
+ }
1033
+ case OcgcoreCommonConstants.OPCODE_AND: {
1034
+ if (stack.length >= 2) {
1035
+ const rhs = stack.pop();
1036
+ const lhs = stack.pop();
1037
+ stack.push(lhs && rhs ? 1 : 0);
1038
+ }
1039
+ break;
1040
+ }
1041
+ case OcgcoreCommonConstants.OPCODE_OR: {
1042
+ if (stack.length >= 2) {
1043
+ const rhs = stack.pop();
1044
+ const lhs = stack.pop();
1045
+ stack.push(lhs || rhs ? 1 : 0);
1046
+ }
1047
+ break;
1048
+ }
1049
+ case OcgcoreCommonConstants.OPCODE_NEG: {
1050
+ if (stack.length >= 1) {
1051
+ const val = stack.pop();
1052
+ stack.push(-val);
1053
+ }
1054
+ break;
1055
+ }
1056
+ case OcgcoreCommonConstants.OPCODE_NOT: {
1057
+ if (stack.length >= 1) {
1058
+ const val = stack.pop();
1059
+ stack.push(!val ? 1 : 0);
1060
+ }
1061
+ break;
1062
+ }
1063
+ case OcgcoreCommonConstants.OPCODE_ISCODE: {
1064
+ if (stack.length >= 1) {
1065
+ const code = stack.pop();
1066
+ stack.push(this.code === code ? 1 : 0);
1067
+ }
1068
+ break;
1069
+ }
1070
+ case OcgcoreCommonConstants.OPCODE_ISSETCARD: {
1071
+ if (stack.length >= 1) {
1072
+ const setCode = stack.pop();
1073
+ const res = this.isSetCard(setCode);
1074
+ stack.push(res ? 1 : 0);
1075
+ }
1076
+ break;
1077
+ }
1078
+ case OcgcoreCommonConstants.OPCODE_ISTYPE: {
1079
+ if (stack.length >= 1) {
1080
+ const val = stack.pop();
1081
+ stack.push(this.type & val ? 1 : 0);
1082
+ }
1083
+ break;
1084
+ }
1085
+ case OcgcoreCommonConstants.OPCODE_ISRACE: {
1086
+ if (stack.length >= 1) {
1087
+ const raceVal = stack.pop();
1088
+ stack.push(this.race & raceVal ? 1 : 0);
1089
+ }
1090
+ break;
1091
+ }
1092
+ case OcgcoreCommonConstants.OPCODE_ISATTRIBUTE: {
1093
+ if (stack.length >= 1) {
1094
+ const attributeVal = stack.pop();
1095
+ stack.push(this.attribute & attributeVal ? 1 : 0);
1096
+ }
1097
+ break;
1098
+ }
1099
+ default: {
1100
+ stack.push(it);
1101
+ break;
1102
+ }
1103
+ }
1104
+ }
1105
+ if (stack.length !== 1 || stack[0] === 0) {
1106
+ return false;
1107
+ }
1108
+ return this.code === CARD_MARINE_DOLPHIN || this.code === CARD_TWINKLE_MOSS || !this.alias && (this.type & (OcgcoreCommonConstants.TYPE_MONSTER | OcgcoreCommonConstants.TYPE_TOKEN)) !== (OcgcoreCommonConstants.TYPE_MONSTER | OcgcoreCommonConstants.TYPE_TOKEN);
1109
+ }
1110
+ };
1111
+ __decorateClass([
1112
+ BinaryField("u32", 0)
1113
+ ], CardData.prototype, "code", 2);
1114
+ __decorateClass([
1115
+ BinaryField("u32", 4)
1116
+ ], CardData.prototype, "alias", 2);
1117
+ __decorateClass([
1118
+ BinaryField("u16", 8, 16)
1119
+ ], CardData.prototype, "setcode", 2);
1120
+ __decorateClass([
1121
+ BinaryField("u32", 40)
1122
+ ], CardData.prototype, "type", 2);
1123
+ __decorateClass([
1124
+ BinaryField("u32", 44)
1125
+ ], CardData.prototype, "level", 2);
1126
+ __decorateClass([
1127
+ BinaryField("u32", 48)
1128
+ ], CardData.prototype, "attribute", 2);
1129
+ __decorateClass([
1130
+ BinaryField("u32", 52)
1131
+ ], CardData.prototype, "race", 2);
1132
+ __decorateClass([
1133
+ BinaryField("i32", 56)
1134
+ ], CardData.prototype, "attack", 2);
1135
+ __decorateClass([
1136
+ BinaryField("i32", 60)
1137
+ ], CardData.prototype, "defense", 2);
1138
+ __decorateClass([
1139
+ BinaryField("u32", 64)
1140
+ ], CardData.prototype, "lscale", 2);
1141
+ __decorateClass([
1142
+ BinaryField("u32", 68)
1143
+ ], CardData.prototype, "rscale", 2);
1144
+ __decorateClass([
1145
+ BinaryField("u32", 72)
1146
+ ], CardData.prototype, "linkMarker", 2);
1147
+
1148
+ // src/protos/ctos/base.ts
1149
+ var YGOProCtosBase = class extends PayloadBase {
1150
+ /**
1151
+ * Serialize to full payload including header (length + identifier + body)
1152
+ * Format: [length 2 bytes LE][identifier 1 byte][body]
1153
+ * Length = 1 (identifier) + body.length
1154
+ */
1155
+ toFullPayload() {
1156
+ const body = this.toPayload();
1157
+ const length = 1 + body.length;
1158
+ const fullPayload = new Uint8Array(3 + body.length);
1159
+ fullPayload[0] = length & 255;
1160
+ fullPayload[1] = length >> 8 & 255;
1161
+ fullPayload[2] = this.identifier;
1162
+ fullPayload.set(body, 3);
1163
+ return fullPayload;
1164
+ }
1165
+ /**
1166
+ * Deserialize from full payload including header (length + identifier + body)
1167
+ * Format: [length 2 bytes LE][identifier 1 byte][body]
1168
+ * @param data - Full payload data
1169
+ * @returns this instance
1170
+ * @throws Error if data is too short or identifier mismatch
1171
+ */
1172
+ fromFullPayload(data) {
1173
+ if (data.length < 3) {
1174
+ throw new Error(
1175
+ `CTOS payload too short: expected at least 3 bytes, got ${data.length}`
1176
+ );
1177
+ }
1178
+ const declaredLength = data[0] | data[1] << 8;
1179
+ const identifier = data[2];
1180
+ if (identifier !== this.identifier) {
1181
+ throw new Error(
1182
+ `CTOS identifier mismatch: expected 0x${this.identifier.toString(16)}, got 0x${identifier.toString(16)}`
1183
+ );
1184
+ }
1185
+ const expectedTotalLength = 3 + declaredLength - 1;
1186
+ if (data.length < expectedTotalLength) {
1187
+ throw new Error(
1188
+ `CTOS payload too short: declared length ${declaredLength} requires ${expectedTotalLength} bytes total, got ${data.length}`
1189
+ );
1190
+ }
1191
+ const bodyData = data.length > expectedTotalLength ? data.slice(3, expectedTotalLength) : data.slice(3);
1192
+ return this.fromPayload(bodyData);
1193
+ }
1194
+ };
1195
+
1196
+ // src/proto-base/registry-base.ts
1197
+ var RegistryBase = class {
1198
+ constructor(payloadClass, options = {}) {
1199
+ this.payloadClass = payloadClass;
1200
+ this.options = options;
1201
+ this.protos = /* @__PURE__ */ new Map();
1202
+ }
1203
+ register(proto) {
1204
+ const identifier = proto.identifier;
1205
+ this.protos.set(identifier, proto);
1206
+ }
1207
+ get(identifier) {
1208
+ return this.protos.get(identifier);
1209
+ }
1210
+ getInstanceFromPayload(data) {
1211
+ const identifier = data[this.options.identifierOffset ?? 0];
1212
+ const proto = this.get(identifier);
1213
+ if (!proto) {
1214
+ return void 0;
1215
+ }
1216
+ return new proto().fromPayload(
1217
+ data.slice(this.options.dataOffset ?? 0)
1218
+ );
1219
+ }
1220
+ };
1221
+
1222
+ // src/protos/ctos/proto/response.ts
1223
+ var YGOProCtosResponse = class extends YGOProCtosBase {
1224
+ fromPayload(data) {
1225
+ this.response = data;
1226
+ return this;
1227
+ }
1228
+ toPayload() {
1229
+ return this.response || new Uint8Array(0);
1230
+ }
1231
+ };
1232
+ YGOProCtosResponse.identifier = 1;
1233
+
1234
+ // src/protos/ctos/proto/update-deck.ts
1235
+ var import_ygopro_deck_encode = __toESM(require("ygopro-deck-encode"));
1236
+ var YGOProCtosUpdateDeck = class extends YGOProCtosBase {
1237
+ constructor() {
1238
+ super();
1239
+ this.deck = new import_ygopro_deck_encode.default();
1240
+ }
1241
+ fromPayload(data) {
1242
+ this.deck = import_ygopro_deck_encode.default.fromUpdateDeckPayload(data);
1243
+ return this;
1244
+ }
1245
+ toPayload() {
1246
+ return this.deck.toUpdateDeckPayload();
1247
+ }
1248
+ fromPartial(data) {
1249
+ if (data.deck) {
1250
+ this.deck = new import_ygopro_deck_encode.default(data.deck);
1251
+ }
1252
+ return this;
1253
+ }
1254
+ copy() {
1255
+ const copied = new this.constructor();
1256
+ copied.deck = new import_ygopro_deck_encode.default(this.deck);
1257
+ return copied;
1258
+ }
1259
+ };
1260
+ YGOProCtosUpdateDeck.identifier = 2;
1261
+
1262
+ // src/protos/ctos/proto/hand-result.ts
1263
+ var YGOProCtosHandResult = class extends YGOProCtosBase {
1264
+ };
1265
+ YGOProCtosHandResult.identifier = 3;
1266
+ __decorateClass([
1267
+ BinaryField("u8", 0)
1268
+ ], YGOProCtosHandResult.prototype, "res", 2);
1269
+
1270
+ // src/protos/ctos/proto/tp-result.ts
1271
+ var YGOProCtosTpResult = class extends YGOProCtosBase {
1272
+ };
1273
+ YGOProCtosTpResult.identifier = 4;
1274
+ __decorateClass([
1275
+ BinaryField("u8", 0)
1276
+ ], YGOProCtosTpResult.prototype, "res", 2);
1277
+
1278
+ // src/protos/ctos/proto/player-info.ts
1279
+ var YGOProCtosPlayerInfo = class extends YGOProCtosBase {
1280
+ };
1281
+ YGOProCtosPlayerInfo.identifier = 16;
1282
+ __decorateClass([
1283
+ BinaryField("utf16", 0, 20)
1284
+ ], YGOProCtosPlayerInfo.prototype, "name", 2);
1285
+
1286
+ // src/protos/ctos/proto/create-game.ts
1287
+ var YGOProCtosCreateGame = class extends YGOProCtosBase {
1288
+ };
1289
+ YGOProCtosCreateGame.identifier = 17;
1290
+ __decorateClass([
1291
+ BinaryField(() => HostInfo, 0)
1292
+ ], YGOProCtosCreateGame.prototype, "info", 2);
1293
+ __decorateClass([
1294
+ BinaryField("utf16", 20, 20)
1295
+ ], YGOProCtosCreateGame.prototype, "name", 2);
1296
+ __decorateClass([
1297
+ BinaryField("utf16", 60, 20)
1298
+ ], YGOProCtosCreateGame.prototype, "pass", 2);
1299
+
1300
+ // src/protos/ctos/proto/join-game.ts
1301
+ var YGOProCtosJoinGame = class extends YGOProCtosBase {
1302
+ };
1303
+ YGOProCtosJoinGame.identifier = 18;
1304
+ __decorateClass([
1305
+ BinaryField("u16", 0)
1306
+ ], YGOProCtosJoinGame.prototype, "version", 2);
1307
+ __decorateClass([
1308
+ BinaryField("u32", 4)
1309
+ ], YGOProCtosJoinGame.prototype, "gameid", 2);
1310
+ __decorateClass([
1311
+ BinaryField("utf16", 8, 20)
1312
+ ], YGOProCtosJoinGame.prototype, "pass", 2);
1313
+
1314
+ // src/protos/ctos/proto/leave-game.ts
1315
+ var YGOProCtosLeaveGame = class extends YGOProCtosBase {
1316
+ };
1317
+ YGOProCtosLeaveGame.identifier = 19;
1318
+
1319
+ // src/protos/ctos/proto/surrender.ts
1320
+ var YGOProCtosSurrender = class extends YGOProCtosBase {
1321
+ };
1322
+ YGOProCtosSurrender.identifier = 20;
1323
+
1324
+ // src/protos/ctos/proto/time-confirm.ts
1325
+ var YGOProCtosTimeConfirm = class extends YGOProCtosBase {
1326
+ };
1327
+ YGOProCtosTimeConfirm.identifier = 21;
1328
+
1329
+ // src/protos/ctos/proto/chat.ts
1330
+ var YGOProCtosChat = class extends YGOProCtosBase {
1331
+ constructor() {
1332
+ super();
1333
+ this.msg = "";
1334
+ }
1335
+ fromPayload(data) {
1336
+ const decoder = new TextDecoder("utf-16le");
1337
+ this.msg = decoder.decode(data).replace(/\0+$/, "");
1338
+ return this;
1339
+ }
1340
+ toPayload() {
1341
+ const encoder = new TextEncoder();
1342
+ const utf8 = encoder.encode(this.msg);
1343
+ const decoder = new TextDecoder("utf-8");
1344
+ const text = decoder.decode(utf8);
1345
+ const utf16 = new Uint16Array(text.length + 1);
1346
+ for (let i = 0; i < text.length; i++) {
1347
+ utf16[i] = text.charCodeAt(i);
1348
+ }
1349
+ utf16[text.length] = 0;
1350
+ const result = new Uint8Array(utf16.buffer);
1351
+ return result;
1352
+ }
1353
+ fromPartial(data) {
1354
+ if (data.msg !== void 0) {
1355
+ this.msg = data.msg;
1356
+ }
1357
+ return this;
1358
+ }
1359
+ };
1360
+ YGOProCtosChat.identifier = 22;
1361
+
1362
+ // src/protos/ctos/proto/external-address.ts
1363
+ var YGOProCtosExternalAddress = class extends YGOProCtosBase {
1364
+ constructor() {
1365
+ super();
1366
+ this.real_ip = "0.0.0.0";
1367
+ this.hostname = "";
1368
+ }
1369
+ // Convert IPv4 string to uint32 (network byte order / big endian)
1370
+ ipToUint32(ip) {
1371
+ let ipv4 = ip;
1372
+ if (ip.startsWith("::ffff:")) {
1373
+ ipv4 = ip.substring(7);
1374
+ }
1375
+ const parts = ipv4.split(".");
1376
+ if (parts.length !== 4) {
1377
+ return 0;
1378
+ }
1379
+ const bytes = parts.map((p) => parseInt(p, 10));
1380
+ if (bytes.some((b) => isNaN(b) || b < 0 || b > 255)) {
1381
+ return 0;
1382
+ }
1383
+ return bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3];
1384
+ }
1385
+ // Convert uint32 (network byte order / big endian) to IPv4 string
1386
+ uint32ToIp(value) {
1387
+ const byte1 = value >>> 24 & 255;
1388
+ const byte2 = value >>> 16 & 255;
1389
+ const byte3 = value >>> 8 & 255;
1390
+ const byte4 = value & 255;
1391
+ return `${byte1}.${byte2}.${byte3}.${byte4}`;
1392
+ }
1393
+ fromPayload(data) {
1394
+ if (data.length < 4) {
1395
+ throw new Error("CTOS_EXTERNAL_ADDRESS data too short");
1396
+ }
1397
+ const ipUint32 = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
1398
+ this.real_ip = this.uint32ToIp(ipUint32);
1399
+ if (data.length > 4) {
1400
+ const decoder = new TextDecoder("utf-16le");
1401
+ this.hostname = decoder.decode(data.slice(4)).replace(/\0+$/, "");
1402
+ } else {
1403
+ this.hostname = "";
1404
+ }
1405
+ return this;
1406
+ }
1407
+ toPayload() {
1408
+ const encoder = new TextEncoder();
1409
+ const utf8 = encoder.encode(this.hostname);
1410
+ const decoder = new TextDecoder("utf-8");
1411
+ const text = decoder.decode(utf8);
1412
+ const utf16 = new Uint16Array(text.length + 1);
1413
+ for (let i = 0; i < text.length; i++) {
1414
+ utf16[i] = text.charCodeAt(i);
1415
+ }
1416
+ utf16[text.length] = 0;
1417
+ const result = new Uint8Array(4 + utf16.byteLength);
1418
+ const ipUint32 = this.ipToUint32(this.real_ip);
1419
+ result[0] = ipUint32 >>> 24 & 255;
1420
+ result[1] = ipUint32 >>> 16 & 255;
1421
+ result[2] = ipUint32 >>> 8 & 255;
1422
+ result[3] = ipUint32 & 255;
1423
+ result.set(new Uint8Array(utf16.buffer), 4);
1424
+ return result;
1425
+ }
1426
+ fromPartial(data) {
1427
+ if (data.real_ip !== void 0) {
1428
+ this.real_ip = data.real_ip;
1429
+ }
1430
+ if (data.hostname !== void 0) {
1431
+ this.hostname = data.hostname;
1432
+ }
1433
+ return this;
1434
+ }
1435
+ };
1436
+ YGOProCtosExternalAddress.identifier = 23;
1437
+
1438
+ // src/protos/ctos/proto/hs-toduelist.ts
1439
+ var YGOProCtosHsToDuelist = class extends YGOProCtosBase {
1440
+ };
1441
+ YGOProCtosHsToDuelist.identifier = 32;
1442
+
1443
+ // src/protos/ctos/proto/hs-toobserver.ts
1444
+ var YGOProCtosHsToObserver = class extends YGOProCtosBase {
1445
+ };
1446
+ YGOProCtosHsToObserver.identifier = 33;
1447
+
1448
+ // src/protos/ctos/proto/hs-ready.ts
1449
+ var YGOProCtosHsReady = class extends YGOProCtosBase {
1450
+ };
1451
+ YGOProCtosHsReady.identifier = 34;
1452
+
1453
+ // src/protos/ctos/proto/hs-notready.ts
1454
+ var YGOProCtosHsNotReady = class extends YGOProCtosBase {
1455
+ };
1456
+ YGOProCtosHsNotReady.identifier = 35;
1457
+
1458
+ // src/protos/ctos/proto/kick.ts
1459
+ var YGOProCtosKick = class extends YGOProCtosBase {
1460
+ };
1461
+ YGOProCtosKick.identifier = 36;
1462
+ __decorateClass([
1463
+ BinaryField("u8", 0)
1464
+ ], YGOProCtosKick.prototype, "pos", 2);
1465
+
1466
+ // src/protos/ctos/proto/hs-start.ts
1467
+ var YGOProCtosHsStart = class extends YGOProCtosBase {
1468
+ };
1469
+ YGOProCtosHsStart.identifier = 37;
1470
+
1471
+ // src/protos/ctos/proto/request-field.ts
1472
+ var YGOProCtosRequestField = class extends YGOProCtosBase {
1473
+ };
1474
+ YGOProCtosRequestField.identifier = 48;
1475
+
1476
+ // src/protos/ctos/registry.ts
1477
+ var YGOProCtos = new RegistryBase(YGOProCtosBase, {
1478
+ identifierOffset: 2,
1479
+ dataOffset: 3
1480
+ });
1481
+ YGOProCtos.register(YGOProCtosResponse);
1482
+ YGOProCtos.register(YGOProCtosUpdateDeck);
1483
+ YGOProCtos.register(YGOProCtosHandResult);
1484
+ YGOProCtos.register(YGOProCtosTpResult);
1485
+ YGOProCtos.register(YGOProCtosPlayerInfo);
1486
+ YGOProCtos.register(YGOProCtosCreateGame);
1487
+ YGOProCtos.register(YGOProCtosJoinGame);
1488
+ YGOProCtos.register(YGOProCtosLeaveGame);
1489
+ YGOProCtos.register(YGOProCtosSurrender);
1490
+ YGOProCtos.register(YGOProCtosTimeConfirm);
1491
+ YGOProCtos.register(YGOProCtosChat);
1492
+ YGOProCtos.register(YGOProCtosExternalAddress);
1493
+ YGOProCtos.register(YGOProCtosHsToDuelist);
1494
+ YGOProCtos.register(YGOProCtosHsToObserver);
1495
+ YGOProCtos.register(YGOProCtosHsReady);
1496
+ YGOProCtos.register(YGOProCtosHsNotReady);
1497
+ YGOProCtos.register(YGOProCtosKick);
1498
+ YGOProCtos.register(YGOProCtosHsStart);
1499
+ YGOProCtos.register(YGOProCtosRequestField);
1500
+
1501
+ // src/protos/stoc/base.ts
1502
+ var YGOProStocBase = class extends PayloadBase {
1503
+ /**
1504
+ * Serialize to full payload including header (length + identifier + body)
1505
+ * Format: [length 2 bytes LE][identifier 1 byte][body]
1506
+ * Length = 1 (identifier) + body.length
1507
+ */
1508
+ toFullPayload() {
1509
+ const body = this.toPayload();
1510
+ const length = 1 + body.length;
1511
+ const fullPayload = new Uint8Array(3 + body.length);
1512
+ fullPayload[0] = length & 255;
1513
+ fullPayload[1] = length >> 8 & 255;
1514
+ fullPayload[2] = this.identifier;
1515
+ fullPayload.set(body, 3);
1516
+ return fullPayload;
1517
+ }
1518
+ /**
1519
+ * Deserialize from full payload including header (length + identifier + body)
1520
+ * Format: [length 2 bytes LE][identifier 1 byte][body]
1521
+ * @param data - Full payload data
1522
+ * @returns this instance
1523
+ * @throws Error if data is too short or identifier mismatch
1524
+ */
1525
+ fromFullPayload(data) {
1526
+ if (data.length < 3) {
1527
+ throw new Error(
1528
+ `STOC payload too short: expected at least 3 bytes, got ${data.length}`
1529
+ );
1530
+ }
1531
+ const declaredLength = data[0] | data[1] << 8;
1532
+ const identifier = data[2];
1533
+ if (identifier !== this.identifier) {
1534
+ throw new Error(
1535
+ `STOC identifier mismatch: expected 0x${this.identifier.toString(16)}, got 0x${identifier.toString(16)}`
1536
+ );
1537
+ }
1538
+ const expectedTotalLength = 3 + declaredLength - 1;
1539
+ if (data.length < expectedTotalLength) {
1540
+ throw new Error(
1541
+ `STOC payload too short: declared length ${declaredLength} requires ${expectedTotalLength} bytes total, got ${data.length}`
1542
+ );
1543
+ }
1544
+ const bodyData = data.length > expectedTotalLength ? data.slice(3, expectedTotalLength) : data.slice(3);
1545
+ return this.fromPayload(bodyData);
1546
+ }
1547
+ };
1548
+
1549
+ // src/protos/msg/base.ts
1550
+ var YGOProMsgBase = class extends PayloadBase {
1551
+ fromPayload(data) {
1552
+ if (data.length < 1) {
1553
+ throw new Error("MSG data too short");
1554
+ }
1555
+ const msgType = data[0];
1556
+ if (msgType !== this.identifier) {
1557
+ throw new Error(
1558
+ `MSG type mismatch: expected ${this.identifier}, got ${msgType}`
1559
+ );
1560
+ }
1561
+ return super.fromPayload(data.slice(1));
1562
+ }
1563
+ toPayload() {
1564
+ const payload = super.toPayload();
1565
+ const result = new Uint8Array(1 + payload.length);
1566
+ result[0] = this.identifier;
1567
+ result.set(payload, 1);
1568
+ return result;
1569
+ }
1570
+ opponentView() {
1571
+ return this.copy();
1572
+ }
1573
+ teammateView() {
1574
+ return this.copy();
1575
+ }
1576
+ observerView() {
1577
+ return this.opponentView();
1578
+ }
1579
+ playerView(playerId) {
1580
+ if (typeof this["player"] === "number") {
1581
+ const selfPlayerId = this["player"];
1582
+ if (selfPlayerId === playerId) {
1583
+ return this.copy();
1584
+ }
1585
+ return this.opponentView();
1586
+ }
1587
+ return this.copy();
1588
+ }
1589
+ };
1590
+
1390
1591
  // src/protos/msg/proto/add-counter.ts
1391
1592
  var YGOProMsgAddCounter = class extends YGOProMsgBase {
1392
1593
  };
@@ -5651,6 +5852,7 @@ var RoomStatus = /* @__PURE__ */ ((RoomStatus2) => {
5651
5852
  0 && (module.exports = {
5652
5853
  BattleCmdType,
5653
5854
  BinaryField,
5855
+ CardData,
5654
5856
  CardQuery,
5655
5857
  CardQuery_CardLocation,
5656
5858
  CardQuery_Counter,