From 9307994060b27ee502a79a016277be2ea259afb0 Mon Sep 17 00:00:00 2001 From: Pavol Marko Date: Fri, 28 May 2004 11:29:44 +0000 Subject: [PATCH] Cleaned up some code, added checks for msgid != 0 (so AMXX doesn't crash mods which don't support text based menus for example) --- amxmodx/util.cpp | 367 +++++++++++++++++++++++++---------------------- 1 file changed, 197 insertions(+), 170 deletions(-) diff --git a/amxmodx/util.cpp b/amxmodx/util.cpp index 42332f02..113f4bae 100755 --- a/amxmodx/util.cpp +++ b/amxmodx/util.cpp @@ -35,237 +35,264 @@ int UTIL_ReadFlags(const char* c) { - int flags = 0; - while (*c) flags |= ( 1 << ( *c++ - 'a' ) ); - return flags; + int flags = 0; + while (*c) flags |= ( 1 << ( *c++ - 'a' ) ); + return flags; } void UTIL_GetFlags(char* f,int a) { - for(int i='a';i<='z';++i){ - if ( a & 1 ) *f++ = i; - a >>= 1; - } - *f = 0; + for(int i='a';i<='z';++i){ + if ( a & 1 ) *f++ = i; + a >>= 1; + } + *f = 0; } /* warning - don't pass here const string */ void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen ) { - char *n = menu; - char c = 0; - int a; + char *n = menu; + char c = 0; + int a; - while ( *n ) { - a = mlen; - if ( a > 175 ) a = 175; - mlen -= a; - c = *(n+=a); - *n = 0; - MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict ); - WRITE_SHORT( slots ); - WRITE_CHAR( time ); - WRITE_BYTE( c ? TRUE : FALSE); - WRITE_STRING( menu ); - MESSAGE_END(); - *n = c; - menu = n; - } + if (!gmsgShowMenu) + return; // some games don't support ShowMenu (Firearms) + + while ( *n ) { + a = mlen; + if ( a > 175 ) a = 175; + mlen -= a; + c = *(n+=a); + *n = 0; + MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict ); + WRITE_SHORT( slots ); + WRITE_CHAR( time ); + WRITE_BYTE( c ? TRUE : FALSE); + WRITE_STRING( menu ); + MESSAGE_END(); + *n = c; + menu = n; + } } /* warning - don't pass here const string */ void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name) { - MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client ); - WRITE_STRING(name); - MESSAGE_END(); + if (!gmsgServerName) + return; // :TODO: Maybe output a warning log? - char *n = motd; - char c = 0; - int a; + MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client ); + WRITE_STRING(name); + MESSAGE_END(); - while ( *n ) { - a = mlen; - if ( a > 175 ) a = 175; - mlen -= a; - c = *(n+=a); - *n = 0; - MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client ); - WRITE_BYTE( c ? FALSE : TRUE ); - WRITE_STRING( motd ); - MESSAGE_END(); - *n = c; - motd = n; - } + char *n = motd; + char c = 0; + int a; - MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client ); - WRITE_STRING( hostname->string ); - MESSAGE_END(); + while ( *n ) { + a = mlen; + if ( a > 175 ) a = 175; + mlen -= a; + c = *(n+=a); + *n = 0; + MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client ); + WRITE_BYTE( c ? FALSE : TRUE ); + WRITE_STRING( motd ); + MESSAGE_END(); + *n = c; + motd = n; + } + + MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client ); + WRITE_STRING( hostname->string ); + MESSAGE_END(); } void UTIL_IntToString(int value, char *output) { - static const char *words[] = {"zero ","one ","two ","three ","four ", - "five ", "six ","seven ","eight ","nine ","ten ", - "eleven ","twelve ","thirteen ","fourteen ","fifteen ", - "sixteen ","seventeen ","eighteen ","nineteen ", - "twenty ","thirty ","fourty ", "fifty ","sixty ", - "seventy ","eighty ","ninety ", - "hundred ","thousand "}; - *output = 0; - if (value < 0) value = -value; - int tho = value / 1000; - int aaa = 0; - if (tho){ - aaa += sprintf(&output[aaa], words[ tho ] ); - aaa += sprintf(&output[aaa], words[29] ); - value = value % 1000; - } - int hun = value / 100; - if (hun) { - aaa += sprintf(&output[aaa], words[ hun ] ); - aaa += sprintf(&output[aaa], words[28] ); - value = value % 100; - } - int ten = value / 10; - int unit = value % 10; - if ( ten ) - aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] ); - if ( ten != 1 && ( unit || (!value && !hun && !tho) ) ) - sprintf(&output[aaa], words[ unit ] ); + static const char *words[] = {"zero ","one ","two ","three ","four ", + "five ", "six ","seven ","eight ","nine ","ten ", + "eleven ","twelve ","thirteen ","fourteen ","fifteen ", + "sixteen ","seventeen ","eighteen ","nineteen ", + "twenty ","thirty ","fourty ", "fifty ","sixty ", + "seventy ","eighty ","ninety ", + "hundred ","thousand "}; + *output = 0; + if (value < 0) value = -value; + int tho = value / 1000; + int aaa = 0; + if (tho){ + aaa += sprintf(&output[aaa], words[ tho ] ); + aaa += sprintf(&output[aaa], words[29] ); + value = value % 1000; + } + int hun = value / 100; + if (hun) { + aaa += sprintf(&output[aaa], words[ hun ] ); + aaa += sprintf(&output[aaa], words[28] ); + value = value % 100; + } + int ten = value / 10; + int unit = value % 10; + if ( ten ) + aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] ); + if ( ten != 1 && ( unit || (!value && !hun && !tho) ) ) + sprintf(&output[aaa], words[ unit ] ); } char* UTIL_SplitHudMessage(const char *src) { - static char message[512]; - short b = 0, d = 0, e = 0, c = -1; + static char message[512]; + short b = 0, d = 0, e = 0, c = -1; - while ( src[ d ] && e < 480 ) { - if ( src[ d ] == ' ' ) { - c = e; - } - else if ( src[ d ] == '\n' ) { - c = -1; - b = 0; - } - message[ e++ ] = src[ d++ ]; - if ( ++b == 69 ) { - if ( c == -1 ) { - message[ e++ ] = '\n'; - b = 0; - } - else { - message[ c ] = '\n'; - b = e - c - 1; - c = -1; - } - } - } - message[ e ] = 0; - return message; + while ( src[ d ] && e < 480 ) { + if ( src[ d ] == ' ' ) { + c = e; + } + else if ( src[ d ] == '\n' ) { + c = -1; + b = 0; + } + message[ e++ ] = src[ d++ ]; + if ( ++b == 69 ) { + if ( c == -1 ) { + message[ e++ ] = '\n'; + b = 0; + } + else { + message[ c ] = '\n'; + b = e - c - 1; + c = -1; + } + } + } + message[ e ] = 0; + return message; } unsigned short FixedUnsigned16( float value, float scale ) { - int output = (int)(value * scale); + int output = (int)(value * scale); - if ( output < 0 ) - output = 0; - else if ( output > 0xFFFF ) - output = 0xFFFF; + if ( output < 0 ) + output = 0; + else if ( output > 0xFFFF ) + output = 0xFFFF; - return (unsigned short)output; + return (unsigned short)output; } short FixedSigned16( float value, float scale ) { - int output = (int)(value * scale); + int output = (int)(value * scale); - if ( output > 32767 ) - output = 32767; - else if ( output < -32768 ) - output = -32768; + if ( output > 32767 ) + output = 32767; + else if ( output < -32768 ) + output = -32768; - return (short)output; + return (short)output; } void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage) { - if ( pEntity ) - MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity ); - else - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); + if ( pEntity ) + MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity ); + else + MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE(29); - WRITE_BYTE(textparms.channel & 0xFF); - WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) )); - WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) )); - WRITE_BYTE(textparms.effect); - WRITE_BYTE(textparms.r1); - WRITE_BYTE(textparms.g1); - WRITE_BYTE(textparms.b1); - WRITE_BYTE(0); - WRITE_BYTE(255); - WRITE_BYTE(255); - WRITE_BYTE(250); - WRITE_BYTE(0); - WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) )); - WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) )); - WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) )); - if (textparms.effect==2) - WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) ); - WRITE_STRING(pMessage); - MESSAGE_END(); + WRITE_BYTE(29); + WRITE_BYTE(textparms.channel & 0xFF); + WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) )); + WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) )); + WRITE_BYTE(textparms.effect); + WRITE_BYTE(textparms.r1); + WRITE_BYTE(textparms.g1); + WRITE_BYTE(textparms.b1); + WRITE_BYTE(0); + WRITE_BYTE(255); + WRITE_BYTE(255); + WRITE_BYTE(250); + WRITE_BYTE(0); + WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) )); + WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) )); + WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) )); + if (textparms.effect==2) + WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) ); + WRITE_STRING(pMessage); + MESSAGE_END(); } /* warning - buffer of msg must be longer than 190 chars! - (here in AMX it is always longer) */ +(here in AMX it is always longer) */ void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg ) { - char c = msg[190]; - msg[190] = 0; // truncate without checking with strlen() - if ( pEntity ) - MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity ); - else - MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg); - WRITE_BYTE( msg_dest ); - WRITE_STRING( msg ); - MESSAGE_END(); - msg[190] = c; + if (!gmsgTextMsg) + return; // :TODO: Maybe output a warning log? + + char c = msg[190]; + msg[190] = 0; // truncate without checking with strlen() + if ( pEntity ) + MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity ); + else + MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg); + WRITE_BYTE( msg_dest ); + WRITE_STRING( msg ); + MESSAGE_END(); + msg[190] = c; } -void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2) { - if (!cmd) return; - //strncpy(g_fakecmd.argv[0], cmd, 127 ); - //g_fakecmd.argv[0][ 127 ] = 0; +// UTIL_FakeClientCommand +// PURPOSE: Sends a fake client command to GameDLL +// HOW DOES IT WORK: +// 1) Stores command and arguments into a global and sets the global "fake" flag to true +// 2) Invokes ClientCommand in GameDLL +// 3) meta_api.cpp overrides Cmd_Args, Cmd_Argv, Cmd_Argc and gives them fake values if the "fake" flag is set +// 4) unsets the global "fake" flag +void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1, const char *arg2) +{ + if (!cmd) + return; // no command + + // store command g_fakecmd.argv[0] = cmd; - if (arg2){ - g_fakecmd.argc = 3; + // if only arg2 is passed, swap the arguments + if (!arg1 && arg2) + { + arg1 = arg2; + arg2 = NULL; + } + + // store arguments + if (arg2) + { // both arguments passed + g_fakecmd.argc = 3; // 2 arguments + 1 command + // store arguments g_fakecmd.argv[1] = arg1; g_fakecmd.argv[2] = arg2; - snprintf( g_fakecmd.args ,255 , "%s %s",arg1,arg2 ); + // build argument line + snprintf(g_fakecmd.args, 255, "%s %s", arg1, arg2); + // if snprintf reached 255 chars limit, this will make sure there will be no access violation g_fakecmd.args[255] = 0; - //strncpy(g_fakecmd.argv[1], arg1 , 127 ); - //g_fakecmd.argv[1][ 127 ] = 0; - //strncpy(g_fakecmd.argv[2], arg2 , 127 ); - //g_fakecmd.argv[2][ 127 ] = 0; - //snprintf(g_fakecmd.args, 255 , "%s %s",arg1,arg2); - //g_fakecmd.args[255] = 0; } - else if (arg1){ - g_fakecmd.argc = 2; + else if (arg1) + { // only one argument passed + g_fakecmd.argc = 2; // 1 argument + 1 command + // store argument g_fakecmd.argv[1] = arg1; - snprintf( g_fakecmd.args ,255 , "%s" , arg1 ); + // build argument line + snprintf( g_fakecmd.args, 255, "%s", arg1); + // if snprintf reached 255 chars limit, this will make sure there will be no access violation g_fakecmd.args[255] = 0; - //strncpy(g_fakecmd.argv[1], arg1, 127 ); - //g_fakecmd.argv[1][ 127 ] = 0; - //*g_fakecmd.argv[2] = 0; - //snprintf(g_fakecmd.args, 255 ,"%s",arg1); - //g_fakecmd.args[255] = 0; } else - g_fakecmd.argc = 1; + g_fakecmd.argc = 1; // no argmuents -> only one command + + // set the global "fake" flag so the Cmd_Arg* functions will be superceded g_fakecmd.fake = true; + // tell the GameDLL that the client sent a command MDLL_ClientCommand(pEdict); + // unset the global "fake" flag g_fakecmd.fake = false; }