new message system and string class

This commit is contained in:
David Anderson 2005-07-22 09:26:37 +00:00
parent 99f65175ff
commit 191824d72a
4 changed files with 291 additions and 313 deletions

View File

@ -39,9 +39,7 @@ public:
String() String()
{ {
v = NULL; v = NULL;
mSize = 0; a_size = 0;
cSize = 0;
Grow(2);
assign(""); assign("");
} }
@ -54,41 +52,38 @@ public:
String(const char *src) String(const char *src)
{ {
v = NULL; v = NULL;
mSize = 0; a_size = 0;
cSize = 0; assign(src); assign(src);
} }
String(String &src) String(String &src)
{ {
v = NULL; v = NULL;
mSize = 0; a_size = 0;
cSize = 0;
assign(src.c_str()); assign(src.c_str());
} }
const char *c_str() { return v?v:""; } const char *c_str() { return v; }
const char *c_str() const { return v?v:""; }
const char *c_str() const { return v; }
void append(const char *t) void append(const char *t)
{ {
Grow(cSize + strlen(t) + 1); Grow(strlen(v) + strlen(t) + 1);
strcat(v, t); strcat(v, t);
cSize = strlen(v);
} }
void append(const char c) void append(const char c)
{ {
Grow(cSize + 2); size_t len = strlen(v);
v[cSize] = c; Grow(len + 2);
v[++cSize] = 0; v[len] = c;
v[len + 1] = '\0';
} }
void append(String &d) void append(String &d)
{ {
const char *t = d.c_str(); append(d.c_str());
Grow(cSize + strlen(t));
strcat(v, t);
cSize = strlen(v);
} }
void assign(const String &src) void assign(const String &src)
@ -100,79 +95,51 @@ public:
{ {
if (!d) if (!d)
{ {
Grow(1); clear();
cSize = 0;
strcpy(v, "");
return;
}
Grow(strlen(d));
if (v)
{
strcpy(v, d);
cSize = strlen(v);
} else { } else {
cSize = 0; Grow(strlen(d) + 1, false);
strcpy(v, d);
} }
} }
void clear() void clear()
{ {
if (v) v[0] = '\0';
{
v[0] = 0;
cSize = 0;
}
} }
int compare (const char *d) int compare (const char *d)
{ {
if (v) { return strcmp(v, d);
if (d) {
return strcmp(v, d);
} else {
return strlen(v);
}
} else {
if (d) {
return strlen(d);
} else {
return 0;
}
}
} }
//Added this for amxx inclusion //Added this for amxx inclusion
bool empty() bool empty()
{ {
if (!v || !cSize) if (v[0] == '\0')
return true; return true;
return false; return false;
} }
int size() size_t size()
{ {
if (!v) return strlen(v);
return 0;
return cSize;
} }
const char * _fread(FILE *fp) const char * _fread(FILE *fp)
{ {
Grow(512); Grow(512);
char * ret = fgets(v, 511, fp); char * ret = fgets(v, 511, fp);
cSize = strlen(v);
return ret; return ret;
} }
int find(const char c, int index = 0) int find(const char c, int index = 0)
{ {
if (!v) size_t len = strlen(v);
return npos; if (index >= (int)len || index < 0)
if (index >= (int)cSize || index < 0)
return npos; return npos;
unsigned int i = 0; unsigned int i = 0;
for (i=index; i<cSize; i++) for (i=index; i<(int)len; i++)
{ {
if (v[i] == c) if (v[i] == c)
{ {
@ -197,12 +164,11 @@ public:
void trim() void trim()
{ {
if (!v)
return;
unsigned int i = 0; unsigned int i = 0;
unsigned int j = 0; unsigned int j = 0;
size_t len = strlen(v);
if (cSize == 1) if (len == 1)
{ {
if (is_space(v[i])) if (is_space(v[i]))
{ {
@ -215,9 +181,9 @@ public:
if (is_space(c0)) if (is_space(c0))
{ {
for (i=0; i<cSize; i++) for (i=0; i<len; i++)
{ {
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==cSize-1))) if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
{ {
erase(0, i); erase(0, i);
break; break;
@ -225,16 +191,16 @@ public:
} }
} }
cSize = strlen(v); len = strlen(v);
if (cSize < 1) if (len < 1)
{ {
return; return;
} }
if (is_space(v[cSize-1])) if (is_space(v[len-1]))
{ {
for (i=cSize-1; i>=0; i--) for (i=len-1; i>=0; i--)
{ {
if (!is_space(v[i]) if (!is_space(v[i])
|| (is_space(v[i]) && i==0)) || (is_space(v[i]) && i==0))
@ -246,7 +212,7 @@ public:
} }
} }
if (cSize == 1) if (len == 1)
{ {
if (is_space(v[0])) if (is_space(v[0]))
{ {
@ -256,21 +222,20 @@ public:
} }
} }
String & erase(unsigned int start, int num = npos) void erase(unsigned int start, int num = npos)
{ {
if (!v)
return (*this);
unsigned int i = 0; unsigned int i = 0;
size_t len = size();
//check for bounds //check for bounds
if (num == npos || start+num > cSize-num+1) if (num == npos || start+num > len-num+1)
num = cSize - start; num = len - start;
//do the erasing //do the erasing
bool copyflag = false; bool copyflag = false;
for (i=0; i<cSize; i++) for (i=0; i<len; i++)
{ {
if (i>=start && i<start+num) if (i>=start && i<start+num)
{ {
if (i+num < cSize) if (i+num < len)
{ {
v[i] = v[i+num]; v[i] = v[i+num];
} else { } else {
@ -278,7 +243,7 @@ public:
} }
copyflag = true; copyflag = true;
} else if (copyflag) { } else if (copyflag) {
if (i+num < cSize) if (i+num < len)
{ {
v[i] = v[i+num]; v[i] = v[i+num];
} else { } else {
@ -286,51 +251,45 @@ public:
} }
} }
} }
cSize -= num; len -= num;
v[cSize] = 0; v[len] = 0;
return (*this);
} }
String substr(unsigned int index, int num = npos) String substr(unsigned int index, int num = npos)
{ {
String ns; String ns;
if (index >= cSize || !v) size_t len = size();
if (index >= len || !v)
return ns; return ns;
if (num == npos) if (num == npos)
{ {
num = cSize - index; num = len - index;
} else if (index+num >= cSize) { } else if (index+num >= len) {
num = cSize - index; num = len - index;
} }
unsigned int i = 0, j=0; unsigned int i = 0, j=0;
char *s = new char[cSize+1]; unsigned int nslen = num + 2;
ns.Grow(nslen);
for (i=index; i<index+num; i++) for (i=index; i<index+num; i++)
{ ns.append(v[i]);
s[j++] = v[i];
}
s[j] = 0;
ns.assign(s);
delete [] s;
return ns; return ns;
} }
void toLower() void toLower()
{ {
if (!v)
return;
unsigned int i = 0; unsigned int i = 0;
for (i=0; i<cSize; i++) size_t len = strlen(v);
for (i=0; i<len; i++)
{ {
if (v[i] >= 65 && v[i] <= 90) if (v[i] >= 65 && v[i] <= 90)
v[i] |= 32; v[i] &= ~(1<<5);
} }
} }
@ -349,7 +308,7 @@ public:
char operator [] (unsigned int index) char operator [] (unsigned int index)
{ {
if (index > cSize) if (index > size())
{ {
return -1; return -1;
} else { } else {
@ -359,7 +318,7 @@ public:
int at(int a) int at(int a)
{ {
if (a < 0 || a >= (int)cSize) if (a < 0 || a >= (int)size())
return -1; return -1;
return v[a]; return v[a];
@ -367,7 +326,7 @@ public:
bool at(int at, char c) bool at(int at, char c)
{ {
if (at < 0 || at >= (int)cSize) if (at < 0 || at >= (int)size())
return false; return false;
v[at] = c; v[at] = c;
@ -376,27 +335,20 @@ public:
} }
private: private:
void Grow(unsigned int d) void Grow(unsigned int d, bool copy=true)
{ {
if (d<1) if (d <= a_size)
return; return;
if (d > mSize) char *n = new char[d + 1];
{ if (copy)
mSize = d + 16; // allocate a buffer strcpy(n, v);
char *t = new char[d+1]; delete [] v;
if (v) { v = n;
strcpy(t, v); a_size = d + 1;
t[cSize] = 0;
delete [] v;
}
v = t;
mSize = d;
}
} }
char *v; char *v;
unsigned int mSize; unsigned int a_size;
unsigned int cSize;
public: public:
static const int npos = -1; static const int npos = -1;
}; };

View File

@ -26,7 +26,6 @@ void ClearHooks()
for (i=0; i<Thinks.size(); i++) for (i=0; i<Thinks.size(); i++)
delete Thinks[i]; delete Thinks[i];
Msg.clear();
Touches.clear(); Touches.clear();
Impulses.clear(); Impulses.clear();
Thinks.clear(); Thinks.clear();
@ -226,7 +225,6 @@ void ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{ {
for(int f = 1; f <= gpGlobals->maxClients;f++) for(int f = 1; f <= gpGlobals->maxClients;f++)
g_player_edicts[f]=pEdictList + f; g_player_edicts[f]=pEdictList + f;
Msg.clear();
register int i = 0, j = 0; register int i = 0, j = 0;
for (i=0; i<256; i++) { for (i=0; i<256; i++) {
for (j=0; j<(int)msgHooks[i].size(); j++) for (j=0; j<(int)msgHooks[i].size(); j++)

View File

@ -1,6 +1,6 @@
#include "engine.h" #include "engine.h"
CVector<argMsg> Msg; Message Msg;
CVector<int> msgHooks[256]; CVector<int> msgHooks[256];
int msgBlocks[256] = {0}; int msgBlocks[256] = {0};
int msgDest; int msgDest;
@ -9,83 +9,162 @@ float *msgOrigin;
edict_t *msgpEntity; edict_t *msgpEntity;
bool inhook = false; bool inhook = false;
bool inblock = false; bool inblock = false;
unsigned int msgCount = 0;
argMsg::argMsg() Message::Message()
{ {
Reset(); msgparam *p = new msgparam;
m_Params.push_back(p);
m_CurParam = 0;
} }
void argMsg::Reset() Message::~Message()
{ {
memset(&v, 0, sizeof(v)); for (size_t i=0; i<m_Params.size(); i++)
cData.clear(); delete m_Params[i];
type = 0;
m_Params.clear();
} }
void argMsg::Send() msgparam *Message::AdvPtr()
{ {
switch (type) msgparam *pParam = NULL;
if (++m_CurParam >= m_Params.size())
{ {
case arg_byte: pParam = new msgparam;
WRITE_BYTE(v.iData); m_Params.push_back(pParam);
break; } else {
case arg_char: pParam = m_Params[m_CurParam];
WRITE_CHAR(v.iData);
break;
case arg_short:
WRITE_SHORT(v.iData);
break;
case arg_long:
WRITE_LONG(v.iData);
break;
case arg_angle:
WRITE_ANGLE(v.fData);
break;
case arg_coord:
WRITE_COORD(v.fData);
break;
case arg_string:
WRITE_STRING(cData.c_str());
break;
case arg_entity:
WRITE_ENTITY(v.iData);
break;
}
Reset();
}
int argMsg::Type()
{
switch (type)
{
case arg_byte:
return type_int;
break;
case arg_char:
return type_int;
break;
case arg_short:
return type_int;
break;
case arg_long:
return type_int;
break;
case arg_angle:
return type_float;
break;
case arg_coord:
return type_float;
break;
case arg_string:
return type_string;
break;
case arg_entity:
return type_int;
break;
} }
return 0; return pParam;
}
void Message::AddParam(const char *data, msgtype type)
{
msgparam *pParam = AdvPtr();
pParam->szData.assign(data);
pParam->type = type;
}
void Message::AddParam(int data, msgtype type)
{
msgparam *pParam = AdvPtr();
pParam->v.iData = data;
pParam->type = type;
}
void Message::AddParam(float data, msgtype type)
{
msgparam *pParam = AdvPtr();
pParam->v.fData = data;
pParam->type = type;
}
msgtype Message::GetParamType(size_t index)
{
if (index < 1 || index > m_CurParam)
return static_cast<msgtype>(0);
return m_Params[index]->type;
}
float Message::GetParamFloat(size_t index)
{
if (index < 1 || index > m_CurParam)
return 0;
return m_Params[index]->v.fData;
}
const char *Message::GetParamString(size_t index)
{
if (index < 1 || index > m_CurParam)
return 0;
return m_Params[index]->szData.c_str();
}
int Message::GetParamInt(size_t index)
{
if (index < 1 || index > m_CurParam)
return 0;
return m_Params[index]->v.iData;
}
void Message::SetParam(size_t index, float data)
{
if (index < 1 || index > m_CurParam)
return;
m_Params[index]->v.fData = data;
}
void Message::SetParam(size_t index, int data)
{
if (index < 1 || index > m_CurParam)
return;
m_Params[index]->v.iData = data;
}
void Message::SetParam(size_t index, const char *data)
{
if (index < 1 || index > m_CurParam)
return;
m_Params[index]->szData.assign(data);
}
void Message::Reset()
{
m_CurParam = 0;
}
size_t Message::Params()
{
return m_CurParam;
}
void Message::Send()
{
msgparam *pParam = NULL;
for (size_t i=1; i<=m_CurParam; i++)
{
pParam = m_Params[i];
switch (pParam->type)
{
case arg_byte:
WRITE_BYTE(pParam->v.iData);
break;
case arg_char:
WRITE_CHAR(pParam->v.iData);
break;
case arg_short:
WRITE_SHORT(pParam->v.iData);
break;
case arg_long:
WRITE_LONG(pParam->v.iData);
break;
case arg_angle:
WRITE_ANGLE(pParam->v.fData);
break;
case arg_coord:
WRITE_COORD(pParam->v.fData);
break;
case arg_string:
WRITE_STRING(pParam->szData.c_str());
break;
case arg_entity:
WRITE_ENTITY(pParam->v.iData);
break;
}
}
} }
void MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) void MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
@ -96,7 +175,6 @@ void MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (msgHooks[msg_type].size()) { } else if (msgHooks[msg_type].size()) {
inhook = true; inhook = true;
msgCount = 0;
msgDest = msg_dest; msgDest = msg_dest;
msgType = msg_type; msgType = msg_type;
msgOrigin = (float *)pOrigin; msgOrigin = (float *)pOrigin;
@ -112,15 +190,7 @@ void WriteByte(int iValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(iValue, arg_byte);
argMsg p;
p.v.iData = iValue;
p.type = arg_byte;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.iData = iValue;
Msg[msgCount-1].type = arg_byte;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -132,15 +202,7 @@ void WriteChar(int iValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(iValue, arg_char);
argMsg p;
p.v.iData = iValue;
p.type = arg_char;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.iData = iValue;
Msg[msgCount-1].type = arg_char;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -152,15 +214,7 @@ void WriteShort(int iValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(iValue, arg_short);
argMsg p;
p.v.iData = iValue;
p.type = arg_short;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.iData = iValue;
Msg[msgCount-1].type = arg_short;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -172,15 +226,7 @@ void WriteLong(int iValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(iValue, arg_long);
argMsg p;
p.v.iData = iValue;
p.type = arg_long;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.iData = iValue;
Msg[msgCount-1].type = arg_long;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -192,15 +238,7 @@ void WriteAngle(float flValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(flValue, arg_angle);
argMsg p;
p.v.fData = flValue;
p.type = arg_angle;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.fData = flValue;
Msg[msgCount-1].type = arg_angle;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -212,15 +250,7 @@ void WriteCoord(float flValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(flValue, arg_coord);
argMsg p;
p.v.fData = flValue;
p.type = arg_coord;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.fData = flValue;
Msg[msgCount-1].type = arg_coord;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -232,15 +262,7 @@ void WriteString(const char *sz)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(sz, arg_string);
argMsg p;
p.cData.assign(sz);
p.type = arg_string;
Msg.push_back(p);
} else {
Msg[msgCount-1].cData.assign(sz);
Msg[msgCount-1].type = arg_string;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -252,15 +274,7 @@ void WriteEntity(int iValue)
if (inblock) { if (inblock) {
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} else if (inhook) { } else if (inhook) {
if (++msgCount > Msg.size()) { Msg.AddParam(iValue, arg_entity);
argMsg p;
p.v.iData = iValue;
p.type = arg_entity;
Msg.push_back(p);
} else {
Msg[msgCount-1].v.iData = iValue;
Msg[msgCount-1].type = arg_entity;
}
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -286,16 +300,13 @@ void MessageEnd(void)
inhook = false; inhook = false;
if (mres & 1) if (mres & 1)
{ {
msgCount = 0; Msg.Reset();
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
MESSAGE_BEGIN(msgDest, msgType, msgOrigin, msgpEntity); MESSAGE_BEGIN(msgDest, msgType, msgOrigin, msgpEntity);
for (i=0; i<msgCount; i++) { Msg.Send();
Msg[i].Send();
Msg[i].Reset();
}
MESSAGE_END(); MESSAGE_END();
msgCount = 0; Msg.Reset();
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
@ -350,105 +361,109 @@ static cell AMX_NATIVE_CALL get_msg_block(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params)
{ {
return msgCount; return Msg.Params();
} }
static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
return Msg[argn].type; return Msg.GetParamType(argn);
} }
static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
int iVal = Msg[argn].v.iData; return Msg.GetParamInt(argn);
return iVal;
} }
static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
Msg[argn].type = params[2]; Msg.SetParam(argn, params[2]);
Msg[argn].v.iData = params[3];
return 1; return 1;
} }
static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
return amx_ftoc(Msg[argn].v.fData); return amx_ftoc(Msg.GetParamFloat(argn));
} }
static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
REAL fVal = amx_ctof(params[2]); REAL fVal = amx_ctof(params[2]);
Msg[argn].v.fData = fVal; Msg.SetParam(argn, fVal);
return 1; return 1;
} }
static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
const char *szVal = Msg[argn].cData.c_str(); const char *szVal = Msg.GetParamString(argn);
return MF_SetAmxString(amx, params[2], szVal?szVal:"", params[3]); return MF_SetAmxString(amx, params[2], szVal, params[3]);
} }
static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params)
{ {
unsigned int argn = params[1]-1; size_t argn = static_cast<size_t>(params[1]);
int iLen; int iLen;
if (!inhook || argn >= Msg.size()) { if (!inhook || argn > Msg.Params())
MF_RaiseAmxError(amx, AMX_ERR_NATIVE); {
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0; return 0;
} }
char *szVal = MF_GetAmxString(amx, params[2], 0, &iLen); char *szVal = MF_GetAmxString(amx, params[2], 0, &iLen);
Msg[argn].cData.assign(szVal); Msg.SetParam(argn, szVal);
return 1; return 1;
} }

View File

@ -9,7 +9,8 @@
#define BLOCK_ONCE 1 #define BLOCK_ONCE 1
#define BLOCK_SET 2 #define BLOCK_SET 2
enum { enum msgtype
{
arg_byte = 1, arg_byte = 1,
arg_char, arg_char,
arg_short, arg_short,
@ -20,31 +21,43 @@ enum {
arg_entity, arg_entity,
}; };
enum { struct msgparam
type_int = 1,
type_float,
type_string,
};
class argMsg
{ {
public: msgtype type;
argMsg();
void Reset();
void Send();
int Type();
int type;
union union
{ {
REAL fData; REAL fData;
int iData; int iData;
} v; } v;
String cData; String szData;
};
class Message
{
public:
Message();
~Message();
void AddParam(float data, msgtype type);
void AddParam(int data, msgtype type);
void AddParam(const char *data, msgtype type);
void SetParam(size_t index, float data);
void SetParam(size_t index, int data);
void SetParam(size_t index, const char *data);
const char *GetParamString(size_t index);
float GetParamFloat(size_t index);
int GetParamInt(size_t index);
msgtype GetParamType(size_t index);
void Reset();
void Send();
size_t Params();
private:
msgparam *AdvPtr();
private:
CVector<msgparam *> m_Params;
size_t m_CurParam;
}; };
extern AMX_NATIVE_INFO msg_Natives[]; extern AMX_NATIVE_INFO msg_Natives[];
extern CVector<argMsg> Msg;
extern CVector<int> msgHooks[256]; extern CVector<int> msgHooks[256];
extern int msgBlocks[256]; extern int msgBlocks[256];