Raised This Month: $51 Target: $400
 12% 

[TUT] Dynamic / Fake Natives


Post New Thread Reply   
 
Thread Tools Display Modes
Zefir
Member
Join Date: Oct 2007
Location: Kiev, Ukraine
Old 05-01-2010 , 12:05   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #11

Tnx, Hawk552.

I writing wrapper for sqlx, and cannot emulate SQL_ThreadQuery()

Cannot get array data[], added some values, run SQL_ThreadQuery() with my callback function and call original callback function from caller plugin with original array data[]
__________________
Zefir is offline
Send a message via ICQ to Zefir
Hawk552
AMX Mod X Moderator
Join Date: Aug 2005
Old 05-01-2010 , 13:17   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #12

Quote:
Originally Posted by Zefir View Post
Tnx, Hawk552.

I writing wrapper for sqlx, and cannot emulate SQL_ThreadQuery()

Cannot get array data[], added some values, run SQL_ThreadQuery() with my callback function and call original callback function from caller plugin with original array data[]
Yeah, I always just use style 0 because I like having direct access to the number of parameters and the plugin id.

Why are you making a wrapper for SQL_ThreadQuery(), though?
__________________
Hawk552 is offline
Send a message via AIM to Hawk552
Zefir
Member
Join Date: Oct 2007
Location: Kiev, Ukraine
Old 05-01-2010 , 13:56   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #13

Quote:
Originally Posted by Hawk552 View Post
Why are you making a wrapper for SQL_ThreadQuery(), though?
For centralized setting and controlling all accounts to all used SQL servers in all plugins.
__________________
Zefir is offline
Send a message via ICQ to Zefir
Hawk552
AMX Mod X Moderator
Join Date: Aug 2005
Old 05-01-2010 , 14:10   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #14

Check out this code. Requires CellTravTrie.

A few notes:
  • This is basically a trie which saves itself into SQL for you.
  • It has some things unique to the environment it was written for. If you understand it, you can remove those things.
  • UTIL_ARP_CleverQuery() can be treated as though it were SQL_ThreadQuery().

