Giter VIP home page Giter VIP logo

pawn-natives's Introduction

pawn-natives

Macros and templates for quickly defining PAWN (SA:MP mostly) natives and also exporting them for other plguins to use.

Example.

Old method:

(Example taken from the streamer plugin, because why not):

Header:

	cell AMX_NATIVE_CALL IsValidDynamicCP(AMX *amx, cell *params);

Registration:

	{ "IsValidDynamicCP", Natives::IsValidDynamicCP },

Implementation:

cell AMX_NATIVE_CALL Natives::IsValidDynamicCP(AMX *amx, cell *params)
{
	CHECK_PARAMS(1, "IsValidDynamicCP");
	boost::unordered_map<int, Item::SharedCheckpoint>::iterator c = core->getData()->checkpoints.find(static_cast<int>(params[1]));
	if (c != core->getData()->checkpoints.end())
	{
		return 1;
	}
	return 0;
}

New method:

PAWN_NATIVE(Natives, IsValidDynamicCP, bool(int id))
{
	boost::unordered_map<int, Item::SharedCheckpoint>::iterator c = core->getData()->checkpoints.find(id);
	return (c != core->getData()->checkpoints.end());
}

Advantages:

  • No more messing about with registering natives.
  • Correct types - no need to deal with params.
  • Your natives are exported for other plugins to call directly (instead of going through an AMX).

Macros

PAWN_NATIVE

This will declare a static native and register it. If you want the function available to the rest of your code in other files, you need to perform declaration and definition separately - just like prototyping any other normal C function:

Prototype (declaration):

PAWN_NATIVE_DECL(Natives, IsValidDynamicCP, bool(int id));

Defintion:

PAWN_NATIVE_DEFN(Natives, IsValidDynamicCP, bool(int id))
{
	boost::unordered_map<int, Item::SharedCheckpoint>::iterator c = core->getData()->checkpoints.find(id);
	return (c != core->getData()->checkpoints.end())
}

PAWN_NATIVE_DECL

See above.

PAWN_NATIVE_DEFN

See above.

PAWN_NATIVE_DECLARE

Synonym for PAWN_NATIVE_DECL.

PAWN_NATIVE_DEFINE

Synonym for PAWN_NATIVE_DEFN.

PAWN_HOOK

This is similar to PAWN_NATIVE, but hooks an existing native function instead of creating an entirely new one. It again exports your new version for calling directly (note that this may bypass other hooks on the same function):

PAWN_HOOK(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z))
{
	logprintf("my_namespace::SetPlayerPos called");
	return SetPlayerPos(playerid, x, y, z),
}

While this function is being run, the hook is disabled so that calling the original does not get stuck in an infinite loop.

For prototyping, there are also equivalent macros:

PAWN_HOOK_DECL
PAWN_HOOK_DEFN
PAWN_HOOK_DECLARE
PAWN_HOOK_DEFINE

If you are using sampgdk (which is required for hooks anyway) you may need to undefine the existing symbols (unless you are not using the C++ wrappers):

#undef SetPlayerPos
PAWN_HOOK(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z))
{
	logprintf("my_namespace::SetPlayerPos called");
	return SetPlayerPos(playerid, x, y, z),
}

PAWN_IMPORT

If you want to use the functions from another plugin in your plugin, simply add:

PAWN_IMPORT(Natives, IsValidDynamicCP, bool(int id));

This is the same whether the original was a hook or a new native - so you as a user don't need to worry about which it is or if it is going change (that was a nice string of two-letter words, you don't see that very often). Calling it then becomes as simple as:

// You can also have `using namespace Natives;` if you want.
bool exists = Natives::IsValidDynamicCP(42);

Use

Inclusion

To use just the native declarations is easiest - there are no additional dependencies. Just include the following to any file in which you wish to declare or use this new style of native:

#include <pawn-natives/NativeFunc>

To use hooks, the inclusion is mostly the same:

#include <pawn-natives/NativeHook>

However note that this include requires you to have sampgdk - for accessing the original versions of natives, and subhook - for installing the hooks at an assembly level. These are assumed to be includable as <subhook/file> and <sampgdk/file>. Again - if you only want to declare natives and not hooks, you do not need these two dependencies.

To import natives from another plugin, use this instead:

#include <pawn-natives/NativeImport>

Initialisation

