First commit of the rewrite

Doesn't build on windows for some retarded reason
This commit is contained in:
Steve Dudenhoeffer 2007-05-04 12:51:13 +00:00
parent 46bd9127fb
commit 66d7d39bee
34 changed files with 12537 additions and 0 deletions

413
dlls/hamsandwich/CString.h Normal file
View File

@ -0,0 +1,413 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef _INCLUDE_CSTRING_H
#define _INCLUDE_CSTRING_H
#include <string.h>
#include <stdio.h>
//by David "BAILOPAN" Anderson
class String
{
public:
String()
{
v = NULL;
a_size = 0;
//assign("");
}
~String()
{
if (v)
delete [] v;
}
String(const char *src)
{
v = NULL;
a_size = 0;
assign(src);
}
const char * _fread(FILE *fp)
{
Grow(512, false);
char *ret = fgets(v, 511, fp);
return ret;
}
String(const String &src)
{
v = NULL;
a_size = 0;
assign(src.c_str());
}
const char *c_str() { return v?v:""; }
const char *c_str() const { return v?v:""; }
void append(const char *t)
{
Grow(size() + strlen(t) + 1);
strcat(v, t);
}
void append(const char c)
{
size_t len = size();
Grow(len + 2);
v[len] = c;
v[len + 1] = '\0';
}
void append(String &d)
{
append(d.c_str());
}
void assign(const String &src)
{
assign(src.c_str());
}
void assign(const char *d)
{
if (!d)
{
clear();
} else {
size_t len = strlen(d);
Grow(len + 1, false);
memcpy(v, d, len);
v[len] = '\0';
}
}
void clear()
{
if (v)
v[0] = '\0';
}
int compare (const char *d) const
{
if (!v)
return strcmp("", d);
else
return strcmp(v, d);
}
//Added this for amxx inclusion
bool empty()
{
if (!v)
return true;
if (v[0] == '\0')
return true;
return false;
}
size_t size()
{
if (v)
return strlen(v);
else
return 0;
}
int find(const char c, int index = 0)
{
int len = static_cast<int>(size());
if (len < 1)
return npos;
if (index >= len || index < 0)
return npos;
int i = 0;
for (i=index; i<len; i++)
{
if (v[i] == c)
{
return i;
}
}
return npos;
}
bool is_space(int c)
{
if (c == '\f' || c == '\n' ||
c == '\t' || c == '\r' ||
c == '\v' || c == ' ')
{
return true;
}
return false;
}
void reparse_newlines()
{
size_t len = size();
int offs = 0;
char c;
if (!len)
return;
for (size_t i=0; i<len; i++)
{
c = v[i];
if (c == '^' && (i != len-1))
{
c = v[++i];
if (c == 'n')
c = '\n';
else if (c == 't')
c = '\t';
offs++;
}
v[i-offs] = c;
}
v[len-offs] = '\0';
}
void trim()
{
if (!v)
return;
unsigned int i = 0;
unsigned int j = 0;
size_t len = strlen(v);
if (len == 1)
{
if (is_space(v[i]))
{
clear();
return;
}
}
unsigned char c0 = v[0];
if (is_space(c0))
{
for (i=0; i<len; i++)
{
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
{
erase(0, i);
break;
}
}
}
len = strlen(v);
if (len < 1)
{
return;
}
if (is_space(v[len-1]))
{
for (i=len-1; i>=0; i--)
{
if (!is_space(v[i])
|| (is_space(v[i]) && i==0))
{
erase(i+1, j);
break;
}
j++;
}
}
if (len == 1)
{
if (is_space(v[0]))
{
clear();
return;
}
}
}
void erase(unsigned int start, int num = npos)
{
if (!v)
return;
unsigned int i = 0;
size_t len = size();
//check for bounds
if (num == npos || start+num > len-start)
num = len - start;
//do the erasing
bool copyflag = false;
for (i=0; i<len; i++)
{
if (i>=start && i<start+num)
{
if (i+num < len)
{
v[i] = v[i+num];
} else {
v[i] = 0;
}
copyflag = true;
} else if (copyflag) {
if (i+num < len)
{
v[i] = v[i+num];
} else {
v[i] = 0;
}
}
}
len -= num;
v[len] = 0;
}
String substr(unsigned int index, int num = npos)
{
if (!v)
{
String b("");
return b;
}
String ns;
size_t len = size();
if (index >= len || !v)
return ns;
if (num == npos)
{
num = len - index;
} else if (index+num >= len) {
num = len - index;
}
unsigned int i = 0;
unsigned int nslen = num + 2;
ns.Grow(nslen);
for (i=index; i<index+num; i++)
ns.append(v[i]);
return ns;
}
void toLower()
{
if (!v)
return;
unsigned int i = 0;
size_t len = strlen(v);
for (i=0; i<len; i++)
{
if (v[i] >= 65 && v[i] <= 90)
v[i] &= ~(1<<5);
}
}
String & operator = (const String &src)
{
assign(src);
return *this;
}
String & operator = (const char *src)
{
assign(src);
return *this;
}
char operator [] (unsigned int index)
{
if (index > size() || !v)
{
return -1;
} else {
return v[index];
}
}
int at(int a)
{
if (a < 0 || a >= (int)size() || !v)
return -1;
return v[a];
}
bool at(int at, char c)
{
if (at < 0 || at >= (int)size() || !v)
return false;
v[at] = c;
return true;
}
private:
void Grow(unsigned int d, bool copy=true)
{
if (d <= a_size)
return;
char *n = new char[d + 1];
if (copy && v)
strcpy(n, v);
if (v)
delete [] v;
else
strcpy(n, "");
v = n;
a_size = d + 1;
}
char *v;
unsigned int a_size;
public:
static const int npos = -1;
};
#endif //_INCLUDE_CSTRING_H

491
dlls/hamsandwich/CVector.h Normal file
View File

@ -0,0 +1,491 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef __CVECTOR_H__
#define __CVECTOR_H__
#include <assert.h>
// Vector
template <class T> class CVector
{
bool Grow()
{
// automatic grow
size_t newSize = m_Size * 2;
if (newSize == 0)
newSize = 8; // a good init value
T *newData = new T[newSize];
if (!newData)
return false;
if (m_Data)
{
for (size_t i=0; i<m_CurrentUsedSize; i++)
newData[i] = m_Data[i];
delete [] m_Data;
}
m_Data = newData;
m_Size = newSize;
return true;
}
bool GrowIfNeeded()
{
if (m_CurrentUsedSize >= m_Size)
return Grow();
else
return true;
}
bool ChangeSize(size_t size)
{
// change size
if (size == m_Size)
return true;
if (!size)
{
if (m_Data)
{
delete [] m_Data;
m_Data = NULL;
m_Size = 0;
}
return true;
}
T *newData = new T[size];
if (!newData)
return false;
if (m_Data)
{
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
for (size_t i=0; i<end; i++)
newData[i] = m_Data[i];
delete [] m_Data;
}
m_Data = newData;
m_Size = size;
if (m_CurrentUsedSize > m_Size)
m_CurrentUsedSize = m_Size;
return true;
}
void FreeMemIfPossible()
{
if (!m_Data)
return;
if (!m_CurrentUsedSize)
{
ChangeSize(0);
return;
}
size_t newSize = m_Size;
while (m_CurrentUsedSize <= newSize / 2)
newSize /= 2;
if (newSize != m_Size)
ChangeSize(newSize);
}
protected:
T *m_Data;
size_t m_Size;
size_t m_CurrentUsedSize;
public:
class iterator
{
protected:
T *m_Ptr;
public:
// constructors / destructors
iterator()
{
m_Ptr = NULL;
}
iterator(T * ptr)
{
m_Ptr = ptr;
}
// member functions
T * base()
{
return m_Ptr;
}
const T * base() const
{
return m_Ptr;
}
// operators
T & operator*()
{
return *m_Ptr;
}
T * operator->()
{
return m_Ptr;
}
iterator & operator++() // preincrement
{
++m_Ptr;
return (*this);
}
iterator operator++(int) // postincrement
{
iterator tmp = *this;
++m_Ptr;
return tmp;
}
iterator & operator--() // predecrement
{
--m_Ptr;
return (*this);
}
iterator operator--(int) // postdecrememnt
{
iterator tmp = *this;
--m_Ptr;
return tmp;
}
bool operator==(T * right) const
{
return (m_Ptr == right);
}
bool operator==(const iterator & right) const
{
return (m_Ptr == right.m_Ptr);
}
bool operator!=(T * right) const
{
return (m_Ptr != right);
}
bool operator!=(const iterator & right) const
{
return (m_Ptr != right.m_Ptr);
}
iterator & operator+=(size_t offset)
{
m_Ptr += offset;
return (*this);
}
iterator & operator-=(size_t offset)
{
m_Ptr -= offset;
return (*this);
}
iterator operator+(size_t offset) const
{
iterator tmp(*this);
tmp.m_Ptr += offset;
return tmp;
}
iterator operator-(size_t offset) const
{
iterator tmp(*this);
tmp.m_Ptr -= offset;
return tmp;
}
T & operator[](size_t offset)
{
return (*(*this + offset));
}
const T & operator[](size_t offset) const
{
return (*(*this + offset));
}
bool operator<(const iterator & right) const
{
return m_Ptr < right.m_Ptr;
}
bool operator>(const iterator & right) const
{
return m_Ptr > right.m_Ptr;
}
bool operator<=(const iterator & right) const
{
return m_Ptr <= right.m_Ptr;
}
bool operator>=(const iterator & right) const
{
return m_Ptr >= right.m_Ptr;
}
size_t operator-(const iterator & right) const
{
return m_Ptr - right.m_Ptr;
}
};
// constructors / destructors
CVector<T>()
{
m_Size = 0;
m_CurrentUsedSize = 0;
m_Data = NULL;
}
CVector<T>(const CVector<T> & other)
{
// copy data
m_Data = new T [other.m_CurrentUsedSize];
m_Size = other.m_CurrentUsedSize;
m_CurrentUsedSize = other.m_CurrentUsedSize;
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
m_Data[i] = other.m_Data[i];
}
~CVector<T>()
{
clear();
}
// interface
size_t size() const
{
return m_CurrentUsedSize;
}
size_t capacity() const
{
return m_Size;
}
iterator begin() const
{
return iterator(m_Data);
}
iterator end() const
{
return iterator(m_Data + m_CurrentUsedSize);
}
iterator iterAt(size_t pos)
{
if (pos > m_CurrentUsedSize)
assert(0);
return iterator(m_Data + pos);
}
bool reserve(size_t newSize)
{
if (newSize > m_Size)
return ChangeSize(newSize);
return true;
}
bool push_back(const T & elem)
{
++m_CurrentUsedSize;
if (!GrowIfNeeded())
{
--m_CurrentUsedSize;
return false;
}
m_Data[m_CurrentUsedSize - 1] = elem;
return true;
}
void pop_back()
{
--m_CurrentUsedSize;
if (m_CurrentUsedSize < 0)
m_CurrentUsedSize = 0;
FreeMemIfPossible();
}
bool resize(size_t newSize)
{
if (!ChangeSize(newSize))
return false;
m_CurrentUsedSize = newSize;
return true;
}
bool empty() const
{
return (m_CurrentUsedSize == 0);
}
T & at(size_t pos)
{
if (pos > m_CurrentUsedSize)
{
assert(0);
}
return m_Data[pos];
}
const T & at(size_t pos) const
{
if (pos > m_CurrentUsedSize)
{
assert(0);
}
return m_Data[pos];
}
T & operator[](size_t pos)
{
return at(pos);
}
const T & operator[](size_t pos) const
{
return at(pos);
}
T & front()
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[0];
}
const T & front() const
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[0];
}
T & back()
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[m_CurrentUsedSize - 1];
}
const T & back() const
{
if (m_CurrentUsedSize < 1)
{
assert(0);
}
return m_Data[m_CurrentUsedSize - 1];
}
iterator insert(iterator where, const T & value)
{
// validate iter
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
return iterator(0);
size_t ofs = where - begin();
++m_CurrentUsedSize;
if (!GrowIfNeeded())
{
--m_CurrentUsedSize;
return false;
}
where = begin() + ofs;
// Move subsequent entries
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
*(ptr + 1) = *ptr;
*where.base() = value;
return where;
}
iterator erase(iterator where)
{
// validate iter
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
return iterator(0);
size_t ofs = where - begin();
if (m_CurrentUsedSize > 1)
{
// move
T *theend = m_Data + m_CurrentUsedSize;
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
*(ptr - 1) = *ptr;
}
--m_CurrentUsedSize;
FreeMemIfPossible();
return begin() + ofs;
}
void clear()
{
m_Size = 0;
m_CurrentUsedSize = 0;
if (m_Data)
{
delete [] m_Data;
m_Data = NULL;
}
}
};
#endif // __CVECTOR_H__

101
dlls/hamsandwich/Makefile Normal file
View File

@ -0,0 +1,101 @@
#(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 amxx_api.cpp config_parser.cpp \
hook_callbacks.cpp hook_native.cpp srvcmd.cpp \
call_funcs.cpp ecall_funcs.cpp hook_create.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)

View File

@ -0,0 +1,88 @@
/* 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)
{
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

View File

@ -0,0 +1,706 @@
/* 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
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#if _MSC_VER >= 1400
#ifdef offsetof
#undef offsetof
#endif // offsetof
#endif // _MSC_VER >= 1400
#include <windows.h>
#elif defined __linux__
#include <sys/mman.h>
#include <malloc.h>
#endif
#include <stddef.h> // size_t
#include <string.h> // memcpy
#include <stdlib.h> // memalign
#include <stdio.h>
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;
int m_maxsize;
/**
* 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_maxsize=512;
m_buffer=(unsigned char *)malloc(m_maxsize);
}
else if (m_size > m_maxsize)
{
m_maxsize = m_size + 512;
m_buffer=(unsigned char *)realloc(m_buffer,m_maxsize);
}
unsigned char *dat=m_buffer+orig; // point dat to the end of the prewritten
while (orig<m_size)
{
*dat++=*src++;
orig++;
};
};
public:
TrampolineMaker()
{
m_buffer=NULL;
m_size=0;
m_mystack=0;
m_calledstack=0;
m_paramstart=0;
m_thiscall=0;
m_maxsize=0;
};
/**
* Inserts a breakpoint (int 3) into the trampoline.
*/
void Breakpoint()
{
Append(&::Trampolines::Bytecode::codeBreakpoint[0],sizeof(::Trampolines::Bytecode::codeBreakpoint));
};
/**
* Adds the "return prologue", pushes registers and prepares stack
*/
void ReturnPrologue()
{
Append(&::Trampolines::Bytecode::codeReturnPrologue[0],sizeof(::Trampolines::Bytecode::codeReturnPrologue));
m_paramstart=0;
m_thiscall=0;
};
void ThisReturnPrologue()
{
this->ReturnPrologue();
m_thiscall=1;
};
/**
* Adds the void prologue pushes registers, prepares the stack
*/
void VoidPrologue()
{
Append(&::Trampolines::Bytecode::codeVoidPrologue[0],sizeof(::Trampolines::Bytecode::codeVoidPrologue));
m_paramstart=0;
m_thiscall=0;
};
/**
* Flags this trampoline as a thiscall trampoline, and prepares the void prologue.
*/
void ThisVoidPrologue()
{
this->VoidPrologue();
m_thiscall=1;
};
/**
* Epilogue for a returning function pops registers but does not free any more of the stack!
*/
void ReturnEpilogue()
{
Append(&::Trampolines::Bytecode::codeReturnEpilogue[0],sizeof(::Trampolines::Bytecode::codeReturnEpilogue));
};
/**
* Epilogue that also frees it's estimated stack usage. Useful for stdcall/thiscall/fastcall.
*/
void ReturnEpilogueAndFree()
{
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()
{
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;
}
// Reallocate with proper flags
#if defined _WIN32
void *ret=VirtualAlloc(NULL, m_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#elif defined __linux__
void *ret=memalign(sysconf(_SC_PAGESIZE), m_size);
mprotect(ret,m_size,PROT_READ|PROT_WRITE|PROT_EXEC);
#endif
memcpy(ret, m_buffer, m_size);
m_size=0;
free(m_buffer);
m_buffer=NULL; // so we don't accidentally rewrite!
m_mystack=0;
m_calledstack=0;
m_maxsize=512;
return ret;
};
};
};
/**
* Utility to make a generic trampoline.
*/
inline void *CreateGenericTrampoline(bool thiscall, bool voidcall, int paramcount, void *extraptr, void *callee)
{
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(reinterpret_cast<int>(extraptr));
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
}
return tramp.Finish(NULL);
};
#endif // TRAMPOLINEMANAGER_H

