diff --git a/extensions/tf2/Makefile.ep1 b/extensions/tf2/Makefile.ep1
index 6bfeafe5..87f0423f 100644
--- a/extensions/tf2/Makefile.ep1
+++ b/extensions/tf2/Makefile.ep1
@@ -1,21 +1,21 @@
#(C)2004-2006 SourceMM Development Team
# Makefile written by David "BAILOPAN" Anderson
-SMSDK = ../..
-SRCDS = ~/srcds
-SOURCEMM = ../../../sourcemm
-HL2SDK = ../../../hl2sdk
+SMSDK = ../smsdk
+SRCDS = ~/srcds_l/steaminstall
+SOURCEMM = ../sourcemm
+HL2SDK = ../hl2sdk
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
-PROJECT = game.cstrike
+PROJECT = game.tf2
#Uncomment for SourceMM-enabled extensions
LINK_HL2 = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so
-OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp timeleft.cpp
+OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
diff --git a/extensions/tf2/Makefile.ep2 b/extensions/tf2/Makefile.ep2
index 5852266e..ff407f70 100644
--- a/extensions/tf2/Makefile.ep2
+++ b/extensions/tf2/Makefile.ep2
@@ -1,21 +1,21 @@
#(C)2004-2006 SourceMM Development Team
# Makefile written by David "BAILOPAN" Anderson
-SMSDK = ../..
-SRCDS = ~/srcds
-SOURCEMM = ../../../sourcemm
-HL2SDK = ../../../hl2sdk-ob
+SMSDK = ../smsdk
+SRCDS = ~/srcds_l/steaminstall
+SOURCEMM = ../sourcemm
+HL2SDK = ../hl2sdk-ob
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
-PROJECT = game.cstrike
+PROJECT = game.tf2
#Uncomment for SourceMM-enabled extensions
LINK_HL2 = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so
-OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp timeleft.cpp
+OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
diff --git a/extensions/tf2/Makefile.orig b/extensions/tf2/Makefile.orig
index 4ae96fd1..f31cf6f2 100644
--- a/extensions/tf2/Makefile.orig
+++ b/extensions/tf2/Makefile.orig
@@ -1,21 +1,21 @@
#(C)2004-2006 SourceMM Development Team
# Makefile written by David "BAILOPAN" Anderson
-SMSDK = ../..
-SRCDS = ~/srcds
-SOURCEMM = ../../../sourcemm-1.4.2
-HL2SDK = ../../../hl2sdk
+SMSDK = ../smsdk
+SRCDS = ~/srcds_l/steaminstall
+SOURCEMM = ../sourcemm
+HL2SDK = ../hl2sdk
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
-PROJECT = game.cstrike
+PROJECT = game.tf2
#Uncomment for SourceMM-enabled extensions
LINK_HL2 = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so
-OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp timeleft.cpp
+OBJECTS = sdk/smsdk_ext.cpp extension.cpp natives.cpp RegNatives.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
diff --git a/extensions/tf2/RegNatives.cpp b/extensions/tf2/RegNatives.cpp
new file mode 100644
index 00000000..70c2b525
--- /dev/null
+++ b/extensions/tf2/RegNatives.cpp
@@ -0,0 +1,50 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Counter-Strike:Source Extension
+ * Copyright (C) 2004-2007 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: RegNatives.cpp 1558 2007-10-14 19:34:46Z faluco $
+ */
+
+#include "extension.h"
+#include "RegNatives.h"
+
+RegNatives g_RegNatives;
+
+void RegNatives::Register(ICallWrapper *pWrapper)
+{
+ m_List.push_back(pWrapper);
+}
+
+void RegNatives::UnregisterAll()
+{
+ SourceHook::List::iterator iter;
+
+ for (iter=m_List.begin(); iter!=m_List.end(); iter++)
+ {
+ (*iter)->Destroy();
+ }
+}
diff --git a/extensions/tf2/RegNatives.h b/extensions/tf2/RegNatives.h
new file mode 100644
index 00000000..07ee59ca
--- /dev/null
+++ b/extensions/tf2/RegNatives.h
@@ -0,0 +1,48 @@
+/**
+ * vim: set ts=4 :
+ * =============================================================================
+ * SourceMod Counter-Strike:Source Extension
+ * Copyright (C) 2004-2007 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: RegNatives.h 1558 2007-10-14 19:34:46Z faluco $
+ */
+
+#ifndef _INCLUDE_TF2TOOLS_REGNATIVES_H_
+#define _INCLUDE_TF2TOOLS_REGNATIVES_H_
+
+#include
+
+class RegNatives
+{
+public:
+ void Register(ICallWrapper *pWrapper);
+ void UnregisterAll();
+private:
+ SourceHook::List m_List;
+};
+
+extern RegNatives g_RegNatives;
+
+#endif //_INCLUDE_TF2TOOLS_REGNATIVES_H_
diff --git a/extensions/tf2/extension.cpp b/extensions/tf2/extension.cpp
index 919a6ea4..ae67d077 100644
--- a/extensions/tf2/extension.cpp
+++ b/extensions/tf2/extension.cpp
@@ -30,19 +30,24 @@
*/
#include "extension.h"
+#include "RegNatives.h"
+#include "iplayerinfo.h"
/**
* @file extension.cpp
* @brief Implement extension code here.
*/
-SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
TF2Tools g_TF2Tools;
IGameConfig *g_pGameConf = NULL;
+IBinTools *g_pBinTools = NULL;
+
SMEXT_LINK(&g_TF2Tools);
+SendProp *playerSharedOffset;
+
extern sp_nativeinfo_t g_TFNatives[];
bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
@@ -54,7 +59,7 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
if (error)
{
- snprintf(error, maxlength, "Could not read sm-cstrike.games.txt: %s", conf_error);
+ snprintf(error, maxlength, "Could not read sm-tf2.games.txt: %s", conf_error);
}
return false;
}
@@ -62,6 +67,10 @@ bool TF2Tools::SDK_OnLoad(char *error, size_t maxlength, bool late)
sharesys->AddNatives(myself, g_TFNatives);
sharesys->RegisterLibrary(myself, "tf2");
+ playerSharedOffset = gamehelpers->FindInSendTable("CTFPlayer", "DT_TFPlayerShared");
+
+ playerhelpers->RegisterCommandTargetProcessor(this);
+
return true;
}
@@ -74,15 +83,147 @@ bool TF2Tools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
void TF2Tools::SDK_OnUnload()
{
+ g_RegNatives.UnregisterAll();
gameconfs->CloseGameConfigFile(g_pGameConf);
}
void TF2Tools::SDK_OnAllLoaded()
{
+ SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
}
bool TF2Tools::QueryRunning(char *error, size_t maxlength)
{
+ SM_CHECK_IFACE(BINTOOLS, g_pBinTools);
+
+ return true;
+}
+
+bool TF2Tools::QueryInterfaceDrop(SMInterface *pInterface)
+{
+ if (pInterface == g_pBinTools)
+ {
+ return false;
+ }
+
+ return IExtensionInterface::QueryInterfaceDrop(pInterface);
+}
+
+void TF2Tools::NotifyInterfaceDrop(SMInterface *pInterface)
+{
+ g_RegNatives.UnregisterAll();
+}
+
+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;
+ }
+}
+
+bool TF2Tools::ProcessCommandTarget(cmd_target_info_t *info)
+{
+ int max_clients;
+ IPlayerInfo *pInfo;
+ unsigned int team_index = 0;
+ IGamePlayer *pPlayer, *pAdmin;
+
+ if ((info->flags & COMMAND_FILTER_NO_MULTI) == COMMAND_FILTER_NO_MULTI)
+ {
+ return false;
+ }
+
+ if (info->admin)
+ {
+ if ((pAdmin = playerhelpers->GetGamePlayer(info->admin)) == NULL)
+ {
+ return false;
+ }
+ if (!pAdmin->IsInGame())
+ {
+ return false;
+ }
+ }
+ else
+ {
+ pAdmin = NULL;
+ }
+
+ if (strcmp(info->pattern, "@red") == 0 )
+ {
+ team_index = 2;
+ }
+ else if (strcmp(info->pattern, "@blue") == 0)
+ {
+ team_index = 3;
+ }
+ else
+ {
+ return false;
+ }
+
+ info->num_targets = 0;
+
+ max_clients = playerhelpers->GetMaxClients();
+ for (int i = 1;
+ i <= max_clients && (cell_t)info->num_targets < info->max_targets;
+ i++)
+ {
+ if ((pPlayer = playerhelpers->GetGamePlayer(i)) == NULL)
+ {
+ continue;
+ }
+ if (!pPlayer->IsInGame())
+ {
+ continue;
+ }
+ if ((pInfo = pPlayer->GetPlayerInfo()) == NULL)
+ {
+ continue;
+ }
+ if (pInfo->GetTeamIndex() != (int)team_index)
+ {
+ continue;
+ }
+ if (playerhelpers->FilterCommandTarget(pAdmin, pPlayer, info->flags)
+ != COMMAND_TARGET_VALID)
+ {
+ continue;
+ }
+ info->targets[info->num_targets] = i;
+ info->num_targets++;
+ }
+
+ if (info->num_targets == 0)
+ {
+ info->reason = COMMAND_TARGET_EMPTY_FILTER;
+ }
+ else
+ {
+ info->reason = COMMAND_TARGET_VALID;
+ }
+
+ info->target_name_style = COMMAND_TARGETNAME_RAW;
+ if (team_index == 2)
+ {
+ UTIL_Format(info->target_name, info->target_name_maxlength, "Red Team");
+ }
+ else if (team_index == 3)
+ {
+ UTIL_Format(info->target_name, info->target_name_maxlength, "Blue Team");
+ }
+
return true;
}
diff --git a/extensions/tf2/extension.h b/extensions/tf2/extension.h
index 740d7531..91090fd9 100644
--- a/extensions/tf2/extension.h
+++ b/extensions/tf2/extension.h
@@ -38,12 +38,15 @@
*/
#include "smsdk_ext.h"
+#include
/**
* @brief Sample implementation of the SDK Extension.
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
*/
-class TF2Tools : public SDKExtension
+class TF2Tools :
+ public SDKExtension,
+ public ICommandTargetProcessor
{
public:
/**
@@ -81,8 +84,10 @@ public:
*/
virtual bool QueryRunning(char *error, size_t maxlength);
- //void NotifyInterfaceDrop(SMInterface *pInterface);
- //bool QueryInterfaceDrop(SMInterface *pInterface);
+ void NotifyInterfaceDrop(SMInterface *pInterface);
+ bool QueryInterfaceDrop(SMInterface *pInterface);
+public:
+ bool ProcessCommandTarget(cmd_target_info_t *info);
public:
#if defined SMEXT_CONF_METAMOD
/**
@@ -118,4 +123,8 @@ public:
#endif
};
+extern IBinTools *g_pBinTools;
+extern IGameConfig *g_pGameConf;
+extern SendProp *playerSharedOffset;
+
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
diff --git a/extensions/tf2/msvc8/tf2.vcproj b/extensions/tf2/msvc8/tf2.vcproj
index 697bfec7..67172d95 100644
--- a/extensions/tf2/msvc8/tf2.vcproj
+++ b/extensions/tf2/msvc8/tf2.vcproj
@@ -675,6 +675,10 @@
RelativePath="..\natives.cpp"
>
+
+
+
+
GetMemSig(name, &addr)) \
+ { \
+ return pContext->ThrowNativeError("Failed to locate function"); \
+ } \
+ code; \
+ g_RegNatives.Register(pWrapper);
inline CBaseEntity *GetCBaseEntity(int num, bool onlyPlayers)
{
@@ -61,7 +71,89 @@ inline CBaseEntity *GetCBaseEntity(int num, bool onlyPlayers)
return pUnk->GetBaseEntity();
}
+
+// native TF2_Burn(client)
+cell_t TF2_Burn(IPluginContext *pContext, const cell_t *params)
+{
+ static ICallWrapper *pWrapper = NULL;
+
+ // CTFPlayerShared::Burn(CTFPlayer*)
+ if (!pWrapper)
+ {
+ REGISTER_NATIVE_ADDR("Burn",
+ PassInfo pass[1]; \
+ pass[0].flags = PASSFLAG_BYVAL; \
+ pass[0].size = sizeof(CBaseEntity *); \
+ pass[0].type = PassType_Basic; \
+ pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
+ }
+
+ CBaseEntity *pEntity;
+ if (!(pEntity=GetCBaseEntity(params[1], true)))
+ {
+ return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
+ }
+
+ void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->GetOffset());
+
+ unsigned char vstk[sizeof(void *) + sizeof(CBaseEntity *)];
+ unsigned char *vptr = vstk;
+
+ *(void **)vptr = obj;
+ vptr += sizeof(void *);
+ *(CBaseEntity **)vptr = pEntity;
+
+ pWrapper->Execute(vstk, NULL);
+
+ return 1;
+}
+
+// native TF2_Invuln(client, bool:something, bool:anothersomething)
+cell_t TF2_Invuln(IPluginContext *pContext, const cell_t *params)
+{
+ static ICallWrapper *pWrapper = NULL;
+
+ //CTFPlayerShared::SetInvulnerable(bool, bool)
+ if (!pWrapper)
+ {
+ REGISTER_NATIVE_ADDR("Invuln",
+ PassInfo pass[2]; \
+ pass[0].flags = PASSFLAG_BYVAL; \
+ pass[0].size = sizeof(bool); \
+ pass[0].type = PassType_Basic; \
+ pass[1].flags = PASSFLAG_BYVAL; \
+ pass[1].size = sizeof(bool); \
+ pass[1].type = PassType_Basic; \
+ pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2))
+ }
+
+ CBaseEntity *pEntity;
+ if (!(pEntity=GetCBaseEntity(params[1], true)))
+ {
+ return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
+ }
+
+ void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->GetOffset());
+
+ unsigned char vstk[sizeof(void *) + 2*sizeof(bool)];
+ unsigned char *vptr = vstk;
+
+
+ *(void **)vptr = obj;
+ vptr += sizeof(bool);
+ *(bool *)vptr = !!params[2];
+ vptr += sizeof(bool);
+ *(bool *)vptr = !!params[3];
+
+ pWrapper->Execute(vstk, NULL);
+
+ return 1;
+}
+
+
sp_nativeinfo_t g_TFNatives[] =
{
+ {"TF2_Burn", TF2_Burn},
+ {"TF2_Invuln", TF2_Invuln},
{NULL, NULL}
};
diff --git a/extensions/tf2/sdk/smsdk_config.h b/extensions/tf2/sdk/smsdk_config.h
index a3cf616c..09397393 100644
--- a/extensions/tf2/sdk/smsdk_config.h
+++ b/extensions/tf2/sdk/smsdk_config.h
@@ -58,7 +58,7 @@
* @brief Sets whether or not this plugin required Metamod.
* NOTE: Uncomment to enable, comment to disable.
*/
-#define SMEXT_CONF_METAMOD
+#define SMEXT_CONF_METAMOD
/** Enable interfaces you want to use here by uncommenting lines */
//#define SMEXT_ENABLE_FORWARDSYS
@@ -67,7 +67,7 @@
//#define SMEXT_ENABLE_DBMANAGER
#define SMEXT_ENABLE_GAMECONF
//#define SMEXT_ENABLE_MEMUTILS
-//#define SMEXT_ENABLE_GAMEHELPERS
+#define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS
//#define SMEXT_ENABLE_THREADER
//#define SMEXT_ENABLE_LIBSYS
diff --git a/extensions/tf2/sm-tf2.games.txt b/extensions/tf2/sm-tf2.games.txt
new file mode 100644
index 00000000..3adc88b2
--- /dev/null
+++ b/extensions/tf2/sm-tf2.games.txt
@@ -0,0 +1,21 @@
+"Games"
+{
+ "tf"
+ {
+ "Signatures"
+ {
+ "Burn"
+ {
+ "library" "server"
+ "windows" "\x56\x8B\xF1\x8B\x4E\x7C\x8B\x01\x8B\x90\xF8\x00\x00\x00\xFF\xD2\x84\xC0\x2A\x2A\x2A\x2A\x2A\x2A\x8B\x46\x7C"
+ "linux" "@_ZN15CTFPlayerShared4BurnEP9CTFPlayer"
+ }
+ "Invuln"
+ {
+ "library" "server"
+ "windows" "\x8A\x44\x24\x04\x83\xEC\x20\x56\x8B\xF1\x8B\x4E\x08\x57\x8D\x7E\x08\xC1\xE9\x05\x80\xE1\x01\x3A\xC8\x75\x32\x84\xC0"
+ "linux" "@_ZN15CTFPlayerShared15SetInvulnerableEbb"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/extensions/tf2/tf2-test.sp b/extensions/tf2/tf2-test.sp
new file mode 100644
index 00000000..b1239543
--- /dev/null
+++ b/extensions/tf2/tf2-test.sp
@@ -0,0 +1,55 @@
+#include
+#include "tf2.inc"
+
+public Plugin:myinfo =
+{
+ name = "TF2 Test",
+ author = "pRED*",
+ description = "Test of Tf2 functions",
+ version = "1.0",
+ url = "www.sourcemod.net"
+}
+
+public OnPluginStart()
+{
+ RegConsoleCmd("sm_burnme", Command_Burn);
+ RegConsoleCmd("sm_invuln", Command_Invuln);
+}
+
+public Action:Command_Burn(client, args)
+{
+ if (client == 0)
+ {
+ return Plugin_Continue;
+ }
+
+ TF2_Burn(client);
+
+ return Plugin_Continue;
+}
+
+public Action:Command_Invuln(client, args)
+{
+ if (client == 0)
+ {
+ return Plugin_Continue;
+ }
+
+ if (args < 2)
+ {
+ return Plugin_Continue;
+ }
+
+ decl String:text[10];
+ decl String:text2[10];
+ GetCmdArg(1, text, sizeof(text));
+ GetCmdArg(2, text2, sizeof(text2));
+
+ new bool:one = !!StringToInt(text);
+ new bool:two = !!StringToInt(text2);
+
+ TF2_Invuln(client, one, two)
+
+ return Plugin_Continue;
+}
+
diff --git a/extensions/tf2/tf2.inc b/extensions/tf2/tf2.inc
new file mode 100644
index 00000000..c2c4c39a
--- /dev/null
+++ b/extensions/tf2/tf2.inc
@@ -0,0 +1,24 @@
+#if defined _tf2_included
+ #endinput
+#endif
+#define _tf2_included
+
+
+native TF2_Invuln(client, bool:something, bool:anothersomething);
+
+native TF2_Burn(client);
+
+/**
+ * Do not edit below this line!
+ */
+public Extension:__ext_tf2 =
+{
+ name = "TF2 Tools",
+ file = "game.tf2.ext",
+ autoload = 0,
+#if defined REQUIRE_EXTENSIONS
+ required = 1,
+#else
+ required = 0,
+#endif
+};