Like most things, this does require initialisation. Fortunately this is quite simple. In one file (probably your main file) add:

#include <pawn-natives/NativesMain>

That will provide storage space for required objects and variables. It is important that this comes AFTER NativeFunc and NativeHook if you want them - it only includes objects for the parts it knows you want.

This is good:

#include <pawn-natives/NativeFunc>
#include <pawn-natives/NativeHook>
#include <pawn-natives/NativesMain>

These are bad:

#include <pawn-natives/NativeFunc>
#include <pawn-natives/NativesMain>
#include <pawn-natives/NativeHook>
#include <pawn-natives/NativesMain>
#include <pawn-natives/NativeHook>
#include <pawn-natives/NativeFunc>

etc.

You also need to add a call to pawn_natives::AmxLoad(amx); in AmxLoad. If all your natives use this method, return it:

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx)
{
	return pawn_natives::AmxLoad(amx);
}

If you are only importing natives, not declaring any, you don't need NativesMain or pawn_natives::AmxLoad.

Calls

If you want to call a native or hook directly from your code, that is very easy:

PAWN_NATIVE(my_namespace, Native2, bool(int id))
{
	return id == 42;
}

PAWN_NATIVE(my_namespace, Native1, bool(int id))
{
	return Native2(id);
}

If you want to call an original native, bypassing the hook, dereference it first:

PAWN_HOOK(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z))
{
	logprintf("my_namespace::SetPlayerPos called");
	return sampgdk::SetPlayerPos(playerid, x, y, z),
}

PAWN_NATIVE(my_namespace, SetPlayerPosAndAngle, bool(int playerid, float x, float y, float z, float a))
{
	(*SetPlayerPos)(playerid, x, y, z);
	return sampgdk::SetPlayerAngle(playerid, a);
}

That code will NOT print my_namespace::SetPlayerPos called because we bypassed the hook. This will:

PAWN_HOOK(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z))
{
	logprintf("my_namespace::SetPlayerPos called");
	return sampgdk::SetPlayerPos(playerid, x, y, z),
}

PAWN_NATIVE(my_namespace, SetPlayerPosAndAngle, bool(int playerid, float x, float y, float z, float a))
{
	SetPlayerPos(playerid, x, y, z);
	return sampgdk::SetPlayerAngle(playerid, a);
}

Importantly, so will this - proving that hooks work even if you just call the original AMX functions from plugins:

PAWN_HOOK(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z))
{
	logprintf("my_namespace::SetPlayerPos called");
	return sampgdk::SetPlayerPos(playerid, x, y, z),
}

PAWN_NATIVE(my_namespace, SetPlayerPosAndAngle, bool(int playerid, float x, float y, float z, float a))
{
	sampgdk::SetPlayerPos(playerid, x, y, z);
	return sampgdk::SetPlayerAngle(playerid, a);
}

You can deal with the namespaces however you like - using or not. Note that pawn_natives is a separate namespace to the one specified in your declarations, it holds the functions used to initialise the system itself.

Logging

You can add debugging to the system by defining macros first. For example:

#define LOG_NATIVE_ERROR(...)   logprintf("ERROR: " __VA_ARGS__)
#define LOG_NATIVE_WARNING(...) logprintf("WARNING: " __VA_ARGS__)
#define LOG_NATIVE_DEBUG(...)   logprintf("DEBUG: " __VA_ARGS__)
#define LOG_NATIVE_INFO(...)    logprintf("INFO: " __VA_ARGS__)

#include <pawn-natives/NativeFunc>
#include <pawn-natives/NativeHook>

Or using samp-log-core (note that you may need a recent branch to allow variable parameters in the calls):

#define LOG_NATIVE_ERROR(...)   gMyLogger(LogLevel::ERROR, __VA_ARGS__)
#define LOG_NATIVE_WARNING(...) gMyLogger(LogLevel::WARNING, __VA_ARGS__)
#define LOG_NATIVE_DEBUG(...)   gMyLogger(LogLevel::DEBUG, __VA_ARGS__)
#define LOG_NATIVE_INFO(...)    gMyLogger(LogLevel::INFO, __VA_ARGS__)

#include <pawn-natives/NativeFunc>
#include <pawn-natives/NativeHook>

You will also need to do that each time you include one of the headers in to a new file, so I suggest wrapping the whole lot in a new include.