View File

@ -0,0 +1,31 @@
#include <extdll.h>
#include "sdk/amxxmodule.h"
#include "NEW_Util.h"
edict_t *NEW_FirstEdict;
bool NEW_Initialized;
extern AMX_NATIVE_INFO RegisterNatives[];
int ReadConfig(void);
void OnAmxxAttach(void)
{
printf("LOLOL");
if (ReadConfig() > 0)
{
MF_AddNatives(RegisterNatives);
}
}
void HamCommand(void);
void OnPluginsLoaded(void)
{
NEW_Initialize(INDEXENT(0));
}
void OnMetaAttach(void)
{
REG_SVR_COMMAND("ham", HamCommand);
}

View File

@ -0,0 +1,502 @@
#include "sdk/amxxmodule.h"
#include "offsets.h"
#include "ham_utils.h"
#include "hooklist.h"
#include "CVector.h"
#include "forward.h"
#include "hook.h"
#ifdef _WIN32
#define LOL_CDECL __cdecl
#else
#define LOL_CDECL
#endif
extern CVector<Hook *> hooks[HAM_LAST_ENTRY_DONT_USE_ME_LOL];
void FailPlugin(AMX *amx, int id, int err, const char *reason);
inline void *GetFunction(void *pthis, int id)
{
void **vtbl=GetVTable(pthis, Offsets.GetBase());
int **ivtbl=(int **)vtbl;
void *func=ivtbl[hooklist[id].vtid];
// Iterate through the hooks for the id, see if the function is found
CVector<Hook *>::iterator end=hooks[id].end();
for (CVector<Hook *>::iterator i=hooks[id].begin();
i!=end;
++i)
{
// If the function points to a trampoline, then return the original
// function.
if (func==(*i)->tramp)
{
return (*i)->func;
}
}
// this is an original function
return func;
}
#define SETUP(NUMARGS) \
if (((NUMARGS + 2) * sizeof(cell)) > (unsigned)params[0]) \
{ \
MF_LogError(amx, AMX_ERR_NATIVE, "Bad arg count. Expected %d, got %d.", NUMARGS + 2, params[0] / sizeof(cell)); \
return 0; \
} \
int func=params[1]; \
int id=params[2]; \
CHECK_FUNCTION(func); \
CHECK_ENTITY(id); \
void *pv=IndexToPrivate(id);
cell LOL_CDECL Call_Void_Void(AMX *amx, cell *params)
{
SETUP(0);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
reinterpret_cast<void (*)(void *)>(GetFunction(pv, func))(pv);
#endif
return 1;
}
cell LOL_CDECL Call_Int_Void(AMX *amx, cell *params)
{
SETUP(0);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
return reinterpret_cast<int (*)(void *)>(GetFunction(pv, func))(pv);
#endif
}
cell LOL_CDECL Call_Void_Entvar(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
entvars_t *ev1=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, entvars_t *)>(GetFunction(pv, func))(pv, 0, ev1);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *)>(GetFunction(pv, func))(pv, ev1);
#endif
return 1;
}
cell LOL_CDECL Call_Void_Cbase(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
void *pv1=(INDEXENT_NEW(id3)->pvPrivateData);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, void *)>(GetFunction(pv, func))(pv, 0, pv1);
#elif defined __linux__
reinterpret_cast<void (*)(void *, void *)>(GetFunction(pv, func))(pv, pv1);
#endif
return 1;
}
cell LOL_CDECL Call_Int_Float_Int(AMX *amx, cell *params)
{
SETUP(2);
float f3=amx_ftoc2(*MF_GetAmxAddr(amx, params[3]));
int i4=*MF_GetAmxAddr(amx, params[4]);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, float, int)>(GetFunction(pv, func))(pv, 0, f3, i4);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, float, int)>(GetFunction(pv, func))(pv, f3, i4);
#endif
}
cell LOL_CDECL Call_Void_Entvar_Int(AMX *amx, cell *params)
{
SETUP(2);
int id3=*MF_GetAmxAddr(amx, params[3]);
int i4=*MF_GetAmxAddr(amx, params[4]);
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, entvars_t *, int)>(GetFunction(pv, func))(pv, 0, ev3, i4);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, int)>(GetFunction(pv, func))(pv, ev3, i4);
#endif
return 1;
}
cell LOL_CDECL Call_Int_Cbase(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
void *pv1=(INDEXENT_NEW(id3)->pvPrivateData);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, void *)>(GetFunction(pv, func))(pv, 0, pv1);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, void *)>(GetFunction(pv, func))(pv, pv1);
#endif
}
cell LOL_CDECL Call_Void_Int_Int(AMX *amx, cell *params)
{
SETUP(2);
int i3=*MF_GetAmxAddr(amx, params[3]);
int i4=*MF_GetAmxAddr(amx, params[4]);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, int, int)>(GetFunction(pv, func))(pv, 0, i3, i4);
#elif defined __linux__
reinterpret_cast<void (*)(void *, int, int)>(GetFunction(pv, func))(pv, i3, i4);
#endif
return 1;
}
cell LOL_CDECL Call_Int_Int_Str_Int(AMX *amx, cell *params)
{
SETUP(3);
int i3=*MF_GetAmxAddr(amx, params[3]);
char *sz4=MF_GetAmxString(amx, params[4], 0, NULL);
int i5=*MF_GetAmxAddr(amx, params[5]);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, int, const char *, int)>(GetFunction(pv, func))(pv, 0, i3, sz4, i5);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, int, const char *, int)>(GetFunction(pv, func))(pv, i3, sz4, i5);
#endif
}
cell LOL_CDECL Call_Int_Int(AMX *amx, cell *params)
{
SETUP(1);
int i3=*MF_GetAmxAddr(amx, params[3]);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, int)>(GetFunction(pv, func))(pv, 0, i3);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, int)>(GetFunction(pv, func))(pv, i3);
#endif
}
cell LOL_CDECL Call_Int_Entvar(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, entvars_t *)>(GetFunction(pv, func))(pv, 0, ev3);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, entvars_t *)>(GetFunction(pv, func))(pv, ev3);
#endif
}
cell LOL_CDECL Call_Int_Entvar_Entvar_Float_Int(AMX *amx, cell *params)
{
SETUP(4);
int id3=*MF_GetAmxAddr(amx, params[3]);
int id4=*MF_GetAmxAddr(amx, params[4]);
float f5=amx_ctof2(*MF_GetAmxAddr(amx, params[5]));
int i6=*MF_GetAmxAddr(amx, params[6]);
CHECK_ENTITY(id3);
CHECK_ENTITY(id4);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
entvars_t *ev4=&(INDEXENT_NEW(id4)->v);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, entvars_t *, entvars_t *, float, int)>(GetFunction(pv, func))(pv, 0, ev3, ev4, f5, i6);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, entvars_t *, entvars_t *, float, int)>(GetFunction(pv, func))(pv, ev3, ev4, f5, i6);
#endif
}
cell LOL_CDECL Call_Void_Int(AMX *amx, cell *params)
{
SETUP(1);
int i3=*MF_GetAmxAddr(amx, params[3]);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, int)>(GetFunction(pv, func))(pv, 0, i3);
#elif defined __linux__
reinterpret_cast<void (*)(void *, int)>(GetFunction(pv, func))(pv, i3);
#endif
return 1;
}
cell LOL_CDECL Call_Void_Cbase_Cbase_Int_Float(AMX *amx, cell *params)
{
SETUP(4);
int id3=*MF_GetAmxAddr(amx, params[3]);
int id4=*MF_GetAmxAddr(amx, params[4]);
int i5=*MF_GetAmxAddr(amx, params[5]);
float f6=amx_ctof(*MF_GetAmxAddr(amx, params[6]));
CHECK_ENTITY(id3);
CHECK_ENTITY(id4);
void *p3=IndexToPrivate(id3);
void *p4=IndexToPrivate(id4);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, void *, void *, int, float)>(GetFunction(pv, func))(pv, 0, p3, p4, i5, f6);
#elif defined __linux__
reinterpret_cast<void (*)(void *, void *, void *, int, float)>(GetFunction(pv, func))(pv, p3, p4, i5, f6);
#endif
return 1;
}
cell LOL_CDECL Call_Void_Entvar_Float_Vector_Trace_Int(AMX *amx, cell *params)
{
SETUP(5);
int id3=*MF_GetAmxAddr(amx, params[3]);
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
Vector v5;
TraceResult *tr6=reinterpret_cast<TraceResult *>(*MF_GetAmxAddr(amx, params[6]));
int i7=*MF_GetAmxAddr(amx, params[7]);
float *fl5=(float *)MF_GetAmxAddr(amx, params[5]);
v5.x=fl5[0];
v5.y=fl5[1];
v5.z=fl5[2];
if (tr6==NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Null traceresult provided.");
return 0;
}
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, entvars_t *, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, 0, ev3, f4, v5, tr6, i7);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, ev3, f4, v5, tr6, i7);
#endif
return 1;
}
cell LOL_CDECL Call_Void_Float_Vector_TraceResult_Int(AMX *amx, cell *params)
{
SETUP(4);
float f3=amx_ctof2(*MF_GetAmxAddr(amx, params[3]));
Vector v4;
TraceResult *tr5=reinterpret_cast<TraceResult *>(*MF_GetAmxAddr(amx, params[5]));
int i6=*MF_GetAmxAddr(amx, params[6]);
float *fl4=(float *)MF_GetAmxAddr(amx, params[4]);
v4.x=fl4[0];
v4.y=fl4[1];
v4.z=fl4[2];
if (tr5==NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Null traceresult provided.");
return 0;
}
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, 0, f3, v4, tr5, i6);
#elif defined __linux__
reinterpret_cast<void (*)(void *, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, f3, v4, tr5, i6);
#endif
return 1;
}
cell LOL_CDECL Call_Str_Void(AMX *amx, cell *params)
{
SETUP(2);
#ifdef _WIN32
char *v=reinterpret_cast<char *(__fastcall *)(void *, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
char *v=reinterpret_cast<char *(*)(void *)>(GetFunction(pv, func))(pv);
#endif
return MF_SetAmxString(amx, params[3], v == NULL ? "" : v, *MF_GetAmxAddr(amx, params[4]));
}
cell LOL_CDECL Call_Cbase_Void(AMX *amx, cell *params)
{
SETUP(0);
#ifdef _WIN32
void *ret=reinterpret_cast<void *(__fastcall *)(void *, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
void *ret=reinterpret_cast<void *(*)(void *)>(GetFunction(pv, func))(pv);
#endif
return PrivateToIndex(ret);
}
cell LOL_CDECL Call_Vector_Void(AMX *amx, cell *params)
{
SETUP(1);
#ifdef _WIN32
Vector ret=reinterpret_cast<Vector (__fastcall *)(void *, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
Vector ret=reinterpret_cast<Vector (*)(void *)>(GetFunction(pv, func))(pv);
#endif
float *out=(float *)MF_GetAmxAddr(amx, params[3]);
out[0]=ret.x;
out[1]=ret.y;
out[2]=ret.z;
return 1;
}
cell LOL_CDECL Call_Vector_pVector(AMX *amx, cell *params)
{
SETUP(2);
Vector v3;
float *fl3=(float *)MF_GetAmxAddr(amx, params[3]);
v3.x=fl3[0];
v3.y=fl3[1];
v3.z=fl3[2];
#ifdef _WIN32
Vector ret=reinterpret_cast<Vector (__fastcall *)(void *, int, Vector*)>(GetFunction(pv, func))(pv, 0, &v3);
#elif defined __linux__
Vector ret=reinterpret_cast<Vector (*)(void *, Vector*)>(GetFunction(pv, func))(pv, &v3);
#endif
float *out=(float *)MF_GetAmxAddr(amx, params[4]);
out[0]=ret.x;
out[1]=ret.y;
out[2]=ret.z;
fl3[0]=v3.x;
fl3[1]=v3.y;
fl3[2]=v3.z;
return 1;
}
cell LOL_CDECL Call_Int_pVector(AMX *amx, cell *params)
{
SETUP(1);
Vector v3;
float *fl3=(float *)MF_GetAmxAddr(amx, params[3]);
v3.x=fl3[0];
v3.y=fl3[1];
v3.z=fl3[2];
#ifdef _WIN32
int ret=reinterpret_cast<int (__fastcall *)(void *, int, Vector*)>(GetFunction(pv, func))(pv, 0, &v3);
#elif defined __linux__
int ret=reinterpret_cast<int (*)(void *, Vector*)>(GetFunction(pv, func))(pv, &v3);
#endif
fl3[0]=v3.x;
fl3[1]=v3.y;
fl3[2]=v3.z;
return ret;
}
cell LOL_CDECL Call_Void_Entvar_Float_Float(AMX *amx, cell *params)
{
SETUP(3);
int id3=*MF_GetAmxAddr(amx, params[3]);
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
float f5=amx_ctof2(*MF_GetAmxAddr(amx, params[5]));
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, entvars_t *, float, float)>(GetFunction(pv, func))(pv, 0, ev3, f4, f5);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, float, float)>(GetFunction(pv, func))(pv, ev3, f4, f5);
#endif
return 1;
}
cell LOL_CDECL Call_Int_pFloat_pFloat(AMX *amx, cell *params)
{
SETUP(2);
float f3=amx_ctof2(*MF_GetAmxAddr(amx, params[3]));
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, float*, float*)>(GetFunction(pv, func))(pv, 0, &f3, &f4);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, float*, float*)>(GetFunction(pv, func))(pv, &f3, &f4);
#endif
}
cell LOL_CDECL Call_Void_Entvar_Float(AMX *amx, cell *params)
{
SETUP(2);
int id3=*MF_GetAmxAddr(amx, params[3]);
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, entvars_t*, float)>(GetFunction(pv, func))(pv, 0, ev3, f4);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, entvars_t*, float)>(GetFunction(pv, func))(pv, ev3, f4);
#endif
}

View File

