AmyrAhmady/samp-node

Plugin adaptation for NodeSamp

MayotaNebrs opened this issue · 4 comments

I am interested in such a question, will there be an adaptation of the Pawn.Raknet plug-in for NodeSamp?

same problem. see katursis/Pawn.RakNet#53.

  • When you try to use the callNative method directly, the console prompts [Pawn.Raknet] Script not found.
    For example, samp.callNative("BS_New", "");

  • When the event is registered directly, the corresponding callback is not executed.

samp.registerEvent("OnIncomingPacket", "iii");
samp.on("OnIncomingPacket", (playerid: number, packetid: number, bs: number) => {
    console.log("nerver callback");
});
};

However, this can be used directly in streamer, it is not clear how the implementation inside the pawn.raknet plugin and between the open.mp-gdk plugin differs from the traditional plugin for streamer

This problem has lasted for a long time.
I don't know when this problem will be solved and how the development of omp-node adapted to omp-gdk is going (although samp-node is compatible with omp in most cases, there is no solution for things like Raknet) @AmyrAhmady

Invoke native solutions

Now, a rather silly solution is to use custom public functions to manually pass arguments and return the native function's return value.

If we pass the wrong parameter, the server will simply kill the process without any error notification.

forward BitStream:RakNetNative(...);
public BitStream:RakNetNative(...)
{
	new idx = getarg(0);
	switch(idx) 
	{
		case 0:				
		{
			return BS_New();
		}
		case 1:		
		{
			return BS_NewCopy(BitStream:getarg(0, 1));
		}
	}
	return BitStream:-1;
}
samp.on("OnGameModeInit", () => {
  const bs = samp.callPublic("RakNetNative", "a", [0]);
  console.log(bs);
  const bs_copy = samp.callPublic("RakNetNative", "a", [1, bs]);
  console.log(bs_copy);
});

Why am I passing it in an array instead of one by one?

Because when i pass a number by "i", such as 1, pawn internally through printf, it's always going to be a long integer, not a 1 itself, more like a memory address or random data, and passing it through an array is fine.

The second argument to getarg reads the number of indices in the one-dimensional array, which defaults to 0. When I pass an integer in, the inside can still be treated as an array to get the 0th element of the 0th parameter, so the data is weird.

For the BS_New and NewCopy calls above, because I'm not sure what type BitStream is inside the custom type, but printf(%d) in pawn is the same as what js prints out, it looks like a memory address or pointer, Or a large number, so it should be okay, right

Untested

I haven't tested for compatibility with callbacks, but it should be possible to write raknet's callback in pawn, return SAMPNode_CallEvent internally, and then register our callback in js through registerEvent to get it.

For the second parameter of a function like BS_ReadValue or BS_WriteValue, I haven't tested the idea of passing an array directly

Performance

In order to achieve syntax compatibility for samp or omp, some small sacrifices need to be made, but the overhead can be negligible. The amx of gamemode only did a small part of the work, such as calling an extra layer of function stack.

What we should focus on is developing libraries that wrap around commonly used plugins for samp/omp, expanding the ecosystem for writing server scripts in node, rather than being stuck in a situation where there are no "wheels".

Once in the node.js ecosystem, it's easy to use some commonly used libraries like mysql, so we no longer need to wrap samp's mysql plugin. We can also give up the timers in pawn language and directly use the native ones in node, which have more convenient asynchronous writing methods.

You can try using the latest infernus and infernus-starter, which internally uses a stupid way to implement api calls to raknet.