Seamless Use

The best way to use this library is in combination with sampgdk WITHOUT C++ wrappers. To do this, ensure the symbol SAMPGDK_CPP_WRAPPERS is not defined anywhere. This means that instead of:

namespace sampgdk {

inline bool IsValidVehicle(int vehicleid) {
  return sampgdk_IsValidVehicle(vehicleid);
}
}

You get:

#undef  IsValidVehicle
#define IsValidVehicle sampgdk_IsValidVehicle

Why is that better? Surely namespaces are good and the pre-processor is bad? Normally yes, but with this you can do:

#undef SetPlayerPos
PAWN_HOOK_DECL(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z));

PAWN_HOOK_DEFN(my_namespace, SetPlayerPos, bool(int playerid, float x, float y, float z))
{
	logprintf("my_namespace::SetPlayerPos called");
	return SetPlayerPos(playerid, x, y, z),
}

using namespace my_namespace;

Then in other code you just call:

SetPlayerPos(playerid, 10.0, 10.0, 1000.0);

And you don't need to know if there is a hook or not. If there is one, because of the #undef that will call the hook function directly, instead of going through the AMX. If there isn't one, that will call sampgdk_SetPlayerPos. Were we to use the namespaces instead of the pre-processor, we would have to use sampgdk::SetPlayerPos or my_namespace::SetPlayerPos explicitly. Using two using namespaces would introduce two identically named symbols in to the current scope and the compiler would complain, forcing you to distinguish with the prefix despite using using.

This makes your code more future-proof. You don't need to worry if there ever will be a hook on that function in the future - just write it like that and the compiler will deal with changes.

Testing

# Before you start
pip install PLY cidl
mkdir build
cmake .
cd build
cmake --build ..
# Optional
cmake --build .. --config Release
# If there's a problem
cmake .. -DMAIN_RUN=FALSE
cmake --build ..

pawn-natives's People

Contributors

hual avatar y-less avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pawn-natives's Issues

Building on Linux fails

I have no idea where to start with this one unfortunately...

Environment described here: https://github.com/maddinat0r/docker-debian-samp/blob/master/Dockerfile

Build config etc: https://github.com/Southclaws/pawn-uuid/blob/master/CMakeLists.txt

[ 12%] Building CXX object src/CMakeFiles/uuid.dir/__/lib/samp-plugin-sdk/amxplugin.cpp.o
[ 25%] Building CXX object src/CMakeFiles/uuid.dir/__/lib/samp-plugin-sdk/amxplugin2.cpp.o
[ 37%] Building C object src/CMakeFiles/uuid.dir/__/lib/samp-plugin-sdk/amx/getch.c.o
[ 50%] Building CXX object src/CMakeFiles/uuid.dir/guid.cpp.o
[ 62%] Building CXX object src/CMakeFiles/uuid.dir/main.cpp.o
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/NativeFunc.hpp: In constructor 'pawn_natives::NativeFunc<RET()>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:165:122: error: class 'pawn_natives::NativeFunc<RET()>' does not have any field named 'NativeFunc0'
  class NativeFunc<RET()> : public NativeFunc0<RET> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : NativeFunc0(name, native) {} };
                                                                                                                          ^~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:170:30: error: class 'pawn_natives::NativeFunc<RET(A)>' does not have any field named 'NativeFunc1'
 #define PAWN_HOOK_NAME       NativeFunc1
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:184:30: error: class 'pawn_natives::NativeFunc<RET(A, B)>' does not have any field named 'NativeFunc2'
 #define PAWN_HOOK_NAME       NativeFunc2
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:198:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C)>' does not have any field named 'NativeFunc3'
 #define PAWN_HOOK_NAME       NativeFunc3
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:212:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D)>' does not have any field named 'NativeFunc4'
 #define PAWN_HOOK_NAME       NativeFunc4
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:226:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E)>' does not have any field named 'NativeFunc5'
 #define PAWN_HOOK_NAME       NativeFunc5
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:240:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F)>' does not have any field named 'NativeFunc6'
 #define PAWN_HOOK_NAME       NativeFunc6
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:254:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G)>' does not have any field named 'NativeFunc7'
 #define PAWN_HOOK_NAME       NativeFunc7
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:268:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H)>' does not have any field named 'NativeFunc8'
 #define PAWN_HOOK_NAME       NativeFunc8
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:282:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I)>' does not have any field named 'NativeFunc9'
 #define PAWN_HOOK_NAME       NativeFunc9
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:296:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J)>' does not have any field named 'NativeFunc10'
 #define PAWN_HOOK_NAME       NativeFunc10
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:310:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K)>' does not have any field named 'NativeFunc11'
 #define PAWN_HOOK_NAME       NativeFunc11
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:324:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L)>' does not have any field named 'NativeFunc12'
 #define PAWN_HOOK_NAME       NativeFunc12
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:338:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M)>' does not have any field named 'NativeFunc13'
 #define PAWN_HOOK_NAME       NativeFunc13
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M, N)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:352:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M, N)>' does not have any field named 'NativeFunc14'
 #define PAWN_HOOK_NAME       NativeFunc14
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:366:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)>' does not have any field named 'NativeFunc15'
 #define PAWN_HOOK_NAME       NativeFunc15
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In constructor 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)>::NativeFunc(const char*, AMX_NATIVE)':
/root/src/plugin-natives/NativeFunc.hpp:380:30: error: class 'pawn_natives::NativeFunc<RET(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)>' does not have any field named 'NativeFunc16'
 #define PAWN_HOOK_NAME       NativeFunc16
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:157: note: in expansion of macro 'PAWN_HOOK_NAME'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                             ^~~~~~~~~~~~~~
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/natives.hpp: In static member function 'static cell uuid::Native_uuid_UUID::Call(AMX*, cell*)':
/root/src/natives.hpp:18:18: error: 'UUID' is not a member of 'uuid'
 PAWN_NATIVE_DECL(uuid, UUID, bool(char *))
                  ^