Code:
// Generalized table query for MySQL: /*    CREATE TABLE IF NOT EXISTS %s (classkey VARCHAR(64),value TEXT,UNIQUE KEY (classkey)) */ // Generalized table query for SQLite: /*    CREATE TABLE IF NOT EXISTS %s (classkey VARCHAR(64),value TEXT,UNIQUE (classkey)) */ new TravTrie:g_ClassArray // ... public _ARP_ClassLoad(Plugin,Params) {     if(Params != 4)     {         format(g_Query,4095,"Parameters do not match. Expected: 3, Found: %d",Params)         return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,Plugin)     }         new Param[64],Handler[64],Temp[128],Table[64],ClassName[128]//,Len = min(4095,get_param(4))     get_string(1,Param,63)     get_string(2,Handler,63)     get_string(3,g_Query,4095)     get_string(4,Table,63)         if(!Table[0])         copy(Table,63,g_DataTable)         format(ClassName,127,"%s|%s",Table,Param)         //g_Query[0] = Len         format(Temp,127,"%d|%s",Plugin,Handler)         new travTrieIter:Iter = GetTravTrieIterator(g_ClassArray),Cell,ClassHeader[64],Loaded,TravTrie:CurTrie,TravTrie:PluginTrie,Flag,ReadTable[64],Garbage[1]     while(MoreTravTrie(Iter))     {               ReadTravTrieKey(Iter,ClassHeader,63)         ReadTravTrieCell(Iter,Cell)                 strtok(ClassHeader,ReadTable,63,Garbage,0,'|')         if(Table[0] && equali(ReadTable,Table))             Flag = 1                 if(equali(ClassName,ClassHeader))         {                      TravTrieGetCell(g_ClassArray,ClassHeader,CurTrie)                         TravTrieGetHCell(CurTrie,"/plugins",PluginTrie)             TravTrieSetCellEx(PluginTrie,Plugin,1)                         TravTrieGetHCell(CurTrie,"/loaded",Loaded)             if(!Loaded)             {                             new TravTrie:CallsTrie                 TravTrieGetHCell(CurTrie,"/calls",CallsTrie)                                 TravTrieSetString(CallsTrie,Temp,g_Query)                                 return -1             }                             /*new Forward = CreateOneForward(Plugin,"ARP_ClassLoaded",FP_CELL,FP_STRING),Return             if(!Forward || !ExecuteForward(Forward,Return,_:CurTrie,Class))             {                 format(g_Query,4095,"Could not execute ARP_ClassLoaded forward")                 return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,Plugin)             }             DestroyForward(Forward)*/                         new Forward = CreateOneForward(Plugin,Handler,FP_CELL,FP_STRING,FP_STRING),Return             //new CurArray = PrepareArray(g_Query[1],Len)             if(!Forward || !ExecuteForward(Forward,Return,_:CurTrie,ClassHeader,g_Query))             {                 format(g_Query,4095,"Could not execute %s forward to %d",Handler,Plugin)                 return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,Plugin)             }                         DestroyForward(Forward)                         return PLUGIN_HANDLED         }     }     DestroyTravTrieIterator(Iter)         if(!Flag && !equali(g_DataTable,Table))     {               static Query[512]         switch(g_SqlMode)         {             case MYSQL:                 format(Query,511,"CREATE TABLE IF NOT EXISTS %s (classkey VARCHAR(64),value TEXT,UNIQUE KEY (classkey))",Table)             case SQLITE:                 format(Query,511,"CREATE TABLE IF NOT EXISTS %s (classkey VARCHAR(64),value TEXT,UNIQUE (classkey))",Table)         }         UTIL_ARP_CleverQuery(g_Plugin,g_SqlHandle,"IgnoreHandle",Query)     }         new Buffer[128] //,TravTrie:CallTrie = TravTrieCreate()     //SQL_QuoteString(g_SqlHandle,Buffer,127,Param)     copy(Buffer,126,Param)         //server_print("Setting array: %d | %s | %s | %d",CallTrie,Handler,g_Query,Len)     new TravTrie:CallTrie = TravTrieCreate()     TravTrieSetString(CallTrie,Temp,g_Query)         CurTrie = TravTrieCreate()     TravTrieSetCell(g_ClassArray,ClassName,CurTrie)     TravTrieSetHCell(CurTrie,"/loaded",0)     TravTrieSetHCell(CurTrie,"/saving",0)     TravTrieSetHCell(CurTrie,"/lastquery",0)     TravTrieSetHCell(CurTrie,"/plugins",TravTrieCreate())     TravTrieSetHCell(CurTrie,"/changed",TravTrieCreate())     TravTrieSetHCell(CurTrie,"/calls",CallTrie)     TravTrieSetHCell(CurTrie,"/savetrie",TravTrieCreate())     TravTrieSetString(CurTrie,"/table",Table)     //TravTrieSetString(CurTrie,"/table",Table)         Buffer[127] = _:CurTrie         format(g_Query,4095,"SELECT * FROM %s WHERE classkey LIKE '%s|%%'",Table,Buffer)     //UTIL_ARP_CleverQuery(g_Plugin,g_SqlHandle,"ClassLoadHandle",g_Query,Buffer,128)     SQL_ThreadQuery(g_SqlHandle,"ClassLoadHandle",g_Query,Buffer,128)         return PLUGIN_CONTINUE } public ClassLoadHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize) {        if(FailState == TQUERY_CONNECT_FAILED)     {         format(g_Query,4095,"Could not connect to database: %s",Error)         return UTIL_ARP_ThrowError(0,0,g_Query,0)     }     else if(FailState == TQUERY_QUERY_FAILED)     {         format(g_Query,4095,"Internal error: %s",Error)         return UTIL_ARP_ThrowError(0,0,g_Query,0)     }         if(Errcode)     {         format(g_Query,4095,"Error on query: %s",Error)         return UTIL_ARP_ThrowError(0,0,g_Query,0)     }         new ClassKey[128],Key[64],Value[128],Garbage[2],TravTrie:CurTrie = TravTrie:Data[127],TravTrie:CallsTrie     while(SQL_MoreResults(Query))     {         SQL_ReadResult(Query,0,ClassKey,127)         strtok(ClassKey,Garbage,1,Key,63,'|')         SQL_ReadResult(Query,1,Value,127)                 TravTrieSetString(CurTrie,Key,Value)                 SQL_NextRow(Query)     }         TravTrieSetHCell(CurTrie,"/loaded",1)         TravTrieGetHCell(CurTrie,"/calls",CallsTrie)     new travTrieIter:Iter = GetTravTrieIterator(CallsTrie),Handler[64],Forward,Return,Temp[64],PluginStr[10],Plugin     while(MoreTravTrie(Iter))     {               ReadTravTrieKey(Iter,Temp,63)         strtok(Temp,PluginStr,9,Handler,63,'|')         Plugin = str_to_num(PluginStr)         ReadTravTrieString(Iter,g_Query,4095)                 Forward = CreateOneForward(Plugin,Handler,FP_CELL,FP_STRING,FP_STRING)         //CurArray = PrepareArray(g_Query[1],g_Query[0])         if(!Forward || !ExecuteForward(Forward,Return,_:CurTrie,Data,g_Query))         {             format(g_Query,4095,"Could not execute %s forward to %d",Handler,Plugin)             return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,0)         }         DestroyForward(Forward)     }     DestroyTravTrieIterator(Iter)         TravTrieDestroy(CallsTrie)         Forward = CreateMultiForward("ARP_ClassLoaded",ET_IGNORE,FP_CELL,FP_STRING)     if(!Forward || !ExecuteForward(Forward,Return,_:CurTrie,Data))     {         format(g_Query,4095,"Could not execute ARP_ClassLoaded forward")         return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,0)     }     DestroyForward(Forward)         return PLUGIN_CONTINUE } public _ARP_ClassSave(Plugin,Params) {     if(Params != 2)     {         format(g_Query,4095,"Parameters do not match. Expected: 2, Found: %d",Params)         return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,Plugin)     }         new TravTrie:ClassNum = TravTrie:get_param_byref(1),ProcClass[128],Close = get_param(2),travTrieIter:Iter = GetTravTrieIterator(g_ClassArray),TrieClass[64],TravTrie:CurTrie,TravTrie:PluginTrie,ClassName[64]     while(MoreTravTrie(Iter))     {         ReadTravTrieKey(Iter,TrieClass,63)         ReadTravTrieCell(Iter,CurTrie)                 copy(ClassName,63,TrieClass[containi(TrieClass,"|") + 1])                 if(CurTrie == ClassNum && !task_exists(_:CurTrie))         {             //SQL_QuoteString(g_SqlHandle,ProcClass,127,Class)             copy(ProcClass[1],126,TrieClass)                         //format(g_Query,4095,"DELETE FROM %s WHERE classkey LIKE '%s|%%'",g_DataTable,ProcClass)             //UTIL_ARP_CleverQuery(g_Plugin,g_SqlHandle,"IgnoreHandle",g_Query)                         ProcClass[0] = _:CurTrie                         new TravTrie:SaveTrie             TravTrieGetHCell(CurTrie,"/savetrie",SaveTrie)                         new travTrieIter:Iter = GetTravTrieIterator(SaveTrie),Handler[64],Temp[128],PluginStr[10],Plugin,Forward,Return             //server_print("ITERATOR: %d, SAVETRIE: %d",Iter,SaveTrie)             while(MoreTravTrie(Iter))             {                 ReadTravTrieKey(Iter,Temp,127)                 ReadTravTrieString(Iter,g_Query,4095)                                 strtok(Temp,PluginStr,9,Handler,63,'|')                 Plugin = str_to_num(PluginStr)                                 //server_print("Calling forward to: %d , %s",Plugin,Handler)                                 Forward = CreateOneForward(Plugin,Handler,FP_CELL,FP_STRING,FP_STRING)                 if(!Forward || !ExecuteForward(Forward,Return,CurTrie,ClassName,g_Query))                 {                     format(g_Query,4095,"Could not register forward")                     return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,g_Plugin)                 }                 DestroyForward(Forward)             }             DestroyTravTrieIterator(Iter)                         if(_CallEvent("Class_Save",ClassName,128))                 return FAILED                         if(Close)             {                             TravTrieGetHCell(CurTrie,"/plugins",PluginTrie)                 TravTrieDeleteKeyEx(PluginTrie,Plugin)                                 set_param_byref(1,_:Invalid_TravTrie)             }                         SaveClass(CurTrie,ProcClass[1])                         return SUCCEEDED         }     }     DestroyTravTrieIterator(Iter)         return SUCCEEDED } public SaveClass(TravTrie:CurTrie,ProcClass[]) {        new Saving     TravTrieGetHCell(CurTrie,"/saving",Saving)     if(Saving)         return SUCCEEDED         new TravTrie:ChangedTrie,Table[64],ClassName[64]//,Garbage[1]     TravTrieGetHCell(CurTrie,"/changed",ChangedTrie)     //TravTrieGetString(CurTrie,"/table",Table,63)     //TravTrieGetHCell(CurTrie,"/table",TableTrie)     //TravTrieGetStringEx(TableTrie,0,Table,63)         strtok(ProcClass,Table,63,ClassName,63,'|')         TravTrieSetHCell(CurTrie,"/saving",1)         new Key[128],Data[64],TrieClass[64]     Data[1] = _:CurTrie         copy(Data[2],60,ProcClass)         //format(g_Query,4095,"DELETE FROM %s WHERE classkey LIKE '%s|%%'",g_DataTable,ProcClass)     //UTIL_ARP_CleverQuery(g_Plugin,g_SqlHandle,"IgnoreHandle",g_Query)         new travTrieIter:Iter = GetTravTrieIterator(CurTrie),Changed,ChangedNum         // Run through it once to get the number     while(MoreTravTrie(Iter))     {         ReadTravTrieKey(Iter,TrieClass,63)         ReadTravTrieString(Iter,g_Query,4095)                 TravTrieGetCell(ChangedTrie,TrieClass,Changed)                 if(TrieClass[0] != '^n' && TrieClass[0] != '/' && Changed) ChangedNum++                 Changed = 0     }         TravTrieSetHCell(CurTrie,"/lastquery",ChangedNum)     DestroyTravTrieIterator(Iter)         Iter = GetTravTrieIterator(CurTrie)     while(MoreTravTrie(Iter))     {                     ReadTravTrieKey(Iter,TrieClass,63)         ReadTravTrieString(Iter,g_Query,4095)         TravTrieGetCell(ChangedTrie,TrieClass,Changed)                 if(TrieClass[0] == '^0' || TrieClass[0] == '/' || !Changed) continue                 TravTrieSetCell(ChangedTrie,TrieClass,0)                 Changed = 0                 //SQL_QuoteString(g_SqlHandle,Key,127,TrieClass)         copy(Key,127,TrieClass)         //SQL_QuoteString(g_SqlHandle,g_Cache,4095,g_Query)         copy(g_Cache,4095,g_Query)                 Data[0]++                 ARP_SqlEscape(ClassName,127)         ARP_SqlEscape(Key,127)         ARP_SqlEscape(g_Cache,4095)         //replace_all(ClassName,127,"'","\'")         //replace_all(Key,127,"'","\'")         //replace_all(g_Cache,4095,"'","\'")                 switch(g_SqlMode)         {             case MYSQL:                 format(g_Query,4095,"INSERT INTO %s VALUES ('%s|%s','%s') ON DUPLICATE KEY UPDATE value='%s'",Table,ClassName,Key,g_Cache,g_Cache)             case SQLITE:                 format(g_Query,4095,"REPLACE INTO %s VALUES ('%s|%s','%s')",Table,ClassName,Key,g_Cache)         }         UTIL_ARP_CleverQuery(g_Plugin,g_SqlHandle,"ClassSaveHandle",g_Query,Data,64)     }     DestroyTravTrieIterator(Iter)         new TravTrie:PluginTrie,TravTrie:SaveTrie     TravTrieGetHCell(CurTrie,"/plugins",PluginTrie)     TravTrieGetHCell(CurTrie,"/savetrie",SaveTrie)         if(!ChangedNum && !TravTrieSize(PluginTrie) && g_SqlMode == SQLITE)     {               TravTrieDestroy(PluginTrie)         TravTrieDestroy(CurTrie)         TravTrieDestroy(ChangedTrie)         TravTrieDestroy(SaveTrie)                     TravTrieDeleteKey(g_ClassArray,ProcClass)     }         return SUCCEEDED } public ClassSaveHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize) {     if(FailState == TQUERY_CONNECT_FAILED)     {         format(g_Query,4095,"Could not connect to database: %s",Error)         return UTIL_ARP_ThrowError(0,0,g_Query,0)     }     else if(FailState == TQUERY_QUERY_FAILED)     {         SQL_GetQueryString(Query,g_Query,4095)            format(g_Query,4095,"Internal error: %s^nQuery: %s",Error,g_Query)         return UTIL_ARP_ThrowError(0,0,g_Query,0)     }         if(Errcode)     {         format(g_Query,4095,"Error on query: %s",Error)         return UTIL_ARP_ThrowError(0,0,g_Query,0)     }         new LastQuery,TravTrie:CurTrie = TravTrie:Data[1]     TravTrieGetHCell(CurTrie,"/lastquery",LastQuery)         if(Data[0] == LastQuery && g_SqlMode != SQLITE)     {         TravTrieSetHCell(CurTrie,"/saving",0)             new TravTrie:PluginTrie,TravTrie:ChangedTrie,TravTrie:SaveTrie         TravTrieGetHCell(CurTrie,"/plugins",PluginTrie)         TravTrieGetHCell(CurTrie,"/changed",ChangedTrie)         TravTrieGetHCell(CurTrie,"/savetrie",SaveTrie)         if(!TravTrieSize(PluginTrie) && !g_PluginEnd)         {             TravTrieDestroy(PluginTrie)             TravTrieDestroy(CurTrie)             TravTrieDestroy(ChangedTrie)             TravTrieDestroy(SaveTrie)                         TravTrieDeleteKey(g_ClassArray,Data[2])         }                 //if(g_PluginEnd && g_LastOverallQuery == Data[2]) TravTrieDestroy(g_ClassArray)     }         return PLUGIN_CONTINUE } public _ARP_ClassSaveHook(Plugin,Params) {     if(Params != 3)     {         format(g_Query,4095,"Parameters do not match. Expected: 3, Found: %d",Params)         return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,Plugin)     }         new TravTrie:CurTrie = TravTrie:get_param(1),Handler[64],Temp[128],TravTrie:SaveTrie     get_string(2,Handler,63)     get_string(3,g_Query,4095)         format(Temp,127,"%d|%s",Plugin,Handler)         TravTrieGetHCell(CurTrie,"/savetrie",SaveTrie)     TravTrieSetString(SaveTrie,Temp,g_Query)         return SUCCEEDED } public _ARP_ClassDeleteKey(Plugin,Params) {     if(Params != 2)     {         format(g_Query,4095,"Parameters do not match. Expected: 2, Found: %d",Params)         return UTIL_ARP_ThrowError(AMX_ERR_NATIVE,0,g_Query,Plugin)     }         new TravTrie:ClassNum = TravTrie:get_param(1),Key[64]     get_string(2,Key,63)         if(Key[0] == '/' || Key[0] == '^n' || !Class)         return FAILED         new travTrieIter:Iter = GetTravTrieIterator(g_ClassArray),Cell,Name[64]     while(MoreTravTrie(Iter))     {         ReadTravTrieKey(Iter,Name,63)         ReadTravTrieCell(Iter,Cell)         if(Cell == _:ClassNum)                  break     }     DestroyTravTrieIterator(Iter)         //if(!Name[0])     //  return FAILED         format(g_Query,4095,"DELETE FROM %s WHERE classkey='%s|%s'",g_DataTable,Name,Key)     UTIL_ARP_CleverQuery(g_Plugin,g_SqlHandle,"IgnoreHandle",g_Query)         return TravTrieDeleteKey(ClassNum,Key) }
__________________
Hawk552 is offline
Send a message via AIM to Hawk552
Lt.RAT
Member
Join Date: Sep 2008
Location: Russia Yekaterinburg
Old 05-01-2010 , 15:29   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #15

