mirror of
https://github.com/jwetzell/psn-js.git
synced 2026-08-26 01:19:18 +00:00
@@ -1,16 +1,16 @@
|
|||||||
import { Chunk } from '../models/chunk';
|
import { Chunk } from '../models/chunk';
|
||||||
|
|
||||||
export default (buffer: Uint8Array): Chunk => {
|
export default (buffer: Uint8Array): Chunk => {
|
||||||
let offset = 0;
|
if (buffer.length < 4) {
|
||||||
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
throw new Error('Chunk buffer must be at least 4 bytes');
|
||||||
const id = view.getUint16(offset, true);
|
}
|
||||||
offset += 2;
|
|
||||||
|
const id = (buffer[1] << 8) + buffer[0];
|
||||||
|
|
||||||
// NOTE(jwetzell): this data is split up as 1 bit for hasSubchunks and 15 bits for the dataLen
|
// NOTE(jwetzell): this data is split up as 1 bit for hasSubchunks and 15 bits for the dataLen
|
||||||
const combinedLengthAndFlag = view.getUint16(offset, true);
|
const combinedLengthAndFlag = (buffer[3] << 8) + buffer[2];
|
||||||
const hasSubchunks = combinedLengthAndFlag > 32768;
|
const hasSubchunks = combinedLengthAndFlag > 32768;
|
||||||
const dataLen = hasSubchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag;
|
const dataLen = hasSubchunks ? combinedLengthAndFlag - 32768 : combinedLengthAndFlag;
|
||||||
offset += 2;
|
|
||||||
|
|
||||||
const header = {
|
const header = {
|
||||||
id,
|
id,
|
||||||
@@ -18,7 +18,7 @@ export default (buffer: Uint8Array): Chunk => {
|
|||||||
hasSubchunks,
|
hasSubchunks,
|
||||||
};
|
};
|
||||||
|
|
||||||
const chunkData = buffer.subarray(offset, offset + header.dataLen);
|
const chunkData = buffer.subarray(4, 4 + header.dataLen);
|
||||||
|
|
||||||
const chunk = {
|
const chunk = {
|
||||||
chunkData,
|
chunkData,
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ export default (buffer: Uint8Array): DataPacketChunk => {
|
|||||||
if (chunk.header.hasSubchunks && chunk.chunkData && chunk.header.dataLen) {
|
if (chunk.header.hasSubchunks && chunk.chunkData && chunk.header.dataLen) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < chunk.header.dataLen) {
|
while (offset < chunk.header.dataLen) {
|
||||||
const view = new DataView(chunk.chunkData.buffer, chunk.chunkData.byteOffset, chunk.chunkData.byteLength);
|
const chunkId = (chunk.chunkData.subarray(offset)[1] << 8) + chunk.chunkData.subarray(offset)[0];
|
||||||
const chunkId = view.getUint16(offset, true);
|
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
data.packetHeader = Decoders.PacketHeaderChunk(chunk.chunkData.subarray(offset));
|
data.packetHeader = Decoders.PacketHeaderChunk(chunk.chunkData.subarray(offset));
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ export default (buffer: Uint8Array): InfoPacketChunk => {
|
|||||||
if (chunk.header.hasSubchunks && chunk.chunkData && chunk.header.dataLen) {
|
if (chunk.header.hasSubchunks && chunk.chunkData && chunk.header.dataLen) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < chunk.header.dataLen) {
|
while (offset < chunk.header.dataLen) {
|
||||||
const view = new DataView(chunk.chunkData.buffer, chunk.chunkData.byteOffset, chunk.chunkData.byteLength);
|
const chunkId = (chunk.chunkData.subarray(offset)[1] << 8) + chunk.chunkData.subarray(offset)[0];
|
||||||
const chunkId = view.getUint16(offset, true);
|
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
data.packetHeader = Decoders.PacketHeaderChunk(chunk.chunkData.subarray(offset));
|
data.packetHeader = Decoders.PacketHeaderChunk(chunk.chunkData.subarray(offset));
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Decoders } from '..';
|
import { Decoders } from '..';
|
||||||
import { InfoSystemNameChunk, InfoSystemNameChunkData } from '../../models/info/info-system-name-chunk';
|
import { InfoSystemNameChunk, InfoSystemNameChunkData } from '../../models/info/info-system-name-chunk';
|
||||||
|
|
||||||
|
const nameDecoder = new TextDecoder();
|
||||||
export default (buffer: Uint8Array): InfoSystemNameChunk => {
|
export default (buffer: Uint8Array): InfoSystemNameChunk => {
|
||||||
const chunk = Decoders.Chunk(buffer);
|
const chunk = Decoders.Chunk(buffer);
|
||||||
|
|
||||||
const data: InfoSystemNameChunkData = {
|
const data: InfoSystemNameChunkData = {
|
||||||
systemName: new TextDecoder().decode(chunk.chunkData.subarray(0, chunk.header.dataLen)),
|
systemName: nameDecoder.decode(chunk.chunkData.subarray(0, chunk.header.dataLen)),
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ export default (buffer: Uint8Array): InfoTrackerChunk => {
|
|||||||
if (chunk.header.hasSubchunks && chunk.chunkData && chunk.header.dataLen) {
|
if (chunk.header.hasSubchunks && chunk.chunkData && chunk.header.dataLen) {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
while (offset < chunk.header.dataLen) {
|
while (offset < chunk.header.dataLen) {
|
||||||
const view = new DataView(chunk.chunkData.buffer, chunk.chunkData.byteOffset, chunk.chunkData.byteLength);
|
const chunkId = (chunk.chunkData.subarray(offset)[1] << 8) + chunk.chunkData.subarray(offset)[0];
|
||||||
const chunkId = view.getUint16(offset, true);
|
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
case 0x0000: {
|
case 0x0000: {
|
||||||
const data: InfoTrackerChunkData = {
|
const data: InfoTrackerChunkData = {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Decoders } from '..';
|
import { Decoders } from '..';
|
||||||
import { InfoTrackerNameChunk, InfoTrackerNameChunkData } from '../../models/info/info-tracker-name-chunk';
|
import { InfoTrackerNameChunk, InfoTrackerNameChunkData } from '../../models/info/info-tracker-name-chunk';
|
||||||
|
|
||||||
|
const nameDecoder = new TextDecoder();
|
||||||
export default (buffer: Uint8Array): InfoTrackerNameChunk => {
|
export default (buffer: Uint8Array): InfoTrackerNameChunk => {
|
||||||
const chunk = Decoders.Chunk(buffer);
|
const chunk = Decoders.Chunk(buffer);
|
||||||
|
|
||||||
const data: InfoTrackerNameChunkData = {
|
const data: InfoTrackerNameChunkData = {
|
||||||
trackerName: new TextDecoder().decode(chunk.chunkData.subarray(0, chunk.header.dataLen)),
|
trackerName: nameDecoder.decode(chunk.chunkData.subarray(0, chunk.header.dataLen)),
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -4,9 +4,16 @@ import { PacketHeaderChunk, PacketHeaderChunkData } from '../models/packet-heade
|
|||||||
export default (buffer: Uint8Array): PacketHeaderChunk => {
|
export default (buffer: Uint8Array): PacketHeaderChunk => {
|
||||||
const chunk = Decoders.Chunk(buffer);
|
const chunk = Decoders.Chunk(buffer);
|
||||||
|
|
||||||
const view = new DataView(chunk.chunkData.buffer, chunk.chunkData.byteOffset, chunk.chunkData.byteLength);
|
let packetTimestamp = BigInt(chunk.chunkData[7]) << BigInt(56);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[6]) << BigInt(48);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[5]) << BigInt(40);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[4]) << BigInt(32);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[3]) << BigInt(24);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[2]) << BigInt(16);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[1]) << BigInt(8);
|
||||||
|
packetTimestamp += BigInt(chunk.chunkData[0]);
|
||||||
const data: PacketHeaderChunkData = {
|
const data: PacketHeaderChunkData = {
|
||||||
packetTimestamp: view.getBigUint64(0, true),
|
packetTimestamp,
|
||||||
versionHigh: chunk.chunkData[8],
|
versionHigh: chunk.chunkData[8],
|
||||||
versionLow: chunk.chunkData[9],
|
versionLow: chunk.chunkData[9],
|
||||||
frameId: chunk.chunkData[10],
|
frameId: chunk.chunkData[10],
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
const header = new DataView(new ArrayBuffer(4));
|
||||||
export default (id: number, chunkData: Uint8Array, hasSubchunks: boolean): Uint8Array => {
|
export default (id: number, chunkData: Uint8Array, hasSubchunks: boolean): Uint8Array => {
|
||||||
if (!Number.isInteger(id)) {
|
if (!Number.isInteger(id)) {
|
||||||
throw new Error('chunk id must be an integer');
|
throw new Error('chunk id must be an integer');
|
||||||
@@ -11,7 +12,6 @@ export default (id: number, chunkData: Uint8Array, hasSubchunks: boolean): Uint8
|
|||||||
throw new Error('chunkData can not be greater than 32767 bytes');
|
throw new Error('chunkData can not be greater than 32767 bytes');
|
||||||
}
|
}
|
||||||
|
|
||||||
const header = new DataView(new ArrayBuffer(4));
|
|
||||||
header.setUint16(0, id, true);
|
header.setUint16(0, id, true);
|
||||||
const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15;
|
const hasSubChunksBit = (hasSubchunks ? 1 : 0) << 15;
|
||||||
header.setUint16(2, hasSubChunksBit + chunkData.length, true);
|
header.setUint16(2, hasSubChunksBit + chunkData.length, true);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const floatArray = new Float32Array(3);
|
||||||
export default (x: number, y: number, z: number): Uint8Array => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(12));
|
floatArray[0] = x;
|
||||||
buf.setFloat32(0, x, true);
|
floatArray[1] = y;
|
||||||
buf.setFloat32(4, y, true);
|
floatArray[2] = z;
|
||||||
buf.setFloat32(8, z, true);
|
return chunk(0x0004, new Uint8Array(floatArray.buffer), false);
|
||||||
return chunk(0x0004, new Uint8Array(buf.buffer), false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const floatArray = new Float32Array(3);
|
||||||
export default (x: number, y: number, z: number): Uint8Array => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(12));
|
floatArray[0] = x;
|
||||||
|
floatArray[1] = y;
|
||||||
buf.setFloat32(0, x, true);
|
floatArray[2] = z;
|
||||||
buf.setFloat32(4, y, true);
|
return chunk(0x0002, new Uint8Array(floatArray.buffer), false);
|
||||||
buf.setFloat32(8, z, true);
|
|
||||||
return chunk(0x0002, new Uint8Array(buf.buffer), false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const floatArray = new Float32Array(3);
|
||||||
export default (x: number, y: number, z: number): Uint8Array => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(12));
|
floatArray[0] = x;
|
||||||
|
floatArray[1] = y;
|
||||||
|
floatArray[2] = z;
|
||||||
|
|
||||||
buf.setFloat32(0, x, true);
|
return chunk(0x0000, new Uint8Array(floatArray.buffer), false);
|
||||||
buf.setFloat32(4, y, true);
|
|
||||||
buf.setFloat32(8, z, true);
|
|
||||||
|
|
||||||
return chunk(0x0000, new Uint8Array(buf.buffer), false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const floatArray = new Float32Array(3);
|
||||||
export default (x: number, y: number, z: number): Uint8Array => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(12));
|
floatArray[0] = x;
|
||||||
|
floatArray[1] = y;
|
||||||
|
floatArray[2] = z;
|
||||||
|
|
||||||
buf.setFloat32(0, x, true);
|
return chunk(0x0001, new Uint8Array(floatArray.buffer), false);
|
||||||
buf.setFloat32(4, y, true);
|
|
||||||
buf.setFloat32(8, z, true);
|
|
||||||
|
|
||||||
return chunk(0x0001, new Uint8Array(buf.buffer), false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const floatArray = new Float32Array(1);
|
||||||
export default (validity: number): Uint8Array => {
|
export default (validity: number): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(4));
|
floatArray[0] = validity;
|
||||||
buf.setFloat32(0, validity, true);
|
return chunk(0x0003, new Uint8Array(floatArray.buffer), false);
|
||||||
return chunk(0x0003, new Uint8Array(buf.buffer), false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const buf = new DataView(new ArrayBuffer(8));
|
||||||
export default (timestamp: bigint): Uint8Array => {
|
export default (timestamp: bigint): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(8));
|
|
||||||
buf.setBigUint64(0, BigInt(timestamp), true);
|
buf.setBigUint64(0, BigInt(timestamp), true);
|
||||||
return chunk(0x0006, new Uint8Array(buf.buffer), false);
|
return chunk(0x0006, new Uint8Array(buf.buffer), false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
|
const floatArray = new Float32Array(3);
|
||||||
export default (x: number, y: number, z: number): Uint8Array => {
|
export default (x: number, y: number, z: number): Uint8Array => {
|
||||||
const buf = new DataView(new ArrayBuffer(12));
|
floatArray[0] = x;
|
||||||
|
floatArray[1] = y;
|
||||||
|
floatArray[2] = z;
|
||||||
|
|
||||||
buf.setFloat32(0, x, true);
|
return chunk(0x0005, new Uint8Array(floatArray.buffer), false);
|
||||||
buf.setFloat32(4, y, true);
|
|
||||||
buf.setFloat32(8, z, true);
|
|
||||||
|
|
||||||
return chunk(0x0005, new Uint8Array(buf.buffer), false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
const nameEncoder = new TextEncoder();
|
||||||
export default (systemName: string): Uint8Array => chunk(0x0001, new TextEncoder().encode(systemName), false);
|
export default (systemName: string): Uint8Array => chunk(0x0001, nameEncoder.encode(systemName), false);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import chunk from '../chunk';
|
import chunk from '../chunk';
|
||||||
|
|
||||||
export default (trackerName: string) => chunk(0x0000, new TextEncoder().encode(trackerName), false);
|
const nameEncoder = new TextEncoder();
|
||||||
|
export default (trackerName: string) => chunk(0x0000, nameEncoder.encode(trackerName), false);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import chunk from './chunk';
|
import chunk from './chunk';
|
||||||
|
|
||||||
|
const packetHeader = new DataView(new ArrayBuffer(12));
|
||||||
export default (
|
export default (
|
||||||
timestamp: bigint,
|
timestamp: bigint,
|
||||||
versionHigh: number,
|
versionHigh: number,
|
||||||
@@ -33,7 +34,6 @@ export default (
|
|||||||
throw new Error('frame packet count must be >= 0 and <= 255');
|
throw new Error('frame packet count must be >= 0 and <= 255');
|
||||||
}
|
}
|
||||||
|
|
||||||
const packetHeader = new DataView(new ArrayBuffer(12));
|
|
||||||
packetHeader.setBigUint64(0, BigInt(timestamp), true);
|
packetHeader.setBigUint64(0, BigInt(timestamp), true);
|
||||||
packetHeader.setUint8(8, versionHigh);
|
packetHeader.setUint8(8, versionHigh);
|
||||||
packetHeader.setUint8(9, versionLow);
|
packetHeader.setUint8(9, versionLow);
|
||||||
|
|||||||
Reference in New Issue
Block a user