ygopro-deck-encode 1.0.6 → 1.0.7

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/README.md CHANGED
@@ -23,6 +23,10 @@ const ygomobileDeckUrl = deck.toYGOMobileDeckURL(); // YGOMobile Deck URL
23
23
  const yetAnotherDeck3 = YGOProDeck.fromYGOMobileDeckURL(ygomobileDeckUrl); // decode it back
24
24
 
25
25
  const updateDeckPayload = deck.toUpdateDeckPayload(); // payload for MSG_UPDATE_DECK
26
+ // decode it back, but a callback is needed for check if it's extra deck
27
+ // use SQLite3 is recommended
28
+ // by default, it would assume everything is main deck
29
+ const yetAnotherDeck4 = YGOProDeck.fromUpdateDeckPayload(updateDeckPayload, (code, i, mainc) => i >= mainc - 15);
26
30
  ```
27
31
 
28
32
 
package/dist/index.cjs CHANGED
@@ -50,46 +50,120 @@ function countItems(arr) {
50
50
  }
51
51
  return map;
52
52
  }
53
- var BufferWriter = class {
54
- constructor(length) {
53
+ var BufferCursor = class {
54
+ constructor(bufOrLength) {
55
55
  this.pointer = 0;
56
- this.buffer = new Uint8Array(length);
56
+ if (typeof bufOrLength === "number") {
57
+ this.buffer = new Uint8Array(bufOrLength);
58
+ } else {
59
+ this.buffer = bufOrLength;
60
+ }
61
+ }
62
+ /**
63
+ * 安全地将 pointer 向前移动指定字节数。
64
+ * @param bytes 要移动的字节数
65
+ * @returns 原来 pointer 的值
66
+ * @throws RangeError 如果越界
67
+ */
68
+ increasePointer(bytes) {
69
+ const old = this.pointer;
70
+ const next = old + bytes;
71
+ if (next > this.buffer.length) {
72
+ throw new RangeError(
73
+ `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`
74
+ );
75
+ }
76
+ this.pointer = next;
77
+ return old;
78
+ }
79
+ };
80
+ var BufferWriter = class extends BufferCursor {
81
+ constructor(length) {
82
+ super(length);
57
83
  }
58
84
  writeUint32LE(value) {
59
- this.buffer[this.pointer++] = value & 255;
60
- this.buffer[this.pointer++] = value >>> 8 & 255;
61
- this.buffer[this.pointer++] = value >>> 16 & 255;
62
- this.buffer[this.pointer++] = value >>> 24 & 255;
85
+ const idx = this.increasePointer(4);
86
+ this.buffer[idx] = value & 255;
87
+ this.buffer[idx + 1] = value >>> 8 & 255;
88
+ this.buffer[idx + 2] = value >>> 16 & 255;
89
+ this.buffer[idx + 3] = value >>> 24 & 255;
63
90
  return this;
64
91
  }
65
92
  writeUint32BE(value) {
66
- this.buffer[this.pointer++] = value >>> 24 & 255;
67
- this.buffer[this.pointer++] = value >>> 16 & 255;
68
- this.buffer[this.pointer++] = value >>> 8 & 255;
69
- this.buffer[this.pointer++] = value & 255;
93
+ const idx = this.increasePointer(4);
94
+ this.buffer[idx] = value >>> 24 & 255;
95
+ this.buffer[idx + 1] = value >>> 16 & 255;
96
+ this.buffer[idx + 2] = value >>> 8 & 255;
97
+ this.buffer[idx + 3] = value & 255;
70
98
  return this;
71
99
  }
72
100
  writeUint16LE(value) {
73
- this.buffer[this.pointer++] = value & 255;
74
- this.buffer[this.pointer++] = value >>> 8 & 255;
101
+ const idx = this.increasePointer(2);
102
+ this.buffer[idx] = value & 255;
103
+ this.buffer[idx + 1] = value >>> 8 & 255;
75
104
  return this;
76
105
  }
77
106
  writeUint16BE(value) {
78
- this.buffer[this.pointer++] = value >>> 8 & 255;
79
- this.buffer[this.pointer++] = value & 255;
107
+ const idx = this.increasePointer(2);
108
+ this.buffer[idx] = value >>> 8 & 255;
109
+ this.buffer[idx + 1] = value & 255;
80
110
  return this;
81
111
  }
82
112
  writeUint8(value) {
83
- this.buffer[this.pointer++] = value & 255;
113
+ const idx = this.increasePointer(1);
114
+ this.buffer[idx] = value & 255;
84
115
  return this;
85
116
  }
86
117
  writeString(str) {
87
118
  for (let i = 0; i < str.length; i++) {
88
- this.buffer[this.pointer++] = str.charCodeAt(i);
119
+ const idx = this.increasePointer(1);
120
+ this.buffer[idx] = str.charCodeAt(i);
89
121
  }
90
122
  return this;
91
123
  }
92
124
  };
125
+ var BufferReader = class extends BufferCursor {
126
+ constructor(buf) {
127
+ super(buf);
128
+ }
129
+ readUint32LE() {
130
+ const idx = this.increasePointer(4);
131
+ const b = this.buffer;
132
+ return (b[idx] | b[idx + 1] << 8 | b[idx + 2] << 16 | b[idx + 3] << 24) >>> 0;
133
+ }
134
+ readUint32BE() {
135
+ const idx = this.increasePointer(4);
136
+ const b = this.buffer;
137
+ return (b[idx] << 24 | b[idx + 1] << 16 | b[idx + 2] << 8 | b[idx + 3]) >>> 0;
138
+ }
139
+ readUint16LE() {
140
+ const idx = this.increasePointer(2);
141
+ const b = this.buffer;
142
+ return b[idx] | b[idx + 1] << 8;
143
+ }
144
+ readUint16BE() {
145
+ const idx = this.increasePointer(2);
146
+ const b = this.buffer;
147
+ return b[idx] << 8 | b[idx + 1];
148
+ }
149
+ readUint8() {
150
+ const idx = this.increasePointer(1);
151
+ return this.buffer[idx];
152
+ }
153
+ readString(length) {
154
+ let s = "";
155
+ for (let i = 0; i < length; i++) {
156
+ const idx = this.increasePointer(1);
157
+ s += String.fromCharCode(this.buffer[idx]);
158
+ }
159
+ return s;
160
+ }
161
+ readRemaining() {
162
+ const remaining = this.buffer.length - this.pointer;
163
+ const idx = this.increasePointer(remaining);
164
+ return this.buffer.subarray(idx, this.buffer.length);
165
+ }
166
+ };
93
167
 
94
168
  // src/ydke.ts
95
169
  function base64ToUint32Array(base64) {
@@ -323,6 +397,30 @@ var YGOProDeck = class {
323
397
  static fromYdkString(str) {
324
398
  return new YGOProDeck().fromYdkString(str);
325
399
  }
400
+ fromUpdateDeckPayload(buf, isExtraDeckCard = () => false) {
401
+ const reader = new BufferReader(buf);
402
+ const mainc = reader.readUint32LE();
403
+ const sidec = reader.readUint32LE();
404
+ this.main = [];
405
+ this.extra = [];
406
+ this.side = [];
407
+ for (let i = 0; i < mainc; i++) {
408
+ const id = reader.readUint32LE();
409
+ if (isExtraDeckCard(id, i, mainc)) {
410
+ this.extra.push(id);
411
+ } else {
412
+ this.main.push(id);
413
+ }
414
+ }
415
+ for (let i = 0; i < sidec; i++) {
416
+ const id = reader.readUint32LE();
417
+ this.side.push(id);
418
+ }
419
+ return this;
420
+ }
421
+ static fromUpdateDeckPayload(buf, isExtraDeckCard = () => false) {
422
+ return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);
423
+ }
326
424
  toUpdateDeckPayload() {
327
425
  const cards = [...this.main, ...this.extra, ...this.side];
328
426
  const writer = new BufferWriter(cards.length * 4 + 8).writeUint32LE(this.main.length + this.extra.length).writeUint32LE(this.side.length);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../index.ts", "../src/base64.ts", "../src/utils.ts", "../src/ydke.ts", "../src/ygom.ts"],
4
- "sourcesContent": ["import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferWriter, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n return counted.reduce((a, b) => a + b.size * 4, 0);\n }\n\n toUint8Array() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.size * 4, 0),\n );\n const writeCards = (countMap: Map<number, number>, type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const [id, count] of countMap.entries()) {\n if (count > 4) {\n throw new Error(`Too many cards: ${id}`);\n }\n const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString() {\n return toBase64Url(this.toUint8Array());\n }\n\n toString() {\n return this.toEncodedString();\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n", "export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n return map;\n}\n\nexport class BufferWriter {\n buffer: Uint8Array;\n pointer = 0;\n constructor(length: number) {\n this.buffer = new Uint8Array(length);\n }\n writeUint32LE(value: number) {\n this.buffer[this.pointer++] = value & 0xff;\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n this.buffer[this.pointer++] = (value >>> 16) & 0xff;\n this.buffer[this.pointer++] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n this.buffer[this.pointer++] = (value >>> 24) & 0xff;\n this.buffer[this.pointer++] = (value >>> 16) & 0xff;\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n this.buffer[this.pointer++] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n this.buffer[this.pointer++] = value & 0xff;\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n this.buffer[this.pointer++] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n this.buffer[this.pointer++] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n this.buffer[this.pointer++] = str.charCodeAt(i);\n }\n return this;\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF\u533A\u57DF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\n\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction toBinary(value: number, length: number): string {\n return value.toString(2).padStart(length, '0');\n}\n\nfunction encodeCards(cards: number[]): string {\n const bits: string[] = [];\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? '10' : count === 3 ? '11' : '01';\n bits.push(prefix + toBinary(id, 27));\n i += count;\n }\n return bits.join('');\n}\n\nfunction countUnique(cards: number[]): number {\n let num = 0;\n for (let i = 0; i < cards.length; i++) {\n const id = cards[i];\n if (id > 0) {\n num++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n }\n }\n }\n }\n return num;\n}\n\n// === \u4E3B\u51FD\u6570 ===\n\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const header = toBinary(mNum, 8) + toBinary(eNum, 4) + toBinary(sNum, 4);\n let bitString = header + encodeCards(main) + encodeCards(extra) + encodeCards(side);\n while (bitString.length % 8 !== 0) bitString += '0';\n\n const bytes = new Uint8Array(bitString.length / 8);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(bitString.slice(i * 8, i * 8 + 8), 2);\n }\n\n let encoded = toBase64Url(bytes)\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(customParams)) {\n searchParams.set(key, value);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Not a YGO Mobile deck URI');\n }\n\n let encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n\n const bits = Array.from(bytes)\n .map((b) => b.toString(2).padStart(8, '0'))\n .join('');\n\n const mNum = parseInt(bits.slice(0, 8), 2);\n const eNum = parseInt(bits.slice(8, 12), 2);\n const sNum = parseInt(bits.slice(12, 16), 2);\n\n const all = mNum + eNum + sNum;\n const cards: number[] = [];\n let pos = 16;\n \n const res = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n }\n\n let i = 0;\n\n while (pos + 29 <= bits.length && cards.length < all) {\n const countBits = bits.slice(pos, pos + 2);\n const count = countBits === '10' ? 2 : countBits === '11' ? 3 : 1;\n const id = parseInt(bits.slice(pos + 2, pos + 29), 2);\n const field = i < mNum ? 'main' : i < mNum + eNum ? 'extra' : 'side';\n res[field].push(...Array(count).fill(id));\n pos += 29;\n i++;\n }\n\n return {\n ...res,\n name: url.searchParams.get(QUERY_NAME),\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferReader, BufferWriter, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n return counted.reduce((a, b) => a + b.size * 4, 0);\n }\n\n toUint8Array() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.size * 4, 0),\n );\n const writeCards = (countMap: Map<number, number>, type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const [id, count] of countMap.entries()) {\n if (count > 4) {\n throw new Error(`Too many cards: ${id}`);\n }\n const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString() {\n return toBase64Url(this.toUint8Array());\n }\n\n toString() {\n return this.toEncodedString();\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {\n const reader = new BufferReader(buf);\n const mainc = reader.readUint32LE();\n const sidec = reader.readUint32LE();\n this.main = [];\n this.extra = [];\n this.side = [];\n for(let i = 0; i < mainc; i++) {\n const id = reader.readUint32LE();\n if (isExtraDeckCard(id, i, mainc)) {\n this.extra.push(id);\n } else {\n this.main.push(id);\n }\n }\n for(let i = 0; i < sidec; i++) {\n const id = reader.readUint32LE();\n this.side.push(id);\n }\n return this;\n }\n\n static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) { \n return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n", "export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n return map;\n}\nabstract class BufferCursor {\n buffer: Uint8Array;\n pointer = 0;\n\n constructor(bufOrLength: Uint8Array | number) {\n if (typeof bufOrLength === 'number') {\n this.buffer = new Uint8Array(bufOrLength);\n } else {\n this.buffer = bufOrLength;\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5C06 pointer \u5411\u524D\u79FB\u52A8\u6307\u5B9A\u5B57\u8282\u6570\u3002\n * @param bytes \u8981\u79FB\u52A8\u7684\u5B57\u8282\u6570\n * @returns \u539F\u6765 pointer \u7684\u503C\n * @throws RangeError \u5982\u679C\u8D8A\u754C\n */\n protected increasePointer(bytes: number): number {\n const old = this.pointer;\n const next = old + bytes;\n if (next > this.buffer.length) {\n throw new RangeError(\n `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`\n );\n }\n this.pointer = next;\n return old;\n }\n}\n\nexport class BufferWriter extends BufferCursor {\n constructor(length: number) {\n super(length);\n }\n\n writeUint32LE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n this.buffer[idx + 2] = (value >>> 16) & 0xff;\n this.buffer[idx + 3] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = (value >>> 24) & 0xff;\n this.buffer[idx + 1] = (value >>> 16) & 0xff;\n this.buffer[idx + 2] = (value >>> 8) & 0xff;\n this.buffer[idx + 3] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = (value >>> 8) & 0xff;\n this.buffer[idx + 1] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = str.charCodeAt(i);\n }\n return this;\n }\n}\n\nexport class BufferReader extends BufferCursor {\n constructor(buf: Uint8Array) {\n super(buf);\n }\n\n readUint32LE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n // >>>0 \u4FDD\u8BC1\u65E0\u7B26\u53F7\u8F93\u51FA\n return (\n (b[idx ] ) |\n (b[idx + 1] << 8) |\n (b[idx + 2] << 16) |\n (b[idx + 3] << 24)\n ) >>> 0;\n }\n\n readUint32BE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n return (\n (b[idx ] << 24) |\n (b[idx + 1] << 16) |\n (b[idx + 2] << 8) |\n (b[idx + 3] )\n ) >>> 0;\n }\n\n readUint16LE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return (b[idx] | (b[idx + 1] << 8));\n }\n\n readUint16BE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return ((b[idx] << 8) | b[idx + 1]);\n }\n\n readUint8(): number {\n const idx = this.increasePointer(1);\n return this.buffer[idx];\n }\n\n readString(length: number): string {\n let s = '';\n for (let i = 0; i < length; i++) {\n const idx = this.increasePointer(1);\n s += String.fromCharCode(this.buffer[idx]);\n }\n return s;\n }\n\n readRemaining(): Uint8Array {\n const remaining = this.buffer.length - this.pointer;\n const idx = this.increasePointer(remaining);\n return this.buffer.subarray(idx, this.buffer.length);\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF\u533A\u57DF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\n\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction toBinary(value: number, length: number): string {\n return value.toString(2).padStart(length, '0');\n}\n\nfunction encodeCards(cards: number[]): string {\n const bits: string[] = [];\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? '10' : count === 3 ? '11' : '01';\n bits.push(prefix + toBinary(id, 27));\n i += count;\n }\n return bits.join('');\n}\n\nfunction countUnique(cards: number[]): number {\n let num = 0;\n for (let i = 0; i < cards.length; i++) {\n const id = cards[i];\n if (id > 0) {\n num++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n }\n }\n }\n }\n return num;\n}\n\n// === \u4E3B\u51FD\u6570 ===\n\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const header = toBinary(mNum, 8) + toBinary(eNum, 4) + toBinary(sNum, 4);\n let bitString = header + encodeCards(main) + encodeCards(extra) + encodeCards(side);\n while (bitString.length % 8 !== 0) bitString += '0';\n\n const bytes = new Uint8Array(bitString.length / 8);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(bitString.slice(i * 8, i * 8 + 8), 2);\n }\n\n let encoded = toBase64Url(bytes)\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(customParams)) {\n searchParams.set(key, value);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Not a YGO Mobile deck URI');\n }\n\n let encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n\n const bits = Array.from(bytes)\n .map((b) => b.toString(2).padStart(8, '0'))\n .join('');\n\n const mNum = parseInt(bits.slice(0, 8), 2);\n const eNum = parseInt(bits.slice(8, 12), 2);\n const sNum = parseInt(bits.slice(12, 16), 2);\n\n const all = mNum + eNum + sNum;\n const cards: number[] = [];\n let pos = 16;\n \n const res = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n }\n\n let i = 0;\n\n while (pos + 29 <= bits.length && cards.length < all) {\n const countBits = bits.slice(pos, pos + 2);\n const count = countBits === '10' ? 2 : countBits === '11' ? 3 : 1;\n const id = parseInt(bits.slice(pos + 2, pos + 29), 2);\n const field = i < mNum ? 'main' : i < mNum + eNum ? 'extra' : 'side';\n res[field].push(...Array(count).fill(id));\n pos += 29;\n i++;\n }\n\n return {\n ...res,\n name: url.searchParams.get(QUERY_NAME),\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/index.d.ts CHANGED
@@ -14,6 +14,8 @@ export default class YGOProDeck {
14
14
  toYdkString(): string;
15
15
  fromYdkString(str: string): this;
16
16
  static fromYdkString(str: string): YGOProDeck;
17
+ fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard?: (code: number, i: number, mainc: number) => boolean): this;
18
+ static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard?: (code: number) => boolean): YGOProDeck;
17
19
  toUpdateDeckPayload(): Uint8Array;
18
20
  fromYGOMobileDeckURL(uri: string): YGOProDeck;
19
21
  static fromYGOMobileDeckURL(uri: string): YGOProDeck;
package/dist/index.mjs CHANGED
@@ -25,47 +25,121 @@ function countItems(arr) {
25
25
  }
26
26
  return map;
27
27
  }
28
- var BufferWriter = class {
28
+ var BufferCursor = class {
29
29
  buffer;
30
30
  pointer = 0;
31
+ constructor(bufOrLength) {
32
+ if (typeof bufOrLength === "number") {
33
+ this.buffer = new Uint8Array(bufOrLength);
34
+ } else {
35
+ this.buffer = bufOrLength;
36
+ }
37
+ }
38
+ /**
39
+ * 安全地将 pointer 向前移动指定字节数。
40
+ * @param bytes 要移动的字节数
41
+ * @returns 原来 pointer 的值
42
+ * @throws RangeError 如果越界
43
+ */
44
+ increasePointer(bytes) {
45
+ const old = this.pointer;
46
+ const next = old + bytes;
47
+ if (next > this.buffer.length) {
48
+ throw new RangeError(
49
+ `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`
50
+ );
51
+ }
52
+ this.pointer = next;
53
+ return old;
54
+ }
55
+ };
56
+ var BufferWriter = class extends BufferCursor {
31
57
  constructor(length) {
32
- this.buffer = new Uint8Array(length);
58
+ super(length);
33
59
  }
34
60
  writeUint32LE(value) {
35
- this.buffer[this.pointer++] = value & 255;
36
- this.buffer[this.pointer++] = value >>> 8 & 255;
37
- this.buffer[this.pointer++] = value >>> 16 & 255;
38
- this.buffer[this.pointer++] = value >>> 24 & 255;
61
+ const idx = this.increasePointer(4);
62
+ this.buffer[idx] = value & 255;
63
+ this.buffer[idx + 1] = value >>> 8 & 255;
64
+ this.buffer[idx + 2] = value >>> 16 & 255;
65
+ this.buffer[idx + 3] = value >>> 24 & 255;
39
66
  return this;
40
67
  }
41
68
  writeUint32BE(value) {
42
- this.buffer[this.pointer++] = value >>> 24 & 255;
43
- this.buffer[this.pointer++] = value >>> 16 & 255;
44
- this.buffer[this.pointer++] = value >>> 8 & 255;
45
- this.buffer[this.pointer++] = value & 255;
69
+ const idx = this.increasePointer(4);
70
+ this.buffer[idx] = value >>> 24 & 255;
71
+ this.buffer[idx + 1] = value >>> 16 & 255;
72
+ this.buffer[idx + 2] = value >>> 8 & 255;
73
+ this.buffer[idx + 3] = value & 255;
46
74
  return this;
47
75
  }
48
76
  writeUint16LE(value) {
49
- this.buffer[this.pointer++] = value & 255;
50
- this.buffer[this.pointer++] = value >>> 8 & 255;
77
+ const idx = this.increasePointer(2);
78
+ this.buffer[idx] = value & 255;
79
+ this.buffer[idx + 1] = value >>> 8 & 255;
51
80
  return this;
52
81
  }
53
82
  writeUint16BE(value) {
54
- this.buffer[this.pointer++] = value >>> 8 & 255;
55
- this.buffer[this.pointer++] = value & 255;
83
+ const idx = this.increasePointer(2);
84
+ this.buffer[idx] = value >>> 8 & 255;
85
+ this.buffer[idx + 1] = value & 255;
56
86
  return this;
57
87
  }
58
88
  writeUint8(value) {
59
- this.buffer[this.pointer++] = value & 255;
89
+ const idx = this.increasePointer(1);
90
+ this.buffer[idx] = value & 255;
60
91
  return this;
61
92
  }
62
93
  writeString(str) {
63
94
  for (let i = 0; i < str.length; i++) {
64
- this.buffer[this.pointer++] = str.charCodeAt(i);
95
+ const idx = this.increasePointer(1);
96
+ this.buffer[idx] = str.charCodeAt(i);
65
97
  }
66
98
  return this;
67
99
  }
68
100
  };
101
+ var BufferReader = class extends BufferCursor {
102
+ constructor(buf) {
103
+ super(buf);
104
+ }
105
+ readUint32LE() {
106
+ const idx = this.increasePointer(4);
107
+ const b = this.buffer;
108
+ return (b[idx] | b[idx + 1] << 8 | b[idx + 2] << 16 | b[idx + 3] << 24) >>> 0;
109
+ }
110
+ readUint32BE() {
111
+ const idx = this.increasePointer(4);
112
+ const b = this.buffer;
113
+ return (b[idx] << 24 | b[idx + 1] << 16 | b[idx + 2] << 8 | b[idx + 3]) >>> 0;
114
+ }
115
+ readUint16LE() {
116
+ const idx = this.increasePointer(2);
117
+ const b = this.buffer;
118
+ return b[idx] | b[idx + 1] << 8;
119
+ }
120
+ readUint16BE() {
121
+ const idx = this.increasePointer(2);
122
+ const b = this.buffer;
123
+ return b[idx] << 8 | b[idx + 1];
124
+ }
125
+ readUint8() {
126
+ const idx = this.increasePointer(1);
127
+ return this.buffer[idx];
128
+ }
129
+ readString(length) {
130
+ let s = "";
131
+ for (let i = 0; i < length; i++) {
132
+ const idx = this.increasePointer(1);
133
+ s += String.fromCharCode(this.buffer[idx]);
134
+ }
135
+ return s;
136
+ }
137
+ readRemaining() {
138
+ const remaining = this.buffer.length - this.pointer;
139
+ const idx = this.increasePointer(remaining);
140
+ return this.buffer.subarray(idx, this.buffer.length);
141
+ }
142
+ };
69
143
 
70
144
  // src/ydke.ts
71
145
  function base64ToUint32Array(base64) {
@@ -298,6 +372,30 @@ var YGOProDeck = class {
298
372
  static fromYdkString(str) {
299
373
  return new YGOProDeck().fromYdkString(str);
300
374
  }
375
+ fromUpdateDeckPayload(buf, isExtraDeckCard = () => false) {
376
+ const reader = new BufferReader(buf);
377
+ const mainc = reader.readUint32LE();
378
+ const sidec = reader.readUint32LE();
379
+ this.main = [];
380
+ this.extra = [];
381
+ this.side = [];
382
+ for (let i = 0; i < mainc; i++) {
383
+ const id = reader.readUint32LE();
384
+ if (isExtraDeckCard(id, i, mainc)) {
385
+ this.extra.push(id);
386
+ } else {
387
+ this.main.push(id);
388
+ }
389
+ }
390
+ for (let i = 0; i < sidec; i++) {
391
+ const id = reader.readUint32LE();
392
+ this.side.push(id);
393
+ }
394
+ return this;
395
+ }
396
+ static fromUpdateDeckPayload(buf, isExtraDeckCard = () => false) {
397
+ return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);
398
+ }
301
399
  toUpdateDeckPayload() {
302
400
  const cards = [...this.main, ...this.extra, ...this.side];
303
401
  const writer = new BufferWriter(cards.length * 4 + 8).writeUint32LE(this.main.length + this.extra.length).writeUint32LE(this.side.length);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/base64.ts", "../src/utils.ts", "../src/ydke.ts", "../src/ygom.ts", "../index.ts"],
4
- "sourcesContent": ["export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n return map;\n}\n\nexport class BufferWriter {\n buffer: Uint8Array;\n pointer = 0;\n constructor(length: number) {\n this.buffer = new Uint8Array(length);\n }\n writeUint32LE(value: number) {\n this.buffer[this.pointer++] = value & 0xff;\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n this.buffer[this.pointer++] = (value >>> 16) & 0xff;\n this.buffer[this.pointer++] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n this.buffer[this.pointer++] = (value >>> 24) & 0xff;\n this.buffer[this.pointer++] = (value >>> 16) & 0xff;\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n this.buffer[this.pointer++] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n this.buffer[this.pointer++] = value & 0xff;\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n this.buffer[this.pointer++] = (value >>> 8) & 0xff;\n this.buffer[this.pointer++] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n this.buffer[this.pointer++] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n this.buffer[this.pointer++] = str.charCodeAt(i);\n }\n return this;\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF\u533A\u57DF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\n\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction toBinary(value: number, length: number): string {\n return value.toString(2).padStart(length, '0');\n}\n\nfunction encodeCards(cards: number[]): string {\n const bits: string[] = [];\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? '10' : count === 3 ? '11' : '01';\n bits.push(prefix + toBinary(id, 27));\n i += count;\n }\n return bits.join('');\n}\n\nfunction countUnique(cards: number[]): number {\n let num = 0;\n for (let i = 0; i < cards.length; i++) {\n const id = cards[i];\n if (id > 0) {\n num++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n }\n }\n }\n }\n return num;\n}\n\n// === \u4E3B\u51FD\u6570 ===\n\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const header = toBinary(mNum, 8) + toBinary(eNum, 4) + toBinary(sNum, 4);\n let bitString = header + encodeCards(main) + encodeCards(extra) + encodeCards(side);\n while (bitString.length % 8 !== 0) bitString += '0';\n\n const bytes = new Uint8Array(bitString.length / 8);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(bitString.slice(i * 8, i * 8 + 8), 2);\n }\n\n let encoded = toBase64Url(bytes)\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(customParams)) {\n searchParams.set(key, value);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Not a YGO Mobile deck URI');\n }\n\n let encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n\n const bits = Array.from(bytes)\n .map((b) => b.toString(2).padStart(8, '0'))\n .join('');\n\n const mNum = parseInt(bits.slice(0, 8), 2);\n const eNum = parseInt(bits.slice(8, 12), 2);\n const sNum = parseInt(bits.slice(12, 16), 2);\n\n const all = mNum + eNum + sNum;\n const cards: number[] = [];\n let pos = 16;\n \n const res = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n }\n\n let i = 0;\n\n while (pos + 29 <= bits.length && cards.length < all) {\n const countBits = bits.slice(pos, pos + 2);\n const count = countBits === '10' ? 2 : countBits === '11' ? 3 : 1;\n const id = parseInt(bits.slice(pos + 2, pos + 29), 2);\n const field = i < mNum ? 'main' : i < mNum + eNum ? 'extra' : 'side';\n res[field].push(...Array(count).fill(id));\n pos += 29;\n i++;\n }\n\n return {\n ...res,\n name: url.searchParams.get(QUERY_NAME),\n };\n}\n", "import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferWriter, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n return counted.reduce((a, b) => a + b.size * 4, 0);\n }\n\n toUint8Array() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.size * 4, 0),\n );\n const writeCards = (countMap: Map<number, number>, type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const [id, count] of countMap.entries()) {\n if (count > 4) {\n throw new Error(`Too many cards: ${id}`);\n }\n const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString() {\n return toBase64Url(this.toUint8Array());\n }\n\n toString() {\n return this.toEncodedString();\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export function toBase64Url(bytes: Uint8Array): string {\n const base64 = typeof Buffer !== 'undefined'\n ? Buffer.from(bytes).toString('base64')\n : btoa(String.fromCharCode(...bytes));\n\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function fromBase64Url(encoded: string): Uint8Array {\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');\n\n if (typeof Buffer !== 'undefined') {\n return Uint8Array.from(Buffer.from(padded, 'base64'));\n }\n\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n", "export function countItems<T>(arr: T[]) {\n const map = new Map<T, number>();\n for (const item of arr) {\n map.set(item, (map.get(item) || 0) + 1);\n }\n return map;\n}\nabstract class BufferCursor {\n buffer: Uint8Array;\n pointer = 0;\n\n constructor(bufOrLength: Uint8Array | number) {\n if (typeof bufOrLength === 'number') {\n this.buffer = new Uint8Array(bufOrLength);\n } else {\n this.buffer = bufOrLength;\n }\n }\n\n /**\n * \u5B89\u5168\u5730\u5C06 pointer \u5411\u524D\u79FB\u52A8\u6307\u5B9A\u5B57\u8282\u6570\u3002\n * @param bytes \u8981\u79FB\u52A8\u7684\u5B57\u8282\u6570\n * @returns \u539F\u6765 pointer \u7684\u503C\n * @throws RangeError \u5982\u679C\u8D8A\u754C\n */\n protected increasePointer(bytes: number): number {\n const old = this.pointer;\n const next = old + bytes;\n if (next > this.buffer.length) {\n throw new RangeError(\n `Pointer overflow: tried to move to ${next}, but buffer length is ${this.buffer.length}`\n );\n }\n this.pointer = next;\n return old;\n }\n}\n\nexport class BufferWriter extends BufferCursor {\n constructor(length: number) {\n super(length);\n }\n\n writeUint32LE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n this.buffer[idx + 2] = (value >>> 16) & 0xff;\n this.buffer[idx + 3] = (value >>> 24) & 0xff;\n return this;\n }\n\n writeUint32BE(value: number) {\n const idx = this.increasePointer(4);\n this.buffer[idx ] = (value >>> 24) & 0xff;\n this.buffer[idx + 1] = (value >>> 16) & 0xff;\n this.buffer[idx + 2] = (value >>> 8) & 0xff;\n this.buffer[idx + 3] = value & 0xff;\n return this;\n }\n\n writeUint16LE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = value & 0xff;\n this.buffer[idx + 1] = (value >>> 8) & 0xff;\n return this;\n }\n\n writeUint16BE(value: number) {\n const idx = this.increasePointer(2);\n this.buffer[idx ] = (value >>> 8) & 0xff;\n this.buffer[idx + 1] = value & 0xff;\n return this;\n }\n\n writeUint8(value: number) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = value & 0xff;\n return this;\n }\n\n writeString(str: string) {\n for (let i = 0; i < str.length; i++) {\n const idx = this.increasePointer(1);\n this.buffer[idx] = str.charCodeAt(i);\n }\n return this;\n }\n}\n\nexport class BufferReader extends BufferCursor {\n constructor(buf: Uint8Array) {\n super(buf);\n }\n\n readUint32LE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n // >>>0 \u4FDD\u8BC1\u65E0\u7B26\u53F7\u8F93\u51FA\n return (\n (b[idx ] ) |\n (b[idx + 1] << 8) |\n (b[idx + 2] << 16) |\n (b[idx + 3] << 24)\n ) >>> 0;\n }\n\n readUint32BE(): number {\n const idx = this.increasePointer(4);\n const b = this.buffer;\n return (\n (b[idx ] << 24) |\n (b[idx + 1] << 16) |\n (b[idx + 2] << 8) |\n (b[idx + 3] )\n ) >>> 0;\n }\n\n readUint16LE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return (b[idx] | (b[idx + 1] << 8));\n }\n\n readUint16BE(): number {\n const idx = this.increasePointer(2);\n const b = this.buffer;\n return ((b[idx] << 8) | b[idx + 1]);\n }\n\n readUint8(): number {\n const idx = this.increasePointer(1);\n return this.buffer[idx];\n }\n\n readString(length: number): string {\n let s = '';\n for (let i = 0; i < length; i++) {\n const idx = this.increasePointer(1);\n s += String.fromCharCode(this.buffer[idx]);\n }\n return s;\n }\n\n readRemaining(): Uint8Array {\n const remaining = this.buffer.length - this.pointer;\n const idx = this.increasePointer(remaining);\n return this.buffer.subarray(idx, this.buffer.length);\n }\n}\n", "// ydke.ts\n\nexport interface TypedDeck {\n main: number[];\n extra: number[];\n side: number[];\n}\n\nfunction base64ToUint32Array(base64: string): number[] {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const view = new DataView(bytes.buffer);\n const result: number[] = [];\n for (let i = 0; i < bytes.length; i += 4) {\n result.push(view.getUint32(i, true)); // little-endian\n }\n return result;\n}\n\nfunction uint32ArrayToBase64(data: number[]): string {\n const buffer = new ArrayBuffer(data.length * 4);\n const view = new DataView(buffer);\n data.forEach((val, i) => view.setUint32(i * 4, val, true));\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nexport function toYdkeURL(deck: TypedDeck): string {\n return (\n 'ydke://' +\n uint32ArrayToBase64(deck.main) +\n '!' +\n uint32ArrayToBase64(deck.extra) +\n '!' +\n uint32ArrayToBase64(deck.side) +\n '!'\n );\n}\n\nexport function fromYdkeURL(ydke: string): TypedDeck {\n if (!ydke.startsWith('ydke://')) {\n throw new Error('Invalid ydke:// URI');\n }\n const [mainStr, extraStr, sideStr] = ydke.slice(7).split('!');\n if (mainStr === undefined || extraStr === undefined || sideStr === undefined) {\n throw new Error('Incomplete ydke:// URI');\n }\n return {\n main: base64ToUint32Array(mainStr),\n extra: base64ToUint32Array(extraStr),\n side: base64ToUint32Array(sideStr),\n };\n}\n", "import { fromBase64Url, toBase64Url } from \"./base64\";\n\n// === \u5E38\u91CF\u533A\u57DF ===\nconst QUERY_YGO_TYPE = 'ygotype';\nconst QUERY_VERSION = 'v';\nconst ARG_DECK = 'deck';\nconst QUERY_DECK = 'd';\nconst QUERY_NAME = 'name';\n\nconst URL_SCHEME_HTTP = 'http';\nconst URL_HOST_DECK = 'deck.ourygo.top';\n\n// === \u5DE5\u5177\u51FD\u6570 ===\nfunction toBinary(value: number, length: number): string {\n return value.toString(2).padStart(length, '0');\n}\n\nfunction encodeCards(cards: number[]): string {\n const bits: string[] = [];\n for (let i = 0; i < cards.length; ) {\n const id = cards[i];\n let count = 1;\n while (i + count < cards.length && cards[i + count] === id && count < 3) count++;\n const prefix = count === 2 ? '10' : count === 3 ? '11' : '01';\n bits.push(prefix + toBinary(id, 27));\n i += count;\n }\n return bits.join('');\n}\n\nfunction countUnique(cards: number[]): number {\n let num = 0;\n for (let i = 0; i < cards.length; i++) {\n const id = cards[i];\n if (id > 0) {\n num++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n if (i < cards.length - 1 && cards[i + 1] === id) {\n i++;\n }\n }\n }\n }\n return num;\n}\n\n// === \u4E3B\u51FD\u6570 ===\n\nexport function toYGOMobileDeckURL(\n main: number[],\n extra: number[],\n side: number[],\n customParams: Record<string, string> = {},\n): string {\n const mNum = countUnique(main);\n const eNum = countUnique(extra);\n const sNum = countUnique(side);\n\n const header = toBinary(mNum, 8) + toBinary(eNum, 4) + toBinary(sNum, 4);\n let bitString = header + encodeCards(main) + encodeCards(extra) + encodeCards(side);\n while (bitString.length % 8 !== 0) bitString += '0';\n\n const bytes = new Uint8Array(bitString.length / 8);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(bitString.slice(i * 8, i * 8 + 8), 2);\n }\n\n let encoded = toBase64Url(bytes)\n\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(customParams)) {\n searchParams.set(key, value);\n }\n searchParams.set(QUERY_YGO_TYPE, ARG_DECK);\n searchParams.set(QUERY_VERSION, '1');\n searchParams.set(QUERY_DECK, encoded);\n\n return `${URL_SCHEME_HTTP}://${URL_HOST_DECK}?${searchParams.toString()}`;\n}\n\n\nexport function fromYGOMobileDeckURL(uri: string): {\n main: number[];\n extra: number[];\n side: number[];\n name?: string;\n} {\n const url = new URL(uri);\n if (url.searchParams.get(QUERY_YGO_TYPE) !== ARG_DECK) {\n throw new Error('Not a YGO Mobile deck URI');\n }\n\n let encoded = url.searchParams.get(QUERY_DECK);\n if (!encoded) throw new Error('Missing deck data');\n\n const bytes = fromBase64Url(encoded);\n\n const bits = Array.from(bytes)\n .map((b) => b.toString(2).padStart(8, '0'))\n .join('');\n\n const mNum = parseInt(bits.slice(0, 8), 2);\n const eNum = parseInt(bits.slice(8, 12), 2);\n const sNum = parseInt(bits.slice(12, 16), 2);\n\n const all = mNum + eNum + sNum;\n const cards: number[] = [];\n let pos = 16;\n \n const res = {\n main: [] as number[],\n extra: [] as number[],\n side: [] as number[],\n }\n\n let i = 0;\n\n while (pos + 29 <= bits.length && cards.length < all) {\n const countBits = bits.slice(pos, pos + 2);\n const count = countBits === '10' ? 2 : countBits === '11' ? 3 : 1;\n const id = parseInt(bits.slice(pos + 2, pos + 29), 2);\n const field = i < mNum ? 'main' : i < mNum + eNum ? 'extra' : 'side';\n res[field].push(...Array(count).fill(id));\n pos += 29;\n i++;\n }\n\n return {\n ...res,\n name: url.searchParams.get(QUERY_NAME),\n };\n}\n", "import { fromBase64Url, toBase64Url } from './src/base64';\nimport { BufferReader, BufferWriter, countItems } from './src/utils';\nimport { fromYdkeURL, toYdkeURL } from './src/ydke';\nimport { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';\n\nexport default class YGOProDeck {\n main: number[] = [];\n extra: number[] = [];\n side: number[] = [];\n name?: string;\n\n bufferLength() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n return counted.reduce((a, b) => a + b.size * 4, 0);\n }\n\n toUint8Array() {\n const counted = [this.main, this.extra, this.side].map(countItems);\n const writer = new BufferWriter(\n counted.reduce((a, b) => a + b.size * 4, 0),\n );\n const writeCards = (countMap: Map<number, number>, type: number) => {\n // each card: 28 bits for id, 2 bits(0, 1, 2, 3) for type(0: main, 1: extra, 2: side, 3: unknown), 2 bits for count (0: 1, 1: 2, 2: 3, 3: 4)\n for (const [id, count] of countMap.entries()) {\n if (count > 4) {\n throw new Error(`Too many cards: ${id}`);\n }\n const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);\n writer.writeUint32LE(value);\n }\n };\n counted.forEach(writeCards);\n return writer.buffer;\n }\n\n toEncodedString() {\n return toBase64Url(this.toUint8Array());\n }\n\n toString() {\n return this.toEncodedString();\n }\n\n fromUint8Array(buf: Uint8Array) {\n for (let i = 0; i < buf.length - 3; i += 4) {\n const value =\n buf[i] | (buf[i + 1] << 8) | (buf[i + 2] << 16) | (buf[i + 3] << 24);\n const id = value & 0xfffffff;\n const type = (value >>> 28) & 0x3;\n const count = ((value >>> 30) & 0x3) + 1;\n const cards = [this.main, this.extra, this.side][type];\n for (let j = 0; j < count; j++) {\n cards.push(id);\n }\n }\n return this;\n }\n\n static fromUint8Array(buf: Uint8Array) {\n return new YGOProDeck().fromUint8Array(buf);\n }\n\n fromEncodedString(str: string) {\n return this.fromUint8Array(fromBase64Url(str));\n }\n\n static fromEncodedString(str: string) {\n return new YGOProDeck().fromEncodedString(str);\n }\n\n toYdkString() {\n return [\n '#created by ygopro-deck-encode',\n '#main',\n ...this.main.map((id) => id.toString()),\n '#extra',\n ...this.extra.map((id) => id.toString()),\n '!side',\n ...this.side.map((id) => id.toString()),\n ].join('\\n');\n }\n\n fromYdkString(str: string) {\n const lines = str.split(/\\r?\\n/);\n let current = this.main;\n for (const _line of lines) {\n const line = _line.trim();\n if (line === '#main') {\n current = this.main;\n }\n if (line === '#extra') {\n current = this.extra;\n }\n if (line === '!side') {\n current = this.side;\n }\n if (line.match(/^\\d+$/)) {\n current.push(parseInt(line, 10));\n }\n }\n return this;\n }\n\n static fromYdkString(str: string) {\n return new YGOProDeck().fromYdkString(str);\n }\n\n fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {\n const reader = new BufferReader(buf);\n const mainc = reader.readUint32LE();\n const sidec = reader.readUint32LE();\n this.main = [];\n this.extra = [];\n this.side = [];\n for(let i = 0; i < mainc; i++) {\n const id = reader.readUint32LE();\n if (isExtraDeckCard(id, i, mainc)) {\n this.extra.push(id);\n } else {\n this.main.push(id);\n }\n }\n for(let i = 0; i < sidec; i++) {\n const id = reader.readUint32LE();\n this.side.push(id);\n }\n return this;\n }\n\n static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) { \n return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);\n }\n\n toUpdateDeckPayload() {\n const cards = [...this.main, ...this.extra, ...this.side];\n const writer = new BufferWriter(cards.length * 4 + 8)\n .writeUint32LE(this.main.length + this.extra.length)\n .writeUint32LE(this.side.length);\n cards.forEach((id) => writer.writeUint32LE(id));\n return writer.buffer;\n }\n\n fromYGOMobileDeckURL(uri: string): YGOProDeck {\n const parsed = fromYGOMobileDeckURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n this.name = parsed.name;\n return this;\n }\n\n static fromYGOMobileDeckURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYGOMobileDeckURL(uri);\n }\n\n toYGOMobileDeckURL(): string {\n return toYGOMobileDeckURL(this.main, this.extra, this.side, this.name && {\n name: this.name,\n });\n }\n\n fromYdkeURL(uri: string): YGOProDeck {\n const parsed = fromYdkeURL(uri);\n this.main = parsed.main;\n this.extra = parsed.extra;\n this.side = parsed.side;\n return this;\n }\n\n static fromYdkeURL(uri: string): YGOProDeck {\n return new YGOProDeck().fromYdkeURL(uri);\n }\n\n toYdkeURL(): string {\n return toYdkeURL({\n main: this.main,\n extra: this.extra,\n side: this.side,\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,17 @@
1
1
  export declare function countItems<T>(arr: T[]): Map<T, number>;