@ -0,0 +1,54 @@
#ifndef HOOK_Call_H
#define HOOK_Call_H
int Call_Void_Void(AMX *amx, cell *params);
int Call_Int_Void(AMX *amx, cell *params);
int Call_Void_Entvar(AMX *amx, cell *params);
int Call_Void_Cbase(AMX *amx, cell *params);
int Call_Int_Float_Int(AMX *amx, cell *params);
int Call_Void_Entvar_Int(AMX *amx, cell *params);
int Call_Int_Cbase(AMX *amx, cell *params);
int Call_Void_Int_Int(AMX *amx, cell *params);
int Call_Int_Int_Str_Int(AMX *amx, cell *params);
int Call_Int_Int(AMX *amx, cell *params);
int Call_Int_Entvar(AMX *amx, cell *params);
int Call_Int_Entvar_Entvar_Float_Int(AMX *amx, cell *params);
int Call_Void_Int(AMX *amx, cell *params);
int Call_Void_Cbase_Cbase_Int_Float(AMX *amx, cell *params);
int Call_Void_Entvar_Float_Vector_Trace_Int(AMX *amx, cell *params);
int Call_Void_Float_Vector_TraceResult_Int(AMX *amx, cell *params);
int Call_Str_Void(AMX *amx, cell *params);
int Call_Cbase_Void(AMX *amx, cell *params);
int Call_Vector_Void(AMX *amx, cell *params);
int Call_Vector_pVector(AMX *amx, cell *params);
int Call_Int_pVector(AMX *amx, cell *params);
int Call_Void_Entvar_Float_Float(AMX *amx, cell *params);
int Call_Int_pFloat_pFloat(AMX *amx, cell *params);
int Call_Void_Entvar_Float(AMX *amx, cell *params);
#endif

View File

@ -0,0 +1,54 @@
#ifndef CELLTOTYPE_H
#define CELLTOTYPE_H
#include <extdll.h>
#include "sdk/amxxmodule.h"
#include "CVector.h"
#include "hook.h"
#include "forward.h"
#include "ham_const.h"
#include "ham_utils.h"
inline void CellToType(const AMX*& amx, const cell& in, int& out)
{
out=static_cast<int>(in);
}
inline void CellToType(const AMX*& amx, const cell& in, float& out)
{
out=amx_ctof2(in);
}
inline void CellToType(const AMX*& amx, const cell& in, edict_t*& out)
{
out=INDEXENT_NEW(in);
}
inline void CellToType(const AMX*& amx, const cell& in, entvars_t*& out)
{
out=&(INDEXENT_NEW(in)->v);
}
inline void CellToType(const AMX*& amx, const cell& in, HLBaseEntity*& out)
{
out=(HLBaseEntity *)(INDEXENT_NEW(in)->pvPrivateData);
}
inline void CellToType(const AMX*& amx, const cell& in, Vector& out)
{
float *v=(float *)MF_GetAmxAddr(amx, in);
out.x=v[0];
out.y=v[1];
out.z=v[2];
}
inline void CellToType(const AMX*& amx, const cell& in, TraceResult*& out)
{
out=reinterpret_cast<TraceResult*>(in);
}
#endif

View File

@ -0,0 +1,690 @@
; Ham Sandwich module config file.
;
; IMPORTANT: It is highly suggested that you do not modify this file unless
; you know _exactly_ what you are doing!
;
; NOTE: Just because a mod contains a function does not means it will work
; as expected. If, for example, HamKilled() does not work as you think
; it should in Counter-Strike DO NOT FILE A BUG REPORT. This just
; exposes the function for you, whether or not it works, or how it
; works is up to plugin authors to figure out.
;
; 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 HamUse and HamePdataCbase natives
; will be registered, but the HamTakeDamage native will not register.
; In addition, any attempts to hook a function who's key is missing will
; result in the plugin failing.
;
; NOTE: The base key is only needed for the linux configs.
;
; NOTE: Any keys that begin with a modname (eg: cstrike_restart) will,
; obviously, only work on that mod and all mirrors of it (eg: czero).
;
; NOTE: If you change this file while the module is already loaded, you will
; need to restart the server for the changes to take effect. Changes to
; this file before the module is loaded will take effect when the module
; loads.
;
; NOTE: All of these offsets and settings are for the latest (at the time of
; release) legitimate version of the mod. However, there is a _chance_
; that they will work on older (and even newer) versions.
; eg: If they work on non-Steam CS 1.6 this is coincidental, if they do
; not work on non-Steam CS 1.6 this will not be officially fixed.
;
; Mirrors: These take the name of one mod, and copy all of its data to another
; name. An example of a use for this would be cstrike and czero: they
; use the same binary so all of its vtable offsets are guaranteed to
; be identical. Mirrors should always come first in the file!
;
; Version: $Id$
@mirror cstrike czero
@mirror ns nsp
@mirror esf esf_openbeta
; TODO: check these - all are estimates
@section cstrike linux
pev 0
base 0x94
spawn 2
precache 3
cstrike_restart 4
keyvalue 5
objectcaps 8
activate 9
setobjectcollisionbox 10
classify 11
deathnotice 12
traceattack 13
takedamage 14
takehealth 15
killed 16
bloodcolor 17
tracebleed 18
istriggered 19
gettogglestate 22
addpoints 23
addpointstoteam 24
addplayeritem 25
removeplayeritem 26
giveammo 27
getdelay 28
ismoving 29
overridereset 30
damagedecal 31
settogglestate 32
startsneaking 33
stopsneaking 34
oncontrols 35
issneaking 36
isalive 37
isbspmodel 38
reflectgauss 39
hastarget 40
isinworld 41
isplayer 42
isnetclient 43
teamid 44
getnexttarget 45
think 46
touch 47
use 48
blocked 49
respawn 50
updateowner 51
fbecomeprone 52
center 53
eyeposition 54
earposition 55
bodytarget 56
illumination 57
fvisible 58
fvecvisible 59
@end
@section cstrike windows
pev 4
base 0x0
spawn 0
precache 1
cstrike_restart 2
keyvalue 3
objectcaps 6
activate 7
setobjectcollisionbox 8
classify 9
deathnotice 10
traceattack 11
takedamage 12
takehealth 13
killed 14
bloodcolor 15
tracebleed 16
istriggered 17
gettogglestate 20
addpoints 21
addpointstoteam 22
addplayeritem 23
removeplayeritem 24
giveammo 25
getdelay 26
ismoving 27
overridereset 28
damagedecal 29
settogglestate 30
startsneaking 31
stopsneaking 32
oncontrols 33
issneaking 34
isalive 35
isbspmodel 36
reflectgauss 37
hastarget 38
isinworld 39
isplayer 40
isnetclient 41
teamid 42
getnexttarget 43
think 44
touch 45
use 46
blocked 47
respawn 48
updateowner 49
fbecomeprone 50
center 51
eyeposition 52
earposition 53
bodytarget 54
illumination 55
fvisible 56
fvecvisible 57
@end
@section dod linux
pev 0
base 0x154
dod_roundrespawn 2
dod_roundrespawnent 3
dod_roundstore 4
spawn 5
precache 6
keyvalue 7
objectcaps 10
activate 11
dod_areasetindex 12
dod_areasendstatus 13
objectcollisionbox 14
classify 15
deathnotice 16
dod_getstate 17
dod_getstateent 18
traceattack 19
takedamage 20
takehealth 21
killed 22
bloodcolor 23
tracebleed 24
gettogglestate 27
addpoints 28
addpointstoteam 29
addplayeritem 30
removeplayeritem 31
giveammo 32
getdelay 33
ismoving 34
overridereset 35
damagedecal 36
settogglestate 37
startsneaking 38
stopsneaking 39
oncontrols 40
issneaking 41
isalive 42
isbspmodel 43
reflectgauss 44
hastarget 45
isinworld 46
isplayer 47
isnetclient 48
teamid 49
getnexttarget 50
touch 51
think 52
use 53
blocked 54
respawn 55
updateowner 56
fbecomeprone 57
center 58
eyeposition 59
earposition 60
bodytarget 61
illumination 62
fvisible 63
fvecvisible 64
@end
@section dod windows
pev 4
base 0x0
dod_roundrespawn 0
dod_roundrespawnent 1
dod_roundstore 2
spawn 3
precache 4
keyvalue 5
objectcaps 8
activate 9
dod_areasetindex 10
dod_areasendstatus 11
objectcollisionbox 12
classify 13
deathnotice 14
dod_getstate 15
dod_getstateent 16
traceattack 17
takedamage 18
takehealth 19
killed 20
bloodcolor 21
tracebleed 22
gettogglestate 25
addpoints 26
addpointstoteam 27
addplayeritem 28
removeplayeritem 29
giveammo 30
getdelay 31
ismoving 32
overridereset 33
damagedecal 34
settogglestate 35
startsneaking 36
stopsneaking 37
oncontrols 48
issneaking 39
isalive 40
isbspmodel 41
reflectgauss 42
hastarget 43
isinworld 44
isplayer 45
isnetclient 46
teamid 47
getnexttarget 48
touch 49
think 50
use 51
blocked 52
respawn 53
updateowner 54
fbecomeprone 55
center 56
eyeposition 57
earposition 58
bodytarget 59
illumination 60
fvisible 61
fvecvisible 62
@end
; TFC Does not have the following "standard" entries in its vtable:
; addpoints, addpointstoteam
@section tfc linux
pev 0
base 0x470
spawn 3
precache 4
keyvalue 5
objectcaps 8
activate 9
setobjectcollisionbox 10
classify 11
deathnotice 12
traceattack 13
takedamage 14
takehealth 15
killed 16
bloodcolor 17
tracebleed 18
istriggered 19
gettogglestate 22
addplayeritem 23
removeplayeritem 24
giveammo 25
getdelay 26
ismoving 27
overridereset 28
damagedecal 29
settogglestate 30
startsneaking 31
stopsneaking 32
oncontrols 33
issneaking 34
isalive 35
isbspmodel 36
reflectgauss 37
hastarget 38
isinworld 39
isplayer 40
isnetclient 41
tfc_dbgetitemname 42
getnexttarget 43
think 44
touch 45
use 46
blocked 47
respawn 48
updateowner 49
fbecomeprone 50
center 51
eyeposition 52
earposition 53
bodytarget 54
illumination 55
fvisible 56
fvecvisible 57
tfc_engineeruse 58
tfc_finished 59
tfc_empexplode 60
tfc_calcempdmgrad 61
tfc_takeempblast 62
tfc_empremove 63
tfc_takeconcussionblast 64
tfc_concuss 65
@end
@section tfc windows
pev 4
base 0x0
spawn 1
precache 2
keyvalue 3
objectcaps 6
activate 7
setobjectcollisionbox 8
classify 9
deathnotice 10
traceattack 11
takedamage 12
takehealth 13
killed 14
bloodcolor 15
tracebleed 16
istriggered 17
gettogglestate 20
addplayeritem 21
removeplayeritem 22
giveammo 23
getdelay 24
ismoving 25
overridereset 26
damagedecal 27
settogglestate 28
startsneaking 29
stopsneaking 30
oncontrols 31
issneaking 32
isalive 33
isbspmodel 34
reflectgauss 35
hastarget 36
isinworld 37
isplayer 38
isnetclient 39
tfc_dbgetitemname 40
getnexttarget 41
think 42
touch 43
use 44
blocked 45
respawn 46
updateowner 47
fbecomeprone 48
center 49
eyeposition 50
earposition 51
bodytarget 52
illumination 53
fvisible 54
fvecvisible 55
tfc_engineeruse 56
tfc_finished 57
tfc_empexplode 58
tfc_calcempdmgrad 59
tfc_takeempblast 60
tfc_empremove 61
tfc_takeconcussionblast 62
tfc_concuss 63
@end
; ns's linux binary is compiled with gcc 3.3, so the "base" is 0, and pev is 4
@section ns linux
pev 4
base 0x0
spawn 1
precache 2
keyvalue 3
objectcaps 6
activate 7
setobjectcollisionbox 8
classify 9
deathnotice 10
traceattack 11
takedamage 12
takehealth 13
ns_getpointvalue 14
killed 15
ns_awardkill 16
bloodcolor 17
tracebleed 18
istriggered 19
gettogglestate 22
addpoints 23
addpointstoteam 24
addplayeritem 25
removeplayeritem 26
giveammo 27
getdelay 28
ismoving 29
overridereset 30
damagedecal 31
settogglestate 32
startsneaking 33
stopsneaking 34
oncontrols 35
issneaking 36
isalive 37
isbspmodel 38
reflectgauss 39
hastarget 40
isinworld 41
isplayer 42
isnetclient 43
teamid 44
ns_resetentity 46
getnexttarget 47
think 48
touch 49
use 50
blocked 51
ns_updateonremove 52
respawn 53
updateowner 54
fbecomeprone 55
center 56
eyeposition 57
earposition 58
bodytarget 59
illumination 60
fvisible 61
fvecvisible 62
@end
@section ns windows
pev 4
base 0x0
spawn 0
precache 1
keyvalue 2
objectcaps 5
activate 6
setobjectcollisionbox 7
classify 8
deathnotice 9
traceattack 10
takedamage 11
takehealth 12
ns_getpointvalue 13
killed 14
ns_awardkill 15
bloodcolor 16
tracebleed 17
istriggered 18
gettogglestate 21
addpoints 22
addpointstoteam 23
addplayeritem 24
removeplayeritem 25
giveammo 26
getdelay 27
ismoving 28
overridereset 29
damagedecal 30
settogglestate 31
startsneaking 32
stopsneaking 33
oncontrols 34
issneaking 35
isalive 36
isbspmodel 37
reflectgauss 38
hastarget 39
isinworld 40
isplayer 41
isnetclient 42
teamid 43
ns_resetentity 45
getnexttarget 46
think 47
touch 48
use 49
blocked 50
ns_updateonremove 51
respawn 52
updateowner 53
fbecomeprone 54
center 55
eyeposition 56
earposition 57
bodytarget 58
illumination 59
fvisible 60
fvecvisible 61
@end
@section ts linux
pev 0
base 0x60
ts_breakablerespawn 2
ts_canusedthroughwalls 3
ts_respawnwait 4
spawn 5
precache 6
keyvalue 7
objectcaps 10
activate 11
setobjectcollisionbox 12
classify 13
deathnotice 14
traceattack 15
takedamage 16
takehealth 17
killed 18
bloodcolor 19
tracebleed 20
istriggered 21
gettogglestate 24
addpoints 25
addpointstoteam 26
addplayeritem 27
removeplayeritem 28
giveammo 29
getdelay 30
ismoving 31
overridereset 32
damagedecal 33
settogglestate 34
startsneaking 35
stopsneaking 36
oncontrols 37
issneaking 38
isalive 39
isbspmodel 40
reflectgauss 41
hastarget 42
isinworld 43
isplayer 44
isnetclient 45
teamid 46
getnexttarget 47
think 48
touch 49
use 50
blocked 51
respawn 52
updateowner 53
fbecomeprone 54
center 55
eyeposition 56
earposition 57
bodytarget 58
illumination 59
fvisible 60
fvecvisible 61
@end
@section ts windows
pev 4
base 0x0
ts_breakablerespawn 0
ts_canusedthroughwalls 1
ts_respawnwait 2
spawn 3
precache 4
keyvalue 5
objectcaps 8
activate 9
setobjectcollisionbox 10
classify 11
deathnotice 12
traceattack 13
takedamage 14
takehealth 15
killed 16
bloodcolor 17
tracebleed 18
istriggered 19
gettogglestate 22
addpoints 23
addpointstoteam 24
addplayeritem 25
removeplayeritem 26
giveammo 27
getdelay 28
ismoving 29
overridereset 30
damagedecal 31
settogglestate 32
startsneaking 33
stopsneaking 34
oncontrols 35
issneaking 36
isalive 37
isbspmodel 38
reflectgauss 39
hastarget 40
isinworld 41
isplayer 42
isnetclient 43
teamid 44
getnexttarget 45
think 46
touch 47
use 48
blocked 49
respawn 50
updateowner 51
fbecomeprone 52
center 53
eyeposition 54
earposition 55
bodytarget 56
illumination 57
fvisible 58
fvecvisible 59
@end
; Sven-Coop has no linux binaries. This makes disassembly much harder.
@section svencoop windows
pev 4
base 0x0
takedamage 11
use 46
@end
; ESF also has no linux binaries.
@section esf windows
pev 4
base 0x0
takedamage 12
use 46
@end