/root/src/plugin-natives/NativeFunc.hpp:422:21: note: in definition of macro 'PAWN_NATIVE_DECL'
              return nspace::func.CallDoOuter(amx, params);                   \
                     ^~~~~~
/root/src/natives.hpp:18:18: note: suggested alternative:
 PAWN_NATIVE_DECL(uuid, UUID, bool(char *))
                  ^
/root/src/plugin-natives/NativeFunc.hpp:422:21: note: in definition of macro 'PAWN_NATIVE_DECL'
              return nspace::func.CallDoOuter(amx, params);                   \
                     ^~~~~~
In file included from /root/src/natives.hpp:15:0,
                 from /root/src/main.cpp:15:
/root/src/impl.hpp:17:13: note:   'Impl::UUID'
 std::string UUID();
             ^~~~
In file included from /root/src/plugin-natives/NativeFunc.hpp:175:0,
                 from /root/src/natives.hpp:16,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp: In instantiation of 'pawn_natives::NativeFunc<RET(A)>::NativeFunc(const char*, AMX_NATIVE) [with RET = bool; A = char*; AMX_NATIVE = int (*)(tagAMX*, int*); cell = int]':
/root/src/natives.hpp:18:1:   required from here
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:147:184: error: no matching function for call to 'pawn_natives::NativeFunc1<bool, char*>::NativeFunc1()'
  class NativeFunc<RET(PAWN_HOOK_TYPES)> : public PAWN_HOOK_NAME<RET, PAWN_HOOK_TYPES> { protected: NativeFunc(char const * const name, AMX_NATIVE native) : PAWN_HOOK_NAME(name, native) {} };
                                                                                                                                                                                        ^
In file included from /root/src/natives.hpp:16:0,
                 from /root/src/main.cpp:15:
/root/src/plugin-natives/NativeFunc.hpp:170:30: note: candidate: pawn_natives::NativeFunc1<RET, A>::NativeFunc1(const char*, AMX_NATIVE) [with RET = bool; A = char*; AMX_NATIVE = int (*)(tagAMX*,int*); cell = int]
 #define PAWN_HOOK_NAME       NativeFunc1
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:13:3: note: in expansion of macro 'PAWN_HOOK_NAME'
   PAWN_HOOK_NAME(char const * const name, AMX_NATIVE native) : NativeFuncBase(PAWN_HOOK_NUMBER, name, native) {}
   ^~~~~~~~~~~~~~
/root/src/plugin-natives/NativeFunc.hpp:170:30: note:   candidate expects 2 arguments, 0 provided
 #define PAWN_HOOK_NAME       NativeFunc1
                              ^
