Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v8/scripting): swap from msgpack-lite to msgpackr #3018

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 25 additions & 14 deletions data/shared/citizen/scripting/v8/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// CFX JS runtime
/// <reference path="./natives_server.d.ts" />
/// <reference path="./msgpack.d.ts" />

const EXT_FUNCREF = 10;
const EXT_LOCALFUNCREF = 11;
Expand Down Expand Up @@ -41,18 +42,34 @@ const EXT_LOCALFUNCREF = 11;
const nextRefIdx = () => refIndex++;
const refFunctionsMap = new Map();

const codec = msgpack.createCodec({
uint8array: true,
preset: false,
binarraybuffer: true
});
/** @type {import("./msgpack").Options} */
const packrOptions = {
// use "std::map" for the underlying msgpack type for compatibility
useRecords: false,
// allow Map, Set, and Error to be serialized
moreTypes: true,
// keep compatibility Lua/C#
encodeUndefinedAsNil: true,
}

/** @type {import("./msgpack").Packr} */
const packr = new Packr(packrOptions);

const pack = data => msgpack.encode(data, { codec });
const unpack = data => msgpack.decode(data, { codec });
addExtension({
Class: Function,
type: EXT_FUNCREF,
pack: refFunctionPacker,
unpack: refFunctionUnpacker
})


const pack = (value) => packr.pack(value);
const unpack = (packed_value) => packr.unpack(packed_value);

// store for use by natives.js
global.msgpack_pack = pack;
global.msgpack_unpack = unpack;
global.msgpack_packr = packr;

/**
* @param {Function} refFunction
Expand All @@ -72,7 +89,7 @@ const EXT_LOCALFUNCREF = 11;
function refFunctionPacker(refFunction) {
const ref = Citizen.makeRefFunction(refFunction);

return ref;
return Buffer.from(ref);
}

function refFunctionUnpacker(refSerialized) {
Expand Down Expand Up @@ -134,12 +151,6 @@ const EXT_LOCALFUNCREF = 11;
};
}

const AsyncFunction = (async () => {}).constructor;
codec.addExtPacker(EXT_FUNCREF, AsyncFunction, refFunctionPacker);
codec.addExtPacker(EXT_FUNCREF, Function, refFunctionPacker);
codec.addExtUnpacker(EXT_FUNCREF, refFunctionUnpacker);
codec.addExtUnpacker(EXT_LOCALFUNCREF, refFunctionUnpacker);

/**
* Deletes ref function
*
Expand Down
89 changes: 89 additions & 0 deletions data/shared/citizen/scripting/v8/msgpack.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
export enum FLOAT32_OPTIONS {
NEVER = 0,
ALWAYS = 1,
DECIMAL_ROUND = 3,
DECIMAL_FIT = 4
}

export interface Options {
useFloat32?: FLOAT32_OPTIONS
useRecords?: boolean | ((value:any)=> boolean)
structures?: {}[]
moreTypes?: boolean
sequential?: boolean
structuredClone?: boolean
mapsAsObjects?: boolean
variableMapSize?: boolean
coercibleKeyAsNumber?: boolean
copyBuffers?: boolean
bundleStrings?: boolean
useTimestamp32?: boolean
largeBigIntToFloat?: boolean
largeBigIntToString?: boolean
useBigIntExtension?: boolean
encodeUndefinedAsNil?: boolean
maxSharedStructures?: number
maxOwnStructures?: number
mapAsEmptyObject?: boolean
setAsEmptyObject?: boolean
writeFunction?: () => any
/** @deprecated use int64AsType: 'number' */
int64AsNumber?: boolean
int64AsType?: 'bigint' | 'number' | 'string'
shouldShareStructure?: (keys: string[]) => boolean
getStructures?(): {}[]
saveStructures?(structures: {}[]): boolean | void
onInvalidDate?: () => any
}
interface Extension {
Class?: Function
type?: number
pack?(value: any): Buffer | Uint8Array
unpack?(messagePack: Buffer | Uint8Array): any
read?(datum: any): any
write?(instance: any): any
}
export type UnpackOptions = { start?: number; end?: number; lazy?: boolean; } | number;
export class Unpackr {
constructor(options?: Options)
unpack(messagePack: Buffer | Uint8Array, options?: UnpackOptions): any
decode(messagePack: Buffer | Uint8Array, options?: UnpackOptions): any
unpackMultiple(messagePack: Buffer | Uint8Array): any[]
unpackMultiple(messagePack: Buffer | Uint8Array, forEach: (value: any, start?: number, end?: number) => any): void
}
export class Decoder extends Unpackr {}
export function unpack(messagePack: Buffer | Uint8Array, options?: UnpackOptions): any
export function unpackMultiple(messagePack: Buffer | Uint8Array): any[]
export function unpackMultiple(messagePack: Buffer | Uint8Array, forEach: (value: any, start?: number, end?: number) => any): void
export function decode(messagePack: Buffer | Uint8Array, options?: UnpackOptions): any
export function addExtension(extension: Extension): void
export function clearSource(): void
export function roundFloat32(float32Number: number): number
export const C1: {}
export let isNativeAccelerationEnabled: boolean

export class Packr extends Unpackr {
offset: number;
position: number;
pack(value: any, encodeOptions?: number): Buffer
encode(value: any, encodeOptions?: number): Buffer
useBuffer(buffer: Buffer | Uint8Array): void;
clearSharedData(): void;
}
export class Encoder extends Packr {}
export function pack(value: any, encodeOptions?: number): Buffer
export function encode(value: any, encodeOptions?: number): Buffer

export const REUSE_BUFFER_MODE: number;
export const RESET_BUFFER_MODE: number;
export const RESERVE_START_SPACE: number;

import { Transform, Readable } from 'stream'

export as namespace msgpackr;
export class UnpackrStream extends Transform {
constructor(options?: Options | { highWaterMark: number, emitClose: boolean, allowHalfOpen: boolean })
}
export class PackrStream extends Transform {
constructor(options?: Options | { highWaterMark: number, emitClose: boolean, allowHalfOpen: boolean })
}
Loading
Loading