View File

@ -0,0 +1,369 @@
#include "sdk/amxxmodule.h"
#include "ham_const.h"
#include "hooklist.h"
#include "offsets.h"
extern hook_t hooklist[];
enum
{
LEX_INVALID = 0,
LEX_UNKNOWN,
LEX_START_SEC,
LEX_END_SEC,
LEX_MIRROR,
LEX_PEV,
LEX_BASE,
LEX_END
};
const char *tokens[] =
{
"", // LEX_INVALID
"", // LEX_UNKNOWN
"@section", // LEX_START_SEC
"@end", // LEX_END_SEC
"@mirror", // LEX_MIRROR
"pev", // LEX_PEV
"base", // LEX_BASE
"", // LEX_END
};
static void trim_line(char *input);
static void read_mirror(char *input);
static void skip_to_end_of_section(FILE *fp);
static int lex(char*& buffer);
int lex(char*& buffer)
{
trim_line(buffer);
size_t len;
for (int i=0; i<LEX_END; i++)
{
if (tokens[i]!=NULL && *(tokens[i])!='\0')
{
len=strlen(tokens[i]);
if (strncmp(buffer,tokens[i],len)==0)
{
buffer+=len+1;
return i;
}
}
}
return LEX_UNKNOWN;
}
// How we handle "mirrors"
// We just note down the current mod name, and every time
// we come across a mirror with the destination that matches
// the current mod name, we change the current mod name to
// the source for that mirror.
char CurrentModName[64];
static void read_mirror(char *input)
{
char *data=input;
char *data2;
char source[64];
char dest[64];
char old;
while ( *data!=' ' &&
*data!='\t' &&
*data!='\0')
{
data++;
}
old=*data;
*data='\0';
// mark down the source
snprintf(source, sizeof(source)-1, "%s", input);
*data=old;
while ( *data==' ' ||
*data=='\t')
{
data++;
}
data2=data;
while ( *data!=' ' &&
*data!='\t' &&
*data!='\0')
{
data++;
}
old=*data;
*data='\0';
snprintf(dest, sizeof(dest)-1, "%s", data2);
*data=old;
if (strcmp(dest, CurrentModName)==0)
{
snprintf(CurrentModName, sizeof(CurrentModName)-1, "%s", dest);
}
}
static void trim_line(char *input)
{
char *oldinput=input;
char *start=input;
while ( *start==' ' ||
*start=='\t')
{
start++;
}
// Overwrite the whitespace
if (start != input)
{
while ((*input++=*start++)!='\0')
/* do nothing */ ;
}
start=oldinput;
start+=strlen(start) - 1;
while ( start > oldinput &&
( *start == '\0' ||
*start == ' ' ||
*start == '\r' ||
*start == '\n' ||
*start == '\t'))
{
start--;
}
start++;
*start='\0';
// Now find any comments and cut off at the start
while (*start != '\0')
{
if (*start == ';')
{
*start='\0';
break;
}
start++;
}
}
void skip_to_end_of_section(FILE *fp)
{
char buffer[1024];
while (!feof(fp))
{
buffer[0]='\0';
fgets(buffer, sizeof(buffer)-1, fp);
trim_line(buffer);
char *b=&buffer[0];
if (lex(b)==LEX_END_SEC)
{
break;
}
}
}
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;
}
int read_start_section(char *data)
{
printf("Section: %s\n", data);
if (strncmp(data, CurrentModName, strlen(CurrentModName))==0)
{
data+=strlen(CurrentModName)+1;
trim_line(data);
#ifdef _WIN32
if (strcmp(data, "windows")==0)
#elif defined __linux__
if (strcmp(data, "linux")==0)
#endif
{
return 1;
}
}
return 0;
}
int read_number(char *input)
{
char *end; /* Temporary pointer, needed for strtoul(). */
// if begins with 0x or 0X it's to be interpretted as hex
if (*input=='0' &&
(*(input+1)=='x' || *(input+1)=='X'))
{
return strtoul(input,&end,16);
}
// otherwise it's to be interpretted as base 10
return strtoul(input,&end,10);
}
void process_pev(char *data)
{
trim_line(data);
Offsets.SetPev(read_number(data));
}
void process_base(char *data)
{
trim_line(data);
Offsets.SetBase(read_number(data));
}
void process_key(char *data)
{
size_t size=0;
char *a=data;
while (*a != ' ' && *a != '\t' && *a != '\0')
{
a++;
size++;
}
int set=0;
for (int i=0; i< HAM_LAST_ENTRY_DONT_USE_ME_LOL; i++)
{
if (strncmp(data, hooklist[i].name, size)==0)
{
data+=size+1;
trim_line(data);
int value=read_number(data);
hooklist[i].isset=1;
hooklist[i].vtid=value;
printf("setting \"%s\" to %d", hooklist[i].name, hooklist[i].vtid);
set=1;
break;
}
}
if (set==0)
{
printf("stray key in process_key: %s", data);
}
}
int ReadConfig(void)
{
char FileName[512];
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");
snprintf(CurrentModName, sizeof(CurrentModName)-1, "%s", MF_GetModname());
if (!fp)
{
MF_Log("Unable to open \"%s\" for reading.", FileName);
return -1;
}
char data[2048];
int insec=0;
while (!feof(fp))
{
data[0]='\0';
fgets(data, sizeof(data)-1, fp);
char *b=&data[0];
switch(lex(b))
{
case LEX_PEV:
{
if (insec)
{
process_pev(b);
}
break;
};
case LEX_BASE:
{
if (insec)
{
process_base(b);
}
break;
};
case LEX_MIRROR:
{
read_mirror(b);
break;
};
case LEX_START_SEC:
{
insec=read_start_section(b);
if (!insec)
{
skip_to_end_of_section(fp);
}
break;
};
case LEX_END_SEC:
{
insec=0;
break;
};
case LEX_UNKNOWN:
{
if (insec)
{
process_key(b);
}
};
}
}
return 1;
}

View File

@ -0,0 +1,479 @@
#include "sdk/amxxmodule.h"
#include "offsets.h"
#include "ham_utils.h"
#include "hooklist.h"
#include "CVector.h"
#include "forward.h"
#include "hook.h"
extern CVector<Hook *> hooks[HAM_LAST_ENTRY_DONT_USE_ME_LOL];
void FailPlugin(AMX *amx, int id, int err, const char *reason);
inline void *GetFunction(void *pthis, int id)
{
void **vtbl=GetVTable(pthis, Offsets.GetBase());
int **ivtbl=(int **)vtbl;
void *func=ivtbl[hooklist[id].vtid];
return func;
}
#define SETUP(NUMARGS) \
if (((NUMARGS + 2) * sizeof(cell)) > (unsigned)params[0]) \
{ \
MF_LogError(amx, AMX_ERR_NATIVE, "Bad arg count. Expected %d, got %d.", NUMARGS + 2, params[0] / sizeof(cell)); \
return 0; \
} \
int func=params[1]; \
int id=params[2]; \
CHECK_FUNCTION(func); \
CHECK_ENTITY(id); \
void *pv=IndexToPrivate(id);
cell eCall_Void_Void(AMX *amx, cell *params)
{
SETUP(0);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
reinterpret_cast<void (*)(void *)>(GetFunction(pv, func))(pv);
#endif
return 1;
}
cell eCall_Int_Void(AMX *amx, cell *params)
{
SETUP(0);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
return reinterpret_cast<int (*)(void *)>(GetFunction(pv, func))(pv);
#endif
}
cell eCall_Void_Entvar(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
entvars_t *ev1=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, entvars_t *)>(GetFunction(pv, func))(pv, 0, ev1);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *)>(GetFunction(pv, func))(pv, ev1);
#endif
return 1;
}
cell eCall_Void_Cbase(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
void *pv1=(INDEXENT_NEW(id3)->pvPrivateData);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, void *)>(GetFunction(pv, func))(pv, 0, pv1);
#elif defined __linux__
reinterpret_cast<void (*)(void *, void *)>(GetFunction(pv, func))(pv, pv1);
#endif
return 1;
}
cell eCall_Int_Float_Int(AMX *amx, cell *params)
{
SETUP(2);
float f3=amx_ftoc2(*MF_GetAmxAddr(amx, params[3]));
int i4=*MF_GetAmxAddr(amx, params[4]);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, float, int)>(GetFunction(pv, func))(pv, 0, f3, i4);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, float, int)>(GetFunction(pv, func))(pv, f3, i4);
#endif
}
cell eCall_Void_Entvar_Int(AMX *amx, cell *params)
{
SETUP(2);
int id3=*MF_GetAmxAddr(amx, params[3]);
int i4=*MF_GetAmxAddr(amx, params[4]);
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, entvars_t *, int)>(GetFunction(pv, func))(pv, 0, ev3, i4);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, int)>(GetFunction(pv, func))(pv, ev3, i4);
#endif
return 1;
}
cell eCall_Int_Cbase(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
void *pv1=(INDEXENT_NEW(id3)->pvPrivateData);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, void *)>(GetFunction(pv, func))(pv, 0, pv1);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, void *)>(GetFunction(pv, func))(pv, pv1);
#endif
}
cell eCall_Void_Int_Int(AMX *amx, cell *params)
{
SETUP(2);
int i3=*MF_GetAmxAddr(amx, params[3]);
int i4=*MF_GetAmxAddr(amx, params[4]);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void*, int, int, int)>(GetFunction(pv, func))(pv, 0, i3, i4);
#elif defined __linux__
reinterpret_cast<void (*)(void *, int, int)>(GetFunction(pv, func))(pv, i3, i4);
#endif
return 1;
}
cell eCall_Int_Int_Str_Int(AMX *amx, cell *params)
{
SETUP(3);
int i3=*MF_GetAmxAddr(amx, params[3]);
char *sz4=MF_GetAmxString(amx, params[4], 0, NULL);
int i5=*MF_GetAmxAddr(amx, params[5]);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, int, const char *, int)>(GetFunction(pv, func))(pv, 0, i3, sz4, i5);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, int, const char *, int)>(GetFunction(pv, func))(pv, i3, sz4, i5);
#endif
}
cell eCall_Int_Int(AMX *amx, cell *params)
{
SETUP(1);
int i3=*MF_GetAmxAddr(amx, params[3]);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void*, int, int)>(GetFunction(pv, func))(pv, 0, i3);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, int)>(GetFunction(pv, func))(pv, i3);
#endif
}
cell eCall_Int_Entvar(AMX *amx, cell *params)
{
SETUP(1);
int id3=*MF_GetAmxAddr(amx, params[3]);
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, entvars_t *)>(GetFunction(pv, func))(pv, 0, ev3);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, entvars_t *)>(GetFunction(pv, func))(pv, ev3);
#endif
}
cell eCall_Int_Entvar_Entvar_Float_Int(AMX *amx, cell *params)
{
SETUP(4);
int id3=*MF_GetAmxAddr(amx, params[3]);
int id4=*MF_GetAmxAddr(amx, params[4]);
float f5=amx_ctof2(*MF_GetAmxAddr(amx, params[5]));
int i6=*MF_GetAmxAddr(amx, params[6]);
CHECK_ENTITY(id3);
CHECK_ENTITY(id4);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
entvars_t *ev4=&(INDEXENT_NEW(id4)->v);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, entvars_t *, entvars_t *, float, int)>(GetFunction(pv, func))(pv, 0, ev3, ev4, f5, i6);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, entvars_t *, entvars_t *, float, int)>(GetFunction(pv, func))(pv, ev3, ev4, f5, i6);
#endif
}
cell eCall_Void_Int(AMX *amx, cell *params)
{
SETUP(1);
int i3=*MF_GetAmxAddr(amx, params[3]);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, int)>(GetFunction(pv, func))(pv, 0, i3);
#elif defined __linux__
reinterpret_cast<void (*)(void *, int)>(GetFunction(pv, func))(pv, i3);
#endif
return 1;
}
cell eCall_Void_Cbase_Cbase_Int_Float(AMX *amx, cell *params)
{
SETUP(4);
int id3=*MF_GetAmxAddr(amx, params[3]);
int id4=*MF_GetAmxAddr(amx, params[4]);
int i5=*MF_GetAmxAddr(amx, params[5]);
float f6=amx_ctof(*MF_GetAmxAddr(amx, params[6]));
CHECK_ENTITY(id3);
CHECK_ENTITY(id4);
void *p3=IndexToPrivate(id3);
void *p4=IndexToPrivate(id4);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, void *, void *, int, float)>(GetFunction(pv, func))(pv, 0, p3, p4, i5, f6);
#elif defined __linux__
reinterpret_cast<void (*)(void *, void *, void *, int, float)>(GetFunction(pv, func))(pv, p3, p4, i5, f6);
#endif
return 1;
}
cell eCall_Void_Entvar_Float_Vector_Trace_Int(AMX *amx, cell *params)
{
SETUP(5);
int id3=*MF_GetAmxAddr(amx, params[3]);
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
Vector v5;
TraceResult *tr6=reinterpret_cast<TraceResult *>(*MF_GetAmxAddr(amx, params[6]));
int i7=*MF_GetAmxAddr(amx, params[7]);
float *fl5=(float *)MF_GetAmxAddr(amx, params[5]);
v5.x=fl5[0];
v5.y=fl5[1];
v5.z=fl5[2];
if (tr6==NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Null traceresult provided.");
return 0;
}
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, entvars_t *, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, 0, ev3, f4, v5, tr6, i7);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, ev3, f4, v5, tr6, i7);
#endif
return 1;
}
cell eCall_Void_Float_Vector_TraceResult_Int(AMX *amx, cell *params)
{
SETUP(4);
float f3=amx_ctof2(*MF_GetAmxAddr(amx, params[3]));
Vector v4;
TraceResult *tr5=reinterpret_cast<TraceResult *>(*MF_GetAmxAddr(amx, params[5]));
int i6=*MF_GetAmxAddr(amx, params[6]);
float *fl4=(float *)MF_GetAmxAddr(amx, params[4]);
v4.x=fl4[0];
v4.y=fl4[1];
v4.z=fl4[2];
if (tr5==NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Null traceresult provided.");
return 0;
}
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, 0, f3, v4, tr5, i6);
#elif defined __linux__
reinterpret_cast<void (*)(void *, float, Vector, TraceResult *, int)>(GetFunction(pv, func))(pv, f3, v4, tr5, i6);
#endif
return 1;
}
cell eCall_Str_Void(AMX *amx, cell *params)
{
SETUP(2);
#ifdef _WIN32
char *v=reinterpret_cast<char *(__fastcall *)(void *, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
char *v=reinterpret_cast<char *(*)(void *)>(GetFunction(pv, func))(pv);
#endif
return MF_SetAmxString(amx, params[3], v == NULL ? "" : v, *MF_GetAmxAddr(amx, params[4]));
}
cell eCall_Cbase_Void(AMX *amx, cell *params)
{
SETUP(0);
#ifdef _WIN32
void *ret=reinterpret_cast<void *(__fastcall *)(void *, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
void *ret=reinterpret_cast<void *(*)(void *)>(GetFunction(pv, func))(pv);
#endif
return PrivateToIndex(ret);
}
cell eCall_Vector_Void(AMX *amx, cell *params)
{
SETUP(1);
#ifdef _WIN32
Vector ret=reinterpret_cast<Vector (__fastcall *)(void *, int)>(GetFunction(pv, func))(pv, 0);
#elif defined __linux__
Vector ret=reinterpret_cast<Vector (*)(void *)>(GetFunction(pv, func))(pv);
#endif
float *out=(float *)MF_GetAmxAddr(amx, params[3]);
out[0]=ret.x;
out[1]=ret.y;
out[2]=ret.z;
return 1;
}
cell eCall_Vector_pVector(AMX *amx, cell *params)
{
SETUP(2);
Vector v3;
float *fl3=(float *)MF_GetAmxAddr(amx, params[3]);
v3.x=fl3[0];
v3.y=fl3[1];
v3.z=fl3[2];
#ifdef _WIN32
Vector ret=reinterpret_cast<Vector (__fastcall *)(void *, int, Vector*)>(GetFunction(pv, func))(pv, 0, &v3);
#elif defined __linux__
Vector ret=reinterpret_cast<Vector (*)(void *, Vector*)>(GetFunction(pv, func))(pv, &v3);
#endif
float *out=(float *)MF_GetAmxAddr(amx, params[4]);
out[0]=ret.x;
out[1]=ret.y;
out[2]=ret.z;
fl3[0]=v3.x;
fl3[1]=v3.y;
fl3[2]=v3.z;
return 1;
}
cell eCall_Int_pVector(AMX *amx, cell *params)
{
SETUP(1);
Vector v3;
float *fl3=(float *)MF_GetAmxAddr(amx, params[3]);
v3.x=fl3[0];
v3.y=fl3[1];
v3.z=fl3[2];
#ifdef _WIN32
int ret=reinterpret_cast<int (__fastcall *)(void *, int, Vector*)>(GetFunction(pv, func))(pv, 0, &v3);
#elif defined __linux__
int ret=reinterpret_cast<int (*)(void *, Vector*)>(GetFunction(pv, func))(pv, &v3);
#endif
fl3[0]=v3.x;
fl3[1]=v3.y;
fl3[2]=v3.z;
return ret;
}
cell eCall_Void_Entvar_Float_Float(AMX *amx, cell *params)
{
SETUP(3);
int id3=*MF_GetAmxAddr(amx, params[3]);
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
float f5=amx_ctof2(*MF_GetAmxAddr(amx, params[5]));
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
reinterpret_cast<void (__fastcall *)(void *, int, entvars_t *, float, float)>(GetFunction(pv, func))(pv, 0, ev3, f4, f5);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, float, float)>(GetFunction(pv, func))(pv, ev3, f4, f5);
#endif
return 1;
}
cell eCall_Int_pFloat_pFloat(AMX *amx, cell *params)
{
SETUP(2);
float f3=amx_ctof2(*MF_GetAmxAddr(amx, params[3]));
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, float*, float*)>(GetFunction(pv, func))(pv, 0, &f3, &f4);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, float*, float*)>(GetFunction(pv, func))(pv, &f3, &f4);
#endif
}
cell eCall_Void_Entvar_Float(AMX *amx, cell *params)
{
SETUP(2);
int id3=*MF_GetAmxAddr(amx, params[3]);
float f4=amx_ctof2(*MF_GetAmxAddr(amx, params[4]));
CHECK_ENTITY(id3);
entvars_t *ev3=&(INDEXENT_NEW(id3)->v);
#ifdef _WIN32
return reinterpret_cast<int (__fastcall *)(void *, int, entvars_t*, float)>(GetFunction(pv, func))(pv, 0, ev3, f4);
#elif defined __linux__
return reinterpret_cast<int (*)(void *, entvars_t*, float)>(GetFunction(pv, func))(pv, ev3, f4);
#endif
}

