Skip to content

Commit

Permalink
feat: support omp component raknet by patch call public
Browse files Browse the repository at this point in the history
  • Loading branch information
dockfries committed Apr 16, 2023
1 parent 82b15ee commit 8f855a8
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 103 deletions.
5 changes: 4 additions & 1 deletion packages/raknet/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@infernus/raknet",
"version": "0.0.1",
"version": "0.0.2",
"description": "A functional wrapper of the popular open.mp raknet plugin for samp-node.",
"keywords": [
"samp",
Expand Down Expand Up @@ -35,5 +35,8 @@
},
"peerDependencies": {
"@infernus/core": "workspace:^"
},
"dependencies": {
"iconv-lite": "^0.6.3"
}
}
60 changes: 40 additions & 20 deletions packages/raknet/src/callbacks/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,51 @@
// - It's not clear if registering multiple callbacks at the same time and then having one false followed by the next true will still execute (whether it's the same eventId i.e. packetId or rpcId)

// If they affect each other, a copy of the global array will be saved, and then the callback will be called in a loop. If one of them returns false, the return will be executed.
// Otherwise return true when the loop is complete, maybe?
import { packetCallback, rpcCallback } from "@/types";

// raw callback
export const OnIncomingPacket = (
func: (playerId: number, packetId: number, bs: number) => boolean
) => {
return samp.addEventListener("OnIncomingPacket", func);
const incomingPackets: packetCallback[] = [];
const incomingRPCs: rpcCallback[] = [];
const outgoingPackets: packetCallback[] = [];
const outgoingRPCs: rpcCallback[] = [];

samp.registerEvent("OnIncomingPacket", "iii");
samp.addEventListener(
"OnIncomingPacket",
(...args: [number, number, number]) => {
return incomingPackets.every((func) => func(...args));
}
);

samp.registerEvent("OnIncomingRPC", "iii");
samp.addEventListener("OnIncomingRPC", (...args: [number, number, number]) => {
return incomingRPCs.every((func) => func(...args));
});

samp.registerEvent("OnOutgoingPacket", "iii");
samp.addEventListener(
"OnOutgoingPacket",
(...args: [number, number, number]) => {
return outgoingPackets.every((func) => func(...args));
}
);

samp.registerEvent("OnOutgoingRPC", "iii");
samp.addEventListener("OnOutgoingRPC", (...args: [number, number, number]) => {
return outgoingRPCs.every((func) => func(...args));
});

export const OnIncomingPacket = (func: packetCallback) => {
incomingPackets.push(func);
};

export const OnIncomingRPC = (
func: (playerId: number, rpcId: number, bs: number) => boolean
) => {
return samp.addEventListener("OnIncomingRPC", func);
export const OnIncomingRPC = (func: rpcCallback) => {
incomingRPCs.push(func);
};

export const OnOutgoingPacket = (
func: (playerId: number, packetId: number, bs: number) => boolean
) => {
return samp.addEventListener("OnOutgoingPacket", func);
export const OnOutgoingPacket = (func: packetCallback) => {
outgoingPackets.push(func);
};

export const OnOutgoingRPC = (
func: (playerId: number, rpcId: number, bs: number) => boolean
) => {
return samp.addEventListener("OnOutgoingRPC", func);
export const OnOutgoingRPC = (func: rpcCallback) => {
outgoingRPCs.push(func);
};

// syntactic sugar callback
Expand Down
24 changes: 24 additions & 0 deletions packages/raknet/src/enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,27 @@ export enum PR_PacketReliability {
RELIABLE_ORDERED,
RELIABLE_SEQUENCED,
}

export enum RakNetNatives {
SEND_PACKET,
SEND_RPC,
EMULATE_INCOMING_PACKET,
EMULATE_INCOMING_RPC,
NEW,
NEW_COPY,
DELETE,
RESET,
RESET_READ_POINTER,
RESET_WRITE_POINTER,
IGNORE_BITS,
SET_WRITE_OFFSET,
GET_WRITE_OFFSET,
SET_READ_OFFSET,
GET_READ_OFFSET,
GET_NUMBER_OF_BITS_USED,
GET_NUMBER_OF_BYTES_USED,
GET_NUMBER_OF_UNREAD_BITS,
GET_NUMBER_OF_BITS_ALLOCATED,
WRITE_VALUE,
READ_VALUE,
}
3 changes: 3 additions & 0 deletions packages/raknet/src/functions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./macros";
export * from "./natives";
export * from "./stocks";
3 changes: 1 addition & 2 deletions packages/raknet/src/functions/macros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ export const BS_ReadCompressedBool = (bs: BitStream) =>
BS_ReadValue(bs, PR_ValueType.CBOOL);

export const BS_ReadCompressedString = (bs: BitStream, size: number) => {
const byteArr = BS_ReadValue(bs, [PR_ValueType.CSTRING, size]) as number[];
return byteArr.slice(0, byteArr.indexOf(0));
return BS_ReadStringX(bs, size, true);
};

export const BS_ReadBits = (bs: BitStream, size: number) =>
Expand Down
107 changes: 49 additions & 58 deletions packages/raknet/src/functions/natives.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { PR_PacketPriority, PR_PacketReliability, PR_ValueType } from "@/enums";
import {
PR_PacketPriority,
PR_PacketReliability,
PR_ValueType,
RakNetNatives,
} from "@/enums";
import { BitStream } from "@/types";

export const PR_Init = () => {
samp.callNative("PR_Init", "");
};
import { patchRakNetNative } from "./patch";

export const PR_SendPacket = (
bs: BitStream,
Expand All @@ -12,9 +14,8 @@ export const PR_SendPacket = (
reliability = PR_PacketReliability.RELIABLE_ORDERED,
orderingChannel = 0
) => {
samp.callNative(
"PR_SendPacket",
"iiiii",
patchRakNetNative(
RakNetNatives.SEND_PACKET,
bs,
playerId,
priority,
Expand All @@ -31,9 +32,8 @@ export const PR_SendRPC = (
reliability = PR_PacketReliability.RELIABLE_ORDERED,
orderingChannel = 0
) => {
samp.callNative(
"PR_SendRPC",
"iiiiii",
patchRakNetNative(
RakNetNatives.SEND_RPC,
bs,
playerId,
rpcId,
Expand All @@ -44,103 +44,97 @@ export const PR_SendRPC = (
};

export const PR_EmulateIncomingPacket = (bs: BitStream, playerId: number) => {
samp.callNative("PR_EmulateIncomingPacket", "ii", bs, playerId);
patchRakNetNative(RakNetNatives.EMULATE_INCOMING_PACKET, bs, playerId);
};

export const PR_EmulateIncomingRPC = (
bs: BitStream,
playerId: number,
rpcId: number
) => {
samp.callNative("PR_EmulateIncomingRPC", "iii", bs, playerId, rpcId);
patchRakNetNative(RakNetNatives.EMULATE_INCOMING_RPC, bs, playerId, rpcId);
};

export const BS_New = (): BitStream => {
return samp.callNative("BS_New", "");
return patchRakNetNative(RakNetNatives.NEW);
};

export const BS_NewCopy = (bs: BitStream): BitStream => {
return samp.callNative("BS_NewCopy", "i", bs);
return patchRakNetNative(RakNetNatives.NEW_COPY, bs);
};

export const BS_Delete = (bs: BitStream): BitStream => {
return samp.callNative("BS_Delete", "i", bs);
patchRakNetNative(RakNetNatives.DELETE, bs);
return bs;
};

export const BS_Reset = (bs: BitStream) => {
samp.callNative("BS_Reset", "i", bs);
patchRakNetNative(RakNetNatives.RESET, bs);
};

export const BS_ResetReadPointer = (bs: BitStream) => {
samp.callNative("BS_ResetReadPointer", "i", bs);
patchRakNetNative(RakNetNatives.RESET_READ_POINTER, bs);
};

export const BS_ResetWritePointer = (bs: BitStream) => {
samp.callNative("BS_ResetWritePointer", "i", bs);
patchRakNetNative(RakNetNatives.RESET_WRITE_POINTER, bs);
};

export const BS_IgnoreBits = (bs: BitStream, number_of_bits: number) => {
samp.callNative("BS_IgnoreBits", "ii", bs, number_of_bits);
patchRakNetNative(RakNetNatives.IGNORE_BITS, bs, number_of_bits);
};

export const BS_SetWriteOffset = (bs: BitStream, offset: number) => {
samp.callNative("BS_SetWriteOffset", "ii", bs, offset);
patchRakNetNative(RakNetNatives.SET_WRITE_OFFSET, bs, offset);
};

export const BS_GetWriteOffset = (bs: BitStream): number => {
return samp.callNative("BS_GetWriteOffset", "iI", bs);
return patchRakNetNative(RakNetNatives.GET_WRITE_OFFSET, bs);
};

export const BS_SetReadOffset = (bs: BitStream, offset: number) => {
samp.callNative("BS_SetReadOffset", "ii", bs, offset);
patchRakNetNative(RakNetNatives.SET_READ_OFFSET, bs, offset);
};

export const BS_GetReadOffset = (bs: BitStream): number => {
return samp.callNative("BS_GetReadOffset", "iI", bs);
return patchRakNetNative(RakNetNatives.GET_READ_OFFSET, bs);
};

export const BS_GetNumberOfBitsUsed = (bs: BitStream): number => {
return samp.callNative("BS_GetNumberOfBitsUsed", "iI", bs);
return patchRakNetNative(RakNetNatives.GET_NUMBER_OF_BITS_USED, bs);
};

export const BS_GetNumberOfBytesUsed = (bs: BitStream): number => {
return samp.callNative("BS_GetNumberOfBytesUsed", "iI", bs);
return patchRakNetNative(RakNetNatives.GET_NUMBER_OF_BYTES_USED, bs);
};

export const BS_GetNumberOfUnreadBits = (bs: BitStream): number => {
return samp.callNative("BS_GetNumberOfUnreadBits", "iI", bs);
return patchRakNetNative(RakNetNatives.GET_NUMBER_OF_UNREAD_BITS, bs);
};

export const BS_GetNumberOfBitsAllocated = (bs: BitStream): number => {
return samp.callNative("BS_GetNumberOfBitsAllocated", "iI", bs);
};

const isArrValueType = (type: PR_ValueType) => {
return [
PR_ValueType.STRING,
PR_ValueType.CSTRING,
PR_ValueType.STRING8,
PR_ValueType.STRING32,
PR_ValueType.FLOAT3,
PR_ValueType.FLOAT4,
PR_ValueType.VECTOR,
PR_ValueType.NORM_QUAT,
].includes(type);
return patchRakNetNative(RakNetNatives.GET_NUMBER_OF_BITS_ALLOCATED, bs);
};

export function BS_ReadValue(
bs: BitStream,
...types: (PR_ValueType | [PR_ValueType, number])[]
): number | number[] | (number | number[])[] {
let paramTypes = "";
const ret: any[] = [];
types.forEach((item) => {
const isReplaceItem = Array.isArray(item);
const type = isReplaceItem ? item[0] : item;
paramTypes += "i";
paramTypes += isArrValueType(type) ? "A" : "F";
isReplaceItem && (paramTypes += "i");
const isPlaceholder = Array.isArray(item);
const type = isPlaceholder ? item[0] : item;
ret.push(
patchRakNetNative(
RakNetNatives.READ_VALUE,
bs,
type,
isPlaceholder ? item[1] : 0
)
);
});
return samp.callNative("BS_ReadValue", `i${paramTypes}`, bs, ...types);
if (ret.length === 1) return ret[0];
return ret;
}

export const BS_WriteValue = (
Expand All @@ -157,16 +151,13 @@ export const BS_WriteValue = (
]
)[]
) => {
let paramTypes = "";
types.forEach((item) => {
paramTypes += "i";
paramTypes += isArrValueType(item[0]) ? "a" : "f";
if (item.length === 3) paramTypes += "i";
patchRakNetNative(
RakNetNatives.WRITE_VALUE,
bs,
item[0],
item[1],
item[2] || 0
);
});
samp.callNative(
"BS_WriteValue",
`i${paramTypes}`,
bs,
...types.flat(Infinity)
);
};
3 changes: 3 additions & 0 deletions packages/raknet/src/functions/patch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const patchRakNetNative = (...args: any[]) => {
return samp.callPublic("RakNetNative", `a`, args);
};
18 changes: 6 additions & 12 deletions packages/raknet/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { GameMode, IFilterScript } from "@infernus/core";
import { PR_Init } from "./functions/natives";

export default {
name: "raknet",
load() {
new GameMode().onInit = PR_Init;
},
unload() {
/* empty */
},
} as IFilterScript;
export * from "./callbacks";
export * from "./defines";
export * from "./enums";
export * from "./functions";
export * from "./interfaces";
export * from "./types";
10 changes: 10 additions & 0 deletions packages/raknet/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
export type BitStream = number;
export type Vector3 = [number, number, number];
export type Vector4 = [number, number, number, number];
export type packetCallback = (
playerId: number,
packetId: number,
bs: number
) => boolean;
export type rpcCallback = (
playerId: number,
rpcId: number,
bs: number
) => boolean;
Loading

0 comments on commit 8f855a8

Please sign in to comment.