diff --git a/amxmodx/CFlagManager.cpp b/amxmodx/CFlagManager.cpp new file mode 100644 index 00000000..2bc71342 --- /dev/null +++ b/amxmodx/CFlagManager.cpp @@ -0,0 +1,409 @@ +#include +#include +#include + +#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(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(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(&Command[0]),&Flags[0]); + + nonconst=const_cast(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::iterator iter; + List::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::iterator iter; + List::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::iterator iter; + List::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; + } +}; diff --git a/amxmodx/CFlagManager.h b/amxmodx/CFlagManager.h new file mode 100644 index 00000000..7084bad3 --- /dev/null +++ b/amxmodx/CFlagManager.h @@ -0,0 +1,219 @@ +#ifndef CFLAGMANAGER_H +#define CFLAGMANAGER_H + +#include +#include +#include + +#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 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 diff --git a/amxmodx/CMisc.h b/amxmodx/CMisc.h index 9313cf58..b9dbe3a0 100755 --- a/amxmodx/CMisc.h +++ b/amxmodx/CMisc.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 (iSetAccess(src.GetAccess()); + this->SetFlags(src.GetFlags()); + this->SetAuthID(src.GetAuthID()); + this->SetPass(src.GetPass()); + + return *this; + } +}; #endif //CMISC_H diff --git a/amxmodx/CString.h b/amxmodx/CString.h index 3f9d6531..b5398edd 100755 --- a/amxmodx/CString.h +++ b/amxmodx/CString.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); diff --git a/amxmodx/Makefile b/amxmodx/Makefile index 3727bf10..15cac948 100755 --- a/amxmodx/Makefile +++ b/amxmodx/Makefile @@ -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 diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 6c289e5f..55078e8e 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -35,8 +35,13 @@ #include "debugger.h" #include "binlog.h" #include "libraries.h" +#include "CFlagManager.h" #include "nongpl_matches.h" +extern CFlagManager FlagMan; +CVector 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) @@ -1254,7 +1259,12 @@ static cell AMX_NATIVE_CALL register_concmd(AMX *amx, cell *params) /* 4 param * access = 0; 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; @@ -1294,7 +1304,12 @@ static cell AMX_NATIVE_CALL register_clcmd(AMX *amx, cell *params) /* 4 param */ access = 0; 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(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(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(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}, diff --git a/amxmodx/amxmodx.h b/amxmodx/amxmodx.h index 8237fb85..5e5093b2 100755 --- a/amxmodx/amxmodx.h +++ b/amxmodx/amxmodx.h @@ -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 diff --git a/amxmodx/meta_api.cpp b/amxmodx/meta_api.cpp index ac304650..38fafc90 100755 --- a/amxmodx/meta_api.cpp +++ b/amxmodx/meta_api.cpp @@ -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 g_auth_funcs; +extern CVector 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; iv.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); } diff --git a/amxmodx/msvc/amxmodx_mm.vcproj b/amxmodx/msvc/amxmodx_mm.vcproj index c3bf6972..d9587091 100755 --- a/amxmodx/msvc/amxmodx_mm.vcproj +++ b/amxmodx/msvc/amxmodx_mm.vcproj @@ -361,6 +361,9 @@ + + @@ -515,6 +518,9 @@ + + diff --git a/amxmodx/msvc8/amxmodx_mm.vcproj b/amxmodx/msvc8/amxmodx_mm.vcproj index 114f0edb..a3c8b6ea 100644 --- a/amxmodx/msvc8/amxmodx_mm.vcproj +++ b/amxmodx/msvc8/amxmodx_mm.vcproj @@ -505,6 +505,10 @@ RelativePath="..\CFile.cpp" > + + @@ -710,6 +714,10 @@ RelativePath="..\CFile.h" > + + diff --git a/amxmodx/newmenus.cpp b/amxmodx/newmenus.cpp index e6a8e686..bd77cdfa 100755 --- a/amxmodx/newmenus.cpp +++ b/amxmodx/newmenus.cpp @@ -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; } diff --git a/dlls/dod2/dodfun/amxxmodule.cpp b/dlls/dod2/dodfun/amxxmodule.cpp index 30ef9c79..d8c8c56c 100755 --- a/dlls/dod2/dodfun/amxxmodule.cpp +++ b/dlls/dod2/dodfun/amxxmodule.cpp @@ -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 diff --git a/dlls/dod2/dodfun/dodfun.h b/dlls/dod2/dodfun/dodfun.h index a1c6f33b..69d6f3a4 100755 --- a/dlls/dod2/dodfun/dodfun.h +++ b/dlls/dod2/dodfun/dodfun.h @@ -57,6 +57,7 @@ extern int gmsgInitObj; extern int gmsgSetObj; extern int iFGrenade; +extern int iFRocket; extern int iFInitCP; extern CPlayer players[33]; diff --git a/dlls/dod2/dodfun/moduleconfig.cpp b/dlls/dod2/dodfun/moduleconfig.cpp index aa20da3e..f310a03a 100755 --- a/dlls/dod2/dodfun/moduleconfig.cpp +++ b/dlls/dod2/dodfun/moduleconfig.cpp @@ -29,6 +29,7 @@ * */ +#include #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); } diff --git a/dlls/dod2/dodfun/moduleconfig.h b/dlls/dod2/dodfun/moduleconfig.h index e14d4682..5e00afba 100755 --- a/dlls/dod2/dodfun/moduleconfig.h +++ b/dlls/dod2/dodfun/moduleconfig.h @@ -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" diff --git a/dlls/dod2/dodx/CMisc.cpp b/dlls/dod2/dodx/CMisc.cpp index 759788f3..b0ee3c1d 100755 --- a/dlls/dod2/dodx/CMisc.cpp +++ b/dlls/dod2/dodx/CMisc.cpp @@ -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<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; + } } // ***************************************************** diff --git a/dlls/dod2/dodx/CMisc.h b/dlls/dod2/dodx/CMisc.h index 6bb14c10..21d843c2 100755 --- a/dlls/dod2/dodx/CMisc.h +++ b/dlls/dod2/dodx/CMisc.h @@ -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 diff --git a/dlls/dod2/dodx/NBase.cpp b/dlls/dod2/dodx/NBase.cpp index 09a0a07f..49613a26 100755 --- a/dlls/dod2/dodx/NBase.cpp +++ b/dlls/dod2/dodx/NBase.cpp @@ -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){ + + 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 (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< 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 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 }, @@ -397,6 +627,8 @@ AMX_NATIVE_INFO base_Natives[] = { { "dod_get_user_score", get_user_score }, { "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 }, @@ -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 } diff --git a/dlls/dod2/dodx/Utils.cpp b/dlls/dod2/dodx/Utils.cpp index ca39fbb5..aa8b0157 100755 --- a/dlls/dod2/dodx/Utils.cpp +++ b/dlls/dod2/dodx/Utils.cpp @@ -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; +} diff --git a/dlls/dod2/dodx/dodx.h b/dlls/dod2/dodx/dodx.h index ce1412e0..be489e57 100755 --- a/dlls/dod2/dodx/dodx.h +++ b/dlls/dod2/dodx/dodx.h @@ -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) { \ diff --git a/dlls/dod2/dodx/moduleconfig.cpp b/dlls/dod2/dodx/moduleconfig.cpp index 94c7aeaa..6b90b8cb 100755 --- a/dlls/dod2/dodx/moduleconfig.cpp +++ b/dlls/dod2/dodx/moduleconfig.cpp @@ -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;iv.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); +} \ No newline at end of file diff --git a/dlls/dod2/dodx/moduleconfig.h b/dlls/dod2/dodx/moduleconfig.h index f2fda0b3..d965b103 100755 --- a/dlls/dod2/dodx/moduleconfig.h +++ b/dlls/dod2/dodx/moduleconfig.h @@ -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" diff --git a/dlls/dod2/dodx/usermsg.cpp b/dlls/dod2/dodx/usermsg.cpp index 22c20bbb..6d265712 100755 --- a/dlls/dod2/dodx/usermsg.cpp +++ b/dlls/dod2/dodx/usermsg.cpp @@ -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) -{ - if ( !isModuleActive() ) - return; - - CPlayer* pVictim = mPlayer; - - edict_t *enemy = pVictim->pEdict->v.dmg_inflictor; - int damage = (int)pVictim->pEdict->v.dmg_take; - - if(!pVictim || !damage || !enemy) - return; - - int weapon = 0; - int aim = 0; - - pVictim->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); - - 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); - } -} - -/* -Working on being able to modify and switch weapons as they are sent to the client - -void WeaponList(void* value) +// 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(!mPlayer) return; - if(!mPlayer->ingame || ignoreBots(mPlayer->pEdict)) - return; - - switch(mPlayer->position) - { - 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->position++; + mPlayer->Scoping(*(int*)mValue); } -void WeaponList_End(void* mValue) +void Client_SetFOV_End(void* mValue) { if(!mPlayer) return; - MF_Log("Done with %d", mPlayer->position); - mPlayer->position = 0; + mPlayer->ScopingCheck(); } -struct weapon_info_s +void Client_Object(void* mValue) { - 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; + if(!mPlayer) + return; -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(); -*/ + // First need to find out what was picked up + const char *classname; + edict_t* pObject = NULL; + + const char* value; + + if(mValue) + { + value = (char*)mValue; + } + + if(!mPlayer->object.carrying) + { + // We grab the first object within the sphere of our player + pObject = FindEntityInSphere(mPlayer->pEdict, mPlayer->pEdict, 50.0); + + // The loop through all the objects within the sphere + while(pObject && !FNullEnt(pObject)) + { + classname = STRING(pObject->v.classname); + + if(strcmp(classname, "dod_object") == 0) + { + mPlayer->object.pEdict = pObject; + mPlayer->object.do_forward = true; + return; + } + + pObject = FindEntityInSphere(pObject, mPlayer->pEdict, 50.0); + } + } + + else + { + mPlayer->object.do_forward = true; + } +} + +void Client_Object_End(void* mValue) +{ + if(!mPlayer) + return; + + float fposition[3]; + + if(mPlayer->object.do_forward) + { + mPlayer->object.do_forward = (mPlayer->object.do_forward) ? false : true; + mPlayer->object.carrying = (mPlayer->object.carrying) ? false : true; + + 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; + } +} diff --git a/dlls/hamsandwich/CString.h b/dlls/hamsandwich/CString.h new file mode 100644 index 00000000..3bdc3605 --- /dev/null +++ b/dlls/hamsandwich/CString.h @@ -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 +#include + +//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(size()); + if (len < 1) + return npos; + if (index >= len || index < 0) + return npos; + int i = 0; + for (i=index; 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=start && i= 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= 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 diff --git a/dlls/hamsandwich/CVector.h b/dlls/hamsandwich/CVector.h new file mode 100644 index 00000000..d0fef2be --- /dev/null +++ b/dlls/hamsandwich/CVector.h @@ -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 + +// Vector +template 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_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 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() + { + m_Size = 0; + m_CurrentUsedSize = 0; + m_Data = NULL; + } + + CVector(const CVector & 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() + { + 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__ + diff --git a/dlls/hamsandwich/FileParser.cpp b/dlls/hamsandwich/FileParser.cpp new file mode 100644 index 00000000..e116d14c --- /dev/null +++ b/dlls/hamsandwich/FileParser.cpp @@ -0,0 +1,161 @@ +#include +#include +#include +#include + +#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); +} diff --git a/dlls/hamsandwich/FileParser.h b/dlls/hamsandwich/FileParser.h new file mode 100644 index 00000000..8cae8d79 --- /dev/null +++ b/dlls/hamsandwich/FileParser.h @@ -0,0 +1,6 @@ +#ifndef FILEPARSER_H +#define FILEPARSER_H + +typedef bool (*FP_ptrFeedback)(const char *key, const char *value); + +#endif // FILEPARSER_H diff --git a/dlls/hamsandwich/Makefile b/dlls/hamsandwich/Makefile new file mode 100644 index 00000000..886c7d93 --- /dev/null +++ b/dlls/hamsandwich/Makefile @@ -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) + diff --git a/dlls/hamsandwich/NEW_Util.h b/dlls/hamsandwich/NEW_Util.h new file mode 100644 index 00000000..e76fbf23 --- /dev/null +++ b/dlls/hamsandwich/NEW_Util.h @@ -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 + diff --git a/dlls/hamsandwich/Trampolines.h b/dlls/hamsandwich/Trampolines.h new file mode 100644 index 00000000..40611a37 --- /dev/null +++ b/dlls/hamsandwich/Trampolines.h @@ -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 +#elif defined __linux__ +#include +#endif +#include // size_t +#include // 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 (origReturnPrologue(); + 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 diff --git a/dlls/hamsandwich/amxxapi.cpp b/dlls/hamsandwich/amxxapi.cpp new file mode 100644 index 00000000..ad7b643d --- /dev/null +++ b/dlls/hamsandwich/amxxapi.cpp @@ -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 +#include + +#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 SuffixNames; /**< List of names being searched for in the config file. */ +CVector SuffixFunctions; /**< Callback functions for when we find a hunted keyvalue. */ +CVector 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 _ 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__ 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 (ic_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(); +}; diff --git a/dlls/hamsandwich/hamdata.ini b/dlls/hamsandwich/hamdata.ini new file mode 100644 index 00000000..b113e837 --- /dev/null +++ b/dlls/hamsandwich/hamdata.ini @@ -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 \ No newline at end of file diff --git a/dlls/hamsandwich/hamsandwich.h b/dlls/hamsandwich/hamsandwich.h new file mode 100644 index 00000000..46662b38 --- /dev/null +++ b/dlls/hamsandwich/hamsandwich.h @@ -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 diff --git a/dlls/sven/sven.sln b/dlls/hamsandwich/msvc8/hs.sln similarity index 54% rename from dlls/sven/sven.sln rename to dlls/hamsandwich/msvc8/hs.sln index 78e1fc1b..21904bc2 100644 --- a/dlls/sven/sven.sln +++ b/dlls/hamsandwich/msvc8/hs.sln @@ -1,20 +1,20 @@ - -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}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - 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 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ham sandwich", "hs.vcproj", "{5B5DEFD0-28ED-4D0E-A1B0-50F9304A65DF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {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 + EndGlobalSection +EndGlobal diff --git a/dlls/sven/sven.vcproj b/dlls/hamsandwich/msvc8/hs.vcproj similarity index 60% rename from dlls/sven/sven.vcproj rename to dlls/hamsandwich/msvc8/hs.vcproj index 9e2e1745..6e22a6e8 100644 --- a/dlls/sven/sven.vcproj +++ b/dlls/hamsandwich/msvc8/hs.vcproj @@ -1,252 +1,268 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dlls/hamsandwich/msvc8/include/hamsandwich.inc b/dlls/hamsandwich/msvc8/include/hamsandwich.inc new file mode 100644 index 00000000..06243f3f --- /dev/null +++ b/dlls/hamsandwich/msvc8/include/hamsandwich.inc @@ -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[]); \ No newline at end of file diff --git a/dlls/hamsandwich/natives.cpp b/dlls/hamsandwich/natives.cpp new file mode 100644 index 00000000..18f19e6d --- /dev/null +++ b/dlls/hamsandwich/natives.cpp @@ -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( + 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++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); +} + diff --git a/dlls/sven/amxxmodule.cpp b/dlls/hamsandwich/sdk/amxxmodule.cpp similarity index 96% rename from dlls/sven/amxxmodule.cpp rename to dlls/hamsandwich/sdk/amxxmodule.cpp index 7355cded..ab2cbdb6 100644 --- a/dlls/sven/amxxmodule.cpp +++ b/dlls/hamsandwich/sdk/amxxmodule.cpp @@ -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 diff --git a/dlls/sven/amxxmodule.h b/dlls/hamsandwich/sdk/amxxmodule.h similarity index 91% rename from dlls/sven/amxxmodule.h rename to dlls/hamsandwich/sdk/amxxmodule.h index 3d20f50e..964ad53b 100644 --- a/dlls/sven/amxxmodule.h +++ b/dlls/hamsandwich/sdk/amxxmodule.h @@ -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 ***/ diff --git a/dlls/hamsandwich/sdk/moduleconfig.h b/dlls/hamsandwich/sdk/moduleconfig.h new file mode 100644 index 00000000..13309082 --- /dev/null +++ b/dlls/hamsandwich/sdk/moduleconfig.h @@ -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__ diff --git a/dlls/hamsandwich/tableentries/Blocked.cpp b/dlls/hamsandwich/tableentries/Blocked.cpp new file mode 100644 index 00000000..d99c3edb --- /dev/null +++ b/dlls/hamsandwich/tableentries/Blocked.cpp @@ -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 ("__" 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(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 (iThisEntries[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 (iresult) + { + result=thisresult; + } + }; + + if (result>=HAM_SUPERCEDE) + { + return; + } + +#if defined _WIN32 + reinterpret_cast(function)(pthis,0,other); +#elif defined __linux__ + reinterpret_cast(function)(pthis,other); +#endif + + +}; diff --git a/dlls/hamsandwich/tableentries/TakeDamage.cpp b/dlls/hamsandwich/tableentries/TakeDamage.cpp new file mode 100644 index 00000000..a763fa28 --- /dev/null +++ b/dlls/hamsandwich/tableentries/TakeDamage.cpp @@ -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 ("__" 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 (iIsTrampoline(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(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(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( + 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(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 (iThisEntries[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 (iresult) + { + result=thisresult; + } + }; + + // stop here + if (result>=HAM_SUPERCEDE) + { + return 0; + } + +#if defined _WIN32 + int ireturn=reinterpret_cast(function)(pthis,0,inflictor,attacker,damage,type); +#elif defined __linux__ + int ireturn=reinterpret_cast(function)(pthis,inflictor,attacker,damage,type); +#endif + + if (result!=HAM_OVERRIDE) + return ireturn; + + return 0; +}; diff --git a/dlls/hamsandwich/tableentries/Use.cpp b/dlls/hamsandwich/tableentries/Use.cpp new file mode 100644 index 00000000..e039d517 --- /dev/null +++ b/dlls/hamsandwich/tableentries/Use.cpp @@ -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 ("__" 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(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 (iThisEntries[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 (iresult) + { + result=thisresult; + } + }; + + if (result>=HAM_SUPERCEDE) + { + return; + } + +#if defined _WIN32 + reinterpret_cast(function)(pthis,0,activator,caller,type,value); +#elif defined __linux__ + reinterpret_cast(function)(pthis,activator,caller,type,value); +#endif + +}; diff --git a/dlls/hamsandwich/tableentries/VTableEntries.h b/dlls/hamsandwich/tableentries/VTableEntries.h new file mode 100644 index 00000000..9e0aeafe --- /dev/null +++ b/dlls/hamsandwich/tableentries/VTableEntries.h @@ -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 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 ("__" 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 ("__" 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 ("__" 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 diff --git a/dlls/hamsandwich/tableentries/VTableManager.cpp b/dlls/hamsandwich/tableentries/VTableManager.cpp new file mode 100644 index 00000000..8abfd317 --- /dev/null +++ b/dlls/hamsandwich/tableentries/VTableManager.cpp @@ -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); +}; diff --git a/dlls/hamsandwich/tableentries/VTableManager.h b/dlls/hamsandwich/tableentries/VTableManager.h new file mode 100644 index 00000000..03fca45f --- /dev/null +++ b/dlls/hamsandwich/tableentries/VTableManager.h @@ -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 UseEntries; + CVector TakeDamageEntries; + CVector 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 diff --git a/dlls/hamsandwich/vfunc_gcc295.h b/dlls/hamsandwich/vfunc_gcc295.h new file mode 100644 index 00000000..bb8559a1 --- /dev/null +++ b/dlls/hamsandwich/vfunc_gcc295.h @@ -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 +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(vtbl[ventry]); + + function(pThis,pa,pb,pc,pd); +}; +template +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(vtbl[ventry]); + return function(pThis,pa,pb,pc,pd); +}; +template +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(vtbl[ventry]); + function(pThis,pa); +}; +template +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(vtbl[ventry]); + return function(pThis,pa); +}; + +#endif //VFUNC_GCC295_H +#endif // __linux__ diff --git a/dlls/hamsandwich/vfunc_msvc.h b/dlls/hamsandwich/vfunc_msvc.h new file mode 100644 index 00000000..ab51e2c7 --- /dev/null +++ b/dlls/hamsandwich/vfunc_msvc.h @@ -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 +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 +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 +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 +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 diff --git a/dlls/hamsandwich/vtable.cpp b/dlls/hamsandwich/vtable.cpp new file mode 100644 index 00000000..15380ac0 --- /dev/null +++ b/dlls/hamsandwich/vtable.cpp @@ -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); +}; + +*/ diff --git a/dlls/sven/pdata.h b/dlls/sven/pdata.h deleted file mode 100644 index 7aacb9e9..00000000 --- a/dlls/sven/pdata.h +++ /dev/null @@ -1,39 +0,0 @@ -// prevent double include -#ifndef __PDATA_H__ -#define __PDATA_H__ - -#include -#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 -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 -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 \ No newline at end of file diff --git a/dlls/sven/sven/CString.h b/dlls/sven/sven/CString.h new file mode 100644 index 00000000..1c77cfac --- /dev/null +++ b/dlls/sven/sven/CString.h @@ -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 +#include + +//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(size()); + if (len < 1) + return npos; + if (index >= len || index < 0) + return npos; + int i = 0; + for (i=index; 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=start && i= 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= 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 diff --git a/dlls/sven/sven/Trie.h b/dlls/sven/sven/Trie.h new file mode 100644 index 00000000..1bbe72d0 --- /dev/null +++ b/dlls/sven/sven/Trie.h @@ -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 +#include + +// Rukia: Metaprogramming to aid in compile time constants and such. +template +struct Exponential +{ + enum { value = base * Exponential::value }; +}; + +template +struct Exponential +{ + 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) 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 +template +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(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 diff --git a/dlls/sven/sven/amxxmodule.cpp b/dlls/sven/sven/amxxmodule.cpp new file mode 100644 index 00000000..83067916 --- /dev/null +++ b/dlls/sven/sven/amxxmodule.cpp @@ -0,0 +1,3119 @@ +/* AMX Mod X +* +* by the AMX Mod X Development Team +* originally developed by OLO +* +* Parts Copyright (C) 2001-2003 Will Day +* +* 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 Functions +*/ + +#include +#include +#include +#include +#include +#include "amxxmodule.h" + +/************* METAMOD SUPPORT *************/ +#ifdef USE_METAMOD + +enginefuncs_t g_engfuncs; +globalvars_t *gpGlobals; + +DLL_FUNCTIONS *g_pFunctionTable; +DLL_FUNCTIONS *g_pFunctionTable_Post; +enginefuncs_t *g_pengfuncsTable; +enginefuncs_t *g_pengfuncsTable_Post; +NEW_DLL_FUNCTIONS *g_pNewFunctionsTable; +NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post; + +// GetEntityAPI2 functions +static DLL_FUNCTIONS g_EntityAPI_Table = +{ +#ifdef FN_GameDLLInit + FN_GameDLLInit, +#else + NULL, +#endif +#ifdef FN_DispatchSpawn + FN_DispatchSpawn, +#else + NULL, +#endif +#ifdef FN_DispatchThink + FN_DispatchThink, +#else + NULL, +#endif +#ifdef FN_DispatchUse + FN_DispatchUse, +#else + NULL, +#endif +#ifdef FN_DispatchTouch + FN_DispatchTouch, +#else + NULL, +#endif +#ifdef FN_DispatchBlocked + FN_DispatchBlocked, +#else + NULL, +#endif +#ifdef FN_DispatchKeyValue + FN_DispatchKeyValue, +#else + NULL, +#endif +#ifdef FN_DispatchSave + FN_DispatchSave, +#else + NULL, +#endif +#ifdef FN_DispatchRestore + FN_DispatchRestore, +#else + NULL, +#endif +#ifdef FN_DispatchObjectCollsionBox + FN_DispatchObjectCollsionBox, +#else + NULL, +#endif +#ifdef FN_SaveWriteFields + FN_SaveWriteFields, +#else + NULL, +#endif +#ifdef FN_SaveReadFields + FN_SaveReadFields, +#else + NULL, +#endif +#ifdef FN_SaveGlobalState + FN_SaveGlobalState, +#else + NULL, +#endif +#ifdef FN_RestoreGlobalState + FN_RestoreGlobalState, +#else + NULL, +#endif +#ifdef FN_ResetGlobalState + FN_ResetGlobalState, +#else + NULL, +#endif +#ifdef FN_ClientConnect + FN_ClientConnect, +#else + NULL, +#endif +#ifdef FN_ClientDisconnect + FN_ClientDisconnect, +#else + NULL, +#endif +#ifdef FN_ClientKill + FN_ClientKill, +#else + NULL, +#endif +#ifdef FN_ClientPutInServer + FN_ClientPutInServer, +#else + NULL, +#endif +#ifdef FN_ClientCommand + FN_ClientCommand, +#else + NULL, +#endif +#ifdef FN_ClientUserInfoChanged + FN_ClientUserInfoChanged, +#else + NULL, +#endif +#ifdef FN_ServerActivate + FN_ServerActivate, +#else + NULL, +#endif +#ifdef FN_ServerDeactivate + FN_ServerDeactivate, +#else + NULL, +#endif +#ifdef FN_PlayerPreThink + FN_PlayerPreThink, +#else + NULL, +#endif +#ifdef FN_PlayerPostThink + FN_PlayerPostThink, +#else + NULL, +#endif +#ifdef FN_StartFrame + FN_StartFrame, +#else + NULL, +#endif +#ifdef FN_ParmsNewLevel + FN_ParmsNewLevel, +#else + NULL, +#endif +#ifdef FN_ParmsChangeLevel + FN_ParmsChangeLevel, +#else + NULL, +#endif +#ifdef FN_GetGameDescription + FN_GetGameDescription, +#else + NULL, +#endif +#ifdef FN_PlayerCustomization + FN_PlayerCustomization, +#else + NULL, +#endif +#ifdef FN_SpectatorConnect + FN_SpectatorConnect, +#else + NULL, +#endif +#ifdef FN_SpectatorDisconnect + FN_SpectatorDisconnect, +#else + NULL, +#endif +#ifdef FN_SpectatorThink + FN_SpectatorThink, +#else + NULL, +#endif +#ifdef FN_Sys_Error + FN_Sys_Error, +#else + NULL, +#endif +#ifdef FN_PM_Move + FN_PM_Move, +#else + NULL, +#endif +#ifdef FN_PM_Init + FN_PM_Init, +#else + NULL, +#endif +#ifdef FN_PM_FindTextureType + FN_PM_FindTextureType, +#else + NULL, +#endif +#ifdef FN_SetupVisibility + FN_SetupVisibility, +#else + NULL, +#endif +#ifdef FN_UpdateClientData + FN_UpdateClientData, +#else + NULL, +#endif +#ifdef FN_AddToFullPack + FN_AddToFullPack, +#else + NULL, +#endif +#ifdef FN_CreateBaseline + FN_CreateBaseline, +#else + NULL, +#endif +#ifdef FN_RegisterEncoders + FN_RegisterEncoders, +#else + NULL, +#endif +#ifdef FN_GetWeaponData + FN_GetWeaponData, +#else + NULL, +#endif +#ifdef FN_CmdStart + FN_CmdStart, +#else + NULL, +#endif +#ifdef FN_CmdEnd + FN_CmdEnd, +#else + NULL, +#endif +#ifdef FN_ConnectionlessPacket + FN_ConnectionlessPacket, +#else + NULL, +#endif +#ifdef FN_GetHullBounds + FN_GetHullBounds, +#else + NULL, +#endif +#ifdef FN_CreateInstancedBaselines + FN_CreateInstancedBaselines, +#else + NULL, +#endif +#ifdef FN_InconsistentFile + FN_InconsistentFile, +#else + NULL, +#endif +#ifdef FN_AllowLagCompensation + FN_AllowLagCompensation +#else + NULL +#endif +}; // g_EntityAPI2_Table + +// GetEntityAPI2_Post functions +static DLL_FUNCTIONS g_EntityAPI_Post_Table = +{ +#ifdef FN_GameDLLInit_Post + FN_GameDLLInit_Post, +#else + NULL, +#endif +#ifdef FN_DispatchSpawn_Post + FN_DispatchSpawn_Post, +#else + NULL, +#endif +#ifdef FN_DispatchThink_Post + FN_DispatchThink_Post, +#else + NULL, +#endif +#ifdef FN_DispatchUse_Post + FN_DispatchUse_Post, +#else + NULL, +#endif +#ifdef FN_DispatchTouch_Post + FN_DispatchTouch_Post, +#else + NULL, +#endif +#ifdef FN_DispatchBlocked_Post + FN_DispatchBlocked_Post, +#else + NULL, +#endif +#ifdef FN_DispatchKeyValue_Post + FN_DispatchKeyValue_Post, +#else + NULL, +#endif +#ifdef FN_DispatchSave_Post + FN_DispatchSave_Post, +#else + NULL, +#endif +#ifdef FN_DispatchRestore_Post + FN_DispatchRestore_Post, +#else + NULL, +#endif +#ifdef FN_DispatchObjectCollsionBox_Post + FN_DispatchObjectCollsionBox_Post, +#else + NULL, +#endif +#ifdef FN_SaveWriteFields_Post + FN_SaveWriteFields_Post, +#else + NULL, +#endif +#ifdef FN_SaveReadFields_Post + FN_SaveReadFields_Post, +#else + NULL, +#endif +#ifdef FN_SaveGlobalState_Post + FN_SaveGlobalState_Post, +#else + NULL, +#endif +#ifdef FN_RestoreGlobalState_Post + FN_RestoreGlobalState_Post, +#else + NULL, +#endif +#ifdef FN_ResetGlobalState_Post + FN_ResetGlobalState_Post, +#else + NULL, +#endif +#ifdef FN_ClientConnect_Post + FN_ClientConnect_Post, +#else + NULL, +#endif +#ifdef FN_ClientDisconnect_Post + FN_ClientDisconnect_Post, +#else + NULL, +#endif +#ifdef FN_ClientKill_Post + FN_ClientKill_Post, +#else + NULL, +#endif +#ifdef FN_ClientPutInServer_Post + FN_ClientPutInServer_Post, +#else + NULL, +#endif +#ifdef FN_ClientCommand_Post + FN_ClientCommand_Post, +#else + NULL, +#endif +#ifdef FN_ClientUserInfoChanged_Post + FN_ClientUserInfoChanged_Post, +#else + NULL, +#endif +#ifdef FN_ServerActivate_Post + FN_ServerActivate_Post, +#else + NULL, +#endif +#ifdef FN_ServerDeactivate_Post + FN_ServerDeactivate_Post, +#else + NULL, +#endif +#ifdef FN_PlayerPreThink_Post + FN_PlayerPreThink_Post, +#else + NULL, +#endif +#ifdef FN_PlayerPostThink_Post + FN_PlayerPostThink_Post, +#else + NULL, +#endif +#ifdef FN_StartFrame_Post + FN_StartFrame_Post, +#else + NULL, +#endif +#ifdef FN_ParmsNewLevel_Post + FN_ParmsNewLevel_Post, +#else + NULL, +#endif +#ifdef FN_ParmsChangeLevel_Post + FN_ParmsChangeLevel_Post, +#else + NULL, +#endif +#ifdef FN_GetGameDescription_Post + FN_GetGameDescription_Post, +#else + NULL, +#endif +#ifdef FN_PlayerCustomization_Post + FN_PlayerCustomization_Post, +#else + NULL, +#endif +#ifdef FN_SpectatorConnect_Post + FN_SpectatorConnect_Post, +#else + NULL, +#endif +#ifdef FN_SpectatorDisconnect_Post + FN_SpectatorDisconnect_Post, +#else + NULL, +#endif +#ifdef FN_SpectatorThink_Post + FN_SpectatorThink_Post, +#else + NULL, +#endif +#ifdef FN_Sys_Error_Post + FN_Sys_Error_Post, +#else + NULL, +#endif +#ifdef FN_PM_Move_Post + FN_PM_Move_Post, +#else + NULL, +#endif +#ifdef FN_PM_Init_Post + FN_PM_Init_Post, +#else + NULL, +#endif +#ifdef FN_PM_FindTextureType_Post + FN_PM_FindTextureType_Post, +#else + NULL, +#endif +#ifdef FN_SetupVisibility_Post + FN_SetupVisibility_Post, +#else + NULL, +#endif +#ifdef FN_UpdateClientData_Post + FN_UpdateClientData_Post, +#else + NULL, +#endif +#ifdef FN_AddToFullPack_Post + FN_AddToFullPack_Post, +#else + NULL, +#endif +#ifdef FN_CreateBaseline_Post + FN_CreateBaseline_Post, +#else + NULL, +#endif +#ifdef FN_RegisterEncoders_Post + FN_RegisterEncoders_Post, +#else + NULL, +#endif +#ifdef FN_GetWeaponData_Post + FN_GetWeaponData_Post, +#else + NULL, +#endif +#ifdef FN_CmdStart_Post + FN_CmdStart_Post, +#else + NULL, +#endif +#ifdef FN_CmdEnd_Post + FN_CmdEnd_Post, +#else + NULL, +#endif +#ifdef FN_ConnectionlessPacket_Post + FN_ConnectionlessPacket_Post, +#else + NULL, +#endif +#ifdef FN_GetHullBounds_Post + FN_GetHullBounds_Post, +#else + NULL, +#endif +#ifdef FN_CreateInstancedBaselines_Post + FN_CreateInstancedBaselines_Post, +#else + NULL, +#endif +#ifdef FN_InconsistentFile_Post + FN_InconsistentFile_Post, +#else + NULL, +#endif +#ifdef FN_AllowLagCompensation + FN_AllowLagCompensation, +#else + NULL, +#endif +}; // g_EntityAPI2_Table + +static enginefuncs_t g_EngineFuncs_Table = +{ +#ifdef FN_PrecacheModel + FN_PrecacheModel, +#else + NULL, +#endif +#ifdef FN_PrecacheSound + FN_PrecacheSound, +#else + NULL, +#endif +#ifdef FN_SetModel + FN_SetModel, +#else + NULL, +#endif +#ifdef FN_ModelIndex + FN_ModelIndex, +#else + NULL, +#endif +#ifdef FN_ModelFrames + FN_ModelFrames, +#else + NULL, +#endif +#ifdef FN_SetSize + FN_SetSize, +#else + NULL, +#endif +#ifdef FN_ChangeLevel + FN_ChangeLevel, +#else + NULL, +#endif +#ifdef FN_GetSpawnParms + FN_GetSpawnParms, +#else + NULL, +#endif +#ifdef FN_SaveSpawnParms + FN_SaveSpawnParms, +#else + NULL, +#endif +#ifdef FN_VecToYaw + FN_VecToYaw, +#else + NULL, +#endif +#ifdef FN_VecToAngles + FN_VecToAngles, +#else + NULL, +#endif +#ifdef FN_MoveToOrigin + FN_MoveToOrigin, +#else + NULL, +#endif +#ifdef FN_ChangeYaw + FN_ChangeYaw, +#else + NULL, +#endif +#ifdef FN_ChangePitch + FN_ChangePitch, +#else + NULL, +#endif +#ifdef FN_FindEntityByString + FN_FindEntityByString, +#else + NULL, +#endif +#ifdef FN_GetEntityIllum + FN_GetEntityIllum, +#else + NULL, +#endif +#ifdef FN_FindEntityInSphere + FN_FindEntityInSphere, +#else + NULL, +#endif +#ifdef FN_FindClientInPVS + FN_FindClientInPVS, +#else + NULL, +#endif +#ifdef FN_EntitiesInPVS + FN_EntitiesInPVS, +#else + NULL, +#endif +#ifdef FN_MakeVectors + FN_MakeVectors, +#else + NULL, +#endif +#ifdef FN_AngleVectors + FN_AngleVectors, +#else + NULL, +#endif +#ifdef FN_CreateEntity + FN_CreateEntity, +#else + NULL, +#endif +#ifdef FN_RemoveEntity + FN_RemoveEntity, +#else + NULL, +#endif +#ifdef FN_CreateNamedEntity + FN_CreateNamedEntity, +#else + NULL, +#endif +#ifdef FN_MakeStatic + FN_MakeStatic, +#else + NULL, +#endif +#ifdef FN_EntIsOnFloor + FN_EntIsOnFloor, +#else + NULL, +#endif +#ifdef FN_DropToFloor + FN_DropToFloor, +#else + NULL, +#endif +#ifdef FN_WalkMove + FN_WalkMove, +#else + NULL, +#endif +#ifdef FN_SetOrigin + FN_SetOrigin, +#else + NULL, +#endif +#ifdef FN_EmitSound + FN_EmitSound, +#else + NULL, +#endif +#ifdef FN_EmitAmbientSound + FN_EmitAmbientSound, +#else + NULL, +#endif +#ifdef FN_TraceLine + FN_TraceLine, +#else + NULL, +#endif +#ifdef FN_TraceToss + FN_TraceToss, +#else + NULL, +#endif +#ifdef FN_TraceMonsterHull + FN_TraceMonsterHull, +#else + NULL, +#endif +#ifdef FN_TraceHull + FN_TraceHull, +#else + NULL, +#endif +#ifdef FN_TraceModel + FN_TraceModel, +#else + NULL, +#endif +#ifdef FN_TraceTexture + FN_TraceTexture, +#else + NULL, +#endif +#ifdef FN_TraceSphere + FN_TraceSphere, +#else + NULL, +#endif +#ifdef FN_GetAimVector + FN_GetAimVector, +#else + NULL, +#endif +#ifdef FN_ServerCommand + FN_ServerCommand, +#else + NULL, +#endif +#ifdef FN_ServerExecute + FN_ServerExecute, +#else + NULL, +#endif +#ifdef FN_engClientCommand + FN_engClientCommand, +#else + NULL, +#endif +#ifdef FN_ParticleEffect + FN_ParticleEffect, +#else + NULL, +#endif +#ifdef FN_LightStyle + FN_LightStyle, +#else + NULL, +#endif +#ifdef FN_DecalIndex + FN_DecalIndex, +#else + NULL, +#endif +#ifdef FN_PointContents + FN_PointContents, +#else + NULL, +#endif +#ifdef FN_MessageBegin + FN_MessageBegin, +#else + NULL, +#endif +#ifdef FN_MessageEnd + FN_MessageEnd, +#else + NULL, +#endif +#ifdef FN_WriteByte + FN_WriteByte, +#else + NULL, +#endif +#ifdef FN_WriteChar + FN_WriteChar, +#else + NULL, +#endif +#ifdef FN_WriteShort + FN_WriteShort, +#else + NULL, +#endif +#ifdef FN_WriteLong + FN_WriteLong, +#else + NULL, +#endif +#ifdef FN_WriteAngle + FN_WriteAngle, +#else + NULL, +#endif +#ifdef FN_WriteCoord + FN_WriteCoord, +#else + NULL, +#endif +#ifdef FN_WriteString + FN_WriteString, +#else + NULL, +#endif +#ifdef FN_WriteEntity + FN_WriteEntity, +#else + NULL, +#endif +#ifdef FN_CVarRegister + FN_CVarRegister, +#else + NULL, +#endif +#ifdef FN_CVarGetFloat + FN_CVarGetFloat, +#else + NULL, +#endif +#ifdef FN_CVarGetString + FN_CVarGetString, +#else + NULL, +#endif +#ifdef FN_CVarSetFloat + FN_CVarSetFloat, +#else + NULL, +#endif +#ifdef FN_CVarSetString + FN_CVarSetString, +#else + NULL, +#endif +#ifdef FN_AlertMessage + FN_AlertMessage, +#else + NULL, +#endif +#ifdef FN_EngineFprintf + FN_EngineFprintf, +#else + NULL, +#endif +#ifdef FN_PvAllocEntPrivateData + FN_PvAllocEntPrivateData, +#else + NULL, +#endif +#ifdef FN_PvEntPrivateData + FN_PvEntPrivateData, +#else + NULL, +#endif +#ifdef FN_FreeEntPrivateData + FN_FreeEntPrivateData, +#else + NULL, +#endif +#ifdef FN_SzFromIndex + FN_SzFromIndex, +#else + NULL, +#endif +#ifdef FN_AllocString + FN_AllocString, +#else + NULL, +#endif +#ifdef FN_GetVarsOfEnt + FN_GetVarsOfEnt, +#else + NULL, +#endif +#ifdef FN_PEntityOfEntOffset + FN_PEntityOfEntOffset, +#else + NULL, +#endif +#ifdef FN_EntOffsetOfPEntity + FN_EntOffsetOfPEntity, +#else + NULL, +#endif +#ifdef FN_IndexOfEdict + FN_IndexOfEdict, +#else + NULL, +#endif +#ifdef FN_PEntityOfEntIndex + FN_PEntityOfEntIndex, +#else + NULL, +#endif +#ifdef FN_FindEntityByVars + FN_FindEntityByVars, +#else + NULL, +#endif +#ifdef FN_GetModelPtr + FN_GetModelPtr, +#else + NULL, +#endif +#ifdef FN_RegUserMsg + FN_RegUserMsg, +#else + NULL, +#endif +#ifdef FN_AnimationAutomove + FN_AnimationAutomove, +#else + NULL, +#endif +#ifdef FN_GetBonePosition + FN_GetBonePosition, +#else + NULL, +#endif +#ifdef FN_FunctionFromName + FN_FunctionFromName, +#else + NULL, +#endif +#ifdef FN_NameForFunction + FN_NameForFunction, +#else + NULL, +#endif +#ifdef FN_ClientPrintf + FN_ClientPrintf, +#else + NULL, +#endif +#ifdef FN_ServerPrint + FN_ServerPrint, +#else + NULL, +#endif +#ifdef FN_Cmd_Args + FN_Cmd_Args, +#else + NULL, +#endif +#ifdef FN_Cmd_Argv + FN_Cmd_Argv, +#else + NULL, +#endif +#ifdef FN_Cmd_Argc + FN_Cmd_Argc, +#else + NULL, +#endif +#ifdef FN_GetAttachment + FN_GetAttachment, +#else + NULL, +#endif +#ifdef FN_CRC32_Init + FN_CRC32_Init, +#else + NULL, +#endif +#ifdef FN_CRC32_ProcessBuffer + FN_CRC32_ProcessBuffer, +#else + NULL, +#endif +#ifdef FN_CRC32_ProcessByte + FN_CRC32_ProcessByte, +#else + NULL, +#endif +#ifdef FN_CRC32_Final + FN_CRC32_Final, +#else + NULL, +#endif +#ifdef FN_RandomLong + FN_RandomLong, +#else + NULL, +#endif +#ifdef FN_RandomFloat + FN_RandomFloat, +#else + NULL, +#endif +#ifdef FN_SetView + FN_SetView, +#else + NULL, +#endif +#ifdef FN_Time + FN_Time, +#else + NULL, +#endif +#ifdef FN_CrosshairAngle + FN_CrosshairAngle, +#else + NULL, +#endif +#ifdef FN_LoadFileForMe + FN_LoadFileForMe, +#else + NULL, +#endif +#ifdef FN_FreeFile + FN_FreeFile, +#else + NULL, +#endif +#ifdef FN_EndSection + FN_EndSection, +#else + NULL, +#endif +#ifdef FN_CompareFileTime + FN_CompareFileTime, +#else + NULL, +#endif +#ifdef FN_GetGameDir + FN_GetGameDir, +#else + NULL, +#endif +#ifdef FN_Cvar_RegisterVariable + FN_Cvar_RegisterVariable, +#else + NULL, +#endif +#ifdef FN_FadeClientVolume + FN_FadeClientVolume, +#else + NULL, +#endif +#ifdef FN_SetClientMaxspeed + FN_SetClientMaxspeed, +#else + NULL, +#endif +#ifdef FN_CreateFakeClient + FN_CreateFakeClient, +#else + NULL, +#endif +#ifdef FN_RunPlayerMove + FN_RunPlayerMove, +#else + NULL, +#endif +#ifdef FN_NumberOfEntities + FN_NumberOfEntities, +#else + NULL, +#endif +#ifdef FN_GetInfoKeyBuffer + FN_GetInfoKeyBuffer, +#else + NULL, +#endif +#ifdef FN_InfoKeyValue + FN_InfoKeyValue, +#else + NULL, +#endif +#ifdef FN_SetKeyValue + FN_SetKeyValue, +#else + NULL, +#endif +#ifdef FN_SetClientKeyValue + FN_SetClientKeyValue, +#else + NULL, +#endif +#ifdef FN_IsMapValid + FN_IsMapValid, +#else + NULL, +#endif +#ifdef FN_StaticDecal + FN_StaticDecal, +#else + NULL, +#endif +#ifdef FN_PrecacheGeneric + FN_PrecacheGeneric, +#else + NULL, +#endif +#ifdef FN_GetPlayerUserId + FN_GetPlayerUserId, +#else + NULL, +#endif +#ifdef FN_BuildSoundMsg + FN_BuildSoundMsg, +#else + NULL, +#endif +#ifdef FN_IsDedicatedServer + FN_IsDedicatedServer, +#else + NULL, +#endif +#ifdef FN_CVarGetPointer + FN_CVarGetPointer, +#else + NULL, +#endif +#ifdef FN_GetPlayerWONId + FN_GetPlayerWONId, +#else + NULL, +#endif +#ifdef FN_Info_RemoveKey + FN_Info_RemoveKey, +#else + NULL, +#endif +#ifdef FN_GetPhysicsKeyValue + FN_GetPhysicsKeyValue, +#else + NULL, +#endif +#ifdef FN_SetPhysicsKeyValue + FN_SetPhysicsKeyValue, +#else + NULL, +#endif +#ifdef FN_GetPhysicsInfoString + FN_GetPhysicsInfoString, +#else + NULL, +#endif +#ifdef FN_PrecacheEvent + FN_PrecacheEvent, +#else + NULL, +#endif +#ifdef FN_PlaybackEvent + FN_PlaybackEvent, +#else + NULL, +#endif +#ifdef FN_SetFatPVS + FN_SetFatPVS, +#else + NULL, +#endif +#ifdef FN_SetFatPAS + FN_SetFatPAS, +#else + NULL, +#endif +#ifdef FN_CheckVisibility + FN_CheckVisibility, +#else + NULL, +#endif +#ifdef FN_DeltaSetField + FN_DeltaSetField, +#else + NULL, +#endif +#ifdef FN_DeltaUnsetField + FN_DeltaUnsetField, +#else + NULL, +#endif +#ifdef FN_DeltaAddEncoder + FN_DeltaAddEncoder, +#else + NULL, +#endif +#ifdef FN_GetCurrentPlayer + FN_GetCurrentPlayer, +#else + NULL, +#endif +#ifdef FN_CanSkipPlayer + FN_CanSkipPlayer, +#else + NULL, +#endif +#ifdef FN_DeltaFindField + FN_DeltaFindField, +#else + NULL, +#endif +#ifdef FN_DeltaSetFieldByIndex + FN_DeltaSetFieldByIndex, +#else + NULL, +#endif +#ifdef FN_DeltaUnsetFieldByIndex + FN_DeltaUnsetFieldByIndex, +#else + NULL, +#endif +#ifdef FN_SetGroupMask + FN_SetGroupMask, +#else + NULL, +#endif +#ifdef FN_engCreateInstancedBaseline + FN_engCreateInstancedBaseline, +#else + NULL, +#endif +#ifdef FN_Cvar_DirectSet + FN_Cvar_DirectSet, +#else + NULL, +#endif +#ifdef FN_ForceUnmodified + FN_ForceUnmodified, +#else + NULL, +#endif +#ifdef FN_GetPlayerStats + FN_GetPlayerStats, +#else + NULL, +#endif +#ifdef FN_AddServerCommand + FN_AddServerCommand, +#else + NULL, +#endif +#ifdef FN_Voice_GetClientListening + FN_Voice_GetClientListening, +#else + NULL, +#endif +#ifdef FN_Voice_SetClientListening + FN_Voice_SetClientListening, +#else + NULL, +#endif +#ifdef FN_GetPlayerAuthId + FN_GetPlayerAuthId +#else + NULL +#endif +}; // g_EngineFuncs_Table + + +static enginefuncs_t g_EngineFuncs_Post_Table = +{ +#ifdef FN_PrecacheModel_Post + FN_PrecacheModel_Post, +#else + NULL, +#endif +#ifdef FN_PrecacheSound_Post + FN_PrecacheSound_Post, +#else + NULL, +#endif +#ifdef FN_SetModel_Post + FN_SetModel_Post, +#else + NULL, +#endif +#ifdef FN_ModelIndex_Post + FN_ModelIndex_Post, +#else + NULL, +#endif +#ifdef FN_ModelFrames_Post + FN_ModelFrames_Post, +#else + NULL, +#endif +#ifdef FN_SetSize_Post + FN_SetSize_Post, +#else + NULL, +#endif +#ifdef FN_ChangeLevel_Post + FN_ChangeLevel_Post, +#else + NULL, +#endif +#ifdef FN_GetSpawnParms_Post + FN_GetSpawnParms_Post, +#else + NULL, +#endif +#ifdef FN_SaveSpawnParms_Post + FN_SaveSpawnParms_Post, +#else + NULL, +#endif +#ifdef FN_VecToYaw_Post + FN_VecToYaw_Post, +#else + NULL, +#endif +#ifdef FN_VecToAngles_Post + FN_VecToAngles_Post, +#else + NULL, +#endif +#ifdef FN_MoveToOrigin_Post + FN_MoveToOrigin_Post, +#else + NULL, +#endif +#ifdef FN_ChangeYaw_Post + FN_ChangeYaw_Post, +#else + NULL, +#endif +#ifdef FN_ChangePitch_Post + FN_ChangePitch_Post, +#else + NULL, +#endif +#ifdef FN_FindEntityByString_Post + FN_FindEntityByString_Post, +#else + NULL, +#endif +#ifdef FN_GetEntityIllum_Post + FN_GetEntityIllum_Post, +#else + NULL, +#endif +#ifdef FN_FindEntityInSphere_Post + FN_FindEntityInSphere_Post, +#else + NULL, +#endif +#ifdef FN_FindClientInPVS_Post + FN_FindClientInPVS_Post, +#else + NULL, +#endif +#ifdef FN_EntitiesInPVS_Post + FN_EntitiesInPVS_Post, +#else + NULL, +#endif +#ifdef FN_MakeVectors_Post + FN_MakeVectors_Post, +#else + NULL, +#endif +#ifdef FN_AngleVectors_Post + FN_AngleVectors_Post, +#else + NULL, +#endif +#ifdef FN_CreateEntity_Post + FN_CreateEntity_Post, +#else + NULL, +#endif +#ifdef FN_RemoveEntity_Post + FN_RemoveEntity_Post, +#else + NULL, +#endif +#ifdef FN_CreateNamedEntity_Post + FN_CreateNamedEntity_Post, +#else + NULL, +#endif +#ifdef FN_MakeStatic_Post + FN_MakeStatic_Post, +#else + NULL, +#endif +#ifdef FN_EntIsOnFloor_Post + FN_EntIsOnFloor_Post, +#else + NULL, +#endif +#ifdef FN_DropToFloor_Post + FN_DropToFloor_Post, +#else + NULL, +#endif +#ifdef FN_WalkMove_Post + FN_WalkMove_Post, +#else + NULL, +#endif +#ifdef FN_SetOrigin_Post + FN_SetOrigin_Post, +#else + NULL, +#endif +#ifdef FN_EmitSound_Post + FN_EmitSound_Post, +#else + NULL, +#endif +#ifdef FN_EmitAmbientSound_Post + FN_EmitAmbientSound_Post, +#else + NULL, +#endif +#ifdef FN_TraceLine_Post + FN_TraceLine_Post, +#else + NULL, +#endif +#ifdef FN_TraceToss_Post + FN_TraceToss_Post, +#else + NULL, +#endif +#ifdef FN_TraceMonsterHull_Post + FN_TraceMonsterHull_Post, +#else + NULL, +#endif +#ifdef FN_TraceHull_Post + FN_TraceHull_Post, +#else + NULL, +#endif +#ifdef FN_TraceModel_Post + FN_TraceModel_Post, +#else + NULL, +#endif +#ifdef FN_TraceTexture_Post + FN_TraceTexture_Post, +#else + NULL, +#endif +#ifdef FN_TraceSphere_Post + FN_TraceSphere_Post, +#else + NULL, +#endif +#ifdef FN_GetAimVector_Post + FN_GetAimVector_Post, +#else + NULL, +#endif +#ifdef FN_ServerCommand_Post + FN_ServerCommand_Post, +#else + NULL, +#endif +#ifdef FN_ServerExecute_Post + FN_ServerExecute_Post, +#else + NULL, +#endif +#ifdef FN_engClientCommand_Post + FN_engClientCommand_Post, +#else + NULL, +#endif +#ifdef FN_ParticleEffect_Post + FN_ParticleEffect_Post, +#else + NULL, +#endif +#ifdef FN_LightStyle_Post + FN_LightStyle_Post, +#else + NULL, +#endif +#ifdef FN_DecalIndex_Post + FN_DecalIndex_Post, +#else + NULL, +#endif +#ifdef FN_PointContents_Post + FN_PointContents_Post, +#else + NULL, +#endif +#ifdef FN_MessageBegin_Post + FN_MessageBegin_Post, +#else + NULL, +#endif +#ifdef FN_MessageEnd_Post + FN_MessageEnd_Post, +#else + NULL, +#endif +#ifdef FN_WriteByte_Post + FN_WriteByte_Post, +#else + NULL, +#endif +#ifdef FN_WriteChar_Post + FN_WriteChar_Post, +#else + NULL, +#endif +#ifdef FN_WriteShort_Post + FN_WriteShort_Post, +#else + NULL, +#endif +#ifdef FN_WriteLong_Post + FN_WriteLong_Post, +#else + NULL, +#endif +#ifdef FN_WriteAngle_Post + FN_WriteAngle_Post, +#else + NULL, +#endif +#ifdef FN_WriteCoord_Post + FN_WriteCoord_Post, +#else + NULL, +#endif +#ifdef FN_WriteString_Post + FN_WriteString_Post, +#else + NULL, +#endif +#ifdef FN_WriteEntity_Post + FN_WriteEntity_Post, +#else + NULL, +#endif +#ifdef FN_CVarRegister_Post + FN_CVarRegister_Post, +#else + NULL, +#endif +#ifdef FN_CVarGetFloat_Post + FN_CVarGetFloat_Post, +#else + NULL, +#endif +#ifdef FN_CVarGetString_Post + FN_CVarGetString_Post, +#else + NULL, +#endif +#ifdef FN_CVarSetFloat_Post + FN_CVarSetFloat_Post, +#else + NULL, +#endif +#ifdef FN_CVarSetString_Post + FN_CVarSetString_Post, +#else + NULL, +#endif +#ifdef FN_AlertMessage_Post + FN_AlertMessage_Post, +#else + NULL, +#endif +#ifdef FN_EngineFprintf_Post + FN_EngineFprintf_Post, +#else + NULL, +#endif +#ifdef FN_PvAllocEntPrivateData_Post + FN_PvAllocEntPrivateData_Post, +#else + NULL, +#endif +#ifdef FN_PvEntPrivateData_Post + FN_PvEntPrivateData_Post, +#else + NULL, +#endif +#ifdef FN_FreeEntPrivateData_Post + FN_FreeEntPrivateData_Post, +#else + NULL, +#endif +#ifdef FN_SzFromIndex_Post + FN_SzFromIndex_Post, +#else + NULL, +#endif +#ifdef FN_AllocString_Post + FN_AllocString_Post, +#else + NULL, +#endif +#ifdef FN_GetVarsOfEnt_Post + FN_GetVarsOfEnt_Post, +#else + NULL, +#endif +#ifdef FN_PEntityOfEntOffset_Post + FN_PEntityOfEntOffset_Post, +#else + NULL, +#endif +#ifdef FN_EntOffsetOfPEntity_Post + FN_EntOffsetOfPEntity_Post, +#else + NULL, +#endif +#ifdef FN_IndexOfEdict_Post + FN_IndexOfEdict_Post, +#else + NULL, +#endif +#ifdef FN_PEntityOfEntIndex_Post + FN_PEntityOfEntIndex_Post, +#else + NULL, +#endif +#ifdef FN_FindEntityByVars_Post + FN_FindEntityByVars_Post, +#else + NULL, +#endif +#ifdef FN_GetModelPtr_Post + FN_GetModelPtr_Post, +#else + NULL, +#endif +#ifdef FN_RegUserMsg_Post + FN_RegUserMsg_Post, +#else + NULL, +#endif +#ifdef FN_AnimationAutomove_Post + FN_AnimationAutomove_Post, +#else + NULL, +#endif +#ifdef FN_GetBonePosition_Post + FN_GetBonePosition_Post, +#else + NULL, +#endif +#ifdef FN_FunctionFromName_Post + FN_FunctionFromName_Post, +#else + NULL, +#endif +#ifdef FN_NameForFunction_Post + FN_NameForFunction_Post, +#else + NULL, +#endif +#ifdef FN_ClientPrintf_Post + FN_ClientPrintf_Post, +#else + NULL, +#endif +#ifdef FN_ServerPrint_Post + FN_ServerPrint_Post, +#else + NULL, +#endif +#ifdef FN_Cmd_Args_Post + FN_Cmd_Args_Post, +#else + NULL, +#endif +#ifdef FN_Cmd_Argv_Post + FN_Cmd_Argv_Post, +#else + NULL, +#endif +#ifdef FN_Cmd_Argc_Post + FN_Cmd_Argc_Post, +#else + NULL, +#endif +#ifdef FN_GetAttachment_Post + FN_GetAttachment_Post, +#else + NULL, +#endif +#ifdef FN_CRC32_Init_Post + FN_CRC32_Init_Post, +#else + NULL, +#endif +#ifdef FN_CRC32_ProcessBuffer_Post + FN_CRC32_ProcessBuffer_Post, +#else + NULL, +#endif +#ifdef FN_CRC32_ProcessByte_Post + FN_CRC32_ProcessByte_Post, +#else + NULL, +#endif +#ifdef FN_CRC32_Final_Post + FN_CRC32_Final_Post, +#else + NULL, +#endif +#ifdef FN_RandomLong_Post + FN_RandomLong_Post, +#else + NULL, +#endif +#ifdef FN_RandomFloat_Post + FN_RandomFloat_Post, +#else + NULL, +#endif +#ifdef FN_SetView_Post + FN_SetView_Post, +#else + NULL, +#endif +#ifdef FN_Time_Post + FN_Time_Post, +#else + NULL, +#endif +#ifdef FN_CrosshairAngle_Post + FN_CrosshairAngle_Post, +#else + NULL, +#endif +#ifdef FN_LoadFileForMe_Post + FN_LoadFileForMe_Post, +#else + NULL, +#endif +#ifdef FN_FreeFile_Post + FN_FreeFile_Post, +#else + NULL, +#endif +#ifdef FN_EndSection_Post + FN_EndSection_Post, +#else + NULL, +#endif +#ifdef FN_CompareFileTime_Post + FN_CompareFileTime_Post, +#else + NULL, +#endif +#ifdef FN_GetGameDir_Post + FN_GetGameDir_Post, +#else + NULL, +#endif +#ifdef FN_Cvar_RegisterVariable_Post + FN_Cvar_RegisterVariable_Post, +#else + NULL, +#endif +#ifdef FN_FadeClientVolume_Post + FN_FadeClientVolume_Post, +#else + NULL, +#endif +#ifdef FN_SetClientMaxspeed_Post + FN_SetClientMaxspeed_Post, +#else + NULL, +#endif +#ifdef FN_CreateFakeClient_Post + FN_CreateFakeClient_Post, +#else + NULL, +#endif +#ifdef FN_RunPlayerMove_Post + FN_RunPlayerMove_Post, +#else + NULL, +#endif +#ifdef FN_NumberOfEntities_Post + FN_NumberOfEntities_Post, +#else + NULL, +#endif +#ifdef FN_GetInfoKeyBuffer_Post + FN_GetInfoKeyBuffer_Post, +#else + NULL, +#endif +#ifdef FN_InfoKeyValue_Post + FN_InfoKeyValue_Post, +#else + NULL, +#endif +#ifdef FN_SetKeyValue_Post + FN_SetKeyValue_Post, +#else + NULL, +#endif +#ifdef FN_SetClientKeyValue_Post + FN_SetClientKeyValue_Post, +#else + NULL, +#endif +#ifdef FN_IsMapValid_Post + FN_IsMapValid_Post, +#else + NULL, +#endif +#ifdef FN_StaticDecal_Post + FN_StaticDecal_Post, +#else + NULL, +#endif +#ifdef FN_PrecacheGeneric_Post + FN_PrecacheGeneric_Post, +#else + NULL, +#endif +#ifdef FN_GetPlayerUserId_Post + FN_GetPlayerUserId_Post, +#else + NULL, +#endif +#ifdef FN_BuildSoundMsg_Post + FN_BuildSoundMsg_Post, +#else + NULL, +#endif +#ifdef FN_IsDedicatedServer_Post + FN_IsDedicatedServer_Post, +#else + NULL, +#endif +#ifdef FN_CVarGetPointer_Post + FN_CVarGetPointer_Post, +#else + NULL, +#endif +#ifdef FN_GetPlayerWONId_Post + FN_GetPlayerWONId_Post, +#else + NULL, +#endif +#ifdef FN_Info_RemoveKey_Post + FN_Info_RemoveKey_Post, +#else + NULL, +#endif +#ifdef FN_GetPhysicsKeyValue_Post + FN_GetPhysicsKeyValue_Post, +#else + NULL, +#endif +#ifdef FN_SetPhysicsKeyValue_Post + FN_SetPhysicsKeyValue_Post, +#else + NULL, +#endif +#ifdef FN_GetPhysicsInfoString_Post + FN_GetPhysicsInfoString_Post, +#else + NULL, +#endif +#ifdef FN_PrecacheEvent_Post + FN_PrecacheEvent_Post, +#else + NULL, +#endif +#ifdef FN_PlaybackEvent_Post + FN_PlaybackEvent_Post, +#else + NULL, +#endif +#ifdef FN_SetFatPVS_Post + FN_SetFatPVS_Post, +#else + NULL, +#endif +#ifdef FN_SetFatPAS_Post + FN_SetFatPAS_Post, +#else + NULL, +#endif +#ifdef FN_CheckVisibility_Post + FN_CheckVisibility_Post, +#else + NULL, +#endif +#ifdef FN_DeltaSetField_Post + FN_DeltaSetField_Post, +#else + NULL, +#endif +#ifdef FN_DeltaUnsetField_Post + FN_DeltaUnsetField_Post, +#else + NULL, +#endif +#ifdef FN_DeltaAddEncoder_Post + FN_DeltaAddEncoder_Post, +#else + NULL, +#endif +#ifdef FN_GetCurrentPlayer_Post + FN_GetCurrentPlayer_Post, +#else + NULL, +#endif +#ifdef FN_CanSkipPlayer_Post + FN_CanSkipPlayer_Post, +#else + NULL, +#endif +#ifdef FN_DeltaFindField_Post + FN_DeltaFindField_Post, +#else + NULL, +#endif +#ifdef FN_DeltaSetFieldByIndex_Post + FN_DeltaSetFieldByIndex_Post, +#else + NULL, +#endif +#ifdef FN_DeltaUnsetFieldByIndex_Post + FN_DeltaUnsetFieldByIndex_Post, +#else + NULL, +#endif +#ifdef FN_SetGroupMask_Post + FN_SetGroupMask_Post, +#else + NULL, +#endif +#ifdef FN_engCreateInstancedBaseline_Post + FN_engCreateInstancedBaseline_Post, +#else + NULL, +#endif +#ifdef FN_Cvar_DirectSet_Post + FN_Cvar_DirectSet_Post, +#else + NULL, +#endif +#ifdef FN_ForceUnmodified_Post + FN_ForceUnmodified_Post, +#else + NULL, +#endif +#ifdef FN_GetPlayerStats_Post + FN_GetPlayerStats_Post, +#else + NULL, +#endif +#ifdef FN_AddServerCommand_Post + FN_AddServerCommand_Post, +#else + NULL, +#endif +#ifdef FN_Voice_GetClientListening_Post + FN_Voice_GetClientListening_Post, +#else + NULL, +#endif +#ifdef FN_Voice_SetClientListening_Post + FN_Voice_SetClientListening_Post, +#else + NULL, +#endif +#ifdef FN_GetPlayerAuthId_Post + FN_GetPlayerAuthId_Post +#else + NULL +#endif +}; // g_EngineFuncs_Post_Table + + +static NEW_DLL_FUNCTIONS g_NewFuncs_Table = +{ +#ifdef FN_OnFreeEntPrivateData + FN_OnFreeEntPrivateData, +#else + NULL, +#endif +#ifdef FN_GameShutdown + FN_GameShutdown, +#else + NULL, +#endif +#ifdef FN_ShouldCollide + ShouldCollide, +#else + NULL, +#endif +}; + + +static NEW_DLL_FUNCTIONS g_NewFuncs_Post_Table = +{ +#ifdef FN_OnFreeEntPrivateData_Post + FN_OnFreeEntPrivateData_Post, +#else + NULL, +#endif +#ifdef FN_GameShutdown_Post + FN_GameShutdown_Post, +#else + NULL, +#endif +#ifdef FN_ShouldCollide_Post + ShouldCollide_Post, +#else + NULL, +#endif +}; + +// Global variables from metamod. These variable names are referenced by +// various macros. +meta_globals_t *gpMetaGlobals; // metamod globals +gamedll_funcs_t *gpGamedllFuncs; // gameDLL function tables +mutil_funcs_t *gpMetaUtilFuncs; // metamod utility functions + + +plugin_info_t Plugin_info = { + META_INTERFACE_VERSION, + MODULE_NAME, + MODULE_VERSION, + MODULE_DATE, + MODULE_AUTHOR, + MODULE_URL, + MODULE_LOGTAG, + PT_ANYTIME, + PT_ANYTIME +}; + +/* +C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetEntityAPI; version=%d", interfaceVersion); + if(!pFunctionTable) { + LOG_ERROR(PLID, "GetEntityAPI called with null pFunctionTable"); + return(FALSE); + } + else if(interfaceVersion != INTERFACE_VERSION) { + LOG_ERROR(PLID, "GetEntityAPI version mismatch; requested=%d ours=%d", interfaceVersion, INTERFACE_VERSION); + return(FALSE); + } + memcpy(pFunctionTable, &g_EntityAPI_Table, sizeof( DLL_FUNCTIONS ) ); + + return (TRUE); +} + +C_DLLEXPORT int GetEntityAPI_Post(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetEntityAPI_Post; version=%d", interfaceVersion); + if(!pFunctionTable) { + LOG_ERROR(PLID, "GetEntityAPI_Post called with null pFunctionTable"); + return(FALSE); + } + else if(interfaceVersion != INTERFACE_VERSION) { + LOG_ERROR(PLID, "GetEntityAPI_Post version mismatch; requested=%d ours=%d", interfaceVersion, INTERFACE_VERSION); + return(FALSE); + } + memcpy(pFunctionTable, &g_EntityAPI_Post_Table, sizeof( DLL_FUNCTIONS ) ); + + return(TRUE); +} +*/ + +C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetEntityAPI2; version=%d", *interfaceVersion); + if(!pFunctionTable) { + LOG_ERROR(PLID, "GetEntityAPI2 called with null pFunctionTable"); + return(FALSE); + } + else if(*interfaceVersion != INTERFACE_VERSION) { + LOG_ERROR(PLID, + "GetEntityAPI2 version mismatch; requested=%d ours=%d", + *interfaceVersion, INTERFACE_VERSION); + //! Tell engine what version we had, so it can figure out who is + //! out of date. + *interfaceVersion = INTERFACE_VERSION; + return(FALSE); + } + memcpy(pFunctionTable, &g_EntityAPI_Table, sizeof(DLL_FUNCTIONS)); + g_pFunctionTable=pFunctionTable; + return(TRUE); +} + +C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetEntityAPI2_Post; version=%d", *interfaceVersion); + if(!pFunctionTable) { + LOG_ERROR(PLID, "GetEntityAPI2_Post called with null pFunctionTable"); + return(FALSE); + } + else if(*interfaceVersion != INTERFACE_VERSION) { + LOG_ERROR(PLID, "GetEntityAPI2_Post version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION); + //! Tell engine what version we had, so it can figure out who is out of date. + *interfaceVersion = INTERFACE_VERSION; + return(FALSE); + } + memcpy( pFunctionTable, &g_EntityAPI_Post_Table, sizeof( DLL_FUNCTIONS ) ); + g_pFunctionTable_Post=pFunctionTable; + return(TRUE); +} + +C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetEngineFunctions; version=%d", + *interfaceVersion); + if(!pengfuncsFromEngine) { + LOG_ERROR(PLID, + "GetEngineFunctions called with null pengfuncsFromEngine"); + return(FALSE); + } + else if(*interfaceVersion != ENGINE_INTERFACE_VERSION) { + LOG_ERROR(PLID, + "GetEngineFunctions version mismatch; requested=%d ours=%d", + *interfaceVersion, ENGINE_INTERFACE_VERSION); + // Tell metamod what version we had, so it can figure out who is + // out of date. + *interfaceVersion = ENGINE_INTERFACE_VERSION; + return(FALSE); + } + memcpy(pengfuncsFromEngine, &g_EngineFuncs_Table, sizeof(enginefuncs_t)); + g_pengfuncsTable=pengfuncsFromEngine; + return TRUE; +} + +C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetEngineFunctions_Post; version=%d", *interfaceVersion); + if(!pengfuncsFromEngine) { + LOG_ERROR(PLID, "GetEngineFunctions_Post called with null pengfuncsFromEngine"); + return(FALSE); + } + else if(*interfaceVersion != ENGINE_INTERFACE_VERSION) { + LOG_ERROR(PLID, "GetEngineFunctions_Post version mismatch; requested=%d ours=%d", *interfaceVersion, ENGINE_INTERFACE_VERSION); + // Tell metamod what version we had, so it can figure out who is out of date. + *interfaceVersion = ENGINE_INTERFACE_VERSION; + return(FALSE); + } + memcpy(pengfuncsFromEngine, &g_EngineFuncs_Post_Table, sizeof(enginefuncs_t)); + g_pengfuncsTable_Post=pengfuncsFromEngine; + return TRUE; + +} + +C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, + int *interfaceVersion) +{ + LOG_DEVELOPER(PLID, "called: GetNewDLLFunctions; version=%d", + *interfaceVersion); + if(!pNewFunctionTable) { + LOG_ERROR(PLID, + "GetNewDLLFunctions called with null pNewFunctionTable"); + return(FALSE); + } + else if(*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) { + LOG_ERROR(PLID, + "GetNewDLLFunctions version mismatch; requested=%d ours=%d", + *interfaceVersion, NEW_DLL_FUNCTIONS_VERSION); + //! Tell engine what version we had, so it can figure out who is + //! out of date. + *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; + return(FALSE); + } + memcpy(pNewFunctionTable, &g_NewFuncs_Table, sizeof(NEW_DLL_FUNCTIONS)); + g_pNewFunctionsTable=pNewFunctionTable; + return TRUE; +} + +C_DLLEXPORT int GetNewDLLFunctions_Post( NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion ) +{ + LOG_DEVELOPER(PLID, "called: GetNewDLLFunctions_Post; version=%d", *interfaceVersion); + if(!pNewFunctionTable) { + LOG_ERROR(PLID, "GetNewDLLFunctions_Post called with null pNewFunctionTable"); + return(FALSE); + } + else if(*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) { + LOG_ERROR(PLID, "GetNewDLLFunctions_Post version mismatch; requested=%d ours=%d", *interfaceVersion, NEW_DLL_FUNCTIONS_VERSION); + //! Tell engine what version we had, so it can figure out who is out of date. + *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; + return(FALSE); + } + memcpy(pNewFunctionTable, &g_NewFuncs_Post_Table, sizeof(NEW_DLL_FUNCTIONS)); + g_pNewFunctionsTable_Post=pNewFunctionTable; + return TRUE; +} + + +static META_FUNCTIONS g_MetaFunctions_Table = +{ + NULL, + NULL, + GetEntityAPI2, + GetEntityAPI2_Post, + GetNewDLLFunctions, + GetNewDLLFunctions_Post, + GetEngineFunctions, + GetEngineFunctions_Post +}; + +C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs) +{ + if ((int) CVAR_GET_FLOAT("developer") != 0) + UTIL_LogPrintf("[%s] dev: called: Meta_Query; version=%s, ours=%s\n", + Plugin_info.logtag, ifvers, Plugin_info.ifvers); + + // Check for valid pMetaUtilFuncs before we continue. + if(!pMetaUtilFuncs) { + UTIL_LogPrintf("[%s] ERROR: Meta_Query called with null pMetaUtilFuncs\n", Plugin_info.logtag); + return(FALSE); + } + + gpMetaUtilFuncs = pMetaUtilFuncs; + + *pPlugInfo = &Plugin_info; + + // Check for interface version compatibility. + if(!FStrEq(ifvers, Plugin_info.ifvers)) { + int mmajor=0, mminor=0, pmajor=0, pminor=0; + LOG_MESSAGE(PLID, "WARNING: meta-interface version mismatch; requested=%s ours=%s", + Plugin_info.logtag, ifvers); + // If plugin has later interface version, it's incompatible (update + // metamod). + sscanf(ifvers, "%d:%d", &mmajor, &mminor); + sscanf(META_INTERFACE_VERSION, "%d:%d", &pmajor, &pminor); + if(pmajor > mmajor || (pmajor==mmajor && pminor > mminor)) { + LOG_ERROR(PLID, "metamod version is too old for this module; update metamod"); + return(FALSE); + } + // If plugin has older major interface version, it's incompatible + // (update plugin). + else if(pmajor < mmajor) { + LOG_ERROR(PLID, "metamod version is incompatible with this module; please find a newer version of this module"); + return(FALSE); + } + // Minor interface is older, but this is guaranteed to be backwards + // compatible, so we warn, but we still accept it. + else if(pmajor==mmajor && pminor < mminor) + LOG_MESSAGE(PLID, "WARNING: metamod version is newer than expected; consider finding a newer version of this module"); + else + LOG_ERROR(PLID, "unexpected version comparison; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", ifvers, mmajor, mminor, META_INTERFACE_VERSION, pmajor, pminor); + } + +#ifdef FN_META_QUERY + return FN_META_QUERY(); +#endif // FN_META_QUERY + + return 1; +} + + +C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs) +{ + if(now > Plugin_info.loadable) { + LOG_ERROR(PLID, "Can't load module right now"); + return(FALSE); + } + if(!pMGlobals) { + LOG_ERROR(PLID, "Meta_Attach called with null pMGlobals"); + return(FALSE); + } + gpMetaGlobals=pMGlobals; + if(!pFunctionTable) { + LOG_ERROR(PLID, "Meta_Attach called with null pFunctionTable"); + return(FALSE); + } + + memcpy(pFunctionTable, &g_MetaFunctions_Table, sizeof(META_FUNCTIONS)); + gpGamedllFuncs=pGamedllFuncs; + + // Let's go. + +#ifdef FN_META_ATTACH + FN_META_ATTACH(); +#endif // FN_META_ATTACH + + return TRUE; +} + +C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) +{ + if(now > Plugin_info.unloadable && reason != PNL_CMD_FORCED) { + LOG_ERROR(PLID, "Can't unload plugin right now"); + return(FALSE); + } + +#ifdef FN_META_DETACH + return FN_META_DETACH(); +#endif // FN_META_DETACH + return TRUE; +} + + + +#ifdef __linux__ +// linux prototype +C_DLLEXPORT void GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) { + +#else +#ifdef _MSC_VER +// MSVC: Simulate __stdcall calling convention +C_DLLEXPORT __declspec(naked) void GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +{ + __asm // Prolog + { + // Save ebp + push ebp + // Set stack frame pointer + mov ebp, esp + // Allocate space for local variables + // The MSVC compiler gives us the needed size in __LOCAL_SIZE. + sub esp, __LOCAL_SIZE + // Push registers + push ebx + push esi + push edi + } +#else // _MSC_VER +#ifdef __GNUC__ +// GCC can also work with this +C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) +{ +#else // __GNUC__ +// compiler not known +#error There is no support (yet) for your compiler. Please use MSVC or GCC compilers or contact the AMX Mod X dev team. +#endif // __GNUC__ +#endif // _MSC_VER +#endif // __linux__ + + // ** Function core <-- + memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t)); + gpGlobals = pGlobals; + // NOTE! Have to call logging function _after_ copying into g_engfuncs, so + // that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :) + UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag); + // --> ** Function core + +#ifdef _MSC_VER + // Epilog + if (sizeof(int*) == 8) + { // 64 bit + __asm + { + // Pop registers + pop edi + pop esi + pop ebx + // Restore stack frame pointer + mov esp, ebp + // Restore ebp + pop ebp + // 2 * sizeof(int*) = 16 on 64 bit + ret 16 + } + } + else + { // 32 bit + __asm + { + // Pop registers + pop edi + pop esi + pop ebx + // Restore stack frame pointer + mov esp, ebp + // Restore ebp + pop ebp + // 2 * sizeof(int*) = 8 on 32 bit + ret 8 + } + } +#endif // #ifdef _MSC_VER +} + +#endif // #ifdef USE_METAMOD + +/************* AMXX Stuff *************/ + +// *** Globals *** +// Module info +static amxx_module_info_s g_ModuleInfo = +{ + MODULE_NAME, + MODULE_AUTHOR, + MODULE_VERSION, +#ifdef MODULE_RELOAD_ON_MAPCHANGE + 1, +#else // MODULE_RELOAD_ON_MAPCHANGE + 0, +#endif // MODULE_RELOAD_ON_MAPCHANGE + MODULE_LOGTAG, + MODULE_LIBRARY, + MODULE_LIBCLASS +}; + +// Storage for the requested functions +PFN_ADD_NATIVES g_fn_AddNatives; +PFN_BUILD_PATHNAME g_fn_BuildPathname; +PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR; +PFN_GET_AMXADDR g_fn_GetAmxAddr; +PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole; +PFN_GET_MODNAME g_fn_GetModname; +PFN_GET_AMXSCRIPTNAME g_fn_GetAmxScriptName; +PFN_GET_AMXSCRIPT g_fn_GetAmxScript; +PFN_FIND_AMXSCRIPT_BYAMX g_fn_FindAmxScriptByAmx; +PFN_FIND_AMXSCRIPT_BYNAME g_fn_FindAmxScriptByName; +PFN_SET_AMXSTRING g_fn_SetAmxString; +PFN_GET_AMXSTRING g_fn_GetAmxString; +PFN_GET_AMXSTRINGLEN g_fn_GetAmxStringLen; +PFN_FORMAT_AMXSTRING g_fn_FormatAmxString; +PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory; +PFN_LOG g_fn_Log; +PFN_LOG_ERROR g_fn_LogErrorFunc; +PFN_RAISE_AMXERROR g_fn_RaiseAmxError; +PFN_REGISTER_FORWARD g_fn_RegisterForward; +PFN_EXECUTE_FORWARD g_fn_ExecuteForward; +PFN_PREPARE_CELLARRAY g_fn_PrepareCellArray; +PFN_PREPARE_CHARARRAY g_fn_PrepareCharArray; +PFN_PREPARE_CELLARRAY_A g_fn_PrepareCellArrayA; +PFN_PREPARE_CHARARRAY_A g_fn_PrepareCharArrayA; +PFN_IS_PLAYER_VALID g_fn_IsPlayerValid; +PFN_GET_PLAYER_NAME g_fn_GetPlayerName; +PFN_GET_PLAYER_IP g_fn_GetPlayerIP; +PFN_IS_PLAYER_INGAME g_fn_IsPlayerIngame; +PFN_IS_PLAYER_BOT g_fn_IsPlayerBot; +PFN_IS_PLAYER_AUTHORIZED g_fn_IsPlayerAuthorized; +PFN_GET_PLAYER_TIME g_fn_GetPlayerTime; +PFN_GET_PLAYER_PLAYTIME g_fn_GetPlayerPlayTime; +PFN_GET_PLAYER_CURWEAPON g_fn_GetPlayerCurweapon; +PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam; +PFN_GET_PLAYER_TEAMID g_fn_GetPlayerTeamID; +PFN_GET_PLAYER_DEATHS g_fn_GetPlayerDeaths; +PFN_GET_PLAYER_MENU g_fn_GetPlayerMenu; +PFN_GET_PLAYER_KEYS g_fn_GetPlayerKeys; +PFN_IS_PLAYER_ALIVE g_fn_IsPlayerAlive; +PFN_GET_PLAYER_FRAGS g_fn_GetPlayerFrags; +PFN_IS_PLAYER_CONNECTING g_fn_IsPlayerConnecting; +PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV; +PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor; +PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth; +#ifdef MEMORY_TEST +PFN_ALLOCATOR g_fn_Allocator; +PFN_REALLOCATOR g_fn_Reallocator; +PFN_DEALLOCATOR g_fn_Deallocator; +#endif +PFN_AMX_EXEC g_fn_AmxExec; +PFN_AMX_EXECV g_fn_AmxExecv; +PFN_AMX_ALLOT g_fn_AmxAllot; +PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic; +PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript; +PFN_UNLOAD_AMXSCRIPT g_fn_UnloadAmxScript; +PFN_REAL_TO_CELL g_fn_RealToCell; +PFN_CELL_TO_REAL g_fn_CellToReal; +PFN_REGISTER_SPFORWARD g_fn_RegisterSPForward; +PFN_REGISTER_SPFORWARD_BYNAME g_fn_RegisterSPForwardByName; +PFN_UNREGISTER_SPFORWARD g_fn_UnregisterSPForward; +PFN_MERGEDEFINITION_FILE g_fn_MergeDefinition_File; +PFN_AMX_FINDNATIVE g_fn_AmxFindNative; +PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags; +PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict; +PFN_FORMAT g_fn_Format; +PFN_REGISTERFUNCTION g_fn_RegisterFunction; +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; + +// *** Exports *** +C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo) +{ + // check parameters + if (!interfaceVersion || !moduleInfo) + return AMXX_PARAM; + + // check interface version + if (*interfaceVersion != AMXX_INTERFACE_VERSION) + { + // Tell amxx core our interface version + *interfaceVersion = AMXX_INTERFACE_VERSION; + return AMXX_IFVERS; + } + + // copy module info + memcpy(moduleInfo, &g_ModuleInfo, sizeof(amxx_module_info_s)); + +#ifdef FN_AMXX_QUERY + FN_AMXX_QUERY(); +#endif // FN_AMXX_QUERY + // Everything ok :) + return AMXX_OK; +} + +// request function +#define REQFUNC(name, fptr, type) if ((fptr = (type)reqFnptrFunc(name)) == 0) return AMXX_FUNC_NOT_PRESENT +// request optional function +#define REQFUNC_OPT(name, fptr, type) fptr = (type)reqFnptrFunc(name) + +C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc) +{ + // Check pointer + if (!reqFnptrFunc) + return AMXX_PARAM; + + g_fn_RequestFunction = reqFnptrFunc; + + // Req all known functions + // Misc + REQFUNC("BuildPathname", g_fn_BuildPathname, PFN_BUILD_PATHNAME); + REQFUNC("BuildPathnameR", g_fn_BuildPathnameR, PFN_BUILD_PATHNAME_R); + REQFUNC("PrintSrvConsole", g_fn_PrintSrvConsole, PFN_PRINT_SRVCONSOLE); + REQFUNC("GetModname", g_fn_GetModname, PFN_GET_MODNAME); + REQFUNC("Log", g_fn_Log, PFN_LOG); + REQFUNC("LogError", g_fn_LogErrorFunc, PFN_LOG_ERROR); + REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE); + REQFUNC("Format", g_fn_Format, PFN_FORMAT); + REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION); + + // Amx scripts + REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT); + REQFUNC("FindAmxScriptByAmx", g_fn_FindAmxScriptByAmx, PFN_FIND_AMXSCRIPT_BYAMX); + REQFUNC("FindAmxScriptByName", g_fn_FindAmxScriptByName, PFN_FIND_AMXSCRIPT_BYNAME); + REQFUNC("LoadAmxScript", g_fn_LoadAmxScript, PFN_LOAD_AMXSCRIPT); + REQFUNC("UnloadAmxScript", g_fn_UnloadAmxScript, PFN_UNLOAD_AMXSCRIPT); + REQFUNC("GetAmxScriptName", g_fn_GetAmxScriptName, PFN_GET_AMXSCRIPTNAME); + + // String / mem in amx scripts support + REQFUNC("SetAmxString", g_fn_SetAmxString, PFN_SET_AMXSTRING); + REQFUNC("GetAmxString", g_fn_GetAmxString, PFN_GET_AMXSTRING); + REQFUNC("GetAmxStringLen", g_fn_GetAmxStringLen, PFN_GET_AMXSTRINGLEN); + REQFUNC("FormatAmxString", g_fn_FormatAmxString, PFN_FORMAT_AMXSTRING); + REQFUNC("CopyAmxMemory", g_fn_CopyAmxMemory, PFN_COPY_AMXMEMORY); + REQFUNC("GetAmxAddr", g_fn_GetAmxAddr, PFN_GET_AMXADDR); + + REQFUNC("amx_Exec", g_fn_AmxExec, PFN_AMX_EXEC); + REQFUNC("amx_Execv", g_fn_AmxExecv, PFN_AMX_EXECV); + REQFUNC("amx_FindPublic", g_fn_AmxFindPublic, PFN_AMX_FINDPUBLIC); + REQFUNC("amx_Allot", g_fn_AmxAllot, PFN_AMX_ALLOT); + REQFUNC("amx_FindNative", g_fn_AmxFindNative, PFN_AMX_FINDNATIVE); + + // Natives / Forwards + REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_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); + REQFUNC("RegisterSPForwardByName", g_fn_RegisterSPForwardByName, PFN_REGISTER_SPFORWARD_BYNAME); + REQFUNC("UnregisterSPForward", g_fn_UnregisterSPForward, PFN_UNREGISTER_SPFORWARD); + REQFUNC("ExecuteForward", g_fn_ExecuteForward, PFN_EXECUTE_FORWARD); + REQFUNC("PrepareCellArray", g_fn_PrepareCellArray, PFN_PREPARE_CELLARRAY); + REQFUNC("PrepareCharArray", g_fn_PrepareCharArray, PFN_PREPARE_CHARARRAY); + REQFUNC("PrepareCellArrayA", g_fn_PrepareCellArrayA, PFN_PREPARE_CELLARRAY_A); + REQFUNC("PrepareCharArrayA", g_fn_PrepareCharArrayA, PFN_PREPARE_CHARARRAY_A); + // Player + REQFUNC("IsPlayerValid", g_fn_IsPlayerValid, PFN_IS_PLAYER_VALID); + REQFUNC("GetPlayerName", g_fn_GetPlayerName, PFN_GET_PLAYER_NAME); + REQFUNC("GetPlayerIP", g_fn_GetPlayerIP, PFN_GET_PLAYER_IP); + REQFUNC("IsPlayerInGame", g_fn_IsPlayerIngame, PFN_IS_PLAYER_INGAME); + REQFUNC("IsPlayerBot", g_fn_IsPlayerBot, PFN_IS_PLAYER_BOT); + REQFUNC("IsPlayerAuthorized", g_fn_IsPlayerAuthorized, PFN_IS_PLAYER_AUTHORIZED); + REQFUNC("GetPlayerTime", g_fn_GetPlayerTime, PFN_GET_PLAYER_TIME); + REQFUNC("GetPlayerPlayTime", g_fn_GetPlayerPlayTime, PFN_GET_PLAYER_PLAYTIME); + REQFUNC("GetPlayerCurweapon", g_fn_GetPlayerCurweapon, PFN_GET_PLAYER_CURWEAPON); + REQFUNC("GetPlayerTeamID", g_fn_GetPlayerTeamID, PFN_GET_PLAYER_TEAMID); + REQFUNC("GetPlayerTeam",g_fn_GetPlayerTeam, PFN_GET_PLAYER_TEAM); + REQFUNC("GetPlayerDeaths", g_fn_GetPlayerDeaths, PFN_GET_PLAYER_DEATHS); + REQFUNC("GetPlayerMenu", g_fn_GetPlayerMenu, PFN_GET_PLAYER_MENU); + REQFUNC("GetPlayerKeys", g_fn_GetPlayerKeys, PFN_GET_PLAYER_KEYS); + REQFUNC("IsPlayerAlive", g_fn_IsPlayerAlive, PFN_IS_PLAYER_ALIVE); + REQFUNC("GetPlayerFrags", g_fn_GetPlayerFrags, PFN_GET_PLAYER_FRAGS); + REQFUNC("IsPlayerConnecting", g_fn_IsPlayerConnecting, PFN_IS_PLAYER_CONNECTING); + REQFUNC("IsPlayerHLTV", g_fn_IsPlayerHLTV, PFN_IS_PLAYER_HLTV); + REQFUNC("GetPlayerArmor", g_fn_GetPlayerArmor, PFN_GET_PLAYER_ARMOR); + REQFUNC("GetPlayerHealth", g_fn_GetPlayerHealth, PFN_GET_PLAYER_HEALTH); + REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS); + REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT); + 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); + + 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); + +#ifdef MEMORY_TEST + // Memory + REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR); + REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR); + REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR); +#endif + + REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL); + REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL); + +#ifdef FN_AMXX_ATTACH + FN_AMXX_ATTACH(); +#endif // FN_AMXX_ATACH + + return AMXX_OK; +} + +C_DLLEXPORT int AMXX_Detach() +{ +#ifdef FN_AMXX_DETACH + FN_AMXX_DETACH(); +#endif // FN_AMXX_DETACH + + return AMXX_OK; +} + +C_DLLEXPORT int AMXX_PluginsLoaded() +{ +#ifdef FN_AMXX_PLUGINSLOADED + FN_AMXX_PLUGINSLOADED(); +#endif // FN_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, ...) +{ + char msg[3072]; + va_list arglst; + va_start(arglst, fmt); + vsnprintf(msg, sizeof(msg) - 1, fmt, arglst); + va_end(arglst); + + g_fn_Log("[%s] %s", MODULE_LOGTAG, msg); +} + +void MF_LogError(AMX *amx, int err, const char *fmt, ...) +{ + char msg[3072]; + va_list arglst; + va_start(arglst, fmt); + vsnprintf(msg, sizeof(msg) - 1, fmt, arglst); + va_end(arglst); + + g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg); +} + + +#ifdef _DEBUG +// validate macros +// Makes sure compiler reports errors when macros are invalid +void ValidateMacros_DontCallThis_Smiley() +{ + MF_BuildPathname("str", "str", 0); + MF_BuildPathnameR(NULL, 0, "%d", 0); + MF_FormatAmxString(NULL, 0, 0, NULL); + MF_GetAmxAddr(NULL, 0); + MF_PrintSrvConsole("str", "str", 0); + MF_GetModname(); + MF_GetScriptName(0); + MF_GetScriptAmx(0); + MF_FindScriptByAmx(NULL); + MF_FindScriptByName("str"); + MF_SetAmxString(NULL, 0, "str", 0); + MF_GetAmxString(NULL, 0, 0, 0); + MF_GetAmxStringLen(NULL); + MF_CopyAmxMemory(NULL, NULL, 0); + MF_Log("str", "str", 0); + MF_LogError(NULL, 0, NULL); + MF_RaiseAmxError(NULL, 0); + MF_RegisterForward("str", (ForwardExecType)0, 0, 0, 0); + MF_ExecuteForward(0, 0, 0); + MF_PrepareCellArray(NULL, 0); + MF_PrepareCharArray(NULL, 0); + MF_PrepareCellArrayA(NULL, 0, true); + MF_PrepareCharArrayA(NULL, 0, true); + MF_IsPlayerValid(0); + MF_GetPlayerName(0); + MF_GetPlayerIP(0); + MF_IsPlayerIngame(0); + MF_IsPlayerBot(0); + MF_IsPlayerAuthorized(0); + MF_GetPlayerTime(0); + MF_GetPlayerPlayTime(0); + MF_GetPlayerCurweapon(0); + MF_GetPlayerTeamID(0); + MF_GetPlayerTeam(0); + MF_GetPlayerDeaths(0); + MF_GetPlayerMenu(0); + MF_GetPlayerKeys(0); + MF_IsPlayerAlive(0); + MF_GetPlayerFrags(0); + MF_IsPlayerConnecting(0); + MF_IsPlayerHLTV(0); + MF_GetPlayerArmor(0); + MF_GetPlayerHealth(0); + MF_AmxExec(0, 0, 0); + MF_AmxExecv(0, 0, 0, 0, 0); + MF_AmxFindPublic(0, 0, 0); + MF_AmxAllot(0, 0, 0, 0); + MF_LoadAmxScript(0, 0, 0, 0, 0); + MF_UnloadAmxScript(0, 0); + MF_RegisterSPForward(0, 0, 0, 0, 0, 0); + MF_RegisterSPForwardByName(0, 0, 0, 0, 0, 0); + MF_UnregisterSPForward(0); + MF_GetPlayerFrags(0); + MF_GetPlayerEdict(0); + MF_Format("", 4, "str"); + MF_RegisterFunction(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, ""); +} +#endif + +#ifdef MEMORY_TEST + +/************* MEMORY *************/ +// undef all defined macros +#undef new +#undef delete +#undef malloc +#undef calloc +#undef realloc +#undef free + +const unsigned int m_alloc_unknown = 0; +const unsigned int m_alloc_new = 1; +const unsigned int m_alloc_new_array = 2; +const unsigned int m_alloc_malloc = 3; +const unsigned int m_alloc_calloc = 4; +const unsigned int m_alloc_realloc = 5; +const unsigned int m_alloc_delete = 6; +const unsigned int m_alloc_delete_array = 7; +const unsigned int m_alloc_free = 8; + +const char *g_Mem_CurrentFilename = "??"; +int g_Mem_CurrentLine = 0; +const char *g_Mem_CurrentFunc = "??"; + +const char *Mem_MakeSourceFile(const char *sourceFile) +{ + static char buffer[512]; + static size_t pos = 0; + if (!pos) + { + // init + buffer[0] = '['; + strcpy(buffer + 1, MODULE_NAME); + pos = strlen(MODULE_NAME) + 1; + buffer[pos++] = ']'; + } + + // convert from absolute path to [modulename]filename + const char *ptr = strrchr(sourceFile, '\\'); + if (ptr) + ptr++; + else + { + ptr = strrchr(sourceFile, '/'); + if (ptr) + ptr++; + else + ptr = sourceFile; + } + strcpy(buffer + pos, ptr); + return buffer; +} + +void Mem_SetOwner(const char *filename, int line, const char *function) +{ + g_Mem_CurrentFilename = filename; + g_Mem_CurrentLine = line; + g_Mem_CurrentFunc = function; +} + +void Mem_ResetGlobals() +{ + Mem_SetOwner("??", 0, "??"); +} + +// raw (re/de)allocators +void * Mem_Allocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc, + const unsigned int allocationType, const size_t reportedSize) +{ + if (g_fn_Allocator) + return g_fn_Allocator(Mem_MakeSourceFile(sourceFile), sourceLine, sourceFunc, allocationType, reportedSize); + else + return malloc(reportedSize); +} + +void * Mem_Reallocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc, + const unsigned int reallocationType, const size_t reportedSize, void *reportedAddress) +{ + if (g_fn_Reallocator) + return g_fn_Reallocator(Mem_MakeSourceFile(sourceFile), sourceLine, sourceFunc, reallocationType, reportedSize, reportedAddress); + else + return realloc(reportedAddress, reportedSize); +} + +void Mem_Deallocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc, + const unsigned int deallocationType, void *reportedAddress) +{ + // If you you get user breakpoint here, something failed :) + // - invalid pointer + // - alloc type mismatch ( for example + // char *a = new char[5]; delete char; + // ) + // - The allocation unit is damaged (for example + // char *a = new char[5]; a[6] = 8; + // ) + // - break on dealloc flag set (somehow) + + if (g_fn_Deallocator) + g_fn_Deallocator(Mem_MakeSourceFile(sourceFile), sourceLine, sourceFunc, deallocationType, reportedAddress); + else + free(reportedAddress); +} + +// new and delete operators +void *operator new(size_t reportedSize) +{ + if (reportedSize == 0) + reportedSize = 1; + void *ptr = Mem_Allocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_new, reportedSize); + // :TODO: Handler support ? + if (ptr) + return ptr; + + // allocation failed + return NULL; +} + +void *operator new[](size_t reportedSize) +{ + if (reportedSize == 0) + reportedSize = 1; + void *ptr = Mem_Allocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_new_array, reportedSize); + // :TODO: Handler support ? + if (ptr) + return ptr; + + // allocation failed + return NULL; +} + +// Microsoft memory tracking operators +void *operator new(size_t reportedSize, const char *sourceFile, int sourceLine) +{ + if (reportedSize == 0) + reportedSize = 1; + void *ptr = Mem_Allocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_new, reportedSize); + // :TODO: Handler support ? + if (ptr) + return ptr; + + // allocation failed + return NULL; +} +void *operator new[](size_t reportedSize, const char *sourceFile, int sourceLine) +{ + if (reportedSize == 0) + reportedSize = 1; + void *ptr = Mem_Allocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_new_array, reportedSize); + // :TODO: Handler support ? + if (ptr) + return ptr; + + // allocation failed + return NULL; +} + +void operator delete(void *reportedAddress) +{ + if (!reportedAddress) + return; + + Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete, reportedAddress); +} + +void operator delete[](void *reportedAddress) +{ + if (!reportedAddress) + return; + + Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress); +} + +#else + +#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32 +void * operator new(size_t size) { + return(calloc(1, size)); +} + +void * operator new[](size_t size) { + return(calloc(1, size)); +} + +void operator delete(void * ptr) { + if(ptr) + free(ptr); +} + +void operator delete[](void * ptr) { + if(ptr) + free(ptr); +} +#endif + +#endif //MEMORY_TEST + +/************* stuff from dlls/util.cpp *************/ +// must come here because cbase.h declares it's own operator new + +#ifdef USE_METAMOD + +// Selected portions of dlls/util.cpp from SDK 2.1. +// Functions copied from there as needed... +// And modified to avoid buffer overflows (argh). + +/*** +* +* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +/* + +===== util.cpp ======================================================== + + Utility code. Really not optional after all. + +*/ + +#include +#include "sdk_util.h" +#include + +#include // for strncpy(), etc + +#include "osdep.h" // win32 vsnprintf, etc + +char* UTIL_VarArgs( char *format, ... ) +{ + va_list argptr; + static char string[1024]; + + va_start (argptr, format); + vsnprintf (string, sizeof(string), format, argptr); + va_end (argptr); + + return string; +} + + +//========================================================= +// UTIL_LogPrintf - Prints a logged message to console. +// Preceded by LOG: ( timestamp ) < message > +//========================================================= +void UTIL_LogPrintf( char *fmt, ... ) +{ + va_list argptr; + static char string[1024]; + + va_start ( argptr, fmt ); + vsnprintf ( string, sizeof(string), fmt, argptr ); + va_end ( argptr ); + + // Print to server console + ALERT( at_logged, "%s", string ); +} + + +void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, + const char *pMessage) +{ + if ( !pEntity ) + return; + + MESSAGE_BEGIN( MSG_ONE, SVC_TEMPENTITY, NULL, ENT(pEntity->pev) ); + WRITE_BYTE( TE_TEXTMESSAGE ); + WRITE_BYTE( textparms.channel & 0xFF ); + + WRITE_SHORT( FixedSigned16( textparms.x, 1<<13 ) ); + WRITE_SHORT( FixedSigned16( textparms.y, 1<<13 ) ); + WRITE_BYTE( textparms.effect ); + + WRITE_BYTE( textparms.r1 ); + WRITE_BYTE( textparms.g1 ); + WRITE_BYTE( textparms.b1 ); + WRITE_BYTE( textparms.a1 ); + + WRITE_BYTE( textparms.r2 ); + WRITE_BYTE( textparms.g2 ); + WRITE_BYTE( textparms.b2 ); + WRITE_BYTE( textparms.a2 ); + + WRITE_SHORT( FixedUnsigned16( textparms.fadeinTime, 1<<8 ) ); + WRITE_SHORT( FixedUnsigned16( textparms.fadeoutTime, 1<<8 ) ); + WRITE_SHORT( FixedUnsigned16( textparms.holdTime, 1<<8 ) ); + + if ( textparms.effect == 2 ) + WRITE_SHORT( FixedUnsigned16( textparms.fxTime, 1<<8 ) ); + + if ( strlen( pMessage ) < 512 ) + { + WRITE_STRING( pMessage ); + } + else + { + char tmp[512]; + strncpy( tmp, pMessage, 511 ); + tmp[511] = 0; + WRITE_STRING( tmp ); + } + MESSAGE_END(); +} + +short FixedSigned16( float value, float scale ) +{ + int output; + + output = (int) (value * scale); + + if ( output > 32767 ) + output = 32767; + + if ( output < -32768 ) + output = -32768; + + return (short)output; +} + +unsigned short FixedUnsigned16( float value, float scale ) +{ + int output; + + output = (int) (value * scale); + if ( output < 0 ) + output = 0; + if ( output > 0xFFFF ) + output = 0xFFFF; + + return (unsigned short)output; +} +#endif // USE_METAMOD diff --git a/dlls/sven/sven/amxxmodule.h b/dlls/sven/sven/amxxmodule.h new file mode 100644 index 00000000..33e1d9c0 --- /dev/null +++ b/dlls/sven/sven/amxxmodule.h @@ -0,0 +1,2454 @@ +/* + * AMX Mod X Module Interface Functions + * This file may be freely used +*/ + +// prevent double include +#ifndef __AMXXMODULE_H__ +#define __AMXXMODULE_H__ + +// config +#include "moduleconfig.h" + +// metamod include files +#ifdef USE_METAMOD +#include +#include +#include "osdep.h" +#endif // #ifdef USE_METAMOD + +// DLL Export +#undef DLLEXPORT +#ifndef __linux__ +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT __attribute__((visibility("default"))) +#define LINUX +#endif + +#undef C_DLLEXPORT +#define C_DLLEXPORT extern "C" DLLEXPORT + +// ***** AMXX stuff ***** + +// module interface version was 1 +// 2 - added logtag to struct (amxx1.1-rc1) +// 3 - added new tagAMX structure (amxx1.5) +// 4 - added new 'library' setting for direct loading +#define AMXX_INTERFACE_VERSION 4 + +// amxx module info +struct amxx_module_info_s +{ + const char *name; + const char *author; + 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 +#define AMXX_OK 0 /* no error */ +#define AMXX_IFVERS 1 /* interface version */ +#define AMXX_PARAM 2 /* Invalid parameter */ +#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */ + +// *** Small stuff *** +// The next section is copied from the amx.h file +// Copyright (c) ITB CompuPhase, 1997-2005 + +#if defined HAVE_STDINT_H + #include +#else + #if defined __LCC__ || defined __DMC__ || defined LINUX + #if defined HAVE_INTTYPES_H + #include + #else + #include + #endif + #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L + /* The ISO C99 defines the int16_t and int_32t types. If the compiler got + * here, these types are probably undefined. + */ + #if defined __MACH__ + #include + typedef unsigned short int uint16_t; + typedef unsigned long int uint32_t; + #elif defined __FreeBSD__ + #include + #else + typedef short int int16_t; + typedef unsigned short int uint16_t; + #if defined SN_TARGET_PS2 + typedef int int32_t; + typedef unsigned int uint32_t; + #else + typedef long int int32_t; + typedef unsigned long int uint32_t; + #endif + #if defined __WIN32__ || defined _WIN32 || defined WIN32 + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #define HAVE_I64 + #elif defined __GNUC__ + typedef long long int64_t; + typedef unsigned long long uint64_t; + #define HAVE_I64 + #endif + #endif + #endif + #define HAVE_STDINT_H +#endif +#if defined _LP64 || defined WIN64 || defined _WIN64 + #if !defined __64BIT__ + #define __64BIT__ + #endif +#endif + +/* calling convention for native functions */ +#if !defined AMX_NATIVE_CALL + #define AMX_NATIVE_CALL +#endif +/* calling convention for all interface functions and callback functions */ +#if !defined AMXAPI + #if defined STDECL + #define AMXAPI __stdcall + #elif defined CDECL + #define AMXAPI __cdecl + #else + #define AMXAPI + #endif +#endif +#if !defined AMXEXPORT + #define AMXEXPORT +#endif + +#if !defined PAWN_CELL_SIZE + #define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */ +#endif +#if PAWN_CELL_SIZE==16 + typedef uint16_t ucell; + typedef int16_t cell; +#elif PAWN_CELL_SIZE==32 + typedef uint32_t ucell; + typedef int32_t cell; +#define REAL float +#elif PAWN_CELL_SIZE==64 + typedef uint64_t ucell; + typedef int64_t cell; +#define REAL double +#else + #error Unsupported cell size (PAWN_CELL_SIZE) +#endif + +#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1) +#define UNLIMITED (~1u >> 1) + +struct tagAMX; +typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params); +typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index, + cell *result, cell *params); +typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx); +#if !defined _FAR + #define _FAR +#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" */ + + #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 + + +/* Some compilers do not support the #pragma align, which should be fine. Some + * compilers give a warning on unknown #pragmas, which is not so fine... + */ +#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN + #define AMX_NO_ALIGN +#endif + +#if defined __GNUC__ + #define PACKED __attribute__((packed)) +#else + #define PACKED +#endif + +#if !defined AMX_NO_ALIGN + #if defined LINUX || defined __FreeBSD__ + #pragma pack(1) /* structures must be packed (byte-aligned) */ + #elif defined MACOS && defined __MWERKS__ + #pragma options align=mac68k + #else + #pragma pack(push) + #pragma pack(1) /* structures must be packed (byte-aligned) */ + #if defined __TURBOC__ + #pragma option -a- /* "pack" pragma for older Borland compilers */ + #endif + #endif +#endif + +typedef struct { + const char _FAR *name PACKED; + AMX_NATIVE func PACKED; +} AMX_NATIVE_INFO; + +#define AMX_USERNUM 4 + +/* The AMX structure is the internal structure for many functions. Not all + * fields are valid at all times; many fields are cached in local variables. + */ +typedef struct tagAMX { + unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */ + unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */ + AMX_CALLBACK callback PACKED; + AMX_DEBUG debug PACKED; /* debug callback */ + /* for external functions a few registers must be accessible from the outside */ + cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */ + cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */ + cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */ + cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */ + cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */ + cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ + int flags PACKED; /* current status, see amx_Flags() */ + /* user data */ + long usertags[AMX_USERNUM] PACKED; + //okay userdata[3] in AMX Mod X is for the CPlugin * pointer + //we're also gonna set userdata[2] to a special debug structure + void _FAR *userdata[AMX_USERNUM] PACKED; + /* native functions can raise an error */ + int error PACKED; + /* passing parameters requires a "count" field */ + int paramcount; + /* the sleep opcode needs to store the full AMX status */ + cell pri PACKED; + cell alt PACKED; + cell reset_stk PACKED; + cell reset_hea PACKED; + cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */ + /* support variables for the JIT */ + int reloc_size PACKED; /* required temporary buffer for relocations */ + long code_size PACKED; /* estimated memory footprint of the native code */ +} PACKED AMX; + +enum { + AMX_ERR_NONE, + /* reserve the first 15 error codes for exit codes of the abstract machine */ + AMX_ERR_EXIT, /* forced exit */ + AMX_ERR_ASSERT, /* assertion failed */ + AMX_ERR_STACKERR, /* stack/heap collision */ + AMX_ERR_BOUNDS, /* index out of bounds */ + AMX_ERR_MEMACCESS, /* invalid memory access */ + AMX_ERR_INVINSTR, /* invalid instruction */ + AMX_ERR_STACKLOW, /* stack underflow */ + AMX_ERR_HEAPLOW, /* heap underflow */ + AMX_ERR_CALLBACK, /* no callback, or invalid callback */ + AMX_ERR_NATIVE, /* native function failed */ + AMX_ERR_DIVIDE, /* divide by zero */ + AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */ + AMX_ERR_INVSTATE, /* invalid state for this access */ + + AMX_ERR_MEMORY = 16, /* out of memory */ + AMX_ERR_FORMAT, /* invalid file format */ + AMX_ERR_VERSION, /* file is for a newer version of the AMX */ + AMX_ERR_NOTFOUND, /* function not found */ + AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */ + AMX_ERR_DEBUG, /* debugger cannot run */ + AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */ + AMX_ERR_USERDATA, /* unable to set user data field (table full) */ + AMX_ERR_INIT_JIT, /* cannot initialize the JIT */ + AMX_ERR_PARAMS, /* parameter error */ + AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */ +}; + +#if !defined AMX_NO_ALIGN + #if defined __linux__ + #pragma pack() /* reset default packing */ + #else + #pragma pack(pop) /* reset previous packing */ + #endif +#endif + + +// ***** declare functions ***** + +#ifdef USE_METAMOD +void UTIL_LogPrintf( char *fmt, ... ); +void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage); +short FixedSigned16( float value, float scale ); +unsigned short FixedUnsigned16( float value, float scale ); + +#ifdef FN_META_QUERY +void FN_META_QUERY(void); +#endif // FN_META_QUERY + +#ifdef FN_META_ATTACH +void FN_META_ATTACH(void); +#endif // FN_META_ATTACH + +#ifdef FN_META_DETACH +void FN_META_DETACH(void); +#endif // FN_META_DETACH + + + + + +#ifdef FN_GameDLLInit +void FN_GameDLLInit(void); +#endif // FN_GameDLLInit + +#ifdef FN_DispatchSpawn +int FN_DispatchSpawn(edict_t *pent); +#endif // FN_DispatchSpawn + +#ifdef FN_DispatchThink +void FN_DispatchThink(edict_t *pent); +#endif // FN_DispatchThink + +#ifdef FN_DispatchUse +void FN_DispatchUse(edict_t *pentUser, edict_t *pentOther); +#endif // FN_DispatchUse + +#ifdef FN_DispatchTouch +void FN_DispatchTouch(edict_t *pentTouched, edict_t *pentOther); +#endif // FN_DispatchTouch + +#ifdef FN_DispatchBlocked +void FN_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther); +#endif // FN_DispatchBlocked + +#ifdef FN_DispatchKeyValue +void FN_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd); +#endif // FN_DispatchKeyValue + +#ifdef FN_DispatchSave +void FN_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData); +#endif // FN_DispatchSave + +#ifdef FN_DispatchRestore +int FN_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity); +#endif // FN_DispatchRestore + +#ifdef FN_DispatchObjectCollsionBox +void FN_DispatchObjectCollsionBox(edict_t *pent); +#endif // FN_DispatchObjectCollsionBox + +#ifdef FN_SaveWriteFields +void FN_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount); +#endif // FN_SaveWriteFields + +#ifdef FN_SaveReadFields +void FN_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount); +#endif // FN_SaveReadFields + +#ifdef FN_SaveGlobalState +void FN_SaveGlobalState(SAVERESTOREDATA *pSaveData); +#endif // FN_SaveGlobalState + +#ifdef FN_RestoreGlobalState +void FN_RestoreGlobalState(SAVERESTOREDATA *pSaveData); +#endif // FN_RestoreGlobalState + +#ifdef FN_ResetGlobalState +void FN_ResetGlobalState(void); +#endif // FN_ResetGlobalState + +#ifdef FN_ClientConnect +BOOL FN_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]); +#endif // FN_ClientConnect + +#ifdef FN_ClientDisconnect +void FN_ClientDisconnect(edict_t *pEntity); +#endif // FN_ClientDisconnect + +#ifdef FN_ClientKill +void FN_ClientKill(edict_t *pEntity); +#endif // FN_ClientKill + +#ifdef FN_ClientPutInServer +void FN_ClientPutInServer(edict_t *pEntity); +#endif // FN_ClientPutInServer + +#ifdef FN_ClientCommand +void FN_ClientCommand(edict_t *pEntity); +#endif // FN_ClientCommand + +#ifdef FN_ClientUserInfoChanged +void FN_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer); +#endif // FN_ClientUserInfoChanged + +#ifdef FN_ServerActivate +void FN_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); +#endif // FN_ServerActivate + +#ifdef FN_ServerDeactivate +void FN_ServerDeactivate(void); +#endif // FN_ServerDeactivate + +#ifdef FN_PlayerPreThink +void FN_PlayerPreThink(edict_t *pEntity); +#endif // FN_PlayerPreThink + +#ifdef FN_PlayerPostThink +void FN_PlayerPostThink(edict_t *pEntity); +#endif // FN_PlayerPostThink + +#ifdef FN_StartFrame +void FN_StartFrame(void); +#endif // FN_StartFrame + +#ifdef FN_ParmsNewLevel +void FN_ParmsNewLevel(void); +#endif // FN_ParmsNewLevel + +#ifdef FN_ParmsChangeLevel +void FN_ParmsChangeLevel(void); +#endif // FN_ParmsChangeLevel + +#ifdef FN_GetGameDescription +const char *FN_GetGameDescription(void); +#endif // FN_GetGameDescription + +#ifdef FN_PlayerCustomization +void FN_PlayerCustomization(edict_t *pEntity, customization_t *pCust); +#endif // FN_PlayerCustomization + +#ifdef FN_SpectatorConnect +void FN_SpectatorConnect(edict_t *pEntity); +#endif // FN_SpectatorConnect + +#ifdef FN_SpectatorDisconnect +void FN_SpectatorDisconnect(edict_t *pEntity); +#endif // FN_SpectatorDisconnect + +#ifdef FN_SpectatorThink +void FN_SpectatorThink(edict_t *pEntity); +#endif // FN_SpectatorThink + +#ifdef FN_Sys_Error +void FN_Sys_Error(const char *error_string); +#endif // FN_Sys_Error + +#ifdef FN_PM_Move +void FN_PM_Move(struct playermove_s *ppmove, int server); +#endif // FN_PM_Move + +#ifdef FN_PM_Init +void FN_PM_Init(struct playermove_s *ppmove); +#endif // FN_PM_Init + +#ifdef FN_PM_FindTextureType +char FN_PM_FindTextureType(char *name); +#endif // FN_PM_FindTextureType + +#ifdef FN_SetupVisibility +void FN_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas); +#endif // FN_SetupVisibility + +#ifdef FN_UpdateClientData +void FN_UpdateClientData(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd); +#endif // FN_UpdateClientData + +#ifdef FN_AddToFullPack +int FN_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet); +#endif // FN_AddToFullPack + +#ifdef FN_CreateBaseline +void FN_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs); +#endif // FN_CreateBaseline + +#ifdef FN_RegisterEncoders +void FN_RegisterEncoders(void); +#endif // FN_RegisterEncoders + +#ifdef FN_GetWeaponData +int FN_GetWeaponData(struct edict_s *player, struct weapon_data_s *info); +#endif // FN_GetWeaponData + +#ifdef FN_CmdStart +void FN_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed); +#endif // FN_CmdStart + +#ifdef FN_CmdEnd +void FN_CmdEnd(const edict_t *player); +#endif // FN_CmdEnd + +#ifdef FN_ConnectionlessPacket +int FN_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size); +#endif // FN_ConnectionlessPacket + +#ifdef FN_GetHullBounds +int FN_GetHullBounds(int hullnumber, float *mins, float *maxs); +#endif // FN_GetHullBounds + +#ifdef FN_CreateInstancedBaselines +void FN_CreateInstancedBaselines(void); +#endif // FN_CreateInstancedBaselines + +#ifdef FN_InconsistentFile +int FN_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message); +#endif // FN_InconsistentFile + +#ifdef FN_AllowLagCompensation +int FN_AllowLagCompensation(void); +#endif // FN_AllowLagCompensation + + + + +#ifdef FN_GameDLLInit_Post +void FN_GameDLLInit_Post(void); +#endif // FN_GameDLLInit_Post + +#ifdef FN_DispatchSpawn_Post +int FN_DispatchSpawn_Post(edict_t *pent); +#endif // FN_DispatchSpawn_Post + +#ifdef FN_DispatchThink_Post +void FN_DispatchThink_Post(edict_t *pent); +#endif // FN_DispatchThink_Post + +#ifdef FN_DispatchUse_Post +void FN_DispatchUse_Post(edict_t *pentUser, edict_t *pentOther); +#endif // FN_DispatchUse_Post + +#ifdef FN_DispatchTouch_Post +void FN_DispatchTouch_Post(edict_t *pentTouched, edict_t *pentOther); +#endif // FN_DispatchTouch_Post + +#ifdef FN_DispatchBlocked_Post +void FN_DispatchBlocked_Post(edict_t *pentBlocked, edict_t *pentOther); +#endif // FN_DispatchBlocked_Post + +#ifdef FN_DispatchKeyValue_Post +void FN_DispatchKeyValue_Post(edict_t *pentKeyvalue, KeyValueData *pkvd); +#endif // FN_DispatchKeyValue_Post + +#ifdef FN_DispatchSave_Post +void FN_DispatchSave_Post(edict_t *pent, SAVERESTOREDATA *pSaveData); +#endif // FN_DispatchSave_Post + +#ifdef FN_DispatchRestore_Post +int FN_DispatchRestore_Post(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity); +#endif // FN_DispatchRestore_Post + +#ifdef FN_DispatchObjectCollsionBox_Post +void FN_DispatchObjectCollsionBox_Post(edict_t *pent); +#endif // FN_DispatchObjectCollsionBox_Post + +#ifdef FN_SaveWriteFields_Post +void FN_SaveWriteFields_Post(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount); +#endif // FN_SaveWriteFields_Post + +#ifdef FN_SaveReadFields_Post +void FN_SaveReadFields_Post(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount); +#endif // FN_SaveReadFields_Post + +#ifdef FN_SaveGlobalState_Post +void FN_SaveGlobalState_Post(SAVERESTOREDATA *pSaveData); +#endif // FN_SaveGlobalState_Post + +#ifdef FN_RestoreGlobalState_Post +void FN_RestoreGlobalState_Post(SAVERESTOREDATA *pSaveData); +#endif // FN_RestoreGlobalState_Post + +#ifdef FN_ResetGlobalState_Post +void FN_ResetGlobalState_Post(void); +#endif // FN_ResetGlobalState_Post + +#ifdef FN_ClientConnect_Post +BOOL FN_ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]); +#endif // FN_ClientConnect_Post + +#ifdef FN_ClientDisconnect_Post +void FN_ClientDisconnect_Post(edict_t *pEntity); +#endif // FN_ClientDisconnect_Post + +#ifdef FN_ClientKill_Post +void FN_ClientKill_Post(edict_t *pEntity); +#endif // FN_ClientKill_Post + +#ifdef FN_ClientPutInServer_Post +void FN_ClientPutInServer_Post(edict_t *pEntity); +#endif // FN_ClientPutInServer_Post + +#ifdef FN_ClientCommand_Post +void FN_ClientCommand_Post(edict_t *pEntity); +#endif // FN_ClientCommand_Post + +#ifdef FN_ClientUserInfoChanged_Post +void FN_ClientUserInfoChanged_Post(edict_t *pEntity, char *infobuffer); +#endif // FN_ClientUserInfoChanged_Post + +#ifdef FN_ServerActivate_Post +void FN_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax); +#endif // FN_ServerActivate_Post + +#ifdef FN_ServerDeactivate_Post +void FN_ServerDeactivate_Post(void); +#endif // FN_ServerDeactivate_Post + +#ifdef FN_PlayerPreThink_Post +void FN_PlayerPreThink_Post(edict_t *pEntity); +#endif // FN_PlayerPreThink_Post + +#ifdef FN_PlayerPostThink_Post +void FN_PlayerPostThink_Post(edict_t *pEntity); +#endif // FN_PlayerPostThink_Post + +#ifdef FN_StartFrame_Post +void FN_StartFrame_Post(void); +#endif // FN_StartFrame_Post + +#ifdef FN_ParmsNewLevel_Post +void FN_ParmsNewLevel_Post(void); +#endif // FN_ParmsNewLevel_Post + +#ifdef FN_ParmsChangeLevel_Post +void FN_ParmsChangeLevel_Post(void); +#endif // FN_ParmsChangeLevel_Post + +#ifdef FN_GetGameDescription_Post +const char *FN_GetGameDescription_Post(void); +#endif // FN_GetGameDescription_Post + +#ifdef FN_PlayerCustomization_Post +void FN_PlayerCustomization_Post(edict_t *pEntity, customization_t *pCust); +#endif // FN_PlayerCustomization_Post + +#ifdef FN_SpectatorConnect_Post +void FN_SpectatorConnect_Post(edict_t *pEntity); +#endif // FN_SpectatorConnect_Post + +#ifdef FN_SpectatorDisconnect_Post +void FN_SpectatorDisconnect_Post(edict_t *pEntity); +#endif // FN_SpectatorDisconnect_Post + +#ifdef FN_SpectatorThink_Post +void FN_SpectatorThink_Post(edict_t *pEntity); +#endif // FN_SpectatorThink_Post + +#ifdef FN_Sys_Error_Post +void FN_Sys_Error_Post(const char *error_string); +#endif // FN_Sys_Error_Post + +#ifdef FN_PM_Move_Post +void FN_PM_Move_Post(struct playermove_s *ppmove, int server); +#endif // FN_PM_Move_Post + +#ifdef FN_PM_Init_Post +void FN_PM_Init_Post(struct playermove_s *ppmove); +#endif // FN_PM_Init_Post + +#ifdef FN_PM_FindTextureType_Post +char FN_PM_FindTextureType_Post(char *name); +#endif // FN_PM_FindTextureType_Post + +#ifdef FN_SetupVisibility_Post +void FN_SetupVisibility_Post(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas); +#endif // FN_SetupVisibility_Post + +#ifdef FN_UpdateClientData_Post +void FN_UpdateClientData_Post(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd); +#endif // FN_UpdateClientData_Post + +#ifdef FN_AddToFullPack_Post +int FN_AddToFullPack_Post(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet); +#endif // FN_AddToFullPack_Post + +#ifdef FN_CreateBaseline_Post +void FN_CreateBaseline_Post(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs); +#endif // FN_CreateBaseline_Post + +#ifdef FN_RegisterEncoders_Post +void FN_RegisterEncoders_Post(void); +#endif // FN_RegisterEncoders_Post + +#ifdef FN_GetWeaponData_Post +int FN_GetWeaponData_Post(struct edict_s *player, struct weapon_data_s *info); +#endif // FN_GetWeaponData_Post + +#ifdef FN_CmdStart_Post +void FN_CmdStart_Post(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed); +#endif // FN_CmdStart_Post + +#ifdef FN_CmdEnd_Post +void FN_CmdEnd_Post(const edict_t *player); +#endif // FN_CmdEnd_Post + +#ifdef FN_ConnectionlessPacket_Post +int FN_ConnectionlessPacket_Post(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size); +#endif // FN_ConnectionlessPacket_Post + +#ifdef FN_GetHullBounds_Post +int FN_GetHullBounds_Post(int hullnumber, float *mins, float *maxs); +#endif // FN_GetHullBounds_Post + +#ifdef FN_CreateInstancedBaselines_Post +void FN_CreateInstancedBaselines_Post(void); +#endif // FN_CreateInstancedBaselines_Post + +#ifdef FN_InconsistentFile_Post +int FN_InconsistentFile_Post(const edict_t *player, const char *filename, char *disconnect_message); +#endif // FN_InconsistentFile_Post + +#ifdef FN_AllowLagCompensation_Post +int FN_AllowLagCompensation_Post(void); +#endif // FN_AllowLagCompensation_Post + + + +#ifdef FN_PrecacheModel +int FN_PrecacheModel(char *s); +#endif // FN_PrecacheModel + +#ifdef FN_PrecacheSound +int FN_PrecacheSound(char *s); +#endif // FN_PrecacheSound + +#ifdef FN_SetModel +void FN_SetModel(edict_t *e, const char *m); +#endif // FN_SetModel + +#ifdef FN_ModelIndex +int FN_ModelIndex(const char *m); +#endif // FN_ModelIndex + +#ifdef FN_ModelFrames +int FN_ModelFrames(int modelIndex); +#endif // FN_ModelFrames + +#ifdef FN_SetSize +void FN_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax); +#endif // FN_SetSize + +#ifdef FN_ChangeLevel +void FN_ChangeLevel(char *s1, char *s2); +#endif // FN_ChangeLevel + +#ifdef FN_GetSpawnParms +void FN_GetSpawnParms(edict_t *ent); +#endif // FN_GetSpawnParms + +#ifdef FN_SaveSpawnParms +void FN_SaveSpawnParms(edict_t *ent); +#endif // FN_SaveSpawnParms + +#ifdef FN_VecToYaw +float FN_VecToYaw(const float *rgflVector); +#endif // FN_VecToYaw + +#ifdef FN_VecToAngles +void FN_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut); +#endif // FN_VecToAngles + +#ifdef FN_MoveToOrigin +void FN_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType); +#endif // FN_MoveToOrigin + +#ifdef FN_ChangeYaw +void FN_ChangeYaw(edict_t *ent); +#endif // FN_ChangeYaw + +#ifdef FN_ChangePitch +void FN_ChangePitch(edict_t *ent); +#endif // FN_ChangePitch + +#ifdef FN_FindEntityByString +edict_t *FN_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); +#endif // FN_FindEntityByString + +#ifdef FN_GetEntityIllum +int FN_GetEntityIllum(edict_t *pEnt); +#endif // FN_GetEntityIllum + +#ifdef FN_FindEntityInSphere +edict_t *FN_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad); +#endif // FN_FindEntityInSphere + +#ifdef FN_FindClientInPVS +edict_t *FN_FindClientInPVS(edict_t *pEdict); +#endif // FN_FindClientInPVS + +#ifdef FN_EntitiesInPVS +edict_t *FN_EntitiesInPVS(edict_t *pplayer); +#endif // FN_EntitiesInPVS + +#ifdef FN_MakeVectors +void FN_MakeVectors(const float *rgflVector); +#endif // FN_MakeVectors + +#ifdef FN_AngleVectors +void FN_AngleVectors(const float *rgflVector, float *forward, float *right, float *up); +#endif // FN_AngleVectors + +#ifdef FN_CreateEntity +edict_t *FN_CreateEntity(void); +#endif // FN_CreateEntity + +#ifdef FN_RemoveEntity +void FN_RemoveEntity(edict_t *e); +#endif // FN_RemoveEntity + +#ifdef FN_CreateNamedEntity +edict_t *FN_CreateNamedEntity(int className); +#endif // FN_CreateNamedEntity + +#ifdef FN_MakeStatic +void FN_MakeStatic(edict_t *ent); +#endif // FN_MakeStatic + +#ifdef FN_EntIsOnFloor +int FN_EntIsOnFloor(edict_t *ent); +#endif // FN_EntIsOnFloor + +#ifdef FN_DropToFloor +int FN_DropToFloor(edict_t *ent); +#endif // FN_DropToFloor + +#ifdef FN_WalkMove +int FN_WalkMove(edict_t *ent, float yaw, float dist, int iMode); +#endif // FN_WalkMove + +#ifdef FN_SetOrigin +void FN_SetOrigin(edict_t *e, const float *rgflOrigin); +#endif // FN_SetOrigin + +#ifdef FN_EmitSound +void FN_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); +#endif // FN_EmitSound + +#ifdef FN_EmitAmbientSound +void FN_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); +#endif // FN_EmitAmbientSound + +#ifdef FN_TraceLine +void FN_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceLine + +#ifdef FN_TraceToss +void FN_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); +#endif // FN_TraceToss + +#ifdef FN_TraceMonsterHull +int FN_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceMonsterHull + +#ifdef FN_TraceHull +void FN_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceHull + +#ifdef FN_TraceModel +void FN_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); +#endif // FN_TraceModel + +#ifdef FN_TraceTexture +const char *FN_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2 ); +#endif // FN_TraceTexture + +#ifdef FN_TraceSphere +void FN_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceSphere + +#ifdef FN_GetAimVector +void FN_GetAimVector(edict_t *ent, float speed, float *rgflReturn); +#endif // FN_GetAimVector + +#ifdef FN_ServerCommand +void FN_ServerCommand(char *str); +#endif // FN_ServerCommand + +#ifdef FN_ServerExecute +void FN_ServerExecute(void); +#endif // FN_ServerExecute + +#ifdef FN_engClientCommand +void FN_engClientCommand(edict_t *pEdict, char *szFmt, ...); +#endif // FN_engClientCommand + +#ifdef FN_ParticleEffect +void FN_ParticleEffect(const float *org, const float *dir, float color, float count); +#endif // FN_ParticleEffect + +#ifdef FN_LightStyle +void FN_LightStyle(int style, char *val); +#endif // FN_LightStyle + +#ifdef FN_DecalIndex +int FN_DecalIndex(const char *name); +#endif // FN_DecalIndex + +#ifdef FN_PointContents +int FN_PointContents(const float *rgflVector); +#endif // FN_PointContents + +#ifdef FN_MessageBegin +void FN_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +#endif // FN_MessageBegin + +#ifdef FN_MessageEnd +void FN_MessageEnd(void); +#endif // FN_MessageEnd + +#ifdef FN_WriteByte +void FN_WriteByte(int iValue); +#endif // FN_WriteByte + +#ifdef FN_WriteChar +void FN_WriteChar(int iValue); +#endif // FN_WriteChar + +#ifdef FN_WriteShort +void FN_WriteShort(int iValue); +#endif // FN_WriteShort + +#ifdef FN_WriteLong +void FN_WriteLong(int iValue); +#endif // FN_WriteLong + +#ifdef FN_WriteAngle +void FN_WriteAngle(float flValue); +#endif // FN_WriteAngle + +#ifdef FN_WriteCoord +void FN_WriteCoord(float flValue); +#endif // FN_WriteCoord + +#ifdef FN_WriteString +void FN_WriteString(const char *sz); +#endif // FN_WriteString + +#ifdef FN_WriteEntity +void FN_WriteEntity(int iValue); +#endif // FN_WriteEntity + +#ifdef FN_CVarRegister +void FN_CVarRegister(cvar_t *pCvar); +#endif // FN_CVarRegister + +#ifdef FN_CVarGetFloat +float FN_CVarGetFloat(const char *szVarName); +#endif // FN_CVarGetFloat + +#ifdef FN_CVarGetString +const char *FN_CVarGetString(const char *szVarName); +#endif // FN_CVarGetString + +#ifdef FN_CVarSetFloat +void FN_CVarSetFloat(const char *szVarName, float flValue); +#endif // FN_CVarSetFloat + +#ifdef FN_CVarSetString +void FN_CVarSetString(const char *szVarName, const char *szValue); +#endif // FN_CVarSetString + +#ifdef FN_AlertMessage +void FN_AlertMessage(ALERT_TYPE atype, char *szFmt, ...); +#endif // FN_AlertMessage + +#ifdef FN_EngineFprintf +void FN_EngineFprintf(FILE *pfile, char *szFmt, ...); +#endif // FN_EngineFprintf + +#ifdef FN_PvAllocEntPrivateData +void *FN_PvAllocEntPrivateData(edict_t *pEdict, int32 cb); +#endif // FN_PvAllocEntPrivateData + +#ifdef FN_PvEntPrivateData +void *FN_PvEntPrivateData(edict_t *pEdict); +#endif // FN_PvEntPrivateData + +#ifdef FN_FreeEntPrivateData +void FN_FreeEntPrivateData(edict_t *pEdict); +#endif // FN_FreeEntPrivateData + +#ifdef FN_SzFromIndex +const char *FN_SzFromIndex(int iString); +#endif // FN_SzFromIndex + +#ifdef FN_AllocString +int FN_AllocString(const char *szValue); +#endif // FN_AllocString + +#ifdef FN_GetVarsOfEnt +struct entvars_s *FN_GetVarsOfEnt(edict_t *pEdict); +#endif // FN_GetVarsOfEnt + +#ifdef FN_PEntityOfEntOffset +edict_t *FN_PEntityOfEntOffset(int iEntOffset); +#endif // FN_PEntityOfEntOffset + +#ifdef FN_EntOffsetOfPEntity +int FN_EntOffsetOfPEntity(const edict_t *pEdict); +#endif // FN_EntOffsetOfPEntity + +#ifdef FN_IndexOfEdict +int FN_IndexOfEdict(const edict_t *pEdict); +#endif // FN_IndexOfEdict + +#ifdef FN_PEntityOfEntIndex +edict_t *FN_PEntityOfEntIndex(int iEntIndex); +#endif // FN_PEntityOfEntIndex + +#ifdef FN_FindEntityByVars +edict_t *FN_FindEntityByVars(struct entvars_s *pvars); +#endif // FN_FindEntityByVars + +#ifdef FN_GetModelPtr +void *FN_GetModelPtr(edict_t *pEdict); +#endif // FN_GetModelPtr + +#ifdef FN_RegUserMsg +int FN_RegUserMsg(const char *pszName, int iSize); +#endif // FN_RegUserMsg + +#ifdef FN_AnimationAutomove +void FN_AnimationAutomove(const edict_t *pEdict, float flTime); +#endif // FN_AnimationAutomove + +#ifdef FN_GetBonePosition +void FN_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles); +#endif // FN_GetBonePosition + +#ifdef FN_FunctionFromName +unsigned long FN_FunctionFromName(const char *pName); +#endif // FN_FunctionFromName + +#ifdef FN_NameForFunction +const char *FN_NameForFunction(unsigned long function); +#endif // FN_NameForFunction + +#ifdef FN_ClientPrintf +void FN_ClientPrintf(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg); +#endif // FN_ClientPrintf + +#ifdef FN_ServerPrint +void FN_ServerPrint(const char *szMsg); +#endif // FN_ServerPrint + +#ifdef FN_Cmd_Args +const char *FN_Cmd_Args(void); +#endif // FN_Cmd_Args + +#ifdef FN_Cmd_Argv +const char *FN_Cmd_Argv(int argc); +#endif // FN_Cmd_Argv + +#ifdef FN_Cmd_Argc +int FN_Cmd_Argc(void); +#endif // FN_Cmd_Argc + +#ifdef FN_GetAttachment +void FN_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); +#endif // FN_GetAttachment + +#ifdef FN_CRC32_Init +void FN_CRC32_Init(CRC32_t *pulCRC); +#endif // FN_CRC32_Init + +#ifdef FN_CRC32_ProcessBuffer +void FN_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len); +#endif // FN_CRC32_ProcessBuffer + +#ifdef FN_CRC32_ProcessByte +void FN_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch); +#endif // FN_CRC32_ProcessByte + +#ifdef FN_CRC32_Final +CRC32_t FN_CRC32_Final(CRC32_t pulCRC); +#endif // FN_CRC32_Final + +#ifdef FN_RandomLong +long FN_RandomLong(long lLow, long lHigh); +#endif // FN_RandomLong + +#ifdef FN_RandomFloat +float FN_RandomFloat(float flLow, float flHigh); +#endif // FN_RandomFloat + +#ifdef FN_SetView +void FN_SetView(const edict_t *pClient, const edict_t *pViewent); +#endif // FN_SetView + +#ifdef FN_Time +float FN_Time(void); +#endif // FN_Time + +#ifdef FN_CrosshairAngle +void FN_CrosshairAngle(const edict_t *pClient, float pitch, float yaw); +#endif // FN_CrosshairAngle + +#ifdef FN_LoadFileForMe +byte *FN_LoadFileForMe(char *filename, int *pLength); +#endif // FN_LoadFileForMe + +#ifdef FN_FreeFile +void FN_FreeFile(void *buffer); +#endif // FN_FreeFile + +#ifdef FN_EndSection +void FN_EndSection(const char *pszSectionName); +#endif // FN_EndSection + +#ifdef FN_CompareFileTime +int FN_CompareFileTime(char *filename1, char *filename2, int *iCompare); +#endif // FN_CompareFileTime + +#ifdef FN_GetGameDir +void FN_GetGameDir(char *szGetGameDir); +#endif // FN_GetGameDir + +#ifdef FN_Cvar_RegisterVariable +void FN_Cvar_RegisterVariable(cvar_t *variable); +#endif // FN_Cvar_RegisterVariable + +#ifdef FN_FadeClientVolume +void FN_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); +#endif // FN_FadeClientVolume + +#ifdef FN_SetClientMaxspeed +void FN_SetClientMaxspeed(const edict_t *pEdict, float fNewMaxspeed); +#endif // FN_SetClientMaxspeed + +#ifdef FN_CreateFakeClient +edict_t *FN_CreateFakeClient(const char *netname); +#endif // FN_CreateFakeClient + +#ifdef FN_RunPlayerMove +void FN_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec); +#endif // FN_RunPlayerMove + +#ifdef FN_NumberOfEntities +int FN_NumberOfEntities(void); +#endif // FN_NumberOfEntities + +#ifdef FN_GetInfoKeyBuffer +char *FN_GetInfoKeyBuffer(edict_t *e); +#endif // FN_GetInfoKeyBuffer + +#ifdef FN_InfoKeyValue +char *FN_InfoKeyValue(char *infobuffer, char *key); +#endif // FN_InfoKeyValue + +#ifdef FN_SetKeyValue +void FN_SetKeyValue(char *infobuffer, char *key, char *value); +#endif // FN_SetKeyValue + +#ifdef FN_SetClientKeyValue +void FN_SetClientKeyValue(int clientIndex, char *infobuffer, char *key, char *value); +#endif // FN_SetClientKeyValue + +#ifdef FN_IsMapValid +int FN_IsMapValid(char *filename); +#endif // FN_IsMapValid + +#ifdef FN_StaticDecal +void FN_StaticDecal(const float *origin, int decalIndex, int entityIndex, int modelIndex); +#endif // FN_StaticDecal + +#ifdef FN_PrecacheGeneric +int FN_PrecacheGeneric(char *s); +#endif // FN_PrecacheGeneric + +#ifdef FN_GetPlayerUserId +int FN_GetPlayerUserId(edict_t *e ); +#endif // FN_GetPlayerUserId + +#ifdef FN_BuildSoundMsg +void FN_BuildSoundMsg(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +#endif // FN_BuildSoundMsg + +#ifdef FN_IsDedicatedServer +int FN_IsDedicatedServer(void); +#endif // FN_IsDedicatedServer + +#ifdef FN_CVarGetPointer +cvar_t *FN_CVarGetPointer(const char *szVarName); +#endif // FN_CVarGetPointer + +#ifdef FN_GetPlayerWONId +unsigned int FN_GetPlayerWONId(edict_t *e); +#endif // FN_GetPlayerWONId + +#ifdef FN_Info_RemoveKey +void FN_Info_RemoveKey( char *s, const char *key); +#endif // FN_Info_RemoveKey + +#ifdef FN_GetPhysicsKeyValue +const char *FN_GetPhysicsKeyValue(const edict_t *pClient, const char *key); +#endif // FN_GetPhysicsKeyValue + +#ifdef FN_SetPhysicsKeyValue +void FN_SetPhysicsKeyValue(const edict_t *pClient, const char *key, const char *value); +#endif // FN_SetPhysicsKeyValue + +#ifdef FN_GetPhysicsInfoString +const char *FN_GetPhysicsInfoString( const edict_t *pClient); +#endif // FN_GetPhysicsInfoString + +#ifdef FN_PrecacheEvent +unsigned short FN_PrecacheEvent(int type, const char *psz); +#endif // FN_PrecacheEvent + +#ifdef FN_PlaybackEvent +void FN_PlaybackEvent(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); +#endif // FN_PlaybackEvent + +#ifdef FN_SetFatPVS +unsigned char *FN_SetFatPVS(float *org); +#endif // FN_SetFatPVS + +#ifdef FN_SetFatPAS +unsigned char *FN_SetFatPAS(float *org); +#endif // FN_SetFatPAS + +#ifdef FN_CheckVisibility +int FN_CheckVisibility(const edict_t *entity, unsigned char *pset); +#endif // FN_CheckVisibility + +#ifdef FN_DeltaSetField +void FN_DeltaSetField(struct delta_s *pFields, const char *fieldname); +#endif // FN_DeltaSetField + +#ifdef FN_DeltaUnsetField +void FN_DeltaUnsetField(struct delta_s *pFields, const char *fieldname); +#endif // FN_DeltaUnsetField + +#ifdef FN_DeltaAddEncoder +void FN_DeltaAddEncoder(char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); +#endif // FN_DeltaAddEncoder + +#ifdef FN_GetCurrentPlayer +int FN_GetCurrentPlayer(void); +#endif // FN_GetCurrentPlayer + +#ifdef FN_CanSkipPlayer +int FN_CanSkipPlayer(const edict_t *player); +#endif // FN_CanSkipPlayer + +#ifdef FN_DeltaFindField +int FN_DeltaFindField(struct delta_s *pFields, const char *fieldname); +#endif // FN_DeltaFindField + +#ifdef FN_DeltaSetFieldByIndex +void FN_DeltaSetFieldByIndex(struct delta_s *pFields, int fieldNumber); +#endif // FN_DeltaSetFieldByIndex + +#ifdef FN_DeltaUnsetFieldByIndex +void FN_DeltaUnsetFieldByIndex(struct delta_s *pFields, int fieldNumber); +#endif // FN_DeltaUnsetFieldByIndex + +#ifdef FN_SetGroupMask +void FN_SetGroupMask(int mask, int op); +#endif // FN_SetGroupMask + +#ifdef FN_engCreateInstancedBaseline +int FN_engCreateInstancedBaseline(int classname, struct entity_state_s *baseline); +#endif // FN_engCreateInstancedBaseline + +#ifdef FN_Cvar_DirectSet +void FN_Cvar_DirectSet(struct cvar_s *var, char *value); +#endif // FN_Cvar_DirectSet + +#ifdef FN_ForceUnmodified +void FN_ForceUnmodified(FORCE_TYPE type, float *mins, float *maxs, const char *filename); +#endif // FN_ForceUnmodified + +#ifdef FN_GetPlayerStats +void FN_GetPlayerStats(const edict_t *pClient, int *ping, int *packet_loss); +#endif // FN_GetPlayerStats + +#ifdef FN_AddServerCommand +void FN_AddServerCommand(char *cmd_name, void (*function) (void)); +#endif // FN_AddServerCommand + +#ifdef FN_Voice_GetClientListening +qboolean FN_Voice_GetClientListening(int iReceiver, int iSender); +#endif // FN_Voice_GetClientListening + +#ifdef FN_Voice_SetClientListening +qboolean FN_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen); +#endif // FN_Voice_SetClientListening + +#ifdef FN_GetPlayerAuthId +const char *FN_GetPlayerAuthId(edict_t *e); +#endif // FN_GetPlayerAuthId + + + + + + +#ifdef FN_PrecacheModel_Post +int FN_PrecacheModel_Post(char *s); +#endif // FN_PrecacheModel_Post + +#ifdef FN_PrecacheSound_Post +int FN_PrecacheSound_Post(char *s); +#endif // FN_PrecacheSound_Post + +#ifdef FN_SetModel_Post +void FN_SetModel_Post(edict_t *e, const char *m); +#endif // FN_SetModel_Post + +#ifdef FN_ModelIndex_Post +int FN_ModelIndex_Post(const char *m); +#endif // FN_ModelIndex_Post + +#ifdef FN_ModelFrames_Post +int FN_ModelFrames_Post(int modelIndex); +#endif // FN_ModelFrames_Post + +#ifdef FN_SetSize_Post +void FN_SetSize_Post(edict_t *e, const float *rgflMin, const float *rgflMax); +#endif // FN_SetSize_Post + +#ifdef FN_ChangeLevel_Post +void FN_ChangeLevel_Post(char *s1, char *s2); +#endif // FN_ChangeLevel_Post + +#ifdef FN_GetSpawnParms_Post +void FN_GetSpawnParms_Post(edict_t *ent); +#endif // FN_GetSpawnParms_Post + +#ifdef FN_SaveSpawnParms_Post +void FN_SaveSpawnParms_Post(edict_t *ent); +#endif // FN_SaveSpawnParms_Post + +#ifdef FN_VecToYaw_Post +float FN_VecToYaw_Post(const float *rgflVector); +#endif // FN_VecToYaw_Post + +#ifdef FN_VecToAngles_Post +void FN_VecToAngles_Post(const float *rgflVectorIn, float *rgflVectorOut); +#endif // FN_VecToAngles_Post + +#ifdef FN_MoveToOrigin_Post +void FN_MoveToOrigin_Post(edict_t *ent, const float *pflGoal, float dist, int iMoveType); +#endif // FN_MoveToOrigin_Post + +#ifdef FN_ChangeYaw_Post +void FN_ChangeYaw_Post(edict_t *ent); +#endif // FN_ChangeYaw_Post + +#ifdef FN_ChangePitch_Post +void FN_ChangePitch_Post(edict_t *ent); +#endif // FN_ChangePitch_Post + +#ifdef FN_FindEntityByString_Post +edict_t *FN_FindEntityByString_Post(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); +#endif // FN_FindEntityByString_Post + +#ifdef FN_GetEntityIllum_Post +int FN_GetEntityIllum_Post(edict_t *pEnt); +#endif // FN_GetEntityIllum_Post + +#ifdef FN_FindEntityInSphere_Post +edict_t *FN_FindEntityInSphere_Post(edict_t *pEdictStartSearchAfter, const float *org, float rad); +#endif // FN_FindEntityInSphere_Post + +#ifdef FN_FindClientInPVS_Post +edict_t *FN_FindClientInPVS_Post(edict_t *pEdict); +#endif // FN_FindClientInPVS_Post + +#ifdef FN_EntitiesInPVS_Post +edict_t *FN_EntitiesInPVS_Post(edict_t *pplayer); +#endif // FN_EntitiesInPVS_Post + +#ifdef FN_MakeVectors_Post +void FN_MakeVectors_Post(const float *rgflVector); +#endif // FN_MakeVectors_Post + +#ifdef FN_AngleVectors_Post +void FN_AngleVectors_Post(const float *rgflVector, float *forward, float *right, float *up); +#endif // FN_AngleVectors_Post + +#ifdef FN_CreateEntity_Post +edict_t *FN_CreateEntity_Post(void); +#endif // FN_CreateEntity_Post + +#ifdef FN_RemoveEntity_Post +void FN_RemoveEntity_Post(edict_t *e); +#endif // FN_RemoveEntity_Post + +#ifdef FN_CreateNamedEntity_Post +edict_t *FN_CreateNamedEntity_Post(int className); +#endif // FN_CreateNamedEntity_Post + +#ifdef FN_MakeStatic_Post +void FN_MakeStatic_Post(edict_t *ent); +#endif // FN_MakeStatic_Post + +#ifdef FN_EntIsOnFloor_Post +int FN_EntIsOnFloor_Post(edict_t *ent); +#endif // FN_EntIsOnFloor_Post + +#ifdef FN_DropToFloor_Post +int FN_DropToFloor_Post(edict_t *ent); +#endif // FN_DropToFloor_Post + +#ifdef FN_WalkMove_Post +int FN_WalkMove_Post(edict_t *ent, float yaw, float dist, int iMode); +#endif // FN_WalkMove_Post + +#ifdef FN_SetOrigin_Post +void FN_SetOrigin_Post(edict_t *e, const float *rgflOrigin); +#endif // FN_SetOrigin_Post + +#ifdef FN_EmitSound_Post +void FN_EmitSound_Post(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); +#endif // FN_EmitSound_Post + +#ifdef FN_EmitAmbientSound_Post +void FN_EmitAmbientSound_Post(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); +#endif // FN_EmitAmbientSound_Post + +#ifdef FN_TraceLine_Post +void FN_TraceLine_Post(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceLine_Post + +#ifdef FN_TraceToss_Post +void FN_TraceToss_Post(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); +#endif // FN_TraceToss_Post + +#ifdef FN_TraceMonsterHull_Post +int FN_TraceMonsterHull_Post(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceMonsterHull_Post + +#ifdef FN_TraceHull_Post +void FN_TraceHull_Post(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceHull_Post + +#ifdef FN_TraceModel_Post +void FN_TraceModel_Post(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); +#endif // FN_TraceModel_Post + +#ifdef FN_TraceTexture_Post +const char *FN_TraceTexture_Post(edict_t *pTextureEntity, const float *v1, const float *v2 ); +#endif // FN_TraceTexture_Post + +#ifdef FN_TraceSphere_Post +void FN_TraceSphere_Post(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); +#endif // FN_TraceSphere_Post + +#ifdef FN_GetAimVector_Post +void FN_GetAimVector_Post(edict_t *ent, float speed, float *rgflReturn); +#endif // FN_GetAimVector_Post + +#ifdef FN_ServerCommand_Post +void FN_ServerCommand_Post(char *str); +#endif // FN_ServerCommand_Post + +#ifdef FN_ServerExecute_Post +void FN_ServerExecute_Post(void); +#endif // FN_ServerExecute_Post + +#ifdef FN_engClientCommand_Post +void FN_engClientCommand_Post(edict_t *pEdict, char *szFmt, ...); +#endif // FN_engClientCommand_Post + +#ifdef FN_ParticleEffect_Post +void FN_ParticleEffect_Post(const float *org, const float *dir, float color, float count); +#endif // FN_ParticleEffect_Post + +#ifdef FN_LightStyle_Post +void FN_LightStyle_Post(int style, char *val); +#endif // FN_LightStyle_Post + +#ifdef FN_DecalIndex_Post +int FN_DecalIndex_Post(const char *name); +#endif // FN_DecalIndex_Post + +#ifdef FN_PointContents_Post +int FN_PointContents_Post(const float *rgflVector); +#endif // FN_PointContents_Post + +#ifdef FN_MessageBegin_Post +void FN_MessageBegin_Post(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +#endif // FN_MessageBegin_Post + +#ifdef FN_MessageEnd_Post +void FN_MessageEnd_Post(void); +#endif // FN_MessageEnd_Post + +#ifdef FN_WriteByte_Post +void FN_WriteByte_Post(int iValue); +#endif // FN_WriteByte_Post + +#ifdef FN_WriteChar_Post +void FN_WriteChar_Post(int iValue); +#endif // FN_WriteChar_Post + +#ifdef FN_WriteShort_Post +void FN_WriteShort_Post(int iValue); +#endif // FN_WriteShort_Post + +#ifdef FN_WriteLong_Post +void FN_WriteLong_Post(int iValue); +#endif // FN_WriteLong_Post + +#ifdef FN_WriteAngle_Post +void FN_WriteAngle_Post(float flValue); +#endif // FN_WriteAngle_Post + +#ifdef FN_WriteCoord_Post +void FN_WriteCoord_Post(float flValue); +#endif // FN_WriteCoord_Post + +#ifdef FN_WriteString_Post +void FN_WriteString_Post(const char *sz); +#endif // FN_WriteString_Post + +#ifdef FN_WriteEntity_Post +void FN_WriteEntity_Post(int iValue); +#endif // FN_WriteEntity_Post + +#ifdef FN_CVarRegister_Post +void FN_CVarRegister_Post(cvar_t *pCvar); +#endif // FN_CVarRegister_Post + +#ifdef FN_CVarGetFloat_Post +float FN_CVarGetFloat_Post(const char *szVarName); +#endif // FN_CVarGetFloat_Post + +#ifdef FN_CVarGetString_Post +const char *FN_CVarGetString_Post(const char *szVarName); +#endif // FN_CVarGetString_Post + +#ifdef FN_CVarSetFloat_Post +void FN_CVarSetFloat_Post(const char *szVarName, float flValue); +#endif // FN_CVarSetFloat_Post + +#ifdef FN_CVarSetString_Post +void FN_CVarSetString_Post(const char *szVarName, const char *szValue); +#endif // FN_CVarSetString_Post + +#ifdef FN_AlertMessage_Post +void FN_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...); +#endif // FN_AlertMessage_Post + +#ifdef FN_EngineFprintf_Post +void FN_EngineFprintf_Post(FILE *pfile, char *szFmt, ...); +#endif // FN_EngineFprintf_Post + +#ifdef FN_PvAllocEntPrivateData_Post +void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, long cb); +#endif // FN_PvAllocEntPrivateData_Post + +#ifdef FN_PvEntPrivateData_Post +void *FN_PvEntPrivateData_Post(edict_t *pEdict); +#endif // FN_PvEntPrivateData_Post + +#ifdef FN_FreeEntPrivateData_Post +void FN_FreeEntPrivateData_Post(edict_t *pEdict); +#endif // FN_FreeEntPrivateData_Post + +#ifdef FN_SzFromIndex_Post +const char *FN_SzFromIndex_Post(int iString); +#endif // FN_SzFromIndex_Post + +#ifdef FN_AllocString_Post +int FN_AllocString_Post(const char *szValue); +#endif // FN_AllocString_Post + +#ifdef FN_GetVarsOfEnt_Post +struct entvars_s *FN_GetVarsOfEnt_Post(edict_t *pEdict); +#endif // FN_GetVarsOfEnt_Post + +#ifdef FN_PEntityOfEntOffset_Post +edict_t *FN_PEntityOfEntOffset_Post(int iEntOffset); +#endif // FN_PEntityOfEntOffset_Post + +#ifdef FN_EntOffsetOfPEntity_Post +int FN_EntOffsetOfPEntity_Post(const edict_t *pEdict); +#endif // FN_EntOffsetOfPEntity_Post + +#ifdef FN_IndexOfEdict_Post +int FN_IndexOfEdict_Post(const edict_t *pEdict); +#endif // FN_IndexOfEdict_Post + +#ifdef FN_PEntityOfEntIndex_Post +edict_t *FN_PEntityOfEntIndex_Post(int iEntIndex); +#endif // FN_PEntityOfEntIndex_Post + +#ifdef FN_FindEntityByVars_Post +edict_t *FN_FindEntityByVars_Post(struct entvars_s *pvars); +#endif // FN_FindEntityByVars_Post + +#ifdef FN_GetModelPtr_Post +void *FN_GetModelPtr_Post(edict_t *pEdict); +#endif // FN_GetModelPtr_Post + +#ifdef FN_RegUserMsg_Post +int FN_RegUserMsg_Post(const char *pszName, int iSize); +#endif // FN_RegUserMsg_Post + +#ifdef FN_AnimationAutomove_Post +void FN_AnimationAutomove_Post(const edict_t *pEdict, float flTime); +#endif // FN_AnimationAutomove_Post + +#ifdef FN_GetBonePosition_Post +void FN_GetBonePosition_Post(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles); +#endif // FN_GetBonePosition_Post + +#ifdef FN_FunctionFromName_Post +unsigned long FN_FunctionFromName_Post(const char *pName); +#endif // FN_FunctionFromName_Post + +#ifdef FN_NameForFunction_Post +const char *FN_NameForFunction_Post(unsigned long function); +#endif // FN_NameForFunction_Post + +#ifdef FN_ClientPrintf_Post +void FN_ClientPrintf_Post(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg); +#endif // FN_ClientPrintf_Post + +#ifdef FN_ServerPrint_Post +void FN_ServerPrint_Post(const char *szMsg); +#endif // FN_ServerPrint_Post + +#ifdef FN_Cmd_Args_Post +const char *FN_Cmd_Args_Post(void); +#endif // FN_Cmd_Args_Post + +#ifdef FN_Cmd_Argv_Post +const char *FN_Cmd_Argv_Post(int argc); +#endif // FN_Cmd_Argv_Post + +#ifdef FN_Cmd_Argc_Post +int FN_Cmd_Argc_Post(void); +#endif // FN_Cmd_Argc_Post + +#ifdef FN_GetAttachment_Post +void FN_GetAttachment_Post(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); +#endif // FN_GetAttachment_Post + +#ifdef FN_CRC32_Init_Post +void FN_CRC32_Init_Post(CRC32_t *pulCRC); +#endif // FN_CRC32_Init_Post + +#ifdef FN_CRC32_ProcessBuffer_Post +void FN_CRC32_ProcessBuffer_Post(CRC32_t *pulCRC, void *p, int len); +#endif // FN_CRC32_ProcessBuffer_Post + +#ifdef FN_CRC32_ProcessByte_Post +void FN_CRC32_ProcessByte_Post(CRC32_t *pulCRC, unsigned char ch); +#endif // FN_CRC32_ProcessByte_Post + +#ifdef FN_CRC32_Final_Post +CRC32_t FN_CRC32_Final_Post(CRC32_t pulCRC); +#endif // FN_CRC32_Final_Post + +#ifdef FN_RandomLong_Post +long FN_RandomLong_Post(long lLow, long lHigh); +#endif // FN_RandomLong_Post + +#ifdef FN_RandomFloat_Post +float FN_RandomFloat_Post(float flLow, float flHigh); +#endif // FN_RandomFloat_Post + +#ifdef FN_SetView_Post +void FN_SetView_Post(const edict_t *pClient, const edict_t *pViewent); +#endif // FN_SetView_Post + +#ifdef FN_Time_Post +float FN_Time_Post(void); +#endif // FN_Time_Post + +#ifdef FN_CrosshairAngle_Post +void FN_CrosshairAngle_Post(const edict_t *pClient, float pitch, float yaw); +#endif // FN_CrosshairAngle_Post + +#ifdef FN_LoadFileForMe_Post +byte *FN_LoadFileForMe_Post(char *filename, int *pLength); +#endif // FN_LoadFileForMe_Post + +#ifdef FN_FreeFile_Post +void FN_FreeFile_Post(void *buffer); +#endif // FN_FreeFile_Post + +#ifdef FN_EndSection_Post +void FN_EndSection_Post(const char *pszSectionName); +#endif // FN_EndSection_Post + +#ifdef FN_CompareFileTime_Post +int FN_CompareFileTime_Post(char *filename1, char *filename2, int *iCompare); +#endif // FN_CompareFileTime_Post + +#ifdef FN_GetGameDir_Post +void FN_GetGameDir_Post(char *szGetGameDir); +#endif // FN_GetGameDir_Post + +#ifdef FN_Cvar_RegisterVariable_Post +void FN_Cvar_RegisterVariable_Post(cvar_t *variable); +#endif // FN_Cvar_RegisterVariable_Post + +#ifdef FN_FadeClientVolume_Post +void FN_FadeClientVolume_Post(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); +#endif // FN_FadeClientVolume_Post + +#ifdef FN_SetClientMaxspeed_Post +void FN_SetClientMaxspeed_Post(const edict_t *pEdict, float fNewMaxspeed); +#endif // FN_SetClientMaxspeed_Post + +#ifdef FN_CreateFakeClient_Post +edict_t *FN_CreateFakeClient_Post(const char *netname); +#endif // FN_CreateFakeClient_Post + +#ifdef FN_RunPlayerMove_Post +void FN_RunPlayerMove_Post(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec); +#endif // FN_RunPlayerMove_Post + +#ifdef FN_NumberOfEntities_Post +int FN_NumberOfEntities_Post(void); +#endif // FN_NumberOfEntities_Post + +#ifdef FN_GetInfoKeyBuffer_Post +char *FN_GetInfoKeyBuffer_Post(edict_t *e); +#endif // FN_GetInfoKeyBuffer_Post + +#ifdef FN_InfoKeyValue_Post +char *FN_InfoKeyValue_Post(char *infobuffer, char *key); +#endif // FN_InfoKeyValue_Post + +#ifdef FN_SetKeyValue_Post +void FN_SetKeyValue_Post(char *infobuffer, char *key, char *value); +#endif // FN_SetKeyValue_Post + +#ifdef FN_SetClientKeyValue_Post +void FN_SetClientKeyValue_Post(int clientIndex, char *infobuffer, char *key, char *value); +#endif // FN_SetClientKeyValue_Post + +#ifdef FN_IsMapValid_Post +int FN_IsMapValid_Post(char *filename); +#endif // FN_IsMapValid_Post + +#ifdef FN_StaticDecal_Post +void FN_StaticDecal_Post(const float *origin, int decalIndex, int entityIndex, int modelIndex); +#endif // FN_StaticDecal_Post + +#ifdef FN_PrecacheGeneric_Post +int FN_PrecacheGeneric_Post(char *s); +#endif // FN_PrecacheGeneric_Post + +#ifdef FN_GetPlayerUserId_Post +int FN_GetPlayerUserId_Post(edict_t *e ); +#endif // FN_GetPlayerUserId_Post + +#ifdef FN_BuildSoundMsg_Post +void FN_BuildSoundMsg_Post(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +#endif // FN_BuildSoundMsg_Post + +#ifdef FN_IsDedicatedServer_Post +int FN_IsDedicatedServer_Post(void); +#endif // FN_IsDedicatedServer_Post + +#ifdef FN_CVarGetPointer_Post +cvar_t *FN_CVarGetPointer_Post(const char *szVarName); +#endif // FN_CVarGetPointer_Post + +#ifdef FN_GetPlayerWONId_Post +unsigned int FN_GetPlayerWONId_Post(edict_t *e); +#endif // FN_GetPlayerWONId_Post + +#ifdef FN_Info_RemoveKey_Post +void FN_Info_RemoveKey_Post( char *s, const char *key); +#endif // FN_Info_RemoveKey_Post + +#ifdef FN_GetPhysicsKeyValue_Post +const char *FN_GetPhysicsKeyValue_Post(const edict_t *pClient, const char *key); +#endif // FN_GetPhysicsKeyValue_Post + +#ifdef FN_SetPhysicsKeyValue_Post +void FN_SetPhysicsKeyValue_Post(const edict_t *pClient, const char *key, const char *value); +#endif // FN_SetPhysicsKeyValue_Post + +#ifdef FN_GetPhysicsInfoString_Post +const char *FN_GetPhysicsInfoString_Post( const edict_t *pClient); +#endif // FN_GetPhysicsInfoString_Post + +#ifdef FN_PrecacheEvent_Post +unsigned short FN_PrecacheEvent_Post(int type, const char *psz); +#endif // FN_PrecacheEvent_Post + +#ifdef FN_PlaybackEvent_Post +void FN_PlaybackEvent_Post(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); +#endif // FN_PlaybackEvent_Post + +#ifdef FN_SetFatPVS_Post +unsigned char *FN_SetFatPVS_Post(float *org); +#endif // FN_SetFatPVS_Post + +#ifdef FN_SetFatPAS_Post +unsigned char *FN_SetFatPAS_Post(float *org); +#endif // FN_SetFatPAS_Post + +#ifdef FN_CheckVisibility_Post +int FN_CheckVisibility_Post(const edict_t *entity, unsigned char *pset); +#endif // FN_CheckVisibility_Post + +#ifdef FN_DeltaSetField_Post +void FN_DeltaSetField_Post(struct delta_s *pFields, const char *fieldname); +#endif // FN_DeltaSetField_Post + +#ifdef FN_DeltaUnsetField_Post +void FN_DeltaUnsetField_Post(struct delta_s *pFields, const char *fieldname); +#endif // FN_DeltaUnsetField_Post + +#ifdef FN_DeltaAddEncoder_Post +void FN_DeltaAddEncoder_Post(char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); +#endif // FN_DeltaAddEncoder_Post + +#ifdef FN_GetCurrentPlayer_Post +int FN_GetCurrentPlayer_Post(void); +#endif // FN_GetCurrentPlayer_Post + +#ifdef FN_CanSkipPlayer_Post +int FN_CanSkipPlayer_Post(const edict_t *player); +#endif // FN_CanSkipPlayer_Post + +#ifdef FN_DeltaFindField_Post +int FN_DeltaFindField_Post(struct delta_s *pFields, const char *fieldname); +#endif // FN_DeltaFindField_Post + +#ifdef FN_DeltaSetFieldByIndex_Post +void FN_DeltaSetFieldByIndex_Post(struct delta_s *pFields, int fieldNumber); +#endif // FN_DeltaSetFieldByIndex_Post + +#ifdef FN_DeltaUnsetFieldByIndex_Post +void FN_DeltaUnsetFieldByIndex_Post(struct delta_s *pFields, int fieldNumber); +#endif // FN_DeltaUnsetFieldByIndex_Post + +#ifdef FN_SetGroupMask_Post +void FN_SetGroupMask_Post(int mask, int op); +#endif // FN_SetGroupMask_Post + +#ifdef FN_engCreateInstancedBaseline_Post +int FN_engCreateInstancedBaseline_Post(int classname, struct entity_state_s *baseline); +#endif // FN_engCreateInstancedBaseline_Post + +#ifdef FN_Cvar_DirectSet_Post +void FN_Cvar_DirectSet_Post(struct cvar_s *var, char *value); +#endif // FN_Cvar_DirectSet_Post + +#ifdef FN_ForceUnmodified_Post +void FN_ForceUnmodified_Post(FORCE_TYPE type, float *mins, float *maxs, const char *filename); +#endif // FN_ForceUnmodified_Post + +#ifdef FN_GetPlayerStats_Post +void FN_GetPlayerStats_Post(const edict_t *pClient, int *ping, int *packet_loss); +#endif // FN_GetPlayerStats_Post + +#ifdef FN_AddServerCommand_Post +void FN_AddServerCommand_Post(char *cmd_name, void (*function)(void)); +#endif // FN_AddServerCommand_Post + +#ifdef FN_Voice_GetClientListening_Post +qboolean FN_Voice_GetClientListening_Post(int iReceiver, int iSender); +#endif // FN_Voice_GetClientListening_Post + +#ifdef FN_Voice_SetClientListening_Post +qboolean FN_Voice_SetClientListening_Post(int iReceiver, int iSender, qboolean bListen); +#endif // FN_Voice_SetClientListening_Post + +#ifdef FN_GetPlayerAuthId_Post +const char *FN_GetPlayerAuthId_Post(edict_t *e); +#endif // FN_GetPlayerAuthId + + + + +#ifdef FN_OnFreeEntPrivateData +void FN_OnFreeEntPrivateData(edict_t *pEnt); +#endif // FN_OnFreeEntPrivateData + +#ifdef FN_GameShutdown +void FN_GameShutdown(void); +#endif // FN_GameShutdown + +#ifdef FN_ShouldCollide +int FN_ShouldCollide(edict_t *pentTouched, edict_t *pentOther); +#endif // FN_ShouldCollide + + + + + +#ifdef FN_OnFreeEntPrivateData_Post +void FN_OnFreeEntPrivateData_Post(edict_t *pEnt); +#endif // FN_OnFreeEntPrivateData_Post + +#ifdef FN_GameShutdown_Post +void FN_GameShutdown_Post(void); +#endif // FN_GameShutdown_Post + +#ifdef FN_ShouldCollide_Post +int FN_ShouldCollide_Post(edict_t *pentTouched, edict_t *pentOther); +#endif // FN_ShouldCollide_Post + +#endif // USE_METAMOD + + +#ifdef FN_AMXX_QUERY +void FN_AMXX_QUERY(void); +#endif // FN_AMXX_QUERY + +#ifdef FN_AMXX_ATTACH +void FN_AMXX_ATTACH(void); +#endif // FN_AMXX_ATTACH + +#ifdef FN_AMXX_DETACH +void FN_AMXX_DETACH(void); +#endif // FN_AMXX_DETACH + +#ifdef FN_AMXX_PLUGINSLOADED +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*/); + +// ***** Module funcs stuff ***** +enum ForwardExecType +{ + ET_IGNORE = 0, // Ignore return vaue + ET_STOP, // Stop on PLUGIN_HANDLED + ET_STOP2, // Stop on PLUGIN_HANDLED, continue on other values, return biggest return value + ET_CONTINUE, // Continue; return biggest return value +}; + +enum ForwardParam +{ + FP_DONE = -1, // specify this as the last argument + // only tells the function that there are no more arguments + FP_CELL, // normal cell + FP_FLOAT, // float; used as normal cell though + FP_STRING, // string + FP_STRINGEX, // string; will be updated to the last function's value + FP_ARRAY, // array; use the return value of prepareArray. +}; + +enum PlayerProp +{ + Player_Name, //String + Player_Ip, //String + Player_Team, //String + Player_Ingame, //bool + Player_Authorized, //bool + Player_Vgui, //bool + Player_Time, //float + Player_Playtime, //float + Player_MenuExpire, //float + Player_Weapons, //struct{int,int}[32] + Player_CurrentWeapon, //int + Player_TeamID, //int + Player_Deaths, //int + Player_Aiming, //int + Player_Menu, //int + Player_Keys, //int + Player_Flags, //int[32] + Player_Newmenu, //int + Player_NewmenuPage, //int +}; + +enum LibType +{ + LibType_Library, + LibType_Class +}; + +typedef void (*AUTHORIZEFUNC)(int player, const char *authstring); + +typedef int (*PFN_ADD_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*/); +typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...); +typedef const char * (*PFN_GET_MODNAME) (void); +typedef const char * (*PFN_GET_AMXSCRIPTNAME) (int /*id*/); +typedef AMX * (*PFN_GET_AMXSCRIPT) (int /*id*/); +typedef int (*PFN_FIND_AMXSCRIPT_BYAMX) (const AMX * /*amx*/); +typedef int (*PFN_FIND_AMXSCRIPT_BYNAME) (const char * /*name*/); +typedef int (*PFN_SET_AMXSTRING) (AMX * /*amx*/, cell /*amx_addr*/, const char * /* source */, int /* max */); +typedef char * (*PFN_GET_AMXSTRING) (AMX * /*amx*/, cell /*amx_addr*/, int /*bufferId*/, int * /*pLen*/); +typedef int (*PFN_GET_AMXSTRINGLEN) (const cell *ptr); +typedef char * (*PFN_FORMAT_AMXSTRING) (AMX * /*amx*/, cell * /*params*/, int /*startParam*/, int * /*pLen*/); +typedef void (*PFN_COPY_AMXMEMORY) (cell * /*dest*/, const cell * /*src*/, int /*len*/); +typedef void (*PFN_LOG) (const char * /*fmt*/, ...); +typedef void (*PFN_LOG_ERROR) (AMX * /*amx*/, int /*err*/, const char * /*fmt*/, ...); +typedef int (*PFN_RAISE_AMXERROR) (AMX * /*amx*/, int /*error*/); +typedef int (*PFN_REGISTER_FORWARD) (const char * /*funcname*/, ForwardExecType /*exectype*/, ... /*paramtypes terminated by PF_DONE*/); +typedef int (*PFN_EXECUTE_FORWARD) (int /*id*/, ... /*params*/); +typedef cell (*PFN_PREPARE_CELLARRAY) (cell * /*ptr*/, unsigned int /*size*/); +typedef cell (*PFN_PREPARE_CHARARRAY) (char * /*ptr*/, unsigned int /*size*/); +typedef cell (*PFN_PREPARE_CELLARRAY_A) (cell * /*ptr*/, unsigned int /*size*/, bool /*copyBack*/); +typedef cell (*PFN_PREPARE_CHARARRAY_A) (char * /*ptr*/, unsigned int /*size*/, bool /*copyBack*/); +typedef int (*PFN_IS_PLAYER_VALID) (int /*id*/); +typedef const char * (*PFN_GET_PLAYER_NAME) (int /*id*/); +typedef const char * (*PFN_GET_PLAYER_IP) (int /*id*/); +typedef int (*PFN_IS_PLAYER_INGAME) (int /*id*/); +typedef int (*PFN_IS_PLAYER_BOT) (int /*id*/); +typedef int (*PFN_IS_PLAYER_AUTHORIZED) (int /*id*/); +typedef float (*PFN_GET_PLAYER_TIME) (int /*id*/); +typedef float (*PFN_GET_PLAYER_PLAYTIME) (int /*id*/); +typedef int (*PFN_GETPLAYERFLAGS) (int /* id*/); +typedef int (*PFN_GET_PLAYER_CURWEAPON) (int /*id*/); +typedef const char * (*PFN_GET_PLAYER_TEAM) (int /*id*/); +typedef int (*PFN_GET_PLAYER_TEAMID) (int /*id*/); +typedef int (*PFN_GET_PLAYER_DEATHS) (int /*id*/); +typedef int (*PFN_GET_PLAYER_MENU) (int /*id*/); +typedef int (*PFN_GET_PLAYER_KEYS) (int /*id*/); +typedef int (*PFN_IS_PLAYER_ALIVE) (int /*id*/); +typedef int (*PFN_GET_PLAYER_FRAGS) (int /*id*/); +typedef int (*PFN_IS_PLAYER_CONNECTING) (int /*id*/); +typedef int (*PFN_IS_PLAYER_HLTV) (int /*id*/); +typedef int (*PFN_GET_PLAYER_ARMOR) (int /*id*/); +typedef int (*PFN_GET_PLAYER_HEALTH) (int /*id*/); +#ifdef USE_METAMOD +typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/); +#else +typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/); +#endif +typedef void * (*PFN_PLAYER_PROP_ADDR) (int /*id*/, int /*prop*/); + +#ifdef MEMORY_TEST +typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, + const unsigned int /*type*/, const size_t /*size*/); +typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, + const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ ); +typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, + const unsigned int /*type*/, const void* /*addr*/ ); +#endif +typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/); +typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/); +typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/); +typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/); +typedef int (*PFN_AMX_FINDNATIVE) (AMX* /*amx*/, char* /*func name*/, int* /*index*/); +typedef int (*PFN_LOAD_AMXSCRIPT) (AMX* /*amx*/, void** /*code*/, const char* /*path*/, char[64] /*error info*/, int /* debug */); +typedef int (*PFN_UNLOAD_AMXSCRIPT) (AMX* /*amx*/,void** /*code*/); +typedef cell (*PFN_REAL_TO_CELL) (REAL /*x*/); +typedef REAL (*PFN_CELL_TO_REAL) (cell /*x*/); +typedef int (*PFN_REGISTER_SPFORWARD) (AMX * /*amx*/, int /*func*/, ... /*params*/); +typedef int (*PFN_REGISTER_SPFORWARD_BYNAME) (AMX * /*amx*/, const char * /*funcName*/, ... /*params*/); +typedef void (*PFN_UNREGISTER_SPFORWARD) (int /*id*/); +typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/); +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*/); + +extern PFN_ADD_NATIVES g_fn_AddNatives; +extern PFN_BUILD_PATHNAME g_fn_BuildPathname; +extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR; +extern PFN_GET_AMXADDR g_fn_GetAmxAddr; +extern PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole; +extern PFN_GET_MODNAME g_fn_GetModname; +extern PFN_GET_AMXSCRIPTNAME g_fn_GetAmxScriptName; +extern PFN_GET_AMXSCRIPT g_fn_GetAmxScript; +extern PFN_FIND_AMXSCRIPT_BYAMX g_fn_FindAmxScriptByAmx; +extern PFN_FIND_AMXSCRIPT_BYNAME g_fn_FindAmxScriptByName; +extern PFN_SET_AMXSTRING g_fn_SetAmxString; +extern PFN_GET_AMXSTRING g_fn_GetAmxString; +extern PFN_GET_AMXSTRINGLEN g_fn_GetAmxStringLen; +extern PFN_FORMAT_AMXSTRING g_fn_FormatAmxString; +extern PFN_COPY_AMXMEMORY g_fn_CopyAmxMemory; +extern PFN_LOG g_fn_Log; +extern PFN_LOG_ERROR g_fn_LogErrorFunc; +extern PFN_RAISE_AMXERROR g_fn_RaiseAmxError; +extern PFN_REGISTER_FORWARD g_fn_RegisterForward; +extern PFN_EXECUTE_FORWARD g_fn_ExecuteForward; +extern PFN_PREPARE_CELLARRAY g_fn_PrepareCellArray; +extern PFN_PREPARE_CHARARRAY g_fn_PrepareCharArray; +extern PFN_PREPARE_CELLARRAY_A g_fn_PrepareCellArrayA; +extern PFN_PREPARE_CHARARRAY_A g_fn_PrepareCharArrayA; +extern PFN_IS_PLAYER_VALID g_fn_IsPlayerValid; +extern PFN_GET_PLAYER_NAME g_fn_GetPlayerName; +extern PFN_GET_PLAYER_IP g_fn_GetPlayerIP; +extern PFN_IS_PLAYER_INGAME g_fn_IsPlayerIngame; +extern PFN_IS_PLAYER_BOT g_fn_IsPlayerBot; +extern PFN_IS_PLAYER_AUTHORIZED g_fn_IsPlayerAuthorized; +extern PFN_GET_PLAYER_TIME g_fn_GetPlayerTime; +extern PFN_GET_PLAYER_PLAYTIME g_fn_GetPlayerPlayTime; +extern PFN_GET_PLAYER_CURWEAPON g_fn_GetPlayerCurweapon; +extern PFN_GET_PLAYER_TEAMID g_fn_GetPlayerTeamID; +extern PFN_GET_PLAYER_DEATHS g_fn_GetPlayerDeaths; +extern PFN_GET_PLAYER_MENU g_fn_GetPlayerMenu; +extern PFN_GET_PLAYER_KEYS g_fn_GetPlayerKeys; +extern PFN_IS_PLAYER_ALIVE g_fn_IsPlayerAlive; +extern PFN_GET_PLAYER_FRAGS g_fn_GetPlayerFrags; +extern PFN_IS_PLAYER_CONNECTING g_fn_IsPlayerConnecting; +extern PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV; +extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor; +extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth; +extern PFN_AMX_EXEC g_fn_AmxExec; +extern PFN_AMX_ALLOT g_fn_AmxAllot; +extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic; +extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript; +extern PFN_UNLOAD_AMXSCRIPT g_fn_UnloadAmxScript; +extern PFN_REAL_TO_CELL g_fn_RealToCell; +extern PFN_CELL_TO_REAL g_fn_CellToReal; +extern PFN_REGISTER_SPFORWARD g_fn_RegisterSPForward; +extern PFN_REGISTER_SPFORWARD_BYNAME g_fn_RegisterSPForwardByName; +extern PFN_UNREGISTER_SPFORWARD g_fn_UnregisterSPForward; +extern PFN_MERGEDEFINITION_FILE g_fn_MergeDefinition_File; +extern PFN_AMX_FINDNATIVE g_fn_AmxFindNative; +extern PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags; +extern PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict; +extern PFN_FORMAT g_fn_Format; +extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam; +extern PFN_REGISTERFUNCTION g_fn_RegisterFunction; +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; + +#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) { } +char * MF_BuildPathname (const char * format, ...) { } +char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { } +cell * MF_GetAmxAddr (AMX * amx, cell offset) { } +void MF_PrintSrvConsole (char * format, ...) { } +const char * MF_GetModname (void) { } +const char * MF_GetScriptName (int id) { } +AMX * MF_GetScriptAmx (int id) { } +int MF_FindScriptByAmx (const AMX * amx) { } +int MF_FindScriptByAmx (const char * name) { } +int MF_SetAmxString (AMX * amx, cell amx_addr, const char * source , int max ) { } +char * MF_GetAmxString (AMX * amx, cell amx_addr, int bufferId, int * pLen) { } +int MF_GetAmxStringLen (const cell *ptr) { } +char * MF_FormatAmxString (AMX * amx, cell * params, int startParam, int * pLen) { } +void MF_CopyAmxMemory (cell * dest, const cell * src, int len) { } +void MF_Log (const char * fmt, ...) { } +void MF_LogError (AMX * amx, int err, const char *fmt, ...) { } +int MF_RaiseAmxError (AMX * amx, int error) { } +int MF_RegisterForward (const char * funcname, ForwardExecType exectype, ...) { } +int MF_ExecuteForward (int id, ...) { } +cell MF_PrepareCellArray (cell * ptr, unsigned int size) { } +cell MF_PrepareCharArray (char * ptr, unsigned int size) { } +cell MF_PrepareCellArrayA (cell * ptr, unsigned int size, bool copyBack) { } +cell MF_PrepareCharArrayA (char * ptr, unsigned int size, bool copyBack) { } +int MF_IsPlayerValid (int id) { } +const char * MF_GetPlayerName (int id) { } +const char * MF_GetPlayerIP (int id) { } +int MF_IsPlayerIngame (int id) { } +int MF_IsPlayerBot (int id) { } +int MF_IsPlayerAuthorized (int id) { } +float MF_GetPlayerTime (int id) { } +float MF_GetPlayerPlayTime (int id) { } +int MF_GetPlayerCurweapon (int id) { } +const char * MF_GetPlayerTeam (int id) { } +int MF_GetPlayerTeamID (int id) { } +int MF_GetPlayerDeaths (int id) { } +int MF_GetPlayerMenu (int id) { } +int MF_GetPlayerKeys (int id) { } +int MF_IsPlayerAlive (int id) { } +int MF_GetPlayerFrags (int id) { } +int MF_IsPlayerConnecting (int id) { } +int MF_IsPlayerHLTV (int id) { } +int MF_GetPlayerArmor (int id) { } +int MF_GetPlayerHealth (int id) { } +REAL amx_ctof (cell x) { } +cell amx_ftoc (float x) { } +int MF_RegisterSPForwardByName (AMX * amx, const char *str, ...) { } +int MF_RegisterSPForward (AMX * amx, int func, ...) { } +void MF_UnregisterSPForward (int id) { } +int MF_GetPlayerFlags (int id) { } +edict_t* MF_GetPlayerEdict (int id) { } +const char * MF_Format (const char *fmt, ...) { } +void MF_RegisterFunction (void *pfn, const char *description) { } +void * MF_RequestFunction (const char *description) { } +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) { } +#endif // MAY_NEVER_BE_DEFINED + +#define MF_AddNatives g_fn_AddNatives +#define MF_BuildPathname g_fn_BuildPathname +#define MF_BuildPathnameR g_fn_BuildPathnameR +#define MF_FormatAmxString g_fn_FormatAmxString +#define MF_GetAmxAddr g_fn_GetAmxAddr +#define MF_PrintSrvConsole g_fn_PrintSrvConsole +#define MF_GetModname g_fn_GetModname +#define MF_GetScriptName g_fn_GetAmxScriptName +#define MF_GetScriptAmx g_fn_GetAmxScript +#define MF_FindScriptByAmx g_fn_FindAmxScriptByAmx +#define MF_FindScriptByName g_fn_FindAmxScriptByName +#define MF_SetAmxString g_fn_SetAmxString +#define MF_GetAmxString g_fn_GetAmxString +#define MF_GetAmxStringLen g_fn_GetAmxStringLen +#define MF_CopyAmxMemory g_fn_CopyAmxMemory +void MF_Log(const char *fmt, ...); +void MF_LogError(AMX *amx, int err, const char *fmt, ...); +#define MF_RaiseAmxError g_fn_RaiseAmxError +#define MF_RegisterForward g_fn_RegisterForward +#define MF_ExecuteForward g_fn_ExecuteForward +#define MF_PrepareCellArray g_fn_PrepareCellArray +#define MF_PrepareCharArray g_fn_PrepareCharArray +#define MF_PrepareCellArrayA g_fn_PrepareCellArrayA +#define MF_PrepareCharArrayA g_fn_PrepareCharArrayA +#define MF_IsPlayerValid g_fn_IsPlayerValid +#define MF_GetPlayerName g_fn_GetPlayerName +#define MF_GetPlayerIP g_fn_GetPlayerIP +#define MF_IsPlayerIngame g_fn_IsPlayerIngame +#define MF_IsPlayerBot g_fn_IsPlayerBot +#define MF_IsPlayerAuthorized g_fn_IsPlayerAuthorized +#define MF_GetPlayerTime g_fn_GetPlayerTime +#define MF_GetPlayerPlayTime g_fn_GetPlayerPlayTime +#define MF_GetPlayerCurweapon g_fn_GetPlayerCurweapon +#define MF_GetPlayerTeam g_fn_GetPlayerTeam +#define MF_GetPlayerTeamID g_fn_GetPlayerTeamID +#define MF_GetPlayerDeaths g_fn_GetPlayerDeaths +#define MF_GetPlayerMenu g_fn_GetPlayerMenu +#define MF_GetPlayerKeys g_fn_GetPlayerKeys +#define MF_IsPlayerAlive g_fn_IsPlayerAlive +#define MF_GetPlayerFrags g_fn_GetPlayerFrags +#define MF_IsPlayerConnecting g_fn_IsPlayerConnecting +#define MF_IsPlayerHLTV g_fn_IsPlayerHLTV +#define MF_GetPlayerArmor g_fn_GetPlayerArmor +#define MF_GetPlayerHealth g_fn_GetPlayerHealth +#define MF_AmxExec g_fn_AmxExec +#define MF_AmxExecv g_fn_AmxExecv +#define MF_AmxFindPublic g_fn_AmxFindPublic +#define MF_AmxAllot g_fn_AmxAllot +#define MF_AmxFindNative g_fn_AmxFindNative +#define MF_LoadAmxScript g_fn_LoadAmxScript +#define MF_UnloadAmxScript g_fn_UnloadAmxScript +#define MF_MergeDefinitionFile g_fn_MergeDefinition_File +#define amx_ctof g_fn_CellToReal +#define amx_ftoc g_fn_RealToCell +#define MF_RegisterSPForwardByName g_fn_RegisterSPForwardByName +#define MF_RegisterSPForward g_fn_RegisterSPForward +#define MF_UnregisterSPForward g_fn_UnregisterSPForward +#define MF_GetPlayerFlags g_fn_GetPlayerFlags +#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_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 + +#ifdef MEMORY_TEST +/*** Memory ***/ +void *operator new(size_t reportedSize); +void *operator new[](size_t reportedSize); +void *operator new(size_t reportedSize, const char *sourceFile, int sourceLine); +void *operator new[](size_t reportedSize, const char *sourceFile, int sourceLine); +void operator delete(void *reportedAddress); +void operator delete[](void *reportedAddress); + +// Allocation types +extern const unsigned int m_alloc_unknown; +extern const unsigned int m_alloc_new; +extern const unsigned int m_alloc_new_array; +extern const unsigned int m_alloc_malloc; +extern const unsigned int m_alloc_calloc; +extern const unsigned int m_alloc_realloc; +extern const unsigned int m_alloc_delete; +extern const unsigned int m_alloc_delete_array; +extern const unsigned int m_alloc_free; + +// To be called before new / delete +void Mem_SetOwner(const char *filename, int line, const char *function); +// Actual allocator +void * Mem_Allocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc, + const unsigned int allocationType, const size_t reportedSize); +void * Mem_Reallocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc, + const unsigned int reallocationType, const size_t reportedSize, void *reportedAddress); +void Mem_Deallocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc, + const unsigned int deallocationType, void *reportedAddress); + +// memory macros +#ifndef __FUNCTION__ +#define __FUNCTION__ "??" +#endif + +// call Mem_SetOwner, followed by the actual new operator +#define new (Mem_SetOwner(__FILE__,__LINE__,__FUNCTION__),false) ? NULL : new +// call Mem_SetOwner, followed by the actual delete operator +#define delete (Mem_SetOwner(__FILE__,__LINE__,__FUNCTION__),false) ? Mem_SetOwner("",0,"") : delete +#define malloc(sz) Mem_Allocator (__FILE__,__LINE__,__FUNCTION__,m_alloc_malloc,sz) +#define calloc(sz) Mem_Allocator (__FILE__,__LINE__,__FUNCTION__,m_alloc_calloc,sz) +#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr) +#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr) + +#endif //MEMORY_TEST + +#endif // #ifndef __AMXXMODULE_H__ diff --git a/dlls/sven/sven/moduleconfig.cpp b/dlls/sven/sven/moduleconfig.cpp new file mode 100644 index 00000000..353d3a4a --- /dev/null +++ b/dlls/sven/sven/moduleconfig.cpp @@ -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 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); +} diff --git a/dlls/sven/moduleconfig.h b/dlls/sven/sven/moduleconfig.h similarity index 92% rename from dlls/sven/moduleconfig.h rename to dlls/sven/sven/moduleconfig.h index 8c87a6e2..e22c2f99 100644 --- a/dlls/sven/moduleconfig.h +++ b/dlls/sven/sven/moduleconfig.h @@ -1,472 +1,492 @@ -// Configuration - -#ifndef __MODULECONFIG_H__ -#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" -// 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 - -// - 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 -//#define FN_AMXX_DETACH OnAmxxDetach -// All plugins loaded -// Do forward functions init here (MF_RegisterForward) -// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded - -/**** 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__ +// Configuration + +#ifndef __MODULECONFIG_H__ +#define __MODULECONFIG_H__ + +// Module info +#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 + +#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__ diff --git a/dlls/sven/sven/msvc7/svencoop.sln b/dlls/sven/sven/msvc7/svencoop.sln new file mode 100644 index 00000000..348a94a0 --- /dev/null +++ b/dlls/sven/sven/msvc7/svencoop.sln @@ -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 diff --git a/dlls/sven/sven/msvc7/svencoop.vcproj b/dlls/sven/sven/msvc7/svencoop.vcproj new file mode 100644 index 00000000..72216192 --- /dev/null +++ b/dlls/sven/sven/msvc7/svencoop.vcproj @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dlls/sven/sven/svencoop.cpp b/dlls/sven/sven/svencoop.cpp new file mode 100644 index 00000000..d986fa3c --- /dev/null +++ b/dlls/sven/sven/svencoop.cpp @@ -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(classname); + kvd->szKeyName = const_cast("displayname"); + kvd->szValue = const_cast(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(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} +}; diff --git a/dlls/sven/sven/svencoop.h b/dlls/sven/sven/svencoop.h new file mode 100644 index 00000000..4a28569e --- /dev/null +++ b/dlls/sven/sven/svencoop.h @@ -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 +#include +#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 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)) + diff --git a/dlls/sven/sven/svencoop.inc b/dlls/sven/sven/svencoop.inc new file mode 100644 index 00000000..dd2dea42 --- /dev/null +++ b/dlls/sven/sven/svencoop.inc @@ -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 + +/* 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); diff --git a/dlls/sven/sven/svencoop_const.inc b/dlls/sven/sven/svencoop_const.inc new file mode 100644 index 00000000..71541482 --- /dev/null +++ b/dlls/sven/sven/svencoop_const.inc @@ -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 +} diff --git a/dlls/sven/svencoop.cpp b/dlls/sven/svencoop.cpp deleted file mode 100644 index ec0922ca..00000000 --- a/dlls/sven/svencoop.cpp +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/dlls/sven/svencoop.h b/dlls/sven/svencoop.h deleted file mode 100644 index 8cc10d02..00000000 --- a/dlls/sven/svencoop.h +++ /dev/null @@ -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(val) ); -}; - -inline long GetFrags( long& targetid) -{ - return static_cast( 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(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(val) ); - SetPData(targetid, sven_wep[1], static_cast(val) ); - - return 1; -} - -inline long GetSvenWeapon(long& targetid, const long sven_wep[2]) -{ - return GetPData(targetid, sven_wep[0], int(NULL) ); -} - -#endif diff --git a/dlls/sven/svencoop.inc b/dlls/sven/svencoop.inc deleted file mode 100644 index 4e6364ad..00000000 --- a/dlls/sven/svencoop.inc +++ /dev/null @@ -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 -#include - -#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) \ No newline at end of file diff --git a/dlls/sven/svencoop_const.h b/dlls/sven/svencoop_const.h deleted file mode 100644 index 86be447b..00000000 --- a/dlls/sven/svencoop_const.h +++ /dev/null @@ -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 \ No newline at end of file diff --git a/dlls/sven/svencoop_const.inc b/dlls/sven/svencoop_const.inc deleted file mode 100644 index a44a7b4e..00000000 --- a/dlls/sven/svencoop_const.inc +++ /dev/null @@ -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 - \ No newline at end of file diff --git a/dlls/sven/svencoop_stocks.inc b/dlls/sven/svencoop_stocks.inc deleted file mode 100644 index 84d2b1bf..00000000 --- a/dlls/sven/svencoop_stocks.inc +++ /dev/null @@ -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 - -//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; } \ No newline at end of file diff --git a/dlls/tfc/tfcx/NBase.cpp b/dlls/tfc/tfcx/NBase.cpp index faa201b7..bfcdb585 100755 --- a/dlls/tfc/tfcx/NBase.cpp +++ b/dlls/tfc/tfcx/NBase.cpp @@ -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}, diff --git a/dlls/tfc/tfcx/moduleconfig.cpp b/dlls/tfc/tfcx/moduleconfig.cpp index ae70e053..16e2c193 100755 --- a/dlls/tfc/tfcx/moduleconfig.cpp +++ b/dlls/tfc/tfcx/moduleconfig.cpp @@ -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; @@ -166,7 +168,13 @@ void ServerDeactivate() { weaponData[i].ammoSlot = false; 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); +} diff --git a/dlls/tfc/tfcx/moduleconfig.h b/dlls/tfc/tfcx/moduleconfig.h index 3a53fb5b..a51631f2 100755 --- a/dlls/tfc/tfcx/moduleconfig.h +++ b/dlls/tfc/tfcx/moduleconfig.h @@ -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() */ diff --git a/plugins/admin.sma b/plugins/admin.sma index b2c9b25f..3bfd684a 100755 --- a/plugins/admin.sma +++ b/plugins/admin.sma @@ -33,7 +33,7 @@ */ // Uncomment for SQL version -//#define USING_SQL +// #define USING_SQL #include #include @@ -41,7 +41,8 @@ #include #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 szText[256], szFlags[32], szAccess[32] - new a, pos = 0 - - while (g_aNum < MAX_ADMINS && read_file(szFilename, pos++, szText, 255, a)) + new File=fopen(szFilename,"r"); + + if (File) { - if (szText[0] == ';') - continue + new Text[512]; + new Flags[32]; + new Access[32] + new AuthData[44]; + new Password[32]; + + while (!feof(File)) + { + fgets(File,Text,sizeof(Text)-1); + + // 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)); - if (parse(szText, g_aName[g_aNum], 31, g_aPassword[g_aNum], 31, szAccess, 31, szFlags, 31) < 2) - continue + AdminCount++; + } + + fclose(File); + } - g_aAccess[g_aNum] = read_flags(szAccess) - g_aFlags[g_aNum] = read_flags(szFlags) - ++g_aNum + if (AdminCount == 1) + { + server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMIN"); + } + else + { + server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", AdminCount); } - if (g_aNum == 1) - server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMIN") - else - server_print("[AMXX] %L", LANG_SERVER, "LOADED_ADMINS", g_aNum) - - 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) - - 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) + + admins_lookup(index,AdminProp_Password,Password,sizeof(Password)-1); + + 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 } diff --git a/plugins/admincmd.sma b/plugins/admincmd.sma index e422eb14..23b84601 100755 --- a/plugins/admincmd.sma +++ b/plugins/admincmd.sma @@ -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, " [reason]") register_concmd("amx_ban", "cmdBan", ADMIN_BAN, " [reason]") register_concmd("amx_banip", "cmdBanIP", ADMIN_BAN, " [reason]") @@ -69,6 +74,18 @@ public plugin_init() register_clcmd("amx_rcon", "cmdRcon", ADMIN_RCON, "") register_clcmd("amx_showrcon", "cmdShowRcon", ADMIN_RCON, "") 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 } @@ -517,8 +536,9 @@ 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) @@ -550,6 +570,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 <%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) diff --git a/plugins/adminslots.sma b/plugins/adminslots.sma index 2387e8d2..b2b261ab 100755 --- a/plugins/adminslots.sma +++ b/plugins/adminslots.sma @@ -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) diff --git a/plugins/antiflood.sma b/plugins/antiflood.sma index 9ad0e23a..a96e30da 100755 --- a/plugins/antiflood.sma +++ b/plugins/antiflood.sma @@ -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) { diff --git a/plugins/dod/plmenu.sma b/plugins/dod/plmenu.sma index 393019a5..a1d98b1e 100755 --- a/plugins/dod/plmenu.sma +++ b/plugins/dod/plmenu.sma @@ -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)) diff --git a/plugins/include/amxconst.inc b/plugins/include/amxconst.inc index 704f963b..f01af7ba 100755 --- a/plugins/include/amxconst.inc +++ b/plugins/include/amxconst.inc @@ -312,3 +312,11 @@ enum LibType LibType_Library, LibType_Class }; + +enum AdminProp +{ + AdminProp_Auth = 0, + AdminProp_Password, + AdminProp_Access, + AdminProp_Flags +}; diff --git a/plugins/include/amxmisc.inc b/plugins/include/amxmisc.inc index 704ce3fc..7eaced69 100755 --- a/plugins/include/amxmisc.inc +++ b/plugins/include/amxmisc.inc @@ -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); +} diff --git a/plugins/include/amxmodx.inc b/plugins/include/amxmodx.inc index ef737e27..01231a0b 100755 --- a/plugins/include/amxmodx.inc +++ b/plugins/include/amxmodx.inc @@ -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 diff --git a/plugins/include/dodconst.inc b/plugins/include/dodconst.inc index cc683988..f7a0b8e2 100755 --- a/plugins/include/dodconst.inc +++ b/plugins/include/dodconst.inc @@ -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, diff --git a/plugins/include/dodfun.inc b/plugins/include/dodfun.inc index abcd84ae..defe0b39 100755 --- a/plugins/include/dodfun.inc +++ b/plugins/include/dodfun.inc @@ -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); diff --git a/plugins/include/dodx.inc b/plugins/include/dodx.inc index a30197fc..99a361d3 100755 --- a/plugins/include/dodx.inc +++ b/plugins/include/dodx.inc @@ -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); diff --git a/plugins/include/float.inc b/plugins/include/float.inc index 5370de5e..885c16c5 100755 --- a/plugins/include/float.inc +++ b/plugins/include/float.inc @@ -176,4 +176,38 @@ stock bool:operator!(Float:oper) /* forbidden operations */ forward operator%(Float:oper1, Float:oper2); forward operator%(Float:oper1, oper2); -forward operator%(oper1, Float:oper2); \ No newline at end of file +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; +} diff --git a/plugins/include/hlsdk_const.inc b/plugins/include/hlsdk_const.inc index 112773a8..397db13e 100644 --- a/plugins/include/hlsdk_const.inc +++ b/plugins/include/hlsdk_const.inc @@ -466,3 +466,16 @@ #define HLW_SNARK 15 #define HLW_SUIT 31 #define HLW_ALLWEAPONS (~(1<4 + * Team 0 will always return 0 + * Any other team will result in an error + */ +native tfc_is_team_ally(TeamA,TeamB); diff --git a/plugins/include/tsfun.inc b/plugins/include/tsfun.inc index f30fba16..5fbb6a50 100755 --- a/plugins/include/tsfun.inc +++ b/plugins/include/tsfun.inc @@ -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); diff --git a/plugins/plmenu.sma b/plugins/plmenu.sma index 172aee99..c10e5857 100755 --- a/plugins/plmenu.sma +++ b/plugins/plmenu.sma @@ -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() diff --git a/plugins/testsuite/admins_test.sma b/plugins/testsuite/admins_test.sma new file mode 100644 index 00000000..f3edd7aa --- /dev/null +++ b/plugins/testsuite/admins_test.sma @@ -0,0 +1,123 @@ +#include + +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 (AB) 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); +} \ No newline at end of file diff --git a/plugins/tfc/plmenu.sma b/plugins/tfc/plmenu.sma index cd25edfb..1c07e5c0 100755 --- a/plugins/tfc/plmenu.sma +++ b/plugins/tfc/plmenu.sma @@ -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))