View File

@ -0,0 +1,54 @@
#ifndef HOOK_ECALL_H
#define HOOK_ECALL_H
int eCall_Void_Void(AMX *amx, cell *params);
int eCall_Int_Void(AMX *amx, cell *params);
int eCall_Void_Entvar(AMX *amx, cell *params);
int eCall_Void_Cbase(AMX *amx, cell *params);
int eCall_Int_Float_Int(AMX *amx, cell *params);
int eCall_Void_Entvar_Int(AMX *amx, cell *params);
int eCall_Int_Cbase(AMX *amx, cell *params);
int eCall_Void_Int_Int(AMX *amx, cell *params);
int eCall_Int_Int_Str_Int(AMX *amx, cell *params);
int eCall_Int_Int(AMX *amx, cell *params);
int eCall_Int_Entvar(AMX *amx, cell *params);
int eCall_Int_Entvar_Entvar_Float_Int(AMX *amx, cell *params);
int eCall_Void_Int(AMX *amx, cell *params);
int eCall_Void_Cbase_Cbase_Int_Float(AMX *amx, cell *params);
int eCall_Void_Entvar_Float_Vector_Trace_Int(AMX *amx, cell *params);
int eCall_Void_Float_Vector_TraceResult_Int(AMX *amx, cell *params);
int eCall_Str_Void(AMX *amx, cell *params);
int eCall_Cbase_Void(AMX *amx, cell *params);
int eCall_Vector_Void(AMX *amx, cell *params);
int eCall_Vector_pVector(AMX *amx, cell *params);
int eCall_Int_pVector(AMX *amx, cell *params);
int eCall_Void_Entvar_Float_Float(AMX *amx, cell *params);
int eCall_Int_pFloat_pFloat(AMX *amx, cell *params);
int eCall_Void_Entvar_Float(AMX *amx, cell *params);
#endif

View File

@ -0,0 +1,40 @@
#include "sdk/amxxmodule.h"
#ifndef FORWARD_H
#define FORWARD_H
enum fwdstate
{
FSTATE_INVALID = 0,
FSTATE_OK,
FSTATE_PAUSE,
FSTATE_STOP,
FSTATE_DESTROY
};
class Forward
{
public:
int id; // id of the forward
fwdstate state;
Forward(int id_) : id(id_), state(FSTATE_OK)
{
/* do nothing */
};
Forward() : id(-1), state(FSTATE_INVALID)
{
/* do nothing */
}
~Forward()
{
MF_UnregisterSPForward(id);
}
inline void Set(int i)
{
state=FSTATE_OK;
id=i;
};
};
#endif

View File

@ -0,0 +1,113 @@
#ifndef HAM_CONST_H
#define HAM_CONST_H
enum
{
HAM_UNSET = 0,
HAM_IGNORED,
HAM_HANDLED,
HAM_OVERRIDE,
HAM_SUPERCEDE
};
enum
{
Ham_Spawn = 0,
Ham_Precache,
Ham_Keyvalue,
Ham_ObjectCaps,
Ham_Activate,
Ham_SetObjectCollisionBox,
Ham_Classify,
Ham_DeathNotice,
Ham_TraceAttack,
Ham_TakeDamage,
Ham_TakeHealth,
Ham_Killed,
Ham_BloodColor,
Ham_TraceBleed,
Ham_IsTriggered,
Ham_GetToggleState,
Ham_AddPoints,
Ham_AddPointsToTeam,
Ham_AddPlayerItem,
Ham_RemovePlayerItem,
Ham_GiveAmmo,
Ham_GetDelay,
Ham_IsMoving,
Ham_OverrideReset,
Ham_DamageDecal,
Ham_SetToggleState,
Ham_StartSneaking,
Ham_StopSneaking,
Ham_OnControls,
Ham_IsSneaking,
Ham_IsAlive,
Ham_IsBSPModel,
Ham_ReflectGauss,
Ham_HasTarget,
Ham_IsInWorld,
Ham_IsPlayer,
Ham_IsNetClient,
Ham_TeamId,
Ham_GetNextTarget,
Ham_Think,
Ham_Touch,
Ham_Use,
Ham_Blocked,
Ham_Respawn,
Ham_UpdateOwner,
Ham_FBecomeProne,
Ham_Center,
Ham_EyePosition,
Ham_EarPosition,
Ham_BodyTarget,
Ham_Illumination,
Ham_FVisible,
Ham_FVecVisible,
Ham_TS_BreakableRespawn,
Ham_TS_CanUsedThroughWalls,
Ham_TS_RespawnWait,
Ham_CS_Restart,
Ham_DOD_RoundRespawn,
Ham_DOD_RoundRespawnEnt,
Ham_DOD_RoundStore,
Ham_DOD_AreaSetIndex,
Ham_DOD_AreaSendStatus,
Ham_DOD_GetState,
Ham_DOD_GetStateEnt,
Ham_TFC_DbGetItemName,
Ham_TFC_EngineerUse,
Ham_TFC_Finished,
Ham_TFC_EmpExplode,
Ham_TFC_CalcEmpDmgRad,
Ham_TFC_TakeEmpBlast,
Ham_TFC_EmpRemove,
Ham_TFC_TakeConcussionBlast,
Ham_TFC_Concuss,
Ham_NS_GetPointValue,
Ham_NS_AwardKill,
Ham_NS_ResetEntity,
Ham_NS_UpdateOnRemove,
HAM_LAST_ENTRY_DONT_USE_ME_LOL
};
enum
{
HAM_OK = 0,
HAM_INVALID_FUNC, // The function is not valid
HAM_FUNC_NOT_CONFIGURED, // This function is not configured in hamdata.ini
HAM_ERR_END
};
#endif

View File

@ -0,0 +1,124 @@
#ifndef HAM_UTILS_H
#define HAM_UTILS_H
#include "sdk/amxxmodule.h"
#include "offsets.h"
#include "NEW_Util.h"
#define CHECK_FUNCTION(x) \
if (x < 0 || x > HAM_LAST_ENTRY_DONT_USE_ME_LOL) { \
FailPlugin(amx, x, HAM_INVALID_FUNC, "Function out of bounds."); \
return 0; \
} else if (hooklist[x].isset == 0) { \
FailPlugin(amx, x, HAM_FUNC_NOT_CONFIGURED, "Function not configured in hamdata.ini"); \
return 0; \
}
#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 (INDEXENT_NEW(x)->free) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid entity (%d)", x); \
return 0; \
} else if (INDEXENT_NEW(x)->pvPrivateData == NULL) { \
MF_LogError(amx, AMX_ERR_NATIVE, "Entity has null private data (%d)", x); \
return 0; \
} \
}
inline edict_t *PrivateToEdict(const void *pdata)
{
if (!pdata)
{
return NULL;
}
char *ptr=(char*)pdata + Offsets.GetPev();
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+=Offsets.GetPev();
entvars_t *pev=*(entvars_t **)ptr;
if (pev==NULL)
{
return -1;
}
if (pev->pContainingEntity==NULL)
{
return -1;
}
return ENTINDEX_NEW(pev->pContainingEntity);
};
inline void *IndexToPrivate(int index)
{
return INDEXENT_NEW(index)->pvPrivateData;
};
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+=Offsets.GetBase();
return *((void ***)btbl);
};
inline void **GetVTable(void *pthis, int size)
{
return *((void***)(((char*)pthis)+size));
}
inline void *GetVTableEntry(void *pthis, int ventry, int size)
{
void **vtbl=GetVTable(pthis, size);
return vtbl[ventry];
}
void print_srvconsole(char *fmt, ...);
#endif

80
dlls/hamsandwich/hook.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef HOOK_H
#define HOOK_H
#include "forward.h"
#include "Trampolines.h"
// This is just a simple container for data so I only have to add 1 extra
// parameter to calls that get trampolined
class Hook
{
public:
CVector<Forward *> pre; // pre forwards
CVector<Forward *> post; // post forwards
void *func; // original function
void **vtable; // vtable of the original location
int entry; // vtable entry of the function
void *target; // target function being called (the hook)
int exec; // 1 when this hook is in execution
int del; // 1 if this hook should be destroyed after exec
void *tramp; // trampoline for this hook
char *ent; // ent name that's being hooked
Hook(void **vtable_, int entry_, void *target_, bool voidcall, int paramcount, char *name) :
func(NULL), vtable(vtable_), entry(entry_), target(target_), exec(0), del(0), tramp(NULL)
{
// original function is vtable[entry]
// to not make the compiler whine, cast vtable to int **
int **ivtable=(int **)vtable;
func=(void *)ivtable[entry];
// now install a trampoline
// (int thiscall, int voidcall, int paramcount, void *extraptr)
tramp=CreateGenericTrampoline(true, voidcall, paramcount, (void*)this, target);
// Insert into vtable
#if defined _WIN32
DWORD OldFlags;
VirtualProtect(&ivtable[entry],sizeof(int*),PAGE_READWRITE,&OldFlags);
#elif defined __linux__
mprotect(&ivtable[entry],sizeof(int*),PROT_READ|PROT_WRITE);
#endif
ivtable[entry]=(int*)tramp;
size_t len=strlen(name);
ent=new char[len+1];
snprintf(ent,len+1,"%s",name);
};
~Hook()
{
// Insert the original function back into the vtable
int **ivtable=(int **)vtable;
#if defined _WIN32
DWORD OldFlags;
VirtualProtect(&ivtable[entry],sizeof(int*),PAGE_READWRITE,&OldFlags);
#elif defined __linux__
mprotect(&ivtable[entry],sizeof(int*),PROT_READ|PROT_WRITE);
#endif
ivtable[entry]=(int *)func;
free(tramp);
delete[] ent;
CVector<Forward *>::iterator end=pre.end();
for (CVector<Forward *>::iterator i=pre.begin();
i!=end;
++i)
{
delete (*i);
}
}
};
#endif

View File

