diff --git a/extensions/structs/IStructAbstacter.h b/extensions/structs/IStructAbstacter.h
new file mode 100644
index 000000000..61c9f2914
--- /dev/null
+++ b/extensions/structs/IStructAbstacter.h
@@ -0,0 +1,61 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#ifndef _INCLUDE_SOURCEMOD_ISTRUCTABSTACTER_H
+#define _INCLUDE_SOURCEMOD_ISTRUCTABSTACTER_H
+
+#include
+#include
+
+using namespace SourceMod;
+
+#define SMINTERFACE_ISTRUCTABSTACTER_NAME "IStructAbstacter"
+#define SMINTERFACE_ISTRUCTABSTACTER_VERSION 1
+
+class IStructAbstracter : public SourceMod::SMInterface
+{
+public:
+ virtual const char *GetInterfaceName()
+ {
+ return SMINTERFACE_ISTRUCTABSTACTER_NAME;
+ }
+ virtual unsigned int GetInterfaceVersion()
+ {
+ return SMINTERFACE_ISTRUCTABSTACTER_VERSION;
+ }
+
+public:
+ virtual Handle_t CreateStructHandle(const char *type, void *str) =0;
+ //virtual void SetInitializer(char *type, STRUCT_INITIALIZER init);
+
+};
+
+#endif //_INCLUDE_SOURCEMOD_ISTRUCTABSTACTER_H
diff --git a/extensions/structs/Makefile b/extensions/structs/Makefile
new file mode 100644
index 000000000..bfc0ad340
--- /dev/null
+++ b/extensions/structs/Makefile
@@ -0,0 +1,126 @@
+# (C)2004-2008 SourceMod Development Team
+# Makefile written by David "BAILOPAN" Anderson
+
+SMSDK = ../..
+SRCDS_BASE = ~/srcds
+HL2SDK_ORIG = ../../../hl2sdk
+HL2SDK_OB = ../../../hl2sdk-ob
+SOURCEMM14 = ../../../sourcemm-1.4
+SOURCEMM16 = ../../../sourcemm-1.6
+
+#####################################
+### EDIT BELOW FOR OTHER PROJECTS ###
+#####################################
+
+PROJECT = structs
+
+#Uncomment for Metamod: Source enabled extension
+USEMETA = true
+
+OBJECTS = sdk/smsdk_ext.cpp extension.cpp Struct.cpp StructHandle.cpp StructManager.cpp natives.cpp
+
+##############################################
+### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
+##############################################
+
+C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
+C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
+C_GCC4_FLAGS = -fvisibility=hidden
+CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
+CPP = gcc-4.1
+
+override ENGSET = false
+ifeq "$(ENGINE)" "original"
+ HL2SDK = $(HL2SDK_ORIG)
+ HL2PUB = $(HL2SDK_ORIG)/public
+ HL2LIB = $(HL2SDK_ORIG)/linux_sdk
+ METAMOD = $(SOURCEMM14)
+ INCLUDE += -I$(HL2SDK)/public/dlls
+ SRCDS = $(SRCDS_BASE)
+ override ENGSET = true
+endif
+ifeq "$(ENGINE)" "orangebox"
+ HL2SDK = $(HL2SDK_OB)
+ HL2PUB = $(HL2SDK_OB)/public
+ HL2LIB = $(HL2SDK_OB)/lib/linux
+ CFLAGS += -DORANGEBOX_BUILD
+ METAMOD = $(SOURCEMM16)
+ INCLUDE += -I$(HL2SDK)/public/game/server
+ SRCDS = $(SRCDS_BASE)/orangebox
+ override ENGSET = true
+endif
+
+ifeq "$(USEMETA)" "true"
+ LINK_HL2 = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so $(SRCDS)/tf/bin/server_i486.so
+
+ LINK += $(LINK_HL2)
+
+ INCLUDE += -I. -I.. -Isdk -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \
+ -I$(METAMOD) -I$(METAMOD)/sourcehook -I$(METAMOD)/sourcemm -I$(SMSDK)/public \
+ -I$(SMSDK)/public/sourcepawn -I$(HL2SDK_OB)/game/shared
+else
+ INCLUDE += -I. -I.. -Isdk -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn
+endif
+
+LINK += -static-libgcc
+
+CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
+ -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror -Wno-switch \
+ -Wno-unused -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -m32
+CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
+
+################################################
+### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
+################################################
+
+ifeq "$(DEBUG)" "true"
+ BIN_DIR = Debug
+ CFLAGS += $(C_DEBUG_FLAGS)
+else
+ BIN_DIR = Release
+ CFLAGS += $(C_OPT_FLAGS)
+endif
+
+ifeq "$(USEMETA)" "true"
+ BIN_DIR := $(BIN_DIR).$(ENGINE)
+endif
+
+GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
+ifeq "$(GCC_VERSION)" "4"
+ CFLAGS += $(C_GCC4_FLAGS)
+ CPPFLAGS += $(CPP_GCC4_FLAGS)
+endif
+
+BINARY = $(PROJECT).ext.so
+
+OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
+
+$(BIN_DIR)/%.o: %.cpp
+ $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
+
+all: check
+ mkdir -p $(BIN_DIR)/sdk
+ if [ "$(USEMETA)" == "true" ]; then \
+ ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so; \
+ ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so; \
+ fi
+ $(MAKE) -f Makefile extension
+
+check:
+ if [ "$(USEMETA)" == "true" ] && [ "$(ENGSET)" == "false" ]; then \
+ echo "You must supply ENGINE=orangebox or ENGINE=original"; \
+ exit 1; \
+ fi
+
+extension: check $(OBJ_LINUX)
+ $(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
+
+debug:
+ $(MAKE) -f Makefile all DEBUG=true
+
+default: all
+
+clean: check
+ rm -rf $(BIN_DIR)/*.o
+ rm -rf $(BIN_DIR)/sdk/*.o
+ rm -rf $(BIN_DIR)/$(BINARY)
diff --git a/extensions/structs/Struct.cpp b/extensions/structs/Struct.cpp
new file mode 100644
index 000000000..970b9246e
--- /dev/null
+++ b/extensions/structs/Struct.cpp
@@ -0,0 +1,108 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#include "Struct.h"
+
+bool StructInfo::getOffset( const char *member, int *offset )
+{
+ MemberInfo **pInfo = members.retrieve(member);
+
+ if (pInfo == NULL)
+ {
+ return false;
+ }
+
+ *offset = (*pInfo)->offset;
+
+ return true;
+}
+
+bool StructInfo::getType( const char *member, MemberType*type )
+{
+ MemberInfo **pInfo = members.retrieve(member);
+
+ if (pInfo == NULL)
+ {
+ return false;
+ }
+
+ *type = (*pInfo)->type;
+
+ return true;
+}
+
+bool StructInfo::getSize( const char *member, int *size )
+{
+ MemberInfo **pInfo = members.retrieve(member);
+
+ if (pInfo == NULL)
+ {
+ return false;
+ }
+
+ *size = (*pInfo)->size;
+
+ return true;
+}
+
+void StructInfo::AddMember( const char *name, MemberInfo *member )
+{
+ members.insert(name, member);
+ membersList.push_back(member);
+}
+
+StructInfo::~StructInfo()
+{
+ SourceHook::List::iterator iter;
+
+ iter = membersList.begin();
+
+ while (iter != membersList.end())
+ {
+ delete (MemberInfo *)*iter;
+ iter = membersList.erase(iter);
+ }
+
+ members.clear();
+}
+
+StructInfo::StructInfo()
+{
+ name[0] = 0;
+ size = -1;
+}
+MemberInfo::MemberInfo()
+{
+ name[0] = 0;
+ size = -1;
+ type = Member_Unknown;
+ offset = -1;
+}
diff --git a/extensions/structs/Struct.h b/extensions/structs/Struct.h
new file mode 100644
index 000000000..1a43e5d3a
--- /dev/null
+++ b/extensions/structs/Struct.h
@@ -0,0 +1,85 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#ifndef _INCLUDE_SOURCEMOD_STRUCT_H_
+#define _INCLUDE_SOURCEMOD_STRUCT_H_
+
+#include "sm_trie_tpl.h"
+#include "sh_list.h"
+
+enum MemberType
+{
+ Member_Unknown,
+ Member_Int8,
+ Member_Int8Pointer,
+ Member_Int16,
+ Member_Int16Pointer,
+ Member_Int32,
+ Member_Int32Pointer,
+ Member_Float,
+ Member_FloatPointer,
+ //Member_Struct,
+ //Member_StructPointer,
+ Member_Char,
+ Member_CharPointer,
+ Member_Vector,
+ Member_VectorPointer,
+ Member_EHandle,
+ Member_EHandlePointer,
+};
+
+struct MemberInfo
+{
+ MemberInfo();
+
+ char name[100];
+ MemberType type;
+ int size;
+ int offset;
+};
+
+struct StructInfo
+{
+ StructInfo();
+ ~StructInfo();
+ void AddMember(const char *name, MemberInfo *member);
+
+ char name[100];
+ int size;
+ KTrie members;
+ SourceHook::List membersList;
+
+ bool getOffset(const char *member, int *offset);
+ bool getType(const char *member, MemberType*type);
+ bool getSize(const char *member, int *size);
+};
+
+#endif //_INCLUDE_SOURCEMOD_STRUCT_H_
diff --git a/extensions/structs/StructHandle.cpp b/extensions/structs/StructHandle.cpp
new file mode 100644
index 000000000..8093f7c74
--- /dev/null
+++ b/extensions/structs/StructHandle.cpp
@@ -0,0 +1,556 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#include "StructHandle.h"
+#include "extension.h"
+
+bool StructHandle::GetInt( const char *member, int *value )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Int8:
+ {
+ *value = *(uint8 *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_Int16:
+ {
+ *value = *(uint16 *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_Int32:
+ {
+ *value = *(uint32 *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_Int8Pointer:
+ {
+ *value = **(uint8 **)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_Int16Pointer:
+ {
+ *value = **(uint16 **)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_Int32Pointer:
+ {
+ *value = **(uint32 **)((unsigned char *)data + offset);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::GetFloat( const char *member, float *value )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Float:
+ {
+ *value = *(float *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_FloatPointer:
+ {
+ *value = **(float **)((unsigned char *)data + offset);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::SetInt( const char *member, int value )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Int8:
+ {
+ *(uint8 *)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ case Member_Int16:
+ {
+ *(uint16 *)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ case Member_Int32:
+ {
+ *(uint32 *)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ case Member_Int8Pointer:
+ {
+ **(uint8 **)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ case Member_Int16Pointer:
+ {
+ **(uint16 **)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ case Member_Int32Pointer:
+ {
+ **(uint32 **)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::SetFloat( const char *member, float value )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Float:
+ {
+ *(float *)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ case Member_FloatPointer:
+ {
+ **(float **)((unsigned char *)data + offset) = value;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::IsPointerNull( const char *member, bool *result )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Int8Pointer:
+ case Member_Int16Pointer:
+ case Member_Int32Pointer:
+ case Member_FloatPointer:
+ case Member_CharPointer:
+ case Member_VectorPointer:
+ case Member_EHandlePointer:
+ {
+ *result = *((unsigned char **)data + offset) == NULL;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::setPointerNull( const char *member )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Int8Pointer:
+ case Member_Int16Pointer:
+ case Member_Int32Pointer:
+ case Member_FloatPointer:
+ case Member_CharPointer:
+ case Member_VectorPointer:
+ case Member_EHandlePointer:
+ {
+ *((unsigned char **)data + offset) = NULL;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::GetVector( const char *member, Vector *vec )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Vector:
+ {
+ *vec = *(Vector *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_VectorPointer:
+ {
+ *vec = **(Vector **)((unsigned char *)data + offset);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::SetVector( const char *member, Vector vec )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Vector:
+ {
+ *(Vector *)((unsigned char *)data + offset) = vec;
+ break;
+ }
+
+ case Member_VectorPointer:
+ {
+ **(Vector **)((unsigned char *)data + offset) = vec;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::GetString( const char *member, char **string )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Char:
+ {
+ *string = (char *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_CharPointer:
+ {
+ *string = *(char **)((unsigned char *)data + offset);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::SetString( const char *member, char *string )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Char:
+ {
+ int size;
+ info->getSize(member, &size);
+ char *location = (char *)data + offset;
+ UTIL_Format(location, size, "%s", string);
+ break;
+ }
+
+ case Member_CharPointer:
+ {
+ int size;
+ info->getSize(member, &size);
+ char *location = *(char **)((unsigned char *)data + offset);
+ UTIL_Format(location, size, "%s", string);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::GetEHandle( const char *member, CBaseHandle **handle )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_EHandle:
+ {
+ *handle = (CBaseHandle *)((unsigned char *)data + offset);
+ break;
+ }
+
+ case Member_EHandlePointer:
+ {
+ *handle = *(CBaseHandle **)((unsigned char *)data + offset);
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool StructHandle::SetEHandle( const char *member, CBaseHandle *handle )
+{
+ int offset;
+
+ if (!info->getOffset(member, &offset))
+ {
+ return false;
+ }
+
+ MemberType type;
+
+ if (!info->getType(member, &type))
+ {
+ return false;
+ }
+
+ switch (type)
+ {
+ case Member_Float:
+ {
+ *(CBaseHandle *)((unsigned char *)data + offset) = *handle;
+ break;
+ }
+
+ case Member_FloatPointer:
+ {
+ **(CBaseHandle **)((unsigned char *)data + offset) = *handle;
+ break;
+ }
+
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
diff --git a/extensions/structs/StructHandle.h b/extensions/structs/StructHandle.h
new file mode 100644
index 000000000..7762f85aa
--- /dev/null
+++ b/extensions/structs/StructHandle.h
@@ -0,0 +1,64 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#ifndef _INCLUDE_SOURCEMOD_STRUCT_HANDLE_H_
+#define _INCLUDE_SOURCEMOD_STRUCT_HANDLE_H_
+
+#include "Struct.h"
+#include "mathlib/vector.h"
+#include "basehandle.h"
+
+class StructHandle
+{
+public:
+ StructInfo *info;
+ void *data;
+ bool canDelete;
+
+ bool GetInt(const char *member, int *value);
+ bool GetFloat(const char *member, float *value);
+ bool GetVector(const char *member, Vector *vec);
+ bool GetEHandle(const char *member, CBaseHandle **handle);
+ bool GetString(const char *member, char **string);
+ //bool GetStruct(const char *member, handle_t *value);
+
+ bool SetInt(const char *member, int value);
+ bool SetFloat(const char *member, float value);
+ bool SetVector(const char *member, Vector vec);
+ bool SetEHandle(const char *member, CBaseHandle *handle);
+ bool SetString(const char *member, char *string);
+ //bool SetStruct(const char *member, StructHandle *struct);
+
+ bool IsPointerNull(const char *member, bool *result);
+ bool setPointerNull(const char *member);
+};
+
+#endif //_INCLUDE_SOURCEMOD_STRUCT_HANDLE_H_
diff --git a/extensions/structs/StructManager.cpp b/extensions/structs/StructManager.cpp
new file mode 100644
index 000000000..4739453b9
--- /dev/null
+++ b/extensions/structs/StructManager.cpp
@@ -0,0 +1,78 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#include "StructManager.h"
+#include "extension.h"
+
+StructManager g_StructManager;
+
+void StructManager::AddStruct( const char *name, StructInfo *str )
+{
+ structs.insert(name, str);
+ structsList.push_back(str);
+}
+
+StructManager::~StructManager()
+{
+ SourceHook::List::iterator iter;
+
+ iter = structsList.begin();
+
+ while (iter != structsList.end())
+ {
+ delete (MemberInfo *)*iter;
+ iter = structsList.erase(iter);
+ }
+
+ structs.clear();
+}
+
+Handle_t StructManager::CreateStructHandle( const char *type, void *str )
+{
+ StructInfo **pInfo = structs.retrieve(type);
+
+ if (pInfo == NULL)
+ {
+ return BAD_HANDLE;
+ }
+
+ StructHandle *pHandle = new StructHandle;
+
+ pHandle->canDelete = false;
+ pHandle->data = str;
+ pHandle->info = *pInfo;
+
+ return handlesys->CreateHandle(g_StructHandle,
+ pHandle,
+ NULL,
+ myself->GetIdentity(),
+ NULL);
+}
diff --git a/extensions/structs/StructManager.h b/extensions/structs/StructManager.h
new file mode 100644
index 000000000..484fd38ae
--- /dev/null
+++ b/extensions/structs/StructManager.h
@@ -0,0 +1,56 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#ifndef _INCLUDE_SOURCEMOD_STRUCTMANAGER_H
+#define _INCLUDE_SOURCEMOD_STRUCTMANAGER_H
+
+#include "Struct.h"
+#include "StructHandle.h"
+#include "IStructAbstacter.h"
+#include "IHandleSys.h"
+#include "smsdk_ext.h"
+
+int CheckBaseHandle(CBaseHandle &hndl);
+
+class StructManager : public IStructAbstracter
+{
+public:
+ ~StructManager();
+ Handle_t CreateStructHandle(const char *type, void *str);
+ void AddStruct(const char *name, StructInfo *str);
+private:
+ KTrie structs;
+ SourceHook::List structsList;
+};
+
+extern StructManager g_StructManager;
+
+#endif //_INCLUDE_SOURCEMOD_STRUCTMANAGER_H
diff --git a/extensions/structs/extension.cpp b/extensions/structs/extension.cpp
new file mode 100644
index 000000000..22a612409
--- /dev/null
+++ b/extensions/structs/extension.cpp
@@ -0,0 +1,285 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Sample Extension
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#include "extension.h"
+
+/**
+ * @file extension.cpp
+ * @brief Implement extension code here.
+ */
+
+Structs g_Structs; /**< Global singleton for extension's main interface */
+
+SMEXT_LINK(&g_Structs);
+
+HandleType_t g_StructHandle = 0;
+StructHandler g_StructHandler;
+
+IGameConfig *conf;
+
+size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ size_t len = vsnprintf(buffer, maxlength, fmt, ap);
+ va_end(ap);
+
+ if (len >= maxlength)
+ {
+ buffer[maxlength - 1] = '\0';
+ return (maxlength - 1);
+ }
+ else
+ {
+ return len;
+ }
+}
+
+void Structs::SDK_OnAllLoaded()
+{
+ g_StructHandle = handlesys->CreateType("Struct",
+ &g_StructHandler,
+ 0,
+ NULL,
+ NULL,
+ myself->GetIdentity(),
+ NULL);
+
+ gameconfs->AddUserConfigHook("Structs", this);
+
+ sharesys->AddNatives(myself, MyNatives);
+
+
+ char error[100];
+ if (!gameconfs->LoadGameConfigFile("structs", &conf, error, sizeof(error)))
+ {
+ g_pSM->LogError(myself, "Parsing Failed!");
+ }
+}
+
+void Structs::SDK_OnUnload()
+{
+ handlesys->RemoveType(g_StructHandle, myself->GetIdentity());
+
+ gameconfs->RemoveUserConfigHook("Structs", this);
+}
+
+bool Structs::SDK_OnLoad( char *error, size_t maxlength, bool late )
+{
+ sharesys->AddInterface(myself, &g_StructManager);
+
+ m_typeLookup.insert("int", Member_Int32);
+ m_typeLookup.insert("int*", Member_Int32Pointer);
+ m_typeLookup.insert("float", Member_Float);
+ m_typeLookup.insert("float*", Member_FloatPointer);
+ m_typeLookup.insert("char", Member_Char);
+ m_typeLookup.insert("char*", Member_CharPointer);
+ m_typeLookup.insert("Vector", Member_Vector);
+ m_typeLookup.insert("Vector*", Member_VectorPointer);
+ m_typeLookup.insert("ent", Member_EHandle);
+ m_typeLookup.insert("ent*", Member_EHandlePointer);
+
+ return true;
+}
+
+void Structs::ReadSMC_ParseStart()
+{
+ m_bInStruct = false;
+ m_currentStruct = NULL;
+ m_bInMember = false;
+ m_currentMember = NULL;
+}
+
+SourceMod::SMCResult Structs::ReadSMC_NewSection( const SMCStates *states, const char *name )
+{
+ if (!m_bInStruct)
+ {
+ m_currentStruct = new StructInfo();
+ UTIL_Format(m_currentStruct->name, sizeof(m_currentStruct->name), "%s", name);
+ m_bInStruct = true;
+
+ return SMCResult_Continue;
+ }
+
+ if (!m_bInMember)
+ {
+ m_bInMember = true;
+ m_currentMember = new MemberInfo();
+ UTIL_Format(m_currentMember->name, sizeof(m_currentMember->name), "%s", name);
+
+ return SMCResult_Continue;
+ }
+
+ g_pSM->LogMessage(myself, "Cannot nest within a member: line: %i col: %i", states->line, states->col);
+
+ return SMCResult_HaltFail;
+}
+
+SourceMod::SMCResult Structs::ReadSMC_KeyValue( const SMCStates *states, const char *key, const char *value )
+{
+ if (!m_bInStruct)
+ {
+ //hrm..
+ g_pSM->LogMessage(myself, "Unknown value %s: line: %i col: %i", key, states->line, states->col);
+ return SMCResult_HaltFail;
+ }
+
+ if (m_bInMember)
+ {
+ if (strcmp(key, "type") == 0)
+ {
+ MemberType *pType = m_typeLookup.retrieve(value);
+
+ if (pType == NULL)
+ {
+ //invalid type
+ g_pSM->LogMessage(myself, "Invalid Type: line: %i col: %i", states->line, states->col);
+ return SMCResult_HaltFail;
+ }
+
+ /* Note all 'int' types are assumed to be 32bit for the moment */
+ m_currentMember->type = *pType;
+ }
+ else if (strcmp(key, "size") == 0)
+ {
+ m_currentMember->size = atoi(value);
+ }
+#if defined WIN32
+ else if (strcmp(key, "windows") == 0)
+#else
+ else if (strcmp(key, "linux") == 0)
+#endif
+ {
+ m_currentMember->offset = atoi(value);
+ }
+ }
+ else
+ {
+ if (strcmp(key, "size") == 0)
+ {
+ m_currentStruct->size = atoi(value);
+ }
+ }
+
+ return SMCResult_Continue;
+}
+
+SourceMod::SMCResult Structs::ReadSMC_LeavingSection( const SMCStates *states )
+{
+ if (m_bInMember)
+ {
+ /** Check for missing or invalid parameters */
+ if (m_currentMember->type == Member_Unknown || m_currentMember->offset == -1)
+ {
+ g_pSM->LogMessage(myself, "Missing offset or type: line: %i col: %i", states->line, states->col);
+ return SMCResult_HaltFail;
+ }
+
+ if (m_currentMember->size == -1)
+ {
+ switch (m_currentMember->type)
+ {
+ case Member_Float:
+ case Member_FloatPointer:
+ case Member_Vector:
+ case Member_VectorPointer:
+ case Member_EHandle:
+ case Member_EHandlePointer:
+ {
+ break;
+ }
+
+ default:
+ {
+ g_pSM->LogMessage(myself, "Missing size: line: %i col: %i", states->line, states->col);
+ return SMCResult_HaltFail;
+ }
+ }
+ }
+
+ /* Work out the int size */
+ if (m_currentMember->type == Member_Int32)
+ {
+ if (m_currentMember->size == 1)
+ {
+ m_currentMember->type = Member_Int8;
+ }
+ else if (m_currentMember->size == 2)
+ {
+ m_currentMember->type = Member_Int16;
+ }
+ else if (m_currentMember->size == 4)
+ {
+ m_currentMember->type = Member_Int32;
+ }
+ else
+ {
+ g_pSM->LogMessage(myself, "Invalid int size %i: line: %i col: %i", m_currentMember->size, states->line, states->col);
+ return SMCResult_HaltFail;
+ }
+
+ }
+ else if (m_currentMember->type == Member_Int32)
+ {
+ if (m_currentMember->size == 1)
+ {
+ m_currentMember->type = Member_Int8Pointer;
+ }
+ else if (m_currentMember->size == 2)
+ {
+ m_currentMember->type = Member_Int16Pointer;
+ }
+ else if (m_currentMember->size == 4)
+ {
+ m_currentMember->type = Member_Int32Pointer;
+ }
+ else
+ {
+ g_pSM->LogMessage(myself, "Invalid int size %i: line: %i col: %i", m_currentMember->size, states->line, states->col);
+ return SMCResult_HaltFail;
+ }
+ }
+
+ m_currentStruct->AddMember(m_currentMember->name, m_currentMember);
+
+ m_bInMember = false;
+ m_currentMember = NULL;
+
+ return SMCResult_Continue;
+ }
+
+ g_StructManager.AddStruct(m_currentStruct->name, m_currentStruct);
+
+ m_bInStruct = false;
+ m_currentStruct = NULL;
+
+ return SMCResult_Continue;
+}
diff --git a/extensions/structs/extension.h b/extensions/structs/extension.h
new file mode 100644
index 000000000..0c7bee274
--- /dev/null
+++ b/extensions/structs/extension.h
@@ -0,0 +1,165 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Sample Extension
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
+
+/**
+ * @file extension.h
+ * @brief Sample extension code header.
+ */
+
+#include "smsdk_ext.h"
+#include "StructManager.h"
+#include "StructHandle.h"
+#include "Struct.h"
+
+/**
+ * @brief Sample implementation of the SDK Extension.
+ * Note: Uncomment one of the pre-defined virtual functions in order to use it.
+ */
+class Structs :
+ public SDKExtension,
+ public ITextListener_SMC
+{
+public:
+ /**
+ * @brief This is called after the initial loading sequence has been processed.
+ *
+ * @param error Error message buffer.
+ * @param maxlength Size of error message buffer.
+ * @param late Whether or not the module was loaded after map load.
+ * @return True to succeed loading, false to fail.
+ */
+ virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
+
+ /**
+ * @brief This is called right before the extension is unloaded.
+ */
+ virtual void SDK_OnUnload();
+
+ /**
+ * @brief This is called once all known extensions have been loaded.
+ * Note: It is is a good idea to add natives here, if any are provided.
+ */
+ virtual void SDK_OnAllLoaded();
+
+ /**
+ * @brief Called when the pause state is changed.
+ */
+ //virtual void SDK_OnPauseChange(bool paused);
+
+ /**
+ * @brief this is called when Core wants to know if your extension is working.
+ *
+ * @param error Error message buffer.
+ * @param maxlength Size of error message buffer.
+ * @return True if working, false otherwise.
+ */
+ //virtual bool QueryRunning(char *error, size_t maxlength);
+public:
+#if defined SMEXT_CONF_METAMOD
+ /**
+ * @brief Called when Metamod is attached, before the extension version is called.
+ *
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @param late Whether or not Metamod considers this a late load.
+ * @return True to succeed, false to fail.
+ */
+ //virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
+
+ /**
+ * @brief Called when Metamod is detaching, after the extension version is called.
+ * NOTE: By default this is blocked unless sent from SourceMod.
+ *
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @return True to succeed, false to fail.
+ */
+ //virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
+
+ /**
+ * @brief Called when Metamod's pause state is changing.
+ * NOTE: By default this is blocked unless sent from SourceMod.
+ *
+ * @param paused Pause state being set.
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @return True to succeed, false to fail.
+ */
+ //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
+#endif
+
+public:
+ //ITextListener_SMC
+ SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
+ SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
+ SMCResult ReadSMC_LeavingSection(const SMCStates *states);
+ void ReadSMC_ParseStart();
+
+private:
+ bool m_bInStruct;
+ StructInfo *m_currentStruct;
+ bool m_bInMember;
+ MemberInfo *m_currentMember;
+
+ KTrie m_typeLookup;
+};
+
+size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
+
+class StructHandler : public IHandleTypeDispatch
+{
+public:
+ void OnHandleDestroy(HandleType_t type, void *object)
+ {
+ StructHandle *pHandle = (StructHandle *)object;
+
+ if (pHandle->canDelete)
+ {
+ //delete pHandle->data;
+ }
+
+ delete pHandle;
+ }
+};
+
+extern HandleType_t g_StructHandle;
+extern StructHandler g_StructHandler;
+
+extern StructManager g_StructManager;
+
+extern const sp_nativeinfo_t MyNatives[];
+
+extern IGameConfig *conf;
+
+#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
diff --git a/extensions/structs/msvc8/sdk.sln b/extensions/structs/msvc8/sdk.sln
new file mode 100644
index 000000000..0692ab26e
--- /dev/null
+++ b/extensions/structs/msvc8/sdk.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdk", "sdk.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug - Episode 1|Win32 = Debug - Episode 1|Win32
+ Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32
+ Debug - Orange Box|Win32 = Debug - Orange Box|Win32
+ Debug|Win32 = Debug|Win32
+ Release - Episode 1|Win32 = Release - Episode 1|Win32
+ Release - Old Metamod|Win32 = Release - Old Metamod|Win32
+ Release - Orange Box|Win32 = Release - Orange Box|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/extensions/structs/msvc8/sdk.vcproj b/extensions/structs/msvc8/sdk.vcproj
new file mode 100644
index 000000000..13c60d1b3
--- /dev/null
+++ b/extensions/structs/msvc8/sdk.vcproj
@@ -0,0 +1,750 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/structs/msvc9/sdk.sln b/extensions/structs/msvc9/sdk.sln
new file mode 100644
index 000000000..a9964794f
--- /dev/null
+++ b/extensions/structs/msvc9/sdk.sln
@@ -0,0 +1,38 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdk", "sdk.vcproj", "{B3E797CF-4E77-4C9D-B8A8-7589B6902206}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug - Episode 1|Win32 = Debug - Episode 1|Win32
+ Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32
+ Debug - Orange Box|Win32 = Debug - Orange Box|Win32
+ Debug|Win32 = Debug|Win32
+ Release - Episode 1|Win32 = Release - Episode 1|Win32
+ Release - Old Metamod|Win32 = Release - Old Metamod|Win32
+ Release - Orange Box|Win32 = Release - Orange Box|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Debug|Win32.Build.0 = Debug|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.ActiveCfg = Release|Win32
+ {B3E797CF-4E77-4C9D-B8A8-7589B6902206}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/extensions/structs/msvc9/sdk.vcproj b/extensions/structs/msvc9/sdk.vcproj
new file mode 100644
index 000000000..f573da3ca
--- /dev/null
+++ b/extensions/structs/msvc9/sdk.vcproj
@@ -0,0 +1,743 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extensions/structs/natives.cpp b/extensions/structs/natives.cpp
new file mode 100644
index 000000000..85b92301b
--- /dev/null
+++ b/extensions/structs/natives.cpp
@@ -0,0 +1,530 @@
+/**
+* vim: set ts=4 :
+* =============================================================================
+* SourceMod Sample Extension
+* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+* =============================================================================
+*
+* This program is free software; you can redistribute it and/or modify it under
+* the terms of the GNU General Public License, version 3.0, as published by the
+* Free Software Foundation.
+*
+* 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, see .
+*
+* As a special exception, AlliedModders LLC gives you permission to link the
+* code of this program (as well as its derivative works) to "Half-Life 2," the
+* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+* by the Valve Corporation. You must obey the GNU General Public License in
+* all respects for all other code used. Additionally, AlliedModders LLC grants
+* this exception to all derivative works. AlliedModders LLC defines further
+* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+* or .
+*
+* Version: $Id$
+*/
+
+#include "extension.h"
+#include "utldict.h"
+#include "weapon_parse.h"
+
+class FileWeaponInfo_t;
+typedef unsigned short WEAPON_FILE_INFO_HANDLE;
+
+inline edict_t *GetEdict(cell_t num)
+{
+ edict_t *pEdict = engine->PEntityOfEntIndex(num);
+ if (!pEdict || pEdict->IsFree())
+ {
+ return NULL;
+ }
+
+ return pEdict;
+}
+
+inline edict_t *GetEntity(cell_t num, CBaseEntity **pData)
+{
+ edict_t *pEdict = engine->PEntityOfEntIndex(num);
+ if (!pEdict || pEdict->IsFree())
+ {
+ return NULL;
+ }
+
+ IServerUnknown *pUnk;
+ if ((pUnk=pEdict->GetUnknown()) == NULL)
+ {
+ return NULL;
+ }
+ *pData = pUnk->GetBaseEntity();
+ return pEdict;
+}
+
+int CheckBaseHandle(CBaseHandle &hndl)
+{
+ if (!hndl.IsValid())
+ {
+ return -1;
+ }
+
+ int index = hndl.GetEntryIndex();
+
+ edict_t *pStoredEdict;
+ CBaseEntity *pStoredEntity;
+
+ pStoredEdict = GetEntity(index, &pStoredEntity);
+
+ if (pStoredEdict == NULL || pStoredEntity == NULL)
+ {
+ return -1;
+ }
+
+ IServerEntity *pSE = pStoredEdict->GetIServerEntity();
+
+ if (pSE == NULL)
+ {
+ return -1;
+ }
+
+ if (pSE->GetRefEHandle() != hndl)
+ {
+ return -1;
+ }
+
+ return index;
+}
+
+//native GetStructInt(Handle:struct, const String:member[]);
+static cell_t GetStructInt(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ int value;
+
+ if (!pHandle->GetInt(member, &value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return value;
+}
+
+//native SetStructInt(Handle:struct, const String:member[], value);
+static cell_t SetStructInt(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = handlesys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ if (!pHandle->SetInt(member, params[3]))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return 1;
+}
+
+//native GetStructFloat(Handle:struct, const String:member[], &Float:value);
+static cell_t GetStructFloat(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ float value;
+
+ if (!pHandle->GetFloat(member, &value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return sp_ftoc(value);
+}
+
+//native SetStructFloat(Handle:struct, const String:member[], Float:value);
+static cell_t SetStructFloat(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ if (!pHandle->SetFloat(member, sp_ctof(params[3])))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return 1;
+}
+
+//native GetStructVector(Handle:struct, const String:member[], Float:vec[3]);
+static cell_t GetStructVector(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ cell_t *addr;
+ pContext->LocalToPhysAddr(params[3], &addr);
+
+ Vector value;
+
+ if (!pHandle->GetVector(member, &value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ addr[0] = sp_ftoc(value.x);
+ addr[1] = sp_ftoc(value.y);
+ addr[2] = sp_ftoc(value.z);
+
+ return 1;
+}
+
+//native SetStructVector(Handle:struct, const String:member[], Float:vec[3]);
+static cell_t SetStructVector(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ Vector value;
+
+ cell_t *addr;
+ pContext->LocalToPhysAddr(params[3], &addr);
+
+ value.x = sp_ctof(addr[0]);
+ value.y = sp_ctof(addr[1]);
+ value.z = sp_ctof(addr[2]);
+
+ if (!pHandle->SetVector(member, value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return 1;
+}
+
+//native GetStructString(Handle:struct, const String:member[], String:value[], maxlen);
+static cell_t GetStructString(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ char *string;
+ if (!pHandle->GetString(member, &string))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ pContext->StringToLocal(params[3], params[4], string);
+
+ return 1;
+}
+
+//native SetStructString(Handle:struct, const String:member[], String:value[]);
+static cell_t SetStructString(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ char *string;
+ pContext->LocalToString(params[3], &string);
+
+ if (!pHandle->SetString(member, string))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return 1;
+}
+
+//native GetStructEnt(Handle:struct, const String:member[], &ent);
+static cell_t GetStructEnt(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ CBaseHandle *value;
+ if (!pHandle->GetEHandle(member, &value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return CheckBaseHandle(*value);
+}
+
+//native SetStructEnt(Handle:struct, const String:member[], ent);
+static cell_t SetStructEnt(IPluginContext *pContext, const cell_t *params)
+{
+ Handle_t hndl = static_cast(params[1]);
+ HandleError err;
+ HandleSecurity sec;
+
+ sec.pOwner = NULL;
+ sec.pIdentity = myself->GetIdentity();
+
+ StructHandle *pHandle;
+ if ((err = g_pHandleSys->ReadHandle(hndl, g_StructHandle, &sec, (void **)&pHandle))
+ != HandleError_None)
+ {
+ return pContext->ThrowNativeError("Invalid struct handle %x (error %d)", hndl, err);
+ }
+
+ char *member;
+ pContext->LocalToString(params[2], &member);
+
+ CBaseHandle *value;
+ if (!pHandle->GetEHandle(member, &value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ edict_t *pEdict = GetEdict(params[3]);
+
+ if (pEdict == NULL)
+ {
+ return pContext->ThrowNativeError("Invalid entity %i", params[3]);
+ }
+
+ IServerEntity *pEntOther = pEdict->GetIServerEntity();
+ value->Set(pEntOther);
+
+ if (!pHandle->SetEHandle(member, value))
+ {
+ return pContext->ThrowNativeError("Invalid member, or incorrect data type");
+ }
+
+ return 1;
+}
+
+static cell_t GetWeaponStruct(IPluginContext *pContext, const cell_t *params)
+{
+ char *weapon;
+ pContext->LocalToString(params[1], &weapon);
+
+ void **func;
+
+#if defined WIN32
+ void *addr = NULL;
+ func = &addr;
+#else
+ WEAPON_FILE_INFO_HANDLE (*LookupWeaponInfoSlot)(const char *) = NULL;
+ func = (void **)&LookupWeaponInfoSlot;
+#endif
+
+ FileWeaponInfo_t *(*GetFileWeaponInfoFromHandle)( WEAPON_FILE_INFO_HANDLE handle ) = NULL;
+
+ if (!conf->GetMemSig("LookupWeaponInfoSlot", func) || *func == NULL)
+ {
+ return pContext->ThrowNativeError("Failed to locate signature LookupWeaponInfoSlot");
+ }
+
+ if (!conf->GetMemSig("GetFileWeaponInfoFromHandle", (void **)&GetFileWeaponInfoFromHandle) || GetFileWeaponInfoFromHandle == NULL)
+ {
+ return pContext->ThrowNativeError("Failed to locate signature GetFileWeaponInfoFromHandle");
+ }
+
+#if defined WIN32
+ int offset;
+
+ if (!conf->GetOffset("m_WeaponInfoDatabase", &offset))
+ {
+ return pContext->ThrowNativeError("Failed to locate offset m_WeaponInfoDatabase");
+ }
+
+ addr = (unsigned char *)addr + offset;
+
+ CUtlDict< FileWeaponInfo_t*, unsigned short > *m_WeaponInfoDatabase = *(CUtlDict< FileWeaponInfo_t*, unsigned short > **)addr;
+
+ WEAPON_FILE_INFO_HANDLE handle = m_WeaponInfoDatabase->Find(weapon);
+
+ if (handle == -1 || handle == m_WeaponInfoDatabase->InvalidIndex())
+ {
+ return pContext->ThrowNativeError("Could not find weapon %s", weapon);
+ }
+#else
+ WEAPON_FILE_INFO_HANDLE handle = LookupWeaponInfoSlot(weapon);
+#endif
+ FileWeaponInfo_t *info = GetFileWeaponInfoFromHandle(handle);
+
+ //g_pSM->LogMessage(myself, "%i %i %x", handle, GetInvalidWeaponInfoHandle(), info);
+
+ if (!info)
+ {
+ return pContext->ThrowNativeError("Weapon does not exist!");
+ }
+
+ /* Offsets! */
+ /*
+ g_pSM->LogMessage(myself, "Offsets for FileWeaponInfo_t");
+ g_pSM->LogMessage(myself, "bParsed: %i", (unsigned char *)&(info->bParsedScript) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "bLoadedHudElements: %i", (unsigned char *)&(info->bLoadedHudElements) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szClassName: %i", (unsigned char *)&(info->szClassName) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szPrintName: %i", (unsigned char *)&(info->szPrintName) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szViewModel: %i", (unsigned char *)&(info->szViewModel) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szWorldModel: %i", (unsigned char *)&(info->szWorldModel) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szAnimationPrefix: %i", (unsigned char *)&(info->szAnimationPrefix) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iSlot: %i", (unsigned char *)&(info->iSlot) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iPosition: %i", (unsigned char *)&(info->iPosition) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iMaxClip1: %i", (unsigned char *)&(info->iMaxClip1) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iMaxClip2: %i", (unsigned char *)&(info->iMaxClip2) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iDefaultClip1: %i", (unsigned char *)&(info->iDefaultClip1) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iDefaultClip2: %i", (unsigned char *)&(info->iDefaultClip2) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iWeight: %i", (unsigned char *)&(info->iWeight) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iRumbleEffect: %i", (unsigned char *)&(info->iRumbleEffect) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "bAutoSwitchTo: %i", (unsigned char *)&(info->bAutoSwitchTo) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "bAutoSwitchFrom: %i", (unsigned char *)&(info->bAutoSwitchFrom) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iFlags: %i", (unsigned char *)&(info->iFlags) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szAmmo1: %i", (unsigned char *)&(info->szAmmo1) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "szAmmo2: %i", (unsigned char *)&(info->szAmmo2) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "aShootSounds: %i", (unsigned char *)&(info->aShootSounds) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iAmmoType: %i", (unsigned char *)&(info->iAmmoType) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "iAmmo2Type: %i", (unsigned char *)&(info->iAmmo2Type) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "m_bMeleeWeapon: %i", (unsigned char *)&(info->m_bMeleeWeapon) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "m_bBuiltRightHanded: %i", (unsigned char *)&(info->m_bBuiltRightHanded) - (unsigned char *)info);
+ g_pSM->LogMessage(myself, "m_bAllowFlipping: %i", (unsigned char *)&(info->m_bAllowFlipping) - (unsigned char *)info);
+ */
+ return g_StructManager.CreateStructHandle("FileWeaponInfo_t", info);
+};
+
+const sp_nativeinfo_t MyNatives[] =
+{
+ {"GetStructInt", GetStructInt},
+ {"SetStructInt", SetStructInt},
+ {"GetStructFloat", GetStructFloat},
+ {"SetStructFloat", SetStructFloat},
+ {"GetStructVector", GetStructVector},
+ {"SetStructVector", SetStructVector},
+ {"GetStructString", GetStructString},
+ {"SetStructString", SetStructString},
+ {"GetStructEnt", GetStructEnt},
+ {"SetStructEnt", SetStructEnt},
+ {"GetWeaponStruct", GetWeaponStruct},
+ {NULL, NULL},
+};
diff --git a/extensions/structs/sdk/smsdk_config.h b/extensions/structs/sdk/smsdk_config.h
new file mode 100644
index 000000000..197f103df
--- /dev/null
+++ b/extensions/structs/sdk/smsdk_config.h
@@ -0,0 +1,80 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Sample Extension
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
+
+/**
+ * @file smsdk_config.h
+ * @brief Contains macros for configuring basic extension information.
+ */
+
+/* Basic information exposed publicly */
+#define SMEXT_CONF_NAME "Struct Abstraction Extension"
+#define SMEXT_CONF_DESCRIPTION "Makes complex structs available in SourcePawn"
+#define SMEXT_CONF_VERSION "1.0.0.0"
+#define SMEXT_CONF_AUTHOR "AlliedModders"
+#define SMEXT_CONF_URL "http://www.sourcemod.net/"
+#define SMEXT_CONF_LOGTAG "STRUCTS"
+#define SMEXT_CONF_LICENSE "GPL"
+#define SMEXT_CONF_DATESTRING __DATE__
+
+/**
+ * @brief Exposes plugin's main interface.
+ */
+#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name;
+
+/**
+ * @brief Sets whether or not this plugin required Metamod.
+ * NOTE: Uncomment to enable, comment to disable.
+ */
+#define SMEXT_CONF_METAMOD
+
+/** Enable interfaces you want to use here by uncommenting lines */
+//#define SMEXT_ENABLE_FORWARDSYS
+#define SMEXT_ENABLE_HANDLESYS
+//#define SMEXT_ENABLE_PLAYERHELPERS
+//#define SMEXT_ENABLE_DBMANAGER
+#define SMEXT_ENABLE_GAMECONF
+//#define SMEXT_ENABLE_MEMUTILS
+//#define SMEXT_ENABLE_GAMEHELPERS
+//#define SMEXT_ENABLE_TIMERSYS
+//#define SMEXT_ENABLE_THREADER
+//#define SMEXT_ENABLE_LIBSYS
+//#define SMEXT_ENABLE_MENUS
+//#define SMEXT_ENABLE_ADTFACTORY
+//#define SMEXT_ENABLE_PLUGINSYS
+//#define SMEXT_ENABLE_ADMINSYS
+#define SMEXT_ENABLE_TEXTPARSERS
+//#define SMEXT_ENABLE_USERMSGS
+//#define SMEXT_ENABLE_TRANSLATOR
+
+#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
diff --git a/extensions/structs/sdk/smsdk_ext.cpp b/extensions/structs/sdk/smsdk_ext.cpp
new file mode 100644
index 000000000..865f536ed
--- /dev/null
+++ b/extensions/structs/sdk/smsdk_ext.cpp
@@ -0,0 +1,461 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Base Extension Code
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#include
+#include
+#include "smsdk_ext.h"
+
+/**
+ * @file smsdk_ext.cpp
+ * @brief Contains wrappers for making Extensions easier to write.
+ */
+
+IExtension *myself = NULL; /**< Ourself */
+IShareSys *g_pShareSys = NULL; /**< Share system */
+IShareSys *sharesys = NULL; /**< Share system */
+ISourceMod *g_pSM = NULL; /**< SourceMod helpers */
+ISourceMod *smutils = NULL; /**< SourceMod helpers */
+
+#if defined SMEXT_ENABLE_FORWARDSYS
+IForwardManager *g_pForwards = NULL; /**< Forward system */
+IForwardManager *forwards = NULL; /**< Forward system */
+#endif
+#if defined SMEXT_ENABLE_HANDLESYS
+IHandleSys *g_pHandleSys = NULL; /**< Handle system */
+IHandleSys *handlesys = NULL; /**< Handle system */
+#endif
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+IPlayerManager *playerhelpers = NULL; /**< Player helpers */
+#endif //SMEXT_ENABLE_PLAYERHELPERS
+#if defined SMEXT_ENABLE_DBMANAGER
+IDBManager *dbi = NULL; /**< DB Manager */
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMECONF
+IGameConfigManager *gameconfs = NULL; /**< Game config manager */
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_MEMUTILS
+IMemoryUtils *memutils = NULL;
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMEHELPERS
+IGameHelpers *gamehelpers = NULL;
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+ITimerSystem *timersys = NULL;
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+IADTFactory *adtfactory = NULL;
+#endif
+#if defined SMEXT_ENABLE_THREADER
+IThreader *threader = NULL;
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+ILibrarySys *libsys = NULL;
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+SourceMod::IPluginManager *plsys;
+#endif
+#if defined SMEXT_ENABLE_MENUS
+IMenuManager *menus = NULL;
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+IAdminSystem *adminsys = NULL;
+#endif
+#if defined SMEXT_ENABLE_TEXTPARSERS
+ITextParsers *textparsers = NULL;
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+IUserMessages *usermsgs = NULL;
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+ITranslator *translator = NULL;
+#endif
+
+/** Exports the main interface */
+PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
+{
+ return g_pExtensionIface;
+}
+
+SDKExtension::SDKExtension()
+{
+#if defined SMEXT_CONF_METAMOD
+ m_SourceMMLoaded = false;
+ m_WeAreUnloaded = false;
+ m_WeGotPauseChange = false;
+#endif
+}
+
+bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late)
+{
+ g_pShareSys = sharesys = sys;
+ myself = me;
+
+#if defined SMEXT_CONF_METAMOD
+ m_WeAreUnloaded = true;
+
+ if (!m_SourceMMLoaded)
+ {
+ if (error)
+ {
+ snprintf(error, maxlength, "Metamod attach failed");
+ }
+ return false;
+ }
+#endif
+ SM_GET_IFACE(SOURCEMOD, g_pSM);
+ smutils = g_pSM;
+#if defined SMEXT_ENABLE_HANDLESYS
+ SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys);
+ handlesys = g_pHandleSys;
+#endif
+#if defined SMEXT_ENABLE_FORWARDSYS
+ SM_GET_IFACE(FORWARDMANAGER, g_pForwards);
+ forwards = g_pForwards;
+#endif
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+ SM_GET_IFACE(PLAYERMANAGER, playerhelpers);
+#endif
+#if defined SMEXT_ENABLE_DBMANAGER
+ SM_GET_IFACE(DBI, dbi);
+#endif
+#if defined SMEXT_ENABLE_GAMECONF
+ SM_GET_IFACE(GAMECONFIG, gameconfs);
+#endif
+#if defined SMEXT_ENABLE_MEMUTILS
+ SM_GET_IFACE(MEMORYUTILS, memutils);
+#endif
+#if defined SMEXT_ENABLE_GAMEHELPERS
+ SM_GET_IFACE(GAMEHELPERS, gamehelpers);
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+ SM_GET_IFACE(TIMERSYS, timersys);
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+ SM_GET_IFACE(ADTFACTORY, adtfactory);
+#endif
+#if defined SMEXT_ENABLE_THREADER
+ SM_GET_IFACE(THREADER, threader);
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+ SM_GET_IFACE(LIBRARYSYS, libsys);
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+ SM_GET_IFACE(PLUGINSYSTEM, plsys);
+#endif
+#if defined SMEXT_ENABLE_MENUS
+ SM_GET_IFACE(MENUMANAGER, menus);
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+ SM_GET_IFACE(ADMINSYS, adminsys);
+#endif
+#if defined SMEXT_ENABLE_TEXTPARSERS
+ SM_GET_IFACE(TEXTPARSERS, textparsers);
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+ SM_GET_IFACE(USERMSGS, usermsgs);
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+ SM_GET_IFACE(TRANSLATOR, translator);
+#endif
+
+ if (SDK_OnLoad(error, maxlength, late))
+ {
+#if defined SMEXT_CONF_METAMOD
+ m_WeAreUnloaded = true;
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+bool SDKExtension::IsMetamodExtension()
+{
+#if defined SMEXT_CONF_METAMOD
+ return true;
+#else
+ return false;
+#endif
+}
+
+void SDKExtension::OnExtensionPauseChange(bool state)
+{
+#if defined SMEXT_CONF_METAMOD
+ m_WeGotPauseChange = true;
+#endif
+ SDK_OnPauseChange(state);
+}
+
+void SDKExtension::OnExtensionsAllLoaded()
+{
+ SDK_OnAllLoaded();
+}
+
+void SDKExtension::OnExtensionUnload()
+{
+#if defined SMEXT_CONF_METAMOD
+ m_WeAreUnloaded = true;
+#endif
+ SDK_OnUnload();
+}
+
+const char *SDKExtension::GetExtensionAuthor()
+{
+ return SMEXT_CONF_AUTHOR;
+}
+
+const char *SDKExtension::GetExtensionDateString()
+{
+ return SMEXT_CONF_DATESTRING;
+}
+
+const char *SDKExtension::GetExtensionDescription()
+{
+ return SMEXT_CONF_DESCRIPTION;
+}
+
+const char *SDKExtension::GetExtensionVerString()
+{
+ return SMEXT_CONF_VERSION;
+}
+
+const char *SDKExtension::GetExtensionName()
+{
+ return SMEXT_CONF_NAME;
+}
+
+const char *SDKExtension::GetExtensionTag()
+{
+ return SMEXT_CONF_LOGTAG;
+}
+
+const char *SDKExtension::GetExtensionURL()
+{
+ return SMEXT_CONF_URL;
+}
+
+bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late)
+{
+ return true;
+}
+
+void SDKExtension::SDK_OnUnload()
+{
+}
+
+void SDKExtension::SDK_OnPauseChange(bool paused)
+{
+}
+
+void SDKExtension::SDK_OnAllLoaded()
+{
+}
+
+#if defined SMEXT_CONF_METAMOD
+
+PluginId g_PLID = 0; /**< Metamod plugin ID */
+ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */
+SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */
+ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */
+
+IVEngineServer *engine = NULL; /**< IVEngineServer pointer */
+IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */
+
+/** Exposes the extension to Metamod */
+SMM_API void *PL_EXPOSURE(const char *name, int *code)
+{
+#if defined METAMOD_PLAPI_VERSION
+ if (name && !strcmp(name, METAMOD_PLAPI_NAME))
+#else
+ if (name && !strcmp(name, PLAPI_NAME))
+#endif
+ {
+ if (code)
+ {
+ *code = IFACE_OK;
+ }
+ return static_cast(g_pExtensionIface);
+ }
+
+ if (code)
+ {
+ *code = IFACE_FAILED;
+ }
+
+ return NULL;
+}
+
+bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late)
+{
+ PLUGIN_SAVEVARS();
+
+#if !defined METAMOD_PLAPI_VERSION
+ GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
+ GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
+#else
+ GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
+ GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER);
+#endif
+
+ m_SourceMMLoaded = true;
+
+ return SDK_OnMetamodLoad(ismm, error, maxlen, late);
+}
+
+bool SDKExtension::Unload(char *error, size_t maxlen)
+{
+ if (!m_WeAreUnloaded)
+ {
+ if (error)
+ {
+ snprintf(error, maxlen, "This extension must be unloaded by SourceMod.");
+ }
+ return false;
+ }
+
+ return SDK_OnMetamodUnload(error, maxlen);
+}
+
+bool SDKExtension::Pause(char *error, size_t maxlen)
+{
+ if (!m_WeGotPauseChange)
+ {
+ if (error)
+ {
+ snprintf(error, maxlen, "This extension must be paused by SourceMod.");
+ }
+ return false;
+ }
+
+ m_WeGotPauseChange = false;
+
+ return SDK_OnMetamodPauseChange(true, error, maxlen);
+}
+
+bool SDKExtension::Unpause(char *error, size_t maxlen)
+{
+ if (!m_WeGotPauseChange)
+ {
+ if (error)
+ {
+ snprintf(error, maxlen, "This extension must be unpaused by SourceMod.");
+ }
+ return false;
+ }
+
+ m_WeGotPauseChange = false;
+
+ return SDK_OnMetamodPauseChange(false, error, maxlen);
+}
+
+const char *SDKExtension::GetAuthor()
+{
+ return GetExtensionAuthor();
+}
+
+const char *SDKExtension::GetDate()
+{
+ return GetExtensionDateString();
+}
+
+const char *SDKExtension::GetDescription()
+{
+ return GetExtensionDescription();
+}
+
+const char *SDKExtension::GetLicense()
+{
+ return SMEXT_CONF_LICENSE;
+}
+
+const char *SDKExtension::GetLogTag()
+{
+ return GetExtensionTag();
+}
+
+const char *SDKExtension::GetName()
+{
+ return GetExtensionName();
+}
+
+const char *SDKExtension::GetURL()
+{
+ return GetExtensionURL();
+}
+
+const char *SDKExtension::GetVersion()
+{
+ return GetExtensionVerString();
+}
+
+bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late)
+{
+ return true;
+}
+
+bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength)
+{
+ return true;
+}
+
+bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength)
+{
+ return true;
+}
+
+#endif
+
+/* Overload a few things to prevent libstdc++ linking */
+#if defined __linux__
+extern "C" void __cxa_pure_virtual(void)
+{
+}
+
+void *operator new(size_t size)
+{
+ return malloc(size);
+}
+
+void *operator new[](size_t size)
+{
+ return malloc(size);
+}
+
+void operator delete(void *ptr)
+{
+ free(ptr);
+}
+
+void operator delete[](void * ptr)
+{
+ free(ptr);
+}
+#endif
diff --git a/extensions/structs/sdk/smsdk_ext.h b/extensions/structs/sdk/smsdk_ext.h
new file mode 100644
index 000000000..115fc8008
--- /dev/null
+++ b/extensions/structs/sdk/smsdk_ext.h
@@ -0,0 +1,333 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Base Extension Code
+ * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
+#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
+
+/**
+ * @file smsdk_ext.h
+ * @brief Contains wrappers for making Extensions easier to write.
+ */
+
+#include "smsdk_config.h"
+#include
+#include
+#include
+#include
+#include
+#if defined SMEXT_ENABLE_FORWARDSYS
+#include
+#endif //SMEXT_ENABLE_FORWARDSYS
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+#include
+#endif //SMEXT_ENABLE_PlAYERHELPERS
+#if defined SMEXT_ENABLE_DBMANAGER
+#include
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMECONF
+#include
+#endif
+#if defined SMEXT_ENABLE_MEMUTILS
+#include
+#endif
+#if defined SMEXT_ENABLE_GAMEHELPERS
+#include
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+#include
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+#include
+#endif
+#if defined SMEXT_ENABLE_THREADER
+#include
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+#include
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+#include
+#endif
+#if defined SMEXT_ENABLE_MENUS
+#include
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+#include
+#endif
+#if defined SMEXT_ENABLE_TEXTPARSERS
+#include
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+#include
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+#include
+#endif
+
+#if defined SMEXT_CONF_METAMOD
+#include
+#include
+#endif
+
+using namespace SourceMod;
+using namespace SourcePawn;
+
+class SDKExtension :
+#if defined SMEXT_CONF_METAMOD
+ public ISmmPlugin,
+#endif
+ public IExtensionInterface
+{
+public:
+ /** Constructor */
+ SDKExtension();
+public:
+ /**
+ * @brief This is called after the initial loading sequence has been processed.
+ *
+ * @param error Error message buffer.
+ * @param maxlength Size of error message buffer.
+ * @param late Whether or not the module was loaded after map load.
+ * @return True to succeed loading, false to fail.
+ */
+ virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
+
+ /**
+ * @brief This is called right before the extension is unloaded.
+ */
+ virtual void SDK_OnUnload();
+
+ /**
+ * @brief This is called once all known extensions have been loaded.
+ */
+ virtual void SDK_OnAllLoaded();
+
+ /**
+ * @brief Called when the pause state is changed.
+ */
+ virtual void SDK_OnPauseChange(bool paused);
+
+#if defined SMEXT_CONF_METAMOD
+ /**
+ * @brief Called when Metamod is attached, before the extension version is called.
+ *
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @param late Whether or not Metamod considers this a late load.
+ * @return True to succeed, false to fail.
+ */
+ virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
+
+ /**
+ * @brief Called when Metamod is detaching, after the extension version is called.
+ * NOTE: By default this is blocked unless sent from SourceMod.
+ *
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @return True to succeed, false to fail.
+ */
+ virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
+
+ /**
+ * @brief Called when Metamod's pause state is changing.
+ * NOTE: By default this is blocked unless sent from SourceMod.
+ *
+ * @param paused Pause state being set.
+ * @param error Error buffer.
+ * @param maxlength Maximum size of error buffer.
+ * @return True to succeed, false to fail.
+ */
+ virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
+#endif
+
+public: //IExtensionInterface
+ virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late);
+ virtual void OnExtensionUnload();
+ virtual void OnExtensionsAllLoaded();
+
+ /** Returns whether or not this is a Metamod-based extension */
+ virtual bool IsMetamodExtension();
+
+ /**
+ * @brief Called when the pause state changes.
+ *
+ * @param state True if being paused, false if being unpaused.
+ */
+ virtual void OnExtensionPauseChange(bool state);
+
+ /** Returns name */
+ virtual const char *GetExtensionName();
+ /** Returns URL */
+ virtual const char *GetExtensionURL();
+ /** Returns log tag */
+ virtual const char *GetExtensionTag();
+ /** Returns author */
+ virtual const char *GetExtensionAuthor();
+ /** Returns version string */
+ virtual const char *GetExtensionVerString();
+ /** Returns description string */
+ virtual const char *GetExtensionDescription();
+ /** Returns date string */
+ virtual const char *GetExtensionDateString();
+#if defined SMEXT_CONF_METAMOD
+public: //ISmmPlugin
+ /** Called when the extension is attached to Metamod. */
+ virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late);
+ /** Returns the author to MM */
+ virtual const char *GetAuthor();
+ /** Returns the name to MM */
+ virtual const char *GetName();
+ /** Returns the description to MM */
+ virtual const char *GetDescription();
+ /** Returns the URL to MM */
+ virtual const char *GetURL();
+ /** Returns the license to MM */
+ virtual const char *GetLicense();
+ /** Returns the version string to MM */
+ virtual const char *GetVersion();
+ /** Returns the date string to MM */
+ virtual const char *GetDate();
+ /** Returns the logtag to MM */
+ virtual const char *GetLogTag();
+ /** Called on unload */
+ virtual bool Unload(char *error, size_t maxlength);
+ /** Called on pause */
+ virtual bool Pause(char *error, size_t maxlength);
+ /** Called on unpause */
+ virtual bool Unpause(char *error, size_t maxlength);
+private:
+ bool m_SourceMMLoaded;
+ bool m_WeAreUnloaded;
+ bool m_WeGotPauseChange;
+#endif
+};
+
+extern SDKExtension *g_pExtensionIface;
+extern IExtension *myself;
+
+extern IShareSys *g_pShareSys;
+extern IShareSys *sharesys; /* Note: Newer name */
+extern ISourceMod *g_pSM;
+extern ISourceMod *smutils; /* Note: Newer name */
+
+/* Optional interfaces are below */
+#if defined SMEXT_ENABLE_FORWARDSYS
+extern IForwardManager *g_pForwards;
+extern IForwardManager *forwards; /* Note: Newer name */
+#endif //SMEXT_ENABLE_FORWARDSYS
+#if defined SMEXT_ENABLE_HANDLESYS
+extern IHandleSys *g_pHandleSys;
+extern IHandleSys *handlesys; /* Note: Newer name */
+#endif //SMEXT_ENABLE_HANDLESYS
+#if defined SMEXT_ENABLE_PLAYERHELPERS
+extern IPlayerManager *playerhelpers;
+#endif //SMEXT_ENABLE_PLAYERHELPERS
+#if defined SMEXT_ENABLE_DBMANAGER
+extern IDBManager *dbi;
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_GAMECONF
+extern IGameConfigManager *gameconfs;
+#endif //SMEXT_ENABLE_DBMANAGER
+#if defined SMEXT_ENABLE_MEMUTILS
+extern IMemoryUtils *memutils;
+#endif
+#if defined SMEXT_ENABLE_GAMEHELPERS
+extern IGameHelpers *gamehelpers;
+#endif
+#if defined SMEXT_ENABLE_TIMERSYS
+extern ITimerSystem *timersys;
+#endif
+#if defined SMEXT_ENABLE_ADTFACTORY
+extern IADTFactory *adtfactory;
+#endif
+#if defined SMEXT_ENABLE_THREADER
+extern IThreader *threader;
+#endif
+#if defined SMEXT_ENABLE_LIBSYS
+extern ILibrarySys *libsys;
+#endif
+#if defined SMEXT_ENABLE_PLUGINSYS
+extern SourceMod::IPluginManager *plsys;
+#endif
+#if defined SMEXT_ENABLE_MENUS
+extern IMenuManager *menus;
+#endif
+#if defined SMEXT_ENABLE_ADMINSYS
+extern IAdminSystem *adminsys;
+#endif
+#if defined SMEXT_ENABLE_USERMSGS
+extern IUserMessages *usermsgs;
+#endif
+#if defined SMEXT_ENABLE_TRANSLATOR
+extern ITranslator *translator;
+#endif
+
+#if defined SMEXT_CONF_METAMOD
+PLUGIN_GLOBALVARS();
+extern IVEngineServer *engine;
+extern IServerGameDLL *gamedll;
+#endif
+
+/** Creates a SourceMod interface macro pair */
+#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION
+/** Automates retrieving SourceMod interfaces */
+#define SM_GET_IFACE(prefix, addr) \
+ if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \
+ { \
+ if (error != NULL && maxlength) \
+ { \
+ size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \
+ if (len >= maxlength) \
+ { \
+ error[maxlength - 1] = '\0'; \
+ } \
+ } \
+ return false; \
+ }
+/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */
+#define SM_GET_LATE_IFACE(prefix, addr) \
+ g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)
+/** Validates a SourceMod interface pointer */
+#define SM_CHECK_IFACE(prefix, addr) \
+ if (!addr) \
+ { \
+ if (error != NULL && maxlength) \
+ { \
+ size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \
+ if (len >= maxlength) \
+ { \
+ error[maxlength - 1] = '\0'; \
+ } \
+ } \
+ return false; \
+ }
+
+#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_
diff --git a/extensions/structs/structs.inc b/extensions/structs/structs.inc
new file mode 100644
index 000000000..19819d404
--- /dev/null
+++ b/extensions/structs/structs.inc
@@ -0,0 +1,178 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved.
+ * =============================================================================
+ *
+ * This file is part of the SourceMod/SourcePawn SDK.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 3.0, as published by the
+ * Free Software Foundation.
+ *
+ * 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, see .
+ *
+ * As a special exception, AlliedModders LLC gives you permission to link the
+ * code of this program (as well as its derivative works) to "Half-Life 2," the
+ * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
+ * by the Valve Corporation. You must obey the GNU General Public License in
+ * all respects for all other code used. Additionally, AlliedModders LLC grants
+ * this exception to all derivative works. AlliedModders LLC defines further
+ * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
+ * or .
+ *
+ * Version: $Id$
+ */
+
+#if defined _structs_included
+ #endinput
+#endif
+#define _structs_included
+
+/**
+ * Struct Gamedata Notes:
+ *
+ * Types: Sizes:
+ * int/int* 1/2/4
+ * float/float* Not required
+ * char/char* Length of char array
+ * Vector/Vector* Not required
+ * ent/ent* Not required
+ */
+
+/**
+ * Retrieves an integer value from a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to retrieve.
+ * @return Integer value.
+ * @error Undefined member, or member type mismatch.
+ */
+native GetStructInt(Handle:strct, const String:member[]);
+
+/**
+ * Sets an integer value in a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to set.
+ * @param value Value to set.
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native SetStructInt(Handle:strct, const String:member[], value);
+
+/**
+ * Retrieves a float value from a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to retrieve.
+ * @return Float value.
+ * @error Undefined member, or member type mismatch.
+ */
+native Float:GetStructFloat(Handle:strct, const String:member[]);
+
+/**
+ * Sets a float value in a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to set.
+ * @param value Value to set.
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native SetStructFloat(Handle:strct, const String:member[], Float:value);
+
+/**
+ * Retrieves an integer value from a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to retrieve.
+ * @param vec Buffer for the retrieved vector.
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native GetStructVector(Handle:strct, const String:member[], Float:vec[3]);
+
+/**
+ * Sets a Vector value in a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to set.
+ * @param vec Value to set.
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native SetStructVector(Handle:strct, const String:member[], Float:vec[3]);
+
+/**
+ * Retrieves a string from a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to retrieve.
+ * @param value Buffer for the retrieved string.
+ * @param maxlen Max length of the buffer
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native GetStructString(Handle:strct, const String:member[], const String:value[], maxlen);
+
+/**
+ * Sets a string value in a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to set.
+ * @param value Value to set.
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native SetStructString(Handle:strct, const String:member[], String:value[]);
+
+/**
+ * Retrieves an entity handle from a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to retrieve.
+ * @return Entity index.
+ * @error Undefined member, or member type mismatch.
+ */
+native GetStructEnt(Handle:strct, const String:member[]);
+
+/**
+ * Sets an entity handle value in a struct.
+ *
+ * @param strct Struct Handle.
+ * @param member Member name to set.
+ * @param entity Entity index to set.
+ * @noreturn
+ * @error Undefined member, or member type mismatch.
+ */
+native SetStructEnt(Handle:strct, const String:member[], entity);
+
+/**
+ * Retrieves a struct handle to a FileWeaponInfo_t for the given weapon name.
+ *
+ * @param weapon Weapon name to retrieve.
+ * @return Struct handle or INVALID_HANDLE on failure.
+ */
+native Handle:GetWeaponStruct(const String:weapon[]);
+
+/**
+ * Do not edit below this line!
+ */
+public Extension:__ext_struct =
+{
+ name = "Struct Abstraction Extension",
+ file = "structs.ext",
+ autoload = 1,
+#if defined REQUIRE_EXTENSIONS
+ required = 1,
+#else
+ required = 0,
+#endif
+};
diff --git a/extensions/structs/structs.txt b/extensions/structs/structs.txt
new file mode 100644
index 000000000..52ad8db49
--- /dev/null
+++ b/extensions/structs/structs.txt
@@ -0,0 +1,610 @@
+"Games"
+{
+ "#default"
+ {
+ "Signatures"
+ {
+ "LookupWeaponInfoSlot"
+ {
+ "library" "server"
+ "linux" "@_Z20LookupWeaponInfoSlotPKc"
+ /* This is actually ReadWeaponDataFromFileForSlot - We get find using an offset from here */
+ "windows" "\x81\xEC\x84\x00\x00\x00\x56\x8B\xB4\x24\x94\x00\x00\x00\x85\xF6\x75\x0A"
+ }
+
+ "GetFileWeaponInfoFromHandle"
+ {
+ "library" "server"
+ "linux" "@_Z27GetFileWeaponInfoFromHandlet"
+ "windows" "\x66\x8B\x44\x24\x04\x66\x3B\x05\x2A\x2A\x2A\x2A\x73\x17"
+ }
+ }
+
+ "Offsets"
+ {
+ "m_WeaponInfoDatabase"
+ {
+ "windows" "38"
+ }
+ }
+
+ "Structs"
+ {
+ "TestStruct"
+ {
+ "size" "155"
+
+ "seven"
+ {
+ "type" "float"
+ "windows" "0"
+ "linux" "0"
+ }
+ "eight"
+ {
+ "type" "float*"
+ "windows" "4"
+ "linux" "4"
+ }
+ "nine"
+ {
+ "type" "Vector"
+ "windows" "8"
+ "linux" "8"
+ }
+ "ten"
+ {
+ "type" "Vector*"
+ "windows" "20"
+ "linux" "20"
+ }
+ "eleven"
+ {
+ "type" "char"
+ "size" "100"
+ "windows" "24"
+ "linux" "24"
+ }
+ "twelve"
+ {
+ "type" "char*"
+ "size" "100"
+ "windows" "124"
+ "linux" "124"
+ }
+ "thirteen"
+ {
+ "type" "ent"
+ "windows" "128"
+ "linux" "128"
+ }
+ "fourteen"
+ {
+ "type" "ent*"
+ "windows" "132"
+ "linux" "132"
+ }
+ "one"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "136"
+ "linux" "136"
+ }
+ "two"
+ {
+ "type" "int"
+ "size" "2"
+ "windows" "137"
+ "linux" "137"
+ }
+ "three"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "139"
+ "linux" "139"
+ }
+ "four"
+ {
+ "type" "int*"
+ "size" "1"
+ "windows" "143"
+ "linux" "143"
+ }
+ "five"
+ {
+ "type" "int*"
+ "size" "2"
+ "windows" "147"
+ "linux" "147"
+ }
+ "six"
+ {
+ "type" "int*"
+ "size" "4"
+ "windows" "151"
+ "linux" "151"
+ }
+ }
+ }
+ }
+
+ "tf"
+ {
+ "Structs"
+ {
+
+ "FileWeaponInfo_t"
+ {
+ "bParsedScript"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "4"
+ "linux" "4"
+ }
+
+ "bLoadedHudElements"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "5"
+ "linux" "5"
+ }
+
+ "szClassName"
+ {
+ "type" "char"
+ "size" "80"
+ "windows" "6"
+ "linux" "6"
+ }
+
+ "szPrintName"
+ {
+ "type" "char"
+ "size" "80"
+ "windows" "86"
+ "linux" "86"
+ }
+
+ "szViewModel"
+ {
+ "type" "char"
+ "size" "80"
+ "windows" "166"
+ "linux" "166"
+ }
+
+ "szWorldModel"
+ {
+ "type" "char"
+ "size" "80"
+ "windows" "246"
+ "linux" "246"
+ }
+
+ "szAnimationPrefix"
+ {
+ "type" "char"
+ "size" "16"
+ "windows" "326"
+ "linux" "326"
+ }
+
+ "iSlot"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "344"
+ "linux" "344"
+ }
+
+ "iPosition"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "348"
+ "linux" "348"
+ }
+
+ "iMaxClip1"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "352"
+ "linux" "352"
+ }
+
+ "iMaxClip2"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "356"
+ "linux" "356"
+ }
+
+ "iDefaultClip1"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "360"
+ "linux" "360"
+ }
+
+ "iDefaultClip2"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "364"
+ "linux" "364"
+ }
+
+ "iWeight"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "368"
+ "linux" "368"
+ }
+
+ "iRumbleEffect"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "372"
+ "linux" "372"
+ }
+
+ "bAutoSwitchFrom"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "376"
+ "linux" "376"
+ }
+
+ "bAutoSwitchTo"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "377"
+ "linux" "377"
+ }
+
+ "iFlags"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "380"
+ "linux" "380"
+ }
+
+ "szAmmo1"
+ {
+ "type" "char"
+ "size" "32"
+ "windows" "384"
+ "linux" "384"
+ }
+
+ "szAmmo2"
+ {
+ "type" "char"
+ "size" "32"
+ "windows" "416"
+ "linux" "416"
+ }
+
+ /* I could split this up into 15 strings of length 80 */
+ "aShootSounds"
+ {
+ "type" "char"
+ "size" "1200"
+ "windows" "448"
+ "linux" "448"
+ }
+
+ "iAmmoType"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "1648"
+ "linux" "1648"
+ }
+
+ "iAmmo2Type"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "1652"
+ "linux" "1652"
+ }
+
+ "m_bMeleeWeapon"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1656"
+ "linux" "1656"
+ }
+
+ "m_bBuiltRightHanded"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1657"
+ "linux" "1657"
+ }
+
+ "m_bAllowFlipping"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1658"
+ "linux" "1658"
+ }
+
+ "iDamage"
+ {
+ "type" "int"
+ "size" "4"
+ "linux" "1704"
+ "windows" "1704"
+ }
+
+ "iBulletsPerShot"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "1708"
+ "linux" "1708"
+ }
+
+ "fRange"
+ {
+ "type" "float"
+ "linux" "1712"
+ "windows" "1712"
+ }
+
+ "fSpread"
+ {
+ "type" "float"
+ "windows" "1716"
+ "linux" "1716"
+ }
+
+ "fPunchAngle"
+ {
+ "type" "float"
+ "windows" "1720"
+ "linux" "1720"
+ }
+
+ "fTimeFireDelay"
+ {
+ "type" "float"
+ "windows" "1724"
+ "linux" "1724"
+ }
+
+ "fTimeIdle"
+ {
+ "type" "float"
+ "windows" "1728"
+ "linux" "1728"
+ }
+
+ "fTimeIdleEmpty"
+ {
+ "type" "float"
+ "windows" "1732"
+ "linux" "1732"
+ }
+
+ "fTimeReloadStart"
+ {
+ "type" "float"
+ "windows" "1736"
+ "linux" "1736"
+ }
+
+ "fTimeReload"
+ {
+ "type" "float"
+ "windows" "1740"
+ "linux" "1740"
+ }
+
+ "bDrawCrosshair"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1744"
+ "linux" "1744"
+ }
+
+ "iAmmoPerShot"
+ {
+ "type" "int"
+ "size" "4"
+ "windows" "1752"
+ "linux" "1752"
+ }
+
+ "bUseRapidFireCrits"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1764"
+ "linux" "1764"
+ }
+
+ "iProjectileType"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1748"
+ "linux" "1748"
+ }
+
+ "fProjectileSpeed"
+ {
+ "type" "float"
+ "windows" "1756"
+ "linux" "1756"
+ }
+
+ "fSmackDelay"
+ {
+ "type" "float"
+ "windows" "1760"
+ "linux" "1760"
+ }
+
+ "bDoInstantEjectBrass"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "2240"
+ "linux" "2240"
+ }
+
+ "szBrassModel"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "2241"
+ "linux" "2241"
+ }
+
+ "bGrenade"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1836"
+ "linux" "1836"
+ }
+
+ "fDamageRadius"
+ {
+ "type" "float"
+ "windows" "1840"
+ "linux" "1840"
+ }
+
+ "fPrimerTime"
+ {
+ "type" "float"
+ "windows" "1844"
+ "linux" "1844"
+ }
+
+ "bPlayGrenTimer"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1849"
+ "linux" "1849"
+ }
+
+ "bLowerMainWeapon"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1848"
+ "linux" "1848"
+ }
+
+ "bHasTeamSkins_Viewmodel"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1850"
+ "linux" "1850"
+ }
+
+ "bHasTeamSkins_Worldmodel"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "1851"
+ "linux" "1851"
+ }
+
+ "szMuzzleFlashModel"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "1852"
+ "linux" "1852"
+ }
+
+ "fMuzzleFlashModelDuration"
+ {
+ "type" "float"
+ "windows" "1980"
+ "linux" "1980"
+ }
+
+ "szMuzzleFlashParticleEffect"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "1984"
+ "linux" "1984"
+ }
+
+ "szTracerEffect"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "2112"
+ "linux" "2112"
+ }
+
+ "szExplosionSound"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "2369"
+ "linux" "2369"
+ }
+
+ "szExplosionEffect"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "2497"
+ "linux" "2497"
+ }
+
+ "szExplosionPlayerEffect"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "2625"
+ "linux" "2625"
+ }
+
+ "szExplosionWaterEffect"
+ {
+ "type" "char"
+ "size" "128"
+ "windows" "2753"
+ "linux" "2753"
+ }
+
+ "bDontDrop"
+ {
+ "type" "int"
+ "size" "1"
+ "windows" "2881"
+ "linux" "2881"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/extensions/structs/structtest.sp b/extensions/structs/structtest.sp
new file mode 100644
index 000000000..5a399dfa0
--- /dev/null
+++ b/extensions/structs/structtest.sp
@@ -0,0 +1,156 @@
+#include
+#include "structs.inc"
+
+public Plugin:myinfo =
+{
+ name = "Struct Abstraction Test",
+ author = "pRED*",
+ description = "",
+ version = "1.0",
+ url = "http://www.sourcemod.net/"
+};
+
+public OnPluginStart()
+{
+ RegServerCmd("sm_getstructstring", Command_GetString);
+ RegServerCmd("sm_setstructstring", Command_SetString);
+
+ RegServerCmd("sm_getstructint", Command_GetInt);
+ RegServerCmd("sm_setstructint", Command_SetInt);
+
+ RegServerCmd("sm_getstructfloat", Command_GetFloat);
+ RegServerCmd("sm_setstructfloat", Command_SetFloat);
+
+}
+
+public Action:Command_GetString(args)
+{
+ if (args != 2)
+ {
+ ReplyToCommand(0, "[SM] Usage: sm_getstructstring ");
+ return Plugin_Handled;
+ }
+
+ decl String:arg1[32], String:arg2[32], String:value[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
+ GetCmdArg(2, arg2, sizeof(arg2));
+
+ new Handle:strct = GetWeaponStruct(arg1);
+ GetStructString(strct, arg2, value, sizeof(value));
+
+ LogMessage("Value of %s: %s", arg2, value);
+
+ CloseHandle(strct);
+
+ return Plugin_Handled;
+}
+
+public Action:Command_SetString(args)
+{
+ if (args != 3)
+ {
+ ReplyToCommand(0, "[SM] Usage: sm_setstructstring ");
+ return Plugin_Handled;
+ }
+
+ decl String:arg1[32], String:arg2[32], String:value[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
+ GetCmdArg(2, arg2, sizeof(arg2));
+ GetCmdArg(3, value, sizeof(value));
+
+ new Handle:strct = GetWeaponStruct(arg1);
+ SetStructString(strct, arg2, value);
+
+ CloseHandle(strct);
+
+ return Plugin_Handled;
+
+}
+
+public Action:Command_GetInt(args)
+{
+ if (args != 2)
+ {
+ ReplyToCommand(0, "[SM] Usage: sm_getstructint ");
+ return Plugin_Handled;
+ }
+
+ decl String:arg1[32], String:arg2[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
+ GetCmdArg(2, arg2, sizeof(arg2));
+
+ new Handle:strct = GetWeaponStruct(arg1);
+ new value = GetStructInt(strct, arg2);
+
+ LogMessage("Value of %s: %i", arg2, value);
+
+ CloseHandle(strct);
+
+ return Plugin_Handled;
+}
+
+public Action:Command_SetInt(args)
+{
+ if (args != 3)
+ {
+ ReplyToCommand(0, "[SM] Usage: sm_setstructint ");
+ return Plugin_Handled;
+ }
+
+ decl String:arg1[32], String:arg2[32], String:value[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
+ GetCmdArg(2, arg2, sizeof(arg2));
+ GetCmdArg(3, value, sizeof(value));
+
+ new Handle:strct = GetWeaponStruct(arg1);
+ SetStructInt(strct, arg2, StringToInt(value));
+
+
+ CloseHandle(strct);
+
+ return Plugin_Handled;
+}
+
+public Action:Command_GetFloat(args)
+{
+ if (args != 2)
+ {
+ ReplyToCommand(0, "[SM] Usage: sm_getstructint ");
+ return Plugin_Handled;
+ }
+
+ decl String:arg1[32], String:arg2[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
+ GetCmdArg(2, arg2, sizeof(arg2));
+
+ new Handle:strct = GetWeaponStruct(arg1);
+ new Float:value = GetStructFloat(strct, arg2);
+
+ LogMessage("Value of %s: %f", arg2, value);
+
+ CloseHandle(strct);
+
+ return Plugin_Handled;
+}
+
+public Action:Command_SetFloat(args)
+{
+ if (args != 3)
+ {
+ ReplyToCommand(0, "[SM] Usage: sm_setstructint ");
+ return Plugin_Handled;
+ }
+
+ decl String:arg1[32], String:arg2[32], String:value[32];
+ GetCmdArg(1, arg1, sizeof(arg1));
+ GetCmdArg(2, arg2, sizeof(arg2));
+ GetCmdArg(3, value, sizeof(value));
+
+ new Handle:strct = GetWeaponStruct(arg1);
+ SetStructFloat(strct, arg2, StringToFloat(value));
+
+
+ CloseHandle(strct);
+
+ return Plugin_Handled;
+}