AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   callfunc_push_str(string, true) only return single letter (https://forums.alliedmods.net/showthread.php?t=189454)

Liverwiz 07-07-2012 11:27

callfunc_push_str(string, true) only return single letter
 
Why? Here's my code....in an API where the core asks an extension for a string, gives it the string buffer and max length, then the function returns it in that buffer. But it only seems to be returning a single letter. Does anyone know why?

Core calling function.....
PHP Code:

public setHud(id)
{
        
// Set Powerups Message on HUD
    // Variables for controlling the HUD message
    
new pus[90], RGB[3]
    
//new const pus[] = "This woks, yes?"
    // X location for HUD, Y location for HUD, DURATION of message
    
const Float:0.26
    
const Float:0.9
    
const Float:duration 10.0
    
    
if( !getColor(pucolor_pcvarRGB) )
    {
        
RGB[0] = 10
        RGB
[1] = 10
        RGB
[2] = 10
    
}
    
set_hudmessage(RGB[0], RGB[1], RGB[2], XY01.0duration0.10.2, .channel=1)
    
//formatex(pus, charsmax(pus), "%L:", id, "PU_STD", level)
    //client_print(id, print_chat, "Set Powers has been executed. This is number 2. Your level: %d", level)
    
new level getLevel(id)
    switch(
level)
    {
        case -
1
        {
            
client_print(idprint_chat"Your level has been executed as -1. Level: %d"level)
            return 
PLUGIN_HANDLED    // this is error state of client
        
}
        case 
0
        {
            
formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_LOW")
            
client_print(idprint_chat"Set Powers has been executed. This is level 0.")
        }
        case 
1formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_NORMAL")
        case 
2:
        {    
// Run faster
            
formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_SPEED")
        }
        case 
3:
        {    
// jump higher
            
formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_GRAVITY")
        }
        case 
4formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_DAMAGE")
        
// case 5: power ups
    #if defined INSTAKILL
        
case INSTAKILL:
        {
            
client_print(idprint_chat"You have instakill!")
            
formatex(puscharsmax(pus), "Powers{level %d): %L"levelid"PU_INSTAKILL")
        }
    
#endif
        
default: 
        {
        
#if defined INSTAKILL
            
if(level INSTAKILL)
                
formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_DAMAGE")
            else 
//(level > INSTAKILL
                
formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_INSTAKILL")
        
#else
            
formatex(puscharsmax(pus), "%L: %L"id"PU_STD"levelid"PU_DAMAGE")
        
#endif
        
}
    }
    
        
// This is where i call all extensions to retrieve their powers string.
        // Each string must then be added to the 'pus' string and displayed on the HUD
    /*new retVal
    if( !ExecuteForward(g_hudFwd, retVal, id ,g_PowerHud, pus, charsmax(pus)) )
    {
        ShowSyncHudMsg(id, g_PowerHud, pus)    // show hud message of powers
        log_amx("[BKF] bkf_setHud was not fired properly.")
    }
    else if(!retVal)
    {
        ShowSyncHudMsg(id, g_PowerHud, pus)
        client_print(id, print_chat, "bkf_setHud returned 0")
    }*/
    //else
        //ShowSyncHudMsg(id, g_PowerHud, pus)
    
new func[64], plugin[32], powerName[16]
    for(new 
0ArraySize(g_hudFuncs); i++)
    {
        
ArrayGetString(g_hudFuncsifunccharsmax(func) )
        
strtok(funcfunccharsmax(func), plugincharsmax(plugin), '.')
        
        
callfunc_begin(funcplugin)
        
callfunc_push_int(id)
        
callfunc_push_str(powerNametrue)
        
callfunc_push_int(15)
        if(
callfunc_end() )
            
format(puscharsmax(pus), "%s, %s"puspowerName)
        else        
// This just says when the extension didn't add strings
            
formatex(puscharsmax(pus), "%s, Vulgar Obscenities of Frustration."pus)
            
        
client_print(idprint_chatpowerName)
    }
        
    
ShowSyncHudMsg(idg_PowerHudpus)
    return 
PLUGIN_CONTINUE


Extension.....
Code:
public bkf_setHud(id, input[], len) {     static PowerClass:pwr     pwr = powers[id]     client_print(id, print_chat, "setHud executed.")     switch(pwr)     {         case PC_DAMAGE:         {             formatex(input, len, "Extra Damage")             return 1         }         case PC_HEALTH:         {             formatex(input, len, "Health Regenration")             return 1         }         case PC_SPEED:         {             formatex(input, len, "Constant Speed")             return 1         }         case PC_GRAVITY:         {             formatex(input, len, "Constant Gravity")             return 1         }         case PC_SILENT:         {             formatex(input, len, "Silent Run")             client_print(id, print_chat, input)             //ShowSyncHudMsg(id, hud, "%s, Silent Run", input)             return 1         }         default:         {             client_print(id, print_chat, "Default hud executed.")                     }     }     client_print(id, print_chat, "setHud executed. END")     return 0 }

I know it runs properly because the prints are displayed and the first letters are correct. Its just a single letter, not the whole string. I've been diong it mostly with PC_SILENT, which shows that Silent Run IS in the input string. But then when it returns and goes back to the core the string only shows as 'S'. Is this limitations in the engine or bugs in my code?

NOTE: i used a hardcoded 15 as the length for debug purposes. Wondering if charsmax was causing the problem. It wasn't. Just haven't changed it back yet.
Before anyone tries to "improve" it.

ConnorMcLeod 07-07-2012 11:57

Re: callfunc_push_str(string, true) only return single letter
 
When you code an api, don't use call_func, use dynamic natives.
call_func_X are more when you wan't to add some support to an existing plugin that has already been released.

Liverwiz 07-07-2012 12:02

Re: callfunc_push_str(string, true) only return single letter
 
Quote:

Originally Posted by ConnorMcLeod (Post 1745400)
When you code an api, don't use call_func, use dynamic natives.
call_func_X are more when you wan't to add some support to an existing plugin that has already been released.

Dynamic natives do not return strings in the manner in which i wish them to. That is why i used callfunc. That and i'm amused by my use of dynamic arrays and how i did this. But, really, if i can't figure it out i'll go back to natives because they ARE easier.

ConnorMcLeod 07-07-2012 15:04

Re: callfunc_push_str(string, true) only return single letter
 
Dynamic natives are more efficient, and appropriated for what you are doing. Forget callfunc !!

Liverwiz 07-07-2012 23:11

Re: callfunc_push_str(string, true) only return single letter
 
Quote:

Originally Posted by ConnorMcLeod (Post 1745519)
Dynamic natives are more efficient, and appropriated for what you are doing. Forget callfunc !!

I'm aware dynamic natives are more efficient and appropriate, that is why i tried them first. But how would you suggest i set up a dynamic native for the string to go back to the core, so the core can handle everything. This is especially important if i have more than one extension adding more than one hud string. THIS is the case that i'm trying to account for.

EDIT: This is how i set up the dynamic native (my original design) but it didn't do what i wished for it to, though did what i needed successfully.

PHP Code:

new g_hudFwd
// init
    
g_hudFwd CreateMultiForward("bkf_setHud"ET_CONTINUEFP_CELLFP_CELLFP_STRINGFP_CELL)

// calling function
new retVal
    
if( !ExecuteForward(g_hudFwdretValid ,g_PowerHudpuscharsmax(pus)) )
    {
        
ShowSyncHudMsg(idg_PowerHudpus)    // show hud message of powers
        
log_amx("[BKF] bkf_setHud was not fired properly.")
    }
    else if(!
retVal)
    {
        
ShowSyncHudMsg(idg_PowerHudpus)
        
client_print(idprint_chat"bkf_setHud returned 0")
    } 


hornet 07-08-2012 02:18

Re: callfunc_push_str(string, true) only return single letter
 
Quote:

Originally Posted by Liverwiz (Post 1745776)
I'm aware dynamic natives are more efficient and appropriate, that is why i tried them first. But how would you suggest i set up a dynamic native for the string to go back to the core, so the core can handle everything.

I can't really see enough info to re-write your snippet to accommodate dynamic natives, so instead I'll write you a quick example on how you can return a string from a dynamic native, of course after registering it and defining it as a native.
Code:
//Core plugin sends native new iMessageNum = 0; new szOutput[ 32 ]; MyStringFunction( iMessageNum, szOutput, charsmax( szOutput) );
Code:
new const MyStrings[][] = {     "Some text",     "Some more text",     "more and more" } //Sub plugin sends string back public _MyStringFunction( iPlugin, iParams ) {     new iMessageNum = get_param( 1 );     new iCharsMax = get_param( 3 );         //2 is the argument to return the string to     return set_string( 2, MyStrings[ iMessageNum ], iCharsMax ); }
Code:
//test your message client_print( id, print_chat, "Message return: %s", szOutput ); //You get - "Message return: Some text"   ( w/o quotes )

ConnorMcLeod 07-08-2012 05:10

Re: callfunc_push_str(string, true) only return single letter
 
Last arg of your forward is not required, you should only pass the string, not the array size.

hornet 07-08-2012 09:39

Re: callfunc_push_str(string, true) only return single letter
 
Quote:

Originally Posted by ConnorMcLeod (Post 1745908)
Last arg of your forward is not required, you should only pass the string, not the array size.

But then wouldn't you risk getting a stack error if your return string is larger than the output string specified when the native is first sent?

Liverwiz 07-08-2012 09:56

Re: callfunc_push_str(string, true) only return single letter
 
Quote:

Originally Posted by hornet (Post 1745862)
I can't really see enough info to re-write your snippet to accommodate dynamic natives, so instead I'll write you a quick example on how you can return a string from a dynamic native, of course after registering it and defining it as a native.

:oops: I confused forward with dynamic native.
EDIT: But still, how would i have multiple extensions sending strings back to the core to be displayed?
I'll update my first post's code to show more of what i'm doing.

Quote:

Originally Posted by hornet (Post 1746044)
Quote:

Originally Posted by ConnorMcLeod (Post 1745908)
Last arg of your forward is not required, you should only pass the string, not the array size.

But then wouldn't you risk getting a stack error if your return string is larger than the output string specified when the native is first sent?

That is my concern as well....because when i've tried using charsmax on a string after a forward (considering a native as a forward in this context because it gets pushed through the engine on call) it throws compilation errors.
EDIT: Connor talking about in your example, hornet. Which, no, you don't need to send lengths because it is constant and you're not manipulating a string. But if you're working with actual non-static strings, yes, i do believe you should send lengths in params.

hornet 07-08-2012 10:32

Re: callfunc_push_str(string, true) only return single letter
 
Quote:

Originally Posted by Liverwiz (Post 1746050)
:oops: I confused forward with dynamic native.
EDIT: But still, how would i have multiple extensions sending strings back to the core to be displayed?

Exactly how I showed you?

Quote:

That is my concern as well....because when i've tried using charsmax on a string after a forward (considering a native as a forward in this context because it gets pushed through the engine on call) it throws compilation errors.
I was referring to ingame errors.

Quote:

EDIT: Connor talking about in your example, hornet. Which, no, you don't need to send lengths because it is constant and you're not manipulating a string. But if you're working with actual non-static strings, yes, i do believe you should send lengths in params.
Without the length, the string will have to fit the output size array. Otherwise, it should work fine, but you'll still get a memory access error.


All times are GMT -4. The time now is 15:05.

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