Quote:
Originally Posted by Hawk552 View Post
The first thing we see is #pragma reqclass "dyn_test".
^_____^
Lt.RAT is offline
Send a message via ICQ to Lt.RAT
Hawk552
AMX Mod X Moderator
Join Date: Aug 2005
Old 05-01-2010 , 17:36   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #16

Quote:
Originally Posted by Lt.RAT View Post
^_____^
Oops, it was "#pragma reqlib" in the example. Dunno what happened there. Fixed.
__________________
Hawk552 is offline
Send a message via AIM to Hawk552
drekes
Veteran Member
Join Date: Jul 2009
Location: Vault 11
Old 05-02-2010 , 18:54   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #17

Quote:
[ style = 0 ] - this is will be covered later

Now, onto style = 1. This style basically forgets about the iPlugin,iParams part of the header, and then assumes the plugin will pass the parameters correctly. This means _half_user_hp would look like:
I see you'r talking about style but i read the code 4 times but can't seem to find it. Is'nt it there or am i blind?
__________________

Quote:
Originally Posted by nikhilgupta345 View Post
You're retarded.
drekes is offline
Send a message via MSN to drekes
wrecked_
Veteran Member
Join Date: Jan 2010
Location: New York (GMT-5)
Old 05-02-2010 , 19:36   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #18

