Commit daa6eb35 authored by nanahira's avatar nanahira

add toUpdateDeckPayload

parent 80a9cdc5
import { countItems } from './src/utils';
import { BufferWriter, countItems } from './src/utils';
import { Base64 } from 'js-base64';
export default class YGOProDeck {
......@@ -13,14 +13,9 @@ export default class YGOProDeck {
toUint8Array() {
const counted = [this.main, this.extra, this.side].map(countItems);
const buf = new Uint8Array(counted.reduce((a, b) => a + b.size * 4, 0));
let pointer = 0;
const writeUint32LE = (value: number) => {
buf[pointer++] = value & 0xff;
buf[pointer++] = (value >> 8) & 0xff;
buf[pointer++] = (value >> 16) & 0xff;
buf[pointer++] = (value >> 24) & 0xff;
};
const writer = new BufferWriter(
counted.reduce((a, b) => a + b.size * 4, 0),
);
const writeCards = (countMap: Map<number, number>, type: number) => {
// 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)
for (const [id, count] of countMap.entries()) {
......@@ -28,11 +23,11 @@ export default class YGOProDeck {
throw new Error(`Too many cards: ${id}`);
}
const value = (id & 0xfffffff) | (type << 28) | ((count - 1) << 30);
writeUint32LE(value);
writer.writeUint32LE(value);
}
};
counted.forEach(writeCards);
return buf;
return writer.buffer;
}
toEncodedString() {
......@@ -106,4 +101,13 @@ export default class YGOProDeck {
static fromYdkString(str: string) {
return new YGOProDeck().fromYdkString(str);
}
toUpdateDeckPayload() {
const cards = [...this.main, ...this.extra, ...this.side];
const writer = new BufferWriter(cards.length * 4 + 8)
.writeUint32LE(this.main.length + this.extra.length)
.writeUint32LE(this.side.length);
cards.forEach((id) => writer.writeUint32LE(id));
return writer.buffer;
}
}
......@@ -5,3 +5,50 @@ export function countItems<T>(arr: T[]) {
}
return map;
}
export class BufferWriter {
buffer: Uint8Array;
pointer = 0;
constructor(length: number) {
this.buffer = new Uint8Array(length);
}
writeUint32LE(value: number) {
this.buffer[this.pointer++] = value & 0xff;
this.buffer[this.pointer++] = (value >> 8) & 0xff;
this.buffer[this.pointer++] = (value >> 16) & 0xff;
this.buffer[this.pointer++] = (value >> 24) & 0xff;
return this;
}
writeUint32BE(value: number) {
this.buffer[this.pointer++] = (value >> 24) & 0xff;
this.buffer[this.pointer++] = (value >> 16) & 0xff;
this.buffer[this.pointer++] = (value >> 8) & 0xff;
this.buffer[this.pointer++] = value & 0xff;
return this;
}
writeUint16LE(value: number) {
this.buffer[this.pointer++] = value & 0xff;
this.buffer[this.pointer++] = (value >> 8) & 0xff;
return this;
}
writeUint16BE(value: number) {
this.buffer[this.pointer++] = (value >> 8) & 0xff;
this.buffer[this.pointer++] = value & 0xff;
return this;
}
writeUint8(value: number) {
this.buffer[this.pointer++] = value & 0xff;
return this;
}
writeString(str: string) {
for (let i = 0; i < str.length; i++) {
this.buffer[this.pointer++] = str.charCodeAt(i);
}
return this;
}
}
......@@ -18,6 +18,24 @@ describe('Sample test.', () => {
encoded.replace(/[-_]/g, (m0) => (m0 == '-' ? '+' : '/')),
'base64',
);
expect(buf.readUInt32LE(0) & 0xfffffff).toBe(123);
expect((buf.readUInt32LE(0) >> 28) & 0x3).toBe(0);
expect(((buf.readUInt32LE(0) >> 30) & 0x3) + 1).toBe(3);
expect(buf.readUInt32LE(4) & 0xfffffff).toBe(456);
expect((buf.readUInt32LE(4) >> 28) & 0x3).toBe(0);
expect(((buf.readUInt32LE(4) >> 30) & 0x3) + 1).toBe(2);
expect(buf.readUInt32LE(8) & 0xfffffff).toBe(789);
expect((buf.readUInt32LE(8) >> 28) & 0x3).toBe(0);
expect(((buf.readUInt32LE(8) >> 30) & 0x3) + 1).toBe(1);
expect(buf.readUInt32LE(12) & 0xfffffff).toBe(1234);
expect((buf.readUInt32LE(12) >> 28) & 0x3).toBe(1);
expect(((buf.readUInt32LE(12) >> 30) & 0x3) + 1).toBe(1);
expect(buf.readUInt32LE(16) & 0xfffffff).toBe(5678);
expect((buf.readUInt32LE(16) >> 28) & 0x3).toBe(1);
expect(((buf.readUInt32LE(16) >> 30) & 0x3) + 1).toBe(1);
expect(buf.readUInt32LE(20) & 0xfffffff).toBe(12345);
expect((buf.readUInt32LE(20) >> 28) & 0x3).toBe(2);
expect(((buf.readUInt32LE(20) >> 30) & 0x3) + 1).toBe(1);
expect(buf.length).toBe(24);
const decoded = new YGOProDeck().fromEncodedString(encoded);
expect(decoded.main).toStrictEqual(deck.main);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment