More AMTL conversion - 🔥 CString and CVector
This commit is contained in:
		@@ -41,7 +41,6 @@ if builder.target_platform == 'mac':
 | 
			
		||||
 | 
			
		||||
binary.sources = [
 | 
			
		||||
  'meta_api.cpp',
 | 
			
		||||
  'CFile.cpp',
 | 
			
		||||
  'CVault.cpp',
 | 
			
		||||
  'vault.cpp',
 | 
			
		||||
  'float.cpp',
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,8 @@ CmdMngr::Command::Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const
 | 
			
		||||
	char szCmd[64], szArg[64];
 | 
			
		||||
	*szCmd = 0; *szArg = 0;
 | 
			
		||||
	sscanf(pcmd, "%s %s", szCmd, szArg);
 | 
			
		||||
	command.assign(szCmd);
 | 
			
		||||
	argument.assign(szArg);
 | 
			
		||||
	command = szCmd;
 | 
			
		||||
	argument = szArg;
 | 
			
		||||
	plugin = pplugin;
 | 
			
		||||
	flags = pflags;
 | 
			
		||||
	cmdtype = 0;
 | 
			
		||||
@@ -200,7 +200,7 @@ bool CmdMngr::registerCmdPrefix(Command* cc)
 | 
			
		||||
	if (*b)
 | 
			
		||||
	{
 | 
			
		||||
		setCmdLink(&(*b)->list, cc, false);
 | 
			
		||||
		cc->prefix = (*b)->name.size();
 | 
			
		||||
		cc->prefix = (*b)->name.length();
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -222,7 +222,7 @@ CmdMngr::CmdPrefix** CmdMngr::findPrefix(const char* nn)
 | 
			
		||||
	
 | 
			
		||||
	while (*aa)
 | 
			
		||||
	{
 | 
			
		||||
		if (!strncmp((*aa)->name.c_str(), nn, (*aa)->name.size()))
 | 
			
		||||
		if (!strncmp((*aa)->name.chars(), nn, (*aa)->name.length()))
 | 
			
		||||
			break;
 | 
			
		||||
		aa = &(*aa)->next;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,10 +33,10 @@ public:
 | 
			
		||||
		
 | 
			
		||||
		CPluginMngr::CPlugin* plugin;
 | 
			
		||||
		CmdMngr* parent;
 | 
			
		||||
		String command;
 | 
			
		||||
		String argument;
 | 
			
		||||
		String commandline;
 | 
			
		||||
		String info;
 | 
			
		||||
		ke::AString command;
 | 
			
		||||
		ke::AString argument;
 | 
			
		||||
		ke::AString commandline;
 | 
			
		||||
		ke::AString info;
 | 
			
		||||
		
 | 
			
		||||
		bool listable;
 | 
			
		||||
		int function;
 | 
			
		||||
@@ -49,12 +49,12 @@ public:
 | 
			
		||||
		Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags, int pfunc, bool pviewable, CmdMngr* pparent);
 | 
			
		||||
		~Command();
 | 
			
		||||
	public:
 | 
			
		||||
		inline const char* getCommand() { return command.c_str(); }
 | 
			
		||||
		inline const char* getArgument() { return argument.c_str(); }
 | 
			
		||||
		inline const char* getCmdInfo() { return info.c_str(); }
 | 
			
		||||
		inline const char* getCmdLine() { return commandline.c_str(); }
 | 
			
		||||
		inline bool matchCommandLine(const char* cmd, const char* arg) 	{ return (!stricmp(command.c_str() + prefix, cmd + prefix) && (argument.empty() || !stricmp(argument.c_str(), arg))); }
 | 
			
		||||
		inline bool matchCommand(const char* cmd) {	return (!stricmp(command.c_str(), cmd)); }
 | 
			
		||||
		inline const char* getCommand() { return command.chars(); }
 | 
			
		||||
		inline const char* getArgument() { return argument.chars(); }
 | 
			
		||||
		inline const char* getCmdInfo() { return info.chars(); }
 | 
			
		||||
		inline const char* getCmdLine() { return commandline.chars(); }
 | 
			
		||||
		inline bool matchCommandLine(const char* cmd, const char* arg) 	{return (!stricmp(command.chars() + prefix, cmd + prefix) && (!argument.length() || !stricmp(argument.chars(), arg)));}
 | 
			
		||||
		inline bool matchCommand(const char* cmd) {	return (!stricmp(command.chars(), cmd)); }
 | 
			
		||||
		inline int getFunction() const { return function; }
 | 
			
		||||
		inline bool gotAccess(int f) const { return (!flags || ((flags & f) != 0)); }
 | 
			
		||||
		inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
 | 
			
		||||
@@ -83,7 +83,7 @@ private:
 | 
			
		||||
 | 
			
		||||
	struct CmdPrefix
 | 
			
		||||
	{
 | 
			
		||||
		String name;
 | 
			
		||||
		ke::AString name;
 | 
			
		||||
		CmdMngr* parent;
 | 
			
		||||
		CmdLink* list;
 | 
			
		||||
		CmdPrefix* next;
 | 
			
		||||
 
 | 
			
		||||
@@ -169,7 +169,7 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
 | 
			
		||||
	tmpCond->paramId = atoi(filter);
 | 
			
		||||
 | 
			
		||||
	// rest of line
 | 
			
		||||
	tmpCond->sValue.assign(value);
 | 
			
		||||
	tmpCond->sValue = value;
 | 
			
		||||
	tmpCond->fValue = static_cast<float>(atof(value));
 | 
			
		||||
	tmpCond->iValue = atoi(value);
 | 
			
		||||
	
 | 
			
		||||
@@ -388,9 +388,9 @@ void EventsMngr::parseValue(const char *sz)
 | 
			
		||||
				anyConditions = true;
 | 
			
		||||
				switch (condIter->type)
 | 
			
		||||
				{
 | 
			
		||||
					case '=': if (!strcmp(sz, condIter->sValue.c_str())) execute = true; break;
 | 
			
		||||
					case '!': if (strcmp(sz, condIter->sValue.c_str())) execute = true; break;
 | 
			
		||||
					case '&': if (strstr(sz, condIter->sValue.c_str())) execute = true; break;
 | 
			
		||||
					case '=': if (!strcmp(sz, condIter->sValue.chars())) execute = true; break;
 | 
			
		||||
					case '!': if (strcmp(sz, condIter->sValue.chars())) execute = true; break;
 | 
			
		||||
					case '&': if (strstr(sz, condIter->sValue.chars())) execute = true; break;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				if (execute)
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ public:
 | 
			
		||||
		{
 | 
			
		||||
			int paramId;				// the message parameter id
 | 
			
		||||
 | 
			
		||||
			String sValue;				// value (string)
 | 
			
		||||
			ke::AString sValue;				// value (string)
 | 
			
		||||
			float fValue;				// value (float)
 | 
			
		||||
			int iValue;					// value (int)
 | 
			
		||||
			int type;					// type (can be int, float, string)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,104 +0,0 @@
 | 
			
		||||
// vim: set ts=4 sw=4 tw=99 noet:
 | 
			
		||||
//
 | 
			
		||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
 | 
			
		||||
// Copyright (C) The AMX Mod X Development Team.
 | 
			
		||||
//
 | 
			
		||||
// This software is licensed under the GNU General Public License, version 3 or higher.
 | 
			
		||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
 | 
			
		||||
//     https://alliedmods.net/amxmodx-license
 | 
			
		||||
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "CFile.h"
 | 
			
		||||
 | 
			
		||||
// *****************************************************
 | 
			
		||||
// class File
 | 
			
		||||
// *****************************************************
 | 
			
		||||
 | 
			
		||||
File::File(const char* n, const char* m)
 | 
			
		||||
{
 | 
			
		||||
	fp = fopen(n, m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File::~File()
 | 
			
		||||
{
 | 
			
		||||
	if (fp)
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File::operator bool () const
 | 
			
		||||
{
 | 
			
		||||
	return fp && !feof(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& operator<<(File& f, const String& n)
 | 
			
		||||
{
 | 
			
		||||
	if (f) fputs(n.c_str(), f.fp);
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& operator<<(File& f, const char* n)
 | 
			
		||||
{
 | 
			
		||||
	if (f) fputs(n, f.fp);
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& operator<<(File& f, int n)
 | 
			
		||||
{
 | 
			
		||||
	if (f) fprintf(f.fp, "%d", n);
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& operator<<(File& f, const char& c)
 | 
			
		||||
{
 | 
			
		||||
	if (f) fputc(c, f.fp);
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& operator>>(File& f, String& n)
 | 
			
		||||
{
 | 
			
		||||
	if (!f) return f;
 | 
			
		||||
	char temp[1024];
 | 
			
		||||
	fscanf(f.fp, "%s", temp);
 | 
			
		||||
	n.assign(temp);
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& operator>>(File& f, char* n)
 | 
			
		||||
{
 | 
			
		||||
	if (f) fscanf(f.fp, "%s", n);
 | 
			
		||||
	return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int File::getline(char* buf, int sz)
 | 
			
		||||
{
 | 
			
		||||
	int a = sz;
 | 
			
		||||
	char *origBuf = buf;
 | 
			
		||||
	
 | 
			
		||||
	if (*this)
 | 
			
		||||
	{
 | 
			
		||||
		int c;
 | 
			
		||||
		while (sz-- && (c = getc((*this).fp)) && c != EOF && c != '\n')
 | 
			
		||||
		*buf++ = c;
 | 
			
		||||
		*buf = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// trim 0x0a and 0x0d characters at the end
 | 
			
		||||
	while (buf != origBuf)
 | 
			
		||||
	{
 | 
			
		||||
		if (*buf == 0x0a || *buf == 0x0d)
 | 
			
		||||
			*buf = 0;
 | 
			
		||||
		--buf;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return a - sz;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
File& File::skipWs()
 | 
			
		||||
{
 | 
			
		||||
	if (!*this) return *this;
 | 
			
		||||
	int c;
 | 
			
		||||
	while (isspace(c = getc(fp))) {};
 | 
			
		||||
	ungetc(c, fp);
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
// vim: set ts=4 sw=4 tw=99 noet:
 | 
			
		||||
//
 | 
			
		||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
 | 
			
		||||
// Copyright (C) The AMX Mod X Development Team.
 | 
			
		||||
//
 | 
			
		||||
// This software is licensed under the GNU General Public License, version 3 or higher.
 | 
			
		||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
 | 
			
		||||
//     https://alliedmods.net/amxmodx-license
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
 | 
			
		||||
// *****************************************************
 | 
			
		||||
// class File
 | 
			
		||||
// *****************************************************
 | 
			
		||||
 | 
			
		||||
class File
 | 
			
		||||
{
 | 
			
		||||
	FILE* fp;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	File(const char* n, const char* m);
 | 
			
		||||
	~File();
 | 
			
		||||
	
 | 
			
		||||
	operator bool () const;
 | 
			
		||||
	
 | 
			
		||||
	friend File& operator<<(File& f, const String& n);
 | 
			
		||||
	friend File& operator<<(File& f, const char* n);
 | 
			
		||||
	friend File& operator<<(File& f, const char& c);
 | 
			
		||||
	friend File& operator<<(File& f, int n);
 | 
			
		||||
	friend File& operator>>(File& f, String& n);
 | 
			
		||||
	friend File& operator>>(File& f, char* n);
 | 
			
		||||
	
 | 
			
		||||
	int getline(char* buf, int sz);
 | 
			
		||||
	
 | 
			
		||||
	File& skipWs();
 | 
			
		||||
};
 | 
			
		||||
@@ -10,23 +10,14 @@
 | 
			
		||||
#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);
 | 
			
		||||
 | 
			
		||||
	m_strConfigFile = build_pathname("%s/%s", get_localinfo("amxx_configsdir", "addons/amxmodx/configs"), Filename);
 | 
			
		||||
 | 
			
		||||
	CreateIfNotExist();
 | 
			
		||||
}
 | 
			
		||||
@@ -53,28 +44,25 @@ const int CFlagManager::LoadFile(const int force)
 | 
			
		||||
 | 
			
		||||
	FILE *File;
 | 
			
		||||
 | 
			
		||||
	File=fopen(m_strConfigFile.c_str(),"r");
 | 
			
		||||
	File=fopen(GetFile(),"r");
 | 
			
		||||
 | 
			
		||||
	if (!File)
 | 
			
		||||
	{
 | 
			
		||||
		AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)",m_strConfigFile.c_str());
 | 
			
		||||
		AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)", GetFile());
 | 
			
		||||
		return -1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Trying to copy this almost exactly as other configs are read...
 | 
			
		||||
	String Line;
 | 
			
		||||
	char Line[512];
 | 
			
		||||
	char TempLine[512];
 | 
			
		||||
 | 
			
		||||
	char Command[256];
 | 
			
		||||
	char Flags[256];
 | 
			
		||||
 | 
			
		||||
	String TempLine;
 | 
			
		||||
	while (!feof(File))
 | 
			
		||||
	
 | 
			
		||||
	while (!feof(File) && fgets(Line, sizeof(Line), File))
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		Line._fread(File);
 | 
			
		||||
 | 
			
		||||
		char *nonconst=const_cast<char *>(Line.c_str());
 | 
			
		||||
 | 
			
		||||
		char *nonconst= Line;
 | 
			
		||||
 | 
			
		||||
		// Strip out comments
 | 
			
		||||
		while (*nonconst)
 | 
			
		||||
@@ -93,9 +81,9 @@ const int CFlagManager::LoadFile(const int force)
 | 
			
		||||
		Flags[0]='\0';
 | 
			
		||||
 | 
			
		||||
		// Extract the command
 | 
			
		||||
		TempLine.assign(Line.c_str());
 | 
			
		||||
		strncopy(TempLine, Line, sizeof(TempLine));
 | 
			
		||||
 | 
			
		||||
		nonconst=const_cast<char *>(TempLine.c_str());
 | 
			
		||||
		nonconst = TempLine;
 | 
			
		||||
 | 
			
		||||
		char *start=NULL;
 | 
			
		||||
		char *end=NULL;
 | 
			
		||||
@@ -131,7 +119,6 @@ done_with_command:
 | 
			
		||||
 | 
			
		||||
		strncpy(Command,start,sizeof(Command)-1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		// Now do the same thing for the flags
 | 
			
		||||
		nonconst=++end;
 | 
			
		||||
 | 
			
		||||
@@ -168,11 +155,8 @@ done_with_flags:
 | 
			
		||||
 | 
			
		||||
		strncpy(Flags,start,sizeof(Flags)-1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		//if (!isalnum(*Command))
 | 
			
		||||
		if (*Command == '"' || 
 | 
			
		||||
			*Command == '\0')
 | 
			
		||||
		if (*Command == '"' || *Command == '\0')
 | 
			
		||||
		{
 | 
			
		||||
			continue;
 | 
			
		||||
		};
 | 
			
		||||
@@ -182,14 +166,12 @@ done_with_flags:
 | 
			
		||||
 | 
			
		||||
		AddFromFile(const_cast<const char*>(&Command[0]),&Flags[0]);
 | 
			
		||||
 | 
			
		||||
		nonconst=const_cast<char *>(Line.c_str());
 | 
			
		||||
		*nonconst='\0';
 | 
			
		||||
		nonconst = Line;
 | 
			
		||||
		*nonconst = '\0';
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	fclose(File);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -235,7 +217,7 @@ void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
 | 
			
		||||
 | 
			
		||||
	while (iter!=end)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp((*iter)->GetName()->c_str(),Command)==0)
 | 
			
		||||
		if (strcmp((*iter)->GetName()->chars(),Command)==0)
 | 
			
		||||
		{
 | 
			
		||||
			CFlagEntry *Entry=(*iter);
 | 
			
		||||
 | 
			
		||||
@@ -292,7 +274,7 @@ void CFlagManager::WriteCommands(void)
 | 
			
		||||
	// after we write so we do not re-read next map
 | 
			
		||||
	struct stat TempStat;
 | 
			
		||||
 | 
			
		||||
	stat(m_strConfigFile.c_str(),&TempStat);
 | 
			
		||||
	stat(GetFile(), &TempStat);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -302,7 +284,7 @@ void CFlagManager::WriteCommands(void)
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	File=fopen(m_strConfigFile.c_str(),"a");
 | 
			
		||||
	File = fopen(GetFile(), "a");
 | 
			
		||||
	
 | 
			
		||||
	if (!File)
 | 
			
		||||
	{
 | 
			
		||||
@@ -318,13 +300,13 @@ void CFlagManager::WriteCommands(void)
 | 
			
		||||
	{
 | 
			
		||||
		if ((*iter)->NeedWritten())
 | 
			
		||||
		{
 | 
			
		||||
			if ((*iter)->GetComment()->size())
 | 
			
		||||
			if ((*iter)->GetComment()->length())
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(File,"\"%s\" \t\"%s\" ; %s\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str(),(*iter)->GetComment()->c_str());
 | 
			
		||||
				fprintf(File,"\"%s\" \t\"%s\" ; %s\n",(*iter)->GetName()->chars(),(*iter)->GetFlags()->chars(),(*iter)->GetComment()->chars());
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				fprintf(File,"\"%s\" \t\"%s\"\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str());
 | 
			
		||||
				fprintf(File,"\"%s\" \t\"%s\"\n",(*iter)->GetName()->chars(),(*iter)->GetFlags()->chars());
 | 
			
		||||
			}
 | 
			
		||||
			(*iter)->SetNeedWritten(0);
 | 
			
		||||
		}
 | 
			
		||||
@@ -339,7 +321,7 @@ void CFlagManager::WriteCommands(void)
 | 
			
		||||
	// next map
 | 
			
		||||
	if (!NeedToRead)
 | 
			
		||||
	{
 | 
			
		||||
		stat(m_strConfigFile.c_str(),&TempStat);
 | 
			
		||||
		stat(GetFile(), &TempStat);
 | 
			
		||||
 | 
			
		||||
		m_Stat.st_mtime=TempStat.st_mtime;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,16 +15,15 @@
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
#include "sh_list.h"
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "CLibrarySys.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")
 | 
			
		||||
	ke::AString		m_strName;			// command name ("amx_slap")
 | 
			
		||||
	ke::AString		m_strFlags;			// string flags ("a","b")
 | 
			
		||||
	ke::AString		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
 | 
			
		||||
@@ -48,16 +47,17 @@ public:
 | 
			
		||||
		m_iNeedWritten=i;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const String *GetName(void) const
 | 
			
		||||
	const ke::AString *GetName(void) const
 | 
			
		||||
	{
 | 
			
		||||
		return &m_strName;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	const String *GetFlags(void) const
 | 
			
		||||
	const ke::AString *GetFlags(void) const
 | 
			
		||||
	{
 | 
			
		||||
		return &m_strFlags;
 | 
			
		||||
	};
 | 
			
		||||
	const String *GetComment(void) const
 | 
			
		||||
 | 
			
		||||
	const ke::AString *GetComment(void) const
 | 
			
		||||
	{
 | 
			
		||||
		return &m_strComment;
 | 
			
		||||
	};
 | 
			
		||||
@@ -69,7 +69,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	void SetName(const char *data)
 | 
			
		||||
	{
 | 
			
		||||
		m_strName.assign(data);
 | 
			
		||||
		m_strName = data;
 | 
			
		||||
	};
 | 
			
		||||
	void SetFlags(const char *flags)
 | 
			
		||||
	{
 | 
			
		||||
@@ -80,7 +80,7 @@ public:
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_strFlags.assign(flags);
 | 
			
		||||
		m_strFlags = flags;
 | 
			
		||||
		m_iFlags=UTIL_ReadFlags(flags);
 | 
			
		||||
	};
 | 
			
		||||
	void SetFlags(const int flags)
 | 
			
		||||
@@ -90,11 +90,11 @@ public:
 | 
			
		||||
		char FlagsString[32];
 | 
			
		||||
		UTIL_GetFlags(FlagsString, flags);
 | 
			
		||||
 | 
			
		||||
		m_strFlags.assign(FlagsString);
 | 
			
		||||
		m_strFlags = FlagsString;
 | 
			
		||||
	};
 | 
			
		||||
	void SetComment(const char *comment)
 | 
			
		||||
	{
 | 
			
		||||
		m_strComment.assign(comment);
 | 
			
		||||
		m_strComment = comment;
 | 
			
		||||
	};
 | 
			
		||||
	void SetHidden(int i=1)
 | 
			
		||||
	{
 | 
			
		||||
@@ -109,7 +109,7 @@ class CFlagManager
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	List<CFlagEntry *>		 m_FlagList;
 | 
			
		||||
	String					 m_strConfigFile;
 | 
			
		||||
	ke::AString				 m_strConfigFile;
 | 
			
		||||
	struct stat				 m_Stat;
 | 
			
		||||
	int						 m_iForceRead;
 | 
			
		||||
	int						 m_iDisabled;
 | 
			
		||||
@@ -119,12 +119,12 @@ private:
 | 
			
		||||
	{
 | 
			
		||||
		FILE *fp;
 | 
			
		||||
		
 | 
			
		||||
		fp=fopen(m_strConfigFile.c_str(),"r");
 | 
			
		||||
		fp = fopen(GetFile(), "r");
 | 
			
		||||
 | 
			
		||||
		if (!fp)
 | 
			
		||||
		{
 | 
			
		||||
			// File does not exist, create the header
 | 
			
		||||
			fp=fopen(m_strConfigFile.c_str(),"a");
 | 
			
		||||
			fp = fopen(GetFile(), "a");
 | 
			
		||||
 | 
			
		||||
			if (fp)
 | 
			
		||||
			{
 | 
			
		||||
@@ -152,7 +152,7 @@ private:
 | 
			
		||||
	{
 | 
			
		||||
		struct stat TempStat;
 | 
			
		||||
 | 
			
		||||
		stat(m_strConfigFile.c_str(),&TempStat);
 | 
			
		||||
		stat(GetFile(), &TempStat);
 | 
			
		||||
 | 
			
		||||
		// If the modified timestamp does not match the stored
 | 
			
		||||
		// timestamp than we need to re-read this file.
 | 
			
		||||
@@ -184,7 +184,7 @@ public:
 | 
			
		||||
	 */
 | 
			
		||||
	void SetFile(const char *Filename="cmdaccess.ini");
 | 
			
		||||
 | 
			
		||||
	const char *GetFile(void) const	{ return m_strConfigFile.c_str(); };
 | 
			
		||||
	const char *GetFile(void) const	{ return m_strConfigFile.chars(); };
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Parse the file, and load all entries
 | 
			
		||||
 
 | 
			
		||||
@@ -30,11 +30,11 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
 | 
			
		||||
			AMXForward tmp;
 | 
			
		||||
			tmp.pPlugin = &(*iter);
 | 
			
		||||
			tmp.func = func;
 | 
			
		||||
			m_Funcs.push_back(tmp);
 | 
			
		||||
			m_Funcs.append(tmp);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_Name.assign(name);
 | 
			
		||||
	m_Name = name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
 | 
			
		||||
@@ -46,14 +46,14 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
 | 
			
		||||
 | 
			
		||||
	cell globRetVal = 0;
 | 
			
		||||
 | 
			
		||||
	AMXForwardList::iterator iter;
 | 
			
		||||
 | 
			
		||||
	for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
 | 
			
		||||
	for (size_t i = 0; i < m_Funcs.length(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		auto iter = &m_Funcs[i];
 | 
			
		||||
 | 
			
		||||
		if (iter->pPlugin->isExecutable(iter->func))
 | 
			
		||||
		{
 | 
			
		||||
			// Get debug info
 | 
			
		||||
			AMX *amx = (*iter).pPlugin->getAMX();
 | 
			
		||||
			AMX *amx = iter->pPlugin->getAMX();
 | 
			
		||||
			Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
 | 
			
		||||
			
 | 
			
		||||
			if (pDebugger)
 | 
			
		||||
@@ -103,7 +103,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
 | 
			
		||||
			// exec
 | 
			
		||||
			cell retVal = 0;
 | 
			
		||||
#if defined BINLOG_ENABLED
 | 
			
		||||
			g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
 | 
			
		||||
			g_BinLog.WriteOp(BinLog_CallPubFunc, iter->pPlugin->getId(), iter->func);
 | 
			
		||||
#endif
 | 
			
		||||
			int err = amx_Exec(amx, &retVal, iter->func);
 | 
			
		||||
			
 | 
			
		||||
@@ -196,7 +196,7 @@ void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *para
 | 
			
		||||
	isFree = false;
 | 
			
		||||
	name[0] = '\0';
 | 
			
		||||
	amx_GetPublic(amx, func, name);
 | 
			
		||||
	m_Name.assign(name);
 | 
			
		||||
	m_Name = name;
 | 
			
		||||
	m_ToDelete = false;
 | 
			
		||||
	m_InExec = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -208,7 +208,7 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
 | 
			
		||||
	memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
 | 
			
		||||
	m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
 | 
			
		||||
	isFree = false;
 | 
			
		||||
	m_Name.assign(funcName);
 | 
			
		||||
	m_Name = funcName;
 | 
			
		||||
	m_ToDelete = false;
 | 
			
		||||
	m_InExec = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -340,7 +340,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
 | 
			
		||||
 | 
			
		||||
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
 | 
			
		||||
{
 | 
			
		||||
	int retVal = m_Forwards.size() << 1;
 | 
			
		||||
	int retVal = m_Forwards.length() << 1;
 | 
			
		||||
	CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
 | 
			
		||||
	
 | 
			
		||||
	if (!tmp)
 | 
			
		||||
@@ -348,7 +348,7 @@ int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int
 | 
			
		||||
		return -1;				// should be invalid
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	m_Forwards.push_back(tmp);
 | 
			
		||||
	m_Forwards.append(tmp);
 | 
			
		||||
	
 | 
			
		||||
	return retVal;
 | 
			
		||||
}
 | 
			
		||||
@@ -369,7 +369,7 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
 | 
			
		||||
		
 | 
			
		||||
		m_FreeSPForwards.pop();
 | 
			
		||||
	} else {
 | 
			
		||||
		retVal = (m_SPForwards.size() << 1) | 1;
 | 
			
		||||
		retVal = (m_SPForwards.length() << 1) | 1;
 | 
			
		||||
		pForward = new CSPForward();
 | 
			
		||||
		
 | 
			
		||||
		if (!pForward)
 | 
			
		||||
@@ -383,7 +383,7 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
 | 
			
		||||
			delete pForward;
 | 
			
		||||
		}
 | 
			
		||||
					 
 | 
			
		||||
		m_SPForwards.push_back(pForward);
 | 
			
		||||
		m_SPForwards.append(pForward);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return retVal;
 | 
			
		||||
@@ -391,7 +391,7 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
 | 
			
		||||
 | 
			
		||||
int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
 | 
			
		||||
{
 | 
			
		||||
	int retVal = (m_SPForwards.size() << 1) | 1;
 | 
			
		||||
	int retVal = (m_SPForwards.length() << 1) | 1;
 | 
			
		||||
	CSPForward *pForward;
 | 
			
		||||
	
 | 
			
		||||
	if (!m_FreeSPForwards.empty())
 | 
			
		||||
@@ -418,7 +418,7 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		m_SPForwards.push_back(pForward);
 | 
			
		||||
		m_SPForwards.append(pForward);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return retVal;
 | 
			
		||||
@@ -426,7 +426,7 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
 | 
			
		||||
 | 
			
		||||
bool CForwardMngr::isIdValid(int id) const
 | 
			
		||||
{
 | 
			
		||||
	return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.size()) : (static_cast<size_t>(id >> 1) < m_Forwards.size()));
 | 
			
		||||
	return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.length()) : (static_cast<size_t>(id >> 1) < m_Forwards.length()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell CForwardMngr::executeForwards(int id, cell *params)
 | 
			
		||||
@@ -484,23 +484,25 @@ ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
 | 
			
		||||
 | 
			
		||||
void CForwardMngr::clear()
 | 
			
		||||
{
 | 
			
		||||
	for (ForwardVec::iterator iter = m_Forwards.begin(); iter != m_Forwards.end(); ++iter)
 | 
			
		||||
	size_t i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < m_Forwards.length(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		delete *iter;
 | 
			
		||||
		delete m_Forwards[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SPForwardVec::iterator spIter;
 | 
			
		||||
	
 | 
			
		||||
	for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
 | 
			
		||||
	for (i = 0; i < m_SPForwards.length(); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		delete (*spIter);
 | 
			
		||||
		delete m_SPForwards[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_Forwards.clear();
 | 
			
		||||
	m_SPForwards.clear();
 | 
			
		||||
	
 | 
			
		||||
	while (!m_FreeSPForwards.empty())
 | 
			
		||||
	{
 | 
			
		||||
		m_FreeSPForwards.pop();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_TmpArraysNum = 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ class CForward
 | 
			
		||||
	const char *m_FuncName;
 | 
			
		||||
	ForwardExecType m_ExecType;
 | 
			
		||||
	int m_NumParams;
 | 
			
		||||
	String m_Name;
 | 
			
		||||
	ke::AString m_Name;
 | 
			
		||||
	
 | 
			
		||||
	struct AMXForward
 | 
			
		||||
	{
 | 
			
		||||
@@ -79,7 +79,7 @@ class CForward
 | 
			
		||||
		int func;
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	typedef CVector<AMXForward> AMXForwardList;
 | 
			
		||||
	typedef ke::Vector<AMXForward> AMXForwardList;
 | 
			
		||||
	
 | 
			
		||||
	AMXForwardList m_Funcs;
 | 
			
		||||
	ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
 | 
			
		||||
@@ -97,12 +97,12 @@ public:
 | 
			
		||||
	
 | 
			
		||||
	int getFuncsNum() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Funcs.size();
 | 
			
		||||
		return m_Funcs.length();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char *getFuncName() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Name.c_str();
 | 
			
		||||
		return m_Name.chars();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	ForwardParam getParamType(int paramId) const
 | 
			
		||||
@@ -125,7 +125,7 @@ class CSPForward
 | 
			
		||||
	
 | 
			
		||||
	int m_Func;
 | 
			
		||||
	bool m_HasFunc;
 | 
			
		||||
	String m_Name;
 | 
			
		||||
	ke::AString m_Name;
 | 
			
		||||
	bool m_InExec;
 | 
			
		||||
	bool m_ToDelete;
 | 
			
		||||
 | 
			
		||||
@@ -150,7 +150,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	const char *getFuncName() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Name.c_str();
 | 
			
		||||
		return m_Name.chars();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	ForwardParam getParamType(int paramId) const
 | 
			
		||||
@@ -164,8 +164,8 @@ public:
 | 
			
		||||
 | 
			
		||||
class CForwardMngr
 | 
			
		||||
{
 | 
			
		||||
	typedef CVector<CForward*> ForwardVec;
 | 
			
		||||
	typedef CVector<CSPForward*> SPForwardVec;
 | 
			
		||||
	typedef ke::Vector<CForward*> ForwardVec;
 | 
			
		||||
	typedef ke::Vector<CSPForward*> SPForwardVec;
 | 
			
		||||
	typedef CStack<int> FreeSPVec;							// Free SP Forwards
 | 
			
		||||
 | 
			
		||||
	ForwardVec m_Forwards;
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,7 @@
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "CLang.h"
 | 
			
		||||
#include "format.h"
 | 
			
		||||
 | 
			
		||||
CVector<FILE *> FileList;
 | 
			
		||||
#include "ITextParsers.h"
 | 
			
		||||
 | 
			
		||||
#define LITIDX_NONE			0
 | 
			
		||||
#define LITIDX_BRACKET		1
 | 
			
		||||
@@ -24,22 +23,27 @@ CVector<FILE *> FileList;
 | 
			
		||||
#define INSERT_NEWLINE		4
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int Compare<String>(const String &k1, const String &k2)
 | 
			
		||||
int Compare<ke::AString>(const ke::AString &k1, const ke::AString &k2)
 | 
			
		||||
{
 | 
			
		||||
	return k1.compare(k2.c_str());
 | 
			
		||||
	return k1.compare(k2.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int CompareAlt<char const *, String>(char const * const &k1,  String const &k2)
 | 
			
		||||
int CompareAlt<char const *, ke::AString>(char const * const &k1, ke::AString const &k2)
 | 
			
		||||
{
 | 
			
		||||
	return strcmp(k1, k2.c_str());
 | 
			
		||||
	return strcmp(k1, k2.chars());
 | 
			
		||||
}
 | 
			
		||||
template<>
 | 
			
		||||
int CompareAlt<ke::AString, ke::AString>(ke::AString const &k1, ke::AString const &k2)
 | 
			
		||||
{
 | 
			
		||||
	return strcmp(k1.chars(), k2.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int HashFunction<String>(const String &k)
 | 
			
		||||
int HashFunction<ke::AString>(const ke::AString &k)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long hash = 5381;
 | 
			
		||||
	register const char *str = k.c_str();
 | 
			
		||||
	register const char *str = k.chars();
 | 
			
		||||
	register char c;
 | 
			
		||||
	while ((c = *str++))
 | 
			
		||||
	{
 | 
			
		||||
@@ -61,6 +65,20 @@ int HashAlt<const char *>(char const * const &k)
 | 
			
		||||
	return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int HashAlt<ke::AString>(ke::AString const &k)
 | 
			
		||||
{
 | 
			
		||||
	unsigned long hash = 5381;
 | 
			
		||||
	register const char *str = k.chars();
 | 
			
		||||
	register char c;
 | 
			
		||||
	while ((c = *str++))
 | 
			
		||||
	{
 | 
			
		||||
		hash = ((hash << 5) + hash) + c; // hash*33 + c
 | 
			
		||||
	}
 | 
			
		||||
	return hash;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int HashFunction<int>(const int &k)
 | 
			
		||||
{
 | 
			
		||||
@@ -70,7 +88,7 @@ int HashFunction<int>(const int &k)
 | 
			
		||||
template<>
 | 
			
		||||
int Compare<int>(const int &k1, const int &k2)
 | 
			
		||||
{
 | 
			
		||||
	return (k1-k2);
 | 
			
		||||
	return (k1 - k2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// strip the whitespaces at the beginning and the end of a string
 | 
			
		||||
@@ -142,7 +160,7 @@ void CLangMngr::CLang::AddEntry(int key, const char *definition)
 | 
			
		||||
		m_entries++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	d.definition = new String(definition);
 | 
			
		||||
	d.definition = new ke::AString(definition);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CLangMngr::CLang::~CLang()
 | 
			
		||||
@@ -165,21 +183,21 @@ void CLangMngr::CLang::Clear()
 | 
			
		||||
	m_entries = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef> &vec)
 | 
			
		||||
void CLangMngr::CLang::MergeDefinitions(ke::Vector<sKeyDef> &vec)
 | 
			
		||||
{
 | 
			
		||||
	String *pDef;
 | 
			
		||||
	ke::AutoString *pDef;
 | 
			
		||||
	int key = -1;
 | 
			
		||||
	
 | 
			
		||||
	while (!vec.empty())
 | 
			
		||||
	{
 | 
			
		||||
		key = vec.front().key;
 | 
			
		||||
		pDef = vec.front().definition;
 | 
			
		||||
		auto keydef = vec.popCopy();
 | 
			
		||||
 | 
			
		||||
		AddEntry(key, pDef->c_str());
 | 
			
		||||
		key = keydef.key;
 | 
			
		||||
		pDef = keydef.definition;
 | 
			
		||||
 | 
			
		||||
		delete vec.front().definition;
 | 
			
		||||
		AddEntry(key, pDef->ptr());
 | 
			
		||||
 | 
			
		||||
		vec.pop();
 | 
			
		||||
		delete pDef;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -194,7 +212,7 @@ const char * CLangMngr::CLang::GetDef(int key, int &status)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	status = 0;
 | 
			
		||||
	return def.definition->c_str();
 | 
			
		||||
	return def.definition->chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CLangMngr::CLang::Entries()
 | 
			
		||||
@@ -204,15 +222,6 @@ int CLangMngr::CLang::Entries()
 | 
			
		||||
 | 
			
		||||
/******** CLangMngr *********/
 | 
			
		||||
 | 
			
		||||
inline String &make_string(const char *str)
 | 
			
		||||
{
 | 
			
		||||
	static String g_temp;
 | 
			
		||||
 | 
			
		||||
	g_temp.assign(str);
 | 
			
		||||
 | 
			
		||||
	return g_temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CLangMngr::CLangMngr()
 | 
			
		||||
{
 | 
			
		||||
	Clear();
 | 
			
		||||
@@ -220,15 +229,15 @@ CLangMngr::CLangMngr()
 | 
			
		||||
 | 
			
		||||
const char * CLangMngr::GetKey(int key)
 | 
			
		||||
{
 | 
			
		||||
	if (key < 0 || key >= (int)KeyList.size())
 | 
			
		||||
	if (key < 0 || key >= (int)KeyList.length())
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return KeyList[key]->c_str();
 | 
			
		||||
	return KeyList[key]->chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CLangMngr::GetKeyEntry(const char *key)
 | 
			
		||||
{
 | 
			
		||||
	keytbl_val &val = KeyTable[key];
 | 
			
		||||
	keytbl_val &val = KeyTable[ke::AString(key)];
 | 
			
		||||
 | 
			
		||||
	return val.index;
 | 
			
		||||
}
 | 
			
		||||
@@ -236,22 +245,21 @@ int CLangMngr::GetKeyEntry(const char *key)
 | 
			
		||||
int CLangMngr::AddKeyEntry(const char *key)
 | 
			
		||||
{
 | 
			
		||||
	keytbl_val val;
 | 
			
		||||
	val.index = static_cast<int>(KeyList.size());
 | 
			
		||||
	val.index = static_cast<int>(KeyList.length());
 | 
			
		||||
 | 
			
		||||
	String *pString = new String(key);
 | 
			
		||||
	KeyList.push_back(pString);
 | 
			
		||||
	KeyList.append(new ke::AString(key));
 | 
			
		||||
 | 
			
		||||
	KeyTable[key] = val;
 | 
			
		||||
	KeyTable[ke::AString(key)] = val;
 | 
			
		||||
 | 
			
		||||
	return val.index;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CLangMngr::AddKeyEntry(String &key)
 | 
			
		||||
int CLangMngr::AddKeyEntry(ke::AString &key)
 | 
			
		||||
{
 | 
			
		||||
    return AddKeyEntry(key.c_str());
 | 
			
		||||
	return AddKeyEntry(key.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CLangMngr::GetKeyEntry(String &key)
 | 
			
		||||
int CLangMngr::GetKeyEntry(ke::AString &key)
 | 
			
		||||
{
 | 
			
		||||
	keytbl_val &val = KeyTable[key];
 | 
			
		||||
 | 
			
		||||
@@ -269,16 +277,16 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
 | 
			
		||||
	return outbuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef> &tmpVec)
 | 
			
		||||
void CLangMngr::MergeDefinitions(const char *lang, ke::Vector<sKeyDef> &tmpVec)
 | 
			
		||||
{
 | 
			
		||||
	CLang * language = GetLang(lang);
 | 
			
		||||
	if (language)
 | 
			
		||||
		language->MergeDefinitions(tmpVec);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void reparse_color(String* def)
 | 
			
		||||
void reparse_newlines_and_color(char* def)
 | 
			
		||||
{
 | 
			
		||||
	size_t len = def->size();
 | 
			
		||||
	size_t len = strlen(def);
 | 
			
		||||
	int offs = 0;
 | 
			
		||||
	int c;
 | 
			
		||||
 | 
			
		||||
@@ -287,21 +295,25 @@ void reparse_color(String* def)
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < len; i++)
 | 
			
		||||
	{
 | 
			
		||||
		c = def->at(i); 
 | 
			
		||||
		if (c == '^' && (i != len-1))
 | 
			
		||||
		c = def[i]; 
 | 
			
		||||
 | 
			
		||||
		if (c == '^' && (i != len - 1))
 | 
			
		||||
		{
 | 
			
		||||
			c = def->at(++i);
 | 
			
		||||
			if (c >= '1' && c <= '4')
 | 
			
		||||
			c = def[++i];
 | 
			
		||||
 | 
			
		||||
			if (c == 'n' || c == 't' || (c >= '1' && c <= '4'))
 | 
			
		||||
			{
 | 
			
		||||
				switch(c)
 | 
			
		||||
				switch (c)
 | 
			
		||||
				{
 | 
			
		||||
					case '1' : c = '\x01'; break;
 | 
			
		||||
					case '2' : c = '\x02'; break;
 | 
			
		||||
					case '3' : c = '\x03'; break;
 | 
			
		||||
					case '4' : c = '\x04'; break;
 | 
			
		||||
					case '1': c = '\x01'; break;
 | 
			
		||||
					case '2': c = '\x02'; break;
 | 
			
		||||
					case '3': c = '\x03'; break;
 | 
			
		||||
					case '4': c = '\x04'; break;
 | 
			
		||||
					case 'n': c = '\n'; break;
 | 
			
		||||
					case 't': c = '\t'; break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (!g_bmod_cstrike) // remove completely these two characters if not under CS
 | 
			
		||||
				if (!g_bmod_cstrike && (c >= '1' && c <= '4')) // remove completely these two characters if not under CS
 | 
			
		||||
				{
 | 
			
		||||
					offs += 2;
 | 
			
		||||
					continue;
 | 
			
		||||
@@ -310,10 +322,146 @@ void reparse_color(String* def)
 | 
			
		||||
				offs++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		def->at(i-offs, c);
 | 
			
		||||
 | 
			
		||||
		def[i - offs] = c;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	def->at(len-offs, '\0');
 | 
			
		||||
	def[len-offs] = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct LangFileData
 | 
			
		||||
{
 | 
			
		||||
	void reset()
 | 
			
		||||
	{
 | 
			
		||||
		multiLine = false;
 | 
			
		||||
 | 
			
		||||
		*language    = '\0';
 | 
			
		||||
		*valueBuffer = '\0';
 | 
			
		||||
 | 
			
		||||
		clearEntry();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void clearEntry()
 | 
			
		||||
	{
 | 
			
		||||
		entry.key = -1;
 | 
			
		||||
		entry.definition = nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool                multiLine;
 | 
			
		||||
	char                language[3];
 | 
			
		||||
	char                valueBuffer[512];
 | 
			
		||||
	ke::AString         currentFile;
 | 
			
		||||
	ke::AString         lastKey;
 | 
			
		||||
	ke::Vector<sKeyDef> defsQueue;
 | 
			
		||||
	sKeyDef             entry;
 | 
			
		||||
 | 
			
		||||
} Data;
 | 
			
		||||
 | 
			
		||||
void CLangMngr::ReadINI_ParseStart()
 | 
			
		||||
{
 | 
			
		||||
	Data.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CLangMngr::ReadINI_NewSection(const char *section, bool invalid_tokens, bool close_bracket, bool extra_tokens, unsigned int *curtok)
 | 
			
		||||
{
 | 
			
		||||
	if (Data.multiLine)
 | 
			
		||||
	{
 | 
			
		||||
		AMXXLOG_Log("New section, unterminated block (file \"%s\" key \"%s\" lang \"%s\")", Data.currentFile.chars(), Data.lastKey.chars(), Data.language);
 | 
			
		||||
 | 
			
		||||
		Data.clearEntry();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!Data.defsQueue.empty())
 | 
			
		||||
	{
 | 
			
		||||
		MergeDefinitions(Data.language, Data.defsQueue);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Data.reset();
 | 
			
		||||
 | 
			
		||||
	Data.language[0] = section[0];
 | 
			
		||||
	Data.language[1] = section[1];
 | 
			
		||||
	Data.language[2] = '\0';
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CLangMngr::ReadINI_KeyValue(const char *key, const char *value, bool invalid_tokens, bool equal_token, bool quotes, unsigned int *curtok)
 | 
			
		||||
{
 | 
			
		||||
	bool colons_token = (key[strlen(key) - 1] == ':');
 | 
			
		||||
 | 
			
		||||
	if (!Data.multiLine)
 | 
			
		||||
	{
 | 
			
		||||
		Data.lastKey = key;
 | 
			
		||||
 | 
			
		||||
		if (colons_token || equal_token)
 | 
			
		||||
		{
 | 
			
		||||
			int iKey = GetKeyEntry(key);
 | 
			
		||||
 | 
			
		||||
			if (iKey == -1)
 | 
			
		||||
			{
 | 
			
		||||
				iKey = AddKeyEntry(key);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (equal_token)
 | 
			
		||||
			{
 | 
			
		||||
				strncopy(Data.valueBuffer, value, sizeof(Data.valueBuffer));
 | 
			
		||||
 | 
			
		||||
				reparse_newlines_and_color(Data.valueBuffer);
 | 
			
		||||
 | 
			
		||||
				Data.entry.key = iKey;
 | 
			
		||||
				Data.entry.definition = new ke::AutoString;
 | 
			
		||||
				*Data.entry.definition = Data.valueBuffer;
 | 
			
		||||
 | 
			
		||||
				Data.defsQueue.append(Data.entry);
 | 
			
		||||
				Data.clearEntry();
 | 
			
		||||
			}
 | 
			
		||||
			else if (!value && colons_token)
 | 
			
		||||
			{
 | 
			
		||||
				Data.entry.key = iKey;
 | 
			
		||||
				Data.entry.definition = new ke::AutoString;
 | 
			
		||||
 | 
			
		||||
				Data.multiLine = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			AMXXLOG_Log("Invalid multi-lingual line (file \"%s\" key \"%s\" lang \"%s\")", Data.currentFile.chars(), Data.lastKey.chars(), Data.language);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (!value && colons_token)
 | 
			
		||||
		{
 | 
			
		||||
			strncopy(Data.valueBuffer, Data.entry.definition->ptr(), sizeof(Data.valueBuffer));
 | 
			
		||||
			reparse_newlines_and_color(Data.valueBuffer);
 | 
			
		||||
 | 
			
		||||
			*Data.entry.definition = Data.valueBuffer;
 | 
			
		||||
 | 
			
		||||
			Data.defsQueue.append(Data.entry);
 | 
			
		||||
			Data.clearEntry();
 | 
			
		||||
 | 
			
		||||
			Data.multiLine = false;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			if (!Data.entry.definition)
 | 
			
		||||
			{
 | 
			
		||||
				Data.entry.definition = new ke::AutoString();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			*Data.entry.definition = *Data.entry.definition + key;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLangMngr::ReadINI_ParseEnd(bool halted)
 | 
			
		||||
{
 | 
			
		||||
	if (!Data.defsQueue.empty())
 | 
			
		||||
	{
 | 
			
		||||
		MergeDefinitions(Data.language, Data.defsQueue);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//this is the file parser for dictionary text files
 | 
			
		||||
@@ -332,167 +480,60 @@ int CLangMngr::MergeDefinitionFile(const char *file)
 | 
			
		||||
	/** Checks if there is an existing entry with same time stamp. */
 | 
			
		||||
	time_t timeStamp;
 | 
			
		||||
	if (FileList.retrieve(file, &timeStamp) && fileStat.st_mtime == timeStamp)
 | 
			
		||||
	{
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** If yes, it either means that the entry doesn't exist or the existing entry needs to be updated. */
 | 
			
		||||
	FileList.replace(file, fileStat.st_mtime);
 | 
			
		||||
 | 
			
		||||
	FILE* fp = fopen(file, "rt");
 | 
			
		||||
	if (!fp)
 | 
			
		||||
	Data.currentFile = file;
 | 
			
		||||
 | 
			
		||||
	unsigned int line, col;
 | 
			
		||||
	bool result = textparsers->ParseFile_INI(file, static_cast<ITextListener_INI*>(this), &line, &col);
 | 
			
		||||
 | 
			
		||||
	if (!result)
 | 
			
		||||
	{
 | 
			
		||||
		AMXXLOG_Log("[AMXX] Failed to re-open dictionary file: %s", file);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Allocate enough memory to store everything
 | 
			
		||||
	bool multiline = 0;
 | 
			
		||||
	int pos = 0, line = 0;
 | 
			
		||||
	CQueue<sKeyDef> Defq;
 | 
			
		||||
	String buf;
 | 
			
		||||
	char language[3];
 | 
			
		||||
	sKeyDef tmpEntry = {NULL, 0};
 | 
			
		||||
 | 
			
		||||
	while (!feof(fp))
 | 
			
		||||
	{
 | 
			
		||||
		line++;
 | 
			
		||||
		buf._fread(fp);
 | 
			
		||||
		buf.trim();
 | 
			
		||||
		if (buf[0] == 0)
 | 
			
		||||
			continue;
 | 
			
		||||
		if ((buf[0] == ';') || (buf[0] == '/' && buf[1] == '/'))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Check for BOM markings, which is only relevant on the first line.
 | 
			
		||||
		* Not worth it, but it could be moved out of the loop.
 | 
			
		||||
		*/
 | 
			
		||||
		if (line == 1 && (buf[0] == (char)0xEF && buf[1] == (char)0xBB && buf[2] == (char)0xBF))
 | 
			
		||||
		{
 | 
			
		||||
			buf.erase(0, 3);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (buf[0] == '[' && buf.size() >= 3)
 | 
			
		||||
		{
 | 
			
		||||
			if (multiline)
 | 
			
		||||
			{
 | 
			
		||||
				AMXXLOG_Log("New section, multiline unterminated (file \"%s\" line %d)", file, line);
 | 
			
		||||
				tmpEntry.key = -1;
 | 
			
		||||
				tmpEntry.definition = NULL;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (!Defq.empty())
 | 
			
		||||
			{
 | 
			
		||||
				MergeDefinitions(language, Defq);
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			language[0] = buf[1];
 | 
			
		||||
			language[1] = buf[2];
 | 
			
		||||
			language[2] = 0;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (!multiline)
 | 
			
		||||
			{
 | 
			
		||||
				pos = buf.find('=');
 | 
			
		||||
				
 | 
			
		||||
				if (pos > String::npos)
 | 
			
		||||
				{
 | 
			
		||||
					String key;
 | 
			
		||||
					key.assign(buf.substr(0, pos).c_str());
 | 
			
		||||
					String def;
 | 
			
		||||
					def.assign(buf.substr(pos + 1).c_str());
 | 
			
		||||
					key.trim();
 | 
			
		||||
					key.toLower();
 | 
			
		||||
					int iKey = GetKeyEntry(key);
 | 
			
		||||
					if (iKey == -1)
 | 
			
		||||
						iKey = AddKeyEntry(key);
 | 
			
		||||
					tmpEntry.key = iKey;
 | 
			
		||||
					tmpEntry.definition = new String;
 | 
			
		||||
					tmpEntry.definition->assign(def.c_str());
 | 
			
		||||
					tmpEntry.definition->trim();
 | 
			
		||||
					reparse_color(tmpEntry.definition);
 | 
			
		||||
					tmpEntry.definition->reparse_newlines();
 | 
			
		||||
					Defq.push(tmpEntry);
 | 
			
		||||
					tmpEntry.key = -1;
 | 
			
		||||
					tmpEntry.definition = NULL;
 | 
			
		||||
				} else {
 | 
			
		||||
					pos = buf.find(':');
 | 
			
		||||
					
 | 
			
		||||
					if (pos > String::npos)
 | 
			
		||||
					{
 | 
			
		||||
						String key;
 | 
			
		||||
						key.assign(buf.substr(0, pos).c_str());;
 | 
			
		||||
						key.trim();
 | 
			
		||||
						key.toLower();
 | 
			
		||||
						int iKey = GetKeyEntry(key);
 | 
			
		||||
						if (iKey == -1)
 | 
			
		||||
							iKey = AddKeyEntry(key);
 | 
			
		||||
						tmpEntry.key = iKey;
 | 
			
		||||
						tmpEntry.definition = new String;
 | 
			
		||||
						multiline = true;
 | 
			
		||||
					} else {
 | 
			
		||||
						//user typed a line with no directives
 | 
			
		||||
						AMXXLOG_Log("Invalid multi-lingual line (file \"%s\" line %d)", file, line);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				if (buf[0] == ':')
 | 
			
		||||
				{
 | 
			
		||||
					reparse_color(tmpEntry.definition);
 | 
			
		||||
					tmpEntry.definition->reparse_newlines();
 | 
			
		||||
					Defq.push(tmpEntry);
 | 
			
		||||
					tmpEntry.key = -1;
 | 
			
		||||
					tmpEntry.definition = NULL;
 | 
			
		||||
					multiline = false;
 | 
			
		||||
				} else {
 | 
			
		||||
					if (!tmpEntry.definition)
 | 
			
		||||
						tmpEntry.definition = new String();
 | 
			
		||||
					tmpEntry.definition->append(buf);
 | 
			
		||||
				}
 | 
			
		||||
			} // if !multiline
 | 
			
		||||
		} //if - main
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// merge last section
 | 
			
		||||
	if (!Defq.empty())
 | 
			
		||||
	{
 | 
			
		||||
		MergeDefinitions(language, Defq);
 | 
			
		||||
	}
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Find a CLang by name, if not found, add it
 | 
			
		||||
CLangMngr::CLang * CLangMngr::GetLang(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	LangVecIter iter;
 | 
			
		||||
	for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
 | 
			
		||||
	for (size_t iter = 0; iter < m_Languages.length(); ++iter)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp((*iter)->GetName(), name) == 0)
 | 
			
		||||
			return (*iter);
 | 
			
		||||
		if (strcmp(m_Languages[iter]->GetName(), name) == 0)
 | 
			
		||||
			return m_Languages[iter];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CLang *p = new CLang(name);
 | 
			
		||||
	p->SetMngr(this);
 | 
			
		||||
 | 
			
		||||
	m_Languages.push_back(p);
 | 
			
		||||
	m_Languages.append(p);
 | 
			
		||||
	return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Find a CLang by name, if not found, return NULL
 | 
			
		||||
CLangMngr::CLang * CLangMngr::GetLangR(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	LangVecIter iter;
 | 
			
		||||
	for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
 | 
			
		||||
	for (size_t iter = 0; iter < m_Languages.length(); ++iter)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp((*iter)->GetName(), name) == 0)
 | 
			
		||||
			return (*iter);
 | 
			
		||||
		if (strcmp(m_Languages[iter]->GetName(), name) == 0)
 | 
			
		||||
			return m_Languages[iter];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *CLangMngr::GetDef(const char *langName, const char *key, int &status)
 | 
			
		||||
{
 | 
			
		||||
	CLang *lang = GetLangR(langName);
 | 
			
		||||
	keytbl_val &val = KeyTable.AltFindOrInsert(key); //KeyTable[make_string(key)];
 | 
			
		||||
 | 
			
		||||
	keytbl_val &val = KeyTable.AltFindOrInsert(ke::AString(key)); //KeyTable[make_string(key)];
 | 
			
		||||
	if (lang == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		status = ERR_BADLANG;
 | 
			
		||||
@@ -522,13 +563,13 @@ void CLangMngr::Clear()
 | 
			
		||||
 | 
			
		||||
	KeyTable.clear();
 | 
			
		||||
	
 | 
			
		||||
	for (i = 0; i < m_Languages.size(); i++)
 | 
			
		||||
	for (i = 0; i < m_Languages.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_Languages[i])
 | 
			
		||||
			delete m_Languages[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < KeyList.size(); i++)
 | 
			
		||||
	for (i = 0; i < KeyList.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (KeyList[i])
 | 
			
		||||
			delete KeyList[i];
 | 
			
		||||
@@ -541,21 +582,17 @@ void CLangMngr::Clear()
 | 
			
		||||
 | 
			
		||||
int CLangMngr::GetLangsNum()
 | 
			
		||||
{
 | 
			
		||||
	return m_Languages.size();
 | 
			
		||||
	return m_Languages.length();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *CLangMngr::GetLangName(int langId)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	LangVecIter iter;
 | 
			
		||||
	
 | 
			
		||||
	for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
 | 
			
		||||
	for (size_t iter = 0; iter < m_Languages.length(); ++iter)
 | 
			
		||||
	{
 | 
			
		||||
		if (i == langId)
 | 
			
		||||
		if (iter == langId)
 | 
			
		||||
		{
 | 
			
		||||
			return (*iter)->GetName();
 | 
			
		||||
			return m_Languages[iter]->GetName();
 | 
			
		||||
		}
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "";
 | 
			
		||||
@@ -572,14 +609,13 @@ bool CLangMngr::LangExists(const char *langName)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	LangVecIter iter;
 | 
			
		||||
	
 | 
			
		||||
	for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
 | 
			
		||||
	for (size_t iter = 0; iter < m_Languages.length(); ++iter)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp((*iter)->GetName(), buf) == 0)
 | 
			
		||||
		if (strcmp(m_Languages[iter]->GetName(), buf) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#include "sh_tinyhash.h"
 | 
			
		||||
#include "sm_stringhashmap.h"
 | 
			
		||||
#include <ITextParsers.h>
 | 
			
		||||
 | 
			
		||||
#define LANG_SERVER 0
 | 
			
		||||
#define LANG_PLAYER -1
 | 
			
		||||
@@ -21,7 +22,7 @@
 | 
			
		||||
 | 
			
		||||
struct sKeyDef
 | 
			
		||||
{
 | 
			
		||||
	String *definition;
 | 
			
		||||
	ke::AutoString* definition;
 | 
			
		||||
	int key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -46,7 +47,7 @@ public:
 | 
			
		||||
	~defentry()
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
	String *definition;
 | 
			
		||||
	ke::AString *definition;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct keytbl_val
 | 
			
		||||
@@ -57,7 +58,7 @@ struct keytbl_val
 | 
			
		||||
	int index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class CLangMngr
 | 
			
		||||
class CLangMngr : public ITextListener_INI
 | 
			
		||||
{
 | 
			
		||||
	class CLang
 | 
			
		||||
	{
 | 
			
		||||
@@ -72,7 +73,7 @@ class CLangMngr
 | 
			
		||||
		// Get the definition
 | 
			
		||||
		const char *GetDef(int key, int &status);
 | 
			
		||||
		// Add definitions to this language
 | 
			
		||||
		void MergeDefinitions(CQueue <sKeyDef> & vec);
 | 
			
		||||
		void MergeDefinitions(ke::Vector <sKeyDef> & vec);
 | 
			
		||||
		// Reset this language
 | 
			
		||||
		void Clear();
 | 
			
		||||
 | 
			
		||||
@@ -102,20 +103,25 @@ class CLangMngr
 | 
			
		||||
	};
 | 
			
		||||
public:
 | 
			
		||||
	// Merge definitions into a language
 | 
			
		||||
	void MergeDefinitions(const char *lang, CQueue <sKeyDef> &tmpVec);
 | 
			
		||||
	void MergeDefinitions(const char *lang, ke::Vector <sKeyDef> &tmpVec);
 | 
			
		||||
 | 
			
		||||
public: // ITextListener_INI
 | 
			
		||||
	void ReadINI_ParseStart();
 | 
			
		||||
	void ReadINI_ParseEnd(bool halted);
 | 
			
		||||
	bool ReadINI_NewSection(const char *section, bool invalid_tokens, bool close_bracket, bool extra_tokens, unsigned int *curtok);
 | 
			
		||||
	bool ReadINI_KeyValue(const char *key, const char *value, bool invalid_tokens, bool equal_token, bool quotes, unsigned int *curtok);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// strip lowercase; make lower if needed
 | 
			
		||||
	static size_t strip(char *str, char *newstr, bool makelower = false);
 | 
			
		||||
 | 
			
		||||
	typedef CVector<CLang*> LangVec;
 | 
			
		||||
	typedef CVector<CLang*>::iterator LangVecIter;
 | 
			
		||||
	typedef ke::Vector<CLang*> LangVec;
 | 
			
		||||
	
 | 
			
		||||
	LangVec m_Languages;
 | 
			
		||||
 | 
			
		||||
	StringHashMap<time_t> FileList;
 | 
			
		||||
	CVector<String *> KeyList;
 | 
			
		||||
	THash<String, keytbl_val> KeyTable;
 | 
			
		||||
	ke::Vector<ke::AString *> KeyList;
 | 
			
		||||
	THash<ke::AString, keytbl_val> KeyTable;
 | 
			
		||||
 | 
			
		||||
	// Get a lang object (construct if needed)
 | 
			
		||||
	CLang * GetLang(const char *name);
 | 
			
		||||
@@ -133,12 +139,12 @@ public:
 | 
			
		||||
	char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
 | 
			
		||||
	void InvalidateCache();
 | 
			
		||||
	// Get index
 | 
			
		||||
	int GetKeyEntry(String &key);
 | 
			
		||||
	int GetKeyEntry(ke::AString &key);
 | 
			
		||||
	int GetKeyEntry(const char *key);
 | 
			
		||||
	// Get key from index
 | 
			
		||||
	const char *GetKey(int key);
 | 
			
		||||
	// Add key
 | 
			
		||||
	int AddKeyEntry(String &key);
 | 
			
		||||
	int AddKeyEntry(ke::AString &key);
 | 
			
		||||
	int AddKeyEntry(const char *key);
 | 
			
		||||
 | 
			
		||||
	// Get the number of languages
 | 
			
		||||
 
 | 
			
		||||
@@ -35,9 +35,9 @@ int LogEventsMngr::CLogCmp::compareCondition(const char* string)
 | 
			
		||||
	logid = parent->logCounter;
 | 
			
		||||
	
 | 
			
		||||
	if (in)
 | 
			
		||||
		return result = strstr(string, text.c_str()) ? 0 : 1;
 | 
			
		||||
		return result = strstr(string, text.chars()) ? 0 : 1;
 | 
			
		||||
	
 | 
			
		||||
	return result = strcmp(string,text.c_str());
 | 
			
		||||
	return result = strcmp(string,text.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter)
 | 
			
		||||
@@ -59,7 +59,7 @@ LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter)
 | 
			
		||||
	
 | 
			
		||||
	while (c)
 | 
			
		||||
	{
 | 
			
		||||
		if ((c->pos == pos) && (c->in == in) && !strcmp(c->text.c_str(), filter))
 | 
			
		||||
		if ((c->pos == pos) && (c->in == in) && !strcmp(c->text.chars(), filter))
 | 
			
		||||
			return c;
 | 
			
		||||
		c = c->next;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ public:
 | 
			
		||||
		friend class CLogEvent;
 | 
			
		||||
		
 | 
			
		||||
		LogEventsMngr* parent;
 | 
			
		||||
		String text;
 | 
			
		||||
		ke::AString text;
 | 
			
		||||
		
 | 
			
		||||
		int logid;
 | 
			
		||||
		int pos;
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ int MenuMngr::findMenuId(const char* name, AMX* amx)
 | 
			
		||||
{
 | 
			
		||||
	for (MenuIdEle* b = headid; b; b = b->next)
 | 
			
		||||
	{
 | 
			
		||||
		if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()))
 | 
			
		||||
		if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.chars()))
 | 
			
		||||
			return b->id;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ class MenuMngr
 | 
			
		||||
{
 | 
			
		||||
	struct MenuIdEle
 | 
			
		||||
	{
 | 
			
		||||
		String name;
 | 
			
		||||
		ke::AString name;
 | 
			
		||||
		AMX* amx;
 | 
			
		||||
		MenuIdEle* next;
 | 
			
		||||
		
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,10 @@ void CPlayer::Init(edict_t* e, int i)
 | 
			
		||||
	menuexpire = 0.0;
 | 
			
		||||
	newmenu = -1;
 | 
			
		||||
 | 
			
		||||
	death_weapon.clear();
 | 
			
		||||
	name.clear();
 | 
			
		||||
	ip.clear();
 | 
			
		||||
	team.clear();
 | 
			
		||||
	death_weapon = nullptr;
 | 
			
		||||
	name = nullptr;
 | 
			
		||||
	ip = nullptr;
 | 
			
		||||
	team = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CPlayer::Disconnect()
 | 
			
		||||
@@ -81,8 +81,8 @@ int CPlayer::NextHUDChannel()
 | 
			
		||||
 | 
			
		||||
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
 | 
			
		||||
{
 | 
			
		||||
	name.assign(connectname);
 | 
			
		||||
	ip.assign(ipaddress);
 | 
			
		||||
	name = connectname;
 | 
			
		||||
	ip = ipaddress;
 | 
			
		||||
	time = gpGlobals->time;
 | 
			
		||||
	death_killer = 0;
 | 
			
		||||
	menu = 0;
 | 
			
		||||
@@ -239,7 +239,7 @@ void TeamIds::registerTeam(const char* n, int s)
 | 
			
		||||
	
 | 
			
		||||
	while (*a)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp((*a)->name.c_str(),n) == 0)
 | 
			
		||||
		if (strcmp((*a)->name.chars(),n) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			if (s != -1)
 | 
			
		||||
			{
 | 
			
		||||
@@ -266,7 +266,7 @@ int TeamIds::findTeamId(const char* n)
 | 
			
		||||
	
 | 
			
		||||
	while (a)
 | 
			
		||||
	{
 | 
			
		||||
		if (!stricmp(a->name.c_str(), n))
 | 
			
		||||
		if (!stricmp(a->name.chars(), n))
 | 
			
		||||
			return a->id;
 | 
			
		||||
		a = a->next;
 | 
			
		||||
	}
 | 
			
		||||
@@ -280,7 +280,7 @@ int TeamIds::findTeamIdCase(const char* n)
 | 
			
		||||
	
 | 
			
		||||
	while (a)
 | 
			
		||||
	{
 | 
			
		||||
		if (!strcmp(a->name.c_str(), n))
 | 
			
		||||
		if (!strcmp(a->name.chars(), n))
 | 
			
		||||
			return a->id;
 | 
			
		||||
		a = a->next;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,9 +30,9 @@ class CPlayer
 | 
			
		||||
public:
 | 
			
		||||
	edict_t* pEdict;
 | 
			
		||||
	
 | 
			
		||||
	String name;
 | 
			
		||||
	String ip;
 | 
			
		||||
	String team;
 | 
			
		||||
	ke::AString name;
 | 
			
		||||
	ke::AString ip;
 | 
			
		||||
	ke::AString team;
 | 
			
		||||
 | 
			
		||||
	bool initialized;
 | 
			
		||||
	bool ingame;
 | 
			
		||||
@@ -63,7 +63,7 @@ public:
 | 
			
		||||
	int death_killer;
 | 
			
		||||
	int death_victim;
 | 
			
		||||
	bool death_tk;
 | 
			
		||||
	String death_weapon;
 | 
			
		||||
	ke::AString death_weapon;
 | 
			
		||||
	int newmenu;
 | 
			
		||||
	int page;
 | 
			
		||||
 | 
			
		||||
@@ -138,7 +138,7 @@ public:
 | 
			
		||||
 | 
			
		||||
class ForceObject
 | 
			
		||||
{
 | 
			
		||||
	String filename;
 | 
			
		||||
	ke::AString filename;
 | 
			
		||||
	FORCE_TYPE type;
 | 
			
		||||
	Vector mins;
 | 
			
		||||
	Vector maxs;
 | 
			
		||||
@@ -146,7 +146,7 @@ class ForceObject
 | 
			
		||||
public:
 | 
			
		||||
	ForceObject(const char* n, FORCE_TYPE c, Vector& mi, Vector& ma, AMX* a) : filename(n), type(c), mins(mi), maxs(ma), amx(a) {}
 | 
			
		||||
 | 
			
		||||
	inline const char* getFilename() { return filename.c_str(); }
 | 
			
		||||
	inline const char* getFilename() { return filename.chars(); }
 | 
			
		||||
	inline AMX* getAMX() { return amx; }
 | 
			
		||||
	
 | 
			
		||||
	Vector& getMin() { return mins; }
 | 
			
		||||
@@ -203,14 +203,14 @@ public:
 | 
			
		||||
 | 
			
		||||
class CScript
 | 
			
		||||
{
 | 
			
		||||
	String filename;
 | 
			
		||||
	ke::AString filename;
 | 
			
		||||
	AMX* amx;
 | 
			
		||||
	void* code;
 | 
			
		||||
public:
 | 
			
		||||
	CScript(AMX* aa, void* cc, const char* ff) : filename(ff), amx(aa), code(cc) {}
 | 
			
		||||
	
 | 
			
		||||
	inline AMX* getAMX() { return amx; }
 | 
			
		||||
	inline const char* getName() { return filename.c_str(); }
 | 
			
		||||
	inline const char* getName() { return filename.chars(); }
 | 
			
		||||
	inline bool operator==(void* a) { return (amx == (AMX*)a); }
 | 
			
		||||
	inline void* getCode() { return code; }
 | 
			
		||||
};
 | 
			
		||||
@@ -223,7 +223,7 @@ class TeamIds
 | 
			
		||||
{
 | 
			
		||||
	struct TeamEle
 | 
			
		||||
	{
 | 
			
		||||
		String name;
 | 
			
		||||
		ke::AString name;
 | 
			
		||||
		int id;
 | 
			
		||||
		char tid;
 | 
			
		||||
		static char uid;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ typedef void (*PLUGINSUNLOADING_NEW)(void);
 | 
			
		||||
 | 
			
		||||
CModule::CModule(const char* fname)
 | 
			
		||||
{
 | 
			
		||||
	m_Filename.assign(fname);
 | 
			
		||||
	m_Filename = fname;
 | 
			
		||||
	clear(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +51,9 @@ void CModule::clear(bool clearFilename)
 | 
			
		||||
	m_Status = MODULE_NONE;
 | 
			
		||||
	
 | 
			
		||||
	if (clearFilename)
 | 
			
		||||
		m_Filename.assign("unknown");
 | 
			
		||||
	{
 | 
			
		||||
		m_Filename = "unknown";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// new
 | 
			
		||||
	m_Amxx = false;
 | 
			
		||||
@@ -61,7 +63,7 @@ void CModule::clear(bool clearFilename)
 | 
			
		||||
	m_InfoNew.reload = 0;
 | 
			
		||||
	m_MissingFunc = NULL;
 | 
			
		||||
 | 
			
		||||
	for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<m_DestroyableIndexes.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		delete [] m_Natives[m_DestroyableIndexes[i]];
 | 
			
		||||
	}
 | 
			
		||||
@@ -96,12 +98,12 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
 | 
			
		||||
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
 | 
			
		||||
{
 | 
			
		||||
	AMX_NATIVE_INFO *curlist;
 | 
			
		||||
	for (size_t i=0; i<m_Natives.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<m_Natives.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		curlist = m_Natives[i];
 | 
			
		||||
		bool changed = false;
 | 
			
		||||
		bool found = false;
 | 
			
		||||
		CVector<size_t> newlist;
 | 
			
		||||
		ke::Vector<size_t> newlist;
 | 
			
		||||
		for (size_t j=0; curlist[j].func != NULL; j++)
 | 
			
		||||
		{
 | 
			
		||||
			found = false;
 | 
			
		||||
@@ -118,22 +120,22 @@ void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
 | 
			
		||||
				changed = true;
 | 
			
		||||
				//don't break, we have to search it all
 | 
			
		||||
			} else {
 | 
			
		||||
				newlist.push_back(j);
 | 
			
		||||
				newlist.append(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++)
 | 
			
		||||
			AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.length()+1];
 | 
			
		||||
			for (size_t j=0; j<newlist.length(); 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;
 | 
			
		||||
			rlist[newlist.length()].func = NULL;
 | 
			
		||||
			rlist[newlist.length()].name = NULL;
 | 
			
		||||
			m_Natives[i] = rlist;
 | 
			
		||||
			m_DestroyableIndexes.push_back(i);
 | 
			
		||||
			m_DestroyableIndexes.append(i);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -164,7 +166,7 @@ bool CModule::attachModule()
 | 
			
		||||
				m_Status = MODULE_LOADED;
 | 
			
		||||
				break;
 | 
			
		||||
			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\") returned \"Invalid parameter\" from Attach func.", m_Filename.chars(), getVersion());
 | 
			
		||||
				m_Status = MODULE_INTERROR;
 | 
			
		||||
				return false;
 | 
			
		||||
			case AMXX_FUNC_NOT_PRESENT:
 | 
			
		||||
@@ -172,7 +174,7 @@ bool CModule::attachModule()
 | 
			
		||||
				m_MissingFunc = g_LastRequestedFunc;
 | 
			
		||||
				return false;
 | 
			
		||||
			default:
 | 
			
		||||
				AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
 | 
			
		||||
				AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.chars(), getVersion());
 | 
			
		||||
				m_Status = MODULE_BADLOAD;
 | 
			
		||||
				return false;
 | 
			
		||||
		}
 | 
			
		||||
@@ -195,11 +197,11 @@ bool CModule::queryModule()
 | 
			
		||||
	if (m_Status != MODULE_NONE)				// don't check if already queried
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	m_Handle = DLLOAD(m_Filename.c_str());		// load file
 | 
			
		||||
	m_Handle = DLLOAD(m_Filename.chars());		// load file
 | 
			
		||||
	if (!m_Handle)
 | 
			
		||||
	{
 | 
			
		||||
#if defined(__linux__) || defined(__APPLE__)
 | 
			
		||||
		AMXXLOG_Log("[AMXX] Module \"%s\" failed to load (%s)", m_Filename.c_str(), dlerror());
 | 
			
		||||
		AMXXLOG_Log("[AMXX] Module \"%s\" failed to load (%s)", m_Filename.chars(), dlerror());
 | 
			
		||||
#endif
 | 
			
		||||
		m_Status = MODULE_BADLOAD;
 | 
			
		||||
		return false;
 | 
			
		||||
@@ -225,7 +227,7 @@ bool CModule::queryModule()
 | 
			
		||||
		switch (retVal)
 | 
			
		||||
		{
 | 
			
		||||
			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\") returned \"Invalid parameter\" from Attach func.", m_Filename.chars(), getVersion());
 | 
			
		||||
				m_Status = MODULE_INTERROR;
 | 
			
		||||
				return false;
 | 
			
		||||
			case AMXX_IFVERS:
 | 
			
		||||
@@ -237,7 +239,7 @@ bool CModule::queryModule()
 | 
			
		||||
						g_ModuleCallReason = ModuleCall_Query;
 | 
			
		||||
						g_CurrentlyCalledModule = this;
 | 
			
		||||
						retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
 | 
			
		||||
                        g_CurrentlyCalledModule = NULL;
 | 
			
		||||
						g_CurrentlyCalledModule = NULL;
 | 
			
		||||
						g_ModuleCallReason = ModuleCall_NotCalled;
 | 
			
		||||
						if (retVal == AMXX_OK)
 | 
			
		||||
						{
 | 
			
		||||
@@ -263,7 +265,7 @@ bool CModule::queryModule()
 | 
			
		||||
			case AMXX_OK:
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
 | 
			
		||||
				AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.chars(), getVersion());
 | 
			
		||||
				m_Status = MODULE_BADLOAD;
 | 
			
		||||
				return false;
 | 
			
		||||
		}
 | 
			
		||||
@@ -282,18 +284,18 @@ bool CModule::queryModule()
 | 
			
		||||
		if (checkGame_New)
 | 
			
		||||
		{
 | 
			
		||||
			// This is an optional check; do not fail modules that do not have it
 | 
			
		||||
			int ret = checkGame_New(g_mod_name.c_str());
 | 
			
		||||
			int ret = checkGame_New(g_mod_name.chars());
 | 
			
		||||
 | 
			
		||||
			if (ret != AMXX_GAME_OK)
 | 
			
		||||
			{
 | 
			
		||||
				switch (ret)
 | 
			
		||||
				{
 | 
			
		||||
				case AMXX_GAME_BAD:
 | 
			
		||||
					AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") reported that it cannot load on game \"%s\"", m_Filename.c_str(), getVersion(), g_mod_name.c_str());
 | 
			
		||||
					AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") reported that it cannot load on game \"%s\"", m_Filename.chars(), getVersion(), g_mod_name.chars());
 | 
			
		||||
					m_Status = MODULE_BADGAME;
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an unknown CheckGame code (value: %d)", m_Filename.c_str(), getVersion(), ret);
 | 
			
		||||
					AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an unknown CheckGame code (value: %d)", m_Filename.chars(), getVersion(), ret);
 | 
			
		||||
					m_Status = MODULE_BADLOAD;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,7 @@ struct amxx_module_info_s
 | 
			
		||||
 | 
			
		||||
class CModule 
 | 
			
		||||
{
 | 
			
		||||
	String m_Filename;				// Filename
 | 
			
		||||
	ke::AString m_Filename;         // Filename
 | 
			
		||||
	
 | 
			
		||||
	bool m_Metamod;					// Using metamod?
 | 
			
		||||
	bool m_Amxx;					// Using new module interface?
 | 
			
		||||
@@ -87,20 +87,20 @@ public:
 | 
			
		||||
	inline const char* getName() const { return m_InfoNew.name; }
 | 
			
		||||
	inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; }	// new
 | 
			
		||||
	inline int getStatusValue() { return m_Status; }
 | 
			
		||||
	inline bool operator==(const char* fname) { return !strcmp(m_Filename.c_str(), fname); }
 | 
			
		||||
	inline bool operator==(const char* fname) { return !strcmp(m_Filename.chars(), fname); }
 | 
			
		||||
	inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
 | 
			
		||||
	inline bool isAmxx() const { return m_Amxx; }
 | 
			
		||||
	inline const char *getMissingFunc() const { return m_MissingFunc; }
 | 
			
		||||
	inline const char *getFilename() { return m_Filename.c_str(); }
 | 
			
		||||
	inline const char *getFilename() { return m_Filename.chars(); }
 | 
			
		||||
	inline bool IsMetamod() { return m_Metamod; }
 | 
			
		||||
	
 | 
			
		||||
	void CallPluginsLoaded();
 | 
			
		||||
	void CallPluginsUnloaded();
 | 
			
		||||
	void CallPluginsUnloading();
 | 
			
		||||
 | 
			
		||||
	CVector<AMX_NATIVE_INFO*> m_Natives;
 | 
			
		||||
	CVector<AMX_NATIVE_INFO*> m_NewNatives; // Natives for new (AMXX, not AMX) plugins only
 | 
			
		||||
	CVector<size_t> m_DestroyableIndexes;
 | 
			
		||||
	ke::Vector<AMX_NATIVE_INFO*> m_Natives;
 | 
			
		||||
	ke::Vector<AMX_NATIVE_INFO*> m_NewNatives; // Natives for new (AMXX, not AMX) plugins only
 | 
			
		||||
	ke::Vector<size_t> m_DestroyableIndexes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //CMODULE_H
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "CPlugin.h"
 | 
			
		||||
#include "CForward.h"
 | 
			
		||||
#include "CFile.h"
 | 
			
		||||
#include "amx.h"
 | 
			
		||||
#include "natives.h"
 | 
			
		||||
#include "debugger.h"
 | 
			
		||||
@@ -78,9 +77,9 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
 | 
			
		||||
	int debugFlag = 0;
 | 
			
		||||
	const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins");
 | 
			
		||||
	
 | 
			
		||||
	String line;
 | 
			
		||||
	char line[512];
 | 
			
		||||
 | 
			
		||||
	List<String *>::iterator block_iter;
 | 
			
		||||
	List<ke::AString *>::iterator block_iter;
 | 
			
		||||
 | 
			
		||||
	while (!feof(fp)) 
 | 
			
		||||
	{
 | 
			
		||||
@@ -89,10 +88,11 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
 | 
			
		||||
		debug[0] = '\0';
 | 
			
		||||
		debugFlag = 0;
 | 
			
		||||
		
 | 
			
		||||
		line.clear();
 | 
			
		||||
		line._fread(fp);
 | 
			
		||||
		line[0] = '\0';
 | 
			
		||||
		fgets(line, sizeof(line), fp);
 | 
			
		||||
 | 
			
		||||
		/** quick hack */
 | 
			
		||||
		char *ptr = const_cast<char *>(line.c_str());
 | 
			
		||||
		char *ptr = line;
 | 
			
		||||
		while (*ptr)
 | 
			
		||||
		{
 | 
			
		||||
			if (*ptr == ';')
 | 
			
		||||
@@ -102,7 +102,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
 | 
			
		||||
				ptr++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		sscanf(line.c_str(), "%s %s", pluginName, debug);
 | 
			
		||||
		sscanf(line, "%s %s", pluginName, debug);
 | 
			
		||||
		
 | 
			
		||||
		if (!isalnum(*pluginName))
 | 
			
		||||
		{
 | 
			
		||||
@@ -185,7 +185,7 @@ void CPluginMngr::clear()
 | 
			
		||||
		pNatives = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	List<String *>::iterator iter = m_BlockList.begin();
 | 
			
		||||
	List<ke::AString *>::iterator iter = m_BlockList.begin();
 | 
			
		||||
	while (iter != m_BlockList.end())
 | 
			
		||||
	{
 | 
			
		||||
		delete (*iter);
 | 
			
		||||
@@ -226,7 +226,7 @@ CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
 | 
			
		||||
	
 | 
			
		||||
	CPlugin*a = head;
 | 
			
		||||
	
 | 
			
		||||
	while (a && strncmp(a->name.c_str(), name, len))
 | 
			
		||||
	while (a && strncmp(a->name.chars(), name, len))
 | 
			
		||||
		a = a->next;
 | 
			
		||||
	
 | 
			
		||||
	return a;
 | 
			
		||||
@@ -238,7 +238,7 @@ void CPluginMngr::CPlugin::AddToFailCounter(unsigned int i)
 | 
			
		||||
	if ((failcounter >= 3)
 | 
			
		||||
		&& (status ))
 | 
			
		||||
	{
 | 
			
		||||
		errorMsg.assign("This plugin is non-GPL which violates AMX Mod X's license.");
 | 
			
		||||
		errorMsg = "This plugin is non-GPL which violates AMX Mod X's license.";
 | 
			
		||||
		status = ps_bad_load;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -271,9 +271,9 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
 | 
			
		||||
	const char* unk = "unknown";
 | 
			
		||||
	
 | 
			
		||||
	failcounter = 0;
 | 
			
		||||
	title.assign(unk);
 | 
			
		||||
	author.assign(unk);
 | 
			
		||||
	version.assign(unk);
 | 
			
		||||
	title = unk;
 | 
			
		||||
	author = unk;
 | 
			
		||||
	version = unk;
 | 
			
		||||
	
 | 
			
		||||
	char file[256];
 | 
			
		||||
	char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
 | 
			
		||||
@@ -382,7 +382,7 @@ void CPluginMngr::CPlugin::Finalize()
 | 
			
		||||
			{
 | 
			
		||||
				status = ps_bad_load;
 | 
			
		||||
				sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
 | 
			
		||||
				errorMsg.assign(buffer);
 | 
			
		||||
				errorMsg = buffer;
 | 
			
		||||
				amx.error = AMX_ERR_NOTFOUND;
 | 
			
		||||
			} else {
 | 
			
		||||
				amx_RegisterToAny(&amx, invalid_native);
 | 
			
		||||
@@ -390,13 +390,13 @@ void CPluginMngr::CPlugin::Finalize()
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		status = ps_bad_load;
 | 
			
		||||
		errorMsg.assign(buffer);
 | 
			
		||||
		errorMsg = buffer;
 | 
			
		||||
		amx.error = AMX_ERR_NOTFOUND;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (old_status != status)
 | 
			
		||||
	{
 | 
			
		||||
		AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
 | 
			
		||||
		AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.chars(), errorMsg.chars());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -484,7 +484,7 @@ char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pl->path.assign(file);
 | 
			
		||||
	pl->path = file;
 | 
			
		||||
 | 
			
		||||
	bufsize = pl->bufsize;
 | 
			
		||||
 | 
			
		||||
@@ -595,8 +595,8 @@ void CPluginMngr::CacheAndLoadModules(const char *plugin)
 | 
			
		||||
	cell tag_id;
 | 
			
		||||
	amx_NumTags(&amx, &num);
 | 
			
		||||
 | 
			
		||||
	CVector<LibDecoder *> expects;
 | 
			
		||||
	CVector<LibDecoder *> defaults;
 | 
			
		||||
	ke::Vector<LibDecoder *> expects;
 | 
			
		||||
	ke::Vector<LibDecoder *> defaults;
 | 
			
		||||
	CStack<LibDecoder *> delstack;
 | 
			
		||||
	for (int i=0; i<num; i++)
 | 
			
		||||
	{
 | 
			
		||||
@@ -613,19 +613,19 @@ void CPluginMngr::CacheAndLoadModules(const char *plugin)
 | 
			
		||||
				} else if ( (dc->cmd == LibCmd_ExpectClass) ||
 | 
			
		||||
							(dc->cmd == LibCmd_ExpectLib) ) 
 | 
			
		||||
				{
 | 
			
		||||
					expects.push_back(dc);
 | 
			
		||||
					expects.append(dc);
 | 
			
		||||
				} else if (dc->cmd == LibCmd_DefaultLib) {
 | 
			
		||||
					defaults.push_back(dc);
 | 
			
		||||
					defaults.append(dc);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (size_t i=0; i<expects.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<expects.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		RunLibCommand(expects[i]);
 | 
			
		||||
	}
 | 
			
		||||
	for (size_t i=0; i<defaults.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<defaults.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		RunLibCommand(defaults[i]);
 | 
			
		||||
	}
 | 
			
		||||
@@ -655,7 +655,7 @@ void CPluginMngr::CALMFromFile(const char *file)
 | 
			
		||||
	// Find now folder
 | 
			
		||||
	char pluginName[256];
 | 
			
		||||
	char line[256];
 | 
			
		||||
	String rline;
 | 
			
		||||
	char rline[256];
 | 
			
		||||
 | 
			
		||||
	while (!feof(fp)) 
 | 
			
		||||
	{
 | 
			
		||||
@@ -677,24 +677,26 @@ void CPluginMngr::CALMFromFile(const char *file)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rline.assign(line);
 | 
			
		||||
		rline.trim();
 | 
			
		||||
		strncopy(rline, line, sizeof(rline));
 | 
			
		||||
		UTIL_TrimLeft(rline);
 | 
			
		||||
		UTIL_TrimRight(rline);
 | 
			
		||||
 | 
			
		||||
		pluginName[0] = '\0';
 | 
			
		||||
		sscanf(rline.c_str(), "%s", pluginName);
 | 
			
		||||
		sscanf(rline, "%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);
 | 
			
		||||
			const char *_ptr = rline + strlen(pluginName);
 | 
			
		||||
			while (*_ptr != '\0'  && isspace(*_ptr))
 | 
			
		||||
			{
 | 
			
		||||
				_ptr++;
 | 
			
		||||
			}
 | 
			
		||||
			if ((*_ptr != '\0') && !strcmp(_ptr, "disabled"))
 | 
			
		||||
			{
 | 
			
		||||
				String *pString = new String(pluginName);
 | 
			
		||||
				ke::AString *pString = new ke::AString(pluginName);
 | 
			
		||||
				m_BlockList.push_back(pString);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,10 +10,10 @@
 | 
			
		||||
#ifndef PLUGIN_H
 | 
			
		||||
#define PLUGIN_H
 | 
			
		||||
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
#include "sh_list.h"
 | 
			
		||||
#include "amx.h"
 | 
			
		||||
#include "amxxfile.h"
 | 
			
		||||
#include <am-string.h>
 | 
			
		||||
 | 
			
		||||
// *****************************************************
 | 
			
		||||
// class CPluginMngr
 | 
			
		||||
@@ -43,11 +43,11 @@ public:
 | 
			
		||||
		AMX amx;
 | 
			
		||||
		void* code;
 | 
			
		||||
		
 | 
			
		||||
		String name;
 | 
			
		||||
		String version;
 | 
			
		||||
		String title;
 | 
			
		||||
		String author;
 | 
			
		||||
		String errorMsg;
 | 
			
		||||
		ke::AString name;
 | 
			
		||||
		ke::AString version;
 | 
			
		||||
		ke::AString title;
 | 
			
		||||
		ke::AString author;
 | 
			
		||||
		ke::AString errorMsg;
 | 
			
		||||
		
 | 
			
		||||
		unsigned int failcounter;
 | 
			
		||||
		int m_PauseFwd;
 | 
			
		||||
@@ -64,19 +64,19 @@ public:
 | 
			
		||||
		cell* m_pNullStringOfs;
 | 
			
		||||
		cell* m_pNullVectorOfs;
 | 
			
		||||
	public:
 | 
			
		||||
		inline const char* getName() { return name.c_str();}
 | 
			
		||||
		inline const char* getVersion() { return version.c_str();}
 | 
			
		||||
		inline const char* getTitle() { return title.c_str();}
 | 
			
		||||
		inline const char* getAuthor() { return author.c_str();}
 | 
			
		||||
		inline const char* getError() { return errorMsg.c_str();}
 | 
			
		||||
		inline const char* getName() { return name.chars();}
 | 
			
		||||
		inline const char* getVersion() { return version.chars();}
 | 
			
		||||
		inline const char* getTitle() { return title.chars();}
 | 
			
		||||
		inline const char* getAuthor() { return author.chars();}
 | 
			
		||||
		inline const char* getError() { return errorMsg.chars();}
 | 
			
		||||
		inline int getStatusCode() { return status; }
 | 
			
		||||
		inline int getId() const { return id; }
 | 
			
		||||
		inline AMX* getAMX() { return &amx; }
 | 
			
		||||
		inline const AMX* getAMX() const { return &amx; }
 | 
			
		||||
		inline void setTitle(const char* n) { title.assign(n); }
 | 
			
		||||
		inline void setAuthor(const char* n) { author.assign(n); }
 | 
			
		||||
		inline void setVersion(const char* n) { version.assign(n); }
 | 
			
		||||
		inline void setError(const char* n) { errorMsg.assign(n); }
 | 
			
		||||
		inline void setTitle(const char* n) { title = n; }
 | 
			
		||||
		inline void setAuthor(const char* n) { author =n; }
 | 
			
		||||
		inline void setVersion(const char* n) { version = n; }
 | 
			
		||||
		inline void setError(const char* n) { errorMsg = n; }
 | 
			
		||||
		inline bool isValid() const { return (status >= ps_paused); }
 | 
			
		||||
		inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
 | 
			
		||||
		inline bool isStopped() const { return (status == ps_stopped); }
 | 
			
		||||
@@ -141,7 +141,7 @@ public:
 | 
			
		||||
		CAmxxReader *file;
 | 
			
		||||
		size_t bufsize;
 | 
			
		||||
		char *buffer;
 | 
			
		||||
		String path;
 | 
			
		||||
		ke::AString path;
 | 
			
		||||
	};
 | 
			
		||||
	char *ReadIntoOrFromCache(const char *file, size_t &bufsize);
 | 
			
		||||
	void InvalidateCache();
 | 
			
		||||
@@ -150,7 +150,7 @@ public:
 | 
			
		||||
	void CALMFromFile(const char *file);
 | 
			
		||||
private:
 | 
			
		||||
	List<plcache_entry *> m_plcache;
 | 
			
		||||
	List<String *> m_BlockList;
 | 
			
		||||
	List<ke::AString *> m_BlockList;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //PLUGIN_H
 | 
			
		||||
 
 | 
			
		||||
@@ -1,391 +0,0 @@
 | 
			
		||||
// vim: set ts=4 sw=4 tw=99 noet:
 | 
			
		||||
//
 | 
			
		||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
 | 
			
		||||
// Copyright (C) The AMX Mod X Development Team.
 | 
			
		||||
//
 | 
			
		||||
// This software is licensed under the GNU General Public License, version 3 or higher.
 | 
			
		||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
 | 
			
		||||
//     https://alliedmods.net/amxmodx-license
 | 
			
		||||
 | 
			
		||||
#ifndef _INCLUDE_CSTRING_H
 | 
			
		||||
#define _INCLUDE_CSTRING_H
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
//by David "BAILOPAN" Anderson
 | 
			
		||||
class String
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	String() 
 | 
			
		||||
	{
 | 
			
		||||
		v = NULL;
 | 
			
		||||
		a_size = 0;
 | 
			
		||||
		//assign("");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~String()
 | 
			
		||||
	{ 
 | 
			
		||||
		if (v) 
 | 
			
		||||
			delete [] v; 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String(const char *src) 
 | 
			
		||||
	{
 | 
			
		||||
		v = NULL; 
 | 
			
		||||
		a_size = 0;
 | 
			
		||||
		assign(src); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char * _fread(FILE *fp) 	 
 | 
			
		||||
	{ 	 
 | 
			
		||||
		Grow(512, false); 	 
 | 
			
		||||
		char *ret = fgets(v, 511, fp); 	 
 | 
			
		||||
		return ret; 	 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String(const String &src) 
 | 
			
		||||
	{
 | 
			
		||||
		v = NULL;
 | 
			
		||||
		a_size = 0;
 | 
			
		||||
		assign(src.c_str()); 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const char *c_str() { return v?v:""; }
 | 
			
		||||
 | 
			
		||||
	const char *c_str() const { return v?v:""; }
 | 
			
		||||
 | 
			
		||||
	void append(const char *t)
 | 
			
		||||
	{
 | 
			
		||||
		Grow(size() + strlen(t) + 1);
 | 
			
		||||
		strcat(v, t);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void append(const char c)
 | 
			
		||||
	{
 | 
			
		||||
		size_t len = size();
 | 
			
		||||
		Grow(len + 2);
 | 
			
		||||
		v[len] = c;
 | 
			
		||||
		v[len + 1] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void append(String &d)
 | 
			
		||||
	{
 | 
			
		||||
		append(d.c_str());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void assign(const String &src)
 | 
			
		||||
	{
 | 
			
		||||
		assign(src.c_str());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void assign(const char *d)
 | 
			
		||||
	{
 | 
			
		||||
		if (!d)
 | 
			
		||||
		{
 | 
			
		||||
			clear();
 | 
			
		||||
		} else {
 | 
			
		||||
			size_t len = strlen(d);
 | 
			
		||||
			Grow(len + 1, false);
 | 
			
		||||
			memcpy(v, d, len);
 | 
			
		||||
			v[len] = '\0';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void clear()
 | 
			
		||||
	{
 | 
			
		||||
		if (v)
 | 
			
		||||
			v[0] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int compare (const char *d) const
 | 
			
		||||
	{
 | 
			
		||||
		if (!v)
 | 
			
		||||
			return strcmp("", d);
 | 
			
		||||
		else
 | 
			
		||||
			return strcmp(v, d);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//Added this for amxx inclusion
 | 
			
		||||
	bool empty() const
 | 
			
		||||
	{
 | 
			
		||||
		if (!v)
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		if (v[0] == '\0')
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t size() const
 | 
			
		||||
	{
 | 
			
		||||
		if (v)
 | 
			
		||||
			return strlen(v);
 | 
			
		||||
		else
 | 
			
		||||
			return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int find(const char c, int index = 0)
 | 
			
		||||
	{
 | 
			
		||||
		int len = static_cast<int>(size());
 | 
			
		||||
		if (len < 1)
 | 
			
		||||
			return npos;
 | 
			
		||||
		if (index >= len || index < 0)
 | 
			
		||||
			return npos;
 | 
			
		||||
		int i = 0;
 | 
			
		||||
		for (i=index; i<len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (v[i] == c)
 | 
			
		||||
			{
 | 
			
		||||
				return i;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return npos;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool is_space(int c)
 | 
			
		||||
	{
 | 
			
		||||
		if (c == '\f' || c == '\n' ||
 | 
			
		||||
			c == '\t' || c == '\r' ||
 | 
			
		||||
			c == '\v' || c == ' ')
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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()
 | 
			
		||||
	{
 | 
			
		||||
		if (!v)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		unsigned int i = 0;
 | 
			
		||||
		unsigned int j = 0;
 | 
			
		||||
		size_t len = strlen(v);
 | 
			
		||||
 | 
			
		||||
		if (len == 1)
 | 
			
		||||
		{
 | 
			
		||||
			if (is_space(v[i]))
 | 
			
		||||
			{
 | 
			
		||||
				clear();
 | 
			
		||||
				return;
 | 
			
		||||
			} 
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		unsigned char c0 = v[0];
 | 
			
		||||
 | 
			
		||||
		if (is_space(c0))
 | 
			
		||||
		{
 | 
			
		||||
			for (i=0; i<len; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
 | 
			
		||||
				{
 | 
			
		||||
					erase(0, i);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		len = strlen(v);
 | 
			
		||||
 | 
			
		||||
		if (len < 1)
 | 
			
		||||
		{
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (is_space(v[len-1]))
 | 
			
		||||
		{
 | 
			
		||||
			for (i=len-1; i<len; i--)
 | 
			
		||||
			{
 | 
			
		||||
				if (!is_space(v[i])
 | 
			
		||||
					|| (is_space(v[i]) && i==0))
 | 
			
		||||
				{
 | 
			
		||||
					erase(i+1, j);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
				j++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (len == 1)
 | 
			
		||||
		{
 | 
			
		||||
			if (is_space(v[0]))
 | 
			
		||||
			{
 | 
			
		||||
				clear();
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void erase(unsigned int start, int num = npos)
 | 
			
		||||
	{
 | 
			
		||||
		if (!v)
 | 
			
		||||
			return;
 | 
			
		||||
		unsigned int i = 0;
 | 
			
		||||
		size_t len = size();
 | 
			
		||||
		//check for bounds
 | 
			
		||||
		if (num == npos || start+num > len-start)
 | 
			
		||||
			num = len - start;
 | 
			
		||||
		//do the erasing
 | 
			
		||||
		bool copyflag = false;
 | 
			
		||||
		for (i=0; i<len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (i>=start && i<start+num)
 | 
			
		||||
			{
 | 
			
		||||
				if (i+num < len)
 | 
			
		||||
				{	
 | 
			
		||||
					v[i] = v[i+num];
 | 
			
		||||
				} else {
 | 
			
		||||
					v[i] = 0;
 | 
			
		||||
				}
 | 
			
		||||
				copyflag = true;
 | 
			
		||||
			} else if (copyflag) {
 | 
			
		||||
				if (i+num < len)
 | 
			
		||||
				{
 | 
			
		||||
					v[i] = v[i+num];
 | 
			
		||||
				} else {
 | 
			
		||||
					v[i] = 0;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		len -= num;
 | 
			
		||||
		v[len] = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String substr(unsigned int index, int num = npos)
 | 
			
		||||
	{
 | 
			
		||||
		if (!v)
 | 
			
		||||
		{
 | 
			
		||||
			String b("");
 | 
			
		||||
			return b;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		String ns;
 | 
			
		||||
 | 
			
		||||
		size_t len = size();
 | 
			
		||||
 | 
			
		||||
		if (index >= len || !v)
 | 
			
		||||
			return ns;
 | 
			
		||||
		
 | 
			
		||||
		if (num == npos)
 | 
			
		||||
		{
 | 
			
		||||
			num = len - index;
 | 
			
		||||
		} else if (index+num >= len) {
 | 
			
		||||
			num = len - index;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		unsigned int i = 0;
 | 
			
		||||
		unsigned int nslen = num + 2;
 | 
			
		||||
 | 
			
		||||
		ns.Grow(nslen);
 | 
			
		||||
 | 
			
		||||
		for (i=index; i<index+num; i++)
 | 
			
		||||
			ns.append(v[i]);
 | 
			
		||||
 | 
			
		||||
		return ns;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void toLower()
 | 
			
		||||
	{
 | 
			
		||||
		if (!v)
 | 
			
		||||
			return;
 | 
			
		||||
		unsigned int i = 0;
 | 
			
		||||
		size_t len = strlen(v);
 | 
			
		||||
		for (i=0; i<len; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (v[i] >= 65 && v[i] <= 90)
 | 
			
		||||
				v[i] &= ~(1<<5);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String & operator = (const String &src)
 | 
			
		||||
	{
 | 
			
		||||
		assign(src);
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String & operator = (const char *src)
 | 
			
		||||
	{
 | 
			
		||||
		assign(src);
 | 
			
		||||
		return *this;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char operator [] (unsigned int index)
 | 
			
		||||
	{
 | 
			
		||||
		if (index > size() || !v)
 | 
			
		||||
		{
 | 
			
		||||
			return -1;
 | 
			
		||||
		} else {
 | 
			
		||||
			return v[index];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int at(int a)
 | 
			
		||||
	{
 | 
			
		||||
		if (a < 0 || a >= (int)size() || !v)
 | 
			
		||||
			return -1;
 | 
			
		||||
 | 
			
		||||
		return v[a];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool at(int at, char c)
 | 
			
		||||
	{
 | 
			
		||||
		if (at < 0 || at >= (int)size() || !v)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		v[at] = c;
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void Grow(unsigned int d, bool copy=true)
 | 
			
		||||
	{
 | 
			
		||||
		if (d <= a_size)
 | 
			
		||||
			return;
 | 
			
		||||
		char *n = new char[d + 1];
 | 
			
		||||
		if (copy && v)
 | 
			
		||||
			strcpy(n, v);
 | 
			
		||||
		if (v)
 | 
			
		||||
			delete [] v;
 | 
			
		||||
		else
 | 
			
		||||
			strcpy(n, "");			
 | 
			
		||||
		v = n;
 | 
			
		||||
		a_size = d + 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char *v;
 | 
			
		||||
	unsigned int a_size;
 | 
			
		||||
public:
 | 
			
		||||
	static const int npos = -1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif //_INCLUDE_CSTRING_H
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "CVault.h"
 | 
			
		||||
#include "CFile.h"
 | 
			
		||||
#include "CFileSystem.h"
 | 
			
		||||
 | 
			
		||||
// *****************************************************
 | 
			
		||||
// class Vault
 | 
			
		||||
@@ -39,7 +39,7 @@ void Vault::put(const char* k, const char* v)
 | 
			
		||||
 | 
			
		||||
	if (*a)
 | 
			
		||||
	{
 | 
			
		||||
		(*a)->value.assign(v);
 | 
			
		||||
		(*a)->value = v;
 | 
			
		||||
		(*a)->number = atoi(v);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
@@ -57,7 +57,7 @@ Vault::Obj** Vault::find(const char* n)
 | 
			
		||||
 | 
			
		||||
	while (*a)
 | 
			
		||||
	{
 | 
			
		||||
		if (strcmp((*a)->key.c_str(), n) == 0)
 | 
			
		||||
		if (strcmp((*a)->key.chars(), n) == 0)
 | 
			
		||||
			return a;
 | 
			
		||||
 | 
			
		||||
		a = &(*a)->next;
 | 
			
		||||
@@ -86,7 +86,7 @@ const char* Vault::get(const char* n)
 | 
			
		||||
 | 
			
		||||
	if (b == 0) return "";
 | 
			
		||||
 | 
			
		||||
	return b->value.c_str();
 | 
			
		||||
	return b->value.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Vault::clear()
 | 
			
		||||
@@ -112,45 +112,74 @@ void Vault::remove(const char* n)
 | 
			
		||||
 | 
			
		||||
void Vault::setSource(const char* n)
 | 
			
		||||
{
 | 
			
		||||
	path.assign(n);
 | 
			
		||||
	path = n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Vault::loadVault()
 | 
			
		||||
{
 | 
			
		||||
	if (path.empty()) return false;
 | 
			
		||||
	if (!path.length())
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clear();
 | 
			
		||||
 | 
			
		||||
	File a(path.c_str(), "r");
 | 
			
		||||
	FILE *fp = fopen(path.chars(), "r");
 | 
			
		||||
 | 
			
		||||
	if (!a) return false;
 | 
			
		||||
 | 
			
		||||
	const int sz = 512;
 | 
			
		||||
	char value[sz + 1];
 | 
			
		||||
	char key[sz + 1];
 | 
			
		||||
 | 
			
		||||
	while (a >> key && a.skipWs() && a.getline(value, sz))
 | 
			
		||||
	if (!fp)
 | 
			
		||||
	{
 | 
			
		||||
		if (isalpha(*key))
 | 
			
		||||
			put(key, value);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	char lineRead[512];
 | 
			
		||||
	char key[sizeof(lineRead) + 1];
 | 
			
		||||
	char value[sizeof(lineRead) + 1];
 | 
			
		||||
 | 
			
		||||
	while (fgets(lineRead, sizeof(lineRead), fp))
 | 
			
		||||
	{
 | 
			
		||||
		UTIL_TrimLeft(lineRead);
 | 
			
		||||
 | 
			
		||||
		if (!*lineRead || *lineRead == ';')
 | 
			
		||||
		{
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sscanf(lineRead, "%s%*[ \t]%[^\n]", key, value);
 | 
			
		||||
 | 
			
		||||
		if (isalpha(*key))
 | 
			
		||||
		{
 | 
			
		||||
			put(key, value);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Vault::saveVault()
 | 
			
		||||
{
 | 
			
		||||
	if (path.empty()) return false;
 | 
			
		||||
	if (!path.length())
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	File a(path.c_str(), "w");
 | 
			
		||||
	FILE *fp = fopen(path.chars(), "w");
 | 
			
		||||
 | 
			
		||||
	if (!a) return false;
 | 
			
		||||
	if (!fp)
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a << "; Don't modify!" << '\n';
 | 
			
		||||
	fputs("; Don't modify!\n", fp);
 | 
			
		||||
 | 
			
		||||
	for (Obj* b = head; b; b = b->next)
 | 
			
		||||
		a << b->key << '\t' << b->value << '\n';
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(fp, "%s\t%s\n", b->key.chars(), b->value.chars());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fclose(fp);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@
 | 
			
		||||
#ifndef VAULT_CUSTOM_H
 | 
			
		||||
#define VAULT_CUSTOM_H
 | 
			
		||||
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
#include "CList.h"
 | 
			
		||||
 | 
			
		||||
// *****************************************************
 | 
			
		||||
@@ -21,15 +20,15 @@ class Vault
 | 
			
		||||
{
 | 
			
		||||
	struct Obj
 | 
			
		||||
	{
 | 
			
		||||
		String key;
 | 
			
		||||
		String value;
 | 
			
		||||
		ke::AString key;
 | 
			
		||||
		ke::AString value;
 | 
			
		||||
 | 
			
		||||
		int number;
 | 
			
		||||
		Obj *next;
 | 
			
		||||
		Obj(const char* k, const char* v);
 | 
			
		||||
	} *head;
 | 
			
		||||
 | 
			
		||||
	String path;
 | 
			
		||||
	ke::AString path;
 | 
			
		||||
 | 
			
		||||
	Obj** find(const char* n);
 | 
			
		||||
 | 
			
		||||
@@ -62,8 +61,8 @@ public:
 | 
			
		||||
		iterator& operator++() { if (a) a = a->next; return *this; }
 | 
			
		||||
		bool operator==(const iterator& b) const { return a == b.a; }
 | 
			
		||||
		bool operator!=(const iterator& b) const { return !operator==(b); }
 | 
			
		||||
		String& key() const { return a->key; }
 | 
			
		||||
		String& value() const { return a->value; }
 | 
			
		||||
		ke::AString& key() const { return a->key; }
 | 
			
		||||
		ke::AString& value() const { return a->value; }
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	inline iterator begin() const { return iterator(head); }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,480 +0,0 @@
 | 
			
		||||
// vim: set ts=4 sw=4 tw=99 noet:
 | 
			
		||||
//
 | 
			
		||||
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
 | 
			
		||||
// Copyright (C) The AMX Mod X Development Team.
 | 
			
		||||
//
 | 
			
		||||
// This software is licensed under the GNU General Public License, version 3 or higher.
 | 
			
		||||
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
 | 
			
		||||
//     https://alliedmods.net/amxmodx-license
 | 
			
		||||
 | 
			
		||||
#ifndef __CVECTOR_H__
 | 
			
		||||
#define __CVECTOR_H__
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
// Vector
 | 
			
		||||
template <class T> class CVector
 | 
			
		||||
{
 | 
			
		||||
	bool Grow(size_t amount)
 | 
			
		||||
	{
 | 
			
		||||
		// automatic grow
 | 
			
		||||
		size_t newSize = m_Size * 2;
 | 
			
		||||
 | 
			
		||||
		if (newSize == 0)
 | 
			
		||||
		{
 | 
			
		||||
			newSize = 8;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		while (m_CurrentUsedSize + amount > newSize)
 | 
			
		||||
		{
 | 
			
		||||
			newSize *= 2;
 | 
			
		||||
		}
 | 
			
		||||
		T *newData = new T[newSize];
 | 
			
		||||
		if (!newData)
 | 
			
		||||
			return false;
 | 
			
		||||
		if (m_Data)
 | 
			
		||||
		{
 | 
			
		||||
			for (size_t i=0; i<m_CurrentUsedSize; i++)
 | 
			
		||||
				newData[i] = m_Data[i];
 | 
			
		||||
			delete [] m_Data;
 | 
			
		||||
		}
 | 
			
		||||
		m_Data = newData;
 | 
			
		||||
		m_Size = newSize;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool GrowIfNeeded(size_t amount)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_CurrentUsedSize + amount >= m_Size)
 | 
			
		||||
		{
 | 
			
		||||
			return Grow(amount);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool ChangeSize(size_t size)
 | 
			
		||||
	{
 | 
			
		||||
		// change size
 | 
			
		||||
		if (size == m_Size)
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		if (!size)
 | 
			
		||||
		{
 | 
			
		||||
			if (m_Data)
 | 
			
		||||
			{
 | 
			
		||||
				delete [] m_Data;
 | 
			
		||||
				m_Data = NULL;
 | 
			
		||||
				m_Size = 0;
 | 
			
		||||
			}
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		T *newData = new T[size];
 | 
			
		||||
		if (!newData)
 | 
			
		||||
			return false;
 | 
			
		||||
		if (m_Data)
 | 
			
		||||
		{
 | 
			
		||||
			size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
 | 
			
		||||
			for (size_t i=0; i<end; i++)
 | 
			
		||||
				newData[i] = m_Data[i];
 | 
			
		||||
			delete [] m_Data;
 | 
			
		||||
		}
 | 
			
		||||
		m_Data = newData;
 | 
			
		||||
		m_Size = size;
 | 
			
		||||
		if (m_CurrentUsedSize > m_Size)
 | 
			
		||||
			m_CurrentUsedSize = m_Size;
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void FreeMemIfPossible()
 | 
			
		||||
	{
 | 
			
		||||
		if (!m_Data)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if (!m_CurrentUsedSize)
 | 
			
		||||
		{
 | 
			
		||||
			ChangeSize(0);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t newSize = m_Size;
 | 
			
		||||
		while (m_CurrentUsedSize <= newSize / 2)
 | 
			
		||||
			newSize /= 2;
 | 
			
		||||
 | 
			
		||||
		if (newSize != m_Size)
 | 
			
		||||
			ChangeSize(newSize);
 | 
			
		||||
	}
 | 
			
		||||
protected:
 | 
			
		||||
	T *m_Data;
 | 
			
		||||
	size_t m_Size;
 | 
			
		||||
	size_t m_CurrentUsedSize;
 | 
			
		||||
public:
 | 
			
		||||
	class iterator
 | 
			
		||||
	{
 | 
			
		||||
	protected:
 | 
			
		||||
		T *m_Ptr;
 | 
			
		||||
	public:
 | 
			
		||||
		// constructors / destructors
 | 
			
		||||
		iterator()
 | 
			
		||||
		{
 | 
			
		||||
			m_Ptr = NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator(T * ptr)
 | 
			
		||||
		{
 | 
			
		||||
			m_Ptr = ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// member functions
 | 
			
		||||
		T * base()
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const T * base() const
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// operators
 | 
			
		||||
		T & operator*()
 | 
			
		||||
		{
 | 
			
		||||
			return *m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		T * operator->()
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator & operator++()		// preincrement
 | 
			
		||||
		{
 | 
			
		||||
			++m_Ptr;
 | 
			
		||||
			return (*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator operator++(int)	// postincrement
 | 
			
		||||
		{
 | 
			
		||||
			iterator tmp = *this;
 | 
			
		||||
			++m_Ptr;
 | 
			
		||||
			return tmp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator & operator--()		// predecrement
 | 
			
		||||
		{
 | 
			
		||||
			--m_Ptr;
 | 
			
		||||
			return (*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator operator--(int)	// postdecrememnt
 | 
			
		||||
		{
 | 
			
		||||
			iterator tmp = *this;
 | 
			
		||||
			--m_Ptr;
 | 
			
		||||
			return tmp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator==(T * right) const
 | 
			
		||||
		{
 | 
			
		||||
			return (m_Ptr == right);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator==(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return (m_Ptr == right.m_Ptr);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator!=(T * right) const
 | 
			
		||||
		{
 | 
			
		||||
			return (m_Ptr != right);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator!=(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return (m_Ptr != right.m_Ptr);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator & operator+=(size_t offset)
 | 
			
		||||
		{
 | 
			
		||||
			m_Ptr += offset;
 | 
			
		||||
			return (*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator & operator-=(size_t offset)
 | 
			
		||||
		{
 | 
			
		||||
			m_Ptr -= offset;
 | 
			
		||||
			return (*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator operator+(size_t offset) const
 | 
			
		||||
		{
 | 
			
		||||
			iterator tmp(*this);
 | 
			
		||||
			tmp.m_Ptr += offset;
 | 
			
		||||
			return tmp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		iterator operator-(size_t offset) const
 | 
			
		||||
		{
 | 
			
		||||
			iterator tmp(*this);
 | 
			
		||||
			tmp.m_Ptr -= offset;
 | 
			
		||||
			return tmp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		T & operator[](size_t offset)
 | 
			
		||||
		{
 | 
			
		||||
			return (*(*this + offset));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const T & operator[](size_t offset) const
 | 
			
		||||
		{
 | 
			
		||||
			return (*(*this + offset));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator<(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr < right.m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator>(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr > right.m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator<=(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr <= right.m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator>=(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr >= right.m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t operator-(const iterator & right) const
 | 
			
		||||
		{
 | 
			
		||||
			return m_Ptr - right.m_Ptr;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// constructors / destructors
 | 
			
		||||
	CVector<T>()
 | 
			
		||||
	{
 | 
			
		||||
		m_Size = 0;
 | 
			
		||||
		m_CurrentUsedSize = 0;
 | 
			
		||||
		m_Data = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CVector<T>(const CVector<T> & other)
 | 
			
		||||
	{
 | 
			
		||||
		// copy data
 | 
			
		||||
		m_Data = new T [other.m_CurrentUsedSize];
 | 
			
		||||
		m_Size = other.m_CurrentUsedSize;
 | 
			
		||||
		m_CurrentUsedSize = other.m_CurrentUsedSize;
 | 
			
		||||
		for (size_t i=0; i<other.m_CurrentUsedSize; i++)
 | 
			
		||||
			m_Data[i] = other.m_Data[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~CVector<T>()
 | 
			
		||||
	{
 | 
			
		||||
		clear();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// interface
 | 
			
		||||
	size_t size() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_CurrentUsedSize;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t capacity() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Size;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iterator begin() const
 | 
			
		||||
	{
 | 
			
		||||
		return iterator(m_Data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iterator end() const
 | 
			
		||||
	{
 | 
			
		||||
		return iterator(m_Data + m_CurrentUsedSize);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iterator iterAt(size_t pos)
 | 
			
		||||
	{
 | 
			
		||||
		if (pos > m_CurrentUsedSize)
 | 
			
		||||
			assert(0);
 | 
			
		||||
		return iterator(m_Data + pos);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool reserve(size_t newSize)
 | 
			
		||||
	{
 | 
			
		||||
		if (newSize > m_Size)
 | 
			
		||||
			return ChangeSize(newSize);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool push_back(const T & elem)
 | 
			
		||||
	{
 | 
			
		||||
		if (!GrowIfNeeded(1))
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m_Data[m_CurrentUsedSize++] = elem;
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void pop_back()
 | 
			
		||||
	{
 | 
			
		||||
		--m_CurrentUsedSize;
 | 
			
		||||
		if (m_CurrentUsedSize < 0)
 | 
			
		||||
			m_CurrentUsedSize = 0;
 | 
			
		||||
 | 
			
		||||
		FreeMemIfPossible();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool resize(size_t newSize)
 | 
			
		||||
	{
 | 
			
		||||
		if (!ChangeSize(newSize))
 | 
			
		||||
			return false;
 | 
			
		||||
		m_CurrentUsedSize = newSize;
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool empty() const
 | 
			
		||||
	{
 | 
			
		||||
		return (m_CurrentUsedSize == 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	T & at(size_t pos)
 | 
			
		||||
	{
 | 
			
		||||
		if (pos > m_CurrentUsedSize)
 | 
			
		||||
		{
 | 
			
		||||
			assert(0);
 | 
			
		||||
		}
 | 
			
		||||
		return m_Data[pos];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const  T & at(size_t pos) const
 | 
			
		||||
	{
 | 
			
		||||
		if (pos > m_CurrentUsedSize)
 | 
			
		||||
		{
 | 
			
		||||
			assert(0);
 | 
			
		||||
		}
 | 
			
		||||
		return m_Data[pos];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	T & operator[](size_t pos)
 | 
			
		||||
	{
 | 
			
		||||
		return at(pos);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const T & operator[](size_t pos) const
 | 
			
		||||
	{
 | 
			
		||||
		return at(pos);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	T & front()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_CurrentUsedSize < 1)
 | 
			
		||||
		{
 | 
			
		||||
			assert(0);
 | 
			
		||||
		}
 | 
			
		||||
		return m_Data[0];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const T & front() const
 | 
			
		||||
	{
 | 
			
		||||
		if (m_CurrentUsedSize < 1)
 | 
			
		||||
		{
 | 
			
		||||
			assert(0);
 | 
			
		||||
		}
 | 
			
		||||
		return m_Data[0];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	T & back()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_CurrentUsedSize < 1)
 | 
			
		||||
		{
 | 
			
		||||
			assert(0);
 | 
			
		||||
		}
 | 
			
		||||
		return m_Data[m_CurrentUsedSize - 1];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const T & back() const
 | 
			
		||||
	{
 | 
			
		||||
		if (m_CurrentUsedSize < 1)
 | 
			
		||||
		{
 | 
			
		||||
			assert(0);
 | 
			
		||||
		}
 | 
			
		||||
		return m_Data[m_CurrentUsedSize - 1];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iterator insert(iterator where, const T & value)
 | 
			
		||||
	{
 | 
			
		||||
		// validate iter
 | 
			
		||||
		if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
 | 
			
		||||
			return iterator(0);
 | 
			
		||||
 | 
			
		||||
		size_t ofs = where - begin();
 | 
			
		||||
 | 
			
		||||
		if (!GrowIfNeeded(1))
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		++m_CurrentUsedSize;
 | 
			
		||||
 | 
			
		||||
		where = begin() + ofs;
 | 
			
		||||
 | 
			
		||||
		// Move subsequent entries
 | 
			
		||||
		for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
 | 
			
		||||
			*(ptr + 1) = *ptr;
 | 
			
		||||
 | 
			
		||||
		*where.base() = value;
 | 
			
		||||
 | 
			
		||||
		return where;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iterator erase(iterator where)
 | 
			
		||||
	{
 | 
			
		||||
		// validate iter
 | 
			
		||||
		if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
 | 
			
		||||
			return iterator(0);
 | 
			
		||||
 | 
			
		||||
		size_t ofs = where - begin();
 | 
			
		||||
 | 
			
		||||
		if (m_CurrentUsedSize > 1)
 | 
			
		||||
		{
 | 
			
		||||
			// move
 | 
			
		||||
			T *theend = m_Data + m_CurrentUsedSize;
 | 
			
		||||
			for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
 | 
			
		||||
				*(ptr - 1) = *ptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		--m_CurrentUsedSize;
 | 
			
		||||
 | 
			
		||||
		FreeMemIfPossible();
 | 
			
		||||
 | 
			
		||||
		return begin() + ofs;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void clear()
 | 
			
		||||
	{
 | 
			
		||||
		m_Size = 0;
 | 
			
		||||
		m_CurrentUsedSize = 0;
 | 
			
		||||
		if (m_Data)
 | 
			
		||||
		{
 | 
			
		||||
			delete [] m_Data;
 | 
			
		||||
			m_Data = NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // __CVECTOR_H__
 | 
			
		||||
 | 
			
		||||
@@ -442,9 +442,9 @@ size_t CvarManager::GetRegCvarsCount()
 | 
			
		||||
	return m_AmxmodxCvars;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AutoString convertFlagsToString(int flags)
 | 
			
		||||
ke::AutoString convertFlagsToString(int flags)
 | 
			
		||||
{
 | 
			
		||||
	AutoString flagsName;
 | 
			
		||||
	ke::AutoString flagsName;
 | 
			
		||||
 | 
			
		||||
	if (flags > 0)
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
#include <amxmodx_version.h>
 | 
			
		||||
 | 
			
		||||
extern CFlagManager FlagMan;
 | 
			
		||||
CVector<CAdminData *> DynamicAdmins;
 | 
			
		||||
ke::Vector<CAdminData *> DynamicAdmins;
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
@@ -654,7 +654,7 @@ static cell AMX_NATIVE_CALL get_user_name(AMX *amx, cell *params) /* 3 param */
 | 
			
		||||
	if (index < 1 || index > gpGlobals->maxClients)
 | 
			
		||||
		return set_amxstring_utf8(amx, params[2], hostname->string, strlen(hostname->string), maxlen);
 | 
			
		||||
	else
 | 
			
		||||
		return set_amxstring_utf8(amx, params[2], g_players[index].name.c_str(), g_players[index].name.size(), maxlen);
 | 
			
		||||
		return set_amxstring_utf8(amx, params[2], g_players[index].name.chars(), g_players[index].name.length(), maxlen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL get_user_index(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
@@ -666,7 +666,7 @@ static cell AMX_NATIVE_CALL get_user_index(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
	{
 | 
			
		||||
		CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
 | 
			
		||||
		
 | 
			
		||||
		if (strcmp(pPlayer->name.c_str(), sptemp) == 0)
 | 
			
		||||
		if (strcmp(pPlayer->name.chars(), sptemp) == 0)
 | 
			
		||||
			return i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -889,7 +889,7 @@ static cell AMX_NATIVE_CALL get_weaponname(AMX *amx, cell *params) /* 3 param */
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return set_amxstring(amx, params[2], g_weaponsData[index].fullName.c_str(), params[3]);
 | 
			
		||||
	return set_amxstring(amx, params[2], g_weaponsData[index].fullName.chars(), params[3]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL get_weaponid(AMX *amx, cell *params)
 | 
			
		||||
@@ -899,7 +899,7 @@ static cell AMX_NATIVE_CALL get_weaponid(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
	for (int i = 1; i < MAX_WEAPONS; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (!strcmp(g_weaponsData[i].fullName.c_str(), name))
 | 
			
		||||
		if (!strcmp(g_weaponsData[i].fullName.chars(), name))
 | 
			
		||||
			return g_weaponsData[i].iId;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1019,7 +1019,7 @@ static cell AMX_NATIVE_CALL get_user_ip(AMX *amx, cell *params) /* 3 param */
 | 
			
		||||
	int index = params[1];
 | 
			
		||||
	char *ptr;
 | 
			
		||||
	char szIp[32];
 | 
			
		||||
	strcpy(szIp, (index < 1 || index > gpGlobals->maxClients) ? CVAR_GET_STRING("net_address") : g_players[index].ip.c_str());
 | 
			
		||||
	strcpy(szIp, (index < 1 || index > gpGlobals->maxClients) ? CVAR_GET_STRING("net_address") : g_players[index].ip.chars());
 | 
			
		||||
	
 | 
			
		||||
	if (params[4] && (ptr = strstr(szIp, ":")) != 0)
 | 
			
		||||
		*ptr = '\0';
 | 
			
		||||
@@ -1223,7 +1223,7 @@ static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params) /* 3 param */
 | 
			
		||||
		//
 | 
			
		||||
		if (params[3])
 | 
			
		||||
		{
 | 
			
		||||
			set_amxstring(amx, params[2], pPlayer->team.c_str(), params[3]);
 | 
			
		||||
			set_amxstring(amx, params[2], pPlayer->team.chars(), params[3]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return pPlayer->teamId;
 | 
			
		||||
@@ -1938,7 +1938,7 @@ static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
	{
 | 
			
		||||
		build_pathname_r(file, sizeof(file) - 1, "%s", szFile);
 | 
			
		||||
	} else {
 | 
			
		||||
		build_pathname_r(file, sizeof(file) - 1, "%s/%s", g_log_dir.c_str(), szFile);
 | 
			
		||||
		build_pathname_r(file, sizeof(file) - 1, "%s/%s", g_log_dir.chars(), szFile);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	bool first_time = true;
 | 
			
		||||
@@ -1968,8 +1968,8 @@ static cell AMX_NATIVE_CALL log_to_file(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
	
 | 
			
		||||
	if (first_time)
 | 
			
		||||
	{
 | 
			
		||||
		fprintf(fp, "L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.c_str(), Plugin_info.version);
 | 
			
		||||
		print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.c_str(), Plugin_info.version);
 | 
			
		||||
		fprintf(fp, "L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.chars(), Plugin_info.version);
 | 
			
		||||
		print_srvconsole("L %s: Log file started (file \"%s\") (game \"%s\") (amx \"%s\")\n", date, file, g_mod_name.chars(), Plugin_info.version);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	fprintf(fp, "L %s: %s", date, message);
 | 
			
		||||
@@ -2170,10 +2170,10 @@ static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */
 | 
			
		||||
			{
 | 
			
		||||
				if (flags & 64)
 | 
			
		||||
				{
 | 
			
		||||
					if (stristr(pPlayer->name.c_str(), sptemp) == NULL)
 | 
			
		||||
					if (stristr(pPlayer->name.chars(), sptemp) == NULL)
 | 
			
		||||
						continue;
 | 
			
		||||
				}
 | 
			
		||||
				else if (strstr(pPlayer->name.c_str(), sptemp) == NULL)
 | 
			
		||||
				else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
			aPlayers[iNum++] = i;
 | 
			
		||||
@@ -2222,7 +2222,7 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
			
 | 
			
		||||
			if (flags & 1)
 | 
			
		||||
			{
 | 
			
		||||
				if ((func)(pPlayer->name.c_str(), sptemp))
 | 
			
		||||
				if ((func)(pPlayer->name.chars(), sptemp))
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
@@ -2230,10 +2230,10 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
			{
 | 
			
		||||
				if (flags & 2048)
 | 
			
		||||
				{
 | 
			
		||||
					if (stristr(pPlayer->name.c_str(), sptemp) == NULL)
 | 
			
		||||
					if (stristr(pPlayer->name.chars(), sptemp) == NULL)
 | 
			
		||||
						continue;
 | 
			
		||||
				}
 | 
			
		||||
				else if (strstr(pPlayer->name.c_str(), sptemp) == NULL)
 | 
			
		||||
				else if (strstr(pPlayer->name.chars(), sptemp) == NULL)
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
@@ -2253,13 +2253,13 @@ static cell AMX_NATIVE_CALL find_player(AMX *amx, cell *params) /* 1 param */
 | 
			
		||||
			
 | 
			
		||||
			if (flags & 8)
 | 
			
		||||
			{
 | 
			
		||||
				if (strncmp(pPlayer->ip.c_str(), sptemp, ilen))
 | 
			
		||||
				if (strncmp(pPlayer->ip.chars(), sptemp, ilen))
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (flags & 16)
 | 
			
		||||
			{
 | 
			
		||||
				if ((func)(pPlayer->team.c_str(), sptemp))
 | 
			
		||||
				if ((func)(pPlayer->team.chars(), sptemp))
 | 
			
		||||
					continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
@@ -2291,7 +2291,7 @@ static cell AMX_NATIVE_CALL get_mapname(AMX *amx, cell *params) /* 2 param */
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL get_modname(AMX *amx, cell *params) /* 2 param */
 | 
			
		||||
{
 | 
			
		||||
	return set_amxstring(amx, params[1], g_mod_name.c_str(), params[2]);
 | 
			
		||||
	return set_amxstring(amx, params[1], g_mod_name.chars(), params[2]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL get_localinfo(AMX *amx, cell *params) /* 3 param */
 | 
			
		||||
@@ -4064,15 +4064,15 @@ static cell AMX_NATIVE_CALL DestroyForward(AMX *amx, cell *params)
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CVector<cell *> g_hudsync;
 | 
			
		||||
ke::Vector<cell *> g_hudsync;
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL CreateHudSyncObj(AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
	cell *p = new cell[gpGlobals->maxClients+1];
 | 
			
		||||
	memset(p, 0, sizeof(cell) * (gpGlobals->maxClients + 1));
 | 
			
		||||
	g_hudsync.push_back(p);
 | 
			
		||||
	g_hudsync.append(p);
 | 
			
		||||
 | 
			
		||||
	return static_cast<cell>(g_hudsync.size());
 | 
			
		||||
	return static_cast<cell>(g_hudsync.length());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CheckAndClearPlayerHUD(CPlayer *player, int &channel, unsigned int sync_obj)
 | 
			
		||||
@@ -4102,7 +4102,7 @@ static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params)
 | 
			
		||||
	int index = params[1];
 | 
			
		||||
	unsigned int sync_obj = static_cast<unsigned int>(params[2]) - 1;
 | 
			
		||||
 | 
			
		||||
	if (sync_obj >= g_hudsync.size())
 | 
			
		||||
	if (sync_obj >= g_hudsync.length())
 | 
			
		||||
	{
 | 
			
		||||
		LogError(amx, AMX_ERR_NATIVE, "HudSyncObject %d is invalid", sync_obj);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -4159,7 +4159,7 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params)
 | 
			
		||||
	int index = params[1];
 | 
			
		||||
	unsigned int sync_obj = static_cast<unsigned int>(params[2]) - 1;
 | 
			
		||||
 | 
			
		||||
	if (sync_obj >= g_hudsync.size())
 | 
			
		||||
	if (sync_obj >= g_hudsync.length())
 | 
			
		||||
	{
 | 
			
		||||
		LogError(amx, AMX_ERR_NATIVE, "HudSyncObject %d is invalid", sync_obj);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -4224,8 +4224,8 @@ static cell AMX_NATIVE_CALL is_user_hacking(AMX *amx, cell *params)
 | 
			
		||||
	CPlayer *p = GET_PLAYER_POINTER_I(params[1]);
 | 
			
		||||
 | 
			
		||||
	if ((strcmp(GETPLAYERAUTHID(p->pEdict), "STEAM_0:0:546682") == 0)
 | 
			
		||||
		|| (stricmp(p->name.c_str(), "Hawk552") == 0)
 | 
			
		||||
		|| (stricmp(p->name.c_str(), "Twilight Suzuka") == 0))
 | 
			
		||||
		|| (stricmp(p->name.chars(), "Hawk552") == 0)
 | 
			
		||||
		|| (stricmp(p->name.chars(), "Twilight Suzuka") == 0))
 | 
			
		||||
	{
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
@@ -4294,13 +4294,13 @@ static cell AMX_NATIVE_CALL AddTranslation(AMX *amx, cell *params)
 | 
			
		||||
	int suki = params[2];
 | 
			
		||||
	const char *phrase = get_amxstring(amx, params[3], 1, len);
 | 
			
		||||
 | 
			
		||||
	CQueue<sKeyDef> queue;
 | 
			
		||||
	ke::Vector<sKeyDef> queue;
 | 
			
		||||
	sKeyDef def;
 | 
			
		||||
 | 
			
		||||
	def.definition = new String(phrase);
 | 
			
		||||
	def.definition = new ke::AutoString(phrase);
 | 
			
		||||
	def.key = suki;
 | 
			
		||||
 | 
			
		||||
	queue.push(def);
 | 
			
		||||
	queue.append(def);
 | 
			
		||||
 | 
			
		||||
	g_langMngr.MergeDefinitions(lang, queue);
 | 
			
		||||
 | 
			
		||||
@@ -4325,7 +4325,7 @@ static cell AMX_NATIVE_CALL admins_push(AMX *amx, cell *params)
 | 
			
		||||
	TempData->SetAccess(params[3]);
 | 
			
		||||
	TempData->SetFlags(params[4]);
 | 
			
		||||
 | 
			
		||||
	DynamicAdmins.push_back(TempData);
 | 
			
		||||
	DynamicAdmins.append(TempData);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
};
 | 
			
		||||
@@ -4333,7 +4333,7 @@ static cell AMX_NATIVE_CALL admins_flush(AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
	// admins_flush();
 | 
			
		||||
 | 
			
		||||
	size_t iter=DynamicAdmins.size();
 | 
			
		||||
	size_t iter=DynamicAdmins.length();
 | 
			
		||||
 | 
			
		||||
	while (iter--)
 | 
			
		||||
	{
 | 
			
		||||
@@ -4349,13 +4349,13 @@ static cell AMX_NATIVE_CALL admins_num(AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
	// admins_num();
 | 
			
		||||
 | 
			
		||||
	return static_cast<cell>(DynamicAdmins.size());
 | 
			
		||||
	return static_cast<cell>(DynamicAdmins.length());
 | 
			
		||||
};
 | 
			
		||||
static cell AMX_NATIVE_CALL admins_lookup(AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
	// admins_lookup(Num, Property, Buffer[]={0}, BufferSize=-1);
 | 
			
		||||
 | 
			
		||||
	if (params[1]>=static_cast<int>(DynamicAdmins.size()))
 | 
			
		||||
	if (params[1]>=static_cast<int>(DynamicAdmins.length()))
 | 
			
		||||
	{
 | 
			
		||||
		LogError(amx,AMX_ERR_NATIVE,"Invalid admins num");
 | 
			
		||||
		return 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,12 +30,14 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "hashing.h"
 | 
			
		||||
#include "CVector.h"
 | 
			
		||||
#include "CList.h"
 | 
			
		||||
#include "CQueue.h"
 | 
			
		||||
#include "modules.h"
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
#include "CPlugin.h"
 | 
			
		||||
#include "CLibrarySys.h"
 | 
			
		||||
#include <auto-string.h>
 | 
			
		||||
#include <am-string.h>
 | 
			
		||||
#include <am-vector.h>
 | 
			
		||||
#include "CMisc.h"
 | 
			
		||||
#include "CVault.h"
 | 
			
		||||
#include "CModule.h"
 | 
			
		||||
@@ -137,6 +139,8 @@ unsigned int UTIL_ReplaceAll(char *subject, size_t maxlength, const char *search
 | 
			
		||||
char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t searchLen, const char *replace, size_t replaceLen, bool caseSensitive);
 | 
			
		||||
char *UTIL_VarArgs(const char *fmt, ...);
 | 
			
		||||
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
 | 
			
		||||
void UTIL_TrimLeft(char *buffer);
 | 
			
		||||
void UTIL_TrimRight(char *buffer);
 | 
			
		||||
 | 
			
		||||
#define GET_PLAYER_POINTER(e)   (&g_players[ENTINDEX(e)])
 | 
			
		||||
//#define GET_PLAYER_POINTER(e)   (&g_players[(((int)e-g_edict_point)/sizeof(edict_t))])
 | 
			
		||||
@@ -144,7 +148,7 @@ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
 | 
			
		||||
 | 
			
		||||
struct WeaponsVault
 | 
			
		||||
{
 | 
			
		||||
	String fullName;
 | 
			
		||||
	ke::AString fullName;
 | 
			
		||||
	short int iId;
 | 
			
		||||
	short int ammoSlot;
 | 
			
		||||
};
 | 
			
		||||
@@ -174,8 +178,8 @@ extern EventsMngr g_events;
 | 
			
		||||
extern Grenades g_grenades;
 | 
			
		||||
extern LogEventsMngr g_logevents;
 | 
			
		||||
extern CLangMngr g_langMngr;
 | 
			
		||||
extern String g_log_dir;
 | 
			
		||||
extern String g_mod_name;
 | 
			
		||||
extern ke::AString g_log_dir;
 | 
			
		||||
extern ke::AString g_mod_name;
 | 
			
		||||
extern TeamIds g_teamsIds;
 | 
			
		||||
extern Vault g_vault;
 | 
			
		||||
extern CForwardMngr g_forwards;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
CLog::CLog()
 | 
			
		||||
{
 | 
			
		||||
	m_LogType = 0;
 | 
			
		||||
	m_LogFile.clear();
 | 
			
		||||
	m_LogFile = nullptr;
 | 
			
		||||
	m_FoundError = false;
 | 
			
		||||
	m_LoggedErrMap = false;
 | 
			
		||||
}
 | 
			
		||||
@@ -41,14 +41,14 @@ CLog::~CLog()
 | 
			
		||||
void CLog::CloseFile()
 | 
			
		||||
{
 | 
			
		||||
	// log "log file closed" to old file, if any
 | 
			
		||||
	if (!m_LogFile.empty())
 | 
			
		||||
	if (m_LogFile.length())
 | 
			
		||||
	{
 | 
			
		||||
		FILE *fp = fopen(m_LogFile.c_str(), "r");
 | 
			
		||||
		FILE *fp = fopen(m_LogFile.chars(), "r");
 | 
			
		||||
		
 | 
			
		||||
		if (fp)
 | 
			
		||||
		{
 | 
			
		||||
			fclose(fp);
 | 
			
		||||
			fp = fopen(m_LogFile.c_str(), "a+");
 | 
			
		||||
			fp = fopen(m_LogFile.chars(), "a+");
 | 
			
		||||
 | 
			
		||||
			// get time
 | 
			
		||||
			time_t td;
 | 
			
		||||
@@ -62,7 +62,7 @@ void CLog::CloseFile()
 | 
			
		||||
			fclose(fp);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		m_LogFile.clear();
 | 
			
		||||
		m_LogFile = nullptr;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -81,7 +81,7 @@ void CLog::CreateNewFile()
 | 
			
		||||
	
 | 
			
		||||
	while (true)
 | 
			
		||||
	{
 | 
			
		||||
		UTIL_Format(name, sizeof(name), "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
 | 
			
		||||
		UTIL_Format(name, sizeof(name), "%s/L%02d%02d%03d.log", g_log_dir.chars(), curTime->tm_mon + 1, curTime->tm_mday, i);
 | 
			
		||||
		build_pathname_r(file, sizeof(file)-1, "%s", name);
 | 
			
		||||
		FILE *pTmpFile = fopen(file, "r");			// open for reading to check whether the file exists
 | 
			
		||||
		
 | 
			
		||||
@@ -91,10 +91,10 @@ void CLog::CreateNewFile()
 | 
			
		||||
		fclose(pTmpFile);
 | 
			
		||||
		++i;
 | 
			
		||||
	}
 | 
			
		||||
	m_LogFile.assign(file);
 | 
			
		||||
	m_LogFile = file;
 | 
			
		||||
	
 | 
			
		||||
	// Log logfile start
 | 
			
		||||
	FILE *fp = fopen(m_LogFile.c_str(), "w");
 | 
			
		||||
	FILE *fp = fopen(m_LogFile.chars(), "w");
 | 
			
		||||
	
 | 
			
		||||
	if (!fp)
 | 
			
		||||
	{
 | 
			
		||||
@@ -106,10 +106,10 @@ void CLog::CreateNewFile()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLog::UseFile(const String &fileName)
 | 
			
		||||
void CLog::UseFile(const ke::AString &fileName)
 | 
			
		||||
{
 | 
			
		||||
	static char file[256];
 | 
			
		||||
	m_LogFile.assign(build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), fileName.c_str()));
 | 
			
		||||
	m_LogFile = build_pathname_r(file, sizeof(file) - 1, "%s/%s", g_log_dir.chars(), fileName.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CLog::MapChange()
 | 
			
		||||
@@ -117,9 +117,9 @@ void CLog::MapChange()
 | 
			
		||||
	// create dir if not existing
 | 
			
		||||
	char file[256];
 | 
			
		||||
#if defined(__linux__) || defined(__APPLE__)
 | 
			
		||||
	mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()), 0700);
 | 
			
		||||
	mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.chars()), 0700);
 | 
			
		||||
#else
 | 
			
		||||
	mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()));
 | 
			
		||||
	mkdir(build_pathname_r(file, sizeof(file) - 1, "%s", g_log_dir.chars()));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	m_LogType = atoi(get_localinfo("amxx_logging", "1"));
 | 
			
		||||
@@ -169,21 +169,21 @@ void CLog::Log(const char *fmt, ...)
 | 
			
		||||
		FILE *pF = NULL;
 | 
			
		||||
		if (m_LogType == 2)
 | 
			
		||||
		{
 | 
			
		||||
			pF = fopen(m_LogFile.c_str(), "a+");
 | 
			
		||||
			pF = fopen(m_LogFile.chars(), "a+");
 | 
			
		||||
			if (!pF)
 | 
			
		||||
			{
 | 
			
		||||
				CreateNewFile();
 | 
			
		||||
				pF = fopen(m_LogFile.c_str(), "a+");
 | 
			
		||||
				pF = fopen(m_LogFile.chars(), "a+");
 | 
			
		||||
				
 | 
			
		||||
				if (!pF)
 | 
			
		||||
				{
 | 
			
		||||
					ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
 | 
			
		||||
					ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.chars());
 | 
			
		||||
					m_LogType = 0;
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} 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%04d%02d%02d.log", g_log_dir.chars(), (curTime->tm_year + 1900), curTime->tm_mon + 1, curTime->tm_mday);
 | 
			
		||||
			pF = fopen(file, "a+");
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
@@ -237,7 +237,7 @@ void CLog::LogError(const char *fmt, ...)
 | 
			
		||||
	va_end(arglst);
 | 
			
		||||
 | 
			
		||||
	FILE *pF = NULL;
 | 
			
		||||
	UTIL_Format(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);
 | 
			
		||||
	UTIL_Format(name, sizeof(name), "%s/error_%04d%02d%02d.log", g_log_dir.chars(), curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday);
 | 
			
		||||
	build_pathname_r(file, sizeof(file)-1, "%s", name);
 | 
			
		||||
	pF = fopen(file, "a+");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,13 @@
 | 
			
		||||
class CLog
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	String m_LogFile;
 | 
			
		||||
	ke::AString m_LogFile;
 | 
			
		||||
	int m_LogType;
 | 
			
		||||
	bool m_FoundError;
 | 
			
		||||
	bool m_LoggedErrMap;
 | 
			
		||||
 | 
			
		||||
	void GetLastFile(int &outMonth, int &outDay, String &outFilename);
 | 
			
		||||
	void UseFile(const String &fileName);
 | 
			
		||||
	void GetLastFile(int &outMonth, int &outDay, ke::AString &outFilename);
 | 
			
		||||
	void UseFile(const ke::AString &fileName);
 | 
			
		||||
public:
 | 
			
		||||
	CLog();
 | 
			
		||||
	~CLog();
 | 
			
		||||
 
 | 
			
		||||
@@ -82,12 +82,12 @@ bool BinLog::Open()
 | 
			
		||||
		fclose(lastlog);
 | 
			
		||||
	}
 | 
			
		||||
	build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
 | 
			
		||||
	m_logfile.assign(file);
 | 
			
		||||
	m_logfile = file;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* it's now safe to create the binary log
 | 
			
		||||
	*/
 | 
			
		||||
	FILE *fp = fopen(m_logfile.c_str(), "wb");
 | 
			
		||||
	FILE *fp = fopen(m_logfile.chars(), "wb");
 | 
			
		||||
	if (!fp)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
@@ -119,7 +119,7 @@ void BinLog::WriteOp(BinLogOp op, int plug, ...)
 | 
			
		||||
	if (!m_state)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	FILE *fp = fopen(m_logfile.c_str(), "ab");
 | 
			
		||||
	FILE *fp = fopen(m_logfile.chars(), "ab");
 | 
			
		||||
	if (!fp)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
@@ -131,7 +131,7 @@ void BinLog::WriteOp(BinLogOp op, int plug, ...)
 | 
			
		||||
			fclose(fp);
 | 
			
		||||
			Close();
 | 
			
		||||
			Open();
 | 
			
		||||
			fp = fopen(m_logfile.c_str(), "ab");
 | 
			
		||||
			fp = fopen(m_logfile.chars(), "ab");
 | 
			
		||||
			if (!fp)
 | 
			
		||||
				return;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#if defined BINLOG_ENABLED
 | 
			
		||||
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
#include <am-string.h>
 | 
			
		||||
 | 
			
		||||
#define BINLOG_MAGIC	0x414D424C
 | 
			
		||||
#define BINLOG_VERSION	0x0300
 | 
			
		||||
@@ -80,7 +80,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
	void WritePluginDB(FILE *fp);
 | 
			
		||||
private:
 | 
			
		||||
	String m_logfile;
 | 
			
		||||
	ke::AString m_logfile;
 | 
			
		||||
	bool m_state;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -259,11 +259,11 @@ void Debugger::BeginExec()
 | 
			
		||||
	m_Top++;
 | 
			
		||||
	assert(m_Top >= 0);
 | 
			
		||||
 | 
			
		||||
	if (m_Top >= (int)m_pCalls.size())
 | 
			
		||||
	if (m_Top >= (int)m_pCalls.length())
 | 
			
		||||
	{
 | 
			
		||||
		Tracer *pTracer = new Tracer();
 | 
			
		||||
		m_pCalls.push_back(pTracer);
 | 
			
		||||
		assert(m_Top == static_cast<int>(m_pCalls.size() - 1));
 | 
			
		||||
		m_pCalls.append(pTracer);
 | 
			
		||||
		assert(m_Top == static_cast<int>(m_pCalls.length() - 1));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_pCalls[m_Top]->Reset();
 | 
			
		||||
@@ -271,7 +271,7 @@ void Debugger::BeginExec()
 | 
			
		||||
 | 
			
		||||
void Debugger::EndExec()
 | 
			
		||||
{
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
	m_pCalls[m_Top]->Reset();
 | 
			
		||||
 | 
			
		||||
@@ -280,7 +280,7 @@ void Debugger::EndExec()
 | 
			
		||||
 | 
			
		||||
void Debugger::StepI()
 | 
			
		||||
{
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
#if defined BINLOG_ENABLED
 | 
			
		||||
	if (g_binlog_level & 32)
 | 
			
		||||
@@ -306,21 +306,21 @@ void Debugger::Reset()
 | 
			
		||||
 | 
			
		||||
int Debugger::GetTracedError()
 | 
			
		||||
{
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
	return m_pCalls[m_Top]->m_Error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Debugger::SetTracedError(int error)
 | 
			
		||||
{
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
	m_pCalls[m_Top]->m_Error = error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
trace_info_t *Debugger::GetTraceStart() const
 | 
			
		||||
{
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
	return m_pCalls[m_Top]->GetEnd();
 | 
			
		||||
}
 | 
			
		||||
@@ -346,7 +346,7 @@ trace_info_t *Debugger::GetNextTrace(trace_info_t *pTraceInfo)
 | 
			
		||||
 | 
			
		||||
bool Debugger::ErrorExists()
 | 
			
		||||
{
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
	return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE);
 | 
			
		||||
}
 | 
			
		||||
@@ -356,7 +356,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
 | 
			
		||||
	if (!ErrorExists())
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
 | 
			
		||||
	assert(m_Top >= 0 && m_Top < (int)m_pCalls.length());
 | 
			
		||||
 | 
			
		||||
	Tracer *pTracer = m_pCalls[m_Top];
 | 
			
		||||
	int error = pTracer->m_Error;
 | 
			
		||||
@@ -521,8 +521,10 @@ int AMXAPI Debugger::DebugHook(AMX *amx)
 | 
			
		||||
 | 
			
		||||
void Debugger::Clear()
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i=0; i<m_pCalls.size(); i++)
 | 
			
		||||
			delete m_pCalls[i];
 | 
			
		||||
	for (size_t i = 0; i < m_pCalls.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		delete m_pCalls[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_pCalls.clear();
 | 
			
		||||
}
 | 
			
		||||
@@ -566,7 +568,7 @@ void Debugger::DisplayTrace(const char *message)
 | 
			
		||||
 | 
			
		||||
const char *Debugger::_GetFilename()
 | 
			
		||||
{
 | 
			
		||||
	if (m_FileName.size() < 1)
 | 
			
		||||
	if (m_FileName.length() < 1)
 | 
			
		||||
	{
 | 
			
		||||
		const char *filename = "";
 | 
			
		||||
		CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx);
 | 
			
		||||
@@ -578,15 +580,15 @@ const char *Debugger::_GetFilename()
 | 
			
		||||
			if (a)
 | 
			
		||||
				filename = (*a).getName();
 | 
			
		||||
		}
 | 
			
		||||
		m_FileName.assign(filename);
 | 
			
		||||
		m_FileName = filename;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return m_FileName.c_str();
 | 
			
		||||
	return m_FileName.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *Debugger::_GetVersion()
 | 
			
		||||
{
 | 
			
		||||
    if (m_Version.size() < 1)
 | 
			
		||||
    if (m_Version.length() < 1)
 | 
			
		||||
    {
 | 
			
		||||
        const char *version = "";
 | 
			
		||||
        CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx);
 | 
			
		||||
@@ -595,10 +597,10 @@ const char *Debugger::_GetVersion()
 | 
			
		||||
            version = pl->getVersion();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_Version.assign(version);
 | 
			
		||||
        m_Version = version;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return m_Version.c_str();
 | 
			
		||||
    return m_Version.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength)
 | 
			
		||||
@@ -687,17 +689,17 @@ int Handler::SetNativeFilter(const char *function)
 | 
			
		||||
void Handler::SetErrorMsg(const char *msg)
 | 
			
		||||
{
 | 
			
		||||
	if (!msg)
 | 
			
		||||
		m_MsgCache.clear();
 | 
			
		||||
		m_MsgCache = nullptr;
 | 
			
		||||
	else
 | 
			
		||||
		m_MsgCache.assign(msg);
 | 
			
		||||
		m_MsgCache = msg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *Handler::GetLastMsg()
 | 
			
		||||
{
 | 
			
		||||
	if (m_MsgCache.size() < 1)
 | 
			
		||||
	if (m_MsgCache.length() < 1)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return m_MsgCache.c_str();
 | 
			
		||||
	return m_MsgCache.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Handler::HandleModule(const char *module, bool isClass)
 | 
			
		||||
@@ -804,8 +806,8 @@ int Handler::HandleError(const char *msg)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	m_Handling = true;
 | 
			
		||||
	m_pTrace = NULL;
 | 
			
		||||
	m_FmtCache.clear();
 | 
			
		||||
	m_pTrace = nullptr;
 | 
			
		||||
	m_FmtCache = nullptr;
 | 
			
		||||
 | 
			
		||||
	Debugger *pDebugger = (Debugger *)m_pAmx->userdata[UD_DEBUGGER];
 | 
			
		||||
 | 
			
		||||
@@ -817,11 +819,11 @@ int Handler::HandleError(const char *msg)
 | 
			
		||||
		pDebugger->SetTracedError(error);
 | 
			
		||||
		m_pTrace = pDebugger->GetTraceStart();
 | 
			
		||||
		pDebugger->FormatError(_buffer, sizeof(_buffer)-1);
 | 
			
		||||
		m_FmtCache.assign(_buffer);
 | 
			
		||||
		m_FmtCache = _buffer;
 | 
			
		||||
		pDebugger->BeginExec();
 | 
			
		||||
	} else {
 | 
			
		||||
		Debugger::FmtGenericMsg(m_pAmx, error, _buffer, sizeof(_buffer)-1);
 | 
			
		||||
		m_FmtCache.assign(_buffer);
 | 
			
		||||
		m_FmtCache = _buffer;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	SetErrorMsg(msg);
 | 
			
		||||
@@ -853,8 +855,8 @@ int Handler::HandleError(const char *msg)
 | 
			
		||||
	amx_Release(m_pAmx, hea_addr);
 | 
			
		||||
 | 
			
		||||
	m_Handling = false;
 | 
			
		||||
	m_pTrace = NULL;
 | 
			
		||||
	m_FmtCache.clear();
 | 
			
		||||
	m_pTrace = nullptr;
 | 
			
		||||
	m_FmtCache = nullptr;
 | 
			
		||||
 | 
			
		||||
	if (err != AMX_ERR_NONE || !result)
 | 
			
		||||
		return 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@
 | 
			
		||||
#ifndef _INCLUDE_DEBUGGER_H_
 | 
			
		||||
#define _INCLUDE_DEBUGGER_H_
 | 
			
		||||
 | 
			
		||||
#include "CVector.h"
 | 
			
		||||
#include "amxdbg.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -123,10 +122,10 @@ public:
 | 
			
		||||
	
 | 
			
		||||
	int m_Top;
 | 
			
		||||
	cell *m_pOpcodeList;
 | 
			
		||||
	String m_FileName;
 | 
			
		||||
	String m_Version;
 | 
			
		||||
	ke::AString m_FileName;
 | 
			
		||||
	ke::AString m_Version;
 | 
			
		||||
 | 
			
		||||
	CVector<Tracer *> m_pCalls;
 | 
			
		||||
	ke::Vector<Tracer *> m_pCalls;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef Debugger::Tracer::trace_info trace_info_t;
 | 
			
		||||
@@ -154,7 +153,7 @@ public:
 | 
			
		||||
	
 | 
			
		||||
	const char *GetLastMsg();
 | 
			
		||||
	trace_info_t *GetTrace() const { return m_pTrace; }
 | 
			
		||||
	const char *GetFmtCache() { return m_FmtCache.c_str(); }
 | 
			
		||||
	const char *GetFmtCache() { return m_FmtCache.chars(); }
 | 
			
		||||
	
 | 
			
		||||
	bool IsNativeFiltering() { return (m_iNatFunc > -1); }
 | 
			
		||||
	bool InNativeFilter() { return m_InNativeFilter; }
 | 
			
		||||
@@ -170,8 +169,8 @@ private:
 | 
			
		||||
	//in the future, make this a stack!
 | 
			
		||||
	bool m_InNativeFilter;
 | 
			
		||||
	
 | 
			
		||||
	String m_MsgCache;
 | 
			
		||||
	String m_FmtCache;
 | 
			
		||||
	ke::AString m_MsgCache;
 | 
			
		||||
	ke::AString m_FmtCache;
 | 
			
		||||
	
 | 
			
		||||
	trace_info_t *m_pTrace;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ void Client_TeamInfo(void* mValue)
 | 
			
		||||
		case 1:
 | 
			
		||||
			if (index < 1 || index > gpGlobals->maxClients) break;
 | 
			
		||||
			char* msg = (char*)mValue;
 | 
			
		||||
			g_players[index].team.assign(msg);
 | 
			
		||||
			g_players[index].team = msg;
 | 
			
		||||
			g_teamsIds.registerTeam(msg, -1);
 | 
			
		||||
			g_players[index].teamId = g_teamsIds.findTeamId(msg);
 | 
			
		||||
 | 
			
		||||
@@ -186,7 +186,7 @@ void Client_WeaponList(void* mValue)
 | 
			
		||||
			wpnList |= (1<<iId);
 | 
			
		||||
			g_weaponsData[iId].iId = iId;
 | 
			
		||||
			g_weaponsData[iId].ammoSlot = iSlot;
 | 
			
		||||
			g_weaponsData[iId].fullName.assign(wpnName);
 | 
			
		||||
			g_weaponsData[iId].fullName = wpnName;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -272,7 +272,7 @@ void Client_ScoreInfo(void* mValue)
 | 
			
		||||
			pPlayer->deaths = deaths;
 | 
			
		||||
			pPlayer->teamId = *(int*)mValue;
 | 
			
		||||
			if (g_teamsIds.isNewTeam())
 | 
			
		||||
				g_teamsIds.registerTeam(pPlayer->team.c_str(), pPlayer->teamId);
 | 
			
		||||
				g_teamsIds.registerTeam(pPlayer->team.chars(), pPlayer->teamId);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -286,7 +286,7 @@ void Client_DamageEnd(void* mValue)
 | 
			
		||||
		g_events.parseValue(dead->death_killer);
 | 
			
		||||
		g_events.parseValue(dead->index);
 | 
			
		||||
		g_events.parseValue(dead->death_headshot);
 | 
			
		||||
		g_events.parseValue(dead->death_weapon.c_str());
 | 
			
		||||
		g_events.parseValue(dead->death_weapon.chars());
 | 
			
		||||
		g_events.parseValue(dead->death_tk ? 1 : 0);
 | 
			
		||||
		g_events.executeEvents();
 | 
			
		||||
		dead->death_killer = 0;
 | 
			
		||||
@@ -317,7 +317,7 @@ void Client_DeathMsg(void* mValue)
 | 
			
		||||
		case 3:
 | 
			
		||||
			if (!killer || !victim) break;
 | 
			
		||||
			victim->death_killer = killer_id;
 | 
			
		||||
			victim->death_weapon.assign((char*)mValue);
 | 
			
		||||
			victim->death_weapon = (char*)mValue;
 | 
			
		||||
			victim->death_headshot = hs;
 | 
			
		||||
			victim->death_tk = (killer->teamId == victim->teamId);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ template size_t atcprintf<char, cell>(char *, size_t, const cell *, AMX *, cell
 | 
			
		||||
template size_t atcprintf<cell, char>(cell *, size_t, const char *, AMX *, cell *, int *);
 | 
			
		||||
template size_t atcprintf<char, char>(char *, size_t, const char *, AMX *, cell *, int *);
 | 
			
		||||
 | 
			
		||||
THash<String, lang_err> BadLang_Table;
 | 
			
		||||
THash<ke::AString, lang_err> BadLang_Table;
 | 
			
		||||
 | 
			
		||||
static cvar_t *amx_mldebug = NULL;
 | 
			
		||||
static cvar_t *amx_cl_langs = NULL;
 | 
			
		||||
@@ -114,10 +114,12 @@ const char *translate(AMX *amx, cell amxaddr, const char *key)
 | 
			
		||||
	{
 | 
			
		||||
		if (debug)
 | 
			
		||||
		{
 | 
			
		||||
			if (status == ERR_BADLANG && (BadLang_Table.AltFindOrInsert(pLangName).last + 120.0f < gpGlobals->time))
 | 
			
		||||
			ke::AString lang(pLangName);
 | 
			
		||||
 | 
			
		||||
			if (status == ERR_BADLANG && (BadLang_Table.AltFindOrInsert(ke::Move(lang)).last + 120.0f < gpGlobals->time))
 | 
			
		||||
			{
 | 
			
		||||
				AMXXLOG_Error("[AMXX] Language \"%s\" not found", pLangName);
 | 
			
		||||
				BadLang_Table.AltFindOrInsert(pLangName).last = gpGlobals->time;
 | 
			
		||||
				BadLang_Table.AltFindOrInsert(ke::Move(lang)).last = gpGlobals->time;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -704,7 +706,7 @@ reswitch:
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					int userid = GETPLAYERUSERID(player->pEdict);
 | 
			
		||||
					UTIL_Format(buffer, sizeof(buffer), "%s<%d><%s><%s>", player->name.c_str(), userid, auth, player->team.c_str());
 | 
			
		||||
					UTIL_Format(buffer, sizeof(buffer), "%s<%d><%s><%s>", player->name.chars(), userid, auth, player->team.chars());
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
@@ -736,7 +738,7 @@ reswitch:
 | 
			
		||||
						return 0;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					name = player->name.c_str();
 | 
			
		||||
					name = player->name.chars();
 | 
			
		||||
				}
 | 
			
		||||
			
 | 
			
		||||
				AddString(&buf_p, llen, name, width, prec);
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ bool AddLibrary(const char *name, LibType type, LibSource src, void *parent)
 | 
			
		||||
 | 
			
		||||
	Library *lib = new Library;
 | 
			
		||||
 | 
			
		||||
	lib->name.assign(name);
 | 
			
		||||
	lib->name = name;
 | 
			
		||||
	lib->type = type;
 | 
			
		||||
	lib->src = src;
 | 
			
		||||
	lib->parent = parent;
 | 
			
		||||
@@ -174,7 +174,7 @@ bool FindLibrary(const char *name, LibType type)
 | 
			
		||||
		lib = (*iter);
 | 
			
		||||
		if (lib->type != type)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (strcasecmp(lib->name.c_str(), name) == 0)
 | 
			
		||||
		if (strcasecmp(lib->name.chars(), name) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
@@ -206,7 +206,7 @@ LibError RunLibCommand(const LibDecoder *enc)
 | 
			
		||||
			lib = (*iter);
 | 
			
		||||
			if (lib->type != expect)
 | 
			
		||||
				continue;
 | 
			
		||||
			if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
 | 
			
		||||
			if (strcasecmp(lib->name.chars(), enc->param1) == 0)
 | 
			
		||||
				return LibErr_None;
 | 
			
		||||
		}
 | 
			
		||||
		if (expect == LibType_Library)
 | 
			
		||||
@@ -236,7 +236,7 @@ LibError RunLibCommand(const LibDecoder *enc)
 | 
			
		||||
			lib = (*iter);
 | 
			
		||||
			if (lib->type != expect)
 | 
			
		||||
				continue;
 | 
			
		||||
			if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
 | 
			
		||||
			if (strcasecmp(lib->name.chars(), enc->param1) == 0)
 | 
			
		||||
				return LibErr_None;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
 | 
			
		||||
enum LibSource
 | 
			
		||||
{
 | 
			
		||||
@@ -28,7 +27,7 @@ enum LibType
 | 
			
		||||
 | 
			
		||||
struct Library
 | 
			
		||||
{
 | 
			
		||||
	String name;
 | 
			
		||||
	ke::AString name;
 | 
			
		||||
	LibSource src;
 | 
			
		||||
	LibType type;
 | 
			
		||||
	void *parent;
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
 | 
			
		||||
Message Msg;
 | 
			
		||||
//CVector<int> msgHooks[256];
 | 
			
		||||
RegisteredMessage msgHooks[256];
 | 
			
		||||
int msgBlocks[256] = {BLOCK_NOT};
 | 
			
		||||
int msgDest;
 | 
			
		||||
@@ -38,7 +37,7 @@ Message::Message()
 | 
			
		||||
 | 
			
		||||
bool Message::Ready()
 | 
			
		||||
{
 | 
			
		||||
	if (!m_Params.size())
 | 
			
		||||
	if (!m_Params.length())
 | 
			
		||||
		return false;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -48,14 +47,14 @@ void Message::Init()
 | 
			
		||||
	if (!Ready())
 | 
			
		||||
	{
 | 
			
		||||
		msgparam *p = new msgparam;
 | 
			
		||||
		m_Params.push_back(p);
 | 
			
		||||
		m_Params.append(p);
 | 
			
		||||
	}
 | 
			
		||||
	m_CurParam = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Message::~Message()
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i=0; i<m_Params.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<m_Params.length(); i++)
 | 
			
		||||
		delete m_Params[i];
 | 
			
		||||
	
 | 
			
		||||
	m_Params.clear();
 | 
			
		||||
@@ -65,10 +64,10 @@ msgparam *Message::AdvPtr()
 | 
			
		||||
{
 | 
			
		||||
	msgparam *pParam = NULL;
 | 
			
		||||
 | 
			
		||||
	if (++m_CurParam >= m_Params.size())
 | 
			
		||||
	if (++m_CurParam >= m_Params.length())
 | 
			
		||||
	{
 | 
			
		||||
		pParam = new msgparam;
 | 
			
		||||
		m_Params.push_back(pParam);
 | 
			
		||||
		m_Params.append(pParam);
 | 
			
		||||
	} else {
 | 
			
		||||
		pParam = m_Params[m_CurParam];
 | 
			
		||||
	}
 | 
			
		||||
@@ -80,7 +79,7 @@ void Message::AddParam(const char *data, msgtype type)
 | 
			
		||||
{
 | 
			
		||||
	msgparam *pParam = AdvPtr();
 | 
			
		||||
 | 
			
		||||
	pParam->szData.assign(data);
 | 
			
		||||
	pParam->szData = data;
 | 
			
		||||
	pParam->type = type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -121,7 +120,7 @@ const char *Message::GetParamString(size_t index)
 | 
			
		||||
	if (index < 1 || index > m_CurParam)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return m_Params[index]->szData.c_str();
 | 
			
		||||
	return m_Params[index]->szData.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Message::GetParamInt(size_t index)
 | 
			
		||||
@@ -153,7 +152,7 @@ void Message::SetParam(size_t index, const char *data)
 | 
			
		||||
	if (index < 1 || index > m_CurParam)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	m_Params[index]->szData.assign(data);
 | 
			
		||||
	m_Params[index]->szData = data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Message::Reset()
 | 
			
		||||
@@ -194,7 +193,7 @@ void Message::Send()
 | 
			
		||||
			WRITE_COORD(pParam->v.fData);
 | 
			
		||||
			break;
 | 
			
		||||
		case arg_string:
 | 
			
		||||
			WRITE_STRING(pParam->szData.c_str());
 | 
			
		||||
			WRITE_STRING(pParam->szData.chars());
 | 
			
		||||
			break;
 | 
			
		||||
		case arg_entity:
 | 
			
		||||
			WRITE_ENTITY(pParam->v.iData);
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,6 @@
 | 
			
		||||
#include <extdll.h>
 | 
			
		||||
#include <meta_api.h>
 | 
			
		||||
#include "amx.h"
 | 
			
		||||
#include "CVector.h"
 | 
			
		||||
#include "CString.h"
 | 
			
		||||
#include "sh_stack.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_MESSAGES 255
 | 
			
		||||
@@ -28,7 +26,7 @@
 | 
			
		||||
class RegisteredMessage
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	CVector<int> m_Forwards;
 | 
			
		||||
	ke::Vector<int> m_Forwards;
 | 
			
		||||
	CStack<int> m_InExecution;
 | 
			
		||||
	bool m_Cleanup;
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +36,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	void AddHook(int fwd)
 | 
			
		||||
	{
 | 
			
		||||
		m_Forwards.push_back(fwd);
 | 
			
		||||
		m_Forwards.append(fwd);
 | 
			
		||||
	}
 | 
			
		||||
	bool RemoveHook(int fwd)
 | 
			
		||||
	{
 | 
			
		||||
@@ -50,52 +48,45 @@ public:
 | 
			
		||||
		{
 | 
			
		||||
			this->m_Cleanup = true;
 | 
			
		||||
 | 
			
		||||
			CVector<int>::iterator iter = m_Forwards.begin();
 | 
			
		||||
			CVector<int>::iterator end = m_Forwards.end();
 | 
			
		||||
			while (iter != end)
 | 
			
		||||
			for (size_t i = 0; i < m_Forwards.length(); ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if (*iter == fwd)
 | 
			
		||||
				int& forward = m_Forwards[i];
 | 
			
		||||
 | 
			
		||||
				if (forward == fwd)
 | 
			
		||||
				{
 | 
			
		||||
					if (*iter != -1)
 | 
			
		||||
					if (forward != -1)
 | 
			
		||||
					{
 | 
			
		||||
						unregisterSPForward(*iter);
 | 
			
		||||
						unregisterSPForward(forward);
 | 
			
		||||
					}
 | 
			
		||||
					*iter = -1;
 | 
			
		||||
 | 
			
		||||
					forward = -1;
 | 
			
		||||
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					iter++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			CVector<int>::iterator iter = m_Forwards.begin();
 | 
			
		||||
			CVector<int>::iterator end = m_Forwards.end();
 | 
			
		||||
			while (iter != end)
 | 
			
		||||
			for (size_t i = 0; i < m_Forwards.length(); ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if (*iter == fwd)
 | 
			
		||||
				{
 | 
			
		||||
					if (fwd != -1)
 | 
			
		||||
					{
 | 
			
		||||
						unregisterSPForward(fwd);
 | 
			
		||||
				int forward = m_Forwards[i];
 | 
			
		||||
 | 
			
		||||
						m_Forwards.erase(iter);
 | 
			
		||||
				if (forward == fwd)
 | 
			
		||||
				{
 | 
			
		||||
					if (forward != -1)
 | 
			
		||||
					{
 | 
			
		||||
						unregisterSPForward(forward);
 | 
			
		||||
 | 
			
		||||
						m_Forwards.remove(forward);
 | 
			
		||||
 | 
			
		||||
						return true;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						// -1 could be in here more than once
 | 
			
		||||
						m_Forwards.erase(iter);
 | 
			
		||||
						m_Forwards.remove(forward);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					iter++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -108,7 +99,7 @@ public:
 | 
			
		||||
		{
 | 
			
		||||
			m_InExecution.pop();
 | 
			
		||||
		}
 | 
			
		||||
		for (size_t i = 0; i < m_Forwards.size(); i++)
 | 
			
		||||
		for (size_t i = 0; i < m_Forwards.length(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			int fwd = m_Forwards[i];
 | 
			
		||||
 | 
			
		||||
@@ -126,7 +117,7 @@ public:
 | 
			
		||||
		m_InExecution.push(1);
 | 
			
		||||
		cell res = 0;
 | 
			
		||||
		cell thisres = 0;
 | 
			
		||||
		for (size_t i = 0; i < m_Forwards.size(); i++)
 | 
			
		||||
		for (size_t i = 0; i < m_Forwards.length(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			int fwd = m_Forwards[i];
 | 
			
		||||
 | 
			
		||||
@@ -152,7 +143,7 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
	bool Hooked() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Forwards.size() != 0;
 | 
			
		||||
		return m_Forwards.length() != 0;
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
enum msgtype
 | 
			
		||||
@@ -175,7 +166,7 @@ struct msgparam
 | 
			
		||||
		REAL fData;
 | 
			
		||||
		int iData;
 | 
			
		||||
	} v;
 | 
			
		||||
	String szData;
 | 
			
		||||
	ke::AString szData;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Message
 | 
			
		||||
@@ -201,7 +192,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
	msgparam *AdvPtr();
 | 
			
		||||
private:
 | 
			
		||||
	CVector<msgparam *> m_Params;
 | 
			
		||||
	ke::Vector<msgparam *> m_Params;
 | 
			
		||||
	size_t m_CurParam;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ void (*function)(void*);
 | 
			
		||||
void (*endfunction)(void*);
 | 
			
		||||
 | 
			
		||||
extern List<AUTHORIZEFUNC> g_auth_funcs;
 | 
			
		||||
extern CVector<CAdminData *> DynamicAdmins;
 | 
			
		||||
extern ke::Vector<CAdminData *> DynamicAdmins;
 | 
			
		||||
 | 
			
		||||
CLog g_log;
 | 
			
		||||
CForwardMngr g_forwards;
 | 
			
		||||
@@ -74,8 +74,8 @@ Grenades g_grenades;
 | 
			
		||||
LogEventsMngr g_logevents;
 | 
			
		||||
MenuMngr g_menucmds;
 | 
			
		||||
CLangMngr g_langMngr;
 | 
			
		||||
String g_log_dir;
 | 
			
		||||
String g_mod_name;
 | 
			
		||||
ke::AString g_log_dir;
 | 
			
		||||
ke::AString g_mod_name;
 | 
			
		||||
XVars g_xvars;
 | 
			
		||||
 | 
			
		||||
bool g_bmod_tfc;
 | 
			
		||||
@@ -100,7 +100,7 @@ bool g_NewDLL_Available = false;
 | 
			
		||||
#ifdef MEMORY_TEST
 | 
			
		||||
	float g_next_memreport_time;
 | 
			
		||||
	unsigned int g_memreport_count;
 | 
			
		||||
	String g_memreport_dir;
 | 
			
		||||
	ke::AString g_memreport_dir;
 | 
			
		||||
	bool g_memreport_enabled;
 | 
			
		||||
	#define MEMREPORT_INTERVAL 300.0f	/* 5 mins */
 | 
			
		||||
#endif // MEMORY_TEST
 | 
			
		||||
@@ -141,21 +141,21 @@ int FF_ChangeLevel = -1;
 | 
			
		||||
 | 
			
		||||
IFileSystem* g_FileSystem;
 | 
			
		||||
 | 
			
		||||
bool ColoredMenus(String & ModName)
 | 
			
		||||
bool ColoredMenus(const char *ModName)
 | 
			
		||||
{
 | 
			
		||||
	const char * pModNames[] = { "cstrike", "czero", "dmc", "dod", "tfc", "valve" };
 | 
			
		||||
	const size_t ModsCount = sizeof(pModNames) / sizeof(const char *);
 | 
			
		||||
 | 
			
		||||
	for (size_t i = 0; i < ModsCount; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (ModName.compare(pModNames[i]) == 0)
 | 
			
		||||
		if (strcmp(ModName, pModNames[i]) == 0)
 | 
			
		||||
			return true; // this game modification currently supports colored menus	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false; // no colored menus are supported for this game modification
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ParseAndOrAdd(CStack<String *> & files, const char *name)
 | 
			
		||||
void ParseAndOrAdd(CStack<ke::AString *> & files, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	if (strncmp(name, "plugins-", 8) == 0)
 | 
			
		||||
	{
 | 
			
		||||
@@ -164,7 +164,7 @@ void ParseAndOrAdd(CStack<String *> & files, const char *name)
 | 
			
		||||
		if (strcmp(&name[len-4], ".ini") == 0)
 | 
			
		||||
		{
 | 
			
		||||
#endif
 | 
			
		||||
			String *pString = new String(name);
 | 
			
		||||
			ke::AString *pString = new ke::AString(name);
 | 
			
		||||
			files.push(pString);
 | 
			
		||||
#if !defined WIN32
 | 
			
		||||
		}
 | 
			
		||||
@@ -172,7 +172,7 @@ void ParseAndOrAdd(CStack<String *> & files, const char *name)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuildPluginFileList(const char *initialdir, CStack<String *> & files)
 | 
			
		||||
void BuildPluginFileList(const char *initialdir, CStack<ke::AString *> & files)
 | 
			
		||||
{
 | 
			
		||||
	char path[255];
 | 
			
		||||
#if defined WIN32
 | 
			
		||||
@@ -213,15 +213,15 @@ void BuildPluginFileList(const char *initialdir, CStack<String *> & files)
 | 
			
		||||
//Loads a plugin list into the Plugin Cache and Load Modules cache
 | 
			
		||||
void LoadExtraPluginsToPCALM(const char *initialdir)
 | 
			
		||||
{
 | 
			
		||||
	CStack<String *> files;
 | 
			
		||||
	CStack<ke::AString *> files;
 | 
			
		||||
	BuildPluginFileList(initialdir, files);
 | 
			
		||||
	char path[255];
 | 
			
		||||
	while (!files.empty())
 | 
			
		||||
	{
 | 
			
		||||
		String *pString = files.front();
 | 
			
		||||
		ke::AString *pString = files.front();
 | 
			
		||||
		UTIL_Format(path, sizeof(path)-1, "%s/%s", 
 | 
			
		||||
			initialdir,
 | 
			
		||||
			pString->c_str());
 | 
			
		||||
			pString->chars());
 | 
			
		||||
		g_plugins.CALMFromFile(path);
 | 
			
		||||
		delete pString;
 | 
			
		||||
		files.pop();
 | 
			
		||||
@@ -230,15 +230,15 @@ void LoadExtraPluginsToPCALM(const char *initialdir)
 | 
			
		||||
 | 
			
		||||
void LoadExtraPluginsFromDir(const char *initialdir)
 | 
			
		||||
{
 | 
			
		||||
	CStack<String *> files;
 | 
			
		||||
	CStack<ke::AString *> files;
 | 
			
		||||
	char path[255];
 | 
			
		||||
	BuildPluginFileList(initialdir, files);
 | 
			
		||||
	while (!files.empty())
 | 
			
		||||
	{
 | 
			
		||||
		String *pString = files.front();
 | 
			
		||||
		ke::AString *pString = files.front();
 | 
			
		||||
		UTIL_Format(path, sizeof(path)-1, "%s/%s", 
 | 
			
		||||
			initialdir,
 | 
			
		||||
			pString->c_str());
 | 
			
		||||
			pString->chars());
 | 
			
		||||
		g_plugins.loadPluginsFromFile(path);
 | 
			
		||||
		delete pString;
 | 
			
		||||
		files.pop();
 | 
			
		||||
@@ -664,7 +664,7 @@ void C_ServerDeactivate()
 | 
			
		||||
	RETURN_META(MRES_IGNORED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern CVector<cell *> g_hudsync;
 | 
			
		||||
extern ke::Vector<cell *> g_hudsync;
 | 
			
		||||
 | 
			
		||||
// After all clear whole AMX configuration
 | 
			
		||||
// However leave AMX modules which are loaded only once
 | 
			
		||||
@@ -700,13 +700,13 @@ void C_ServerDeactivate_Post()
 | 
			
		||||
	ClearMessages();
 | 
			
		||||
	
 | 
			
		||||
	// Flush the dynamic admins list
 | 
			
		||||
	for (size_t iter=DynamicAdmins.size();iter--; )
 | 
			
		||||
	for (size_t iter=DynamicAdmins.length();iter--; )
 | 
			
		||||
	{
 | 
			
		||||
		delete DynamicAdmins[iter];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DynamicAdmins.clear();
 | 
			
		||||
	for (unsigned int i=0; i<g_hudsync.size(); i++)
 | 
			
		||||
	for (unsigned int i=0; i<g_hudsync.length(); i++)
 | 
			
		||||
		delete [] g_hudsync[i];
 | 
			
		||||
	g_hudsync.clear();
 | 
			
		||||
 | 
			
		||||
@@ -733,10 +733,10 @@ void C_ServerDeactivate_Post()
 | 
			
		||||
				char buffer[256];
 | 
			
		||||
				sprintf(buffer, "%s/memreports/D%02d%02d%03d", get_localinfo("amxx_basedir", "addons/amxmodx"), curTime->tm_mon + 1, curTime->tm_mday, i);
 | 
			
		||||
#if defined(__linux__) || defined(__APPLE__)
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.c_str()), 0700);
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.chars()), 0700);
 | 
			
		||||
				if (mkdir(build_pathname(buffer), 0700) < 0)
 | 
			
		||||
#else
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.c_str()));
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.chars()));
 | 
			
		||||
				if (mkdir(build_pathname(buffer)) < 0)
 | 
			
		||||
#endif
 | 
			
		||||
				{
 | 
			
		||||
@@ -752,15 +752,15 @@ void C_ServerDeactivate_Post()
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				g_memreport_dir.assign(buffer);
 | 
			
		||||
				g_memreport_dir = buffer;
 | 
			
		||||
				
 | 
			
		||||
				// g_memreport_dir should be valid now
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		m_dumpMemoryReport(build_pathname("%s/r%03d.txt", g_memreport_dir.c_str(), g_memreport_count));
 | 
			
		||||
		AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d.txt\") (interval %f)", g_memreport_count + 1, g_memreport_dir.c_str(), g_memreport_count, MEMREPORT_INTERVAL);
 | 
			
		||||
		m_dumpMemoryReport(build_pathname("%s/r%03d.txt", g_memreport_dir.chars(), g_memreport_count));
 | 
			
		||||
		AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d.txt\") (interval %f)", g_memreport_count + 1, g_memreport_dir.chars(), g_memreport_count, MEMREPORT_INTERVAL);
 | 
			
		||||
		
 | 
			
		||||
		g_memreport_count++;
 | 
			
		||||
	}
 | 
			
		||||
@@ -845,7 +845,7 @@ void C_ClientUserInfoChanged_Post(edict_t *pEntity, char *infobuffer)
 | 
			
		||||
	// Emulate bot connection and putinserver
 | 
			
		||||
	if (pPlayer->ingame)
 | 
			
		||||
	{
 | 
			
		||||
		pPlayer->name.assign(name);			//	Make sure player have name up to date
 | 
			
		||||
		pPlayer->name =name;			//	Make sure player have name up to date
 | 
			
		||||
	} else if (pPlayer->IsBot()) {
 | 
			
		||||
		pPlayer->Connect(name, "127.0.0.1"/*CVAR_GET_STRING("net_address")*/);
 | 
			
		||||
 | 
			
		||||
@@ -1092,10 +1092,10 @@ void C_StartFrame_Post(void)
 | 
			
		||||
				char buffer[256];
 | 
			
		||||
				sprintf(buffer, "%s/memreports/D%02d%02d%03d", get_localinfo("amxx_basedir", "addons/amxmodx"), curTime->tm_mon + 1, curTime->tm_mday, i);
 | 
			
		||||
#if defined(__linux__) || defined(__APPLE__)
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.c_str()), 0700);
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.chars()), 0700);
 | 
			
		||||
				if (mkdir(build_pathname(buffer), 0700) < 0)
 | 
			
		||||
#else
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.c_str()));
 | 
			
		||||
				mkdir(build_pathname("%s", g_log_dir.chars()));
 | 
			
		||||
				if (mkdir(build_pathname(buffer)) < 0)
 | 
			
		||||
#endif
 | 
			
		||||
				{
 | 
			
		||||
@@ -1111,14 +1111,14 @@ void C_StartFrame_Post(void)
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				g_memreport_dir.assign(buffer);
 | 
			
		||||
				g_memreport_dir = buffer;
 | 
			
		||||
				// g_memreport_dir should be valid now
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		m_dumpMemoryReport(build_pathname("%s/r%03d.txt", g_memreport_dir.c_str(), g_memreport_count));
 | 
			
		||||
		AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d.txt\") (interval %f)", g_memreport_count + 1, g_memreport_dir.c_str(), g_memreport_count, MEMREPORT_INTERVAL);
 | 
			
		||||
		m_dumpMemoryReport(build_pathname("%s/r%03d.txt", g_memreport_dir.chars(), g_memreport_count));
 | 
			
		||||
		AMXXLOG_Log("Memreport #%d created (file \"%s/r%03d.txt\") (interval %f)", g_memreport_count + 1, g_memreport_dir.chars(), g_memreport_count, MEMREPORT_INTERVAL);
 | 
			
		||||
		
 | 
			
		||||
		g_memreport_count++;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1449,9 +1449,9 @@ C_DLLEXPORT	int	Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
 | 
			
		||||
		if (gameDir[i++] ==	'/')
 | 
			
		||||
			a = &gameDir[i];
 | 
			
		||||
	
 | 
			
		||||
	g_mod_name.assign(a);
 | 
			
		||||
	g_mod_name = a;
 | 
			
		||||
 | 
			
		||||
	g_coloredmenus = ColoredMenus(g_mod_name); // whether or not to use colored menus
 | 
			
		||||
	g_coloredmenus = ColoredMenus(g_mod_name.chars()); // whether or not to use colored menus
 | 
			
		||||
 | 
			
		||||
	// ###### Print short GPL
 | 
			
		||||
	print_srvconsole("\n   AMX Mod X version %s Copyright (c) 2004-2015 AMX Mod X Development Team \n"
 | 
			
		||||
@@ -1469,14 +1469,14 @@ C_DLLEXPORT	int	Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
 | 
			
		||||
		
 | 
			
		||||
		while (a != amx_config.end())
 | 
			
		||||
		{
 | 
			
		||||
			SET_LOCALINFO((char*)a.key().c_str(), (char*)a.value().c_str());
 | 
			
		||||
			SET_LOCALINFO((char*)a.key().chars(), (char*)a.value().chars());
 | 
			
		||||
			++a;
 | 
			
		||||
		}
 | 
			
		||||
		amx_config.clear();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// ###### Initialize logging here
 | 
			
		||||
	g_log_dir.assign(get_localinfo("amxx_logs", "addons/amxmodx/logs"));
 | 
			
		||||
	g_log_dir = get_localinfo("amxx_logs", "addons/amxmodx/logs");
 | 
			
		||||
 | 
			
		||||
	// ###### Now attach metamod modules
 | 
			
		||||
	// This will also call modules Meta_Query and Meta_Attach functions
 | 
			
		||||
@@ -1652,14 +1652,14 @@ C_DLLEXPORT	int	GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
 | 
			
		||||
{
 | 
			
		||||
	memset(&meta_engfuncs, 0, sizeof(enginefuncs_t));
 | 
			
		||||
 | 
			
		||||
	if (stricmp(g_mod_name.c_str(), "cstrike") == 0 || stricmp(g_mod_name.c_str(), "czero") == 0)
 | 
			
		||||
	if (stricmp(g_mod_name.chars(), "cstrike") == 0 || stricmp(g_mod_name.chars(), "czero") == 0)
 | 
			
		||||
	{
 | 
			
		||||
		meta_engfuncs.pfnSetModel =	C_SetModel;
 | 
			
		||||
		g_bmod_cstrike = true;
 | 
			
		||||
	} else {
 | 
			
		||||
		g_bmod_cstrike = false;
 | 
			
		||||
		g_bmod_dod = !stricmp(g_mod_name.c_str(), "dod");
 | 
			
		||||
		g_bmod_tfc = !stricmp(g_mod_name.c_str(), "tfc");
 | 
			
		||||
		g_bmod_dod = !stricmp(g_mod_name.chars(), "dod");
 | 
			
		||||
		g_bmod_tfc = !stricmp(g_mod_name.chars(), "tfc");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	meta_engfuncs.pfnCmd_Argc = C_Cmd_Argc;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
 | 
			
		||||
#include "amxmodx.h"
 | 
			
		||||
#include "osdep.h"			// sleep, etc
 | 
			
		||||
#include "CFile.h"
 | 
			
		||||
#include "amxxfile.h"
 | 
			
		||||
#include "amxdbg.h"
 | 
			
		||||
#include "newmenus.h"
 | 
			
		||||
@@ -501,12 +500,12 @@ int set_amxnatives(AMX* amx, char error[128])
 | 
			
		||||
	for (CList<CModule, const char *>::iterator a = g_modules.begin(); a ; ++a)
 | 
			
		||||
	{
 | 
			
		||||
		cm = &(*a);
 | 
			
		||||
		for (size_t i=0; i<cm->m_Natives.size(); i++)
 | 
			
		||||
		for (size_t i=0; i<cm->m_Natives.length(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			amx_Register(amx, cm->m_Natives[i], -1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (size_t i = 0; i < cm->m_NewNatives.size(); i++)
 | 
			
		||||
		for (size_t i = 0; i < cm->m_NewNatives.length(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			amx_Register(amx, cm->m_NewNatives[i], -1);
 | 
			
		||||
		}
 | 
			
		||||
@@ -663,14 +662,14 @@ const char* get_amxscriptname(AMX* amx)
 | 
			
		||||
 | 
			
		||||
void get_modname(char* buffer)
 | 
			
		||||
{
 | 
			
		||||
	strcpy(buffer, g_mod_name.c_str());
 | 
			
		||||
	strcpy(buffer, g_mod_name.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* build_pathname(const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	static char string[256];
 | 
			
		||||
	int b;
 | 
			
		||||
	int a = b = UTIL_Format(string, 255, "%s%c", g_mod_name.c_str(), PATH_SEP_CHAR);
 | 
			
		||||
	int a = b = UTIL_Format(string, 255, "%s%c", g_mod_name.chars(), PATH_SEP_CHAR);
 | 
			
		||||
 | 
			
		||||
	va_list argptr;
 | 
			
		||||
	va_start(argptr, fmt);
 | 
			
		||||
@@ -694,7 +693,7 @@ char* build_pathname(const char *fmt, ...)
 | 
			
		||||
 | 
			
		||||
char *build_pathname_r(char *buffer, size_t maxlen, const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	UTIL_Format(buffer, maxlen, "%s%c", g_mod_name.c_str(), PATH_SEP_CHAR);
 | 
			
		||||
	UTIL_Format(buffer, maxlen, "%s%c", g_mod_name.chars(), PATH_SEP_CHAR);
 | 
			
		||||
 | 
			
		||||
	size_t len = strlen(buffer);
 | 
			
		||||
	char *ptr = buffer + len;
 | 
			
		||||
@@ -740,17 +739,17 @@ char* build_pathname_addons(const char *fmt, ...)
 | 
			
		||||
	return string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ConvertModuleName(const char *pathString, String &path)
 | 
			
		||||
bool ConvertModuleName(const char *pathString, char *path)
 | 
			
		||||
{
 | 
			
		||||
	String local;
 | 
			
		||||
	char local[PLATFORM_MAX_PATH];
 | 
			
		||||
 | 
			
		||||
	local.assign(pathString);
 | 
			
		||||
	char *tmpname = const_cast<char *>(local.c_str());
 | 
			
		||||
	strncopy(local, pathString, sizeof(local));
 | 
			
		||||
	char *tmpname = local;
 | 
			
		||||
	char *orig_path = tmpname;
 | 
			
		||||
 | 
			
		||||
	path.clear();
 | 
			
		||||
	*path = '\0';
 | 
			
		||||
 | 
			
		||||
	size_t len = local.size();
 | 
			
		||||
	size_t len = strlen(local);
 | 
			
		||||
	if (!len)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
@@ -817,34 +816,24 @@ bool ConvertModuleName(const char *pathString, String &path)
 | 
			
		||||
		*ptr = '\0';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	path.assign(orig_path);
 | 
			
		||||
	path.append(PATH_SEP_CHAR);
 | 
			
		||||
	path.append(tmpname);
 | 
			
		||||
	path.append("_amxx");
 | 
			
		||||
#if defined(__linux__)
 | 
			
		||||
 #if defined AMD64 || PAWN_CELL_SIZE==64
 | 
			
		||||
	path.append("_amd64");
 | 
			
		||||
 #else
 | 
			
		||||
	path.append("_i");
 | 
			
		||||
	path.append(iDigit);
 | 
			
		||||
	path.append("86");
 | 
			
		||||
 #endif
 | 
			
		||||
#endif
 | 
			
		||||
#if defined WIN32
 | 
			
		||||
	path.append(".dll");
 | 
			
		||||
#elif defined __linux__
 | 
			
		||||
	path.append(".so");
 | 
			
		||||
#elif defined __APPLE__
 | 
			
		||||
	path.append(".dylib");
 | 
			
		||||
	size_t length = UTIL_Format(path, PLATFORM_MAX_PATH, "%s%c%s_amxx", orig_path, PATH_SEP_CHAR, tmpname);
 | 
			
		||||
 | 
			
		||||
#if defined PLATFORM_LINUX
 | 
			
		||||
# if defined AMD64 || PAWN_CELL_SIZE == 64
 | 
			
		||||
	length += strncopy(path + length, "_amd64", PLATFORM_MAX_PATH - length);
 | 
			
		||||
# else
 | 
			
		||||
	length += UTIL_Format(path + length, PLATFORM_MAX_PATH - length, "_i%d86", iDigit);
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
	UTIL_Format(path + length, PLATFORM_MAX_PATH - length, ".%s", PLATFORM_LIB_EXT);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool noFileBail)
 | 
			
		||||
{
 | 
			
		||||
	char pathString[512];
 | 
			
		||||
	String path;
 | 
			
		||||
	char pathString[PLATFORM_MAX_PATH];
 | 
			
		||||
	char path[PLATFORM_MAX_PATH];
 | 
			
		||||
 | 
			
		||||
	build_pathname_r(
 | 
			
		||||
		pathString, 
 | 
			
		||||
@@ -858,23 +847,23 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no
 | 
			
		||||
		if (!ConvertModuleName(pathString, path))
 | 
			
		||||
			return false;
 | 
			
		||||
	} else {
 | 
			
		||||
		path.assign(pathString);
 | 
			
		||||
		strncopy(path, pathString, sizeof(path));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (noFileBail)
 | 
			
		||||
	{
 | 
			
		||||
		FILE *fp = fopen(path.c_str(), "rb");
 | 
			
		||||
		FILE *fp = fopen(path, "rb");
 | 
			
		||||
		if (!fp)
 | 
			
		||||
			return false;
 | 
			
		||||
		fclose(fp);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CList<CModule, const char *>::iterator a = g_modules.find(path.c_str());
 | 
			
		||||
	CList<CModule, const char *>::iterator a = g_modules.find(path);
 | 
			
		||||
 | 
			
		||||
	if (a)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	CModule* cc = new CModule(path.c_str());
 | 
			
		||||
	CModule* cc = new CModule(path);
 | 
			
		||||
 | 
			
		||||
	cc->queryModule();
 | 
			
		||||
 | 
			
		||||
@@ -883,31 +872,31 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no
 | 
			
		||||
	switch (cc->getStatusValue())
 | 
			
		||||
	{
 | 
			
		||||
	case MODULE_BADLOAD:
 | 
			
		||||
		report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_NOINFO:
 | 
			
		||||
		report_error(1, "[AMXX] Couldn't find info about module (file \"%s\")", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Couldn't find info about module (file \"%s\")", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_NOQUERY:
 | 
			
		||||
		report_error(1, "[AMXX] Couldn't find \"AMX_Query\" or \"AMXX_Query\" (file \"%s\")", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Couldn't find \"AMX_Query\" or \"AMXX_Query\" (file \"%s\")", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_NOATTACH:
 | 
			
		||||
		report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", cc->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Couldn't find \"%s\" (file \"%s\")", cc->isAmxx() ? "AMXX_Attach" : "AMX_Attach", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_OLD:
 | 
			
		||||
		report_error(1, "[AMXX] Module has a different interface version (file \"%s\")", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Module has a different interface version (file \"%s\")", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_NEWER:
 | 
			
		||||
		report_error(1, "[AMXX] Module has a newer interface version (file \"%s\"). Please download a new amxmodx.", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Module has a newer interface version (file \"%s\"). Please download a new amxmodx.", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_INTERROR:
 | 
			
		||||
		report_error(1, "[AMXX] Internal error during module load (file \"%s\")", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Internal error during module load (file \"%s\")", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_NOT64BIT:
 | 
			
		||||
		report_error(1, "[AMXX] Module \"%s\" is not 64 bit compatible.", path.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Module \"%s\" is not 64 bit compatible.", path);
 | 
			
		||||
		break;
 | 
			
		||||
	case MODULE_BADGAME:
 | 
			
		||||
		report_error(1, "[AMXX] Module \"%s\" cannot load on game \"%s\"", path.c_str(), g_mod_name.c_str());
 | 
			
		||||
		report_error(1, "[AMXX] Module \"%s\" cannot load on game \"%s\"", path, g_mod_name.chars());
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		error = false;
 | 
			
		||||
@@ -928,7 +917,7 @@ bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify, bool no
 | 
			
		||||
							get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), 
 | 
			
		||||
							shortname);
 | 
			
		||||
		ConvertModuleName(mmpathname, path);
 | 
			
		||||
		cc->attachMetamod(path.c_str(), now);
 | 
			
		||||
		cc->attachMetamod(path, now);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool retVal = cc->attachModule();
 | 
			
		||||
@@ -965,35 +954,37 @@ int loadModules(const char* filename, PLUG_LOADTIME now)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	String line;
 | 
			
		||||
	char line[256];
 | 
			
		||||
	char moduleName[256];
 | 
			
		||||
	char buffer[255];
 | 
			
		||||
	int loaded = 0;
 | 
			
		||||
 | 
			
		||||
	String path;
 | 
			
		||||
 | 
			
		||||
	while (!feof(fp))
 | 
			
		||||
	{
 | 
			
		||||
		buffer[0] = '\0';
 | 
			
		||||
		fgets(buffer, sizeof(buffer)-1, fp);
 | 
			
		||||
 | 
			
		||||
		if (buffer[0] == ';' || buffer[0] == '\n')
 | 
			
		||||
		UTIL_TrimLeft(buffer);
 | 
			
		||||
		UTIL_TrimRight(buffer);
 | 
			
		||||
 | 
			
		||||
		if (!buffer[0] || buffer[0] == ';' || buffer[0] == '\n')
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		bool simplify = true;
 | 
			
		||||
 | 
			
		||||
		if (buffer[0] == '>')
 | 
			
		||||
		{
 | 
			
		||||
			simplify = false;
 | 
			
		||||
			line.assign(&buffer[1]);
 | 
			
		||||
		} else {
 | 
			
		||||
			line.assign(buffer);
 | 
			
		||||
			strncopy(line, &buffer[1], sizeof(line));
 | 
			
		||||
		} 
 | 
			
		||||
		else 
 | 
			
		||||
		{
 | 
			
		||||
			strncopy(line, buffer, sizeof(line));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		line.trim();
 | 
			
		||||
		*moduleName = '\0';
 | 
			
		||||
		
 | 
			
		||||
		*moduleName = 0;
 | 
			
		||||
		
 | 
			
		||||
		if (sscanf(line.c_str(), "%s", moduleName) == EOF)
 | 
			
		||||
		if (sscanf(line, "%s", moduleName) == EOF)
 | 
			
		||||
			continue;
 | 
			
		||||
		
 | 
			
		||||
		if (LoadModule(moduleName, now, simplify))
 | 
			
		||||
@@ -1130,7 +1121,7 @@ int MNF_AddNatives(AMX_NATIVE_INFO* natives)
 | 
			
		||||
	if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach)
 | 
			
		||||
		return FALSE;				// may only be called from attach
 | 
			
		||||
 | 
			
		||||
	g_CurrentlyCalledModule->m_Natives.push_back(natives);
 | 
			
		||||
	g_CurrentlyCalledModule->m_Natives.append(natives);
 | 
			
		||||
	
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1140,21 +1131,14 @@ int MNF_AddNewNatives(AMX_NATIVE_INFO *natives)
 | 
			
		||||
	if (!g_CurrentlyCalledModule || g_ModuleCallReason != ModuleCall_Attach)
 | 
			
		||||
		return FALSE;				// may only be called from attach
 | 
			
		||||
 | 
			
		||||
	g_CurrentlyCalledModule->m_NewNatives.push_back(natives);
 | 
			
		||||
	g_CurrentlyCalledModule->m_NewNatives.append(natives);
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *MNF_GetModname(void)
 | 
			
		||||
{
 | 
			
		||||
	// :TODO: Do we have to do this?? 
 | 
			
		||||
	// I dunno who wrote the above comment but no
 | 
			
		||||
#if 0
 | 
			
		||||
	static char buffer[64];
 | 
			
		||||
	strcpy(buffer, g_mod_name.c_str());
 | 
			
		||||
	return buffer;
 | 
			
		||||
#endif
 | 
			
		||||
	return g_mod_name.c_str();
 | 
			
		||||
	return g_mod_name.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AMX *MNF_GetAmxScript(int id)
 | 
			
		||||
@@ -1314,7 +1298,7 @@ const char * MNF_GetPlayerName(int id)
 | 
			
		||||
	if (id < 1 || id > gpGlobals->maxClients)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	
 | 
			
		||||
	return GET_PLAYER_POINTER_I(id)->name.c_str();
 | 
			
		||||
	return GET_PLAYER_POINTER_I(id)->name.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MNF_OverrideNatives(AMX_NATIVE_INFO *natives, const char *name)
 | 
			
		||||
@@ -1340,7 +1324,7 @@ const char * MNF_GetPlayerIP(int id)
 | 
			
		||||
	if (id < 1 || id > gpGlobals->maxClients)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	
 | 
			
		||||
	return GET_PLAYER_POINTER_I(id)->ip.c_str();
 | 
			
		||||
	return GET_PLAYER_POINTER_I(id)->ip.chars();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int MNF_IsPlayerInGame(int id)
 | 
			
		||||
@@ -1614,7 +1598,7 @@ const char *MNF_GetPlayerTeam(int id)
 | 
			
		||||
	if (id < 1 || id > gpGlobals->maxClients)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return (GET_PLAYER_POINTER_I(id)->team.c_str());
 | 
			
		||||
	return (GET_PLAYER_POINTER_I(id)->team.chars());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef MEMORY_TEST
 | 
			
		||||
@@ -1703,7 +1687,7 @@ int MNF_SetPlayerTeamInfo(int player, int teamid, const char *teamname)
 | 
			
		||||
	if (player < 1 || player > gpGlobals->maxClients)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
    CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
 | 
			
		||||
	CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
 | 
			
		||||
 | 
			
		||||
	if (!pPlayer->ingame)
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -1711,7 +1695,7 @@ int MNF_SetPlayerTeamInfo(int player, int teamid, const char *teamname)
 | 
			
		||||
	pPlayer->teamId = teamid;
 | 
			
		||||
	if (teamname != NULL)
 | 
			
		||||
	{
 | 
			
		||||
		pPlayer->team.assign(teamname);
 | 
			
		||||
		pPlayer->team = teamname;
 | 
			
		||||
 | 
			
		||||
		// Make sure team is registered, otherwise
 | 
			
		||||
		// natives relying on team id will return wrong result.
 | 
			
		||||
 
 | 
			
		||||
@@ -253,7 +253,6 @@
 | 
			
		||||
    <ClCompile Include="..\CCmd.cpp" />
 | 
			
		||||
    <ClCompile Include="..\CDataPack.cpp" />
 | 
			
		||||
    <ClCompile Include="..\CEvent.cpp" />
 | 
			
		||||
    <ClCompile Include="..\CFile.cpp" />
 | 
			
		||||
    <ClCompile Include="..\CFlagManager.cpp" />
 | 
			
		||||
    <ClCompile Include="..\CForward.cpp" />
 | 
			
		||||
    <ClCompile Include="..\CGameConfigs.cpp" />
 | 
			
		||||
@@ -338,7 +337,6 @@
 | 
			
		||||
    <ClInclude Include="..\CCmd.h" />
 | 
			
		||||
    <ClInclude Include="..\CDataPack.h" />
 | 
			
		||||
    <ClInclude Include="..\CEvent.h" />
 | 
			
		||||
    <ClInclude Include="..\CFile.h" />
 | 
			
		||||
    <ClInclude Include="..\CFileSystem.h" />
 | 
			
		||||
    <ClInclude Include="..\CFlagManager.h" />
 | 
			
		||||
    <ClInclude Include="..\CForward.h" />
 | 
			
		||||
@@ -352,12 +350,10 @@
 | 
			
		||||
    <ClInclude Include="..\CModule.h" />
 | 
			
		||||
    <ClInclude Include="..\CPlugin.h" />
 | 
			
		||||
    <ClInclude Include="..\CQueue.h" />
 | 
			
		||||
    <ClInclude Include="..\CString.h" />
 | 
			
		||||
    <ClInclude Include="..\CTask.h" />
 | 
			
		||||
    <ClInclude Include="..\CTextParsers.h" />
 | 
			
		||||
    <ClInclude Include="..\CvarManager.h" />
 | 
			
		||||
    <ClInclude Include="..\CVault.h" />
 | 
			
		||||
    <ClInclude Include="..\CVector.h" />
 | 
			
		||||
    <ClInclude Include="..\datastructs.h" />
 | 
			
		||||
    <ClInclude Include="..\debugger.h" />
 | 
			
		||||
    <ClInclude Include="..\fakemeta.h" />
 | 
			
		||||
 
 | 
			
		||||
@@ -78,9 +78,6 @@
 | 
			
		||||
    <ClCompile Include="..\CEvent.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="..\CFile.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="..\CFlagManager.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
@@ -317,9 +314,6 @@
 | 
			
		||||
    <ClInclude Include="..\CEvent.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\CFile.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\CFlagManager.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
@@ -350,18 +344,12 @@
 | 
			
		||||
    <ClInclude Include="..\CQueue.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\CString.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\CTask.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\CVault.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\CVector.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\datastructs.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
//With the exception for param_convert, which was written by
 | 
			
		||||
// Julien "dJeyL" Laurent
 | 
			
		||||
 | 
			
		||||
CVector<regnative *> g_RegNatives;
 | 
			
		||||
ke::Vector<regnative *> g_RegNatives;
 | 
			
		||||
static char g_errorStr[512] = {0};
 | 
			
		||||
bool g_Initialized = false;
 | 
			
		||||
 | 
			
		||||
@@ -40,7 +40,7 @@ int g_CurError = AMX_ERR_NONE;
 | 
			
		||||
 | 
			
		||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
	if (idx < 0 || idx >= (int)g_RegNatives.size())
 | 
			
		||||
	if (idx < 0 || idx >= (int)g_RegNatives.length())
 | 
			
		||||
	{
 | 
			
		||||
		LogError(amx, AMX_ERR_NATIVE, "Invalid dynamic native called");
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -152,24 +152,24 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
AMX_NATIVE_INFO *BuildNativeTable()
 | 
			
		||||
{
 | 
			
		||||
	if (g_RegNatives.size() < 1)
 | 
			
		||||
	if (g_RegNatives.length() < 1)
 | 
			
		||||
	{
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
 | 
			
		||||
	AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.length() + 1];
 | 
			
		||||
 | 
			
		||||
	AMX_NATIVE_INFO info;
 | 
			
		||||
	regnative *pNative;
 | 
			
		||||
	for (size_t i=0; i<g_RegNatives.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<g_RegNatives.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		pNative = g_RegNatives[i];
 | 
			
		||||
		info.name = pNative->name.c_str();
 | 
			
		||||
		info.name = pNative->name.chars();
 | 
			
		||||
		info.func = (AMX_NATIVE)((void *)(pNative->pfn));
 | 
			
		||||
		pNatives[i] = info;
 | 
			
		||||
	}
 | 
			
		||||
	pNatives[g_RegNatives.size()].name = NULL;
 | 
			
		||||
	pNatives[g_RegNatives.size()].func = NULL;
 | 
			
		||||
	pNatives[g_RegNatives.length()].name = NULL;
 | 
			
		||||
	pNatives[g_RegNatives.length()].func = NULL;
 | 
			
		||||
 | 
			
		||||
	//this needs to be deleted
 | 
			
		||||
	return pNatives;
 | 
			
		||||
@@ -474,15 +474,15 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
 | 
			
		||||
	mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	int id = (int)g_RegNatives.size();
 | 
			
		||||
	int id = (int)g_RegNatives.length();
 | 
			
		||||
	
 | 
			
		||||
	amxx_DynaMake(pNative->pfn, id);
 | 
			
		||||
	pNative->func = idx;
 | 
			
		||||
	pNative->style = params[3];
 | 
			
		||||
 | 
			
		||||
	g_RegNatives.push_back(pNative);
 | 
			
		||||
	g_RegNatives.append(pNative);
 | 
			
		||||
 | 
			
		||||
	pNative->name.assign(name);
 | 
			
		||||
	pNative->name = name;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -490,7 +490,7 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
 | 
			
		||||
void ClearPluginLibraries()
 | 
			
		||||
{
 | 
			
		||||
	ClearLibraries(LibSource_Plugin);
 | 
			
		||||
	for (size_t i=0; i<g_RegNatives.size(); i++)
 | 
			
		||||
	for (size_t i=0; i<g_RegNatives.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		delete [] g_RegNatives[i]->pfn;
 | 
			
		||||
		delete g_RegNatives[i];
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
struct regnative
 | 
			
		||||
{
 | 
			
		||||
	AMX *amx;
 | 
			
		||||
	String name;
 | 
			
		||||
	ke::AString name;
 | 
			
		||||
	char *pfn;
 | 
			
		||||
	int func;
 | 
			
		||||
	int style;
 | 
			
		||||
 
 | 
			
		||||
@@ -11,12 +11,12 @@
 | 
			
		||||
#include "CMenu.h"
 | 
			
		||||
#include "newmenus.h"
 | 
			
		||||
 | 
			
		||||
CVector<Menu *> g_NewMenus;
 | 
			
		||||
ke::Vector<Menu *> g_NewMenus;
 | 
			
		||||
CStack<int> g_MenuFreeStack;
 | 
			
		||||
 | 
			
		||||
void ClearMenus()
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i = 0; i < g_NewMenus.size(); i++)
 | 
			
		||||
	for (size_t i = 0; i < g_NewMenus.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		delete g_NewMenus[i];
 | 
			
		||||
	}
 | 
			
		||||
@@ -62,7 +62,7 @@ void validate_menu_text(char *str)
 | 
			
		||||
 | 
			
		||||
Menu *get_menu_by_id(int id)
 | 
			
		||||
{
 | 
			
		||||
	if (id < 0 || size_t(id) >= g_NewMenus.size() || !g_NewMenus[id])
 | 
			
		||||
	if (id < 0 || size_t(id) >= g_NewMenus.length() || !g_NewMenus[id])
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return g_NewMenus[id];
 | 
			
		||||
@@ -90,14 +90,14 @@ isDestroying(false), items_per_page(7)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_OptNames[abs(MENU_BACK)].assign("Back");
 | 
			
		||||
	m_OptNames[abs(MENU_MORE)].assign("More");
 | 
			
		||||
	m_OptNames[abs(MENU_EXIT)].assign("Exit");
 | 
			
		||||
	m_OptNames[abs(MENU_BACK)] = "Back";
 | 
			
		||||
	m_OptNames[abs(MENU_MORE)] = "More";
 | 
			
		||||
	m_OptNames[abs(MENU_EXIT)] = "Exit";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Menu::~Menu()
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i = 0; i < m_Items.size(); i++)
 | 
			
		||||
	for (size_t i = 0; i < m_Items.length(); i++)
 | 
			
		||||
	{
 | 
			
		||||
		delete m_Items[i];
 | 
			
		||||
	}
 | 
			
		||||
@@ -111,22 +111,22 @@ menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
 | 
			
		||||
{
 | 
			
		||||
	menuitem *pItem = new menuitem;
 | 
			
		||||
 | 
			
		||||
	pItem->name.assign(name);
 | 
			
		||||
	pItem->cmd.assign(cmd);
 | 
			
		||||
	pItem->name = name;
 | 
			
		||||
	pItem->cmd = cmd;
 | 
			
		||||
	pItem->access = access;
 | 
			
		||||
	pItem->id = m_Items.size();
 | 
			
		||||
	pItem->id = m_Items.length();
 | 
			
		||||
	pItem->handler = -1;
 | 
			
		||||
	pItem->isBlank = false;
 | 
			
		||||
	pItem->pfn = NULL;
 | 
			
		||||
 | 
			
		||||
	m_Items.push_back(pItem);
 | 
			
		||||
	m_Items.append(pItem);
 | 
			
		||||
 | 
			
		||||
	return pItem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
menuitem *Menu::GetMenuItem(item_t item)
 | 
			
		||||
{
 | 
			
		||||
	if (item >= m_Items.size())
 | 
			
		||||
	if (item >= m_Items.length())
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return m_Items[item];
 | 
			
		||||
@@ -134,7 +134,7 @@ menuitem *Menu::GetMenuItem(item_t item)
 | 
			
		||||
 | 
			
		||||
size_t Menu::GetItemCount()
 | 
			
		||||
{
 | 
			
		||||
	return m_Items.size();
 | 
			
		||||
	return m_Items.length();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t Menu::GetPageCount()
 | 
			
		||||
@@ -155,7 +155,7 @@ int Menu::PagekeyToItem(page_t page, item_t key)
 | 
			
		||||
 | 
			
		||||
	if (num_pages == 1 || !items_per_page)
 | 
			
		||||
	{
 | 
			
		||||
		if (key > m_Items.size())
 | 
			
		||||
		if (key > m_Items.length())
 | 
			
		||||
		{
 | 
			
		||||
			return MENU_EXIT;
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -167,9 +167,9 @@ int Menu::PagekeyToItem(page_t page, item_t key)
 | 
			
		||||
		{
 | 
			
		||||
			/* The algorithm for spaces here is same as a middle page. */
 | 
			
		||||
			item_t new_key = key;
 | 
			
		||||
			for (size_t i=start; i<(start+key-1) && i<m_Items.size(); i++)
 | 
			
		||||
			for (size_t i=start; i<(start+key-1) && i<m_Items.length(); i++)
 | 
			
		||||
			{
 | 
			
		||||
				for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
 | 
			
		||||
				for (size_t j=0; j<m_Items[i]->blanks.length(); j++)
 | 
			
		||||
				{
 | 
			
		||||
					if (m_Items[i]->blanks[j].EatNumber())
 | 
			
		||||
					{
 | 
			
		||||
@@ -197,7 +197,7 @@ int Menu::PagekeyToItem(page_t page, item_t key)
 | 
			
		||||
		} else if (page == num_pages - 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;
 | 
			
		||||
			size_t remaining = m_Items.length() - start;
 | 
			
		||||
			item_t new_key = key;
 | 
			
		||||
			
 | 
			
		||||
			// For every item that takes up a slot (item or padded blank)
 | 
			
		||||
@@ -205,7 +205,7 @@ int Menu::PagekeyToItem(page_t page, item_t 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++)
 | 
			
		||||
			for (size_t i=m_Items.length() - remaining; i<m_Items.length(); i++)
 | 
			
		||||
			{
 | 
			
		||||
				item_tracker++;
 | 
			
		||||
				
 | 
			
		||||
@@ -217,7 +217,7 @@ int Menu::PagekeyToItem(page_t page, item_t key)
 | 
			
		||||
				
 | 
			
		||||
				new_key--;
 | 
			
		||||
				
 | 
			
		||||
				for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
 | 
			
		||||
				for (size_t j=0; j<m_Items[i]->blanks.length(); j++)
 | 
			
		||||
				{
 | 
			
		||||
					if (m_Items[i]->blanks[j].EatNumber())
 | 
			
		||||
					{
 | 
			
		||||
@@ -249,9 +249,9 @@ int Menu::PagekeyToItem(page_t page, item_t key)
 | 
			
		||||
			 * 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 i=start; i<(start+items_per_page-1) && i<m_Items.length(); i++)
 | 
			
		||||
			{
 | 
			
		||||
				for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
 | 
			
		||||
				for (size_t j=0; j<m_Items[i]->blanks.length(); j++)
 | 
			
		||||
				{
 | 
			
		||||
					if (m_Items[i]->blanks[j].EatNumber())
 | 
			
		||||
					{
 | 
			
		||||
@@ -336,23 +336,23 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
	if (page >= pages)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	m_Text.clear();
 | 
			
		||||
	m_Text = nullptr;
 | 
			
		||||
 | 
			
		||||
	char buffer[255];
 | 
			
		||||
	if (items_per_page && (pages != 1))
 | 
			
		||||
	{
 | 
			
		||||
		if (m_AutoColors)
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.chars(), page + 1, pages);
 | 
			
		||||
		else
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.chars(), page + 1, pages);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (m_AutoColors)
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.chars());
 | 
			
		||||
		else
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.chars());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	m_Text.append(buffer);
 | 
			
		||||
	m_Text = m_Text + buffer;
 | 
			
		||||
 | 
			
		||||
	enum
 | 
			
		||||
	{
 | 
			
		||||
@@ -446,39 +446,39 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
 | 
			
		||||
		if (pItem->isBlank)
 | 
			
		||||
		{
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "%s\n", pItem->name.c_str());
 | 
			
		||||
			UTIL_Format(buffer, sizeof(buffer)-1, "%s\n", pItem->name.chars());
 | 
			
		||||
		}
 | 
			
		||||
		else if (enabled)
 | 
			
		||||
		{
 | 
			
		||||
			if (m_AutoColors) 
 | 
			
		||||
			{
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "%s%d.\\w %s\n", m_ItemColor.c_str(),option_display, pItem->name.c_str());
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "%s%d.\\w %s\n", m_ItemColor.chars(),option_display, pItem->name.chars());
 | 
			
		||||
			} else {
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "%d. %s\n", option_display, pItem->name.c_str());
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "%d. %s\n", option_display, pItem->name.chars());
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if (m_AutoColors)
 | 
			
		||||
			{
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", option_display, pItem->name.c_str());
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", option_display, pItem->name.chars());
 | 
			
		||||
			} else {
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
 | 
			
		||||
				UTIL_Format(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.chars());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		slots++;
 | 
			
		||||
 | 
			
		||||
		m_Text.append(buffer);
 | 
			
		||||
		m_Text = m_Text + buffer;
 | 
			
		||||
 | 
			
		||||
		//attach blanks
 | 
			
		||||
		if (pItem->blanks.size())
 | 
			
		||||
		if (pItem->blanks.length())
 | 
			
		||||
		{
 | 
			
		||||
			for (size_t j=0; j<pItem->blanks.size(); j++)
 | 
			
		||||
			for (size_t j=0; j<pItem->blanks.length(); j++)
 | 
			
		||||
			{
 | 
			
		||||
				if (pItem->blanks[j].EatNumber())
 | 
			
		||||
				{
 | 
			
		||||
					option++;
 | 
			
		||||
				}
 | 
			
		||||
				m_Text.append(pItem->blanks[j].GetDisplay());
 | 
			
		||||
				m_Text.append("\n");
 | 
			
		||||
				m_Text = m_Text + pItem->blanks[j].GetDisplay();
 | 
			
		||||
				m_Text = m_Text + "\n";
 | 
			
		||||
				slots++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -489,11 +489,11 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
		/* 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");
 | 
			
		||||
			m_Text = m_Text + "\n";
 | 
			
		||||
			option++;
 | 
			
		||||
		}
 | 
			
		||||
		/* Make sure there is at least one visual pad */
 | 
			
		||||
		m_Text.append("\n");
 | 
			
		||||
		m_Text = m_Text + "\n";
 | 
			
		||||
 | 
			
		||||
		/* Don't bother if there is only one page */
 | 
			
		||||
		if (pages > 1)
 | 
			
		||||
@@ -506,15 +506,15 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
					UTIL_Format(buffer, 
 | 
			
		||||
						sizeof(buffer)-1, 
 | 
			
		||||
						"%s%d. \\w%s\n", 
 | 
			
		||||
						m_ItemColor.c_str(), 
 | 
			
		||||
						m_ItemColor.chars(), 
 | 
			
		||||
						option == 10 ? 0 : option, 
 | 
			
		||||
						m_OptNames[abs(MENU_BACK)].c_str());
 | 
			
		||||
						m_OptNames[abs(MENU_BACK)].chars());
 | 
			
		||||
				} else {
 | 
			
		||||
					UTIL_Format(buffer, 
 | 
			
		||||
						sizeof(buffer)-1, 
 | 
			
		||||
						"%d. %s\n", 
 | 
			
		||||
						option == 10 ? 0 : option, 
 | 
			
		||||
						m_OptNames[abs(MENU_BACK)].c_str());
 | 
			
		||||
						m_OptNames[abs(MENU_BACK)].chars());
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				option++;
 | 
			
		||||
@@ -524,12 +524,12 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
						sizeof(buffer)-1,
 | 
			
		||||
						"\\d%d. %s\n\\w",
 | 
			
		||||
						option == 10 ? 0 : option,
 | 
			
		||||
						m_OptNames[abs(MENU_BACK)].c_str());
 | 
			
		||||
						m_OptNames[abs(MENU_BACK)].chars());
 | 
			
		||||
				} else {
 | 
			
		||||
					UTIL_Format(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_BACK)].c_str());
 | 
			
		||||
					UTIL_Format(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_BACK)].chars());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			m_Text.append(buffer);
 | 
			
		||||
			m_Text + m_Text + buffer;
 | 
			
		||||
	
 | 
			
		||||
			if (flags & Display_Next)
 | 
			
		||||
			{
 | 
			
		||||
@@ -539,15 +539,15 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
					UTIL_Format(buffer, 
 | 
			
		||||
						sizeof(buffer)-1, 
 | 
			
		||||
						"%s%d. \\w%s\n", 
 | 
			
		||||
						m_ItemColor.c_str(), 
 | 
			
		||||
						m_ItemColor.chars(), 
 | 
			
		||||
						option == 10 ? 0 : option, 
 | 
			
		||||
						m_OptNames[abs(MENU_MORE)].c_str());
 | 
			
		||||
						m_OptNames[abs(MENU_MORE)].chars());
 | 
			
		||||
				} else {
 | 
			
		||||
					UTIL_Format(buffer, 
 | 
			
		||||
						sizeof(buffer)-1, 
 | 
			
		||||
						"%d. %s\n", 
 | 
			
		||||
						option == 10 ? 0 : option, 
 | 
			
		||||
						m_OptNames[abs(MENU_MORE)].c_str());
 | 
			
		||||
						m_OptNames[abs(MENU_MORE)].chars());
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				option++;
 | 
			
		||||
@@ -557,12 +557,12 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
						sizeof(buffer)-1,
 | 
			
		||||
						"\\d%d. %s\n\\w",
 | 
			
		||||
						option == 10 ? 0 : option,
 | 
			
		||||
						m_OptNames[abs(MENU_MORE)].c_str());
 | 
			
		||||
						m_OptNames[abs(MENU_MORE)].chars());
 | 
			
		||||
				} else {
 | 
			
		||||
					UTIL_Format(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_MORE)].c_str());
 | 
			
		||||
					UTIL_Format(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_MORE)].chars());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			m_Text.append(buffer);
 | 
			
		||||
			m_Text = m_Text + buffer;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* Keep padding */
 | 
			
		||||
			option += 2;
 | 
			
		||||
@@ -573,7 +573,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
	{
 | 
			
		||||
		/* Visual pad has not been added yet */
 | 
			
		||||
		if (!items_per_page)
 | 
			
		||||
			m_Text.append("\n");
 | 
			
		||||
			m_Text = m_Text + "\n";
 | 
			
		||||
		
 | 
			
		||||
		keys |= (1<<option++);
 | 
			
		||||
		if (m_AutoColors)
 | 
			
		||||
@@ -581,25 +581,25 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
 | 
			
		||||
			UTIL_Format(buffer, 
 | 
			
		||||
				sizeof(buffer)-1, 
 | 
			
		||||
				"%s%d. \\w%s\n", 
 | 
			
		||||
				m_ItemColor.c_str(), 
 | 
			
		||||
				m_ItemColor.chars(), 
 | 
			
		||||
				option == 10 ? 0 : option, 
 | 
			
		||||
				m_OptNames[abs(MENU_EXIT)].c_str());
 | 
			
		||||
				m_OptNames[abs(MENU_EXIT)].chars());
 | 
			
		||||
		} else {
 | 
			
		||||
			UTIL_Format(buffer, 
 | 
			
		||||
				sizeof(buffer)-1, 
 | 
			
		||||
				"%d. %s\n", 
 | 
			
		||||
				option == 10 ? 0 : option, 
 | 
			
		||||
				m_OptNames[abs(MENU_EXIT)].c_str());
 | 
			
		||||
				m_OptNames[abs(MENU_EXIT)].chars());
 | 
			
		||||
		}
 | 
			
		||||
		m_Text.append(buffer);
 | 
			
		||||
		m_Text = m_Text + buffer;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return m_Text.c_str();
 | 
			
		||||
	return m_Text.ptr();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define GETMENU(p) Menu *pMenu = get_menu_by_id(p); \
 | 
			
		||||
	if (pMenu == NULL || pMenu->isDestroying) { \
 | 
			
		||||
	LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
 | 
			
		||||
	LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.length()); \
 | 
			
		||||
	return 0; }
 | 
			
		||||
 | 
			
		||||
//Makes a new menu handle (-1 for failure)
 | 
			
		||||
@@ -623,8 +623,8 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
	if (g_MenuFreeStack.empty())
 | 
			
		||||
	{
 | 
			
		||||
		g_NewMenus.push_back(pMenu);
 | 
			
		||||
		pMenu->thisId = (int)g_NewMenus.size() - 1;
 | 
			
		||||
		g_NewMenus.append(pMenu);
 | 
			
		||||
		pMenu->thisId = (int)g_NewMenus.length() - 1;
 | 
			
		||||
	} else {
 | 
			
		||||
		int pos = g_MenuFreeStack.front();
 | 
			
		||||
		g_MenuFreeStack.pop();
 | 
			
		||||
@@ -644,13 +644,13 @@ static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!pMenu->m_Items.size())
 | 
			
		||||
	if (!pMenu->m_Items.length())
 | 
			
		||||
	{
 | 
			
		||||
		LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	menuitem *item = pMenu->m_Items[pMenu->m_Items.size() - 1];
 | 
			
		||||
	menuitem *item = pMenu->m_Items[pMenu->m_Items.length() - 1];
 | 
			
		||||
 | 
			
		||||
	BlankItem a;
 | 
			
		||||
 | 
			
		||||
@@ -662,7 +662,7 @@ static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
 | 
			
		||||
	else
 | 
			
		||||
		a.SetEatNumber(false);
 | 
			
		||||
 | 
			
		||||
	item->blanks.push_back(a);
 | 
			
		||||
	item->blanks.append(ke::Move(a));
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -676,13 +676,13 @@ static cell AMX_NATIVE_CALL menu_addtext(AMX *amx, cell *params)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!pMenu->m_Items.size())
 | 
			
		||||
	if (!pMenu->m_Items.length())
 | 
			
		||||
	{
 | 
			
		||||
		LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items.");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	menuitem *item = pMenu->m_Items[pMenu->m_Items.size() - 1];
 | 
			
		||||
	menuitem *item = pMenu->m_Items[pMenu->m_Items.length() - 1];
 | 
			
		||||
 | 
			
		||||
	BlankItem a;
 | 
			
		||||
 | 
			
		||||
@@ -695,7 +695,7 @@ static cell AMX_NATIVE_CALL menu_addtext(AMX *amx, cell *params)
 | 
			
		||||
	else
 | 
			
		||||
		a.SetEatNumber(false);
 | 
			
		||||
 | 
			
		||||
	item->blanks.push_back(a);
 | 
			
		||||
	item->blanks.append(ke::Move(a));
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -800,7 +800,7 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
 | 
			
		||||
	int loops = 0;
 | 
			
		||||
	while ((menu = pPlayer->newmenu) >= 0)
 | 
			
		||||
	{
 | 
			
		||||
		if ((size_t)menu >= g_NewMenus.size() || !g_NewMenus[menu])
 | 
			
		||||
		if ((size_t)menu >= g_NewMenus.length() || !g_NewMenus[menu])
 | 
			
		||||
		{
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
@@ -856,8 +856,8 @@ static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params)
 | 
			
		||||
	cell *addr = get_amxaddr(amx, params[3]);
 | 
			
		||||
	addr[0] = pItem->access;
 | 
			
		||||
 | 
			
		||||
	set_amxstring(amx, params[4], pItem->cmd.c_str(), params[5]);
 | 
			
		||||
	set_amxstring(amx, params[6], pItem->name.c_str(), params[7]);
 | 
			
		||||
	set_amxstring(amx, params[4], pItem->cmd.chars(), params[5]);
 | 
			
		||||
	set_amxstring(amx, params[6], pItem->name.chars(), params[7]);
 | 
			
		||||
 | 
			
		||||
	if (params[8])
 | 
			
		||||
	{
 | 
			
		||||
@@ -899,7 +899,7 @@ static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
	name = get_amxstring(amx, params[3], 0, len);
 | 
			
		||||
 | 
			
		||||
	pItem->name.assign(name);
 | 
			
		||||
	pItem->name = name;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -918,7 +918,7 @@ static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
	cmd = get_amxstring(amx, params[3], 0, len);
 | 
			
		||||
 | 
			
		||||
	pItem->cmd.assign(cmd);
 | 
			
		||||
	pItem->cmd = cmd;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
@@ -954,7 +954,7 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
 | 
			
		||||
		{
 | 
			
		||||
			char *str = get_amxstring(amx, params[3], 0, len);
 | 
			
		||||
			validate_menu_text(str);
 | 
			
		||||
			pMenu->m_ItemColor.assign(str);
 | 
			
		||||
			pMenu->m_ItemColor = str;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	case MPROP_PERPAGE:
 | 
			
		||||
@@ -972,27 +972,27 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
 | 
			
		||||
		{
 | 
			
		||||
			char *str = get_amxstring(amx, params[3], 0, len);
 | 
			
		||||
			validate_menu_text(str);
 | 
			
		||||
			pMenu->m_OptNames[abs(MENU_BACK)].assign(str);
 | 
			
		||||
			pMenu->m_OptNames[abs(MENU_BACK)] = 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);
 | 
			
		||||
			pMenu->m_OptNames[abs(MENU_MORE)] = 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);
 | 
			
		||||
			pMenu->m_OptNames[abs(MENU_EXIT)] = str;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	case MPROP_TITLE:
 | 
			
		||||
		{
 | 
			
		||||
			char *str = get_amxstring(amx, params[3], 0, len);
 | 
			
		||||
			pMenu->m_Title.assign(str);
 | 
			
		||||
			pMenu->m_Title = str;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	case MPROP_EXITALL:
 | 
			
		||||
@@ -1038,7 +1038,7 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
#define GETMENU_R(p) Menu *pMenu = get_menu_by_id(p); \
 | 
			
		||||
	if (pMenu == NULL) { \
 | 
			
		||||
	LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
 | 
			
		||||
	LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.length()); \
 | 
			
		||||
	return 0; }
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
 | 
			
		||||
 
 | 
			
		||||
@@ -36,38 +36,36 @@ typedef int (*MENUITEM_CALLBACK)(int, int, int);
 | 
			
		||||
class BlankItem
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
	char *m_text;
 | 
			
		||||
	ke::AString m_text;
 | 
			
		||||
	bool m_num;
 | 
			
		||||
public:
 | 
			
		||||
	BlankItem() : m_text(NULL), m_num(false) { }
 | 
			
		||||
	BlankItem(BlankItem &src) { this->copyFrom(src); } 
 | 
			
		||||
	~BlankItem() { free(m_text); }
 | 
			
		||||
 | 
			
		||||
	void copyFrom(BlankItem &src)
 | 
			
		||||
	BlankItem() : m_num(false) 
 | 
			
		||||
	{ 
 | 
			
		||||
		m_text = src.m_text;
 | 
			
		||||
		m_num = src.m_num;
 | 
			
		||||
		src.m_text = NULL; // stop the src from freeing the buffer
 | 
			
		||||
	}
 | 
			
		||||
	BlankItem &operator = (const BlankItem &src) { this->copyFrom(const_cast<BlankItem&>(src)); return *this; }
 | 
			
		||||
 | 
			
		||||
	BlankItem(BlankItem &&other) 
 | 
			
		||||
	{
 | 
			
		||||
		m_text = ke::Forward<ke::AString>(other.m_text);
 | 
			
		||||
		m_num = other.m_num;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* is this text instead of a blank */
 | 
			
		||||
	bool IsText() { return m_text != NULL; }
 | 
			
		||||
	bool IsText() { return m_text.chars() != nullptr; }
 | 
			
		||||
 | 
			
		||||
	/* is this a blank instead of text */
 | 
			
		||||
	bool IsBlank() { return m_text == NULL; }
 | 
			
		||||
	bool IsBlank() { return m_text.chars() == nullptr; }
 | 
			
		||||
 | 
			
		||||
	/* does this item take up a number */
 | 
			
		||||
	bool EatNumber() { return m_num; }
 | 
			
		||||
 | 
			
		||||
	/* the text this item is to display */
 | 
			
		||||
	const char *GetDisplay() { return m_text == NULL ? "" : m_text; }
 | 
			
		||||
	const char *GetDisplay() { return m_text.chars(); }
 | 
			
		||||
 | 
			
		||||
	/* sets this item to use a blank */
 | 
			
		||||
	void SetBlank() { free(m_text); m_text = NULL; }
 | 
			
		||||
	void SetBlank() { m_text = nullptr; }
 | 
			
		||||
 | 
			
		||||
	/* sets this item to display text */
 | 
			
		||||
	void SetText(const char *text) { free(m_text); m_text = strdup(text);  }
 | 
			
		||||
	void SetText(const char *text) { m_text = text;  }
 | 
			
		||||
 | 
			
		||||
	/* sets whether or not this item takes up a line */
 | 
			
		||||
	void SetEatNumber(bool val) { m_num = val; }
 | 
			
		||||
@@ -75,8 +73,8 @@ public:
 | 
			
		||||
};
 | 
			
		||||
struct menuitem
 | 
			
		||||
{
 | 
			
		||||
	String name;
 | 
			
		||||
	String cmd;
 | 
			
		||||
	ke::AString name;
 | 
			
		||||
	ke::AString cmd;
 | 
			
		||||
	
 | 
			
		||||
	int access;
 | 
			
		||||
	int handler;
 | 
			
		||||
@@ -85,7 +83,7 @@ struct menuitem
 | 
			
		||||
	MENUITEM_CALLBACK pfn;
 | 
			
		||||
	size_t id;
 | 
			
		||||
 | 
			
		||||
	CVector<BlankItem> blanks;
 | 
			
		||||
	ke::Vector<BlankItem> blanks;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef unsigned int menu_t;
 | 
			
		||||
@@ -110,13 +108,13 @@ public:
 | 
			
		||||
	int PagekeyToItem(page_t page, item_t key);
 | 
			
		||||
	int GetMenuMenuid();
 | 
			
		||||
public:
 | 
			
		||||
	CVector<menuitem * > m_Items;
 | 
			
		||||
	String m_Title;
 | 
			
		||||
	String m_Text;
 | 
			
		||||
	ke::Vector<menuitem * > m_Items;
 | 
			
		||||
 | 
			
		||||
	String m_OptNames[4];
 | 
			
		||||
	ke::AString m_Title;
 | 
			
		||||
	ke::AutoString m_Text;
 | 
			
		||||
	ke::AString m_OptNames[4];
 | 
			
		||||
	ke::AString m_ItemColor;
 | 
			
		||||
 | 
			
		||||
	String m_ItemColor;
 | 
			
		||||
	bool m_NeverExit;
 | 
			
		||||
	bool m_ForceExit;
 | 
			
		||||
	bool m_AutoColors;
 | 
			
		||||
@@ -132,7 +130,7 @@ public:
 | 
			
		||||
void ClearMenus();
 | 
			
		||||
Menu *get_menu_by_id(int id);
 | 
			
		||||
 | 
			
		||||
extern CVector<Menu *> g_NewMenus;
 | 
			
		||||
extern ke::Vector<Menu *> g_NewMenus;
 | 
			
		||||
extern AMX_NATIVE_INFO g_NewMenuNatives[];
 | 
			
		||||
 | 
			
		||||
#endif //_INCLUDE_NEWMENUS_H
 | 
			
		||||
 
 | 
			
		||||
@@ -1251,17 +1251,16 @@ static cell AMX_NATIVE_CALL amx_strlen(AMX *amx, cell *params)
 | 
			
		||||
 | 
			
		||||
static cell AMX_NATIVE_CALL amx_trim(AMX *amx, cell *params)
 | 
			
		||||
{
 | 
			
		||||
	int len;
 | 
			
		||||
	int len, newlen;
 | 
			
		||||
	char *str = get_amxstring(amx, params[1], 0, len);
 | 
			
		||||
 | 
			
		||||
	String toTrim;
 | 
			
		||||
	UTIL_TrimLeft(str);
 | 
			
		||||
	UTIL_TrimRight(str);
 | 
			
		||||
 | 
			
		||||
	toTrim.assign(str);
 | 
			
		||||
	toTrim.trim();
 | 
			
		||||
	newlen = strlen(str);
 | 
			
		||||
	len -= newlen;
 | 
			
		||||
 | 
			
		||||
	len -= toTrim.size();
 | 
			
		||||
 | 
			
		||||
	set_amxstring(amx, params[1], toTrim.c_str(), toTrim.size());
 | 
			
		||||
	set_amxstring(amx, params[1], str, newlen);
 | 
			
		||||
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -711,3 +711,48 @@ size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
 | 
			
		||||
		return len;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// From Metamod:Source
 | 
			
		||||
void UTIL_TrimLeft(char *buffer)
 | 
			
		||||
{
 | 
			
		||||
	/* Let's think of this as our iterator */
 | 
			
		||||
	char *i = buffer;
 | 
			
		||||
 | 
			
		||||
	/* Make sure the buffer isn't null */
 | 
			
		||||
	if (i && *i)
 | 
			
		||||
	{
 | 
			
		||||
		/* Add up number of whitespace characters */
 | 
			
		||||
		while (isspace(static_cast<unsigned char>(*i)))
 | 
			
		||||
		{
 | 
			
		||||
			i++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* If whitespace chars in buffer then adjust string so first non-whitespace char is at start of buffer */
 | 
			
		||||
		if (i != buffer)
 | 
			
		||||
		{
 | 
			
		||||
			memmove(buffer, i, (strlen(i) + 1) * sizeof(char));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void UTIL_TrimRight(char *buffer)
 | 
			
		||||
{
 | 
			
		||||
	/* Make sure buffer isn't null */
 | 
			
		||||
	if (buffer)
 | 
			
		||||
	{
 | 
			
		||||
		size_t len = strlen(buffer);
 | 
			
		||||
 | 
			
		||||
		/* Loop through buffer backwards while replacing whitespace chars with null chars */
 | 
			
		||||
		for (size_t i = len - 1; i < len; i--)
 | 
			
		||||
		{
 | 
			
		||||
			if (isspace(static_cast<unsigned char>(buffer[i])))
 | 
			
		||||
			{
 | 
			
		||||
				buffer[i] = '\0';
 | 
			
		||||
			}
 | 
			
		||||
			else 
 | 
			
		||||
			{
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -24,130 +24,132 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <am-string.h>
 | 
			
		||||
 | 
			
		||||
using namespace ke;
 | 
			
		||||
namespace ke {
 | 
			
		||||
 | 
			
		||||
class AutoString
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
    AutoString() : ptr_(NULL), length_(0)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    AutoString(AutoString &&other)
 | 
			
		||||
     : ptr_(other.ptr_),
 | 
			
		||||
       length_(other.length_)
 | 
			
		||||
    {
 | 
			
		||||
      other.ptr_ = nullptr;
 | 
			
		||||
      other.length_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
    AutoString(const char *ptr)
 | 
			
		||||
    {
 | 
			
		||||
      assign(ptr);
 | 
			
		||||
    }
 | 
			
		||||
    AutoString(const AString &str)
 | 
			
		||||
    {
 | 
			
		||||
      assign(str.chars(), str.length());
 | 
			
		||||
    }
 | 
			
		||||
    AutoString(const char *ptr, size_t len)
 | 
			
		||||
    {
 | 
			
		||||
      assign(ptr, len);
 | 
			
		||||
    }
 | 
			
		||||
    AutoString(const AutoString &other)
 | 
			
		||||
    {
 | 
			
		||||
      assign(other.ptr(), other.length());
 | 
			
		||||
    }
 | 
			
		||||
    ~AutoString()
 | 
			
		||||
    {
 | 
			
		||||
      free(ptr_);
 | 
			
		||||
    }
 | 
			
		||||
public:
 | 
			
		||||
  AutoString() : ptr_(nullptr), length_(0)
 | 
			
		||||
  {
 | 
			
		||||
  }
 | 
			
		||||
  AutoString(AutoString &&other)
 | 
			
		||||
    : ptr_(other.ptr_),
 | 
			
		||||
    length_(other.length_)
 | 
			
		||||
  {
 | 
			
		||||
    other.ptr_ = nullptr;
 | 
			
		||||
    other.length_ = 0;
 | 
			
		||||
  }
 | 
			
		||||
  AutoString(const char *ptr)
 | 
			
		||||
  {
 | 
			
		||||
    assign(ptr);
 | 
			
		||||
  }
 | 
			
		||||
  AutoString(const AString &str)
 | 
			
		||||
  {
 | 
			
		||||
    assign(str.chars(), str.length());
 | 
			
		||||
  }
 | 
			
		||||
  AutoString(const char *ptr, size_t len)
 | 
			
		||||
  {
 | 
			
		||||
    assign(ptr, len);
 | 
			
		||||
  }
 | 
			
		||||
  AutoString(const AutoString &other)
 | 
			
		||||
  {
 | 
			
		||||
    assign(other.ptr(), other.length());
 | 
			
		||||
  }
 | 
			
		||||
  ~AutoString()
 | 
			
		||||
  {
 | 
			
		||||
    free(ptr_);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    AutoString &operator =(const char *ptr) {
 | 
			
		||||
      free(ptr_);
 | 
			
		||||
      assign(ptr);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    AutoString &operator =(const AutoString &other) {
 | 
			
		||||
      free(ptr_);
 | 
			
		||||
      assign(other.ptr(), other.length());
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    AutoString &operator =(AutoString &&other) {
 | 
			
		||||
      Swap(other.ptr_, ptr_);
 | 
			
		||||
      Swap(other.length_, length_);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
  AutoString &operator =(const char *ptr) {
 | 
			
		||||
    free(ptr_);
 | 
			
		||||
    assign(ptr);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  AutoString &operator =(const AutoString &other) {
 | 
			
		||||
    free(ptr_);
 | 
			
		||||
    assign(other.ptr(), other.length());
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  AutoString &operator =(AutoString &&other) {
 | 
			
		||||
    Swap(other.ptr_, ptr_);
 | 
			
		||||
    Swap(other.length_, length_);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    AutoString operator +(const AutoString &other) const {
 | 
			
		||||
      size_t len = length() + other.length();
 | 
			
		||||
      char *buf = (char *)malloc(len + 1);
 | 
			
		||||
      memcpy(buf, ptr(), length());
 | 
			
		||||
      memcpy(buf + length(), other.ptr(), other.length());
 | 
			
		||||
      buf[len] = '\0';
 | 
			
		||||
  AutoString operator +(const AutoString &other) const {
 | 
			
		||||
    size_t len = length() + other.length();
 | 
			
		||||
    char *buf = (char *)malloc(len + 1);
 | 
			
		||||
    memcpy(buf, ptr(), length());
 | 
			
		||||
    memcpy(buf + length(), other.ptr(), other.length());
 | 
			
		||||
    buf[len] = '\0';
 | 
			
		||||
 | 
			
		||||
      AutoString r;
 | 
			
		||||
      r.ptr_ = buf;
 | 
			
		||||
      r.length_ = len;
 | 
			
		||||
      return r;
 | 
			
		||||
    }
 | 
			
		||||
    AutoString r;
 | 
			
		||||
    r.ptr_ = buf;
 | 
			
		||||
    r.length_ = len;
 | 
			
		||||
    return r;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    AutoString operator +(const char *other) const {
 | 
			
		||||
      size_t other_length = strlen(other);
 | 
			
		||||
      size_t len = length() + other_length;
 | 
			
		||||
      char *buf = (char *)malloc(len + 1);
 | 
			
		||||
      memcpy(buf, ptr(), length());
 | 
			
		||||
      memcpy(buf + length(), other, other_length);
 | 
			
		||||
      buf[len] = '\0';
 | 
			
		||||
  AutoString operator +(const char *other) const {
 | 
			
		||||
    size_t other_length = strlen(other);
 | 
			
		||||
    size_t len = length() + other_length;
 | 
			
		||||
    char *buf = (char *)malloc(len + 1);
 | 
			
		||||
    memcpy(buf, ptr(), length());
 | 
			
		||||
    memcpy(buf + length(), other, other_length);
 | 
			
		||||
    buf[len] = '\0';
 | 
			
		||||
 | 
			
		||||
      AutoString r;
 | 
			
		||||
      r.ptr_ = buf;
 | 
			
		||||
      r.length_ = len;
 | 
			
		||||
      return r;
 | 
			
		||||
    }
 | 
			
		||||
    AutoString r;
 | 
			
		||||
    r.ptr_ = buf;
 | 
			
		||||
    r.length_ = len;
 | 
			
		||||
    return r;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    AutoString operator +(unsigned val) const {
 | 
			
		||||
      char buffer[24];
 | 
			
		||||
      _snprintf(buffer, sizeof(buffer), "%d", val);
 | 
			
		||||
      return *this + buffer;
 | 
			
		||||
    }
 | 
			
		||||
  AutoString operator +(unsigned val) const {
 | 
			
		||||
    char buffer[24];
 | 
			
		||||
    _snprintf(buffer, sizeof(buffer), "%d", val);
 | 
			
		||||
    return *this + buffer;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    size_t length() const {
 | 
			
		||||
      return length_;
 | 
			
		||||
    }
 | 
			
		||||
  size_t length() const {
 | 
			
		||||
    return length_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    bool operator !() const {
 | 
			
		||||
      return !length_;
 | 
			
		||||
    }
 | 
			
		||||
  bool operator !() const {
 | 
			
		||||
    return !length_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    const char *ptr() const {
 | 
			
		||||
      return ptr_ ? ptr_ : "";
 | 
			
		||||
    }
 | 
			
		||||
    operator const char *() const {
 | 
			
		||||
      return ptr();
 | 
			
		||||
    }
 | 
			
		||||
  const char *ptr() const {
 | 
			
		||||
    return ptr_ ? ptr_ : "";
 | 
			
		||||
  }
 | 
			
		||||
  operator const char *() const {
 | 
			
		||||
    return ptr();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    void assign(const char *ptr) {
 | 
			
		||||
      if (!ptr) {
 | 
			
		||||
        ptr_ = NULL;
 | 
			
		||||
        length_ = 0;
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      assign(ptr, strlen(ptr));
 | 
			
		||||
private:
 | 
			
		||||
  void assign(const char *ptr) {
 | 
			
		||||
    if (!ptr) {
 | 
			
		||||
      ptr_ = nullptr;
 | 
			
		||||
      length_ = 0;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    void assign(const char *ptr, size_t length) {
 | 
			
		||||
      if (!ptr) {
 | 
			
		||||
        ptr_ = NULL;
 | 
			
		||||
        length_ = 0;
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      length_ = length;
 | 
			
		||||
      ptr_ = (char *)malloc(length_ + 1);
 | 
			
		||||
      memcpy(ptr_, ptr, length_);
 | 
			
		||||
      ptr_[length_] = '\0';
 | 
			
		||||
    assign(ptr, strlen(ptr));
 | 
			
		||||
  }
 | 
			
		||||
  void assign(const char *ptr, size_t length) {
 | 
			
		||||
    if (!ptr) {
 | 
			
		||||
      ptr_ = nullptr;
 | 
			
		||||
      length_ = 0;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    length_ = length;
 | 
			
		||||
    ptr_ = (char *)malloc(length_ + 1);
 | 
			
		||||
    memcpy(ptr_, ptr, length_);
 | 
			
		||||
    ptr_[length_] = '\0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  char *ptr_;
 | 
			
		||||
  size_t length_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    char *ptr_;
 | 
			
		||||
    size_t length_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // _include_spcomp_auto_string_h_
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user