@ -0,0 +1,563 @@
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <extdll.h>
#include "sdk/amxxmodule.h"
#include "CVector.h"
#include "hook.h"
#include "forward.h"
#include "ham_const.h"
#include "ham_utils.h"
#define PRE_START() \
int result=HAM_UNSET; \
int thisresult=HAM_UNSET; \
int iThis=PrivateToIndex(pthis); \
CVector<Forward*>::iterator end=hook->pre.end(); \
for (CVector<Forward*>::iterator i=hook->pre.begin(); i!=end; i++) \
{ \
if ((*i)->state == FSTATE_OK) \
{ \
printf("id=%d\n",(*i)->id); \
thisresult=MF_ExecuteForward((*i)->id,iThis
#define PRE_END() \
); \
} \
if (thisresult > result) \
{ \
result=thisresult; \
} \
} \
if (result < HAM_SUPERCEDE) \
{
#define POST_START() \
} \
end=hook->post.end(); \
for (CVector<Forward*>::iterator i=hook->post.begin(); i!=end; i++)\
{ \
if ((*i)->state == FSTATE_OK) \
{ \
MF_ExecuteForward((*i)->id,iThis
#define POST_END() \
); \
} \
}
void Hook_Void_Void(Hook *hook, void *pthis)
{
PRE_START()
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*,int)>(hook->func)(pthis,0);
#elif defined __linux__
reinterpret_cast<void (*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
}
int Hook_Int_Void(Hook *hook, void *pthis)
{
int ireturn=0;
PRE_START()
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*,int)>(hook->func)(pthis,0);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
return ireturn;
}
void Hook_Void_Entvar(Hook *hook, void *pthis, entvars_t *entvar)
{
int iOther=EntvarToIndex(entvar);
PRE_START()
, iOther
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, entvars_t *)>(hook->func)(pthis, 0, entvar);
#elif defined __linux__
reinterpret_cast<void (*)(void*, entvars_t *)>(hook->func)(pthis, entvar);
#endif
POST_START()
, iOther
POST_END()
}
void Hook_Void_Cbase(Hook *hook, void *pthis, void *other)
{
int iOther=PrivateToIndex(other);
PRE_START()
, iOther
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, void *)>(hook->func)(pthis, 0, other);
#elif defined __linux__
reinterpret_cast<void (*)(void*, void *)>(hook->func)(pthis, other);
#endif
POST_START()
, iOther
POST_END()
}
int Hook_Int_Float_Int(Hook *hook, void *pthis, float f1, int i1)
{
int ireturn=0;
PRE_START()
, f1, i1
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, float, int)>(hook->func)(pthis, 0, f1, i1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, float, int)>(hook->func)(pthis, f1, i1);
#endif
POST_START()
, f1, i1
POST_END()
return ireturn;
}
void Hook_Void_Entvar_Int(Hook *hook, void *pthis, entvars_t *ev1, int i1)
{
int iOther=EntvarToIndex(ev1);
PRE_START()
, iOther, i1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, entvars_t *, int)>(hook->func)(pthis, 0, ev1, i1);
#elif defined __linux__
reinterpret_cast<void (*)(void*, entvars_t *, int)>(hook->func)(pthis, ev1, i1);
#endif
POST_START()
, iOther, i1
POST_END()
}
int Hook_Int_Cbase(Hook *hook, void *pthis, void *cb1)
{
int iOther=PrivateToIndex(cb1);
int ireturn=0;
PRE_START()
, iOther
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, void *)>(hook->func)(pthis, 0, cb1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, void *)>(hook->func)(pthis, cb1);
#endif
POST_START()
, iOther
POST_END()
return ireturn;
}
void Hook_Void_Int_Int(Hook *hook, void *pthis, int i1, int i2)
{
PRE_START()
,i1, i2
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, int, int)>(hook->func)(pthis, 0, i1, i2);
#elif defined __linux__
reinterpret_cast<void (*)(void*, int, int)>(hook->func)(pthis, i1, i2);
#endif
POST_START()
,i1, i2
POST_END()
}
int Hook_Int_Int_Str_Int(Hook *hook, void *pthis, int i1, const char *sz1, int i2)
{
int ireturn=0;
PRE_START()
,i1, sz1, i2
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, int, const char *, int)>(hook->func)(pthis, 0, i1, sz1, i2);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, int, const char *, int)>(hook->func)(pthis, i1, sz1, i2);
#endif
POST_START()
,i1, sz1, i2
POST_END()
return ireturn;
}
int Hook_Int_Int(Hook *hook, void *pthis, int i1)
{
int ireturn=0;
PRE_START()
,i1
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, int)>(hook->func)(pthis, 0, i1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, int)>(hook->func)(pthis, i1);
#endif
POST_START()
,i1
POST_END()
return ireturn;
}
int Hook_Int_Entvar(Hook *hook, void *pthis, entvars_t *ev1)
{
int ireturn=0;
int iOther=EntvarToIndex(ev1);
PRE_START()
,iOther
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, entvars_t *)>(hook->func)(pthis, 0, ev1);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, entvars_t *)>(hook->func)(pthis, ev1);
#endif
POST_START()
, iOther
POST_END()
return ireturn;
}
// Takedamage
int Hook_Int_Entvar_Entvar_Float_Int(Hook *hook, void *pthis, entvars_t *inflictor, entvars_t *attacker, float damage, int damagebits)
{
int ireturn=0;
int iInflictor=EntvarToIndex(inflictor);
int iAttacker=EntvarToIndex(attacker);
PRE_START()
,iInflictor, iAttacker, damage, damagebits
PRE_END()
#if defined _WIN32
ireturn=reinterpret_cast<int (__fastcall*)(void*, int, entvars_t *, entvars_t *, float, int)>(hook->func)(pthis, 0, inflictor, attacker, damage, damagebits);
#elif defined __linux__
ireturn=reinterpret_cast<int (*)(void*, entvars_t *, entvars_t *, float, int)>(hook->func)(pthis, inflictor, attacker, damage, damagebits);
#endif
POST_START()
,iInflictor, iAttacker, damage, damagebits
POST_END()
return ireturn;
}
void Hook_Void_Int(Hook *hook, void *pthis, int i1)
{
PRE_START()
, i1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, int)>(hook->func)(pthis, 0, i1);
#elif defined __linux__
reinterpret_cast<void (*)(void*, int)>(hook->func)(pthis, i1);
#endif
POST_START()
,i1
POST_END()
}
void Hook_Void_Cbase_Cbase_Int_Float(Hook *hook, void *pthis, void *cb1, void *cb2, int i1, float f1)
{
int iCaller=PrivateToIndex(cb1);
int iActivator=PrivateToIndex(cb2);
PRE_START()
,iCaller, iActivator, i1, f1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, void *, void *, int, float)>(hook->func)(pthis, 0, cb1, cb2, i1, f1);
#elif defined __linux__
reinterpret_cast<void (*)(void*, void *, void *, int, float)>(hook->func)(pthis, cb1, cb2, i1, f1);
#endif
POST_START()
,iCaller, iActivator, i1, f1
POST_END()
}
void Hook_Void_Entvar_Float_Vector_Trace_Int(Hook *hook, void *pthis, entvars_t *ev1, float f1, Vector v1, TraceResult *tr1, int i1)
{
int iev1=EntvarToIndex(ev1);
cell cvec[3];
cvec[0]=amx_ftoc2(v1.x);
cvec[1]=amx_ftoc2(v1.y);
cvec[2]=amx_ftoc2(v1.z);
PRE_START()
,iev1, f1, MF_PrepareCellArrayA(cvec, 3, false), tr1, i1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, entvars_t *, float, Vector, TraceResult *, int)>(hook->func)(pthis, 0, ev1, f1, v1, tr1, i1);
#elif defined __linux__
reinterpret_cast<void (*)(void*, entvars_t *, float, Vector, TraceResult *, int)>(hook->func)(pthis, ev1, f1, v1, tr1, i1);
#endif
POST_START()
, iev1, f1, MF_PrepareCellArrayA(cvec, 3, false), tr1, i1
POST_END()
}
void Hook_Void_Float_Vector_TraceResult_Int(Hook *hook, void *pthis, float f1, Vector v1, TraceResult *tr1, int i1)
{
cell cvec[3];
cvec[0]=amx_ftoc2(v1.x);
cvec[1]=amx_ftoc2(v1.y);
cvec[2]=amx_ftoc2(v1.z);
PRE_START()
, f1, MF_PrepareCellArrayA(cvec, 3, false), tr1, i1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void*, int, float, Vector, TraceResult *, int)>(hook->func)(pthis, 0, f1, v1, tr1, i1);
#elif defined __linux__
reinterpret_cast<void (*)(void*, float, Vector, TraceResult *, int)>(hook->func)(pthis, f1, v1, tr1, i1);
#endif
POST_START()
, f1, MF_PrepareCellArrayA(cvec, 3, false), tr1, i1
POST_END()
}
const char *Hook_Str_Void(Hook *hook, void *pthis)
{
const char *ret=NULL;
PRE_START()
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<const char *(__fastcall*)(void*, int)>(hook->func)(pthis, 0);
#elif defined __linux__
ret=reinterpret_cast<const char *(*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
return ret;
}
void *Hook_Cbase_Void(Hook *hook, void *pthis)
{
void *ret=NULL;
PRE_START()
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<void *(__fastcall*)(void*, int)>(hook->func)(pthis, 0);
#elif defined __linux__
ret=reinterpret_cast<void *(*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
return ret;
}
Vector Hook_Vector_Void(Hook *hook, void *pthis)
{
Vector ret;
memset(&ret, 0x0, sizeof(Vector));
PRE_START()
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<Vector (__fastcall*)(void*, int)>(hook->func)(pthis, 0);
#elif defined __linux__
ret=reinterpret_cast<Vector (*)(void*)>(hook->func)(pthis);
#endif
POST_START()
POST_END()
return ret;
}
Vector Hook_Vector_pVector(Hook *hook, void *pthis, Vector *v1)
{
Vector ret;
memset(&ret, 0x0, sizeof(Vector));
cell cv1[3];
cv1[0]=amx_ftoc2(v1->x);
cv1[1]=amx_ftoc2(v1->y);
cv1[2]=amx_ftoc2(v1->z);
PRE_START()
, MF_PrepareCellArrayA(cv1, 3, false)
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<Vector (__fastcall*)(void*, int, Vector *)>(hook->func)(pthis, 0, v1);
#elif defined __linux__
ret=reinterpret_cast<Vector (*)(void*, Vector *)>(hook->func)(pthis, v1);
#endif
POST_START()
, MF_PrepareCellArrayA(cv1, 3, false)
POST_END()
return ret;
}
int Hook_Int_pVector(Hook *hook, void *pthis, Vector *v1)
{
int ret=0;
cell cv1[3];
cv1[0]=amx_ftoc2(v1->x);
cv1[1]=amx_ftoc2(v1->y);
cv1[2]=amx_ftoc2(v1->z);
PRE_START()
, MF_PrepareCellArrayA(cv1, 3, false)
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<int (__fastcall*)(void*, int, Vector *)>(hook->func)(pthis, 0, v1);
#elif defined __linux__
ret=reinterpret_cast<int (*)(void*, Vector *)>(hook->func)(pthis, v1);
#endif
POST_START()
, MF_PrepareCellArrayA(cv1, 3, false)
POST_END()
return ret;
}
void Hook_Void_Entvar_Float_Float(Hook *hook, void *pthis, entvars_t *ev1, float f1, float f2)
{
cell cev1=EntvarToIndex(ev1);
PRE_START()
, cev1, f1, f2
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void *, int, entvars_t *, float, float)>(hook->func)(pthis, 0, ev1, f1, f2);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, float, float)>(hook->func)(pthis, ev1, f1, f2);
#endif
POST_START()
, cev1, f1, f2
POST_END()
}
int Hook_Int_pFloat_pFloat(Hook *hook, void *pthis, float *f1, float *f2)
{
int ret=0;
cell cf1=amx_ftoc2(f1 == NULL ? 0.0 : *f1);
cell cf2=amx_ftoc2(f2 == NULL ? 0.0 : *f2);
PRE_START()
, cf1, cf2
PRE_END()
#if defined _WIN32
ret=reinterpret_cast<int (__fastcall*)(void *, int, float *, float *)>(hook->func)(pthis, 0, f1, f2);
#elif defined __linux__
ret=reinterpret_cast<int (*)(void *, float *, float *)>(hook->func)(pthis, f1, f2);
#endif
POST_START()
, cf1, cf2
POST_END()
return ret;
}
void Hook_Void_Entvar_Float(Hook *hook, void *pthis, entvars_t *ev1, float f1)
{
cell cev1=EntvarToIndex(ev1);
PRE_START()
, cev1, f1
PRE_END()
#if defined _WIN32
reinterpret_cast<void (__fastcall*)(void *, int, entvars_t *, float)>(hook->func)(pthis, 0, ev1, f1);
#elif defined __linux__
reinterpret_cast<void (*)(void *, entvars_t *, float)>(hook->func)(pthis, ev1, f1);
#endif
POST_START()
, cev1, f1
POST_END()
}

View File

@ -0,0 +1,67 @@
#ifndef HOOK_CALLBACKS_H
#define HOOK_CALLBACKS_H
void Hook_Void_Void(Hook *hook, void *pthis);
int Hook_Int_Void(Hook *hook, void *pthis);
void Hook_Void_Entvar(Hook *hook, void *pthis, entvars_t *entvar);
void Hook_Void_Cbase(Hook *hook, void *pthis, void *other);
int Hook_Int_Float_Int(Hook *hook, void *pthis, float f1, int i1);
void Hook_Void_Entvar_Int(Hook *hook, void *ptis, entvars_t *ev1, int i1);
int Hook_Int_Cbase(Hook *hook, void *pthis, void *cb1);
void Hook_Void_Int_Int(Hook *hook, void *pthis, int i1, int i2);
int Hook_Int_Int_Str_Int(Hook *hook, void *pthis, int i1, const char *sz1,
int i2);
int Hook_Int_Int(Hook *hook, void *pthis, int i1);
int Hook_Int_Entvar(Hook *hook, void *pthis, entvars_t *ev1);
int Hook_Int_Entvar_Entvar_Float_Int(Hook *hook, void *pthis,
entvars_t *inflictor,
entvars_t *attacker, float damage,
int damagebits);
void Hook_Void_Int(Hook *hook, void *pthis, int i1);
void Hook_Void_Cbase_Cbase_Int_Float(Hook *hook, void *pthis, void *cb1,
void *cb2, int i1, float f1);
void Hook_Void_Entvar_Float_Vector_Trace_Int(Hook *hook, void *pthis,
entvars_t *ev1, float f1,
Vector v1, TraceResult *tr1,
int i1);
void Hook_Void_Float_Vector_TraceResult_Int(Hook *hook, void *pthis, float f1,
Vector v1, TraceResult *tr1,
int i1);
const char *Hook_Str_Void(Hook *hook, void *pthis);
void *Hook_Cbase_Void(Hook *hook, void *pthis);
Vector Hook_Vector_Void(Hook *hook, void *pthis);
Vector Hook_Vector_pVector(Hook *hook, void *pthis, Vector *v1);
int Hook_Int_pVector(Hook *hook, void *pthis, Vector *v1);
void Hook_Void_Entvar_Float_Float(Hook *hook, void *pthis, entvars_t *ev1,
float f1, float f2);
int Hook_Int_pFloat_pFloat(Hook *hook, void *pthis, float *f1,
float *f2);
void Hook_Void_Entvar_Float(Hook *hook, void *pthis, entvars_t *ev1, float f1);
#endif

View File

@ -0,0 +1,125 @@
#include "sdk/amxxmodule.h"
int Create_Void_Void(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE);
}
int Create_Int_Void(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE);
}
int Create_Void_Entvar(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Void_Cbase(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Int_Float_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_FLOAT, FP_CELL, FP_DONE);
}
int Create_Void_Entvar_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Int_Cbase(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Void_Int_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Int_Int_Str_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_DONE);
}
int Create_Int_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Int_Entvar(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Int_Entvar_Entvar_Float_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_CELL, FP_DONE);
}
int Create_Void_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Void_Cbase_Cbase_Int_Float(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_FLOAT, FP_DONE);
}
int Create_Void_Entvar_Float_Vector_Trace_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_FLOAT, FP_ARRAY, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Void_Float_Vector_TraceResult_Int(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_FLOAT, FP_ARRAY, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Str_Void(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE);
}
int Create_Cbase_Void(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE);
}
int Create_Vector_Void(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_DONE);
}
int Create_Vector_pVector(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_ARRAY, FP_DONE);
}
int Create_Int_pVector(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_ARRAY, FP_DONE);
}
int Create_Void_Entvar_Float_Float(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_FLOAT, FP_FLOAT, FP_DONE);
}
int Create_Int_pFloat_pFloat(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
}
int Create_Void_Entvar_Float(AMX *amx, const char *func)
{
return MF_RegisterSPForwardByName(amx, func, FP_CELL, FP_CELL, FP_FLOAT, FP_DONE);
}

