attempted merge at 1.77 back into trunk... Oh MY GOD
This commit is contained in:
parent
7adc49c541
commit
71065a65dd
409
amxmodx/CFlagManager.cpp
Normal file
409
amxmodx/CFlagManager.cpp
Normal file
|
@ -0,0 +1,409 @@
|
|||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "sh_list.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
#include "CFlagManager.h"
|
||||
|
||||
void CFlagManager::SetFile(const char *Filename)
|
||||
{
|
||||
|
||||
m_strConfigFile.assign(g_mod_name.c_str());
|
||||
m_strConfigFile.append("/");
|
||||
m_strConfigFile.append(get_localinfo("amxx_configsdir","addons/amxmodx/configs"));
|
||||
m_strConfigFile.append("/");
|
||||
m_strConfigFile.append(Filename);
|
||||
|
||||
|
||||
CreateIfNotExist();
|
||||
}
|
||||
|
||||
const int CFlagManager::LoadFile(const int force)
|
||||
{
|
||||
CheckIfDisabled();
|
||||
// If we're disabled get the hell out. now.
|
||||
if (m_iDisabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// if we're not forcing this, and NeedToLoad says we dont have to
|
||||
// then just stop
|
||||
if (!force && !NeedToLoad())
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
this->Clear();
|
||||
|
||||
|
||||
// We need to load the file
|
||||
|
||||
FILE *File;
|
||||
|
||||
File=fopen(m_strConfigFile.c_str(),"r");
|
||||
|
||||
if (!File)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)",m_strConfigFile.c_str());
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Trying to copy this almost exactly as other configs are read...
|
||||
String Line;
|
||||
|
||||
char Command[256];
|
||||
char Flags[256];
|
||||
|
||||
String TempLine;
|
||||
while (!feof(File))
|
||||
{
|
||||
|
||||
Line._fread(File);
|
||||
|
||||
char *nonconst=const_cast<char *>(Line.c_str());
|
||||
|
||||
|
||||
// Strip out comments
|
||||
while (*nonconst)
|
||||
{
|
||||
if (*nonconst==';') // End the line at comments
|
||||
{
|
||||
*nonconst='\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
nonconst++;
|
||||
}
|
||||
};
|
||||
|
||||
Command[0]='\0';
|
||||
Flags[0]='\0';
|
||||
|
||||
// Extract the command
|
||||
TempLine.assign(Line.c_str());
|
||||
|
||||
nonconst=const_cast<char *>(TempLine.c_str());
|
||||
|
||||
char *start=NULL;
|
||||
char *end=NULL;
|
||||
|
||||
// move up line until the first ", mark this down as the start
|
||||
// then find the second " and mark it down as the end
|
||||
while (*nonconst!='\0')
|
||||
{
|
||||
if (*nonconst=='"')
|
||||
{
|
||||
if (start==NULL)
|
||||
{
|
||||
start=nonconst+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
end=nonconst;
|
||||
goto done_with_command;
|
||||
}
|
||||
}
|
||||
nonconst++;
|
||||
}
|
||||
done_with_command:
|
||||
|
||||
// invalid line?
|
||||
if (start==NULL || end==NULL)
|
||||
{
|
||||
// TODO: maybe warn for an invalid non-commented line?
|
||||
continue;
|
||||
}
|
||||
|
||||
*end='\0';
|
||||
|
||||
strncpy(Command,start,sizeof(Command)-1);
|
||||
|
||||
|
||||
// Now do the same thing for the flags
|
||||
nonconst=++end;
|
||||
|
||||
start=NULL;
|
||||
end=NULL;
|
||||
|
||||
// move up line until the first ", mark this down as the start
|
||||
// then find the second " and mark it down as the end
|
||||
while (*nonconst!='\0')
|
||||
{
|
||||
if (*nonconst=='"')
|
||||
{
|
||||
if (start==NULL)
|
||||
{
|
||||
start=nonconst+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
end=nonconst;
|
||||
goto done_with_flags;
|
||||
}
|
||||
}
|
||||
nonconst++;
|
||||
}
|
||||
done_with_flags:
|
||||
// invalid line?
|
||||
if (start==NULL || end==NULL)
|
||||
{
|
||||
// TODO: maybe warn for an invalid non-commented line?
|
||||
continue;
|
||||
}
|
||||
|
||||
*end='\0';
|
||||
|
||||
strncpy(Flags,start,sizeof(Flags)-1);
|
||||
|
||||
|
||||
|
||||
if (!isalnum(*Command))
|
||||
{
|
||||
continue;
|
||||
};
|
||||
|
||||
// Done sucking the command and flags out of the line
|
||||
// now insert this command into the linked list
|
||||
|
||||
AddFromFile(const_cast<const char*>(&Command[0]),&Flags[0]);
|
||||
|
||||
nonconst=const_cast<char *>(Line.c_str());
|
||||
*nonconst='\0';
|
||||
};
|
||||
|
||||
|
||||
fclose(File);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called from LoadFile
|
||||
* Do NOT flag the entries as NeedToWrite
|
||||
* No comment is passed from the file because
|
||||
* this should never get written
|
||||
*/
|
||||
void CFlagManager::AddFromFile(const char *Command, const char *Flags)
|
||||
{
|
||||
|
||||
CFlagEntry *Entry=new CFlagEntry;
|
||||
|
||||
Entry->SetName(Command);
|
||||
Entry->SetFlags(Flags);
|
||||
|
||||
// Link it
|
||||
m_FlagList.push_back(Entry);
|
||||
|
||||
};
|
||||
|
||||
|
||||
void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
|
||||
{
|
||||
if (m_iDisabled) // if disabled in core.ini stop
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int TempFlags=Flags;
|
||||
if (TempFlags==-1)
|
||||
{
|
||||
TempFlags=0;
|
||||
}
|
||||
|
||||
List<CFlagEntry *>::iterator iter;
|
||||
List<CFlagEntry *>::iterator end;
|
||||
|
||||
iter=m_FlagList.begin();
|
||||
end=m_FlagList.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
if (strcmp((*iter)->GetName()->c_str(),Command)==0)
|
||||
{
|
||||
CFlagEntry *Entry=(*iter);
|
||||
|
||||
if (Entry->IsHidden()) // "!" flag, exclude this function
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Found, byref the new flags
|
||||
Flags=Entry->Flags();
|
||||
|
||||
// Move it to the back of the list for faster lookup for the rest
|
||||
m_FlagList.erase(iter);
|
||||
|
||||
m_FlagList.push_back(Entry);
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
// was not found, add it
|
||||
|
||||
CFlagEntry *Entry=new CFlagEntry;
|
||||
|
||||
Entry->SetName(Command);
|
||||
Entry->SetFlags(TempFlags);
|
||||
|
||||
if (Plugin)
|
||||
{
|
||||
CPluginMngr::CPlugin* a = g_plugins.findPluginFast(Plugin);
|
||||
|
||||
if (a)
|
||||
{
|
||||
Entry->SetComment(a->getName());
|
||||
}
|
||||
}
|
||||
|
||||
// This entry was added from a register_* native
|
||||
// it needs to be written during map change
|
||||
Entry->SetNeedWritten(1);
|
||||
|
||||
// Link it
|
||||
m_FlagList.push_back(Entry);
|
||||
|
||||
}
|
||||
void CFlagManager::WriteCommands(void)
|
||||
{
|
||||
List<CFlagEntry *>::iterator iter;
|
||||
List<CFlagEntry *>::iterator end;
|
||||
FILE *File;
|
||||
int NeedToRead=0;
|
||||
|
||||
// First off check the modified time of this file
|
||||
// if it matches the stored modified time, then update
|
||||
// after we write so we do not re-read next map
|
||||
struct stat TempStat;
|
||||
|
||||
stat(m_strConfigFile.c_str(),&TempStat);
|
||||
|
||||
|
||||
|
||||
if (TempStat.st_mtime != m_Stat.st_mtime)
|
||||
{
|
||||
NeedToRead=1;
|
||||
};
|
||||
|
||||
|
||||
File=fopen(m_strConfigFile.c_str(),"a");
|
||||
|
||||
iter=m_FlagList.begin();
|
||||
end=m_FlagList.end();
|
||||
|
||||
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
if ((*iter)->NeedWritten())
|
||||
{
|
||||
if ((*iter)->GetComment()->size())
|
||||
{
|
||||
fprintf(File,"\"%s\" \t\"%s\" ; %s\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str(),(*iter)->GetComment()->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(File,"\"%s\" \t\"%s\"\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str());
|
||||
}
|
||||
(*iter)->SetNeedWritten(0);
|
||||
}
|
||||
++iter;
|
||||
};
|
||||
|
||||
fclose(File);
|
||||
|
||||
|
||||
// If NeedToRead was 0, then update the timestamp
|
||||
// that was saved so we do not re-read this file
|
||||
// next map
|
||||
if (!NeedToRead)
|
||||
{
|
||||
stat(m_strConfigFile.c_str(),&TempStat);
|
||||
|
||||
m_Stat.st_mtime=TempStat.st_mtime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int CFlagManager::ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const
|
||||
{
|
||||
|
||||
// If flagmanager is disabled then ignore this
|
||||
if (m_iDisabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If 5th param exists it was compiled after this change was made
|
||||
// if it does not exist, try our logic at the end of this function
|
||||
// 5th param being > 0 means explicit yes
|
||||
// < 0 means auto detect (default is -1), treat it like there was no 5th param
|
||||
// 0 means explicit no
|
||||
|
||||
if ((params[0] / sizeof(cell)) >= 5)
|
||||
{
|
||||
if (params[5]>0) // This command was explicitly told to be included
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (params[5]==0) // this command was explicitly told to NOT be used
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// auto detect if we should use this command
|
||||
|
||||
// if command access is -1 (default, not set to ADMIN_ALL or any other access), then no
|
||||
if (params[3]==-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// if command is (or starts with) "say", then no
|
||||
if (strncmp(cmdname,"say",3)==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// else use it
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
void CFlagManager::Clear(void)
|
||||
{
|
||||
List<CFlagEntry *>::iterator iter;
|
||||
List<CFlagEntry *>::iterator end;
|
||||
|
||||
iter=m_FlagList.begin();
|
||||
end=m_FlagList.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
delete (*iter);
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
m_FlagList.clear();
|
||||
};
|
||||
|
||||
void CFlagManager::CheckIfDisabled(void)
|
||||
{
|
||||
if (atoi(get_localinfo("disableflagman","0"))==0)
|
||||
{
|
||||
m_iDisabled=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iDisabled=1;
|
||||
}
|
||||
};
|
219
amxmodx/CFlagManager.h
Normal file
219
amxmodx/CFlagManager.h
Normal file
|
@ -0,0 +1,219 @@
|
|||
#ifndef CFLAGMANAGER_H
|
||||
#define CFLAGMANAGER_H
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "sh_list.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
class CFlagEntry
|
||||
{
|
||||
private:
|
||||
String m_strName; // command name ("amx_slap")
|
||||
String m_strFlags; // string flags ("a","b")
|
||||
String m_strComment; // comment to write ("; admincmd.amxx")
|
||||
int m_iFlags; // bitmask flags
|
||||
int m_iNeedWritten; // write this command on map change?
|
||||
int m_iHidden; // set to 1 when the command is set to "!" access in
|
||||
// the .ini file: this means do not process this command
|
||||
|
||||
public:
|
||||
|
||||
CFlagEntry()
|
||||
{
|
||||
m_iNeedWritten=0;
|
||||
m_iFlags=0;
|
||||
m_iHidden=0;
|
||||
};
|
||||
const int NeedWritten(void) const
|
||||
{
|
||||
return m_iNeedWritten;
|
||||
};
|
||||
|
||||
void SetNeedWritten(const int i=1)
|
||||
{
|
||||
m_iNeedWritten=i;
|
||||
};
|
||||
|
||||
const String *GetName(void) const
|
||||
{
|
||||
return &m_strName;
|
||||
};
|
||||
|
||||
const String *GetFlags(void) const
|
||||
{
|
||||
return &m_strFlags;
|
||||
};
|
||||
const String *GetComment(void) const
|
||||
{
|
||||
return &m_strComment;
|
||||
};
|
||||
|
||||
const int Flags(void) const
|
||||
{
|
||||
return m_iFlags;
|
||||
};
|
||||
|
||||
void SetName(const char *data)
|
||||
{
|
||||
m_strName.assign(data);
|
||||
};
|
||||
void SetFlags(const char *flags)
|
||||
{
|
||||
// If this is a "!" entry then stop
|
||||
if (flags && flags[0]=='!')
|
||||
{
|
||||
SetHidden(1);
|
||||
return;
|
||||
}
|
||||
|
||||
m_strFlags.assign(flags);
|
||||
m_iFlags=UTIL_ReadFlags(flags);
|
||||
};
|
||||
void SetFlags(const int flags)
|
||||
{
|
||||
m_iFlags=flags;
|
||||
|
||||
char FlagsString[32];
|
||||
UTIL_GetFlags(FlagsString, flags);
|
||||
|
||||
m_strFlags.assign(FlagsString);
|
||||
};
|
||||
void SetComment(const char *comment)
|
||||
{
|
||||
m_strComment.assign(comment);
|
||||
};
|
||||
void SetHidden(int i=1)
|
||||
{
|
||||
m_iHidden=i;
|
||||
};
|
||||
int IsHidden(void) const
|
||||
{
|
||||
return m_iHidden;
|
||||
};
|
||||
};
|
||||
class CFlagManager
|
||||
{
|
||||
private:
|
||||
List<CFlagEntry *> m_FlagList;
|
||||
String m_strConfigFile;
|
||||
struct stat m_Stat;
|
||||
int m_iForceRead;
|
||||
int m_iDisabled;
|
||||
|
||||
|
||||
void CreateIfNotExist(void) const
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp=fopen(m_strConfigFile.c_str(),"r");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
// File does not exist, create the header
|
||||
fp=fopen(m_strConfigFile.c_str(),"a");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp,"; This file will store the commands used by plugins, and their access level\n");
|
||||
fprintf(fp,"; To change the access of a command, edit the flags beside it and then\n");
|
||||
fprintf(fp,"; change the server's map.\n;\n");
|
||||
fprintf(fp,"; Example: If I wanted to change the amx_slap access to require\n");
|
||||
fprintf(fp,"; RCON access (flag \"l\") I would change this:\n");
|
||||
fprintf(fp,"; \"amx_slap\" \"e\" ; admincmd.amxx\n");
|
||||
fprintf(fp,"; To this:\n");
|
||||
fprintf(fp,"; \"amx_slap\" \"l\" ; admincmd.amxx\n;\n");
|
||||
fprintf(fp,"; To disable a specific command from being used with the command manager\n");
|
||||
fprintf(fp,"; and to only use the plugin-specified access set the flag to \"!\"\n;\n");
|
||||
fprintf(fp,"; NOTE: The plugin name at the end is just for reference to what plugin\n");
|
||||
fprintf(fp,"; uses what commands. It is ignored.\n\n");
|
||||
fclose(fp);
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns 1 if the timestamp for the file is different than the one we have loaded
|
||||
* 0 otherwise
|
||||
*/
|
||||
inline int NeedToLoad(void)
|
||||
{
|
||||
struct stat TempStat;
|
||||
|
||||
stat(m_strConfigFile.c_str(),&TempStat);
|
||||
|
||||
// If the modified timestamp does not match the stored
|
||||
// timestamp than we need to re-read this file.
|
||||
// Otherwise, ignore the file.
|
||||
if (TempStat.st_mtime != m_Stat.st_mtime)
|
||||
{
|
||||
// Save down the modified timestamp
|
||||
m_Stat.st_mtime=TempStat.st_mtime;
|
||||
return 1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
public:
|
||||
|
||||
CFlagManager()
|
||||
{
|
||||
memset(&m_Stat,0x0,sizeof(struct stat));
|
||||
m_iDisabled=0;
|
||||
m_iForceRead=0;
|
||||
};
|
||||
~CFlagManager()
|
||||
{
|
||||
WriteCommands();
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the filename in relation to amxmodx/configs
|
||||
*/
|
||||
void SetFile(const char *Filename="cmdaccess.ini");
|
||||
|
||||
const char *GetFile(void) const { return m_strConfigFile.c_str(); };
|
||||
|
||||
/**
|
||||
* Parse the file, and load all entries
|
||||
* Returns 1 on success, 0 on refusal (no need to), and -1 on error
|
||||
*/
|
||||
const int LoadFile(const int force=0);
|
||||
|
||||
/**
|
||||
* Checks if the command exists in the list
|
||||
* If it does, it byrefs the flags for it
|
||||
* If it does not, it adds it to the list
|
||||
* These are added from register_*cmd calls
|
||||
*/
|
||||
void LookupOrAdd(const char *Command, int &Flags, AMX *Plugin);
|
||||
|
||||
|
||||
/**
|
||||
* Write the commands back to the file
|
||||
*/
|
||||
void WriteCommands(void);
|
||||
|
||||
/**
|
||||
* Add this straight from the cmdaccess.ini file
|
||||
*/
|
||||
void AddFromFile(const char *Command, const char *Flags);
|
||||
|
||||
/**
|
||||
* Checks if this command should be added to flagman or not
|
||||
* This is only checked when adding commands from the register_* natives
|
||||
* If an admin manually adds a command to cmdaccess.ini it will be used
|
||||
* regardless of whatever this function would say should be done with it
|
||||
*/
|
||||
int ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const;
|
||||
|
||||
void Clear(void);
|
||||
|
||||
void CheckIfDisabled(void);
|
||||
};
|
||||
|
||||
#endif // CFLAGMANAGER_H
|
|
@ -304,4 +304,87 @@ public:
|
|||
inline bool isNewTeam() { return newTeam ? true : false; }
|
||||
};
|
||||
|
||||
class CAdminData
|
||||
{
|
||||
private:
|
||||
cell m_AuthData[44];
|
||||
cell m_Password[32];
|
||||
cell m_Flags;
|
||||
cell m_Access;
|
||||
public:
|
||||
|
||||
CAdminData()
|
||||
{
|
||||
m_AuthData[0]=0;
|
||||
m_Password[0]=0;
|
||||
m_Flags=0;
|
||||
m_Access=0;
|
||||
};
|
||||
|
||||
void SetAccess(cell Access)
|
||||
{
|
||||
m_Access=Access;
|
||||
};
|
||||
cell GetAccess(void) const
|
||||
{
|
||||
return m_Access;
|
||||
};
|
||||
|
||||
void SetFlags(cell Flags)
|
||||
{
|
||||
m_Flags=Flags;
|
||||
};
|
||||
cell GetFlags(void) const
|
||||
{
|
||||
return m_Flags;
|
||||
};
|
||||
|
||||
void SetAuthID(const cell *Input)
|
||||
{
|
||||
unsigned int i=0;
|
||||
while (i<sizeof(m_AuthData)-1)
|
||||
{
|
||||
if ((m_AuthData[i++]=*Input++)==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_AuthData[sizeof(m_AuthData)-1]=0;
|
||||
|
||||
};
|
||||
const cell *GetAuthID(void) const
|
||||
{
|
||||
return &m_AuthData[0];
|
||||
};
|
||||
|
||||
void SetPass(const cell *Input)
|
||||
{
|
||||
unsigned int i=0;
|
||||
while (i<sizeof(m_Password)-1)
|
||||
{
|
||||
if ((m_Password[i++]=*Input++)==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_Password[sizeof(m_Password)-1]=0;
|
||||
|
||||
};
|
||||
const cell *GetPass(void) const
|
||||
{
|
||||
return &m_Password[0];
|
||||
};
|
||||
|
||||
CAdminData & operator = (const CAdminData &src)
|
||||
{
|
||||
this->SetAccess(src.GetAccess());
|
||||
this->SetFlags(src.GetFlags());
|
||||
this->SetAuthID(src.GetAuthID());
|
||||
this->SetPass(src.GetPass());
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
#endif //CMISC_H
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
}
|
||||
|
||||
//Added this for amxx inclusion
|
||||
bool empty()
|
||||
bool empty() const
|
||||
{
|
||||
if (!v)
|
||||
return true;
|
||||
|
@ -140,7 +140,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
size_t size() const
|
||||
{
|
||||
if (v)
|
||||
return strlen(v);
|
||||
|
|
|
@ -20,7 +20,7 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
|
|||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
||||
amxmod_compat.cpp nongpl_matches.cpp
|
||||
amxmod_compat.cpp nongpl_matches.cpp CFlagManager.cpp
|
||||
|
||||
LINK = -lgcc -static-libgcc
|
||||
|
||||
|
|
|
@ -35,8 +35,13 @@
|
|||
#include "debugger.h"
|
||||
#include "binlog.h"
|
||||
#include "libraries.h"
|
||||
#include "CFlagManager.h"
|
||||
#include "nongpl_matches.h"
|
||||
|
||||
extern CFlagManager FlagMan;
|
||||
CVector<CAdminData *> DynamicAdmins;
|
||||
char CVarTempBuffer[64];
|
||||
|
||||
const char *invis_cvar_list[5] = {"amxmodx_version", "amxmodx_modules", "amx_debug", "amx_mldebug", "amx_client_languages"};
|
||||
|
||||
bool CheckBadConList(const char *cvar, int type)
|
||||
|
@ -1255,6 +1260,11 @@ static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) /* 4 param *
|
|||
listable = false;
|
||||
}
|
||||
|
||||
if (FlagMan.ShouldIAddThisCommand(amx,params,temp)==1)
|
||||
{
|
||||
FlagMan.LookupOrAdd(temp,access,amx);
|
||||
}
|
||||
|
||||
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable)) == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -1295,6 +1305,11 @@ static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) /* 4 param */
|
|||
listable = false;
|
||||
}
|
||||
|
||||
if (FlagMan.ShouldIAddThisCommand(amx,params,temp)==1)
|
||||
{
|
||||
FlagMan.LookupOrAdd(temp,access,amx);
|
||||
}
|
||||
|
||||
if ((cmd = g_commands.registerCommand(plugin, idx, temp, info, access, listable)) == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -1713,8 +1728,8 @@ static cell AMX_NATIVE_CALL set_pcvar_float(AMX *amx, cell *params)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ptr->value = amx_ctof(params[2]);
|
||||
|
||||
snprintf(CVarTempBuffer,sizeof(CVarTempBuffer)-1,"%f",amx_ctof(params[2]));
|
||||
(*g_engfuncs.pfnCvar_DirectSet)(ptr, &CVarTempBuffer[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1735,7 +1750,7 @@ static cell AMX_NATIVE_CALL get_pcvar_num(AMX *amx, cell *params)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return (int)ptr->value;
|
||||
return atoi(ptr->string);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_cvar_num(AMX *amx, cell *params) /* 1 param */
|
||||
|
@ -1753,7 +1768,7 @@ static cell AMX_NATIVE_CALL get_cvar_num(AMX *amx, cell *params) /* 1 param */
|
|||
}
|
||||
}
|
||||
}
|
||||
return (int)CVAR_GET_FLOAT(get_amxstring(amx, params[1], 0, ilen));
|
||||
return atoi(CVAR_GET_STRING(get_amxstring(amx, params[1], 0, ilen)));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_pcvar_num(AMX *amx, cell *params)
|
||||
|
@ -1765,7 +1780,8 @@ static cell AMX_NATIVE_CALL set_pcvar_num(AMX *amx, cell *params)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ptr->value = (float)params[2];
|
||||
snprintf(CVarTempBuffer,sizeof(CVarTempBuffer)-1,"%d",params[2]);
|
||||
(*g_engfuncs.pfnCvar_DirectSet)(ptr, &CVarTempBuffer[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1789,6 +1805,22 @@ static cell AMX_NATIVE_CALL set_cvar_string(AMX *amx, cell *params) /* 2 param *
|
|||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_pcvar_string(AMX *amx, cell *params) /* 2 param */
|
||||
{
|
||||
cvar_t *ptr = reinterpret_cast<cvar_t *>(params[1]);
|
||||
if (!ptr)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid CVAR pointer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int len;
|
||||
|
||||
(*g_engfuncs.pfnCvar_DirectSet)(ptr, get_amxstring(amx,params[2],0,len));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL log_message(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int len;
|
||||
|
@ -4408,9 +4440,109 @@ static cell AMX_NATIVE_CALL GetLangTransKey(AMX *amx, cell *params)
|
|||
return g_langMngr.GetKeyEntry(key);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL admins_push(AMX *amx, cell *params)
|
||||
{
|
||||
// admins_push("SteamID","password",access,flags);
|
||||
CAdminData *TempData=new CAdminData;;
|
||||
|
||||
TempData->SetAuthID(get_amxaddr(amx,params[1]));
|
||||
TempData->SetPass(get_amxaddr(amx,params[2]));
|
||||
TempData->SetAccess(params[3]);
|
||||
TempData->SetFlags(params[4]);
|
||||
|
||||
DynamicAdmins.push_back(TempData);
|
||||
|
||||
return 0;
|
||||
};
|
||||
static cell AMX_NATIVE_CALL admins_flush(AMX *amx, cell *params)
|
||||
{
|
||||
// admins_flush();
|
||||
|
||||
size_t iter=DynamicAdmins.size();
|
||||
|
||||
while (iter--)
|
||||
{
|
||||
delete DynamicAdmins[iter];
|
||||
}
|
||||
|
||||
DynamicAdmins.clear();
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
static cell AMX_NATIVE_CALL admins_num(AMX *amx, cell *params)
|
||||
{
|
||||
// admins_num();
|
||||
|
||||
return static_cast<cell>(DynamicAdmins.size());
|
||||
};
|
||||
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()))
|
||||
{
|
||||
LogError(amx,AMX_ERR_NATIVE,"Invalid admins num");
|
||||
return 1;
|
||||
};
|
||||
|
||||
int BufferSize;
|
||||
cell *Buffer;
|
||||
const cell *Input;
|
||||
|
||||
switch(params[2])
|
||||
{
|
||||
case Admin_Auth:
|
||||
BufferSize=params[4];
|
||||
Buffer=get_amxaddr(amx, params[3]);
|
||||
Input=DynamicAdmins[params[1]]->GetAuthID();
|
||||
|
||||
while (BufferSize-->0)
|
||||
{
|
||||
if ((*Buffer++=*Input++)==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// hit max buffer size, terminate string
|
||||
*Buffer=0;
|
||||
return 0;
|
||||
break;
|
||||
case Admin_Password:
|
||||
BufferSize=params[4];
|
||||
Buffer=get_amxaddr(amx, params[3]);
|
||||
Input=DynamicAdmins[params[1]]->GetPass();
|
||||
|
||||
while (BufferSize-->0)
|
||||
{
|
||||
if ((*Buffer++=*Input++)==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// hit max buffer size, terminate string
|
||||
*Buffer=0;
|
||||
return 0;
|
||||
break;
|
||||
case Admin_Access:
|
||||
return DynamicAdmins[params[1]]->GetAccess();
|
||||
break;
|
||||
case Admin_Flags:
|
||||
return DynamicAdmins[params[1]]->GetFlags();
|
||||
break;
|
||||
};
|
||||
|
||||
// unknown property
|
||||
return 0;
|
||||
};
|
||||
|
||||
AMX_NATIVE_INFO amxmodx_Natives[] =
|
||||
{
|
||||
{"abort", amx_abort},
|
||||
{"admins_flush", admins_flush},
|
||||
{"admins_lookup", admins_lookup},
|
||||
{"admins_num", admins_num},
|
||||
{"admins_push", admins_push},
|
||||
{"amxx_setpl_curweap", amxx_setpl_curweap},
|
||||
{"arrayset", arrayset},
|
||||
{"get_addr_val", get_addr_val},
|
||||
|
@ -4575,6 +4707,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
|||
{"set_localinfo", set_localinfo},
|
||||
{"set_pcvar_flags", set_pcvar_flags},
|
||||
{"set_pcvar_float", set_pcvar_float},
|
||||
{"set_pcvar_string", set_pcvar_string},
|
||||
{"set_pcvar_num", set_pcvar_num},
|
||||
{"set_task", set_task},
|
||||
{"set_user_flags", set_user_flags},
|
||||
|
|
|
@ -339,6 +339,14 @@ struct func_s
|
|||
const char *desc;
|
||||
};
|
||||
|
||||
enum AdminProperty
|
||||
{
|
||||
Admin_Auth = 0,
|
||||
Admin_Password,
|
||||
Admin_Access,
|
||||
Admin_Flags
|
||||
};
|
||||
|
||||
extern enginefuncs_t *g_pEngTable;
|
||||
|
||||
#endif // AMXMODX_H
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
#include "messages.h"
|
||||
#include "amxmod_compat.h"
|
||||
|
||||
#include "CFlagManager.h"
|
||||
|
||||
|
||||
plugin_info_t Plugin_info =
|
||||
{
|
||||
META_INTERFACE_VERSION, // ifvers
|
||||
|
@ -73,6 +76,7 @@ void (*function)(void*);
|
|||
void (*endfunction)(void*);
|
||||
|
||||
extern List<AUTHORIZEFUNC> g_auth_funcs;
|
||||
extern CVector<CAdminData *> DynamicAdmins;
|
||||
|
||||
CLog g_log;
|
||||
CForwardMngr g_forwards;
|
||||
|
@ -86,7 +90,7 @@ CPlayer* mPlayer;
|
|||
CPluginMngr g_plugins;
|
||||
CTaskMngr g_tasksMngr;
|
||||
CmdMngr g_commands;
|
||||
|
||||
CFlagManager FlagMan;
|
||||
EventsMngr g_events;
|
||||
Grenades g_grenades;
|
||||
LogEventsMngr g_logevents;
|
||||
|
@ -381,6 +385,8 @@ int C_Spawn(edict_t *pent)
|
|||
get_localinfo("amx_pluginsdir", "addons/amxmodx/plugins");
|
||||
get_localinfo("amx_logdir", "addons/amxmodx/logs");
|
||||
|
||||
FlagMan.LoadFile();
|
||||
|
||||
char map_pluginsfile_path[256];
|
||||
char configs_dir[256];
|
||||
|
||||
|
@ -390,6 +396,31 @@ int C_Spawn(edict_t *pent)
|
|||
get_localinfo_r("amxx_configsdir", "addons/amxmodx/configs", configs_dir, sizeof(configs_dir)-1);
|
||||
g_plugins.CALMFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini"));
|
||||
LoadExtraPluginsToPCALM(configs_dir);
|
||||
char temporaryMap[64];
|
||||
|
||||
strncpy(temporaryMap,STRING(gpGlobals->mapname),sizeof(temporaryMap)-1);
|
||||
|
||||
int i=0;
|
||||
|
||||
while (temporaryMap[i]!='_' && temporaryMap[i]!='\0')
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
if (temporaryMap[i]=='_')
|
||||
{
|
||||
// this map has a prefix
|
||||
|
||||
temporaryMap[i]='\0';
|
||||
snprintf(map_pluginsfile_path, sizeof(map_pluginsfile_path)-1,
|
||||
"%s/maps/prefixes/plugins-%s.ini",
|
||||
configs_dir,
|
||||
temporaryMap);
|
||||
g_plugins.CALMFromFile(map_pluginsfile_path);
|
||||
|
||||
}
|
||||
|
||||
snprintf(map_pluginsfile_path, sizeof(map_pluginsfile_path)-1,
|
||||
"%s/maps/plugins-%s.ini",
|
||||
configs_dir,
|
||||
|
@ -650,10 +681,19 @@ void C_ServerDeactivate_Post()
|
|||
|
||||
ClearMessages();
|
||||
|
||||
// Flush the dynamic admins list
|
||||
for (size_t iter=DynamicAdmins.size();iter--; )
|
||||
{
|
||||
delete DynamicAdmins[iter];
|
||||
}
|
||||
|
||||
DynamicAdmins.clear();
|
||||
for (unsigned int i=0; i<g_hudsync.size(); i++)
|
||||
delete [] g_hudsync[i];
|
||||
g_hudsync.clear();
|
||||
|
||||
FlagMan.WriteCommands();
|
||||
|
||||
// last memreport
|
||||
#ifdef MEMORY_TEST
|
||||
if (g_memreport_enabled)
|
||||
|
@ -1062,20 +1102,6 @@ void C_MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict
|
|||
{
|
||||
if (ed)
|
||||
{
|
||||
if (gmsgBattery == msg_type && g_bmod_cstrike)
|
||||
{
|
||||
void* ptr = GET_PRIVATE(ed);
|
||||
#ifdef __linux__
|
||||
int *z = (int*)ptr + 0x171;
|
||||
#else
|
||||
int *z = (int*)ptr + 0x16C;
|
||||
#endif
|
||||
int stop = (int)ed->v.armorvalue;
|
||||
|
||||
*z = stop;
|
||||
ed->v.armorvalue = (float)stop;
|
||||
}
|
||||
|
||||
mPlayerIndex = ENTINDEX(ed);
|
||||
mPlayer = GET_PLAYER_POINTER_I(mPlayerIndex);
|
||||
} else {
|
||||
|
@ -1424,6 +1450,8 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
|
|||
|
||||
GET_HOOK_TABLES(PLID, &g_pEngTable, NULL, NULL);
|
||||
|
||||
FlagMan.SetFile("cmdaccess.ini");
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -361,6 +361,9 @@
|
|||
<File
|
||||
RelativePath="..\CFile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFlagManager.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.cpp">
|
||||
</File>
|
||||
|
@ -515,6 +518,9 @@
|
|||
<File
|
||||
RelativePath="..\CFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFlagManager.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.h">
|
||||
</File>
|
||||
|
|
|
@ -505,6 +505,10 @@
|
|||
RelativePath="..\CFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFlagManager.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.cpp"
|
||||
>
|
||||
|
@ -710,6 +714,10 @@
|
|||
RelativePath="..\CFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFlagManager.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.h"
|
||||
>
|
||||
|
|
|
@ -892,7 +892,9 @@ static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
|
|||
GETMENU_R(params[1]);
|
||||
|
||||
if (pMenu->isDestroying)
|
||||
{
|
||||
return 0; //prevent infinite recursion
|
||||
}
|
||||
|
||||
pMenu->isDestroying = true;
|
||||
g_menucmds.removeMenuId(pMenu->menuId);
|
||||
|
@ -938,8 +940,16 @@ static cell AMX_NATIVE_CALL player_menu_info(AMX *amx, cell *params)
|
|||
*m = player->menu;
|
||||
*n = player->newmenu;
|
||||
|
||||
if (params[0] / sizeof(cell) == 4)
|
||||
{
|
||||
cell *addr = get_amxaddr(amx, params[4]);
|
||||
*addr = player->page;
|
||||
}
|
||||
|
||||
if ( (*m != 0 && *m != -1) || (*n != -1))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2773,7 +2773,7 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||
MF_FindLibrary(NULL, LibType_Class);
|
||||
MF_AddLibraries(NULL, LibType_Class, NULL);
|
||||
MF_RemoveLibraries(NULL);
|
||||
MF_OverrideNatives(NULL);
|
||||
MF_OverrideNatives(NULL, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ extern int gmsgInitObj;
|
|||
extern int gmsgSetObj;
|
||||
|
||||
extern int iFGrenade;
|
||||
extern int iFRocket;
|
||||
extern int iFInitCP;
|
||||
|
||||
extern CPlayer players[33];
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "amxxmodule.h"
|
||||
#include "dodfun.h"
|
||||
|
||||
|
@ -37,6 +38,7 @@ funEventCall modMsgs[MAX_REG_MSGS];
|
|||
void (*function)(void*);
|
||||
void (*endfunction)(void*);
|
||||
CPlayer* mPlayer;
|
||||
CPlayer* gPlayerRocket;
|
||||
CPlayer players[33];
|
||||
|
||||
CObjective mObjects;
|
||||
|
@ -46,6 +48,7 @@ int mDest;
|
|||
int mPlayerIndex;
|
||||
|
||||
int iFGrenade;
|
||||
int iFRocket;
|
||||
int iFInitCP;
|
||||
|
||||
int gmsgCurWeapon;
|
||||
|
@ -96,20 +99,6 @@ void ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax ){
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void PlayerPreThink_Post( edict_t *pEntity ) {
|
||||
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
|
||||
if ( pPlayer->staminaSet ) {
|
||||
if ( (int)pEntity->v.fuser4 > pPlayer->staminaMax )
|
||||
pEntity->v.fuser4 = (float)pPlayer->staminaMax;
|
||||
else if ( (int)pEntity->v.fuser4 < pPlayer->staminaMin )
|
||||
pEntity->v.fuser4 = (float)pPlayer->staminaMin;
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void ServerDeactivate() {
|
||||
for(int i = 1;i<=gpGlobals->maxClients; ++i){
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
||||
|
@ -208,55 +197,108 @@ void WriteEntity_Post(int iValue) {
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void SetModel_Post(edict_t *e, const char *m){
|
||||
if ( !e->v.owner || !e->v.dmgtime )
|
||||
RETURN_META(MRES_IGNORED);
|
||||
void PlayerPreThink_Post(edict_t *pEntity)
|
||||
{
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
|
||||
int owner = ENTINDEX(e->v.owner);
|
||||
if ( owner && owner<33 && m[7]=='w' && m[8]=='_' ){
|
||||
// Stamina
|
||||
if(pPlayer->staminaSet)
|
||||
{
|
||||
if ( (int)pEntity->v.fuser4 > pPlayer->staminaMax)
|
||||
pEntity->v.fuser4 = (float)pPlayer->staminaMax;
|
||||
|
||||
int w_id = 0;
|
||||
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(owner);
|
||||
bool newNade = ( pPlayer->current == 13 || pPlayer->current == 14 ) ? true:false;
|
||||
|
||||
if ( m[9]=='g' && m[10]=='r' && m[11]=='e' && m[12]=='n' )
|
||||
newNade ? w_id = 13 : w_id = 16; // grenade
|
||||
else if ( m[9]=='m' && m[10]=='i' )
|
||||
newNade ? w_id = 36 : w_id = 16 ; // mills ; should I add mills_grenade_ex weapon ?
|
||||
else if ( m[9]=='s' && m[10]=='t' && m[11]=='i')
|
||||
newNade ? w_id = 14 : w_id = 15; // stick
|
||||
|
||||
if ( !w_id )
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
MF_ExecuteForward( iFGrenade, pPlayer->index, ENTINDEX(e) ,w_id );
|
||||
/* fuse start */
|
||||
if ( pPlayer->fuseSet ){
|
||||
if ( newNade ){
|
||||
if ( pPlayer->fuseType & 1<<0 ){
|
||||
e->v.dmgtime += pPlayer->nadeFuse - 5.0;
|
||||
}
|
||||
}
|
||||
else{ // cought
|
||||
bool ownNade = ( (pPlayer->pEdict->v.team == 1 && pPlayer->current == 16) || (pPlayer->pEdict->v.team == 2 && pPlayer->current == 15) ) ? true:false;
|
||||
if ( ownNade ){
|
||||
float fExp = e->v.dmgtime - gpGlobals->time;
|
||||
e->v.dmgtime += pPlayer->nadeFuse - fExp;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* fuse end */
|
||||
else if ( (int)pEntity->v.fuser4 < pPlayer->staminaMin)
|
||||
pEntity->v.fuser4 = (float)pPlayer->staminaMin;
|
||||
}
|
||||
|
||||
if(pPlayer->current == 29 || pPlayer->current == 30 || pPlayer->current == 31)
|
||||
{
|
||||
if(!(pPlayer->pEdict->v.oldbuttons&IN_ATTACK) && (pPlayer->pEdict->v.button&IN_ATTACK))
|
||||
gPlayerRocket = GET_PLAYER_POINTER(pEntity);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void OnAmxxAttach() {
|
||||
void SetModel_Post(edict_t *e, const char *m)
|
||||
{
|
||||
int w_id = 0;
|
||||
|
||||
if(!e->v.owner || !e->v.dmgtime)
|
||||
{
|
||||
int owner = ENTINDEX(e->v.owner);
|
||||
|
||||
if(owner && owner < 33 && m[7]=='w' && m[8]=='_')
|
||||
{
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(owner);
|
||||
bool newNade = (pPlayer->current == 13 || pPlayer->current == 14) ? true : false;
|
||||
|
||||
if(m[9]=='g' && m[10]=='r' && m[11]=='e' && m[12]=='n')
|
||||
w_id = newNade ? 13 : 16; // grenade
|
||||
|
||||
else if(m[9]=='m' && m[10]=='i')
|
||||
w_id = newNade ? 36 : 16 ; // mills ; should I add mills_grenade_ex weapon ?
|
||||
|
||||
else if(m[9]=='s' && m[10]=='t' && m[11]=='i')
|
||||
w_id = newNade ? 14 : 15; // stick
|
||||
|
||||
if(!w_id)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
if(w_id == 13 || w_id == 14 || w_id == 15 || w_id == 16 || w_id == 36)
|
||||
{
|
||||
MF_ExecuteForward(iFGrenade, pPlayer->index, ENTINDEX(e), w_id);
|
||||
|
||||
/* fuse start */
|
||||
if(pPlayer->fuseSet)
|
||||
{
|
||||
if(newNade)
|
||||
{
|
||||
if(pPlayer->fuseType & 1<<0)
|
||||
{
|
||||
e->v.dmgtime += pPlayer->nadeFuse - 5.0;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
float fExp = e->v.dmgtime - gpGlobals->time;
|
||||
e->v.dmgtime += pPlayer->nadeFuse - fExp;
|
||||
}
|
||||
}
|
||||
/* fuse end */
|
||||
}
|
||||
}
|
||||
|
||||
else if(strstr(m, "rocket") && gPlayerRocket)
|
||||
{
|
||||
if(strstr(m, "bazooka"))
|
||||
w_id = 29;
|
||||
|
||||
else if(strstr(m, "piat"))
|
||||
w_id = 30;
|
||||
|
||||
else if(strstr(m, "pschreck"))
|
||||
w_id = 31;
|
||||
|
||||
MF_ExecuteForward(iFRocket, gPlayerRocket->index, ENTINDEX(e), w_id);
|
||||
|
||||
gPlayerRocket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
MF_AddNatives( base_Natives );
|
||||
MF_AddNatives( pd_Natives );
|
||||
}
|
||||
|
||||
void OnPluginsLoaded(){
|
||||
iFGrenade = MF_RegisterForward("grenade_throw",ET_IGNORE,FP_CELL,FP_CELL,FP_CELL,FP_DONE);
|
||||
void OnPluginsLoaded()
|
||||
{
|
||||
iFGrenade = MF_RegisterForward("grenade_throw",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*Grenade Ent*/,FP_CELL/*Weapon ID*/,FP_DONE);
|
||||
iFRocket = MF_RegisterForward("rocket_shoot",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*Rocket Ent*/,FP_CELL/*Weapon ID*/,FP_DONE);
|
||||
iFInitCP = MF_RegisterForward("controlpoints_init",ET_IGNORE,FP_DONE);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// Module info
|
||||
#define MODULE_NAME "DoD Fun"
|
||||
#define MODULE_VERSION "1.76b"
|
||||
#define MODULE_VERSION "1.76c_beta_a"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "DODFUN"
|
||||
|
|
|
@ -33,73 +33,31 @@
|
|||
#include "CMisc.h"
|
||||
#include "dodx.h"
|
||||
|
||||
// *****************************************************
|
||||
// class Grenades
|
||||
// *****************************************************
|
||||
void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
|
||||
{
|
||||
Obj* a = new Obj;
|
||||
a->player = player;
|
||||
a->grenade = grenade;
|
||||
a->time = gpGlobals->time + time;
|
||||
a->type = type;
|
||||
a->next = head;
|
||||
head = a;
|
||||
}
|
||||
|
||||
bool Grenades::find( edict_t* enemy, CPlayer** p, int& type )
|
||||
{
|
||||
bool found = false;
|
||||
float lastTime = 0.0;
|
||||
Obj** a = &head;
|
||||
while ( *a ){
|
||||
if ( (*a)->time > gpGlobals->time ) {
|
||||
if ( (*a)->grenade == enemy ) {
|
||||
found = true;
|
||||
if ( (*a)->time > lastTime ){ // we need this because of catched grenades
|
||||
(*p) = (*a)->player; // two people can have the same nade in our list
|
||||
type = (*a)->type;
|
||||
lastTime = (*a)->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Obj* next = (*a)->next;
|
||||
delete *a;
|
||||
*a = next;
|
||||
continue;
|
||||
|
||||
}
|
||||
a = &(*a)->next;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void Grenades::clear()
|
||||
{
|
||||
while(head){
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
|
||||
void CPlayer::Disconnect(){
|
||||
void CPlayer::Disconnect()
|
||||
{
|
||||
ingame = false;
|
||||
bot = false;
|
||||
savedScore = 0;
|
||||
|
||||
// Zors
|
||||
olddeadflag=0;
|
||||
oldteam=0;
|
||||
oldplayerclass=0;
|
||||
is_model_set=false;
|
||||
body_num=0;
|
||||
position = 0;
|
||||
olddeadflag = 0;
|
||||
oldteam = 0;
|
||||
oldclass = 0;
|
||||
oldprone = 0;
|
||||
oldstamina = 0.0f;
|
||||
|
||||
// Model Stuff
|
||||
sModel.is_model_set = false;
|
||||
sModel.body_num = 0;
|
||||
|
||||
// Object stuff
|
||||
object.pEdict = NULL;
|
||||
object.type = 0;
|
||||
object.carrying = false;
|
||||
object.do_forward = false;
|
||||
|
||||
if ( ignoreBots(pEdict) || !isModuleActive() ) // ignore if he is bot and bots rank is disabled or module is paused
|
||||
return;
|
||||
|
@ -141,11 +99,13 @@ void CPlayer::Connect(const char* nn,const char* ippp ){
|
|||
|
||||
void CPlayer::restartStats(bool all)
|
||||
{
|
||||
if ( all ){
|
||||
if ( all )
|
||||
{
|
||||
memset(weapons,0,sizeof(weapons));
|
||||
memset(&round,0,sizeof(round));
|
||||
memset(weaponsRnd,0,sizeof(weaponsRnd));
|
||||
}
|
||||
|
||||
memset(weaponsLife,0,sizeof(weaponsLife)); //DEC-Weapon (Round) stats
|
||||
memset(attackers,0,sizeof(attackers));
|
||||
memset(victims,0,sizeof(victims));
|
||||
|
@ -154,6 +114,12 @@ void CPlayer::restartStats(bool all)
|
|||
|
||||
void CPlayer::Init( int pi, edict_t* pe )
|
||||
{
|
||||
aiming = 0;
|
||||
wpnModel = 0;
|
||||
wpnscount = 0;
|
||||
lastScore = 0;
|
||||
sendScore = 0;
|
||||
clearRound = 0.0f;
|
||||
pEdict = pe;
|
||||
index = pi;
|
||||
current = 0;
|
||||
|
@ -161,14 +127,24 @@ void CPlayer::Init( int pi, edict_t* pe )
|
|||
ingame = false;
|
||||
bot = false;
|
||||
savedScore = 0;
|
||||
olddeadflag = 0;
|
||||
oldteam = 0;
|
||||
oldclass = 0;
|
||||
oldprone = 0;
|
||||
oldstamina = 0.0f;
|
||||
|
||||
// Zors
|
||||
olddeadflag=0;
|
||||
oldteam=0;
|
||||
oldplayerclass=0;
|
||||
is_model_set=false;
|
||||
body_num=0;
|
||||
position = 0;
|
||||
do_scoped = false;
|
||||
is_scoped = false;
|
||||
|
||||
// Model Stuff
|
||||
sModel.is_model_set = false;
|
||||
sModel.body_num = 0;
|
||||
|
||||
// Object stuff
|
||||
object.pEdict = NULL;
|
||||
object.type = 0;
|
||||
object.carrying = false;
|
||||
object.do_forward = false;
|
||||
}
|
||||
|
||||
void CPlayer::saveKill(CPlayer* pVictim, int wweapon, int hhs, int ttk){
|
||||
|
@ -176,7 +152,8 @@ void CPlayer::saveKill(CPlayer* pVictim, int wweapon, int hhs, int ttk){
|
|||
if ( ignoreBots(pEdict,pVictim->pEdict) )
|
||||
return;
|
||||
|
||||
if ( pVictim->index == index ){ // killed self
|
||||
if ( pVictim->index == index )
|
||||
{ // killed self
|
||||
pVictim->weapons[0].deaths++;
|
||||
pVictim->life.deaths++;
|
||||
pVictim->round.deaths++;
|
||||
|
@ -293,7 +270,8 @@ void CPlayer::saveHit(CPlayer* pVictim, int wweapon, int ddamage, int bbody){
|
|||
round.bodyHits[bbody]++;
|
||||
}
|
||||
|
||||
void CPlayer::saveShot(int weapon){
|
||||
void CPlayer::saveShot(int weapon)
|
||||
{
|
||||
|
||||
if ( ignoreBots(pEdict) )
|
||||
return;
|
||||
|
@ -310,7 +288,8 @@ void CPlayer::saveShot(int weapon){
|
|||
weaponsRnd[0].shots++; // DEC-Weapon (round) stats
|
||||
}
|
||||
|
||||
void CPlayer::updateScore(int weapon, int score){
|
||||
void CPlayer::updateScore(int weapon, int score)
|
||||
{
|
||||
|
||||
if ( ignoreBots(pEdict) )
|
||||
return;
|
||||
|
@ -325,7 +304,8 @@ void CPlayer::updateScore(int weapon, int score){
|
|||
weapons[0].points += score;
|
||||
}
|
||||
|
||||
void CPlayer::killPlayer(){
|
||||
void CPlayer::killPlayer()
|
||||
{
|
||||
pEdict->v.dmg_inflictor = NULL;
|
||||
pEdict->v.health = 0;
|
||||
pEdict->v.deadflag = DEAD_RESPAWNABLE;
|
||||
|
@ -335,13 +315,13 @@ void CPlayer::killPlayer(){
|
|||
|
||||
void CPlayer::initModel(char* model)
|
||||
{
|
||||
newmodel = model;
|
||||
is_model_set = true;
|
||||
strcpy(sModel.modelclass, (const char*)model);
|
||||
sModel.is_model_set = true;
|
||||
}
|
||||
|
||||
void CPlayer::clearModel()
|
||||
{
|
||||
is_model_set = false;
|
||||
sModel.is_model_set = false;
|
||||
}
|
||||
|
||||
bool CPlayer::setModel()
|
||||
|
@ -349,10 +329,10 @@ bool CPlayer::setModel()
|
|||
if(!ingame || ignoreBots(pEdict))
|
||||
return false;
|
||||
|
||||
if(is_model_set)
|
||||
if(sModel.is_model_set)
|
||||
{
|
||||
ENTITY_SET_KEYVALUE(pEdict, "model", newmodel);
|
||||
pEdict->v.body = body_num;
|
||||
ENTITY_SET_KEYVALUE(pEdict, "model", sModel.modelclass);
|
||||
pEdict->v.body = sModel.body_num;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -364,12 +344,17 @@ void CPlayer::setBody(int bn)
|
|||
if(!ingame || ignoreBots(pEdict))
|
||||
return;
|
||||
|
||||
body_num = bn;
|
||||
sModel.body_num = bn;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void CPlayer::checkStatus()
|
||||
/*
|
||||
iuser3 = 0 standing up
|
||||
iuser3 = 1 going prone or mg tearing down
|
||||
iuser3 = 2 setting up mg
|
||||
*/
|
||||
void CPlayer::PreThink()
|
||||
{
|
||||
if(!ingame || ignoreBots(pEdict))
|
||||
return;
|
||||
|
@ -380,12 +365,160 @@ void CPlayer::checkStatus()
|
|||
if(oldteam != pEdict->v.team && iFTeamForward != -1)
|
||||
MF_ExecuteForward(iFTeamForward, index, pEdict->v.team, oldteam);
|
||||
|
||||
if(oldplayerclass != pEdict->v.playerclass)
|
||||
MF_ExecuteForward(iFClassForward, index, pEdict->v.playerclass, oldplayerclass);
|
||||
if(oldclass != pEdict->v.playerclass && iFClassForward != -1)
|
||||
MF_ExecuteForward(iFClassForward, index, pEdict->v.playerclass, oldclass);
|
||||
|
||||
if(oldprone != pEdict->v.iuser3 && oldprone != 2 && pEdict->v.iuser3 != 2 && iFProneForward != -1)
|
||||
MF_ExecuteForward(iFProneForward, index, pEdict->v.iuser3);
|
||||
|
||||
if(oldstamina > pEdict->v.fuser4 && iFStaminaForward != -1)
|
||||
MF_ExecuteForward(iFStaminaForward, index, ((int)pEdict->v.fuser4));
|
||||
|
||||
if(wpns_bitfield != pEdict->v.weapons)
|
||||
WeaponsCheck(pEdict->v.weapons & ~(1<<31));
|
||||
|
||||
// Set the old variables for
|
||||
oldprone = pEdict->v.iuser3;
|
||||
olddeadflag = pEdict->v.deadflag;
|
||||
oldteam = pEdict->v.team;
|
||||
oldplayerclass = pEdict->v.playerclass;
|
||||
oldclass = pEdict->v.playerclass;
|
||||
oldstamina = pEdict->v.fuser4;
|
||||
|
||||
wpns_bitfield = pEdict->v.weapons & ~(1<<31);
|
||||
}
|
||||
|
||||
void CPlayer::Scoping(int value)
|
||||
{
|
||||
// Everyone gets a 0 then another call for 90, so I need to figure out
|
||||
// what weapon they have before I can then check if they are scoped or not
|
||||
|
||||
do_scoped = false;
|
||||
|
||||
switch(value)
|
||||
{
|
||||
// This is when the scope is dropped from the eye
|
||||
case 0:
|
||||
// Is this an initial call
|
||||
if(mPlayer->current == 0)
|
||||
return;
|
||||
|
||||
// SKar Spring SFG42 SEnfield
|
||||
if((mPlayer->current == 6 || mPlayer->current == 9 || mPlayer->current == 32 || mPlayer->current == 35) && is_scoped)
|
||||
{
|
||||
is_scoped = false;
|
||||
do_scoped = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// This is when the scope is put up to the eye
|
||||
case 20:
|
||||
// SKar Spring SFG42 SEnfield
|
||||
if((mPlayer->current == 6 || mPlayer->current == 9 || mPlayer->current == 32 || mPlayer->current == 35) && !is_scoped)
|
||||
{
|
||||
is_scoped = true;
|
||||
do_scoped = true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// This means the scope has been initialized
|
||||
case 90:
|
||||
is_scoped = false;
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
void CPlayer::ScopingCheck()
|
||||
{
|
||||
if(do_scoped)
|
||||
MF_ExecuteForward(iFScopeForward, index, (int)is_scoped);
|
||||
}
|
||||
|
||||
void CPlayer::WeaponsCheck(int weapons)
|
||||
{
|
||||
if(wpns_bitfield == 0)
|
||||
return;
|
||||
|
||||
else if(pEdict->v.weapons == 0)
|
||||
return;
|
||||
|
||||
int old;
|
||||
int cur;
|
||||
|
||||
for(int i = 1; i < MAX_WEAPONS; ++i)
|
||||
{
|
||||
// Check to see we are not talking about a grenade and we have changed
|
||||
if(i != 13 && i != 14 && i != 15 && i != 16 && i != 36)
|
||||
{
|
||||
old = wpns_bitfield&(1<<i);
|
||||
cur = weapons&(1<<i);
|
||||
|
||||
if(old != cur)
|
||||
MF_ExecuteForward(iFWpnPickupForward, index, i, ((weapons&(1<<i)) ? 1 : 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// class Grenades
|
||||
// *****************************************************
|
||||
void Grenades::put(edict_t* grenade, float time, int type, CPlayer* player )
|
||||
{
|
||||
Obj* a = new Obj;
|
||||
a->player = player;
|
||||
a->grenade = grenade;
|
||||
a->time = gpGlobals->time + time;
|
||||
a->type = type;
|
||||
a->next = head;
|
||||
head = a;
|
||||
}
|
||||
|
||||
bool Grenades::find( edict_t* enemy, CPlayer** p, int& type )
|
||||
{
|
||||
bool found = false;
|
||||
float lastTime = 0.0;
|
||||
Obj** a = &head;
|
||||
|
||||
while(*a)
|
||||
{
|
||||
if((*a)->time > gpGlobals->time)
|
||||
{
|
||||
if((*a)->grenade == enemy)
|
||||
{
|
||||
found = true;
|
||||
|
||||
// we need this because of catched grenades
|
||||
if((*a)->time > lastTime)
|
||||
{
|
||||
(*p) = (*a)->player; // two people can have the same nade in our list
|
||||
type = (*a)->type;
|
||||
lastTime = (*a)->time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Obj* next = (*a)->next;
|
||||
delete *a;
|
||||
*a = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
a = &(*a)->next;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void Grenades::clear()
|
||||
{
|
||||
while(head)
|
||||
{
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
|
|
|
@ -47,101 +47,131 @@
|
|||
|
||||
#define MAX_TRACE 6
|
||||
|
||||
struct traceVault {
|
||||
struct traceVault
|
||||
{
|
||||
char szName[16];
|
||||
int iId;
|
||||
int iAction;
|
||||
float fDel;
|
||||
};
|
||||
|
||||
#define ACT_NADE_NONE 0
|
||||
#define ACT_NADE_SHOT 1<<0
|
||||
#define ACT_NADE_PUT 1<<1
|
||||
#define ACT_NADE_THROW 1<<2
|
||||
#define ACT_NADE_NONE (0)
|
||||
#define ACT_NADE_SHOT (1<<0)
|
||||
#define ACT_NADE_PUT (1<<1)
|
||||
#define ACT_NADE_THROW (1<<2)
|
||||
|
||||
#define ACT_ROCKET_NONE (0)
|
||||
#define ACT_ROCKET_SHOT (1<<0)
|
||||
#define ACT_ROCKET_PUT (1<<3)
|
||||
|
||||
|
||||
// *****************************************************
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
|
||||
class CPlayer {
|
||||
private:
|
||||
char ip[32];
|
||||
public:
|
||||
edict_t* pEdict;
|
||||
int index;
|
||||
int aiming;
|
||||
int current;
|
||||
int wpnModel;
|
||||
class CPlayer
|
||||
{
|
||||
private:
|
||||
char ip[32];
|
||||
|
||||
float savedScore;
|
||||
int lastScore;
|
||||
int sendScore;
|
||||
public:
|
||||
edict_t* pEdict;
|
||||
int index;
|
||||
int aiming;
|
||||
int current;
|
||||
int old;
|
||||
int wpnModel;
|
||||
int wpnscount;
|
||||
int wpns_bitfield;
|
||||
int old_weapons[DODMAX_WEAPONS];
|
||||
|
||||
bool ingame;
|
||||
bool bot;
|
||||
float clearStats;
|
||||
float clearRound;
|
||||
float savedScore;
|
||||
int lastScore;
|
||||
int sendScore;
|
||||
|
||||
struct PlayerWeapon : public Stats {
|
||||
char* name;
|
||||
int ammo;
|
||||
int clip;
|
||||
};
|
||||
bool ingame;
|
||||
bool bot;
|
||||
float clearStats;
|
||||
float clearRound;
|
||||
|
||||
PlayerWeapon weapons[DODMAX_WEAPONS];
|
||||
PlayerWeapon attackers[33];
|
||||
PlayerWeapon victims[33];
|
||||
Stats weaponsLife[DODMAX_WEAPONS]; // DEC-Weapon (Life) stats
|
||||
Stats weaponsRnd[DODMAX_WEAPONS]; // DEC-Weapon (Round) stats
|
||||
Stats life;
|
||||
Stats round;
|
||||
int oldteam;
|
||||
int olddeadflag;
|
||||
int oldclass;
|
||||
float oldstamina;
|
||||
|
||||
RankSystem::RankStats* rank;
|
||||
struct ModelStruct
|
||||
{
|
||||
int body_num;
|
||||
bool is_model_set;
|
||||
char* modelclass;
|
||||
}
|
||||
sModel;
|
||||
|
||||
void Init( int pi, edict_t* pe );
|
||||
void Connect(const char* name,const char* ip );
|
||||
void PutInServer();
|
||||
void Disconnect();
|
||||
void saveKill(CPlayer* pVictim, int weapon, int hs, int tk);
|
||||
void saveHit(CPlayer* pVictim, int weapon, int damage, int aiming);
|
||||
void saveShot(int weapon);
|
||||
void updateScore(int weapon, int score);
|
||||
void restartStats(bool all = true);
|
||||
void killPlayer();
|
||||
int oldprone;
|
||||
bool do_scoped;
|
||||
bool is_scoped;
|
||||
|
||||
// Zors
|
||||
int oldteam;
|
||||
int olddeadflag;
|
||||
int oldplayerclass;
|
||||
struct ObjectStruct
|
||||
{
|
||||
edict_t* pEdict;
|
||||
bool carrying;
|
||||
bool do_forward;
|
||||
int type;
|
||||
}
|
||||
object;
|
||||
|
||||
bool is_model_set;
|
||||
char* newmodel;
|
||||
int body_num;
|
||||
struct PlayerWeapon : public Stats
|
||||
{
|
||||
char* name;
|
||||
int ammo;
|
||||
int clip;
|
||||
};
|
||||
|
||||
int position;
|
||||
PlayerWeapon weapons[DODMAX_WEAPONS];
|
||||
PlayerWeapon attackers[33];
|
||||
PlayerWeapon victims[33];
|
||||
Stats weaponsLife[DODMAX_WEAPONS]; // DEC-Weapon (Life) stats
|
||||
Stats weaponsRnd[DODMAX_WEAPONS]; // DEC-Weapon (Round) stats
|
||||
Stats life;
|
||||
Stats round;
|
||||
|
||||
void initModel(char*);
|
||||
void clearModel();
|
||||
bool setModel();
|
||||
void setBody(int);
|
||||
void checkStatus();
|
||||
// Zors
|
||||
RankSystem::RankStats* rank;
|
||||
|
||||
inline bool IsBot(){
|
||||
const char* auth= (*g_engfuncs.pfnGetPlayerAuthId)(pEdict);
|
||||
return ( auth && !strcmp( auth , "BOT" ) );
|
||||
}
|
||||
inline bool IsAlive(){
|
||||
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
|
||||
}
|
||||
void Init( int pi, edict_t* pe );
|
||||
void Connect(const char* name,const char* ip );
|
||||
void PutInServer();
|
||||
void Disconnect();
|
||||
void saveKill(CPlayer* pVictim, int weapon, int hs, int tk);
|
||||
void saveHit(CPlayer* pVictim, int weapon, int damage, int aiming);
|
||||
void saveShot(int weapon);
|
||||
void updateScore(int weapon, int score);
|
||||
void restartStats(bool all = true);
|
||||
void killPlayer();
|
||||
void initModel(char*);
|
||||
void clearModel();
|
||||
bool setModel();
|
||||
void setBody(int);
|
||||
void PreThink();
|
||||
void Scoping(int);
|
||||
void ScopingCheck();
|
||||
void WeaponsCheck(int);
|
||||
|
||||
inline bool IsBot()
|
||||
{
|
||||
const char* auth= (*g_engfuncs.pfnGetPlayerAuthId)(pEdict);
|
||||
return ( auth && !strcmp( auth , "BOT" ) );
|
||||
}
|
||||
|
||||
inline bool IsAlive()
|
||||
{
|
||||
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
|
||||
}
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
// class Grenades
|
||||
// *****************************************************
|
||||
|
||||
class Grenades
|
||||
class Grenades // : public CObject
|
||||
{
|
||||
struct Obj
|
||||
{
|
||||
|
@ -154,11 +184,11 @@ class Grenades
|
|||
|
||||
|
||||
public:
|
||||
Grenades() { head = 0; }
|
||||
~Grenades() { clear(); }
|
||||
void put( edict_t* grenade, float time, int type, CPlayer* player );
|
||||
bool find( edict_t* enemy, CPlayer** p, int& type );
|
||||
void clear();
|
||||
Grenades() { head = 0; }
|
||||
~Grenades() { clear(); }
|
||||
void put(edict_t* grenade, float time, int type, CPlayer* player);
|
||||
bool find(edict_t* enemy, CPlayer** p, int& type);
|
||||
void clear();
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
|
@ -178,5 +208,7 @@ public:
|
|||
void Init();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // CMISC_H
|
||||
|
||||
|
|
|
@ -32,62 +32,134 @@
|
|||
#include "amxxmodule.h"
|
||||
#include "dodx.h"
|
||||
|
||||
static cell AMX_NATIVE_CALL get_weapon_name(AMX *amx, cell *params){ // from id to name 3 params id, name, len
|
||||
#define WEAPONLIST 71
|
||||
|
||||
/* Weapon names aren't send in WeaponList message in DoD */
|
||||
weaponlist_s weaponlist[] =
|
||||
{
|
||||
{ 0, 0, 0, false}, // 0,
|
||||
{ -1, 0, -1, true }, // DODW_AMERKNIFE = 1,
|
||||
{ -1, 0, -1, true }, // DODW_GERKNIFE,
|
||||
{ 4, 64, 7, true }, // DODW_COLT,
|
||||
{ 4, 64, 8, true }, // DODW_LUGER,
|
||||
{ 3, 128, 8, true }, // DODW_GARAND,
|
||||
{ 3, 128, 5, true }, // DODW_SCOPED_KAR,
|
||||
{ 1, 128, 30, true }, // DODW_THOMPSON,
|
||||
{ 6, 128, 30, true }, // DODW_STG44,
|
||||
{ 5, 128, 5, true }, // DODW_SPRINGFIELD,
|
||||
{ 3, 128, 5, true }, // DODW_KAR,
|
||||
{ 6, 128, 20, true }, // DODW_BAR,
|
||||
{ 1, 130, 30, true }, // DODW_MP40,
|
||||
{ 9, 24, -1, true }, // DODW_HANDGRENADE,
|
||||
{ 11, 24, -1, true }, // DODW_STICKGRENADE,
|
||||
{ 12, 24, -1, true }, // DODW_STICKGRENADE_EX,
|
||||
{ 10, 24, -1, true }, // DODW_HANDGRENADE_EX,
|
||||
{ 7, 2178, 250, true }, // DODW_MG42,
|
||||
{ 8, 130, 150, true }, // DODW_30_CAL,
|
||||
{ -1, 0, -1, true }, // DODW_SPADE,
|
||||
{ 2, 128, 15, true }, // DODW_M1_CARBINE,
|
||||
{ 2, 130, 75, true }, // DODW_MG34,
|
||||
{ 1, 128, 30, true }, // DODW_GREASEGUN,
|
||||
{ 6, 128, 20, true }, // DODW_FG42,
|
||||
{ 2, 128, 10, true }, // DODW_K43,
|
||||
{ 3, 128, 10, true }, // DODW_ENFIELD,
|
||||
{ 1, 128, 30, true }, // DODW_STEN,
|
||||
{ 6, 128, 30, true }, // DODW_BREN,
|
||||
{ 4, 64, 6, true }, // DODW_WEBLEY,
|
||||
{ 13, 642, 1, true }, // DODW_BAZOOKA,
|
||||
{ 13, 642, 1, true }, // DODW_PANZERSCHRECK,
|
||||
{ 13, 642, 1, true }, // DODW_PIAT,
|
||||
{ 3, 128, 20, true }, // DODW_SCOPED_FG42, UNSURE ABOUT THIS ONE
|
||||
{ 2, 128, 15, true }, // DODW_FOLDING_CARBINE,
|
||||
{ 0, 0, 0, false}, // DODW_KAR_BAYONET,
|
||||
{ 3, 128, 10, true }, // DODW_SCOPED_ENFIELD, UNSURE ABOUT THIS ONE
|
||||
{ 9, 24, -1, true }, // DODW_MILLS_BOMB,
|
||||
{ -1, 0, -1, true }, // DODW_BRITKNIFE,
|
||||
{ 38, 0, 0, false}, // DODW_GARAND_BUTT,
|
||||
{ 39, 0, 0, false}, // DODW_ENFIELD_BAYONET,
|
||||
{ 40, 0, 0, false}, // DODW_MORTAR,
|
||||
{ 41, 0, 0, false}, // DODW_K43_BUTT,
|
||||
};
|
||||
|
||||
// from id to name 3 params id, name, len
|
||||
static cell AMX_NATIVE_CALL get_weapon_name(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id<0 || id>=DODMAX_WEAPONS){
|
||||
|
||||
if(id < 0 || id >= DODMAX_WEAPONS)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MF_SetAmxString(amx,params[2],weaponData[id].name,params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL wpnlog_to_name(AMX *amx, cell *params){ // from log to name
|
||||
// from log to name
|
||||
static cell AMX_NATIVE_CALL wpnlog_to_name(AMX *amx, cell *params)
|
||||
{
|
||||
int iLen;
|
||||
char *log = MF_GetAmxString(amx,params[1],0,&iLen);
|
||||
int i;
|
||||
for ( i=0; i<DODMAX_WEAPONS; i++ ){
|
||||
if ( strcmp(log,weaponData[i].logname ) == 0 )
|
||||
|
||||
for(int i = 0; i < DODMAX_WEAPONS; i++)
|
||||
{
|
||||
if(strcmp(log,weaponData[i].logname ) == 0)
|
||||
return MF_SetAmxString(amx,params[2],weaponData[i].name,params[3]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL wpnlog_to_id(AMX *amx, cell *params){ // from log to id
|
||||
// from log to id
|
||||
static cell AMX_NATIVE_CALL wpnlog_to_id(AMX *amx, cell *params)
|
||||
{
|
||||
int iLen;
|
||||
char *log = MF_GetAmxString(amx,params[1],0,&iLen);
|
||||
char *log = MF_GetAmxString(amx, params[1], 0, &iLen);
|
||||
|
||||
int i;
|
||||
for ( i=0; i<DODMAX_WEAPONS; i++ ){
|
||||
if ( strcmp(log,weaponData[i].logname) == 0 )
|
||||
for(int i = 0; i < DODMAX_WEAPONS; i++)
|
||||
{
|
||||
if(strcmp(log,weaponData[i].logname) == 0)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_weapon_logname(AMX *amx, cell *params){ // from id to log
|
||||
// from id to log
|
||||
static cell AMX_NATIVE_CALL get_weapon_logname(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id<0 || id>=DODMAX_WEAPONS){
|
||||
|
||||
if (id<0 || id>=DODMAX_WEAPONS)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return MF_SetAmxString(amx,params[2],weaponData[id].logname,params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL is_melee(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL is_melee(AMX *amx, cell *params)
|
||||
{
|
||||
int id = params[1];
|
||||
if (id<0 || id>=DODMAX_WEAPONS){
|
||||
|
||||
if(id < 0 || id >= DODMAX_WEAPONS)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon id %d", id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return weaponData[id].melee;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_team_score(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_team_score(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
switch ( index ){
|
||||
|
||||
switch ( index )
|
||||
{
|
||||
case 1:
|
||||
return AlliesScore;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return AxisScore;
|
||||
break;
|
||||
|
@ -95,30 +167,38 @@ static cell AMX_NATIVE_CALL get_team_score(AMX *amx, cell *params){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_user_score(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_user_score(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
|
||||
if (pPlayer->ingame)
|
||||
return (cell)pPlayer->savedScore;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_user_class(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_user_class(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
|
||||
if (pPlayer->ingame)
|
||||
return pPlayer->pEdict->v.playerclass;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
|
||||
if (pPlayer->ingame && pPlayer->IsAlive() ){
|
||||
if(pPlayer->ingame && pPlayer->IsAlive())
|
||||
{
|
||||
pPlayer->killPlayer();
|
||||
return 1;
|
||||
}
|
||||
|
@ -126,17 +206,22 @@ static cell AMX_NATIVE_CALL user_kill(AMX *amx, cell *params){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_map_info(AMX *amx, cell *params){
|
||||
switch( params[1] ){
|
||||
static cell AMX_NATIVE_CALL get_map_info(AMX *amx, cell *params)
|
||||
{
|
||||
switch(params[1])
|
||||
{
|
||||
case 0:
|
||||
return g_map.detect_allies_country;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
return g_map.detect_allies_paras;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return g_map.detect_axis_paras;
|
||||
break;
|
||||
|
||||
default:
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid map info id %d", params[1]);
|
||||
break;
|
||||
|
@ -144,21 +229,26 @@ static cell AMX_NATIVE_CALL get_map_info(AMX *amx, cell *params){
|
|||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_user_pronestate(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_user_pronestate(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
|
||||
if (pPlayer->ingame)
|
||||
return pPlayer->pEdict->v.iuser3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_user_weapon(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_user_weapon(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if (pPlayer->ingame){
|
||||
|
||||
if (pPlayer->ingame)
|
||||
{
|
||||
int wpn = pPlayer->current;
|
||||
cell *cpTemp = MF_GetAmxAddr(amx,params[2]);
|
||||
*cpTemp = pPlayer->weapons[wpn].clip;
|
||||
|
@ -170,55 +260,100 @@ static cell AMX_NATIVE_CALL get_user_weapon(AMX *amx, cell *params){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
|
||||
{ // forward
|
||||
/* We want to get just the weapon of whichever type that the player is on him */
|
||||
static cell AMX_NATIVE_CALL dod_weapon_type(AMX *amx, cell *params) /* 2 params */
|
||||
{
|
||||
int index = params[1];
|
||||
int type = params[2];
|
||||
|
||||
#ifdef FORWARD_OLD_SYSTEM
|
||||
CHECK_PLAYER(index);
|
||||
|
||||
int iFunctionIndex;
|
||||
int err;
|
||||
switch( params[1] ){
|
||||
case 0:
|
||||
if( (err=MF_AmxFindPublic(amx, "client_damage", &iFunctionIndex)) == AMX_ERR_NONE )
|
||||
g_damage_info.put( amx , iFunctionIndex );
|
||||
else
|
||||
MF_LogError(amx, err, "client_damage not found");
|
||||
return 0;
|
||||
break;
|
||||
case 1:
|
||||
if( (err=MF_AmxFindPublic(amx, "client_death", &iFunctionIndex)) == AMX_ERR_NONE )
|
||||
g_death_info.put( amx , iFunctionIndex );
|
||||
else
|
||||
MF_LogError(amx, err, "client_Death not found");
|
||||
return 0;
|
||||
break;
|
||||
case 2:
|
||||
if( (err=MF_AmxFindPublic(amx, "client_score", &iFunctionIndex)) == AMX_ERR_NONE )
|
||||
g_score_info.put( amx , iFunctionIndex );
|
||||
else
|
||||
MF_LogError(amx, err, "client_score not found");
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid forward id %d", params[2]);
|
||||
if(type < DODWT_PRIMARY || type > DODWT_OTHER)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon type id %d", type);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
|
||||
if(pPlayer->ingame)
|
||||
{
|
||||
int weaponsbit = pPlayer->pEdict->v.weapons & ~(1<<31); // don't count last element
|
||||
|
||||
for(int x = 1; x < MAX_WEAPONS; ++x)
|
||||
{
|
||||
if((weaponsbit&(1<<x)) > 0)
|
||||
{
|
||||
if(weaponData[x].type == type)
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// forward
|
||||
static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
|
||||
{
|
||||
|
||||
#ifdef FORWARD_OLD_SYSTEM
|
||||
int iFunctionIndex;
|
||||
int err;
|
||||
switch( params[1] )
|
||||
{
|
||||
case 0:
|
||||
if((err = MF_AmxFindPublic(amx, "client_damage", &iFunctionIndex)) == AMX_ERR_NONE)
|
||||
g_damage_info.put( amx , iFunctionIndex );
|
||||
|
||||
else
|
||||
MF_LogError(amx, err, "client_damage not found");
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if((err = MF_AmxFindPublic(amx, "client_death", &iFunctionIndex)) == AMX_ERR_NONE)
|
||||
g_death_info.put( amx , iFunctionIndex );
|
||||
|
||||
else
|
||||
MF_LogError(amx, err, "client_Death not found");
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if((err = MF_AmxFindPublic(amx, "client_score", &iFunctionIndex)) == AMX_ERR_NONE)
|
||||
g_score_info.put( amx , iFunctionIndex );
|
||||
|
||||
else
|
||||
MF_LogError(amx, err, "client_score not found");
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid forward id %d", params[2]);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL register_cwpn(AMX *amx, cell *params){ // name,logname,melee=0
|
||||
// name,logname,melee=0
|
||||
static cell AMX_NATIVE_CALL register_cwpn(AMX *amx, cell *params)
|
||||
{
|
||||
int i;
|
||||
bool bFree = false;
|
||||
for ( i=DODMAX_WEAPONS-DODMAX_CUSTOMWPNS;i<DODMAX_WEAPONS;i++){
|
||||
if ( !weaponData[i].needcheck ){
|
||||
|
||||
for(i = DODMAX_WEAPONS - DODMAX_CUSTOMWPNS; i < DODMAX_WEAPONS; i++)
|
||||
{
|
||||
if(!weaponData[i].needcheck)
|
||||
{
|
||||
bFree = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bFree )
|
||||
if(!bFree)
|
||||
return 0;
|
||||
|
||||
int iLen;
|
||||
|
@ -232,9 +367,14 @@ static cell AMX_NATIVE_CALL register_cwpn(AMX *amx, cell *params){ // name,logna
|
|||
return i;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL cwpn_dmg(AMX *amx, cell *params){ // wid,att,vic,dmg,hp=0
|
||||
// wid,att,vic,dmg,hp=0
|
||||
static cell AMX_NATIVE_CALL cwpn_dmg(AMX *amx, cell *params)
|
||||
{
|
||||
int weapon = params[1];
|
||||
if ( weapon < DODMAX_WEAPONS-DODMAX_CUSTOMWPNS ){ // only for custom weapons
|
||||
|
||||
// only for custom weapons
|
||||
if(weapon < DODMAX_WEAPONS-DODMAX_CUSTOMWPNS)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid custom weapon id %d", weapon);
|
||||
return 0;
|
||||
}
|
||||
|
@ -246,13 +386,15 @@ static cell AMX_NATIVE_CALL cwpn_dmg(AMX *amx, cell *params){ // wid,att,vic,dmg
|
|||
CHECK_PLAYER(params[3]);
|
||||
|
||||
int dmg = params[4];
|
||||
if ( dmg<1 ){
|
||||
if(dmg<1)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid damage %d", dmg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aim = params[5];
|
||||
if ( aim < 0 || aim > 7 ){
|
||||
if(aim < 0 || aim > 7)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid aim %d", aim);
|
||||
return 0;
|
||||
}
|
||||
|
@ -262,33 +404,39 @@ static cell AMX_NATIVE_CALL cwpn_dmg(AMX *amx, cell *params){ // wid,att,vic,dmg
|
|||
|
||||
pVic->pEdict->v.dmg_inflictor = NULL;
|
||||
|
||||
if ( pAtt->index != pVic->index )
|
||||
pAtt->saveHit( pVic , weapon , dmg, aim );
|
||||
if(pAtt->index != pVic->index)
|
||||
pAtt->saveHit(pVic , weapon , dmg, aim);
|
||||
|
||||
if(!pAtt)
|
||||
pAtt = pVic;
|
||||
|
||||
if ( !pAtt ) pAtt = pVic;
|
||||
int TA = 0;
|
||||
if ( (pVic->pEdict->v.team == pAtt->pEdict->v.team ) && ( pVic != pAtt) )
|
||||
|
||||
if((pVic->pEdict->v.team == pAtt->pEdict->v.team) && (pVic != pAtt))
|
||||
TA = 1;
|
||||
|
||||
MF_ExecuteForward( iFDamage,pAtt->index, pVic->index, dmg, weapon, aim, TA );
|
||||
MF_ExecuteForward(iFDamage,pAtt->index, pVic->index, dmg, weapon, aim, TA);
|
||||
|
||||
if ( pVic->IsAlive() )
|
||||
if(pVic->IsAlive())
|
||||
return 1;
|
||||
|
||||
pAtt->saveKill(pVic,weapon,( aim == 1 ) ? 1:0 ,TA);
|
||||
|
||||
MF_ExecuteForward( iFDeath,pAtt->index, pVic->index, weapon, aim, TA );
|
||||
MF_ExecuteForward(iFDeath,pAtt->index, pVic->index, weapon, aim, TA);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL cwpn_shot(AMX *amx, cell *params){ // player,wid
|
||||
// player,wid
|
||||
static cell AMX_NATIVE_CALL cwpn_shot(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[2];
|
||||
|
||||
CHECK_PLAYER(index);
|
||||
|
||||
int weapon = params[1];
|
||||
if ( weapon < DODMAX_WEAPONS-DODMAX_CUSTOMWPNS ){
|
||||
if(weapon < DODMAX_WEAPONS-DODMAX_CUSTOMWPNS)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid custom weapon id %d", weapon);
|
||||
return 0;
|
||||
}
|
||||
|
@ -299,23 +447,30 @@ static cell AMX_NATIVE_CALL cwpn_shot(AMX *amx, cell *params){ // player,wid
|
|||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_maxweapons(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_maxweapons(AMX *amx, cell *params)
|
||||
{
|
||||
return DODMAX_WEAPONS;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_stats_size(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL get_stats_size(AMX *amx, cell *params)
|
||||
{
|
||||
return 9;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL is_custom(AMX *amx, cell *params){
|
||||
static cell AMX_NATIVE_CALL is_custom(AMX *amx, cell *params)
|
||||
{
|
||||
int weapon = params[1];
|
||||
if ( weapon < DODMAX_WEAPONS-DODMAX_CUSTOMWPNS ){
|
||||
|
||||
if(weapon < DODMAX_WEAPONS-DODMAX_CUSTOMWPNS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dod_get_user_team(AMX *amx, cell *params){ // player,wid
|
||||
// player,wid
|
||||
static cell AMX_NATIVE_CALL dod_get_user_team(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
|
||||
|
@ -324,22 +479,29 @@ static cell AMX_NATIVE_CALL dod_get_user_team(AMX *amx, cell *params){ // player
|
|||
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params){ // player,wid
|
||||
// player,wid
|
||||
static cell AMX_NATIVE_CALL get_user_team(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
int iTeam = pPlayer->pEdict->v.team;
|
||||
if ( params[3] ){
|
||||
|
||||
if ( params[3] )
|
||||
{
|
||||
char *szTeam = "";
|
||||
switch(iTeam){
|
||||
switch(iTeam)
|
||||
{
|
||||
case 1:
|
||||
szTeam = "Allies";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
szTeam = "Axis";
|
||||
break;
|
||||
}
|
||||
|
||||
MF_SetAmxString(amx,params[2],szTeam,params[3]);
|
||||
}
|
||||
return iTeam;
|
||||
|
@ -352,7 +514,10 @@ static cell AMX_NATIVE_CALL dod_set_model(AMX *amx, cell *params) // player,mode
|
|||
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if(!pPlayer->ingame)
|
||||
return false;
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid Player, Not on Server");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int length;
|
||||
pPlayer->initModel((char*)STRING(ALLOC_STRING(MF_GetAmxString(amx, params[2], 1, &length))));
|
||||
|
@ -367,7 +532,10 @@ static cell AMX_NATIVE_CALL dod_set_body(AMX *amx, cell *params) // player,bodyn
|
|||
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
if(!pPlayer->ingame)
|
||||
return false;
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid Player, Not on Server");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pPlayer->setBody(params[2]);
|
||||
|
||||
|
@ -388,8 +556,70 @@ static cell AMX_NATIVE_CALL dod_clear_model(AMX *amx, cell *params) // player
|
|||
return true;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO base_Natives[] = {
|
||||
/*
|
||||
0 [Byte] 1 // Weapons Groupings
|
||||
1 [Byte] 210 // Total Rounds Allowed
|
||||
2 [Byte] -1 // Undefined Not Used
|
||||
3 [Byte] -1 // Undefined Not Used
|
||||
4 [Byte] 2 // Weapon Slot
|
||||
5 [Byte] 0 // Bucket ( Position Under Weapon Slot )
|
||||
6 [Short] 7 // Weapon Number / Bit Field for the weapon
|
||||
7 [Byte] 128 // Bit Field for the Ammo or Ammo Type
|
||||
8 [Byte] 30 // Rounds Per Mag
|
||||
|
||||
id, wpnID, slot, position, totalrds
|
||||
*/
|
||||
static cell AMX_NATIVE_CALL dod_weaponlist(AMX *amx, cell *params) // player
|
||||
{
|
||||
if(!weaponlist[params[1]].changeable)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "This Weapon Cannot be Changed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id = params[1];
|
||||
int wpnID = params[2];
|
||||
int slot = params[3];
|
||||
int position = params[4];
|
||||
int totalrds = params[5];
|
||||
|
||||
UTIL_LogPrintf("ID (%d) WpnID (%d) Slot (%d) Pos (%d) Rounds (%d)", id, wpnID, slot, position, totalrds);
|
||||
|
||||
CHECK_PLAYER(id);
|
||||
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(id);
|
||||
if(!pPlayer->ingame)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid Player, Not on Server");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MESSAGE_BEGIN(MSG_ONE, GET_USER_MSG_ID(PLID, "WeaponList", NULL), NULL, INDEXENT(id));
|
||||
WRITE_BYTE(weaponlist[wpnID].grp);
|
||||
WRITE_BYTE(totalrds);
|
||||
WRITE_BYTE(-1);
|
||||
WRITE_BYTE(-1);
|
||||
WRITE_BYTE(slot - 1);
|
||||
WRITE_BYTE(position);
|
||||
WRITE_SHORT(wpnID);
|
||||
WRITE_BYTE(weaponlist[wpnID].bitfield);
|
||||
|
||||
// Is it grenades
|
||||
if(wpnID == 13 || wpnID == 14 || wpnID == 15 || wpnID == 16 || wpnID == 36)
|
||||
WRITE_BYTE(-1);
|
||||
else if(wpnID == 29 || wpnID == 30 || wpnID == 31)
|
||||
WRITE_BYTE(1);
|
||||
else
|
||||
WRITE_BYTE(weaponlist[wpnID].clip);
|
||||
MESSAGE_END();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AMX_NATIVE_INFO base_Natives[] =
|
||||
{
|
||||
{ "dod_wpnlog_to_name", wpnlog_to_name },
|
||||
{ "dod_wpnlog_to_id", wpnlog_to_id },
|
||||
|
||||
|
@ -398,6 +628,8 @@ AMX_NATIVE_INFO base_Natives[] = {
|
|||
{ "dod_get_user_class", get_user_class },
|
||||
{ "dod_get_user_weapon", get_user_weapon },
|
||||
|
||||
{ "dod_weapon_type", dod_weapon_type },
|
||||
|
||||
{ "dod_get_map_info", get_map_info },
|
||||
{ "dod_user_kill", user_kill },
|
||||
{ "dod_get_pronestate", get_user_pronestate },
|
||||
|
@ -426,10 +658,10 @@ AMX_NATIVE_INFO base_Natives[] = {
|
|||
{ "dod_get_wpnlogname", get_weapon_logname },
|
||||
{ "dod_is_melee", is_melee },
|
||||
|
||||
// Zors
|
||||
{"dod_set_model", dod_set_model},
|
||||
{"dod_set_body_number", dod_set_body},
|
||||
{"dod_clear_model", dod_clear_model},
|
||||
{"dod_set_weaponlist", dod_weaponlist},
|
||||
|
||||
///*******************
|
||||
{ NULL, NULL }
|
||||
|
|
|
@ -33,113 +33,140 @@
|
|||
#include "dodx.h"
|
||||
|
||||
/* Weapon names aren't send in WeaponList message in DoD */
|
||||
weapon_t weaponData[] = {
|
||||
{ false,false,"mortar","mortar",0 },
|
||||
{ true,true,"amerknife","knife",0 }, // aknife->bknife
|
||||
{ false,true,"gerknife","knife",0 },
|
||||
{ false,false,"colt","Colt",4 },
|
||||
{ false,false,"luger","Luger",4 },
|
||||
{ true,false,"garand","Garand",3 }, // Garand->Garand butt
|
||||
{ false,false,"scopedkar","scoped K98",3 },
|
||||
{ false,false,"thompson","Thompson",1 },
|
||||
{ false,false,"mp44","STG44",6 },
|
||||
{ false,false,"spring","Springfield",5 },
|
||||
{ true,false,"kar","K98",3 }, // KAR->KAR bayonet
|
||||
{ false,false,"bar","BAR",6 },
|
||||
{ false,false,"mp40","MP40",1 },
|
||||
{ false,false,"grenade","handgrenade",9 },
|
||||
{ false,false,"grenade2","stickgrenade",11 },
|
||||
{ false,false,"stickgrenade_ex","stickgrenade_ex",11 },
|
||||
{ false,false,"handgrenade_ex","handgrenade_ex",9 },
|
||||
{ false,false,"mg42","MG42",7 },
|
||||
{ false,false,"30cal",".30 cal",8 },
|
||||
{ false,true,"spade","spade",0 },
|
||||
{ true,false,"m1carbine","M1 Carbine",2 }, // M1 Carbine->Folding Carbine
|
||||
{ false,false,"mg34","MG34",2 },
|
||||
{ false,false,"greasegun","Greasegun",1 },
|
||||
{ true,false,"fg42","FG42",6 }, // FG42 -> scoped FG42
|
||||
{ true,false,"k43","K43",2 },
|
||||
{ true,false,"enfield","Enfield",3 }, // Enfield->Scoped Enfield->Enfield bayonet
|
||||
{ false,false,"sten","Sten",1 },
|
||||
{ false,false,"bren","Bren",6 },
|
||||
{ false,false,"webley","Webley",4 },
|
||||
{ false,false,"bazooka","Bazooka",13 },
|
||||
{ false,false,"pschreck","Panzerschrek",13 },
|
||||
{ false,false,"piat","Piat",13 },
|
||||
{ false,false,"scoped_fg42","scoped FG42",6 },
|
||||
{ false,false,"fcarbine","Folding Carbine" },
|
||||
{ false,true,"bayonet","K98 bayonet",0 }, // KAR bayonet
|
||||
{ false,false,"scoped_enfield","scoped Enfield",3 },
|
||||
{ false,false,"mills_bomb","mills bomb",9 },
|
||||
{ false,true,"brit_knife","knife",0 },
|
||||
{ false,true,"garandbutt","Garand butt",0 }, // Garand butt
|
||||
{ false,true,"enf_bayonet","Enfield bayonet",0 },
|
||||
{ false,false,"mortar","mortar",0 }, // mortar new id
|
||||
{ false,true,"k43butt","K43 butt",0 },
|
||||
weapon_t weaponData[] =
|
||||
{
|
||||
{ false, false, "mortar", "mortar", 0, DODWT_OTHER },
|
||||
{ true, true, "amerknife", "knife", 0, DODWT_MELEE }, // aknife->bknife
|
||||
{ false, true, "gerknife", "knife", 0, DODWT_MELEE },
|
||||
{ false, false, "colt", "Colt", 4, DODWT_SECONDARY },
|
||||
{ false, false, "luger", "Luger", 4, DODWT_SECONDARY },
|
||||
{ true, false, "garand", "Garand", 3, DODWT_PRIMARY }, // Garand->Garand butt
|
||||
{ false, false, "scopedkar", "scoped K98", 3, DODWT_PRIMARY },
|
||||
{ false, false, "thompson", "Thompson", 1, DODWT_PRIMARY },
|
||||
{ false, false, "mp44", "STG44", 6, DODWT_PRIMARY },
|
||||
{ false, false, "spring", "Springfield", 5, DODWT_PRIMARY },
|
||||
{ true, false, "kar", "K98", 3, DODWT_PRIMARY }, // KAR->KAR bayonet
|
||||
{ false, false, "bar", "BAR", 6, DODWT_PRIMARY },
|
||||
{ false, false, "mp40", "MP40", 1, DODWT_PRIMARY },
|
||||
{ false, false, "grenade", "handgrenade", 9, DODWT_GRENADE },
|
||||
{ false, false, "grenade2", "stickgrenade", 11, DODWT_GRENADE },
|
||||
{ false, false, "stickgrenade_ex", "stickgrenade_ex", 11, DODWT_GRENADE },
|
||||
{ false, false, "handgrenade_ex", "handgrenade_ex", 9, DODWT_GRENADE },
|
||||
{ false, false, "mg42", "MG42", 7, DODWT_PRIMARY },
|
||||
{ false, false, "30cal", ".30 cal", 8, DODWT_PRIMARY },
|
||||
{ false, true, "spade", "spade", 0, DODWT_MELEE },
|
||||
{ true, false, "m1carbine", "M1 Carbine", 2, DODWT_PRIMARY }, // M1 Carbine->Folding Carbine
|
||||
{ false, false, "mg34", "MG34", 2, DODWT_PRIMARY },
|
||||
{ false, false, "greasegun", "Greasegun", 1, DODWT_PRIMARY },
|
||||
{ true, false, "fg42", "FG42", 6, DODWT_PRIMARY }, // FG42 -> scoped FG42
|
||||
{ true, false, "k43", "K43", 2, DODWT_PRIMARY },
|
||||
{ true, false, "enfield", "Enfield", 3, DODWT_PRIMARY }, // Enfield->Scoped Enfield->Enfield bayonet
|
||||
{ false, false, "sten", "Sten", 1, DODWT_PRIMARY },
|
||||
{ false, false, "bren", "Bren", 6, DODWT_PRIMARY },
|
||||
{ false, false, "webley", "Webley", 4, DODWT_PRIMARY },
|
||||
{ false, false, "bazooka", "Bazooka", 13, DODWT_PRIMARY },
|
||||
{ false, false, "pschreck", "Panzerschrek", 13, DODWT_PRIMARY },
|
||||
{ false, false, "piat", "Piat", 13, DODWT_PRIMARY },
|
||||
{ false, false, "scoped_fg42", "scoped FG42", 6, DODWT_PRIMARY },
|
||||
{ false, false, "fcarbine", "Folding Carbine", 0, DODWT_PRIMARY },
|
||||
{ false, true, "bayonet", "K98 bayonet", 0, DODWT_MELEE }, // KAR bayonet
|
||||
{ false, false, "scoped_enfield", "scoped Enfield", 3, DODWT_PRIMARY },
|
||||
{ false, false, "mills_bomb", "mills bomb", 9, DODWT_GRENADE },
|
||||
{ false, true, "brit_knife", "knife", 0, DODWT_MELEE },
|
||||
{ false, true, "garandbutt", "Garand butt", 0, DODWT_MELEE }, // Garand butt
|
||||
{ false, true, "enf_bayonet", "Enfield bayonet", 0, DODWT_MELEE },
|
||||
{ false, false, "mortar", "mortar", 0, DODWT_OTHER }, // mortar new id
|
||||
{ false, true, "k43butt", "K43 butt", 0, DODWT_MELEE },
|
||||
};
|
||||
|
||||
/* Function will select correct id */
|
||||
int get_weaponid(CPlayer* pPlayer){
|
||||
int get_weaponid(CPlayer* pPlayer)
|
||||
{
|
||||
int weapon = pPlayer->current;
|
||||
const char *sz;
|
||||
switch(weapon) {
|
||||
case 1: if ( g_map.detect_allies_country ) weapon = 37; break;
|
||||
case 5: if ( pPlayer->pEdict->v.button&IN_ATTACK2 ) weapon = 38; break;
|
||||
case 10: if ( pPlayer->pEdict->v.button&IN_ATTACK2 ) weapon = 34; break;
|
||||
case 20:
|
||||
if ( g_map.detect_allies_paras ) weapon = 33;
|
||||
switch(weapon)
|
||||
{
|
||||
case 1:
|
||||
if(g_map.detect_allies_country) weapon = 37;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if(pPlayer->pEdict->v.button&IN_ATTACK2) weapon = 38;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
if(pPlayer->pEdict->v.button&IN_ATTACK2) weapon = 34;
|
||||
break;
|
||||
|
||||
case 20:
|
||||
if(g_map.detect_allies_paras) weapon = 33;
|
||||
break;
|
||||
|
||||
case 23:
|
||||
sz = STRING(pPlayer->pEdict->v.weaponmodel);
|
||||
if ( sz[13] == 's' )
|
||||
if(sz[13] == 's')
|
||||
weapon = 32;
|
||||
break;
|
||||
case 24: if ( pPlayer->pEdict->v.button&IN_ATTACK2 ) weapon = 41; break;
|
||||
|
||||
case 24:
|
||||
if(pPlayer->pEdict->v.button&IN_ATTACK2) weapon = 41;
|
||||
break;
|
||||
|
||||
case 25:
|
||||
sz = STRING(pPlayer->pEdict->v.weaponmodel);
|
||||
if ( sz[16] == 's' )
|
||||
if(sz[16] == 's')
|
||||
weapon = 35;
|
||||
else if ( pPlayer->pEdict->v.button&IN_ATTACK2 )
|
||||
else if(pPlayer->pEdict->v.button&IN_ATTACK2)
|
||||
weapon = 39;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
weapon = 14;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if ( g_map.detect_allies_country ) weapon = 36;
|
||||
if(g_map.detect_allies_country) weapon = 36;
|
||||
else weapon = 13;
|
||||
break;
|
||||
}
|
||||
|
||||
return weapon;
|
||||
}
|
||||
|
||||
traceVault traceData[] = {
|
||||
traceVault traceData[] =
|
||||
{
|
||||
{ "grenade", 13, ACT_NADE_PUT|ACT_NADE_SHOT, 2.0 }, // or 36
|
||||
{ "grenade2", 14, ACT_NADE_PUT|ACT_NADE_SHOT, 2.0 },
|
||||
{ "shell_bazooka", 29, ACT_NADE_PUT, 2.0 },
|
||||
{ "shell_pschreck", 30, ACT_NADE_PUT, 2.0 },
|
||||
{ "shell_piat", 31, ACT_NADE_PUT, 2.0 },
|
||||
{ "shell_bazooka", 29, ACT_ROCKET_PUT|ACT_ROCKET_SHOT, 2.0 },
|
||||
{ "shell_pschreck", 30, ACT_ROCKET_PUT|ACT_ROCKET_SHOT, 2.0 },
|
||||
{ "shell_piat", 31, ACT_ROCKET_PUT|ACT_ROCKET_SHOT, 2.0 },
|
||||
{ "monster_mortar", 40, ACT_NADE_PUT|ACT_NADE_SHOT, 2.0 },
|
||||
};
|
||||
|
||||
bool ignoreBots (edict_t *pEnt, edict_t *pOther){
|
||||
if ( !rankBots && ( pEnt->v.flags & FL_FAKECLIENT || ( pOther && pOther->v.flags & FL_FAKECLIENT ) ) )
|
||||
bool ignoreBots (edict_t *pEnt, edict_t *pOther)
|
||||
{
|
||||
if(!rankBots && (pEnt->v.flags & FL_FAKECLIENT || (pOther && pOther->v.flags & FL_FAKECLIENT)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isModuleActive(){
|
||||
if ( !(int)CVAR_GET_FLOAT("dodstats_pause") )
|
||||
bool isModuleActive()
|
||||
{
|
||||
if(!(int)CVAR_GET_FLOAT("dodstats_pause"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
edict_t *FindEntityByString(edict_t *pentStart, const char *szKeyword, const char *szValue)
|
||||
{
|
||||
edict_t *pentEntity;
|
||||
pentEntity=FIND_ENTITY_BY_STRING(pentStart, szKeyword, szValue);
|
||||
pentEntity = FIND_ENTITY_BY_STRING(pentStart, szKeyword, szValue);
|
||||
|
||||
if(!FNullEnt(pentEntity))
|
||||
return pentEntity;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -147,3 +174,13 @@ edict_t *FindEntityByClassname(edict_t *pentStart, const char *szName)
|
|||
{
|
||||
return FindEntityByString(pentStart, "classname", szName);
|
||||
}
|
||||
|
||||
edict_t *FindEntityInSphere(edict_t *pentStart, edict_t *origin, float radius)
|
||||
{
|
||||
edict_t* temp = FIND_ENTITY_IN_SPHERE(pentStart, origin->v.origin, radius);
|
||||
|
||||
if(!temp)
|
||||
return NULL;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
|
|
@ -47,30 +47,64 @@ extern AMX_NATIVE_INFO stats_Natives[];
|
|||
extern AMX_NATIVE_INFO base_Natives[];
|
||||
extern AMX_NATIVE_INFO pd_Natives[];
|
||||
|
||||
struct weapon_t {
|
||||
// Weapons grabbing by type
|
||||
enum
|
||||
{
|
||||
DODWT_PRIMARY = 0,
|
||||
DODWT_SECONDARY,
|
||||
DODWT_MELEE,
|
||||
DODWT_GRENADE,
|
||||
DODWT_OTHER
|
||||
};
|
||||
|
||||
// Model Sequences
|
||||
enum
|
||||
{
|
||||
DOD_SEQ_PRONE_IDLE = 15,
|
||||
DOD_SEQ_PRONE_FORWARD,
|
||||
DOD_SEQ_PRONE_DOWN,
|
||||
DOD_SEQ_PRONE_UP
|
||||
};
|
||||
|
||||
// Weapons Structure
|
||||
struct weapon_t
|
||||
{
|
||||
bool needcheck;
|
||||
bool melee;
|
||||
char logname[16];
|
||||
char name[32];
|
||||
char hashname[32];
|
||||
int ammoSlot;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct weaponlist_s
|
||||
{
|
||||
int grp;
|
||||
int bitfield;
|
||||
int clip;
|
||||
bool changeable;
|
||||
};
|
||||
|
||||
extern bool rankBots;
|
||||
extern int mState;
|
||||
extern int mDest;
|
||||
extern int mCurWpnEnd;
|
||||
extern int mPlayerIndex;
|
||||
|
||||
void Client_CurWeapon(void*);
|
||||
void Client_CurWeapon_End(void*);
|
||||
void Client_Health_End(void*);
|
||||
void Client_ResetHUD_End(void*);
|
||||
void Client_ObjScore(void*);
|
||||
void Client_TeamScore(void*);
|
||||
void Client_RoundState(void*);
|
||||
void Client_AmmoX(void*);
|
||||
void Client_AmmoShort(void*);
|
||||
void Client_Health_End(void*);
|
||||
|
||||
// Zors
|
||||
//void WeaponList(void*);
|
||||
//void WeaponList_End(void*);
|
||||
void Client_SetFOV(void*);
|
||||
void Client_SetFOV_End(void*);
|
||||
void Client_Object(void*);
|
||||
void Client_Object_End(void*);
|
||||
|
||||
typedef void (*funEventCall)(void*);
|
||||
|
||||
|
@ -78,6 +112,8 @@ extern int AlliesScore;
|
|||
extern int AxisScore;
|
||||
|
||||
extern int gmsgCurWeapon;
|
||||
extern int gmsgCurWeaponEnd;
|
||||
extern int gmsgHealth;
|
||||
extern int gmsgResetHUD;
|
||||
extern int gmsgObjScore;
|
||||
extern int gmsgRoundState;
|
||||
|
@ -86,7 +122,10 @@ extern int gmsgScoreShort;
|
|||
extern int gmsgPTeam;
|
||||
extern int gmsgAmmoX;
|
||||
extern int gmsgAmmoShort;
|
||||
extern int gmsgHealth_End;
|
||||
extern int gmsgSetFOV;
|
||||
extern int gmsgSetFOV_End;
|
||||
extern int gmsgObject;
|
||||
extern int gmsgObject_End;
|
||||
|
||||
extern int iFDamage;
|
||||
extern int iFDeath;
|
||||
|
@ -94,6 +133,14 @@ extern int iFScore;
|
|||
extern int iFSpawnForward;
|
||||
extern int iFTeamForward;
|
||||
extern int iFClassForward;
|
||||
extern int iFScopeForward;
|
||||
extern int iFProneForward;
|
||||
extern int iFWpnPickupForward;
|
||||
extern int iFCurWpnForward;
|
||||
extern int iFGrenadeExplode;
|
||||
extern int iFRocketExplode;
|
||||
extern int iFObjectTouched;
|
||||
extern int iFStaminaForward;
|
||||
|
||||
extern cvar_t* dodstats_maxsize;
|
||||
extern cvar_t* dodstats_rank;
|
||||
|
@ -113,7 +160,9 @@ extern CMapInfo g_map;
|
|||
int get_weaponid(CPlayer* player);
|
||||
bool ignoreBots (edict_t *pEnt, edict_t *pOther = NULL );
|
||||
bool isModuleActive();
|
||||
edict_t *FindEntityByString(edict_t *pentStart, const char *szKeyword, const char *szValue);
|
||||
edict_t *FindEntityByClassname(edict_t *pentStart, const char *szName);
|
||||
edict_t *FindEntityInSphere(edict_t *pentStart, edict_t *origin, float radius);
|
||||
|
||||
#define CHECK_ENTITY(x) \
|
||||
if (x < 0 || x > gpGlobals->maxEntities) { \
|
||||
|
|
|
@ -42,6 +42,8 @@ CMapInfo g_map;
|
|||
|
||||
bool rankBots;
|
||||
int mState;
|
||||
int mDest;
|
||||
int mCurWpnEnd;
|
||||
int mPlayerIndex;
|
||||
|
||||
int AlliesScore;
|
||||
|
@ -50,13 +52,21 @@ int AxisScore;
|
|||
int iFDamage = -1;
|
||||
int iFDeath = -1;
|
||||
int iFScore = -1;
|
||||
|
||||
// Zors
|
||||
int iFSpawnForward = -1;
|
||||
int iFTeamForward = -1;
|
||||
int iFClassForward = -1;
|
||||
int iFScopeForward = -1;
|
||||
int iFProneForward = -1;
|
||||
int iFWpnPickupForward = -1;
|
||||
int iFCurWpnForward = -1;
|
||||
int iFGrenadeExplode = -1;
|
||||
int iFRocketExplode = -1;
|
||||
int iFObjectTouched = -1;
|
||||
int iFStaminaForward = -1;
|
||||
|
||||
int gmsgCurWeapon;
|
||||
int gmsgCurWeaponEnd;
|
||||
int gmsgHealth;
|
||||
int gmsgResetHUD;
|
||||
int gmsgObjScore;
|
||||
int gmsgRoundState;
|
||||
|
@ -65,11 +75,10 @@ int gmsgScoreShort;
|
|||
int gmsgPTeam;
|
||||
int gmsgAmmoX;
|
||||
int gmsgAmmoShort;
|
||||
int gmsgHealth_End;
|
||||
|
||||
// Zors
|
||||
//int gmsgWeaponList;
|
||||
//int gmsgWeaponList_End;
|
||||
int gmsgSetFOV;
|
||||
int gmsgSetFOV_End;
|
||||
int gmsgObject;
|
||||
int gmsgObject_End;
|
||||
|
||||
RankSystem g_rank;
|
||||
Grenades g_grenades;
|
||||
|
@ -85,29 +94,31 @@ cvar_t *dodstats_rank;
|
|||
cvar_t *dodstats_rankbots;
|
||||
cvar_t *dodstats_pause;
|
||||
|
||||
struct sUserMsg {
|
||||
// User Messages
|
||||
struct sUserMsg
|
||||
{
|
||||
const char *name;
|
||||
int* id;
|
||||
funEventCall func;
|
||||
bool endmsg;
|
||||
} g_user_msg[] =
|
||||
}
|
||||
g_user_msg[] =
|
||||
{
|
||||
{ "CurWeapon", &gmsgCurWeapon, Client_CurWeapon, false },
|
||||
{ "ObjScore", &gmsgObjScore, Client_ObjScore, false },
|
||||
{ "RoundState", &gmsgRoundState, Client_RoundState, false },
|
||||
{ "ResetHUD", &gmsgResetHUD, Client_ResetHUD_End, true },
|
||||
{ "TeamScore", &gmsgTeamScore, Client_TeamScore, false },
|
||||
{ "AmmoX", &gmsgAmmoX, Client_AmmoX, false },
|
||||
{ "AmmoShort", &gmsgAmmoShort, Client_AmmoShort, false },
|
||||
{ "Health", &gmsgHealth_End, Client_Health_End, true },
|
||||
|
||||
//Zors
|
||||
//{ "WeaponList", &gmsgWeaponList, WeaponList, true },
|
||||
//{ "WeaponList", &gmsgWeaponList_End, WeaponList_End, true },
|
||||
|
||||
{ "PTeam", &gmsgPTeam, NULL, false },
|
||||
{ "ScoreShort", &gmsgScoreShort, NULL, false },
|
||||
|
||||
{ "CurWeapon", &gmsgCurWeapon, Client_CurWeapon, false },
|
||||
{ "CurWeapon", &gmsgCurWeaponEnd, Client_CurWeapon_End, true },
|
||||
{ "ObjScore", &gmsgObjScore, Client_ObjScore, false },
|
||||
{ "RoundState", &gmsgRoundState, Client_RoundState, false },
|
||||
{ "Health", &gmsgHealth, Client_Health_End, true },
|
||||
{ "ResetHUD", &gmsgResetHUD, Client_ResetHUD_End, true },
|
||||
{ "TeamScore", &gmsgTeamScore, Client_TeamScore, false },
|
||||
{ "AmmoX", &gmsgAmmoX, Client_AmmoX, false },
|
||||
{ "AmmoShort", &gmsgAmmoShort, Client_AmmoShort, false },
|
||||
{ "SetFOV", &gmsgSetFOV, Client_SetFOV, false },
|
||||
{ "SetFOV", &gmsgSetFOV_End, Client_SetFOV_End, true },
|
||||
{ "Object", &gmsgObject, Client_Object, false },
|
||||
{ "Object", &gmsgObject_End, Client_Object_End, true },
|
||||
{ "ScoreShort", &gmsgScoreShort, NULL, false },
|
||||
{ "PTeam", &gmsgPTeam, NULL, false },
|
||||
{ 0,0,0,false }
|
||||
};
|
||||
|
||||
|
@ -119,18 +130,20 @@ const char* get_localinfo( const char* name , const char* def = 0 )
|
|||
return b;
|
||||
}
|
||||
|
||||
int RegUserMsg_Post(const char *pszName, int iSize){
|
||||
for (int i = 0; g_user_msg[ i ].name; ++i ){
|
||||
if ( !*g_user_msg[i].id && strcmp( g_user_msg[ i ].name , pszName ) == 0 ){
|
||||
int id = META_RESULT_ORIG_RET( int );
|
||||
int RegUserMsg_Post(const char *pszName, int iSize)
|
||||
{
|
||||
for (int i = 0; g_user_msg[i].name; ++i )
|
||||
{
|
||||
if(!*g_user_msg[i].id && strcmp(g_user_msg[i].name, pszName) == 0)
|
||||
{
|
||||
int id = META_RESULT_ORIG_RET(int);
|
||||
|
||||
*g_user_msg[ i ].id = id;
|
||||
*g_user_msg[i].id = id;
|
||||
|
||||
if ( g_user_msg[ i ].endmsg )
|
||||
modMsgsEnd[ id ] = g_user_msg[ i ].func;
|
||||
if(g_user_msg[i].endmsg)
|
||||
modMsgsEnd[id] = g_user_msg[i].func;
|
||||
else
|
||||
modMsgs[ id ] = g_user_msg[ i ].func;
|
||||
|
||||
modMsgs[id] = g_user_msg[i].func;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -149,47 +162,55 @@ void ServerActivate_Post( edict_t *pEdictList, int edictCount, int clientMax ){
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void PlayerPreThink_Post( edict_t *pEntity ) {
|
||||
void PlayerPreThink_Post(edict_t *pEntity)
|
||||
{
|
||||
if ( !isModuleActive() )
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
if ( !pPlayer->ingame )
|
||||
if (!pPlayer->ingame)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
// Zors
|
||||
pPlayer->checkStatus();
|
||||
pPlayer->PreThink();
|
||||
|
||||
if (pPlayer->clearStats && pPlayer->clearStats < gpGlobals->time){
|
||||
if ( !ignoreBots(pEntity) ){
|
||||
if(pPlayer->clearStats && pPlayer->clearStats < gpGlobals->time)
|
||||
{
|
||||
if(!ignoreBots(pEntity))
|
||||
{
|
||||
pPlayer->clearStats = 0.0f;
|
||||
pPlayer->rank->updatePosition( &pPlayer->life );
|
||||
pPlayer->restartStats(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (pPlayer->clearRound && pPlayer->clearRound < gpGlobals->time){
|
||||
if(pPlayer->clearRound && pPlayer->clearRound < gpGlobals->time)
|
||||
{
|
||||
pPlayer->clearRound = 0.0f;
|
||||
memset(&pPlayer->round,0,sizeof(pPlayer->round));
|
||||
memset(pPlayer->weaponsRnd,0,sizeof(pPlayer->weaponsRnd));
|
||||
}
|
||||
|
||||
if (pPlayer->sendScore && pPlayer->sendScore < gpGlobals->time){
|
||||
if (pPlayer->sendScore && pPlayer->sendScore < gpGlobals->time)
|
||||
{
|
||||
pPlayer->sendScore = 0;
|
||||
MF_ExecuteForward( iFScore,pPlayer->index, pPlayer->lastScore, pPlayer->savedScore );
|
||||
MF_ExecuteForward(iFScore, pPlayer->index, pPlayer->lastScore, pPlayer->savedScore);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void ServerDeactivate() {
|
||||
void ServerDeactivate()
|
||||
{
|
||||
int i;
|
||||
for( i = 1;i<=gpGlobals->maxClients; ++i){
|
||||
for( i = 1;i<=gpGlobals->maxClients; ++i)
|
||||
{
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
|
||||
if (pPlayer->ingame) pPlayer->Disconnect();
|
||||
}
|
||||
|
||||
if ( (g_rank.getRankNum() >= (int)dodstats_maxsize->value) || ((int)dodstats_reset->value == 1) ) {
|
||||
if ( (g_rank.getRankNum() >= (int)dodstats_maxsize->value) || ((int)dodstats_reset->value == 1) )
|
||||
{
|
||||
CVAR_SET_FLOAT("dodstats_reset",0.0);
|
||||
g_rank.clear();
|
||||
}
|
||||
|
@ -205,13 +226,15 @@ void ServerDeactivate() {
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
BOOL ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ){
|
||||
BOOL ClientConnect_Post( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
|
||||
{
|
||||
GET_PLAYER_POINTER(pEntity)->Connect(pszName,pszAddress);
|
||||
|
||||
RETURN_META_VALUE(MRES_IGNORED, TRUE);
|
||||
}
|
||||
|
||||
void ClientDisconnect( edict_t *pEntity ) {
|
||||
void ClientDisconnect( edict_t *pEntity )
|
||||
{
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
|
||||
if (pPlayer->ingame)
|
||||
|
@ -220,27 +243,33 @@ void ClientDisconnect( edict_t *pEntity ) {
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void ClientPutInServer_Post( edict_t *pEntity ) {
|
||||
void ClientPutInServer_Post( edict_t *pEntity )
|
||||
{
|
||||
GET_PLAYER_POINTER(pEntity)->PutInServer();
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer ) {
|
||||
void ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer )
|
||||
{
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
|
||||
|
||||
const char* name = INFOKEY_VALUE(infobuffer,"name");
|
||||
const char* oldname = STRING(pEntity->v.netname);
|
||||
|
||||
if ( pPlayer->ingame){
|
||||
if ( strcmp(oldname,name) ) {
|
||||
if ( pPlayer->ingame)
|
||||
{
|
||||
if ( strcmp(oldname,name) )
|
||||
{
|
||||
if (!dodstats_rank->value)
|
||||
pPlayer->rank = g_rank.findEntryInRank( name, name );
|
||||
else
|
||||
pPlayer->rank->setName( name );
|
||||
}
|
||||
}
|
||||
else if ( pPlayer->IsBot() ) {
|
||||
|
||||
else if ( pPlayer->IsBot() )
|
||||
{
|
||||
pPlayer->Connect( name , "127.0.0.1" );
|
||||
pPlayer->PutInServer();
|
||||
}
|
||||
|
@ -248,17 +277,26 @@ void ClientUserInfoChanged_Post( edict_t *pEntity, char *infobuffer ) {
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) {
|
||||
if (ed){
|
||||
void MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
|
||||
{
|
||||
if(ed)
|
||||
{
|
||||
mPlayerIndex = ENTINDEX(ed);
|
||||
mPlayer = GET_PLAYER_POINTER_I(mPlayerIndex);
|
||||
} else {
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mPlayerIndex = 0;
|
||||
mPlayer = NULL;
|
||||
}
|
||||
|
||||
mDest = msg_dest;
|
||||
mState = 0;
|
||||
|
||||
if ( msg_type < 0 || msg_type >= MAX_REG_MSGS )
|
||||
msg_type = 0;
|
||||
|
||||
function=modMsgs[msg_type];
|
||||
endfunction=modMsgsEnd[msg_type];
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
@ -309,26 +347,48 @@ void WriteEntity_Post(int iValue) {
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *e, TraceResult *ptr) {
|
||||
if (ptr->pHit&&(ptr->pHit->v.flags& (FL_CLIENT | FL_FAKECLIENT) )&&
|
||||
e && (e->v.flags&(FL_CLIENT | FL_FAKECLIENT) )){
|
||||
void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *e, TraceResult *ptr)
|
||||
{
|
||||
if(ptr->pHit && (ptr->pHit->v.flags&(FL_CLIENT | FL_FAKECLIENT)) && e && (e->v.flags&(FL_CLIENT | FL_FAKECLIENT)))
|
||||
{
|
||||
GET_PLAYER_POINTER(e)->aiming = ptr->iHitgroup;
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
if ( e && e->v.owner && e->v.owner->v.flags& (FL_CLIENT | FL_FAKECLIENT) ){
|
||||
if(e && e->v.owner && e->v.owner->v.flags&(FL_CLIENT | FL_FAKECLIENT))
|
||||
{
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER(e->v.owner);
|
||||
for ( int i=0;i<MAX_TRACE;i++){
|
||||
if ( strcmp( traceData[i].szName,STRING(e->v.classname)) == 0 ){
|
||||
if ( traceData[i].iAction & ACT_NADE_SHOT ){
|
||||
if ( traceData[i].iId == 13 && g_map.detect_allies_country )
|
||||
pPlayer->saveShot(36);
|
||||
|
||||
for(int i = 0;i < MAX_TRACE; i++)
|
||||
{
|
||||
if(strcmp(traceData[i].szName, STRING(e->v.classname)) == 0)
|
||||
{
|
||||
int grenId = (traceData[i].iId == 13 && g_map.detect_allies_country) ? 36 : traceData[i].iId;
|
||||
int rocketId = traceData[i].iId;
|
||||
|
||||
if(traceData[i].iAction&ACT_NADE_SHOT)
|
||||
{
|
||||
if(traceData[i].iId == 13 && g_map.detect_allies_country)
|
||||
pPlayer->saveShot(grenId);
|
||||
else
|
||||
pPlayer->saveShot(traceData[i].iId);
|
||||
}
|
||||
if ( traceData[i].iAction & ACT_NADE_PUT ){
|
||||
g_grenades.put(e,traceData[i].fDel, (traceData[i].iId == 13 && g_map.detect_allies_country )?36:traceData[i].iId ,GET_PLAYER_POINTER(e->v.owner));
|
||||
|
||||
else if(traceData[i].iAction&ACT_ROCKET_SHOT)
|
||||
pPlayer->saveShot(traceData[i].iId);
|
||||
|
||||
cell position[3] = {v2[0], v2[1], v2[2]};
|
||||
cell pos = MF_PrepareCellArray(position, 3);
|
||||
|
||||
if(traceData[i].iAction&ACT_NADE_PUT)
|
||||
{
|
||||
g_grenades.put(e, traceData[i].fDel, grenId, GET_PLAYER_POINTER(e->v.owner));
|
||||
MF_ExecuteForward(iFGrenadeExplode, GET_PLAYER_POINTER(e->v.owner)->index, pos, grenId);
|
||||
}
|
||||
|
||||
if(traceData[i].iAction&ACT_ROCKET_PUT)
|
||||
MF_ExecuteForward(iFRocketExplode, pPlayer->index, pos, rocketId);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -338,7 +398,6 @@ void TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *
|
|||
|
||||
void DispatchKeyValue_Post( edict_t *pentKeyvalue, KeyValueData *pkvd )
|
||||
{
|
||||
|
||||
if ( !pkvd->szClassName ){
|
||||
// info_doddetect
|
||||
if ( pkvd->szValue[0]=='i' && pkvd->szValue[5]=='d' ){
|
||||
|
@ -392,6 +451,7 @@ void SetClientKeyValue(int id, char *protocol, char *type, char *var)
|
|||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
|
||||
void OnMetaAttach()
|
||||
{
|
||||
CVAR_REGISTER (&init_dodstats_maxsize);
|
||||
|
@ -408,7 +468,6 @@ void OnMetaAttach()
|
|||
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
|
||||
MF_AddNatives( stats_Natives );
|
||||
MF_AddNatives( base_Natives );
|
||||
|
||||
|
@ -444,5 +503,12 @@ void OnPluginsLoaded()
|
|||
iFTeamForward = MF_RegisterForward("dod_client_changeteam",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*team*/,FP_CELL/*oldteam*/,FP_DONE);
|
||||
iFSpawnForward = MF_RegisterForward("dod_client_spawn",ET_IGNORE,FP_CELL/*id*/,FP_DONE);
|
||||
iFClassForward = MF_RegisterForward("dod_client_changeclass",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*class*/,FP_CELL/*oldclass*/,FP_DONE);
|
||||
iFScopeForward = MF_RegisterForward("dod_client_scope",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*value*/,FP_DONE);
|
||||
iFWpnPickupForward = MF_RegisterForward("dod_client_weaponpickup",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*weapon*/,FP_CELL/*value*/,FP_DONE);
|
||||
iFProneForward = MF_RegisterForward("dod_client_prone",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*value*/,FP_DONE);
|
||||
iFCurWpnForward = MF_RegisterForward("dod_client_weaponswitch",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*wpnold*/,FP_CELL/*wpnew*/,FP_DONE);
|
||||
iFGrenadeExplode = MF_RegisterForward("dod_grenade_explosion",ET_IGNORE,FP_CELL/*id*/,FP_ARRAY/*pos[3]*/,FP_CELL/*wpnid*/,FP_DONE);
|
||||
iFRocketExplode = MF_RegisterForward("dod_rocket_explosion",ET_IGNORE,FP_CELL/*id*/,FP_ARRAY/*pos[3]*/,FP_CELL/*wpnid*/,FP_DONE);
|
||||
iFObjectTouched = MF_RegisterForward("dod_client_objectpickup",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*object*/,FP_ARRAY/*pos[3]*/,FP_CELL/*value*/,FP_DONE);
|
||||
iFStaminaForward = MF_RegisterForward("dod_client_stamina",ET_IGNORE,FP_CELL/*id*/,FP_CELL/*stamina*/,FP_DONE);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
// Module info
|
||||
#define MODULE_NAME "DoDX"
|
||||
#define MODULE_VERSION "1.76b"
|
||||
#define MODULE_VERSION "1.76c_beta_6"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "DODX"
|
||||
|
|
|
@ -98,47 +98,129 @@ void Client_ObjScore(void* mValue)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Client_CurWeapon(void* mValue)
|
||||
{
|
||||
static int iState;
|
||||
static int iId;
|
||||
static int iState;
|
||||
static int iId;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
iState = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!iState) break;
|
||||
iId = *(int*)mValue;
|
||||
break;
|
||||
case 2:
|
||||
if ( !iState || !isModuleActive() )
|
||||
break;
|
||||
int iClip = *(int*)mValue;
|
||||
mPlayer->current = iId;
|
||||
|
||||
if ( weaponData[iId].needcheck )
|
||||
switch (mState++)
|
||||
{
|
||||
iId = get_weaponid(mPlayer);
|
||||
mPlayer->current = iId;
|
||||
case 0:
|
||||
iState = *(int*)mValue;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (!iState)
|
||||
break;
|
||||
|
||||
iId = *(int*)mValue;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if(!iState || !isModuleActive())
|
||||
break;
|
||||
|
||||
int iClip = *(int*)mValue;
|
||||
mPlayer->old = mPlayer->current;
|
||||
mPlayer->current = iId;
|
||||
|
||||
if(weaponData[iId].needcheck)
|
||||
{
|
||||
iId = get_weaponid(mPlayer);
|
||||
mPlayer->current = iId;
|
||||
}
|
||||
|
||||
if(iClip > -1)
|
||||
{
|
||||
if(mPlayer->current == 17)
|
||||
{
|
||||
if(iClip+2 == mPlayer->weapons[iId].clip)
|
||||
mPlayer->saveShot(iId);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( iClip+1 == mPlayer->weapons[iId].clip)
|
||||
mPlayer->saveShot(iId);
|
||||
}
|
||||
}
|
||||
|
||||
mPlayer->weapons[iId].clip = iClip;
|
||||
mCurWpnEnd = 1;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void Client_CurWeapon_End(void*)
|
||||
{
|
||||
if(mCurWpnEnd == 1 && mPlayer->index && mPlayer->current && mPlayer->old && (mPlayer->current != mPlayer->old))
|
||||
MF_ExecuteForward(iFCurWpnForward, mPlayer->index, mPlayer->current, mPlayer->old);
|
||||
|
||||
mCurWpnEnd = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Nie ma damage event ...
|
||||
*/
|
||||
void Client_Health_End(void* mValue)
|
||||
{
|
||||
if ( !isModuleActive() )
|
||||
return;
|
||||
|
||||
edict_t *enemy = mPlayer->pEdict->v.dmg_inflictor;
|
||||
int damage = (int)mPlayer->pEdict->v.dmg_take;
|
||||
|
||||
if ( !mPlayer || !damage || !enemy )
|
||||
return;
|
||||
|
||||
int weapon = 0;
|
||||
int aim = 0;
|
||||
|
||||
mPlayer->pEdict->v.dmg_take = 0.0;
|
||||
|
||||
CPlayer* pAttacker = NULL;
|
||||
|
||||
if(enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT))
|
||||
{
|
||||
pAttacker = GET_PLAYER_POINTER(enemy);
|
||||
weapon = pAttacker->current;
|
||||
|
||||
if ( weaponData[weapon].needcheck )
|
||||
weapon = get_weaponid(pAttacker);
|
||||
|
||||
aim = pAttacker->aiming;
|
||||
|
||||
if ( weaponData[weapon].melee )
|
||||
pAttacker->saveShot(weapon);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_grenades.find(enemy , &pAttacker , weapon);
|
||||
}
|
||||
|
||||
if (iClip > -1) {
|
||||
if ( mPlayer->current == 17 )
|
||||
{
|
||||
if ( iClip+2 == mPlayer->weapons[iId].clip)
|
||||
mPlayer->saveShot(iId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iClip+1 == mPlayer->weapons[iId].clip)
|
||||
mPlayer->saveShot(iId);
|
||||
}
|
||||
int TA = 0;
|
||||
|
||||
if ( !pAttacker )
|
||||
{
|
||||
pAttacker = mPlayer;
|
||||
}
|
||||
|
||||
if ( pAttacker->index != mPlayer->index )
|
||||
{
|
||||
pAttacker->saveHit( mPlayer , weapon , damage, aim );
|
||||
|
||||
if ( mPlayer->pEdict->v.team == pAttacker->pEdict->v.team )
|
||||
TA = 1;
|
||||
}
|
||||
|
||||
MF_ExecuteForward( iFDamage, pAttacker->index, mPlayer->index, damage, weapon, aim, TA );
|
||||
|
||||
if ( !mPlayer->IsAlive() )
|
||||
{
|
||||
pAttacker->saveKill(mPlayer,weapon,( aim == 1 ) ? 1:0 ,TA);
|
||||
MF_ExecuteForward( iFDeath, pAttacker->index, mPlayer->index, weapon, aim, TA );
|
||||
}
|
||||
mPlayer->weapons[iId].clip = iClip;
|
||||
}
|
||||
}
|
||||
|
||||
void Client_AmmoX(void* mValue)
|
||||
|
@ -170,135 +252,97 @@ void Client_AmmoShort(void* mValue)
|
|||
case 0:
|
||||
iAmmo = *(int*)mValue;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (!mPlayer ) break;
|
||||
if(!mPlayer )
|
||||
break;
|
||||
|
||||
for(int i = 1; i < MAX_WEAPONS ; ++i)
|
||||
{
|
||||
if (iAmmo == weaponData[i].ammoSlot)
|
||||
mPlayer->weapons[i].ammo = *(int*)mValue;
|
||||
mPlayer->weapons[i].ammo = *(int*)mValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client_Health_End(void* mValue)
|
||||
// Called with a value of 90 at start 20 when someone scopes in and 0 when they scope out
|
||||
void Client_SetFOV(void* mValue)
|
||||
{
|
||||
if ( !isModuleActive() )
|
||||
if(!mPlayer)
|
||||
return;
|
||||
|
||||
CPlayer* pVictim = mPlayer;
|
||||
mPlayer->Scoping(*(int*)mValue);
|
||||
}
|
||||
|
||||
edict_t *enemy = pVictim->pEdict->v.dmg_inflictor;
|
||||
int damage = (int)pVictim->pEdict->v.dmg_take;
|
||||
|
||||
if(!pVictim || !damage || !enemy)
|
||||
void Client_SetFOV_End(void* mValue)
|
||||
{
|
||||
if(!mPlayer)
|
||||
return;
|
||||
|
||||
int weapon = 0;
|
||||
int aim = 0;
|
||||
mPlayer->ScopingCheck();
|
||||
}
|
||||
|
||||
pVictim->pEdict->v.dmg_take = 0.0;
|
||||
void Client_Object(void* mValue)
|
||||
{
|
||||
if(!mPlayer)
|
||||
return;
|
||||
|
||||
CPlayer* pAttacker = NULL;
|
||||
// First need to find out what was picked up
|
||||
const char *classname;
|
||||
edict_t* pObject = NULL;
|
||||
|
||||
if(enemy->v.flags & (FL_CLIENT | FL_FAKECLIENT))
|
||||
const char* value;
|
||||
|
||||
if(mValue)
|
||||
{
|
||||
pAttacker = GET_PLAYER_POINTER(enemy);
|
||||
weapon = pAttacker->current;
|
||||
value = (char*)mValue;
|
||||
}
|
||||
|
||||
if(weaponData[weapon].needcheck)
|
||||
weapon = get_weaponid(pAttacker);
|
||||
if(!mPlayer->object.carrying)
|
||||
{
|
||||
// We grab the first object within the sphere of our player
|
||||
pObject = FindEntityInSphere(mPlayer->pEdict, mPlayer->pEdict, 50.0);
|
||||
|
||||
aim = pAttacker->aiming;
|
||||
// The loop through all the objects within the sphere
|
||||
while(pObject && !FNullEnt(pObject))
|
||||
{
|
||||
classname = STRING(pObject->v.classname);
|
||||
|
||||
if(weaponData[weapon].melee)
|
||||
pAttacker->saveShot(weapon);
|
||||
if(strcmp(classname, "dod_object") == 0)
|
||||
{
|
||||
mPlayer->object.pEdict = pObject;
|
||||
mPlayer->object.do_forward = true;
|
||||
return;
|
||||
}
|
||||
|
||||
pObject = FindEntityInSphere(pObject, mPlayer->pEdict, 50.0);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
g_grenades.find(enemy , &pAttacker , weapon);
|
||||
|
||||
int TA = 0;
|
||||
|
||||
if(!pAttacker)
|
||||
{
|
||||
pAttacker = pVictim;
|
||||
}
|
||||
|
||||
if(pAttacker->index != pVictim->index)
|
||||
{
|
||||
pAttacker->saveHit(pVictim , weapon , damage, aim);
|
||||
|
||||
if(pVictim->pEdict->v.team == pAttacker->pEdict->v.team)
|
||||
TA = 1;
|
||||
}
|
||||
|
||||
MF_ExecuteForward(iFDamage, pAttacker->index, pVictim->index, damage, weapon, aim, TA);
|
||||
|
||||
if(!pVictim->IsAlive())
|
||||
{
|
||||
pAttacker->saveKill(pVictim, weapon, (aim == 1) ? 1:0 , TA);
|
||||
MF_ExecuteForward(iFDeath, pAttacker->index, pVictim->index, weapon, aim, TA);
|
||||
mPlayer->object.do_forward = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Working on being able to modify and switch weapons as they are sent to the client
|
||||
|
||||
void WeaponList(void* value)
|
||||
void Client_Object_End(void* mValue)
|
||||
{
|
||||
if(!mPlayer)
|
||||
return;
|
||||
|
||||
if(!mPlayer->ingame || ignoreBots(mPlayer->pEdict))
|
||||
return;
|
||||
float fposition[3];
|
||||
|
||||
switch(mPlayer->position)
|
||||
if(mPlayer->object.do_forward)
|
||||
{
|
||||
case 0: MF_Log("pszName = %s", value); break; // string weapon name
|
||||
case 1: MF_Log("pszAmmo1 = %d", (int)value); break; // byte Ammo Type
|
||||
case 2: MF_Log("iMaxAmmo1 = %d", (int)value); break; // byte Max Ammo 1
|
||||
case 3: MF_Log("pszAmmo2 = %d", (int)value); break; // byte Ammo2 Type
|
||||
case 4: MF_Log("iMaxAmmo2 = %d", (int)value); break; // byte Max Ammo 2
|
||||
case 5: MF_Log("iSlot = %d", (int)value); break; // byte bucket
|
||||
case 6: MF_Log("iPosition = %d", (int)value); break; // byte bucket pos
|
||||
case 7: MF_Log("iId = %d", (int)value); break; // byte id (bit index into pev->weapons)
|
||||
case 8: MF_Log("iFlags = %d", (int)value); break; // byte Flags
|
||||
};
|
||||
mPlayer->object.do_forward = (mPlayer->object.do_forward) ? false : true;
|
||||
mPlayer->object.carrying = (mPlayer->object.carrying) ? false : true;
|
||||
|
||||
mPlayer->position++;
|
||||
mPlayer->object.pEdict->v.origin.CopyToArray(fposition);
|
||||
cell position[3] = {fposition[0], fposition[1], fposition[2]};
|
||||
cell pos = MF_PrepareCellArray(position, 3);
|
||||
MF_ExecuteForward(iFObjectTouched, mPlayer->index, ENTINDEX(mPlayer->object.pEdict), pos, mPlayer->object.carrying);
|
||||
|
||||
if(!mPlayer->object.carrying)
|
||||
mPlayer->object.pEdict = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void WeaponList_End(void* mValue)
|
||||
{
|
||||
if(!mPlayer)
|
||||
return;
|
||||
|
||||
MF_Log("Done with %d", mPlayer->position);
|
||||
mPlayer->position = 0;
|
||||
}
|
||||
|
||||
struct weapon_info_s
|
||||
{
|
||||
char *pszName; // string weapon name
|
||||
int pszAmmo1; // byte Ammo Type
|
||||
int iMaxAmmo1; // byte Max Ammo 1
|
||||
int pszAmmo2; // byte Ammo2 Type
|
||||
int iMaxAmmo2; // byte Max Ammo 2
|
||||
int iSlot; // byte bucket
|
||||
int iPosition; // byte bucket pos
|
||||
int iId; // byte id (bit index into pev->weapons)
|
||||
int iFlags; // byte Flags
|
||||
}weapon_info_t;
|
||||
|
||||
MESSAGE_BEGIN( MSG_ONE, gmsgWeaponList, NULL, pev );
|
||||
WRITE_STRING(pszName); // string weapon name
|
||||
WRITE_BYTE(GetAmmoIndex(II.pszAmmo1)); // byte Ammo Type
|
||||
WRITE_BYTE(II.iMaxAmmo1); // byte Max Ammo 1
|
||||
WRITE_BYTE(GetAmmoIndex(II.pszAmmo2)); // byte Ammo2 Type
|
||||
WRITE_BYTE(II.iMaxAmmo2); // byte Max Ammo 2
|
||||
WRITE_BYTE(II.iSlot); // byte bucket
|
||||
WRITE_BYTE(II.iPosition); // byte bucket pos
|
||||
WRITE_BYTE(II.iId); // byte id (bit index into pev->weapons)
|
||||
WRITE_BYTE(II.iFlags); // byte Flags
|
||||
MESSAGE_END();
|
||||
*/
|
||||
|
|
413
dlls/hamsandwich/CString.h
Normal file
413
dlls/hamsandwich/CString.h
Normal file
|
@ -0,0 +1,413 @@
|
|||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _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>=0; 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
|
491
dlls/hamsandwich/CVector.h
Normal file
491
dlls/hamsandwich/CVector.h
Normal file
|
@ -0,0 +1,491 @@
|
|||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef __CVECTOR_H__
|
||||
#define __CVECTOR_H__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Vector
|
||||
template <class T> class CVector
|
||||
{
|
||||
bool Grow()
|
||||
{
|
||||
// automatic grow
|
||||
size_t newSize = m_Size * 2;
|
||||
if (newSize == 0)
|
||||
newSize = 8; // a good init value
|
||||
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()
|
||||
{
|
||||
if (m_CurrentUsedSize >= m_Size)
|
||||
return Grow();
|
||||
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)
|
||||
{
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data[m_CurrentUsedSize - 1] = 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();
|
||||
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
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__
|
||||
|
161
dlls/hamsandwich/FileParser.cpp
Normal file
161
dlls/hamsandwich/FileParser.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "FileParser.h"
|
||||
|
||||
#define FP_MAX_LENGTH 2048
|
||||
|
||||
|
||||
/**
|
||||
* Given a string, this will remove whitespace at the beginning and end, and remove comments.
|
||||
*
|
||||
* @param data The string to format. It changes this data directly.
|
||||
* @return Returns a pointer to the end of the newly formated string.
|
||||
*/
|
||||
static char *FP_FormatLine(char *data)
|
||||
{
|
||||
char *End; /**< Pointer to the end of the string. */
|
||||
char *Start; /**< Pointer to the start of the string. */
|
||||
char *Temp=Start; /**< Temporary pointer for parsing. */
|
||||
|
||||
Start=data;
|
||||
|
||||
// Strip beginning whitespace
|
||||
while (*Start==' ' || *Start=='\t') Start++;
|
||||
|
||||
// if the beginning non-whitespace character is a ';', then it's a comment
|
||||
// ignore the rest of the file
|
||||
if (*Start==';')
|
||||
{
|
||||
// just set data[0] to \0 and return out of here.
|
||||
*data='\0';
|
||||
return data;
|
||||
}
|
||||
|
||||
// now strip comments from the end of a line
|
||||
Temp=Start;
|
||||
|
||||
End=Start+(strlen(Start)-1);
|
||||
|
||||
|
||||
while (Temp<=End)
|
||||
{
|
||||
if (*Temp==';')
|
||||
{
|
||||
*Temp='\0';
|
||||
break;
|
||||
}
|
||||
++Temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// now go to the end of the line, and remove whitespace
|
||||
|
||||
while ( (*End=='\n' ||
|
||||
*End=='\r' ||
|
||||
*End==' ' ||
|
||||
*End=='\t') &&
|
||||
End>=Start)
|
||||
{
|
||||
End--;
|
||||
}
|
||||
++End;
|
||||
*End='\0';
|
||||
|
||||
// if Start==data, we're done
|
||||
if (Start==data)
|
||||
{
|
||||
return End;
|
||||
}
|
||||
|
||||
// otherwise, copy from Start to data
|
||||
|
||||
while ((*data++=*Start++)!='\0')/*do nothing*/;
|
||||
|
||||
return End;
|
||||
};
|
||||
|
||||
static const char* get_localinfo( const char* name , const char* def = 0 )
|
||||
{
|
||||
const char* b = LOCALINFO( (char*)name );
|
||||
if (((b==0)||(*b==0)) && def )
|
||||
SET_LOCALINFO((char*)name,(char*)(b = def) );
|
||||
return b;
|
||||
}
|
||||
/**
|
||||
* Reads the config file and parses keys.
|
||||
*
|
||||
* @param Category The category (prefix) to look for. Eg.: "cs_linux_", "dod_windows_"
|
||||
* @param Feedback The function to call when a match is made.
|
||||
* @noreturn
|
||||
*/
|
||||
void FP_SetupOffsets(const char *Category, FP_ptrFeedback Feedback)
|
||||
{
|
||||
char FileName[512];
|
||||
|
||||
size_t CatLen=strlen(Category);
|
||||
|
||||
MF_BuildPathnameR(FileName,sizeof(FileName)-1,"%s",get_localinfo("amxx_configsdir","addons/amxmodx/configs"));
|
||||
|
||||
strncat(FileName,"/hamdata.ini",sizeof(FileName)-1);
|
||||
|
||||
FILE *fp=fopen(FileName,"r");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
MF_Log("Unable to open \"%s\" for reading",FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
char Data[FP_MAX_LENGTH + 1];
|
||||
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
|
||||
Data[0]='\0';
|
||||
|
||||
fgets(Data,FP_MAX_LENGTH,fp);
|
||||
|
||||
FP_FormatLine(Data);
|
||||
|
||||
if (strncmp(Data,Category,CatLen)==0)
|
||||
{
|
||||
// Find the first space, set it to NULL
|
||||
char *Param=&Data[0];
|
||||
|
||||
while (*Param!=' ' && *Param!='\t' && *Param!='\0')
|
||||
{
|
||||
++Param;
|
||||
}
|
||||
if (*Param=='\0')
|
||||
{
|
||||
// special instance; if this is NULL get out of here
|
||||
continue;
|
||||
}
|
||||
|
||||
// NULL this space, and then find the first non whitespace character and
|
||||
// use that as the parameter field in the callback
|
||||
*Param++='\0';
|
||||
while (*Param==' ' || *Param=='\t')
|
||||
{
|
||||
++Param;
|
||||
}
|
||||
|
||||
if (*Param=='\0')
|
||||
{
|
||||
// special instance; if this is NULL get out of here
|
||||
continue;
|
||||
}
|
||||
Feedback(&Data[0],Param);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fclose(fp);
|
||||
}
|
6
dlls/hamsandwich/FileParser.h
Normal file
6
dlls/hamsandwich/FileParser.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef FILEPARSER_H
|
||||
#define FILEPARSER_H
|
||||
|
||||
typedef bool (*FP_ptrFeedback)(const char *key, const char *value);
|
||||
|
||||
#endif // FILEPARSER_H
|
110
dlls/hamsandwich/Makefile
Normal file
110
dlls/hamsandwich/Makefile
Normal file
|
@ -0,0 +1,110 @@
|
|||
#(C)2004-2005 AMX Mod X Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
HLSDK = ../../../hlsdk
|
||||
MM_ROOT = ../../../metamod/metamod
|
||||
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
|
||||
CRAZY_OPT_FLAGS = -DCRAZY_OPTS -O3 -funroll-loops -ffast-math -s -pipe -fomit-frame-pointer -fno-strict-aliasing -DNDEBUG -fmerge-all-constants -fmodulo-sched -fgcse-sm -fgcse-las -fgcse-after-reload -floop-optimize2 -funsafe-loop-optimizations -ftree-loop-linear -ftree-loop-im -ftree-loop-ivcanon -fivopts -ftree-vectorize -fvariable-expansion-in-unroller -funsafe-math-optimizations -ffinite-math-only -fpeel-loops -funswitch-loops -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -Wall -Wno-unknown-pragmas -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Wsign-compare -Wmissing-noreturn -Winline -Wlong-long -Wunsafe-loop-optimizations -Wctor-dtor-privacy -Wno-non-virtual-dtor -Wreorder -Woverloaded-virtual -Wsign-promo -Wsynth -shared
|
||||
|
||||
CRAZY_LINK_FLAGS = -fwhole-program
|
||||
#-fwhole-program -combine
|
||||
|
||||
SANE_OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer -fno-strict-aliasing -DNDEBUG
|
||||
|
||||
OPT_FLAGS =
|
||||
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc-4.1
|
||||
#CPP = gcc-2.95
|
||||
NAME = hamsandwich
|
||||
|
||||
BIN_SUFFIX = amxx_i386.so
|
||||
|
||||
OBJECTS = sdk/amxxmodule.cpp FileParser.cpp amxxapi.cpp hooks.cpp \
|
||||
tableentries/VTableManager.cpp tableentries/TakeDamage.cpp tableentries/Use.cpp \
|
||||
tableentries/Blocked.cpp
|
||||
|
||||
|
||||
#natives.cpp vtable.cpp
|
||||
|
||||
#tableentries/VTableUse.cpp tableentries/VTableTakedamage.cpp
|
||||
|
||||
|
||||
#natives/cs.cpp natives/dod.cpp natives/tfc.cpp \
|
||||
#natives/ns.cpp natives/ts.cpp natives/sven.cpp \
|
||||
#FileParser.cpp
|
||||
|
||||
LINK =
|
||||
|
||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
||||
-I$(MM_ROOT) -I$(HLSDK)/common -I$(HLSDK)/pm_shared -I./tableentries
|
||||
|
||||
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS = $(DEBUG_FLAGS)
|
||||
else
|
||||
ifeq "$(CRAZY)" "true"
|
||||
BIN_DIR = Optimized
|
||||
OPT_FLAGS = $(CRAZY_OPT_FLAGS)
|
||||
LINK = $(CRAZY_LINK_FLAGS)
|
||||
else
|
||||
BIN_DIR = Release
|
||||
OPT_FLAGS = $(SANE_OPT_FLAGS)
|
||||
endif
|
||||
ifeq "$(GCC_VERSION)" "4"
|
||||
OPT_FLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
endif
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS += -fPIC -Wall -Wno-non-virtual-dtor -fno-exceptions -DHAVE_STDINT_H -fno-rtti
|
||||
|
||||
BINARY = $(NAME)_$(BIN_SUFFIX)
|
||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
||||
OPT_FLAGS += -march=i586
|
||||
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
mkdir -p $(BIN_DIR)/sdk
|
||||
mkdir -p $(BIN_DIR)/natives
|
||||
mkdir -p $(BIN_DIR)/tableentries
|
||||
$(MAKE) hamsandwich
|
||||
|
||||
hamsandwich: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
|
||||
debug:
|
||||
$(MAKE) all DEBUG=true
|
||||
|
||||
default: all
|
||||
|
||||
crazy:
|
||||
$(MAKE) all CRAZY=true
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/sdk/*.o
|
||||
rm -rf Release/natives/*.o
|
||||
rm -rf Release/tableentries/*.o
|
||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/sdk/*.o
|
||||
rm -rf Debug/natives/*.o
|
||||
rm -rf Debug/tableentries/*.o
|
||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX)
|
||||
rm -rf Optimized/*.o
|
||||
rm -rf Optimized/sdk/*.o
|
||||
rm -rf Optimized/natives/*.o
|
||||
rm -rf Optimized/tableentries/*.o
|
||||
rm -rf Optimized/$(NAME)_$(BIN_SUFFIX)
|
||||
|
90
dlls/hamsandwich/NEW_Util.h
Normal file
90
dlls/hamsandwich/NEW_Util.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* Ham Sandwich
|
||||
*
|
||||
* by sawce
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
/* Inlined replacements for INDEXENT/ENTINDEX
|
||||
* It only really removes the overhead of the push/jump
|
||||
* but since INDEXENT/ENTINDEX are used a lot with amxx
|
||||
* it might be beneficial to include.
|
||||
* NOTE: Bad stuff will happen if you call these before
|
||||
* NEW_Initialize()
|
||||
* NOTE: No bounds checking is done because natives
|
||||
* should use their own bounds checking!
|
||||
*/
|
||||
|
||||
#ifndef NEW_UTIL_H
|
||||
#define NEW_UTIL_H
|
||||
|
||||
|
||||
extern edict_t *NEW_FirstEdict;
|
||||
extern bool NEW_Initialized;
|
||||
|
||||
/**
|
||||
* This is called on the first Spawn() ever hooked. This would be worldspawn (index 0)
|
||||
*/
|
||||
inline void NEW_Initialize(edict_t *Entity)
|
||||
{
|
||||
// This is not worldspawn?
|
||||
// compensate
|
||||
NEW_FirstEdict=Entity;
|
||||
NEW_Initialized=true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an integer index into an edict pointer
|
||||
*/
|
||||
inline edict_t *INDEXENT_NEW(const int Index)
|
||||
{
|
||||
return (edict_t *)(NEW_FirstEdict + Index);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts an edict pointer into an integer index
|
||||
*/
|
||||
inline int ENTINDEX_NEW(const edict_t *Ent)
|
||||
{
|
||||
return (int)(Ent - NEW_FirstEdict);
|
||||
};
|
||||
|
||||
// Inlined replacement of MF_GetAmxAddr
|
||||
|
||||
|
||||
inline REAL amx_ctof2(cell x)
|
||||
{
|
||||
return *(REAL*)&x;
|
||||
}
|
||||
inline cell amx_ftoc2(REAL x)
|
||||
{
|
||||
return *(cell*)&x;
|
||||
}
|
||||
|
||||
|
||||
#endif // NEW_UTIL_H
|
||||
|
624
dlls/hamsandwich/Trampolines.h
Normal file
624
dlls/hamsandwich/Trampolines.h
Normal file
|
@ -0,0 +1,624 @@
|
|||
/* Trampolines
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TRAMPOLINES_H
|
||||
#define TRAMPOLINES_H
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define TPRINT(msg) printf msg
|
||||
#else
|
||||
#define TPRINT(msg) /* nothing */
|
||||
#endif
|
||||
|
||||
#if defined _WIN32
|
||||
#include <windows.h>
|
||||
#elif defined __linux__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include <stddef.h> // size_t
|
||||
#include <string.h> // memcpy
|
||||
|
||||
|
||||
namespace Trampolines
|
||||
{
|
||||
|
||||
/**
|
||||
* List of x86 bytecodes for creating
|
||||
* basic trampolines at runtime.
|
||||
* -
|
||||
* These are defined here so that, should
|
||||
* the need ever arise, this can be ported
|
||||
* to other architectures fairly painlessly
|
||||
*/
|
||||
namespace Bytecode
|
||||
{
|
||||
/**
|
||||
* Prologue for a void function
|
||||
* Clobbers EBX and EAX
|
||||
*/
|
||||
const unsigned char codeVoidPrologue[] = {
|
||||
0x55, // push ebp
|
||||
0x89, 0xE5, // mov ebp, esp
|
||||
0x50, // push eax
|
||||
};
|
||||
|
||||
/**
|
||||
* Prologue for a function that returns
|
||||
* Clobbers EBX, EAX too but not after call
|
||||
*/
|
||||
const unsigned char codeReturnPrologue[] = {
|
||||
0x55, // push ebp
|
||||
0x89, 0xE5, // mov ebp, esp
|
||||
};
|
||||
const unsigned char codeThisReturnPrologue[] = {
|
||||
0x55, // push ebp
|
||||
0x89, 0xE5, // mov ebp, esp
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes a paramter from the trampoline's stack
|
||||
* and pushes it onto the target's stack.
|
||||
*/
|
||||
const unsigned char codePushParam[] = {
|
||||
0xFF, 0x75, 0xFF // pushl [ebp+0xFF]
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset of codePushParam to modify at runtime
|
||||
* that contains the stack offset
|
||||
*/
|
||||
const unsigned int codePushParamReplace = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Takes the "this" pointer from the trampoline and
|
||||
* pushes it onto the target's stack.
|
||||
*/
|
||||
const unsigned char codePushThis[] = {
|
||||
#if defined _WIN32
|
||||
0x51 // push ecx
|
||||
#elif defined __linux__
|
||||
0xFF, 0x75, 0x04 // pushl [ebp+0x08h]
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined __linux__
|
||||
const int codePushThisReplace = 2;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Pushes a raw number onto the target's stack
|
||||
*/
|
||||
const unsigned char codePushID[] = {
|
||||
0x68, 0xDE, 0xFA, 0xAD, 0xDE // push DEADFADEh
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset of codePushID to modify at runtime
|
||||
* to contain the number to push
|
||||
*/
|
||||
const unsigned int codePushIDReplace = 1;
|
||||
|
||||
/**
|
||||
* Call our procedure
|
||||
*/
|
||||
const unsigned char codeCall[] = {
|
||||
0xB8, 0xDE, 0xFA, 0xAD, 0xDE,// mov eax, DEADFADEh
|
||||
0xFF, 0xD0 // call eax
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset of codeCall to modify at runtime
|
||||
* to contain the pointer to the function
|
||||
*/
|
||||
const unsigned int codeCallReplace = 1;
|
||||
|
||||
/**
|
||||
* Adds to ESP, freeing up stack space
|
||||
*/
|
||||
const unsigned char codeFreeStack[] = {
|
||||
0x81, 0xC4, 0xFF, 0xFF, 0xFF, 0xFF// add esp REPLACEME
|
||||
};
|
||||
|
||||
/**
|
||||
* Offset of codeFreeStack to modify at runtime
|
||||
* to contain how much data to free
|
||||
*/
|
||||
const unsigned int codeFreeStackReplace = 2;
|
||||
|
||||
/**
|
||||
* Epilogue of a simple return function
|
||||
*/
|
||||
const unsigned char codeReturnEpilogue[] = {
|
||||
0x5D, // pop ebp
|
||||
0xC3 // ret
|
||||
};
|
||||
const unsigned char codeReturnEpilogueN[] = {
|
||||
0x5D, // pop ebp
|
||||
0xC2, 0xCD, 0xAB // retn 0xABCD
|
||||
};
|
||||
const int codeReturnEpilogueNReplace = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Epilogue of a void return function
|
||||
*/
|
||||
const unsigned char codeVoidEpilogue[] = {
|
||||
0x58, // pop eax
|
||||
0x5D, // pop ebp
|
||||
0xC3 // ret
|
||||
};
|
||||
|
||||
const unsigned char codeVoidEpilogueN[] = {
|
||||
0x58, // pop eax
|
||||
0x5D, // pop ebp
|
||||
0xC2, 0xCD, 0xAB // retn 0xABCD
|
||||
};
|
||||
const int codeVoidEpilogueNReplace = 3;
|
||||
|
||||
|
||||
|
||||
const unsigned char codeBreakpoint[] = {
|
||||
0xCC // int 3
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Our actual maker of the trampolines!!@$
|
||||
* I've no idea why I made this a class and not a namespace
|
||||
* Oh well!
|
||||
*/
|
||||
|
||||
class TrampolineMaker
|
||||
{
|
||||
private:
|
||||
unsigned char *m_buffer; // the actual buffer containing the code
|
||||
int m_size; // size of the buffer
|
||||
int m_mystack; // stack for the trampoline itself
|
||||
int m_calledstack; // stack for the target function
|
||||
int m_paramstart;
|
||||
int m_thiscall;
|
||||
|
||||
/**
|
||||
* Adds data to the buffer
|
||||
* data must be pre-formatted before hand!
|
||||
*/
|
||||
void Append(const unsigned char *src, size_t size)
|
||||
{
|
||||
int orig=m_size;
|
||||
m_size+=size;
|
||||
|
||||
if (m_buffer==NULL)
|
||||
{
|
||||
m_buffer=(unsigned char *)malloc(m_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer=(unsigned char *)realloc(m_buffer,m_size);
|
||||
}
|
||||
|
||||
unsigned char *dat=m_buffer+orig; // point dat to the end of the prewritten
|
||||
|
||||
while (orig<m_size)
|
||||
{
|
||||
*dat++=*src++;
|
||||
|
||||
orig++;
|
||||
};
|
||||
|
||||
};
|
||||
public:
|
||||
TrampolineMaker()
|
||||
{
|
||||
m_buffer=NULL;
|
||||
m_size=0;
|
||||
m_mystack=0;
|
||||
m_calledstack=0;
|
||||
m_paramstart=0;
|
||||
m_thiscall=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inserts a breakpoint (int 3) into the trampoline.
|
||||
*/
|
||||
void Breakpoint()
|
||||
{
|
||||
Append(&::Trampolines::Bytecode::codeBreakpoint[0],sizeof(::Trampolines::Bytecode::codeBreakpoint));
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the "return prologue", pushes registers and prepares stack
|
||||
*/
|
||||
void ReturnPrologue()
|
||||
{
|
||||
Append(&::Trampolines::Bytecode::codeReturnPrologue[0],sizeof(::Trampolines::Bytecode::codeReturnPrologue));
|
||||
m_paramstart=0;
|
||||
m_thiscall=0;
|
||||
};
|
||||
void ThisReturnPrologue()
|
||||
{
|
||||
this->ReturnPrologue();
|
||||
m_thiscall=1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the void prologue pushes registers, prepares the stack
|
||||
*/
|
||||
void VoidPrologue()
|
||||
{
|
||||
Append(&::Trampolines::Bytecode::codeVoidPrologue[0],sizeof(::Trampolines::Bytecode::codeVoidPrologue));
|
||||
m_paramstart=0;
|
||||
m_thiscall=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Flags this trampoline as a thiscall trampoline, and prepares the void prologue.
|
||||
*/
|
||||
void ThisVoidPrologue()
|
||||
{
|
||||
this->VoidPrologue();
|
||||
m_thiscall=1;
|
||||
};
|
||||
/**
|
||||
* Epilogue for a returning function pops registers but does not free any more of the stack!
|
||||
*/
|
||||
void ReturnEpilogue()
|
||||
{
|
||||
Append(&::Trampolines::Bytecode::codeReturnEpilogue[0],sizeof(::Trampolines::Bytecode::codeReturnEpilogue));
|
||||
};
|
||||
|
||||
/**
|
||||
* Epilogue that also frees it's estimated stack usage. Useful for stdcall/thiscall/fastcall.
|
||||
*/
|
||||
void ReturnEpilogueAndFree()
|
||||
{
|
||||
printf("Freeing %d bytes\n",m_mystack);
|
||||
this->ReturnEpilogue(m_mystack);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return epilogue. Pops registers, and frees given amount of data from the stack.
|
||||
*
|
||||
* @param howmuch How many bytes to free from the stack.
|
||||
*/
|
||||
void ReturnEpilogue(int howmuch)
|
||||
{
|
||||
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codeReturnEpilogueN)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codeReturnEpilogueN[0],sizeof(::Trampolines::Bytecode::codeReturnEpilogueN));
|
||||
|
||||
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
union
|
||||
{
|
||||
int i;
|
||||
unsigned char b[4];
|
||||
} bi;
|
||||
|
||||
bi.i=howmuch;
|
||||
|
||||
c+=::Trampolines::Bytecode::codeReturnEpilogueNReplace;
|
||||
*c++=bi.b[0];
|
||||
*c++=bi.b[1];
|
||||
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codeReturnEpilogueN));
|
||||
//Append(&::Trampolines::Bytecode::codeReturnEpilogueN[0],sizeof(::Trampolines::Bytecode::codeReturnEpilogueN));
|
||||
};
|
||||
|
||||
/**
|
||||
* Void epilogue, pops registers and frees the estimated stack usage of the trampoline.
|
||||
*/
|
||||
void VoidEpilogueAndFree()
|
||||
{
|
||||
printf("Freeing %d bytes\n",m_mystack);
|
||||
this->VoidEpilogue(m_mystack);
|
||||
};
|
||||
/**
|
||||
* Void epilogue, pops registers, nothing else done with stack.
|
||||
*/
|
||||
void VoidEpilogue()
|
||||
{
|
||||
Append(&::Trampolines::Bytecode::codeVoidEpilogue[0],sizeof(::Trampolines::Bytecode::codeVoidEpilogue));
|
||||
};
|
||||
/**
|
||||
* Void epilogue, pops registers, frees given amount of data off of the stack.
|
||||
*
|
||||
* @param howmuch How many bytes to free from the stack.
|
||||
*/
|
||||
void VoidEpilogue(int howmuch)
|
||||
{
|
||||
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codeVoidEpilogueN)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codeVoidEpilogueN[0],sizeof(::Trampolines::Bytecode::codeVoidEpilogueN));
|
||||
|
||||
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
union
|
||||
{
|
||||
int i;
|
||||
unsigned char b[4];
|
||||
} bi;
|
||||
|
||||
bi.i=howmuch;
|
||||
|
||||
c+=::Trampolines::Bytecode::codeVoidEpilogueNReplace;
|
||||
*c++=bi.b[0];
|
||||
*c++=bi.b[1];
|
||||
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codeVoidEpilogueN));
|
||||
Append(&::Trampolines::Bytecode::codeVoidEpilogueN[0],sizeof(::Trampolines::Bytecode::codeVoidEpilogueN));
|
||||
};
|
||||
|
||||
/**
|
||||
* Pushes the "this" pointer onto the callee stack. Pushes ECX for MSVC, and param0 on GCC.
|
||||
*/
|
||||
void PushThis()
|
||||
{
|
||||
|
||||
if (!m_thiscall)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codePushThis)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codePushThis[0],sizeof(::Trampolines::Bytecode::codePushThis));
|
||||
|
||||
|
||||
#if defined __linux__
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
union
|
||||
{
|
||||
int i;
|
||||
unsigned char b[4];
|
||||
} bi;
|
||||
|
||||
bi.i=m_paramstart+8;
|
||||
|
||||
c+=::Trampolines::Bytecode::codePushThisReplace;
|
||||
*c++=bi.b[0];
|
||||
#endif
|
||||
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codePushThis));
|
||||
|
||||
#if defined __linux__
|
||||
TPRINT(("mystack=%d+4\n",m_mystack));
|
||||
m_mystack+=4;
|
||||
#endif
|
||||
TPRINT(("calledstack=%d+4\n",m_calledstack));
|
||||
m_calledstack+=4;
|
||||
};
|
||||
|
||||
/**
|
||||
* Frees what is estimated as the stack usage of the trampoline.
|
||||
*/
|
||||
void FreeMyStack(void)
|
||||
{
|
||||
|
||||
TPRINT(("freeing mystack=%d+4\n",m_mystack));
|
||||
this->FreeStack(m_mystack);
|
||||
};
|
||||
|
||||
/**
|
||||
* Frees the estimated stack usage of the callee.
|
||||
*/
|
||||
void FreeTargetStack(void)
|
||||
{
|
||||
TPRINT(("freeing calledstack=%d+4\n",m_calledstack));
|
||||
this->FreeStack(m_calledstack);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Frees the estimated stack usage of the callee and the trampoline.
|
||||
*/
|
||||
void FreeBothStacks(void)
|
||||
{
|
||||
TPRINT(("freeing mystack=%d+4\n",m_mystack));
|
||||
TPRINT(("freeing calledstack=%d+4\n",m_calledstack));
|
||||
this->FreeStack(m_calledstack + m_mystack);
|
||||
};
|
||||
|
||||
/**
|
||||
* Frees a given amount of bytes from the stack.
|
||||
*
|
||||
* @param howmuch How many bytes to free.
|
||||
*/
|
||||
void FreeStack(int howmuch)
|
||||
{
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codeFreeStack)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codeFreeStack[0],sizeof(::Trampolines::Bytecode::codeFreeStack));
|
||||
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
union
|
||||
{
|
||||
int i;
|
||||
unsigned char b[4];
|
||||
} bi;
|
||||
|
||||
bi.i=howmuch;
|
||||
|
||||
c+=::Trampolines::Bytecode::codeFreeStackReplace;
|
||||
*c++=bi.b[0];
|
||||
*c++=bi.b[1];
|
||||
*c++=bi.b[2];
|
||||
*c++=bi.b[3];
|
||||
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codeFreeStack));
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Pushes a raw number onto the callee stack.
|
||||
*
|
||||
* @param Number The number to push onto the callee stack.
|
||||
*/
|
||||
void PushNum(int Number)
|
||||
{
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codePushID)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codePushID[0],sizeof(::Trampolines::Bytecode::codePushID));
|
||||
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
union
|
||||
{
|
||||
int i;
|
||||
unsigned char b[4];
|
||||
} bi;
|
||||
|
||||
bi.i=Number;
|
||||
|
||||
c+=::Trampolines::Bytecode::codePushIDReplace;
|
||||
*c++=bi.b[0];
|
||||
*c++=bi.b[1];
|
||||
*c++=bi.b[2];
|
||||
*c++=bi.b[3];
|
||||
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codePushID));
|
||||
|
||||
TPRINT(("calledstack=%d+4\n",m_calledstack));
|
||||
m_calledstack+=4; // increase auto detected stack size
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes a parameter passed on the trampoline's stack and inserts it into the callee's stack.
|
||||
*
|
||||
* @param which The parameter number to push. 1-based. "thiscall" trampolines automatically compensate for the off-number on GCC.
|
||||
*/
|
||||
void PushParam(int which)
|
||||
{
|
||||
#if defined __linux__
|
||||
if (m_thiscall)
|
||||
{
|
||||
which++;
|
||||
}
|
||||
#endif
|
||||
which=which*4;
|
||||
which+=m_paramstart+4;
|
||||
|
||||
unsigned char value=which;
|
||||
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codePushParam)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codePushParam[0],sizeof(::Trampolines::Bytecode::codePushParam));
|
||||
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
|
||||
c+=::Trampolines::Bytecode::codePushParamReplace;
|
||||
|
||||
*c=value;
|
||||
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codePushParam));
|
||||
|
||||
TPRINT(("calledstack=%d+4\n",m_calledstack));
|
||||
m_calledstack+=4; // increase auto detected stack size
|
||||
TPRINT(("mystack=%d+4\n",m_mystack));
|
||||
m_mystack+=4;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert a function to call into the trampoline.
|
||||
*
|
||||
* @param ptr The function to call, cast to void*.
|
||||
*/
|
||||
void Call(void *ptr)
|
||||
{
|
||||
unsigned char code[sizeof(::Trampolines::Bytecode::codeCall)];
|
||||
|
||||
memcpy(&code[0],&::Trampolines::Bytecode::codeCall[0],sizeof(::Trampolines::Bytecode::codeCall));
|
||||
|
||||
unsigned char *c=&code[0];
|
||||
|
||||
union
|
||||
{
|
||||
void *p;
|
||||
unsigned char b[4];
|
||||
} bp;
|
||||
|
||||
bp.p=ptr;
|
||||
|
||||
c+=::Trampolines::Bytecode::codeCallReplace;
|
||||
|
||||
*c++=bp.b[0];
|
||||
*c++=bp.b[1];
|
||||
*c++=bp.b[2];
|
||||
*c++=bp.b[3];
|
||||
Append(&code[0],sizeof(::Trampolines::Bytecode::codeCall));
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Finalizes the trampoline. Do not try to modify it after this.
|
||||
*
|
||||
* @param size A pointer to retrieve the size of the trampoline. Ignored if set to NULL.
|
||||
* @return The trampoline pointer, cast to void*.
|
||||
*/
|
||||
void *Finish(int *size)
|
||||
{
|
||||
void *ret=(void *)m_buffer;
|
||||
|
||||
if (size)
|
||||
{
|
||||
*size=m_size;
|
||||
}
|
||||
#if defined _WIN32
|
||||
DWORD OldFlags;
|
||||
VirtualProtect(ret,m_size,PAGE_EXECUTE_READWRITE,&OldFlags);
|
||||
#elif defined __linux__
|
||||
mprotect(ret,m_size,PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
|
||||
|
||||
m_size=0;
|
||||
m_buffer=NULL; // so we don't accidentally rewrite!
|
||||
m_mystack=0;
|
||||
m_calledstack=0;
|
||||
|
||||
return ret;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // TRAMPOLINEMANAGER_H
|
243
dlls/hamsandwich/amxxapi.cpp
Normal file
243
dlls/hamsandwich/amxxapi.cpp
Normal file
|
@ -0,0 +1,243 @@
|
|||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
* Description: AMX Mod X Module Interface hooks
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "hamsandwich.h"
|
||||
|
||||
#include "CVector.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "FileParser.h"
|
||||
|
||||
#include "NEW_Util.h"
|
||||
|
||||
#include "VTableManager.h"
|
||||
#include "VTableEntries.h"
|
||||
|
||||
CVector<String *> SuffixNames; /**< List of names being searched for in the config file. */
|
||||
CVector<void (*)(const char *, const char *)> SuffixFunctions; /**< Callback functions for when we find a hunted keyvalue. */
|
||||
CVector<void (*)(void)> ConfigDoneCallbacks; /**< Callbacks when our config file is done being parsed. */
|
||||
|
||||
edict_t *NEW_FirstEdict=NULL; /**< Used for the NEW_Utils INDEXENT/ENTINDEX replacements. */
|
||||
bool NEW_Initialized=false; /**< Whether NEW_Utils has been initialized yet. */
|
||||
|
||||
void FP_SetupOffsets(const char *name, FP_ptrFeedback feedback);
|
||||
|
||||
|
||||
unsigned int HAM_pev=0; /**< Offset of pev from the this pointer. */
|
||||
unsigned int HAM_pevset=0; /**< Whether or not the pev offset has been set. */
|
||||
unsigned int HAM_classbase=0; /**< Offset of the vtable from the this pointer. */
|
||||
unsigned int HAM_classbaseset=0; /**< Whether or not the classbase offset has been set. */
|
||||
|
||||
char ModKey[256]; /**< Temporary buffer for holding the <modname>_<os> prefix. */
|
||||
|
||||
/**
|
||||
* Adds a callback to the config parser for this config suffix.
|
||||
*
|
||||
* @param suffix The suffix to add, eg "takedamage" would be called for "cs_linux_takedamage"
|
||||
* @param callback The function to call when this key is found.
|
||||
* @noreturn
|
||||
*/
|
||||
void RegisterKeySuffix(const char *suffix, void (*callback)(const char *,const char *))
|
||||
{
|
||||
String *Suffix=new String(suffix);
|
||||
|
||||
|
||||
SuffixNames.push_back(Suffix);
|
||||
|
||||
SuffixFunctions.push_back(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds this entry to the configdone callback.
|
||||
*
|
||||
* @param callback Function to call when the config file is done being parsed.
|
||||
* @noreturn
|
||||
*/
|
||||
void RegisterConfigCallback(void (*callback)(void))
|
||||
{
|
||||
ConfigDoneCallbacks.push_back(callback);
|
||||
};
|
||||
/**
|
||||
* Starts each vtable entry. This needs to be edited for every additional hook.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
void HAM_CallInitialization(void)
|
||||
{
|
||||
#define VTINIT(TableName) VTable##TableName::Initialize(&HAM_pev,&HAM_pevset,&HAM_classbase,&HAM_classbaseset)
|
||||
|
||||
VTINIT(TakeDamage);
|
||||
VTINIT(Use);
|
||||
|
||||
#undef VTINIT
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells all the table entries that the config file is done being parsed. Register their natives now.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
void HAM_CallConfigDone(void)
|
||||
{
|
||||
int i=0; /**< Iterator. */
|
||||
int end=ConfigDoneCallbacks.size(); /**< How many to parse. */
|
||||
|
||||
while (i<end)
|
||||
{
|
||||
ConfigDoneCallbacks[i]();
|
||||
++i;
|
||||
}
|
||||
|
||||
// done with this, free up the vector
|
||||
ConfigDoneCallbacks.clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple wrapper to uniform string to number conversion. I don't just use -1 on strtol base because I don't want octal conversion.
|
||||
*
|
||||
* @param input The input string.
|
||||
* @return The input string converted to an unsigned integer.
|
||||
*/
|
||||
int HAM_StrToNum(const char *input)
|
||||
{
|
||||
char *end; /**< Temporary pointer, needed for strtoul(). */
|
||||
|
||||
// if begins with 0x or 0X it's to be interpretted as hex
|
||||
if (*input=='0' &&
|
||||
(*(input+1)=='x' || *(input+1)=='X'))
|
||||
{
|
||||
return strtoul(input,&end,16);
|
||||
}
|
||||
|
||||
// otherwise it's to be interpretted as base 10
|
||||
return strtoul(input,&end,10);
|
||||
}
|
||||
/**
|
||||
* This is called every time a key with the <mod>_<os>_ prefix is found.
|
||||
*
|
||||
* @param key The full key (eg: cs_windows_takedamage)
|
||||
* @param data The corresponding data.
|
||||
* @return true when key is used, false otherwise
|
||||
*/
|
||||
bool HAM_GetKey(const char *key, const char *data)
|
||||
{
|
||||
char TempKey[512]; /**< Temporary buffer. */
|
||||
int i=0; /**< Iterator. */
|
||||
int end=SuffixNames.size(); /**< How many suffixes to check. */
|
||||
bool found=false; /**< Whether this key has been used or not. */
|
||||
|
||||
while (i<end)
|
||||
{
|
||||
snprintf(TempKey,sizeof(TempKey)-1,"%s_%s",ModKey,SuffixNames[i]->c_str());
|
||||
if (strcmp(TempKey,key)==0)
|
||||
{
|
||||
SuffixFunctions[i](SuffixNames[i]->c_str(),data);
|
||||
found=true;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
/**
|
||||
* Simple function to set the "pev" field that is used by all forwards.
|
||||
*
|
||||
* @param key The key suffix being forwarded.
|
||||
* @param data The data corresponding to the key.
|
||||
* @noreturn
|
||||
*/
|
||||
void HAM_SetPev(const char *key, const char *data)
|
||||
{
|
||||
HAM_pev=HAM_StrToNum(data);
|
||||
HAM_pevset=1;
|
||||
}
|
||||
/**
|
||||
* Simple function to set the "classbase" field that is used by all natives when built with GCC.
|
||||
*
|
||||
* @param key The key suffix being forwarded.
|
||||
* @param data The data corresponding to the key.
|
||||
* @noreturn
|
||||
*/
|
||||
#if defined __linux__
|
||||
void HAM_SetClassBase(const char *key, const char *data)
|
||||
{
|
||||
HAM_classbase=HAM_StrToNum(data);
|
||||
HAM_classbaseset=1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
HAM_CallInitialization();
|
||||
#ifdef __linux__
|
||||
snprintf(ModKey,sizeof(ModKey)-1,"%s_linux",MF_GetModname());
|
||||
#else
|
||||
snprintf(ModKey,sizeof(ModKey)-1,"%s_windows",MF_GetModname());
|
||||
#endif
|
||||
|
||||
RegisterKeySuffix("pev",HAM_SetPev);
|
||||
|
||||
// this is only needed for Linux
|
||||
#if defined __linux__
|
||||
RegisterKeySuffix("classbase",HAM_SetClassBase);
|
||||
#else // Emulate it being set on Windows, since it's not needed
|
||||
HAM_classbase=0;
|
||||
HAM_classbaseset=1;
|
||||
#endif
|
||||
|
||||
FP_SetupOffsets(ModKey,HAM_GetKey);
|
||||
|
||||
HAM_CallConfigDone();
|
||||
|
||||
/* TODO: Cbase natives
|
||||
if (HAM_Set & HAM_GOT_PEV)
|
||||
{
|
||||
HAM_RegisterCbaseFast();
|
||||
}
|
||||
HAM_RegisterCbaseSafe();
|
||||
|
||||
VTH_Natives();
|
||||
*/
|
||||
}
|
||||
|
||||
void OnPluginsLoaded()
|
||||
{
|
||||
NEW_Initialize(INDEXENT(0));
|
||||
|
||||
};
|
||||
void OnPluginsUnloaded()
|
||||
{
|
||||
VTMan.Cleanup();
|
||||
};
|
109
dlls/hamsandwich/hamdata.ini
Normal file
109
dlls/hamsandwich/hamdata.ini
Normal file
|
@ -0,0 +1,109 @@
|
|||
; Ham Sandwich module config file
|
||||
; -
|
||||
; Do not modify this file unless you know exactly what you're doing!
|
||||
; -
|
||||
; entry syntax is as follows:
|
||||
; [modname]_[os]_key
|
||||
; Example: the "use" key on TS running Linux would be "ts_linux_use"
|
||||
; "modname" is the game directory, NOT the game description!
|
||||
; eg: "ts", not "The Specialists"
|
||||
; -
|
||||
; Keys support either hexadecimal (MUST prefix with 0x) or base 10
|
||||
; -
|
||||
; Key types:
|
||||
; * takedamage: this is the vtable index of the takedamage routine
|
||||
; * use: this is the vtable index of the use routine
|
||||
; * pev: this is the offset in bytes of the location of pev in the cbaseentity
|
||||
; * classbase: this is the size in bytes of the cbaseentity base class LINUX ONLY
|
||||
; NOTE: If the mod is compiled with GCC 3.3+ (NS is the only one
|
||||
; I know of), then the classbase will always be 0x0
|
||||
; -
|
||||
; NOTE: If a mod is missing keys for a certain native, that particular native
|
||||
; will not be loaded! Example: Say CS is missing the "takedamage" index
|
||||
; but has the use and pev indexes. The hs_use and hs_pdata_cbase natives
|
||||
; will be registered, but the hs_takedamage native will not be registered.
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 1.6 Steam (legitimate)
|
||||
cstrike_windows_takedamage 12
|
||||
cstrike_windows_use 46
|
||||
cstrike_windows_pev 4
|
||||
cstrike_linux_takedamage 14
|
||||
cstrike_linux_use 48
|
||||
cstrike_linux_pev 0
|
||||
cstrike_linux_classbase 0x94
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 1.6 Steam (legitimate)
|
||||
czero_windows_takedamage 12
|
||||
czero_windows_use 46
|
||||
czero_windows_pev 4
|
||||
czero_linux_takedamage 14
|
||||
czero_linux_use 48
|
||||
czero_linux_pev 0
|
||||
czero_linux_classbase 0x94
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 3.1
|
||||
ns_windows_takedamage 10
|
||||
ns_windows_use 48
|
||||
ns_windows_pev 4
|
||||
ns_linux_takedamage 11
|
||||
ns_linux_use 49
|
||||
ns_linux_pev 4
|
||||
ns_linux_classbase 0x0
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 3.2 beta 2
|
||||
nsp_windows_takedamage 10
|
||||
nsp_windows_use 48
|
||||
nsp_windows_pev 4
|
||||
nsp_linux_takedamage 11
|
||||
nsp_linux_use 49
|
||||
nsp_linux_pev 4
|
||||
nsp_linux_classbase 0x0
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 1.3 (?) Steam (legitimate)
|
||||
dod_windows_takedamage 18
|
||||
dod_windows_use 51
|
||||
dod_windows_pev 4
|
||||
dod_linux_takedamage 20
|
||||
dod_linux_use 51
|
||||
dod linux_pev 0
|
||||
dod_linux_classbase 0x154
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 2.1
|
||||
ts_windows_takedamage 14
|
||||
ts_windows_use 48
|
||||
ts_windows_pev 4
|
||||
ts_linux_takedamage 16
|
||||
ts_linux_use 50
|
||||
ts_linux_pev 0
|
||||
ts_linux_classbase 0x60
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: ?? (Most up to date) Steam (legitimate)
|
||||
tfc_windows_takedamage 12
|
||||
tfc_windows_use 44
|
||||
tfc_windows_pev 4
|
||||
tfc_linux_takedamage 14
|
||||
tfc_linux_use 46
|
||||
tfc_linux_pev 0
|
||||
tfc_linux_classbase 0x470
|
||||
|
||||
; Data dated: 2007-02-23
|
||||
; Version tested: 3.0
|
||||
; Sven-Coop does not have a Linux build
|
||||
svencoop_windows_takedamage 11
|
||||
svencoop_windows_use 46
|
||||
svencoop_windows_pev 4
|
||||
|
||||
; Data dated: 2007-02-26
|
||||
; Version tested: 2.18.07
|
||||
; Earth's Special Forces (I can't find the non beta version, but it should still work!
|
||||
; ESF does not have a Linux binary!
|
||||
esf_openbeta_windows_takedamage 12
|
||||
esf_openbeta_windows_use 46
|
||||
esf_openbeta_windows_pev 4
|
132
dlls/hamsandwich/hamsandwich.h
Normal file
132
dlls/hamsandwich/hamsandwich.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/* Ham Sandwich
|
||||
*
|
||||
* by sawce
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef HAMSANDWICH_H
|
||||
#define HAMSANDWICH_H
|
||||
|
||||
#include "NEW_Util.h"
|
||||
|
||||
extern unsigned int HAM_pev;
|
||||
extern unsigned int HAM_classbase;
|
||||
|
||||
|
||||
inline edict_t *PrivateToEdict(const void *pdata)
|
||||
{
|
||||
|
||||
if (!pdata)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ptr=(char*)pdata + HAM_pev;
|
||||
entvars_t *pev=(entvars_t *)ptr;
|
||||
|
||||
if (!pev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return pev->pContainingEntity;
|
||||
};
|
||||
|
||||
inline int PrivateToIndex(const void *pdata)
|
||||
{
|
||||
|
||||
if (pdata==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
char *ptr=(char*)pdata;
|
||||
|
||||
ptr+=HAM_pev;
|
||||
|
||||
entvars_t *pev=*(entvars_t **)ptr;
|
||||
|
||||
|
||||
if (pev==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pev->pContainingEntity==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(pev->pContainingEntity);
|
||||
};
|
||||
|
||||
inline int EntvarToIndex(entvars_t *pev)
|
||||
{
|
||||
if (pev==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pev->pContainingEntity==NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(pev->pContainingEntity);
|
||||
};
|
||||
|
||||
inline edict_t *EntvarToEdict(entvars_t *pev)
|
||||
{
|
||||
if (pev==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pev->pContainingEntity;
|
||||
};
|
||||
inline void **EdictToVTable(edict_t *ent)
|
||||
{
|
||||
char *btbl=(char *)ent->pvPrivateData;
|
||||
btbl+=HAM_classbase;
|
||||
return *((void ***)btbl);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void RegisterKeySuffix(const char *suffix, void (*callback)(const char *,const char *));
|
||||
void RegisterConfigCallback(void (*callback)(void));
|
||||
void HAM_CallConfigDone(void);
|
||||
void HAM_CallInitialization(void);
|
||||
int HAM_StrToNum(const char *input);
|
||||
bool HAM_GetKey(const char *key, const char *data);
|
||||
void HAM_SetPev(const char *key, const char *data);
|
||||
#ifdef __linux__
|
||||
void HAM_SetClassBase(const char *key, const char *data);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif //HAMSANDWICH_H
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sven", "sven.vcproj", "{29798873-02F2-4075-AFE7-58CE8F9B5124}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ham sandwich", "hs.vcproj", "{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -9,10 +9,10 @@ Global
|
|||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Release|Win32.Build.0 = Release|Win32
|
||||
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
|
@ -2,8 +2,9 @@
|
|||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="sven"
|
||||
ProjectGUID="{29798873-02F2-4075-AFE7-58CE8F9B5124}"
|
||||
Name="ham sandwich"
|
||||
ProjectGUID="{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}"
|
||||
RootNamespace="hamsandwich"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
|
@ -37,27 +38,24 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/sven.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SVEN_EXPORTS"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="z:\metamod\metamod;z:\hlsdk\common;z:\hlsdk\engine;z:\hlsdk\dlls;z:\hlsdk\pm_shared;.."
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=".\Release/sven.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -65,20 +63,14 @@
|
|||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1053"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile=".\Release/sven_amxx.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\Release/sven.pdb"
|
||||
ImportLibrary=".\Release/sven.lib"
|
||||
TargetMachine="1"
|
||||
OutputFile="$(OutDir)\hamsandwich_amxx.dll"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
@ -120,6 +112,8 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="del c:\HLServer\tfc\addons\amxmodx\modules
copy $(TargetDir)$(TargetFileName) c:\HLServer\tfc\addons\amxmodx\modules
"
|
||||
Outputs=""echo lol"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
|
@ -133,24 +127,26 @@
|
|||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/sven.tlb"
|
||||
TypeLibraryName=".\Debug/ns_amxx.tlb"
|
||||
HeaderFileName=""
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SVEN_EXPORTS"
|
||||
AdditionalIncludeDirectories="z:\metamod\metamod;z:\hlsdk\common;z:\hlsdk\engine;z:\hlsdk\dlls;z:\hlsdk\pm_shared;.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;ns_amxx_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeLibrary="3"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderFile=".\Debug/sven.pch"
|
||||
PrecompiledHeaderFile=".\Debug/ns_amxx.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -158,20 +154,19 @@
|
|||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1053"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="Debug/sven_amxx.dll"
|
||||
OutputFile=".\Debug/hamsandwich_amxx.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\Debug/sven_debug.pdb"
|
||||
ImportLibrary=".\Debug/sven_debug.lib"
|
||||
ProgramDatabaseFile=".\Debug/ns_amxx.pdb"
|
||||
ImportLibrary=".\Debug/ns_amxx.lib"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
|
@ -204,48 +199,69 @@
|
|||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
Name="sdk"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\amxxmodule.cpp"
|
||||
RelativePath="..\sdk\amxxmodule.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\svencoop.cpp"
|
||||
RelativePath="..\sdk\amxxmodule.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\moduleconfig.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
<File
|
||||
RelativePath="..\amxxapi.cpp"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\amxxmodule.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\moduleconfig.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pdata.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\svencoop.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\svencoop_const.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\FileParser.cpp"
|
||||
>
|
||||
</Filter>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\FileParser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\hamsandwich.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Makefile"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\NEW_Util.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Trampolines.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vfunc_gcc295.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vfunc_msvc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vtable.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\VTableManager.h"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
148
dlls/hamsandwich/msvc8/include/hamsandwich.inc
Normal file
148
dlls/hamsandwich/msvc8/include/hamsandwich.inc
Normal file
|
@ -0,0 +1,148 @@
|
|||
#if defined _hamsandwich_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _hamsandwich_included
|
||||
|
||||
#if AMXX_VERSION_NUM >= 175
|
||||
#pragma reqlib hamsandwich
|
||||
#if !defined AMXMODX_NOAUTOLOAD
|
||||
#pragma loadlib hamsandwich
|
||||
#endif
|
||||
#else
|
||||
#pragma library hamsandwich
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Ham Sandwich general usage
|
||||
* -
|
||||
* Mods supported:
|
||||
* cs:
|
||||
* * 1.6 - legimate, most up to date version
|
||||
* * linux 32bit and windows
|
||||
* * czero - legimate, most up to date version
|
||||
* * linux 32bit and windows
|
||||
* * czero untested, theoretically it should work
|
||||
* dod:
|
||||
* * whatever the most up to date legitimate version is (1.3?)
|
||||
* * linux and windows
|
||||
* * windows untested, should work
|
||||
* tfc:
|
||||
* * whatever most up to date legitimate version is
|
||||
* * linux and windows
|
||||
* * windows untested, should work
|
||||
* ns:
|
||||
* * 3.2 beta 2
|
||||
* * linux and windows
|
||||
* * windows untested, should work
|
||||
* ts:
|
||||
* * 2.1
|
||||
* * linux and windows
|
||||
* * windows untested, should work
|
||||
* sven:
|
||||
* * 3.0
|
||||
* * windows
|
||||
* * windows untested, should work
|
||||
* -
|
||||
* The module will automatically use the relevant function depending
|
||||
* on what game mod is loaded. You only have to tell it to do the damage.
|
||||
* -
|
||||
* Be VERY VERY careful. I check _NO_ bounds in any of the natives
|
||||
* Also, these call the game's private function, and I do not have
|
||||
* the time nor desire to figure out the quirks of each mod's function
|
||||
* -
|
||||
* The USE natives haven't been tested yet, but should work!
|
||||
* -
|
||||
* The only mod I tested the windows version of takedamage
|
||||
* for was cs 1.6. It's much easier for me to test linux.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calls the mod's private damage routine.
|
||||
* -
|
||||
* parameters:
|
||||
* id: index of the entity that is to be damaged
|
||||
*
|
||||
* inflictor: the entity that is "doing the damage" (eg a weapon)
|
||||
*
|
||||
* attacker: the entity who controls the inflictor (eg weapon holder)
|
||||
*
|
||||
* damage: how much damage to do to the victim
|
||||
*
|
||||
* type: bitmask of damage flags. Most mods do not
|
||||
* follow the standard HLSDK damage flags, so
|
||||
* you may have to do some testing!
|
||||
* The only flags I figured out were CS related:
|
||||
* * (1<<6) = no slowdown on damage
|
||||
* * (1<<13) = always gib
|
||||
* * (1<<12) = never gib
|
||||
*
|
||||
* -
|
||||
* Note: Setting damage to a ridiculously high value can mess up
|
||||
* some mods!
|
||||
*/
|
||||
native hs_takedamage(id,inflictor,attacker,Float:damage,type);
|
||||
native hs_etakedamage(id,inflictor,attacker,Float:damage,type);
|
||||
|
||||
|
||||
/**
|
||||
* Calls the mod's private use routine.
|
||||
* -
|
||||
* parameters:
|
||||
* id: index of the entity that is to be used
|
||||
*
|
||||
* activator: the entity that is "doing the use" (eg a trigger_multiple)
|
||||
*
|
||||
* caller: the entity who controls the activator (eg the player who trigger the trigger_multiple)
|
||||
*
|
||||
* use_type: how to use the entity
|
||||
* TYPICAL settings in HLSDK are:
|
||||
* 0 = USE_OFF - turns the object "off"
|
||||
* 1 = USE_ON - turns the object "on"
|
||||
* 2 = USE_SET - sets the object use state (uses the value flag)
|
||||
* 3 = USE_TOGGLE - toggles the state (from on->off and off->on)
|
||||
*
|
||||
* use_value: set when USE_SET is invoked
|
||||
* TYPICALLY USE_SET is only used for players using an object
|
||||
* when he begins using it, the use_value is set to 1.0
|
||||
* when he's done using it, the use_value is set to 0.0
|
||||
*
|
||||
* -
|
||||
* NOTE: This native was not tested at all beyond theory tests!
|
||||
*/
|
||||
native hs_use(id,activator,caller,use_type,Float:use_value);
|
||||
native hs_euse(id,activator,caller,use_type,Float:use_value);
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
HAM_UNSET = 0,
|
||||
HAM_IGNORED,
|
||||
HAM_HANDLED,
|
||||
HAM_OVERRIDE,
|
||||
HAM_SUPERCEDE
|
||||
};
|
||||
|
||||
/**
|
||||
* Forwards all takedamage routines that would occur to the given
|
||||
* classname to the public provided.
|
||||
*
|
||||
* Parameters are:
|
||||
* function(IDVictim, IDInflictor, IDAttacker, Float:Damage, DamageType)
|
||||
*
|
||||
* Note: For now, this will also intercept calls to hs_takedamage
|
||||
* that is very likely to change shortly in the future.
|
||||
*/
|
||||
native register_takedamage(const classname[], const function[]);
|
||||
|
||||
/**
|
||||
* Forwards all use routines that would occur to the given
|
||||
* classname to the public provided.
|
||||
*
|
||||
* Parameters are:
|
||||
* function(IDUsed, IDActivator, IDCaller, UseType, Float:UseValue)
|
||||
*
|
||||
* Note: For now, this will also intercept calls to hs_use
|
||||
* that is very likely to change shortly in the future.
|
||||
*/
|
||||
native register_use(const classname[], const function[]);
|
185
dlls/hamsandwich/natives.cpp
Normal file
185
dlls/hamsandwich/natives.cpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
|
||||
/* Ham Sandwich
|
||||
*
|
||||
* by sawce
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "hamsandwich.h"
|
||||
#include "NEW_Util.h"
|
||||
|
||||
#include "vfunc_msvc.h"
|
||||
#include "vfunc_gcc295.h"
|
||||
|
||||
static cell AMX_NATIVE_CALL hs_takedamage(AMX *amx, cell *params)
|
||||
{
|
||||
return VCall4<int>(
|
||||
INDEXENT_NEW(params[1])->pvPrivateData, /*this*/
|
||||
HAM_Takedamage, /*vtable entry*/
|
||||
HAM_Classbase, /*size of class*/
|
||||
&(INDEXENT_NEW(params[2])->v), /*inflictor*/
|
||||
&(INDEXENT_NEW(params[3])->v), /*attacker*/
|
||||
amx_ctof2(params[4]), /*damage*/
|
||||
(int)params[5]); /*dmgtype*/
|
||||
};
|
||||
static cell AMX_NATIVE_CALL hs_use(AMX *amx, cell *params)
|
||||
{
|
||||
VoidVCall4(
|
||||
INDEXENT_NEW(params[1])->pvPrivateData, /*this*/
|
||||
HAM_Use, /*vtable entry*/
|
||||
HAM_Classbase, /*size of class*/
|
||||
INDEXENT_NEW(params[2])->pvPrivateData, /*activator*/
|
||||
INDEXENT_NEW(params[3])->pvPrivateData, /*caller*/
|
||||
params[4], /*use type*/
|
||||
amx_ctof2(params[5])); /*value*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Very fast, but potentially unsafe (if you use the wrong index/offset)
|
||||
* method of converting a CBaseEntity pointer into a usable entity index
|
||||
*/
|
||||
static cell AMX_NATIVE_CALL hs_pdata_cbase(AMX *amx, cell *params)
|
||||
{
|
||||
// Get the offset of the private data
|
||||
int Offset=params[2];
|
||||
|
||||
// If this is a linux server increase the offset
|
||||
#ifdef __linux__
|
||||
Offset+=params[3];
|
||||
#endif
|
||||
|
||||
// Get the CBase pointer
|
||||
int *ent=*((int **)INDEXENT_NEW(params[1])->pvPrivateData + Offset);
|
||||
|
||||
// Null pointer; get out
|
||||
if (ent==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Now move up HAM_Pev bytes
|
||||
char *bent=*(char**)&ent;
|
||||
|
||||
bent+=HAM_Pev;
|
||||
|
||||
entvars_t *pev=*(entvars_t **)&bent;
|
||||
|
||||
// Null pointer, get out
|
||||
if (pev==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ENTINDEX_NEW(pev->pContainingEntity);
|
||||
|
||||
|
||||
}
|
||||
/**
|
||||
* Slow, but very safe replacement for hs_pdata_cbase
|
||||
* -
|
||||
* This will scan through all entities to check their private
|
||||
* data against the requested offset's data.
|
||||
* It will never reference the requested PData, so unless
|
||||
* the plugin author is way off with the offset it should
|
||||
* never crash.
|
||||
* -
|
||||
* This should only be used for offset searching; NEVER
|
||||
* in a release quality script.
|
||||
*/
|
||||
static cell AMX_NATIVE_CALL hs_pdata_cbase_safe(AMX *amx, cell *params)
|
||||
{
|
||||
// Get the offset of the private data
|
||||
int Offset=params[2];
|
||||
|
||||
// If this is a linux server increase the offset
|
||||
#ifdef __linux__
|
||||
Offset+=params[3];
|
||||
#endif
|
||||
|
||||
// Get the CBase pointer
|
||||
int *data=*((int **)INDEXENT_NEW(params[1])->pvPrivateData + Offset);
|
||||
|
||||
// Get the first entity
|
||||
edict_t *Entity=INDEXENT_NEW(0);
|
||||
|
||||
// Get the last entity
|
||||
edict_t *Last=INDEXENT_NEW(gpGlobals->maxEntities);
|
||||
|
||||
// Scan through all of the entities (excluding 0, because no other module allows for worldspawn)
|
||||
while (Entity++<Last)
|
||||
{
|
||||
// If this entity's private data matches the CBase pointer requested, return
|
||||
if (((int *)Entity->pvPrivateData)==data)
|
||||
{
|
||||
return ENTINDEX_NEW(Entity);
|
||||
}
|
||||
}
|
||||
|
||||
// Not found
|
||||
return 0;
|
||||
}
|
||||
|
||||
static AMX_NATIVE_INFO reg_takedamage[] = {
|
||||
{ "hs_takedamage", hs_takedamage },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
static AMX_NATIVE_INFO reg_use[] = {
|
||||
{ "hs_use", hs_use },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
static AMX_NATIVE_INFO reg_cbase_fast[] = {
|
||||
{ "hs_pdata_cbase", hs_pdata_cbase },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
static AMX_NATIVE_INFO reg_cbase_safe[] = {
|
||||
{ "hs_pdata_cbase_safe", hs_pdata_cbase_safe },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
void HAM_RegisterTakeDamage()
|
||||
{
|
||||
MF_AddNatives(reg_takedamage);
|
||||
}
|
||||
void HAM_RegisterUse()
|
||||
{
|
||||
MF_AddNatives(reg_use);
|
||||
}
|
||||
void HAM_RegisterCbaseFast()
|
||||
{
|
||||
MF_AddNatives(reg_cbase_fast);
|
||||
}
|
||||
void HAM_RegisterCbaseSafe()
|
||||
{
|
||||
MF_AddNatives(reg_cbase_safe);
|
||||
}
|
||||
|
|
@ -2430,11 +2430,14 @@ static amxx_module_info_s g_ModuleInfo =
|
|||
#else // MODULE_RELOAD_ON_MAPCHANGE
|
||||
0,
|
||||
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
||||
MODULE_LOGTAG
|
||||
MODULE_LOGTAG,
|
||||
MODULE_LIBRARY,
|
||||
MODULE_LIBCLASS
|
||||
};
|
||||
|
||||
// Storage for the requested functions
|
||||
PFN_ADD_NATIVES g_fn_AddNatives;
|
||||
PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
|
||||
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||
|
@ -2504,6 +2507,16 @@ PFN_REQ_FNPTR g_fn_RequestFunction;
|
|||
PFN_AMX_PUSH g_fn_AmxPush;
|
||||
PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
||||
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
||||
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
||||
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
||||
PFN_FINDLIBRARY g_fn_FindLibrary;
|
||||
PFN_ADDLIBRARIES g_fn_AddLibraries;
|
||||
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
||||
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
|
||||
PFN_GETLOCALINFO g_fn_GetLocalInfo;
|
||||
PFN_AMX_REREGISTER g_fn_AmxReRegister;
|
||||
PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
|
||||
PFN_MESSAGE_BLOCK g_fn_MessageBlock;
|
||||
|
||||
// *** Exports ***
|
||||
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
||||
|
@ -2554,6 +2567,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
||||
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
|
||||
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
|
||||
REQFUNC("RegisterFunctionEx", g_fn_RegisterFunctionEx, PFN_REGISTERFUNCTIONEX);
|
||||
|
||||
// Amx scripts
|
||||
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
||||
|
@ -2579,6 +2593,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||
|
||||
// Natives / Forwards
|
||||
REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES);
|
||||
REQFUNC("AddNewNatives", g_fn_AddNewNatives, PFN_ADD_NEW_NATIVES);
|
||||
REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR);
|
||||
REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD);
|
||||
REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD);
|
||||
|
@ -2615,6 +2630,18 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
|||
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
|
||||
REQFUNC("SetPlayerTeamInfo", g_fn_SetTeamInfo, PFN_SET_TEAM_INFO);
|
||||
REQFUNC("PlayerPropAddr", g_fn_PlayerPropAddr, PFN_PLAYER_PROP_ADDR);
|
||||
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
|
||||
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
|
||||
|
||||
//Added in 1.75
|
||||
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
|
||||
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
|
||||
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
|
||||
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
|
||||
REQFUNC("GetLocalInfo", g_fn_GetLocalInfo, PFN_GETLOCALINFO);
|
||||
REQFUNC("AmxReregister", g_fn_AmxReRegister, PFN_AMX_REREGISTER);
|
||||
|
||||
REQFUNC("MessageBlock", g_fn_MessageBlock, PFN_MESSAGE_BLOCK);
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
// Memory
|
||||
|
@ -2650,14 +2677,27 @@ C_DLLEXPORT int AMXX_PluginsLoaded()
|
|||
return AMXX_OK;
|
||||
}
|
||||
|
||||
C_DLLEXPORT void AMXX_PluginsUnloaded()
|
||||
{
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADED
|
||||
FN_AMXX_PLUGINSUNLOADED();
|
||||
#endif // FN_AMXX_PLUGINSUNLOADED
|
||||
}
|
||||
|
||||
C_DLLEXPORT void AMXX_PluginsUnloading()
|
||||
{
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADING
|
||||
FN_AMXX_PLUGINSUNLOADING();
|
||||
#endif // FN_AMXX_PLUGINSUNLOADING
|
||||
}
|
||||
|
||||
// Advanced MF functions
|
||||
void MF_Log(const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
|
||||
|
@ -2665,11 +2705,10 @@ void MF_Log(const char *fmt, ...)
|
|||
|
||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
|
||||
|
@ -2737,8 +2776,16 @@ void ValidateMacros_DontCallThis_Smiley()
|
|||
MF_GetPlayerEdict(0);
|
||||
MF_Format("", 4, "str");
|
||||
MF_RegisterFunction(NULL, "");
|
||||
MF_RegisterFunctionEx(NULL, "");
|
||||
MF_SetPlayerTeamInfo(0, 0, "");
|
||||
MF_PlayerPropAddr(0, 0);
|
||||
MF_RegAuthFunc(NULL);
|
||||
MF_UnregAuthFunc(NULL);
|
||||
MF_FindLibrary(NULL, LibType_Class);
|
||||
MF_AddLibraries(NULL, LibType_Class, NULL);
|
||||
MF_RemoveLibraries(NULL);
|
||||
MF_OverrideNatives(NULL, NULL);
|
||||
MF_MessageBlock(0, 0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef __linux__
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#define DLLEXPORT __attribute__((visibility("default")))
|
||||
#define LINUX
|
||||
#endif
|
||||
|
||||
|
@ -34,7 +34,8 @@
|
|||
// module interface version was 1
|
||||
// 2 - added logtag to struct (amxx1.1-rc1)
|
||||
// 3 - added new tagAMX structure (amxx1.5)
|
||||
#define AMXX_INTERFACE_VERSION 3
|
||||
// 4 - added new 'library' setting for direct loading
|
||||
#define AMXX_INTERFACE_VERSION 4
|
||||
|
||||
// amxx module info
|
||||
struct amxx_module_info_s
|
||||
|
@ -44,6 +45,8 @@ struct amxx_module_info_s
|
|||
const char *version;
|
||||
int reload; // reload on mapchange when nonzero
|
||||
const char *logtag; // added in version 2
|
||||
const char *library; // added in version 4
|
||||
const char *libclass; // added in version 4
|
||||
};
|
||||
|
||||
// return values from functions called by amxx
|
||||
|
@ -153,9 +156,137 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
|||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||
* about pragma pack in a header file */
|
||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||
* about pragma pack in a header file */
|
||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#if !defined NO_MSVC8_AUTO_COMPAT
|
||||
|
||||
/* Disable deprecation warnings concerning unsafe CRT functions */
|
||||
#if !defined _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
/* Replace the POSIX function with ISO C++ conformant ones as they are now deprecated */
|
||||
#define access _access
|
||||
#define cabs _cabs
|
||||
#define cgets _cgets
|
||||
#define chdir _chdir
|
||||
#define chmod _chmod
|
||||
#define chsize _chsize
|
||||
#define close _close
|
||||
#define cprintf _cprintf
|
||||
#define cputs _cputts
|
||||
#define creat _creat
|
||||
#define cscanf _cscanf
|
||||
#define cwait _cwait
|
||||
#define dup _dup
|
||||
#define dup2 _dup2
|
||||
#define ecvt _ecvt
|
||||
#define eof _eof
|
||||
#define execl _execl
|
||||
#define execle _execle
|
||||
#define execlp _execlp
|
||||
#define execlpe _execlpe
|
||||
#define execv _execv
|
||||
#define execve _execv
|
||||
#define execvp _execvp
|
||||
#define execvpe _execvpe
|
||||
#define fcloseall _fcloseall
|
||||
#define fcvt _fcvt
|
||||
#define fdopen _fdopen
|
||||
#define fgetchar _fgetchar
|
||||
#define filelength _filelength
|
||||
#define fileno _fileno
|
||||
#define flushall _flushall
|
||||
#define fputchar _fputchar
|
||||
#define gcvt _gcvt
|
||||
#define getch _getch
|
||||
#define getche _getche
|
||||
#define getcwd _getcwd
|
||||
#define getpid _getpid
|
||||
#define getw _getw
|
||||
#define hypot _hypot
|
||||
#define inp _inp
|
||||
#define inpw _inpw
|
||||
#define isascii __isascii
|
||||
#define isatty _isatty
|
||||
#define iscsym __iscsym
|
||||
#define iscsymf __iscsymf
|
||||
#define itoa _itoa
|
||||
#define j0 _j0
|
||||
#define j1 _j1
|
||||
#define jn _jn
|
||||
#define kbhit _kbhit
|
||||
#define lfind _lfind
|
||||
#define locking _locking
|
||||
#define lsearch _lsearch
|
||||
#define lseek _lseek
|
||||
#define ltoa _ltoa
|
||||
#define memccpy _memccpy
|
||||
#define memicmp _memicmp
|
||||
#define mkdir _mkdir
|
||||
#define mktemp _mktemp
|
||||
#define open _open
|
||||
#define outp _outp
|
||||
#define outpw _outpw
|
||||
#define putch _putch
|
||||
#define putenv _putenv
|
||||
#define putw _putw
|
||||
#define read _read
|
||||
#define rmdir _rmdir
|
||||
#define rmtmp _rmtmp
|
||||
#define setmode _setmode
|
||||
#define sopen _sopen
|
||||
#define spawnl _spawnl
|
||||
#define spawnle _spawnle
|
||||
#define spawnlp _spawnlp
|
||||
#define spawnlpe _spawnlpe
|
||||
#define spawnv _spawnv
|
||||
#define spawnve _spawnve
|
||||
#define spawnvp _spawnvp
|
||||
#define spawnvpe _spawnvpe
|
||||
#define strcmpi _strcmpi
|
||||
#define strdup _strdup
|
||||
#define stricmp _stricmp
|
||||
#define strlwr _strlwr
|
||||
#define strnicmp _strnicmp
|
||||
#define strnset _strnset
|
||||
#define strrev _strrev
|
||||
#define strset _strset
|
||||
#define strupr _strupr
|
||||
#define swab _swab
|
||||
#define tell _tell
|
||||
#define tempnam _tempnam
|
||||
#define toascii __toascii
|
||||
#define tzset _tzset
|
||||
#define ultoa _ultoa
|
||||
#define umask _umask
|
||||
#define ungetch _ungetch
|
||||
#define unlink _unlink
|
||||
#define wcsdup _wcsdup
|
||||
#define wcsicmp _wcsicmp
|
||||
#define wcsicoll _wcsicoll
|
||||
#define wcslwr _wcslwr
|
||||
#define wcsnicmp _wcsnicmp
|
||||
#define wcsnset _wcsnset
|
||||
#define wcsrev _wcsrev
|
||||
#define wcsset _wcsset
|
||||
#define wcsupr _wcsupr
|
||||
#define write _write
|
||||
#define y0 _y0
|
||||
#define y1 _y1
|
||||
#define yn _yn
|
||||
|
||||
/* Disable deprecation warnings because MSVC8 seemingly thinks the ISO C++ conformant
|
||||
* functions above are deprecated. */
|
||||
#pragma warning (disable:4996)
|
||||
|
||||
#endif
|
||||
#else
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1904,6 +2035,14 @@ void FN_AMXX_DETACH(void);
|
|||
void FN_AMXX_PLUGINSLOADED(void);
|
||||
#endif // FN_AMXX_PLUGINSLOADED
|
||||
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADING
|
||||
void FN_AMXX_PLUGINSUNLOADING(void);
|
||||
#endif // FN_AMXX_PLUGINSUNLOADING
|
||||
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADED
|
||||
void FN_AMXX_PLUGINSUNLOADED(void);
|
||||
#endif // FN_AMXX_PLUGINSUNLOADED
|
||||
|
||||
// *** Types ***
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
|
||||
|
@ -1950,7 +2089,22 @@ enum PlayerProp
|
|||
Player_NewmenuPage, //int
|
||||
};
|
||||
|
||||
enum LibType
|
||||
{
|
||||
LibType_Library,
|
||||
LibType_Class
|
||||
};
|
||||
|
||||
#define MSGBLOCK_SET 0
|
||||
#define MSGBLOCK_GET 1
|
||||
#define BLOCK_NOT 0
|
||||
#define BLOCK_ONCE 1
|
||||
#define BLOCK_SET 2
|
||||
|
||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
||||
|
||||
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||
typedef int (*PFN_ADD_NEW_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
||||
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
|
||||
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
||||
|
@ -2027,8 +2181,19 @@ typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
|
|||
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
|
||||
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
||||
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
|
||||
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
|
||||
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
|
||||
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/);
|
||||
typedef size_t (*PFN_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
|
||||
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
|
||||
typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/, const char * /*myname*/);
|
||||
typedef const char * (*PFN_GETLOCALINFO) (const char * /*name*/, const char * /*def*/);
|
||||
typedef int (*PFN_AMX_REREGISTER) (AMX * /*amx*/, AMX_NATIVE_INFO * /*list*/, int /*list*/);
|
||||
typedef void * (*PFN_REGISTERFUNCTIONEX) (void * /*pfn*/, const char * /*desc*/);
|
||||
typedef void (*PFN_MESSAGE_BLOCK) (int /* mode */, int /* message */, int * /* opt */);
|
||||
|
||||
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
||||
extern PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
|
||||
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||
|
@ -2092,11 +2257,22 @@ extern PFN_REQ_FNPTR g_fn_RequestFunction;
|
|||
extern PFN_AMX_PUSH g_fn_AmxPush;
|
||||
extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
||||
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
||||
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
||||
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
||||
extern PFN_FINDLIBRARY g_fn_FindLibrary;
|
||||
extern PFN_ADDLIBRARIES g_fn_AddLibraries;
|
||||
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
||||
extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
|
||||
extern PFN_GETLOCALINFO g_fn_GetLocalInfo;
|
||||
extern PFN_AMX_REREGISTER g_fn_AmxReRegister;
|
||||
extern PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
|
||||
extern PFN_MESSAGE_BLOCK g_fn_MessageBlock;
|
||||
|
||||
#ifdef MAY_NEVER_BE_DEFINED
|
||||
// Function prototypes for intellisense and similar systems
|
||||
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
||||
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
||||
int MF_AddNewNatives (const AMX_NATIVE_INFO *list) { }
|
||||
char * MF_BuildPathname (const char * format, ...) { }
|
||||
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
|
||||
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
||||
|
@ -2154,9 +2330,20 @@ int MF_AmxPush (AMX *amx, cell *params) { }
|
|||
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
||||
int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
|
||||
void * MF_PlayerPropAddr (int id, int prop) { }
|
||||
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
|
||||
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
|
||||
int MF_FindLibrary (const char *name, LibType type) { }
|
||||
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
|
||||
size_t MF_RemoveLibraries (void *parent) { }
|
||||
void MF_OverrideNatives (AMX_NATIVE_INFO *natives, const char *myname) { }
|
||||
const char * MF_GetLocalInfo (const char *name, const char *def) { }
|
||||
int MF_AmxReRegister (AMX *amx, AMX_NATIVE_INFO *list, int number) { return 0; }
|
||||
void * MF_RegisterFunctionEx (void *pfn, const char *description) { }
|
||||
void * MF_MessageBlock (int mode, int msg, int *opt) { }
|
||||
#endif // MAY_NEVER_BE_DEFINED
|
||||
|
||||
#define MF_AddNatives g_fn_AddNatives
|
||||
#define MF_AddNewNatives g_fn_AddNewNatives
|
||||
#define MF_BuildPathname g_fn_BuildPathname
|
||||
#define MF_BuildPathnameR g_fn_BuildPathnameR
|
||||
#define MF_FormatAmxString g_fn_FormatAmxString
|
||||
|
@ -2217,10 +2404,20 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
|||
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
|
||||
#define MF_Format g_fn_Format
|
||||
#define MF_RegisterFunction g_fn_RegisterFunction
|
||||
#define MF_RequestFunction g_fn_RequestFunction;
|
||||
#define MF_RequestFunction g_fn_RequestFunction
|
||||
#define MF_AmxPush g_fn_AmxPush
|
||||
#define MF_SetPlayerTeamInfo g_fn_SetTeamInfo
|
||||
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
|
||||
#define MF_RegAuthFunc g_fn_RegAuthFunc
|
||||
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
|
||||
#define MF_FindLibrary g_fn_FindLibrary
|
||||
#define MF_AddLibraries g_fn_AddLibraries
|
||||
#define MF_RemoveLibraries g_fn_RemoveLibraries
|
||||
#define MF_OverrideNatives g_fn_OverrideNatives
|
||||
#define MF_GetLocalInfo g_fn_GetLocalInfo
|
||||
#define MF_AmxReRegister g_fn_AmxReRegister
|
||||
#define MF_RegisterFunctionEx g_fn_RegisterFunctionEx
|
||||
#define MF_MessageBlock g_fn_MessageBlock
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
/*** Memory ***/
|
491
dlls/hamsandwich/sdk/moduleconfig.h
Normal file
491
dlls/hamsandwich/sdk/moduleconfig.h
Normal file
|
@ -0,0 +1,491 @@
|
|||
// Configuration
|
||||
|
||||
#ifndef __MODULECONFIG_H__
|
||||
#define __MODULECONFIG_H__
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "Ham Sandwich"
|
||||
#define MODULE_VERSION "1.77"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "HAM"
|
||||
#define MODULE_LIBRARY "hamsandwich"
|
||||
#define MODULE_LIBCLASS ""
|
||||
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
||||
// #define MODULE_RELOAD_ON_MAPCHANGE
|
||||
|
||||
#ifdef __DATE__
|
||||
#define MODULE_DATE __DATE__
|
||||
#else // __DATE__
|
||||
#define MODULE_DATE "Unknown"
|
||||
#endif // __DATE__
|
||||
|
||||
// metamod plugin?
|
||||
#define USE_METAMOD
|
||||
|
||||
// use memory manager/tester?
|
||||
// note that if you use this, you cannot construct/allocate
|
||||
// anything before the module attached (OnAmxxAttach).
|
||||
// be careful of default constructors using new/malloc!
|
||||
// #define MEMORY_TEST
|
||||
|
||||
// Unless you use STL or exceptions, keep this commented.
|
||||
// It allows you to compile without libstdc++.so as a dependency
|
||||
// #define NO_ALLOC_OVERRIDES
|
||||
|
||||
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
|
||||
// #define NO_MSVC8_AUTO_COMPAT
|
||||
|
||||
/**
|
||||
* AMXX Init functions
|
||||
* Also consider using FN_META_*
|
||||
*/
|
||||
|
||||
/** AMXX query */
|
||||
//#define FN_AMXX_QUERY OnAmxxQuery
|
||||
|
||||
/** AMXX attach
|
||||
* Do native functions init here (MF_AddNatives)
|
||||
*/
|
||||
#define FN_AMXX_ATTACH OnAmxxAttach
|
||||
|
||||
/** AMXX Detach (unload) */
|
||||
//#define FN_AMXX_DETACH OnAmxxDetach
|
||||
|
||||
/** All plugins loaded
|
||||
* Do forward functions init here (MF_RegisterForward)
|
||||
*/
|
||||
#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||
|
||||
/** All plugins are about to be unloaded */
|
||||
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
|
||||
|
||||
/** All plugins are now unloaded */
|
||||
#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
||||
|
||||
/**** METAMOD ****/
|
||||
// If your module doesn't use metamod, you may close the file now :)
|
||||
#ifdef USE_METAMOD
|
||||
// ----
|
||||
// Hook Functions
|
||||
// Uncomment these to be called
|
||||
// You can also change the function name
|
||||
|
||||
// - Metamod init functions
|
||||
// Also consider using FN_AMXX_*
|
||||
// Meta query
|
||||
//#define FN_META_QUERY OnMetaQuery
|
||||
// Meta attach
|
||||
//#define FN_META_ATTACH OnMetaAttach
|
||||
// Meta detach
|
||||
//#define FN_META_DETACH OnMetaDetach
|
||||
|
||||
// (wd) are Will Day's notes
|
||||
// - GetEntityAPI2 functions
|
||||
// #define FN_GameDLLInit GameDLLInit /* pfnGameInit() */
|
||||
//#define FN_DispatchSpawn DispatchSpawn /* pfnSpawn() */
|
||||
// #define FN_DispatchThink DispatchThink /* pfnThink() */
|
||||
// #define FN_DispatchUse DispatchUse /* pfnUse() */
|
||||
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
|
||||
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
|
||||
//#define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
// #define FN_DispatchSave DispatchSave /* pfnSave() */
|
||||
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
|
||||
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
|
||||
// #define FN_SaveWriteFields SaveWriteFields /* pfnSaveWriteFields() */
|
||||
// #define FN_SaveReadFields SaveReadFields /* pfnSaveReadFields() */
|
||||
// #define FN_SaveGlobalState SaveGlobalState /* pfnSaveGlobalState() */
|
||||
// #define FN_RestoreGlobalState RestoreGlobalState /* pfnRestoreGlobalState() */
|
||||
// #define FN_ResetGlobalState ResetGlobalState /* pfnResetGlobalState() */
|
||||
//#define FN_ClientConnect ClientConnect /* pfnClientConnect() (wd) Client has connected */
|
||||
//#define FN_ClientDisconnect ClientDisconnect /* pfnClientDisconnect() (wd) Player has left the game */
|
||||
// #define FN_ClientKill ClientKill /* pfnClientKill() (wd) Player has typed "kill" */
|
||||
// #define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
|
||||
// #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */
|
||||
// #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */
|
||||
//#define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
|
||||
//#define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */
|
||||
// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
|
||||
// #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */
|
||||
// #define FN_StartFrame StartFrame /* pfnStartFrame() */
|
||||
// #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */
|
||||
// #define FN_ParmsChangeLevel ParmsChangeLevel /* pfnParmsChangeLevel() */
|
||||
// #define FN_GetGameDescription GetGameDescription /* pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2" "Half-Life" */
|
||||
// #define FN_PlayerCustomization PlayerCustomization /* pfnPlayerCustomization() Notifies .dll of new customization for player. */
|
||||
// #define FN_SpectatorConnect SpectatorConnect /* pfnSpectatorConnect() Called when spectator joins server */
|
||||
// #define FN_SpectatorDisconnect SpectatorDisconnect /* pfnSpectatorDisconnect() Called when spectator leaves the server */
|
||||
// #define FN_SpectatorThink SpectatorThink /* pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t) */
|
||||
// #define FN_Sys_Error Sys_Error /* pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2 */
|
||||
// #define FN_PM_Move PM_Move /* pfnPM_Move() (wd) SDK2 */
|
||||
// #define FN_PM_Init PM_Init /* pfnPM_Init() Server version of player movement initialization; (wd) SDK2 */
|
||||
// #define FN_PM_FindTextureType PM_FindTextureType /* pfnPM_FindTextureType() (wd) SDK2 */
|
||||
// #define FN_SetupVisibility SetupVisibility /* pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2 */
|
||||
// #define FN_UpdateClientData UpdateClientData /* pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 */
|
||||
// #define FN_AddToFullPack AddToFullPack /* pfnAddToFullPack() (wd) SDK2 */
|
||||
// #define FN_CreateBaseline CreateBaseline /* pfnCreateBaseline() Tweak entity baseline for network encoding allows setup of player baselines too.; (wd) SDK2 */
|
||||
// #define FN_RegisterEncoders RegisterEncoders /* pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2 */
|
||||
// #define FN_GetWeaponData GetWeaponData /* pfnGetWeaponData() (wd) SDK2 */
|
||||
// #define FN_CmdStart CmdStart /* pfnCmdStart() (wd) SDK2 */
|
||||
// #define FN_CmdEnd CmdEnd /* pfnCmdEnd() (wd) SDK2 */
|
||||
// #define FN_ConnectionlessPacket ConnectionlessPacket /* pfnConnectionlessPacket() (wd) SDK2 */
|
||||
// #define FN_GetHullBounds GetHullBounds /* pfnGetHullBounds() (wd) SDK2 */
|
||||
// #define FN_CreateInstancedBaselines CreateInstancedBaselines /* pfnCreateInstancedBaselines() (wd) SDK2 */
|
||||
// #define FN_InconsistentFile InconsistentFile /* pfnInconsistentFile() (wd) SDK2 */
|
||||
// #define FN_AllowLagCompensation AllowLagCompensation /* pfnAllowLagCompensation() (wd) SDK2 */
|
||||
|
||||
// - GetEntityAPI2_Post functions
|
||||
// #define FN_GameDLLInit_Post GameDLLInit_Post
|
||||
// #define FN_DispatchSpawn_Post DispatchSpawn_Post
|
||||
// #define FN_DispatchThink_Post DispatchThink_Post
|
||||
// #define FN_DispatchUse_Post DispatchUse_Post
|
||||
// #define FN_DispatchTouch_Post DispatchTouch_Post
|
||||
// #define FN_DispatchBlocked_Post DispatchBlocked_Post
|
||||
// #define FN_DispatchKeyValue_Post DispatchKeyValue_Post
|
||||
// #define FN_DispatchSave_Post DispatchSave_Post
|
||||
// #define FN_DispatchRestore_Post DispatchRestore_Post
|
||||
// #define FN_DispatchObjectCollsionBox_Post DispatchObjectCollsionBox_Post
|
||||
// #define FN_SaveWriteFields_Post SaveWriteFields_Post
|
||||
// #define FN_SaveReadFields_Post SaveReadFields_Post
|
||||
// #define FN_SaveGlobalState_Post SaveGlobalState_Post
|
||||
// #define FN_RestoreGlobalState_Post RestoreGlobalState_Post
|
||||
// #define FN_ResetGlobalState_Post ResetGlobalState_Post
|
||||
// #define FN_ClientConnect_Post ClientConnect_Post
|
||||
// #define FN_ClientDisconnect_Post ClientDisconnect_Post
|
||||
// #define FN_ClientKill_Post ClientKill_Post
|
||||
// #define FN_ClientPutInServer_Post ClientPutInServer_Post
|
||||
// #define FN_ClientCommand_Post ClientCommand_Post
|
||||
// #define FN_ClientUserInfoChanged_Post ClientUserInfoChanged_Post
|
||||
//#define FN_ServerActivate_Post ServerActivate_Post
|
||||
// #define FN_ServerDeactivate_Post ServerDeactivate_Post
|
||||
// #define FN_PlayerPreThink_Post PlayerPreThink_Post
|
||||
// #define FN_PlayerPostThink_Post PlayerPostThink_Post
|
||||
// #define FN_StartFrame_Post StartFrame_Post
|
||||
// #define FN_ParmsNewLevel_Post ParmsNewLevel_Post
|
||||
// #define FN_ParmsChangeLevel_Post ParmsChangeLevel_Post
|
||||
// #define FN_GetGameDescription_Post GetGameDescription_Post
|
||||
// #define FN_PlayerCustomization_Post PlayerCustomization_Post
|
||||
// #define FN_SpectatorConnect_Post SpectatorConnect_Post
|
||||
// #define FN_SpectatorDisconnect_Post SpectatorDisconnect_Post
|
||||
// #define FN_SpectatorThink_Post SpectatorThink_Post
|
||||
// #define FN_Sys_Error_Post Sys_Error_Post
|
||||
// #define FN_PM_Move_Post PM_Move_Post
|
||||
// #define FN_PM_Init_Post PM_Init_Post
|
||||
// #define FN_PM_FindTextureType_Post PM_FindTextureType_Post
|
||||
// #define FN_SetupVisibility_Post SetupVisibility_Post
|
||||
// #define FN_UpdateClientData_Post UpdateClientData_Post
|
||||
// #define FN_AddToFullPack_Post AddToFullPack_Post
|
||||
// #define FN_CreateBaseline_Post CreateBaseline_Post
|
||||
// #define FN_RegisterEncoders_Post RegisterEncoders_Post
|
||||
// #define FN_GetWeaponData_Post GetWeaponData_Post
|
||||
// #define FN_CmdStart_Post CmdStart_Post
|
||||
// #define FN_CmdEnd_Post CmdEnd_Post
|
||||
// #define FN_ConnectionlessPacket_Post ConnectionlessPacket_Post
|
||||
// #define FN_GetHullBounds_Post GetHullBounds_Post
|
||||
// #define FN_CreateInstancedBaselines_Post CreateInstancedBaselines_Post
|
||||
// #define FN_InconsistentFile_Post InconsistentFile_Post
|
||||
// #define FN_AllowLagCompensation_Post AllowLagCompensation_Post
|
||||
|
||||
// - GetEngineAPI functions
|
||||
// #define FN_PrecacheModel PrecacheModel
|
||||
// #define FN_PrecacheSound PrecacheSound
|
||||
// #define FN_SetModel SetModel
|
||||
// #define FN_ModelIndex ModelIndex
|
||||
// #define FN_ModelFrames ModelFrames
|
||||
// #define FN_SetSize SetSize
|
||||
// #define FN_ChangeLevel ChangeLevel
|
||||
// #define FN_GetSpawnParms GetSpawnParms
|
||||
// #define FN_SaveSpawnParms SaveSpawnParms
|
||||
// #define FN_VecToYaw VecToYaw
|
||||
// #define FN_VecToAngles VecToAngles
|
||||
// #define FN_MoveToOrigin MoveToOrigin
|
||||
// #define FN_ChangeYaw ChangeYaw
|
||||
// #define FN_ChangePitch ChangePitch
|
||||
// #define FN_FindEntityByString FindEntityByString
|
||||
// #define FN_GetEntityIllum GetEntityIllum
|
||||
// #define FN_FindEntityInSphere FindEntityInSphere
|
||||
// #define FN_FindClientInPVS FindClientInPVS
|
||||
// #define FN_EntitiesInPVS EntitiesInPVS
|
||||
// #define FN_MakeVectors MakeVectors
|
||||
// #define FN_AngleVectors AngleVectors
|
||||
// #define FN_CreateEntity CreateEntity
|
||||
// #define FN_RemoveEntity RemoveEntity
|
||||
// #define FN_CreateNamedEntity CreateNamedEntity
|
||||
// #define FN_MakeStatic MakeStatic
|
||||
// #define FN_EntIsOnFloor EntIsOnFloor
|
||||
// #define FN_DropToFloor DropToFloor
|
||||
// #define FN_WalkMove WalkMove
|
||||
// #define FN_SetOrigin SetOrigin
|
||||
// #define FN_EmitSound EmitSound
|
||||
// #define FN_EmitAmbientSound EmitAmbientSound
|
||||
// #define FN_TraceLine TraceLine
|
||||
// #define FN_TraceToss TraceToss
|
||||
// #define FN_TraceMonsterHull TraceMonsterHull
|
||||
// #define FN_TraceHull TraceHull
|
||||
// #define FN_TraceModel TraceModel
|
||||
// #define FN_TraceTexture TraceTexture
|
||||
// #define FN_TraceSphere TraceSphere
|
||||
// #define FN_GetAimVector GetAimVector
|
||||
// #define FN_ServerCommand ServerCommand
|
||||
// #define FN_ServerExecute ServerExecute
|
||||
// #define FN_engClientCommand engClientCommand
|
||||
// #define FN_ParticleEffect ParticleEffect
|
||||
// #define FN_LightStyle LightStyle
|
||||
// #define FN_DecalIndex DecalIndex
|
||||
// #define FN_PointContents PointContents
|
||||
// #define FN_MessageBegin MessageBegin
|
||||
// #define FN_MessageEnd MessageEnd
|
||||
// #define FN_WriteByte WriteByte
|
||||
// #define FN_WriteChar WriteChar
|
||||
// #define FN_WriteShort WriteShort
|
||||
// #define FN_WriteLong WriteLong
|
||||
// #define FN_WriteAngle WriteAngle
|
||||
// #define FN_WriteCoord WriteCoord
|
||||
// #define FN_WriteString WriteString
|
||||
// #define FN_WriteEntity WriteEntity
|
||||
// #define FN_CVarRegister CVarRegister
|
||||
// #define FN_CVarGetFloat CVarGetFloat
|
||||
// #define FN_CVarGetString CVarGetString
|
||||
// #define FN_CVarSetFloat CVarSetFloat
|
||||
// #define FN_CVarSetString CVarSetString
|
||||
// #define FN_AlertMessage AlertMessage
|
||||
// #define FN_EngineFprintf EngineFprintf
|
||||
// #define FN_PvAllocEntPrivateData PvAllocEntPrivateData
|
||||
// #define FN_PvEntPrivateData PvEntPrivateData
|
||||
// #define FN_FreeEntPrivateData FreeEntPrivateData
|
||||
// #define FN_SzFromIndex SzFromIndex
|
||||
// #define FN_AllocString AllocString
|
||||
// #define FN_GetVarsOfEnt GetVarsOfEnt
|
||||
// #define FN_PEntityOfEntOffset PEntityOfEntOffset
|
||||
// #define FN_EntOffsetOfPEntity EntOffsetOfPEntity
|
||||
// #define FN_IndexOfEdict IndexOfEdict
|
||||
// #define FN_PEntityOfEntIndex PEntityOfEntIndex
|
||||
// #define FN_FindEntityByVars FindEntityByVars
|
||||
// #define FN_GetModelPtr GetModelPtr
|
||||
// #define FN_RegUserMsg RegUserMsg
|
||||
// #define FN_AnimationAutomove AnimationAutomove
|
||||
// #define FN_GetBonePosition GetBonePosition
|
||||
// #define FN_FunctionFromName FunctionFromName
|
||||
// #define FN_NameForFunction NameForFunction
|
||||
// #define FN_ClientPrintf ClientPrintf
|
||||
// #define FN_ServerPrint ServerPrint
|
||||
// #define FN_Cmd_Args Cmd_Args
|
||||
// #define FN_Cmd_Argv Cmd_Argv
|
||||
// #define FN_Cmd_Argc Cmd_Argc
|
||||
// #define FN_GetAttachment GetAttachment
|
||||
// #define FN_CRC32_Init CRC32_Init
|
||||
// #define FN_CRC32_ProcessBuffer CRC32_ProcessBuffer
|
||||
// #define FN_CRC32_ProcessByte CRC32_ProcessByte
|
||||
// #define FN_CRC32_Final CRC32_Final
|
||||
// #define FN_RandomLong RandomLong
|
||||
// #define FN_RandomFloat RandomFloat
|
||||
// #define FN_SetView SetView
|
||||
// #define FN_Time Time
|
||||
// #define FN_CrosshairAngle CrosshairAngle
|
||||
// #define FN_LoadFileForMe LoadFileForMe
|
||||
// #define FN_FreeFile FreeFile
|
||||
// #define FN_EndSection EndSection
|
||||
// #define FN_CompareFileTime CompareFileTime
|
||||
// #define FN_GetGameDir GetGameDir
|
||||
// #define FN_Cvar_RegisterVariable Cvar_RegisterVariable
|
||||
// #define FN_FadeClientVolume FadeClientVolume
|
||||
// #define FN_SetClientMaxspeed SetClientMaxspeed
|
||||
// #define FN_CreateFakeClient CreateFakeClient
|
||||
// #define FN_RunPlayerMove RunPlayerMove
|
||||
// #define FN_NumberOfEntities NumberOfEntities
|
||||
// #define FN_GetInfoKeyBuffer GetInfoKeyBuffer
|
||||
// #define FN_InfoKeyValue InfoKeyValue
|
||||
// #define FN_SetKeyValue SetKeyValue
|
||||
// #define FN_SetClientKeyValue SetClientKeyValue
|
||||
// #define FN_IsMapValid IsMapValid
|
||||
// #define FN_StaticDecal StaticDecal
|
||||
// #define FN_PrecacheGeneric PrecacheGeneric
|
||||
// #define FN_GetPlayerUserId GetPlayerUserId
|
||||
// #define FN_BuildSoundMsg BuildSoundMsg
|
||||
// #define FN_IsDedicatedServer IsDedicatedServer
|
||||
// #define FN_CVarGetPointer CVarGetPointer
|
||||
// #define FN_GetPlayerWONId GetPlayerWONId
|
||||
// #define FN_Info_RemoveKey Info_RemoveKey
|
||||
// #define FN_GetPhysicsKeyValue GetPhysicsKeyValue
|
||||
// #define FN_SetPhysicsKeyValue SetPhysicsKeyValue
|
||||
// #define FN_GetPhysicsInfoString GetPhysicsInfoString
|
||||
// #define FN_PrecacheEvent PrecacheEvent
|
||||
// #define FN_PlaybackEvent PlaybackEvent
|
||||
// #define FN_SetFatPVS SetFatPVS
|
||||
// #define FN_SetFatPAS SetFatPAS
|
||||
// #define FN_CheckVisibility CheckVisibility
|
||||
// #define FN_DeltaSetField DeltaSetField
|
||||
// #define FN_DeltaUnsetField DeltaUnsetField
|
||||
// #define FN_DeltaAddEncoder DeltaAddEncoder
|
||||
// #define FN_GetCurrentPlayer GetCurrentPlayer
|
||||
// #define FN_CanSkipPlayer CanSkipPlayer
|
||||
// #define FN_DeltaFindField DeltaFindField
|
||||
// #define FN_DeltaSetFieldByIndex DeltaSetFieldByIndex
|
||||
// #define FN_DeltaUnsetFieldByIndex DeltaUnsetFieldByIndex
|
||||
// #define FN_SetGroupMask SetGroupMask
|
||||
// #define FN_engCreateInstancedBaseline engCreateInstancedBaseline
|
||||
// #define FN_Cvar_DirectSet Cvar_DirectSet
|
||||
// #define FN_ForceUnmodified ForceUnmodified
|
||||
// #define FN_GetPlayerStats GetPlayerStats
|
||||
// #define FN_AddServerCommand AddServerCommand
|
||||
// #define FN_Voice_GetClientListening Voice_GetClientListening
|
||||
// #define FN_Voice_SetClientListening Voice_SetClientListening
|
||||
// #define FN_GetPlayerAuthId GetPlayerAuthId
|
||||
|
||||
// - GetEngineAPI_Post functions
|
||||
// #define FN_PrecacheModel_Post PrecacheModel_Post
|
||||
// #define FN_PrecacheSound_Post PrecacheSound_Post
|
||||
// #define FN_SetModel_Post SetModel_Post
|
||||
// #define FN_ModelIndex_Post ModelIndex_Post
|
||||
// #define FN_ModelFrames_Post ModelFrames_Post
|
||||
// #define FN_SetSize_Post SetSize_Post
|
||||
// #define FN_ChangeLevel_Post ChangeLevel_Post
|
||||
// #define FN_GetSpawnParms_Post GetSpawnParms_Post
|
||||
// #define FN_SaveSpawnParms_Post SaveSpawnParms_Post
|
||||
// #define FN_VecToYaw_Post VecToYaw_Post
|
||||
// #define FN_VecToAngles_Post VecToAngles_Post
|
||||
// #define FN_MoveToOrigin_Post MoveToOrigin_Post
|
||||
// #define FN_ChangeYaw_Post ChangeYaw_Post
|
||||
// #define FN_ChangePitch_Post ChangePitch_Post
|
||||
// #define FN_FindEntityByString_Post FindEntityByString_Post
|
||||
// #define FN_GetEntityIllum_Post GetEntityIllum_Post
|
||||
// #define FN_FindEntityInSphere_Post FindEntityInSphere_Post
|
||||
// #define FN_FindClientInPVS_Post FindClientInPVS_Post
|
||||
// #define FN_EntitiesInPVS_Post EntitiesInPVS_Post
|
||||
// #define FN_MakeVectors_Post MakeVectors_Post
|
||||
// #define FN_AngleVectors_Post AngleVectors_Post
|
||||
// #define FN_CreateEntity_Post CreateEntity_Post
|
||||
// #define FN_RemoveEntity_Post RemoveEntity_Post
|
||||
// #define FN_CreateNamedEntity_Post CreateNamedEntity_Post
|
||||
// #define FN_MakeStatic_Post MakeStatic_Post
|
||||
// #define FN_EntIsOnFloor_Post EntIsOnFloor_Post
|
||||
// #define FN_DropToFloor_Post DropToFloor_Post
|
||||
// #define FN_WalkMove_Post WalkMove_Post
|
||||
// #define FN_SetOrigin_Post SetOrigin_Post
|
||||
// #define FN_EmitSound_Post EmitSound_Post
|
||||
// #define FN_EmitAmbientSound_Post EmitAmbientSound_Post
|
||||
// #define FN_TraceLine_Post TraceLine_Post
|
||||
// #define FN_TraceToss_Post TraceToss_Post
|
||||
// #define FN_TraceMonsterHull_Post TraceMonsterHull_Post
|
||||
// #define FN_TraceHull_Post TraceHull_Post
|
||||
// #define FN_TraceModel_Post TraceModel_Post
|
||||
// #define FN_TraceTexture_Post TraceTexture_Post
|
||||
// #define FN_TraceSphere_Post TraceSphere_Post
|
||||
// #define FN_GetAimVector_Post GetAimVector_Post
|
||||
// #define FN_ServerCommand_Post ServerCommand_Post
|
||||
// #define FN_ServerExecute_Post ServerExecute_Post
|
||||
// #define FN_engClientCommand_Post engClientCommand_Post
|
||||
// #define FN_ParticleEffect_Post ParticleEffect_Post
|
||||
// #define FN_LightStyle_Post LightStyle_Post
|
||||
// #define FN_DecalIndex_Post DecalIndex_Post
|
||||
// #define FN_PointContents_Post PointContents_Post
|
||||
// #define FN_MessageBegin_Post MessageBegin_Post
|
||||
// #define FN_MessageEnd_Post MessageEnd_Post
|
||||
// #define FN_WriteByte_Post WriteByte_Post
|
||||
// #define FN_WriteChar_Post WriteChar_Post
|
||||
// #define FN_WriteShort_Post WriteShort_Post
|
||||
// #define FN_WriteLong_Post WriteLong_Post
|
||||
// #define FN_WriteAngle_Post WriteAngle_Post
|
||||
// #define FN_WriteCoord_Post WriteCoord_Post
|
||||
// #define FN_WriteString_Post WriteString_Post
|
||||
// #define FN_WriteEntity_Post WriteEntity_Post
|
||||
// #define FN_CVarRegister_Post CVarRegister_Post
|
||||
// #define FN_CVarGetFloat_Post CVarGetFloat_Post
|
||||
// #define FN_CVarGetString_Post CVarGetString_Post
|
||||
// #define FN_CVarSetFloat_Post CVarSetFloat_Post
|
||||
// #define FN_CVarSetString_Post CVarSetString_Post
|
||||
// #define FN_AlertMessage_Post AlertMessage_Post
|
||||
// #define FN_EngineFprintf_Post EngineFprintf_Post
|
||||
// #define FN_PvAllocEntPrivateData_Post PvAllocEntPrivateData_Post
|
||||
// #define FN_PvEntPrivateData_Post PvEntPrivateData_Post
|
||||
// #define FN_FreeEntPrivateData_Post FreeEntPrivateData_Post
|
||||
// #define FN_SzFromIndex_Post SzFromIndex_Post
|
||||
// #define FN_AllocString_Post AllocString_Post
|
||||
// #define FN_GetVarsOfEnt_Post GetVarsOfEnt_Post
|
||||
// #define FN_PEntityOfEntOffset_Post PEntityOfEntOffset_Post
|
||||
// #define FN_EntOffsetOfPEntity_Post EntOffsetOfPEntity_Post
|
||||
// #define FN_IndexOfEdict_Post IndexOfEdict_Post
|
||||
// #define FN_PEntityOfEntIndex_Post PEntityOfEntIndex_Post
|
||||
// #define FN_FindEntityByVars_Post FindEntityByVars_Post
|
||||
// #define FN_GetModelPtr_Post GetModelPtr_Post
|
||||
// #define FN_RegUserMsg_Post RegUserMsg_Post
|
||||
// #define FN_AnimationAutomove_Post AnimationAutomove_Post
|
||||
// #define FN_GetBonePosition_Post GetBonePosition_Post
|
||||
// #define FN_FunctionFromName_Post FunctionFromName_Post
|
||||
// #define FN_NameForFunction_Post NameForFunction_Post
|
||||
// #define FN_ClientPrintf_Post ClientPrintf_Post
|
||||
// #define FN_ServerPrint_Post ServerPrint_Post
|
||||
// #define FN_Cmd_Args_Post Cmd_Args_Post
|
||||
// #define FN_Cmd_Argv_Post Cmd_Argv_Post
|
||||
// #define FN_Cmd_Argc_Post Cmd_Argc_Post
|
||||
// #define FN_GetAttachment_Post GetAttachment_Post
|
||||
// #define FN_CRC32_Init_Post CRC32_Init_Post
|
||||
// #define FN_CRC32_ProcessBuffer_Post CRC32_ProcessBuffer_Post
|
||||
// #define FN_CRC32_ProcessByte_Post CRC32_ProcessByte_Post
|
||||
// #define FN_CRC32_Final_Post CRC32_Final_Post
|
||||
// #define FN_RandomLong_Post RandomLong_Post
|
||||
// #define FN_RandomFloat_Post RandomFloat_Post
|
||||
// #define FN_SetView_Post SetView_Post
|
||||
// #define FN_Time_Post Time_Post
|
||||
// #define FN_CrosshairAngle_Post CrosshairAngle_Post
|
||||
// #define FN_LoadFileForMe_Post LoadFileForMe_Post
|
||||
// #define FN_FreeFile_Post FreeFile_Post
|
||||
// #define FN_EndSection_Post EndSection_Post
|
||||
// #define FN_CompareFileTime_Post CompareFileTime_Post
|
||||
// #define FN_GetGameDir_Post GetGameDir_Post
|
||||
// #define FN_Cvar_RegisterVariable_Post Cvar_RegisterVariable_Post
|
||||
// #define FN_FadeClientVolume_Post FadeClientVolume_Post
|
||||
// #define FN_SetClientMaxspeed_Post SetClientMaxspeed_Post
|
||||
// #define FN_CreateFakeClient_Post CreateFakeClient_Post
|
||||
// #define FN_RunPlayerMove_Post RunPlayerMove_Post
|
||||
// #define FN_NumberOfEntities_Post NumberOfEntities_Post
|
||||
// #define FN_GetInfoKeyBuffer_Post GetInfoKeyBuffer_Post
|
||||
// #define FN_InfoKeyValue_Post InfoKeyValue_Post
|
||||
// #define FN_SetKeyValue_Post SetKeyValue_Post
|
||||
// #define FN_SetClientKeyValue_Post SetClientKeyValue_Post
|
||||
// #define FN_IsMapValid_Post IsMapValid_Post
|
||||
// #define FN_StaticDecal_Post StaticDecal_Post
|
||||
// #define FN_PrecacheGeneric_Post PrecacheGeneric_Post
|
||||
// #define FN_GetPlayerUserId_Post GetPlayerUserId_Post
|
||||
// #define FN_BuildSoundMsg_Post BuildSoundMsg_Post
|
||||
// #define FN_IsDedicatedServer_Post IsDedicatedServer_Post
|
||||
// #define FN_CVarGetPointer_Post CVarGetPointer_Post
|
||||
// #define FN_GetPlayerWONId_Post GetPlayerWONId_Post
|
||||
// #define FN_Info_RemoveKey_Post Info_RemoveKey_Post
|
||||
// #define FN_GetPhysicsKeyValue_Post GetPhysicsKeyValue_Post
|
||||
// #define FN_SetPhysicsKeyValue_Post SetPhysicsKeyValue_Post
|
||||
// #define FN_GetPhysicsInfoString_Post GetPhysicsInfoString_Post
|
||||
//#define FN_PrecacheEvent_Post PrecacheEvent_Post
|
||||
// #define FN_PlaybackEvent_Post PlaybackEvent_Post
|
||||
// #define FN_SetFatPVS_Post SetFatPVS_Post
|
||||
// #define FN_SetFatPAS_Post SetFatPAS_Post
|
||||
// #define FN_CheckVisibility_Post CheckVisibility_Post
|
||||
// #define FN_DeltaSetField_Post DeltaSetField_Post
|
||||
// #define FN_DeltaUnsetField_Post DeltaUnsetField_Post
|
||||
// #define FN_DeltaAddEncoder_Post DeltaAddEncoder_Post
|
||||
// #define FN_GetCurrentPlayer_Post GetCurrentPlayer_Post
|
||||
// #define FN_CanSkipPlayer_Post CanSkipPlayer_Post
|
||||
// #define FN_DeltaFindField_Post DeltaFindField_Post
|
||||
// #define FN_DeltaSetFieldByIndex_Post DeltaSetFieldByIndex_Post
|
||||
// #define FN_DeltaUnsetFieldByIndex_Post DeltaUnsetFieldByIndex_Post
|
||||
// #define FN_SetGroupMask_Post SetGroupMask_Post
|
||||
// #define FN_engCreateInstancedBaseline_Post engCreateInstancedBaseline_Post
|
||||
// #define FN_Cvar_DirectSet_Post Cvar_DirectSet_Post
|
||||
// #define FN_ForceUnmodified_Post ForceUnmodified_Post
|
||||
// #define FN_GetPlayerStats_Post GetPlayerStats_Post
|
||||
// #define FN_AddServerCommand_Post AddServerCommand_Post
|
||||
// #define FN_Voice_GetClientListening_Post Voice_GetClientListening_Post
|
||||
// #define FN_Voice_SetClientListening_Post Voice_SetClientListening_Post
|
||||
// #define FN_GetPlayerAuthId_Post GetPlayerAuthId_Post
|
||||
|
||||
// #define FN_OnFreeEntPrivateData OnFreeEntPrivateData
|
||||
// #define FN_GameShutdown GameShutdown
|
||||
// #define FN_ShouldCollide ShouldCollide
|
||||
|
||||
// #define FN_OnFreeEntPrivateData_Post OnFreeEntPrivateData_Post
|
||||
// #define FN_GameShutdown_Post GameShutdown_Post
|
||||
// #define FN_ShouldCollide_Post ShouldCollide_Post
|
||||
|
||||
|
||||
#endif // USE_METAMOD
|
||||
|
||||
#endif // __MODULECONFIG_H__
|
280
dlls/hamsandwich/tableentries/Blocked.cpp
Normal file
280
dlls/hamsandwich/tableentries/Blocked.cpp
Normal file
|
@ -0,0 +1,280 @@
|
|||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "hamsandwich.h"
|
||||
|
||||
#include "VTableManager.h"
|
||||
#include "VTableEntries.h"
|
||||
|
||||
#include "vfunc_gcc295.h"
|
||||
#include "vfunc_msvc.h"
|
||||
|
||||
#include "NEW_Util.h"
|
||||
|
||||
// Change these on a per-hook basis! Auto-changes all the annoying fields in the following functions
|
||||
#define ThisVTable VTableBlocked
|
||||
#define ThisEntries BlockedEntries
|
||||
#define ThisHook VHOOK_Blocked
|
||||
|
||||
unsigned int *ThisVTable::pevoffset=NULL;
|
||||
unsigned int *ThisVTable::pevset=NULL;
|
||||
unsigned int *ThisVTable::baseoffset=NULL;
|
||||
unsigned int *ThisVTable::baseset=0;
|
||||
unsigned int ThisVTable::index=0;
|
||||
unsigned int ThisVTable::indexset=0;
|
||||
|
||||
static AMX_NATIVE_INFO registernatives[] = {
|
||||
{ "register_blocked", ThisVTable::RegisterNative },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static AMX_NATIVE_INFO callnatives[] = {
|
||||
{ "hs_blocked", ThisVTable::NativeCall },
|
||||
{ "hs_eblocked", ThisVTable::ENativeCall },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize this table hook. This also registers our required keyvalue suffixes to the file parser.
|
||||
*
|
||||
* @param poffset Pointer to an integer that stores the pev offset for this mod.
|
||||
* @param pset Pointer to an integer that tells whether pev offset was set or not.
|
||||
* @param baseoffs Pointer to an integer that stores the class base offset for this mod. (GCC 2.95 only required)
|
||||
* @param baseset Pointer to an integer that tells whether class base offset has been set.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Initialize(unsigned int *poffset, unsigned int *pset, unsigned int *baseoffs, unsigned int *baseset)
|
||||
{
|
||||
ThisVTable::pevoffset=poffset;
|
||||
ThisVTable::pevset=pset;
|
||||
|
||||
ThisVTable::baseoffset=baseoffs;
|
||||
ThisVTable::baseset=baseset;
|
||||
|
||||
ThisVTable::index=0;
|
||||
ThisVTable::indexset=0;
|
||||
|
||||
RegisterConfigCallback(ThisVTable::ConfigDone);
|
||||
|
||||
RegisterKeySuffix("blocked",ThisVTable::KeyValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when one of this table entry's keyvalues is caught in a config file.
|
||||
*
|
||||
* @param key The keyvalue suffix ("<mod>_<os>_" is removed)
|
||||
* @param data The data this keyvalue is set to.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::KeyValue(const char *key, const char *data)
|
||||
{
|
||||
if (strcmp(key,"blocked")==0)
|
||||
{
|
||||
ThisVTable::index=HAM_StrToNum(data);
|
||||
ThisVTable::indexset=1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called immediately after the config file is done being parsed. Register our natives here.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::ConfigDone(void)
|
||||
{
|
||||
if (ThisVTable::indexset && *(ThisVTable::baseset))
|
||||
{
|
||||
MF_AddNatives(callnatives);
|
||||
|
||||
if (*(ThisVTable::pevset))
|
||||
{
|
||||
MF_AddNatives(registernatives);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is registering this entry's virtual hook. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::RegisterNative(AMX *amx, cell *params)
|
||||
{
|
||||
int funcid;
|
||||
char *function=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
|
||||
if (MF_AmxFindPublic(amx,function,&funcid)!=AMX_ERR_NONE)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Can not find function \"%s\"",function);
|
||||
return 0;
|
||||
}
|
||||
// Get the classname
|
||||
char *classname=MF_GetAmxString(amx,params[1],1,NULL);
|
||||
|
||||
// create an entity, assign it the gamedll's class, hook it and destroy it
|
||||
edict_t *Entity=CREATE_ENTITY();
|
||||
|
||||
CALL_GAME_ENTITY(PLID,classname,&Entity->v);
|
||||
|
||||
if (Entity->pvPrivateData)
|
||||
{
|
||||
ThisVTable::Hook(&VTMan,EdictToVTable(Entity),amx,funcid);
|
||||
REMOVE_ENTITY(Entity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
REMOVE_ENTITY(Entity);
|
||||
// class was not found
|
||||
// throw an error alerting console that this hook did not happen
|
||||
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function);
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::NativeCall(AMX *amx, cell *params)
|
||||
{
|
||||
// TODO: This
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function, and will be exposed to all hooks. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::ENativeCall(AMX *amx, cell *params)
|
||||
{
|
||||
VoidVCall1(
|
||||
INDEXENT_NEW(params[1])->pvPrivateData, /*this*/
|
||||
ThisVTable::index, /*vtable entry*/
|
||||
*(ThisVTable::baseoffset), /*size of class*/
|
||||
INDEXENT_NEW(params[2])->pvPrivateData /*other*/
|
||||
);
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook this entry's function! This creates our trampoline and modifies the virtual table.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param outtrampoline The trampoline that was created.
|
||||
* @param origfunc The original function that was hooked.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc)
|
||||
{
|
||||
|
||||
VTableEntryBase::CreateGenericTrampoline(manager,
|
||||
vtable,
|
||||
ThisVTable::index,
|
||||
id,
|
||||
outtrampoline,
|
||||
origfunc,
|
||||
reinterpret_cast<void *>(ThisHook),
|
||||
1, // param count
|
||||
1, // voidcall
|
||||
1); // thiscall
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the virtual function is already being hooked or not. If it's not, it begins hooking it. Either way it registers a forward and adds it to our vector.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param plugin The plugin that's requesting this.
|
||||
* @param funcid The function id of the callback.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid)
|
||||
{
|
||||
void *ptr=vtable[ThisVTable::index];
|
||||
|
||||
int i=0;
|
||||
int end=manager->ThisEntries.size();
|
||||
int fwd=MF_RegisterSPForward(plugin,funcid,FP_CELL/*this*/,FP_CELL/*other*/,FP_DONE);
|
||||
while (i<end)
|
||||
{
|
||||
if (manager->ThisEntries[i]->IsTrampoline(ptr))
|
||||
{
|
||||
// this function is already hooked!
|
||||
|
||||
manager->ThisEntries[i]->AddForward(fwd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
// this function is NOT hooked
|
||||
void *tramp;
|
||||
void *func;
|
||||
ThisVTable::CreateHook(manager,vtable,manager->ThisEntries.size(),&tramp,&func);
|
||||
ThisVTable *entry=new ThisVTable;
|
||||
|
||||
entry->Setup(&vtable[ThisVTable::index],tramp,func);
|
||||
|
||||
manager->ThisEntries.push_back(entry);
|
||||
|
||||
entry->AddForward(fwd);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command. This is called directly from our global hook function.
|
||||
*
|
||||
* @param pthis The "this" pointer, cast to a void. The victim.
|
||||
* @param activator Entity causing the opening.
|
||||
* @param caller Entity controlling the caller.
|
||||
* @param type USE_TYPE (USE_{ON,OFF,SET}
|
||||
* @param value Use value, only seen set when USE_SET is used.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Execute(void *pthis, void *other)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
int end=Forwards.size();
|
||||
|
||||
int result=HAM_UNSET;
|
||||
int thisresult=HAM_UNSET;
|
||||
|
||||
int iThis=PrivateToIndex(pthis);
|
||||
int iOther=PrivateToIndex(other);
|
||||
|
||||
while (i<end)
|
||||
{
|
||||
thisresult=MF_ExecuteForward(Forwards[i++],iThis,iOther);
|
||||
|
||||
if (thisresult>result)
|
||||
{
|
||||
result=thisresult;
|
||||
}
|
||||
};
|
||||
|
||||
if (result>=HAM_SUPERCEDE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
reinterpret_cast<void (__fastcall *)(void *,int, void *)>(function)(pthis,0,other);
|
||||
#elif defined __linux__
|
||||
reinterpret_cast<void (*)(void *,void *)>(function)(pthis,other);
|
||||
#endif
|
||||
|
||||
|
||||
};
|
322
dlls/hamsandwich/tableentries/TakeDamage.cpp
Normal file
322
dlls/hamsandwich/tableentries/TakeDamage.cpp
Normal file
|
@ -0,0 +1,322 @@
|
|||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "hamsandwich.h"
|
||||
|
||||
#include "hooks.h"
|
||||
#include "VTableManager.h"
|
||||
#include "VTableEntries.h"
|
||||
|
||||
#include "vfunc_gcc295.h"
|
||||
#include "vfunc_msvc.h"
|
||||
|
||||
#include "NEW_Util.h"
|
||||
|
||||
// Change these on a per-hook basis! Auto-changes all the annoying fields in the following functions
|
||||
#define ThisVTable VTableTakeDamage
|
||||
#define ThisEntries TakeDamageEntries
|
||||
#define ThisHook VHOOK_TakeDamage
|
||||
|
||||
unsigned int *ThisVTable::pevoffset=NULL;
|
||||
unsigned int *ThisVTable::pevset=NULL;
|
||||
unsigned int *ThisVTable::baseoffset=NULL;
|
||||
unsigned int *ThisVTable::baseset=0;
|
||||
unsigned int ThisVTable::index=0;
|
||||
unsigned int ThisVTable::indexset=0;
|
||||
|
||||
static AMX_NATIVE_INFO registernatives[] = {
|
||||
{ "register_takedamage", ThisVTable::RegisterNative },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static AMX_NATIVE_INFO callnatives[] = {
|
||||
{ "hs_takedamage", ThisVTable::NativeCall },
|
||||
{ "hs_etakedamage", ThisVTable::ENativeCall },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize this table hook. This also registers our required keyvalue suffixes to the file parser.
|
||||
*
|
||||
* @param poffset Pointer to an integer that stores the pev offset for this mod.
|
||||
* @param pset Pointer to an integer that tells whether pev offset was set or not.
|
||||
* @param baseoffs Pointer to an integer that stores the class base offset for this mod. (GCC 2.95 only required)
|
||||
* @param baseset Pointer to an integer that tells whether class base offset has been set.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Initialize(unsigned int *poffset, unsigned int *pset, unsigned int *baseoffs, unsigned int *baseset)
|
||||
{
|
||||
ThisVTable::pevoffset=poffset;
|
||||
ThisVTable::pevset=pset;
|
||||
|
||||
ThisVTable::baseoffset=baseoffs;
|
||||
ThisVTable::baseset=baseset;
|
||||
|
||||
ThisVTable::index=0;
|
||||
ThisVTable::indexset=0;
|
||||
|
||||
RegisterConfigCallback(ThisVTable::ConfigDone);
|
||||
|
||||
RegisterKeySuffix("takedamage",ThisVTable::KeyValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when one of this table entry's keyvalues is caught in a config file.
|
||||
*
|
||||
* @param key The keyvalue suffix ("<mod>_<os>_" is removed)
|
||||
* @param data The data this keyvalue is set to.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::KeyValue(const char *key, const char *data)
|
||||
{
|
||||
if (strcmp(key,"takedamage")==0)
|
||||
{
|
||||
ThisVTable::index=HAM_StrToNum(data);
|
||||
ThisVTable::indexset=1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called immediately after the config file is done being parsed. Register our natives here.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::ConfigDone(void)
|
||||
{
|
||||
if (ThisVTable::indexset && *(ThisVTable::baseset))
|
||||
{
|
||||
MF_AddNatives(callnatives);
|
||||
|
||||
if (*(ThisVTable::pevset))
|
||||
{
|
||||
MF_AddNatives(registernatives);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is registering this entry's virtual hook. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::RegisterNative(AMX *amx, cell *params)
|
||||
{
|
||||
int funcid;
|
||||
char *function=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
|
||||
if (MF_AmxFindPublic(amx,function,&funcid)!=AMX_ERR_NONE)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Can not find function \"%s\"",function);
|
||||
return 0;
|
||||
}
|
||||
// Get the classname
|
||||
char *classname=MF_GetAmxString(amx,params[1],1,NULL);
|
||||
|
||||
// create an entity, assign it the gamedll's class, hook it and destroy it
|
||||
edict_t *Entity=CREATE_ENTITY();
|
||||
|
||||
CALL_GAME_ENTITY(PLID,classname,&Entity->v);
|
||||
|
||||
if (Entity->pvPrivateData)
|
||||
{
|
||||
ThisVTable::Hook(&VTMan,EdictToVTable(Entity),amx,funcid);
|
||||
REMOVE_ENTITY(Entity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
REMOVE_ENTITY(Entity);
|
||||
// class was not found
|
||||
// throw an error alerting console that this hook did not happen
|
||||
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function);
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::NativeCall(AMX *amx, cell *params)
|
||||
{
|
||||
// scan to see if this virtual function is a trampoline
|
||||
void *pthis=INDEXENT_NEW(params[1])->pvPrivateData;
|
||||
void *func=GetVTableEntry(pthis,ThisVTable::index,*ThisVTable::baseoffset);
|
||||
|
||||
int i=0;
|
||||
int end=VTMan.ThisEntries.size();
|
||||
|
||||
while (i<end)
|
||||
{
|
||||
if (VTMan.ThisEntries[i]->IsTrampoline(func))
|
||||
{
|
||||
// this function is a trampoline
|
||||
// use the original function instead
|
||||
func=VTMan.ThisEntries[i]->GetOriginalFunction();
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
// TODO: Inline ASM this
|
||||
#ifdef _WIN32
|
||||
return reinterpret_cast<int (__fastcall *)(void *,int,void *,void *,float,int)>(func)(
|
||||
pthis, /*this*/
|
||||
0, /*fastcall buffer*/
|
||||
&(INDEXENT_NEW(params[2])->v), /*inflictor*/
|
||||
&(INDEXENT_NEW(params[3])->v), /*attacker*/
|
||||
amx_ctof2(params[4]), /*damage*/
|
||||
(int)params[5] /*dmgtype*/
|
||||
);
|
||||
#else
|
||||
return reinterpret_cast<int (*)(void *,void *,void *,float,int)>(func)(
|
||||
pthis, /*this*/
|
||||
&(INDEXENT_NEW(params[2])->v), /*inflictor*/
|
||||
&(INDEXENT_NEW(params[3])->v), /*attacker*/
|
||||
amx_ctof2(params[4]), /*damage*/
|
||||
(int)params[5] /*dmgtype*/
|
||||
);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function, and will be exposed to all hooks. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::ENativeCall(AMX *amx, cell *params)
|
||||
{
|
||||
return VCall4<int>(
|
||||
INDEXENT_NEW(params[1])->pvPrivateData, /*this*/
|
||||
ThisVTable::index, /*vtable entry*/
|
||||
*(ThisVTable::baseoffset), /*size of class*/
|
||||
&(INDEXENT_NEW(params[2])->v), /*inflictor*/
|
||||
&(INDEXENT_NEW(params[3])->v), /*attacker*/
|
||||
amx_ctof2(params[4]), /*damage*/
|
||||
(int)params[5] /*dmgtype*/
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook this entry's function! This creates our trampoline and modifies the virtual table.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param outtrampoline The trampoline that was created.
|
||||
* @param origfunc The original function that was hooked.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc)
|
||||
{
|
||||
|
||||
VTableEntryBase::CreateGenericTrampoline(manager,
|
||||
vtable,
|
||||
ThisVTable::index,
|
||||
id,
|
||||
outtrampoline,
|
||||
origfunc,
|
||||
reinterpret_cast<void *>(ThisHook),
|
||||
4, // param count
|
||||
0, // voidcall
|
||||
1); // thiscall
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the virtual function is already being hooked or not. If it's not, it begins hooking it. Either way it registers a forward and adds it to our vector.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param plugin The plugin that's requesting this.
|
||||
* @param funcid The function id of the callback.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid)
|
||||
{
|
||||
void *ptr=vtable[ThisVTable::index];
|
||||
|
||||
int i=0;
|
||||
int end=manager->ThisEntries.size();
|
||||
int fwd=MF_RegisterSPForward(plugin,funcid,FP_CELL/*this*/,FP_CELL/*inflictor*/,FP_CELL/*attacker*/,FP_CELL/*damage*/,FP_CELL/*type*/,FP_DONE);
|
||||
while (i<end)
|
||||
{
|
||||
if (manager->ThisEntries[i]->IsTrampoline(ptr))
|
||||
{
|
||||
// this function is already hooked!
|
||||
|
||||
manager->ThisEntries[i]->AddForward(fwd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
// this function is NOT hooked
|
||||
void *tramp;
|
||||
void *func;
|
||||
ThisVTable::CreateHook(manager,vtable,manager->ThisEntries.size(),&tramp,&func);
|
||||
ThisVTable *entry=new ThisVTable;
|
||||
|
||||
entry->Setup(&vtable[ThisVTable::index],tramp,func);
|
||||
|
||||
manager->ThisEntries.push_back(entry);
|
||||
|
||||
entry->AddForward(fwd);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command. This is called directly from our global hook function.
|
||||
*
|
||||
* @param pthis The "this" pointer, cast to a void. The victim.
|
||||
* @param inflictor Damage inflictor.
|
||||
* @param attacker The attacker who caused the inflictor to damage the victim.
|
||||
* @param damage How much damage was caused.
|
||||
* @param type Damage type (usually in bitmask form).
|
||||
* @return Unsure. Does not appear to be used.
|
||||
*/
|
||||
int ThisVTable::Execute(void *pthis, void *inflictor, void *attacker, float damage, int type)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
int end=Forwards.size();
|
||||
|
||||
int result=HAM_UNSET;
|
||||
int thisresult=HAM_UNSET;
|
||||
|
||||
int iThis=PrivateToIndex(pthis);
|
||||
int iInflictor=EntvarToIndex((entvars_t *)inflictor);
|
||||
int iAttacker=EntvarToIndex((entvars_t *)attacker);
|
||||
|
||||
while (i<end)
|
||||
{
|
||||
thisresult=MF_ExecuteForward(Forwards[i++],iThis,iInflictor,iAttacker,amx_ftoc2(damage),type);
|
||||
|
||||
if (thisresult>result)
|
||||
{
|
||||
result=thisresult;
|
||||
}
|
||||
};
|
||||
|
||||
// stop here
|
||||
if (result>=HAM_SUPERCEDE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
int ireturn=reinterpret_cast<int (__fastcall *)(void *,int,void *,void *,float,int)>(function)(pthis,0,inflictor,attacker,damage,type);
|
||||
#elif defined __linux__
|
||||
int ireturn=reinterpret_cast<int (*)(void *,void *,void *,float,int)>(function)(pthis,inflictor,attacker,damage,type);
|
||||
#endif
|
||||
|
||||
if (result!=HAM_OVERRIDE)
|
||||
return ireturn;
|
||||
|
||||
return 0;
|
||||
};
|
282
dlls/hamsandwich/tableentries/Use.cpp
Normal file
282
dlls/hamsandwich/tableentries/Use.cpp
Normal file
|
@ -0,0 +1,282 @@
|
|||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "hamsandwich.h"
|
||||
|
||||
#include "VTableManager.h"
|
||||
#include "VTableEntries.h"
|
||||
|
||||
#include "vfunc_gcc295.h"
|
||||
#include "vfunc_msvc.h"
|
||||
|
||||
#include "NEW_Util.h"
|
||||
|
||||
// Change these on a per-hook basis! Auto-changes all the annoying fields in the following functions
|
||||
#define ThisVTable VTableUse
|
||||
#define ThisEntries UseEntries
|
||||
#define ThisHook VHOOK_Use
|
||||
|
||||
unsigned int *ThisVTable::pevoffset=NULL;
|
||||
unsigned int *ThisVTable::pevset=NULL;
|
||||
unsigned int *ThisVTable::baseoffset=NULL;
|
||||
unsigned int *ThisVTable::baseset=0;
|
||||
unsigned int ThisVTable::index=0;
|
||||
unsigned int ThisVTable::indexset=0;
|
||||
|
||||
static AMX_NATIVE_INFO registernatives[] = {
|
||||
{ "register_use", ThisVTable::RegisterNative },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static AMX_NATIVE_INFO callnatives[] = {
|
||||
{ "hs_use", ThisVTable::NativeCall },
|
||||
{ "hs_euse", ThisVTable::ENativeCall },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize this table hook. This also registers our required keyvalue suffixes to the file parser.
|
||||
*
|
||||
* @param poffset Pointer to an integer that stores the pev offset for this mod.
|
||||
* @param pset Pointer to an integer that tells whether pev offset was set or not.
|
||||
* @param baseoffs Pointer to an integer that stores the class base offset for this mod. (GCC 2.95 only required)
|
||||
* @param baseset Pointer to an integer that tells whether class base offset has been set.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Initialize(unsigned int *poffset, unsigned int *pset, unsigned int *baseoffs, unsigned int *baseset)
|
||||
{
|
||||
ThisVTable::pevoffset=poffset;
|
||||
ThisVTable::pevset=pset;
|
||||
|
||||
ThisVTable::baseoffset=baseoffs;
|
||||
ThisVTable::baseset=baseset;
|
||||
|
||||
ThisVTable::index=0;
|
||||
ThisVTable::indexset=0;
|
||||
|
||||
RegisterConfigCallback(ThisVTable::ConfigDone);
|
||||
|
||||
RegisterKeySuffix("use",ThisVTable::KeyValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when one of this table entry's keyvalues is caught in a config file.
|
||||
*
|
||||
* @param key The keyvalue suffix ("<mod>_<os>_" is removed)
|
||||
* @param data The data this keyvalue is set to.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::KeyValue(const char *key, const char *data)
|
||||
{
|
||||
if (strcmp(key,"use")==0)
|
||||
{
|
||||
ThisVTable::index=HAM_StrToNum(data);
|
||||
ThisVTable::indexset=1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called immediately after the config file is done being parsed. Register our natives here.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::ConfigDone(void)
|
||||
{
|
||||
if (ThisVTable::indexset && *(ThisVTable::baseset))
|
||||
{
|
||||
MF_AddNatives(callnatives);
|
||||
|
||||
if (*(ThisVTable::pevset))
|
||||
{
|
||||
MF_AddNatives(registernatives);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is registering this entry's virtual hook. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::RegisterNative(AMX *amx, cell *params)
|
||||
{
|
||||
int funcid;
|
||||
char *function=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
|
||||
if (MF_AmxFindPublic(amx,function,&funcid)!=AMX_ERR_NONE)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Can not find function \"%s\"",function);
|
||||
return 0;
|
||||
}
|
||||
// Get the classname
|
||||
char *classname=MF_GetAmxString(amx,params[1],1,NULL);
|
||||
|
||||
// create an entity, assign it the gamedll's class, hook it and destroy it
|
||||
edict_t *Entity=CREATE_ENTITY();
|
||||
|
||||
CALL_GAME_ENTITY(PLID,classname,&Entity->v);
|
||||
|
||||
if (Entity->pvPrivateData)
|
||||
{
|
||||
ThisVTable::Hook(&VTMan,EdictToVTable(Entity),amx,funcid);
|
||||
REMOVE_ENTITY(Entity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
REMOVE_ENTITY(Entity);
|
||||
// class was not found
|
||||
// throw an error alerting console that this hook did not happen
|
||||
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function);
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::NativeCall(AMX *amx, cell *params)
|
||||
{
|
||||
// TODO: This
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function, and will be exposed to all hooks. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
cell ThisVTable::ENativeCall(AMX *amx, cell *params)
|
||||
{
|
||||
VoidVCall4(
|
||||
INDEXENT_NEW(params[1])->pvPrivateData, /*this*/
|
||||
ThisVTable::index, /*vtable entry*/
|
||||
*(ThisVTable::baseoffset), /*size of class*/
|
||||
INDEXENT_NEW(params[2])->pvPrivateData, /*activator*/
|
||||
INDEXENT_NEW(params[3])->pvPrivateData, /*caller*/
|
||||
params[4], /*type*/
|
||||
amx_ctof2(params[5])); /*value*/
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook this entry's function! This creates our trampoline and modifies the virtual table.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param outtrampoline The trampoline that was created.
|
||||
* @param origfunc The original function that was hooked.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc)
|
||||
{
|
||||
|
||||
VTableEntryBase::CreateGenericTrampoline(manager,
|
||||
vtable,
|
||||
ThisVTable::index,
|
||||
id,
|
||||
outtrampoline,
|
||||
origfunc,
|
||||
reinterpret_cast<void *>(ThisHook),
|
||||
4, // param count
|
||||
1, // voidcall
|
||||
1); // thiscall
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the virtual function is already being hooked or not. If it's not, it begins hooking it. Either way it registers a forward and adds it to our vector.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param plugin The plugin that's requesting this.
|
||||
* @param funcid The function id of the callback.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid)
|
||||
{
|
||||
void *ptr=vtable[ThisVTable::index];
|
||||
|
||||
int i=0;
|
||||
int end=manager->ThisEntries.size();
|
||||
int fwd=MF_RegisterSPForward(plugin,funcid,FP_CELL/*this*/,FP_CELL/*inflictor*/,FP_CELL/*attacker*/,FP_CELL/*damage*/,FP_CELL/*type*/,FP_DONE);
|
||||
while (i<end)
|
||||
{
|
||||
if (manager->ThisEntries[i]->IsTrampoline(ptr))
|
||||
{
|
||||
// this function is already hooked!
|
||||
|
||||
manager->ThisEntries[i]->AddForward(fwd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
// this function is NOT hooked
|
||||
void *tramp;
|
||||
void *func;
|
||||
ThisVTable::CreateHook(manager,vtable,manager->ThisEntries.size(),&tramp,&func);
|
||||
ThisVTable *entry=new ThisVTable;
|
||||
|
||||
entry->Setup(&vtable[ThisVTable::index],tramp,func);
|
||||
|
||||
manager->ThisEntries.push_back(entry);
|
||||
|
||||
entry->AddForward(fwd);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command. This is called directly from our global hook function.
|
||||
*
|
||||
* @param pthis The "this" pointer, cast to a void. The victim.
|
||||
* @param activator Entity causing the opening.
|
||||
* @param caller Entity controlling the caller.
|
||||
* @param type USE_TYPE (USE_{ON,OFF,SET}
|
||||
* @param value Use value, only seen set when USE_SET is used.
|
||||
* @noreturn
|
||||
*/
|
||||
void ThisVTable::Execute(void *pthis, void *activator, void *caller, int type, float value)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
int end=Forwards.size();
|
||||
|
||||
int result=HAM_UNSET;
|
||||
int thisresult=HAM_UNSET;
|
||||
|
||||
int iThis=PrivateToIndex(pthis);
|
||||
int iActivator=PrivateToIndex(activator);
|
||||
int iCaller=PrivateToIndex(caller);
|
||||
|
||||
while (i<end)
|
||||
{
|
||||
thisresult=MF_ExecuteForward(Forwards[i++],iThis,iActivator,iCaller,type,amx_ftoc2(value));
|
||||
|
||||
if (thisresult>result)
|
||||
{
|
||||
result=thisresult;
|
||||
}
|
||||
};
|
||||
|
||||
if (result>=HAM_SUPERCEDE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
reinterpret_cast<void (__fastcall *)(void *,int,void *,void *,int,float)>(function)(pthis,0,activator,caller,type,value);
|
||||
#elif defined __linux__
|
||||
reinterpret_cast<void (*)(void *,void *,void *,int,float)>(function)(pthis,activator,caller,type,value);
|
||||
#endif
|
||||
|
||||
};
|
462
dlls/hamsandwich/tableentries/VTableEntries.h
Normal file
462
dlls/hamsandwich/tableentries/VTableEntries.h
Normal file
|
@ -0,0 +1,462 @@
|
|||
/* Ham Sandwich
|
||||
*
|
||||
* by the AMX Mod X Dev Team
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VTABLEENTRIES_H
|
||||
#define VTABLEENTRIES_H
|
||||
|
||||
#include "CVector.h"
|
||||
|
||||
#include "hooks.h"
|
||||
|
||||
class VTableManager;
|
||||
|
||||
class VTableEntryBase
|
||||
{
|
||||
public:
|
||||
void *function; /**< The pointer to the original function that is being hooked. */
|
||||
void **location; /**< The location of the vtable entry that is being hooked. */
|
||||
void *trampoline; /**< Our trampoline (needs to be freed when it's not hooking any more!). */
|
||||
CVector<int> Forwards; /**< Vector of forwards to call for this hook.*/
|
||||
|
||||
/**
|
||||
* Saves virtual table location, trampoline and function pointers.
|
||||
*
|
||||
* @param vt Pointer to the index in the virtual table.
|
||||
* @param tramp Pointer to the trampoline.
|
||||
* @param func Pointer to the original function.
|
||||
* @noreturn
|
||||
*/
|
||||
void Setup(void **vt,void *tramp, void *func)
|
||||
{
|
||||
location=vt;
|
||||
trampoline=tramp;
|
||||
function=func;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Manually called by VTableManager at destruction. Treat this like a dtor.
|
||||
*
|
||||
* @see VTableManager::Cleanup()
|
||||
* @noreturn
|
||||
*/
|
||||
void Destroy()
|
||||
{
|
||||
// restore original location
|
||||
if (location)
|
||||
{
|
||||
#if defined _WIN32
|
||||
DWORD OldFlags;
|
||||
VirtualProtect(location,sizeof(int*),PAGE_READWRITE,&OldFlags);
|
||||
#elif defined __linux__
|
||||
mprotect(location,sizeof(int*),PROT_READ|PROT_WRITE);
|
||||
#endif
|
||||
|
||||
*location=function;
|
||||
}
|
||||
|
||||
// free the trampoline
|
||||
free(trampoline);
|
||||
|
||||
Forwards.clear();
|
||||
|
||||
};
|
||||
/**
|
||||
* Tells whether the given pointer is this entry's trampoline.
|
||||
*
|
||||
* @param ptr Pointer (cast to void*) of the function in question.
|
||||
* @return true: Yes, the pointer in question is this entry's trampoline.
|
||||
* fase: No, the pointer in question is not this entry's trampoline.
|
||||
*/
|
||||
bool IsTrampoline(void *ptr)
|
||||
{
|
||||
return (ptr==trampoline);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the pointer (cast to void*) of the original function which is being hooked.
|
||||
*
|
||||
* @return Original function pointer, cast to void*.
|
||||
*/
|
||||
void *GetOriginalFunction(void)
|
||||
{
|
||||
return function;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the location of this entry's virtual table entry itself.
|
||||
*
|
||||
* @return Pointer to this entry's virtual table entry.
|
||||
*/
|
||||
void **GetLocation(void)
|
||||
{
|
||||
return location;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a pointer to this entry's trampoline.
|
||||
*
|
||||
* @return Trampoline pointer, cast to void*.
|
||||
*/
|
||||
void *GetTrampoline(void)
|
||||
{
|
||||
return trampoline;
|
||||
};
|
||||
/**
|
||||
* Adds a forward to this entry's forward vector.
|
||||
*
|
||||
* @param fwd Forward index to add.
|
||||
* @noreturn
|
||||
*/
|
||||
void AddForward(int fwd)
|
||||
{
|
||||
Forwards.push_back(fwd);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a generic trampoline.
|
||||
*
|
||||
* @param manager The VTableManager this entry belongs to.
|
||||
* @param vtable Pointer to the virtual table to molest.
|
||||
* @param vindex VTable index to replace.
|
||||
* @param id The unique id of this trampoline.
|
||||
* @param outtrampoline Gets set to the location of the trampoline.
|
||||
* @param origfunc Gets set to the original function which is being hooked.
|
||||
* @param calee Target function this trampoline will call.
|
||||
* @param paramcount How many parameters this trampoline pushes.
|
||||
* @param voidcall Set to 1, this function does not return. 0 otherwise.
|
||||
* @param thiscall Set to 1, treat this function like a thiscall.
|
||||
*/
|
||||
static void CreateGenericTrampoline(VTableManager *manager, void **vtable, int vtableindex, int id, void **outtrampoline, void **origfunc, void *calee, int paramcount, int voidcall=1, int thiscall=1);
|
||||
|
||||
};
|
||||
|
||||
class VTableTakeDamage : public VTableEntryBase
|
||||
{
|
||||
public:
|
||||
static unsigned int *pevoffset; /**< Offset of pev value (globally stored) */
|
||||
static unsigned int *pevset; /**< Whether or not pev entry has been set */
|
||||
static unsigned int *baseoffset; /**< Offset of the base class (only needed for GCC 2.95). */
|
||||
static unsigned int *baseset; /**< Whether or base offset value has been set. */
|
||||
static unsigned int index; /**< This entry's virtual table index. */
|
||||
static unsigned int indexset; /**< Whether or not this entry's virtual table index has been set. */
|
||||
|
||||
/**
|
||||
* Initialize this table hook. This also registers our required keyvalue suffixes to the file parser.
|
||||
*
|
||||
* @param poffset Pointer to an integer that stores the pev offset for this mod.
|
||||
* @param pset Pointer to an integer that tells whether pev offset was set or not.
|
||||
* @param baseoffs Pointer to an integer that stores the class base offset for this mod. (GCC 2.95 only required)
|
||||
* @param baseset Pointer to an integer that tells whether class base offset has been set.
|
||||
* @noreturn
|
||||
*/
|
||||
static void Initialize(unsigned int *poffset, unsigned int *pset, unsigned int *baseoffs, unsigned int *baseset);
|
||||
|
||||
/**
|
||||
* Called when one of this table entry's keyvalues is caught in a config file.
|
||||
*
|
||||
* @param key The keyvalue suffix ("<mod>_<os>_" is removed)
|
||||
* @param data The data this keyvalue is set to.
|
||||
* @noreturn
|
||||
*/
|
||||
static void KeyValue(const char *key, const char *data);
|
||||
|
||||
/**
|
||||
* Called immediately after the config file is done being parsed. Register our natives here.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
static void ConfigDone(void);
|
||||
|
||||
/**
|
||||
* A plugin is registering this entry's virtual hook. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell RegisterNative(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell NativeCall(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function, and will be exposed to all hooks. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell ENativeCall(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* Hook this entry's function! This creates our trampoline and modifies the virtual table.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param outtrampoline The trampoline that was created.
|
||||
* @param origfunc The original function that was hooked.
|
||||
* @noreturn
|
||||
*/
|
||||
static void CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc);
|
||||
|
||||
/**
|
||||
* Checks if the virtual function is already being hooked or not. If it's not, it begins hooking it. Either way it registers a forward and adds it to our vector.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param plugin The plugin that's requesting this.
|
||||
* @param funcid The function id of the callback.
|
||||
* @noreturn
|
||||
*/
|
||||
static void Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid);
|
||||
|
||||
/**
|
||||
* Execute the command. This is called directly from our global hook function.
|
||||
*
|
||||
* @param pthis The "this" pointer, cast to a void. The victim.
|
||||
* @param inflictor Damage inflictor.
|
||||
* @param attacker The attacker who caused the inflictor to damage the victim.
|
||||
* @param damage How much damage was caused.
|
||||
* @param type Damage type (usually in bitmask form).
|
||||
* @return Unsure. Does not appear to be used.
|
||||
*/
|
||||
int Execute(void *pthis, void *inflictor, void *attacker, float damage, int type);
|
||||
};
|
||||
class VTableUse : public VTableEntryBase
|
||||
{
|
||||
public:
|
||||
static unsigned int *pevoffset; /**< Offset of pev value (globally stored) */
|
||||
static unsigned int *pevset; /**< Whether or not pev entry has been set */
|
||||
static unsigned int *baseoffset; /**< Offset of the base class (only needed for GCC 2.95). */
|
||||
static unsigned int *baseset; /**< Whether or base offset value has been set. */
|
||||
static unsigned int index; /**< This entry's virtual table index. */
|
||||
static unsigned int indexset; /**< Whether or not this entry's virtual table index has been set. */
|
||||
|
||||
/**
|
||||
* Initialize this table hook. This also registers our required keyvalue suffixes to the file parser.
|
||||
*
|
||||
* @param poffset Pointer to an integer that stores the pev offset for this mod.
|
||||
* @param pset Pointer to an integer that tells whether pev offset was set or not.
|
||||
* @param baseoffs Pointer to an integer that stores the class base offset for this mod. (GCC 2.95 only required)
|
||||
* @param baseset Pointer to an integer that tells whether class base offset has been set.
|
||||
* @noreturn
|
||||
*/
|
||||
static void Initialize(unsigned int *poffset, unsigned int *pset, unsigned int *baseoffs, unsigned int *baseset);
|
||||
|
||||
/**
|
||||
* Called when one of this table entry's keyvalues is caught in a config file.
|
||||
*
|
||||
* @param key The keyvalue suffix ("<mod>_<os>_" is removed)
|
||||
* @param data The data this keyvalue is set to.
|
||||
* @noreturn
|
||||
*/
|
||||
static void KeyValue(const char *key, const char *data);
|
||||
|
||||
/**
|
||||
* Called immediately after the config file is done being parsed. Register our natives here.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
static void ConfigDone(void);
|
||||
|
||||
/**
|
||||
* A plugin is registering this entry's virtual hook. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell RegisterNative(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell NativeCall(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function, and will be exposed to all hooks. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell ENativeCall(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* Hook this entry's function! This creates our trampoline and modifies the virtual table.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param outtrampoline The trampoline that was created.
|
||||
* @param origfunc The original function that was hooked.
|
||||
* @noreturn
|
||||
*/
|
||||
static void CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc);
|
||||
|
||||
/**
|
||||
* Checks if the virtual function is already being hooked or not. If it's not, it begins hooking it. Either way it registers a forward and adds it to our vector.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param plugin The plugin that's requesting this.
|
||||
* @param funcid The function id of the callback.
|
||||
* @noreturn
|
||||
*/
|
||||
static void Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid);
|
||||
|
||||
/**
|
||||
* Execute the command. This is called directly from our global hook function.
|
||||
*
|
||||
* @param pthis The "this" pointer, cast to a void. The victim.
|
||||
* @param activator Entity causing the opening.
|
||||
* @param caller Entity controlling the caller.
|
||||
* @param type USE_TYPE (USE_{ON,OFF,SET}
|
||||
* @param value Use value, only seen set when USE_SET is used.
|
||||
* @noreturn
|
||||
*/
|
||||
void Execute(void *pthis, void *activator, void *caller, int type, float value);
|
||||
};
|
||||
class VTableBlocked : public VTableEntryBase
|
||||
{
|
||||
public:
|
||||
static unsigned int *pevoffset; /**< Offset of pev value (globally stored) */
|
||||
static unsigned int *pevset; /**< Whether or not pev entry has been set */
|
||||
static unsigned int *baseoffset; /**< Offset of the base class (only needed for GCC 2.95). */
|
||||
static unsigned int *baseset; /**< Whether or base offset value has been set. */
|
||||
static unsigned int index; /**< This entry's virtual table index. */
|
||||
static unsigned int indexset; /**< Whether or not this entry's virtual table index has been set. */
|
||||
|
||||
/**
|
||||
* Initialize this table hook. This also registers our required keyvalue suffixes to the file parser.
|
||||
*
|
||||
* @param poffset Pointer to an integer that stores the pev offset for this mod.
|
||||
* @param pset Pointer to an integer that tells whether pev offset was set or not.
|
||||
* @param baseoffs Pointer to an integer that stores the class base offset for this mod. (GCC 2.95 only required)
|
||||
* @param baseset Pointer to an integer that tells whether class base offset has been set.
|
||||
* @noreturn
|
||||
*/
|
||||
static void Initialize(unsigned int *poffset, unsigned int *pset, unsigned int *baseoffs, unsigned int *baseset);
|
||||
|
||||
/**
|
||||
* Called when one of this table entry's keyvalues is caught in a config file.
|
||||
*
|
||||
* @param key The keyvalue suffix ("<mod>_<os>_" is removed)
|
||||
* @param data The data this keyvalue is set to.
|
||||
* @noreturn
|
||||
*/
|
||||
static void KeyValue(const char *key, const char *data);
|
||||
|
||||
/**
|
||||
* Called immediately after the config file is done being parsed. Register our natives here.
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
static void ConfigDone(void);
|
||||
|
||||
/**
|
||||
* A plugin is registering this entry's virtual hook. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell RegisterNative(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell NativeCall(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* A plugin is requesting a direct call of this entry's virtual function, and will be exposed to all hooks. This is a normal native callback.
|
||||
*
|
||||
* @param amx The AMX structure for the plugin.
|
||||
* @param params The parameters passed from the plugin.
|
||||
* @return 1 on success, 0 on failure. It only fails if the callback function is not found.
|
||||
*/
|
||||
static cell ENativeCall(AMX *amx, cell *params);
|
||||
|
||||
/**
|
||||
* Hook this entry's function! This creates our trampoline and modifies the virtual table.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param outtrampoline The trampoline that was created.
|
||||
* @param origfunc The original function that was hooked.
|
||||
* @noreturn
|
||||
*/
|
||||
static void CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc);
|
||||
|
||||
/**
|
||||
* Checks if the virtual function is already being hooked or not. If it's not, it begins hooking it. Either way it registers a forward and adds it to our vector.
|
||||
*
|
||||
* @param manager The VTableManager this is a child of.
|
||||
* @param vtable The virtual table we're molesting.
|
||||
* @param plugin The plugin that's requesting this.
|
||||
* @param funcid The function id of the callback.
|
||||
* @noreturn
|
||||
*/
|
||||
static void Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid);
|
||||
|
||||
/**
|
||||
* Execute the command. This is called directly from our global hook function.
|
||||
*
|
||||
* @param pthis The "this" pointer, cast to a void. The victim.
|
||||
* @param activator Entity that's blocking.
|
||||
* @noreturn
|
||||
*/
|
||||
void Execute(void *pthis, void *other);
|
||||
};
|
||||
//TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||
/*class VTableTraceAttack : public VTableEntryBase
|
||||
{
|
||||
public:
|
||||
static void CreateHook(VTableManager *manager, void **vtable, int id, void **outtrampoline, void **origfunc);
|
||||
static void Hook(VTableManager *manager, void **vtable, AMX *plugin, int funcid);
|
||||
void Execute(void *pthis, entvars_t *attacker, float damage, float *direction, TraceResult *tr, int damagetype);
|
||||
};
|
||||
*/
|
||||
#endif // VTABLEENTRIES_H
|
104
dlls/hamsandwich/tableentries/VTableManager.cpp
Normal file
104
dlls/hamsandwich/tableentries/VTableManager.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
#include "sdk/amxxmodule.h"
|
||||
|
||||
#include "VTableManager.h"
|
||||
#include "VTableEntries.h"
|
||||
|
||||
#include "NEW_Util.h"
|
||||
|
||||
void *VTableManager::InsertIntoVTable(void **vtable, int index, void *trampoline)
|
||||
{
|
||||
void *func;
|
||||
#if defined _WIN32
|
||||
DWORD OldFlags;
|
||||
VirtualProtect(&vtable[index],sizeof(int*),PAGE_READWRITE,&OldFlags);
|
||||
#elif defined __linux__
|
||||
mprotect(&vtable[index],sizeof(int*),PROT_READ|PROT_WRITE);
|
||||
#endif
|
||||
func=vtable[index];
|
||||
vtable[index]=trampoline;
|
||||
|
||||
return func;
|
||||
};
|
||||
|
||||
|
||||
#define CLEAR_ENTRIES(Container) \
|
||||
i=Container.size(); \
|
||||
while (i--) \
|
||||
{ \
|
||||
Container[i]->Destroy(); \
|
||||
delete Container[i]; \
|
||||
} \
|
||||
Container.clear()
|
||||
|
||||
|
||||
void VTableManager::Cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
CLEAR_ENTRIES(UseEntries);
|
||||
CLEAR_ENTRIES(TakeDamageEntries);
|
||||
};
|
||||
|
||||
|
||||
|
||||
void VTableEntryBase::CreateGenericTrampoline(VTableManager *manager, void **vtable, int vtid, int id, void **outtrampoline, void **origfunc, void *callee, int paramcount, int voidcall, int thiscall)
|
||||
{
|
||||
Trampolines::TrampolineMaker tramp;
|
||||
|
||||
if (voidcall)
|
||||
{
|
||||
if (thiscall)
|
||||
{
|
||||
tramp.ThisVoidPrologue();
|
||||
}
|
||||
else
|
||||
{
|
||||
tramp.VoidPrologue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thiscall)
|
||||
{
|
||||
tramp.ThisReturnPrologue();
|
||||
}
|
||||
else
|
||||
{
|
||||
tramp.ReturnPrologue();
|
||||
}
|
||||
}
|
||||
|
||||
while (paramcount)
|
||||
{
|
||||
tramp.PushParam(paramcount--);
|
||||
}
|
||||
if (thiscall)
|
||||
{
|
||||
tramp.PushThis();
|
||||
}
|
||||
tramp.PushNum(id);
|
||||
tramp.Call(callee);
|
||||
tramp.FreeTargetStack();
|
||||
if (voidcall)
|
||||
{
|
||||
#if defined _WIN32
|
||||
tramp.VoidEpilogueAndFree();
|
||||
#elif defined __linux__
|
||||
tramp.VoidEpilogue();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined _WIN32
|
||||
tramp.ReturnEpilogueAndFree();
|
||||
#elif defined __linux__
|
||||
tramp.ReturnEpilogue();
|
||||
#endif
|
||||
}
|
||||
|
||||
void *trampoline=tramp.Finish(NULL);
|
||||
|
||||
*outtrampoline=trampoline;
|
||||
|
||||
*origfunc=manager->InsertIntoVTable(vtable,vtid,trampoline);
|
||||
};
|
93
dlls/hamsandwich/tableentries/VTableManager.h
Normal file
93
dlls/hamsandwich/tableentries/VTableManager.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef VTABLEMANAGER_H
|
||||
#define VTABLEMANAGER_H
|
||||
|
||||
#include "Trampolines.h"
|
||||
|
||||
#include "CVector.h"
|
||||
#include "hooks.h"
|
||||
#include "VTableEntries.h"
|
||||
|
||||
/* !!WARNING: HERE BE DRAGONS
|
||||
|
||||
.~))>>
|
||||
.~)>>
|
||||
.~))))>>>
|
||||
.~))>> ___
|
||||
.~))>>)))>> .-~))>>
|
||||
.~)))))>> .-~))>>)>
|
||||
.~)))>>))))>> .-~)>>)>
|
||||
) .~))>>))))>> .-~)))))>>)>
|
||||
( )@@*) //)>)))))) .-~))))>>)>
|
||||
).@(@@ //))>>))) .-~))>>)))))>>)>
|
||||
(( @.@). //))))) .-~)>>)))))>>)>
|
||||
)) )@@*.@@ ) //)>))) //))))))>>))))>>)>
|
||||
(( ((@@@.@@ |/))))) //)))))>>)))>>)>
|
||||
)) @@*. )@@ ) (\_(\-\b |))>)) //)))>>)))))))>>)>
|
||||
(( @@@(.@(@ . _/`-` ~|b |>))) //)>>)))))))>>)>
|
||||
)* @@@ )@* (@) (@) /\b|))) //))))))>>))))>>
|
||||
(( @. )@( @ . _/ / / \b)) //))>>)))))>>>_._
|
||||
)@@ (@@*)@@. (6///6)- / ^ \b)//))))))>>)))>> ~~-.
|
||||
( @jgs@@. @@@.*@_ VvvvvV// ^ \b/)>>))))>> _. `bb
|
||||
((@@ @@@*.(@@ . - | o |' \ ( ^ \b)))>> .' b`,
|
||||
((@@).*@@ )@ ) \^^^/ (( ^ ~)_ \ / b `,
|
||||
(@@. (@@ ). `-' ((( ^ `\ \ \ \ \| b `.
|
||||
(*.@* / (((( \| | | \ . b `.
|
||||
/ / ((((( \ \ / _.-~\ Y, b ;
|
||||
/ / / (((((( \ \.-~ _.`" _.-~`, b ;
|
||||
/ / `(((((() ) (((((~ `, b ;
|
||||
_/ _/ `"""/ /' ; b ;
|
||||
_.-~_.-~ / /' _.'~bb _.'
|
||||
((((~~ / /' _.'~bb.--~
|
||||
(((( __.-~bb.-~
|
||||
.' b .~~
|
||||
:bb ,'
|
||||
~~~~
|
||||
*/
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
HAM_UNSET = 0,
|
||||
HAM_IGNORED,
|
||||
HAM_HANDLED,
|
||||
HAM_OVERRIDE,
|
||||
HAM_SUPERCEDE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HAM_TYPE_UNKNOWN = 0,
|
||||
HAM_TYPE_CBASE,
|
||||
HAM_TYPE_ENTVAR,
|
||||
HAM_TYPE_EDICT,
|
||||
HAM_TYPE_INT,
|
||||
HAM_TYPE_FLOAT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HAM_ERROR_BOUNDS = -2,
|
||||
HAM_ERROR_TYPE = -1,
|
||||
HAM_ERROR_NONE = 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class VTableManager
|
||||
{
|
||||
public:
|
||||
CVector<VTableUse *> UseEntries;
|
||||
CVector<VTableTakeDamage *> TakeDamageEntries;
|
||||
CVector<VTableBlocked *> BlockedEntries;
|
||||
|
||||
/* returns the original function */
|
||||
void *InsertIntoVTable(void **vtable, int index, void *trampoline);
|
||||
void Cleanup(void);
|
||||
};
|
||||
|
||||
extern VTableManager VTMan;
|
||||
|
||||
//#include "VTableEntries.h"
|
||||
|
||||
#endif // VTABLEMANAGER_H
|
105
dlls/hamsandwich/vfunc_gcc295.h
Normal file
105
dlls/hamsandwich/vfunc_gcc295.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* Ham Sandwich
|
||||
*
|
||||
* by sawce
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
// Calling virtual functions on binaries compiled with GCC 2.95
|
||||
// 2.95 and before stores the virtual table at the end of the
|
||||
// inheritable size of the base class.
|
||||
// I have no idea how it does it for multiple inheritance; i don't
|
||||
// really care. Everything I'm calling does it in single inheritence.
|
||||
// GCC doesn't put this on a register like MSVC does, so
|
||||
// just pass it like a normal parameter (the first one)
|
||||
// For GCC 3.3 compiled binaries, set the "size" parameter to 0
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef VFUNC_GCC295_H
|
||||
#define VFUNC_GCC295_H
|
||||
|
||||
inline void *GetVTableEntry(void *pThis, int ventry, int size)
|
||||
{
|
||||
char *pcThis=*(char **)&pThis;
|
||||
|
||||
pcThis+=size;
|
||||
|
||||
void **vtbl=*(void ***)pcThis;
|
||||
|
||||
return vtbl[ventry];
|
||||
}
|
||||
|
||||
// I only comment on the first call, because it's jut copy/paste after
|
||||
// the rest are compacted for copy/paste ease
|
||||
template <class PTypeA, class PTypeB, class PTypeC, class PTypeD>
|
||||
inline void VoidVCall4(void *pThis, int ventry, int size, PTypeA pa, PTypeB pb, PTypeC pc, PTypeD pd)
|
||||
{
|
||||
// First move up past the size of the class
|
||||
char *pcThis=*(char **)&pThis;
|
||||
|
||||
pcThis+=size;
|
||||
|
||||
void **vtbl=*(void ***)pcThis;
|
||||
|
||||
// now points to the vtable of this object
|
||||
|
||||
typedef void (*fptr)(void*,PTypeA,PTypeB,PTypeC,PTypeD);
|
||||
fptr function=reinterpret_cast<fptr>(vtbl[ventry]);
|
||||
|
||||
function(pThis,pa,pb,pc,pd);
|
||||
};
|
||||
template <class RetType, class PTypeA, class PTypeB, class PTypeC, class PTypeD>
|
||||
inline RetType VCall4(void *pThis, int ventry, int size, PTypeA pa, PTypeB pb, PTypeC pc, PTypeD pd)
|
||||
{
|
||||
char *pcThis=*(char **)&pThis;
|
||||
pcThis+=size;
|
||||
int **vtbl=*(int ***)pcThis;
|
||||
typedef RetType (*fptr)(void*,PTypeA,PTypeB,PTypeC,PTypeD);
|
||||
fptr function=reinterpret_cast<fptr>(vtbl[ventry]);
|
||||
return function(pThis,pa,pb,pc,pd);
|
||||
};
|
||||
template <class PTypeA>
|
||||
inline void VoidVCall1(void *pThis, int ventry, int size, PTypeA pa)
|
||||
{
|
||||
char *pcThis=*(char **)&pThis;
|
||||
pcThis+=size;
|
||||
int **vtbl=*(int ***)pcThis;
|
||||
typedef void (*fptr)(void*,PTypeA);
|
||||
fptr function=reinterpret_cast<fptr>(vtbl[ventry]);
|
||||
function(pThis,pa);
|
||||
};
|
||||
template <class RetType, class PTypeA>
|
||||
inline RetType VCall1(void *pThis, int ventry, int size, PTypeA pa)
|
||||
{
|
||||
char *pcThis=*(char **)&pThis;
|
||||
pcThis+=size;
|
||||
int **vtbl=*(int ***)pcThis;
|
||||
typedef RetType (*fptr)(void*,PTypeA);
|
||||
fptr function=reinterpret_cast<fptr>(vtbl[ventry]);
|
||||
return function(pThis,pa);
|
||||
};
|
||||
|
||||
#endif //VFUNC_GCC295_H
|
||||
#endif // __linux__
|
137
dlls/hamsandwich/vfunc_msvc.h
Normal file
137
dlls/hamsandwich/vfunc_msvc.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* Ham Sandwich
|
||||
*
|
||||
* by sawce
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
// MSVC stores vtable like normal at the front as well
|
||||
// however these are thiscall functions
|
||||
// i use inline assembly to call them
|
||||
#ifdef _WIN32
|
||||
#ifndef VFUNC_MSVC_H
|
||||
#define VFUNC_MSVC_H
|
||||
|
||||
inline void *GetVTableEntry(void *pThis, int ventry, int size)
|
||||
{
|
||||
void **vtbl=*(void ***)pThis;
|
||||
|
||||
return vtbl[ventry];
|
||||
}
|
||||
template <class PTypeA, class PTypeB, class PTypeC, class PTypeD>
|
||||
inline void VoidVCall4(void *pThis, int ventry, int size, PTypeA pa, PTypeB pb, PTypeC pc, PTypeD pd)
|
||||
{
|
||||
// vtable pointer is stored in the first dword of the object
|
||||
// reference it as an array of objects
|
||||
void **vtbl=*(void ***)pThis;
|
||||
|
||||
void *func=vtbl[ventry];
|
||||
|
||||
// Simulate a thiscall
|
||||
// this on ecx, all other parameters pushed normally
|
||||
_asm {
|
||||
push ecx; // save ecx
|
||||
push eax; // save eax - shouldn't be needed, but just incase
|
||||
|
||||
push pd; // push param 4
|
||||
push pc; // push param 3
|
||||
push pb; // push param 2
|
||||
push pa; // push param 1
|
||||
|
||||
mov ecx, pThis; // store this in ecx
|
||||
|
||||
call [func]; // call function
|
||||
|
||||
pop eax; // restore eax
|
||||
pop ecx; // restore ecx
|
||||
};
|
||||
};
|
||||
template <class RetType, class PTypeA, class PTypeB, class PTypeC, class PTypeD>
|
||||
inline RetType VCall4(void *pThis, int ventry, int size, PTypeA pa, PTypeB pb, PTypeC pc, PTypeD pd)
|
||||
{
|
||||
void **vtbl=*(void ***)pThis;
|
||||
|
||||
void *func=vtbl[ventry];
|
||||
|
||||
RetType _ret;
|
||||
_asm {
|
||||
push ecx;
|
||||
push eax;
|
||||
push pd;
|
||||
push pc;
|
||||
push pb;
|
||||
push pa;
|
||||
mov ecx, pThis;
|
||||
call [func];
|
||||
mov _ret, eax;
|
||||
pop eax;
|
||||
pop ecx;
|
||||
};
|
||||
|
||||
return _ret;
|
||||
};
|
||||
template <class PTypeA>
|
||||
inline void VoidVCall1(void *pThis, int ventry, int size, PTypeA pa)
|
||||
{
|
||||
void **vtbl=*(void ***)pThis;
|
||||
|
||||
void *func=vtbl[ventry];
|
||||
|
||||
_asm {
|
||||
push ecx;
|
||||
push eax;
|
||||
push pa;
|
||||
mov ecx, pThis;
|
||||
call [func];
|
||||
pop eax;
|
||||
pop ecx;
|
||||
};
|
||||
};
|
||||
template <class RetType, class PTypeA>
|
||||
inline RetType VCall1(void *pThis, int ventry, int size, PTypeA pa)
|
||||
{
|
||||
void **vtbl=*(void ***)pThis;
|
||||
|
||||
void *func=vtbl[ventry];
|
||||
|
||||
RetType _ret;
|
||||
_asm {
|
||||
push ecx;
|
||||
push eax;
|
||||
push pa;
|
||||
mov ecx, pThis;
|
||||
call [func];
|
||||
mov _ret, eax;
|
||||
pop eax;
|
||||
pop ecx;
|
||||
};
|
||||
|
||||
return _ret;
|
||||
};
|
||||
|
||||
|
||||
#endif //VFUNC_MSVC_H
|
||||
#endif // _WIN32
|
51
dlls/hamsandwich/vtable.cpp
Normal file
51
dlls/hamsandwich/vtable.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
/**
|
||||
* These are the functions called by the trampolines
|
||||
* I explicitly declare them as cdecl so I know exactly
|
||||
* how to work the stack in the trampoline.
|
||||
*/
|
||||
/*
|
||||
static cell AMX_NATIVE_CALL register_takedamage(AMX *amx, cell *params)
|
||||
{
|
||||
};
|
||||
static cell AMX_NATIVE_CALL register_use(AMX *amx, cell *params)
|
||||
{
|
||||
int funcid;
|
||||
char *function=MF_GetAmxString(amx,params[2],0,NULL);
|
||||
if (MF_AmxFindPublic(amx,function,&funcid)!=AMX_ERR_NONE)
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Can not find function \"%s\"",function);
|
||||
return 0;
|
||||
}
|
||||
// Get the classname
|
||||
char *classname=MF_GetAmxString(amx,params[1],0,NULL);
|
||||
|
||||
edict_t *Entity=CREATE_ENTITY();
|
||||
|
||||
CALL_GAME_ENTITY(PLID,classname,&Entity->v);
|
||||
|
||||
if (Entity->pvPrivateData)
|
||||
{
|
||||
VTableUse::Hook(&VTMan,EdictToVTable(Entity),amx,funcid);
|
||||
REMOVE_ENTITY(Entity);
|
||||
return 1;
|
||||
}
|
||||
|
||||
REMOVE_ENTITY(Entity);
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
|
||||
static AMX_NATIVE_INFO tdhooks[] = {
|
||||
{ "register_takedamage", register_takedamage },
|
||||
{ "register_use", register_use },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void VTH_Natives()
|
||||
{
|
||||
MF_AddNatives(tdhooks);
|
||||
};
|
||||
|
||||
*/
|
|
@ -1,39 +0,0 @@
|
|||
// prevent double include
|
||||
#ifndef __PDATA_H__
|
||||
#define __PDATA_H__
|
||||
|
||||
#include <extdll.h>
|
||||
#include "amxxmodule.h"
|
||||
|
||||
#if defined __linux__
|
||||
#define EXTRAOFFSET 5 // offsets 5 higher in Linux builds
|
||||
#else
|
||||
#define EXTRAOFFSET 0 // no change in Windows builds
|
||||
#endif // defined __linux__
|
||||
|
||||
inline edict_t* MF_GetEntityEdict( long& EntID )
|
||||
{
|
||||
if( (EntID > 0) && (EntID <= (gpGlobals->maxClients) ) )
|
||||
return MF_GetPlayerEdict( EntID );
|
||||
|
||||
return INDEXENT( EntID );
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
inline void SetPData( long& targetid, long offset, ValueType value)
|
||||
{
|
||||
edict_t* target = MF_GetEntityEdict( targetid );
|
||||
if(target == NULL) return;
|
||||
|
||||
*((ValueType *)target->pvPrivateData + offset + EXTRAOFFSET) = value;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
inline ValueType GetPData( long& targetid, long offset, ValueType value )
|
||||
{
|
||||
edict_t* target = MF_GetEntityEdict( targetid );
|
||||
if(target == NULL) return NULL;
|
||||
return *((ValueType *)target->pvPrivateData + offset + EXTRAOFFSET);
|
||||
}
|
||||
|
||||
#endif
|
413
dlls/sven/sven/CString.h
Normal file
413
dlls/sven/sven/CString.h
Normal file
|
@ -0,0 +1,413 @@
|
|||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _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()
|
||||
{
|
||||
if (!v)
|
||||
return true;
|
||||
|
||||
if (v[0] == '\0')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
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>=0; 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
|
254
dlls/sven/sven/Trie.h
Normal file
254
dlls/sven/sven/Trie.h
Normal file
|
@ -0,0 +1,254 @@
|
|||
/* ======== Simple Trie ========
|
||||
* Copyright (C) 2006-2007 Kuchiki Rukia
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): Radical Edward
|
||||
* Notes: Generic simple trie
|
||||
* ============================
|
||||
*/
|
||||
|
||||
// Rukia: Digital trees, or tries, are a combination of vector and tree structures.
|
||||
// They have garanteed O(1) worst case (literally O(m), constant for key length).
|
||||
// However, unless optimized (such as in Judy Arrays), they have terrible memory performance.
|
||||
// We will use a naive approach, due to time constraints.
|
||||
// Judy Arrays would be a better approach, but would destroy the point of the assignment.
|
||||
|
||||
#ifndef __TRIE_CLASS__
|
||||
#define __TRIE_CLASS__
|
||||
|
||||
// Rukia: HACK: Usage of assert to force metatemplates to work right.
|
||||
#include <cassert>
|
||||
#include <string.h>
|
||||
|
||||
// Rukia: Metaprogramming to aid in compile time constants and such.
|
||||
template<size_t base, size_t N>
|
||||
struct Exponential
|
||||
{
|
||||
enum { value = base * Exponential<base,N - 1>::value };
|
||||
};
|
||||
|
||||
template <size_t base>
|
||||
struct Exponential<base,0>
|
||||
{
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
// Rukia: NOTE: This is extremely ugly for these reasons:
|
||||
// 1. It relies on template metaprogramming
|
||||
// 2. It is unoptimized
|
||||
// 3. It was written in exactly 1 hour and 7 minutes.
|
||||
// However, preliminary tests show it is faster than the STL hashmap, in current form.
|
||||
// HACK: Optimize further into a patricia tree and partial specialization digital tree (Judy Array).
|
||||
|
||||
// Rukia: HACK: To optimize:
|
||||
// 1. Add two bitvectors (vector<bool>) to each node.
|
||||
// * 0 0 = nothing at all
|
||||
// * 1 0 = compressed nodes 1
|
||||
// * 0 1 = compressed nodes 2
|
||||
// * 1 1 = uncompressed node
|
||||
// 2. Add compressed node 1; a simple holder for one value
|
||||
// 3. Add compressed node 2; a vector with a bitlookup table for up to 2^sizeof(C) values
|
||||
// 4. Allow for hytersis in deletion for until 1 insert (will increase speed on multiple in row insert/deletes
|
||||
|
||||
// Rukia: Templates <Key, Value, Compare by>
|
||||
template <typename K, typename V, typename C = unsigned char>
|
||||
class Trie
|
||||
{
|
||||
public:
|
||||
|
||||
// Rukia: HACK: Remove this from Trie class eventually; it looks ugly and is slow.
|
||||
class TrieNode
|
||||
{
|
||||
friend class Trie;
|
||||
public:
|
||||
TrieNode()
|
||||
{
|
||||
// Rukia: Render all pointers NULL.
|
||||
// Rukia: HACK: Reformat this somehow, it is ugly.
|
||||
// Rukia: Use 0, not NULL. GCC dislikes usage of NULL.
|
||||
memset(reinterpret_cast<void*>(Children),0,Exponential<2,8*sizeof(C)>::value * sizeof(TrieNode*));
|
||||
Value = NULL;
|
||||
}
|
||||
// Rukia: We can garantee this will be an OK delete; either value, or NULL.
|
||||
~TrieNode()
|
||||
{
|
||||
if( Value != NULL) { delete Value; }
|
||||
for(register long i = 0; i < Exponential<2,8*sizeof(C)>::value; i++)
|
||||
{
|
||||
delete Children[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if( Value != NULL) { delete Value; }
|
||||
for(register long i = 0; i < Exponential<2,8*sizeof(C)>::value; i++)
|
||||
{
|
||||
delete Children[i];
|
||||
Children[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Rukia: Little syntatical sugar for you. Hope you like it.
|
||||
TrieNode* operator[](C size)
|
||||
{
|
||||
return Children[size];
|
||||
}
|
||||
|
||||
void InOrderAlt(void(*func)(V&) )
|
||||
{
|
||||
if( Value != NULL) { func(*Value); }
|
||||
for(register long i = 0; i < Exponential<2,8*sizeof(C)>::value; i++)
|
||||
{
|
||||
if(Children[i] != NULL) { (Children[i])->InOrderAlt(func); }
|
||||
}
|
||||
}
|
||||
|
||||
void Insert(V& newval)
|
||||
{
|
||||
if(Value == NULL) { Value = new V; }
|
||||
|
||||
*Value = newval;
|
||||
}
|
||||
|
||||
// Rukia: This will be inlined out, and it is never good to expose too much.
|
||||
V* Retrieve()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
// Rukia: Return true if node is redundant, so we can remove it.
|
||||
// Rukia: HACK: Perhaps optimize for inserts by analyzing usage?
|
||||
void Delete()
|
||||
{
|
||||
delete Value;
|
||||
Value = NULL;
|
||||
}
|
||||
|
||||
// Rukia: GCC doesn't like redundant friend declarations.
|
||||
//friend class Trie;
|
||||
private:
|
||||
TrieNode* Children[Exponential<2,8*sizeof(C)>::value];
|
||||
V* Value;
|
||||
};
|
||||
|
||||
friend class TrieNode;
|
||||
|
||||
// Rukia: Root/stem node.
|
||||
TrieNode Stem;
|
||||
|
||||
// Simply calls the destructor on any and all children, until everything is dead.
|
||||
void Clear()
|
||||
{
|
||||
Stem.Clear();
|
||||
}
|
||||
|
||||
bool IsValid(const K* key, size_t keylen)
|
||||
{
|
||||
return (Retrieve(key,keylen) != NULL);
|
||||
}
|
||||
|
||||
void InOrderAlt(void(*func)(V&) )
|
||||
{
|
||||
Stem.InOrderAlt(func);
|
||||
}
|
||||
|
||||
// Rukia: We use const for the key, even though we completely subvert the system.
|
||||
// Rukia: Why? Because we don't CHANGE it, even if we subvert the system.
|
||||
V* Retrieve(const K* key, size_t keylen)
|
||||
{
|
||||
// Rukia: Convert to comparison types
|
||||
register C* realkey = (C*)(key);
|
||||
C CurrKey = *realkey;
|
||||
|
||||
// Rukia: HACK: Convert to use bitwise shift operators
|
||||
register size_t reallen = keylen * (sizeof(K) / sizeof(C) );
|
||||
|
||||
if(key == NULL) { return Stem.Retrieve(); }
|
||||
|
||||
// Rukia: Iterate through the nodes till we find a NULL one, or run out of key.
|
||||
register TrieNode* CurrNode = Stem[CurrKey];
|
||||
|
||||
// Rukia: HACK: Return NULL, don't use exceptions, they are slow.
|
||||
if(CurrNode == NULL) { return NULL; }
|
||||
|
||||
// Rukia: initialize one lower because we've already decoded one from the key.
|
||||
for(reallen--;reallen != 0;reallen--)
|
||||
{
|
||||
realkey++;
|
||||
CurrKey = *realkey;
|
||||
|
||||
CurrNode = (*CurrNode)[CurrKey];
|
||||
if(CurrNode == NULL) { return NULL; }
|
||||
}
|
||||
return CurrNode->Retrieve();
|
||||
};
|
||||
|
||||
void Insert( const K* key, size_t keylen, V& value)
|
||||
{
|
||||
// Rukia: Convert to comparison types
|
||||
register C* realkey = (C*)(key);
|
||||
C CurrKey = *realkey;
|
||||
|
||||
// Rukia: HACK: Convert to use bitwise shift operators
|
||||
register size_t reallen = keylen * (sizeof(K) / sizeof(C) );
|
||||
|
||||
if(key == NULL) { Stem.Retrieve(); }
|
||||
|
||||
// Rukia: Iterate through the nodes till we find a NULL one, or run out of key.
|
||||
register TrieNode* CurrNode = Stem[CurrKey];
|
||||
register TrieNode* TmpNode = NULL;
|
||||
|
||||
// Rukia: HACK: Maybe an internal memory allocator?
|
||||
// Rukia: HACK: Quickly resort to 'friend'; reduces encapsulation, but worth the cost.
|
||||
if(CurrNode == NULL) { CurrNode = new TrieNode(); Stem.Children[CurrKey] = CurrNode; }
|
||||
|
||||
// Rukia: initialize one lower because we've already decoded one from the key.
|
||||
for(reallen--;reallen != 0;reallen--)
|
||||
{
|
||||
realkey++;
|
||||
CurrKey = *realkey;
|
||||
|
||||
TmpNode = (*CurrNode)[CurrKey];
|
||||
if(TmpNode == NULL) { TmpNode = new TrieNode; CurrNode->Children[CurrKey] = TmpNode; }
|
||||
|
||||
CurrNode = TmpNode;
|
||||
}
|
||||
CurrNode->Insert(value);
|
||||
}
|
||||
|
||||
// Rukia: HACK HACK HACK: Fix this SOON. Delete will NOT delete nodes, and has no hystersis operandi.
|
||||
void Delete( const K* key, size_t keylen)
|
||||
{
|
||||
// Rukia: Convert to comparison types
|
||||
register C* realkey = (C*)(key);
|
||||
C CurrKey = *realkey;
|
||||
|
||||
// Rukia: HACK: Convert to use bitwise shift operators
|
||||
register size_t reallen = keylen * (sizeof(K) / sizeof(C) );
|
||||
|
||||
if(key == NULL) { Stem.Delete(); return; }
|
||||
|
||||
// Rukia: Iterate through the nodes till we find a NULL one, or run out of key.
|
||||
register TrieNode* CurrNode = Stem[CurrKey];
|
||||
|
||||
// Rukia: HACK: Return NULL, don't use exceptions, they are slow.
|
||||
if(CurrNode == NULL) { return; }
|
||||
|
||||
// Rukia: initialize one lower because we've already decoded one from the key.
|
||||
for(reallen--;reallen != 0;reallen--)
|
||||
{
|
||||
realkey++;
|
||||
CurrKey = *realkey;
|
||||
|
||||
CurrNode = (*CurrNode)[CurrKey];
|
||||
if(CurrNode == NULL) { return; }
|
||||
}
|
||||
CurrNode->Delete();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
3119
dlls/sven/sven/amxxmodule.cpp
Normal file
3119
dlls/sven/sven/amxxmodule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2454
dlls/sven/sven/amxxmodule.h
Normal file
2454
dlls/sven/sven/amxxmodule.h
Normal file
File diff suppressed because it is too large
Load Diff
344
dlls/sven/sven/moduleconfig.cpp
Normal file
344
dlls/sven/sven/moduleconfig.cpp
Normal file
|
@ -0,0 +1,344 @@
|
|||
/* AMX Mod X
|
||||
* Sven Co-op Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "svencoop.h"
|
||||
|
||||
//
|
||||
// EXTERNS
|
||||
//
|
||||
|
||||
int gmsgScoreInfo;
|
||||
KeyValueData g_kvd;
|
||||
Trie<char,String> g_allyNameTrie, g_enemyNameTrie;
|
||||
|
||||
//
|
||||
// GLOBALS
|
||||
//
|
||||
|
||||
int g_lastDeadflag[33] = { 0 }, g_grenadeCount = 0,
|
||||
g_spawnFwd = -1, g_healFwd = -1, g_grenadeFwd = -1;
|
||||
|
||||
edict_t *g_grenadeList[32] = { NULL };
|
||||
|
||||
//
|
||||
// AMXX HOOKS
|
||||
//
|
||||
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
MF_AddNatives(svencoop_Exports);
|
||||
|
||||
// sc_set_displayname
|
||||
g_kvd.szClassName = "";
|
||||
g_kvd.szKeyName = "";
|
||||
g_kvd.szValue = "";
|
||||
g_kvd.fHandled = 0;
|
||||
|
||||
// sc_get_displayname, default displaynames
|
||||
g_allyNameTrie.Insert("monster_alien_babyvoltigore", 27, String("Friendly Baby Voltigore"));
|
||||
g_enemyNameTrie.Insert("monster_alien_babyvoltigore", 27, String("Baby Voltigore"));
|
||||
g_allyNameTrie.Insert("monster_alien_controller", 24, String("Friendly Alien Controller"));
|
||||
g_enemyNameTrie.Insert("monster_alien_controller", 24, String("Alien Controller"));
|
||||
g_allyNameTrie.Insert("monster_alien_grunt", 19, String("Friendly Alien Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_alien_grunt", 19, String("Alien Grunt"));
|
||||
g_allyNameTrie.Insert("monster_alien_slave", 19, String("Friendly Alien Slave"));
|
||||
g_enemyNameTrie.Insert("monster_alien_slave", 19, String("Alien Slave"));
|
||||
g_allyNameTrie.Insert("monster_vortigaunt", 18, String("Friendly Alien Slave"));
|
||||
g_enemyNameTrie.Insert("monster_vortigaunt", 18, String("Alien Slave"));
|
||||
g_allyNameTrie.Insert("monster_alien_voltigore", 23, String("Friendly Voltigore"));
|
||||
g_enemyNameTrie.Insert("monster_alien_voltigore", 23, String("Voltigore"));
|
||||
g_allyNameTrie.Insert("monster_apache", 14, String("Apache"));
|
||||
g_enemyNameTrie.Insert("monster_apache", 14, String("Apache"));
|
||||
g_allyNameTrie.Insert("monster_blkop_apache", 20, String("Apache"));
|
||||
g_enemyNameTrie.Insert("monster_blkop_apache", 20, String("Apache"));
|
||||
g_allyNameTrie.Insert("monster_assassin_repel", 22, String("Friendly Male Assassin"));
|
||||
g_enemyNameTrie.Insert("monster_assassin_repel", 22, String("Male Assassin"));
|
||||
g_allyNameTrie.Insert("monster_male_assassin", 21, String("Friendly Male Assassin"));
|
||||
g_enemyNameTrie.Insert("monster_male_assassin", 21, String("Male Assassin"));
|
||||
g_allyNameTrie.Insert("monster_babycrab", 16, String("Friendly Head Crab"));
|
||||
g_enemyNameTrie.Insert("monster_babycrab", 16, String("Head Crab"));
|
||||
g_allyNameTrie.Insert("monster_headcrab", 16, String("Friendly Head Crab"));
|
||||
g_enemyNameTrie.Insert("monster_headcrab", 16, String("Head Crab"));
|
||||
g_allyNameTrie.Insert("monster_babygarg", 16, String("Friendly Baby Gargantua"));
|
||||
g_enemyNameTrie.Insert("monster_babygarg", 16, String("Baby Gargantua"));
|
||||
g_allyNameTrie.Insert("monster_barnacle", 16, String("Barnacle"));
|
||||
g_enemyNameTrie.Insert("monster_barnacle", 16, String("Barnacle"));
|
||||
g_allyNameTrie.Insert("monster_barney", 14, String("Barney"));
|
||||
g_enemyNameTrie.Insert("monster_barney", 14, String("Barnabus"));
|
||||
g_allyNameTrie.Insert("monster_bigmomma", 16, String("Friendly Big Momma"));
|
||||
g_enemyNameTrie.Insert("monster_bigmomma", 16, String("Big Momma"));
|
||||
g_allyNameTrie.Insert("monster_blkop_osprey", 20, String("Friendly Black Ops Osprey"));
|
||||
g_enemyNameTrie.Insert("monster_blkop_osprey", 20, String("Black Ops Osprey"));
|
||||
g_allyNameTrie.Insert("monster_bloater", 15, String("Friendly Bloater"));
|
||||
g_enemyNameTrie.Insert("monster_bloater", 15, String("Bloater"));
|
||||
g_allyNameTrie.Insert("monster_bullchicken", 19, String("Friendly Bull Squid"));
|
||||
g_enemyNameTrie.Insert("monster_bullchicken", 19, String("Bull Squid"));
|
||||
g_allyNameTrie.Insert("monster_chumtoad", 16, String("Chubby"));
|
||||
g_enemyNameTrie.Insert("monster_chumtoad", 16, String("Chumtoad"));
|
||||
g_allyNameTrie.Insert("monster_cleansuit_scientist", 27, String("Cleansuit Scientist"));
|
||||
g_enemyNameTrie.Insert("monster_cleansuit_scientist", 27, String("Cleansuit Scientist"));
|
||||
g_allyNameTrie.Insert("monster_cockroach", 17, String("Roach"));
|
||||
g_enemyNameTrie.Insert("monster_cockroach", 17, String("Roach"));
|
||||
g_allyNameTrie.Insert("monster_gargantua", 17, String("Friendly Gargantua"));
|
||||
g_enemyNameTrie.Insert("monster_gargantua", 17, String("Gargantua"));
|
||||
g_allyNameTrie.Insert("monster_gman", 12, String("Government Man"));
|
||||
g_enemyNameTrie.Insert("monster_gman", 12, String("Government Man"));
|
||||
g_allyNameTrie.Insert("monster_gonome", 14, String("Friendly Gonome"));
|
||||
g_enemyNameTrie.Insert("monster_gonome", 14, String("Gonome"));
|
||||
g_allyNameTrie.Insert("monster_houndeye", 16, String("Friendly Hound Eye"));
|
||||
g_enemyNameTrie.Insert("monster_houndeye", 16, String("Hound Eye"));
|
||||
g_allyNameTrie.Insert("monster_human_assassin", 22, String("Friendly Female Assassin"));
|
||||
g_enemyNameTrie.Insert("monster_human_assassin", 22, String("Female Assassin"));
|
||||
g_allyNameTrie.Insert("monster_human_grunt", 19, String("Friendly Human Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_human_grunt", 19, String("Human Grunt"));
|
||||
g_allyNameTrie.Insert("monster_grunt_repel", 19, String("Friendly Human Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_grunt_repel", 19, String("Human Grunt"));
|
||||
g_allyNameTrie.Insert("monster_human_grunt_ally", 24, String("Ally Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_human_grunt_ally", 24, String("Enemy Grunt"));
|
||||
g_allyNameTrie.Insert("monster_grunt_ally_repel", 24, String("Ally Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_grunt_ally_repel", 24, String("Enemy Grunt"));
|
||||
g_allyNameTrie.Insert("monster_human_medic_ally", 24, String("Medic Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_human_medic_ally", 24, String("Enemy Medic Grunt"));
|
||||
g_allyNameTrie.Insert("monster_medic_ally_repel", 24, String("Medic Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_medic_ally_repel", 24, String("Enemy Medic Grunt"));
|
||||
g_allyNameTrie.Insert("monster_human_torch_ally", 24, String("Torch Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_human_torch_ally", 24, String("Enemy Torch Grunt"));
|
||||
g_allyNameTrie.Insert("monster_torch_ally_repel", 24, String("Torch Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_torch_ally_repel", 24, String("Enemy Torch Grunt"));
|
||||
g_allyNameTrie.Insert("monster_hwgrunt", 15, String("Friendly Heavy Weapons Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_hwgrunt", 15, String("Heavy Weapons Grunt"));
|
||||
g_allyNameTrie.Insert("monster_hwgrunt_repel", 21, String("Friendly Heavy Weapons Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_hwgrunt_repel", 21, String("Heavy Weapons Grunt"));
|
||||
g_allyNameTrie.Insert("monster_ichthyosaur", 19, String("Friendly Ichthyosaur"));
|
||||
g_enemyNameTrie.Insert("monster_ichthyosaur", 19, String("Ichthyosaur"));
|
||||
g_allyNameTrie.Insert("monster_leech", 13, String("Leech"));
|
||||
g_enemyNameTrie.Insert("monster_leech", 13, String("Leech"));
|
||||
g_allyNameTrie.Insert("monster_miniturret", 18, String("Mini-Turret"));
|
||||
g_enemyNameTrie.Insert("monster_miniturret", 18, String("Mini-Turret"));
|
||||
g_allyNameTrie.Insert("monster_nihilanth", 17, String(""));
|
||||
g_enemyNameTrie.Insert("monster_nihilanth", 17, String(""));
|
||||
g_allyNameTrie.Insert("monster_osprey", 14, String("Friendly Osprey Helicopter"));
|
||||
g_enemyNameTrie.Insert("monster_osprey", 14, String("Osprey Helicopter"));
|
||||
g_allyNameTrie.Insert("monster_otis", 12, String("Otis"));
|
||||
g_enemyNameTrie.Insert("monster_otis", 12, String("Enemy Otis"));
|
||||
g_allyNameTrie.Insert("monster_pitdrone", 16, String("Friendly Pit Drone"));
|
||||
g_enemyNameTrie.Insert("monster_pitdrone", 16, String("Pit Drone"));
|
||||
g_allyNameTrie.Insert("monster_rat", 11, String("Rat"));
|
||||
g_enemyNameTrie.Insert("monster_rat", 11, String("Rat"));
|
||||
g_allyNameTrie.Insert("monster_robogrunt", 17, String("Friendly Robo Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_robogrunt", 17, String("Robo Grunt"));
|
||||
g_allyNameTrie.Insert("monster_robogrunt_repel", 23, String("Friendly Robo Grunt"));
|
||||
g_enemyNameTrie.Insert("monster_robogrunt_repel", 23, String("Robo Grunt"));
|
||||
g_allyNameTrie.Insert("monster_scientist", 17, String("Scientist"));
|
||||
g_enemyNameTrie.Insert("monster_scientist", 17, String("Scientist"));
|
||||
g_allyNameTrie.Insert("monster_sitting_scientist", 25, String("Scientist"));
|
||||
g_enemyNameTrie.Insert("monster_sitting_scientist", 25, String("Scientist"));
|
||||
g_allyNameTrie.Insert("monster_sentry", 14, String("Sentry Turret"));
|
||||
g_enemyNameTrie.Insert("monster_sentry", 14, String("Sentry Turret"));
|
||||
g_allyNameTrie.Insert("monster_shockroach", 18, String("Friendly Shock Roach"));
|
||||
g_enemyNameTrie.Insert("monster_shockroach", 18, String("Shock Roach"));
|
||||
g_allyNameTrie.Insert("monster_shocktrooper", 20, String("Friendly Shock Trooper"));
|
||||
g_enemyNameTrie.Insert("monster_shocktrooper", 20, String("Shock Trooper"));
|
||||
g_allyNameTrie.Insert("monster_snark", 13, String("Snark"));
|
||||
g_enemyNameTrie.Insert("monster_snark", 13, String("Snark"));
|
||||
g_allyNameTrie.Insert("monster_tentacle", 16, String("Tentacle"));
|
||||
g_enemyNameTrie.Insert("monster_tentacle", 16, String("Tentacle"));
|
||||
g_allyNameTrie.Insert("monster_tentaclemaw", 19, String("Tentacle"));
|
||||
g_enemyNameTrie.Insert("monster_tentaclemaw", 19, String("Tentacle"));
|
||||
g_allyNameTrie.Insert("monster_turret", 14, String("Turret"));
|
||||
g_enemyNameTrie.Insert("monster_turret", 14, String("Turret"));
|
||||
g_allyNameTrie.Insert("monster_zombie", 14, String("Friendly Zombie"));
|
||||
g_enemyNameTrie.Insert("monster_zombie", 14, String("Zombie"));
|
||||
g_allyNameTrie.Insert("monster_zombie_barney", 21, String("Friendly Zombie Barney"));
|
||||
g_enemyNameTrie.Insert("monster_zombie_barney", 21, String("Zombie Barney"));
|
||||
g_allyNameTrie.Insert("monster_zombie_soldier", 22, String("Friendly Zombie Soldier"));
|
||||
g_enemyNameTrie.Insert("monster_zombie_soldier", 22, String("Zombie Soldier"));
|
||||
}
|
||||
|
||||
void OnPluginsLoaded()
|
||||
{
|
||||
g_spawnFwd = MF_RegisterForward("sc_client_spawn", ET_IGNORE, FP_CELL, FP_DONE);
|
||||
g_healFwd = MF_RegisterForward("sc_client_heal", ET_IGNORE, FP_CELL, FP_CELL, FP_FLOAT, FP_CELL, FP_CELL, FP_DONE);
|
||||
g_grenadeFwd = MF_RegisterForward("sc_grenade_throw", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
}
|
||||
|
||||
//
|
||||
// METAMOD HOOKS
|
||||
//
|
||||
|
||||
/***GetEntityAPI2******************/
|
||||
|
||||
// sc_client_heal
|
||||
void DispatchThink(edict_t *pEntity)
|
||||
{
|
||||
if(g_healFwd != -1 && UTIL_IsMonster(pEntity))
|
||||
*((float *)pEntity->pvPrivateData + OFFSET_LAST_HEALTH) = pEntity->v.health;
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// sc_get_displayname
|
||||
void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
|
||||
{
|
||||
// catch displayname and store it ourselves for our native
|
||||
// TODO: store this somewhere else besides in the pev
|
||||
if(FStrEq(pkvd->szKeyName, "displayname"))
|
||||
pentKeyvalue->v.message = ALLOC_STRING(pkvd->szValue);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// sc_client_spawn
|
||||
void ClientPutInServer(edict_t *pPlayer)
|
||||
{
|
||||
g_lastDeadflag[ENTINDEX(pPlayer)] = -1;
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// sc_client_spawn / sc_client_heal
|
||||
void PlayerPreThink(edict_t *pPlayer)
|
||||
{
|
||||
if(g_spawnFwd != -1)
|
||||
{
|
||||
int index = ENTINDEX(pPlayer);
|
||||
|
||||
if(g_lastDeadflag[index] == -1 || (g_lastDeadflag[index] != DEAD_NO && pPlayer->v.deadflag == DEAD_NO))
|
||||
MF_ExecuteForward(g_spawnFwd, index);
|
||||
|
||||
g_lastDeadflag[index] = pPlayer->v.deadflag;
|
||||
}
|
||||
|
||||
if(g_healFwd != -1)
|
||||
*((float *)pPlayer->pvPrivateData + OFFSET_LAST_HEALTH) = pPlayer->v.health;
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
// sc_grenade_throw
|
||||
void StartFrame()
|
||||
{
|
||||
if(g_grenadeFwd == -1 || !g_grenadeCount)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
edict_t *pGrenade = g_grenadeList[0];
|
||||
|
||||
if(!FNullEnt(pGrenade) && pGrenade->v.owner)
|
||||
{
|
||||
const char *model = STRING(pGrenade->v.model);
|
||||
|
||||
int wId = 0;
|
||||
switch(model[7])
|
||||
{
|
||||
case 'g': wId = SCW_ARGRENADE; break; // models/grenade.mdl
|
||||
case 'w': wId = SCW_HANDGRENADE; break; // models/w_grenade.mdl
|
||||
//case 'c': wId = SCW_BANANA; break; // models/cretegibs.mdl
|
||||
}
|
||||
|
||||
if(wId) MF_ExecuteForward(g_grenadeFwd, ENTINDEX(pGrenade->v.owner),
|
||||
ENTINDEX(pGrenade), wId, UTIL_IsPlayer(pGrenade->v.owner));
|
||||
}
|
||||
|
||||
// shift the list
|
||||
g_grenadeList[0] = NULL;
|
||||
if(--g_grenadeCount)
|
||||
{
|
||||
for(int i=1;i<=g_grenadeCount;i++) g_grenadeList[i-1] = g_grenadeList[i];
|
||||
g_grenadeList[g_grenadeCount] = NULL;
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
/***GetEntityAPI2_Post*************/
|
||||
|
||||
// sc_set_frags
|
||||
void ServerActivate_Post(struct edict_s *, int, int)
|
||||
{
|
||||
gmsgScoreInfo = GET_USER_MSG_ID(PLID, "ScoreInfo", NULL);
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
/***GetEngineAPI*******************/
|
||||
|
||||
// sc_client_heal
|
||||
void EmitSound(edict_t *pEntity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch)
|
||||
{
|
||||
if(g_healFwd == -1 || !UTIL_IsPlayer(pEntity) || channel != CHAN_WEAPON || strcmp(sample, "items/medshot4.wav") != 0)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
Vector trStart = pEntity->v.origin;
|
||||
|
||||
if(pEntity->v.flags & FL_DUCKING) trStart.z += 12.0;
|
||||
else trStart.z += 28.0;
|
||||
|
||||
Vector trEnd = trStart + gpGlobals->v_forward * 32;
|
||||
|
||||
TraceResult tr;
|
||||
TRACE_LINE(trStart, trEnd, dont_ignore_monsters, pEntity, &tr);
|
||||
|
||||
if(tr.flFraction == 1.0)
|
||||
TRACE_HULL(trStart, trEnd, dont_ignore_monsters, head_hull, pEntity, &tr);
|
||||
|
||||
if(!FNullEnt(tr.pHit))
|
||||
{
|
||||
float amount = tr.pHit->v.health - *((float *)tr.pHit->pvPrivateData + OFFSET_LAST_HEALTH);
|
||||
|
||||
if(UTIL_IsPlayer(tr.pHit))
|
||||
MF_ExecuteForward(g_healFwd, ENTINDEX(pEntity), ENTINDEX(tr.pHit), amount, 1, 1);
|
||||
|
||||
else if(UTIL_IsMonster(tr.pHit))
|
||||
MF_ExecuteForward(g_healFwd, ENTINDEX(pEntity), ENTINDEX(tr.pHit), amount, 0, *((int *)tr.pHit->pvPrivateData + OFFSET_MONSTER_ALLY));
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
/***GetEngineAPI_Post**************/
|
||||
|
||||
// sc_grenade_throw
|
||||
void SetModel_Post(edict_t *pEntity, const char *model)
|
||||
{
|
||||
if(g_grenadeFwd == -1)
|
||||
RETURN_META(MRES_IGNORED);
|
||||
|
||||
const char *classname = STRING(pEntity->v.classname);
|
||||
|
||||
if(!pEntity->v.owner && classname[0] == 'g' && classname[2] == 'e' && model[7] == 'g')
|
||||
{
|
||||
if(g_grenadeCount < sizeof g_grenadeList)
|
||||
g_grenadeList[g_grenadeCount++] = pEntity;
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
|
@ -4,11 +4,13 @@
|
|||
#define __MODULECONFIG_H__
|
||||
|
||||
// Module info
|
||||
#define MODULE_NAME "SvenFun"
|
||||
#define MODULE_VERSION "1.65"
|
||||
#define MODULE_AUTHOR "Sanji"
|
||||
#define MODULE_URL "www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "SF"
|
||||
#define MODULE_NAME "SvenCoop"
|
||||
#define MODULE_VERSION "1.77"
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org"
|
||||
#define MODULE_LOGTAG "SVEN"
|
||||
#define MODULE_LIBRARY "svencoop"
|
||||
#define MODULE_LIBCLASS ""
|
||||
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
||||
#define MODULE_RELOAD_ON_MAPCHANGE
|
||||
|
||||
|
@ -31,18 +33,36 @@
|
|||
// It allows you to compile without libstdc++.so as a dependency
|
||||
// #define NO_ALLOC_OVERRIDES
|
||||
|
||||
// - AMXX Init functions
|
||||
// Also consider using FN_META_*
|
||||
// AMXX query
|
||||
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
|
||||
// #define NO_MSVC8_AUTO_COMPAT
|
||||
|
||||
/**
|
||||
* AMXX Init functions
|
||||
* Also consider using FN_META_*
|
||||
*/
|
||||
|
||||
/** AMXX query */
|
||||
//#define FN_AMXX_QUERY OnAmxxQuery
|
||||
// AMXX attach
|
||||
// Do native functions init here (MF_AddNatives)
|
||||
|
||||
/** AMXX attach
|
||||
* Do native functions init here (MF_AddNatives)
|
||||
*/
|
||||
#define FN_AMXX_ATTACH OnAmxxAttach
|
||||
// AMXX detach
|
||||
|
||||
/** AMXX Detach (unload) */
|
||||
//#define FN_AMXX_DETACH OnAmxxDetach
|
||||
// All plugins loaded
|
||||
// Do forward functions init here (MF_RegisterForward)
|
||||
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||
|
||||
/** All plugins loaded
|
||||
* Do forward functions init here (MF_RegisterForward)
|
||||
*/
|
||||
#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||
|
||||
/** All plugins are about to be unloaded */
|
||||
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
|
||||
|
||||
/** All plugins are now unloaded */
|
||||
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
||||
|
||||
|
||||
/**** METAMOD ****/
|
||||
// If your module doesn't use metamod, you may close the file now :)
|
||||
|
@ -65,11 +85,11 @@
|
|||
// - GetEntityAPI2 functions
|
||||
// #define FN_GameDLLInit GameDLLInit /* pfnGameInit() */
|
||||
// #define FN_DispatchSpawn DispatchSpawn /* pfnSpawn() */
|
||||
// #define FN_DispatchThink DispatchThink /* pfnThink() */
|
||||
#define FN_DispatchThink DispatchThink /* pfnThink() */
|
||||
// #define FN_DispatchUse DispatchUse /* pfnUse() */
|
||||
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
|
||||
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
|
||||
// #define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
#define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
// #define FN_DispatchSave DispatchSave /* pfnSave() */
|
||||
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
|
||||
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
|
||||
|
@ -81,14 +101,14 @@
|
|||
// #define FN_ClientConnect ClientConnect /* pfnClientConnect() (wd) Client has connected */
|
||||
// #define FN_ClientDisconnect ClientDisconnect /* pfnClientDisconnect() (wd) Player has left the game */
|
||||
// #define FN_ClientKill ClientKill /* pfnClientKill() (wd) Player has typed "kill" */
|
||||
// #define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
|
||||
#define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
|
||||
// #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */
|
||||
// #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */
|
||||
// #define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
|
||||
// #define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */
|
||||
// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
|
||||
#define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
|
||||
// #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */
|
||||
// #define FN_StartFrame StartFrame /* pfnStartFrame() */
|
||||
#define FN_StartFrame StartFrame /* pfnStartFrame() */
|
||||
// #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */
|
||||
// #define FN_ParmsChangeLevel ParmsChangeLevel /* pfnParmsChangeLevel() */
|
||||
// #define FN_GetGameDescription GetGameDescription /* pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2" "Half-Life" */
|
||||
|
@ -136,7 +156,7 @@
|
|||
// #define FN_ClientPutInServer_Post ClientPutInServer_Post
|
||||
// #define FN_ClientCommand_Post ClientCommand_Post
|
||||
// #define FN_ClientUserInfoChanged_Post ClientUserInfoChanged_Post
|
||||
// #define FN_ServerActivate_Post ServerActivate_Post
|
||||
#define FN_ServerActivate_Post ServerActivate_Post
|
||||
// #define FN_ServerDeactivate_Post ServerDeactivate_Post
|
||||
// #define FN_PlayerPreThink_Post PlayerPreThink_Post
|
||||
// #define FN_PlayerPostThink_Post PlayerPostThink_Post
|
||||
|
@ -196,7 +216,7 @@
|
|||
// #define FN_DropToFloor DropToFloor
|
||||
// #define FN_WalkMove WalkMove
|
||||
// #define FN_SetOrigin SetOrigin
|
||||
// #define FN_EmitSound EmitSound
|
||||
#define FN_EmitSound EmitSound
|
||||
// #define FN_EmitAmbientSound EmitAmbientSound
|
||||
// #define FN_TraceLine TraceLine
|
||||
// #define FN_TraceToss TraceToss
|
||||
|
@ -315,7 +335,7 @@
|
|||
// - GetEngineAPI_Post functions
|
||||
// #define FN_PrecacheModel_Post PrecacheModel_Post
|
||||
// #define FN_PrecacheSound_Post PrecacheSound_Post
|
||||
// #define FN_SetModel_Post SetModel_Post
|
||||
#define FN_SetModel_Post SetModel_Post
|
||||
// #define FN_ModelIndex_Post ModelIndex_Post
|
||||
// #define FN_ModelFrames_Post ModelFrames_Post
|
||||
// #define FN_SetSize_Post SetSize_Post
|
24
dlls/sven/sven/msvc7/svencoop.sln
Normal file
24
dlls/sven/sven/msvc7/svencoop.sln
Normal file
|
@ -0,0 +1,24 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "svencoop", "svencoop.vcproj", "{AB148B92-4F47-42E6-8268-AB4E588EC6A2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Profile = Profile
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{AB148B92-4F47-42E6-8268-AB4E588EC6A2}.Debug.ActiveCfg = Debug|Win32
|
||||
{AB148B92-4F47-42E6-8268-AB4E588EC6A2}.Debug.Build.0 = Debug|Win32
|
||||
{AB148B92-4F47-42E6-8268-AB4E588EC6A2}.Profile.ActiveCfg = Release|Win32
|
||||
{AB148B92-4F47-42E6-8268-AB4E588EC6A2}.Profile.Build.0 = Release|Win32
|
||||
{AB148B92-4F47-42E6-8268-AB4E588EC6A2}.Release.ActiveCfg = Release|Win32
|
||||
{AB148B92-4F47-42E6-8268-AB4E588EC6A2}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
204
dlls/sven/sven/msvc7/svencoop.vcproj
Normal file
204
dlls/sven/sven/msvc7/svencoop.vcproj
Normal file
|
@ -0,0 +1,204 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="svencoop"
|
||||
ProjectGUID="{AB148B92-4F47-42E6-8268-AB4E588EC6A2}"
|
||||
RootNamespace="svencoop"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SVENCOOP_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Debug/svencoop.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="Debug/svencoop_amxx.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\Debug/svencoop_amx_debug.pdb"
|
||||
ImportLibrary=".\Debug/svencoop_amx_debug.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Debug/cstrike.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1053"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SVENCOOP_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderFile=".\Release/svencoop.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="Release/svencoop_amxx.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\Release/svencoop_amx.pdb"
|
||||
ImportLibrary=".\Release/svencoop_amx.lib"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\Release/cstrike.tlb"
|
||||
HeaderFileName=""/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1053"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="..\moduleconfig.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\svencoop.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\CString.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\svencoop.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Trie.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="AMXX module"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\amxxmodule.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxmodule.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\moduleconfig.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
567
dlls/sven/sven/svencoop.cpp
Normal file
567
dlls/sven/sven/svencoop.cpp
Normal file
|
@ -0,0 +1,567 @@
|
|||
/* AMX Mod X
|
||||
* Sven Co-op Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "svencoop.h"
|
||||
|
||||
//
|
||||
// GLOBALS
|
||||
//
|
||||
|
||||
const char g_weapon_names[24][24] =
|
||||
{
|
||||
"",
|
||||
"weapon_crowbar",
|
||||
"weapon_9mmhandgun",
|
||||
"weapon_357",
|
||||
"weapon_9mmAR",
|
||||
"",
|
||||
"weapon_crossbow",
|
||||
"weapon_shotgun",
|
||||
"weapon_rpg",
|
||||
"weapon_gauss",
|
||||
"weapon_egon",
|
||||
"weapon_hornetgun",
|
||||
"weapon_handgrenade",
|
||||
"weapon_tripmine",
|
||||
"weapon_satchel",
|
||||
"weapon_snark",
|
||||
"weapon_uziakimbo",
|
||||
"weapon_uzi",
|
||||
"weapon_medkit",
|
||||
"weapon_crowbar_electric",
|
||||
"weapon_pipewrench",
|
||||
"weapon_minigun",
|
||||
"weapon_grapple",
|
||||
"weapon_sniperrifle"
|
||||
};
|
||||
|
||||
const int g_ammo_offsets[25] =
|
||||
{
|
||||
-1, // NONE = 0
|
||||
0, // SCW_CROWBAR = 1
|
||||
OFFSET_9MM_AMMO, // SCW_9MMHANDGUN = 2
|
||||
OFFSET_357_AMMO, // SCW_357 = 3
|
||||
OFFSET_9MM_AMMO, // SCW_9MMAR = 4
|
||||
-1, // NONE = 5
|
||||
OFFSET_CROSSBOW_AMMO, // SCW_CROSSBOW = 6
|
||||
OFFSET_SHOTGUN_AMMO, // SCW_SHOTGUN = 7
|
||||
OFFSET_RPG_AMMO, // SCW_RPG = 8
|
||||
OFFSET_ENERGY_AMMO, // SCW_GAUSS = 9
|
||||
OFFSET_ENERGY_AMMO, // SCW_EGON = 10
|
||||
OFFSET_HORNETGUN_AMMO, // SCW_HORNETGUN = 11
|
||||
OFFSET_HANDGRENADE_AMMO,// SCW_HANDGRENADE = 12
|
||||
OFFSET_TRIPMINE_AMMO, // SCW_TRIPMINE = 13
|
||||
OFFSET_SATCHEL_AMMO, // SCW_SATCHEL = 14
|
||||
OFFSET_SNARK_AMMO, // SCW_SNARK = 15
|
||||
OFFSET_9MM_AMMO, // SCW_UZIAKIMBO = 16
|
||||
OFFSET_9MM_AMMO, // SCW_UZI = 17
|
||||
OFFSET_MEDKIT_AMMO, // SCW_MEDKIT = 18
|
||||
0, // SCW_CROWBAR_ELECTRIC = 19
|
||||
0, // SCW_PIPEWRENCH = 20
|
||||
OFFSET_MINIGUN_AMMO, // SCW_MINIGUN = 21
|
||||
0, // SCW_GRAPPLE = 22
|
||||
OFFSET_SNIPERRIFLE_AMMO,// SCW_SNIPERRIFLE = 23
|
||||
OFFSET_ARGRENADE_AMMO // SCW_ARGRENADE = 24
|
||||
};
|
||||
|
||||
//
|
||||
// MONSTER NATIVES
|
||||
//
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_frags(AMX *amx, cell *params) // sc_get_frags(index); = 1 arguments
|
||||
{
|
||||
// Gets a monster's or player's frags
|
||||
// params[1] = monster/player index
|
||||
|
||||
// not CHECK_MONSTER because this works for players
|
||||
CHECK_ENTITY(params[1]);
|
||||
edict_t *pEdict = GETEDICT(params[1]);
|
||||
|
||||
if(!UTIL_IsPlayer(pEdict) && !UTIL_IsMonster(pEdict))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a player or monster_* entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return amx_ftoc(*((float *)pEdict->pvPrivateData + OFFSET_MONSTER_FRAGS));
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_frags(AMX *amx, cell *params) // sc_set_frags(index, Float:value); = 2 arguments
|
||||
{
|
||||
// Sets a monster's or player's frags
|
||||
// params[1] = index = monster/player index
|
||||
// params[2] = (float) new frags
|
||||
|
||||
// not CHECK_MONSTER because this works for players
|
||||
CHECK_ENTITY(params[1]);
|
||||
edict_t *pEdict = GETEDICT(params[1]);
|
||||
|
||||
if(!UTIL_IsPlayer(pEdict) && !UTIL_IsMonster(pEdict))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a player or monster_* entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
float fValue = amx_ctof(params[2]);
|
||||
*((float *)pEdict->pvPrivateData + OFFSET_MONSTER_FRAGS) = fValue;
|
||||
|
||||
if(UTIL_IsPlayer(pEdict))
|
||||
{
|
||||
pEdict->v.frags = fValue;
|
||||
|
||||
// update scoreboard
|
||||
if(gmsgScoreInfo)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
|
||||
WRITE_BYTE(params[1]);
|
||||
WRITE_SHORT((int)fValue);
|
||||
WRITE_SHORT(*((int *)pEdict->pvPrivateData + OFFSET_PLAYER_DEATHS));
|
||||
MESSAGE_END();
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_displayname(AMX *amx, cell *params) // sc_get_displayname(index, displayname[], len); = 3 arguments
|
||||
{
|
||||
// Gets a monster's displayname
|
||||
// params[1] = monster index
|
||||
// params[2] = return variable
|
||||
// params[3] = variable len
|
||||
|
||||
// check non-player (could be squadmaker)
|
||||
CHECK_NONPLAYER(params[1]);
|
||||
edict_t *pEdict = INDEXENT(params[1]);
|
||||
|
||||
// check valid types
|
||||
const char *classname = STRING(pEdict->v.classname);
|
||||
if(strcmp(classname, "squadmaker") != 0 && strncmp(classname, "monster", 7) != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a monstermaker, squadmaker, or monster_* entity", params[1], classname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check for a custom one
|
||||
const char *displayname = STRING(pEdict->v.message);
|
||||
if(displayname[0])
|
||||
{
|
||||
MF_SetAmxString(amx, params[2], displayname, params[3]);
|
||||
return 1; // 1 means custom displayname
|
||||
}
|
||||
|
||||
// maybe from a monstermaker? use its displayname.
|
||||
if(!strncmp(classname, "monster_", 8) && !FNullEnt(pEdict->v.owner))
|
||||
{
|
||||
const char *ownerclass = STRING(pEdict->v.owner->v.classname);
|
||||
if(!strcmp(ownerclass, "squadmaker") || !strcmp(ownerclass, "monstermaker"))
|
||||
{
|
||||
displayname = STRING(pEdict->v.owner->v.message);
|
||||
if(displayname[0])
|
||||
{
|
||||
return MF_SetAmxString(amx, params[2], displayname, params[3]);
|
||||
return 1; // 1 means custom displayname
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String *name = NULL;
|
||||
|
||||
if(*((int *)pEdict->pvPrivateData + OFFSET_MONSTER_ALLY))
|
||||
name = g_allyNameTrie.Retrieve(classname, strlen(classname));
|
||||
else
|
||||
name = g_enemyNameTrie.Retrieve(classname, strlen(classname));
|
||||
|
||||
if(name != NULL)
|
||||
{
|
||||
MF_SetAmxString(amx, params[2], name->c_str(), params[3]);
|
||||
return -1; // -1 means default displayname
|
||||
}
|
||||
|
||||
return 0; // invalid monster
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_displayname(AMX *amx, cell *params) // sc_set_displayname(index, displayname[], {Float,Sql,Result,_}:...); = 2 arguments
|
||||
{
|
||||
// Sets a monster's displayname
|
||||
// params[1] = monster index
|
||||
// params[2] = new displayname
|
||||
// params[3...] = formatting
|
||||
|
||||
// check non-player (could be squadmaker)
|
||||
CHECK_NONPLAYER(params[1]);
|
||||
edict_t *pEdict = INDEXENT(params[1]);
|
||||
|
||||
// check valid types
|
||||
const char *classname = STRING(pEdict->v.classname);
|
||||
if(strcmp(classname, "squadmaker") != 0 && strncmp(classname, "monster", 7) != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a monstermaker, squadmaker, or monster_* entity", params[1], classname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fetch string
|
||||
int len = 0;
|
||||
char *displayname = MF_FormatAmxString(amx, params, 2, &len);
|
||||
|
||||
// set_kvd
|
||||
KeyValueData *kvd = &g_kvd;
|
||||
kvd->szClassName = const_cast<char *>(classname);
|
||||
kvd->szKeyName = const_cast<char *>("displayname");
|
||||
kvd->szValue = const_cast<char *>(displayname);
|
||||
kvd->fHandled = 0;
|
||||
gpGamedllFuncs->dllapi_table->pfnKeyValue(pEdict, kvd);
|
||||
|
||||
// remember it
|
||||
pEdict->v.message = ALLOC_STRING(displayname);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_is_player_ally(AMX *amx, cell *params) // sc_is_player_ally(index); = 1 arguments
|
||||
{
|
||||
// Checks if a monster is a player ally
|
||||
// params[1] = monster index
|
||||
|
||||
CHECK_MONSTER(params[1]);
|
||||
edict_t *pEdict = INDEXENT(params[1]);
|
||||
|
||||
return *((int *)pEdict->pvPrivateData + OFFSET_MONSTER_ALLY);
|
||||
}
|
||||
|
||||
//
|
||||
// PLAYER NATIVES
|
||||
// (ammo excluded)
|
||||
//
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_user_longjump(AMX *amx, cell *params) // sc_get_user_longjump(index); = 1 arguments
|
||||
{
|
||||
// Checks if a player can longjump
|
||||
// params[1] = player index
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||||
|
||||
const char *buffer = (*g_engfuncs.pfnGetPhysicsKeyValue)(pEdict, "slj");
|
||||
if(buffer[0] == '1') return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_user_longjump(AMX *amx, cell *params) // sc_set_user_longjump(index, value); = 2 arguments
|
||||
{
|
||||
// Sets if a player can longjump
|
||||
// params[1] = player index
|
||||
// params[2] = new value
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||||
|
||||
if(params[2]) (*g_engfuncs.pfnSetPhysicsKeyValue)(pEdict, "slj", "1");
|
||||
else (*g_engfuncs.pfnSetPhysicsKeyValue)(pEdict, "slj", "0");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_user_deaths(AMX *amx, cell *params) // sc_get_user_deaths(index); = 1 arguments
|
||||
{
|
||||
// Gets the number of times a player has died (duh!)
|
||||
// params[1] = player index
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||||
|
||||
return *((int *)pEdict->pvPrivateData + OFFSET_PLAYER_DEATHS);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_user_deaths(AMX *amx, cell *params) // sc_set_user_deaths(index, value); = 2 arguments
|
||||
{
|
||||
// Sets the number of times a player has died
|
||||
// params[1] = player index
|
||||
// params[2] = new death amount
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||||
|
||||
*((int *)pEdict->pvPrivateData + OFFSET_PLAYER_DEATHS) = params[2];
|
||||
|
||||
// update scoreboard
|
||||
if(gmsgScoreInfo)
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
|
||||
WRITE_BYTE(params[1]);
|
||||
WRITE_SHORT((int)pEdict->v.frags);
|
||||
WRITE_SHORT(params[2]);
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
*static_cast<int *>(MF_PlayerPropAddr(params[1], Player_Deaths)) = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// AMMO NATIVES
|
||||
//
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_wbox_ammo(AMX *amx, cell *params) // sc_get_wbox_ammo(index); = 1 arguments
|
||||
{
|
||||
// Gets the amount of ammo in dropped ammo weaponbox
|
||||
// params[1] = weaponbox entity index
|
||||
|
||||
CHECK_NONPLAYER(params[1]);
|
||||
edict_t *pEdict = INDEXENT(params[1]);
|
||||
|
||||
if(strcmp(STRING(pEdict->v.classname), "weaponbox") != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weaponbox entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((int *)pEdict->pvPrivateData + OFFSET_WBOX_AMMO);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_wbox_ammo(AMX *amx, cell *params) // sc_set_wbox_ammo(index, value); = 1 arguments
|
||||
{
|
||||
// Sets the amount of ammo in dropped ammo weaponbox
|
||||
// params[1] = weaponbox entity index
|
||||
// params[2] = new ammo amount
|
||||
|
||||
CHECK_NONPLAYER(params[1]);
|
||||
edict_t *pEdict = INDEXENT(params[1]);
|
||||
|
||||
if(strcmp(STRING(pEdict->v.classname), "weaponbox") != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weaponbox entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
*((int *)pEdict->pvPrivateData + OFFSET_WBOX_AMMO) = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_weapon_id(AMX *amx, cell *params) // sc_get_weapon_id(index); = 1 arguments
|
||||
{
|
||||
// Gets the SCW_* constant of a weapon_* entity
|
||||
// params[1] = weapon_* entity index
|
||||
|
||||
CHECK_NONPLAYER(params[1]);
|
||||
edict_t *pEdict = INDEXENT(params[1]);
|
||||
|
||||
// not a valid weapon_*
|
||||
if(strncmp(STRING(pEdict->v.classname), "weapon_", 7) != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weapon_* entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((int *)pEdict->pvPrivateData + OFFSET_WEAPON_TYPE);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_weapon_ammo(AMX *amx, cell *params) // sc_get_weapon_ammo(index1, index2=0); = 2 arguments
|
||||
{
|
||||
// Gets the amount of ammo in weapon's clip
|
||||
// params[1] = weapon_* entity index OR player index
|
||||
// params[2] = (optional) SCW_* constant if using player index
|
||||
|
||||
CHECK_ENTITY(params[1]);
|
||||
edict_t *pEdict = GETEDICT(params[1]);
|
||||
|
||||
// sc_get_weapon_ammo(id, SCW_9MMAR);
|
||||
if(params[2])
|
||||
{
|
||||
if(params[2] < 1 || params[2] > 23 || params[2] == 5)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pWeapon = NULL;
|
||||
|
||||
const char *weaponname = g_weapon_names[params[2]];
|
||||
|
||||
while(true)
|
||||
{
|
||||
pWeapon = FIND_ENTITY_BY_STRING(pWeapon, "classname", weaponname);
|
||||
if(FNullEnt(pWeapon) || pWeapon->v.owner == pEdict) break;
|
||||
}
|
||||
|
||||
if(FNullEnt(pWeapon))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Player %d does not have a \"%s\" (index %d)", params[1], weaponname, params[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((int *)pWeapon->pvPrivateData + OFFSET_WEAPON_CLIP);
|
||||
}
|
||||
|
||||
if(strncmp(STRING(pEdict->v.classname), "weapon_", 7) != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weapon_* entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return *((int *)pEdict->pvPrivateData + OFFSET_WEAPON_CLIP);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_weapon_ammo(AMX *amx, cell *params) // sc_set_weapon_ammo(index1, value, index2=0); = 3 arguments
|
||||
{
|
||||
// Sets the amount of ammo in weapon's clip
|
||||
// params[1] = weapon_* entity index OR player index
|
||||
// params[2] = new clip ammo
|
||||
// params[3] = (optional) SCW_* constant if using player index
|
||||
|
||||
CHECK_ENTITY(params[1]);
|
||||
edict_t *pEdict = GETEDICT(params[1]);
|
||||
|
||||
// sc_set_weapon_ammo(id, SCW_9MMAR, 50);
|
||||
if(params[3])
|
||||
{
|
||||
if(params[3] < 1 || params[3] > 23 || params[3] == 5)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pWeapon = NULL;
|
||||
|
||||
const char *weaponname = g_weapon_names[params[3]];
|
||||
|
||||
while(true)
|
||||
{
|
||||
pWeapon = FIND_ENTITY_BY_STRING(pWeapon, "classname", weaponname);
|
||||
if(FNullEnt(pWeapon) || pWeapon->v.owner == pEdict) break;
|
||||
}
|
||||
|
||||
if(FNullEnt(pWeapon))
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Player %d does not have a \"%s\" (index %d)", params[1], weaponname, params[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*((int *)pWeapon->pvPrivateData + OFFSET_WEAPON_CLIP) = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strncmp(STRING(pEdict->v.classname), "weapon_", 7) != 0)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a weapon_* entity", params[1], STRING(pEdict->v.classname));
|
||||
return 0;
|
||||
}
|
||||
|
||||
*((int *)pEdict->pvPrivateData + OFFSET_WEAPON_CLIP) = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_user_bpammo(AMX *amx, cell *params) // sc_get_user_bpammo(index, weapon); = 2 arguments
|
||||
{
|
||||
// Gets the amount of ammo in player's backpack for a specific weapon
|
||||
// params[1] = player index
|
||||
// params[2] = SCW_* constant
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||||
|
||||
if(params[2] < 1 || params[2] > 23 || params[2] == 5)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// invalid weapon or no bpammo
|
||||
if(g_ammo_offsets[params[2]] <= 0)
|
||||
return 0;
|
||||
|
||||
return *((int *)pEdict->pvPrivateData + g_ammo_offsets[params[2]]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_user_bpammo(AMX *amx, cell *params) // sc_set_user_bpammo(index, weapon, value); = 3 arguments
|
||||
{
|
||||
// Gets the amount of ammo in player's backpack for a specific weapon
|
||||
// params[1] = player index
|
||||
// params[2] = SCW_* constant
|
||||
// params[3] = new backpack ammo
|
||||
|
||||
CHECK_PLAYER(params[1]);
|
||||
edict_t *pEdict = MF_GetPlayerEdict(params[1]);
|
||||
|
||||
if(params[2] < 1 || params[2] > 23 || params[2] == 5)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid weapon index %d", params[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// invalid weapon or no bpammo
|
||||
if(g_ammo_offsets[params[2]] <= 0)
|
||||
return 0;
|
||||
|
||||
*((int *)pEdict->pvPrivateData + g_ammo_offsets[params[2]]) = params[3];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// EXPORT LIST
|
||||
//
|
||||
|
||||
AMX_NATIVE_INFO svencoop_Exports[] =
|
||||
{
|
||||
// monster natives
|
||||
{"sc_get_frags", sc_get_frags},
|
||||
{"sc_set_frags", sc_set_frags},
|
||||
{"sc_get_displayname", sc_get_displayname},
|
||||
{"sc_set_displayname", sc_set_displayname},
|
||||
{"sc_is_player_ally", sc_is_player_ally},
|
||||
|
||||
// player natives
|
||||
{"sc_get_user_longjump", sc_get_user_longjump},
|
||||
{"sc_set_user_longjump", sc_set_user_longjump},
|
||||
{"sc_get_user_deaths", sc_get_user_deaths},
|
||||
{"sc_set_user_deaths", sc_set_user_deaths},
|
||||
|
||||
// ammo natives
|
||||
{"sc_get_wbox_ammo", sc_get_wbox_ammo},
|
||||
{"sc_set_wbox_ammo", sc_set_wbox_ammo},
|
||||
{"sc_get_weapon_id", sc_get_weapon_id},
|
||||
{"sc_get_weapon_ammo", sc_get_weapon_ammo},
|
||||
{"sc_set_weapon_ammo", sc_set_weapon_ammo},
|
||||
{"sc_get_user_bpammo", sc_get_user_bpammo},
|
||||
{"sc_set_user_bpammo", sc_set_user_bpammo},
|
||||
//------------------- <-- max 19 characters?? bleh!
|
||||
{NULL, NULL}
|
||||
};
|
239
dlls/sven/sven/svencoop.h
Normal file
239
dlls/sven/sven/svencoop.h
Normal file
|
@ -0,0 +1,239 @@
|
|||
/* AMX Mod X
|
||||
* Sven Co-op Module
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is part of AMX Mod X.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxxmodule.h"
|
||||
#include "CString.h"
|
||||
#include "Trie.h"
|
||||
|
||||
// right now there is no Linux Sven Co-op, but for the future...
|
||||
#if defined __linux__
|
||||
#define EXTRAOFFSET_MONSTER 0
|
||||
#define EXTRAOFFSET_WEAPON 0
|
||||
#define EXTRAOFFSET_WBOX 0
|
||||
#define EXTRAOFFSET_PLAYER 0
|
||||
#else
|
||||
#define EXTRAOFFSET_MONSTER 0
|
||||
#define EXTRAOFFSET_WEAPON 0
|
||||
#define EXTRAOFFSET_WBOX 0
|
||||
#define EXTRAOFFSET_PLAYER 0
|
||||
#endif // defined __linux__
|
||||
|
||||
// 32-bit
|
||||
#if !defined __amd64__
|
||||
#define OFFSET_LAST_HEALTH 834 // arbitrary, our own storage
|
||||
|
||||
// monster offsets
|
||||
#define OFFSET_MONSTER_FRAGS 9 + EXTRAOFFSET_MONSTER
|
||||
#define OFFSET_MONSTER_ALLY 10 + EXTRAOFFSET_MONSTER
|
||||
|
||||
// player offsets (non-ammo)
|
||||
#define OFFSET_PLAYER_DEATHS 8624 + EXTRAOFFSET_PLAYER
|
||||
|
||||
// weapon offsets
|
||||
#define OFFSET_WEAPON_TYPE 8224 + EXTRAOFFSET_WEAPON
|
||||
#define OFFSET_WEAPON_CLIP 8233 + EXTRAOFFSET_WBOX
|
||||
#define OFFSET_WBOX_AMMO 8255 + EXTRAOFFSET_WBOX
|
||||
|
||||
// ammo offsets
|
||||
#define OFFSET_357_AMMO 8563 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_9MM_AMMO 8557 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_CROSSBOW_AMMO 8566 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SHOTGUN_AMMO 8558 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_RPG_AMMO 8565 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_ENERGY_AMMO 8564 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_HORNETGUN_AMMO 8571 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_HANDGRENADE_AMMO 8569 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_TRIPMINE_AMMO 8567 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SATCHEL_AMMO 8568 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SNARK_AMMO 8570 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_MEDKIT_AMMO 8559 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_MINIGUN_AMMO 8560 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SNIPERRIFLE_AMMO 8561 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_ARGRENADE_AMMO 8562 + EXTRAOFFSET_PLAYER
|
||||
|
||||
// 64-bit (no amd64 Sven Co-op, but thinking ahead)
|
||||
#else
|
||||
#define OFFSET_OLD_HEALTH 834
|
||||
|
||||
// monster offsets
|
||||
#define OFFSET_MONSTER_FRAGS 9 + EXTRAOFFSET_MONSTER
|
||||
#define OFFSET_MONSTER_ALLY 10 + EXTRAOFFSET_MONSTER
|
||||
|
||||
// player offsets (non-ammo)
|
||||
#define OFFSET_PLAYER_DEATHS 8624 + EXTRAOFFSET_PLAYER
|
||||
|
||||
// weapon offsets
|
||||
#define OFFSET_WEAPON_TYPE 8224 + EXTRAOFFSET_WEAPON
|
||||
#define OFFSET_WEAPON_CLIP 8233 + EXTRAOFFSET_WBOX
|
||||
#define OFFSET_WBOX_AMMO 8255 + EXTRAOFFSET_WBOX
|
||||
|
||||
// ammo offsets
|
||||
#define OFFSET_357_AMMO 8563 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_9MM_AMMO 8557 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_CROSSBOW_AMMO 8566 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SHOTGUN_AMMO 8558 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_RPG_AMMO 8565 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_ENERGY_AMMO 8564 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_HORNETGUN_AMMO 8571 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_HANDGRENADE_AMMO 8569 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_TRIPMINE_AMMO 8567 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SATCHEL_AMMO 8568 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SNARK_AMMO 8570 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_MEDKIT_AMMO 8559 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_MINIGUN_AMMO 8560 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_SNIPERRIFLE_AMMO 8561 + EXTRAOFFSET_PLAYER
|
||||
#define OFFSET_ARGRENADE_AMMO 8562 + EXTRAOFFSET_PLAYER
|
||||
#endif
|
||||
|
||||
// weapon ids
|
||||
enum
|
||||
{
|
||||
SCW_CROWBAR = 1,
|
||||
SCW_9MMHANDGUN = 2,
|
||||
SCW_357 = 3,
|
||||
SCW_9MMAR = 4,
|
||||
SCW_CROSSBOW = 6,
|
||||
SCW_SHOTGUN = 7,
|
||||
SCW_RPG = 8,
|
||||
SCW_GAUSS = 9,
|
||||
SCW_EGON = 10,
|
||||
SCW_HORNETGUN = 11,
|
||||
SCW_HANDGRENADE = 12,
|
||||
SCW_TRIPMINE = 13,
|
||||
SCW_SATCHEL = 14,
|
||||
SCW_SNARK = 15,
|
||||
SCW_UZIAKIMBO = 16,
|
||||
SCW_UZI = 17,
|
||||
SCW_MEDKIT = 18,
|
||||
SCW_CROWBAR_ELECTRIC = 19,
|
||||
SCW_PIPEWRENCH = 20,
|
||||
SCW_MINIGUN = 21,
|
||||
SCW_GRAPPLE = 22,
|
||||
SCW_SNIPERRIFLE = 23,
|
||||
SCW_ARGRENADE = 24
|
||||
};
|
||||
|
||||
//
|
||||
// externs
|
||||
//
|
||||
|
||||
extern AMX_NATIVE_INFO svencoop_Exports[];
|
||||
extern int gmsgScoreInfo;
|
||||
extern KeyValueData g_kvd;
|
||||
extern Trie<char,String> g_allyNameTrie, g_enemyNameTrie;
|
||||
|
||||
//
|
||||
// inline functions
|
||||
//
|
||||
|
||||
inline bool UTIL_IsPlayer(edict_t *pPlayer)
|
||||
{
|
||||
if(strcmp(STRING(pPlayer->v.classname), "player") == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool UTIL_IsMonster(edict_t *pMonster)
|
||||
{
|
||||
if(strncmp(STRING(pMonster->v.classname), "monster_", 8) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// entity checking defines
|
||||
//
|
||||
|
||||
#define CHECK_ENTITY(x) \
|
||||
if (x <= 0 || x > gpGlobals->maxEntities) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", x); \
|
||||
return 0; \
|
||||
} else { \
|
||||
if (x <= gpGlobals->maxClients) { \
|
||||
if (!MF_IsPlayerIngame(x)) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not in-game)", x); \
|
||||
return 0; \
|
||||
} \
|
||||
} else { \
|
||||
if (x != 0 && FNullEnt(INDEXENT(x))) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d", x); \
|
||||
return 0; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_PLAYER(x) \
|
||||
if (x < 1 || x > gpGlobals->maxClients) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Player out of range (%d)", x); \
|
||||
return 0; \
|
||||
} else { \
|
||||
if (!MF_IsPlayerIngame(x) || FNullEnt(MF_GetPlayerEdict(x))) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid player %d", x); \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_NONPLAYER(x) \
|
||||
if (x < 1 || x <= gpGlobals->maxClients || x > gpGlobals->maxEntities) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Non-player entity %d out of range", x); \
|
||||
return 0; \
|
||||
} else { \
|
||||
if (FNullEnt(INDEXENT(x))) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid non-player entity %d", x); \
|
||||
return 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_MONSTER(x) \
|
||||
if (x < 1 || x <= gpGlobals->maxClients || x > gpGlobals->maxEntities) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Monster entity %d out of range", x); \
|
||||
return 0; \
|
||||
} else { \
|
||||
if (FNullEnt(INDEXENT(x))) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid monster entity %d", x); \
|
||||
return 0; \
|
||||
} else { \
|
||||
if(strncmp(STRING(GETEDICT(x)->v.classname),"monster_",8) != 0) { \
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Entity %d (\"%s\") is not a monster_* entity", x, STRING(GETEDICT(x)->v.classname)); \
|
||||
return 0; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GETEDICT(n) \
|
||||
((n >= 1 && n <= gpGlobals->maxClients) ? MF_GetPlayerEdict(n) : INDEXENT(n))
|
||||
|
104
dlls/sven/sven/svencoop.inc
Normal file
104
dlls/sven/sven/svencoop.inc
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* Sven Co-op functions
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _svencoop_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _svencoop_included
|
||||
|
||||
#include <svencoop_const>
|
||||
|
||||
/* Gets a monster's or player's frags */
|
||||
native Float:sc_get_frags(index);
|
||||
|
||||
/* Sets a monster's or player's frags */
|
||||
native sc_set_frags(index, Float:value);
|
||||
|
||||
/* Gets a monster's displayname
|
||||
|
||||
Returns 1 if custom displayname, 0 if displayname unavailable, -1 if default displayname
|
||||
*/
|
||||
native sc_get_displayname(index, displayname[], len);
|
||||
|
||||
/* Sets a monster's displayname */
|
||||
native sc_set_displayname(index, displayname[], {Float,Sql,Result,_}:...);
|
||||
|
||||
/* Checks if a monster is a player ally or not */
|
||||
native sc_is_player_ally(index);
|
||||
|
||||
/* Gets if a player has longjump */
|
||||
native sc_get_user_longjump(index);
|
||||
|
||||
/* Sets if a player has longjump */
|
||||
native sc_set_user_longjump(index, value);
|
||||
|
||||
/* Gets a player's deaths */
|
||||
native sc_get_user_deaths(index);
|
||||
|
||||
/* Sets a player's deaths */
|
||||
native sc_set_user_deaths(index, value);
|
||||
|
||||
/* Gets the amount of ammo in dropped ammo weaponbox */
|
||||
native sc_get_wbox_ammo(index);
|
||||
|
||||
/* Sets the amount of ammo in dropped ammo weaponbox */
|
||||
native sc_set_wbox_ammo(index, value);
|
||||
|
||||
/* Gets a weapon's type (in the form of SCW_* constants)
|
||||
|
||||
"index" = weapon_* entity
|
||||
*/
|
||||
native sc_get_weapon_id(index);
|
||||
|
||||
/* Gets the amount of ammo in weapon's clip
|
||||
|
||||
Usage 1:
|
||||
new weapon = find_ent_by_owner(-1,"weapon_9mmAR",id);
|
||||
sc_get_weapon_ammo(weapon);
|
||||
Usage 2:
|
||||
sc_get_weapon_ammo(id,SCW_9MMAR);
|
||||
*/
|
||||
native sc_get_weapon_ammo(index1, index2=0);
|
||||
|
||||
/* Sets the amount of ammo in weapon's clip
|
||||
|
||||
Usage 1:
|
||||
new weapon = find_ent_by_owner(-1,"weapon_9mmAR",id);
|
||||
sc_set_weapon_ammo(weapon,50);
|
||||
Usage 2:
|
||||
sc_set_weapon_ammo(id,50,SCW_9MMAR);
|
||||
*/
|
||||
native sc_set_weapon_ammo(index1, newammo, index2=0);
|
||||
|
||||
/* Gets the amount of ammo in players's backpack for a specific weapon
|
||||
|
||||
"weapon" = SCW_* constant
|
||||
*/
|
||||
native sc_get_user_bpammo(index, weapon);
|
||||
|
||||
/* Sets the amount of ammo in players's backpack for a specific weapon
|
||||
|
||||
"weapon" = SCW_* constant
|
||||
*/
|
||||
native sc_set_user_bpammo(index, weapon, value);
|
||||
|
||||
/* Called whenever a player respawns */
|
||||
forward sc_client_spawn(index);
|
||||
|
||||
/* Called whenever a player or monster throws a grenade
|
||||
|
||||
"isplayer" is 1 if the thrower is a player, 0 if a monster
|
||||
*/
|
||||
forward sc_grenade_throw(index, greindex, wId, isplayer);
|
||||
|
||||
/* Called whenever a player ATTEMPTS to heal another player or monster
|
||||
(so, they could be healing for 0.0 health, or trying to heal an enemy)
|
||||
|
||||
"isplayer" is 1 if the healed entity is a player, 0 if a monster
|
||||
"isally" is 1 if the healed entity is an ally, 0 if an enemy
|
||||
*/
|
||||
forward sc_client_heal(healer, healed, Float:amount, isplayer, isally);
|
98
dlls/sven/sven/svencoop_const.inc
Normal file
98
dlls/sven/sven/svencoop_const.inc
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* Sven Co-op functions
|
||||
*
|
||||
* (c) 2007, XxAvalanchexX
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _svencoop_const_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _svencoop_const_included
|
||||
|
||||
/* SvenCoop weapons */
|
||||
enum
|
||||
{
|
||||
SCW_CROWBAR = 1,
|
||||
SCW_9MMHANDGUN = 2, // ammo_9mmAR, ammo_9mmbox, ammo_9mmclip, ammo_glockclip, ammo_mp5clip
|
||||
SCW_357 = 3, // ammo_357
|
||||
SCW_9MMAR = 4, // ammo_9mmAR, ammo_9mmbox, ammo_9mmclip, ammo_glockclip, ammo_mp5clip,
|
||||
SCW_CROSSBOW = 6, // ammo_crossbow
|
||||
SCW_SHOTGUN = 7, // ammo_buckshot
|
||||
SCW_RPG = 8, // ammo_rpgclip
|
||||
SCW_GAUSS = 9, // ammo_egonclip, ammo_gaussclip
|
||||
SCW_EGON = 10, // ammo_egonclip, ammo_gaussclip
|
||||
SCW_HORNETGUN = 11,
|
||||
SCW_HANDGRENADE = 12,
|
||||
SCW_TRIPMINE = 13,
|
||||
SCW_SATCHEL = 14,
|
||||
SCW_SNARK = 15,
|
||||
SCW_UZIAKIMBO = 16, // ammo_9mmAR, ammo_9mmbox, ammo_9mmclip, ammo_glockclip, ammo_mp5clip
|
||||
SCW_UZI = 17, // ammo_9mmAR, ammo_9mmbox, ammo_9mmclip, ammo_glockclip, ammo_mp5clip
|
||||
SCW_MEDKIT = 18,
|
||||
SCW_CROWBAR_ELECTRIC = 19, // item_battery
|
||||
SCW_PIPEWRENCH = 20,
|
||||
SCW_MINIGUN = 21, // ammo_556
|
||||
SCW_GRAPPLE = 22,
|
||||
SCW_SNIPERRIFLE = 23, // ammo_762
|
||||
|
||||
// USE ONLY FOR sc_*et_user_bpammo NATIVES!
|
||||
SCW_ARGRENADE = 24 // ammo_ARgrenades, ammo_mp5grenades
|
||||
};
|
||||
|
||||
stock const SCW_MAX_CLIP[25] =
|
||||
{
|
||||
-1, // NONE = 0
|
||||
0, // SCW_CROWBAR = 1
|
||||
17, // SCW_9MMHANDGUN = 2
|
||||
6, // SCW_357 = 3
|
||||
50, // SCW_9MMAR = 4
|
||||
-1, // NONE = 5
|
||||
5, // SCW_CROSSBOW = 6
|
||||
8, // SCW_SHOTGUN = 7
|
||||
1, // SCW_RPG = 8
|
||||
0, // SCW_GAUSS = 9
|
||||
0, // SCW_EGON = 10
|
||||
0, // SCW_HORNETGUN = 11
|
||||
0, // SCW_HANDGRENADE = 12
|
||||
0, // SCW_TRIPMINE = 13
|
||||
0, // SCW_SATCHEL = 14
|
||||
0, // SCW_SNARK = 15
|
||||
32, // SCW_UZIAKIMBO = 16
|
||||
32, // SCW_UZI = 17
|
||||
0, // SCW_MEDKIT = 18
|
||||
0, // SCW_CROWBAR_ELECTRIC = 19
|
||||
0, // SCW_PIPEWRENCH = 20
|
||||
0, // SCW_MINIGUN = 21
|
||||
0, // SCW_GRAPPLE = 22
|
||||
5, // SCW_SNIPERRIFLE = 23
|
||||
0 // SCW_ARGRENADE = 24
|
||||
}
|
||||
|
||||
stock const SCW_MAX_AMMO[25] =
|
||||
{
|
||||
-1, // NONE = 0
|
||||
0, // SCW_CROWBAR = 1
|
||||
250, // SCW_9MMHANDGUN = 2
|
||||
36, // SCW_357 = 3
|
||||
250, // SCW_9MMAR = 4
|
||||
-1, // NONE = 5
|
||||
50, // SCW_CROSSBOW = 6
|
||||
125, // SCW_SHOTGUN = 7
|
||||
5, // SCW_RPG = 8
|
||||
100, // SCW_GAUSS = 9
|
||||
100, // SCW_EGON = 10
|
||||
8, // SCW_HORNETGUN = 11
|
||||
10, // SCW_HANDGRENADE = 12
|
||||
5, // SCW_TRIPMINE = 13
|
||||
5, // SCW_SATCHEL = 14
|
||||
15, // SCW_SNARK = 15
|
||||
250, // SCW_UZIAKIMBO = 16
|
||||
250, // SCW_UZI = 17
|
||||
100, // SCW_MEDKIT = 18
|
||||
0, // SCW_CROWBAR_ELECTRIC = 19
|
||||
0, // SCW_PIPEWRENCH = 20
|
||||
999, // SCW_MINIGUN = 21
|
||||
0, // SCW_GRAPPLE = 22
|
||||
15, // SCW_SNIPERRIFLE = 23
|
||||
10 // SCW_ARGRENADE = 24
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
#include "svencoop.h"
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_frags(AMX *amx, cell *params)
|
||||
{
|
||||
return GetFrags(params[1]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_frags(AMX *amx, cell *params)
|
||||
{
|
||||
SetFrags(params[1], params[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_user_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
return GetDeaths(params[1]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_user_deaths(AMX *amx, cell *params)
|
||||
{
|
||||
SetDeaths(params[1], params[2] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_is_player_ally(AMX *amx, cell *params)
|
||||
{
|
||||
return IsEntAlly(params[1]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_get_weapon_ammo(AMX *amx, cell *params)
|
||||
{
|
||||
switch(params[2])
|
||||
{
|
||||
case SVEN_WEP_9MM: return GetSvenWeapon(params[1], sven_9mm);
|
||||
case SVEN_WEP_SHOTGUN: return GetSvenWeapon(params[1], sven_shotgun);
|
||||
case SVEN_WEP_RPG: return GetSvenWeapon(params[1], sven_rpg);
|
||||
|
||||
case SVEN_WEP_RADIO: return GetSvenWeapon(params[1], sven_radio);
|
||||
case SVEN_WEP_SNARK: return GetSvenWeapon(params[1], sven_snark);
|
||||
|
||||
default: MF_LogError(amx, AMX_ERR_NATIVE,"Incorrect weapon specified in SvenCoop Get Weapon Native");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL sc_set_weapon_ammo(AMX *amx, cell *params)
|
||||
{
|
||||
switch(params[3])
|
||||
{
|
||||
case SVEN_WEP_9MM: return SetSvenWeapon(params[1], params[2], sven_9mm);
|
||||
case SVEN_WEP_SHOTGUN: return SetSvenWeapon(params[1], params[2], sven_shotgun);
|
||||
case SVEN_WEP_RPG: return SetSvenWeapon(params[1], params[2], sven_rpg);
|
||||
|
||||
case SVEN_WEP_RADIO: return SetSvenWeapon(params[1], params[2], sven_radio);
|
||||
case SVEN_WEP_SNARK: return SetSvenWeapon(params[1], params[2], sven_snark);
|
||||
|
||||
default: MF_LogError(amx, AMX_ERR_NATIVE,"Incorrect weapon specified in SvenCoop Set Weapon Native");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO sven_Natives[] = {
|
||||
{ "sc_get_frags", sc_get_frags },
|
||||
{ "sc_set_frags", sc_set_frags },
|
||||
{ "sc_get_user_deaths", sc_get_user_deaths },
|
||||
{ "sc_set_user_deaths", sc_set_user_deaths },
|
||||
{ "sc_is_player_ally", sc_is_player_ally },
|
||||
|
||||
{ "sc_get_weapon_ammo", sc_get_weapon_ammo },
|
||||
{ "sc_set_weapon_ammo", sc_set_weapon_ammo },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
MF_AddNatives(sven_Natives);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
// prevent double include
|
||||
#ifndef __SVEN_H__
|
||||
#define __SVEN_H__
|
||||
|
||||
#include "amxxmodule.h"
|
||||
#include "pdata.h"
|
||||
|
||||
#include "svencoop_const.h"
|
||||
|
||||
inline void SetFrags( long& targetid, long val)
|
||||
{
|
||||
SetPData(targetid, PDATA_FRAGS, static_cast<float>(val) );
|
||||
};
|
||||
|
||||
inline long GetFrags( long& targetid)
|
||||
{
|
||||
return static_cast<long>( GetPData(targetid, PDATA_FRAGS, float(NULL) ) );
|
||||
};
|
||||
|
||||
inline long GetDeaths( long& targetid)
|
||||
{
|
||||
return GetPData(targetid, PDATA_DEATHS, int(NULL) );
|
||||
};
|
||||
|
||||
inline void SetDeaths( long& targetid, long val)
|
||||
{
|
||||
SetPData(targetid, PDATA_DEATHS, static_cast<int>(val) );
|
||||
};
|
||||
|
||||
inline long IsEntAlly( long& targetid)
|
||||
{
|
||||
return GetPData(targetid, PDATA_ALLY, unsigned char( NULL ) );
|
||||
};
|
||||
|
||||
inline long SetSvenWeapon(long& targetid, long val, const long sven_wep[2])
|
||||
{
|
||||
SetPData(targetid, sven_wep[0], static_cast<int>(val) );
|
||||
SetPData(targetid, sven_wep[1], static_cast<int>(val) );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline long GetSvenWeapon(long& targetid, const long sven_wep[2])
|
||||
{
|
||||
return GetPData(targetid, sven_wep[0], int(NULL) );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||
/* Sven Coop Natives
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _svencoop_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _svencoop_included
|
||||
|
||||
#include <svencoop_const>
|
||||
#include <svencoop_stocks>
|
||||
|
||||
#pragma library svenfun
|
||||
|
||||
// Gets/sets the amount of frags a monster or player has.
|
||||
native Float:sc_get_frags(id);
|
||||
native sc_set_frags(id,Float:frags);
|
||||
|
||||
// Gets/sets the deaths a player has.
|
||||
native sc_get_user_deaths(id);
|
||||
native sc_set_user_deaths(id,deaths);
|
||||
|
||||
// returns 1 if entity (non-player) is an ally.
|
||||
native sc_is_player_ally(id);
|
||||
|
||||
// Gets the amount of ammo an ent has.
|
||||
// Use the SVEN_WEP_* defines for type
|
||||
native sc_get_weapon_ammo(id, type)
|
||||
|
||||
// Sets the amount of ammo an ent has.
|
||||
// Use the SVEN_WEP_* defines for type
|
||||
native sc_set_weapon_ammo(id, amount, type)
|
|
@ -1,34 +0,0 @@
|
|||
// prevent double include
|
||||
#ifndef __CONST_H__
|
||||
#define __CONST_H__
|
||||
|
||||
#define PDATA_FRAGS 0x9
|
||||
#define PDATA_DEATHS 0x21B0
|
||||
#define PDATA_ALLY 0x28
|
||||
|
||||
#define SVEN_WEP_9MM 0
|
||||
#define PDATA_9MM 0x216D
|
||||
#define PDATA_9MM2 0x218D
|
||||
const long sven_9mm[2] = {PDATA_9MM, PDATA_9MM2};
|
||||
|
||||
#define SVEN_WEP_SHOTGUN 1
|
||||
#define PDATA_SHOTGUN 0x216E
|
||||
#define PDATA_SHOTGUN2 0x218E
|
||||
const long sven_shotgun[2] = {PDATA_9MM, PDATA_9MM2};
|
||||
|
||||
#define SVEN_WEP_RPG 2
|
||||
#define PDATA_RPG 0x2195
|
||||
#define PDATA_RPG2 0x21B5
|
||||
const long sven_rpg[2] = {PDATA_9MM, PDATA_9MM2};
|
||||
|
||||
#define SVEN_WEP_RADIO 3
|
||||
#define PDATA_RADIO 0x217A
|
||||
#define PDATA_RADIO2 0x219A
|
||||
const long sven_radio[2] = {PDATA_9MM, PDATA_9MM2};
|
||||
|
||||
#define SVEN_WEP_SNARK 4
|
||||
#define PDATA_SNARK 0x217A
|
||||
#define PDATA_SNARK2 0x219A
|
||||
const long sven_snark[2] = {PDATA_9MM, PDATA_9MM2};
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
/* Sven Coop Constants
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _svencoop_const_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _svencoop_const_included
|
||||
|
||||
// The PDATA defines are for using with FM
|
||||
// The SVEN_WEP_* defines are for sc_ weapon natives
|
||||
// Please, use the provided stocks.
|
||||
|
||||
#define PDATA_FRAGS 0x9
|
||||
#define PDATA_DEATHS 0x21B0
|
||||
#define PDATA_ALLY 0x28
|
||||
|
||||
#define SVEN_WEP_9MM 0
|
||||
#define PDATA_9MM 0x216D
|
||||
#define PDATA_9MM2 0x218D
|
||||
|
||||
#define SVEN_WEP_SHOTGUN 1
|
||||
#define PDATA_SHOTGUN 0x216E
|
||||
#define PDATA_SHOTGUN2 0x218E
|
||||
|
||||
#define SVEN_WEP_RPG 2
|
||||
#define PDATA_RPG 0x2195
|
||||
#define PDATA_RPG2 0x21B5
|
||||
|
||||
#define SVEN_WEP_RADIO 3
|
||||
#define PDATA_RADIO 0x217A
|
||||
#define PDATA_RADIO2 0x219A
|
||||
|
||||
#define SVEN_WEP_SNARK 4
|
||||
#define PDATA_SNARK 0x217A
|
||||
#define PDATA_SNARK2 0x219A
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/* Sven Coop Stocks
|
||||
*
|
||||
* This file is provided as is (no warranties).
|
||||
*/
|
||||
|
||||
#if defined _svencoop_stocks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _svencoop_stocks_included
|
||||
|
||||
#include <svencoop_const>
|
||||
|
||||
//Stocks for 9mm ammo (mp5, uzi(akimbo))
|
||||
stock sc_get_bpammo_9mm(id) { return sc_get_weapon_ammo(id,SVEN_WEP_9MM; }
|
||||
stock sc_set_bpammo_9mm(id, amount) { return sc_set_weapon_ammo(id, amount, SVEN_WEP_9MM; }
|
||||
|
||||
//Stocks for RPG ammo (RPG launcher)
|
||||
stock sc_get_bpammo_rpg(id) { return sc_get_weapon_ammo(id,SVEN_WEP_RPG; }
|
||||
stock sc_set_bpammo_rpg(id, amount) { return sc_set_weapon_ammo(id, amount, SVEN_WEP_RPG; }
|
||||
|
||||
//Stocks for radioactive ammo (gauss, egon)
|
||||
stock sc_get_bpammo_radio(id) { return sc_get_weapon_ammo(id,SVEN_WEP_RADIO; }
|
||||
stock sc_set_bpammo_radio(id, amount) { return sc_set_weapon_ammo(id, amount, SVEN_WEP_RADIO; }
|
||||
|
||||
//Stocks for snark ammo
|
||||
stock sc_get_bpammo_snark(id) { return sc_get_weapon_ammo(id,SVEN_WEP_SNARK; }
|
||||
stock sc_set_bpammo_snark(id, amount) { return sc_set_weapon_ammo(id, amount, SVEN_WEP_SNARK; }
|
||||
|
||||
//Stocks for shotgun ammo
|
||||
stock sc_get_bpammo_shot(id) { return sc_get_weapon_ammo(id,SVEN_WEP_SHOTGUN; }
|
||||
stock sc_set_bpammo_shot(id, amount) { return sc_set_weapon_ammo(id, amount, SVEN_WEP_SHOTGUN; }
|
|
@ -32,6 +32,8 @@
|
|||
#include "amxxmodule.h"
|
||||
#include "tfcx.h"
|
||||
|
||||
extern int g_AlliesFlags[4];
|
||||
|
||||
// Vexd start
|
||||
|
||||
// Set A TFC Player's model. This works differently then CS.
|
||||
|
@ -429,6 +431,60 @@ static cell AMX_NATIVE_CALL register_forward(AMX *amx, cell *params)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL TFC_IsFeigning(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
CHECK_PLAYER(index);
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
|
||||
return (pPlayer->pEdict->v.playerclass == TFC_PC_SPY && pPlayer->pEdict->v.deadflag == 5);
|
||||
};
|
||||
cvar_t *mp_teamplay=NULL;
|
||||
static cell AMX_NATIVE_CALL TFC_IsTeamAlly(AMX *amx, cell *params)
|
||||
{
|
||||
if (mp_teamplay==NULL)
|
||||
{
|
||||
mp_teamplay=CVAR_GET_POINTER("mp_teamplay");
|
||||
}
|
||||
|
||||
if (mp_teamplay && mp_teamplay->value != 0.0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int TeamA=params[1];
|
||||
int TeamB=params[2];
|
||||
if (TeamA==TeamB) // same team, yes these are allies
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (TeamA==0 || TeamB==0) // spectators
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (TeamA < 1 || TeamA > 4) // out of bounds?
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Team A is out of bounds (got %d, expected 0 through 4)",TeamA);
|
||||
return 0;
|
||||
}
|
||||
if (TeamB < 1 || TeamB > 4) // out of bounds?
|
||||
{
|
||||
MF_LogError(amx,AMX_ERR_NATIVE,"Team B is out of bounds (got %d, expected 0 through 4)",TeamA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_AlliesFlags[--TeamA] & (1<<(--TeamB)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Native list.
|
||||
AMX_NATIVE_INFO base_Natives[] = {
|
||||
{"tfc_setmodel", TFC_SetModel},
|
||||
|
@ -440,6 +496,10 @@ AMX_NATIVE_INFO base_Natives[] = {
|
|||
{"tfc_getweaponammo", TFC_GetWeaponAmmo},
|
||||
{"tfc_setweaponammo", TFC_SetWeaponAmmo},
|
||||
|
||||
{"tfc_is_user_feigning", TFC_IsFeigning},
|
||||
|
||||
{"tfc_is_team_ally", TFC_IsTeamAlly},
|
||||
|
||||
{"tfc_get_user_goalitem", TFC_GetUserGoalItem},
|
||||
|
||||
{"xmod_get_wpnname", TFC_GetWpnName},
|
||||
|
|
|
@ -58,6 +58,8 @@ int mPlayerIndex;
|
|||
int g_death_info = -1;
|
||||
int g_damage_info = -1;
|
||||
|
||||
int g_AlliesFlags[4];
|
||||
|
||||
RankSystem g_rank;
|
||||
Grenades g_grenades;
|
||||
|
||||
|
@ -167,6 +169,12 @@ void ServerDeactivate() {
|
|||
|
||||
g_grenades.clear();
|
||||
|
||||
g_AlliesFlags[0]=0;
|
||||
g_AlliesFlags[1]=0;
|
||||
g_AlliesFlags[2]=0;
|
||||
g_AlliesFlags[3]=0;
|
||||
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
|
@ -349,6 +357,10 @@ void OnAmxxAttach() {
|
|||
pdAmmo[TFC_AMMO_NADE1] = PD_AMMO_NADE1;
|
||||
pdAmmo[TFC_AMMO_NADE2] = PD_AMMO_NADE2;
|
||||
|
||||
g_AlliesFlags[0]=0;
|
||||
g_AlliesFlags[1]=0;
|
||||
g_AlliesFlags[2]=0;
|
||||
g_AlliesFlags[3]=0;
|
||||
}
|
||||
|
||||
void OnPluginsLoaded()
|
||||
|
@ -357,3 +369,37 @@ void OnPluginsLoaded()
|
|||
g_death_info = MF_RegisterForward("client_death", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
}
|
||||
|
||||
void DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
|
||||
{
|
||||
if (pkvd->szClassName && strcmp(pkvd->szClassName,"info_tfdetect")==0)
|
||||
{
|
||||
if (pkvd->szKeyName && strncmp(pkvd->szKeyName,"team",4)==0)
|
||||
{
|
||||
if (strcmp(pkvd->szKeyName,"team1_allies")==0 && pkvd->szValue!=NULL)
|
||||
{
|
||||
g_AlliesFlags[0]=atoi(pkvd->szValue);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
else if (strcmp(pkvd->szKeyName,"team2_allies")==0 && pkvd->szValue!=NULL)
|
||||
{
|
||||
g_AlliesFlags[1]=atoi(pkvd->szValue);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
else if (strcmp(pkvd->szKeyName,"team3_allies")==0 && pkvd->szValue!=NULL)
|
||||
{
|
||||
g_AlliesFlags[2]=atoi(pkvd->szValue);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
else if (strcmp(pkvd->szKeyName,"team4_allies")==0 && pkvd->szValue!=NULL)
|
||||
{
|
||||
g_AlliesFlags[3]=atoi(pkvd->szValue);
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
}
|
||||
}
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
// #define FN_DispatchUse DispatchUse /* pfnUse() */
|
||||
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
|
||||
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
|
||||
// #define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
#define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
|
||||
// #define FN_DispatchSave DispatchSave /* pfnSave() */
|
||||
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
|
||||
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
// Uncomment for SQL version
|
||||
//#define USING_SQL
|
||||
// #define USING_SQL
|
||||
|
||||
#include <amxmodx>
|
||||
#include <amxmisc>
|
||||
|
@ -41,7 +41,8 @@
|
|||
#include <sqlx>
|
||||
#endif
|
||||
|
||||
#define MAX_ADMINS 64
|
||||
new AdminCount;
|
||||
|
||||
new PLUGINNAME[] = "AMX Mod X"
|
||||
|
||||
#define ADMIN_LOOKUP (1<<0)
|
||||
|
@ -50,13 +51,14 @@ new PLUGINNAME[] = "AMX Mod X"
|
|||
#define ADMIN_IPADDR (1<<3)
|
||||
#define ADMIN_NAME (1<<4)
|
||||
|
||||
new g_aPassword[MAX_ADMINS][32]
|
||||
new g_aName[MAX_ADMINS][32]
|
||||
new g_aFlags[MAX_ADMINS]
|
||||
new g_aAccess[MAX_ADMINS]
|
||||
new g_aNum = 0
|
||||
new g_cmdLoopback[16]
|
||||
|
||||
|
||||
// pcvars
|
||||
new amx_mode;
|
||||
new amx_password_field;
|
||||
new amx_default_access;
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
#if defined USING_SQL
|
||||
|
@ -66,9 +68,9 @@ public plugin_init()
|
|||
#endif
|
||||
register_dictionary("admin.txt")
|
||||
register_dictionary("common.txt")
|
||||
register_cvar("amx_mode", "1")
|
||||
register_cvar("amx_password_field", "_pw")
|
||||
register_cvar("amx_default_access", "")
|
||||
amx_mode=register_cvar("amx_mode", "1")
|
||||
amx_password_field=register_cvar("amx_password_field", "_pw")
|
||||
amx_default_access=register_cvar("amx_default_access", "")
|
||||
|
||||
register_cvar("amx_vote_ratio", "0.02")
|
||||
register_cvar("amx_vote_time", "10")
|
||||
|
@ -157,13 +159,13 @@ public addadminfn(id, level, cid)
|
|||
idtype |= ADMIN_LOOKUP
|
||||
player = cmd_target(id, arg, 10)
|
||||
} else {
|
||||
new _steamid[24]
|
||||
new _steamid[44]
|
||||
static _players[32], _num, _pv
|
||||
get_players(_players, _num)
|
||||
for (new _i=0; _i<_num; _i++)
|
||||
{
|
||||
_pv = _players[_i]
|
||||
get_user_authid(_pv, _steamid, 23)
|
||||
get_user_authid(_pv, _steamid, sizeof(_steamid)-1)
|
||||
if (!_steamid[0])
|
||||
continue
|
||||
if (equal(_steamid, arg))
|
||||
|
@ -229,8 +231,10 @@ public addadminfn(id, level, cid)
|
|||
read_argv(3, password, 63)
|
||||
|
||||
new auth[33]
|
||||
new Comment[33]; // name of player to pass to comment field
|
||||
if (idtype & ADMIN_LOOKUP)
|
||||
{
|
||||
get_user_name(player, Comment, sizeof(Comment)-1)
|
||||
if (idtype & ADMIN_STEAM)
|
||||
{
|
||||
get_user_authid(player, auth, 32)
|
||||
|
@ -259,7 +263,7 @@ public addadminfn(id, level, cid)
|
|||
else
|
||||
len += format(type[len], 15-len, "e")
|
||||
|
||||
AddAdmin(id, auth, flags, password, type)
|
||||
AddAdmin(id, auth, flags, password, type, Comment)
|
||||
cmdReload(id, ADMIN_CFG, 0)
|
||||
|
||||
if (player > 0)
|
||||
|
@ -272,7 +276,7 @@ public addadminfn(id, level, cid)
|
|||
return PLUGIN_HANDLED
|
||||
}
|
||||
|
||||
AddAdmin(id, auth[], accessflags[], password[], flags[])
|
||||
AddAdmin(id, auth[], accessflags[], password[], flags[], comment[]="")
|
||||
{
|
||||
#if defined USING_SQL
|
||||
new error[128], errno
|
||||
|
@ -322,7 +326,14 @@ AddAdmin(id, auth[], accessflags[], password[], flags[])
|
|||
// If we came here, steamid doesn't exist in users.ini. Add it.
|
||||
new linetoadd[512]
|
||||
|
||||
formatex(linetoadd, 511, "^r^n^"%s^" ^"%s^" ^"%s^" ^"%s^"", auth, password, accessflags, flags)
|
||||
if (comment[0]==0)
|
||||
{
|
||||
formatex(linetoadd, 511, "^r^n^"%s^" ^"%s^" ^"%s^" ^"%s^"", auth, password, accessflags, flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
formatex(linetoadd, 511, "^r^n^"%s^" ^"%s^" ^"%s^" ^"%s^" ; %s", auth, password, accessflags, flags, comment)
|
||||
}
|
||||
console_print(id, "Adding:^n%s", linetoadd)
|
||||
|
||||
if (!write_file(configsDir, linetoadd))
|
||||
|
@ -357,49 +368,95 @@ AddAdmin(id, auth[], accessflags[], password[], flags[])
|
|||
}
|
||||
public plugin_cfg()
|
||||
{
|
||||
new configFile[64], curMap[32]
|
||||
|
||||
get_configsdir(configFile, 31)
|
||||
get_mapname(curMap, 31)
|
||||
|
||||
new len = format(configFile, 63, "%s/maps/%s.cfg", configFile, curMap)
|
||||
|
||||
if (file_exists(configFile))
|
||||
set_task(6.1, "delayed_load", 0, configFile, len + 1)
|
||||
set_task(6.1, "delayed_load")
|
||||
}
|
||||
|
||||
public delayed_load(configFile[])
|
||||
public delayed_load()
|
||||
{
|
||||
server_cmd("exec %s", configFile)
|
||||
new configFile[128], curMap[64], configDir[128]
|
||||
|
||||
get_configsdir(configDir, sizeof(configDir)-1)
|
||||
get_mapname(curMap, sizeof(curMap)-1)
|
||||
|
||||
new i=0;
|
||||
|
||||
while (curMap[i] != '_' && curMap[i++] != '^0') {/*do nothing*/}
|
||||
|
||||
if (curMap[i]=='_')
|
||||
{
|
||||
// this map has a prefix
|
||||
curMap[i]='^0';
|
||||
formatex(configFile, sizeof(configFile)-1, "%s/maps/prefix_%s.cfg", configDir, curMap);
|
||||
|
||||
if (file_exists(configFile))
|
||||
{
|
||||
server_cmd("exec %s", configFile);
|
||||
}
|
||||
}
|
||||
|
||||
get_mapname(curMap, sizeof(curMap)-1)
|
||||
|
||||
|
||||
formatex(configFile, sizeof(configFile)-1, "%s/maps/%s.cfg", configDir, curMap)
|
||||
|
||||
if (file_exists(configFile))
|
||||
{
|
||||
server_cmd("exec %s", configFile)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
loadSettings(szFilename[])
|
||||
{
|
||||
if (!file_exists(szFilename))
|
||||
return 0
|
||||
new File=fopen(szFilename,"r");
|
||||
|
||||
new szText[256], szFlags[32], szAccess[32]
|
||||
new a, pos = 0
|
||||
|
||||
while (g_aNum < MAX_ADMINS && read_file(szFilename, pos++, szText, 255, a))
|
||||
if (File)
|
||||
{
|
||||
if (szText[0] == ';')
|
||||
continue
|
||||
new Text[512];
|
||||
new Flags[32];
|
||||
new Access[32]
|
||||
new AuthData[44];
|
||||
new Password[32];
|
||||
|
||||
if (parse(szText, g_aName[g_aNum], 31, g_aPassword[g_aNum], 31, szAccess, 31, szFlags, 31) < 2)
|
||||
continue
|
||||
while (!feof(File))
|
||||
{
|
||||
fgets(File,Text,sizeof(Text)-1);
|
||||
|
||||
g_aAccess[g_aNum] = read_flags(szAccess)
|
||||
g_aFlags[g_aNum] = read_flags(szFlags)
|
||||
++g_aNum
|
||||
// comment
|
||||
if (Text[0]==';')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Flags[0]=0;
|
||||
Access[0]=0;
|
||||
AuthData[0]=0;
|
||||
Password[0]=0;
|
||||
|
||||
// not enough parameters
|
||||
if (parse(Text,AuthData,sizeof(AuthData)-1,Password,sizeof(Password)-1,Access,sizeof(Access)-1,Flags,sizeof(Flags)-1) < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
admins_push(AuthData,Password,read_flags(Access),read_flags(Flags));
|
||||
|
||||
AdminCount++;
|
||||
}
|
||||
|
||||
fclose(File);
|
||||
}
|
||||
|
||||
if (g_aNum == 1)
|
||||
server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMIN")
|
||||
if (AdminCount == 1)
|
||||
{
|
||||
server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMIN");
|
||||
}
|
||||
else
|
||||
server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", g_aNum)
|
||||
{
|
||||
server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", AdminCount);
|
||||
}
|
||||
|
||||
return 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined USING_SQL
|
||||
|
@ -450,9 +507,8 @@ public adminSql()
|
|||
} else if (!SQL_NumResults(query)) {
|
||||
server_print("[AMXX] %L", LANG_SERVER, "NO_ADMINS")
|
||||
} else {
|
||||
new szFlags[32], szAccess[32]
|
||||
|
||||
g_aNum = 0
|
||||
AdminCount = 0
|
||||
|
||||
/** do this incase people change the query order and forget to modify below */
|
||||
new qcolAuth = SQL_FieldNameToNum(query, "auth")
|
||||
|
@ -460,25 +516,32 @@ public adminSql()
|
|||
new qcolAccess = SQL_FieldNameToNum(query, "access")
|
||||
new qcolFlags = SQL_FieldNameToNum(query, "flags")
|
||||
|
||||
while ((g_aNum < MAX_ADMINS) && (SQL_MoreResults(query)))
|
||||
new AuthData[44];
|
||||
new Password[44];
|
||||
new Access[32];
|
||||
new Flags[32];
|
||||
|
||||
while (SQL_MoreResults(query))
|
||||
{
|
||||
SQL_ReadResult(query, qcolAuth, g_aName[g_aNum], 31)
|
||||
SQL_ReadResult(query, qcolPass, g_aPassword[g_aNum], 31)
|
||||
SQL_ReadResult(query, qcolAccess, szAccess, 31)
|
||||
SQL_ReadResult(query, qcolFlags, szFlags, 31)
|
||||
SQL_ReadResult(query, qcolAuth, AuthData, sizeof(AuthData)-1);
|
||||
SQL_ReadResult(query, qcolPass, Password, sizeof(Password)-1);
|
||||
SQL_ReadResult(query, qcolAccess, Access, sizeof(Access)-1);
|
||||
SQL_ReadResult(query, qcolFlags, Flags, sizeof(Flags)-1);
|
||||
|
||||
g_aAccess[g_aNum] = read_flags(szAccess)
|
||||
admins_push(AuthData,Password,read_flags(Access),read_flags(Flags));
|
||||
|
||||
g_aFlags[g_aNum] = read_flags(szFlags)
|
||||
|
||||
++g_aNum
|
||||
++AdminCount;
|
||||
SQL_NextRow(query)
|
||||
}
|
||||
|
||||
if (g_aNum == 1)
|
||||
if (AdminCount == 1)
|
||||
{
|
||||
server_print("[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMIN")
|
||||
}
|
||||
else
|
||||
server_print("[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMINS", g_aNum)
|
||||
{
|
||||
server_print("[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMINS", AdminCount)
|
||||
}
|
||||
|
||||
SQL_FreeHandle(query)
|
||||
SQL_FreeHandle(sql)
|
||||
|
@ -503,26 +566,30 @@ public cmdReload(id, level, cid)
|
|||
get_configsdir(filename, 127)
|
||||
format(filename, 63, "%s/users.ini", filename)
|
||||
|
||||
g_aNum = 0
|
||||
loadSettings(filename) // Re-Load admins accounts
|
||||
AdminCount = 0;
|
||||
loadSettings(filename); // Re-Load admins accounts
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
if (g_aNum == 1)
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "LOADED_ADMIN")
|
||||
if (AdminCount == 1)
|
||||
{
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "LOADED_ADMIN");
|
||||
}
|
||||
else
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", g_aNum)
|
||||
{
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", AdminCount);
|
||||
}
|
||||
}
|
||||
#else
|
||||
g_aNum = 0
|
||||
AdminCount = 0
|
||||
adminSql()
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
if (g_aNum == 1)
|
||||
if (AdminCount == 1)
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMIN")
|
||||
else
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMINS", g_aNum)
|
||||
console_print(id, "[AMXX] %L", LANG_SERVER, "SQL_LOADED_ADMINS", AdminCount)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -544,43 +611,55 @@ getAccess(id, name[], authid[], ip[], password[])
|
|||
new index = -1
|
||||
new result = 0
|
||||
|
||||
for (new i = 0; i < g_aNum; ++i)
|
||||
static Count;
|
||||
static Flags;
|
||||
static Access;
|
||||
static AuthData[44];
|
||||
static Password[32];
|
||||
|
||||
Count=admins_num();
|
||||
for (new i = 0; i < Count; ++i)
|
||||
{
|
||||
if (g_aFlags[i] & FLAG_AUTHID)
|
||||
Flags=admins_lookup(i,AdminProp_Flags);
|
||||
admins_lookup(i,AdminProp_Auth,AuthData,sizeof(AuthData)-1);
|
||||
|
||||
if (Flags & FLAG_AUTHID)
|
||||
{
|
||||
if (equal(authid, g_aName[i]))
|
||||
if (equal(authid, AuthData))
|
||||
{
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
else if (g_aFlags[i] & FLAG_IP)
|
||||
else if (Flags & FLAG_IP)
|
||||
{
|
||||
new c = strlen(g_aName[i])
|
||||
new c = strlen(AuthData)
|
||||
|
||||
if (g_aName[i][c - 1] == '.') /* check if this is not a xxx.xxx. format */
|
||||
if (AuthData[c - 1] == '.') /* check if this is not a xxx.xxx. format */
|
||||
{
|
||||
if (equal(g_aName[i], ip, c))
|
||||
if (equal(AuthData, ip, c))
|
||||
{
|
||||
index = i
|
||||
break
|
||||
}
|
||||
} /* in other case an IP must just match */
|
||||
else if (equal(ip, g_aName[i]))
|
||||
else if (equal(ip, AuthData))
|
||||
{
|
||||
index = i
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if (g_aFlags[i] & FLAG_TAG)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Flags & FLAG_TAG)
|
||||
{
|
||||
if (containi(name, g_aName[i]) != -1)
|
||||
if (containi(name, AuthData) != -1)
|
||||
{
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
else if (equali(name, g_aName[i]))
|
||||
else if (equali(name, AuthData))
|
||||
{
|
||||
index = i
|
||||
break
|
||||
|
@ -590,45 +669,59 @@ getAccess(id, name[], authid[], ip[], password[])
|
|||
|
||||
if (index != -1)
|
||||
{
|
||||
if (g_aFlags[index] & FLAG_NOPASS)
|
||||
Access=admins_lookup(index,AdminProp_Access);
|
||||
|
||||
if (Flags & FLAG_NOPASS)
|
||||
{
|
||||
result |= 8
|
||||
new sflags[32]
|
||||
|
||||
get_flags(g_aAccess[index], sflags, 31)
|
||||
set_user_flags(id, g_aAccess[index])
|
||||
get_flags(Access, sflags, 31)
|
||||
set_user_flags(id, Access)
|
||||
|
||||
log_amx("Login: ^"%s<%d><%s><>^" became an admin (account ^"%s^") (access ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, g_aName[index], sflags, ip)
|
||||
log_amx("Login: ^"%s<%d><%s><>^" became an admin (account ^"%s^") (access ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, AuthData, sflags, ip)
|
||||
}
|
||||
else if (equal(password, g_aPassword[index]))
|
||||
else
|
||||
{
|
||||
result |= 12
|
||||
set_user_flags(id, g_aAccess[index])
|
||||
|
||||
new sflags[32]
|
||||
get_flags(g_aAccess[index], sflags, 31)
|
||||
admins_lookup(index,AdminProp_Password,Password,sizeof(Password)-1);
|
||||
|
||||
log_amx("Login: ^"%s<%d><%s><>^" became an admin (account ^"%s^") (access ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, g_aName[index], sflags, ip)
|
||||
} else {
|
||||
result |= 1
|
||||
|
||||
if (g_aFlags[index] & FLAG_KICK)
|
||||
if (equal(password, Password))
|
||||
{
|
||||
result |= 2
|
||||
log_amx("Login: ^"%s<%d><%s><>^" kicked due to invalid password (account ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, g_aName[index], ip)
|
||||
result |= 12
|
||||
set_user_flags(id, Access)
|
||||
|
||||
new sflags[32]
|
||||
get_flags(Access, sflags, 31)
|
||||
|
||||
log_amx("Login: ^"%s<%d><%s><>^" became an admin (account ^"%s^") (access ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, AuthData, sflags, ip)
|
||||
}
|
||||
else
|
||||
{
|
||||
result |= 1
|
||||
|
||||
if (Flags & FLAG_KICK)
|
||||
{
|
||||
result |= 2
|
||||
log_amx("Login: ^"%s<%d><%s><>^" kicked due to invalid password (account ^"%s^") (address ^"%s^")", name, get_user_userid(id), authid, AuthData, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (get_cvar_float("amx_mode") == 2.0)
|
||||
else if (get_pcvar_float(amx_mode) == 2.0)
|
||||
{
|
||||
result |= 2
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
new defaccess[32]
|
||||
|
||||
get_cvar_string("amx_default_access", defaccess, 31)
|
||||
get_pcvar_string(amx_default_access, defaccess, 31)
|
||||
|
||||
if (!strlen(defaccess))
|
||||
{
|
||||
copy(defaccess, 32, "z")
|
||||
}
|
||||
|
||||
new idefaccess = read_flags(defaccess)
|
||||
|
||||
|
@ -660,7 +753,7 @@ accessUser(id, name[] = "")
|
|||
get_user_name(id, username, 31)
|
||||
}
|
||||
|
||||
get_cvar_string("amx_password_field", passfield, 31)
|
||||
get_pcvar_string(amx_password_field, passfield, 31)
|
||||
get_user_info(id, passfield, password, 31)
|
||||
|
||||
new result = getAccess(id, username, userauthid, userip, password)
|
||||
|
@ -691,7 +784,7 @@ accessUser(id, name[] = "")
|
|||
|
||||
public client_infochanged(id)
|
||||
{
|
||||
if (!is_user_connected(id) || !get_cvar_num("amx_mode"))
|
||||
if (!is_user_connected(id) || !get_pcvar_num(amx_mode))
|
||||
{
|
||||
return PLUGIN_CONTINUE
|
||||
}
|
||||
|
@ -712,15 +805,16 @@ public client_infochanged(id)
|
|||
public ackSignal(id)
|
||||
{
|
||||
server_cmd("kick #%d ^"%L^"", get_user_userid(id), id, "NO_ENTRY")
|
||||
return PLUGIN_HANDLED
|
||||
}
|
||||
|
||||
public client_authorized(id)
|
||||
return get_cvar_num("amx_mode") ? accessUser(id) : PLUGIN_CONTINUE
|
||||
return get_pcvar_num(amx_mode) ? accessUser(id) : PLUGIN_CONTINUE
|
||||
|
||||
public client_putinserver(id)
|
||||
{
|
||||
if (!is_dedicated_server() && id == 1)
|
||||
return get_cvar_num("amx_mode") ? accessUser(id) : PLUGIN_CONTINUE
|
||||
return get_pcvar_num(amx_mode) ? accessUser(id) : PLUGIN_CONTINUE
|
||||
|
||||
return PLUGIN_CONTINUE
|
||||
}
|
||||
|
|
|
@ -45,11 +45,16 @@ new bool:g_Paused
|
|||
new bool:g_PauseAllowed = false
|
||||
new g_addCvar[] = "amx_cvar add %s"
|
||||
|
||||
new amx_show_activity;
|
||||
new pausable;
|
||||
new rcon_password;
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
register_plugin("Admin Commands", AMXX_VERSION_STR, "AMXX Dev Team")
|
||||
register_dictionary("admincmd.txt")
|
||||
register_dictionary("common.txt")
|
||||
register_dictionary("adminhelp.txt")
|
||||
register_concmd("amx_kick", "cmdKick", ADMIN_KICK, "<name or #userid> [reason]")
|
||||
register_concmd("amx_ban", "cmdBan", ADMIN_BAN, "<name or #userid> <minutes> [reason]")
|
||||
register_concmd("amx_banip", "cmdBanIP", ADMIN_BAN, "<name or #userid> <minutes> [reason]")
|
||||
|
@ -69,6 +74,18 @@ public plugin_init()
|
|||
register_clcmd("amx_rcon", "cmdRcon", ADMIN_RCON, "<command line>")
|
||||
register_clcmd("amx_showrcon", "cmdShowRcon", ADMIN_RCON, "<command line>")
|
||||
register_clcmd("pauseAck", "cmdLBack")
|
||||
|
||||
|
||||
rcon_password=get_cvar_pointer("rcon_password");
|
||||
pausable=get_cvar_pointer("pausable");
|
||||
|
||||
amx_show_activity=get_cvar_pointer("amx_show_activity");
|
||||
|
||||
if (amx_show_activity==0) // cvar does not exist, register it
|
||||
{
|
||||
amx_show_activity=register_cvar("amx_show_activity", "2");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public plugin_cfg()
|
||||
|
@ -108,7 +125,7 @@ public cmdKick(id, level, cid)
|
|||
|
||||
log_amx("Kick: ^"%s<%d><%s><>^" kick ^"%s<%d><%s><>^" (reason ^"%s^")", name, get_user_userid(id), authid, name2, userid2, authid2, reason)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_KICK_2", name, name2)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_KICK_1", name2)
|
||||
|
@ -149,7 +166,7 @@ public cmdUnban(id, level, cid)
|
|||
|
||||
get_user_name(id, name, 31)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_UNBAN_2", name, arg)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_UNBAN_1", arg)
|
||||
|
@ -183,7 +200,7 @@ public cmdAddBan(id, level, cid)
|
|||
|
||||
get_user_name(id, name, 31)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_ADDBAN_2", name, arg)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_ADDBAN_1", arg)
|
||||
|
@ -234,7 +251,7 @@ public cmdBan(id, level, cid)
|
|||
else
|
||||
server_cmd("kick #%d ^"%s %s^";wait;banid ^"%s^" ^"%s^";wait;writeid", userid2, banned, temp, minutes, authid2)
|
||||
|
||||
new activity = get_cvar_num("amx_show_activity")
|
||||
new activity = get_pcvar_num(amx_show_activity)
|
||||
if (activity != 0)
|
||||
{
|
||||
new players[32], pnum, msg[256], len
|
||||
|
@ -306,7 +323,7 @@ public cmdBanIP(id, level, cid)
|
|||
else
|
||||
server_cmd("kick #%d ^"%s %s^";wait;addip ^"%s^" ^"%s^";wait;writeip", userid2, banned, temp, minutes, address)
|
||||
|
||||
new activity = get_cvar_num("amx_show_activity")
|
||||
new activity = get_pcvar_num(amx_show_activity)
|
||||
if (activity != 0)
|
||||
{
|
||||
new players[32], pnum, msg[256], len
|
||||
|
@ -362,7 +379,7 @@ public cmdSlay(id, level, cid)
|
|||
|
||||
log_amx("Cmd: ^"%s<%d><%s><>^" slay ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, name2, get_user_userid(player), authid2)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_SLAY_2", name, name2)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_SLAY_1", name2)
|
||||
|
@ -400,7 +417,7 @@ public cmdSlap(id, level, cid)
|
|||
|
||||
log_amx("Cmd: ^"%s<%d><%s><>^" slap with %d damage ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, damage, name2, get_user_userid(player), authid2)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_SLAP_2", name, name2, damage)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_SLAP_1", name2, damage)
|
||||
|
@ -434,7 +451,7 @@ public cmdMap(id, level, cid)
|
|||
get_user_authid(id, authid, 31)
|
||||
get_user_name(id, name, 31)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_MAP_2", name, arg)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_MAP_1", arg)
|
||||
|
@ -474,6 +491,8 @@ public cmdCvar(id, level, cid)
|
|||
read_argv(1, arg, 31)
|
||||
read_argv(2, arg2, 63)
|
||||
|
||||
new pointer;
|
||||
|
||||
if (equal(arg, "add") && (get_user_flags(id) & ADMIN_RCON))
|
||||
{
|
||||
if (cvar_exists(arg2))
|
||||
|
@ -486,7 +505,7 @@ public cmdCvar(id, level, cid)
|
|||
return PLUGIN_HANDLED
|
||||
}
|
||||
|
||||
if (!cvar_exists(arg))
|
||||
if ((pointer=get_cvar_pointer(arg))==0)
|
||||
{
|
||||
console_print(id, "[AMXX] %L", id, "UNKNOWN_CVAR", arg)
|
||||
return PLUGIN_HANDLED
|
||||
|
@ -497,7 +516,7 @@ public cmdCvar(id, level, cid)
|
|||
console_print(id, "[AMXX] %L", id, "CVAR_NO_ACC")
|
||||
return PLUGIN_HANDLED
|
||||
}
|
||||
else if (equal(arg, "sv_password") && !(get_user_flags(id) & ADMIN_PASSWORD))
|
||||
else if (equali(arg, "sv_password") && !(get_user_flags(id) & ADMIN_PASSWORD))
|
||||
{
|
||||
console_print(id, "[AMXX] %L", id, "CVAR_NO_ACC")
|
||||
return PLUGIN_HANDLED
|
||||
|
@ -505,7 +524,7 @@ public cmdCvar(id, level, cid)
|
|||
|
||||
if (read_argc() < 3)
|
||||
{
|
||||
get_cvar_string(arg, arg2, 63)
|
||||
get_pcvar_string(pointer, arg2, 63)
|
||||
console_print(id, "[AMXX] %L", id, "CVAR_IS", arg, arg2)
|
||||
return PLUGIN_HANDLED
|
||||
}
|
||||
|
@ -518,7 +537,8 @@ public cmdCvar(id, level, cid)
|
|||
log_amx("Cmd: ^"%s<%d><%s><>^" set cvar (name ^"%s^") (value ^"%s^")", name, get_user_userid(id), authid, arg, arg2)
|
||||
set_cvar_string(arg, arg2)
|
||||
|
||||
new activity = get_cvar_num("amx_show_activity")
|
||||
|
||||
new activity = get_pcvar_num(amx_show_activity)
|
||||
if (activity != 0)
|
||||
{
|
||||
new players[32], pnum, admin[64], cvar_val[64], len
|
||||
|
@ -533,12 +553,12 @@ public cmdCvar(id, level, cid)
|
|||
else
|
||||
len += format(admin[len], 255-len, " %s:", name)
|
||||
|
||||
if (equal(arg, "rcon_password") || equal(arg, "sv_password"))
|
||||
if (get_pcvar_flags(pointer) & FCVAR_PROTECTED || equali(arg,"rcon_password"))
|
||||
format(cvar_val, 63, "*** %L ***", players[i], "PROTECTED")
|
||||
else
|
||||
copy(cvar_val, 63, arg2)
|
||||
|
||||
client_print(players[i], print_chat, "%L", players[i], "SET_CVAR_TO", admin, arg, arg2)
|
||||
client_print(players[i], print_chat, "%L", players[i], "SET_CVAR_TO", admin, arg, cvar_val)
|
||||
}
|
||||
}
|
||||
console_print(id, "[AMXX] %L", id, "CVAR_CHANGED", arg, arg2)
|
||||
|
@ -551,6 +571,12 @@ public cmdPlugins(id, level, cid)
|
|||
if (!cmd_access(id, level, cid, 1))
|
||||
return PLUGIN_HANDLED
|
||||
|
||||
if (id==0) // If server executes redirect this to "amxx plugins" for more in depth output
|
||||
{
|
||||
server_cmd("amxx plugins");
|
||||
return PLUGIN_HANDLED;
|
||||
}
|
||||
|
||||
new name[32], version[32], author[32], filename[32], status[32]
|
||||
new lName[32], lVersion[32], lAuthor[32], lFile[32], lStatus[32]
|
||||
|
||||
|
@ -560,21 +586,50 @@ public cmdPlugins(id, level, cid)
|
|||
format(lFile, 31, "%L", id, "FILE")
|
||||
format(lStatus, 31, "%L", id, "STATUS")
|
||||
|
||||
new StartPLID=0;
|
||||
new EndPLID;
|
||||
|
||||
new Temp[96]
|
||||
|
||||
new num = get_pluginsnum()
|
||||
|
||||
if (read_argc() > 1)
|
||||
{
|
||||
read_argv(1,Temp,sizeof(Temp)-1);
|
||||
StartPLID=str_to_num(Temp)-1; // zero-based
|
||||
}
|
||||
|
||||
EndPLID=min(StartPLID + 10, num);
|
||||
|
||||
new running = 0
|
||||
|
||||
console_print(id, "%L:", id, "LOADED_PLUGINS")
|
||||
console_print(id, "----- %L -----", id, "LOADED_PLUGINS")
|
||||
console_print(id, "%-18.17s %-8.7s %-17.16s %-16.15s %-9.8s", lName, lVersion, lAuthor, lFile, lStatus)
|
||||
|
||||
for (new i = 0; i <num; i++)
|
||||
new i=StartPLID;
|
||||
while (i <EndPLID)
|
||||
{
|
||||
get_plugin(i, filename, 31, name, 31, version, 31, author, 31, status, 31)
|
||||
get_plugin(i++, filename, 31, name, 31, version, 31, author, 31, status, 31)
|
||||
console_print(id, "%-18.17s %-8.7s %-17.16s %-16.15s %-9.8s", name, version, author, filename, status)
|
||||
|
||||
if (status[0]=='d' || status[0]=='r') // "debug" or "running"
|
||||
running++
|
||||
}
|
||||
console_print(id, "%L", id, "PLUGINS_RUN", num, running)
|
||||
console_print(id, "%L", id, "PLUGINS_RUN", EndPLID-StartPLID, running)
|
||||
console_print(id, "----- %L -----",id,"HELP_ENTRIES",StartPLID + 1,EndPLID,num);
|
||||
|
||||
if (EndPLID < num)
|
||||
{
|
||||
formatex(Temp,sizeof(Temp)-1,"----- %L -----",id,"HELP_USE_MORE", EndPLID + 1);
|
||||
replace_all(Temp,sizeof(Temp)-1,"amx_help","amx_plugins");
|
||||
console_print(id,"%s",Temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatex(Temp,sizeof(Temp)-1,"----- %L -----",id,"HELP_USE_BEGIN");
|
||||
replace_all(Temp,sizeof(Temp)-1,"amx_help","amx_plugins");
|
||||
console_print(id,"%s",Temp);
|
||||
}
|
||||
|
||||
return PLUGIN_HANDLED
|
||||
}
|
||||
|
@ -637,7 +692,7 @@ public cmdCfg(id, level, cid)
|
|||
console_print(id, "[AMXX] Executing file ^"%s^"", arg)
|
||||
server_cmd("exec %s", arg)
|
||||
|
||||
switch(get_cvar_num("amx_show_activity"))
|
||||
switch(get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_CONF_2", name, arg)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_CONF_1", arg)
|
||||
|
@ -675,7 +730,10 @@ public cmdPause(id, level, cid)
|
|||
|
||||
get_user_authid(id, authid, 31)
|
||||
get_user_name(id, name, 31)
|
||||
g_pausAble = get_cvar_float("pausable")
|
||||
if (pausable!=0)
|
||||
{
|
||||
g_pausAble = get_pcvar_float(pausable)
|
||||
}
|
||||
|
||||
if (!slayer)
|
||||
slayer = find_player("h")
|
||||
|
@ -694,7 +752,7 @@ public cmdPause(id, level, cid)
|
|||
|
||||
console_print(id, "[AMXX] %L", id, g_Paused ? "UNPAUSING" : "PAUSING")
|
||||
|
||||
new activity = get_cvar_num("amx_show_activity")
|
||||
new activity = get_pcvar_num(amx_show_activity)
|
||||
if (activity != 0)
|
||||
{
|
||||
new players[32], pnum, msg[128], len
|
||||
|
@ -725,7 +783,7 @@ public cmdShowRcon(id, level, cid)
|
|||
|
||||
new password[64]
|
||||
|
||||
get_cvar_string("rcon_password", password, 63)
|
||||
get_pcvar_string(rcon_password, password, 63)
|
||||
|
||||
if (!password[0])
|
||||
{
|
||||
|
@ -862,7 +920,7 @@ public cmdLeave(id, level, cid)
|
|||
get_user_name(id, name, 31)
|
||||
log_amx("Kick: ^"%s<%d><%s><>^" leave some group (tag1 ^"%s^") (tag2 ^"%s^") (tag3 ^"%s^") (tag4 ^"%s^")", name, get_user_userid(id), authid, ltags[0], ltags[1], ltags[2], ltags[3])
|
||||
|
||||
switch(get_cvar_num("amx_show_activity"))
|
||||
switch(get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_LEAVE_2", name, ltags[0], ltags[1], ltags[2], ltags[3])
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_LEAVE_1", ltags[0], ltags[1], ltags[2], ltags[3])
|
||||
|
@ -895,7 +953,7 @@ public cmdNick(id, level, cid)
|
|||
|
||||
log_amx("Cmd: ^"%s<%d><%s><>^" change nick to ^"%s^" ^"%s<%d><%s><>^"", name, get_user_userid(id), authid, arg2, name2, get_user_userid(player), authid2)
|
||||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
switch (get_pcvar_num(amx_show_activity))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_NICK_2", name, name2, arg2)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_NICK_1", name2, arg2)
|
||||
|
|
|
@ -72,6 +72,8 @@ public ackSignal(id)
|
|||
new lReason[64]
|
||||
format(lReason, 63, "%L", id, "DROPPED_RES")
|
||||
server_cmd("kick #%d ^"%s^"", get_user_userid(id), lReason)
|
||||
|
||||
return PLUGIN_HANDLED
|
||||
}
|
||||
|
||||
public client_authorized(id)
|
||||
|
|
|
@ -37,18 +37,20 @@
|
|||
new Float:g_Flooding[33] = {0.0, ...}
|
||||
new g_Flood[33] = {0, ...}
|
||||
|
||||
new amx_flood_time;
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
register_plugin("Anti Flood", AMXX_VERSION_STR, "AMXX Dev Team")
|
||||
register_dictionary("antiflood.txt")
|
||||
register_clcmd("say", "chkFlood")
|
||||
register_clcmd("say_team", "chkFlood")
|
||||
register_cvar("amx_flood_time", "0.75")
|
||||
amx_flood_time=register_cvar("amx_flood_time", "0.75")
|
||||
}
|
||||
|
||||
public chkFlood(id)
|
||||
{
|
||||
new Float:maxChat = get_cvar_float("amx_flood_time")
|
||||
new Float:maxChat = get_pcvar_float(amx_flood_time)
|
||||
|
||||
if (maxChat)
|
||||
{
|
||||
|
|
|
@ -60,6 +60,7 @@ public plugin_init()
|
|||
|
||||
register_dictionary("plmenu.txt")
|
||||
register_dictionary("common.txt")
|
||||
register_dictionary("admincmd.txt")
|
||||
|
||||
register_clcmd("amx_kickmenu", "cmdKickMenu", ADMIN_KICK, "- displays kick menu")
|
||||
register_clcmd("amx_banmenu", "cmdBanMenu", ADMIN_BAN, "- displays ban menu")
|
||||
|
@ -120,8 +121,32 @@ public actionBanMenu(id, key)
|
|||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_BAN_2", name, name2)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_BAN_1", name2)
|
||||
case 2:
|
||||
{
|
||||
if (g_menuSettings[id]==0) // permanent
|
||||
{
|
||||
client_print(0, print_chat, "%L %s: %L %s %L", LANG_PLAYER, "ADMIN", name, LANG_PLAYER, "BAN", name2, LANG_PLAYER, "PERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
new tempTime[32];
|
||||
formatex(tempTime,sizeof(tempTime)-1,"%d",g_menuSettings[id]);
|
||||
client_print(0, print_chat, "%L %s: %L %s %L", LANG_PLAYER, "ADMIN", name, LANG_PLAYER, "BAN", name2, LANG_PLAYER, "FOR_MIN", tempTime);
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (g_menuSettings[id]==0) // permanent
|
||||
{
|
||||
client_print(0, print_chat, "%L: %L %s %L", LANG_PLAYER, "ADMIN", LANG_PLAYER, "BAN", name2, LANG_PLAYER, "PERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
new tempTime[32];
|
||||
formatex(tempTime,sizeof(tempTime)-1,"%d",g_menuSettings[id]);
|
||||
client_print(0, print_chat, "%L: %L %s %L", LANG_PLAYER, "ADMIN", LANG_PLAYER, "BAN", name2, LANG_PLAYER, "FOR_MIN", tempTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (equal("4294967295", authid2))
|
||||
|
|
|
@ -312,3 +312,11 @@ enum LibType
|
|||
LibType_Library,
|
||||
LibType_Class
|
||||
};
|
||||
|
||||
enum AdminProp
|
||||
{
|
||||
AdminProp_Auth = 0,
|
||||
AdminProp_Password,
|
||||
AdminProp_Access,
|
||||
AdminProp_Flags
|
||||
};
|
||||
|
|
|
@ -310,3 +310,19 @@ stock constraint_offset(low, high, seed, offset)
|
|||
|
||||
return 0; // Makes the compiler happy -_-
|
||||
}
|
||||
|
||||
/* Returns true if the user has ANY of the provided flags
|
||||
* false if they have none
|
||||
*/
|
||||
stock has_flag(id, const flags[])
|
||||
{
|
||||
return (get_user_flags(id) & read_flags(flags));
|
||||
}
|
||||
/* Returns true if the user has ALL of the provided flags
|
||||
* false otherwise
|
||||
*/
|
||||
stock has_all_flags(id, const flags[])
|
||||
{
|
||||
new FlagsNumber=read_flags(flags);
|
||||
return ((get_user_flags(id) & FlagsNumber)==FlagsNumber);
|
||||
}
|
||||
|
|
|
@ -239,7 +239,7 @@ native user_has_weapon(index,weapon,setweapon=-1);
|
|||
|
||||
/* Returns id of currently carried weapon. Gets also
|
||||
* ammount of ammo in clip and backpack. */
|
||||
native get_user_weapon(index,&clip,&ammo);
|
||||
native get_user_weapon(index,&clip=0,&ammo=0);
|
||||
|
||||
/* Gets ammo and clip from current weapon. */
|
||||
native get_user_ammo(index,weapon,&clip,&ammo);
|
||||
|
@ -474,14 +474,18 @@ native get_user_flags(index,id=0);
|
|||
native remove_user_flags(index,flags=-1,id=0);
|
||||
|
||||
/* Registers function which will be called from client console.
|
||||
* Set FlagManager to 1 to make FlagManager always include this command
|
||||
* Set FlagManager to 0 to make FlagManager never include this command
|
||||
* Returns the command ID.
|
||||
*/
|
||||
native register_clcmd(const client_cmd[],const function[],flags=-1, const info[]="");
|
||||
native register_clcmd(const client_cmd[],const function[],flags=-1, const info[]="", FlagManager=-1);
|
||||
|
||||
/* Registers function which will be called from any console.
|
||||
* Set FlagManager to 1 to make FlagManager always include this command
|
||||
* Set FlagManager to 0 to make FlagManager never include this command
|
||||
* Returns the command ID.
|
||||
*/
|
||||
native register_concmd(const cmd[],const function[],flags=-1, const info[]="");
|
||||
native register_concmd(const cmd[],const function[],flags=-1, const info[]="", FlagManager=-1);
|
||||
|
||||
/* Registers function which will be called from server console.
|
||||
* Returns the command ID.
|
||||
|
@ -609,7 +613,7 @@ native is_plugin_loaded(const name[]);
|
|||
* Note: the [...] portion should not be used, and is only for backward compatibility.
|
||||
* Use index of -1 to use the calling plugin's ID.
|
||||
*/
|
||||
native get_plugin(index,filename[],len1,name[],len2,version[],len3,author[],len4,status[],len5,...);
|
||||
native get_plugin(index,filename[]="",len1=0,name[]="",len2=0,version[]="",len3=0,author[]="",len4=0,status[]="",len5=0,...);
|
||||
|
||||
/* Returns number of all loaded plugins. */
|
||||
native get_pluginsnum();
|
||||
|
@ -826,7 +830,8 @@ native menu_destroy(menu);
|
|||
|
||||
//Gets info about a player's menu. Returns 1 if the player is viewing a menu.
|
||||
//menu will be >0 for a valid oldmenu. newmenu will be != -1 for a valid newmenu.
|
||||
native player_menu_info(id, &menu, &newmenu);
|
||||
//As of 1.77, there is an optional page parameter.
|
||||
native player_menu_info(id, &menu, &newmenu, &menupage=0);
|
||||
|
||||
//adds a blank line to a menu.
|
||||
//if slot is nonzero (default), the blank line will increase
|
||||
|
@ -1080,6 +1085,7 @@ native set_pcvar_num(pcvar, num);
|
|||
native Float:get_pcvar_float(pcvar);
|
||||
native set_pcvar_float(pcvar, Float:num);
|
||||
native get_pcvar_string(pcvar, string[], maxlen);
|
||||
native set_pcvar_string(pcvar, const string[]);
|
||||
|
||||
/**
|
||||
* Sets a whole array to a certain value.
|
||||
|
@ -1092,5 +1098,29 @@ native arrayset(array[], value, size);
|
|||
*/
|
||||
native get_weaponid(const name[]);
|
||||
|
||||
/**
|
||||
* Adds an admin to the dynamic admin storage
|
||||
* for lookup at a later time
|
||||
*/
|
||||
native admins_push(const AuthData[], const Password[], Access, Flags);
|
||||
|
||||
/**
|
||||
* Gets the number of admins in the dynamic admin
|
||||
* storage list
|
||||
*/
|
||||
native admins_num();
|
||||
|
||||
/**
|
||||
* Gets information about a dynamically stored admin
|
||||
* Use the enum AdminProp
|
||||
* Returns an integer value: AdminProp_Access, AdminProp_Flags
|
||||
* Sets the buffer string: AdminProp_Auth, AdminProp_Password
|
||||
*/
|
||||
native admins_lookup(num, AdminProp:Property, Buffer[]="", BufferSize=0);
|
||||
|
||||
/**
|
||||
* Clears the list of dynamically stored admins
|
||||
*/
|
||||
native admins_flush();
|
||||
// Keep this always at the bottom of this file
|
||||
#include <message_stocks>
|
||||
|
|
|
@ -24,6 +24,27 @@
|
|||
|
||||
#define DODMAX_WEAPONS 46 // 5 slots for custom weapons
|
||||
|
||||
// DoD Weapon Types
|
||||
enum
|
||||
{
|
||||
DODWT_PRIMARY = 0,
|
||||
DODWT_SECONDARY,
|
||||
DODWT_MELEE,
|
||||
DODWT_GRENADE,
|
||||
DODWT_OTHER
|
||||
};
|
||||
|
||||
// Ammo Channels
|
||||
#define AMMO_SMG 1 // thompson, greasegun, sten, mp40
|
||||
#define AMMO_ALTRIFLE 2 // carbine, k43, mg34
|
||||
#define AMMO_RIFLE 3 // garand, enfield, scoped enfield, k98, scoped k98
|
||||
#define AMMO_PISTOL 4 // colt, webley, luger
|
||||
#define AMMO_SPRING 5 // springfield
|
||||
#define AMMO_HEAVY 6 // bar, bren, stg44, fg42, scoped fg42
|
||||
#define AMMO_MG42 7 // mg42
|
||||
#define AMMO_30CAL 8 // 30cal
|
||||
#define AMMO_GREN 9 // grenades (should be all 3 types)
|
||||
#define AMMO_ROCKET 13 // bazooka, piat, panzerschreck
|
||||
enum {
|
||||
PS_NOPRONE =0,
|
||||
PS_PRONE,
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
/* Function is called after grenade throw */
|
||||
forward grenade_throw(index,greindex,wId);
|
||||
|
||||
/* Function is called after a rocket is shot */
|
||||
forward rocket_shoot(index,rocketindex,wId);
|
||||
|
||||
/* Example: for full stamina use dod_player_stamina(1,STAMINA_SET,100,100) */
|
||||
/* value is from 0 - 100 */
|
||||
native dod_set_stamina(index,set=STAMINA_SET,minvalue=0,maxvalue=100);
|
||||
|
|
|
@ -53,6 +53,44 @@ forward dod_client_changeclass(id, class, oldclass);
|
|||
/* This Forward is called when a player spawns */
|
||||
forward dod_client_spawn(id);
|
||||
|
||||
/* This will be called whenever a player scopes or unscopes
|
||||
value = 1 scope up
|
||||
value = 0 scope down */
|
||||
forward dod_client_scope(id, value);
|
||||
|
||||
/* This will be called whenever a player drops a weapon
|
||||
weapon is weapon dropped or picked up
|
||||
value = 1 picked up
|
||||
value = 0 dropped */
|
||||
forward dod_client_weaponpickup(id, weapon, value);
|
||||
|
||||
/* Called whenever the the player goes to or comes from prone position
|
||||
value = 1 going down
|
||||
value = 0 getting up */
|
||||
forward dod_client_prone(id, value);
|
||||
|
||||
/* This will be called whenever a player switches a weapon */
|
||||
forward dod_client_weaponswitch(id, wpnew, wpnold);
|
||||
|
||||
/* Forward for when a grenade explodes and its location */
|
||||
forward dod_grenade_explosion(id, pos[3], wpnid);
|
||||
|
||||
/* Forward for when a rocket explodes and its location */
|
||||
forward dod_rocket_explosion(id, pos[3], wpnid);
|
||||
|
||||
/* Forward for when a player picks up a object */
|
||||
forward dod_client_objectpickup(id, objid, pos[3], value);
|
||||
|
||||
/* Forward for when a users stamina decreases */
|
||||
forward dod_client_stamina(id, stamina);
|
||||
|
||||
/* We want to get just the weapon of whichever type that the player is on him
|
||||
Use DODWT_* in dodconst.inc for type */
|
||||
native dod_weapon_type(id, type);
|
||||
|
||||
/* This native will change the position of a weapon within the users slots and its ammo ammount */
|
||||
native dod_set_weaponlist(id, wpnID, slot, dropslot, totalrds);
|
||||
|
||||
/* Sets the model for a player */
|
||||
native dod_set_model(id, const model[]);
|
||||
|
||||
|
@ -102,7 +140,7 @@ native dod_get_map_info( info );
|
|||
|
||||
/* Returns id of currently carried weapon. Gets also
|
||||
* ammount of ammo in clip and backpack. */
|
||||
native dod_get_user_weapon(index,&clip,&ammo);
|
||||
native dod_get_user_weapon(index,&clip=0,&ammo=0);
|
||||
|
||||
/* Returns team score */
|
||||
native dod_get_team_score(teamId);
|
||||
|
|
|
@ -177,3 +177,37 @@ stock bool:operator!(Float:oper)
|
|||
forward operator%(Float:oper1, Float:oper2);
|
||||
forward operator%(Float:oper1, oper2);
|
||||
forward operator%(oper1, Float:oper2);
|
||||
|
||||
|
||||
stock Float:floatmin(Float:ValueA, Float:ValueB)
|
||||
{
|
||||
if (ValueA<=ValueB)
|
||||
{
|
||||
return ValueA;
|
||||
}
|
||||
|
||||
return ValueB;
|
||||
}
|
||||
|
||||
stock Float:floatmax(Float:ValueA, Float:ValueB)
|
||||
{
|
||||
if (ValueA>=ValueB)
|
||||
{
|
||||
return ValueA;
|
||||
}
|
||||
|
||||
return ValueB;
|
||||
}
|
||||
stock Float:floatclamp(Float:Value, Float:MinValue, Float:MaxValue)
|
||||
{
|
||||
if (Value<=MinValue)
|
||||
{
|
||||
return MinValue;
|
||||
}
|
||||
if (Value>=MaxValue)
|
||||
{
|
||||
return MaxValue;
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
|
|
@ -466,3 +466,16 @@
|
|||
#define HLW_SNARK 15
|
||||
#define HLW_SUIT 31
|
||||
#define HLW_ALLWEAPONS (~(1<<HLW_SUIT))
|
||||
|
||||
|
||||
#define FEV_NOTHOST (1<<0) // Skip local host for event send.
|
||||
#define FEV_RELIABLE (1<<1) // Send the event reliably. You must specify the origin and angles
|
||||
// for this to work correctly on the server for anything
|
||||
// that depends on the event origin/angles. I.e., the origin/angles are not
|
||||
// taken from the invoking edict for reliable events.
|
||||
#define FEV_GLOBAL (1<<2) // Don't restrict to PAS/PVS, send this event to _everybody_ on the server ( useful for stopping CHAN_STATIC
|
||||
// sounds started by client event when client is not in PVS anymore ( hwguy in TFC e.g. ).
|
||||
#define FEV_UPDATE (1<<3) // If this client already has one of these events in its queue, just update the event instead of sending it as a duplicate
|
||||
#define FEV_HOSTONLY (1<<4) // Only send to entity specified as the invoker
|
||||
#define FEV_SERVER (1<<5) // Only send if the event was created on the server.
|
||||
#define FEV_CLIENT (1<<6) // Only issue event client side ( from shared code )
|
||||
|
|
|
@ -23,15 +23,64 @@
|
|||
#define MSG_ONE_UNRELIABLE 8 // Send to one client, but don't put in reliable stream, put in unreliable datagram (could be dropped)
|
||||
#define MSG_SPEC 9 // Sends to all spectator proxies
|
||||
|
||||
/* Message types for message_begin() */
|
||||
#define SVC_TEMPENTITY 23
|
||||
#define SVC_INTERMISSION 30
|
||||
#define SVC_CDTRACK 32
|
||||
#define SVC_WEAPONANIM 35
|
||||
#define SVC_ROOMTYPE 37
|
||||
#define SVC_ADDANGLE 38 // [vec3] add this angle to the view angle
|
||||
#define SVC_NEWUSERMSG 39
|
||||
#define SVC_HLTV 50
|
||||
/* Hardcoded message types for message_begin()
|
||||
* Look in the actual HLSDK for details!
|
||||
*/
|
||||
#define SVC_NOP 1
|
||||
#define SVC_DISCONNECT 2
|
||||
#define SVC_EVENT 3
|
||||
#define SVC_VERSION 4
|
||||
#define SVC_SETVIEW 5
|
||||
#define SVC_SOUND 6
|
||||
#define SVC_TIME 7
|
||||
#define SVC_PRINT 8
|
||||
#define SVC_STUFFTEXT 9
|
||||
#define SVC_SETANGLE 10
|
||||
#define SVC_SERVERINFO 11
|
||||
#define SVC_LIGHTSTYLE 12
|
||||
#define SVC_UPDATEUSERINFO 13
|
||||
#define SVC_DELTADESCRIPTION 14
|
||||
#define SVC_CLIENTDATA 15
|
||||
#define SVC_STOPSOUND 16
|
||||
#define SVC_PINGS 17
|
||||
#define SVC_PARTICLE 18
|
||||
#define SVC_DAMAGE 19
|
||||
#define SVC_SPAWNSTATIC 20
|
||||
#define SVC_EVENT_RELIABLE 21
|
||||
#define SVC_SPAWNBASELINE 22
|
||||
#define SVC_TEMPENTITY 23
|
||||
#define SVC_SETPAUSE 24
|
||||
#define SVC_SIGNONNUM 25
|
||||
#define SVC_CENTERPRINT 26
|
||||
#define SVC_KILLEDMONSTER 27
|
||||
#define SVC_FOUNDSECRET 28
|
||||
#define SVC_SPAWNSTATICSOUND 29
|
||||
#define SVC_INTERMISSION 30
|
||||
#define SVC_FINALE 31
|
||||
#define SVC_CDTRACK 32
|
||||
#define SVC_RESTORE 33
|
||||
#define SVC_CUTSCENE 34
|
||||
#define SVC_WEAPONANIM 35
|
||||
#define SVC_DECALNAME 36
|
||||
#define SVC_ROOMTYPE 37
|
||||
#define SVC_ADDANGLE 38
|
||||
#define SVC_NEWUSERMSG 39
|
||||
#define SVC_PACKETENTITIES 40
|
||||
#define SVC_DELTAPACKETENTITIES 41
|
||||
#define SVC_CHOKE 42
|
||||
#define SVC_RESOURCELIST 43
|
||||
#define SVC_NEWMOVEVARS 44
|
||||
#define SVC_RESOURCEREQUEST 45
|
||||
#define SVC_CUSTOMIZATION 46
|
||||
#define SVC_CROSSHAIRANGLE 47
|
||||
#define SVC_SOUNDFADE 48
|
||||
#define SVC_FILETXFERFAILED 49
|
||||
#define SVC_HLTV 50
|
||||
#define SVC_DIRECTOR 51
|
||||
#define SVC_VOICEINIT 52
|
||||
#define SVC_VOICEDATA 53
|
||||
#define SVC_SENDEXTRAINFO 54
|
||||
#define SVC_TIMESCALE 55
|
||||
|
||||
/* Message flags for set_msg_block() */
|
||||
#define BLOCK_NOT 0
|
||||
|
@ -323,8 +372,6 @@ enum
|
|||
// write_coord(position.z)
|
||||
// write_short(model index)
|
||||
// write_byte(scale / 10)
|
||||
// write_byte(size)
|
||||
// write_byte(brightness)
|
||||
|
||||
#define TE_BEAMRING 24 // Connect a beam ring to two entities
|
||||
// write_byte(TE_BEAMRING)
|
||||
|
@ -364,6 +411,7 @@ enum
|
|||
// write_byte(red)
|
||||
// write_byte(green)
|
||||
// write_byte(blue)
|
||||
// write_byte(brightness)
|
||||
// write_byte(life in 10's)
|
||||
// write_byte(decay rate in 10's)
|
||||
|
||||
|
@ -649,7 +697,7 @@ enum
|
|||
|
||||
#define TE_PLAYERSPRITES 121 // Sprites emit from a player's bounding box (ONLY use for players!)
|
||||
// write_byte(TE_PLAYERSPRITES)
|
||||
// write_short(playernum)
|
||||
// write_byte(playernum)
|
||||
// write_short(sprite modelindex)
|
||||
// write_byte(count)
|
||||
// write_byte(variance) (0 = no variance in size) (10 = 10% variance in size)
|
||||
|
@ -719,3 +767,35 @@ enum
|
|||
// write_byte(life * 10)
|
||||
// write_byte(color) this is an index into an array of color vectors in the engine. (0 - )
|
||||
// write_byte(length * 10)
|
||||
|
||||
// From hltv.h from the HLSDK, these are used in conjunction with SVC_DIRECTOR
|
||||
// sub commands of svc_director:
|
||||
#define DRC_CMD_NONE 0 // NULL director command
|
||||
#define DRC_CMD_START 1 // start director mode
|
||||
#define DRC_CMD_EVENT 2 // informs about director command
|
||||
#define DRC_CMD_MODE 3 // switches camera modes
|
||||
#define DRC_CMD_CAMERA 4 // sets camera registers
|
||||
#define DRC_CMD_TIMESCALE 5 // sets time scale
|
||||
#define DRC_CMD_MESSAGE 6 // send HUD centerprint
|
||||
#define DRC_CMD_SOUND 7 // plays a particular sound
|
||||
#define DRC_CMD_STATUS 8 // status info about broadcast
|
||||
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui
|
||||
#define DRC_CMD_FADE 10 // send screen fade command
|
||||
#define DRC_CMD_SHAKE 11 // send screen shake command
|
||||
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command
|
||||
|
||||
#define DRC_CMD_LAST 12
|
||||
|
||||
// HLTV_EVENT event flags
|
||||
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
|
||||
#define DRC_FLAG_SIDE (1<<4) //
|
||||
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene
|
||||
#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo
|
||||
#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc)
|
||||
#define DRC_FLAG_INTRO (1<<8) // is a introduction scene
|
||||
#define DRC_FLAG_FINAL (1<<9) // is a final scene
|
||||
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
|
||||
|
||||
|
||||
#define MAX_DIRECTOR_CMD_PARAMETERS 4
|
||||
#define MAX_DIRECTOR_CMD_STRING 128
|
||||
|
|
|
@ -133,3 +133,13 @@ native tfc_setweaponammo(index, value);
|
|||
* Use the TFC_GOALITEM_* constants to determine the owning team.
|
||||
*/
|
||||
native tfc_get_user_goalitem(index, &team);
|
||||
|
||||
/* Returns 1 if the player is a spy and is currently feigning death */
|
||||
native tfc_is_user_feigning(index);
|
||||
|
||||
/* Returns 1 if the two teams are allies, 0 otherwise
|
||||
* Note: Team must be 1->4
|
||||
* Team 0 will always return 0
|
||||
* Any other team will result in an error
|
||||
*/
|
||||
native tfc_is_team_ally(TeamA,TeamB);
|
||||
|
|
|
@ -67,7 +67,7 @@ native ts_getuserslots( index );
|
|||
native ts_setuserslots( index, slots );
|
||||
|
||||
native ts_getuserstate( index );
|
||||
native ts_getuserwpn( index,&clip,&ammo,&mode,&extra );
|
||||
native ts_getuserwpn( index,&clip=0,&ammo=0,&mode=0,&extra=0 );
|
||||
native ts_getuserspace( index );
|
||||
|
||||
native ts_getuserkillflags(killer);
|
||||
|
|
|
@ -154,10 +154,33 @@ public actionBanMenu(id, key)
|
|||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_BAN_2", name, name2)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_BAN_1", name2)
|
||||
case 2:
|
||||
{
|
||||
if (g_menuSettings[id]==0) // permanent
|
||||
{
|
||||
client_print(0, print_chat, "%L %s: %L %s %L", LANG_PLAYER, "ADMIN", name, LANG_PLAYER, "BAN", name2, LANG_PLAYER, "PERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
new tempTime[32];
|
||||
formatex(tempTime,sizeof(tempTime)-1,"%d",g_menuSettings[id]);
|
||||
client_print(0, print_chat, "%L %s: %L %s %L", LANG_PLAYER, "ADMIN", name, LANG_PLAYER, "BAN", name2, LANG_PLAYER, "FOR_MIN", tempTime);
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (g_menuSettings[id]==0) // permanent
|
||||
{
|
||||
client_print(0, print_chat, "%L: %L %s %L", LANG_PLAYER, "ADMIN", LANG_PLAYER, "BAN", name2, LANG_PLAYER, "PERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
new tempTime[32];
|
||||
formatex(tempTime,sizeof(tempTime)-1,"%d",g_menuSettings[id]);
|
||||
client_print(0, print_chat, "%L: %L %s %L", LANG_PLAYER, "ADMIN", LANG_PLAYER, "BAN", name2, LANG_PLAYER, "FOR_MIN", tempTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- check for Steam ID added by MistaGee --------------------
|
||||
IF AUTHID == 4294967295 OR VALVE_ID_LAN OR HLTV, BAN PER IP TO NOT BAN EVERYONE */
|
||||
|
||||
|
@ -173,7 +196,9 @@ public actionBanMenu(id, key)
|
|||
server_cmd("addip %d %s;writeip", g_menuSettings[id], ipa)
|
||||
}
|
||||
else
|
||||
{
|
||||
server_cmd("banid %d #%d kick;writeid", g_menuSettings[id], userid2)
|
||||
}
|
||||
|
||||
server_exec()
|
||||
|
||||
|
|
123
plugins/testsuite/admins_test.sma
Normal file
123
plugins/testsuite/admins_test.sma
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include <amxmodx>
|
||||
|
||||
new __testnumber;
|
||||
new errcount;
|
||||
|
||||
enum TestType
|
||||
{
|
||||
TT_Equal = 0,
|
||||
TT_LessThan,
|
||||
TT_GreaterThan,
|
||||
TT_LessThanEqual,
|
||||
TT_GreaterThanEqual,
|
||||
TT_NotEqual
|
||||
};
|
||||
|
||||
new TestWords[6][] = {
|
||||
"==",
|
||||
"<",
|
||||
">",
|
||||
"<=",
|
||||
">=",
|
||||
"!="
|
||||
};
|
||||
|
||||
|
||||
|
||||
stock test(A,B=0,TestType:Type=TT_Equal)
|
||||
{
|
||||
++__testnumber;
|
||||
|
||||
new passed=0;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case TT_Equal: if (A==B) passed=1;
|
||||
case TT_LessThan: if (A<B) passed=1;
|
||||
case TT_GreaterThan: if (A>B) passed=1;
|
||||
case TT_LessThanEqual: if (A<=B) passed=1;
|
||||
case TT_GreaterThanEqual: if (A>=B) passed=1;
|
||||
case TT_NotEqual: if (A!=B) passed=1;
|
||||
}
|
||||
|
||||
if (!passed)
|
||||
{
|
||||
log_amx("Failed test #%d (%d %s %d)",__testnumber,A,TestWords[_:Type],B);
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public plugin_init()
|
||||
{
|
||||
register_srvcmd("testadmins","testadmins");
|
||||
}
|
||||
public testadmins()
|
||||
{
|
||||
|
||||
new AuthData[44];
|
||||
new Password[32];
|
||||
new Access;
|
||||
new Flags;
|
||||
new id;
|
||||
|
||||
__testnumber=0;
|
||||
errcount=0;
|
||||
|
||||
|
||||
test(admins_num(),0);
|
||||
|
||||
admins_push("STEAM_0:1:23456","",read_flags("abcdefghijklmnopqrstu"),read_flags("ce"));
|
||||
|
||||
test(admins_num(),1);
|
||||
|
||||
admins_push("ABCDEFGHIJKLMNOP","abcdefghijklmnop",read_flags("z"),read_flags("a"));
|
||||
|
||||
test(admins_num(),2);
|
||||
|
||||
admins_push("ZYXWVUTSRQPONMLKJIHGFEDCBA","plop",read_flags("a"),read_flags("b"));
|
||||
|
||||
test(admins_num(),3);
|
||||
|
||||
id=0;
|
||||
|
||||
admins_lookup(id,AdminProp_Auth,AuthData,sizeof(AuthData)-1);
|
||||
admins_lookup(id,AdminProp_Password,Password,sizeof(Password)-1);
|
||||
Access=admins_lookup(id,AdminProp_Access);
|
||||
Flags=admins_lookup(id,AdminProp_Flags);
|
||||
|
||||
test(strcmp(AuthData,"STEAM_0:1:23456"),0);
|
||||
test(strcmp(Password,""),0);
|
||||
test(Access,read_flags("abcdefghijklmnopqrstu"));
|
||||
test(Flags,read_flags("ce"));
|
||||
|
||||
id++;
|
||||
|
||||
admins_lookup(id,AdminProp_Auth,AuthData,sizeof(AuthData)-1);
|
||||
admins_lookup(id,AdminProp_Password,Password,sizeof(Password)-1);
|
||||
Access=admins_lookup(id,AdminProp_Access);
|
||||
Flags=admins_lookup(id,AdminProp_Flags);
|
||||
|
||||
test(strcmp(AuthData,"ABCDEFGHIJKLMNOP"),0);
|
||||
test(strcmp(Password,"abcdefghijklmnop"),0);
|
||||
test(Access,read_flags("z"));
|
||||
test(Flags,read_flags("a"));
|
||||
|
||||
id++;
|
||||
|
||||
admins_lookup(id,AdminProp_Auth,AuthData,sizeof(AuthData)-1);
|
||||
admins_lookup(id,AdminProp_Password,Password,sizeof(Password)-1);
|
||||
Access=admins_lookup(id,AdminProp_Access);
|
||||
Flags=admins_lookup(id,AdminProp_Flags);
|
||||
|
||||
test(strcmp(AuthData,"ZYXWVUTSRQPONMLKJIHGFEDCBA"),0);
|
||||
test(strcmp(Password,"plop"),0);
|
||||
test(Access,read_flags("a"));
|
||||
test(Flags,read_flags("b"));
|
||||
|
||||
admins_flush();
|
||||
|
||||
test(admins_num(),0);
|
||||
|
||||
server_print("test complete, %d errors",errcount);
|
||||
}
|
|
@ -62,6 +62,7 @@ public plugin_init()
|
|||
|
||||
register_dictionary("plmenu.txt")
|
||||
register_dictionary("common.txt")
|
||||
register_dictionary("admincmd.txt")
|
||||
|
||||
register_clcmd("amx_kickmenu","cmdKickMenu",ADMIN_KICK,"- displays kick menu")
|
||||
register_clcmd("amx_banmenu","cmdBanMenu",ADMIN_BAN,"- displays ban menu")
|
||||
|
@ -122,8 +123,32 @@ public actionBanMenu(id, key)
|
|||
|
||||
switch (get_cvar_num("amx_show_activity"))
|
||||
{
|
||||
case 2: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_BAN_2", name, name2)
|
||||
case 1: client_print(0, print_chat, "%L", LANG_PLAYER, "ADMIN_BAN_1", name2)
|
||||
case 2:
|
||||
{
|
||||
if (g_menuSettings[id]==0) // permanent
|
||||
{
|
||||
client_print(0, print_chat, "%L %s: %L %s %L", LANG_PLAYER, "ADMIN", name, LANG_PLAYER, "BAN", name2, LANG_PLAYER, "PERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
new tempTime[32];
|
||||
formatex(tempTime,sizeof(tempTime)-1,"%d",g_menuSettings[id]);
|
||||
client_print(0, print_chat, "%L %s: %L %s %L", LANG_PLAYER, "ADMIN", name, LANG_PLAYER, "BAN", name2, LANG_PLAYER, "FOR_MIN", tempTime);
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (g_menuSettings[id]==0) // permanent
|
||||
{
|
||||
client_print(0, print_chat, "%L: %L %s %L", LANG_PLAYER, "ADMIN", LANG_PLAYER, "BAN", name2, LANG_PLAYER, "PERM");
|
||||
}
|
||||
else
|
||||
{
|
||||
new tempTime[32];
|
||||
formatex(tempTime,sizeof(tempTime)-1,"%d",g_menuSettings[id]);
|
||||
client_print(0, print_chat, "%L: %L %s %L", LANG_PLAYER, "ADMIN", LANG_PLAYER, "BAN", name2, LANG_PLAYER, "FOR_MIN", tempTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (equal("4294967295", authid2))
|
||||
|
|
Loading…
Reference in New Issue
Block a user