Quote:
Originally Posted by drekes View Post
I see you'r talking about style but i read the code 4 times but can't seem to find it. Is'nt it there or am i blind?
Just use the style he uses. It's generally better.
__________________
[ Paid Requests ]
DO NOT PM ME ABOUT BLOCKMAKER
NO PRIVATE SUPPORT
wrecked_ is offline
drekes
Veteran Member
Join Date: Jul 2009
Location: Vault 11
Old 05-02-2010 , 19:46   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #19

Quote:
Originally Posted by wrecked_ View Post
Just use the style he uses. It's generally better.
Okay, i'll do that
__________________

Quote:
Originally Posted by nikhilgupta345 View Post
You're retarded.
drekes is offline
Send a message via MSN to drekes
V I R U S
Senior Member
Join Date: Jul 2004
Location: Russia / Germany
Old 01-29-2012 , 19:24   Re: [TUT] Dynamic / Fake Natives
Reply With Quote #20

I have a question about returning a local value:


PHP Code:
#include <amxmodx>

new g_iUserID[33];

public 
plugin_init()
register_plugin("Dynamic Native Test - Handler""1.0""Hawk552")

public 
plugin_natives() {
  
register_library("dyn_test")
  
register_native("getid","_getid")
}

// Here some other functions which set the UserID

public _getid(id) {
  return 
g_iUserID[id];

PHP Code:
#include <amxmodx>
#include <dyn_test>

public plugin_init()   
register_plugin("Dynamic Native Test - Caller""1.0""Hawk552")   

public 
client_putinserver(id) {
  
server_print("UserID: %i"getid(id));

PHP Code:
#pragma reqlib "dyn_test"

native getid(id
Sooooo, i can compile this without a single error. The trouble is, that the caller doesn't return a value. It's simple empty.

Some trick?
__________________
V I R U S is offline
Send a message via ICQ to V I R U S
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 13:50.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode