[Tutorial] Plugin development guide
#61

Thank you very much for tutorial,very useful for me!
Reply
#62

This code:

Код:
#include "..\SDK\amx\amx.h"
#include "..\SDK\plugincommon.h"
#include "..\SDK\Invoke.h"

typedef void (*logprintf_t)(char* format, ...);


logprintf_t logprintf;
extern void *pAMXFunctions;



cell AMX_NATIVE_CALL HelloWorld(AMX* amx, cell* params)
{
    logprintf("This was printed from the Test plugin! Yay!");
    return 1;
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() 
{
    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) 
{
    pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
    logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF];
    logprintf(" * Test plugin was loaded.");
    return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
    logprintf(" * Test plugin was unloaded.");
}

cell AMX_NATIVE_CALL WhereIsPlayer(AMX* amx, cell* params)
{
    float
        x = NULL,
        y = NULL,
        z = NULL;

    //Get the player's position (and check to see if he is even connected).
    if(g_Invoke->callNative(&PAWN::GetPlayerPos, params[1], &x, &y, &z))
    {
        char name[24];

        //Get the rest of the player's information (name, interior, and virtualworld) and print it.
        g_Invoke->callNative(&PAWN::GetPlayerName, params[1], name);
        int interior = g_Invoke->callNative(&PAWN::GetPlayerInterior, params[1]);
        int virtualworld = g_Invoke->callNative(&PAWN::GetPlayerVirtualWorld, params[1]);

        logprintf("%s is at X: %.2f, Y: %.2f, Z: %.2f (Virtual world: %d, Interior %d).", name, x, y, z, virtualworld, interior);
        return 1;

    }
    return 0;
}

AMX_NATIVE_INFO PluginNatives[] =
{
    {"HelloWorld", HelloWorld},
    {0, 0}
};

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx ) 
{
    return amx_Register(amx, PluginNatives, -1);
}


PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx ) 
{
    return AMX_ERR_NONE;
}
Give me errors:

Код:
     Creando biblioteca Test\Debug\Test.lib and object Test\Debug\Test.exp
Test.obj : error LNK2019: extern symbol "public: int __cdecl Invoke::callNative(struct PAWN::Native const *,...)" (?callNative@Invoke@@QAAHPBUNative@PAWN@@ZZ) unresolved external symbol referenced in function 'function' "long __cdecl WhereIsPlayer(struct tagAMX *,long *)" (?WhereIsPlayer@@YAJPAUtagAMX@@PAJ@Z)
Test.obj : error LNK2001: sнmbolo externo "class Invoke * g_Invoke" (?g_Invoke@@3PAVInvoke@@A) unresolved external symbol
Test\Debug\Test.dll : fatal error LNK1120: 2 unresolved external symbols
========== Generated: 0 corrects, 1 incorrect ==========
Sorry for language of compiler.

It's the same problem of:


on page 6, here, on this tutorial.
Reply
#63

Please help.
Reply
#64

I have a small nabass question.
So, via the plugin, we *can* use all functions that c/++ gives, right?
Reply
#65

Quote:
Originally Posted by klklt0
Посмотреть сообщение
I have a small nabass question.
So, via the plugin, we *can* use all functions that c/++ gives, right?
In theory yes...but in some case you need to have install libraries or even clients.
Reply
#66

Am I using it wrongly?

pawn Код:
PLUGIN_EXPORT void PLUGIN_CALL ProcessTick() {
    logprintf("A");
}
This just seems to not print out.

Edit: I already have put the function to export:

Код:
LIBRARY "WItem"
EXPORTS
	Supports
	Load
	Unload
	AmxLoad
	AmxUnload
	ProcessTick
Forgot to add ProcessTick to Supports.
Reply
#67

