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; +}