View File

@ -0,0 +1,54 @@
#ifndef HOOK_CREATE_H
#define HOOK_CREATE_H
int Create_Void_Void(AMX *amx, const char *func);
int Create_Int_Void(AMX *amx, const char *func);
int Create_Void_Entvar(AMX *amx, const char *func);
int Create_Void_Cbase(AMX *amx, const char *func);
int Create_Int_Float_Int(AMX *amx, const char *func);
int Create_Void_Entvar_Int(AMX *amx, const char *func);
int Create_Int_Cbase(AMX *amx, const char *func);
int Create_Void_Int_Int(AMX *amx, const char *func);
int Create_Int_Int_Str_Int(AMX *amx, const char *func);
int Create_Int_Int(AMX *amx, const char *func);
int Create_Int_Entvar(AMX *amx, const char *func);
int Create_Int_Entvar_Entvar_Float_Int(AMX *amx, const char *func);
int Create_Void_Int(AMX *amx, const char *func);
int Create_Void_Cbase_Cbase_Int_Float(AMX *amx, const char *func);
int Create_Void_Entvar_Float_Vector_Trace_Int(AMX *amx, const char *func);
int Create_Void_Float_Vector_TraceResult_Int(AMX *amx, const char *func);
int Create_Str_Void(AMX *amx, const char *func);
int Create_Cbase_Void(AMX *amx, const char *func);
int Create_Vector_Void(AMX *amx, const char *func);
int Create_Vector_pVector(AMX *amx, const char *func);
int Create_Int_pVector(AMX *amx, const char *func);
int Create_Void_Entvar_Float_Float(AMX *amx, const char *func);
int Create_Int_pFloat_pFloat(AMX *amx, const char *func);
int Create_Void_Entvar_Float(AMX *amx, const char *func);
#endif

View File

@ -0,0 +1,267 @@
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <extdll.h>
#include "sdk/amxxmodule.h"
#include "CVector.h"
#include "hook.h"
#include "forward.h"
#include "hook_callbacks.h"
#include "call_funcs.h"
#include "ecall_funcs.h"
#include "hook_create.h"
#include "offsets.h"
#include "hooklist.h"
#include "ham_utils.h"
OffsetManager Offsets;
CVector<Hook *> hooks[HAM_LAST_ENTRY_DONT_USE_ME_LOL];
#define V(__STUFF__) reinterpret_cast<void *>(Hook_##__STUFF__), Create_##__STUFF__, Call_##__STUFF__, eCall_##__STUFF__
hook_t hooklist[] =
{
{ 0, 0, "spawn", true, 0, V(Void_Void) }, // Spawn
{ 0, 0, "precache", true, 0, V(Void_Void) }, // Precache
{ 0, 0, "keyvalue", true, 1, V(Void_Int) }, // Keyvalue
{ 0, 0, "objectcaps", false, 0, V(Int_Void) }, // ObjectCaps
{ 0, 0, "activate", true, 0, V(Void_Void) }, // Activate
{ 0, 0, "setobjectcollisionbox", true, 0, V(Void_Void) }, // SetObjectCollisionBox
{ 0, 0, "classify", false, 0, V(Int_Void) }, // Classify
{ 0, 0, "deathnotice", true, 1, V(Void_Entvar) }, // DeathNotice
{ 0, 0, "traceattack", true, 7, V(Void_Entvar_Float_Vector_Trace_Int) }, // TraceAttack
{ 0, 0, "takedamage", false, 4, V(Int_Entvar_Entvar_Float_Int) }, // Takedamage
{ 0, 0, "takehealth", false, 2, V(Int_Float_Int) }, // TakeHealth
{ 0, 0, "killed", true, 2, V(Void_Entvar_Int) }, // Killed
{ 0, 0, "bloodcolor", false, 0, V(Int_Void) }, // BloodColor
{ 0, 0, "tracebleed", true, 6, V(Void_Float_Vector_TraceResult_Int) }, // TraceBleed
{ 0, 0, "istriggered", false, 1, V(Int_Cbase) }, // IsTriggered
{ 0, 0, "gettogglestate", false, 0, V(Int_Void) }, // GetToggleState
{ 0, 0, "addpoints", true, 2, V(Void_Int_Int) }, // AddPoints
{ 0, 0, "addpointstoteam", true, 2, V(Void_Int_Int) }, // AddPointsToTeam
{ 0, 0, "addplayeritem", false, 1, V(Int_Cbase) }, // AddPlayerItem
{ 0, 0, "removeplayeritem", false, 1, V(Int_Cbase) }, // RemovePlayerItem
{ 0, 0, "giveammo", false, 3, V(Int_Int_Str_Int) }, // GiveAmmo
{ 0, 0, "getdelay", false, 0, V(Int_Void) }, // GetDelay
{ 0, 0, "ismoving", false, 0, V(Int_Void) }, // IsMoving
{ 0, 0, "overridereset", true, 0, V(Void_Void) }, // OverrideReset
{ 0, 0, "damagedecal", false, 1, V(Int_Int) }, // DamageDecal
{ 0, 0, "settogglestate", true, 1, V(Void_Int) }, // SetToggleState
{ 0, 0, "startsneaking", true, 0, V(Void_Void) }, // StartSneaking
{ 0, 0, "stopsneaking", true, 0, V(Void_Void) }, // StopSneaking
{ 0, 0, "oncontrols", false, 1, V(Int_Entvar) }, // OnControls
{ 0, 0, "issneaking", false, 0, V(Int_Void) }, // IsSneaking
{ 0, 0, "isalive", false, 0, V(Int_Void) }, // IsAlive
{ 0, 0, "isbspmodel", false, 0, V(Int_Void) }, // IsBSPModel
{ 0, 0, "reflectgauss", false, 0, V(Int_Void) }, // ReflectGauss
{ 0, 0, "hastarget", false, 1, V(Int_Int) }, // HasTarget
{ 0, 0, "isinworld", false, 0, V(Int_Void) }, // IsInWorld
{ 0, 0, "isplayer", false, 0, V(Int_Void) }, // IsPlayer
{ 0, 0, "isnetclient", false, 0, V(Int_Void) }, // IsNetClient
{ 0, 0, "teamid", false, 0, V(Str_Void) }, // TeamID
{ 0, 0, "getnexttarget", false, 0, V(Cbase_Void) }, // GetNextTarget
{ 0, 0, "think", true, 0, V(Void_Void) }, // Think
{ 0, 0, "touch", true, 1, V(Void_Cbase) }, // Touch
{ 0, 0, "use", true, 4, V(Void_Cbase_Cbase_Int_Float) }, // Use
{ 0, 0, "blocked", true, 1, V(Void_Cbase) }, // Blocked
{ 0, 0, "respawn", false, 0, V(Cbase_Void) }, // Respawn TODO: Cbase this
{ 0, 0, "updateowner", true, 0, V(Void_Void) }, // UpdateOwner
{ 0, 0, "fbecomeprone", false, 0, V(Int_Void) }, // FBecomeProne
// TODO: These
{ 0, 0, "center", false, 0, V(Vector_Void) }, // Center
{ 0, 0, "eyeposition", false, 0, V(Vector_Void) }, // EyePosition
{ 0, 0, "earposition", false, 0, V(Vector_Void) }, // EarPosition
{ 0, 0, "bodytarget", false, 1, V(Vector_pVector) }, // BodyTarget
{ 0, 0, "illumination", false, 0, V(Int_Void) }, // Illumination
{ 0, 0, "fvisible", false, 1, V(Int_Cbase) }, // FVisible
{ 0, 0, "fvecvisible", false, 1, V(Int_pVector) }, // FVecVisible
/** Mod specific hooks **/
/* The Specialists */
{ 0, 0, "ts_breakablerespawn", false, 1, V(Int_Int) }, // TS_BreakableRespawn
{ 0, 0, "ts_canusedthroughwalls", false, 0, V(Int_Void) }, // TS_CanUsedThroughWalls
{ 0, 0, "ts_respawnwait", false, 0, V(Int_Void) }, // TS_RespawnWait
/* Counter-Strike */
{ 0, 0, "cstrike_restart", true, 0, V(Void_Void) }, // CS_Restart
/* Day of Defeat */
{ 0, 0, "dod_roundrespawn", true, 0, V(Void_Void) }, // DOD_RoundRespawn
{ 0, 0, "dod_roundrespawnent", true, 0, V(Void_Void) }, // DOD_RoundRespawnEnt
{ 0, 0, "dod_roundstore", true, 0, V(Void_Void) }, // DOD_RoundStore
{ 0, 0, "dod_areasetindex", true, 1, V(Void_Int) }, // DOD_AreaSetIndex
{ 0, 0, "dod_areasendstatus", true, 1, V(Void_Cbase) }, // DOD_AreaSendStatus
{ 0, 0, "dod_getstate", false, 0, V(Int_Void) }, // DOD_GetState
{ 0, 0, "dod_getstateent", false, 1, V(Int_Cbase) }, // DOD_GetStateEnt
/* Team Fortress Classic */
// This next one is just a huge guess
{ 0, 0, "tfc_dbgetitemname", false, 0, V(Str_Void) }, // TFC_DbGetItemName
{ 0, 0, "tfc_engineeruse", false, 1, V(Int_Cbase) }, // TFC_EngineerUse
{ 0, 0, "tfc_finished", true, 0, V(Void_Void) }, // TFC_Finished
{ 0, 0, "tfc_empexplode", true, 3, V(Void_Entvar_Float_Float) }, // TFC_EmpExplode
{ 0, 0, "tfc_calcempdmgrad", false, 2, V(Int_pFloat_pFloat) }, // TFC_CalcEmpDmgRad
{ 0, 0, "tfc_takeempblast", true, 1, V(Void_Entvar) }, // TFC_TakeEmpBlast
{ 0, 0, "tfc_empremove", true, 0, V(Void_Void) }, // TFC_EmpRemove
{ 0, 0, "tfc_takeconcussionblast", true, 2, V(Void_Entvar_Float) }, // TFC_TakeConcussionBlast
{ 0, 0, "tfc_concuss", true, 1, V(Void_Entvar) }, // TFC_Concuss
/* Natural-Selection */
{ 0, 0, "ns_getpointvalue", false, 0, V(Int_Void) }, // NS_GetPointValue
{ 0, 0, "ns_awardkill", true, 1, V(Void_Entvar) }, // NS_AwardKill
{ 0, 0, "ns_resetentity", true, 0, V(Void_Void) }, // NS_ResetEntity
{ 0, 0, "ns_updateonremove", true, 0, V(Void_Void) }, // NS_UpdateOnRemove
};
void FailPlugin(AMX *amx, int id, int err, const char *reason)
{
int fwd=MF_RegisterSPForwardByName(amx, "__fatal_ham_error", FP_CELL, FP_CELL, FP_STRING, FP_DONE);
MF_ExecuteForward(fwd, id, err, reason);
MF_UnregisterSPForward(fwd);
}
static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params)
{
// Make sure the function we're requesting is within bounds
int func=params[1];
int post=params[4];
CHECK_FUNCTION(func);
char *function=MF_GetAmxString(amx, params[2], 0, NULL);
char *classname=MF_GetAmxString(amx, params[3], 1, NULL);
// Check the entity
// 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 == NULL)
{
REMOVE_ENTITY(Entity);
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function);
return 0;
}
void **vtable=GetVTable(Entity->pvPrivateData, Offsets.GetBase());
REMOVE_ENTITY(Entity);
if (vtable == NULL)
{
MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname,function);
return 0;
}
// Verify that the function is valid
// Don't fail the plugin if this fails, just emit a normal error
int fwd=hooklist[func].makefunc(amx, function);
printf("\n\n----> FORWARD = %d\n\n\n",fwd);
if (fwd == -1)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function);
return 0;
}
// We've passed all tests...
int **ivtable=(int **)vtable;
void *vfunction=(void *)ivtable[hooklist[func].vtid];
// Check the list of this function's hooks, see if the function we have is a hook
CVector<Hook *>::iterator end=hooks[func].end();
for (CVector<Hook *>::iterator i=hooks[func].begin();
i!=end;
++i)
{
if ((*i)->tramp == vfunction)
{
// Yes, this function is hooked
if (post)
{
(*i)->post.push_back(new Forward(fwd));
}
else
{
(*i)->pre.push_back(new Forward(fwd));
}
return 1;
}
}
// If we got here, the function is not hooked
Hook *hook=new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].paramcount, classname);
hooks[func].push_back(hook);
if (post)
{
hook->post.push_back(new Forward(fwd));
}
else
{
hook->pre.push_back(new Forward(fwd));
}
return 1;
}
static cell AMX_NATIVE_CALL ExecuteHam(AMX *amx, cell *params)
{
int func=params[1];
CHECK_FUNCTION(func);
return hooklist[func].call(amx, params);
}
static cell AMX_NATIVE_CALL ExecuteHamB(AMX *amx, cell *params)
{
int func=params[1];
CHECK_FUNCTION(func);
return hooklist[func].ecall(amx, params);
}
static cell AMX_NATIVE_CALL IsHamValid(AMX *amx, cell *params)
{
int func=params[1];
if (func >= 0 &&
func < HAM_LAST_ENTRY_DONT_USE_ME_LOL &&
hooklist[func].isset!=0)
{
return 1;
}
return 0;
}
AMX_NATIVE_INFO RegisterNatives[] =
{
{ "RegisterHam", RegisterHam },
{ "ExecuteHam", ExecuteHam },
{ "ExecuteHamB", ExecuteHamB },
{ "IsHamValid", IsHamValid },
{ NULL, NULL }
};

View File

@ -0,0 +1,19 @@
#ifndef HOOKLIST_T_H
#define HOOKLIST_T_H
typedef struct hook_s
{
int isset; // whether or not this hook is registered with hamdata
int vtid; // vtable index of this function
const char *name; // name used in the keys
bool isvoid; // whether or not the target trampoline uses voids
int paramcount; // how many parameters are in the func
void *targetfunc; // the target hook
int (*makefunc)(AMX *, const char*); // function that creates forwards
int (*call)(AMX *, cell*); // function to call the vcall
int (*ecall)(AMX *, cell*); // function to ecall the vcall
} hook_t;
extern hook_t hooklist[];
#endif

View File