2
- export declare class BufferWriter {
2
+ declare abstract class BufferCursor {
3
3
  buffer: Uint8Array;
4
4
  pointer: number;
5
+ constructor(bufOrLength: Uint8Array | number);
6
+ /**
7
+ * 安全地将 pointer 向前移动指定字节数。
8
+ * @param bytes 要移动的字节数
9
+ * @returns 原来 pointer 的值
10
+ * @throws RangeError 如果越界
11
+ */
12
+ protected increasePointer(bytes: number): number;
13
+ }
14
+ export declare class BufferWriter extends BufferCursor {
5
15
  constructor(length: number);
6
16
  writeUint32LE(value: number): this;
7
17
  writeUint32BE(value: number): this;
@@ -10,3 +20,14 @@ export declare class BufferWriter {
10
20
  writeUint8(value: number): this;
11
21
  writeString(str: string): this;
12
22
  }
23
+ export declare class BufferReader extends BufferCursor {
24
+ constructor(buf: Uint8Array);
25
+ readUint32LE(): number;
26
+ readUint32BE(): number;
27
+ readUint16LE(): number;
28
+ readUint16BE(): number;
29
+ readUint8(): number;
30
+ readString(length: number): string;
31
+ readRemaining(): Uint8Array;
32
+ }
33
+ export {};
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { fromBase64Url, toBase64Url } from './src/base64';
2
- import { BufferWriter, countItems } from './src/utils';
2
+ import { BufferReader, BufferWriter, countItems } from './src/utils';
3
3
  import { fromYdkeURL, toYdkeURL } from './src/ydke';
4
4
  import { fromYGOMobileDeckURL, toYGOMobileDeckURL } from './src/ygom';
5
5
 
@@ -105,6 +105,32 @@ export default class YGOProDeck {
105
105
  return new YGOProDeck().fromYdkString(str);
106
106
  }
107
107
 
108
+ fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number, i: number, mainc: number) => boolean = () => false) {
109
+ const reader = new BufferReader(buf);
110
+ const mainc = reader.readUint32LE();
111
+ const sidec = reader.readUint32LE();
112
+ this.main = [];
113
+ this.extra = [];
114
+ this.side = [];
115
+ for(let i = 0; i < mainc; i++) {
116
+ const id = reader.readUint32LE();
117
+ if (isExtraDeckCard(id, i, mainc)) {
118
+ this.extra.push(id);
119
+ } else {
120
+ this.main.push(id);
121
+ }
122
+ }
123
+ for(let i = 0; i < sidec; i++) {
124
+ const id = reader.readUint32LE();
125
+ this.side.push(id);
126
+ }
127
+ return this;
128
+ }
129
+
130
+ static fromUpdateDeckPayload(buf: Uint8Array, isExtraDeckCard: (code: number) => boolean = () => false) {
131
+ return new YGOProDeck().fromUpdateDeckPayload(buf, isExtraDeckCard);
132
+ }
133
+
108
134
  toUpdateDeckPayload() {
109
135
  const cards = [...this.main, ...this.extra, ...this.side];
110
136
  const writer = new BufferWriter(cards.length * 4 + 8)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ygopro-deck-encode",
3
3
  "description": "YGOPro Deck encode and decode, with well-browser support.",
4
- "version": "1.0.6",
4
+ "version": "1.0.7",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",