/root/src/plugin-natives/Internal/NativeFuncImpl.hpp:13:3: note: in expansion of macro 'PAWN_HOOK_NAME'
   PAWN_HOOK_NAME(char const * const name, AMX_NATIVE native) : NativeFuncBase(PAWN_HOOK_NUMBER, name, native) {}
   ^~~~~~~~~~~~~~
make[3]: *** [src/CMakeFiles/uuid.dir/main.cpp.o] Error 1
make[2]: *** [src/CMakeFiles/uuid.dir/all] Error 2
src/CMakeFiles/uuid.dir/build.make:158: recipe for target 'src/CMakeFiles/uuid.dir/main.cpp.o' failed
make[3]: Leaving directory '/root/build'
CMakeFiles/Makefile2:85: recipe for target 'src/CMakeFiles/uuid.dir/all' failed
make[2]: Leaving directory '/root/build'
make[1]: *** [all] Error 2
Makefile:83: recipe for target 'all' failed
make[1]: Leaving directory '/root/build'
makefile:32: recipe for target 'build-inside' failed
make: *** [build-inside] Error 2
make: *** [build-linux] Error 2

SAMPSDK required

hello
i try to build this fine project
but i get this err

I can't find anywhere in the docs where to get this from either.

$ make
Scanning dependencies of target subhook
[  3%] Creating directories for 'subhook'
[  6%] Performing download step (git clone) for 'subhook'
Cloning into 'subhook'...
Already on 'master'
Your branch is up to date with 'origin/master'.
[  9%] No update step for 'subhook'
[ 12%] No patch step for 'subhook'
[ 15%] No configure step for 'subhook'
[ 18%] No build step for 'subhook'
[ 21%] No install step for 'subhook'
[ 25%] Completed 'subhook'
[ 25%] Built target subhook
Scanning dependencies of target cmake-modules
[ 28%] Creating directories for 'cmake-modules'
[ 31%] Performing download step (git clone) for 'cmake-modules'
Cloning into 'cmake-modules'...
Already on 'master'
Your branch is up to date with 'origin/master'.
[ 34%] No update step for 'cmake-modules'
[ 37%] No patch step for 'cmake-modules'
[ 40%] No configure step for 'cmake-modules'
[ 43%] No build step for 'cmake-modules'
[ 46%] No install step for 'cmake-modules'
[ 50%] Completed 'cmake-modules'
[ 50%] Built target cmake-modules
Scanning dependencies of target sampgdk
[ 53%] Creating directories for 'sampgdk'
[ 56%] Performing download step (git clone) for 'sampgdk'
Cloning into 'sampgdk'...
Already on 'master'
Your branch is up to date with 'origin/master'.
[ 59%] No update step for 'sampgdk'
[ 62%] No patch step for 'sampgdk'
[ 65%] Performing configure step for 'sampgdk'
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at /usr/share/cmake-3.19/Modules/FindPackageHandleStandardArgs.cmake:218 (message):
  Could NOT find SAMPSDK (missing: SAMPSDK_DIR SAMPSDK_INCLUDE_DIR)
Call Stack (most recent call first):
  /usr/share/cmake-3.19/Modules/FindPackageHandleStandardArgs.cmake:582 (_FPHSA_FAILURE_MESSAGE)
  cmake/FindSAMPSDK.cmake:21 (find_package_handle_standard_args)
  CMakeLists.txt:30 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/hidde/projects/pawn-natives/build/sampgdk/src/sampgdk-build/CMakeFiles/CMakeOutput.log".
make[2]: *** [CMakeFiles/sampgdk.dir/build.make:126: sampgdk/src/sampgdk-stamp/sampgdk-configure] Error 1
make[1]: *** [CMakeFiles/Makefile2:155: CMakeFiles/sampgdk.dir/all] Error 2
make: *** [Makefile:103: all] Error 2

Add support for non-string arrays

There are no ParamCast<T> template overloads for non-string arrays. Collections such as std::vector<cell> or std::array<cell, N> could be used to interface with those parameters. std::array<cell, N> can be used if the expected size of an array is known at compile-time.

Some template overload ideas:

Immutable array:

const std::vector<cell>&

or

const std::array<cell, N>&

Mutable array:

std::vector<cell>&

or

std::vector<cell>*

or

std::array<cell, N>&

or

std::array<cell, N>*

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.