@ -0,0 +1,179 @@
#if defined _hamsandwich_included
#endinput
#endif
#define _hamsandwich_included
enum Ham
{
Ham_Spawn = 0,
Ham_Precache,
Ham_Keyvalue,
Ham_ObjectCaps,
Ham_Activate,
Ham_SetObjectCollisionBox,
Ham_Classify,
Ham_DeathNotice,
Ham_TraceAttack,
Ham_TakeDamage,
Ham_TakeHealth,
Ham_Killed,
Ham_BloodColor,
Ham_TraceBleed,
Ham_IsTriggered,
Ham_GetToggleState,
Ham_AddPoints,
Ham_AddPointsToTeam,
Ham_AddPlayerItem,
Ham_RemovePlayerItem,
Ham_GiveAmmo,
Ham_GetDelay,
Ham_IsMoving,
Ham_OverrideReset,
Ham_DamageDecal,
Ham_SetToggleState,
Ham_StartSneaking,
Ham_StopSneaking,
Ham_OnControls,
Ham_IsSneaking,
Ham_IsAlive,
Ham_IsBSPModel,
Ham_ReflectGauss,
Ham_HasTarget,
Ham_IsInWorld,
Ham_IsPlayer,
Ham_IsNetClient,
Ham_TeamId,
Ham_GetNextTarget,
Ham_Think,
Ham_Touch,
Ham_Use,
Ham_Blocked,
Ham_Respawn,
Ham_UpdateOwner,
Ham_FBecomeProne,
Ham_Center,
Ham_EyePosition,
Ham_EarPosition,
Ham_BodyTarget,
Ham_Illumination,
Ham_FVisible,
Ham_FVecVisible,
Ham_TS_BreakableRespawn,
Ham_TS_CanUsedThroughWalls,
Ham_TS_RespawnWait,
Ham_CS_Restart,
Ham_DOD_RoundRespawn,
Ham_DOD_RoundRespawnEnt,
Ham_DOD_RoundStore,
Ham_DOD_AreaSetIndex,
Ham_DOD_AreaSendStatus,
Ham_DOD_GetState,
Ham_DOD_GetStateEnt,
Ham_TFC_DbGetItemName,
Ham_TFC_EngineerUse,
Ham_TFC_Finished,
Ham_TFC_EmpExplode,
Ham_TFC_CalcEmpDmgRad,
Ham_TFC_TakeEmpBlast,
Ham_TFC_EmpRemove,
Ham_TFC_TakeConcussionBlast,
Ham_TFC_Concuss,
Ham_NS_GetPointValue,
Ham_NS_AwardKill,
Ham_NS_ResetEntity,
Ham_NS_UpdateOnRemove,
HAM_LAST_ENTRY_DONT_USE_ME_LOL
};
/**
* Hooks the virtual table for the specified entity class.
* An example would be: RegisterHam(Ham_TakeDamage, "player_hurt", "player");
* Look at the Ham enum for parameter lists.
*
* @param function The function to hook.
* @param callback The forward to call.
* @param entity The entity classname to hook.
* @param post Whether or not to forward this in post.
*/
native RegisterHam(Ham:function, const callback[], const entity[], post=0);
/**
* Executes the virtual function on the entity.
* Look at the Ham enum for parameter lists.
*
* @param function The function to call.
* @param id The id of the entity to execute it on.
*/
native ExecuteHam(Ham:function, id, any:...);
/**
* Executes the virtual function on the entity, this will trigger all hooks on that function.
* Be very careful about recursion!
* Look at the Ham enum for parameter lists.
*
* @param function The function to call.
* @param id The id of the entity to execute it on.
*/
native ExecuteHamB(Ham:function, id, any:...);
/**
* Returns whether or not the function for the specified Ham is valid.
* Things that would make it invalid would be bounds (an older module version
* may not have all of the functions), and the function not being found in
* the mod's hamdata.ini file.
*
* @param function The function to look up.
* @return true if the function is valid, false otherwise.
*/
native bool:IsHamValid(Ham:function);
enum HamError
{
HAM_OK = 0,
HAM_INVALID_FUNC, // The function is not valid
HAM_FUNC_NOT_CONFIGURED, // This function is not configured in hamdata.ini
HAM_ERR_END
};
// This is the callback from the module, this handles any fatal errors.
// This will in turn call the "HamFilter(Ham:id, HamError:err, const reason[])" public, if it exists.
// Return PLUGIN_HANDLED from within the HamFilter to stop the plugin from failing.
// Any other return value will fail the plugin.
// You do not need to have a HamFilter, if there is none, all fatal errors will fail the plugin.
public __fatal_ham_error(Ham:id, HamError:err, const reason[])
{
new func=get_func_id("HamFilter", -1);
new bool:fail=true;
if (callfunc_begin_i(func, -1)==1)
{
callfunc_push_int(_:id);
callfunc_push_int(_:err);
callfunc_push_str(reason, false);
if (callfunc_end()==PLUGIN_HANDLED)
{
fail=false;
}
}
if (fail)
{
set_fail_state(reason);
}
}

View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fakemeta", "fakemeta.vcproj", "{5E393C37-22F2-4CA2-9022-6400DC582447}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{5E393C37-22F2-4CA2-9022-6400DC582447}.Debug.ActiveCfg = Debug|Win32
{5E393C37-22F2-4CA2-9022-6400DC582447}.Debug.Build.0 = Debug|Win32
{5E393C37-22F2-4CA2-9022-6400DC582447}.Release.ActiveCfg = Release|Win32
{5E393C37-22F2-4CA2-9022-6400DC582447}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="fakemeta"
ProjectGUID="{5E393C37-22F2-4CA2-9022-6400DC582447}"
RootNamespace="fakemeta"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\sdk"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/fakemeta_amxx.dll"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/fakemeta.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/fakemeta.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\sdk"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FAKEMETA_EXPORTS"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/fakemeta_amxx.dll"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/fakemeta.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\fakemeta_amxx.cpp">
</File>
<File
RelativePath="..\fakemeta_amxx.h">
</File>
<File
RelativePath="..\fm_tr.cpp">
</File>
<File
RelativePath="..\fm_tr.h">
</File>
<File
RelativePath="..\fm_tr2.cpp">
</File>
<File
RelativePath="..\misc.cpp">
</File>
<File
RelativePath="..\pdata.cpp">
</File>
</Filter>
<Filter
Name="Engine Funcs"
Filter="">
<File
RelativePath="..\dllfunc.cpp">
</File>
<File
RelativePath="..\dllfunc.h">
</File>
<File
RelativePath="..\engfunc.cpp">
</File>
<File
RelativePath="..\engfunc.h">
</File>
</Filter>
<Filter
Name="PEV"
Filter="">
<File
RelativePath="..\pev.cpp">
</File>
<File
RelativePath=".\pev.h">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Forwards"
Filter="">
<File
RelativePath="..\forward.cpp">
</File>
<File
RelativePath="..\forward.h">
</File>
<File
RelativePath="..\forwardmacros.h">
</File>
</Filter>
<Filter
Name="Globals"
Filter="">
<File
RelativePath="..\glb.cpp">
</File>
<File
RelativePath="..\glb.h">
</File>
</Filter>
<Filter
Name="Module SDK"
Filter="">
<File
RelativePath="..\sdk\moduleconfig.h">
</File>
<File
RelativePath="..\sdk\svn_version.h">
</File>
<Filter
Name="AMXX STL"
Filter="">
<File
RelativePath="..\sdk\CString.h">
</File>
<File
RelativePath="..\sdk\CVector.h">
</File>
</Filter>
<Filter
Name="SDK Base"
Filter="">
<File
RelativePath="..\sdk\amxxmodule.cpp">
</File>
<File
RelativePath="..\sdk\amxxmodule.h">
</File>
</Filter>
</Filter>
<Filter
Name="Pawn Includes"
Filter="">
<File
RelativePath="..\..\..\plugins\include\fakemeta.inc">
</File>
<File
RelativePath="..\..\..\plugins\include\fakemeta_const.inc">
</File>
<File
RelativePath="..\..\..\plugins\include\fakemeta_stocks.inc">
</File>
<File
RelativePath="..\..\..\plugins\include\hlsdk_const.inc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hamsandwich", "hamsandwich.vcproj", "{5E393C37-22F2-4CA2-9022-6400DC582447}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5E393C37-22F2-4CA2-9022-6400DC582447}.Debug|Win32.ActiveCfg = Debug|Win32
{5E393C37-22F2-4CA2-9022-6400DC582447}.Debug|Win32.Build.0 = Debug|Win32
{5E393C37-22F2-4CA2-9022-6400DC582447}.Release|Win32.ActiveCfg = Release|Win32
{5E393C37-22F2-4CA2-9022-6400DC582447}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,305 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="hamsandwich"
ProjectGUID="{5E393C37-22F2-4CA2-9022-6400DC582447}"
RootNamespace="hamsandwich"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\hlsdk\dlls;..\..\..\..\hlsdk\common;..\..\..\..\hlsdk\engine\;..\..\..\..\hlsdk\pm_shared; ..\..\..\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/hamsandwich_amxx.dll"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/hamsandwich.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/hamsandwich.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\sdk"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
RuntimeLibrary="0"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/hamsandwich_amxx.dll"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
ImportLibrary="$(OutDir)/hamsandwich.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Hooks"
>
<File
RelativePath="..\call_funcs.cpp"
>
</File>
<File
RelativePath="..\call_funcs.h"
>
</File>
<File
RelativePath="..\ecall_funcs.cpp"
>
</File>
<File
RelativePath="..\ecall_funcs.h"
>
</File>
<File
RelativePath="..\forward.h"
>
</File>
<File
RelativePath="..\hook.h"
>
</File>
<File
RelativePath="..\hook_callbacks.cpp"
>
</File>
<File
RelativePath="..\hook_callbacks.h"
>
</File>
<File
RelativePath="..\hook_create.cpp"
>
</File>
<File
RelativePath="..\hook_create.h"
>
</File>
<File
RelativePath="..\hook_native.cpp"
>
</File>
<File
RelativePath="..\hooklist.h"
>
</File>
<File
RelativePath="..\typetocell.h"
>
</File>
<Filter
Name="Trampolines"
>
<File
RelativePath="..\Trampolines.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="sdk"
>
<File
RelativePath="..\sdk\amxxmodule.cpp"
>
</File>
<File
RelativePath="..\sdk\amxxmodule.h"
>
</File>
<File
RelativePath="..\sdk\moduleconfig.h"
>
</File>
</Filter>
<Filter
Name="Calls"
>
</Filter>
<Filter
Name="Config File"
>
<File
RelativePath="..\config_parser.cpp"
>
</File>
</Filter>
<File
RelativePath="..\amxx_api.cpp"
>
</File>
<File
RelativePath="..\ham_const.h"
>
</File>
<File
RelativePath="..\ham_utils.h"
>
</File>
<File
RelativePath="..\NEW_Util.h"
>
</File>
<File
RelativePath="..\offsets.h"
>
</File>
<File
RelativePath="..\srvcmd.cpp"
>
</File>
<File
RelativePath="..\vfuncs.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,55 @@
#ifndef OFFSETS_H
#define OFFSETS_H
#include "ham_const.h"
// Just a singleton class that keeps pev/base/offset values managed.
class OffsetManager
{
private:
size_t pev;
size_t baseclass;
int baseset;
int pevset;
public:
OffsetManager()
{
memset(this,0x0,sizeof(*this));
}
void SetPev(size_t value)
{
pevset=1;
pev=value;
};
size_t GetPev(void)
{
return pev;
};
int IsPevSet()
{
return pevset;
};
int IsBaseSet()
{
return baseset;
};
void SetBase(size_t value)
{
baseset=1;
baseclass=value;
};
size_t GetBase(void)
{
return baseclass;
};
bool IsValid()
{
return pevset != 0 && baseset != 0;
}
};
extern OffsetManager Offsets;
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,494 @@
// Configuration
#ifndef __MODULECONFIG_H__
#define __MODULECONFIG_H__
//#include "svn_version.h"
// Module info
#define MODULE_NAME "Ham Sandwich"
#define MODULE_VERSION "1.8"
#define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_URL "http://www.amxmodx.org"
#define MODULE_LOGTAG "HAMSANDWICH"
#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 FMH_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__

100
dlls/hamsandwich/srvcmd.cpp Normal file
View File

@ -0,0 +1,100 @@
#include "sdk/amxxmodule.h"
#include <stdarg.h>
#include "CVector.h"
#include "ham_const.h"
#include "hooklist.h"
#include "offsets.h"
#include "forward.h"
#include "hook.h"
extern hook_t hooklist[];
extern CVector<Hook *> hooks[HAM_LAST_ENTRY_DONT_USE_ME_LOL];
void print_srvconsole(char *fmt, ...)
{
va_list argptr;
static char string[384];
va_start(argptr, fmt);
vsnprintf(string, sizeof(string) - 1, fmt, argptr);
string[sizeof(string) - 1] = '\0';
va_end(argptr);
SERVER_PRINT(string);
}
void HamCommand(void)
{
const char *cmd=CMD_ARGV(1);
if (strcmp(cmd, "list")==0)
{
unsigned int Total=0;
print_srvconsole("%-24s | %3s | %10s\n","Name","Set","Value");
print_srvconsole("-------------------------------------------\n");
print_srvconsole("%-24s | %s | %10d\n", "pev", Offsets.IsPevSet() == 0 ? "n" : "y", Offsets.GetPev());
print_srvconsole("%-24s | %s | %10d\n", "base", Offsets.IsBaseSet() == 0 ? "n" : "y", Offsets.GetBase());
int count=0;
for (int i=0; i<HAM_LAST_ENTRY_DONT_USE_ME_LOL; i++)
{
print_srvconsole("%-24s | %s | %10d\n", hooklist[i].name, hooklist[i].isset == 0 ? "n" : "y", hooklist[i].vtid);
if (hooklist[i].isset != 0)
{
Total++;
}
count++;
if (count >= 5)
{
count = 0;
print_srvconsole("-------------------------------------------\n");
}
}
print_srvconsole("\n%u keys, %u set.\n\n", HAM_LAST_ENTRY_DONT_USE_ME_LOL, Total);
return;
}
else if (strcmp(cmd, "hooks")==0)
{
print_srvconsole("%-24s | %-32s | %10s | %10s\n", "Key", "Classname", "Pre", "Post");
print_srvconsole("-------------------------------------------------------------------------------------\n");
unsigned int ForwardCount=0;
unsigned int HookCount=0;
int count = 0;
for (int i=0; i<HAM_LAST_ENTRY_DONT_USE_ME_LOL; i++)
{
CVector<Hook *>::iterator end=hooks[i].end();
for (CVector<Hook *>::iterator j=hooks[i].begin();
j!=end;
++j)
{
HookCount++;
ForwardCount+=(*j)->pre.size() + (*j)->post.size();
print_srvconsole("%-24s | %-32s | %10d | %10d\n",hooklist[i].name, (*j)->ent, (*j)->pre.size(), (*j)->post.size());
if (count >= 5)
{
print_srvconsole("-------------------------------------------------------------------------------------\n");
}
}
}
print_srvconsole("\n%u active hooks, %u active forwards.\n\n", HookCount, ForwardCount);
return;
}
// Unknown command
print_srvconsole("Usage: ham < command > [ argument ]\n");
print_srvconsole("Commands:\n");
print_srvconsole(" %-22s - %s\n", "list", "list all keys and their values from the config file.");
print_srvconsole(" %-22s - %s\n", "hooks", "list all active hooks");
}

View File

@ -0,0 +1,61 @@
#ifndef TYPETOCELL_H
#define TYPETOCELL_H
#include <extdll.h>
#include "sdk/amxxmodule.h"
#include "CVector.h"
#include "hook.h"
#include "forward.h"
#include "ham_const.h"
#include "ham_utils.h"
inline cell TypeToCell(const float& value)
{
return amx_ftoc2(value);
}
inline cell TypeToCell(const float*& value)
{
return amx_ftoc2(*value);
}
inline cell TypeToCell(const Vector*& value)
{
return reinterpret_cast<cell>(value);
}
inline cell TypeToCell(const int& value)
{
return value;
}
inline cell TypeToCell(const edict_t*& value)
{
if (value == NULL)
{
return -1;
}
return ENTINDEX_NEW(value);
}
inline cell TypeToCell(const entvars_t*& value)
{
if (value == NULL)
{
return -1;
}
return ENTINDEX_NEW(value->pContainingEntity);
}
inline cell TypeToCell(const HLBaseEntity*& value)
{
return PrivateToIndex(reinterpret_cast<const void *>(value));
}
#endif