Quote:
Originally Posted by Kyosaur
AmxLoad(AMX*):
This is called when a new AMX instance is loaded into the server. This will be called for every filterscript/gamemode! Because of this it isn't a good idea to store a single AMX instance for the entire plugin, instead use a queue/list/vector. In this function we also register our custom native functions we wish to provide PAWN with
Could someone tell me why this needs to be done please? (storing instances of amx) A small example or explanation would be great if possible? Is that just for calling publics in an amx file, Or must it always be done regardless if your calling publics from the plugin or not?

I have had a look in other plugins but still not sure if or why i need to use this.

Thanks in advance.

EDIT: I know i need to use AmxLoad(AMX*) to register the natives to the amx, just wondering why i would need to store the amx in a container.

EDIT2: I think i get it now, if an amx is unloaded most data that it pointed to, in the plugin becomes redundant. Going to have to re-download the documentation.
Reply
#68

Where can I get SAMP SDK (amx.h, plugincommon.h)?
And how to return value of function in plugin to pawno? I mean for e.g. GetPlayerMousePos and will return X and Y for player cursor pos.
Reply
#69

Quote:
Originally Posted by KubiPL
Посмотреть сообщение
Where can I get SAMP SDK (amx.h, plugincommon.h)?
And how to return value of function in plugin to pawno? I mean for e.g. GetPlayerMousePos and will return X and Y for player cursor pos.
Impossible, we can only create plugins server sided not client sided.
Reply
#70

hmm... just asking generally
will it be fine to start reading this if i'm a begneer pawno scripter?
Reply
#71

I cant find a thread with general questions about plugins that are not really worth a thread of it own but this thread seems to have a lot of general questions so I'll put mine here as well.

In my plugin I'm trying to read some information from the tables that hold the native functions and the public functions by directly accessing it.
I use the pointer to the AMX structure that I have in the the plugin to get the address of the AMX_HEADER structure which holds offsets to those tables.
This all works fine but whenever I try to read something from those tables the application crashes.
I dont know a lot about reading from memory in other locations like that but I have heard of some things that can prevent it and that you need to use something to lift that protection.

What I think is odd about this is that I can read the offsets to the tables out of the header just fine but I cant read data out of the tables.
I am using the address of the header and adding the offset to the tables to get their addresses.

Below is the code I use for my test right now which is only for the native functions table, it crashes on the first loop.
pawn Code:
PLUGIN_EXPORT int PLUGIN_CALL AmxLoad(AMX *amx)
{
    AMX_HEADER* header = (AMX_HEADER*)amx->base;
    AMX_NATIVE_INFO** natives = (AMX_NATIVE_INFO**)(header + header->natives);
    int count = (header->libraries - header->natives) / header->defsize;
    logprintf("%d native functions, header address %d, native table address %d", count, header, natives);
    for(int i=0; i<count; i++)
        logprintf("Native function %s, at index %d, address %d", natives[i]->name, i, natives[i]->func);
    return 0;
}
It prints the addresses just fine and the number of native functions matches the number I get from amx_NumNatives so I think that works fine.
I know I am doing something else wrong or I need to lift some kind of protection but I am unable to get it to work.

For those of you wondering why I want to read data from those tables, I actually dont but I'm planning to change some data there later to try and hook some things so they get called directly in my plugin.
Being able to read data there is just a test in learning about the data structures and how to access them.

Edit: I've found what I'm doing wrong.
I'm using a pointer to an array of pointers for AMX_NATIVE_INFO instead of a pointer to an array.
It doesnt crash anymore now but it's returning empty data, now I'll need figure out what causes that...
Reply
#72

Why if i use ' #include <a_samp.h> ' will get error : No such file or directory ?

But if use ' #include "a_samp.h" ' it work fine.

VS 2012
Reply
#73

Quote:
Originally Posted by Megalock
Посмотреть сообщение
This code:

Код:
#include "..\SDK\amx\amx.h"
#include "..\SDK\plugincommon.h"
#include "..\SDK\Invoke.h"

