1 Commits

Author SHA1 Message Date
5f34f1baaa Tagged 1.60 2006-07-19 20:28:23 +00:00
1227 changed files with 183837 additions and 261198 deletions

View File

@ -124,6 +124,8 @@ CmdMngr::Command* CmdMngr::getCmd(long int id, int type, int access)
int CmdMngr::getCmdNum(int type, int access) int CmdMngr::getCmdNum(int type, int access)
{ {
if ((access == buf_access) && (type == buf_type))
return buf_num; // once calculated don't have to be done again
buf_access = access; buf_access = access;
buf_type = type; buf_type = type;

View File

@ -425,7 +425,7 @@ void EventsMngr::executeEvents()
} }
(*iter).m_Stamp = (float)*m_Timer; (*iter).m_Stamp = (float)*m_Timer;
executeForwards((*iter).m_Func, static_cast<cell>(m_ParseVault ? m_ParseVault[0].iValue : 0)); executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
} }
m_CurrentMsgType = -1; m_CurrentMsgType = -1;

View File

@ -1,413 +0,0 @@
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "sh_list.h"
#include "CString.h"
#include "amxmodx.h"
#include "CFlagManager.h"
void CFlagManager::SetFile(const char *Filename)
{
m_strConfigFile.assign(g_mod_name.c_str());
m_strConfigFile.append("/");
m_strConfigFile.append(get_localinfo("amxx_configsdir","addons/amxmodx/configs"));
m_strConfigFile.append("/");
m_strConfigFile.append(Filename);
CreateIfNotExist();
}
const int CFlagManager::LoadFile(const int force)
{
CheckIfDisabled();
// If we're disabled get the hell out. now.
if (m_iDisabled)
{
return 0;
}
// if we're not forcing this, and NeedToLoad says we dont have to
// then just stop
if (!force && !NeedToLoad())
{
return 0;
};
this->Clear();
// We need to load the file
FILE *File;
File=fopen(m_strConfigFile.c_str(),"r");
if (!File)
{
AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)",m_strConfigFile.c_str());
return -1;
};
// Trying to copy this almost exactly as other configs are read...
String Line;
char Command[256];
char Flags[256];
String TempLine;
while (!feof(File))
{
Line._fread(File);
char *nonconst=const_cast<char *>(Line.c_str());
// Strip out comments
while (*nonconst)
{
if (*nonconst==';') // End the line at comments
{
*nonconst='\0';
}
else
{
nonconst++;
}
};
Command[0]='\0';
Flags[0]='\0';
// Extract the command
TempLine.assign(Line.c_str());
nonconst=const_cast<char *>(TempLine.c_str());
char *start=NULL;
char *end=NULL;
// move up line until the first ", mark this down as the start
// then find the second " and mark it down as the end
while (*nonconst!='\0')
{
if (*nonconst=='"')
{
if (start==NULL)
{
start=nonconst+1;
}
else
{
end=nonconst;
goto done_with_command;
}
}
nonconst++;
}
done_with_command:
// invalid line?
if (start==NULL || end==NULL)
{
// TODO: maybe warn for an invalid non-commented line?
continue;
}
*end='\0';
strncpy(Command,start,sizeof(Command)-1);
// Now do the same thing for the flags
nonconst=++end;
start=NULL;
end=NULL;
// move up line until the first ", mark this down as the start
// then find the second " and mark it down as the end
while (*nonconst!='\0')
{
if (*nonconst=='"')
{
if (start==NULL)
{
start=nonconst+1;
}
else
{
end=nonconst;
goto done_with_flags;
}
}
nonconst++;
}
done_with_flags:
// invalid line?
if (start==NULL || end==NULL)
{
// TODO: maybe warn for an invalid non-commented line?
continue;
}
*end='\0';
strncpy(Flags,start,sizeof(Flags)-1);
//if (!isalnum(*Command))
if (*Command == '"' ||
*Command == '\0')
{
continue;
};
// Done sucking the command and flags out of the line
// now insert this command into the linked list
AddFromFile(const_cast<const char*>(&Command[0]),&Flags[0]);
nonconst=const_cast<char *>(Line.c_str());
*nonconst='\0';
};
fclose(File);
return 1;
}
/**
* This gets called from LoadFile
* Do NOT flag the entries as NeedToWrite
* No comment is passed from the file because
* this should never get written
*/
void CFlagManager::AddFromFile(const char *Command, const char *Flags)
{
CFlagEntry *Entry=new CFlagEntry;
Entry->SetName(Command);
Entry->SetFlags(Flags);
// Link it
m_FlagList.push_back(Entry);
};
void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
{
if (m_iDisabled) // if disabled in core.ini stop
{
return;
}
int TempFlags=Flags;
if (TempFlags==-1)
{
TempFlags=0;
}
List<CFlagEntry *>::iterator iter;
List<CFlagEntry *>::iterator end;
iter=m_FlagList.begin();
end=m_FlagList.end();
while (iter!=end)
{
if (strcmp((*iter)->GetName()->c_str(),Command)==0)
{
CFlagEntry *Entry=(*iter);
if (Entry->IsHidden()) // "!" flag, exclude this function
{
return;
}
// Found, byref the new flags
Flags=Entry->Flags();
// Move it to the back of the list for faster lookup for the rest
m_FlagList.erase(iter);
m_FlagList.push_back(Entry);
return;
}
iter++;
}
// was not found, add it
CFlagEntry *Entry=new CFlagEntry;
Entry->SetName(Command);
Entry->SetFlags(TempFlags);
if (Plugin)
{
CPluginMngr::CPlugin* a = g_plugins.findPluginFast(Plugin);
if (a)
{
Entry->SetComment(a->getName());
}
}
// This entry was added from a register_* native
// it needs to be written during map change
Entry->SetNeedWritten(1);
// Link it
m_FlagList.push_back(Entry);
}
void CFlagManager::WriteCommands(void)
{
List<CFlagEntry *>::iterator iter;
List<CFlagEntry *>::iterator end;
FILE *File;
int NeedToRead=0;
// First off check the modified time of this file
// if it matches the stored modified time, then update
// after we write so we do not re-read next map
struct stat TempStat;
stat(m_strConfigFile.c_str(),&TempStat);
if (TempStat.st_mtime != m_Stat.st_mtime)
{
NeedToRead=1;
};
File=fopen(m_strConfigFile.c_str(),"a");
iter=m_FlagList.begin();
end=m_FlagList.end();
while (iter!=end)
{
if ((*iter)->NeedWritten())
{
if ((*iter)->GetComment()->size())
{
fprintf(File,"\"%s\" \t\"%s\" ; %s\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str(),(*iter)->GetComment()->c_str());
}
else
{
fprintf(File,"\"%s\" \t\"%s\"\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str());
}
(*iter)->SetNeedWritten(0);
}
++iter;
};
fclose(File);
// If NeedToRead was 0, then update the timestamp
// that was saved so we do not re-read this file
// next map
if (!NeedToRead)
{
stat(m_strConfigFile.c_str(),&TempStat);
m_Stat.st_mtime=TempStat.st_mtime;
}
}
int CFlagManager::ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const
{
// If flagmanager is disabled then ignore this
if (m_iDisabled)
{
return 0;
}
// If 5th param exists it was compiled after this change was made
// if it does not exist, try our logic at the end of this function
// 5th param being > 0 means explicit yes
// < 0 means auto detect (default is -1), treat it like there was no 5th param
// 0 means explicit no
if ((params[0] / sizeof(cell)) >= 5)
{
if (params[5]>0) // This command was explicitly told to be included
{
return 1;
}
else if (params[5]==0) // this command was explicitly told to NOT be used
{
return 0;
}
}
// auto detect if we should use this command
// if command access is -1 (default, not set to ADMIN_ALL or any other access), then no
if (params[3]==-1)
{
return 0;
}
// if command is (or starts with) "say", then no
if (strncmp(cmdname,"say",3)==0)
{
return 0;
}
// else use it
return 1;
};
void CFlagManager::Clear(void)
{
List<CFlagEntry *>::iterator iter;
List<CFlagEntry *>::iterator end;
iter=m_FlagList.begin();
end=m_FlagList.end();
while (iter!=end)
{
delete (*iter);
++iter;
}
m_FlagList.clear();
};
void CFlagManager::CheckIfDisabled(void)
{
if (atoi(get_localinfo("disableflagman","0"))==0)
{
m_iDisabled=0;
}
else
{
m_iDisabled=1;
}
};

View File

@ -1,218 +0,0 @@
#ifndef CFLAGMANAGER_H
#define CFLAGMANAGER_H
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "sh_list.h"
#include "CString.h"
#include "amxmodx.h"
class CFlagEntry
{
private:
String m_strName; // command name ("amx_slap")
String m_strFlags; // string flags ("a","b")
String m_strComment; // comment to write ("; admincmd.amxx")
int m_iFlags; // bitmask flags
int m_iNeedWritten; // write this command on map change?
int m_iHidden; // set to 1 when the command is set to "!" access in
// the .ini file: this means do not process this command
public:
CFlagEntry()
{
m_iNeedWritten=0;
m_iFlags=0;
m_iHidden=0;
};
const int NeedWritten(void) const
{
return m_iNeedWritten;
};
void SetNeedWritten(const int i=1)
{
m_iNeedWritten=i;
};
const String *GetName(void) const
{
return &m_strName;
};
const String *GetFlags(void) const
{
return &m_strFlags;
};
const String *GetComment(void) const
{
return &m_strComment;
};
const int Flags(void) const
{
return m_iFlags;
};
void SetName(const char *data)
{
m_strName.assign(data);
};
void SetFlags(const char *flags)
{
// If this is a "!" entry then stop
if (flags && flags[0]=='!')
{
SetHidden(1);
return;
}
m_strFlags.assign(flags);
m_iFlags=UTIL_ReadFlags(flags);
};
void SetFlags(const int flags)
{
m_iFlags=flags;
char FlagsString[32];
UTIL_GetFlags(FlagsString, flags);
m_strFlags.assign(FlagsString);
};
void SetComment(const char *comment)
{
m_strComment.assign(comment);
};
void SetHidden(int i=1)
{
m_iHidden=i;
};
int IsHidden(void) const
{
return m_iHidden;
};
};
class CFlagManager
{
private:
List<CFlagEntry *> m_FlagList;
String m_strConfigFile;
struct stat m_Stat;
int m_iForceRead;
int m_iDisabled;
void CreateIfNotExist(void) const
{
FILE *fp;
fp=fopen(m_strConfigFile.c_str(),"r");
if (!fp)
{
// File does not exist, create the header
fp=fopen(m_strConfigFile.c_str(),"a");
if (fp)
{
fprintf(fp,"; This file will store the commands used by plugins, and their access level\n");
fprintf(fp,"; To change the access of a command, edit the flags beside it and then\n");
fprintf(fp,"; change the server's map.\n;\n");
fprintf(fp,"; Example: If I wanted to change the amx_slap access to require\n");
fprintf(fp,"; RCON access (flag \"l\") I would change this:\n");
fprintf(fp,"; \"amx_slap\" \"e\" ; admincmd.amxx\n");
fprintf(fp,"; To this:\n");
fprintf(fp,"; \"amx_slap\" \"l\" ; admincmd.amxx\n;\n");
fprintf(fp,"; To disable a specific command from being used with the command manager\n");
fprintf(fp,"; and to only use the plugin-specified access set the flag to \"!\"\n;\n");
fprintf(fp,"; NOTE: The plugin name at the end is just for reference to what plugin\n");
fprintf(fp,"; uses what commands. It is ignored.\n\n");
fclose(fp);
};
}
};
/**
* Returns 1 if the timestamp for the file is different than the one we have loaded
* 0 otherwise
*/
inline int NeedToLoad(void)
{
struct stat TempStat;
stat(m_strConfigFile.c_str(),&TempStat);
// If the modified timestamp does not match the stored
// timestamp than we need to re-read this file.
// Otherwise, ignore the file.
if (TempStat.st_mtime != m_Stat.st_mtime)
{
// Save down the modified timestamp
m_Stat.st_mtime=TempStat.st_mtime;
return 1;
};
return 0;
};
public:
CFlagManager()
{
memset(&m_Stat,0x0,sizeof(struct stat));
m_iDisabled=0;
m_iForceRead=0;
};
~CFlagManager()
{
};
/**
* Sets the filename in relation to amxmodx/configs
*/
void SetFile(const char *Filename="cmdaccess.ini");
const char *GetFile(void) const { return m_strConfigFile.c_str(); };
/**
* Parse the file, and load all entries
* Returns 1 on success, 0 on refusal (no need to), and -1 on error
*/
const int LoadFile(const int force=0);
/**
* Checks if the command exists in the list
* If it does, it byrefs the flags for it
* If it does not, it adds it to the list
* These are added from register_*cmd calls
*/
void LookupOrAdd(const char *Command, int &Flags, AMX *Plugin);
/**
* Write the commands back to the file
*/
void WriteCommands(void);
/**
* Add this straight from the cmdaccess.ini file
*/
void AddFromFile(const char *Command, const char *Flags);
/**
* Checks if this command should be added to flagman or not
* This is only checked when adding commands from the register_* natives
* If an admin manually adds a command to cmdaccess.ini it will be used
* regardless of whatever this function would say should be done with it
*/
int ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const;
void Clear(void);
void CheckIfDisabled(void);
};
#endif // CFLAGMANAGER_H

View File

@ -31,9 +31,8 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "debugger.h" #include "debugger.h"
#include "binlog.h"
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes, int fwd_type) CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
{ {
m_FuncName = name; m_FuncName = name;
m_ExecType = et; m_ExecType = et;
@ -43,17 +42,11 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
// find funcs // find funcs
int func; int func;
AMXForward *tmp = NULL;
m_Funcs.clear(); m_Funcs.clear();
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter) for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{ {
if ((fwd_type != FORWARD_ALL) &&
((fwd_type == FORWARD_ONLY_NEW && ((*iter).getAMX()->flags & AMX_FLAG_OLDFILE))
|| (fwd_type == FORWARD_ONLY_OLD && !((*iter).getAMX()->flags & AMX_FLAG_OLDFILE))
))
{
continue;
}
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE) if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
{ {
AMXForward tmp; AMXForward tmp;
@ -62,8 +55,6 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
m_Funcs.push_back(tmp); m_Funcs.push_back(tmp);
} }
} }
m_Name.assign(name);
} }
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays) cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
@ -75,6 +66,8 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
cell globRetVal = 0; cell globRetVal = 0;
unsigned int id = 0;
AMXForwardList::iterator iter; AMXForwardList::iterator iter;
for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++) for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
@ -89,18 +82,15 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
pDebugger->BeginExec(); pDebugger->BeginExec();
// handle strings & arrays // handle strings & arrays
int i; int i, ax = 0;
for (i = 0; i < m_NumParams; ++i) for (i = 0; i < m_NumParams; ++i)
{ {
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX) if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
{ {
const char *str = reinterpret_cast<const char*>(params[i]);
cell *tmp; cell *tmp;
if (!str) amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
str = ""; amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
amx_SetStringOld(tmp, str, 0, 0);
physAddrs[i] = tmp; physAddrs[i] = tmp;
} }
else if (m_ParamTypes[i] == FP_ARRAY) else if (m_ParamTypes[i] == FP_ARRAY)
@ -130,10 +120,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
} }
// exec // exec
cell retVal = 0; cell retVal;
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
#endif
int err = amx_Exec(amx, &retVal, iter->func); int err = amx_Exec(amx, &retVal, iter->func);
// log runtime error, if any // log runtime error, if any
@ -216,18 +203,12 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes) void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
{ {
char name[sNAMEMAX];
m_Func = func; m_Func = func;
m_Amx = amx; m_Amx = amx;
m_NumParams = numParams; m_NumParams = numParams;
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam)); memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
m_HasFunc = true; m_HasFunc = true;
isFree = false; isFree = false;
name[0] = '\0';
amx_GetPublic(amx, func, name);
m_Name.assign(name);
m_ToDelete = false;
m_InExec = false;
} }
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes) void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
@ -237,9 +218,6 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam)); memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE); m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
isFree = false; isFree = false;
m_Name.assign(funcName);
m_ToDelete = false;
m_InExec = false;
} }
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays) cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
@ -252,15 +230,13 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
cell realParams[FORWARD_MAX_PARAMS]; cell realParams[FORWARD_MAX_PARAMS];
cell *physAddrs[FORWARD_MAX_PARAMS]; cell *physAddrs[FORWARD_MAX_PARAMS];
if (!m_HasFunc || m_ToDelete) if (!m_HasFunc)
return 0; return 0;
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx); CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
if (!pPlugin->isExecutable(m_Func)) if (!pPlugin->isExecutable(m_Func))
return 0; return 0;
m_InExec = true;
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER]; Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
if (pDebugger) if (pDebugger)
pDebugger->BeginExec(); pDebugger->BeginExec();
@ -272,12 +248,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{ {
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX) if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
{ {
const char *str = reinterpret_cast<const char*>(params[i]);
if (!str)
str = "";
cell *tmp; cell *tmp;
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp); amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
amx_SetStringOld(tmp, str, 0, 0); amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
physAddrs[i] = tmp; physAddrs[i] = tmp;
} }
else if (m_ParamTypes[i] == FP_ARRAY) else if (m_ParamTypes[i] == FP_ARRAY)
@ -305,9 +278,6 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
// exec // exec
cell retVal; cell retVal;
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
#endif
int err = amx_Exec(m_Amx, &retVal, m_Func); int err = amx_Exec(m_Amx, &retVal, m_Func);
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
@ -362,20 +332,16 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
} }
} }
m_InExec = false;
return retVal; return retVal;
} }
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes, int fwd_type) int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
{ {
int retVal = m_Forwards.size() << 1; int retVal = m_Forwards.size() << 1;
CForward *tmp = new CForward(funcName, et, numParams, paramTypes, fwd_type); CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
if (!tmp) if (!tmp)
{
return -1; // should be invalid return -1; // should be invalid
}
m_Forwards.push_back(tmp); m_Forwards.push_back(tmp);
@ -460,43 +426,12 @@ bool CForwardMngr::isIdValid(int id) const
cell CForwardMngr::executeForwards(int id, cell *params) cell CForwardMngr::executeForwards(int id, cell *params)
{ {
int retVal; int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
if (id & 1)
{
CSPForward *fwd = m_SPForwards[id >> 1];
retVal = fwd->execute(params, m_TmpArrays);
if (fwd->m_ToDelete)
{
fwd->m_ToDelete = false;
unregisterSPForward(id);
}
} else {
retVal = m_Forwards[id >> 1]->execute(params, m_TmpArrays);
}
m_TmpArraysNum = 0; m_TmpArraysNum = 0;
return retVal; return retVal;
} }
const char *CForwardMngr::getFuncName(int id) const
{
if (!isIdValid(id))
{
return "";
}
return (id & 1) ? m_SPForwards[id >> 1]->getFuncName() : m_Forwards[id >> 1]->getFuncName();
}
int CForwardMngr::getFuncsNum(int id) const
{
if (!isIdValid(id))
{
return 0;
}
return (id & 1) ? m_SPForwards[id >> 1]->getFuncsNum() : m_Forwards[id >> 1]->getFuncsNum();
}
int CForwardMngr::getParamsNum(int id) const int CForwardMngr::getParamsNum(int id) const
{ {
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum(); return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
@ -504,10 +439,6 @@ int CForwardMngr::getParamsNum(int id) const
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
{ {
if (!isIdValid(id))
{
return FP_DONE;
}
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum); return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
} }
@ -543,64 +474,11 @@ void CForwardMngr::unregisterSPForward(int id)
{ {
//make sure the id is valid //make sure the id is valid
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree) if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
{
return; return;
}
CSPForward *fwd = m_SPForwards.at(id >> 1); m_SPForwards.at(id >> 1)->isFree = true;
if (fwd->m_InExec)
{
fwd->m_ToDelete = true;
} else {
fwd->isFree = true;
m_FreeSPForwards.push(id); m_FreeSPForwards.push(id);
} }
}
int CForwardMngr::duplicateSPForward(int id)
{
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
{
return -1;
}
CSPForward *fwd = m_SPForwards.at(id >> 1);
return registerSPForward(fwd->m_Func, fwd->m_Amx, fwd->m_NumParams, fwd->m_ParamTypes);
}
int CForwardMngr::isSameSPForward(int id1, int id2)
{
if (!isIdValid(id1) || !isIdValid(id2))
{
return false;
}
CSPForward *fwd1 = m_SPForwards.at(id1 >> 1);
CSPForward *fwd2 = m_SPForwards.at(id2 >> 1);
if (fwd1->isFree || fwd2->isFree)
{
return false;
}
return ((fwd1->m_Amx == fwd2->m_Amx)
&& (fwd1->m_Func == fwd2->m_Func)
&& (fwd1->m_NumParams == fwd2->m_NumParams));
}
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type)
{
ForwardParam params[FORWARD_MAX_PARAMS];
for (size_t i=0; i<num; i++)
{
params[i] = static_cast<ForwardParam>(list[i]);
}
return g_forwards.registerForward(funcName, et, num, params, fwd_type);
}
int registerForward(const char *funcName, ForwardExecType et, ...) int registerForward(const char *funcName, ForwardExecType et, ...)
{ {
@ -631,16 +509,6 @@ int registerForward(const char *funcName, ForwardExecType et, ...)
return g_forwards.registerForward(funcName, et, curParam, params); return g_forwards.registerForward(funcName, et, curParam, params);
} }
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num)
{
ForwardParam params[FORWARD_MAX_PARAMS];
for (size_t i=0; i<num; i++)
params[i] = static_cast<ForwardParam>(list[i]);
return g_forwards.registerSPForward(funcName, amx, num, params);
}
int registerSPForwardByName(AMX *amx, const char *funcName, ...) int registerSPForwardByName(AMX *amx, const char *funcName, ...)
{ {
int curParam = 0; int curParam = 0;

View File

@ -46,15 +46,8 @@
#ifndef FORWARD_H #ifndef FORWARD_H
#define FORWARD_H #define FORWARD_H
#include <stdarg.h>
#include "sh_stack.h"
const int FORWARD_MAX_PARAMS = 32; const int FORWARD_MAX_PARAMS = 32;
#define FORWARD_ONLY_OLD 1
#define FORWARD_ONLY_NEW 2
#define FORWARD_ALL 3
enum ForwardExecType enum ForwardExecType
{ {
ET_IGNORE = 0, // Ignore return vaue ET_IGNORE = 0, // Ignore return vaue
@ -97,7 +90,6 @@ class CForward
const char *m_FuncName; const char *m_FuncName;
ForwardExecType m_ExecType; ForwardExecType m_ExecType;
int m_NumParams; int m_NumParams;
String m_Name;
struct AMXForward struct AMXForward
{ {
@ -111,7 +103,7 @@ class CForward
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS]; ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
public: public:
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes, int fwd_type=FORWARD_ALL); CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
CForward() {} // leaves everything unitialized' CForward() {} // leaves everything unitialized'
cell execute(cell *params, ForwardPreparedArray *preparedArrays); cell execute(cell *params, ForwardPreparedArray *preparedArrays);
@ -126,11 +118,6 @@ public:
return m_Funcs.size(); return m_Funcs.size();
} }
const char *getFuncName() const
{
return m_Name.c_str();
}
ForwardParam getParamType(int paramId) const ForwardParam getParamType(int paramId) const
{ {
if (paramId < 0 || paramId >= m_NumParams) if (paramId < 0 || paramId >= m_NumParams)
@ -143,7 +130,6 @@ public:
// Single plugin forward // Single plugin forward
class CSPForward class CSPForward
{ {
friend class CForwardMngr;
const char *m_FuncName; const char *m_FuncName;
int m_NumParams; int m_NumParams;
@ -152,9 +138,6 @@ class CSPForward
int m_Func; int m_Func;
bool m_HasFunc; bool m_HasFunc;
String m_Name;
bool m_InExec;
bool m_ToDelete;
public: public:
bool isFree; bool isFree;
@ -175,11 +158,6 @@ public:
return (m_HasFunc) ? 1 : 0; return (m_HasFunc) ? 1 : 0;
} }
const char *getFuncName() const
{
return m_Name.c_str();
}
ForwardParam getParamType(int paramId) const ForwardParam getParamType(int paramId) const
{ {
if (paramId < 0 || paramId >= m_NumParams) if (paramId < 0 || paramId >= m_NumParams)
@ -193,7 +171,7 @@ class CForwardMngr
{ {
typedef CVector<CForward*> ForwardVec; typedef CVector<CForward*> ForwardVec;
typedef CVector<CSPForward*> SPForwardVec; typedef CVector<CSPForward*> SPForwardVec;
typedef CStack<int> FreeSPVec; // Free SP Forwards typedef CQueue<int> FreeSPVec; // Free SP Forwards
ForwardVec m_Forwards; ForwardVec m_Forwards;
@ -210,15 +188,13 @@ public:
// Interface // Interface
// Register normal forward // Register normal forward
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes, int fwd_type=FORWARD_ALL); int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
// Register single plugin forward // Register single plugin forward
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes); int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes); int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
// Unregister single plugin forward // Unregister single plugin forward
void unregisterSPForward(int id); void unregisterSPForward(int id);
int duplicateSPForward(int id);
int isSameSPForward(int id1, int id2);
// execute forward // execute forward
cell executeForwards(int id, cell *params); cell executeForwards(int id, cell *params);
@ -228,7 +204,6 @@ public:
bool isSPForward(int id) const; // check whether forward is single plugin bool isSPForward(int id) const; // check whether forward is single plugin
int getParamsNum(int id) const; // get num of params of a forward int getParamsNum(int id) const; // get num of params of a forward
int getFuncsNum(int id) const; // get num of found functions of a forward int getFuncsNum(int id) const; // get num of found functions of a forward
const char *getFuncName(int id) const; // get the function name
ForwardParam getParamType(int id, int paramId) const; ForwardParam getParamType(int id, int paramId) const;
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
@ -236,9 +211,7 @@ public:
// (un)register forward // (un)register forward
int registerForward(const char *funcName, ForwardExecType et, ...); int registerForward(const char *funcName, ForwardExecType et, ...);
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type=FORWARD_ALL);
int registerSPForwardByName(AMX *amx, const char *funcName, ...); int registerSPForwardByName(AMX *amx, const char *funcName, ...);
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num);
int registerSPForward(AMX *amx, int func, ...); int registerSPForward(AMX *amx, int func, ...);
void unregisterSPForward(int id); void unregisterSPForward(int id);

File diff suppressed because it is too large Load Diff

View File

@ -32,56 +32,28 @@
#ifndef _INCLUDE_CLANG_H #ifndef _INCLUDE_CLANG_H
#define _INCLUDE_CLANG_H #define _INCLUDE_CLANG_H
#include "sh_tinyhash.h"
#define LANG_SERVER 0 #define LANG_SERVER 0
#define LANG_PLAYER -1 #define LANG_PLAYER -1
#define ERR_BADKEY 1 // Lang key not found
#define ERR_BADLANG 2 // Invalid lang
struct md5Pair struct md5Pair
{ {
String file; String file;
String val; String val;
}; };
struct keyEntry
{
String key;
uint32_t hash;
};
struct sKeyDef struct sKeyDef
{ {
String *definition; sKeyDef() { key = -1; def = 0; }
~sKeyDef() { if (def) delete def; }
int key; int key;
}; String *def;
struct lang_err
{
lang_err() : last(0.0f)
{
};
float last;
};
class defentry
{
public:
defentry() : definition(NULL)
{
};
defentry(const defentry &src)
{
definition = src.definition;
}
~defentry()
{
}
String *definition;
};
struct keytbl_val
{
keytbl_val() : index(-1)
{
};
int index;
}; };
class CLangMngr class CLangMngr
@ -97,9 +69,9 @@ class CLangMngr
~CLang(); ~CLang();
// Get the definition // Get the definition
const char *GetDef(int key, int &status); const char *GetDef(const char *key);
// Add definitions to this language // Add definitions to this language
void MergeDefinitions(CQueue <sKeyDef> & vec); void MergeDefinitions(CQueue <sKeyDef*> & vec);
// Reset this language // Reset this language
void Clear(); void Clear();
@ -111,27 +83,69 @@ class CLangMngr
// Get language name // Get language name
const char *GetName() { return m_LanguageName; } const char *GetName() { return m_LanguageName; }
// Save to file
bool Save(FILE *fp, int &defOffset, uint32_t &curOffset);
bool SaveDefinitions(FILE *fp, uint32_t &curOffset);
// Load
bool Load(FILE *fp);
void SetMngr(CLangMngr *l) { m_LMan = l; } void SetMngr(CLangMngr *l) { m_LMan = l; }
// Get number of entries // Get number of entries
int Entries(); int Entries() { return m_LookUpTable.size(); }
// Make a hash from a string; convert to lowercase first if needed
static uint32_t MakeHash(const char *src, bool makeLower = false);
protected: protected:
typedef THash<int, defentry> LookUpVec; // An entry in the language
class LangEntry
{
// the definition hash
uint32_t m_DefHash;
// index into the lookup table?
int key;
// the definition
String m_pDef;
// is this from the cache or not?
bool m_isCache;
public:
// Set
void SetKey(int key);
void SetDef(const char *pDef);
void SetCache(bool c);
// Get
uint32_t GetDefHash();
int GetKey();
const char *GetDef();
int GetDefLength();
bool GetCache();
// Constructors / destructors
LangEntry();
LangEntry(int key);
LangEntry(int key, const char *pDef);
LangEntry(const LangEntry &other);
LangEntry(int pKey, uint32_t defHash, const char *pDef);
// Reset
void Clear();
};
// Get (construct if needed) an entry
LangEntry * GetEntry(int key);
typedef CVector<LangEntry*> LookUpVec;
typedef LookUpVec::iterator LookUpVecIter; typedef LookUpVec::iterator LookUpVecIter;
char m_LanguageName[3]; char m_LanguageName[3];
// our lookup table // our lookup table
LookUpVec m_LookUpTable; LookUpVec m_LookUpTable;
int m_entries;
CLangMngr *m_LMan; CLangMngr *m_LMan;
public: public:
void AddEntry(int key, const char *definition); LangEntry *AddEntry(int pKey, uint32_t defHash, const char *def, bool cache);
}; };
public:
// Merge definitions into a language
void MergeDefinitions(const char *lang, CQueue <sKeyDef> &tmpVec);
private: // Merge definitions into a language
void MergeDefinitions(const char *lang, CQueue <sKeyDef*> &tmpVec);
// strip lowercase; make lower if needed // strip lowercase; make lower if needed
static size_t strip(char *str, char *newstr, bool makelower = false); static size_t strip(char *str, char *newstr, bool makelower = false);
@ -141,8 +155,7 @@ private:
LangVec m_Languages; LangVec m_Languages;
CVector<md5Pair *> FileList; CVector<md5Pair *> FileList;
CVector<String *> KeyList; CVector<keyEntry*> KeyList;
THash<String, keytbl_val> KeyTable;
// Get a lang object (construct if needed) // Get a lang object (construct if needed)
CLang * GetLang(const char *name); CLang * GetLang(const char *name);
@ -154,19 +167,30 @@ private:
public: public:
// Merge a definitions file // Merge a definitions file
int MergeDefinitionFile(const char *file); int MergeDefinitionFile(const char *file);
// Get a definition from a lang name and a key // Get a definition from a lang name and a kyer
const char *GetDef(const char *langName, const char *key, int &status); const char *GetDef(const char *langName, const char *key);
// Format a string
const char *Format(const char *src, ...);
// Format a string for an AMX plugin // Format a string for an AMX plugin
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len); char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
void InvalidateCache(); char *FormatString(const char *fmt, va_list &ap);
// Save
bool Save(const char *filename);
// Load
bool Load(const char *filename);
// Cache
bool LoadCache(const char *filename);
bool SaveCache(const char *filename);
// Get index // Get index
int GetKeyEntry(String &key); int GetKeyEntry(String &key);
int GetKeyEntry(const char *key); int GetKeyEntry(const char *key);
int GetKeyHash(int key);
// Get key from index // Get key from index
const char *GetKey(int key); const char *GetKey(int key);
// Add key // Add key
int AddKeyEntry(String &key); int AddKeyEntry(String &key);
int AddKeyEntry(const char *key); // Make a hash from a string; convert to lowercase first if needed
uint32_t MakeHash(const char *src, bool makeLower);
// Get the number of languages // Get the number of languages
int GetLangsNum(); int GetLangsNum();
@ -178,8 +202,6 @@ public:
// When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take. // When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take.
void SetDefLang(int id); void SetDefLang(int id);
inline int GetDefLang() const { return m_CurGlobId; }
// Reset // Reset
void Clear(); void Clear();

View File

@ -35,21 +35,18 @@
// ***************************************************** // *****************************************************
// class MenuMngr // class MenuMngr
// ***************************************************** // *****************************************************
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu) MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f)
{ {
plugin = a; plugin = a;
keys = k; keys = k;
menuid = mi; menuid = mi;
next = 0;
is_new_menu = new_menu;
function = f; function = f;
next = 0;
} }
MenuMngr::~MenuMngr() MenuMngr::~MenuMngr()
{ {
clear(); clear();
MenuMngr::MenuIdEle::uniqueid = 0;
} }
int MenuMngr::findMenuId(const char* name, AMX* amx) int MenuMngr::findMenuId(const char* name, AMX* amx)
@ -68,42 +65,21 @@ int MenuMngr::registerMenuId(const char* n, AMX* a)
int id = findMenuId(n, a); int id = findMenuId(n, a);
if (id) if (id)
{
return id; return id;
}
headid = new MenuIdEle(n, a, headid); headid = new MenuIdEle(n, a, headid);
if (!headid)
return 0; // :TODO: Better error report
return headid->id; return headid->id;
} }
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu) void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f)
{ {
MenuCommand** temp = &headcmd; MenuCommand** temp = &headcmd;
if (from_new_menu) while (*temp) temp = &(*temp)->next;
{ *temp = new MenuCommand(a, mi, k, f);
MenuCommand *ptr;
while (*temp)
{
ptr = *temp;
if (ptr->is_new_menu
&& ptr->plugin == a
&& ptr->menuid == mi)
{
if (g_forwards.isSameSPForward(ptr->function, f))
{
return;
}
}
temp = &(*temp)->next;
}
} else {
while (*temp)
{
temp = &(*temp)->next;
}
}
*temp = new MenuCommand(a, mi, k, f, from_new_menu);
} }
void MenuMngr::clear() void MenuMngr::clear()
@ -123,13 +99,4 @@ void MenuMngr::clear()
} }
} }
MenuMngr::iterator MenuMngr::SetWatchIter(MenuMngr::iterator iter)
{
MenuMngr::iterator old = m_watch_iter;
m_watch_iter = iter;
return old;
}
int MenuMngr::MenuIdEle::uniqueid = 0; int MenuMngr::MenuIdEle::uniqueid = 0;

View File

@ -51,6 +51,8 @@ class MenuMngr
{ {
id = ++uniqueid; id = ++uniqueid;
} }
~MenuIdEle() { --uniqueid; }
} *headid; } *headid;
public: public:
@ -66,34 +68,28 @@ private:
int menuid; int menuid;
int keys; int keys;
int function; int function;
int is_new_menu;
MenuCommand* next; MenuCommand* next;
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu=false); MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f);
public: public:
inline int getFunction() { return function; } inline int getFunction() { return function; }
inline CPluginMngr::CPlugin* getPlugin() { return plugin; } inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline bool matchCommand(int m, int k) inline bool matchCommand(int m, int k) { return ((m == menuid) && (keys & k)); }
{
return ((m == menuid) && (keys & k));
}
} *headcmd; } *headcmd;
public: public:
MenuMngr() : m_watch_iter(end()) MenuMngr() { headid = 0; headcmd = 0; }
{ headid = NULL; headcmd = NULL; }
~MenuMngr(); ~MenuMngr();
// Interface // Interface
int findMenuId(const char* name, AMX* a = 0); int findMenuId(const char* name, AMX* a = 0);
int registerMenuId(const char* n, AMX* a); int registerMenuId(const char* n, AMX* a);
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu=false); void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
void clear(); void clear();
class iterator class iterator
{ {
friend class MenuMngr;
MenuCommand* a; MenuCommand* a;
public: public:
iterator(MenuCommand*aa) : a(aa) {} iterator(MenuCommand*aa) : a(aa) {}
@ -106,13 +102,6 @@ public:
inline iterator begin() const { return iterator(headcmd); } inline iterator begin() const { return iterator(headcmd); }
inline iterator end() const { return iterator(0); } inline iterator end() const { return iterator(0); }
MenuMngr::iterator SetWatchIter(MenuMngr::iterator iter);
inline MenuMngr::iterator GetWatchIter() { return m_watch_iter; }
private:
MenuMngr::iterator m_watch_iter;
}; };
extern MenuMngr g_menucmds;
#endif //MENUS_H #endif //MENUS_H

View File

@ -29,7 +29,6 @@
* version. * version.
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "newmenus.h"
// ***************************************************** // *****************************************************
// class CPlayer // class CPlayer
// ***************************************************** // *****************************************************
@ -40,6 +39,7 @@ void CPlayer::Init(edict_t* e, int i)
pEdict = e; pEdict = e;
initialized = false; initialized = false;
ingame = false; ingame = false;
bot = false;
authorized = false; authorized = false;
current = 0; current = 0;
@ -48,8 +48,6 @@ void CPlayer::Init(edict_t* e, int i)
aiming = 0; aiming = 0;
menu = 0; menu = 0;
keys = 0; keys = 0;
menuexpire = 0.0;
newmenu = -1;
death_weapon.clear(); death_weapon.clear();
name.clear(); name.clear();
@ -63,32 +61,19 @@ void CPlayer::Disconnect()
initialized = false; initialized = false;
authorized = false; authorized = false;
if (newmenu != -1) while (!cvarQueryQueue.empty())
{ {
Menu *pMenu = g_NewMenus[newmenu]; ClientCvarQuery_Info *pQuery = cvarQueryQueue.front();
if (pMenu) unregisterSPForward(pQuery->resultFwd);
{
//prevent recursion if (pQuery->params)
newmenu = -1; delete [] pQuery->params;
menu = 0;
executeForwards(pMenu->func, delete pQuery;
static_cast<cell>(ENTINDEX(pEdict)), cvarQueryQueue.pop();
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
}
} }
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end(); bot = 0;
for (iter=queries.begin(); iter!=end; iter++)
{
unregisterSPForward((*iter)->resultFwd);
delete [] (*iter)->params;
delete (*iter);
}
queries.clear();
menu = 0;
newmenu = -1;
} }
void CPlayer::PutInServer() void CPlayer::PutInServer()
@ -97,27 +82,13 @@ void CPlayer::PutInServer()
ingame = true; ingame = true;
} }
int CPlayer::NextHUDChannel()
{
int ilow = 1;
for (int i=ilow+1; i<=4; i++)
{
if (channels[i] < channels[ilow])
ilow = i;
}
return ilow;
}
bool CPlayer::Connect(const char* connectname, const char* ipaddress) bool CPlayer::Connect(const char* connectname, const char* ipaddress)
{ {
name.assign(connectname); name.assign(connectname);
ip.assign(ipaddress); ip.assign(ipaddress);
time = gpGlobals->time; time = gpGlobals->time;
bot = IsBot();
death_killer = 0; death_killer = 0;
menu = 0;
newmenu = -1;
memset(flags, 0, sizeof(flags)); memset(flags, 0, sizeof(flags));
memset(weapons, 0, sizeof(weapons)); memset(weapons, 0, sizeof(weapons));
@ -125,21 +96,6 @@ bool CPlayer::Connect(const char* connectname, const char* ipaddress)
initialized = true; initialized = true;
authorized = false; authorized = false;
for (int i=0; i<=4; i++)
{
channels[i] = 0.0f;
hudmap[i] = 0;
}
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
for (iter=queries.begin(); iter!=end; iter++)
{
unregisterSPForward((*iter)->resultFwd);
delete [] (*iter)->params;
delete (*iter);
}
queries.clear();
const char* authid = GETPLAYERAUTHID(pEdict); const char* authid = GETPLAYERAUTHID(pEdict);
if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0)) if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))

View File

@ -33,7 +33,6 @@
#define CMISC_H #define CMISC_H
#include "CList.h" #include "CList.h"
#include "sh_list.h"
// ***************************************************** // *****************************************************
// class CCVar // class CCVar
@ -58,7 +57,6 @@ public:
inline const char* getPluginName() { return plugin.c_str(); } inline const char* getPluginName() { return plugin.c_str(); }
inline const char* getName() { return name.c_str(); } inline const char* getName() { return name.c_str(); }
inline bool operator == (const char* string) { return (strcmp(name.c_str(), string) == 0); } inline bool operator == (const char* string) { return (strcmp(name.c_str(), string) == 0); }
int plugin_id;
}; };
// ***************************************************** // *****************************************************
@ -67,8 +65,10 @@ public:
struct ClientCvarQuery_Info struct ClientCvarQuery_Info
{ {
bool querying; // Are we actually waiting for a response at the moment?
String cvarName;
int resultFwd; int resultFwd;
int requestId;
int paramLen; int paramLen;
cell *params; cell *params;
}; };
@ -84,12 +84,11 @@ public:
bool initialized; bool initialized;
bool ingame; bool ingame;
bool bot;
bool authorized; bool authorized;
bool vgui;
float time; float time;
float playtime; float playtime;
float menuexpire;
struct struct
{ {
@ -114,13 +113,11 @@ public:
int newmenu; int newmenu;
int page; int page;
float channels[5];
cell hudmap[5];
Vector lastTrace; Vector lastTrace;
Vector thisTrace;
Vector lastHit; Vector lastHit;
List<ClientCvarQuery_Info *> queries; CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
void Init(edict_t* e, int i); void Init(edict_t* e, int i);
void Disconnect(); void Disconnect();
@ -130,18 +127,7 @@ public:
inline bool IsBot() inline bool IsBot()
{ {
if ((pEdict->v.flags & FL_FAKECLIENT) == FL_FAKECLIENT) return ((pEdict->v.flags & FL_FAKECLIENT) ? true : false);
{
return true;
}
const char *auth = GETPLAYERAUTHID(pEdict);
if (auth && (strcmp(auth, "BOT") == 0))
{
return true;
}
return false;
} }
inline bool IsAlive() inline bool IsAlive()
@ -151,8 +137,6 @@ public:
inline void Authorize() { authorized = true; } inline void Authorize() { authorized = true; }
int NextHUDChannel();
}; };
// ***************************************************** // *****************************************************
@ -296,87 +280,4 @@ public:
inline bool isNewTeam() { return newTeam ? true : false; } inline bool isNewTeam() { return newTeam ? true : false; }
}; };
class CAdminData
{
private:
cell m_AuthData[44];
cell m_Password[32];
cell m_Flags;
cell m_Access;
public:
CAdminData()
{
m_AuthData[0]=0;
m_Password[0]=0;
m_Flags=0;
m_Access=0;
};
void SetAccess(cell Access)
{
m_Access=Access;
};
cell GetAccess(void) const
{
return m_Access;
};
void SetFlags(cell Flags)
{
m_Flags=Flags;
};
cell GetFlags(void) const
{
return m_Flags;
};
void SetAuthID(const cell *Input)
{
unsigned int i=0;
while (i<sizeof(m_AuthData)-1)
{
if ((m_AuthData[i++]=*Input++)==0)
{
return;
}
}
m_AuthData[sizeof(m_AuthData)-1]=0;
};
const cell *GetAuthID(void) const
{
return &m_AuthData[0];
};
void SetPass(const cell *Input)
{
unsigned int i=0;
while (i<sizeof(m_Password)-1)
{
if ((m_Password[i++]=*Input++)==0)
{
return;
}
}
m_Password[sizeof(m_Password)-1]=0;
};
const cell *GetPass(void) const
{
return &m_Password[0];
};
CAdminData & operator = (const CAdminData &src)
{
this->SetAccess(src.GetAccess());
this->SetFlags(src.GetFlags());
this->SetAuthID(src.GetAuthID());
this->SetPass(src.GetPass());
return *this;
}
};
#endif //CMISC_H #endif //CMISC_H

View File

@ -30,7 +30,6 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "libraries.h"
#ifndef FAR #ifndef FAR
#define FAR #define FAR
@ -42,8 +41,6 @@ typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/); typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
typedef int (FAR *DETACHMOD_NEW)(void); typedef int (FAR *DETACHMOD_NEW)(void);
typedef void (FAR *PLUGINSLOADED_NEW)(void); typedef void (FAR *PLUGINSLOADED_NEW)(void);
typedef void (*PLUGINSUNLOADED_NEW)(void);
typedef void (*PLUGINSUNLOADING_NEW)(void);
// ***************************************************** // *****************************************************
// class CModule // class CModule
@ -82,14 +79,7 @@ void CModule::clear(bool clearFilename)
m_InfoNew.reload = 0; m_InfoNew.reload = 0;
m_MissingFunc = NULL; m_MissingFunc = NULL;
for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
{
delete [] m_Natives[m_DestroyableIndexes[i]];
}
m_DestroyableIndexes.clear();
m_Natives.clear(); m_Natives.clear();
m_NewNatives.clear();
} }
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now) bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
@ -112,53 +102,6 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
return true; return true;
} }
//this ugly function is ultimately something like O(n^4).
//sigh. it shouldn't be needed.
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
{
AMX_NATIVE_INFO *curlist;
for (size_t i=0; i<m_Natives.size(); i++)
{
curlist = m_Natives[i];
bool changed = false;
bool found = false;
CVector<size_t> newlist;
for (size_t j=0; curlist[j].func != NULL; j++)
{
found = false;
for (size_t k=0; list[k].func != NULL; k++)
{
if (strcmp(curlist[j].name, list[k].name) == 0)
{
found = true;
break;
}
}
if (found)
{
changed = true;
//don't break, we have to search it all
} else {
newlist.push_back(j);
}
}
if (changed)
{
//now build the new list
AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.size()+1];
for (size_t j=0; j<newlist.size(); j++)
{
rlist[j].func = curlist[newlist[j]].func;
rlist[j].name = curlist[newlist[j]].name;
}
rlist[newlist.size()].func = NULL;
rlist[newlist.size()].name = NULL;
m_Natives[i] = rlist;
m_DestroyableIndexes.push_back(i);
}
}
}
bool CModule::attachModule() bool CModule::attachModule()
{ {
// old & new // old & new
@ -183,7 +126,7 @@ bool CModule::attachModule()
{ {
case AMXX_OK: case AMXX_OK:
m_Status = MODULE_LOADED; m_Status = MODULE_LOADED;
break; return true;
case AMXX_PARAM: case AMXX_PARAM:
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion()); AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
m_Status = MODULE_INTERROR; m_Status = MODULE_INTERROR;
@ -201,13 +144,6 @@ bool CModule::attachModule()
m_Status = MODULE_BADLOAD; m_Status = MODULE_BADLOAD;
} }
if (m_Status == MODULE_LOADED)
{
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
return true;
}
return false; return false;
} }
@ -248,36 +184,10 @@ bool CModule::queryModule()
return false; return false;
case AMXX_IFVERS: case AMXX_IFVERS:
if (ifVers < AMXX_INTERFACE_VERSION) if (ifVers < AMXX_INTERFACE_VERSION)
{
//backwards compat for new defs
if (ifVers == 3)
{
g_ModuleCallReason = ModuleCall_Query;
g_CurrentlyCalledModule = this;
retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
g_CurrentlyCalledModule = NULL;
g_ModuleCallReason = ModuleCall_NotCalled;
if (retVal == AMXX_OK)
{
m_InfoNew.library = m_InfoNew.logtag;
if (StrCaseStr(m_InfoNew.library, "sql")
|| StrCaseStr(m_InfoNew.library, "dbi"))
{
m_InfoNew.libclass = "DBI";
} else {
m_InfoNew.libclass = "";
}
break;
}
return false;
} else {
m_Status = MODULE_OLD; m_Status = MODULE_OLD;
return false; else
}
} else {
m_Status = MODULE_NEWER; m_Status = MODULE_NEWER;
return false; return false;
}
case AMXX_OK: case AMXX_OK:
break; break;
default: default:
@ -307,8 +217,6 @@ bool CModule::detachModule()
if (m_Status != MODULE_LOADED) if (m_Status != MODULE_LOADED)
return false; return false;
RemoveLibraries(this);
if (m_Amxx) if (m_Amxx)
{ {
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach"); DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
@ -336,38 +244,6 @@ bool CModule::detachModule()
return true; return true;
} }
void CModule::CallPluginsUnloaded()
{
if (m_Status != MODULE_LOADED)
return;
if (!m_Handle)
return;
PLUGINSUNLOADED_NEW func = (PLUGINSUNLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloaded");
if (!func)
return;
func();
}
void CModule::CallPluginsUnloading()
{
if (m_Status != MODULE_LOADED)
return;
if (!m_Handle)
return;
PLUGINSUNLOADING_NEW func = (PLUGINSUNLOADING_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloading");
if (!func)
return;
func();
}
void CModule::CallPluginsLoaded() void CModule::CallPluginsLoaded()
{ {
if (m_Status != MODULE_LOADED) if (m_Status != MODULE_LOADED)

View File

@ -59,8 +59,6 @@ struct amxx_module_info_s
const char *version; const char *version;
int reload; // reload on mapchange when nonzero int reload; // reload on mapchange when nonzero
const char *logtag; //added in version 2 const char *logtag; //added in version 2
const char *library; // added in version 4
const char *libclass; // added in version 4
}; };
#define AMXX_OK 0 /* no error */ #define AMXX_OK 0 /* no error */
@ -68,7 +66,7 @@ struct amxx_module_info_s
#define AMXX_PARAM 2 /* Invalid parameter */ #define AMXX_PARAM 2 /* Invalid parameter */
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */ #define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
#define AMXX_INTERFACE_VERSION 4 #define AMXX_INTERFACE_VERSION 3
class CModule class CModule
{ {
@ -92,7 +90,6 @@ public:
bool attachModule(); bool attachModule();
bool queryModule(); bool queryModule();
bool detachModule(); bool detachModule();
void rewriteNativeLists(AMX_NATIVE_INFO *list);
#ifndef FAKEMETA #ifndef FAKEMETA
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now); bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
@ -112,13 +109,9 @@ public:
inline const char *getFilename() { return m_Filename.c_str(); } inline const char *getFilename() { return m_Filename.c_str(); }
inline bool IsMetamod() { return m_Metamod; } inline bool IsMetamod() { return m_Metamod; }
void CallPluginsLoaded(); void CModule::CallPluginsLoaded();
void CallPluginsUnloaded();
void CallPluginsUnloading();
CVector<AMX_NATIVE_INFO*> m_Natives; CList<AMX_NATIVE_INFO*> m_Natives;
CVector<AMX_NATIVE_INFO*> m_NewNatives; // Natives for new (AMXX, not AMX) plugins only
CVector<size_t> m_DestroyableIndexes;
}; };
#endif //CMODULE_H #endif //CMODULE_H

View File

@ -36,7 +36,6 @@
#include "amx.h" #include "amx.h"
#include "natives.h" #include "natives.h"
#include "debugger.h" #include "debugger.h"
#include "libraries.h"
extern const char *no_function; extern const char *no_function;
@ -81,17 +80,14 @@ void CPluginMngr::Finalize()
m_Finalized = true; m_Finalized = true;
} }
int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn) int CPluginMngr::loadPluginsFromFile(const char* filename)
{ {
char file[256]; char file[256];
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt"); FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
if (!fp) if (!fp)
{ {
if (warn) AMXXLOG_Log("[AMXX] Plugins list not found (file \"%s\")", filename);
{
AMXXLOG_Error("[AMXX] Plugins list not found (file \"%s\")", filename);
}
return 1; return 1;
} }
@ -102,8 +98,6 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
String line; String line;
List<String *>::iterator block_iter;
while (!feof(fp)) while (!feof(fp))
{ {
pluginName[0] = '\0'; pluginName[0] = '\0';
@ -113,51 +107,16 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
line.clear(); line.clear();
line._fread(fp); line._fread(fp);
/** quick hack */
char *ptr = const_cast<char *>(line.c_str());
while (*ptr)
{
if (*ptr == ';')
{
*ptr = '\0';
} else {
ptr++;
}
}
sscanf(line.c_str(), "%s %s", pluginName, debug); sscanf(line.c_str(), "%s %s", pluginName, debug);
if (!isalnum(*pluginName)) if (!isalnum(*pluginName))
{
continue; continue;
}
if (isalnum(*debug) && !strcmp(debug, "debug")) if (isalnum(*debug) && strcmp(debug, "debug") == 0)
{ {
debugFlag = 1; debugFlag = 1;
} }
bool skip = false;
for (block_iter = m_BlockList.begin();
block_iter != m_BlockList.end();
block_iter++)
{
if ((*block_iter)->compare(pluginName) == 0)
{
skip = true;
break;
}
}
if (skip || !strcmp(debug, "disabled"))
{
continue;
}
if (findPlugin(pluginName) != NULL)
{
continue;
}
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag); CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
if (plugin->getStatusCode() == ps_bad_load) if (plugin->getStatusCode() == ps_bad_load)
@ -165,7 +124,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
char errorMsg[255]; char errorMsg[255];
sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName); sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName);
plugin->setError(errorMsg); plugin->setError(errorMsg);
AMXXLOG_Error("[AMXX] %s", plugin->getError()); AMXXLOG_Log("[AMXX] %s", plugin->getError());
} }
} }
@ -188,14 +147,11 @@ void CPluginMngr::clear()
delete [] pNatives; delete [] pNatives;
pNatives = NULL; pNatives = NULL;
} }
List<String *>::iterator iter = m_BlockList.begin();
while (iter != m_BlockList.end())
{
delete (*iter);
iter = m_BlockList.erase(iter);
} }
m_BlockList.clear();
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
{
return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]);
} }
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
@ -236,17 +192,6 @@ CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
return a; return a;
} }
void CPluginMngr::CPlugin::AddToFailCounter(unsigned int i)
{
failcounter += i;
if ((failcounter >= 3)
&& (status ))
{
errorMsg.assign("This plugin is non-GPL which violates AMX Mod X's license.");
status = ps_bad_load;
}
}
const char* CPluginMngr::CPlugin::getStatus() const const char* CPluginMngr::CPlugin::getStatus() const
{ {
switch (status) switch (status)
@ -274,7 +219,6 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
{ {
const char* unk = "unknown"; const char* unk = "unknown";
failcounter = 0;
title.assign(unk); title.assign(unk);
author.assign(unk); author.assign(unk);
version.assign(unk); version.assign(unk);
@ -299,8 +243,8 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
if (status == ps_running) if (status == ps_running)
{ {
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE); m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE); m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
if (amx.flags & AMX_FLAG_DEBUG) if (amx.flags & AMX_FLAG_DEBUG)
{ {
@ -349,7 +293,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
} }
char name[sNAMEMAX + 1]; char name[sNAMEMAX + 1];
int native = (int)(_INT_PTR)(amx->usertags[UT_NATIVE]); int native = amx->usertags[UT_NATIVE];
int err = amx_GetNative(amx, native, name); int err = amx_GetNative(amx, native, name);
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
@ -358,7 +302,6 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
//1 - because we're trapping usage //1 - because we're trapping usage
if (!pHandler->HandleNative(name, native, 1)) if (!pHandler->HandleNative(name, native, 1))
{ {
amx->usertags[UT_NATIVE] = (void *)native;
LogError(amx, AMX_ERR_INVNATIVE, NULL); LogError(amx, AMX_ERR_INVNATIVE, NULL);
return 0; return 0;
} }
@ -434,286 +377,13 @@ void CPluginMngr::CPlugin::pausePlugin()
// Unpause a plugin // Unpause a plugin
void CPluginMngr::CPlugin::unpausePlugin() void CPluginMngr::CPlugin::unpausePlugin()
{ {
if (isValid() && (getStatusCode() != ps_stopped)) if (isValid())
{ {
// set status first so the function will be marked executable // set status first so the function will be marked executable
setStatus(ps_running); setStatus(ps_running);
// call plugin_unpause if provided // call plugin_unpause if provided
if (m_UnpauseFwd != -1) if (m_UnpauseFwd != -1)
{
executeForwards(m_UnpauseFwd); executeForwards(m_UnpauseFwd);
} }
} }
}
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
{
List<plcache_entry *>::iterator iter;
plcache_entry *pl;
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
{
pl = (*iter);
if (pl->path.compare(file) == 0)
{
bufsize = pl->bufsize;
return pl->buffer;
}
}
pl = new plcache_entry;
pl->file = new CAmxxReader(file, sizeof(cell));
pl->buffer = NULL;
if (pl->file->GetStatus() != CAmxxReader::Err_None ||
pl->file->IsOldFile())
{
delete pl->file;
delete pl;
return NULL;
}
pl->bufsize = pl->file->GetBufferSize();
if (pl->bufsize)
{
pl->buffer = new char[pl->bufsize];
pl->file->GetSection(pl->buffer);
}
if (!pl->buffer || pl->file->GetStatus() != CAmxxReader::Err_None)
{
delete [] pl->buffer;
delete pl->file;
delete pl;
return NULL;
}
pl->path.assign(file);
bufsize = pl->bufsize;
m_plcache.push_back(pl);
return pl->buffer;
}
void CPluginMngr::InvalidateCache()
{
List<plcache_entry *>::iterator iter;
plcache_entry *pl;
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
{
pl = (*iter);
delete [] pl->buffer;
delete pl->file;
delete pl;
}
m_plcache.clear();
}
void CPluginMngr::InvalidateFileInCache(const char *file, bool freebuf)
{
List<plcache_entry *>::iterator iter;
plcache_entry *pl;
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
{
pl = (*iter);
if (pl->path.compare(file) == 0)
{
if (freebuf)
delete [] pl->buffer;
delete pl->file;
delete pl;
m_plcache.erase(iter);
return;
}
}
}
void CPluginMngr::CacheAndLoadModules(const char *plugin)
{
size_t progsize;
char *prog = ReadIntoOrFromCache(plugin, progsize);
if (!prog)
return;
AMX_HEADER hdr;
memcpy(&hdr, prog, sizeof(AMX_HEADER));
uint16_t magic = hdr.magic;
amx_Align16(&magic);
if (magic != AMX_MAGIC)
{
return;
}
if (hdr.file_version < MIN_FILE_VERSION ||
hdr.file_version > CUR_FILE_VERSION)
{
return;
}
if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) &&
(hdr.defsize != sizeof(AMX_FUNCSTUBNT)))
{
return;
}
amx_Align32((uint32_t*)&hdr.nametable);
uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable);
amx_Align16(namelength);
if (*namelength>sNAMEMAX)
{
return;
}
if (hdr.stp <= 0)
{
return;
}
AMX amx;
memset(&amx, 0, sizeof(AMX));
amx.base = (unsigned char *)prog;
int num;
char name[sNAMEMAX+1];
num = amx_GetLibraries(&amx);
for (int i=0; i<num; i++)
{
amx_GetLibrary(&amx, i, name, sNAMEMAX);
if (stricmp(name, "Float")==0)
continue;
//awful backwards compat hack
if (stricmp(name, "socket")==0)
strcpy(name, "sockets");
//we don't want to report failed modules here...
LoadModule(name, PT_ANYTIME, true, true);
}
cell tag_id;
amx_NumTags(&amx, &num);
CVector<LibDecoder *> expects;
CVector<LibDecoder *> defaults;
CStack<LibDecoder *> delstack;
for (int i=0; i<num; i++)
{
amx_GetTag(&amx, i, name, &tag_id);
if (name[0] == '?')
{
LibDecoder *dc = new LibDecoder;
delstack.push(dc);
if (DecodeLibCmdString(name, dc))
{
if (dc->cmd == LibCmd_ForceLib)
{
RunLibCommand(dc);
} else if ( (dc->cmd == LibCmd_ExpectClass) ||
(dc->cmd == LibCmd_ExpectLib) )
{
expects.push_back(dc);
} else if (dc->cmd == LibCmd_DefaultLib) {
defaults.push_back(dc);
}
}
}
}
for (size_t i=0; i<expects.size(); i++)
{
RunLibCommand(expects[i]);
}
for (size_t i=0; i<defaults.size(); i++)
{
RunLibCommand(defaults[i]);
}
expects.clear();
defaults.clear();
while (!delstack.empty())
{
delete delstack.front();
delstack.pop();
}
return;
}
void CPluginMngr::CALMFromFile(const char *file)
{
char filename[256];
FILE *fp = fopen(build_pathname_r(filename, sizeof(filename) - 1, "%s", file), "rt");
if (!fp)
{
return;
}
// Find now folder
char pluginName[256];
char line[256];
String rline;
while (!feof(fp))
{
fgets(line, sizeof(line)-1, fp);
if (line[0] == ';' || line[0] == '\n' || line[0] == '\0')
{
continue;
}
/** quick hack */
char *ptr = line;
while (*ptr)
{
if (*ptr == ';')
{
*ptr = '\0';
} else {
ptr++;
}
}
rline.assign(line);
rline.trim();
pluginName[0] = '\0';
sscanf(rline.c_str(), "%s", pluginName);
/* HACK: see if there's a 'disabled' coming up
* new block for scopying flexibility
*/
if (1)
{
const char *_ptr = rline.c_str() + strlen(pluginName);
while (*_ptr != '\0' && isspace(*_ptr))
{
_ptr++;
}
if ((*_ptr != '\0') && !strcmp(_ptr, "disabled"))
{
String *pString = new String(pluginName);
m_BlockList.push_back(pString);
continue;
}
}
if (!isalnum(*pluginName))
{
continue;
}
build_pathname_r(filename, sizeof(filename)-1, "%s/%s", get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"), pluginName);
CacheAndLoadModules(filename);
}
fclose(fp);
}

View File

@ -32,23 +32,18 @@
#ifndef PLUGIN_H #ifndef PLUGIN_H
#define PLUGIN_H #define PLUGIN_H
#include "CString.h"
#include "sh_list.h"
#include "amx.h"
#include "amxxfile.h"
// ***************************************************** // *****************************************************
// class CPluginMngr // class CPluginMngr
// ***************************************************** // *****************************************************
enum enum
{ {
ps_bad_load, //Load failed ps_bad_load,
ps_error, //Erroneous state ps_error,
ps_locked, //UNUSED ps_locked,
ps_paused, //Plugin is temporarily paused ps_paused,
ps_stopped, //Plugin is ... more temporarily paused ps_stopped,
ps_running, //Plugin is running ps_running,
}; };
class CPluginMngr class CPluginMngr
@ -71,7 +66,6 @@ public:
String author; String author;
String errorMsg; String errorMsg;
unsigned int failcounter;
int m_PauseFwd; int m_PauseFwd;
int m_UnpauseFwd; int m_UnpauseFwd;
int paused_fun; int paused_fun;
@ -99,11 +93,9 @@ public:
inline void setError(const char* n) { errorMsg.assign(n); } inline void setError(const char* n) { errorMsg.assign(n); }
inline bool isValid() const { return (status >= ps_paused); } inline bool isValid() const { return (status >= ps_paused); }
inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); } inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
inline bool isStopped() const { return (status == ps_stopped); }
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); } inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
void Finalize(); void Finalize();
void AddToFailCounter(unsigned int i);
void pausePlugin(); void pausePlugin();
void unpausePlugin(); void unpausePlugin();
void pauseFunction(int id); void pauseFunction(int id);
@ -119,7 +111,7 @@ private:
int pCounter; int pCounter;
public: public:
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;} CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
~CPluginMngr() { clear(); InvalidateCache(); } ~CPluginMngr() { clear(); }
bool m_Finalized; bool m_Finalized;
AMX_NATIVE_INFO *pNatives; AMX_NATIVE_INFO *pNatives;
@ -128,9 +120,9 @@ public:
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug); CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
void unloadPlugin(CPlugin** a); void unloadPlugin(CPlugin** a);
int loadPluginsFromFile(const char* filename, bool warn=true); int loadPluginsFromFile(const char* filename);
inline CPlugin* findPluginFast(AMX *amx) { return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); } CPlugin* findPluginFast(AMX *amx);
CPlugin* findPlugin(AMX *amx); CPlugin* findPlugin(AMX *amx);
CPlugin* findPlugin(int index); CPlugin* findPlugin(int index);
CPlugin* findPlugin(const char* name); CPlugin* findPlugin(const char* name);
@ -153,22 +145,6 @@ public:
inline iterator begin() const { return iterator(head); } inline iterator begin() const { return iterator(head); }
inline iterator end() const { return iterator(0); } inline iterator end() const { return iterator(0); }
public:
struct plcache_entry
{
CAmxxReader *file;
size_t bufsize;
char *buffer;
String path;
};
char *ReadIntoOrFromCache(const char *file, size_t &bufsize);
void InvalidateCache();
void InvalidateFileInCache(const char *file, bool freebuf);
void CacheAndLoadModules(const char *plugin);
void CALMFromFile(const char *file);
private:
List<plcache_entry *> m_plcache;
List<String *> m_BlockList;
}; };
#endif //PLUGIN_H #endif //PLUGIN_H

80
amxmodx/nongpl_matches.h → amxmodx/CStack.h Normal file → Executable file
View File

@ -29,23 +29,77 @@
* version. * version.
*/ */
#ifndef _INCLUDE_AMXMODX_NONGPL_MATCHES_H_ //by David "BAILOPAN" Anderson
#define _INCLUDE_AMXMODX_NONGPL_MATCHES_H_ #ifndef _INCLUDE_CSTACK_H
#define _INCLUDE_CSTACK_H
struct NONGPL_PLUGIN_T template <class T>
class CStack
{ {
const char *author; public:
const char *title; struct CStackItem
const char *filename; {
public:
T item;
CStackItem *prev;
}; };
struct NONGPL_CVAR_T public:
CStack()
{ {
const char *cvar; mSize = 0;
int type; mStack = NULL;
}
~CStack()
{
CStackItem *p, *t;
p = mStack;
while (p)
{
t = p->prev;
delete p;
p = t;
}
mStack = NULL;
}
bool empty()
{
return (mSize == 0);
}
void push(const T & v)
{
CStackItem *p = new CStackItem;
p->item = v;
p->prev = mStack;
mStack = p;
mSize++;
}
void pop()
{
CStackItem *p = mStack;
mStack = p->prev;
delete p;
mSize--;
}
T & top()
{
return mStack->item;
}
size_t size()
{
return mSize;
}
private:
CStackItem *mStack;
size_t mSize;
}; };
extern NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[]; #endif //_INCLUDE_CQUEUE_H
extern NONGPL_CVAR_T NONGPL_CVAR_LIST[];
#endif //_INCLUDE_AMXMODX_NONGPL_MATCHES_H_

View File

@ -66,7 +66,7 @@ public:
return ret; return ret;
} }
String(const String &src) String(String &src)
{ {
v = NULL; v = NULL;
a_size = 0; a_size = 0;
@ -107,10 +107,8 @@ public:
{ {
clear(); clear();
} else { } else {
size_t len = strlen(d); Grow(strlen(d) + 1, false);
Grow(len + 1, false); strcpy(v, d);
memcpy(v, d, len);
v[len] = '\0';
} }
} }
@ -120,7 +118,7 @@ public:
v[0] = '\0'; v[0] = '\0';
} }
int compare (const char *d) const int compare (const char *d)
{ {
if (!v) if (!v)
return strcmp("", d); return strcmp("", d);
@ -129,7 +127,7 @@ public:
} }
//Added this for amxx inclusion //Added this for amxx inclusion
bool empty() const bool empty()
{ {
if (!v) if (!v)
return true; return true;
@ -140,7 +138,7 @@ public:
return false; return false;
} }
size_t size() const size_t size()
{ {
if (v) if (v)
return strlen(v); return strlen(v);
@ -150,13 +148,13 @@ public:
int find(const char c, int index = 0) int find(const char c, int index = 0)
{ {
int len = static_cast<int>(size()); size_t len = size();
if (len < 1) if (len < 1)
return npos; return npos;
if (index >= len || index < 0) if (index >= (int)len || index < 0)
return npos; return npos;
int i = 0; unsigned int i = 0;
for (i=index; i<len; i++) for (i=index; i<(int)len; i++)
{ {
if (v[i] == c) if (v[i] == c)
{ {
@ -179,30 +177,6 @@ public:
return false; return false;
} }
void reparse_newlines()
{
size_t len = size();
int offs = 0;
char c;
if (!len)
return;
for (size_t i=0; i<len; i++)
{
c = v[i];
if (c == '^' && (i != len-1))
{
c = v[++i];
if (c == 'n')
c = '\n';
else if (c == 't')
c = '\t';
offs++;
}
v[i-offs] = c;
}
v[len-offs] = '\0';
}
void trim() void trim()
{ {
if (!v) if (!v)
@ -273,7 +247,7 @@ public:
unsigned int i = 0; unsigned int i = 0;
size_t len = size(); size_t len = size();
//check for bounds //check for bounds
if (num == npos || start+num > len-start) if (num == npos || start+num > len-num+1)
num = len - start; num = len - start;
//do the erasing //do the erasing
bool copyflag = false; bool copyflag = false;
@ -323,7 +297,7 @@ public:
num = len - index; num = len - index;
} }
unsigned int i = 0; unsigned int i = 0, j=0;
unsigned int nslen = num + 2; unsigned int nslen = num + 2;
ns.Grow(nslen); ns.Grow(nslen);

View File

@ -34,7 +34,17 @@
/*********************** CTask ***********************/ /*********************** CTask ***********************/
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime) int CTaskMngr::CTask::getTaskId() const
{
return m_iId;
}
CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
{
return m_pPlugin;
}
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
{ {
clear(); clear();
m_bFree = false; m_bFree = false;
@ -43,7 +53,6 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
m_iFunc = iFunc; m_iFunc = iFunc;
m_iId = iId; m_iId = iId;
m_fBase = fBase; m_fBase = fBase;
m_bInExecute = false;
if (iFlags & 2) if (iFlags & 2)
{ {
@ -141,7 +150,6 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
//only bother calling if we have something to call //only bother calling if we have something to call
if (!(m_bLoop && !m_iRepeat)) if (!(m_bLoop && !m_iRepeat))
{ {
m_bInExecute = true;
if (m_iParamLen) // call with parameters if (m_iParamLen) // call with parameters
{ {
cell arr = prepareCellArray(m_pParams, m_iParamLen); cell arr = prepareCellArray(m_pParams, m_iParamLen);
@ -149,7 +157,6 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
} else { } else {
executeForwards(m_iFunc, m_iId); executeForwards(m_iFunc, m_iId);
} }
m_bInExecute = false;
} }
if (isFree()) if (isFree())
@ -186,7 +193,6 @@ CTaskMngr::CTask::CTask()
m_bLoop = false; m_bLoop = false;
m_bAfterStart = false; m_bAfterStart = false;
m_bBeforeEnd = false; m_bBeforeEnd = false;
m_bInExecute = false;
m_fNextExecTime = 0.0f; m_fNextExecTime = 0.0f;
@ -220,7 +226,7 @@ void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pT
m_pTmr_TimeLeft = pTimeLeft; m_pTmr_TimeLeft = pTimeLeft;
} }
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat) void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
{ {
// first, search for free tasks // first, search for free tasks
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true)); TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));

View File

@ -41,11 +41,10 @@ private:
// task settings // task settings
CPluginMngr::CPlugin *m_pPlugin; CPluginMngr::CPlugin *m_pPlugin;
cell m_iId; int m_iId;
int m_iFunc; int m_iFunc;
int m_iRepeat; int m_iRepeat;
bool m_bInExecute;
bool m_bLoop; bool m_bLoop;
bool m_bAfterStart; bool m_bAfterStart;
bool m_bBeforeEnd; bool m_bBeforeEnd;
@ -58,19 +57,17 @@ private:
// execution // execution
float m_fNextExecTime; float m_fNextExecTime;
public: public:
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime); void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
void clear(); void clear();
bool isFree() const; bool isFree() const;
inline CPluginMngr::CPlugin *getPlugin() const { return m_pPlugin; } CPluginMngr::CPlugin *getPlugin() const;
inline AMX *getAMX() const { return m_pPlugin->getAMX(); } int getTaskId() const;
inline int getTaskId() const { return m_iId; }
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
void changeBase(float fNewBase); void changeBase(float fNewBase);
void resetNextExecTime(float fCurrentTime); void resetNextExecTime(float fCurrentTime);
inline bool inExecute() const { return m_bInExecute; }
bool shouldRepeat(); bool shouldRepeat();
@ -81,7 +78,7 @@ private:
class CTaskDescriptor class CTaskDescriptor
{ {
public: public:
cell m_iId; int m_iId;
AMX *m_pAmx; AMX *m_pAmx;
bool m_bFree; bool m_bFree;
@ -95,11 +92,9 @@ private:
friend bool operator == (const CTask &left, const CTaskDescriptor &right) friend bool operator == (const CTask &left, const CTaskDescriptor &right)
{ {
if (right.m_bFree) if (right.m_bFree)
return (left.isFree() && !left.inExecute()); return left.isFree();
return (!left.isFree()) && return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId;
(right.m_pAmx ? left.getAMX() == right.m_pAmx : true) &&
(left.getTaskId() == right.m_iId);
} }
}; };
@ -117,7 +112,7 @@ public:
~CTaskMngr(); ~CTaskMngr();
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat); void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx
int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx

View File

@ -37,20 +37,12 @@
// Vector // Vector
template <class T> class CVector template <class T> class CVector
{ {
bool Grow(size_t amount) bool Grow()
{ {
// automatic grow // automatic grow
size_t newSize = m_Size * 2; size_t newSize = m_Size * 2;
if (newSize == 0) if (newSize == 0)
{ newSize = 8; // a good init value
newSize = 8;
}
while (m_CurrentUsedSize + amount > newSize)
{
newSize *= 2;
}
T *newData = new T[newSize]; T *newData = new T[newSize];
if (!newData) if (!newData)
return false; return false;
@ -65,17 +57,13 @@ template <class T> class CVector
return true; return true;
} }
bool GrowIfNeeded(size_t amount) bool GrowIfNeeded()
{ {
if (m_CurrentUsedSize + amount >= m_Size) if (m_CurrentUsedSize >= m_Size)
{ return Grow();
return Grow(amount);
}
else else
{
return true; return true;
} }
}
bool ChangeSize(size_t size) bool ChangeSize(size_t size)
{ {
@ -341,13 +329,14 @@ public:
bool push_back(const T & elem) bool push_back(const T & elem)
{ {
if (!GrowIfNeeded(1)) ++m_CurrentUsedSize;
if (!GrowIfNeeded())
{ {
--m_CurrentUsedSize;
return false; return false;
} }
m_Data[m_CurrentUsedSize++] = elem; m_Data[m_CurrentUsedSize - 1] = elem;
return true; return true;
} }
@ -445,13 +434,13 @@ public:
size_t ofs = where - begin(); size_t ofs = where - begin();
if (!GrowIfNeeded(1)) ++m_CurrentUsedSize;
if (!GrowIfNeeded())
{ {
--m_CurrentUsedSize;
return false; return false;
} }
++m_CurrentUsedSize;
where = begin() + ofs; where = begin() + ofs;
// Move subsequent entries // Move subsequent entries

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,38 +1,27 @@
#(C)2004-2005 AMX Mod X Development Team #(C)2004-2005 AMX Mod X Development Team
# Makefile written by David "BAILOPAN" Anderson # Makefile written by David "BAILOPAN" Anderson
HLSDK = ../../hlsdk HLSDK = ../hlsdk/SourceCode
MM_ROOT = ../../metamod/metamod MM_ROOT = ../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O2 -fno-strict-aliasing -funroll-loops -s -fomit-frame-pointer -pipe OPT_FLAGS = -O2 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc-4.1 CPP = gcc
NAME = amxmodx NAME = amxmodx_mm
BIN_SUFFIX_32 = mm_i386.so
BIN_SUFFIX_64 = mm_amd64.so
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \ CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \ srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \ amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \ CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
amxmod_compat.cpp nongpl_matches.cpp CFlagManager.cpp datastructs.cpp
LINK = -lgcc -static-libgcc LINK = -lz
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \ INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common -I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
endif
ifeq "$(DEBUG)" "true" ifeq "$(DEBUG)" "true"
BIN_DIR = Debug BIN_DIR = Debug
CFLAGS = $(DEBUG_FLAGS) CFLAGS = $(DEBUG_FLAGS)
@ -41,27 +30,22 @@ else
CFLAGS = $(OPT_FLAGS) CFLAGS = $(OPT_FLAGS)
endif endif
ifeq "$(BINLOG)" "true" ifeq "$(MMGR)" "true"
NAME := $(NAME)_bl OBJECTS += mmgr/mmgr.cpp
BIN_DIR := $(BIN_DIR)BinLog CFLAGS += -DMEMORY_TEST
OBJECTS += binlog.cpp
CFLAGS += -DBINLOG_ENABLED
endif endif
CFLAGS += -DLINUX -DNDEBUG -DAMX_NOPROPLIST -fPIC -Wall -Werror -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
ifeq "$(AMD64)" "true" ifeq "$(AMD64)" "true"
BINARY = $(NAME)_$(BIN_SUFFIX_64) BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -DAMD64 -m64 CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
LINK += -lz64
OBJECTS += JIT/natives-amd64.o OBJECTS += JIT/natives-amd64.o
else else
BINARY = $(NAME)_$(BIN_SUFFIX_32) BINARY = $(NAME)_i386.so
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
OBJECTS += JIT/helpers-x86.o
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
LINK += -lz OPT_FLAGS += -march=i686
OPT_FLAGS += -march=i586
endif endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
@ -77,23 +61,23 @@ amd64:
rm -f zlib/libz.a rm -f zlib/libz.a
$(MAKE) all AMD64=true $(MAKE) all AMD64=true
amd64_mmgr:
rm -f zlib/libz.a
$(MAKE) all AMD64=true MMGR=true
amd64_debug_mmgr:
rm -f zlib/libz.a
$(MAKE) all AMD64=true DEBUG=true MMGR=true
amd64_debug: amd64_debug:
rm -f zlib/libz.a rm -f zlib/libz.a
$(MAKE) all AMD64=true DEBUG=true $(MAKE) all AMD64=true DEBUG=true
amd64_binlog: mmgr:
rm -f zlib/libz.a $(MAKE) all MMGR=true
$(MAKE) all AMD64=true BINLOG=true
amd64_binlog_debug: debug_mmgr:
rm -f zlib/libz.a $(MAKE) all MMGR=true DEBUG=true
$(MAKE) all AMD64=true BINLOG=true DEBUG=true
binlog:
$(MAKE) all BINLOG=true
binlog_debug:
$(MAKE) all BINLOG=true DEBUG=true
amxmodx: $(OBJ_LINUX) amxmodx: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
@ -105,14 +89,7 @@ default: all
clean: clean:
rm -rf Release/*.o rm -rf Release/*.o
rm -rf Release/$(NAME)_$(BIN_SUFFIX_32) rm -rf Release/$(BINARY)
rm -rf Release/$(NAME)_$(BIN_SUFFIX_64)
rm -rf ReleaseBinLog/*.o
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)
rm -rf Debug/*.o rm -rf Debug/*.o
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_32) rm -rf Debug/$(BINARY)
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_64)
rm -rf DebugBinLog/*.o
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)

View File

@ -24,7 +24,7 @@
#define AMX_NODYNALOAD #define AMX_NODYNALOAD
#define AMX_ANSIONLY #define AMX_ANSIONLY
#if !defined __linux__ && BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64 #if BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64
/* bad bad workaround but we have to prevent a compiler crash :/ */ /* bad bad workaround but we have to prevent a compiler crash :/ */
#pragma optimize("g",off) #pragma optimize("g",off)
#endif #endif
@ -46,7 +46,6 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include "osdefs.h" #include "osdefs.h"
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ #if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
#include <sclinux.h> #include <sclinux.h>
@ -266,13 +265,6 @@ typedef enum {
OP_SYSREQ_D, OP_SYSREQ_D,
OP_SYMTAG, /* obsolete */ OP_SYMTAG, /* obsolete */
OP_BREAK, OP_BREAK,
OP_FLOAT_MUL,
OP_FLOAT_DIV,
OP_FLOAT_ADD,
OP_FLOAT_SUB,
OP_FLOAT_TO,
OP_FLOAT_ROUND,
OP_FLOAT_CMP,
/* ----- */ /* ----- */
OP_NUM_OPCODES OP_NUM_OPCODES
} OPCODE; } OPCODE;
@ -452,7 +444,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
/* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore. /* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore.
* Otherwise, we'd have no way of knowing the last native to be used. * Otherwise, we'd have no way of knowing the last native to be used.
*/ */
amx->usertags[UT_NATIVE] = (void *)index; amx->usertags[UT_NATIVE] = (long)index;
/* Note: /* Note:
* params[0] == number of bytes for the additional parameters passed to the native function * params[0] == number of bytes for the additional parameters passed to the native function
@ -462,24 +454,8 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
amx->error=AMX_ERR_NONE; amx->error=AMX_ERR_NONE;
#if defined BINLOG_ENABLED
binlogfuncs_t *logfuncs = (binlogfuncs_t *)amx->usertags[UT_BINLOGS];
if (logfuncs)
{
logfuncs->pfnLogNative(amx, index, (int)(params[0] / sizeof(cell)));
logfuncs->pfnLogParams(amx, params);
}
#endif //BINLOG_ENABLED
*result = f(amx,params); *result = f(amx,params);
#if defined BINLOG_ENABLED
if (logfuncs)
{
logfuncs->pfnLogReturn(amx, *result);
}
#endif
return amx->error; return amx->error;
} }
#endif /* defined AMX_INIT */ #endif /* defined AMX_INIT */
@ -511,7 +487,6 @@ static int amx_BrowseRelocate(AMX *amx)
cell cip; cell cip;
long codesize; long codesize;
OPCODE op; OPCODE op;
BROWSEHOOK hook = NULL;
#if defined __GNUC__ || defined ASM32 || defined JIT #if defined __GNUC__ || defined ASM32 || defined JIT
cell *opcode_list; cell *opcode_list;
#endif #endif
@ -527,7 +502,6 @@ static int amx_BrowseRelocate(AMX *amx)
code=amx->base+(int)hdr->cod; code=amx->base+(int)hdr->cod;
codesize=hdr->dat - hdr->cod; codesize=hdr->dat - hdr->cod;
amx->flags|=AMX_FLAG_BROWSE; amx->flags|=AMX_FLAG_BROWSE;
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
/* sanity checks */ /* sanity checks */
assert(OP_PUSH_PRI==36); assert(OP_PUSH_PRI==36);
@ -633,22 +607,11 @@ static int amx_BrowseRelocate(AMX *amx)
case OP_FILL: case OP_FILL:
case OP_HALT: case OP_HALT:
case OP_BOUNDS: case OP_BOUNDS:
case OP_SYSREQ_C:
case OP_PUSHADDR: case OP_PUSHADDR:
case OP_SYSREQ_D: case OP_SYSREQ_D:
cip+=sizeof(cell); cip+=sizeof(cell);
break; break;
case OP_SYSREQ_C:
{
if (hook)
#if defined __GNUC__ || defined ASM32 || defined JIT
hook(amx, opcode_list, &cip);
#else
hook(amx, NULL, &cip);
#endif
else
cip+=sizeof(cell);
break;
}
case OP_LOAD_I: /* instructions without parameters */ case OP_LOAD_I: /* instructions without parameters */
case OP_STOR_I: case OP_STOR_I:
@ -709,13 +672,6 @@ static int amx_BrowseRelocate(AMX *amx)
case OP_SWAP_ALT: case OP_SWAP_ALT:
case OP_NOP: case OP_NOP:
case OP_BREAK: case OP_BREAK:
case OP_FLOAT_MUL:
case OP_FLOAT_DIV:
case OP_FLOAT_ADD:
case OP_FLOAT_SUB:
case OP_FLOAT_TO:
case OP_FLOAT_ROUND:
case OP_FLOAT_CMP:
break; break;
case OP_CALL: /* opcodes that need relocation */ case OP_CALL: /* opcodes that need relocation */
@ -843,7 +799,19 @@ static void expand(unsigned char *code, long codesize, long memsize)
int AMXAPI amx_Init(AMX *amx,void *program) int AMXAPI amx_Init(AMX *amx,void *program)
{ {
AMX_HEADER *hdr; AMX_HEADER *hdr;
BROWSEHOOK hook = NULL; #if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */
#if defined _Windows
typedef int (FAR WINAPI *AMX_ENTRY)(AMX _FAR *amx);
HINSTANCE hlib;
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
typedef int (*AMX_ENTRY)(AMX *amx);
void *hlib;
#endif
int numlibraries,i;
AMX_FUNCSTUB *lib;
AMX_ENTRY libinit;
#endif
if ((amx->flags & AMX_FLAG_RELOC)!=0) if ((amx->flags & AMX_FLAG_RELOC)!=0)
return AMX_ERR_INIT; /* already initialized (may not do so twice) */ return AMX_ERR_INIT; /* already initialized (may not do so twice) */
@ -853,6 +821,22 @@ int AMXAPI amx_Init(AMX *amx, void *program)
* multi-byte words * multi-byte words
*/ */
assert(check_endian()); assert(check_endian());
#if BYTE_ORDER==BIG_ENDIAN
amx_Align32((uint32_t*)&hdr->size);
amx_Align16(&hdr->magic);
amx_Align16((uint16_t*)&hdr->flags);
amx_Align16((uint16_t*)&hdr->defsize);
amx_Align32((uint32_t*)&hdr->cod);
amx_Align32((uint32_t*)&hdr->dat);
amx_Align32((uint32_t*)&hdr->hea);
amx_Align32((uint32_t*)&hdr->stp);
amx_Align32((uint32_t*)&hdr->cip);
amx_Align32((uint32_t*)&hdr->publics);
amx_Align32((uint32_t*)&hdr->natives);
amx_Align32((uint32_t*)&hdr->libraries);
amx_Align32((uint32_t*)&hdr->pubvars);
amx_Align32((uint32_t*)&hdr->tags);
#endif
if (hdr->magic!=AMX_MAGIC) if (hdr->magic!=AMX_MAGIC)
return AMX_ERR_FORMAT; return AMX_ERR_FORMAT;
@ -873,7 +857,13 @@ int AMXAPI amx_Init(AMX *amx, void *program)
} /* if */ } /* if */
if (hdr->stp<=0) if (hdr->stp<=0)
return AMX_ERR_FORMAT; return AMX_ERR_FORMAT;
#if BYTE_ORDER==BIG_ENDIAN
if ((hdr->flags & AMX_FLAG_COMPACT)==0) {
ucell *code=(ucell *)((unsigned char *)program+(int)hdr->cod);
while (code<(ucell *)((unsigned char *)program+(int)hdr->hea))
swapcell(code++);
} /* if */
#endif
assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size); assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size);
if ((hdr->flags & AMX_FLAG_COMPACT)!=0) { if ((hdr->flags & AMX_FLAG_COMPACT)!=0) {
#if AMX_COMPACTMARGIN > 2 #if AMX_COMPACTMARGIN > 2
@ -900,18 +890,111 @@ int AMXAPI amx_Init(AMX *amx, void *program)
amx->callback=amx_Callback; amx->callback=amx_Callback;
amx->data=NULL; amx->data=NULL;
/* also align all addresses in the public function, public variable,
* public tag and native function tables --offsets into the name table
* (if present) must also be swapped.
*/
#if BYTE_ORDER==BIG_ENDIAN
{ /* local */
AMX_FUNCSTUB *fs;
int i,num;
fs=GETENTRY(hdr,natives,0);
num=NUMENTRIES(hdr,natives,libraries);
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address); /* redundant, because it should be zero */
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
fs=GETENTRY(hdr,publics,0);
assert(hdr->publics<=hdr->natives);
num=NUMENTRIES(hdr,publics,natives);
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address);
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
fs=GETENTRY(hdr,pubvars,0);
assert(hdr->pubvars<=hdr->tags);
num=NUMENTRIES(hdr,pubvars,tags);
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address);
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
fs=GETENTRY(hdr,tags,0);
if (hdr->file_version<7) {
assert(hdr->tags<=hdr->cod);
num=NUMENTRIES(hdr,tags,cod);
} else {
assert(hdr->tags<=hdr->nametable);
num=NUMENTRIES(hdr,tags,nametable);
} /* if */
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address);
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
} /* local */
#endif
/* relocate call and jump instructions */ /* relocate call and jump instructions */
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
if (hook)
hook(amx, NULL, NULL);
amx_BrowseRelocate(amx); amx_BrowseRelocate(amx);
/* load any extension modules that the AMX refers to */
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
hdr=(AMX_HEADER *)amx->base;
numlibraries=NUMENTRIES(hdr,libraries,pubvars);
for (i=0; i<numlibraries; i++) {
lib=GETENTRY(hdr,libraries,i);
strcpy(libname,"amx");
strcat(libname,GETENTRYNAME(hdr,lib));
#if defined _Windows
strcat(libname,".dll");
#if defined __WIN32__
hlib=LoadLibraryA(libname);
#else
hlib=LoadLibrary(libname);
if (hlib<=HINSTANCE_ERROR)
hlib=NULL;
#endif
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
strcat(libname,".so");
hlib=dlopen(libname,RTLD_NOW);
#endif
if (hlib!=NULL) {
/* a library that cannot be loaded or that does not have the required
* initialization function is simply ignored
*/
char funcname[sNAMEMAX+9]; /* +1 for '\0', +4 for 'amx_', +4 for 'Init' */
strcpy(funcname,"amx_");
strcat(funcname,GETENTRYNAME(hdr,lib));
strcat(funcname,"Init");
#if defined _Windows
libinit=(AMX_ENTRY)GetProcAddress(hlib,funcname);
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
libinit=(AMX_ENTRY)dlsym(hlib,funcname);
#endif
if (libinit!=NULL)
libinit(amx);
} /* if */
lib->address=(ucell)hlib;
} /* for */
#endif
return AMX_ERR_NONE; return AMX_ERR_NONE;
} }
#if defined JIT #if defined JIT
#define CODESIZE_JIT 65536 /* approximate size of the code for the JIT */ #define CODESIZE_JIT 8192 /* approximate size of the code for the JIT */
#if defined __WIN32__ /* this also applies to Win32 "console" applications */ #if defined __WIN32__ /* this also applies to Win32 "console" applications */
@ -973,25 +1056,26 @@ int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
memcpy(native_code, amx->base, ((AMX_HEADER *)(amx->base))->cod); memcpy(native_code, amx->base, ((AMX_HEADER *)(amx->base))->cod);
hdr = (AMX_HEADER *)native_code; hdr = (AMX_HEADER *)native_code;
/* JIT rulz! (TM) */ /* JIT rulz! (TM) */
/* MP: added check for correct compilation */ /* MP: added check for correct compilation */
//Fixed bug (thanks T(+)rget) //Fixed bug (thanks T(+)rget)
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) == 0) if ((res = asm_runJIT(amx->base, reloc_table, native_code)) == 0)
{ {
/* update the required memory size (the previous value was a
* conservative estimate, now we know the exact size)
*/
amx->code_size = (hdr->dat + hdr->stp + 3) & ~3;
/* The compiled code is relocatable, since only relative jumps are /* The compiled code is relocatable, since only relative jumps are
* used for destinations within the generated code and absoulute * used for destinations within the generated code and absoulute
* addresses for jumps into the runtime, which is fixed in memory. * addresses for jumps into the runtime, which is fixed in memory.
*/ */
amx->base = (unsigned char*) native_code; amx->base = (unsigned char*) native_code;
amx->cip = hdr->cip; amx->cip = hdr->cip;
amx->hea = hdr->hea;
amx->stp = hdr->stp - sizeof(cell);
/* also put a sentinel for strings at the top the stack */ /* also put a sentinel for strings at the top the stack */
*(cell *)((char*)native_code + hdr->dat + amx->stp - sizeof(cell)) = 0; *(cell *)((char*)native_code + hdr->dat + hdr->stp - sizeof(cell)) = 0;
/* update the required memory size (the previous value was a amx->stk = amx->stp;
* conservative estimate, now we know the exact size)
*/
amx->code_size = (hdr->dat + amx->stp + sizeof(cell)) & ~3;
} /* if */ } /* if */
return (res == 0) ? AMX_ERR_NONE : AMX_ERR_INIT_JIT; return (res == 0) ? AMX_ERR_NONE : AMX_ERR_INIT_JIT;
@ -1175,22 +1259,27 @@ int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname)
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index) int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
{ {
int first,last,mid; int first,last,mid,result;
char pname[sNAMEMAX+1]; char pname[sNAMEMAX+1];
amx_NumNatives(amx, &last); amx_NumNatives(amx, &last);
last--; /* last valid index is 1 less than the number of functions */ last--; /* last valid index is 1 less than the number of functions */
first=0; first=0;
/* normal search */ /* binary search */
for (mid=0; mid<=last; mid++) while (first<=last) {
{ mid=(first+last)/2;
amx_GetNative(amx, mid, pname); amx_GetNative(amx, mid, pname);
if (strcmp(pname, name)==0) result=strcmp(pname,name);
{ if (result>0) {
last=mid-1;
} else if (result<0) {
first=mid+1;
} else {
*index=mid; *index=mid;
return AMX_ERR_NONE; return AMX_ERR_NONE;
} /* if */ } /* if */
} /* for */ } /* while */
/* not found, set to an invalid index, so amx_Exec() will fail */
*index=INT_MAX; *index=INT_MAX;
return AMX_ERR_NOTFOUND; return AMX_ERR_NOTFOUND;
} }
@ -1403,11 +1492,37 @@ int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
#if defined AMX_XXXUSERDATA #if defined AMX_XXXUSERDATA
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr) int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
{ {
int index;
assert(amx!=NULL);
assert(tag!=0);
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
/* nothing */;
if (index>=AMX_USERNUM)
return AMX_ERR_USERDATA;
*ptr=amx->userdata[index];
return AMX_ERR_NONE; return AMX_ERR_NONE;
} }
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr) int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
{ {
int index;
assert(amx!=NULL);
assert(tag!=0);
/* try to find existing tag */
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
/* nothing */;
/* if not found, try to find empty tag */
if (index>=AMX_USERNUM)
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=0; index++)
/* nothing */;
/* if still not found, quit with error */
if (index>=AMX_USERNUM)
return AMX_ERR_INDEX;
/* set the tag and the value */
amx->usertags[index]=tag;
amx->userdata[index]=ptr;
return AMX_ERR_NONE; return AMX_ERR_NONE;
} }
#endif /* AMX_XXXUSERDATA */ #endif /* AMX_XXXUSERDATA */
@ -1480,36 +1595,6 @@ int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f)
return err; return err;
} }
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *list, int number)
{
AMX_FUNCSTUB *func;
AMX_HEADER *hdr;
int i,numnatives,count=0;
AMX_NATIVE funcptr;
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
numnatives=NUMENTRIES(hdr,natives,libraries);
count=0;
func=GETENTRY(hdr,natives,0);
for (i=0; i<numnatives; i++) {
if (func->address!=0) {
/* this function is located */
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
if (funcptr!=NULL)
{
func->address=(ucell)funcptr;
count++;
}
} /* if */
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
} /* for */
return count;
}
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number) int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
{ {
AMX_FUNCSTUB *func; AMX_FUNCSTUB *func;
@ -1679,16 +1764,13 @@ static const void * const amx_opcodelist[] = {
&&op_file, &&op_line, &&op_symbol, &&op_srange, &&op_file, &&op_line, &&op_symbol, &&op_srange,
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri, &&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
&&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d, &&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d,
&&op_symtag, &&op_break, &&op_float_mul, &&op_float_div, &&op_symtag, &&op_break };
&&op_float_add, &&op_float_sub, &&op_float_to, &&op_float_round,
&&op_float_cmp};
AMX_HEADER *hdr; AMX_HEADER *hdr;
AMX_FUNCSTUB *func; AMX_FUNCSTUB *func;
unsigned char *code, *data; unsigned char *code, *data;
cell pri,alt,stk,frm,hea; cell pri,alt,stk,frm,hea;
cell reset_stk, reset_hea, *cip; cell reset_stk, reset_hea, *cip;
cell offs, offs2; cell offs;
REAL fnum, fnum2;
ucell codesize; ucell codesize;
int num,i; int num,i;
@ -2534,59 +2616,6 @@ static const void * const amx_opcodelist[] = {
NEXT(cip); NEXT(cip);
op_nop: op_nop:
NEXT(cip); NEXT(cip);
op_float_mul:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) * amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_add:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) + amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_sub:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) - amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_div:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) / amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_to:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
fnum = (REAL)offs;
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_round:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
if (!offs2)
fnum = floor(fnum + 0.5);
else if (offs2 == 1)
fnum = floor(fnum);
else
fnum = ceil(fnum);
pri = (cell)fnum;
NEXT(cip);
op_float_cmp:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
fnum2 = amx_ctof(offs2);
if (fnum == fnum2)
pri = 0;
else if (fnum > fnum2)
pri = 1;
else
pri = -1;
NEXT(cip);
op_break: op_break:
if (amx->debug!=NULL) { if (amx->debug!=NULL) {
/* store status */ /* store status */
@ -2671,8 +2700,7 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
cell parms[9]; /* registers and parameters for assembler AMX */ cell parms[9]; /* registers and parameters for assembler AMX */
#else #else
OPCODE op; OPCODE op;
cell offs, offs2; cell offs;
REAL fnum, fnum2;
int num; int num;
#endif #endif
assert(amx!=NULL); assert(amx!=NULL);
@ -3563,59 +3591,6 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
break; break;
case OP_NOP: case OP_NOP:
break; break;
case OP_FLOAT_MUL:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) * amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_ADD:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) + amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_SUB:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) - amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_DIV:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) / amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_TO:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
fnum = (float)offs;
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_ROUND:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
if (!offs2)
fnum = (REAL)floor(fnum + 0.5);
else if (offs2 == 1)
fnum = floor(fnum);
else
fnum = ceil(fnum);
pri = (cell)fnum;
break;
case OP_FLOAT_CMP:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
fnum2 = amx_ctof(offs2);
if (fnum == fnum2)
pri = 0;
else if (fnum > fnum2)
pri = 1;
else
pri = -1;
break;
case OP_BREAK: case OP_BREAK:
assert((amx->flags & AMX_FLAG_BROWSE)==0); assert((amx->flags & AMX_FLAG_BROWSE)==0);
if (amx->debug!=NULL) { if (amx->debug!=NULL) {

View File

@ -79,6 +79,15 @@
#endif #endif
#endif #endif
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
#if !defined alloca
#define alloca(n) _alloca(n)
#endif
#endif
#if !defined arraysize #if !defined arraysize
#define arraysize(array) (sizeof(array) / sizeof((array)[0])) #define arraysize(array) (sizeof(array) / sizeof((array)[0]))
#endif #endif
@ -166,14 +175,6 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
#pragma warning(disable:4103) /* disable warning message 4103 that complains #pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */ * about pragma pack in a header file */
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */ #pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
#if _MSC_VER >= 1400
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
#define stricmp _stricmp
// Need this because of some stupid bug
#pragma warning (disable : 4996)
#endif
#endif #endif
/* Some compilers do not support the #pragma align, which should be fine. Some /* Some compilers do not support the #pragma align, which should be fine. Some
@ -214,7 +215,7 @@ typedef struct tagAMX_NATIVE_INFO {
typedef struct tagAMX_FUNCSTUB { typedef struct tagAMX_FUNCSTUB {
ucell address PACKED; ucell address PACKED;
char name[sEXPMAX+1]; char name[sEXPMAX+1] PACKED;
} PACKED AMX_FUNCSTUB; } PACKED AMX_FUNCSTUB;
typedef struct tagFUNCSTUBNT { typedef struct tagFUNCSTUBNT {
@ -239,7 +240,7 @@ typedef struct tagAMX {
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
int flags PACKED; /* current status, see amx_Flags() */ int flags PACKED; /* current status, see amx_Flags() */
/* user data */ /* user data */
void _FAR *usertags[AMX_USERNUM] PACKED; long usertags[AMX_USERNUM] PACKED;
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer //okay userdata[3] in AMX Mod X is for the CPlugin * pointer
//we're also gonna set userdata[2] to a special debug structure //we're also gonna set userdata[2] to a special debug structure
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate //lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
@ -265,8 +266,8 @@ typedef struct tagAMX {
typedef struct tagAMX_HEADER { typedef struct tagAMX_HEADER {
int32_t size PACKED; /* size of the "file" */ int32_t size PACKED; /* size of the "file" */
uint16_t magic PACKED; /* signature */ uint16_t magic PACKED; /* signature */
char file_version; /* file format version */ char file_version PACKED; /* file format version */
char amx_version; /* required version of the AMX */ char amx_version PACKED; /* required version of the AMX */
int16_t flags PACKED; int16_t flags PACKED;
int16_t defsize PACKED; /* size of a definition record */ int16_t defsize PACKED; /* size of a definition record */
int32_t cod PACKED; /* initial value of COD - code block */ int32_t cod PACKED; /* initial value of COD - code block */
@ -322,7 +323,6 @@ enum {
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */ #define AMX_FLAG_COMPACT 0x04 /* compact encoding */
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */ #define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */ #define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
#define AMX_FLAG_OLDFILE 0x20 /* Old AMX Mod plugin */
#define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */ #define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */ #define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */ #define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
@ -343,11 +343,6 @@ enum {
#define UD_OPCODELIST 1 #define UD_OPCODELIST 1
#define UD_HANDLER 0 #define UD_HANDLER 0
#define UT_NATIVE 3 #define UT_NATIVE 3
#define UT_OPTIMIZER 2
#define UT_BROWSEHOOK 1
#define UT_BINLOGS 0
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
/* for native functions that use floating point parameters, the following /* for native functions that use floating point parameters, the following
* two macros are convenient for casting a "cell" into a "float" type _without_ * two macros are convenient for casting a "cell" into a "float" type _without_
@ -411,7 +406,6 @@ int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar); int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
int AMXAPI amx_RaiseError(AMX *amx, int error); int AMXAPI amx_RaiseError(AMX *amx, int error);
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number); int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f); int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f);
int AMXAPI amx_Release(AMX *amx, cell amx_addr); int AMXAPI amx_Release(AMX *amx, cell amx_addr);
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback); int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
@ -451,15 +445,6 @@ int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
#endif #endif
#endif #endif
#if defined BINLOG_ENABLED
typedef struct tagBINLOG
{
void (*pfnLogNative)(AMX *amx, int native, int params);
void (*pfnLogReturn)(AMX *amx, cell retval);
void (*pfnLogParams)(AMX *amx, cell *params);
} binlogfuncs_t;
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -65,8 +65,8 @@ extern "C" {
typedef struct tagAMX_DBG_HDR { typedef struct tagAMX_DBG_HDR {
int32_t size PACKED; /* size of the debug information chunk */ int32_t size PACKED; /* size of the debug information chunk */
uint16_t magic PACKED; /* signature, must be 0xf1ef */ uint16_t magic PACKED; /* signature, must be 0xf1ef */
char file_version; /* file format version */ char file_version PACKED; /* file format version */
char amx_version; /* required version of the AMX */ char amx_version PACKED; /* required version of the AMX */
int16_t flags PACKED; /* currently unused */ int16_t flags PACKED; /* currently unused */
int16_t files PACKED; /* number of entries in the "file" table */ int16_t files PACKED; /* number of entries in the "file" table */
int16_t lines PACKED; /* number of entries in the "line" table */ int16_t lines PACKED; /* number of entries in the "line" table */
@ -74,51 +74,51 @@ typedef struct tagAMX_DBG_HDR {
int16_t tags PACKED; /* number of entries in the "tag" table */ int16_t tags PACKED; /* number of entries in the "tag" table */
int16_t automatons PACKED; /* number of entries in the "automaton" table */ int16_t automatons PACKED; /* number of entries in the "automaton" table */
int16_t states PACKED; /* number of entries in the "state" table */ int16_t states PACKED; /* number of entries in the "state" table */
} PACKED AMX_DBG_HDR; } AMX_DBG_HDR PACKED;
#define AMX_DBG_MAGIC 0xf1ef #define AMX_DBG_MAGIC 0xf1ef
typedef struct tagAMX_DBG_FILE { typedef struct tagAMX_DBG_FILE {
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */ ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
const char name[1]; /* ASCII string, zero-terminated */ const char name[1] PACKED; /* ASCII string, zero-terminated */
} PACKED AMX_DBG_FILE; } AMX_DBG_FILE PACKED;
typedef struct tagAMX_DBG_LINE { typedef struct tagAMX_DBG_LINE {
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */ ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
int32_t line PACKED; /* line number */ int32_t line PACKED; /* line number */
} PACKED AMX_DBG_LINE; } AMX_DBG_LINE PACKED;
typedef struct tagAMX_DBG_SYMBOL { typedef struct tagAMX_DBG_SYMBOL {
ucell address PACKED; /* address in the data segment or relative to the frame */ ucell address PACKED; /* address in the data segment or relative to the frame */
int16_t tag PACKED; /* tag for the symbol */ int16_t tag PACKED; /* tag for the symbol */
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */ ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */ ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
char ident; /* kind of symbol (function/variable) */ char ident PACKED; /* kind of symbol (function/variable) */
char vclass; /* class of symbol (global/local) */ char vclass PACKED; /* class of symbol (global/local) */
int16_t dim PACKED; /* number of dimensions */ int16_t dim PACKED; /* number of dimensions */
const char name[1]; /* ASCII string, zero-terminated */ const char name[1] PACKED; /* ASCII string, zero-terminated */
} PACKED AMX_DBG_SYMBOL; } AMX_DBG_SYMBOL PACKED;
typedef struct tagAMX_DBG_SYMDIM { typedef struct tagAMX_DBG_SYMDIM {
int16_t tag PACKED; /* tag for the array dimension */ int16_t tag PACKED; /* tag for the array dimension */
ucell size PACKED; /* size of the array dimension */ ucell size PACKED; /* size of the array dimension */
} PACKED AMX_DBG_SYMDIM; } AMX_DBG_SYMDIM PACKED;
typedef struct tagAMX_DBG_TAG { typedef struct tagAMX_DBG_TAG {
int16_t tag PACKED; /* tag id */ int16_t tag PACKED; /* tag id */
const char name[1]; /* ASCII string, zero-terminated */ const char name[1] PACKED; /* ASCII string, zero-terminated */
} PACKED AMX_DBG_TAG; } AMX_DBG_TAG PACKED;
typedef struct tagAMX_DBG_MACHINE { typedef struct tagAMX_DBG_MACHINE {
int16_t automaton PACKED; /* automaton id */ int16_t automaton PACKED; /* automaton id */
ucell address PACKED; /* address of state variable */ ucell address PACKED; /* address of state variable */
const char name[1]; /* ASCII string, zero-terminated */ const char name[1] PACKED; /* ASCII string, zero-terminated */
} PACKED AMX_DBG_MACHINE; } AMX_DBG_MACHINE PACKED;
typedef struct tagAMX_DBG_STATE { typedef struct tagAMX_DBG_STATE {
int16_t state PACKED; /* state id */ int16_t state PACKED; /* state id */
int16_t automaton PACKED; /* automaton id */ int16_t automaton PACKED; /* automaton id */
const char name[1]; /* ASCII string, zero-terminated */ const char name[1] PACKED; /* ASCII string, zero-terminated */
} PACKED AMX_DBG_STATE; } AMX_DBG_STATE PACKED;
typedef struct tagAMX_DBG { typedef struct tagAMX_DBG {
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */ AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
@ -128,7 +128,7 @@ typedef struct tagAMX_DBG {
AMX_DBG_TAG _FAR **tagtbl PACKED; AMX_DBG_TAG _FAR **tagtbl PACKED;
AMX_DBG_MACHINE _FAR **automatontbl PACKED; AMX_DBG_MACHINE _FAR **automatontbl PACKED;
AMX_DBG_STATE _FAR **statetbl PACKED; AMX_DBG_STATE _FAR **statetbl PACKED;
} PACKED AMX_DBG; } AMX_DBG PACKED;
#if !defined iVARIABLE #if !defined iVARIABLE
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */ #define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */

View File

@ -56,8 +56,6 @@
; ;
;History (list of changes) ;History (list of changes)
;------------------------- ;-------------------------
; 10 february 2006 by David Anderson
; Addition of float opcodes
; 17 february 2005 by Thiadmer Riemersms ; 17 february 2005 by Thiadmer Riemersms
; Addition of the BREAK opcode, removal of the older debugging opcode table. ; Addition of the BREAK opcode, removal of the older debugging opcode table.
; 6 march 2004 by Thiadmer Riemersma ; 6 march 2004 by Thiadmer Riemersma
@ -1408,108 +1406,6 @@ OP_NOP:
add esi,4 add esi,4
GO_ON GO_ON
OP_FLOAT_MUL:
add esi,4
fld dword [edi+ecx+4]
fmul dword [edi+ecx+8]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_DIV:
add esi,4
fld dword [edi+ecx+4]
fdiv dword [edi+ecx+8]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_ADD:
add esi,4
fld dword [edi+ecx+4]
fadd dword [edi+ecx+8]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_SUB:
add esi,4
fld dword [edi+ecx+4]
fsub dword [edi+ecx+8]
sub esp, 4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_TO:
add esi,4
fild dword [edi+ecx+4]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_ROUND:
add esi,4
;get the float control word
push 0
mov ebp,esp
fstcw [ebp]
mov eax,[ebp]
push eax
;clear the top bits
xor ah,ah
;get the control method
push edx
mov edx,[edi+ecx+8]
and edx,3 ;sanity check
shl edx,2 ;shift it to right position
;set the bits
or ah,dl ;set bits 15,14 of FCW to rounding method
or ah,3 ;set precision to 64bit
mov [ebp], eax
fldcw [ebp]
;calculate
sub esp,4
fld dword [edi+ecx+4]
test edx,edx
jz .correct
jmp .skip_correct
.correct:
fadd st0
fadd dword [g_round_nearest]
fistp dword [esp]
pop eax
sar eax,1
jmp .done
.skip_correct:
frndint
fistp dword [esp]
pop eax
.done:
pop edx
;restore bits
pop ebp
mov [esp], ebp
fldcw [esp]
pop ebp
GO_ON
OP_FLOAT_CMP:
add esi, 4
fld dword [edi+ecx+8]
fld dword [edi+ecx+4]
fucompp
fnstsw ax
fwait
sahf
cmovz eax, [g_flags+4]
cmova eax, [g_flags+8]
cmovb eax, [g_flags+0]
GO_ON
OP_BREAK: OP_BREAK:
mov ebp,amx ; get amx into ebp mov ebp,amx ; get amx into ebp
@ -1605,14 +1501,6 @@ Start_DATA
lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh
g_round_nearest DD 0.5
GLOBAL g_flags
g_flags:
DD -1
DD 0
DD 1
GLOBAL amx_opcodelist GLOBAL amx_opcodelist
GLOBAL _amx_opcodelist GLOBAL _amx_opcodelist
amx_opcodelist: amx_opcodelist:
@ -1754,10 +1642,4 @@ _amx_opcodelist DD OP_INVALID
DD OP_SYSREQ_D DD OP_SYSREQ_D
DD OP_SYMTAG DD OP_SYMTAG
DD OP_BREAK DD OP_BREAK
DD OP_FLOAT_MUL
DD OP_FLOAT_DIV
DD OP_FLOAT_ADD
DD OP_FLOAT_SUB
DD OP_FLOAT_TO
DD OP_FLOAT_ROUND
DD OP_FLOAT_CMP

View File

@ -304,11 +304,7 @@
%endmacro %endmacro
%ifdef WIN32
section .data exec
%else
section .text section .text
%endif
global asm_runJIT, _asm_runJIT global asm_runJIT, _asm_runJIT
@ -441,9 +437,7 @@ reloc_done:
; in the compiled code. This is fine, but the .text section in an ELF executable ; in the compiled code. This is fine, but the .text section in an ELF executable
; is usually marked read-only, that's why this code is in the .data section. ; is usually marked read-only, that's why this code is in the .data section.
%ifndef WIN32
section .data exec section .data exec
%endif
OP_LOAD_PRI: OP_LOAD_PRI:
;nop; ;nop;
@ -1882,7 +1876,7 @@ OP_BREAK:
jae code_gen_done jae code_gen_done
jmp DWORD [ebx] ; go on with the next opcode jmp DWORD [ebx] ; go on with the next opcode
%else %else
GO_ON j_break, OP_FLOAT_MUL GO_ON j_break, OP_INVALID
j_break: j_break:
mov ebp,amx mov ebp,amx
cmp DWORD [ebp+_debug], 0 cmp DWORD [ebp+_debug], 0
@ -1891,116 +1885,6 @@ OP_BREAK:
CHECKCODESIZE j_break CHECKCODESIZE j_break
%endif %endif
OP_FLOAT_MUL:
GO_ON j_float_mul, OP_FLOAT_DIV
j_float_mul:
fld dword [esi+4]
fmul dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_mul
OP_FLOAT_DIV:
GO_ON j_float_div, OP_FLOAT_ADD
j_float_div:
fld dword [esi+4]
fdiv dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_div
OP_FLOAT_ADD:
GO_ON j_float_add, OP_FLOAT_SUB
j_float_add:
fld dword [esi+4]
fadd dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_add
OP_FLOAT_SUB:
GO_ON j_float_sub, OP_FLOAT_TO
j_float_sub:
fld dword [esi+4]
fsub dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_sub
OP_FLOAT_TO:
GO_ON j_float_to, OP_FLOAT_ROUND
j_float_to:
fild dword [esi+4]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_to
OP_FLOAT_ROUND:
GO_ON j_float_round, OP_FLOAT_CMP
j_float_round:
;get the float control word
push 0
mov ebp,esp
fstcw [ebp]
mov eax,[ebp]
push eax
;clear the top bits
xor ah,ah
;get the control method
push edx
mov edx,[esi+8]
and edx,3 ;sanity check
shl edx,2 ;shift it to right position
;set the bits
or ah,dl ;set bits 15,14 of FCW to rounding method
or ah,3 ;set precision to 64bit
mov [ebp], eax
fldcw [ebp]
;calculate
sub esp,4
fld dword [esi+4]
test edx,edx
jz .correct
jmp .skip_correct
.correct:
fadd st0
fadd dword [g_round_nearest]
fistp dword [esp]
pop eax
sar eax,1
jmp .done
.skip_correct:
frndint
fistp dword [esp]
pop eax
.done:
pop edx
;restore bits
pop ebp
mov [esp], ebp
fldcw [esp]
pop ebp
CHECKCODESIZE j_float_round
OP_FLOAT_CMP:
GO_ON j_float_cmp, OP_INVALID
j_float_cmp:
fld dword [esi+8]
fld dword [esi+4]
fucompp
fnstsw ax
fwait
sahf
cmovz eax, [g_flagsjit+4]
cmova eax, [g_flagsjit+8]
cmovb eax, [g_flagsjit+0]
CHECKCODESIZE j_float_cmp
OP_INVALID: ; break from the compiler with an error code OP_INVALID: ; break from the compiler with an error code
mov eax,AMX_ERR_INVINSTR mov eax,AMX_ERR_INVINSTR
pop esi pop esi
@ -2122,9 +2006,7 @@ err_heaplow:
_CHKMARGIN_HEAP: _CHKMARGIN_HEAP:
cmp esi,stp cmp esi,stp
jg err_stacklow jg err_stacklow
mov ebp,amx cmp dword hea,0
mov ebp,[ebp+_hlw]
cmp dword hea,ebp
jl err_heaplow jl err_heaplow
ret ret
@ -2431,16 +2313,6 @@ jit_switch DD JIT_OP_SWITCH
; The table for the browser/relocator function. ; The table for the browser/relocator function.
; ;
global g_flagsjit
g_flagsjit:
DD -1
DD 0
DD 1
global g_round_nearest
g_round_nearest:
DD 0.5
global amx_opcodelist_jit, _amx_opcodelist_jit global amx_opcodelist_jit, _amx_opcodelist_jit
amx_opcodelist_jit: amx_opcodelist_jit:
@ -2583,12 +2455,5 @@ _amx_opcodelist_jit:
DD OP_SYSREQ_D ; TR DD OP_SYSREQ_D ; TR
DD OP_SYMTAG ; TR DD OP_SYMTAG ; TR
DD OP_BREAK ; TR DD OP_BREAK ; TR
DD OP_FLOAT_MUL ; DA
DD OP_FLOAT_DIV ; DA
DD OP_FLOAT_ADD ; DA
DD OP_FLOAT_SUB ; DA
DD OP_FLOAT_TO ; DA
DD OP_FLOAT_ROUND ; DA
DD OP_FLOAT_CMP ; DA
END END

View File

@ -1,117 +0,0 @@
#include "amxmodx.h"
#include "amxmod_compat.h"
#include "format.h"
bool GetTranslation(amxtrans_t trans, int &key, int &dest, int &lang)
{
key = (trans & BCOMPAT_TRANSLATE_KEYMASK);
dest = (trans >> BCOMPAT_TRANSLATE_DESTRSH) & BCOMPAT_TRANSLATE_DESTMASK;
lang = (trans >> BCOMPAT_TRANSLATE_LANGRSH) & BCOMPAT_TRANSLATE_LANGMASK;
if (dest == 0x3F)
{
dest = -1;
}
if (lang == 0x1F)
{
lang = -1;
}
return true;
}
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def)
{
amxtrans_t trans = static_cast<amxtrans_t>(*source);
int key, _dest, lang;
if (!GetTranslation(trans, key, _dest, lang))
{
return false;
}
cell amx_addr, *phys_addr;
if (amx_Allot(amx, 3, &amx_addr, &phys_addr) != AMX_ERR_NONE)
{
return false;
}
if (_dest == -1)
{
*phys_addr = LANG_PLAYER;
} else if (_dest == 0) {
*phys_addr = LANG_SERVER;
} else if (lang >= 0 && lang < g_langMngr.GetLangsNum()) {
const char *name = g_langMngr.GetLangName(lang);
phys_addr[0] = static_cast<cell>(name[0]);
phys_addr[1] = static_cast<cell>(name[1]);
phys_addr[2] = static_cast<cell>('\0');
} else {
*phys_addr = LANG_SERVER;
}
//not optimized but it works, eh
//if someone cares they can make a translate() wrapper that takes the key # in directly
const char *r_key = g_langMngr.GetKey(key);
const char *def = translate(amx, amx_addr, r_key);
if (!def)
{
def = r_key;
}
amx_Release(amx, amx_addr);
*_key = g_langMngr.GetKey(key);
*_def = def;
return true;
}
static cell AMX_NATIVE_CALL amx_translate(AMX *amx, cell *params)
{
int len;
char *key = get_amxstring(amx, params[1], 0, len);
amxtrans_t trans;
int suki = g_langMngr.GetKeyEntry(key);
//Some AMX Mod plugins do not register everything they need. Prevent a crash.
if (suki == -1)
{
suki = g_langMngr.AddKeyEntry(key);
}
if (suki > BCOMPAT_TRANSLATE_KEYMASK)
{
LogError(amx, AMX_ERR_NATIVE, "Not enough translation space, aborting!");
return 0;
}
trans = suki & BCOMPAT_TRANSLATE_KEYMASK;
int dest = static_cast<int>(params[2]);
int lang = static_cast<int>(params[3]);
if (dest == -1)
{
trans |= (0x3F << BCOMPAT_TRANSLATE_DESTRSH);
} else {
trans |= (dest & BCOMPAT_TRANSLATE_DESTMASK) << BCOMPAT_TRANSLATE_DESTRSH;
}
if (lang == -1)
{
trans |= (0x1F << BCOMPAT_TRANSLATE_LANGRSH);
} else {
trans |= (lang & BCOMPAT_TRANSLATE_LANGMASK) << BCOMPAT_TRANSLATE_LANGRSH;
}
trans |= BCOMPAT_TRANSLATE_BITS;
return static_cast<cell>(trans);
}
AMX_NATIVE_INFO g_BcompatNatives[] =
{
{"translate", amx_translate},
{NULL, NULL},
};

View File

@ -1,28 +0,0 @@
#ifndef _INCLUDE_AMXMOD_CORE_COMPAT_H
#define _INCLUDE_AMXMOD_CORE_COMPAT_H
/**
* New format for translation:
* Note that we only support:
* 4k keys
* 32 languages
* 0000 0000 0000 0000 0000 0000 0000 0000
* | key id |
* | | <- dest id
* | | <- lang id
*/
#define BCOMPAT_TRANSLATE_BITS 0xFF000000
#define BCOMPAT_TRANSLATE_KEYMASK 0xFFF
#define BCOMPAT_TRANSLATE_DESTMASK 0x3F
#define BCOMPAT_TRANSLATE_DESTRSH 12
#define BCOMPAT_TRANSLATE_LANGMASK 0x1F
#define BCOMPAT_TRANSLATE_LANGRSH 18
typedef unsigned int amxtrans_t;
bool GetTranslation(amxtrans_t trans, int &key, int &dest, int &lang);
extern AMX_NATIVE_INFO g_BcompatNatives[];
#endif //_INCLUDE_AMXMOD_CORE_COMPAT_H

File diff suppressed because it is too large Load Diff

View File

@ -41,14 +41,10 @@
#include "string.h" #include "string.h"
#include <extdll.h> #include <extdll.h>
#include <meta_api.h> #include <meta_api.h>
#include "mm_pextensions.h" // metamod-p extensions
#ifdef _MSC_VER #ifdef MEMORY_TEST
// MSVC8 - replace POSIX functions with ISO C++ conformant ones as they are deprecated #include "mmgr/mmgr.h"
#if _MSC_VER >= 1400
#define unlink _unlink
#define mkdir _mkdir
#define strdup _strdup
#endif
#endif #endif
#include "md5.h" #include "md5.h"
@ -65,13 +61,14 @@
#include "CLogEvent.h" #include "CLogEvent.h"
#include "CForward.h" #include "CForward.h"
#include "CCmd.h" #include "CCmd.h"
#include "CMenu.h"
#include "CEvent.h" #include "CEvent.h"
#include "CLang.h" #include "CLang.h"
#include "fakemeta.h" #include "fakemeta.h"
#include "amxxlog.h" #include "amxxlog.h"
#define AMXXLOG_Log g_log.Log #define AMXXLOG_Log g_log.Log
#define AMXXLOG_Error g_log.LogError #define AMX_VERSION "1.60"
extern AMX_NATIVE_INFO core_Natives[]; extern AMX_NATIVE_INFO core_Natives[];
extern AMX_NATIVE_INFO time_Natives[]; extern AMX_NATIVE_INFO time_Natives[];
@ -81,10 +78,6 @@ extern AMX_NATIVE_INFO file_Natives[];
extern AMX_NATIVE_INFO float_Natives[]; extern AMX_NATIVE_INFO float_Natives[];
extern AMX_NATIVE_INFO string_Natives[]; extern AMX_NATIVE_INFO string_Natives[];
extern AMX_NATIVE_INFO vault_Natives[]; extern AMX_NATIVE_INFO vault_Natives[];
extern AMX_NATIVE_INFO msg_Natives[];
extern AMX_NATIVE_INFO vector_Natives[];
extern AMX_NATIVE_INFO g_SortNatives[];
extern AMX_NATIVE_INFO g_DataStructNatives[];
#ifndef __linux__ #ifndef __linux__
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path) #define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
@ -96,30 +89,10 @@ extern AMX_NATIVE_INFO g_DataStructNatives[];
#define DLFREE(m) dlclose(m) #define DLFREE(m) dlclose(m)
#endif #endif
#if defined __GNUC__
#include <stdint.h>
typedef intptr_t _INT_PTR;
#else
#if defined AMD64
typedef __int64 _INT_PTR;
#else
typedef __int32 _INT_PTR;
#endif
#endif
#ifndef __linux__ #ifndef __linux__
typedef HINSTANCE DLHANDLE; typedef HINSTANCE DLHANDLE;
#else #else
typedef void* DLHANDLE; typedef void* DLHANDLE;
#define INFINITE 0xFFFFFFFF
#endif
#ifndef __linux__
#define PATH_SEP_CHAR '\\'
#define ALT_SEP_CHAR '/'
#else
#define PATH_SEP_CHAR '/'
#define ALT_SEP_CHAR '\\'
#endif #endif
#ifndef GETPLAYERAUTHID #ifndef GETPLAYERAUTHID
@ -166,6 +139,8 @@ struct fakecmd_t
bool fake; bool fake;
}; };
extern bool g_IsNewMM;
extern pextension_funcs_t *gpMetaPExtFuncs;
extern CLog g_log; extern CLog g_log;
extern CPluginMngr g_plugins; extern CPluginMngr g_plugins;
extern CTaskMngr g_tasksMngr; extern CTaskMngr g_tasksMngr;
@ -182,6 +157,7 @@ extern CList<CPlayer*> g_auth;
extern EventsMngr g_events; extern EventsMngr g_events;
extern Grenades g_grenades; extern Grenades g_grenades;
extern LogEventsMngr g_logevents; extern LogEventsMngr g_logevents;
extern MenuMngr g_menucmds;
extern CLangMngr g_langMngr; extern CLangMngr g_langMngr;
extern String g_log_dir; extern String g_log_dir;
extern String g_mod_name; extern String g_mod_name;
@ -272,8 +248,6 @@ enum CountModulesMode
int countModules(CountModulesMode mode); int countModules(CountModulesMode mode);
void modules_callPluginsLoaded(); void modules_callPluginsLoaded();
void modules_callPluginsUnloaded();
void modules_callPluginsUnloading();
cell* get_amxaddr(AMX *amx, cell amx_addr); cell* get_amxaddr(AMX *amx, cell amx_addr);
char* build_pathname(char *fmt, ...); char* build_pathname(char *fmt, ...);
@ -282,7 +256,6 @@ char* format_amxstring(AMX *amx, cell *params, int parm, int& len);
AMX* get_amxscript(int, void**, const char**); AMX* get_amxscript(int, void**, const char**);
const char* get_amxscriptname(AMX* amx); const char* get_amxscriptname(AMX* amx);
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len); char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len);
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
int amxstring_len(cell* cstr); int amxstring_len(cell* cstr);
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug); int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
@ -299,7 +272,7 @@ void free_amxmemory(void **ptr);
// get_localinfo // get_localinfo
const char* get_localinfo(const char* name, const char* def); const char* get_localinfo(const char* name, const char* def);
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params); cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...); void LogError(AMX *amx, int err, const char *fmt, ...);
enum ModuleCallReason enum ModuleCallReason
{ {
@ -332,12 +305,11 @@ extern int FF_PluginLog;
extern int FF_PluginEnd; extern int FF_PluginEnd;
extern int FF_InconsistentFile; extern int FF_InconsistentFile;
extern int FF_ClientAuthorized; extern int FF_ClientAuthorized;
extern int FF_ChangeLevel;
extern bool g_coloredmenus; extern bool g_coloredmenus;
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring); #ifdef FAKEMETA
extern CFakeMeta g_FakeMeta;
#define MM_CVAR2_VERS 13 #endif
struct func_s struct func_s
{ {
@ -345,14 +317,4 @@ struct func_s
const char *desc; const char *desc;
}; };
enum AdminProperty
{
Admin_Auth = 0,
Admin_Password,
Admin_Access,
Admin_Flags
};
extern enginefuncs_t *g_pEngTable;
#endif // AMXMODX_H #endif // AMXMODX_H

View File

@ -54,7 +54,7 @@ static cell AMX_NATIVE_CALL _time(AMX *amx, cell *params)
/* the time() function returns the number of seconds since January 1 1970 /* the time() function returns the number of seconds since January 1 1970
* in Universal Coordinated Time (the successor to Greenwich Mean Time) * in Universal Coordinated Time (the successor to Greenwich Mean Time)
*/ */
return (cell)sec1970; return sec1970;
} }
#if defined __BORLANDC__ || defined __WATCOMC__ #if defined __BORLANDC__ || defined __WATCOMC__

View File

@ -53,7 +53,7 @@
struct TableEntry struct TableEntry
{ {
mint8_t cellSize; mint8_t cellSize PACKED;
mint32_t origSize PACKED; // contains AMX_HEADER->stp mint32_t origSize PACKED; // contains AMX_HEADER->stp
mint32_t offset PACKED; mint32_t offset PACKED;
}; };
@ -109,7 +109,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
{ {
DATAREAD(&m_Bh.version, sizeof(int16_t), 1); DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
if (m_Bh.version > MAGIC_VERSION) if (m_Bh.version != MAGIC_VERSION)
{ {
m_Status = Err_OldFile; m_Status = Err_OldFile;
fclose(m_pFile); fclose(m_pFile);
@ -300,7 +300,7 @@ size_t CAmxxReader::GetBufferSize()
#undef DATAREAD #undef DATAREAD
#define DATAREAD(addr, itemsize, itemcount) \ #define DATAREAD(addr, itemsize, itemcount) \
if (fread(addr, itemsize, itemcount, m_pFile) != static_cast<size_t>(itemcount)) \ if (fread(addr, itemsize, itemcount, m_pFile) != itemcount) \
{ \ { \
if (feof(m_pFile)) \ if (feof(m_pFile)) \
m_Status = Err_FileInvalid; \ m_Status = Err_FileInvalid; \

View File

@ -92,7 +92,6 @@ public:
Error GetStatus(); // Get the current status Error GetStatus(); // Get the current status
size_t GetBufferSize(); // Get the size for the buffer size_t GetBufferSize(); // Get the size for the buffer
Error GetSection(void *buffer); // Copy the currently selected section to the buffer Error GetSection(void *buffer); // Copy the currently selected section to the buffer
inline bool IsOldFile() const { return m_OldFile; }
}; };
#endif // __AMXXFILE_H__ #endif // __AMXXFILE_H__

View File

@ -44,14 +44,10 @@
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#endif #endif
#include "svn_version.h"
CLog::CLog() CLog::CLog()
{ {
m_LogType = 0; m_LogType = 0;
m_LogFile.clear(); m_LogFile.clear();
m_FoundError = false;
m_LoggedErrMap = false;
} }
CLog::~CLog() CLog::~CLog()
@ -96,15 +92,11 @@ void CLog::CreateNewFile()
time(&td); time(&td);
tm *curTime = localtime(&td); tm *curTime = localtime(&td);
char file[256];
char name[256];
int i = 0; int i = 0;
while (true) while (true)
{ {
snprintf(name, sizeof(name), "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i); FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
build_pathname_r(file, sizeof(file)-1, "%s", name);
FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists
if (!pTmpFile) if (!pTmpFile)
break; break;
@ -112,7 +104,6 @@ void CLog::CreateNewFile()
fclose(pTmpFile); fclose(pTmpFile);
++i; ++i;
} }
m_LogFile.assign(file);
// Log logfile start // Log logfile start
FILE *fp = fopen(m_LogFile.c_str(), "w"); FILE *fp = fopen(m_LogFile.c_str(), "w");
@ -122,7 +113,7 @@ void CLog::CreateNewFile()
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n"); ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
SET_LOCALINFO("amxx_logging", "0"); SET_LOCALINFO("amxx_logging", "0");
} else { } else {
fprintf(fp, "AMX Mod X log file started (file \"%s\") (version \"%s\")\n", name, SVN_VERSION_STRING); fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
fclose(fp); fclose(fp);
} }
} }
@ -152,17 +143,17 @@ void CLog::MapChange()
print_srvconsole("[AMXX] Invalid amxx_logging value; setting back to 1..."); print_srvconsole("[AMXX] Invalid amxx_logging value; setting back to 1...");
} }
m_LoggedErrMap = false;
if (m_LogType == 2) if (m_LogType == 2)
{ {
// create new logfile // create new logfile
CreateNewFile(); CreateNewFile();
} else if (m_LogType == 1) {
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
} else {
return;
} }
else if (m_LogType == 1)
{
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
}
else
return;
} }
void CLog::Log(const char *fmt, ...) void CLog::Log(const char *fmt, ...)
@ -204,7 +195,7 @@ void CLog::Log(const char *fmt, ...)
} }
} }
} else { } else {
build_pathname_r(file, sizeof(file)-1, "%s/L%04d%02d%02d.log", g_log_dir.c_str(), (curTime->tm_year + 1900), curTime->tm_mon + 1, curTime->tm_mday); build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
pF = fopen(file, "a+"); pF = fopen(file, "a+");
} }
@ -220,7 +211,9 @@ void CLog::Log(const char *fmt, ...)
// print on server console // print on server console
print_srvconsole("L %s: %s\n", date, msg); print_srvconsole("L %s: %s\n", date, msg);
} else if (m_LogType == 3) { }
else if (m_LogType == 3)
{
// build message // build message
static char msg_[3072]; static char msg_[3072];
va_list arglst; va_list arglst;
@ -230,55 +223,3 @@ void CLog::Log(const char *fmt, ...)
ALERT(at_logged, "%s\n", msg_); ALERT(at_logged, "%s\n", msg_);
} }
} }
void CLog::LogError(const char *fmt, ...)
{
static char file[256];
static char name[256];
if (m_FoundError)
{
return;
}
// get time
time_t td;
time(&td);
tm *curTime = localtime(&td);
char date[32];
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
// msg
static char msg[3072];
va_list arglst;
va_start(arglst, fmt);
vsnprintf(msg, sizeof(msg)-1, fmt, arglst);
va_end(arglst);
FILE *pF = NULL;
snprintf(name, sizeof(name), "%s/error_%04d%02d%02d.log", g_log_dir.c_str(), curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday);
build_pathname_r(file, sizeof(file)-1, "%s", name);
pF = fopen(file, "a+");
if (pF)
{
if (!m_LoggedErrMap)
{
fprintf(pF, "L %s: Start of error session.\n", date);
fprintf(pF, "L %s: Info (map \"%s\") (file \"%s\")\n", date, STRING(gpGlobals->mapname), name);
m_LoggedErrMap = true;
}
fprintf(pF, "L %s: %s\n", date, msg);
fclose(pF);
} else {
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Error Logging disabled for this map.\n", file);
m_FoundError = true;
return;
}
// print on server console
print_srvconsole("L %s: %s\n", date, msg);
}

View File

@ -36,8 +36,6 @@ class CLog
private: private:
String m_LogFile; String m_LogFile;
int m_LogType; int m_LogType;
bool m_FoundError;
bool m_LoggedErrMap;
void GetLastFile(int &outMonth, int &outDay, String &outFilename); void GetLastFile(int &outMonth, int &outDay, String &outFilename);
void UseFile(const String &fileName); void UseFile(const String &fileName);
@ -49,7 +47,6 @@ public:
void CloseFile(); void CloseFile();
void MapChange(); void MapChange();
void Log(const char *fmt, ...); void Log(const char *fmt, ...);
void LogError(const char *fmt, ...);
}; };
#endif // __AMXXLOG_H__ #endif // __AMXXLOG_H__

View File

@ -1,362 +0,0 @@
#if defined BINLOG_ENABLED
#include <time.h>
#include "amxmodx.h"
#include "binlog.h"
#include "debugger.h"
BinLog g_BinLog;
int g_binlog_level = 0;
int g_binlog_maxsize = 0;
// Helper function to get a filename index
#define USHR(x) ((unsigned int)(x)>>1)
int LookupFile(AMX_DBG *amxdbg, ucell address)
{
int high, low, mid;
high = amxdbg->hdr->files;
low = -1;
while (high - low > 1)
{
mid = USHR(low + high);
if (amxdbg->filetbl[mid]->address <= address)
{
low = mid;
} else {
high = mid;
}
}
if (low == -1)
{
return -1;
}
return low;
}
bool BinLog::Open()
{
const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data");
char path[255];
build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data);
if (!DirExists(path))
{
mkdir(path
#if defined __linux__
, 0755
#endif
);
if (!DirExists(path))
return false;
}
char file[255];
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data);
unsigned int lastcntr = 0;
FILE *lastlog = fopen(file, "rb");
if (lastlog)
{
if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1)
lastcntr = 0;
fclose(lastlog);
}
lastlog = fopen(file, "wb");
if (lastlog)
{
lastcntr++;
fwrite(&lastcntr, sizeof(int), 1, lastlog);
fclose(lastlog);
}
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
m_logfile.assign(file);
/**
* it's now safe to create the binary log
*/
FILE *fp = fopen(m_logfile.c_str(), "wb");
if (!fp)
return false;
int magic = BINLOG_MAGIC;
short vers = BINLOG_VERSION;
char c = sizeof(time_t);
fwrite(&magic, sizeof(int), 1, fp);
fwrite(&vers, sizeof(short), 1, fp);
fwrite(&c, sizeof(char), 1, fp);
WritePluginDB(fp);
fclose(fp);
m_state = true;
WriteOp(BinLog_Start, -1);
return true;
}
void BinLog::Close()
{
WriteOp(BinLog_End, -1);
m_state = false;
}
void BinLog::WriteOp(BinLogOp op, int plug, ...)
{
if (!m_state)
return;
FILE *fp = fopen(m_logfile.c_str(), "ab");
if (!fp)
return;
if (g_binlog_maxsize && op != BinLog_End)
{
fseek(fp, 0, SEEK_END);
if (ftell(fp) > (g_binlog_maxsize * (1024 * 1024)))
{
fclose(fp);
Close();
Open();
fp = fopen(m_logfile.c_str(), "ab");
if (!fp)
return;
}
}
unsigned char c = static_cast<char>(op);
time_t t = time(NULL);
float gt = gpGlobals->time;
fwrite(&c, sizeof(char), 1, fp);
fwrite(&t, sizeof(time_t), 1, fp);
fwrite(&gt, sizeof(float), 1, fp);
fwrite(&plug, sizeof(int), 1, fp);
va_list ap;
va_start(ap, plug);
AMX *amx = NULL;
bool debug = false;
AMX_DBG *dbg = NULL;
CPluginMngr::CPlugin *pl = NULL;
if (plug != -1)
{
pl = g_plugins.findPlugin(plug);
if ((debug = pl->isDebug()))
{
amx = pl->getAMX();
dbg = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER])->m_pAmxDbg;
}
}
switch (c)
{
case BinLog_Registered:
{
const char *title = va_arg(ap, const char *);
const char *vers = va_arg(ap, const char *);
c = (char)strlen(title);
fwrite(&c, sizeof(char), 1, fp);
fwrite(title, sizeof(char), c+1, fp);
c = (char)strlen(vers);
fwrite(&c, sizeof(char), 1 ,fp);
fwrite(vers, sizeof(char), c+1, fp);
break;
}
case BinLog_NativeCall:
{
int file;
int native = va_arg(ap, int);
int params = va_arg(ap, int);
fwrite(&native, sizeof(int), 1, fp);
fwrite(&params, sizeof(int), 1, fp);
if (debug)
{
file = LookupFile(dbg, amx->cip);
fwrite(&file, sizeof(int), 1, fp);
} else {
file = 0;
fwrite(&file, sizeof(int), 1, fp);
}
break;
}
case BinLog_NativeRet:
{
cell retval = va_arg(ap, cell);
fwrite(&retval, sizeof(cell), 1, fp);
break;
}
case BinLog_NativeError:
{
int err = va_arg(ap, int);
const char *msg = va_arg(ap, const char *);
short len = (short)strlen(msg);
fwrite(&err, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(msg, sizeof(char), len+1, fp);
break;
}
case BinLog_CallPubFunc:
{
int file;
int num = va_arg(ap, int);
fwrite(&num, sizeof(int), 1, fp);
if (debug)
{
file = LookupFile(dbg, amx->cip);
fwrite(&file, sizeof(int), 1, fp);
} else {
file = 0;
fwrite(&file, sizeof(int), 1, fp);
}
break;
}
case BinLog_SetLine:
{
int file;
int line = va_arg(ap, int);
fwrite(&line, sizeof(int), 1, fp);
if (debug)
{
file = LookupFile(dbg, amx->cip);
fwrite(&file, sizeof(int), 1, fp);
} else {
file = 0;
fwrite(&file, sizeof(int), 1, fp);
}
break;
}
case BinLog_FormatString:
{
int param = va_arg(ap, int);
int maxlen = va_arg(ap, int);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&param, sizeof(int), 1, fp);
fwrite(&maxlen, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
case BinLog_NativeParams:
{
cell *params = va_arg(ap, cell *);
cell num = params[0] / sizeof(cell);
fwrite(&num, sizeof(cell), 1, fp);
for (cell i=1; i<=num; i++)
fwrite(&(params[i]), sizeof(cell), 1, fp);
break;
}
case BinLog_GetString:
{
cell addr = va_arg(ap, cell);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&addr, sizeof(cell), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
case BinLog_SetString:
{
cell addr = va_arg(ap, cell);
int maxlen = va_arg(ap, int);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&addr, sizeof(cell), 1, fp);
fwrite(&maxlen, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
};
va_end(ap);
fclose(fp);
}
void BinLog::WritePluginDB(FILE *fp)
{
int num = g_plugins.getPluginsNum();
fwrite(&num, sizeof(int), 1, fp);
CPluginMngr::CPlugin *pl;
char c;
unsigned char len;
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{
pl = &(*iter);
if (pl->isValid())
c = 1;
else
c = 0;
if (c && pl->isDebug())
c = 2;
fwrite(&c, sizeof(char), 1, fp);
if (c)
{
Debugger *pd = NULL;
len = (char)strlen(pl->getName());
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(pl->getName(), sizeof(char), len, fp);
int natives, publics, files;
AMX *amx = pl->getAMX();
// Write the number of Filenames
if (c == 2)
{
pd = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER]);
files = pd->m_pAmxDbg->hdr->files;
fwrite(&files, sizeof(int), 1, fp);
}
amx_NumNatives(amx, &natives);
amx_NumPublics(amx, &publics);
fwrite(&natives, sizeof(int), 1, fp);
fwrite(&publics, sizeof(int), 1, fp);
char name[34];
// Write the Filenames to the binfile
if (c == 2)
{
AMX_DBG_FILE **ftable = pd->m_pAmxDbg->filetbl;
for (int i=0; i<files; i++)
{
len = (char)strlen(ftable[i]->name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(ftable[i]->name, sizeof(char), len, fp);
}
}
for (int i=0; i<natives; i++)
{
amx_GetNative(amx, i, name);
len = (char)strlen(name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(name, sizeof(char), len, fp);
}
for (int i=0; i<publics; i++)
{
amx_GetPublic(amx, i, name);
len = (char)strlen(name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(name, sizeof(char), len, fp);
}
} else {
char empty[] = " ";
len = 1;
fwrite(&len, sizeof(char), 1, fp);
fwrite(empty, sizeof(char), len, fp);
int no = 0;
fwrite(&no, sizeof(int), 1, fp);
fwrite(&no, sizeof(int), 1, fp);
}
}
}
#endif //BINLOG_ENABLED

View File

@ -1,84 +0,0 @@
#ifndef _INCLUDE_BINLOG_H
#define _INCLUDE_BINLOG_H
#if defined BINLOG_ENABLED
#include "CString.h"
#define BINLOG_MAGIC 0x414D424C
#define BINLOG_VERSION 0x0300
/**
* Format of binlog:
* uint32 magic
* uint16 version
* uint8 sizeof(time_t)
* uint32 num plugins
* [
* uint8 status codes
* str[int8] filename
* if(status==2)
* uint32 num filenames
* uint32 num natives
* uint32 num publics
* if (status==2)
* [
* str[uint8] file name
* ]
* [
* str[uint8] native name
* ]
* [
* str[uint8] public name
* ]
* ]
* [
* uint8 operation code
* time_t realtime
* float gametime
* int32 plugin id
* <extra info>
* ]
* If filename id is 0 skip as plugin was not in debug mode, if -1 there was an error.
*/
enum BinLogOp
{
BinLog_Start=1,
BinLog_End,
BinLog_NativeCall, //<int32 native id> <int32_t num_params> <int32_t filename id>
BinLog_NativeError, //<int32 errornum> <str[int16] string>
BinLog_NativeRet, //<cell value>
BinLog_CallPubFunc, //<int32 public id> <int32_t filename id>
BinLog_SetLine, //<int32 line no#> <int32_t filename id>
BinLog_Registered, //<string title> <string version>
BinLog_FormatString, //<int32 param#> <int32 maxlen> <str[int16] string>
BinLog_NativeParams, //<int32 num> <cell ...>
BinLog_GetString, //<cell addr> <string[int16]>
BinLog_SetString, //<cell addr> <int maxlen> <string[int16]>
};
class BinLog
{
public:
BinLog() : m_state(false)
{
};
public:
bool Open();
void Close();
void WriteOp(BinLogOp op, int plug, ...);
private:
void WritePluginDB(FILE *fp);
private:
String m_logfile;
bool m_state;
};
extern BinLog g_BinLog;
extern int g_binlog_level;
extern int g_binlog_maxsize;
#endif //BINLOG_ENABLED
#endif //_INCLUDE_BINLOG_H

View File

@ -1,608 +0,0 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "amxmodx.h"
#include "datastructs.h"
// Note: All handles start at 1. 0 and below are invalid handles.
// This way, a plugin that doesn't initialize a vector or
// string will not be able to modify another plugin's data
// on accident.
CVector<CellVector*> VectorHolder;
// Array:ArrayCreate(cellsize=1, reserved=32);
static cell AMX_NATIVE_CALL ArrayCreate(AMX* amx, cell* params)
{
// params[1] (cellsize) is how big in cells each element is.
// this MUST be greater than 0!
int cellsize=params[1];
// params[2] (reserved) is how many elements to allocate
// immediately when the list is created.
// this MUST be greater than 0!
int reserved=params[2];
if (cellsize<=0)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid array size (%d)", cellsize);
return -1;
}
if (reserved<=0)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid reserved size (%d)", reserved);
return -1;
}
// Scan through the vector list to see if any are NULL.
// NULL means the vector was previously destroyed.
for (unsigned int i=0; i < VectorHolder.size(); ++i)
{
if (VectorHolder[i]==NULL)
{
VectorHolder[i]=new CellVector(cellsize);
VectorHolder[i]->Grow(reserved);
return i + 1;
}
}
// None are NULL, create a new vector
CellVector* NewVector=new CellVector(cellsize);
NewVector->Grow(reserved);
VectorHolder.push_back(NewVector);
return VectorHolder.size();
}
// ArrayClear(Array:which)
static cell AMX_NATIVE_CALL ArrayClear(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
vec->Clear();
return 1;
}
// ArraySize(Array:which)
static cell AMX_NATIVE_CALL ArraySize(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
return vec->Size();
}
// ArrayGetArray(Array:which, item, any:output[]);
static cell AMX_NATIVE_CALL ArrayGetArray(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
if (vec->GetArray(params[2],get_amxaddr(amx, params[3]))!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
return 0;
}
return 1;
}
// ArrayGetCell(Array:which, item, any:&output);
static cell AMX_NATIVE_CALL ArrayGetCell(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
cell ret;
if (vec->GetCell(params[2],&ret)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
return 0;
}
return ret;
}
// ArrayGetString(Array:which, item, any:output[], size);
static cell AMX_NATIVE_CALL ArrayGetString(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
if (vec->GetString(params[2],get_amxaddr(amx, params[3]),params[4])!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
return 0;
}
return 1;
}
// ArraySetArray(Array:which, item, any:output[]);
static cell AMX_NATIVE_CALL ArraySetArray(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
if (vec->SetArray(params[2],get_amxaddr(amx, params[3]))!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
return 0;
}
return 1;
}
// ArraySetCell(Array:which, item, any:&output);
static cell AMX_NATIVE_CALL ArraySetCell(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
if (vec->SetCell(params[2], params[3])!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
return 0;
}
return 1;
}
// ArraySetString(Array:which, item, any:output[]);
static cell AMX_NATIVE_CALL ArraySetString(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
if (vec->SetString(params[2],get_amxaddr(amx, params[3]))!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
return 0;
}
return 1;
}
// ArrayPushArray(Array:which, any:output[]);
static cell AMX_NATIVE_CALL ArrayPushArray(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
vec->SetArray(vec->Push(),get_amxaddr(amx, params[2]));
return 1;
}
// ArrayPushCell(Array:which, &any:output);
static cell AMX_NATIVE_CALL ArrayPushCell(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
vec->SetCell(vec->Push(), params[2]);
return 1;
}
// ArrayPushString(Array:which, any:output[]);
static cell AMX_NATIVE_CALL ArrayPushString(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec==NULL)
{
return 0;
}
vec->SetString(vec->Push(),get_amxaddr(amx, params[2]));
return 1;
}
static cell AMX_NATIVE_CALL ArrayGetStringHandle(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (vec == NULL)
{
return 0;
}
cell* ptr=vec->GetCellPointer(params[2]);
if (ptr == NULL)
{
return 0;
}
return reinterpret_cast<cell>(ptr);
}
// ArrayInsertArrayAfter(Array:which, item, const value[])
static cell AMX_NATIVE_CALL ArrayInsertArrayAfter(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
int item=params[2]+1;
if (vec->ShiftUpFrom(item)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayAfter (%d:%d)", params[1], vec->Size());
return 0;
}
vec->SetArray(item, get_amxaddr(amx, params[3]));
return 1;
}
// ArrayInsertCellAfter(Array:which, item, value[])
static cell AMX_NATIVE_CALL ArrayInsertCellAfter(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
int item=params[2]+1;
if (vec->ShiftUpFrom(item)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellAfter (%d:%d)", params[1], vec->Size());
return 0;
}
vec->SetCell(item, params[3]);
return 1;
}
// ArrayInsertStringAfter(Array:which, item, const value[])
static cell AMX_NATIVE_CALL ArrayInsertStringAfter(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
int item=params[2]+1;
if (vec->ShiftUpFrom(item)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringAfter (%d:%d)", params[1], vec->Size());
return 0;
}
vec->SetString(item, get_amxaddr(amx, params[3]));
return 1;
}
// ArrayInsertArrayBefore(Array:which, item, const value[])
static cell AMX_NATIVE_CALL ArrayInsertArrayBefore(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
int item=params[2];
if (item==vec->Size())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayBefore (%d:%d)", params[2], vec->Size());
return 0;
}
if (vec->ShiftUpFrom(item)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayBefore (%d:%d)", params[2], vec->Size());
return 0;
}
vec->SetArray(item, get_amxaddr(amx, params[3]));
return 1;
}
// ArrayInsertCellBefore(Array:which, item, const value)
static cell AMX_NATIVE_CALL ArrayInsertCellBefore(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
int item=params[2];
if (item==vec->Size())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellBefore (%d:%d)", params[2], vec->Size());
return 0;
}
if (vec->ShiftUpFrom(item)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellBefore (%d:%d)", params[2], vec->Size());
return 0;
}
vec->SetCell(item, params[3]);
return 1;
}
// ArrayInsertStringBefore(Array:which, item, const value[])
static cell AMX_NATIVE_CALL ArrayInsertStringBefore(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
int item=params[2];
if (item==vec->Size())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringBefore (%d:%d)", params[2], vec->Size());
return 0;
}
if (vec->ShiftUpFrom(item)!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringBefore (%d:%d)", params[2], vec->Size());
return 0;
}
vec->SetString(item, get_amxaddr(amx, params[3]));
return 1;
}
// ArraySwap(Array:which, item1, item2)
static cell AMX_NATIVE_CALL ArraySwap(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
if (vec->Swap(params[2], params[3])!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArraySwap (%d , %d:%d)",params[2], params[3], vec->Size());
return 0;
}
return 1;
}
// ArrayDeleteItem(Array:which, item);
static cell AMX_NATIVE_CALL ArrayDeleteItem(AMX* amx, cell* params)
{
CellVector* vec=HandleToVector(amx, params[1]);
if (!vec)
{
return 0;
}
if (vec->Delete(params[2])!=1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayDeleteItem (%d:%d)", params[2], vec->Size());
return 0;
}
return 1;
}
// ArrayDestroy(Array:&which)
static cell AMX_NATIVE_CALL ArrayDestroy(AMX* amx, cell* params)
{
// byref the handle here so we can zero it out after destroying
// this way they cannot accidentally reuse it
cell* handle=get_amxaddr(amx,params[1]);
CellVector* vec=HandleToVector(amx, *handle);
if (!vec)
{
return 0;
}
delete vec;
VectorHolder[*handle-1]=NULL;
*handle=0;
return 1;
}
typedef struct ArraySort_s
{
int handle;
int forward;
cell data;
cell size;
} ArraySort_t;
static CStack<ArraySort_t *> ArraySortStack;
int SortArrayList(const void *itema, const void *itemb)
{
ArraySort_t *Info = ArraySortStack.front();
return executeForwards(Info->forward, Info->handle, *((int *)itema), *((int *)itemb), Info->data, Info->size);
}
// native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0);
static cell AMX_NATIVE_CALL ArraySort(AMX* amx, cell* params)
{
int handle=params[1];
CellVector* vec=HandleToVector(amx, handle);
if (!vec)
{
return 0;
}
// This is kind of a cheating way to go about this but...
// Create an array of integers as big as however many elements are in the vector.
// Pass that array to qsort
// After the array is sorted out, then create a NEW cellvector
// and copy in the old data in the order of what was sorted
int len;
char* FuncName=get_amxstring(amx, params[2], 0, len);
// MySortFunc(Array:array, item1, item2, const data[], data_size)
int Forward = registerSPForwardByName(amx, FuncName, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (Forward < 0)
{
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", FuncName);
return 0;
}
int *IntList=new int[vec->Size()];
for (int i=0; i< vec->Size(); i++)
{
IntList[i]=i;
}
ArraySort_t *Info=new ArraySort_t;
Info->handle=handle;
Info->forward=Forward;
Info->data=params[3];
Info->size=params[4];
ArraySortStack.push(Info);
qsort(IntList, vec->Size(), sizeof(int), SortArrayList);
ArraySortStack.pop();
CellVector* newvec=new CellVector(vec->GetCellCount());
// Set the new vector's values
for (int i=0; i< vec->Size(); i++)
{
if (newvec->SetArray(newvec->Push(), vec->GetCellPointer(IntList[i]))!=1)
{
// This should never happen..
LogError(amx, AMX_ERR_NATIVE, "Failed to SetArray in ArraySort (i=%d, IntList=%d)",i,IntList[i]);
return 0;
}
}
// Delete the old vector
delete vec;
// Now save the new vector in its handle location
VectorHolder[handle-1]=newvec;
// Cleanup
delete Info;
delete IntList;
unregisterSPForward(Forward);
return 1;
}
AMX_NATIVE_INFO g_DataStructNatives[] =
{
{ "ArrayCreate", ArrayCreate },
{ "ArrayClear", ArrayClear },
{ "ArraySize", ArraySize },
{ "ArrayGetArray", ArrayGetArray },
{ "ArrayGetCell", ArrayGetCell },
{ "ArrayGetString", ArrayGetString },
{ "ArraySetArray", ArraySetArray },
{ "ArraySetCell", ArraySetCell },
{ "ArraySetString", ArraySetString },
{ "ArrayPushArray", ArrayPushArray },
{ "ArrayPushCell", ArrayPushCell },
{ "ArrayPushString", ArrayPushString },
{ "ArrayInsertArrayAfter", ArrayInsertArrayAfter },
{ "ArrayInsertCellAfter", ArrayInsertCellAfter },
{ "ArrayInsertStringAfter", ArrayInsertStringAfter },
{ "ArrayInsertArrayBefore", ArrayInsertArrayBefore },
{ "ArrayInsertCellBefore", ArrayInsertCellBefore },
{ "ArrayInsertStringBefore", ArrayInsertStringBefore },
{ "ArraySwap", ArraySwap },
{ "ArrayDeleteItem", ArrayDeleteItem },
{ "ArrayGetStringHandle", ArrayGetStringHandle },
{ "ArrayDestroy", ArrayDestroy },
{ "ArraySort", ArraySort },
{ NULL, NULL }
};

View File

@ -1,323 +0,0 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef DATASTRUCTS_H
#define DATASTRUCTS_H
class CellVector
{
private:
cell* data; // allocated with malloc
size_t cellcount; // how many cells per element
size_t cursize; // current size of the vector (maximum elements)
size_t count; // how many units of the vector are in use
public:
CellVector(): data(NULL), cellcount(0), cursize(0), count(0)
{
};
CellVector(int cellsize): data(NULL), cellcount(cellsize), cursize(0), count(0)
{
};
~CellVector()
{
if (data)
{
free(data);
}
};
size_t GetCellCount()
{
return cellcount;
};
void Grow(size_t howmany)
{
cursize+=howmany;
if (data)
{
data=(cell*)realloc(data, (sizeof(cell) * cellcount) * cursize);
}
else
{
data=(cell*)malloc((sizeof(cell) * cellcount) * cursize);
}
};
void FreeUnused(void)
{
if (cursize != count &&
data != NULL)
{
cursize=count;
data=(cell*)realloc(data, cursize * (sizeof(cell) * cellcount));
}
};
// Returns 1 on success
// 0 on out of bounds.
int GetArray(size_t which, cell* output)
{
// make sure it is in bounds.
if (which >= count)
{
return 0;
}
// align output data
cell* out=data + (cellcount * which);
memcpy(output, out, sizeof(cell) * cellcount);
return 1;
};
// Returns 1 on success
// 0 on out of bounds
int GetCell(size_t which, cell* output)
{
// check bounds
if (which >= count)
{
return 0;
}
*output=*(data + (cellcount * which));
return 1;
}
// Returns 1 on success
// 0 on out of bounds
int GetString(size_t which, cell* output, size_t size)
{
// check bounds
if (which >= count)
{
return 0;
}
cell* out=data + (cellcount * which);
size_t count=cellcount;
while (size-- &&
count-- &&
(*output++=*out++)!='\0')
/* do nothing */ ;
// If size is zero here, then the string was never null terminated.
if (size==0)
{
*out='\0';
}
return 1;
}
// Returns 1 on success
// 0 on out of bounds
int SetArray(size_t which, cell* output)
{
if (which >= count)
{
return 0;
}
// align output
cell* out=data + (cellcount * which);
memcpy(out, output, sizeof(cell) * cellcount);
return 1;
};
// Returns 1 on success
// 0 on out of bounds
int SetCell(size_t which, cell output)
{
if (which >= count)
{
return 0;
}
// align output
*(data + (cellcount * which))=output;
return 1;
};
// Returns 1 on success
// 0 on out of bounds
int SetString(size_t which, cell* output)
{
if (which >= count)
{
return 0;
}
// align output
cell* out=data + (cellcount * which);
memcpy(out, output, sizeof(cell) * cellcount);
// now force a null terminator on the last entry.
out+=(cellcount - 1);
*out='\0';
return 1;
};
int Push()
{
if (count >= cursize)
{
// Grow in 8s to cause less reallocation
this->Grow(8);
};
this->count++;
return this->count-1;
};
int Size()
{
return this->count;
};
void Clear()
{
free(data);
data=(cell*)malloc(sizeof(cell) * cellcount);
cursize=1;
count=0;
};
cell* GetCellPointer(size_t which)
{
if (which >= count)
{
return NULL;
}
return data + (which * cellcount);
};
// Shifts all items from this item, and including this item up 1.
int ShiftUpFrom(size_t which)
{
// No point shifting this.
if (this->count < 0 ||
which > this->count)
{
return 0;
}
// First make a new item.
this->Push();
// If we got an InsertAfter(lastitem), then which will equal this->count - 1
// all we needed to do was Push()
if (which == this->count ||
which == this->count - 1)
{
return 1;
}
// Allocate a temporary buffer to store data in
size_t tempbuffsize=(sizeof(cell) * cellcount) * (this->count - which);
cell* temp=(cell*)malloc(tempbuffsize);
// Copy old data to temp buffer
memcpy(temp, GetCellPointer(which), tempbuffsize);
// Now copy temp buffer to adjusted location
memcpy(GetCellPointer(which+1), temp, tempbuffsize);
// cleanup
free(temp);
return 1;
};
// Shifts all items from this item, and including this item down 1.
// This deletes the item specified.
int Delete(size_t which)
{
// No point shifting this.
if (this->count < 0 ||
which >= this->count)
{
return 0;
}
for (size_t i=which; i<this->count - 1; i++)
{
memcpy(GetCellPointer(i), GetCellPointer(i + 1), sizeof(cell) * cellcount);
}
this->count--;
return 1;
};
int Swap(size_t item1, size_t item2)
{
if (item1 >= this->count ||
item2 >= this->count)
{
return 0;
}
// Make a temp buffer to store item2
cell* temp=(cell*)malloc(sizeof(cell) * cellcount);
memcpy(temp, GetCellPointer(item2), sizeof(cell) * cellcount);
// copy item1 to item2
memcpy(GetCellPointer(item2), GetCellPointer(item1), sizeof(cell) * cellcount);
// copy item2 to item1
memcpy(GetCellPointer(item1), temp, sizeof(cell) * cellcount);
// Cleanup
free(temp);
return 1;
};
};
extern CVector<CellVector*> VectorHolder;
inline CellVector* HandleToVector(AMX* amx, int handle)
{
if (handle <= 0 ||
handle > (int)VectorHolder.size())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle);
return NULL;
}
CellVector* ret=VectorHolder[handle-1];
if (ret == NULL)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle);
return NULL;
}
return ret;
}
#endif

View File

@ -31,7 +31,6 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "debugger.h" #include "debugger.h"
#include "binlog.h"
#if !defined WIN32 && !defined _WIN32 #if !defined WIN32 && !defined _WIN32
#define _snprintf snprintf #define _snprintf snprintf
@ -308,19 +307,6 @@ void Debugger::StepI()
{ {
assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
#if defined BINLOG_ENABLED
if (g_binlog_level & 32)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx);
if (pl)
{
long line;
dbg_LookupLine(m_pAmxDbg, m_pAmx->cip, &line);
g_BinLog.WriteOp(BinLog_SetLine, pl->getId(), (int)(line + 1));
}
}
#endif
m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip); m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip);
} }
@ -377,6 +363,53 @@ bool Debugger::ErrorExists()
return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE); return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE);
} }
#define FLAG_INDIRECT (1<<0)
//vaddr - the address of our current index vector
//base - the base address of which the array is offset to
//dim - the current dimension to search
//dimNum - the number of dimensions total
//sizes[] - an array containing the dimension sizes
//Indexes[] - an output array to contain each dimension's index
int WalkArray(cell *vaddr, unsigned char *base, cell *addr, int dim, int dimNum, int &flags, int sizes[], int Indexes[])
{
cell *my_addr;
int idx = 0;
//if we are the second to last walker, we only need to check the ranges of our vector.
if (dim == dimNum - 2)
{
my_addr = vaddr;
//first check the actual vectors themselves
for (int i=0; i<sizes[dim]; i++)
{
if (addr == my_addr)
return i;
my_addr++;
}
return -1;
}
//otherwise, search lower vectors!
//vaddr is the address where we can start reading vectors
flags |= FLAG_INDIRECT;
for (int i=0; i<sizes[dim]; i++)
{
//the next vector is offset from the last address!
//this is funky but that's the internal implementation
my_addr = (cell *)((char *)vaddr + i*sizeof(cell) + vaddr[i]);
idx = WalkArray(my_addr, base, addr, dim+1, dimNum, flags, sizes, Indexes);
if (idx != -1)
{
Indexes[dim+1] = idx;
return i;
}
}
return -1;
}
int Debugger::FormatError(char *buffer, size_t maxLength) int Debugger::FormatError(char *buffer, size_t maxLength)
{ {
if (!ErrorExists()) if (!ErrorExists())
@ -388,9 +421,9 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
int error = pTracer->m_Error; int error = pTracer->m_Error;
const char *gen_err = GenericError(error); const char *gen_err = GenericError(error);
int size = 0; int size = 0;
//trace_info_t *pTrace = pTracer->GetEnd(); trace_info_t *pTrace = pTracer->GetEnd();
//cell cip = _CipAsVa(m_pAmx->cip); cell cip = _CipAsVa(m_pAmx->cip);
//cell *p_cip = NULL; cell *p_cip = NULL;
int amx_err = AMX_ERR_NONE; int amx_err = AMX_ERR_NONE;
size += _snprintf(buffer, maxLength, "Run time error %d: %s ", error, gen_err); size += _snprintf(buffer, maxLength, "Run time error %d: %s ", error, gen_err);
@ -409,7 +442,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
num = (int)*p_cip; num = (int)*p_cip;
}*/ }*/
//New code only requires this... //New code only requires this...
num = (int)(_INT_PTR)m_pAmx->usertags[UT_NATIVE]; num = m_pAmx->usertags[UT_NATIVE];
amx_err = amx_GetNative(m_pAmx, num, native_name); amx_err = amx_GetNative(m_pAmx, num, native_name);
/*if (num) /*if (num)
amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name); amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name);
@ -417,6 +450,205 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
amx_err = AMX_ERR_NOTFOUND;*/ amx_err = AMX_ERR_NOTFOUND;*/
//if (!amx_err) //if (!amx_err)
size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name); size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name);
} else if (error == AMX_ERR_BOUNDS) {
tagAMX_DBG *pDbg = m_pAmxDbg;
int symbols = pDbg->hdr->symbols;
int index = 0;
tagAMX_DBG_SYMBOL **pSymbols = pDbg->symboltbl;
tagAMX_DBG_SYMBOL *pSymbol, *pLastSymbol=NULL;
const tagAMX_DBG_SYMDIM *pDims;
ucell addr = 0;
int flags = 0;
char v_class, i_dent;
cell *arr_addr=NULL, *p_addr=NULL;
unsigned char *data = m_pAmx->base + ((AMX_HEADER *)m_pAmx->base)->dat;
bool valid=false;
//we can't really browse the assembly because
// we've no idea what the peephole optimizer did.
// so we're gonna try to go out on a limb and guess.
if (m_pAmx->alt < 0)
{
//take a guess that it's local
addr = m_pAmx->alt - pTrace->frm;
v_class = 1;
} else {
//take a guess that it's a global
//it won't be global if it's passed in from the stack frame, however
// doing this with a hardcoded array size is quite rare, and is probably passed
// as iREFARRAY not iARRAY!
addr = m_pAmx->alt;
v_class = 0;
}
bool found = false;
bool _found = true;
static char _msgbuf[255];
size_t _size = 0;
//take a pre-emptive guess at the v_class!
//are we GLOBAL (0) or LOCAL (1) ?
if (m_pAmx->alt < 0)
{
v_class = 1;
i_dent = iARRAY;
arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt);
} else {
//it's greater than 0, check other things!
if (m_pAmx->alt >= m_pAmx->hlw &&
m_pAmx->alt <= m_pAmx->stp)
{
//it's in the stack somewhere... guess that it's a local!
v_class = 1;
//relocate it
m_pAmx->alt -= pTrace->frm;
//alt cannot be zero
if (m_pAmx->alt < 0)
i_dent = iARRAY;
else
i_dent = iREFARRAY;
arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt);
} else {
//guess that it's DAT
v_class = 0;
i_dent = iARRAY;
arr_addr = (cell *)(data + m_pAmx->alt);
}
}
for (index = 0; index < symbols; index++)
{
pSymbol = pSymbols[index];
if (pSymbol->codestart <= (ucell)cip &&
pSymbol->codeend >= (ucell)cip &&
(pSymbol->ident == iARRAY || pSymbol->ident == iREFARRAY))
{
amx_err = dbg_GetArrayDim(pDbg, pSymbol, &pDims);
if (amx_err != AMX_ERR_NONE)
continue;
//calculate the size of the array. this is important!
ucell size = pDims[0].size;
ucell aggre = pDims[0].size;
valid = false;
for (int16_t i=1; i<pSymbol->dim; i++)
{
aggre *= pDims[i].size;
size += aggre;
}
if (pSymbol->vclass != v_class)
continue;
if (pSymbol->ident != i_dent)
continue;
if (v_class == 1)
{
if (i_dent == iARRAY)
{
p_addr = (cell *)(data + pTrace->frm + pSymbol->address);
} else if (i_dent == iREFARRAY) {
//get the variable off the stack, by reference
ucell _addr = (ucell)*((cell *)(data + pTrace->frm + pSymbol->address));
p_addr = (cell *)(data + _addr);
}
} else if (v_class == 0) {
p_addr = (cell *)(data + pSymbol->address);
}
//make sure our address is in bounds!
if (arr_addr < p_addr || arr_addr > (p_addr + size))
continue;
int *sizes = new int[pSymbol->dim];
int *indexes = new int[pSymbol->dim];
for (int i=0; i<pSymbol->dim; i++)
{
sizes[i] = pDims[i].size;
indexes[i] = -1;
}
flags = 0;
if (pSymbol->dim >= 2)
{
int dims = pSymbol->dim;
indexes[0] = WalkArray(p_addr, data, arr_addr, 0, pSymbol->dim, flags, sizes, indexes);
if (indexes[0] == -1)
{
while (indexes[0] == -1 && --dims > 0)
{
flags = 0;
indexes[0] = WalkArray(p_addr, data, arr_addr, 0, dims, flags, sizes, indexes);
}
}
//find the last known good dimension
for (dims=pSymbol->dim-1; dims>=0; dims--)
{
if (indexes[dims] != -1)
break;
}
//check for the "impossible" case.
//if we have [X][-1], and X is zero, the array did not walk properly.
if (dims >= 0
&& indexes[dims] == 0
&& !(flags & FLAG_INDIRECT)
&& dims < pSymbol->dim - 1)
{
//here we have the dreaded MIXED CASE. we don't know whether
//[-][X] or [0][-] (where - is a bad input) was intended.
//first, we take a guess by checking the bounds.
cell *_cip = (cell *)_CipAsVa(cip);
_cip -= 1;
cell bounds = *_cip;
if (sizes[dims] != sizes[dims+1])
{
//we were checking initial bounds
if (bounds == sizes[dims] - 1)
{
indexes[dims] = m_pAmx->pri;
} else if (bounds == sizes[dims+1] - 1) {
indexes[dims + 1] = m_pAmx->pri;
indexes[dims] = 0;
} else {
//this should really never happen...
_found = false;
}
} else {
_found = false;
}
if (!_found)
{
//we still don't have a good approximation.
//the user did something like:
//new X[40][40]
//we could do some really complicated and random guesswork
// but fact is, we have no way of deterministically knowing
// what the user intended.
}
} else {
//set the last know index to our culprit
indexes[dims + 1] = m_pAmx->pri;
}
} else {
indexes[0] = m_pAmx->pri;
}
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "(array \"%s", pSymbol->name);
for (int i=0; i<pSymbol->dim; i++)
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", pDims[i].size);
if (_found)
{
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (indexed \"");
for (int i=0; i<pSymbol->dim; i++)
{
if (indexes[i] == -1)
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[]");
else
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", indexes[i]);
}
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\")");
} else {
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (unknown index \"%d\")", m_pAmx->pri);
}
found = true;
delete [] indexes;
delete [] sizes;
break;
} /* symbol validation */
} /* is in valid ranges */
if (!found)
_msgbuf[0] = '\0';
size += _snprintf(buffer, maxLength, "%s", _msgbuf);
} }
return size; return size;
@ -556,15 +788,15 @@ void Debugger::Clear()
void Debugger::DisplayTrace(const char *message) void Debugger::DisplayTrace(const char *message)
{ {
if (message != NULL) if (message != NULL)
AMXXLOG_Error("%s", message); AMXXLOG_Log("%s", message);
char buffer[512]; char buffer[512];
FormatError(buffer, sizeof(buffer)-1); FormatError(buffer, sizeof(buffer)-1);
const char *filename = _GetFilename(); const char *filename = _GetFilename();
AMXXLOG_Error("[AMXX] Displaying debug trace (plugin \"%s\")", filename); AMXXLOG_Log("[AMXX] Displaying debug trace (plugin \"%s\")", filename);
AMXXLOG_Error("[AMXX] %s", buffer); AMXXLOG_Log("[AMXX] %s", buffer);
int count = 0; int count = 0;
long lLine; long lLine;
@ -573,7 +805,7 @@ void Debugger::DisplayTrace(const char *message)
while (pTrace) while (pTrace)
{ {
GetTraceInfo(pTrace, lLine, function, file); GetTraceInfo(pTrace, lLine, function, file);
AMXXLOG_Error( AMXXLOG_Log(
"[AMXX] [%d] %s::%s (line %d)", "[AMXX] [%d] %s::%s (line %d)",
count, count,
file, file,
@ -608,7 +840,6 @@ const char *Debugger::_GetFilename()
void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength) void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength)
{ {
const char *filename = ""; const char *filename = "";
char native[sNAMEMAX+1];
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx); CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
if (a) if (a)
@ -623,16 +854,8 @@ void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLengt
} }
} }
if (error == AMX_ERR_EXIT)
{
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - %s", error, filename, GenericError(AMX_ERR_EXIT));
} else if (error == AMX_ERR_NATIVE) {
amx_GetNative(amx, reinterpret_cast<long>(amx->usertags[UT_NATIVE]), native);
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") (native \"%s\") - debug not enabled!", error, filename, native);
} else {
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename); _snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename);
} }
}
void Debugger::GenericMessage(AMX *amx, int err) void Debugger::GenericMessage(AMX *amx, int err)
{ {
@ -642,14 +865,12 @@ void Debugger::GenericMessage(AMX *amx, int err)
Debugger::FmtGenericMsg(amx, err, buffer, sizeof(buffer)-1); Debugger::FmtGenericMsg(amx, err, buffer, sizeof(buffer)-1);
if (buffer[0] != '\0') if (buffer[0] != '\0')
AMXXLOG_Error("[AMXX] %s", buffer); AMXXLOG_Log("[AMXX] %s", buffer);
} }
Debugger::~Debugger() Debugger::~Debugger()
{ {
Clear(); Clear();
dbg_FreeInfo(m_pAmxDbg);
delete m_pAmxDbg;
} }
int Handler::SetErrorHandler(const char *function) int Handler::SetErrorHandler(const char *function)
@ -658,7 +879,7 @@ int Handler::SetErrorHandler(const char *function)
error = amx_FindPublic(m_pAmx, function, &m_iErrFunc); error = amx_FindPublic(m_pAmx, function, &m_iErrFunc);
if (error != AMX_ERR_NONE && m_iErrFunc < 0) if (error != AMX_ERR_NONE && m_iErrFunc < 1)
m_iErrFunc = -1; m_iErrFunc = -1;
return error; return error;
@ -670,7 +891,7 @@ int Handler::SetModuleFilter(const char *function)
error = amx_FindPublic(m_pAmx, function, &m_iModFunc); error = amx_FindPublic(m_pAmx, function, &m_iModFunc);
if (error != AMX_ERR_NONE && m_iModFunc < 0) if (error != AMX_ERR_NONE && m_iModFunc < 1)
m_iModFunc = -1; m_iModFunc = -1;
return error; return error;
@ -704,9 +925,9 @@ const char *Handler::GetLastMsg()
return m_MsgCache.c_str(); return m_MsgCache.c_str();
} }
int Handler::HandleModule(const char *module, bool isClass) int Handler::HandleModule(const char *module)
{ {
if (m_iModFunc < 0) if (m_iModFunc < 1)
return 0; return 0;
/** /**
@ -714,20 +935,14 @@ int Handler::HandleModule(const char *module, bool isClass)
*/ */
cell hea_addr, *phys_addr, retval; cell hea_addr, *phys_addr, retval;
Debugger *pd;
pd = DisableDebugHandler(m_pAmx);
//temporarily set prenit //temporarily set prenit
m_pAmx->flags |= AMX_FLAG_PRENIT; m_pAmx->flags |= AMX_FLAG_PRENIT;
amx_Push(m_pAmx, isClass ? 1 : 0);
amx_PushString(m_pAmx, &hea_addr, &phys_addr, module, 0, 0); amx_PushString(m_pAmx, &hea_addr, &phys_addr, module, 0, 0);
int err = amx_Exec(m_pAmx, &retval, m_iModFunc); int err = amx_Exec(m_pAmx, &retval, m_iModFunc);
amx_Release(m_pAmx, hea_addr); amx_Release(m_pAmx, hea_addr);
m_pAmx->flags &= ~AMX_FLAG_PRENIT; m_pAmx->flags &= ~AMX_FLAG_PRENIT;
EnableDebugHandler(m_pAmx, pd);
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
return 0; return 0;
@ -751,8 +966,6 @@ int Handler::HandleNative(const char *native, int index, int trap)
if (pDebugger && trap) if (pDebugger && trap)
pDebugger->BeginExec(); pDebugger->BeginExec();
else if (pDebugger && !trap)
DisableDebugHandler(m_pAmx);
cell hea_addr, *phys_addr, retval; cell hea_addr, *phys_addr, retval;
@ -774,7 +987,7 @@ int Handler::HandleNative(const char *native, int index, int trap)
} }
if (!trap) if (!trap)
{ {
AMXXLOG_Error("[AMXX] Runtime failure %d occurred in native filter. Aborting plugin load.", err); AMXXLOG_Log("[AMXX] Runtime failure %d occurred in native filter. Aborting plugin load.", err);
return 0; return 0;
} }
//handle this manually. //handle this manually.
@ -785,15 +998,13 @@ int Handler::HandleNative(const char *native, int index, int trap)
} else if (err != -1) { } else if (err != -1) {
LogError(m_pAmx, err, NULL); LogError(m_pAmx, err, NULL);
} }
AMXXLOG_Error("[AMXX] NOTE: Runtime failures in native filters are not good!"); AMXXLOG_Log("[AMXX] NOTE: Runtime failures in native filters are not good!");
retval = 0; retval = 0;
} }
if (!trap) if (!trap)
m_pAmx->flags &= ~AMX_FLAG_PRENIT; m_pAmx->flags &= ~AMX_FLAG_PRENIT;
if (pDebugger && trap) if (pDebugger && trap)
pDebugger->EndExec(); pDebugger->EndExec();
else if (pDebugger && !trap)
EnableDebugHandler(m_pAmx, pDebugger);
amx_Release(m_pAmx, hea_addr); amx_Release(m_pAmx, hea_addr);
@ -845,10 +1056,10 @@ int Handler::HandleError(const char *msg)
pDebugger->DisplayTrace(msg); pDebugger->DisplayTrace(msg);
} else { } else {
if (GetLastMsg()) if (GetLastMsg())
AMXXLOG_Error("%s", GetLastMsg()); AMXXLOG_Log("%s", GetLastMsg());
Debugger::GenericMessage(m_pAmx, err); Debugger::GenericMessage(m_pAmx, err);
} }
AMXXLOG_Error("[AMXX] NOTE: Runtime failures in an error filter are not good!"); AMXXLOG_Log("[AMXX] NOTE: Runtime failures in an error filter are not good!");
} }
if (pDebugger) if (pDebugger)
@ -876,7 +1087,7 @@ static cell AMX_NATIVE_CALL set_error_filter(AMX *amx, cell *params)
if (!pHandler) if (!pHandler)
{ {
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND); Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
AMXXLOG_Error("[AMXX] Plugin not initialized correctly."); AMXXLOG_Log("[AMXX] Plugin not initialized correctly.");
return 0; return 0;
} }
@ -884,7 +1095,7 @@ static cell AMX_NATIVE_CALL set_error_filter(AMX *amx, cell *params)
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
{ {
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND); Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
AMXXLOG_Error("[AMXX] Function not found: %s", function); AMXXLOG_Log("[AMXX] Function not found: %s", function);
return 0; return 0;
} }
@ -964,7 +1175,7 @@ static cell AMX_NATIVE_CALL set_native_filter(AMX *amx, cell *params)
if (!pHandler) if (!pHandler)
{ {
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND); Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
AMXXLOG_Error("[AMXX] Plugin not initialized correctly."); AMXXLOG_Log("[AMXX] Plugin not initialized correctly.");
return 0; return 0;
} }
@ -983,7 +1194,7 @@ static cell AMX_NATIVE_CALL set_native_filter(AMX *amx, cell *params)
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
{ {
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND); Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
AMXXLOG_Error("[AMXX] Function not found: %s", function); AMXXLOG_Log("[AMXX] Function not found: %s", function);
return 0; return 0;
} }

View File

@ -50,7 +50,7 @@ public:
struct trace_info struct trace_info
{ {
trace_info() : cip(0), frm(0), next(NULL), prev(NULL), used(false) {}; trace_info() : cip(0), frm(0), used(false), next(NULL), prev(NULL) {};
cell cip; cell cip;
cell frm; cell frm;
@ -167,7 +167,7 @@ public:
public: public:
int HandleError(const char *msg); int HandleError(const char *msg);
int HandleNative(const char *native, int index, int trap); int HandleNative(const char *native, int index, int trap);
int HandleModule(const char *module, bool isClass=false); int HandleModule(const char *module);
public: public:
bool IsHandling() const { return m_Handling; } bool IsHandling() const { return m_Handling; }
void SetErrorMsg(const char *msg); void SetErrorMsg(const char *msg);
@ -176,7 +176,7 @@ public:
trace_info_t *GetTrace() const { return m_pTrace; } trace_info_t *GetTrace() const { return m_pTrace; }
const char *GetFmtCache() { return m_FmtCache.c_str(); } const char *GetFmtCache() { return m_FmtCache.c_str(); }
bool IsNativeFiltering() { return (m_iNatFunc > -1); } bool IsNativeFiltering() { return (m_iNatFunc > 0); }
bool InNativeFilter() { return m_InNativeFilter; } bool InNativeFilter() { return m_InNativeFilter; }
private: private:
AMX *m_pAmx; AMX *m_pAmx;

View File

@ -30,7 +30,6 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "CMenu.h"
int gmsgAmmoPickup; int gmsgAmmoPickup;
int gmsgAmmoX; int gmsgAmmoX;
@ -60,13 +59,10 @@ void Client_VGUIMenu(void* mValue)
{ {
if (!mPlayer) return; if (!mPlayer) return;
mPlayer->vgui = true;
switch (mState++) switch (mState++)
{ {
case 0: case 0:
mPlayer->menu = -(*(int*)mValue); mPlayer->menu = -(*(int*)mValue);
mPlayer->newmenu = -1;
break; break;
case 1: case 1:
mPlayer->keys = *(int*)mValue; mPlayer->keys = *(int*)mValue;
@ -77,26 +73,19 @@ void Client_ShowMenu(void* mValue)
{ {
if (!mPlayer) return; if (!mPlayer) return;
mPlayer->vgui = true;
switch (mState++) switch (mState++)
{ {
case 0: case 0:
mPlayer->keys = *(int*)mValue; mPlayer->keys = *(int*)mValue;
break; break;
case 3: case 3:
{
mPlayer->menu = g_menucmds.findMenuId((char*)mValue); mPlayer->menu = g_menucmds.findMenuId((char*)mValue);
mPlayer->newmenu = -1;
break;
}
} }
} }
extern bool g_bmod_tfc;
void Client_TeamInfo(void* mValue) void Client_TeamInfo(void* mValue)
{ {
if (mPlayer && !g_bmod_tfc) return; if (mPlayer) return;
static int index; static int index;
switch (mState++) switch (mState++)
@ -109,7 +98,6 @@ void Client_TeamInfo(void* mValue)
char* msg = (char*)mValue; char* msg = (char*)mValue;
g_players[index].team.assign(msg); g_players[index].team.assign(msg);
g_teamsIds.registerTeam(msg, -1); g_teamsIds.registerTeam(msg, -1);
break;
} }
} }
@ -212,15 +200,9 @@ void Client_CurWeapon(void* mValue)
case 2: case 2:
if (!mPlayer) return; if (!mPlayer) return;
if (!iState || (iId < 1 || iId >= MAX_WEAPONS)) break; if (!iState || (iId < 1 || iId >= MAX_WEAPONS)) break;
mPlayer->current = iId;
if (*(int*)mValue < mPlayer->weapons[iId].clip && // Only update the lastHit vector if the clip size is decreasing
*(int*)mValue != -1) // But not if it's a melee weapon
{
mPlayer->lastHit = mPlayer->lastTrace;
}
mPlayer->weapons[iId].clip = *(int*)mValue; mPlayer->weapons[iId].clip = *(int*)mValue;
mPlayer->current = iId;
mPlayer->lastHit = mPlayer->lastTrace;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,203 @@
#ifndef __FAKEMETA_H__ #ifndef __FAKEMETA_H__
#define __FAKEMETA_H__ #define __FAKEMETA_H__
#ifndef FAKEMETA
int UnloadMetamodPlugin(void *handle); int UnloadMetamodPlugin(void *handle);
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now); int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
#else
// Fake metamod api for modules
#include "CList.h"
// from mplugin.h (metamod)
// Flags to indicate current "load" state of plugin.
// NOTE: order is important, as greater/less comparisons are made.
typedef enum
{
PL_EMPTY = 0, // empty slot
PL_VALID, // has valid info in it
PL_BADFILE, // nonexistent file (open failed),
// or not a valid plugin file (query failed)
PL_OPENED, // dlopened and queried
PL_FAILED, // opened, but failed to attach or unattach
PL_RUNNING, // attached and running
PL_PAUSED, // attached but paused
} PLUG_STATUS;
// from h_export.h (metamod)
// Our GiveFnptrsToDll, called by engine.
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals);
// *** CFakeMeta
class CFakeMeta
{
private:
// Core tables
/* DLL_FUNCTIONS m_CoreDllFuncTable;
enginefuncs_t m_CoreEngineFuncTable;
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable;
DLL_FUNCTIONS m_CoreDllFuncTable_Post;
enginefuncs_t m_CoreEngineFuncTable_Post;
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable_Post; */
bool AddCorePlugin(); // Adds the core plugin if needed
public:
class CFakeMetaPlugin
{
private:
// plugin info
String m_Path;
PLUG_STATUS m_Status;
plugin_info_t *m_Info;
// Function tables
META_FUNCTIONS m_MetaFuncTable;
DLL_FUNCTIONS m_DllFuncTable;
enginefuncs_t m_EngineFuncTable;
NEW_DLL_FUNCTIONS m_NewDllFuncTable;
DLL_FUNCTIONS m_DllFuncTable_Post;
enginefuncs_t m_EngineFuncTable_Post;
NEW_DLL_FUNCTIONS m_NewDllFuncTable_Post;
// OS dep handle
DLHANDLE m_Handle;
public:
inline PLUG_STATUS GetStatus() const
{ return m_Status; }
inline void SetStatus(PLUG_STATUS newStatus)
{ m_Status = newStatus; }
inline plugin_info_t * GetInfo()
{ return m_Info; }
inline const plugin_info_t * GetInfo() const
{ return m_Info; }
inline void SetInfo(plugin_info_t *newInfo)
{ m_Info = newInfo; }
inline const char * GetPath()
{ return m_Path.c_str(); }
inline const META_FUNCTIONS &GetMetaFunctions() const
{ return m_MetaFuncTable; }
// Get
inline DLL_FUNCTIONS &GetDllFuncTable()
{ return m_DllFuncTable; }
inline enginefuncs_t &GetEngineFuncTable()
{ return m_EngineFuncTable; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
{ return m_NewDllFuncTable; }
// Get const
inline const DLL_FUNCTIONS &GetDllFuncTable() const
{ return m_DllFuncTable; }
inline const enginefuncs_t &GetEngineFuncTable() const
{ return m_EngineFuncTable; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
{ return m_NewDllFuncTable; }
// Get post
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
{ return m_DllFuncTable_Post; }
inline enginefuncs_t &GetEngineFuncTable_Post()
{ return m_EngineFuncTable_Post; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
{ return m_NewDllFuncTable_Post; }
// Get post const
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
{ return m_DllFuncTable_Post; }
inline const enginefuncs_t &GetEngineFuncTable_Post() const
{ return m_EngineFuncTable_Post; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
{ return m_NewDllFuncTable_Post; }
int Query(mutil_funcs_t *pMetaUtilFuncs); // Also calls GiveFnPtrsToDll
int Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs);
int Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int GetEntityAPI2(int interfaceVersion);
int GetEntityAPI2_Post(int interfaceVersion);
int GetEngineFunctions(int interfaceVersion);
int GetEngineFunctions_Post(int interfaceVersion);
int GetNewDLLFunctions(int interfaceVersion);
int GetNewDLLFunctions_Post(int interfaceVersion);
CFakeMetaPlugin(const char *path);
~CFakeMetaPlugin();
}; // CFakeMetaPlugin
CFakeMeta();
~CFakeMeta();
bool AddPlugin(const char *path /*path relative to moddir*/);
void ReleasePlugins();
// This is public because i don't want to declare all the functions as friends :)
// :NOTE: The core is now a special, first plugin!
CList<CFakeMetaPlugin> m_Plugins;
// ****** Meta functions ******
// Query all added plugins
void Meta_Query(mutil_funcs_t *pMetaUtilFuncs);
// Attach all added plugins
void Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs);
// Detach all added plugins
void Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
// :NOTE: Meta_Init currently not supported
int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
// Get
/*inline DLL_FUNCTIONS &GetDllFuncTable()
{ return m_CoreDllFuncTable; }
inline enginefuncs_t &GetEngineFuncTable()
{ return m_CoreEngineFuncTable; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
{ return m_CoreNewDllFuncTable; }
// Get const
inline const DLL_FUNCTIONS &GetDllFuncTable() const
{ return m_CoreDllFuncTable; }
inline const enginefuncs_t &GetEngineFuncTable() const
{ return m_CoreEngineFuncTable; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
{ return m_CoreNewDllFuncTable; }
// Get post
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
{ return m_CoreDllFuncTable_Post; }
inline enginefuncs_t &GetEngineFuncTable_Post()
{ return m_CoreEngineFuncTable_Post; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
{ return m_CoreNewDllFuncTable_Post; }
// Get post const
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
{ return m_CoreDllFuncTable_Post; }
inline const enginefuncs_t &GetEngineFuncTable_Post() const
{ return m_CoreEngineFuncTable_Post; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
{ return m_CoreNewDllFuncTable_Post; } */
}; // CFakeMeta
// Fake Metamod
// defined in meta_api.cpp
extern CFakeMeta g_FakeMeta;
#endif //FAKEMETA
#endif // #ifndef __FAKEMETA_H__ #endif // #ifndef __FAKEMETA_H__

View File

@ -5,7 +5,7 @@
* *
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public<EFBFBD> License as published by the
* Free Software Foundation; either version 2 of the License, or (at * Free Software Foundation; either version 2 of the License, or (at
* your option) any later version. * your option) any later version.
* *
@ -51,6 +51,8 @@
#include <io.h> #include <io.h>
#endif #endif
#include <extdll.h>
#include <meta_api.h>
#include "amxmodx.h" #include "amxmodx.h"
CVector<FILE *> FileList; CVector<FILE *> FileList;
@ -139,7 +141,7 @@ static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */
if ((fp =fopen(build_pathname("%s", szFile), "r")) == NULL) if ((fp =fopen(build_pathname("%s", szFile), "r")) == NULL)
{ {
LogError(amx, AMX_ERR_NATIVE, "Couldn't read file \"%s\"", szFile); amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
@ -183,7 +185,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
{ {
if ((pFile = fopen(sFile, "a")) == NULL) if ((pFile = fopen(sFile, "a")) == NULL)
{ {
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile); amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
@ -199,7 +201,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
{ {
if ((pFile = fopen(sFile, "w")) == NULL) if ((pFile = fopen(sFile, "w")) == NULL)
{ {
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile); amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
@ -219,7 +221,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
if ((pTemp = tmpfile()) == NULL) if ((pTemp = tmpfile()) == NULL)
{ {
LogError(amx, AMX_ERR_NATIVE, "Couldn't create temp file"); amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
@ -249,7 +251,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
// now rewrite because file can be now smaller... // now rewrite because file can be now smaller...
if ((pFile = fopen(sFile, "w")) == NULL) if ((pFile = fopen(sFile, "w")) == NULL)
{ {
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile); amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
@ -305,7 +307,27 @@ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
char *sFile = get_amxstring(amx, params[1], 0, iLen); char *sFile = get_amxstring(amx, params[1], 0, iLen);
char *file = build_pathname("%s", sFile); char *file = build_pathname("%s", sFile);
return DirExists(file) ? 1 : 0; #if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(file);
if (attr == INVALID_FILE_ATTRIBUTES)
return 0;
if (attr == FILE_ATTRIBUTE_DIRECTORY)
return 1;
return 0;
#else
struct stat s;
if (stat(file, &s) != 0)
return 0;
if (S_ISDIR(s.st_mode))
return 1;
return 0;
#endif
} }
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
@ -356,283 +378,251 @@ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
return -1; return -1;
} }
//ported from Sanji's file access module by BAILOPAN
// Important update - now uses new handles
static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
{ {
int len; unsigned int i;
int len, j = -1;
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len)); char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
char *flags = get_amxstring(amx, params[2], 0, len); char *flags = get_amxstring(amx, params[2], 0, len);
FILE *fp = fopen(file, flags); FILE *fp = fopen(file, flags);
return (cell)fp; if (fp == NULL)
}
static cell AMX_NATIVE_CALL amx_fwrite_blocks(AMX *amx, cell *params)
{ {
FILE *fp = (FILE *)params[1]; // Failed
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
size_t blocks = params[3];
size_t btmp = blocks;
cell mode = params[4];
switch (mode)
{
case 1:
{
char *a = new char[blocks];
char *ptr = a;
while (btmp--)
*ptr++ = static_cast<char>(*addr++);
size_t res = fwrite(a, sizeof(char), blocks, fp);
delete [] a;
return res;
}
case 2:
{
short *a = new short[blocks];
short *ptr = a;
while (btmp--)
*ptr++ = static_cast<short>(*addr++);
size_t res = fwrite(a, sizeof(short), blocks, fp);
delete [] a;
return res;
}
case 4:
{
int *a = new int[blocks];
int *ptr = a;
while (btmp--)
*ptr++ = static_cast<int>(*addr++);
size_t res = fwrite(a, sizeof(int), blocks, fp);
delete [] a;
return res;
}
}
return 0; return 0;
} }
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params) for (i = 0; i < FileList.size(); i++)
{ {
FILE *fp = (FILE *)params[1]; if (FileList.at(i) == NULL)
if (!fp)
return 0;
size_t mode = params[3];
switch (mode)
{ {
case 1: j = i;
{ break;
char a = static_cast<char>(params[2]);
return fwrite(&a, sizeof(char), 1, fp);
}
case 2:
{
short b = static_cast<short>(params[2]);
return fwrite(&b, sizeof(short), 1, fp);
}
case 4:
{
int c = static_cast<int>(params[2]);
return fwrite(&c, sizeof(int), 1, fp);
} }
} }
return 0; if (j == -1)
{
FileList.push_back(fp);
j = FileList.size() - 1;
} else {
FileList.at(j) = fp;
} }
static cell AMX_NATIVE_CALL amx_fwrite_raw(AMX *amx, cell *params) return j + 1;
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
return fwrite(addr, params[3], params[4], fp);
}
static cell AMX_NATIVE_CALL amx_fread_raw(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
size_t size = static_cast<cell>(params[3]);
size_t blocks = static_cast<cell>(params[4]);
return fread(addr, size, blocks, fp);
}
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
switch (params[3])
{
case 1: //char
{
char a;
size_t res = fread(&a, sizeof(char), 1, fp);
*addr = static_cast<cell>(a);
return res;
}
case 2: //short
{
short a;
size_t res = fread(&a, sizeof(short), 1, fp);
*addr = static_cast<cell>(a);
return res;
}
case 4: //int
default:
{
int a;
size_t res = fread(&a, sizeof(int), 1, fp);
*addr = static_cast<cell>(a);
return res;
}
}
return 0;
}
static cell AMX_NATIVE_CALL amx_fread_blocks(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
size_t blocks = params[3];
switch (params[3])
{
case 1: //char
{
char *a = new char[blocks];
char *ptr = a;
size_t res = fread(a, sizeof(char), blocks, fp);
while (blocks--)
*addr++ = static_cast<cell>(*ptr++);
delete [] a;
return res;
}
case 2: //short
{
short *a = new short[blocks];
short *ptr = a;
size_t res = fread(a, sizeof(short), blocks, fp);
while (blocks--)
*addr++ = static_cast<cell>(*ptr++);
delete [] a;
return res;
}
case 4: //int
default:
{
int *a = new int[blocks];
int *ptr = a;
size_t res = fread(a, sizeof(int), blocks, fp);
while (blocks--)
*addr++ = static_cast<cell>(*ptr++);
delete [] a;
return res;
}
}
return 0;
}
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
int len;
char *str = get_amxstring(amx, params[2], 0, len);
return fputs(str, fp);
}
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
static char buffer[4096];
buffer[0] = '\0';
fgets(buffer, sizeof(buffer)-1, fp);
return set_amxstring(amx, params[2], buffer, params[3]);
}
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fseek(fp, params[2], params[3]);
}
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return ftell(fp);
}
static cell AMX_NATIVE_CALL amx_fprintf(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
int len;
char *str = format_amxstring(amx, params, 2, len);
return fprintf(fp, "%s", str);
}
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 1;
return feof(fp);
} }
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
{ {
FILE *fp = (FILE *)params[1]; unsigned int id = params[1] - 1;
if (!fp) if (id >= FileList.size() || FileList.at(id) == NULL)
return 1; return 0;
fclose(fp); FILE *fp = FileList.at(id);
if (fp)
{
return fclose(fp);
} else {
return -1;
}
}
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
char *buffer;
if (fp)
{
buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?)
fread(buffer, sizeof(char), params[3], fp);
set_amxstring(amx, params[2], buffer, params[3]);
delete [] buffer;
return 1; return 1;
} }
return -1;
}
#ifdef UNUSED
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fgetc(fp);
} else {
return -1;
}
}
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
char *buf;
int len;
if (fp)
{
buf = format_amxstring(amx, params, 2, len);
return fwrite(buf, sizeof(char), strlen(buf), fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
if (feof(fp))
{
return 1;
}
return 0;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fseek(fp, (long)params[2], params[3]);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fputc(params[2], fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
rewind(fp);
return 1;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fflush(fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
char *buf;
int len;
buf = format_amxstring(amx, params, 2, len);
if (fp)
{
return fscanf(fp, "%s", buf);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return ftell(fp);
}
return -1;
}
#endif //UNUSED
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
{ {
int len; int len;
@ -652,6 +642,164 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
return -1; return -1;
} }
#ifdef UNUSED
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
long t;
if (fp)
{
fread(&t, sizeof(long), 1, fp);
return t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
int t;
if (fp)
{
fread(&t, sizeof(int), 1, fp);
return t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
short t;
if (fp)
{
fread(&t, sizeof(short), 1, fp);
return t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
short size = params[2];
if (fp)
{
return fwrite(&size, sizeof(short), 1, fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
long size = params[2];
if (fp)
{
return fwrite(&size, sizeof(long), 1, fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
int size = params[2];
if (fp)
{
return fwrite(&size, sizeof(int), 1, fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
float t;
if (fp)
{
fread(&t, sizeof(float), 1, fp);
return *(cell*)&t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
float size = *(float *)((void *)&params[2]);
if (fp)
{
return fwrite(&size, sizeof(float), 1, fp);
}
return -1;
}
#endif //UNUSED
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
{ {
int len; int len;
@ -682,13 +830,13 @@ static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
DIR *dp = opendir(dirname); DIR *dp = opendir(dirname);
if (!dp) if (!dp)
return 0; return NULL;
struct dirent *ep = readdir(dp); struct dirent *ep = readdir(dp);
if (!ep) if (!ep)
{ {
closedir(dp); closedir(dp);
return 0; return NULL;
} }
set_amxstring(amx, params[2], ep->d_name, params[3]); set_amxstring(amx, params[2], ep->d_name, params[3]);
@ -751,110 +899,6 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
#endif #endif
} }
//native fgetc( file );
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fgetc(fp);
}
//native fputc( file, data );
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fputc(static_cast<int>(params[2]), fp);
}
//native ungetc( file, data );
static cell AMX_NATIVE_CALL amx_ungetc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return ungetc(static_cast<int>(params[2]), fp);
}
#if defined __linux__
#define _rmdir rmdir
#endif
static cell AMX_NATIVE_CALL amx_rmdir(AMX *amx, cell *params)
{
int len;
char* sFile = build_pathname("%s", get_amxstring(amx, params[1], 0, len));
if (_rmdir(sFile) != 0)
return 0;
return 1;
}
static cell AMX_NATIVE_CALL amx_rename(AMX *amx, cell *params)
{
int len;
char f_old_r[260];
char f_new_r[260];
char *fold = get_amxstring(amx, params[1], 0, len);
char *fnew = get_amxstring(amx, params[2], 1, len);
if (params[0] / sizeof(cell) == 3 && params[3])
{
build_pathname_r(f_old_r, sizeof(f_old_r)-1, "%s", fold);
build_pathname_r(f_new_r, sizeof(f_new_r)-1, "%s", fnew);
} else {
snprintf(f_old_r, sizeof(f_old_r)-1, "%s", fold);
snprintf(f_new_r, sizeof(f_new_r)-1, "%s", fnew);
}
#if defined __linux__
return (rename(f_old_r, f_new_r) == 0);
#elif defined WIN32
return MoveFileA(f_old_r, f_new_r);
#endif
}
static cell LoadFileForMe(AMX *amx, cell *params)
{
int len;
char *file = get_amxstring(amx, params[1], 0, len);
char path[256];
build_pathname_r(path, sizeof(path), "%s", file);
byte *addr = LOAD_FILE_FOR_ME(path, &len);
if (addr == NULL)
{
return -1;
}
cell *buffer = get_amxaddr(amx, params[2]);
cell maxlength = params[3];
cell *bytes_avail = get_amxaddr(amx, params[4]);
*bytes_avail = len;
cell count;
for (count = 0; count < len && count < maxlength; count++)
{
buffer[count] = addr[count];
}
FREE_FILE(addr);
return count;
}
AMX_NATIVE_INFO file_Natives[] = AMX_NATIVE_INFO file_Natives[] =
{ {
{"delete_file", delete_file}, {"delete_file", delete_file},
@ -863,33 +907,35 @@ AMX_NATIVE_INFO file_Natives[] =
{"read_dir", read_dir}, {"read_dir", read_dir},
{"read_file", read_file}, {"read_file", read_file},
{"write_file", write_file}, {"write_file", write_file},
//new, sane file natives //Sanji's File Natives
{"fopen", amx_fopen}, {"fopen", amx_fopen},
{"fclose", amx_fclose}, {"fclose", amx_fclose},
{"fread", amx_fread}, {"fread", amx_fread},
{"fread_blocks", amx_fread_blocks},
{"fread_raw", amx_fread_raw},
{"fwrite", amx_fwrite},
{"fwrite_blocks", amx_fwrite_blocks},
{"fwrite_raw", amx_fwrite_raw},
{"feof", amx_feof},
{"fprintf", amx_fprintf},
{"fgets", amx_fgets},
{"fseek", amx_fseek},
{"ftell", amx_ftell},
{"filesize", amx_filesize}, {"filesize", amx_filesize},
#ifdef UNUSED
{"fgetc", amx_fgetc},
{"fwrite", amx_fwrite},
{"feof", amx_feof},
{"fseek", amx_fseek},
{"fputc", amx_fputc},
{"rewind", amx_rewind},
{"fflush", amx_fflush},
{"fscanf", amx_fscanf},
{"ftell", amx_ftell},
{"fgetl", amx_fgetl},
{"fgeti", amx_fgeti},
{"fgets", amx_fgets},
{"fputs", amx_fputs},
{"fputl", amx_fputl},
{"fputi", amx_fputi},
{"fgetf", amx_fgetf},
{"fputf", amx_fputf},
#endif
{"unlink", delete_file}, {"unlink", delete_file},
{"build_pathname", amx_build_pathname}, {"build_pathname", amx_build_pathname},
{"dir_exists", dir_exists}, {"dir_exists", dir_exists},
{"open_dir", amx_open_dir}, {"open_dir", amx_open_dir},
{"close_dir", amx_close_dir}, {"close_dir", amx_close_dir},
{"next_file", amx_get_dir}, {"next_file", amx_get_dir},
{"fgetc", amx_fgetc},
{"fputc", amx_fputc},
{"fungetc", amx_ungetc},
{"rmdir", amx_rmdir},
{"fputs", amx_fputs},
{"rename_file", amx_rename},
{"LoadFileForMe", LoadFileForMe},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -368,6 +368,7 @@ static cell AMX_NATIVE_CALL n_floatatan(AMX *amx, cell *params)
* params[2] = radix * params[2] = radix
*/ */
REAL fA = amx_ctof(params[1]); REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = atan(fA); fA = atan(fA);
fA = FromRadians(fA, params[2]); fA = FromRadians(fA, params[2]);
return amx_ftoc(fA); return amx_ftoc(fA);
@ -424,54 +425,6 @@ static cell AMX_NATIVE_CALL n_floatatan2(AMX *amx, cell *params)
return amx_ftoc(fC); return amx_ftoc(fC);
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
/* Added by DS */
static cell AMX_NATIVE_CALL n_floatsinh(AMX *amx, cell *params)
{
/*
* params[1] = angle
* params[2] = radix
*/
REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = sinh(fA);
return amx_ftoc(fA);
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
/* Added by DS */
static cell AMX_NATIVE_CALL n_floatcosh(AMX *amx, cell *params)
{
/*
* params[1] = angle
* params[2] = radix
*/
REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = cosh(fA);
return amx_ftoc(fA);
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
/* Added by DS */
static cell AMX_NATIVE_CALL n_floattanh(AMX *amx, cell *params)
{
/*
* params[1] = angle
* params[2] = radix
*/
REAL fA = amx_ctof(params[1]);
fA = ToRadians(fA, params[2]);
fA = tanh(fA);
return amx_ftoc(fA);
}
#if defined __BORLANDC__ || defined __WATCOMC__ #if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused #pragma argsused
#endif #endif
@ -504,9 +457,6 @@ AMX_NATIVE_INFO float_Natives[] = {
{ "floatacos", n_floatacos }, { "floatacos", n_floatacos },
{ "floatatan", n_floatatan }, { "floatatan", n_floatatan },
{ "floatatan2", n_floatatan2 }, { "floatatan2", n_floatatan2 },
{ "floatsinh", n_floatsinh },
{ "floatcosh", n_floatcosh },
{ "floattanh", n_floattanh },
{ NULL, NULL } /* terminator */ { NULL, NULL } /* terminator */
}; };

View File

@ -1,597 +0,0 @@
#include "amxmodx.h"
#include "format.h"
#include "datastructs.h"
#include "amxmod_compat.h"
//Adapted from Quake3's vsprintf
// thanks to cybermind for linking me to this :)
//I made the following changes:
// - Fixed spacing to be AMX Mod X standard
// - Added 'n' support, no buffer overflows
// - Templatized input/output buffers
#define ALT 0x00000001 /* alternate form */
#define HEXPREFIX 0x00000002 /* add 0x or 0X prefix */
#define LADJUST 0x00000004 /* left adjustment */
#define LONGDBL 0x00000008 /* long double */
#define LONGINT 0x00000010 /* long integer */
#define QUADINT 0x00000020 /* quad integer */
#define SHORTINT 0x00000040 /* short integer */
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
#define FPT 0x00000100 /* floating point number */
#define UPPERDIGITS 0x00000200 /* make alpha digits uppercase */
#define to_digit(c) ((c) - '0')
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
#define to_char(n) ((n) + '0')
#define CHECK_ARGS(n) \
if ((arg+n) > args) { \
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", arg, args); \
return 0; \
}
THash<String, lang_err> BadLang_Table;
static cvar_t *amx_mldebug = NULL;
static cvar_t *amx_cl_langs = NULL;
const char *translate(AMX *amx, cell amxaddr, const char *key)
{
const char *pLangName = NULL;
const char *def = NULL;
int status;
cell *addr = get_amxaddr(amx, amxaddr);
char name[4];
if (addr[0] == LANG_PLAYER)
{
if (!amx_cl_langs)
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if ( (int)amx_cl_langs->value == 0 )
{
pLangName = g_vault.get("server_language");
} else {
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(g_langMngr.GetDefLang())->pEdict, "lang");
}
} else if (addr[0] == LANG_SERVER) {
pLangName = g_vault.get("server_language");
} else if (addr[0] >= 1 && addr[0] <= gpGlobals->maxClients) {
if (!amx_cl_langs)
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if ( (int)amx_cl_langs->value == 0 )
{
pLangName = g_vault.get("server_language");
} else {
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(addr[0])->pEdict, "lang");
}
} else {
get_amxstring_r(amx, amxaddr, name, 3);
pLangName = name;
}
if (!pLangName || !isalpha(pLangName[0]))
pLangName = "en";
//next parameter!
def = g_langMngr.GetDef(pLangName, key, status);
if (!amx_mldebug)
amx_mldebug = CVAR_GET_POINTER("amx_mldebug");
bool debug = (amx_mldebug && amx_mldebug->string && (amx_mldebug->string[0] != '\0'));
if (debug)
{
int debug_status;
bool validlang = true;
const char *testlang = amx_mldebug->string;
if (!g_langMngr.LangExists(testlang))
{
AMXXLOG_Error("[AMXX] \"%s\" is an invalid debug language", testlang);
validlang = false;
}
g_langMngr.GetDef(testlang, key, debug_status);
if (validlang && debug_status == ERR_BADKEY)
AMXXLOG_Error("[AMXX] Language key \"%s\" not found for language \"%s\", check \"%s\"", key, testlang, GetFileName(amx));
}
if (def == NULL)
{
if (debug)
{
if (status == ERR_BADLANG && (BadLang_Table.AltFindOrInsert(pLangName).last + 120.0f < gpGlobals->time))
{
AMXXLOG_Error("[AMXX] Language \"%s\" not found", pLangName);
BadLang_Table.AltFindOrInsert(pLangName).last = gpGlobals->time;
}
}
if (addr[0] != LANG_SERVER)
def = g_langMngr.GetDef(g_vault.get("server_language"), key, status);
if (!def && (strcmp(pLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0))
def = g_langMngr.GetDef("en", key, status);
}
return def;
}
template <typename U>
void AddString(U **buf_p, size_t &maxlen, const cell *string, int width, int prec)
{
int size = 0;
U *buf;
static cell nlstr[] = {'(','n','u','l','l',')','\0'};
buf = *buf_p;
if (string == NULL)
{
string = nlstr;
prec = -1;
}
if (prec >= 0)
{
for (size = 0; size < prec; size++)
{
if (string[size] == '\0')
break;
}
} else {
while (string[size++]) ;
size--;
}
if (size > (int)maxlen)
size = maxlen;
maxlen -= size;
width -= size;
while (size--)
*buf++ = static_cast<U>(*string++);
while (width-- > 0 && maxlen)
{
*buf++ = ' ';
maxlen--;
}
*buf_p = buf;
}
template <typename U>
void AddFloat(U **buf_p, size_t &maxlen, double fval, int width, int prec)
{
U text[32];
int digits;
double signedVal;
U *buf;
int val;
// get the sign
signedVal = fval;
if (fval < 0)
fval = -fval;
// write the float number
digits = 0;
val = (int)fval;
do {
text[digits++] = '0' + val % 10;
val /= 10;
} while (val);
if (signedVal < 0)
text[digits++] = '-';
buf = *buf_p;
while (digits < width && maxlen)
{
*buf++ = ' ';
width--;
maxlen--;
}
while (digits-- && maxlen)
{
*buf++ = text[digits];
maxlen--;
}
*buf_p = buf;
if (prec < 0)
prec = 6;
// write the fraction
digits = 0;
while (digits < prec)
{
fval -= (int) fval;
fval *= 10.0;
val = (int) fval;
text[digits++] = '0' + val % 10;
}
if (digits > 0 && maxlen)
{
buf = *buf_p;
*buf++ = '.';
maxlen--;
for (prec = 0; maxlen && prec < digits; prec++)
{
*buf++ = text[prec];
maxlen--;
}
*buf_p = buf;
}
}
template <typename U>
void AddUInt(U **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
{
U text[32];
int digits;
U *buf;
digits = 0;
do {
text[digits++] = '0' + val % 10;
val /= 10;
} while (val);
buf = *buf_p;
if( !(flags & LADJUST) )
{
while (digits < width && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
width--;
maxlen--;
}
}
while (digits-- && maxlen)
{
*buf++ = text[digits];
width--;
maxlen--;
}
if (flags & LADJUST)
{
while (width-- && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
maxlen--;
}
}
*buf_p = buf;
}
template <typename U>
void AddInt(U **buf_p, size_t &maxlen, int val, int width, int flags)
{
U text[32];
int digits;
int signedVal;
U *buf;
unsigned int unsignedVal;
digits = 0;
signedVal = val;
if (val < 0)
{
/* we want the unsigned version */
unsignedVal = abs(val);
} else {
unsignedVal = val;
}
do {
text[digits++] = '0' + unsignedVal % 10;
unsignedVal /= 10;
} while (unsignedVal);
if (signedVal < 0)
text[digits++] = '-';
buf = *buf_p;
if( !(flags & LADJUST) )
{
while (digits < width && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
width--;
maxlen--;
}
}
while (digits-- && maxlen)
{
*buf++ = text[digits];
width--;
maxlen--;
}
if (flags & LADJUST)
{
while (width-- && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
maxlen--;
}
}
*buf_p = buf;
}
template <typename U>
void AddHex(U **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
{
U text[32];
int digits;
U *buf;
U digit;
int hexadjust;
if (flags & UPPERDIGITS)
{
hexadjust = 'A' - '9' - 1;
} else {
hexadjust = 'a' - '9' - 1;
}
digits = 0;
do
{
digit = ('0' + val % 16);
if (digit > '9')
{
digit += hexadjust;
}
text[digits++] = digit;
val /= 16;
} while (val);
buf = *buf_p;
if( !(flags & LADJUST) )
{
while (digits < width && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
width--;
maxlen--;
}
}
while (digits-- && maxlen)
{
*buf++ = text[digits];
width--;
maxlen--;
}
if (flags & LADJUST)
{
while (width-- && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
maxlen--;
}
}
*buf_p = buf;
}
template <typename D, typename S>
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param)
{
int arg;
int args = params[0] / sizeof(cell);
D *buf_p;
D ch;
int flags;
int width;
int prec;
int n;
char sign;
const S *fmt;
size_t llen = maxlen;
buf_p = buffer;
arg = *param;
fmt = format;
while (true)
{
// run through the format string until we hit a '%' or '\0'
for (ch = static_cast<D>(*fmt);
llen && ((ch = static_cast<D>(*fmt)) != '\0' && ch != '%');
fmt++)
{
*buf_p++ = static_cast<D>(ch);
llen--;
}
if (ch == '\0' || llen <= 0)
goto done;
// skip over the '%'
fmt++;
// reset formatting state
flags = 0;
width = 0;
prec = -1;
sign = '\0';
rflag:
ch = static_cast<D>(*fmt++);
reswitch:
switch(ch)
{
case '-':
flags |= LADJUST;
goto rflag;
case '.':
n = 0;
while( is_digit( ( ch = static_cast<D>(*fmt++)) ) )
n = 10 * n + ( ch - '0' );
prec = n < 0 ? -1 : n;
goto reswitch;
case '0':
flags |= ZEROPAD;
goto rflag;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = 0;
do {
n = 10 * n + ( ch - '0' );
ch = static_cast<D>(*fmt++);
} while( is_digit( ch ) );
width = n;
goto reswitch;
case 'c':
CHECK_ARGS(0);
*buf_p++ = static_cast<D>(*get_amxaddr(amx, params[arg]));
llen--;
arg++;
break;
case 'd':
case 'i':
CHECK_ARGS(0);
AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
arg++;
break;
case 'u':
CHECK_ARGS(0);
AddUInt(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
arg++;
break;
case 'f':
CHECK_ARGS(0);
AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec);
arg++;
break;
case 'X':
CHECK_ARGS(0);
flags |= UPPERDIGITS;
AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
arg++;
break;
case 'x':
CHECK_ARGS(0);
AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
arg++;
break;
case 'a':
{
CHECK_ARGS(0);
// %a is passed a pointer directly to a cell string.
cell* ptr=reinterpret_cast<cell*>(*get_amxaddr(amx, params[arg]));
if (!ptr)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid vector string handle provided (%d)", *get_amxaddr(amx, params[arg]));
return 0;
}
AddString(&buf_p, llen, ptr, width, prec);
arg++;
break;
}
case 's':
CHECK_ARGS(0);
if (amx->flags & AMX_FLAG_OLDFILE)
{
cell *addr = get_amxaddr(amx, params[arg]);
if (*addr & BCOMPAT_TRANSLATE_BITS)
{
const char *key, *def;
if (!translate_bcompat(amx, addr, &key, &def))
{
goto break_to_normal_string;
}
arg++;
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
buf_p += written;
llen -= written;
break;
}
}
break_to_normal_string:
AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec);
arg++;
break;
case 'L':
{
CHECK_ARGS(1);
cell addr = params[arg++];
int len;
const char *key = get_amxstring(amx, params[arg++], 3, len);
const char *def = translate(amx, addr, key);
if (!def)
{
static char buf[255];
snprintf(buf, sizeof(buf)-1, "ML_NOTFOUND: %s", key);
def = buf;
}
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
buf_p += written;
llen -= written;
break;
}
case '%':
*buf_p++ = static_cast<D>(ch);
if (!llen)
goto done;
llen--;
break;
case '\0':
*buf_p++ = static_cast<D>('%');
if (!llen)
goto done;
llen--;
goto done;
break;
default:
*buf_p++ = static_cast<D>(ch);
if (!llen)
goto done;
llen--;
break;
}
}
done:
*buf_p = static_cast<D>(0);
*param = arg;
return maxlen-llen;
}
/**
* HACKHACK: The compiler will generate code for each case we need.
* Don't remove this, otherwise files that use certain code generations
* will have extern problems. For each case you need, add dummy code
* here.
*/
void __WHOA_DONT_CALL_ME_PLZ_K_lol_o_O()
{
//acsprintf
atcprintf((cell *)NULL, 0, (const char *)NULL, NULL, NULL, NULL);
//accprintf
atcprintf((cell *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
//ascprintf
atcprintf((char *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
}

View File

@ -1,11 +0,0 @@
#ifndef _INCLUDE_FORMATTING_H
#define _INCLUDE_FORMATTING_H
//Amx Templatized Cell Printf
template <typename D, typename S>
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param);
const char *translate(AMX *amx, cell amxaddr, const char *key);
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def);
#endif //_INCLUDE_FORMATTING_H

View File

@ -1,51 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; (C)2006 by David "BAILOPAN" Anderson ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Licensed under the GNU General Public License, version 2
;;This is a portion of AMX Mod X
;; and is maintained by the AMX Mod X development team.
section .text
global amxx_CpuSupport, _amxx_CpuSupport
amxx_CpuSupport:
_amxx_CpuSupport:
push ebp
mov ebp, esp
push ebx
mov eax, 0
cpuid
cmp eax, 1
jl .fail
mov eax, 1
cpuid
;check if family == 5 or 4
and eax, 0780h ;family mask
shr eax, 7 ;family shift
cmp eax, 5
je .fail
cmp eax, 4
je .fail
;check if CMOV exists
shr edx, 15
and edx, 1
cmp edx, 0
je .fail
mov eax, 1
jmp .end
.fail:
xor eax, eax
.end
pop ebx
pop ebp
ret

View File

@ -1,243 +0,0 @@
#include "libraries.h"
#include "sh_list.h"
List<Library *> g_libraries;
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent)
{
if (FindLibrary(name, type))
return false;
Library *lib = new Library;
lib->name.assign(name);
lib->type = type;
lib->src = src;
lib->parent = parent;
g_libraries.push_back(lib);
return true;
}
bool DecodeLibCmdString(const char *str, LibDecoder *dec)
{
if (dec->buffer)
{
free(dec->buffer);
dec->buffer = NULL;
}
if (str[0] != '?')
{
return false;
} else {
str++;
if (*str == 'r')
{
str++;
if (*str == 'c')
dec->cmd = LibCmd_ReqClass;
else if (*str == 'l')
dec->cmd = LibCmd_ReqLib;
else
return false;
str++;
} else if (*str == 'f') {
str++;
dec->cmd = LibCmd_ForceLib;
} else if (*str == 'e') {
str++;
if (*str == 'c')
dec->cmd = LibCmd_ExpectClass;
else if (*str == 'l')
dec->cmd = LibCmd_ExpectLib;
else
return false;
str++;
} else if (*str == 'd') {
str++;
dec->cmd = LibCmd_DefaultLib;
}
if (*str != '_')
return false;
str++;
if (dec->cmd < LibCmd_ExpectLib)
{
dec->buffer = strdup(str);
dec->param1 = dec->buffer;
dec->param2 = NULL;
} else {
dec->buffer = strdup(str);
char *p = strchr(dec->buffer, '_');
while (p && (*(p+1) == '_'))
p = strchr(p+2, '_');
if (!p || !*(p+1))
return false;
*p = '\0';
dec->param1 = dec->buffer;
dec->param2 = p+1;
}
}
return true;
}
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent)
{
char buffer[255];
char *ptr, *p, s;
size_t count = 0;
snprintf(buffer, sizeof(buffer)-1, "%s", name);
ptr = buffer;
p = buffer;
while (*p)
{
while (*p && (*p != ','))
p++;
s = *p;
*p = '\0';
if (AddLibrary(ptr, type, src, parent))
count++;
if (!s)
break;
p++;
while (*p && (*p == ','))
p++;
ptr = p;
}
return count;
}
size_t ClearLibraries(LibSource src)
{
List<Library *>::iterator iter;
size_t count = 0;
iter = g_libraries.begin();
while (iter != g_libraries.end())
{
if ( (*iter)->src == src )
{
delete (*iter);
iter = g_libraries.erase(iter);
count++;
} else {
iter++;
}
}
return count;
}
size_t RemoveLibraries(void *parent)
{
List<Library *>::iterator iter;
Library *lib;
size_t count = 0;
iter = g_libraries.begin();
while (iter != g_libraries.end())
{
lib = (*iter);
if (lib->parent == parent)
{
delete (*iter);
iter = g_libraries.erase(iter);
count++;
} else {
iter++;
}
}
return count;
}
bool FindLibrary(const char *name, LibType type)
{
List<Library *>::iterator iter;
Library *lib;
for (iter = g_libraries.begin(); iter != g_libraries.end(); iter++)
{
lib = (*iter);
if (lib->type != type)
continue;
if (strcasecmp(lib->name.c_str(), name) == 0)
{
return true;
}
}
return false;
}
LibError RunLibCommand(const LibDecoder *enc)
{
List<Library *>::iterator iter,end;
Library *lib;
iter = g_libraries.begin();
end = g_libraries.end();
if ( (enc->cmd == LibCmd_ReqLib) || (enc->cmd == LibCmd_ReqClass) )
{
LibType expect = LibType_Library;
if (enc->cmd == LibCmd_ReqLib)
expect = LibType_Library;
else if (enc->cmd == LibCmd_ReqClass)
expect = LibType_Class;
/** see if it exists */
for (; iter != end; iter++)
{
lib = (*iter);
if (lib->type != expect)
continue;
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
return LibErr_None;
}
if (expect == LibType_Library)
return LibErr_NoLibrary;
else if (expect == LibType_Class)
return LibErr_NoClass;
return LibErr_NoLibrary;
} else if (enc->cmd == LibCmd_ForceLib) {
if (!LoadModule(enc->param1, PT_ANYTIME, true, true))
{
return LibErr_NoLibrary;
}
} else if ( (enc->cmd == LibCmd_DefaultLib) ||
((enc->cmd == LibCmd_ExpectLib) || (enc->cmd == LibCmd_ExpectClass)) )
{
LibType expect;
if (enc->cmd == LibCmd_ExpectLib)
expect = LibType_Library;
else
expect = LibType_Class;
/** see if it exists */
for (; iter != end; iter++)
{
lib = (*iter);
if (lib->type != expect)
continue;
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
return LibErr_None;
}
if (!LoadModule(enc->param2, PT_ANYTIME, true, true))
{
return LibErr_NoLibrary;
}
return LibErr_None;
}
return LibErr_None;
}

View File

@ -1,73 +0,0 @@
#ifndef _INCLUDE_LIBRARIES_H
#define _INCLUDE_LIBRARIES_H
#include <string.h>
#include "amxmodx.h"
#include "CString.h"
enum LibSource
{
LibSource_Plugin,
LibSource_Module
};
enum LibType
{
LibType_Library,
LibType_Class
};
struct Library
{
String name;
LibSource src;
LibType type;
void *parent;
};
enum LibCmd
{
LibCmd_ReqLib,
LibCmd_ReqClass,
LibCmd_ForceLib,
LibCmd_ExpectLib,
LibCmd_ExpectClass,
LibCmd_DefaultLib,
};
enum LibError
{
LibErr_None = 0,
LibErr_NoLibrary,
LibErr_NoClass,
};
class LibDecoder
{
public:
LibDecoder() : buffer(NULL)
{
}
~LibDecoder()
{
free(buffer);
buffer = NULL;
param1 = NULL;
param2 = NULL;
}
char *buffer;
char *param1;
char *param2;
LibCmd cmd;
};
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent=NULL);
bool DecodeLibCmdString(const char *str, LibDecoder *cmd);
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent=NULL);
size_t ClearLibraries(LibSource src);
LibError RunLibCommand(const LibDecoder *enc);
size_t RemoveLibraries(void *parent);
bool FindLibrary(const char *name, LibType type);
#endif //_INCLUDE_LIBRARIES_H

View File

@ -111,7 +111,7 @@ void MD5::update(FILE *file){
unsigned char buffer[1024]; unsigned char buffer[1024];
int len; int len;
while ((len=fread(buffer, 1, 1024, file))) while (len=fread(buffer, 1, 1024, file))
update(buffer, len); update(buffer, len);
fclose (file); fclose (file);

View File

@ -1,805 +0,0 @@
#include "amxmodx.h"
#include "messages.h"
Message Msg;
CVector<int> msgHooks[256];
int msgBlocks[256] = {BLOCK_NOT};
int msgDest;
int msgType;
float *msgOrigin;
edict_t *msgpEntity;
bool inhook = false;
bool inblock = false;
enginefuncs_t *g_pEngTable = NULL;
void ClearMessages()
{
for (size_t i=0; i<MAX_MESSAGES; i++)
{
msgHooks[i].clear();
msgBlocks[i] = BLOCK_NOT;
}
}
Message::Message()
{
m_CurParam = 0;
}
bool Message::Ready()
{
if (!m_Params.size())
return false;
return true;
}
void Message::Init()
{
if (!Ready())
{
msgparam *p = new msgparam;
m_Params.push_back(p);
}
m_CurParam = 0;
}
Message::~Message()
{
for (size_t i=0; i<m_Params.size(); i++)
delete m_Params[i];
m_Params.clear();
}
msgparam *Message::AdvPtr()
{
msgparam *pParam = NULL;
if (++m_CurParam >= m_Params.size())
{
pParam = new msgparam;
m_Params.push_back(pParam);
} else {
pParam = m_Params[m_CurParam];
}
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 C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
{
if (msgBlocks[msg_type])
{
inblock = true;
msgType = msg_type;
RETURN_META(MRES_SUPERCEDE);
} else if (msgHooks[msg_type].size()) {
inhook = true;
msgDest = msg_dest;
msgType = msg_type;
msgOrigin = (float *)pOrigin;
msgpEntity = ed;
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteByte(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_byte);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteChar(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_char);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteShort(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_short);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteLong(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_long);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteAngle(float flValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(flValue, arg_angle);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteCoord(float flValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(flValue, arg_coord);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteString(const char *sz)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(sz, arg_string);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteEntity(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_entity);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_MessageEnd(void)
{
int mres = 0, mresB = 0;
unsigned int i = 0;
if (inblock)
{
inblock = false;
if (msgBlocks[msgType] == BLOCK_ONCE)
{
msgBlocks[msgType] = BLOCK_NOT;
}
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
for (i=0; i<msgHooks[msgType].size(); i++)
{
mresB = executeForwards(msgHooks[msgType].at(i), (cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
if (mresB > mres)
mres = mresB;
}
inhook = false;
if (mres & 1)
{
Msg.Reset();
RETURN_META(MRES_SUPERCEDE);
}
/* send the real message */
MESSAGE_BEGIN(msgDest, msgType, msgOrigin, msgpEntity);
Msg.Send();
MESSAGE_END();
/* reset */
Msg.Reset();
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
{
int numparam = *params / sizeof(cell);
float vecOrigin[3];
cell *cpOrigin;
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
return 0;
}
switch (params[1])
{
case MSG_BROADCAST:
case MSG_ALL:
case MSG_SPEC:
MESSAGE_BEGIN(params[1], params[2], NULL);
break;
case MSG_PVS: case MSG_PAS:
case MSG_PVS_R: case MSG_PAS_R:
if (numparam < 3)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cpOrigin = get_amxaddr(amx, params[3]);
vecOrigin[0] = static_cast<float>(*cpOrigin);
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
MESSAGE_BEGIN(params[1], params[2], vecOrigin);
break;
case MSG_ONE_UNRELIABLE:
case MSG_ONE:
if (numparam < 4)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
MESSAGE_BEGIN(params[1], params[2], NULL, INDEXENT(params[4]));
break;
}
return 1;
}
static cell AMX_NATIVE_CALL message_end(AMX *amx, cell *params)
{
MESSAGE_END();
return 1;
}
static cell AMX_NATIVE_CALL write_byte(AMX *amx, cell *params) /* 1 param */
{
WRITE_BYTE(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_char(AMX *amx, cell *params) /* 1 param */
{
WRITE_CHAR(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_short(AMX *amx, cell *params) /* 1 param */
{
WRITE_SHORT(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_long(AMX *amx, cell *params) /* 1 param */
{
WRITE_LONG(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_entity(AMX *amx, cell *params) /* 1 param */
{
WRITE_ENTITY(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_angle(AMX *amx, cell *params) /* 1 param */
{
WRITE_ANGLE(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL write_coord(AMX *amx, cell *params) /* 1 param */
{
WRITE_COORD(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL write_string(AMX *amx, cell *params) /* 1 param */
{
int a;
WRITE_STRING(get_amxstring(amx, params[1], 3, a));
return 1;
}
static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
{
int len;
char *name = get_amxstring(amx, params[2], 0, len);
if (!Msg.Ready())
Msg.Init();
if (params[1]>0 && params[1] < 256)
{
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (id != -1)
{
msgHooks[params[1]].push_back(id);
return id;
} else {
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
return -1;
}
}
return 0;
}
static cell AMX_NATIVE_CALL set_msg_block(AMX *amx, cell *params)
{
int msgid = params[1];
int block = params[2];
if (msgid < 1 || msgid > 255)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
return 0;
}
msgBlocks[msgid] = block;
return 1;
}
static cell AMX_NATIVE_CALL get_msg_block(AMX *amx, cell *params)
{
int msgid = params[1];
if (msgid < 1 || msgid > 255)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
return 0;
}
return msgBlocks[msgid];
}
static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params)
{
return Msg.Params();
}
static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
return Msg.GetParamType(argn);
}
static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
return Msg.GetParamInt(argn);
}
static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
Msg.SetParam(argn, (int)params[3]);
return 1;
}
static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
REAL f = (REAL)Msg.GetParamFloat(argn);
return amx_ftoc(f);
}
static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
REAL fVal = amx_ctof(params[3]);
Msg.SetParam(argn, (float)fVal);
return 1;
}
static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
const char *szVal = Msg.GetParamString(argn);
return set_amxstring(amx, params[2], szVal, params[3]);
}
static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
int iLen;
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
char *szVal = get_amxstring(amx, params[2], 0, iLen);
Msg.SetParam(argn, szVal);
return 1;
}
static cell AMX_NATIVE_CALL get_msg_origin(AMX *amx, cell *params)
{
if (!inhook)
{
LogError(amx, AMX_ERR_NATIVE, "Not in a message hook");
return 0;
}
cell *cAddr = get_amxaddr(amx, params[1]);
if (msgDest >= MSG_PVS && msgDest <= MSG_PAS_R)
{
vec3_t vRet = (Vector)msgOrigin;
cAddr[0] = FloatToCell(vRet.x);
cAddr[1] = FloatToCell(vRet.y);
cAddr[2] = FloatToCell(vRet.z);
} else {
cAddr[0] = 0;
cAddr[1] = 0;
cAddr[2] = 0;
}
return 1;
}
static cell AMX_NATIVE_CALL emessage_begin(AMX *amx, cell *params) /* 4 param */
{
int numparam = *params / sizeof(cell);
float vecOrigin[3];
cell *cpOrigin;
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
return 0;
}
switch (params[1])
{
case MSG_BROADCAST:
case MSG_ALL:
case MSG_SPEC:
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, NULL);
break;
case MSG_PVS: case MSG_PAS:
case MSG_PVS_R: case MSG_PAS_R:
if (numparam < 3)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cpOrigin = get_amxaddr(amx, params[3]);
vecOrigin[0] = static_cast<float>(*cpOrigin);
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
g_pEngTable->pfnMessageBegin(params[1], params[2], vecOrigin, NULL);
break;
case MSG_ONE_UNRELIABLE:
case MSG_ONE:
if (numparam < 4)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, INDEXENT(params[4]));
break;
}
return 1;
}
static cell AMX_NATIVE_CALL emessage_end(AMX *amx, cell *params)
{
g_pEngTable->pfnMessageEnd();
return 1;
}
static cell AMX_NATIVE_CALL ewrite_byte(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteByte(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_char(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteChar(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_short(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteShort(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_long(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteLong(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_entity(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteEntity(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_angle(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteAngle(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL ewrite_coord(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteCoord(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL ewrite_string(AMX *amx, cell *params) /* 1 param */
{
int a;
g_pEngTable->pfnWriteString(get_amxstring(amx, params[1], 3, a));
return 1;
}
AMX_NATIVE_INFO msg_Natives[] =
{
{"message_begin", message_begin},
{"message_end", message_end},
{"write_angle", write_angle},
{"write_byte", write_byte},
{"write_char", write_char},
{"write_coord", write_coord},
{"write_entity", write_entity},
{"write_long", write_long},
{"write_short", write_short},
{"write_string", write_string},
{"register_message", register_message},
{"set_msg_block", set_msg_block},
{"get_msg_block", get_msg_block},
{"get_msg_args", get_msg_args},
{"get_msg_argtype", get_msg_argtype},
{"get_msg_arg_int", get_msg_arg_int},
{"set_msg_arg_int", set_msg_arg_int},
{"get_msg_arg_float", get_msg_arg_float},
{"set_msg_arg_float", set_msg_arg_float},
{"get_msg_arg_string", get_msg_arg_string},
{"set_msg_arg_string", set_msg_arg_string},
{"get_msg_origin", get_msg_origin},
{"emessage_begin", emessage_begin},
{"emessage_end", emessage_end},
{"ewrite_angle", ewrite_angle},
{"ewrite_byte", ewrite_byte},
{"ewrite_char", ewrite_char},
{"ewrite_coord", ewrite_coord},
{"ewrite_entity", ewrite_entity},
{"ewrite_long", ewrite_long},
{"ewrite_short", ewrite_short},
{"ewrite_string", ewrite_string},
{NULL, NULL},
};

File diff suppressed because it is too large Load Diff

116
amxmodx/mm_pextensions.h Executable file
View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2004 Jussi Kivilinna
*
* This file is part of "Metamod All-Mod-Support"-patch for Metamod.
*
* Metamod is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef MM_PEXTENSIONS_H
#define MM_PEXTENSIONS_H
#include "plinfo.h" // plid_t
#include "meta_api.h" // PLUG_LOADTIME
/*
How to use:
1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file.
'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call.
2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION'
and pointer to extension function table.
3. Meta_PExtGiveFnptrs should return plugin's interface version.
4. !NOTE! Metamod will not stop loading plugin even if plugin returns
interface version greater than current. Plugin should disable itself in
this kind of situation.
Example:
#include "mm_pextensions.h"
pextension_funcs_t *gpMetaPExtFuncs;
int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) {
if(interfaceVersion < META_PEXT_VERSION) {
LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!");
gpMetaPExtFuncs = NULL;
return(META_PEXT_VERSION);
}
gpMetaPExtFuncs = pMetaPExtFuncs;
return(META_PEXT_VERSION);
}
Callback functions:
- int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
Parses 'cmdline' as metamod would parse 'meta load <cmdline>' and loads found
plugin. If 'plugin_handle' is set, metamod writes module handle of loaded
plugin at it.
Returns zero on success.
For error codes see 'META_ERRNO' in 'types_meta.h'.
- int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
Parses 'cmdline' as metamod would parse 'meta unload <cmdline>' and
unloads found plugin.
Returns zero on success.
For error codes see 'META_ERRNO' in 'types_meta.h'.
- int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
Unloads plugin with 'plugin_handle'.
Returns zero on success.
For error codes see 'META_ERRNO' in 'types_meta.h'.
!NOTE! Plugin cannot unload itself!
*/
// Interface version
// 1: first version. Used in p13
// 2: Complete remake (p14):
// pfnLoadMetaPluginByName
// pfnUnloadMetaPluginByName
// pfnUnloadMetaPluginByHandle
// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION.
#define META_PEXT_VERSION 2
// Meta PExtension Function table type.
typedef struct pextension_funcs_s {
int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
} pextension_funcs_t;
// Convenience macros for MetaPExtension functions.
#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName)
#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName)
#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle)
// Give plugin extension function table.
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion,
pextension_funcs_t *pMetaPExtFuncs);
typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion,
pextension_funcs_t *pMetaPExtFuncs);
#endif /* MM_PEXTENSIONS_H */

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@
#ifndef __linux__ #ifndef __linux__
#define DLLEXPORT __declspec(dllexport) #define DLLEXPORT __declspec(dllexport)
#else #else
#define DLLEXPORT __attribute__((visibility("default"))) #define DLLEXPORT
#define WINAPI #define WINAPI
#endif #endif
@ -48,44 +48,7 @@
#define RELOAD_MODULE 0 #define RELOAD_MODULE 0
#define STATIC_MODULE 1 #define STATIC_MODULE 1
typedef enum
{
Player_Name, //String
Player_Ip, //String
Player_Team, //String
Player_Ingame, //bool
Player_Authorized, //bool
Player_Vgui, //bool
Player_Time, //float
Player_Playtime, //float
Player_MenuExpire, //float
Player_Weapons, //struct{int,int}[32]
Player_CurrentWeapon, //int
Player_TeamID, //int
Player_Deaths, //int
Player_Aiming, //int
Player_Menu, //int
Player_Keys, //int
Player_Flags, //int[32]
Player_Newmenu, //int
Player_NewmenuPage, //int
} PlayerProp;
int CheckModules(AMX *amx, char error[128]); int CheckModules(AMX *amx, char error[128]);
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify=true, bool noFileBail=false);
const char *StrCaseStr(const char *as, const char *bs); const char *StrCaseStr(const char *as, const char *bs);
class Debugger;
Debugger *DisableDebugHandler(AMX *amx);
void EnableDebugHandler(AMX *amx, Debugger *pd);
bool DirExists(const char *dir);
const char* GetFileName(AMX *amx);
inline cell FloatToCell(float input)
{
REAL output = input;
return *(cell *)&output;
}
#endif // __MODULES_H__ #endif // __MODULES_H__

12
amxmodx/msvc/.cvsignore Executable file
View File

@ -0,0 +1,12 @@
amxmodx.sln
amxmodx.suo
amxmodx.aps
amxmodx.ncb
Debug
JITDebug
JITMemtestRelease
JITRelease
MaximalSpeed
MemtestDebug
MemtestRelease
Release

6
amxmodx/msvc/amxmodx_mm.def Executable file
View File

@ -0,0 +1,6 @@
LIBRARY amxx_mm
EXPORTS
GiveFnptrsToDll @1
SECTIONS
.data READ WRITE

292
amxmodx/msvc/amxmodx_mm.dsp Executable file
View File

@ -0,0 +1,292 @@
# Microsoft Developer Studio Project File - Name="amxmodx_mm" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=amxmodx_mm - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "amxmodx_mm.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "amxmodx_mm.mak" CFG="amxmodx_mm - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "amxmodx_mm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "amxmodx_mm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "amxmodx_mm - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "release"
# PROP Intermediate_Dir "release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\metamod\metamod" /I "..\..\hlsdk\sourcecode\common" /I "..\..\hlsdk\sourcecode\engine" /I "..\..\hlsdk\sourcecode\dlls" /I "..\..\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /def:".\amxmodx_mm.def" /out:"release/amxx_mm.dll" /libpath:"..\extra\lib_win32"
# Begin Custom Build
TargetPath=.\release\amxx_mm.dll
TargetName=amxx_mm
InputPath=.\release\amxx_mm.dll
SOURCE="$(InputPath)"
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
# End Custom Build
!ELSEIF "$(CFG)" == "amxmodx_mm - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "debug"
# PROP Intermediate_Dir "debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /Zp4 /MTd /W3 /Gm /GX /ZI /Od /I "..\..\metamod\metamod" /I "..\...\hlsdk\sourcecode\common" /I "..\...\hlsdk\sourcecode\engine" /I "..\...\hlsdk\sourcecode\dlls" /I "..\...\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:".\amxmodx_mm.def" /out:"debug/amxx_mm.dll" /pdbtype:sept /libpath:"..\extra\lib_win32"
# SUBTRACT LINK32 /incremental:no /nodefaultlib
# Begin Custom Build
TargetPath=.\debug\amxx_mm.dll
TargetName=amxx_mm
InputPath=.\debug\amxx_mm.dll
SOURCE="$(InputPath)"
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
# End Custom Build
!ENDIF
# Begin Target
# Name "amxmodx_mm - Win32 Release"
# Name "amxmodx_mm - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\amx.c
# End Source File
# Begin Source File
SOURCE=..\amxcore.c
# End Source File
# Begin Source File
SOURCE=..\amxmodx.cpp
# End Source File
# Begin Source File
SOURCE=..\amxtime.c
# End Source File
# Begin Source File
SOURCE=..\amxxlog.cpp
# End Source File
# Begin Source File
SOURCE=..\CCmd.cpp
# End Source File
# Begin Source File
SOURCE=..\CEvent.cpp
# End Source File
# Begin Source File
SOURCE=..\CFile.cpp
# End Source File
# Begin Source File
SOURCE=..\CForward.cpp
# End Source File
# Begin Source File
SOURCE=..\CLogEvent.cpp
# End Source File
# Begin Source File
SOURCE=..\CMenu.cpp
# End Source File
# Begin Source File
SOURCE=..\CMisc.cpp
# End Source File
# Begin Source File
SOURCE=..\CModule.cpp
# End Source File
# Begin Source File
SOURCE=..\CPlugin.cpp
# End Source File
# Begin Source File
SOURCE=..\CString.cpp
# End Source File
# Begin Source File
SOURCE=..\CTask.cpp
# End Source File
# Begin Source File
SOURCE=..\CVault.cpp
# End Source File
# Begin Source File
SOURCE=..\emsg.cpp
# End Source File
# Begin Source File
SOURCE=..\file.cpp
# End Source File
# Begin Source File
SOURCE=..\float.cpp
# End Source File
# Begin Source File
SOURCE=..\meta_api.cpp
# End Source File
# Begin Source File
SOURCE=..\modules.cpp
# End Source File
# Begin Source File
SOURCE=..\power.c
# End Source File
# Begin Source File
SOURCE=..\srvcmd.cpp
# End Source File
# Begin Source File
SOURCE=..\string.cpp
# End Source File
# Begin Source File
SOURCE=..\strptime.cpp
# End Source File
# Begin Source File
SOURCE=..\util.cpp
# End Source File
# Begin Source File
SOURCE=..\vault.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\amxmodx.h
# End Source File
# Begin Source File
SOURCE=..\CCmd.h
# End Source File
# Begin Source File
SOURCE=..\CEvent.h
# End Source File
# Begin Source File
SOURCE=..\CFile.h
# End Source File
# Begin Source File
SOURCE=..\CForward.h
# End Source File
# Begin Source File
SOURCE=..\CList.h
# End Source File
# Begin Source File
SOURCE=..\CLogEvent.h
# End Source File
# Begin Source File
SOURCE=..\CMenu.h
# End Source File
# Begin Source File
SOURCE=..\CMisc.h
# End Source File
# Begin Source File
SOURCE=..\CModule.h
# End Source File
# Begin Source File
SOURCE=..\CPlugin.h
# End Source File
# Begin Source File
SOURCE=..\CString.h
# End Source File
# Begin Source File
SOURCE=..\CTask.h
# End Source File
# Begin Source File
SOURCE=..\CVault.h
# End Source File
# Begin Source File
SOURCE=..\modules.h
# End Source File
# End Group
# End Target
# End Project

View File

@ -1,9 +1,9 @@
Microsoft Developer Studio Workspace File, Format Version 6.00 Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
############################################################################### ###############################################################################
Project: "Hello_World"=".\Hello_World.dsp" - Package Owner=<4> Project: "amxmodx_mm"=.\amxmodx_mm.dsp - Package Owner=<4>
Package=<5> Package=<5>
{{{ {{{

39
amxmodx/msvc/amxmodx_mm.sln Executable file
View File

@ -0,0 +1,39 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
JITDebug = JITDebug
JITMemtestRelease = JITMemtestRelease
JITRelease = JITRelease
MaximalSpeed = MaximalSpeed
MemtestDebug = MemtestDebug
MemtestRelease = MemtestRelease
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -4,7 +4,6 @@
Version="7.10" Version="7.10"
Name="amxmodx" Name="amxmodx"
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}" ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
RootNamespace="amxmodx"
SccProjectName="" SccProjectName=""
SccLocalPath=""> SccLocalPath="">
<Platforms> <Platforms>
@ -12,6 +11,287 @@
Name="Win32"/> Name="Win32"/>
</Platforms> </Platforms>
<Configurations> <Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\debug/amxmodx.pch"
AssemblerListingLocation=".\debug/"
ObjectFile=".\debug/"
ProgramDataBaseFileName=".\debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\JIT\natives-x86.obj ..\zlib\zlib.lib"
OutputFile="debug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
ImportLibrary=".\debug/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\release/amxmodx.pch"
AssemblerListingLocation=".\release/"
ObjectFile=".\release/"
ProgramDataBaseFileName=".\release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="release/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="LIBC"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\release/amxx_mm.pdb"
ImportLibrary=".\release/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MemtestDebug|Win32"
OutputDirectory="MemtestDebug"
IntermediateDirectory="MemtestDebug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\memtestdebug/amxmodx.pch"
AssemblerListingLocation=".\memtestdebug/"
ObjectFile=".\memtestdebug/"
ProgramDataBaseFileName=".\memtestdebug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="memtestdebug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
ImportLibrary=".\memtestdebug/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MemtestRelease|Win32"
OutputDirectory="MemtestRelease"
IntermediateDirectory="MemtestRelease"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\memtestrelease/amxmodx.pch"
AssemblerListingLocation=".\memtestrelease/"
ObjectFile=".\memtestrelease/"
ProgramDataBaseFileName=".\memtestrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="memtestrelease/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
GenerateMapFile="TRUE"
MapExports="TRUE"
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration <Configuration
Name="JITDebug|Win32" Name="JITDebug|Win32"
OutputDirectory="JITDebug" OutputDirectory="JITDebug"
@ -23,7 +303,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="" AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
@ -46,14 +326,14 @@
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj" AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebug/amxmodx_mm.dll" OutputFile="jitdebug/amxmodx_mm.dll"
Version="0.1" Version="0.1"
LinkIncremental="2" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC" IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebug/amxmodx_mm.pdb" ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
ImportLibrary=".\jitdebug/amxmodx_mm.lib"/> ImportLibrary=".\jitdebug/amxx_mm.lib"/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG" PreprocessorDefinitions="_DEBUG"
@ -92,13 +372,10 @@
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE" GlobalOptimizations="TRUE"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
OmitFramePointers="TRUE" OmitFramePointers="TRUE"
OptimizeForProcessor="0"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include" AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
IgnoreStandardIncludePath="FALSE" IgnoreStandardIncludePath="FALSE"
@ -113,7 +390,6 @@
ProgramDataBaseFileName=".\jitrelease/" ProgramDataBaseFileName=".\jitrelease/"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/> CompileAs="0"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
@ -128,9 +404,9 @@
IgnoreDefaultLibraryNames="MSVCRT" IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb" ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
GenerateMapFile="TRUE" GenerateMapFile="FALSE"
ImportLibrary=".\jitrelease/amxmodx_mm.lib"/> ImportLibrary=".\jitrelease/amxx_mm.lib"/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG" PreprocessorDefinitions="NDEBUG"
@ -160,30 +436,31 @@
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration <Configuration
Name="JITDebugBinLog|Win32" Name="JITMemtestRelease|Win32"
OutputDirectory="$(ConfigurationName)" OutputDirectory="JITMemtestRelease"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="JITMemtestRelease"
ConfigurationType="2" ConfigurationType="2"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE" ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" GlobalOptimizations="TRUE"
AdditionalIncludeDirectories="" InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED" FavorSizeOrSpeed="1"
BasicRuntimeChecks="3" AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
RuntimeLibrary="5" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
StructMemberAlignment="3" StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2" UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h" PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch" PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
AssemblerListingLocation=".\jitdebugbinlog/" AssemblerListingLocation=".\jitmemtestrelease/"
ObjectFile=".\jitdebugbinlog/" ObjectFile=".\jitmemtestrelease/"
ProgramDataBaseFileName=".\jitdebugbinlog/" ProgramDataBaseFileName=".\jitmemtestrelease/"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/> CompileAs="0"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
@ -191,23 +468,22 @@
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj" AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll" OutputFile="jitmemtestrelease/amxmodx_mm.dll"
Version="0.1" LinkIncremental="1"
LinkIncremental="2"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC" IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb" ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"/> ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG" PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE" MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
TargetEnvironment="1" TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/> TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool <Tool
Name="VCPostBuildEventTool"/> Name="VCPostBuildEventTool"/>
<Tool <Tool
@ -216,7 +492,7 @@
Name="VCPreLinkEventTool"/> Name="VCPreLinkEventTool"/>
<Tool <Tool
Name="VCResourceCompilerTool" Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG" PreprocessorDefinitions="NDEBUG"
Culture="1033"/> Culture="1033"/>
<Tool <Tool
Name="VCWebServiceProxyGeneratorTool"/> Name="VCWebServiceProxyGeneratorTool"/>
@ -230,54 +506,48 @@
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration <Configuration
Name="JITReleaseBinLog|Win32" Name="MaximalSpeed|Win32"
OutputDirectory="$(ConfigurationName)" OutputDirectory="MaximalSpeed"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="MaximalSpeed"
ConfigurationType="2" ConfigurationType="2"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE" ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2"> CharacterSet="2">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE" GlobalOptimizations="TRUE"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE" EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
OmitFramePointers="TRUE" OptimizeForProcessor="2"
OptimizeForProcessor="0" OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include" AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
IgnoreStandardIncludePath="FALSE"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="4" RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2" UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h" PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch" PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
AssemblerListingLocation=".\jitreleasebinlog/" AssemblerListingLocation=".\MaximalSpeed/"
ObjectFile=".\jitreleasebinlog/" ObjectFile=".\MaximalSpeed/"
ProgramDataBaseFileName=".\jitreleasebinlog/" ProgramDataBaseFileName=".\MaximalSpeed/"
WarningLevel="3" WarningLevel="3"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/> CompileAs="0"/>
<Tool <Tool
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj" AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll" OutputFile="MaximalSpeed/amxmodx_mm.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb" ImportLibrary=".\jitrelease/amxx_mm.lib"/>
GenerateMapFile="TRUE"
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG" PreprocessorDefinitions="NDEBUG"
@ -322,9 +592,6 @@
<File <File
RelativePath="..\amxdbg.cpp"> RelativePath="..\amxdbg.cpp">
</File> </File>
<File
RelativePath="..\amxmod_compat.cpp">
</File>
<File <File
RelativePath="..\amxmodx.cpp"> RelativePath="..\amxmodx.cpp">
</File> </File>
@ -337,21 +604,6 @@
<File <File
RelativePath="..\amxxlog.cpp"> RelativePath="..\amxxlog.cpp">
</File> </File>
<File
RelativePath="..\binlog.cpp">
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\CCmd.cpp"> RelativePath="..\CCmd.cpp">
</File> </File>
@ -361,9 +613,6 @@
<File <File
RelativePath="..\CFile.cpp"> RelativePath="..\CFile.cpp">
</File> </File>
<File
RelativePath="..\CFlagManager.cpp">
</File>
<File <File
RelativePath="..\CForward.cpp"> RelativePath="..\CForward.cpp">
</File> </File>
@ -391,9 +640,6 @@
<File <File
RelativePath="..\CVault.cpp"> RelativePath="..\CVault.cpp">
</File> </File>
<File
RelativePath="..\datastructs.cpp">
</File>
<File <File
RelativePath="..\debugger.cpp"> RelativePath="..\debugger.cpp">
</File> </File>
@ -402,6 +648,12 @@
</File> </File>
<File <File
RelativePath="..\fakemeta.cpp"> RelativePath="..\fakemeta.cpp">
<FileConfiguration
Name="MemtestDebug|Win32">
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\file.cpp"> RelativePath="..\file.cpp">
@ -409,30 +661,9 @@
<File <File
RelativePath="..\float.cpp"> RelativePath="..\float.cpp">
</File> </File>
<File
RelativePath="..\format.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath="..\libraries.cpp">
</File>
<File <File
RelativePath="..\md5.cpp"> RelativePath="..\md5.cpp">
</File> </File>
<File
RelativePath="..\messages.cpp">
</File>
<File <File
RelativePath="..\meta_api.cpp"> RelativePath="..\meta_api.cpp">
</File> </File>
@ -445,35 +676,14 @@
<File <File
RelativePath="..\newmenus.cpp"> RelativePath="..\newmenus.cpp">
</File> </File>
<File
RelativePath="..\nongpl_matches.cpp">
</File>
<File
RelativePath="..\optimizer.cpp">
</File>
<File <File
RelativePath="..\power.cpp"> RelativePath="..\power.cpp">
</File> </File>
<File
RelativePath="..\sorting.cpp">
</File>
<File <File
RelativePath="..\srvcmd.cpp"> RelativePath="..\srvcmd.cpp">
</File> </File>
<File <File
RelativePath="..\string.cpp"> RelativePath="..\string.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\strptime.cpp"> RelativePath="..\strptime.cpp">
@ -484,10 +694,44 @@
<File <File
RelativePath="..\vault.cpp"> RelativePath="..\vault.cpp">
</File> </File>
<Filter
Name="mmgr"
Filter="">
<File <File
RelativePath="..\vector.cpp"> RelativePath="..\mmgr\mmgr.cpp">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="MaximalSpeed|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File> </File>
</Filter> </Filter>
</Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
Filter="h;hpp;hxx;hm;inl"> Filter="h;hpp;hxx;hm;inl">
@ -497,9 +741,6 @@
<File <File
RelativePath="..\amxdbg.h"> RelativePath="..\amxdbg.h">
</File> </File>
<File
RelativePath="..\amxmod_compat.h">
</File>
<File <File
RelativePath="..\amxmodx.h"> RelativePath="..\amxmodx.h">
</File> </File>
@ -509,9 +750,6 @@
<File <File
RelativePath="..\amxxlog.h"> RelativePath="..\amxxlog.h">
</File> </File>
<File
RelativePath="..\binlog.h">
</File>
<File <File
RelativePath="..\CCmd.h"> RelativePath="..\CCmd.h">
</File> </File>
@ -521,9 +759,6 @@
<File <File
RelativePath="..\CFile.h"> RelativePath="..\CFile.h">
</File> </File>
<File
RelativePath="..\CFlagManager.h">
</File>
<File <File
RelativePath="..\CForward.h"> RelativePath="..\CForward.h">
</File> </File>
@ -551,6 +786,9 @@
<File <File
RelativePath="..\CQueue.h"> RelativePath="..\CQueue.h">
</File> </File>
<File
RelativePath="..\CStack.h">
</File>
<File <File
RelativePath="..\CString.h"> RelativePath="..\CString.h">
</File> </File>
@ -563,30 +801,18 @@
<File <File
RelativePath="..\CVector.h"> RelativePath="..\CVector.h">
</File> </File>
<File
RelativePath="..\datastructs.h">
</File>
<File <File
RelativePath="..\debugger.h"> RelativePath="..\debugger.h">
</File> </File>
<File <File
RelativePath="..\fakemeta.h"> RelativePath="..\fakemeta.h">
</File> </File>
<File
RelativePath="..\format.h">
</File>
<File
RelativePath="..\libraries.h">
</File>
<File <File
RelativePath="..\md5.h"> RelativePath="..\md5.h">
</File> </File>
<File <File
RelativePath="..\menus.h"> RelativePath="..\menus.h">
</File> </File>
<File
RelativePath="..\messages.h">
</File>
<File <File
RelativePath="..\modules.h"> RelativePath="..\modules.h">
</File> </File>
@ -596,33 +822,25 @@
<File <File
RelativePath="..\newmenus.h"> RelativePath="..\newmenus.h">
</File> </File>
<File
RelativePath="..\nongpl_matches.h">
</File>
<File
RelativePath="..\optimizer.h">
</File>
<File <File
RelativePath="..\resource.h"> RelativePath="..\resource.h">
</File> </File>
<File
RelativePath="..\sh_list.h">
</File>
<File
RelativePath="..\sh_stack.h">
</File>
<File
RelativePath="..\sh_tinyhash.h">
</File>
<File
RelativePath="..\svn_version.h">
</File>
<File <File
RelativePath="..\zlib\zconf.h"> RelativePath="..\zlib\zconf.h">
</File> </File>
<File <File
RelativePath="..\zlib\zlib.h"> RelativePath="..\zlib\zlib.h">
</File> </File>
<Filter
Name="mmgr"
Filter="">
<File
RelativePath="..\mmgr\mmgr.h">
</File>
<File
RelativePath="..\mmgr\nommgr.h">
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="Resource Files" Name="Resource Files"
@ -643,145 +861,12 @@
<File <File
RelativePath="..\amxjitsn.asm"> RelativePath="..\amxjitsn.asm">
</File> </File>
<File
RelativePath="..\helpers-x86.asm">
</File>
<File <File
RelativePath="..\natives-amd64.asm"> RelativePath="..\natives-amd64.asm">
</File> </File>
<File <File
RelativePath="..\natives-x86.asm"> RelativePath="..\natives-x86.asm">
</File> </File>
<Filter
Name="Builds"
Filter="">
<File
RelativePath="..\Jit\helpers-x86.obj">
</File>
</Filter>
</Filter>
<Filter
Name="SDK"
Filter="">
<File
RelativePath="..\sdk\amxxmodule.cpp">
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITDebugBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\sdk\amxxmodule.h">
</File>
<File
RelativePath="..\sdk\moduleconfig.h">
</File>
</Filter>
<Filter
Name="Pawn Includes"
Filter="">
<File
RelativePath="..\..\plugins\include\amxconst.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmisc.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmodx.inc">
</File>
<File
RelativePath="..\..\plugins\include\core.inc">
</File>
<File
RelativePath="..\..\plugins\include\file.inc">
</File>
<File
RelativePath="..\..\plugins\include\float.inc">
</File>
<File
RelativePath="..\..\plugins\include\lang.inc">
</File>
<File
RelativePath="..\..\plugins\include\message_const.inc">
</File>
<File
RelativePath="..\..\plugins\include\message_stocks.inc">
</File>
<File
RelativePath="..\..\plugins\include\messages.inc">
</File>
<File
RelativePath="..\..\plugins\include\sorting.inc">
</File>
<File
RelativePath="..\..\plugins\include\string.inc">
</File>
<File
RelativePath="..\..\plugins\include\svn_version.inc">
</File>
<File
RelativePath="..\..\plugins\include\time.inc">
</File>
<File
RelativePath="..\..\plugins\include\vault.inc">
</File>
<File
RelativePath="..\..\plugins\include\vector.inc">
</File>
<File
RelativePath="..\..\plugins\include\xs.inc">
</File>
<Filter
Name="AMX Mod Compat"
Filter="">
<File
RelativePath="..\..\plugins\include\amxmod_compat\amxmod.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\maths.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\mysql.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\translator.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\Vexd_Utilities.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\VexdUM.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\VexdUM_const.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\VexdUM_stock.inc">
</File>
<File
RelativePath="..\..\plugins\include\amxmod_compat\xtrafun.inc">
</File>
</Filter>
</Filter> </Filter>
</Files> </Files>
<Globals> <Globals>

View File

@ -1,27 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
JITDebug = JITDebug
JITDebugBinLog = JITDebugBinLog
JITRelease = JITRelease
JITReleaseBinLog = JITReleaseBinLog
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.ActiveCfg = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.Build.0 = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.ActiveCfg = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.Build.0 = JITReleaseBinLog|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -1,26 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
JITDebug|Win32 = JITDebug|Win32
JITDebugBinLog|Win32 = JITDebugBinLog|Win32
JITRelease|Win32 = JITRelease|Win32
JITReleaseBinLog|Win32 = JITReleaseBinLog|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.ActiveCfg = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.Build.0 = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.ActiveCfg = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.Build.0 = JITReleaseBinLog|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,8 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "sh_stack.h" #include "CStack.h"
#include "natives.h" #include "natives.h"
#include "debugger.h"
#include "libraries.h"
#include "format.h"
#ifdef __linux__ #ifdef __linux__
#include <malloc.h> #include <malloc.h>
@ -47,15 +44,12 @@
// Julien "dJeyL" Laurent // Julien "dJeyL" Laurent
CVector<regnative *> g_RegNatives; CVector<regnative *> g_RegNatives;
CStack<regnative *> g_NativeStack;
CVector<String> g_Libraries;
static char g_errorStr[512] = {0}; static char g_errorStr[512] = {0};
static int g_errorNum = 0;
bool g_Initialized = false; bool g_Initialized = false;
/* Stack stuff */
regnative *g_pCurNative = NULL;
AMX *g_pCaller = NULL;
cell g_Params[CALLFUNC_MAXPARAMS];
int g_CurError = AMX_ERR_NONE;
int amxx_DynaCallback(int idx, AMX *amx, cell *params) int amxx_DynaCallback(int idx, AMX *amx, cell *params)
{ {
if (idx < 0 || idx >= (int)g_RegNatives.size()) if (idx < 0 || idx >= (int)g_RegNatives.size())
@ -73,97 +67,39 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
return 0; return 0;
} }
//parameter stack
pNative->caller = amx;
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx); CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);
if (!pNativePlugin->isExecutable(pNative->func))
{
LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
pPlugin->setStatus(ps_paused);
return 0;
}
/* Save old values on ZE STACK */
AMX *pSaveCaller = g_pCaller;
cell saveParams[CALLFUNC_MAXPARAMS];
regnative *pSaveNative = g_pCurNative;
int saveError = g_CurError;
if (pSaveNative)
{
for (ucell i = 0; i <= g_Params[0] / sizeof(cell); i++)
{
saveParams[i] = g_Params[i];
}
}
/* Save current info */
g_CurError = AMX_ERR_NONE;
g_pCaller = amx;
g_pCurNative = pNative;
int err = 0; int err = 0;
cell ret = 0; cell ret = 0;
g_errorNum = 0;
g_NativeStack.push(pNative);
if (pNative->style == 0) if (pNative->style == 0)
{ {
amx_Push(pNative->amx, numParams); amx_Push(pNative->amx, numParams);
amx_Push(pNative->amx, pPlugin->getId()); amx_Push(pNative->amx, pPlugin->getId());
for (int i=numParams; i>=0; i--)
{
g_Params[i] = params[i];
}
} else if (pNative->style == 1) {
/**
* use dJeyL's system .. very clever!
* NOTE: clever, but doesn't work at all since the JIT does bounds checking
* this should REALLY be deprecated
*/
for (int i=numParams; i>=1; i--) for (int i=numParams; i>=1; i--)
{ pNative->params[i] = params[i];
} else if (pNative->style == 1) {
//use dJeyL's system .. very clever!
for (int i=numParams; i>=1; i--)
amx_Push(pNative->amx, params[i]); amx_Push(pNative->amx, params[i]);
} }
} if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
if (pDebugger)
{ {
pDebugger->BeginExec(); g_NativeStack.pop();
LogError(pNative->amx, err, "");
return 0;
} }
if (g_errorNum)
err=amx_Exec(pNative->amx, &ret, pNative->func);
if (err != AMX_ERR_NONE)
{ {
if (pDebugger && pDebugger->ErrorExists()) g_NativeStack.pop();
{ LogError(amx, g_errorNum, g_errorStr);
//don't care return ret;
} else if (err != -1) {
//nothing logged the error
LogError(pNative->amx, err, NULL);
}
pNative->amx->error = AMX_ERR_NONE;
//furthermore, log an error in the parent plugin.
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
} else if (g_CurError != AMX_ERR_NONE) {
LogError(amx, g_CurError, g_errorStr);
}
if (pDebugger)
{
pDebugger->EndExec();
}
/* Restore everything */
g_pCurNative = pSaveNative;
g_CurError = saveError;
g_pCaller = pSaveCaller;
if (pSaveNative)
{
for (ucell i = 0; i <= saveParams[0] / sizeof(cell); i++)
{
g_Params[i] = saveParams[i];
}
} }
g_NativeStack.pop();
return ret; return ret;
} }
@ -171,9 +107,7 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
AMX_NATIVE_INFO *BuildNativeTable() AMX_NATIVE_INFO *BuildNativeTable()
{ {
if (g_RegNatives.size() < 1) if (g_RegNatives.size() < 1)
{
return NULL; return NULL;
}
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1]; AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
@ -199,7 +133,7 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
char *err = format_amxstring(amx, params, 2, len); char *err = format_amxstring(amx, params, 2, len);
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err); _snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
g_CurError = params[1]; g_errorNum = params[1];
return 1; return 1;
} }
@ -207,12 +141,13 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
//get_string(param, dest[], len) //get_string(param, dest[], len)
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
@ -220,19 +155,20 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
int p = params[1]; int p = params[1];
int len; int len;
char *str = get_amxstring(g_pCaller, g_Params[p], 0, len); char *str = get_amxstring(pNative->caller, pNative->params[p], 0, len);
return set_amxstring(amx, params[2], str, params[3]); return set_amxstring(amx, params[2], str, params[3]);
} }
//set_string(param, source[], maxlen) //set_string(param, source[], maxlen)
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
@ -242,44 +178,46 @@ static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
int len; int len;
char *str = get_amxstring(amx, params[2], 0, len); char *str = get_amxstring(amx, params[2], 0, len);
return set_amxstring(g_pCaller, g_Params[p], str, params[3]); return set_amxstring(pNative->caller, pNative->params[p], str, params[3]);
} }
//get a byvalue parameter //get a byvalue parameter
//get_param(num) //get_param(num)
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
} }
int p = params[1]; int p = params[1];
return g_Params[p]; return pNative->params[p];
} }
//get_param_byref(num) //get_param_byref(num)
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
} }
int p = params[1]; int p = params[1];
cell *addr = get_amxaddr(g_pCaller, g_Params[p]); cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
return addr[0]; return addr[0];
} }
@ -287,19 +225,20 @@ static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
//set_param_byref(num, val) //set_param_byref(num, val)
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
} }
int p = params[1]; int p = params[1];
cell *addr = get_amxaddr(g_pCaller, g_Params[p]); cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
addr[0] = params[2]; addr[0] = params[2];
@ -309,19 +248,20 @@ static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
//get_array(param, dest[], size) //get_array(param, dest[], size)
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
} }
int p = params[1]; int p = params[1];
cell *source = get_amxaddr(g_pCaller, g_Params[p]); cell *source = get_amxaddr(pNative->caller, pNative->params[p]);
cell *dest = get_amxaddr(amx, params[2]); cell *dest = get_amxaddr(amx, params[2]);
int size = params[3]; int size = params[3];
@ -334,19 +274,20 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
//set_array(param, source[], size) //set_array(param, source[], size)
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style) regnative *pNative = g_NativeStack.top();
if (pNative->style)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
} }
int p = params[1]; int p = params[1];
cell *dest = get_amxaddr(g_pCaller, g_Params[p]); cell *dest = get_amxaddr(pNative->caller, pNative->params[p]);
cell *source = get_amxaddr(amx, params[2]); cell *source = get_amxaddr(amx, params[2]);
int size = params[3]; int size = params[3];
@ -356,84 +297,26 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
return 1; return 1;
} }
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
{
if (!g_pCurNative || (g_pCurNative->amx != amx))
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
if (g_pCurNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int vargPos = static_cast<int>(params[4]);
int fargPos = static_cast<int>(params[3]);
cell max = g_Params[0] / sizeof(cell);
if (vargPos > (int)max + 1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
return 0;
}
if (fargPos > (int)max + 1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid fmtarg parameter passed: %d", fargPos);
return 0;
}
/* get destination info */
cell *fmt;
if (fargPos == 0)
{
if (params[0] / sizeof(cell) != 5)
{
LogError(amx, AMX_ERR_NATIVE, "Expected fmtarg as fifth parameter, found none");
return 0;
}
fmt = get_amxaddr(amx, params[5]);
} else {
fmt = get_amxaddr(g_pCaller, g_Params[fargPos]);
}
cell *realdest = get_amxaddr(amx, params[1]);
size_t maxlen = static_cast<size_t>(params[2]);
cell *dest = realdest;
/* if this is necessary... */
static cell cpbuf[4096];
dest = cpbuf;
/* perform format */
size_t total = atcprintf(dest, maxlen, fmt, g_pCaller, g_Params, &vargPos);
/* copy back */
memcpy(realdest, dest, (total+1) * sizeof(cell));
return total;
}
//This is basically right from dJeyL's lib_convert function //This is basically right from dJeyL's lib_convert function
//This awesome hack modifies the stack frame to have an address offset //This awesome hack modifies the stack frame to have an address offset
// that will align to the other plugin's memory. // that will align to the other plugin's memory.
//I've no idea how he thought of this, but it's great. No idea how well it works. //I've no idea how he thought of this, but it's great. No idea how well it works.
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params) static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
{ {
if (!g_pCurNative || (g_pCurNative->amx != amx)) if (!g_NativeStack.size())
{ {
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0; return 0;
} }
if (g_pCurNative->style != 1) regnative *pNative = g_NativeStack.top();
if (pNative->style != 1)
{ {
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native"); LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0; return 0;
} }
cell p = params[1]; cell p = params[1];
AMX *caller = g_pCaller; AMX *caller = pNative->caller;
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat; unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat; unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
@ -448,7 +331,7 @@ static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
int len; int len;
char *lib = get_amxstring(amx, params[1], 0, len); char *lib = get_amxstring(amx, params[1], 0, len);
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx)); AddPluginLibrary(lib);
return 1; return 1;
} }
@ -501,9 +384,27 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
return 1; return 1;
} }
bool LibraryExists(const char *name)
{
for (size_t i=0; i<g_Libraries.size(); i++)
{
if (stricmp(g_Libraries[i].c_str(), name)==0)
return true;
}
return false;
}
void AddPluginLibrary(const char *name)
{
String f(name);
g_Libraries.push_back(f);
}
void ClearPluginLibraries() void ClearPluginLibraries()
{ {
ClearLibraries(LibSource_Plugin); g_Libraries.clear();
for (size_t i=0; i<g_RegNatives.size(); i++) for (size_t i=0; i<g_RegNatives.size(); i++)
{ {
delete [] g_RegNatives[i]->pfn; delete [] g_RegNatives[i]->pfn;
@ -529,7 +430,6 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
{"set_float_byref", set_param_byref}, {"set_float_byref", set_param_byref},
{"get_array_f", get_array}, {"get_array_f", get_array},
{"set_array_f", set_array}, {"set_array_f", set_array},
{"vdformat", vdformat},
{"param_convert", param_convert}, {"param_convert", param_convert},
////////////////////////// //////////////////////////
{NULL, NULL}, {NULL, NULL},

View File

@ -32,9 +32,7 @@
#define _INCLUDE_NATIVES_H #define _INCLUDE_NATIVES_H
//only 16 for now sorry //only 16 for now sorry
#if !defined CALLFUNC_MAXPARAMS
#define CALLFUNC_MAXPARAMS 16 #define CALLFUNC_MAXPARAMS 16
#endif
#define CALLFUNC_FLAG_BYREF 1 #define CALLFUNC_FLAG_BYREF 1
#define CALLFUNC_FLAG_BYREF_REUSED 2 #define CALLFUNC_FLAG_BYREF_REUSED 2
@ -50,7 +48,9 @@ struct regnative
String name; String name;
char *pfn; char *pfn;
int func; int func;
AMX *caller;
int style; int style;
cell params[CALLFUNC_MAXPARAMS];
}; };
extern "C" void amxx_DynaInit(void *ptr); extern "C" void amxx_DynaInit(void *ptr);
@ -59,7 +59,9 @@ extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
extern "C" int amxx_DynaCodesize(); extern "C" int amxx_DynaCodesize();
AMX_NATIVE_INFO *BuildNativeTable(); AMX_NATIVE_INFO *BuildNativeTable();
void AddPluginLibrary(const char *name);
void ClearPluginLibraries(); void ClearPluginLibraries();
bool LibraryExists(const char *name);
//I couldn't resist :) //I couldn't resist :)
extern AMX_NATIVE_INFO g_NativeNatives[]; extern AMX_NATIVE_INFO g_NativeNatives[];

View File

@ -29,93 +29,29 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "CMenu.h"
#include "newmenus.h" #include "newmenus.h"
CVector<Menu *> g_NewMenus; CVector<Menu *> g_NewMenus;
CStack<int> g_MenuFreeStack;
void ClearMenus() void ClearMenus()
{ {
for (size_t i = 0; i < g_NewMenus.size(); i++) for (size_t i = 0; i < g_NewMenus.size(); i++)
{
delete g_NewMenus[i]; delete g_NewMenus[i];
}
g_NewMenus.clear(); g_NewMenus.clear();
while (!g_MenuFreeStack.empty())
{
g_MenuFreeStack.pop();
}
} }
void validate_menu_text(char *str) Menu::Menu(const char *title, int mid, int tid)
{ {
if (!g_coloredmenus) m_Title.assign(title);
{ menuId = mid;
size_t offs = 0; thisId = tid;
while (*str)
{
if (*str == '\\')
{
str++;
char c = tolower(*str);
if (c == 'r' || c == 'w'
|| c== 'w' || c == 'd')
{
str++;
offs += 2;
continue;
}
}
if (offs)
{
*(str-offs) = *str;
}
str++;
}
if (offs)
{
*(str-offs) = '\0';
}
}
}
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
isDestroying(false), items_per_page(7)
{
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
menuId = g_menucmds.registerMenuId(title, amx);
if (strcmp(pPlugin->getName(), "war3ft.amxx") == 0)
{
const char *version = pPlugin->getVersion();
if (strncmp(pPlugin->getVersion(), "3.0 RC", 6) == 0
&& atoi(&version[6]) <= 8)
{
g_menucmds.registerMenuCmd(
g_plugins.findPluginFast(amx),
menuId,
-1,
g_forwards.duplicateSPForward(fid),
true);
}
}
m_OptNames[abs(MENU_BACK)].assign("Back");
m_OptNames[abs(MENU_MORE)].assign("More");
m_OptNames[abs(MENU_EXIT)].assign("Exit");
} }
Menu::~Menu() Menu::~Menu()
{ {
for (size_t i = 0; i < m_Items.size(); i++) for (size_t i = 0; i < m_Items.size(); i++)
{
delete m_Items[i]; delete m_Items[i];
}
unregisterSPForward(this->func);
m_Items.clear(); m_Items.clear();
} }
@ -152,144 +88,69 @@ size_t Menu::GetItemCount()
size_t Menu::GetPageCount() size_t Menu::GetPageCount()
{ {
size_t items = GetItemCount(); size_t items = GetItemCount();
if (items_per_page == 0) page_t numPages = (items / MENUITEMS) + 1;
{
return 1;
}
return ((items/items_per_page) + ((items % items_per_page) ? 1 : 0)); if (!items)
return 0;
if (numPages % MENUITEMS == 0)
numPages--;
return numPages;
} }
int Menu::PagekeyToItem(page_t page, item_t key) int Menu::PagekeyToItem(page_t page, item_t key)
{ {
size_t start = page * items_per_page; page_t pages = GetPageCount();
size_t num_pages = GetPageCount(); item_t numItems = GetItemCount();
if (num_pages == 1 || !items_per_page) if (page >= pages)
{
if (key > m_Items.size())
{
return MENU_EXIT; return MENU_EXIT;
} else {
return key-1; item_t start = page * 7;
}
} else {
//first page
if (page == 0) if (page == 0)
{ {
/* The algorithm for spaces here is same as a middle page. */ item_t rem = numItems >= 7 ? 7 : numItems;
item_t new_key = key;
for (size_t i=start; i<(start+key-1) && i<m_Items.size(); i++) if (key == rem)
{
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
{
if (m_Items[i]->blanks[j] == 1)
{
if (!new_key)
{
break;
}
new_key--;
}
if (!new_key)
{
break;
}
}
}
key = new_key;
if (key == items_per_page + 2)
{ {
if (pages > 1)
return MENU_MORE; return MENU_MORE;
} else if (key == items_per_page + 3) { else
return MENU_EXIT; return MENU_EXIT;
} else {
return (start + key - 1);
} }
} else if (page == num_pages - 1) { else if (key == rem + 1)
//last page
item_t item_tracker = 0; // tracks how many valid items we have passed so far.
size_t remaining = m_Items.size() - start;
item_t new_key = key;
// For every item that takes up a slot (item or padded blank)
// we subtract one from new key.
// For every item (not blanks), we increase item_tracker.
// When new_key equals 0, item_tracker will then be set to
// whatever valid item was selected.
for (size_t i=m_Items.size() - remaining; i<m_Items.size(); i++)
{ {
item_tracker++; return MENU_EXIT;
if (new_key<=1) // If new_key is 0, or will be 0 after the next decrease
{
new_key=0;
break;
}
new_key--;
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
{
if (m_Items[i]->blanks[j] == 1)
{
new_key--;
}
if (!new_key)
{
break;
} }
} }
} else if (page == pages - 1)
// If new_key doesn't equal zero, then a back/exit button was pressed.
if (new_key!=0)
{ {
if (key == items_per_page + 1) //find number of remaining items
//for example, 11 items on page 1... means start=7, 11-7=4
item_t rem = numItems - start;
//however, the last item is actually this -1, so...
if (key == rem)
{
return MENU_EXIT;
}
else if (key == rem + 1)
{ {
return MENU_BACK; return MENU_BACK;
} }
else if (key == items_per_page + 3)
{
return MENU_EXIT;
}
// MENU_MORE should never happen here.
}
// otherwise our item is now start + item_tracker - 1
return (start + item_tracker - 1);
} else { } else {
/* The algorithm for spaces here is a bit harder. We have to subtract if (key == 7)
* one from the key for each space we find along the way.
*/
item_t new_key = key;
for (size_t i=start; i<(start+items_per_page-1) && i<m_Items.size(); i++)
{ {
for (size_t j=0; j<m_Items[i]->blanks.size(); j++) return MENU_MORE;
}
else if (key == 8)
{ {
if (m_Items[i]->blanks[j] == 1) return MENU_BACK;
{
if (!new_key)
{
break;
}
new_key--;
}
if (!new_key)
{
break;
}
}
}
key = new_key;
if (key > items_per_page && (key-items_per_page<=3))
{
unsigned int num = key - items_per_page - 1;
static int map[] = {MENU_BACK, MENU_MORE, MENU_EXIT};
return map[num];
} else {
return (start + key - 1);
}
} }
} }
return (start + key);
} }
bool Menu::Display(int player, page_t page) bool Menu::Display(int player, page_t page)
@ -326,51 +187,20 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
m_Text.clear(); m_Text.clear();
char buffer[255]; char buffer[255];
if (items_per_page && (pages != 1)) if (g_coloredmenus)
{
if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages); _snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
else else
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages); _snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
} else {
if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
else
_snprintf(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
}
m_Text.append(buffer); m_Text.append(buffer);
enum item_t start = page * 7;
{
Display_Back = (1<<0),
Display_Next = (1<<1),
};
int flags = Display_Back|Display_Next;
item_t start = page * items_per_page;
item_t end = 0; item_t end = 0;
if (items_per_page) if (start + 7 <= numItems)
{ {
if (start + items_per_page >= numItems) end = start + 7;
{
end = numItems - 1;
flags &= ~Display_Next;
} else { } else {
end = start + items_per_page - 1; end = numItems;
}
} else {
end = numItems - 1;
if (end > 10)
{
end = 10;
}
}
if (page == 0)
{
flags &= ~Display_Back;
} }
menuitem *pItem = NULL; menuitem *pItem = NULL;
@ -379,199 +209,77 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
keys = 0; keys = 0;
bool enabled = true; bool enabled = true;
int ret = 0; int ret = 0;
int slots = 0;
int option_display = 0;
for (item_t i = start; i <= end; i++) for (item_t i = start; i < end; i++)
{ {
// reset enabled
enabled = true;
pItem = m_Items[i]; pItem = m_Items[i];
if (pItem->access && !(pItem->access & g_players[player].flags[0])) if (pItem->access && !(pItem->access & g_players[player].flags[0]))
{
enabled = false; enabled = false;
}
if (pItem->handler != -1) if (pItem->handler != -1)
{ {
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i)); ret = executeForwards(pItem->handler, player, thisId, i);
if (ret == ITEM_ENABLED) if (ret == ITEM_ENABLED)
{
enabled = true; enabled = true;
} else if (ret == ITEM_DISABLED) { else if (ret == ITEM_DISABLED)
enabled = false; enabled = false;
} }
}
if (pItem->pfn) if (pItem->pfn)
{ {
ret = (pItem->pfn)(player, thisId, i); ret = (pItem->pfn)(player, thisId, i);
if (ret == ITEM_ENABLED) if (ret == ITEM_ENABLED)
{
enabled = true; enabled = true;
} else if (ret == ITEM_DISABLED) { else if (ret == ITEM_DISABLED)
enabled = false; enabled = false;
} }
}
if (enabled) if (enabled)
{ {
keys |= (1<<option); keys |= (1<<option);
} _snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
option_display = ++option;
if (option_display == 10)
{
option_display = 0;
}
if (enabled)
{
if (m_AutoColors)
{
_snprintf(buffer, sizeof(buffer)-1, "%s%d.\\w %s\n", m_ItemColor.c_str(),option_display, pItem->name.c_str());
} else { } else {
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option_display, pItem->name.c_str()); if (g_coloredmenus)
}
} else {
if (m_AutoColors)
{ {
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", option_display, pItem->name.c_str()); _snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
} else { } else {
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str()); _snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
option++;
} }
} }
slots++; m_Text.append(buffer);
}
//now for a weird part >:o
//this will either be MORE or BACK..
keys |= (1<<option++);
if ((page < pages - 1) && (pages > 1))
{
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
} else {
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
}
m_Text.append(buffer); m_Text.append(buffer);
//attach blanks
if (pItem->blanks.size())
{
for (size_t j=0; j<pItem->blanks.size(); j++)
{
if (pItem->blanks[j] == 1)
{
option++;
}
m_Text.append("\n");
slots++;
}
}
}
if (items_per_page)
{
/* Pad spaces until we reach the end of the max possible items */
for (unsigned int i=(unsigned)slots; i<items_per_page; i++)
{
m_Text.append("\n");
option++;
}
/* Make sure there is at least one visual pad */
m_Text.append("\n");
/* Don't bother if there is only one page */
if (pages > 1) if (pages > 1)
{
if (flags & Display_Back)
{ {
keys |= (1<<option++); keys |= (1<<option++);
if (m_AutoColors) if (pages == 0)
{ {
_snprintf(buffer, _snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
sizeof(buffer)-1,
"%s%d. \\w%s\n",
m_ItemColor.c_str(),
option == 10 ? 0 : option,
m_OptNames[abs(MENU_BACK)].c_str());
} else { } else {
_snprintf(buffer, _snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Back");
sizeof(buffer)-1,
"%d. %s\n",
option == 10 ? 0 : option,
m_OptNames[abs(MENU_BACK)].c_str());
}
} else {
option++;
if (m_AutoColors)
{
_snprintf(buffer,
sizeof(buffer)-1,
"\\d%d. %s\n\\w",
option == 10 ? 0 : option,
m_OptNames[abs(MENU_BACK)].c_str());
} else {
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_BACK)].c_str());
}
} }
m_Text.append(buffer); m_Text.append(buffer);
if (flags & Display_Next)
{
keys |= (1<<option++);
if (m_AutoColors)
{
_snprintf(buffer,
sizeof(buffer)-1,
"%s%d. \\w%s\n",
m_ItemColor.c_str(),
option == 10 ? 0 : option,
m_OptNames[abs(MENU_MORE)].c_str());
} else {
_snprintf(buffer,
sizeof(buffer)-1,
"%d. %s\n",
option == 10 ? 0 : option,
m_OptNames[abs(MENU_MORE)].c_str());
}
} else {
option++;
if (m_AutoColors)
{
_snprintf(buffer,
sizeof(buffer)-1,
"\\d%d. %s\n\\w",
option == 10 ? 0 : option,
m_OptNames[abs(MENU_MORE)].c_str());
} else {
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_MORE)].c_str());
}
}
m_Text.append(buffer);
} else {
/* Keep padding */
option += 2;
}
if (!m_NeverExit)
{
keys |= (1<<option++);
if (m_AutoColors)
{
_snprintf(buffer,
sizeof(buffer)-1,
"%s%d. \\w%s\n",
m_ItemColor.c_str(),
option == 10 ? 0 : option,
m_OptNames[abs(MENU_EXIT)].c_str());
} else {
_snprintf(buffer,
sizeof(buffer)-1,
"%d. %s\n",
option == 10 ? 0 : option,
m_OptNames[abs(MENU_EXIT)].c_str());
}
m_Text.append(buffer);
}
} }
return m_Text.c_str(); return m_Text.c_str();
} }
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p] || g_NewMenus[p]->isDestroying) { \ #define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0) { \
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \ LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \
return 0; } \ return 0; } \
Menu *pMenu = g_NewMenus[p]; Menu *pMenu = g_NewMenus[p];
@ -581,7 +289,6 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
{ {
int len; int len;
char *title = get_amxstring(amx, params[1], 0, len); char *title = get_amxstring(amx, params[1], 0, len);
validate_menu_text(title);
char *handler = get_amxstring(amx, params[2], 1, len); char *handler = get_amxstring(amx, params[2], 1, len);
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE); int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
@ -592,42 +299,13 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
return 0; return 0;
} }
Menu *pMenu = new Menu(title, amx, func); int id = g_menucmds.registerMenuId(title, amx);
g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
if (g_MenuFreeStack.empty()) Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
{
g_NewMenus.push_back(pMenu); g_NewMenus.push_back(pMenu);
pMenu->thisId = (int)g_NewMenus.size() - 1;
} else {
int pos = g_MenuFreeStack.front();
g_MenuFreeStack.pop();
g_NewMenus[pos] = pMenu;
pMenu->thisId = pos;
}
return pMenu->thisId; return (int)g_NewMenus.size() - 1;
}
static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
{
GETMENU(params[1]);
if (params[2] && (!pMenu->items_per_page && pMenu->GetItemCount() >= 10))
{
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
return 0;
}
if (!pMenu->m_Items.size())
{
LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items.");
return 0;
}
menuitem *item = pMenu->m_Items[pMenu->m_Items.size() - 1];
item->blanks.push_back(params[2]);
return 1;
} }
//Adds an item to the menu (returns current item count - 1) //Adds an item to the menu (returns current item count - 1)
@ -640,14 +318,7 @@ static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
GETMENU(params[1]); GETMENU(params[1]);
if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)
{
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
return 0;
}
name = get_amxstring(amx, params[2], 0, len); name = get_amxstring(amx, params[2], 0, len);
validate_menu_text(name);
cmd = get_amxstring(amx, params[3], 1, len); cmd = get_amxstring(amx, params[3], 1, len);
access = params[4]; access = params[4];
@ -683,40 +354,6 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
int player = params[1]; int player = params[1];
int page = params[3]; int page = params[3];
CPlayer* pPlayer = GET_PLAYER_POINTER_I(player);
/* If the stupid handler keeps drawing menus,
* We need to keep cancelling them. But we put in a quick infinite loop
* counter to prevent this from going nuts.
*/
int menu;
int loops = 0;
while ((menu = pPlayer->newmenu) >= 0)
{
if ((size_t)menu >= g_NewMenus.size() || !g_NewMenus[menu])
{
break;
}
Menu *pOther = g_NewMenus[menu];
pPlayer->newmenu = -1;
pPlayer->menu = 0;
executeForwards(pOther->func,
static_cast<cell>(player),
static_cast<cell>(pOther->thisId),
static_cast<cell>(MENU_EXIT));
/* Infinite loop counter */
if (++loops >= 10)
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called menu_display when item=MENU_EXIT");
return 0;
}
}
// This will set the expire time of the menu to infinite
pPlayer->menuexpire = INFINITE;
return pMenu->Display(player, page); return pMenu->Display(player, page);
} }
@ -830,210 +467,10 @@ static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
return 1; return 1;
} }
static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
{
GETMENU(params[1]);
int len = params[0] / sizeof(cell);
if (len < 3)
{
LogError(amx, AMX_ERR_NATIVE, "Expected 3 parameters");
return 0;
}
switch (params[2])
{
case MPROP_SET_NUMBER_COLOR:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_ItemColor.assign(str);
break;
}
case MPROP_PERPAGE:
{
cell count = *get_amxaddr(amx, params[3]);
if (count < 0 || count > 7)
{
LogError(amx, AMX_ERR_NATIVE, "Cannot set %d items per page", count);
return 0;
}
pMenu->items_per_page = count;
break;
}
case MPROP_BACKNAME:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_OptNames[abs(MENU_BACK)].assign(str);
break;
}
case MPROP_NEXTNAME:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_OptNames[abs(MENU_MORE)].assign(str);
break;
}
case MPROP_EXITNAME:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_OptNames[abs(MENU_EXIT)].assign(str);
break;
}
case MPROP_TITLE:
{
char *str = get_amxstring(amx, params[3], 0, len);
pMenu->m_Title.assign(str);
break;
}
case MPROP_EXITALL:
{
cell ans = *get_amxaddr(amx, params[3]);
if (ans == 1 || ans == 0)
{
pMenu->m_NeverExit = false;
} else if (ans == -1) {
pMenu->m_NeverExit = true;
}
break;
}
case MPROP_ORDER:
{
/* Ignored as of 1.8.0 */
break;
}
case MPROP_NOCOLORS:
{
pMenu->m_AutoColors = *get_amxaddr(amx, params[3]) ? true : false;
break;
}
case MPROP_PADMENU:
{
/* Ignored as of 1.8.0 */
break;
}
default:
{
LogError(amx, AMX_ERR_NATIVE, "Invalid menu setting: %d", params[1]);
return 0;
}
}
return 1;
}
#define GETMENU_R(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p]) { \
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
return 0; } \
Menu *pMenu = g_NewMenus[p];
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
{
int index = params[1];
if (index < 1 || index > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not valid", index);
return 0;
}
CPlayer *player = GET_PLAYER_POINTER_I(index);
if (!player->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Played %d is not in game", index);
return 0;
}
int menu = player->newmenu;
if (menu < 0 || menu >= (int)g_NewMenus.size() || !g_NewMenus[menu])
return 0;
Menu *pMenu = g_NewMenus[menu];
player->newmenu = -1;
player->menu = 0;
executeForwards(pMenu->func,
static_cast<cell>(index),
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
return 1;
}
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
{
GETMENU_R(params[1]);
if (pMenu->isDestroying)
{
return 0; //prevent infinite recursion
}
pMenu->isDestroying = true;
CPlayer *player;
for (int i=1; i<=gpGlobals->maxClients; i++)
{
player = GET_PLAYER_POINTER_I(i);
if (player->newmenu == pMenu->thisId)
{
player->newmenu = -1;
player->menu = 0;
executeForwards(pMenu->func,
static_cast<cell>(i),
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
}
}
g_NewMenus[params[1]] = NULL;
delete pMenu;
g_MenuFreeStack.push(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL player_menu_info(AMX *amx, cell *params)
{
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", params[1]);
return 0;
}
CPlayer *player = GET_PLAYER_POINTER_I(params[1]);
if (!player->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not ingame", params[1]);
return 0;
}
cell *m = get_amxaddr(amx, params[2]);
cell *n = get_amxaddr(amx, params[3]);
*m = player->menu;
*n = player->newmenu;
if (params[0] / sizeof(cell) == 4)
{
cell *addr = get_amxaddr(amx, params[4]);
*addr = player->page;
}
if ( (*m != 0 && *m != -1) || (*n != -1))
{
return 1;
}
return 0;
}
AMX_NATIVE_INFO g_NewMenuNatives[] = AMX_NATIVE_INFO g_NewMenuNatives[] =
{ {
{"menu_create", menu_create}, {"menu_create", menu_create},
{"menu_additem", menu_additem}, {"menu_additem", menu_additem},
{"menu_addblank", menu_addblank},
{"menu_pages", menu_pages}, {"menu_pages", menu_pages},
{"menu_items", menu_items}, {"menu_items", menu_items},
{"menu_display", menu_display}, {"menu_display", menu_display},
@ -1043,9 +480,5 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
{"menu_item_setcall", menu_item_setcall}, {"menu_item_setcall", menu_item_setcall},
{"menu_item_setcmd", menu_item_setcmd}, {"menu_item_setcmd", menu_item_setcmd},
{"menu_item_setname", menu_item_setname}, {"menu_item_setname", menu_item_setname},
{"menu_destroy", menu_destroy},
{"menu_setprop", menu_setprop},
{"menu_cancel", menu_cancel},
{"player_menu_info", player_menu_info},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -39,18 +39,7 @@
#define ITEM_ENABLED 1 #define ITEM_ENABLED 1
#define ITEM_DISABLED 2 #define ITEM_DISABLED 2
#define MAX_MENU_ITEMS 10 #define MENUITEMS 7
#define MPROP_PERPAGE 1
#define MPROP_BACKNAME 2
#define MPROP_NEXTNAME 3
#define MPROP_EXITNAME 4
#define MPROP_TITLE 5
#define MPROP_EXITALL 6
#define MPROP_ORDER 7
#define MPROP_NOCOLORS 8
#define MPROP_PADMENU 9
#define MPROP_SET_NUMBER_COLOR 10
typedef int (*MENUITEM_CALLBACK)(int, int, int); typedef int (*MENUITEM_CALLBACK)(int, int, int);
@ -64,8 +53,6 @@ struct menuitem
MENUITEM_CALLBACK pfn; MENUITEM_CALLBACK pfn;
size_t id; size_t id;
CVector<int> blanks;
}; };
typedef unsigned int menu_t; typedef unsigned int menu_t;
@ -75,7 +62,7 @@ typedef unsigned int page_t;
class Menu class Menu
{ {
public: public:
Menu(const char *title, AMX *amx, int fid); Menu(const char *title, int menuId, int thisId);
~Menu(); ~Menu();
menuitem *GetMenuItem(item_t item); menuitem *GetMenuItem(item_t item);
@ -88,25 +75,29 @@ public:
int PagekeyToItem(page_t page, item_t key); int PagekeyToItem(page_t page, item_t key);
int GetMenuMenuid(); int GetMenuMenuid();
public: private:
CVector<menuitem * > m_Items; CVector<menuitem * > m_Items;
String m_Title; String m_Title;
String m_Text; String m_Text;
String m_OptNames[4];
String m_ItemColor;
bool m_NeverExit;
bool m_AutoColors;
int menuId; int menuId;
int thisId; int thisId;
int func;
bool isDestroying;
public:
unsigned int items_per_page;
}; };
/*Menu *CreateMenu(const char *title);
Menu *GetMenuById(menu_t menu);
menuitem *GetMenuItem(menu_t menu, item_t item);
size_t GetMenuPages(menu_t menu);
size_t GetMenuItems(menu_t menu);
menuitem *AddMenuItem(menu_t menu, const char *name, const char *cmd, int access);
bool DisplayMenu(menu_t menu, int player, page_t page);
int MenuPagekeyToItem(menu_t menu, page_t page, int key);
int FindByMenuid(int menuid);
int GetMenuMenuid(menu_t menu);
const char *GetItemName(menu_t menu, item_t item);
const char *GetItemCmd(menu_t menu, item_t item);*/
void ClearMenus(); void ClearMenus();
extern CVector<Menu *> g_NewMenus; extern CVector<Menu *> g_NewMenus;

View File

@ -1,23 +0,0 @@
#include <string.h>
#include "nongpl_matches.h"
NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[] =
{
{"Live", "CZ Gun Game", "czgungame.amxx"},
{"Live", "AMXX Gun Game", "czgungame.amxx"},
{NULL, NULL, NULL},
};
NONGPL_CVAR_T NONGPL_CVAR_LIST[] =
{
{"gg_mode", 0},
{"gg_warmuptimer", 0},
{"gg_ff", 0},
{"gg_fflevel", 0},
{"gg_stats", 0},
{"gg_dm", 0},
{"gg_turbo", 0},
{"amx_ggreset", 1},
{"amx_gg", 1},
{NULL, 0},
};

View File

@ -1,123 +0,0 @@
#include <string.h>
#include "optimizer.h"
int g_opt_level = 0;
#define OP_SYSREQ_C 123
#define OP_NOP 134
#define OP_FLOAT_MUL 138
#define OP_FLOAT_DIV 139
#define OP_FLOAT_ADD 140
#define OP_FLOAT_SUB 141
#define OP_FLOAT_TO 142
#define OP_FLOAT_ROUND 143
#define OP_FLOAT_CMP 144
cell op_trans_table[N_Total_FloatOps] =
{
OP_FLOAT_MUL,
OP_FLOAT_DIV,
OP_FLOAT_ADD,
OP_FLOAT_SUB,
OP_FLOAT_TO,
OP_FLOAT_ROUND,
OP_FLOAT_CMP
};
void OnBrowseRelocate(AMX *amx, cell *oplist, cell *cip)
{
char *codeptr = (char *)amx->base + (long)(((AMX_HEADER *)amx->base)->cod);
//jump to the parameter;
codeptr += *cip;
int native = -1;
cell n_offs = *(cell *)codeptr;
optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER];
for (int i=0; i<N_Total_FloatOps; i++)
{
if (opt->natives[i] == n_offs)
{
native = i;
break;
}
}
if (native != -1)
{
//we're patching this:
// 0x7B 0x?? SYSREQ.C float???
//with:
// 0x8A FLOAT.MUL
// 0x86 NOP
cell new_opcodes[2];
new_opcodes[0] = op_trans_table[native];
new_opcodes[1] = OP_NOP;
codeptr -= sizeof(cell);
#if defined __GNUC__ || defined ASM32 || defined JIT
*(cell *)codeptr = oplist[new_opcodes[0]];
*(cell *)(codeptr + sizeof(cell)) = oplist[new_opcodes[1]];
#else
*(cell *)codeptr = new_opcodes[0];
*(cell *)(codeptr + sizeof(cell)) = new_opcodes[1];
#endif
}
*cip += sizeof(cell);
return;
}
#define FIND_NATIVE(name, bind) \
if (amx_FindNative(amx, name, &index) != AMX_ERR_NOTFOUND) \
opt->natives[bind] = index;
void _Setup_Optimizer_Stage2(AMX *amx, cell *oplist, cell *cip)
{
int index;
amx->usertags[UT_BROWSEHOOK] = (void *)OnBrowseRelocate;
optimizer_s *opt = new optimizer_s;
for (int i=0; i<N_Total_FloatOps; i++)
opt->natives[i] = -1;
amx->usertags[UT_OPTIMIZER] = (void *)opt;
if (g_opt_level & 1)
{
FIND_NATIVE("floatmul", N_Float_Mul);
FIND_NATIVE("floatdiv", N_Float_Div);
FIND_NATIVE("floatadd", N_Float_Add);
FIND_NATIVE("floatsub", N_Float_Sub);
}
if (g_opt_level & 4)
{
FIND_NATIVE("float", N_Float_To);
FIND_NATIVE("floatround", N_Float_Round);
}
if (g_opt_level & 2)
{
#if !defined AMD64
if (amxx_CpuSupport())
{
#endif
FIND_NATIVE("floatcmp", N_Float_Cmp);
#if !defined AMD64
} else {
g_opt_level &= ~(2);
}
#endif
}
/* we don't do these yet because of radix stuff >:\ */
//FIND_NATIVE("floatsin", N_Float_Sin);
//FIND_NATIVE("floatcos", N_Float_Cos);
//FIND_NATIVE("floattan", N_Float_Tan);
}
void SetupOptimizer(AMX *amx)
{
amx->usertags[UT_BROWSEHOOK] = (void *)_Setup_Optimizer_Stage2;
}

View File

@ -1,29 +0,0 @@
#ifndef _INCLUDE_AMXMODX_OPTIMIZER_H
#define _INCLUDE_AMXMODX_OPTIMIZER_H
#include "amx.h"
enum
{
N_Float_Mul=0,
N_Float_Div,
N_Float_Add,
N_Float_Sub,
N_Float_To,
N_Float_Round,
N_Float_Cmp,
/* ------------ */
N_Total_FloatOps,
};
struct optimizer_s
{
int natives[N_Total_FloatOps];
};
void SetupOptimizer(AMX *amx);
extern "C" int amxx_CpuSupport();
extern int g_opt_level;
#endif //_INCLUDE_AMXMODX_OPTIMIZER_H

View File

@ -2284,7 +2284,7 @@ C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_
} }
#ifdef FN_META_QUERY #ifdef FN_META_QUERY
FN_META_QUERY(); return FN_META_QUERY();
#endif // FN_META_QUERY #endif // FN_META_QUERY
return 1; return 1;
@ -2327,7 +2327,7 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
} }
#ifdef FN_META_DETACH #ifdef FN_META_DETACH
FN_META_DETACH(); return FN_META_DETACH();
#endif // FN_META_DETACH #endif // FN_META_DETACH
return TRUE; return TRUE;
} }
@ -2374,7 +2374,7 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine,
gpGlobals = pGlobals; gpGlobals = pGlobals;
// NOTE! Have to call logging function _after_ copying into g_engfuncs, so // NOTE! Have to call logging function _after_ copying into g_engfuncs, so
// that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :) // that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :)
// UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag); UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag);
// --> ** Function core // --> ** Function core
#ifdef _MSC_VER #ifdef _MSC_VER
@ -2430,14 +2430,11 @@ static amxx_module_info_s g_ModuleInfo =
#else // MODULE_RELOAD_ON_MAPCHANGE #else // MODULE_RELOAD_ON_MAPCHANGE
0, 0,
#endif // MODULE_RELOAD_ON_MAPCHANGE #endif // MODULE_RELOAD_ON_MAPCHANGE
MODULE_LOGTAG, MODULE_LOGTAG
MODULE_LIBRARY,
MODULE_LIBCLASS
}; };
// Storage for the requested functions // Storage for the requested functions
PFN_ADD_NATIVES g_fn_AddNatives; PFN_ADD_NATIVES g_fn_AddNatives;
PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
PFN_BUILD_PATHNAME g_fn_BuildPathname; PFN_BUILD_PATHNAME g_fn_BuildPathname;
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR; PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
PFN_GET_AMXADDR g_fn_GetAmxAddr; PFN_GET_AMXADDR g_fn_GetAmxAddr;
@ -2505,18 +2502,6 @@ PFN_FORMAT g_fn_Format;
PFN_REGISTERFUNCTION g_fn_RegisterFunction; PFN_REGISTERFUNCTION g_fn_RegisterFunction;
PFN_REQ_FNPTR g_fn_RequestFunction; PFN_REQ_FNPTR g_fn_RequestFunction;
PFN_AMX_PUSH g_fn_AmxPush; PFN_AMX_PUSH g_fn_AmxPush;
PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
PFN_FINDLIBRARY g_fn_FindLibrary;
PFN_ADDLIBRARIES g_fn_AddLibraries;
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
PFN_GETLOCALINFO g_fn_GetLocalInfo;
PFN_AMX_REREGISTER g_fn_AmxReRegister;
PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
PFN_MESSAGE_BLOCK g_fn_MessageBlock;
// *** Exports *** // *** Exports ***
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo) C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
@ -2567,7 +2552,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE); REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
REQFUNC("Format", g_fn_Format, PFN_FORMAT); REQFUNC("Format", g_fn_Format, PFN_FORMAT);
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION); REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
REQFUNC("RegisterFunctionEx", g_fn_RegisterFunctionEx, PFN_REGISTERFUNCTIONEX);
// Amx scripts // Amx scripts
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT); REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
@ -2593,7 +2577,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
// Natives / Forwards // Natives / Forwards
REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES); REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES);
REQFUNC("AddNewNatives", g_fn_AddNewNatives, PFN_ADD_NEW_NATIVES);
REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR); REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR);
REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD); REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD);
REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD); REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD);
@ -2628,20 +2611,6 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS); REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT); REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH); REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
REQFUNC("SetPlayerTeamInfo", g_fn_SetTeamInfo, PFN_SET_TEAM_INFO);
REQFUNC("PlayerPropAddr", g_fn_PlayerPropAddr, PFN_PLAYER_PROP_ADDR);
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
//Added in 1.75
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
REQFUNC("GetLocalInfo", g_fn_GetLocalInfo, PFN_GETLOCALINFO);
REQFUNC("AmxReregister", g_fn_AmxReRegister, PFN_AMX_REREGISTER);
REQFUNC("MessageBlock", g_fn_MessageBlock, PFN_MESSAGE_BLOCK);
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
// Memory // Memory
@ -2677,27 +2646,14 @@ C_DLLEXPORT int AMXX_PluginsLoaded()
return AMXX_OK; return AMXX_OK;
} }
C_DLLEXPORT void AMXX_PluginsUnloaded()
{
#ifdef FN_AMXX_PLUGINSUNLOADED
FN_AMXX_PLUGINSUNLOADED();
#endif // FN_AMXX_PLUGINSUNLOADED
}
C_DLLEXPORT void AMXX_PluginsUnloading()
{
#ifdef FN_AMXX_PLUGINSUNLOADING
FN_AMXX_PLUGINSUNLOADING();
#endif // FN_AMXX_PLUGINSUNLOADING
}
// Advanced MF functions // Advanced MF functions
void MF_Log(const char *fmt, ...) void MF_Log(const char *fmt, ...)
{ {
// :TODO: Overflow possible here
char msg[3072]; char msg[3072];
va_list arglst; va_list arglst;
va_start(arglst, fmt); va_start(arglst, fmt);
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst); vsprintf(msg, fmt, arglst);
va_end(arglst); va_end(arglst);
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg); g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
@ -2705,10 +2661,11 @@ void MF_Log(const char *fmt, ...)
void MF_LogError(AMX *amx, int err, const char *fmt, ...) void MF_LogError(AMX *amx, int err, const char *fmt, ...)
{ {
// :TODO: Overflow possible here
char msg[3072]; char msg[3072];
va_list arglst; va_list arglst;
va_start(arglst, fmt); va_start(arglst, fmt);
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst); vsprintf(msg, fmt, arglst);
va_end(arglst); va_end(arglst);
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg); g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
@ -2776,16 +2733,6 @@ void ValidateMacros_DontCallThis_Smiley()
MF_GetPlayerEdict(0); MF_GetPlayerEdict(0);
MF_Format("", 4, "str"); MF_Format("", 4, "str");
MF_RegisterFunction(NULL, ""); MF_RegisterFunction(NULL, "");
MF_RegisterFunctionEx(NULL, "");
MF_SetPlayerTeamInfo(0, 0, "");
MF_PlayerPropAddr(0, 0);
MF_RegAuthFunc(NULL);
MF_UnregAuthFunc(NULL);
MF_FindLibrary(NULL, LibType_Class);
MF_AddLibraries(NULL, LibType_Class, NULL);
MF_RemoveLibraries(NULL);
MF_OverrideNatives(NULL, NULL);
MF_MessageBlock(0, 0, NULL);
} }
#endif #endif
@ -2965,20 +2912,20 @@ void operator delete[](void *reportedAddress)
#else #else
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32 #if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
void * operator new(size_t size) { void * ::operator new(size_t size) {
return(calloc(1, size)); return(calloc(1, size));
} }
void * operator new[](size_t size) { void * ::operator new[](size_t size) {
return(calloc(1, size)); return(calloc(1, size));
} }
void operator delete(void * ptr) { void ::operator delete(void * ptr) {
if(ptr) if(ptr)
free(ptr); free(ptr);
} }
void operator delete[](void * ptr) { void ::operator delete[](void * ptr) {
if(ptr) if(ptr)
free(ptr); free(ptr);
} }

View File

@ -22,7 +22,7 @@
#ifndef __linux__ #ifndef __linux__
#define DLLEXPORT __declspec(dllexport) #define DLLEXPORT __declspec(dllexport)
#else #else
#define DLLEXPORT __attribute__((visibility("default"))) #define DLLEXPORT
#define LINUX #define LINUX
#endif #endif
@ -34,8 +34,7 @@
// module interface version was 1 // module interface version was 1
// 2 - added logtag to struct (amxx1.1-rc1) // 2 - added logtag to struct (amxx1.1-rc1)
// 3 - added new tagAMX structure (amxx1.5) // 3 - added new tagAMX structure (amxx1.5)
// 4 - added new 'library' setting for direct loading #define AMXX_INTERFACE_VERSION 3
#define AMXX_INTERFACE_VERSION 4
// amxx module info // amxx module info
struct amxx_module_info_s struct amxx_module_info_s
@ -45,8 +44,6 @@ struct amxx_module_info_s
const char *version; const char *version;
int reload; // reload on mapchange when nonzero int reload; // reload on mapchange when nonzero
const char *logtag; // added in version 2 const char *logtag; // added in version 2
const char *library; // added in version 4
const char *libclass; // added in version 4
}; };
// return values from functions called by amxx // return values from functions called by amxx
@ -159,134 +156,6 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
#pragma warning(disable:4103) /* disable warning message 4103 that complains #pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */ * about pragma pack in a header file */
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */ #pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
#if _MSC_VER >= 1400
#if !defined NO_MSVC8_AUTO_COMPAT
/* Disable deprecation warnings concerning unsafe CRT functions */
#if !defined _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
/* Replace the POSIX function with ISO C++ conformant ones as they are now deprecated */
#define access _access
#define cabs _cabs
#define cgets _cgets
#define chdir _chdir
#define chmod _chmod
#define chsize _chsize
#define close _close
#define cprintf _cprintf
#define cputs _cputts
#define creat _creat
#define cscanf _cscanf
#define cwait _cwait
#define dup _dup
#define dup2 _dup2
#define ecvt _ecvt
#define eof _eof
#define execl _execl
#define execle _execle
#define execlp _execlp
#define execlpe _execlpe
#define execv _execv
#define execve _execv
#define execvp _execvp
#define execvpe _execvpe
#define fcloseall _fcloseall
#define fcvt _fcvt
#define fdopen _fdopen
#define fgetchar _fgetchar
#define filelength _filelength
#define fileno _fileno
#define flushall _flushall
#define fputchar _fputchar
#define gcvt _gcvt
#define getch _getch
#define getche _getche
#define getcwd _getcwd
#define getpid _getpid
#define getw _getw
#define hypot _hypot
#define inp _inp
#define inpw _inpw
#define isascii __isascii
#define isatty _isatty
#define iscsym __iscsym
#define iscsymf __iscsymf
#define itoa _itoa
#define j0 _j0
#define j1 _j1
#define jn _jn
#define kbhit _kbhit
#define lfind _lfind
#define locking _locking
#define lsearch _lsearch
#define lseek _lseek
#define ltoa _ltoa
#define memccpy _memccpy
#define memicmp _memicmp
#define mkdir _mkdir
#define mktemp _mktemp
#define open _open
#define outp _outp
#define outpw _outpw
#define putch _putch
#define putenv _putenv
#define putw _putw
#define read _read
#define rmdir _rmdir
#define rmtmp _rmtmp
#define setmode _setmode
#define sopen _sopen
#define spawnl _spawnl
#define spawnle _spawnle
#define spawnlp _spawnlp
#define spawnlpe _spawnlpe
#define spawnv _spawnv
#define spawnve _spawnve
#define spawnvp _spawnvp
#define spawnvpe _spawnvpe
#define strcmpi _strcmpi
#define strdup _strdup
#define stricmp _stricmp
#define strlwr _strlwr
#define strnicmp _strnicmp
#define strnset _strnset
#define strrev _strrev
#define strset _strset
#define strupr _strupr
#define swab _swab
#define tell _tell
#define tempnam _tempnam
#define toascii __toascii
#define tzset _tzset
#define ultoa _ultoa
#define umask _umask
#define ungetch _ungetch
#define unlink _unlink
#define wcsdup _wcsdup
#define wcsicmp _wcsicmp
#define wcsicoll _wcsicoll
#define wcslwr _wcslwr
#define wcsnicmp _wcsnicmp
#define wcsnset _wcsnset
#define wcsrev _wcsrev
#define wcsset _wcsset
#define wcsupr _wcsupr
#define write _write
#define y0 _y0
#define y1 _y1
#define yn _yn
/* Disable deprecation warnings because MSVC8 seemingly thinks the ISO C++ conformant
* functions above are deprecated. */
#pragma warning (disable:4996)
#endif
#else
#define vsnprintf _vsnprintf
#endif
#endif #endif
@ -1077,7 +946,7 @@ void FN_AlertMessage(ALERT_TYPE atype, char *szFmt, ...);
#endif // FN_AlertMessage #endif // FN_AlertMessage
#ifdef FN_EngineFprintf #ifdef FN_EngineFprintf
void FN_EngineFprintf(void *pfile, char *szFmt, ...); void FN_EngineFprintf(FILE *pfile, char *szFmt, ...);
#endif // FN_EngineFprintf #endif // FN_EngineFprintf
#ifdef FN_PvAllocEntPrivateData #ifdef FN_PvAllocEntPrivateData
@ -1141,11 +1010,11 @@ void FN_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, flo
#endif // FN_GetBonePosition #endif // FN_GetBonePosition
#ifdef FN_FunctionFromName #ifdef FN_FunctionFromName
uint32 FN_FunctionFromName(const char *pName); unsigned long FN_FunctionFromName(const char *pName);
#endif // FN_FunctionFromName #endif // FN_FunctionFromName
#ifdef FN_NameForFunction #ifdef FN_NameForFunction
const char *FN_NameForFunction(uint32); const char *FN_NameForFunction(unsigned long function);
#endif // FN_NameForFunction #endif // FN_NameForFunction
#ifdef FN_ClientPrintf #ifdef FN_ClientPrintf
@ -1189,7 +1058,7 @@ CRC32_t FN_CRC32_Final(CRC32_t pulCRC);
#endif // FN_CRC32_Final #endif // FN_CRC32_Final
#ifdef FN_RandomLong #ifdef FN_RandomLong
int32 FN_RandomLong(int32 lLow, int32 lHigh); long FN_RandomLong(long lLow, long lHigh);
#endif // FN_RandomLong #endif // FN_RandomLong
#ifdef FN_RandomFloat #ifdef FN_RandomFloat
@ -1658,11 +1527,11 @@ void FN_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...);
#endif // FN_AlertMessage_Post #endif // FN_AlertMessage_Post
#ifdef FN_EngineFprintf_Post #ifdef FN_EngineFprintf_Post
void FN_EngineFprintf_Post(void *pfile, char *szFmt, ...); void FN_EngineFprintf_Post(FILE *pfile, char *szFmt, ...);
#endif // FN_EngineFprintf_Post #endif // FN_EngineFprintf_Post
#ifdef FN_PvAllocEntPrivateData_Post #ifdef FN_PvAllocEntPrivateData_Post
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, int32 cb); void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, long cb);
#endif // FN_PvAllocEntPrivateData_Post #endif // FN_PvAllocEntPrivateData_Post
#ifdef FN_PvEntPrivateData_Post #ifdef FN_PvEntPrivateData_Post
@ -1722,11 +1591,11 @@ void FN_GetBonePosition_Post(const edict_t *pEdict, int iBone, float *rgflOrigin
#endif // FN_GetBonePosition_Post #endif // FN_GetBonePosition_Post
#ifdef FN_FunctionFromName_Post #ifdef FN_FunctionFromName_Post
uint32 FN_FunctionFromName_Post(const char *pName); unsigned long FN_FunctionFromName_Post(const char *pName);
#endif // FN_FunctionFromName_Post #endif // FN_FunctionFromName_Post
#ifdef FN_NameForFunction_Post #ifdef FN_NameForFunction_Post
const char *FN_NameForFunction_Post(uint32); const char *FN_NameForFunction_Post(unsigned long function);
#endif // FN_NameForFunction_Post #endif // FN_NameForFunction_Post
#ifdef FN_ClientPrintf_Post #ifdef FN_ClientPrintf_Post
@ -1770,7 +1639,7 @@ CRC32_t FN_CRC32_Final_Post(CRC32_t pulCRC);
#endif // FN_CRC32_Final_Post #endif // FN_CRC32_Final_Post
#ifdef FN_RandomLong_Post #ifdef FN_RandomLong_Post
int32 FN_RandomLong_Post(int32 lLow, int32 lHigh); long FN_RandomLong_Post(long lLow, long lHigh);
#endif // FN_RandomLong_Post #endif // FN_RandomLong_Post
#ifdef FN_RandomFloat_Post #ifdef FN_RandomFloat_Post
@ -2035,14 +1904,6 @@ void FN_AMXX_DETACH(void);
void FN_AMXX_PLUGINSLOADED(void); void FN_AMXX_PLUGINSLOADED(void);
#endif // FN_AMXX_PLUGINSLOADED #endif // FN_AMXX_PLUGINSLOADED
#ifdef FN_AMXX_PLUGINSUNLOADING
void FN_AMXX_PLUGINSUNLOADING(void);
#endif // FN_AMXX_PLUGINSUNLOADING
#ifdef FN_AMXX_PLUGINSUNLOADED
void FN_AMXX_PLUGINSUNLOADED(void);
#endif // FN_AMXX_PLUGINSUNLOADED
// *** Types *** // *** Types ***
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/); typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
@ -2066,45 +1927,8 @@ enum ForwardParam
FP_ARRAY, // array; use the return value of prepareArray. FP_ARRAY, // array; use the return value of prepareArray.
}; };
enum PlayerProp
{
Player_Name, //String
Player_Ip, //String
Player_Team, //String
Player_Ingame, //bool
Player_Authorized, //bool
Player_Vgui, //bool
Player_Time, //float
Player_Playtime, //float
Player_MenuExpire, //float
Player_Weapons, //struct{int,int}[32]
Player_CurrentWeapon, //int
Player_TeamID, //int
Player_Deaths, //int
Player_Aiming, //int
Player_Menu, //int
Player_Keys, //int
Player_Flags, //int[32]
Player_Newmenu, //int
Player_NewmenuPage, //int
};
enum LibType
{
LibType_Library,
LibType_Class
};
#define MSGBLOCK_SET 0
#define MSGBLOCK_GET 1
#define BLOCK_NOT 0
#define BLOCK_ONCE 1
#define BLOCK_SET 2
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/); typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef int (*PFN_ADD_NEW_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...); typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...); typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/); typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
@ -2154,7 +1978,6 @@ typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#else #else
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/); typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#endif #endif
typedef void * (*PFN_PLAYER_PROP_ADDR) (int /*id*/, int /*prop*/);
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
@ -2180,20 +2003,8 @@ typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/); typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/); typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/); typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/);
typedef size_t (*PFN_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/, const char * /*myname*/);
typedef const char * (*PFN_GETLOCALINFO) (const char * /*name*/, const char * /*def*/);
typedef int (*PFN_AMX_REREGISTER) (AMX * /*amx*/, AMX_NATIVE_INFO * /*list*/, int /*list*/);
typedef void * (*PFN_REGISTERFUNCTIONEX) (void * /*pfn*/, const char * /*desc*/);
typedef void (*PFN_MESSAGE_BLOCK) (int /* mode */, int /* message */, int * /* opt */);
extern PFN_ADD_NATIVES g_fn_AddNatives; extern PFN_ADD_NATIVES g_fn_AddNatives;
extern PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
extern PFN_BUILD_PATHNAME g_fn_BuildPathname; extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR; extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
extern PFN_GET_AMXADDR g_fn_GetAmxAddr; extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
@ -2255,24 +2066,11 @@ extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction; extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
extern PFN_REQ_FNPTR g_fn_RequestFunction; extern PFN_REQ_FNPTR g_fn_RequestFunction;
extern PFN_AMX_PUSH g_fn_AmxPush; extern PFN_AMX_PUSH g_fn_AmxPush;
extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
extern PFN_FINDLIBRARY g_fn_FindLibrary;
extern PFN_ADDLIBRARIES g_fn_AddLibraries;
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
extern PFN_GETLOCALINFO g_fn_GetLocalInfo;
extern PFN_AMX_REREGISTER g_fn_AmxReRegister;
extern PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
extern PFN_MESSAGE_BLOCK g_fn_MessageBlock;
#ifdef MAY_NEVER_BE_DEFINED #ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems // Function prototypes for intellisense and similar systems
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED // They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
int MF_AddNatives (const AMX_NATIVE_INFO *list) { } int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
int MF_AddNewNatives (const AMX_NATIVE_INFO *list) { }
char * MF_BuildPathname (const char * format, ...) { } char * MF_BuildPathname (const char * format, ...) { }
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { } char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
cell * MF_GetAmxAddr (AMX * amx, cell offset) { } cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
@ -2328,22 +2126,9 @@ void MF_RegisterFunction (void *pfn, const char *description) { }
void * MF_RequestFunction (const char *description) { } void * MF_RequestFunction (const char *description) { }
int MF_AmxPush (AMX *amx, cell *params) { } int MF_AmxPush (AMX *amx, cell *params) { }
int MF_AmxExec (AMX *amx, cell *retval, int idx) { } int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
void * MF_PlayerPropAddr (int id, int prop) { }
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
int MF_FindLibrary (const char *name, LibType type) { }
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
size_t MF_RemoveLibraries (void *parent) { }
void MF_OverrideNatives (AMX_NATIVE_INFO *natives, const char *myname) { }
const char * MF_GetLocalInfo (const char *name, const char *def) { }
int MF_AmxReRegister (AMX *amx, AMX_NATIVE_INFO *list, int number) { return 0; }
void * MF_RegisterFunctionEx (void *pfn, const char *description) { }
void * MF_MessageBlock (int mode, int msg, int *opt) { }
#endif // MAY_NEVER_BE_DEFINED #endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives #define MF_AddNatives g_fn_AddNatives
#define MF_AddNewNatives g_fn_AddNewNatives
#define MF_BuildPathname g_fn_BuildPathname #define MF_BuildPathname g_fn_BuildPathname
#define MF_BuildPathnameR g_fn_BuildPathnameR #define MF_BuildPathnameR g_fn_BuildPathnameR
#define MF_FormatAmxString g_fn_FormatAmxString #define MF_FormatAmxString g_fn_FormatAmxString
@ -2404,20 +2189,8 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_GetPlayerEdict g_fn_GetPlayerEdict #define MF_GetPlayerEdict g_fn_GetPlayerEdict
#define MF_Format g_fn_Format #define MF_Format g_fn_Format
#define MF_RegisterFunction g_fn_RegisterFunction #define MF_RegisterFunction g_fn_RegisterFunction
#define MF_RequestFunction g_fn_RequestFunction #define MF_RequestFunction g_fn_RequestFunction;
#define MF_AmxPush g_fn_AmxPush #define MF_AmxPush g_fn_AmxPush
#define MF_SetPlayerTeamInfo g_fn_SetTeamInfo
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
#define MF_RegAuthFunc g_fn_RegAuthFunc
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
#define MF_FindLibrary g_fn_FindLibrary
#define MF_AddLibraries g_fn_AddLibraries
#define MF_RemoveLibraries g_fn_RemoveLibraries
#define MF_OverrideNatives g_fn_OverrideNatives
#define MF_GetLocalInfo g_fn_GetLocalInfo
#define MF_AmxReRegister g_fn_AmxReRegister
#define MF_RegisterFunctionEx g_fn_RegisterFunctionEx
#define MF_MessageBlock g_fn_MessageBlock
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
/*** Memory ***/ /*** Memory ***/

View File

@ -3,24 +3,12 @@
#ifndef __MODULECONFIG_H__ #ifndef __MODULECONFIG_H__
#define __MODULECONFIG_H__ #define __MODULECONFIG_H__
/** Module info // Module info
* -The logtag is the tag that the module's log messages will be
* prepended with.
* -The library is the name that the #pragma library
* message will have prepended.
* -The library class is the class of libraries that
* a module belongs to (like DBI). Keep it "" to
* ignore.
* -For both library and library class, you can use a comma
* to add multiple entries.
*/
#define MODULE_NAME "--ENTER NAME HERE--" #define MODULE_NAME "--ENTER NAME HERE--"
#define MODULE_VERSION "--ENTER VERSION HERE--" #define MODULE_VERSION "--ENTER VERSION HERE--"
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--" #define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
#define MODULE_URL "--ENTER URL HERE--" #define MODULE_URL "--ENTER URL HERE--"
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--" #define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
#define MODULE_LIBRARY "--ENTER LIBRARY HERE--"
#define MODULE_LIBCLASS ""
// If you want the module not to be reloaded on mapchange, remove / comment out the next line // If you want the module not to be reloaded on mapchange, remove / comment out the next line
#define MODULE_RELOAD_ON_MAPCHANGE #define MODULE_RELOAD_ON_MAPCHANGE
@ -43,36 +31,19 @@
// It allows you to compile without libstdc++.so as a dependency // It allows you to compile without libstdc++.so as a dependency
// #define NO_ALLOC_OVERRIDES // #define NO_ALLOC_OVERRIDES
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself // - AMXX Init functions
// #define NO_MSVC8_AUTO_COMPAT // Also consider using FN_META_*
// AMXX query
/**
* AMXX Init functions
* Also consider using FN_META_*
*/
/** AMXX query */
//#define FN_AMXX_QUERY OnAmxxQuery //#define FN_AMXX_QUERY OnAmxxQuery
// AMXX attach
/** AMXX attach // Do native functions init here (MF_AddNatives)
* Do native functions init here (MF_AddNatives)
*/
//#define FN_AMXX_ATTACH OnAmxxAttach //#define FN_AMXX_ATTACH OnAmxxAttach
// AMXX detach
/** AMXX Detach (unload) */
//#define FN_AMXX_DETACH OnAmxxDetach //#define FN_AMXX_DETACH OnAmxxDetach
// All plugins loaded
/** All plugins loaded // Do forward functions init here (MF_RegisterForward)
* Do forward functions init here (MF_RegisterForward)
*/
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded // #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
/** All plugins are about to be unloaded */
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
/** All plugins are now unloaded */
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
/**** METAMOD ****/ /**** METAMOD ****/
// If your module doesn't use metamod, you may close the file now :) // If your module doesn't use metamod, you may close the file now :)
#ifdef USE_METAMOD #ifdef USE_METAMOD

View File

@ -1,297 +0,0 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): David "BAILOPAN" Anderson
* ============================
*/
#ifndef _INCLUDE_SMM_LIST_H
#define _INCLUDE_SMM_LIST_H
// MSVC8 fix for offsetof macro redefition warnings
#ifdef _MSC_VER
#if _MSC_VER >= 1400
#undef offsetof
#endif
#endif
#include <new>
#include <malloc.h>
//namespace SourceHook
//{
//This class is from CSDM for AMX Mod X
/*
A circular, doubly-linked list with one sentinel node
Empty:
m_Head = sentinel
m_Head->next = m_Head;
m_Head->prev = m_Head;
One element:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node1
node1->next = m_Head
node1->prev = m_Head
Two elements:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node2
node1->next = node2
node1->prev = m_Head
node2->next = m_Head
node2->prev = node1
*/
template <class T>
class List
{
public:
class iterator;
friend class iterator;
class ListNode
{
public:
ListNode(const T & o) : obj(o) { };
ListNode() { };
T obj;
ListNode *next;
ListNode *prev;
};
private:
// Initializes the sentinel node.
// BAIL used malloc instead of new in order to bypass the need for a constructor.
ListNode *_Initialize()
{
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
n->next = n;
n->prev = n;
return n;
}
public:
List() : m_Head(_Initialize()), m_Size(0)
{
}
List(const List &src) : m_Head(_Initialize()), m_Size(0)
{
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
}
~List()
{
clear();
// Don't forget to free the sentinel
if (m_Head)
{
free(m_Head);
m_Head = NULL;
}
}
void push_back(const T &obj)
{
ListNode *node = new ListNode(obj);
node->prev = m_Head->prev;
node->next = m_Head;
m_Head->prev->next = node;
m_Head->prev = node;
m_Size++;
}
size_t size()
{
return m_Size;
}
void clear()
{
ListNode *node = m_Head->next;
ListNode *temp;
m_Head->next = m_Head;
m_Head->prev = m_Head;
// Iterate through the nodes until we find g_Head (the sentinel) again
while (node != m_Head)
{
temp = node->next;
delete node;
node = temp;
}
m_Size = 0;
}
bool empty()
{
return (m_Size == 0);
}
T & back()
{
return m_Head->prev->obj;
}
private:
ListNode *m_Head;
size_t m_Size;
public:
class iterator
{
friend class List;
public:
iterator()
{
m_This = NULL;
}
iterator(const List &src)
{
m_This = src.m_Head;
}
iterator(ListNode *n) : m_This(n)
{
}
iterator(const iterator &where)
{
m_This = where.m_This;
}
//pre decrement
iterator & operator--()
{
if (m_This)
m_This = m_This->prev;
return *this;
}
//post decrement
iterator operator--(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->prev;
return old;
}
//pre increment
iterator & operator++()
{
if (m_This)
m_This = m_This->next;
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->next;
return old;
}
const T & operator * () const
{
return m_This->obj;
}
T & operator * ()
{
return m_This->obj;
}
T * operator -> ()
{
return &(m_This->obj);
}
const T * operator -> () const
{
return &(m_This->obj);
}
bool operator != (const iterator &where) const
{
return (m_This != where.m_This);
}
bool operator ==(const iterator &where) const
{
return (m_This == where.m_This);
}
private:
ListNode *m_This;
};
public:
iterator begin() const
{
return iterator(m_Head->next);
}
iterator end() const
{
return iterator(m_Head);
}
iterator erase(iterator &where)
{
ListNode *pNode = where.m_This;
iterator iter(where);
iter++;
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
delete pNode;
m_Size--;
return iter;
}
iterator insert(iterator where, const T &obj)
{
// Insert obj right before where
ListNode *node = new ListNode(obj);
ListNode *pWhereNode = where.m_This;
pWhereNode->prev->next = node;
node->prev = pWhereNode->prev;
pWhereNode->prev = node;
node->next = pWhereNode;
m_Size++;
return iterator(node);
}
public:
void remove(const T & obj)
{
iterator b;
for (b=begin(); b!=end(); b++)
{
if ( (*b) == obj )
{
erase( b );
break;
}
}
}
template <typename U>
iterator find(const U & equ)
{
iterator iter;
for (iter=begin(); iter!=end(); iter++)
{
if ( (*iter) == equ )
return iter;
}
return end();
}
List & operator =(const List &src)
{
clear();
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
return *this;
}
};
//}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H

View File

@ -1,219 +0,0 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SH_STACK_H__
#define __SH_STACK_H__
#define SH_STACK_DEFAULT_SIZE 4
//namespace SourceHook
//{/
// Vector
template <class T> class CStack
{
T *m_Elements;
size_t m_AllocatedSize;
size_t m_UsedSize;
public:
friend class iterator;
class iterator
{
CStack<T> *m_pParent;
size_t m_Index;
public:
iterator(CStack<T> *pParent, size_t id) : m_pParent(pParent), m_Index(id)
{
}
iterator(CStack<T> *pParent) : m_pParent(pParent), m_Index(0)
{
}
iterator() : m_pParent(NULL), m_Index(0)
{
}
T &operator *()
{
return m_pParent->m_Elements[m_Index];
}
const T &operator *() const
{
return m_pParent->m_Elements[m_Index];
}
T * operator->()
{
return m_pParent->m_Elements + m_Index;
}
const T * operator->() const
{
return m_pParent->m_Elements + m_Index;
}
iterator & operator++() // preincrement
{
++m_Index;
return (*this);
}
iterator operator++(int) // postincrement
{
iterator tmp = *this;
++m_Index;
return tmp;
}
iterator & operator--() // predecrement
{
--m_Index;
return (*this);
}
iterator operator--(int) // postdecrememnt
{
iterator tmp = *this;
--m_Index;
return tmp;
}
bool operator==(const iterator & right) const
{
return (m_pParent == right.m_pParent && m_Index == right.m_Index);
}
bool operator!=(const iterator & right) const
{
return !(*this == right);
}
};
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
m_UsedSize(0)
{
}
CStack(size_t size) : m_Elements(new T[size]),
m_AllocatedSize(size),
m_UsedSize(0)
{
}
CStack(const CStack &other) : m_Elements(NULL),
m_AllocatedSize(0),
m_UsedSize(0)
{
reserve(other.m_AllocatedSize);
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
~CStack()
{
if (m_Elements)
delete [] m_Elements;
}
void operator=(const CStack &other)
{
if (m_AllocatedSize < other.m_AllocatedSize)
{
if (m_Elements)
delete [] m_Elements;
m_Elements = new T[other.m_AllocatedSize];
m_AllocatedSize = other.m_AllocatedSize;
}
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
bool push(const T &val)
{
if (m_UsedSize + 1 == m_AllocatedSize)
{
// zOHNOES! REALLOCATE!
m_AllocatedSize *= 2;
T *newElements = new T[m_AllocatedSize];
if (!newElements)
{
m_AllocatedSize /= 2;
return false;
}
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
}
m_Elements[m_UsedSize++] = val;
return true;
}
void pop()
{
--m_UsedSize;
}
T &front()
{
return m_Elements[m_UsedSize - 1];
}
const T &front() const
{
return m_Elements[m_UsedSize - 1];
}
iterator begin()
{
return iterator(this, 0);
}
iterator end()
{
return iterator(this, m_UsedSize);
}
size_t size()
{
return m_UsedSize;
}
size_t capacity()
{
return m_AllocatedSize;
}
bool empty()
{
return m_UsedSize == 0 ? true : false;
}
bool reserve(size_t size)
{
if (size > m_AllocatedSize)
{
T *newElements = new T[size];
if (!newElements)
return false;
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
m_AllocatedSize = size;
}
return true;
}
};
//}; //namespace SourceHook
#endif

View File

@ -1,360 +0,0 @@
#include "amxmodx.h"
#include <stdlib.h>
/***********************************
* About the double array hack *
***************************
Double arrays in Pawn are vectors offset by the current offset. For example:
new array[2][2]
In this array, index 0 contains the offset from the current offset which
results in the final vector [2] (at [0][2]). Meaning, to dereference [1][2],
it is equivalent to:
address = &array[1] + array[1] + 2 * sizeof(cell)
The fact that each offset is from the _current_ position rather than the _base_
position is very important. It means that if you to try to swap vector positions,
the offsets will no longer match, because their current position has changed. A
simple and ingenious way around this is to back up the positions in a separate array,
then to overwrite each position in the old array with absolute indices. Pseudo C++ code:
cell *array; //assumed to be set to the 2+D array
cell *old_offsets = new cell[2];
for (int i=0; i<2; i++)
{
old_offsets = array[i];
array[i] = i;
}
Now, you can swap the array indices with no problem, and do a reverse-lookup to find the original addresses.
After sorting/modification is done, you must relocate the new indices. For example, if the two vectors in our
demo array were swapped, array[0] would be 1 and array[1] would be 0. This is invalid to the virtual machine.
Luckily, this is also simple -- all the information is there.
for (int i=0; i<2; i++)
{
//get the # of the vector we want to relocate in
cell vector_index = array[i];
//get the real address of this vector
char *real_address = (char *)array + (vector_index * sizeof(cell)) + old_offsets[vector_index];
//calc and store the new distance offset
array[i] = real_address - ( (char *)array + (vector_index + sizeof(cell)) )
}
Note that the inner expression can be heavily reduced; it is expanded for readability.
**********************************/
enum SortOrder
{
Sort_Ascending = 0,
Sort_Descending = 1,
};
int sort_ints_asc(const void *int1, const void *int2)
{
return (*(int *)int1) - (*(int *)int2);
}
int sort_ints_desc(const void *int1, const void *int2)
{
return (*(int *)int2) - (*(int *)int1);
}
static cell AMX_NATIVE_CALL SortIntegers(AMX *amx, cell *params)
{
cell *array = get_amxaddr(amx, params[1]);
cell array_size = params[2];
cell type = params[3];
if (type == Sort_Ascending)
{
qsort(array, array_size, sizeof(cell), sort_ints_asc);
} else {
qsort(array, array_size, sizeof(cell), sort_ints_desc);
}
return 1;
}
int sort_floats_asc(const void *float1, const void *float2)
{
REAL r1 = *(REAL *)float1;
REAL r2 = *(REAL *)float2;
if (r1 < r2)
{
return -1;
} else if (r2 < r1) {
return 1;
} else {
return 0;
}
}
int sort_floats_desc(const void *float1, const void *float2)
{
REAL r1 = *(REAL *)float1;
REAL r2 = *(REAL *)float2;
if (r1 < r2)
{
return 1;
} else if (r2 < r1) {
return -1;
} else {
return 0;
}
}
static cell AMX_NATIVE_CALL SortFloats(AMX *amx, cell *params)
{
cell *array = get_amxaddr(amx, params[1]);
cell array_size = params[2];
cell type = params[3];
if (type == Sort_Ascending)
{
qsort(array, array_size, sizeof(cell), sort_floats_asc);
} else {
qsort(array, array_size, sizeof(cell), sort_floats_desc);
}
return 1;
}
static cell *g_CurStringArray = NULL;
static cell *g_CurRebaseMap = NULL;
int sort_strings_asc(const void *blk1, const void *blk2)
{
cell reloc1 = *(cell *)blk1;
cell reloc2 = *(cell *)blk2;
register cell *str1 = (cell *)((char *)(&g_CurStringArray[reloc1]) + g_CurRebaseMap[reloc1]);
register cell *str2 = (cell *)((char *)(&g_CurStringArray[reloc2]) + g_CurRebaseMap[reloc2]);
while (*str1 == *str2++)
{
if (*str1++ == 0)
{
return 0;
}
}
return (*str1 - *(str2 - 1));
}
int sort_strings_desc(const void *blk1, const void *blk2)
{
cell reloc1 = *(cell *)blk1;
cell reloc2 = *(cell *)blk2;
register cell *str1 = (cell *)((char *)(&g_CurStringArray[reloc1]) + g_CurRebaseMap[reloc1]);
register cell *str2 = (cell *)((char *)(&g_CurStringArray[reloc2]) + g_CurRebaseMap[reloc2]);
while (*str1 == *str2++)
{
if (*str1++ == 0)
{
return 0;
}
}
return (*(str2 - 1) - *str1);
}
static cell AMX_NATIVE_CALL SortStrings(AMX *amx, cell *params)
{
cell *array = get_amxaddr(amx, params[1]);
cell array_size = params[2];
cell type = params[3];
/** HACKHACK - back up the old indices, replace the indices with something easier */
cell amx_addr, *phys_addr;
int err;
if ((err=amx_Allot(amx, array_size, &amx_addr, &phys_addr)) != AMX_ERR_NONE)
{
LogError(amx, err, "Ran out of memory");
return 0;
}
g_CurStringArray = array;
g_CurRebaseMap = phys_addr;
for (int i=0; i<array_size; i++)
{
phys_addr[i] = array[i];
array[i] = i;
}
if (type == Sort_Ascending)
{
qsort(array, array_size, sizeof(cell), sort_strings_asc);
} else {
qsort(array, array_size, sizeof(cell), sort_strings_desc);
}
/* END HACKHACK - restore what we damaged so Pawn doesn't throw up.
* We'll browse through each index of the array and patch up the distance.
*/
for (int i=0; i<array_size; i++)
{
/* Compute the final address of the old array and subtract the new location.
* This is the fixed up distance.
*/
array[i] = ((char *)&array[array[i]] + phys_addr[array[i]]) - (char *)&array[i];
}
amx_Release(amx, amx_addr);
g_CurStringArray = NULL;
g_CurRebaseMap = NULL;
return 1;
}
struct sort_info
{
int pfn;
cell data_addr;
cell data_size;
cell array_addr;
cell *array_base;
cell *array_remap;
AMX *amx;
};
static CStack<sort_info *> g_AMXSortStack;
int sort1d_amx_custom(const void *elem1, const void *elem2)
{
cell c1 = *(cell *)elem1;
cell c2 = *(cell *)elem2;
sort_info *pInfo = g_AMXSortStack.front();
return executeForwards(pInfo->pfn, c1, c2, pInfo->array_addr, pInfo->data_addr, pInfo->data_size);
}
static cell AMX_NATIVE_CALL SortCustom1D(AMX *amx, cell *params)
{
cell *array = get_amxaddr(amx, params[1]);
cell array_size = params[2];
int len;
const char *funcname = get_amxstring(amx, params[3], 0, len);
int pfn = registerSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (pfn < 0)
{
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcname);
return 0;
}
sort_info *pInfo = new sort_info;
pInfo->pfn = pfn;
pInfo->data_addr = params[4];
pInfo->data_size = params[5];
pInfo->array_addr = params[1];
pInfo->array_remap = NULL;
pInfo->array_base = NULL;
g_AMXSortStack.push(pInfo);
qsort(array, array_size, sizeof(cell), sort1d_amx_custom);
g_AMXSortStack.pop();
unregisterSPForward(pfn);
delete pInfo;
return 1;
}
int sort2d_amx_custom(const void *elem1, const void *elem2)
{
cell c1 = *(cell *)elem1;
cell c2 = *(cell *)elem2;
sort_info *pInfo = g_AMXSortStack.front();
cell c1_addr = pInfo->array_addr + (c1 * sizeof(cell)) + pInfo->array_remap[c1];
cell c2_addr = pInfo->array_addr + (c2 * sizeof(cell)) + pInfo->array_remap[c2];
//cell *c1_r = get_amxaddr(pInfo->amx, c1_addr);
//cell *c2_r = get_amxaddr(pInfo->amx, c2_addr);
return executeForwards(pInfo->pfn, c1_addr, c2_addr, pInfo->array_addr, pInfo->data_addr, pInfo->data_size);
}
static cell AMX_NATIVE_CALL SortCustom2D(AMX *amx, cell *params)
{
cell *array = get_amxaddr(amx, params[1]);
cell array_size = params[2];
int len;
const char *funcname = get_amxstring(amx, params[3], 0, len);
/** back up the old indices, replace the indices with something easier */
cell amx_addr, *phys_addr;
int err;
if ((err=amx_Allot(amx, array_size, &amx_addr, &phys_addr)) != AMX_ERR_NONE)
{
LogError(amx, err, "Ran out of memory");
return 0;
}
int pfn = registerSPForwardByName(amx, funcname, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (pfn < 0)
{
amx_Release(amx, amx_addr);
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcname);
return 0;
}
sort_info *pInfo = new sort_info;
pInfo->pfn = pfn;
pInfo->data_addr = params[4];
pInfo->data_size = params[5];
pInfo->array_addr = params[1];
pInfo->amx = amx;
/** Same process as in strings, back up the old indices for later fixup */
pInfo->array_base = array;
pInfo->array_remap = phys_addr;
for (int i=0; i<array_size; i++)
{
phys_addr[i] = array[i];
array[i] = i;
}
g_AMXSortStack.push(pInfo);
qsort(array, array_size, sizeof(cell), sort2d_amx_custom);
g_AMXSortStack.pop();
/** Fixup process! */
for (int i=0; i<array_size; i++)
{
/* Compute the final address of the old array and subtract the new location.
* This is the fixed up distance.
*/
array[i] = ((char *)&array[array[i]] + phys_addr[array[i]]) - (char *)&array[i];
}
amx_Release(amx, amx_addr);
unregisterSPForward(pInfo->pfn);
delete pInfo;
return 1;
}
AMX_NATIVE_INFO g_SortNatives[] =
{
{"SortIntegers", SortIntegers},
{"SortFloats", SortFloats},
{"SortStrings", SortStrings},
{"SortCustom1D", SortCustom1D},
{"SortCustom2D", SortCustom2D},
{NULL, NULL},
};

View File

@ -39,7 +39,7 @@ void amx_command()
{ {
print_srvconsole("Currently loaded plugins:\n"); print_srvconsole("Currently loaded plugins:\n");
print_srvconsole(" %-23.22s %-11.10s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status"); print_srvconsole(" %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status");
int plugins = 0; int plugins = 0;
int running = 0; int running = 0;
@ -52,23 +52,18 @@ void amx_command()
if ((*a).isValid() && !(*a).isPaused()) if ((*a).isValid() && !(*a).isPaused())
++running; ++running;
print_srvconsole(" [%3d] %-23.22s %-11.10s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus()); print_srvconsole(" [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus());
++a; ++a;
} }
a = g_plugins.begin(); a = g_plugins.begin();
int num = 0;
while (a) while (a)
{ {
num++;
if ((*a).getStatusCode() == ps_bad_load) if ((*a).getStatusCode() == ps_bad_load)
{ {
//error //error
print_srvconsole("(%3d) Load fails: %s\n", num, (*a).getError()); print_srvconsole("Load fails: %s\n", (*a).getError());
} else if ( (*a).getStatusCode() == ps_error) {
//error
print_srvconsole("(%3d) Error: %s\n", num, (*a).getError());
} }
++a; ++a;
} }
@ -82,29 +77,13 @@ void amx_command()
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin); CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
if (plugin && plugin->isValid()) if (plugin && plugin->isValid())
{
if (plugin->isPaused())
{
if (plugin->isStopped())
{
print_srvconsole("Plugin \"%s\" is stopped and may not be paused.\n",plugin->getName());
}
else
{
print_srvconsole("Plugin \"%s\" is already paused.\n",plugin->getName());
}
}
else
{ {
plugin->pausePlugin(); plugin->pausePlugin();
print_srvconsole("Paused plugin \"%s\"\n", plugin->getName()); print_srvconsole("Paused plugin \"%s\"\n", plugin->getName());
} }
}
else else
{
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin); print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
} }
}
else if (!strcmp(cmd, "unpause") && CMD_ARGC() > 2) else if (!strcmp(cmd, "unpause") && CMD_ARGC() > 2)
{ {
const char* sPlugin = CMD_ARGV(2); const char* sPlugin = CMD_ARGV(2);
@ -112,22 +91,15 @@ void amx_command()
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin); CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
if (plugin && plugin->isValid() && plugin->isPaused()) if (plugin && plugin->isValid() && plugin->isPaused())
{
if (plugin->isStopped())
{
print_srvconsole("Plugin \"%s\" is stopped and may not be unpaused.\n", plugin->getName());
}
else
{ {
plugin->unpausePlugin(); plugin->unpausePlugin();
print_srvconsole("Unpaused plugin \"%s\"\n", plugin->getName()); print_srvconsole("Unpaused plugin \"%s\"\n", plugin->getName());
} }
}
else if (!plugin) else if (!plugin)
{ {
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin); print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
} else { } else {
print_srvconsole("Plugin %s can't be unpaused right now.\n", sPlugin); print_srvconsole("Plugin %s can't be unpaused right now.", sPlugin);
} }
} }
else if (!strcmp(cmd, "cvars")) else if (!strcmp(cmd, "cvars"))
@ -137,25 +109,10 @@ void amx_command()
int ammount = 0; int ammount = 0;
if (CMD_ARGC() > 2) // Searching for cvars registered to a plugin
{
const char* targetname = CMD_ARGV(2);
size_t len = strlen(targetname);
for (CList<CCVar>::iterator a = g_cvars.begin(); a; ++a)
{
if (strncmp((*a).getPluginName(), targetname, len) == 0)
{
print_srvconsole(" [%3d] %-24.23s %-24.23s %-16.15s\n", ++ammount, (*a).getName(), CVAR_GET_STRING((*a).getName()), (*a).getPluginName());
}
}
}
else // No search
{
for (CList<CCVar>::iterator a = g_cvars.begin(); a; ++a) for (CList<CCVar>::iterator a = g_cvars.begin(); a; ++a)
{ {
print_srvconsole(" [%3d] %-24.23s %-24.23s %-16.15s\n", ++ammount, (*a).getName(), CVAR_GET_STRING((*a).getName()), (*a).getPluginName()); print_srvconsole(" [%3d] %-24.23s %-24.23s %-16.15s\n", ++ammount, (*a).getName(), CVAR_GET_STRING((*a).getName()), (*a).getPluginName());
} }
}
print_srvconsole("%d cvars\n", ammount); print_srvconsole("%d cvars\n", ammount);
} }
@ -169,38 +126,19 @@ void amx_command()
CmdMngr::iterator a = g_commands.begin(CMD_ConsoleCommand); CmdMngr::iterator a = g_commands.begin(CMD_ConsoleCommand);
if (CMD_ARGC() > 2) // Searching for commands registered to a plugin
{
const char* targetname = CMD_ARGV(2);
size_t len = strlen(targetname);
while (a)
{
if (strncmp((*a).getPlugin()->getName(), targetname, len) == 0)
{
UTIL_GetFlags(access, (*a).getFlags());
print_srvconsole(" [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n", ++ammount, (*a).getCmdLine(), access, (*a).getCmdType(), (*a).getPlugin()->getName());
}
++a;
}
}
else // No search
{
while (a) while (a)
{ {
UTIL_GetFlags(access, (*a).getFlags()); UTIL_GetFlags(access, (*a).getFlags());
print_srvconsole(" [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n", ++ammount, (*a).getCmdLine(), access, (*a).getCmdType(), (*a).getPlugin()->getName()); print_srvconsole(" [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n", ++ammount, (*a).getCmdLine(), access, (*a).getCmdType(), (*a).getPlugin()->getName());
++a; ++a;
} }
}
print_srvconsole("%d commands\n",ammount); print_srvconsole("%d commands\n",ammount);
} }
else if (!strcmp(cmd, "version")) else if (!strcmp(cmd, "version"))
{ {
print_srvconsole("%s %s (%s)\n", Plugin_info.name, Plugin_info.version, Plugin_info.url); print_srvconsole("%s %s\n", Plugin_info.name, Plugin_info.version);
print_srvconsole("Authors:\n\tDavid \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko\n"); print_srvconsole("Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
print_srvconsole("\tFelix \"SniperBeamer\" Geyer, Jonny \"Got His Gun\" Bergstrom\n");
print_srvconsole("\tLukasz \"SidLuke\" Wlasinski, Christian \"Basic-Master\" Hammacher\n");
print_srvconsole("\tBorja \"faluco\" Ferrer, Scott \"Damaged Soul\" Ehlert\n");
print_srvconsole("Compiled: %s\n", __DATE__ ", " __TIME__); print_srvconsole("Compiled: %s\n", __DATE__ ", " __TIME__);
#if defined JIT && !defined ASM32 #if defined JIT && !defined ASM32
print_srvconsole("Core mode: JIT Only\n"); print_srvconsole("Core mode: JIT Only\n");
@ -215,7 +153,7 @@ void amx_command()
else if (!strcmp(cmd, "modules")) else if (!strcmp(cmd, "modules"))
{ {
print_srvconsole("Currently loaded modules:\n"); print_srvconsole("Currently loaded modules:\n");
print_srvconsole(" %-23.22s %-11.10s %-20.19s %-11.10s\n", "name", "version", "author", "status"); print_srvconsole(" %-23.22s %-8.7s %-20.19s %-11.10s\n", "name", "version", "author", "status");
int running = 0; int running = 0;
int modules = 0; int modules = 0;
@ -228,7 +166,7 @@ void amx_command()
++running; ++running;
++modules; ++modules;
print_srvconsole(" [%2d] %-23.22s %-11.10s %-20.19s %-11.10s\n", modules, (*a).getName(), (*a).getVersion(), (*a).getAuthor(), (*a).getStatus()); print_srvconsole(" [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules, (*a).getName(), (*a).getVersion(), (*a).getAuthor(), (*a).getStatus());
++a; ++a;
} }
@ -298,8 +236,8 @@ void amx_command()
print_srvconsole(" gpl - print the license\n"); print_srvconsole(" gpl - print the license\n");
print_srvconsole(" plugins - list plugins currently loaded\n"); print_srvconsole(" plugins - list plugins currently loaded\n");
print_srvconsole(" modules - list modules currently loaded\n"); print_srvconsole(" modules - list modules currently loaded\n");
print_srvconsole(" cvars [ plugin ] - list cvars registered by plugins\n"); print_srvconsole(" cvars - list cvars registered by plugins\n");
print_srvconsole(" cmds [ plugin ] - list commands registered by plugins\n"); print_srvconsole(" cmds - list commands registered by plugins\n");
print_srvconsole(" pause < plugin > - pause a running plugin\n"); print_srvconsole(" pause < plugin > - pause a running plugin\n");
print_srvconsole(" unpause < plugin > - unpause a previously paused plugin\n"); print_srvconsole(" unpause < plugin > - unpause a previously paused plugin\n");
} }
@ -307,6 +245,7 @@ void amx_command()
void plugin_srvcmd() void plugin_srvcmd()
{ {
cell ret = 0;
const char* cmd = CMD_ARGV(0); const char* cmd = CMD_ARGV(0);
CmdMngr::iterator a = g_commands.srvcmdbegin(); CmdMngr::iterator a = g_commands.srvcmdbegin();
@ -315,8 +254,7 @@ void plugin_srvcmd()
{ {
if ((*a).matchCommand(cmd) && (*a).getPlugin()->isExecutable((*a).getFunction())) if ((*a).matchCommand(cmd) && (*a).getPlugin()->isExecutable((*a).getFunction()))
{ {
cell ret = executeForwards((*a).getFunction(), static_cast<cell>(g_srvindex), cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
static_cast<cell>((*a).getFlags()), static_cast<cell>((*a).getId()));
if (ret) break; if (ret) break;
} }
++a; ++a;

View File

@ -31,9 +31,6 @@
#include <ctype.h> #include <ctype.h>
#include "amxmodx.h" #include "amxmodx.h"
#include "format.h"
#include "binlog.h"
#include "amxmod_compat.h"
const char* stristr(const char* str, const char* substr) const char* stristr(const char* str, const char* substr)
{ {
@ -59,18 +56,7 @@ const char* stristr(const char* str, const char* substr)
char* format_amxstring(AMX *amx, cell *params, int parm, int& len) char* format_amxstring(AMX *amx, cell *params, int parm, int& len)
{ {
#if !defined BINLOG_ENABLED
return g_langMngr.FormatAmxString(amx, params, parm, len); return g_langMngr.FormatAmxString(amx, params, parm, len);
#else
char *ans = g_langMngr.FormatAmxString(amx, params, parm, len);
if (g_binlog_level & 4)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_FormatString, pl->getId(), parm, len, ans);
}
return ans;
#endif
} }
int amxstring_len(cell* a) int amxstring_len(cell* a)
@ -90,17 +76,8 @@ cell* get_amxaddr(AMX *amx, cell amx_addr)
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max) int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
{ {
register cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr)); cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register cell* start = dest; cell* start = dest;
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_SetString, pl->getId(), amx_addr, max, source);
}
#endif
while (max-- && *source) while (max-- && *source)
*dest++ = (cell)*source++; *dest++ = (cell)*source++;
@ -110,42 +87,6 @@ int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
return dest - start; return dest - start;
} }
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen)
{
register cell *source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register char *dest = destination;
char *start = dest;
if ( (amx->flags & AMX_FLAG_OLDFILE) &&
(*source & BCOMPAT_TRANSLATE_BITS) )
{
const char *def, *key;
if (!translate_bcompat(amx, source, &key, &def))
{
goto normal_string;
}
while (maxlen-- && *def)
*dest++=(*source++);
} else {
normal_string:
while (maxlen-- && *source)
*dest++=(char)(*source++);
}
*dest = '\0';
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, destination);
}
#endif
return dest - start;
}
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len) char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
{ {
static char buffor[4][3072]; static char buffor[4][3072];
@ -153,31 +94,9 @@ char *get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
register char* dest = buffor[id]; register char* dest = buffor[id];
char* start = dest; char* start = dest;
if ( (amx->flags & AMX_FLAG_OLDFILE) &&
(*source & BCOMPAT_TRANSLATE_BITS) )
{
const char *def, *key;
if (!translate_bcompat(amx, source, &key, &def))
{
goto normal_string;
}
while ( (*dest++ = (*def++)) );
len = --dest - start;
} else {
normal_string:
while ((*dest++=(char)(*source++))); while ((*dest++=(char)(*source++)));
len = --dest - start; len = --dest - start;
}
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, start);
}
#endif
return start; return start;
} }
@ -227,61 +146,62 @@ char* parse_arg(char** line, int& state)
return arg; return arg;
} }
bool fastcellcmp(cell *a, cell *b, cell len)
{
while (len--)
{
if (*a++ != *b++)
return false;
}
return true;
}
static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */ static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
{ {
cell *text = get_amxaddr(amx, params[1]); static char buffor[3072];
cell len = params[2];
cell *what = get_amxaddr(amx, params[3]);
cell *with = get_amxaddr(amx, params[4]);
cell *textptr = text;
int withLen = amxstring_len(with); cell *a = get_amxaddr(amx, params[1]);
int whatLen = amxstring_len(what); cell *b = get_amxaddr(amx, params[3]);
int textLen = amxstring_len(text); cell *c = get_amxaddr(amx, params[4]);
if (whatLen > textLen) int iMain = amxstring_len(a);
return 0; int iWhat = amxstring_len(b);
int iWith = amxstring_len(c);
int iPot = iMain + iWith - iWhat;
if (whatLen < 1) if (iPot >= params[2])
{ {
LogError(amx, AMX_ERR_NATIVE, "No search string specified."); amx_RaiseError(amx,AMX_ERR_NATIVE);
return 0; return 0;
} }
if (textLen - whatLen + withLen > len) char *d = buffor;
cell *x, *y, *z = a, *l = a;
int p = 0;
while (*a)
{ {
LogError(amx, AMX_ERR_NATIVE, "replace() buffer not big enough (%d>=%d)", (textLen - whatLen + withLen), len); if (*a == *b)
return 0; {
x = a + 1;
y = b + 1;
p = 1;
if (!*y) break;
while (*x == *y)
{
x++; y++; p++;
if (!*y) break;
} }
cell browsed = 0; if (!*y) break;
while (*text && (browsed <= (textLen-whatLen))) p = 0;
{ *d++ = (char)*a++;
if (*text == *what) continue;
{
if (fastcellcmp(text, what, whatLen))
{
cell *saveptr = text + whatLen;
cell restlen = textLen - (browsed + whatLen);
textptr = text + withLen;
memmove(textptr, saveptr, (restlen + 1) * sizeof(cell));
memcpy(text, with, withLen * sizeof(cell));
return (textLen - whatLen + withLen);
} }
*d++ = (char)*a++;
} }
text++;
browsed++; if (p)
{
while (*c) *d++ = (char)*c++;
a += p;
while (*a) *d++ = (char)*a++;
*d = 0;
d = buffor;
while (*d) *z++ = *d++;
*z = 0;
return (z - l);
} }
return 0; return 0;
@ -443,43 +363,16 @@ static cell AMX_NATIVE_CALL add(AMX *amx, cell *params) /* 4 param */
static cell AMX_NATIVE_CALL copy(AMX *amx, cell *params) /* 4 param */ static cell AMX_NATIVE_CALL copy(AMX *amx, cell *params) /* 4 param */
{ {
cell *src = get_amxaddr(amx, params[3]); cell *src = get_amxaddr(amx, params[3]);
cell *dest = get_amxaddr(amx, params[1]);
cell *start = dest;
int c = params[2]; int c = params[2];
if (amx->flags & AMX_FLAG_OLDFILE)
{
if (*src & BCOMPAT_TRANSLATE_BITS)
{
const char *key, *def;
if (!translate_bcompat(amx, src, &key, &def))
{
goto normal_string;
}
cell *dest = get_amxaddr(amx, params[1]);
cell *start = dest;
while (c-- && *def)
{
*dest++ = static_cast<cell>(*def++);
}
*dest = '\0';
return dest-start;
} else {
goto normal_string;
}
} else {
normal_string:
cell *dest = get_amxaddr(amx, params[1]);
cell *start = dest;
while (c-- && *src) while (c-- && *src)
{
*dest++ =* src++; *dest++ =* src++;
} *dest = 0;
*dest = '\0';
return (dest - start); return (dest - start);
} }
}
static cell AMX_NATIVE_CALL copyc(AMX *amx, cell *params) /* 4 param */ static cell AMX_NATIVE_CALL copyc(AMX *amx, cell *params) /* 4 param */
{ {
@ -555,73 +448,10 @@ static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params) /* 3 param */
return (f - l) ? 0 : 1; return (f - l) ? 0 : 1;
} }
static cell g_cpbuf[4096];
static cell AMX_NATIVE_CALL formatex(AMX *amx, cell *params)
{
cell *buf = get_amxaddr(amx, params[1]);
size_t maxlen = static_cast<size_t>(params[2]);
cell *fmt = get_amxaddr(amx, params[3]);
int param = 4;
size_t total = atcprintf(buf, maxlen, fmt, amx, params, &param);
return static_cast<cell>(total);
}
static cell AMX_NATIVE_CALL format(AMX *amx, cell *params) /* 3 param */ static cell AMX_NATIVE_CALL format(AMX *amx, cell *params) /* 3 param */
{ {
cell *buf = get_amxaddr(amx, params[1]); int len;
cell *fmt = get_amxaddr(amx, params[3]); return set_amxstring(amx, params[1], format_amxstring(amx, params, 3, len), params[2]);
size_t maxlen = params[2];
/**
* SPECIAL CASE - check if the buffers overlap.
* some users, for whatever reason, do things like:
* format(buf, 255, buf....
* this is considered "deprecated" but we have to support it.
* we do this by checking to see if reading from buf will overlap
*/
cell addr_start = params[1];
cell addr_end = params[1] + maxlen * sizeof(cell);
cell max = params[0] / sizeof(cell);
bool copy = false;
for (cell i = 3; i <= max; i++)
{
//does this clip the bounds?!?!? WELL, DOES IT!?!?! i am a loud dog
if (params[i] >= addr_start && params[i] <= addr_end)
{
copy = true;
break;
}
}
if (copy)
buf = g_cpbuf;
int param = 4;
size_t total = 0;
if (amx->flags & AMX_FLAG_OLDFILE)
{
if (*fmt & BCOMPAT_TRANSLATE_BITS)
{
const char *key, *def;
if (!translate_bcompat(amx, fmt, &key, &def))
{
goto normal_string;
}
total = atcprintf(buf, maxlen, def, amx, params, &param);
} else {
goto normal_string;
}
} else {
normal_string:
total = atcprintf(buf, maxlen, fmt, amx, params, &param);
}
if (copy)
{
/* copy back */
cell *old = get_amxaddr(amx, params[1]);
memcpy(old, g_cpbuf, (total+1) * sizeof(cell));
}
return total;
} }
static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */ static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */
@ -834,66 +664,73 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
//strbreak(String[], First[], FirstLen, Rest[], RestLen) //strbreak(String[], First[], FirstLen, Rest[], RestLen)
static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */ static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
{ {
int _len; bool quote_flag = false;
bool in_quote = false; bool done_flag = false;
bool had_quotes = false; int left_pos = 0;
size_t i = 0; int right_pos = 0;
size_t beg = 0; int l = 0;
unsigned int i = 0;
char hold = '"';
char *string = get_amxstring(amx, params[1], 0, _len); char *string = get_amxstring(amx, params[1], 0, l);
cell *left = get_amxaddr(amx, params[2]); char *left = new char[strlen(string) + 1];
cell *right = get_amxaddr(amx, params[4]); char *right = new char[strlen(string) + 1];
int LeftMax = params[3]; int LeftMax = params[3];
int RightMax = params[5]; int RightMax = params[5];
size_t len = (size_t)_len; for (i = 0; i < (unsigned int)l; i++)
{
if (string[i] == '"' && !quote_flag)
{
quote_flag = true;
}
else if (string[i] == '"' && quote_flag)
{
quote_flag = false;
}
while (isspace(string[i]) && i<len) if (isspace(string[i]) && !quote_flag && !done_flag)
{
done_flag = true;
i++; i++;
beg = i; }
for (; i<len; i++)
if (!done_flag && string[i]!='"')
{ {
if (string[i] == '"' && !in_quote) if (left_pos < LeftMax)
{ {
in_quote = (had_quotes = true); left[left_pos] = string[i];
} else if (string[i] == '"' && in_quote) {
in_quote = false; if (left[left_pos] == '\'')
if (i == len-1) {
goto do_copy; left[left_pos] = hold;
}
left_pos++;
} else { } else {
if (isspace(string[i]) && !in_quote) done_flag = true;
{
do_copy:
size_t pos = i;
while (isspace(string[i]))
i++;
const char *start = had_quotes ? &(string[beg+1]) : &(string[beg]);
size_t _end = had_quotes ? (i==len-1 ? 1 : 2) : 0;
size_t end = (pos - _end > (size_t)LeftMax) ? (size_t)LeftMax : pos - _end;
size_t to_go = end-beg;
if (end && to_go)
{
while (to_go--)
*left++ = (cell)*start++;
} }
*left = '\0'; } else {
end = (len-i+1 > (size_t)RightMax) ? (size_t)RightMax : len-i+1; if (right_pos < RightMax && string[i]!='"')
if (end)
{ {
start = &(string[i]); right[right_pos] = string[i];
while (end--)
*right++ = (cell)*start++; if (right[right_pos] == '\'')
{
right[right_pos] = hold;
} }
*right = '\0';
return 1; right_pos++;
} }
} }
} }
//if we got here, there was nothing to break left[left_pos] = '\0';
set_amxstring(amx, params[2], &(string[beg]), LeftMax); right[right_pos] = '\0';
if (RightMax) set_amxstring(amx, params[2], left, params[3]);
*right = '\0'; set_amxstring(amx, params[4], right, params[5]);
delete [] left;
delete [] right;
return 1; return 1;
} }
@ -905,7 +742,7 @@ static cell AMX_NATIVE_CALL format_args(AMX *amx, cell *params)
if (pos < 0) if (pos < 0)
{ {
LogError(amx, AMX_ERR_NATIVE, "Pos has to be a positive number"); amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
@ -936,6 +773,7 @@ static cell AMX_NATIVE_CALL is_alpha(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_ucfirst(AMX *amx, cell *params)
{ {
int len = 0;
cell *str = get_amxaddr(amx, params[1]); cell *str = get_amxaddr(amx, params[1]);
if (!isalpha((char)str[0]) || !(str[0] & (1<<5))) if (!isalpha((char)str[0]) || !(str[0] & (1<<5)))
@ -1003,7 +841,7 @@ static cell AMX_NATIVE_CALL n_strcmp(AMX *amx, cell *params)
char *str1 = get_amxstring(amx, params[1], 0, len); char *str1 = get_amxstring(amx, params[1], 0, len);
char *str2 = get_amxstring(amx, params[2], 1, len); char *str2 = get_amxstring(amx, params[2], 1, len);
if (params[3]) if (params[1])
return stricmp(str1, str2); return stricmp(str1, str2);
else else
return strcmp(str1, str2); return strcmp(str1, str2);
@ -1016,6 +854,7 @@ static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
int sublen; int sublen;
char *sub = get_amxstring(amx, params[2], 1, sublen); char *sub = get_amxstring(amx, params[2], 1, sublen);
bool found = false;
bool igcase = params[3] ? true : false; bool igcase = params[3] ? true : false;
if (igcase) if (igcase)
@ -1035,6 +874,7 @@ static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
if (params[4] > len) if (params[4] > len)
return -1; return -1;
char *pos = &(str[params[4]]);
char *find = strstr(str, sub); char *find = strstr(str, sub);
if (!find) if (!find)
@ -1043,67 +883,6 @@ static cell AMX_NATIVE_CALL n_strfind(AMX *amx, cell *params)
return (find - str); return (find - str);
} }
static cell AMX_NATIVE_CALL vformat(AMX *amx, cell *params)
{
int vargPos = static_cast<int>(params[4]);
/** get the parent parameter array */
AMX_HEADER *hdr = (AMX_HEADER *)amx->base;
cell *local_params = (cell *)(
(char *)amx->base + (cell)hdr->dat +
(cell)amx->frm + (2 * sizeof(cell))
);
cell max = local_params[0] / sizeof(cell);
if (vargPos > (int)max + 1)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
return 0;
}
/**
* check for bounds clipping
*/
cell addr_start = params[1];
cell addr_end = addr_start + params[2];
bool copy = false;
for (int i = vargPos; i <= max; i++)
{
//does this clip the bounds?
if ( (local_params[i] >= addr_start)
&& (local_params[i] <= addr_end) )
{
copy = true;
break;
}
}
/* get destination info */
cell *fmt = get_amxaddr(amx, params[3]);
cell *realdest = get_amxaddr(amx, params[1]);
size_t maxlen = static_cast<size_t>(params[2]);
cell *dest = realdest;
/* if this is necessary... */
static cell cpbuf[4096];
if (copy)
dest = cpbuf;
/* perform format */
size_t total = atcprintf(dest, maxlen, fmt, amx, local_params, &vargPos);
/* copy back */
if (copy)
{
memcpy(realdest, dest, (total+1) * sizeof(cell));
}
return total;
}
AMX_NATIVE_INFO string_Natives[] = AMX_NATIVE_INFO string_Natives[] =
{ {
{"add", add}, {"add", add},
@ -1114,7 +893,6 @@ AMX_NATIVE_INFO string_Natives[] =
{"equal", equal}, {"equal", equal},
{"equali", equali}, {"equali", equali},
{"format", format}, {"format", format},
{"formatex", formatex},
{"format_args", format_args}, {"format_args", format_args},
{"isdigit", is_digit}, {"isdigit", is_digit},
{"isalnum", is_alnum}, {"isalnum", is_alnum},
@ -1139,6 +917,5 @@ AMX_NATIVE_INFO string_Natives[] =
{"strcmp", n_strcmp}, {"strcmp", n_strcmp},
{"str_to_float", str_to_float}, {"str_to_float", str_to_float},
{"float_to_str", float_to_str}, {"float_to_str", float_to_str},
{"vformat", vformat},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -14,16 +14,6 @@
#define strnicmp strncasecmp #define strnicmp strncasecmp
#endif #endif
#if _MSC_VER
#if _MSC_VER >= 1400
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
#define stricmp _stricmp
// Need this because of some stupid bug
#pragma warning (disable : 4996)
#endif
#endif
// this file does not include amxmodx.h, so we have to include the memory manager here // this file does not include amxmodx.h, so we have to include the memory manager here
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
#include "mmgr/mmgr.h" #include "mmgr/mmgr.h"

View File

@ -1,8 +0,0 @@
#ifndef _INCLUDE_SVN_VERSION_H_
#define _INCLUDE_SVN_VERSION_H_
#define SVN_VERSION_STRING "1.8.0.3660"
#define SVN_VERSION_DWORD 1,8,0,3660
#define SVN_VERSION_PRODUCT "1.8.0"
#endif //_INCLUDE_SVN_VERSION_H_

View File

@ -1,8 +0,0 @@
#ifndef _INCLUDE_SVN_VERSION_H_
#define _INCLUDE_SVN_VERSION_H_
#define SVN_VERSION_STRING "$PMAJOR$.$PMINOR$.$PREVISION$.$GLOBAL_BUILD$"
#define SVN_VERSION_DWORD $PMAJOR$,$PMINOR$,$PREVISION$,$GLOBAL_BUILD$
#define SVN_VERSION_PRODUCT "$PMAJOR$.$PMINOR$.$PREVISION$"
#endif //_INCLUDE_SVN_VERSION_H_

View File

@ -32,7 +32,7 @@
#include <time.h> #include <time.h>
#include "amxmodx.h" #include "amxmodx.h"
#if defined __linux__ && !defined _vsnprintf #ifdef __linux__
#define _vsnprintf vsnprintf #define _vsnprintf vsnprintf
#endif #endif
@ -347,4 +347,3 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
// unset the global "fake" flag // unset the global "fake" flag
g_fakecmd.fake = false; g_fakecmd.fake = false;
} }

View File

@ -1,205 +0,0 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "amxmodx.h"
#define ANGLEVECTORS_FORWARD 1
#define ANGLEVECTORS_RIGHT 2
#define ANGLEVECTORS_UP 3
static cell AMX_NATIVE_CALL get_distance(AMX *amx, cell *params)
{
cell *cpVec1 = get_amxaddr(amx, params[1]);
cell *cpVec2 = get_amxaddr(amx, params[2]);
Vector vec1 = Vector((float)cpVec1[0], (float)cpVec1[1], (float)cpVec1[2]);
Vector vec2 = Vector((float)cpVec2[0], (float)cpVec2[1], (float)cpVec2[2]);
int iDist = (int)((vec1 - vec2).Length());
return iDist;
}
static cell AMX_NATIVE_CALL get_distance_f(AMX *amx, cell *params)
{
cell *cpVec1 = get_amxaddr(amx, params[1]);
cell *cpVec2 = get_amxaddr(amx, params[2]);
Vector vec1 = Vector((float)amx_ctof(cpVec1[0]), (float)amx_ctof(cpVec1[1]), (float)amx_ctof(cpVec1[2]));
Vector vec2 = Vector((float)amx_ctof(cpVec2[0]), (float)amx_ctof(cpVec2[1]), (float)amx_ctof(cpVec2[2]));
REAL fDist = (REAL) (vec1 - vec2).Length();
return amx_ftoc(fDist);
}
static cell AMX_NATIVE_CALL VelocityByAim(AMX *amx, cell *params)
{
int iEnt = params[1];
int iVelocity = params[2];
cell *vRet = get_amxaddr(amx, params[3]);
Vector vVector = Vector(0, 0, 0);
edict_t *pEnt = NULL;
if (iEnt < 0 || iEnt > gpGlobals->maxEntities)
{
LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", iEnt);
return 0;
}
else
{
if (iEnt > 0 && iEnt <= gpGlobals->maxClients)
{
if (!GET_PLAYER_POINTER_I(iEnt)->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not ingame)", iEnt);
return 0;
}
pEnt = GET_PLAYER_POINTER_I(iEnt)->pEdict;
} else {
pEnt = INDEXENT(iEnt);
}
}
if (!pEnt)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d (nullent)", iEnt);
return 0;
}
MAKE_VECTORS(pEnt->v.v_angle);
vVector = gpGlobals->v_forward * iVelocity;
vRet[0] = FloatToCell(vVector.x);
vRet[1] = FloatToCell(vVector.y);
vRet[2] = FloatToCell(vVector.z);
return 1;
}
static cell AMX_NATIVE_CALL vector_to_angle(AMX *amx, cell *params)
{
cell *cAddr = get_amxaddr(amx, params[1]);
REAL fX = amx_ctof(cAddr[0]);
REAL fY = amx_ctof(cAddr[1]);
REAL fZ = amx_ctof(cAddr[2]);
Vector vVector = Vector(fX, fY, fZ);
Vector vAngle = Vector(0, 0, 0);
VEC_TO_ANGLES(vVector, vAngle);
cell *vRet = get_amxaddr(amx, params[2]);
vRet[0] = FloatToCell(vAngle.x);
vRet[1] = FloatToCell(vAngle.y);
vRet[2] = FloatToCell(vAngle.z);
return 1;
}
static cell AMX_NATIVE_CALL angle_vector(AMX *amx, cell *params)
{
Vector v_angles, v_forward, v_right, v_up, v_return;
cell *vCell = get_amxaddr(amx, params[1]);
v_angles.x = amx_ctof(vCell[0]);
v_angles.y = amx_ctof(vCell[1]);
v_angles.z = amx_ctof(vCell[2]);
g_engfuncs.pfnAngleVectors(v_angles, v_forward, v_right, v_up);
switch (params[2])
{
case ANGLEVECTORS_FORWARD:
v_return = v_forward;
break;
case ANGLEVECTORS_RIGHT:
v_return = v_right;
break;
case ANGLEVECTORS_UP:
v_return = v_up;
break;
}
vCell = get_amxaddr(amx, params[3]);
vCell[0] = FloatToCell(v_return.x);
vCell[1] = FloatToCell(v_return.y);
vCell[2] = FloatToCell(v_return.z);
return 1;
}
static cell AMX_NATIVE_CALL vector_length(AMX *amx, cell *params)
{
cell *cAddr = get_amxaddr(amx, params[1]);
REAL fX = amx_ctof(cAddr[0]);
REAL fY = amx_ctof(cAddr[1]);
REAL fZ = amx_ctof(cAddr[2]);
Vector vVector = Vector(fX, fY, fZ);
REAL fLength = vVector.Length();
return amx_ftoc(fLength);
}
static cell AMX_NATIVE_CALL vector_distance(AMX *amx, cell *params)
{
cell *cAddr = get_amxaddr(amx, params[1]);
cell *cAddr2 = get_amxaddr(amx, params[2]);
REAL fX = amx_ctof(cAddr[0]);
REAL fY = amx_ctof(cAddr[1]);
REAL fZ = amx_ctof(cAddr[2]);
REAL fX2 = amx_ctof(cAddr2[0]);
REAL fY2 = amx_ctof(cAddr2[1]);
REAL fZ2 = amx_ctof(cAddr2[2]);
Vector vVector = Vector(fX, fY, fZ);
Vector vVector2 = Vector(fX2, fY2, fZ2);
REAL fLength = (vVector - vVector2).Length();
return amx_ftoc(fLength);
}
AMX_NATIVE_INFO vector_Natives[] = {
{"get_distance", get_distance},
{"get_distance_f", get_distance_f},
{"velocity_by_aim", VelocityByAim},
{"vector_to_angle", vector_to_angle},
{"angle_vector", angle_vector},
{"vector_length", vector_length},
{"vector_distance", vector_distance},
{NULL, NULL},
};

View File

@ -1,12 +1,13 @@
// Microsoft Visual C++ generated resource script. // Microsoft Visual C++ generated resource script.
// //
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS #define APSTUDIO_READONLY_SYMBOLS
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Generated from the TEXTINCLUDE 2 resource. // Generated from the TEXTINCLUDE 2 resource.
// //
#include "winres.h" #include "winres.h"
#include "svn_version.h"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS #undef APSTUDIO_READONLY_SYMBOLS
@ -26,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION SVN_VERSION_DWORD FILEVERSION 1,6,0,0
PRODUCTVERSION SVN_VERSION_DWORD PRODUCTVERSION 1,6,0,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -44,12 +45,12 @@ BEGIN
BEGIN BEGIN
VALUE "Comments", "AMX Mod X" VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X" VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", SVN_VERSION_STRING VALUE "FileVersion", "1.60"
VALUE "InternalName", "amxmodx" VALUE "InternalName", "amxmodx"
VALUE "LegalCopyright", "Copyright (c) 2004-2007, AMX Mod X Dev Team" VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
VALUE "OriginalFilename", "amxmodx_mm.dll" VALUE "OriginalFilename", "amxmodx_mm.dll"
VALUE "ProductName", "AMX Mod X" VALUE "ProductName", "AMX Mod X"
VALUE "ProductVersion", SVN_VERSION_PRODUCT VALUE "ProductVersion", "1.60"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -3,9 +3,9 @@
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -funroll-loops -s -pipe -fno-strict-aliasing OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc-4.1 CPP = gcc
BINARY = amxxpc BINARY = amxxpc
OBJECTS = amx.cpp amxxpc.cpp Binary.cpp OBJECTS = amx.cpp amxxpc.cpp Binary.cpp

View File

@ -62,7 +62,7 @@ int main(int argc, char **argv)
} }
pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING); pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING);
pc_printf("Copyright (c) 1997-2006 ITB CompuPhase, AMX Mod X Team\n\n"); pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n");
if (argc < 2) if (argc < 2)
{ {

View File

@ -1,7 +1,9 @@
#ifndef _AMXXSC_INCLUDE_H #ifndef _AMXXSC_INCLUDE_H
#define _AMXXSC_INCLUDE_H #define _AMXXSC_INCLUDE_H
#define VERSION_STRING "1.76-300" #define VERSION_STRING "1.60-300"
#define VERSION 03000
#define MAGIC_HEADER 0x414D5842
#define MAGIC_HEADER2 0x414D5858 #define MAGIC_HEADER2 0x414D5858
#define MAGIC_VERSION 0x0300 #define MAGIC_VERSION 0x0300

Binary file not shown.

View File

@ -3,14 +3,13 @@
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -funroll-loops -s -pipe -fno-strict-aliasing -fvisibility=hidden OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc-4.1 CPP = gcc
NAME = amxxpc NAME = amxxpc
OBJECTS = sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c scvars.c scmemfil.c \ OBJECTS = sc1.c sc2.c sc3.c sc4.c sc5.c sc6.c sc7.c scvars.c scmemfil.c \
scstate.c sclist.c sci18n.c scexpand.c pawncc.c libpawnc.c prefix.c \ scstate.c sclist.c sci18n.c scexpand.c pawncc.c libpawnc.c prefix.c
memfile.c
LINK = -lpthread LINK = -lpthread

Some files were not shown because too many files have changed in this diff Show More