Cleaned up some code, added checks for msgid != 0 (so AMXX doesn't crash mods which don't support text based menus for example)
This commit is contained in:
parent
8c600f90c3
commit
9307994060
367
amxmodx/util.cpp
367
amxmodx/util.cpp
@ -35,237 +35,264 @@
|
|||||||
|
|
||||||
int UTIL_ReadFlags(const char* c)
|
int UTIL_ReadFlags(const char* c)
|
||||||
{
|
{
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
|
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_GetFlags(char* f,int a)
|
void UTIL_GetFlags(char* f,int a)
|
||||||
{
|
{
|
||||||
for(int i='a';i<='z';++i){
|
for(int i='a';i<='z';++i){
|
||||||
if ( a & 1 ) *f++ = i;
|
if ( a & 1 ) *f++ = i;
|
||||||
a >>= 1;
|
a >>= 1;
|
||||||
}
|
}
|
||||||
*f = 0;
|
*f = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warning - don't pass here const string */
|
/* warning - don't pass here const string */
|
||||||
void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
|
void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
|
||||||
{
|
{
|
||||||
char *n = menu;
|
char *n = menu;
|
||||||
char c = 0;
|
char c = 0;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
while ( *n ) {
|
if (!gmsgShowMenu)
|
||||||
a = mlen;
|
return; // some games don't support ShowMenu (Firearms)
|
||||||
if ( a > 175 ) a = 175;
|
|
||||||
mlen -= a;
|
while ( *n ) {
|
||||||
c = *(n+=a);
|
a = mlen;
|
||||||
*n = 0;
|
if ( a > 175 ) a = 175;
|
||||||
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
|
mlen -= a;
|
||||||
WRITE_SHORT( slots );
|
c = *(n+=a);
|
||||||
WRITE_CHAR( time );
|
*n = 0;
|
||||||
WRITE_BYTE( c ? TRUE : FALSE);
|
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
|
||||||
WRITE_STRING( menu );
|
WRITE_SHORT( slots );
|
||||||
MESSAGE_END();
|
WRITE_CHAR( time );
|
||||||
*n = c;
|
WRITE_BYTE( c ? TRUE : FALSE);
|
||||||
menu = n;
|
WRITE_STRING( menu );
|
||||||
}
|
MESSAGE_END();
|
||||||
|
*n = c;
|
||||||
|
menu = n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warning - don't pass here const string */
|
/* warning - don't pass here const string */
|
||||||
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
|
||||||
{
|
{
|
||||||
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
if (!gmsgServerName)
|
||||||
WRITE_STRING(name);
|
return; // :TODO: Maybe output a warning log?
|
||||||
MESSAGE_END();
|
|
||||||
|
|
||||||
char *n = motd;
|
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
|
||||||
char c = 0;
|
WRITE_STRING(name);
|
||||||
int a;
|
MESSAGE_END();
|
||||||
|
|
||||||
while ( *n ) {
|
char *n = motd;
|
||||||
a = mlen;
|
char c = 0;
|
||||||
if ( a > 175 ) a = 175;
|
int a;
|
||||||
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 );
|
while ( *n ) {
|
||||||
WRITE_STRING( hostname->string );
|
a = mlen;
|
||||||
MESSAGE_END();
|
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)
|
void UTIL_IntToString(int value, char *output)
|
||||||
{
|
{
|
||||||
static const char *words[] = {"zero ","one ","two ","three ","four ",
|
static const char *words[] = {"zero ","one ","two ","three ","four ",
|
||||||
"five ", "six ","seven ","eight ","nine ","ten ",
|
"five ", "six ","seven ","eight ","nine ","ten ",
|
||||||
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
|
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
|
||||||
"sixteen ","seventeen ","eighteen ","nineteen ",
|
"sixteen ","seventeen ","eighteen ","nineteen ",
|
||||||
"twenty ","thirty ","fourty ", "fifty ","sixty ",
|
"twenty ","thirty ","fourty ", "fifty ","sixty ",
|
||||||
"seventy ","eighty ","ninety ",
|
"seventy ","eighty ","ninety ",
|
||||||
"hundred ","thousand "};
|
"hundred ","thousand "};
|
||||||
*output = 0;
|
*output = 0;
|
||||||
if (value < 0) value = -value;
|
if (value < 0) value = -value;
|
||||||
int tho = value / 1000;
|
int tho = value / 1000;
|
||||||
int aaa = 0;
|
int aaa = 0;
|
||||||
if (tho){
|
if (tho){
|
||||||
aaa += sprintf(&output[aaa], words[ tho ] );
|
aaa += sprintf(&output[aaa], words[ tho ] );
|
||||||
aaa += sprintf(&output[aaa], words[29] );
|
aaa += sprintf(&output[aaa], words[29] );
|
||||||
value = value % 1000;
|
value = value % 1000;
|
||||||
}
|
}
|
||||||
int hun = value / 100;
|
int hun = value / 100;
|
||||||
if (hun) {
|
if (hun) {
|
||||||
aaa += sprintf(&output[aaa], words[ hun ] );
|
aaa += sprintf(&output[aaa], words[ hun ] );
|
||||||
aaa += sprintf(&output[aaa], words[28] );
|
aaa += sprintf(&output[aaa], words[28] );
|
||||||
value = value % 100;
|
value = value % 100;
|
||||||
}
|
}
|
||||||
int ten = value / 10;
|
int ten = value / 10;
|
||||||
int unit = value % 10;
|
int unit = value % 10;
|
||||||
if ( ten )
|
if ( ten )
|
||||||
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
|
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
|
||||||
if ( ten != 1 && ( unit || (!value && !hun && !tho) ) )
|
if ( ten != 1 && ( unit || (!value && !hun && !tho) ) )
|
||||||
sprintf(&output[aaa], words[ unit ] );
|
sprintf(&output[aaa], words[ unit ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
char* UTIL_SplitHudMessage(const char *src)
|
char* UTIL_SplitHudMessage(const char *src)
|
||||||
{
|
{
|
||||||
static char message[512];
|
static char message[512];
|
||||||
short b = 0, d = 0, e = 0, c = -1;
|
short b = 0, d = 0, e = 0, c = -1;
|
||||||
|
|
||||||
while ( src[ d ] && e < 480 ) {
|
while ( src[ d ] && e < 480 ) {
|
||||||
if ( src[ d ] == ' ' ) {
|
if ( src[ d ] == ' ' ) {
|
||||||
c = e;
|
c = e;
|
||||||
}
|
}
|
||||||
else if ( src[ d ] == '\n' ) {
|
else if ( src[ d ] == '\n' ) {
|
||||||
c = -1;
|
c = -1;
|
||||||
b = 0;
|
b = 0;
|
||||||
}
|
}
|
||||||
message[ e++ ] = src[ d++ ];
|
message[ e++ ] = src[ d++ ];
|
||||||
if ( ++b == 69 ) {
|
if ( ++b == 69 ) {
|
||||||
if ( c == -1 ) {
|
if ( c == -1 ) {
|
||||||
message[ e++ ] = '\n';
|
message[ e++ ] = '\n';
|
||||||
b = 0;
|
b = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message[ c ] = '\n';
|
message[ c ] = '\n';
|
||||||
b = e - c - 1;
|
b = e - c - 1;
|
||||||
c = -1;
|
c = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message[ e ] = 0;
|
message[ e ] = 0;
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short FixedUnsigned16( float value, float scale )
|
unsigned short FixedUnsigned16( float value, float scale )
|
||||||
{
|
{
|
||||||
int output = (int)(value * scale);
|
int output = (int)(value * scale);
|
||||||
|
|
||||||
if ( output < 0 )
|
if ( output < 0 )
|
||||||
output = 0;
|
output = 0;
|
||||||
else if ( output > 0xFFFF )
|
else if ( output > 0xFFFF )
|
||||||
output = 0xFFFF;
|
output = 0xFFFF;
|
||||||
|
|
||||||
return (unsigned short)output;
|
return (unsigned short)output;
|
||||||
}
|
}
|
||||||
|
|
||||||
short FixedSigned16( float value, float scale )
|
short FixedSigned16( float value, float scale )
|
||||||
{
|
{
|
||||||
int output = (int)(value * scale);
|
int output = (int)(value * scale);
|
||||||
|
|
||||||
if ( output > 32767 )
|
if ( output > 32767 )
|
||||||
output = 32767;
|
output = 32767;
|
||||||
else if ( output < -32768 )
|
else if ( output < -32768 )
|
||||||
output = -32768;
|
output = -32768;
|
||||||
|
|
||||||
return (short)output;
|
return (short)output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
|
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
|
||||||
{
|
{
|
||||||
if ( pEntity )
|
if ( pEntity )
|
||||||
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity );
|
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity );
|
||||||
else
|
else
|
||||||
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
|
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
|
||||||
|
|
||||||
WRITE_BYTE(29);
|
WRITE_BYTE(29);
|
||||||
WRITE_BYTE(textparms.channel & 0xFF);
|
WRITE_BYTE(textparms.channel & 0xFF);
|
||||||
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) ));
|
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) ));
|
||||||
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) ));
|
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) ));
|
||||||
WRITE_BYTE(textparms.effect);
|
WRITE_BYTE(textparms.effect);
|
||||||
WRITE_BYTE(textparms.r1);
|
WRITE_BYTE(textparms.r1);
|
||||||
WRITE_BYTE(textparms.g1);
|
WRITE_BYTE(textparms.g1);
|
||||||
WRITE_BYTE(textparms.b1);
|
WRITE_BYTE(textparms.b1);
|
||||||
WRITE_BYTE(0);
|
WRITE_BYTE(0);
|
||||||
WRITE_BYTE(255);
|
WRITE_BYTE(255);
|
||||||
WRITE_BYTE(255);
|
WRITE_BYTE(255);
|
||||||
WRITE_BYTE(250);
|
WRITE_BYTE(250);
|
||||||
WRITE_BYTE(0);
|
WRITE_BYTE(0);
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
|
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
|
||||||
if (textparms.effect==2)
|
if (textparms.effect==2)
|
||||||
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
|
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
|
||||||
WRITE_STRING(pMessage);
|
WRITE_STRING(pMessage);
|
||||||
MESSAGE_END();
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* warning - buffer of msg must be longer than 190 chars!
|
/* 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 )
|
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg )
|
||||||
{
|
{
|
||||||
char c = msg[190];
|
if (!gmsgTextMsg)
|
||||||
msg[190] = 0; // truncate without checking with strlen()
|
return; // :TODO: Maybe output a warning log?
|
||||||
if ( pEntity )
|
|
||||||
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
|
char c = msg[190];
|
||||||
else
|
msg[190] = 0; // truncate without checking with strlen()
|
||||||
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
|
if ( pEntity )
|
||||||
WRITE_BYTE( msg_dest );
|
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
|
||||||
WRITE_STRING( msg );
|
else
|
||||||
MESSAGE_END();
|
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
|
||||||
msg[190] = c;
|
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) {
|
// UTIL_FakeClientCommand
|
||||||
if (!cmd) return;
|
// PURPOSE: Sends a fake client command to GameDLL
|
||||||
//strncpy(g_fakecmd.argv[0], cmd, 127 );
|
// HOW DOES IT WORK:
|
||||||
//g_fakecmd.argv[0][ 127 ] = 0;
|
// 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;
|
g_fakecmd.argv[0] = cmd;
|
||||||
if (arg2){
|
// if only arg2 is passed, swap the arguments
|
||||||
g_fakecmd.argc = 3;
|
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[1] = arg1;
|
||||||
g_fakecmd.argv[2] = arg2;
|
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;
|
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){
|
else if (arg1)
|
||||||
g_fakecmd.argc = 2;
|
{ // only one argument passed
|
||||||
|
g_fakecmd.argc = 2; // 1 argument + 1 command
|
||||||
|
// store argument
|
||||||
g_fakecmd.argv[1] = arg1;
|
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;
|
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
|
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;
|
g_fakecmd.fake = true;
|
||||||
|
// tell the GameDLL that the client sent a command
|
||||||
MDLL_ClientCommand(pEdict);
|
MDLL_ClientCommand(pEdict);
|
||||||
|
// unset the global "fake" flag
|
||||||
g_fakecmd.fake = false;
|
g_fakecmd.fake = false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user