typedef void (*logprintf_t)(char* format, ...);


logprintf_t logprintf;
extern void *pAMXFunctions;



cell AMX_NATIVE_CALL HelloWorld(AMX* amx, cell* params)
{
    logprintf("This was printed from the Test plugin! Yay!");
    return 1;
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports() 
{
    return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData) 
{
    pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
    logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF];
    logprintf(" * Test plugin was loaded.");
    return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
    logprintf(" * Test plugin was unloaded.");
}

cell AMX_NATIVE_CALL WhereIsPlayer(AMX* amx, cell* params)
{
    float
        x = NULL,
        y = NULL,
        z = NULL;

    //Get the player's position (and check to see if he is even connected).
    if(g_Invoke->callNative(&PAWN::GetPlayerPos, params[1], &x, &y, &z))
    {
        char name[24];

        //Get the rest of the player's information (name, interior, and virtualworld) and print it.
        g_Invoke->callNative(&PAWN::GetPlayerName, params[1], name);
        int interior = g_Invoke->callNative(&PAWN::GetPlayerInterior, params[1]);
        int virtualworld = g_Invoke->callNative(&PAWN::GetPlayerVirtualWorld, params[1]);

        logprintf("%s is at X: %.2f, Y: %.2f, Z: %.2f (Virtual world: %d, Interior %d).", name, x, y, z, virtualworld, interior);
        return 1;

    }
    return 0;
}

AMX_NATIVE_INFO PluginNatives[] =
{
    {"HelloWorld", HelloWorld},
    {0, 0}
};

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx ) 
{
    return amx_Register(amx, PluginNatives, -1);
}


PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx ) 
{
    return AMX_ERR_NONE;
}
Give me errors:

Код:
     Creando biblioteca Test\Debug\Test.lib and object Test\Debug\Test.exp
Test.obj : error LNK2019: extern symbol "public: int __cdecl Invoke::callNative(struct PAWN::Native const *,...)" (?callNative@Invoke@@QAAHPBUNative@PAWN@@ZZ) unresolved external symbol referenced in function 'function' "long __cdecl WhereIsPlayer(struct tagAMX *,long *)" (?WhereIsPlayer@@YAJPAUtagAMX@@PAJ@Z)
Test.obj : error LNK2001: sнmbolo externo "class Invoke * g_Invoke" (?g_Invoke@@3PAVInvoke@@A) unresolved external symbol
Test\Debug\Test.dll : fatal error LNK1120: 2 unresolved external symbols
========== Generated: 0 corrects, 1 incorrect ==========
Sorry for language of compiler.

It's the same problem of:


on page 6, here, on this tutorial.
Same error. Shit, it's hard to fix it.
Reply
#74

Why does IsPlayerConnected always return 0 ??(Streamer Invoke)
Reply
#75

but, how to edit .dll using C++ ?
Reply
#76

Quote:
Originally Posted by Guest123
View Post
but, how to edit .dll using C++ ?
Microsoft Visual Studio C++ or something like that, but you need the source files

On topic: Nice tutorial, still reading it now haha. I'm gonna create some simple stuff with this stuff, thanks :3
Reply
#77

Could someone tell me where to find the following functions (which .h file?)

-amx_Register
-amx_GetString
-amx_GetAddr
-amx_StrLen

Thanks.
Reply
#78

Quote:
Originally Posted by Aeonosphere
View Post
Could someone tell me where to find the following functions (which .h file?)

-amx_Register
-amx_GetString
-amx_GetAddr
-amx_StrLen

Thanks.
https://www.******.se/search?q=amx_G...g+filetype%3Ah
Reply
#79

Quote:
Originally Posted by xeeZ
Посмотреть сообщение
Rename test.def to test.cpp
I don't have that errors now, but now i have:
Код:
1>LINK : fatal error LNK1104: cannot open file 'test.def'
EDIT: Solved.
Reply
#80

delete niggas
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)