commit 4d6400d8bdb775832b54e621bda8febfab29b71b Author: Ivailo Spasov Date: Fri Dec 14 14:38:27 2012 -0800 init commit Signed-off-by: Ivailo Spasov diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b5a7609 --- /dev/null +++ b/Makefile @@ -0,0 +1,123 @@ +# (C)2004-2008 Metamod:Source Development Team +# Makefile written by David "BAILOPAN" Anderson + +########################################### +### EDIT THESE PATHS FOR YOUR OWN SETUP ### +########################################### + +HL2SDK_L4D = ../../hl2sdk-l4d +HL2SDK_L4D2 = ../../hl2sdk-l4d2 +MMSOURCE18 = ../ +SRCDS_BASE = ~/srcds + +##################################### +### EDIT BELOW FOR OTHER PROJECTS ### +##################################### + +OBJECTS = l4dtoolz_mm.cpp +BINARY = l4dtoolz_mm_i486.so + +############################################## +### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### +############################################## +override ENGSET = false + +OPT_FLAGS = -Os -s -pipe +ifeq "$(ENGINE)" "left4dead" +GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden -DL4D1 +else +GCC4_FLAGS = -fvisibility=hidden -fvisibility-inlines-hidden -DL4D2 +endif +DEBUG_FLAGS = -g -ggdb3 -D_DEBUG +CPP = gcc-4.1 + + +ifeq "$(ENGINE)" "left4dead" + HL2SDK = $(HL2SDK_L4D) + HL2PUB = $(HL2SDK)/public + HL2LIB = $(HL2SDK)/lib/linux + CFLAGS += -DSOURCE_ENGINE=4 + METAMOD = $(MMSOURCE18)/core + INCLUDE += -I$(HL2SDK)/public/game/server + SRCDS = $(SRCDS_BASE)/ + override ENGSET = true +else + HL2SDK = $(HL2SDK_L4D2) + HL2PUB = $(HL2SDK)/public + HL2LIB = $(HL2SDK)/lib/linux + CFLAGS += -DSOURCE_ENGINE=4 + METAMOD = $(MMSOURCE18)/core + INCLUDE += -I$(HL2SDK)/public/game/server + SRCDS = $(SRCDS_BASE)/ + override ENGSET = true +endif + +CFLAGS += -DSE_EPISODEONE=1 -SE_DARKMESSIAH=2 -DSE_ORANGEBOX=3 -DSE_LEFT4DEAD=4 + +ifeq "$(ENGINE)" "left4dead" +LINK += $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so -static-libgcc +else +LINK += $(HL2LIB)/tier1_i486.a libvstdlib.so libtier0.so -static-libgcc +endif +INCLUDE += -I. -I.. -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/mathlib -I$(HL2PUB)/vstdlib \ + -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 -I. -I$(METAMOD) -I$(METAMOD)/sourcehook + +################################################ +### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ### +################################################ + +ifeq "$(DEBUG)" "true" + BIN_DIR = Debug.$(ENGINE) + CFLAGS += $(DEBUG_FLAGS) +else + BIN_DIR = Release.$(ENGINE) + CFLAGS += $(OPT_FLAGS) +endif + +GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) + +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 -Wno-non-virtual-dtor -Werror -fPIC -fno-exceptions \ + -fno-rtti -msse -m32 -fno-strict-aliasing + +ifeq "$(GCC_VERSION)" "4" + CFLAGS += $(GCC4_FLAGS) +endif + +OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) + +$(BIN_DIR)/%.o: %.cpp + $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< + +all: check + mkdir -p $(BIN_DIR) +ifeq "$(ENGINE)" "left4dead" + rm -f vstdlib_i486.so + rm -f tier0_i486.so + ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so + ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so + +else + rm -f libvstdlib.so + rm -f libtier0.so + ln -sf $(SRCDS)/bin/libvstdlib.so libvstdlib.so + ln -sf $(SRCDS)/bin/libtier0.so libtier0.so +endif + $(MAKE) -f Makefile l4dtoolz_mm + +check: + if [ "$(ENGSET)" = "false" ]; then \ + echo "You must supply ENGINE=left4dead or ENGINE=left4dead2"; \ + exit 1; \ + fi + +l4dtoolz_mm: check $(OBJ_LINUX) + $(CPP) $(INCLUDE) -m32 $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY) + +default: all + +clean: check + rm -rf $(BIN_DIR)/*.o + rm -rf $(BIN_DIR)/$(BINARY) + diff --git a/engine_wrappers.h b/engine_wrappers.h new file mode 100644 index 0000000..34ab4ba --- /dev/null +++ b/engine_wrappers.h @@ -0,0 +1,100 @@ +/** + * vim: set ts=4 : + * ====================================================== + * Metamod:Source Sample Plugin + * Written by AlliedModders LLC. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * This sample plugin is public domain. + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_SOURCE_ENGINE_WRAPPERS_ +#define _INCLUDE_SOURCE_ENGINE_WRAPPERS_ + +#include + +extern IVEngineServer *engine; +extern CGlobalVars *gpGlobals; + +#if SOURCE_ENGINE == SE_EPISODEONE && defined METAMOD_PLAPI_VERSION +#error "Metamod:Source 1.6 API is not supported on the old engine." +#endif + +/** + * MM:S 1.4.x needs older API calls. + */ +#if !defined METAMOD_PLAPI_VERSION +#define GetEngineFactory engineFactory +#define GetServerFactory serverFactory +#define MM_Format snprintf +#define GetCGlobals pGlobals +#define ENGINE_CALL(func) SH_CALL(m_EngineCC, func) +#else +#define ENGINE_CALL(func) SH_CALL(engine, func) +#define MM_Format g_SMAPI->Format +#endif + +#if SOURCE_ENGINE <= SE_DARKMESSIAH +/** + * Wrap the CCommand class so our code looks the same on all engines. + */ +class CCommand +{ +public: + const char *ArgS() + { + return engine->Cmd_Args(); + } + int ArgC() + { + return engine->Cmd_Argc(); + } + + const char *Arg(int index) + { + return engine->Cmd_Argv(index); + } +}; + +#define CVAR_INTERFACE_VERSION VENGINE_CVAR_INTERFACE_VERSION +#endif + +/** + * Left 4 Dead engine removed these from IVEngineServer. + */ +#if SOURCE_ENGINE >= SE_LEFT4DEAD + +inline int IndexOfEdict(const edict_t *pEdict) +{ + return (int)(pEdict - gpGlobals->baseEdict); +} +inline edict_t *PEntityOfEntIndex(int iEntIndex) +{ + if (iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities) + { + return (edict_t *)(gpGlobals->baseEdict + iEntIndex); + } + return NULL; +} + +#else + +inline int IndexOfEdict(const edict_t *pEdict) +{ + return engine->IndexOfEdict(pEdict); +} +inline edict_t *PEntityOfEntIndex(int iEntIndex) +{ + return engine->PEntityOfEntIndex(iEntIndex); +} + +#endif + +#endif //_INCLUDE_SOURCE_ENGINE_WRAPPERS_ + diff --git a/l4d1_signature_linux.h b/l4d1_signature_linux.h new file mode 100644 index 0000000..563039f --- /dev/null +++ b/l4d1_signature_linux.h @@ -0,0 +1,56 @@ +const char* server_dll = "server_i486.so"; +const char* engine_dll = "engine_i486.so"; +const char* matchmaking_dll = "matchmaking_ds_i486.so"; + +//CBaseServer::GetMaxHumanPlayers(void)const +//fuction is in engine_i486.so +const char* friends_lobby = "\x1B\x53\xE8\x00\x00\x00\x00\x5B\x81\xC3\xC3\xC3\xC3\xC3\x83\xEC\x08\x8B\x83\xC3\xC3\xC3\xC3\x8B\x10\x85\xD2\x74"; +unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +char* friends_lobby_org = NULL; + +//CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int, CUtlVector> &, bool) +//fuction is in engine_i486.so +const char* lobby_sux = "\x0B\x8B\x85\x78\x01\x00\x00\x85\xC0\x74\xC3\x8B"; +const char* lobby_sux_new = "\x02\x09\x90\x90"; +char* lobby_sux_org = NULL; + +//CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int, CUtlVector> &, bool) +//fuction is in engine_i486.so +const char* max_players = "\x13\x89\x2C\xC3\xFF\xC3\xC3\x8D\x14\x37\x29\xC2\x3B\x95\x78\x01\x00\x00\x0F\x8F"; +char max_players_new[]= {0x06, 0x11, 0x83, 0xFA, 0x3C, 0x90, 0x90, 0x90}; +char* max_players_org = NULL; + +//CServerGameClients::GetMaxHumanPlayers(void) +//fuction is in server_i486.so +const char* server_bplayers = "\x1C\x53\xE8\x00\x00\x00\x00\x5B\x81\xC3\xC3\xC3\xC3\xC3\x83\xEC\x08\xE8\xC3\xC3\xC3\xC3\x59\x3C\x01\x5A\x19\xC0\x5B"; +unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +char* server_bplayers_org = NULL; + + +//CTerrorGameRules::ClientConnected(edict_t *, char const*, char const*, char *, int) +//fuction is in server_i486.so +const char* human_limit = "\x15\x8B\x6C\xC3\xC3\x8B\x75\x00\x89\x2C\x24\xFF\x96\xC3\xC3\xC3\xC3\x39\xF8\x7E\xC3\x8B"; +const char* human_limit_new = "\x02\x12\x90\x90"; +char* human_limit_org = NULL; + +//_ZL10maxplayersRK8CCommand +//fuction is in engine_i486.so +const char* players = "\x13\x8B\xB3\xC3\xC3\xC3\xC3\x83\x7E\xC3\xC3\x7F\xC3\x8B\x90\xC3\xC3\x00\x00\x89"; +const char* players_new = "\x02\x0A\x90\x90"; +char* players_org = NULL; + +//CGameServer::SetMaxClients(int) +//fuction is in engine_i486.so +const char* players2 = "\x19\x8B\x54\xC3\xC3\x8B\x86\xC3\xC3\xC3\xC3\x39\xD0\x7C\xC3\x8B\x86\xC3\xC3\xC3\xC3\x39\xC2\x0F\x4D\xC2"; +const char* players_new2 = "\x02\x0C\x90\x90"; +char* players_org2 = NULL; + +//CBaseServer::SetReservationCookie(unsigned long long, char const*, ...) +//function in engine_i486.so +const char* unreserved = "\x31\x55\x57\x56\x53\x81\xEC\x3C\x01\x00\x00\xE8\x00\x00\x00\x00\x5B\x81\xC3\xC3\xC3\xC3\xC3\x8B\x84\x24\xC3\xC3\x00\x00\x8B\xB4\x24\xC3\xC3\x00\x00\x89\xC3\xC3\xC3\x8B\xAC\x24\xC3\xC3\x00\x00\x89\xC2"; +const char* unreserved_new = "\x01\x00\xC3"; +char* unreserved_org = NULL; + +const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3"; +unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3}; +char* lobby_match_org = NULL; diff --git a/l4d1_signature_win32.h b/l4d1_signature_win32.h new file mode 100644 index 0000000..6b62b72 --- /dev/null +++ b/l4d1_signature_win32.h @@ -0,0 +1,40 @@ +const char* server_dll = "server.dll"; +const char* engine_dll = "engine.dll"; +const char* matchmaking_dll = "matchmaking_ds.dll"; + +const char* friends_lobby = "\x12\x56\x8B\xF1\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x01\x8B\x50\x48"; +unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +char* friends_lobby_org = NULL; + +const char* max_players = "\x28\x83\xBE\xC3\xC3\x00\x00\x00\x74\xC3\x8B\x54\xC3\xC3\x8B\x06\x8B\x7A\xC3\x8B\x50\x10\x8B\xCE\xFF\xD2\x2B\xF8\x8B\x06\x8B\x50\x08\x8B\xCE\xFF\xD2\x03\xC7\x3B\x86"; +unsigned char max_players_new[]= {0x06, 0x26, 0x83, 0xF8, 0x3C, 0x90, 0x90, 0x90}; +char* max_players_org = NULL; + +const char* lobby_sux_new = "\x02\x07\x90\x90"; +char* lobby_sux_org = NULL; + +const char* server_bplayers = "\x1D\x56\x8B\xF1\xE8\xC3\xC3\xC3\xC3\x8B\x4C\x24\x08\x89\x01\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x11\x8B\x42\x48"; +unsigned char server_bplayers_new[] = {0x05, 0x1A, 0xB8, 0x3C, 0x00, 0x00, 0x00}; +char* server_bplayers_org = NULL; + +const char* human_limit = "\x15\x8B\x13\x8B\x82\xC3\xC3\x00\x00\x8B\xCB\xFF\xD0\x3B\xF8\x7C\xC3\x8B\xC3\xC3\xC3\x8B"; +const char* human_limit_new = "\x01\x0E\xEB"; +char* human_limit_org = NULL; + +const char* players = "\x15\x83\x3D\xC3\xC3\xC3\xC3\x02\x7C\xC3\x83\xC4\x08\xC7\x44\xC3\xC3\xC3\xC3\xC3\xC3\xFF"; +const char* players_new = "\x01\x07\xEB"; +char* players_org = NULL; + +const char* players2 = "\x10\x56\x8B\xF1\x8B\x86\xC3\x02\x00\x00\x8B\x4C\x24\x08\x3B\xC8\x7F"; +const char* players_new2 = "\x02\x0F\x90\x90"; +char* players_org2 = NULL; + + +const char* unreserved = "\x1E\x81\xEC\xC3\xC3\x00\x00\x55\x8B\xAC\xC3\xC3\xC3\x00\x00\x56\x8B\xB4\xC3\xC3\xC3\x00\x00\x57\x8B\xBC\xC3\xC3\xC3\x00\x00"; +const char* unreserved_new = "\x01\x00\xC3"; +char* unreserved_org = NULL; + +const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3"; +unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3}; +char* lobby_match_org = NULL; + diff --git a/l4d2_signature_linux.h b/l4d2_signature_linux.h new file mode 100644 index 0000000..b20389c --- /dev/null +++ b/l4d2_signature_linux.h @@ -0,0 +1,39 @@ +const char* server_dll = "server.so"; +const char* engine_dll = "engine.so"; +const char* matchmaking_dll = "matchmaking_ds.so"; + +const char* friends_lobby = "\x18\x55\x89\xE5\x56\x53\x83\xEC\x10\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\xC3\xC3\x8B\x83"; +unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +char* friends_lobby_org = NULL; + +const char* lobby_sux = "\x09\x8B\x96\x7C\x01\x00\x00\x85\xD2\x74"; +const char* lobby_sux_new = "\x02\x08\x90\x90"; +char* lobby_sux_org = NULL; + +const char* max_players = "\x10\xFF\xC3\xC3\x03\xC3\xC3\x29\xC7\x3B\xBE\x7C\x01\x00\x00\x0F\x8F"; +char max_players_new[]= {0x06, 0x08, 0x83, 0xFF, 0x3C, 0x90, 0x90, 0x90}; +char* max_players_org = NULL; + +const char* server_bplayers ="\x21\x55\x89\xE5\x53\x83\xEC\x14\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\x83\xC3\xC3\xC3\xC3\x8B\x10\xB8\xFF\xFF\xFF\xFF\x85\xD2"; +unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +char* server_bplayers_org = NULL; + +const char* human_limit = "\x11\x8B\x55\xC3\x8B\x02\x89\x14\xC3\xFF\x90\x24\x02\x00\x00\x39\xF8\x7E"; +const char* human_limit_new = "\x02\x10\x90\x90"; +char* human_limit_org = NULL; + +const char* players = "\x13\x83\xBB\xC3\xC3\xC3\xC3\x01\x7F\xC3\x8B\x80\x0C\xC3\xC3\x00\x89\xC3\xC3\xE8"; +const char* players_new = "\x02\x07\x90\x90"; +char* players_org = NULL; + +const char* players_new2 = "\x01\x1F\xEB"; +char* players_org2 = NULL; + +const char* unreserved = "\x1B\x55\x89\xE5\x57\x56\x53\x81\xEC\x4C\x01\x00\x00\xE8\xC3\xC3\xC3\xC3\x81\xC3\xB7\xEB\x23\x00\x8B\xC3\xC3\x8B"; +const char* unreserved_new = "\x01\x00\xC3"; +char* unreserved_org = NULL; + +const char* lobby_match = "\x0A\x55\x89\xE5\xB8\x08\x00\x00\x00\x5D\xC3"; +unsigned char lobby_match_new[] = {0x01, 0x04, 0xC3}; +char* lobby_match_org = NULL; + diff --git a/l4d2_signature_win32.h b/l4d2_signature_win32.h new file mode 100644 index 0000000..6b62b72 --- /dev/null +++ b/l4d2_signature_win32.h @@ -0,0 +1,40 @@ +const char* server_dll = "server.dll"; +const char* engine_dll = "engine.dll"; +const char* matchmaking_dll = "matchmaking_ds.dll"; + +const char* friends_lobby = "\x12\x56\x8B\xF1\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x01\x8B\x50\x48"; +unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +char* friends_lobby_org = NULL; + +const char* max_players = "\x28\x83\xBE\xC3\xC3\x00\x00\x00\x74\xC3\x8B\x54\xC3\xC3\x8B\x06\x8B\x7A\xC3\x8B\x50\x10\x8B\xCE\xFF\xD2\x2B\xF8\x8B\x06\x8B\x50\x08\x8B\xCE\xFF\xD2\x03\xC7\x3B\x86"; +unsigned char max_players_new[]= {0x06, 0x26, 0x83, 0xF8, 0x3C, 0x90, 0x90, 0x90}; +char* max_players_org = NULL; + +const char* lobby_sux_new = "\x02\x07\x90\x90"; +char* lobby_sux_org = NULL; + +const char* server_bplayers = "\x1D\x56\x8B\xF1\xE8\xC3\xC3\xC3\xC3\x8B\x4C\x24\x08\x89\x01\x8B\x0D\xC3\xC3\xC3\xC3\x85\xC9\x74\xC3\x8B\x11\x8B\x42\x48"; +unsigned char server_bplayers_new[] = {0x05, 0x1A, 0xB8, 0x3C, 0x00, 0x00, 0x00}; +char* server_bplayers_org = NULL; + +const char* human_limit = "\x15\x8B\x13\x8B\x82\xC3\xC3\x00\x00\x8B\xCB\xFF\xD0\x3B\xF8\x7C\xC3\x8B\xC3\xC3\xC3\x8B"; +const char* human_limit_new = "\x01\x0E\xEB"; +char* human_limit_org = NULL; + +const char* players = "\x15\x83\x3D\xC3\xC3\xC3\xC3\x02\x7C\xC3\x83\xC4\x08\xC7\x44\xC3\xC3\xC3\xC3\xC3\xC3\xFF"; +const char* players_new = "\x01\x07\xEB"; +char* players_org = NULL; + +const char* players2 = "\x10\x56\x8B\xF1\x8B\x86\xC3\x02\x00\x00\x8B\x4C\x24\x08\x3B\xC8\x7F"; +const char* players_new2 = "\x02\x0F\x90\x90"; +char* players_org2 = NULL; + + +const char* unreserved = "\x1E\x81\xEC\xC3\xC3\x00\x00\x55\x8B\xAC\xC3\xC3\xC3\x00\x00\x56\x8B\xB4\xC3\xC3\xC3\x00\x00\x57\x8B\xBC\xC3\xC3\xC3\x00\x00"; +const char* unreserved_new = "\x01\x00\xC3"; +char* unreserved_org = NULL; + +const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3"; +unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3}; +char* lobby_match_org = NULL; + diff --git a/l4dtoolz_mm.cpp b/l4dtoolz_mm.cpp new file mode 100644 index 0000000..b688ef1 --- /dev/null +++ b/l4dtoolz_mm.cpp @@ -0,0 +1,495 @@ +#include +#include "l4dtoolz_mm.h" + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif + +#ifdef WIN32 +#ifdef L4D1 +#include "l4d1_signature_win32.h" +#else +#include "l4d2_signature_win32.h" +#endif +#else +#ifdef L4D1 +#include "l4d1_signature_linux.h" +#else +#include "l4d2_signature_linux.h" +#endif +#endif + +l4dtoolz g_l4dtoolz; +IVEngineServer* engine = NULL; +IServerPluginCallbacks* vsp_callbacks = NULL; +ICvar* icvar = NULL; + +#ifdef WIN32 +HANDLE l4dtoolz::hProcess; +#endif + +char* l4dtoolz::max_players_friend_lobby = NULL; +char* l4dtoolz::max_players_connect = NULL; +char* l4dtoolz::max_players_server_browser = NULL; +char* l4dtoolz::lobby_sux_ptr = NULL; +char* l4dtoolz::chuman_limit = NULL; +char* l4dtoolz::tmp_player = NULL; +char* l4dtoolz::tmp_player2 = NULL; +char* l4dtoolz::unreserved_ptr = NULL; +char* l4dtoolz::lobby_match_ptr = NULL; + +ConVar sv_maxplayers("sv_maxplayers", "-1", 0, "Max Human Players", true, -1, true, 32, l4dtoolz::OnChangeMaxplayers); +ConVar sv_removehumanlimit("sv_removehumanlimit", "0", 0, "Remove Human limit reached kick", true, 0, true, 1, l4dtoolz::OnChangeRemovehumanlimit); +ConVar L4DToolZ("L4DToolZ", "",0,"L4DToolZ Author",l4dtoolz::OnChangeIvailosp); +ConVar sv_force_unreserved("sv_force_unreserved", "0", 0, "Disallow lobby reservation cookie", true, 0, true, 1, l4dtoolz::OnChangeUnreserved); + +void* l4dtoolz::FindSignature(const char* mask, const char* base_addr, size_t base_len, bool pure_sign) +{ + char *pBasePtr = (char *)base_addr; + char *pEndPtr = pBasePtr+base_len-(int)mask[0]; + int i; + char* tmp; + if(base_addr == NULL) + return NULL; +#ifndef WIN32 + unsigned int p_size = sysconf(_SC_PAGESIZE); + char* all_adr = (char*)((unsigned int)pBasePtr & ~(p_size-1)); + unsigned int size = pEndPtr - all_adr; + mlock(all_adr, size); +#endif + while(pBasePtr < pEndPtr) + { + tmp = pBasePtr; + + for(i = 1; i <= mask[0]; ++i){ + if(mask[i] == '\xC3' && pure_sign == false){ + tmp++; + continue; + } + if(mask[i] != *tmp ){ + break; + } + tmp++; + } + if(i-1 == mask[0]){ +#ifndef WIN32 + munlock(all_adr, size); +#endif + return pBasePtr; + } + + pBasePtr++; + } +#ifndef WIN32 + munlock(all_adr, size); +#endif + return NULL; +} +#ifndef WIN32 +struct v_data{ + char* fname; + char* baddr; + size_t blen; +}; +static int callback(struct dl_phdr_info *info, size_t size, void *data) +{ + if (!info->dlpi_name || !info->dlpi_name[0]){ + return 0; + } + char* filename = ((v_data*)data)->fname; + if(strstr(info->dlpi_name, filename)){ + if(strstr( info->dlpi_name, "metamod") == NULL){ + ((v_data*)data)->baddr = (char*)info->dlpi_addr; + ((v_data*)data)->blen = 0; + for(int j = 0; j < info->dlpi_phnum; ++j){ + ((v_data*)data)->blen+=info->dlpi_phdr[j].p_filesz; + break; + } + return 1; + } + } + return 0; +} +#endif +bool l4dtoolz::find_base(const char* name, char*& base_addr, size_t& base_len){ + base_addr = NULL; + base_len = 0; +#ifdef WIN32 + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 modent; + hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); + if(hModuleSnap == INVALID_HANDLE_VALUE) + { + return false; + } + + modent.dwSize = sizeof(MODULEENTRY32); + + if(!Module32Next(hModuleSnap, &modent)) + { + CloseHandle(hModuleSnap); + return false; + } + do + { + if(strstr( modent.szExePath, name)) + { + if(strstr( modent.szExePath, "metamod")) + continue; + base_addr = (char*)modent.modBaseAddr; + base_len = modent.modBaseSize; + CloseHandle(hModuleSnap); + return true; + } + } while(Module32Next(hModuleSnap, &modent)); + CloseHandle(hModuleSnap); + return false; +#else + v_data vdata; + vdata.fname = (char*)name; + if(dl_iterate_phdr(callback, &vdata)){ + base_addr = vdata.baddr; + base_len = vdata.blen; + return true; + }else{ + base_addr = 0; + base_len = 0; + return false; + } +#endif +} + +void l4dtoolz::WriteSignature(char* addr, const char* signature){ +#ifdef WIN32 + WriteProcessMemory(hProcess,addr+signature[1], signature+2, signature[0], NULL); +#else + unsigned int p_size = sysconf(_SC_PAGESIZE); + char* all_adr = (char*)(((unsigned int)addr + signature[1]) & ~(p_size-1)); + unsigned int size = addr - all_adr + signature[0]; + mlock(all_adr, size); + mprotect(all_adr, size, PROT_READ|PROT_WRITE|PROT_EXEC); + memcpy(addr+signature[1], signature+2, signature[0]); + munlock(all_adr, size); +#endif +} + +void l4dtoolz::ReadSignature(const char* addr, char* signature){ +#ifdef WIN32 + ReadProcessMemory(hProcess, addr+signature[1], signature+2, signature[0], NULL); +#else + unsigned int p_size = sysconf(_SC_PAGESIZE); + char* all_adr = (char*)(((unsigned int)addr + signature[1]) & ~(p_size-1)); + unsigned int size = addr - all_adr + signature[0]; + mlock(all_adr, size); + memcpy(signature+2, addr+signature[1], signature[0]); + munlock(all_adr, size); +#endif +} + +void l4dtoolz::OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float flOldValue ) +{ + if (max_players_friend_lobby == NULL || max_players_connect == NULL || max_players_server_browser == NULL || lobby_sux_ptr == NULL){ + Msg("sv_maxplayers init error\n"); + return; + } + if(((ConVar*)var)->GetInt() >= 0){ + max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = ((ConVar*)var)->GetInt(); + if(lobby_match_ptr != NULL){ + lobby_match_new[2] = ((ConVar*)var)->GetInt(); + WriteSignature(lobby_match_ptr, (const char*)lobby_match_new); + }else{ + Msg("sv_maxplayers MS init error\n"); + } + WriteSignature(max_players_friend_lobby, (const char*)friends_lobby_new); + WriteSignature(max_players_connect, (const char*)max_players_new); + WriteSignature(lobby_sux_ptr, lobby_sux_new); + WriteSignature(max_players_server_browser, (const char*)server_bplayers_new); + }else{ + WriteSignature(max_players_friend_lobby, friends_lobby_org); + WriteSignature(max_players_connect, max_players_org); + WriteSignature(lobby_sux_ptr, lobby_sux_org); + WriteSignature(max_players_server_browser, server_bplayers_org); + + if(lobby_match_ptr != NULL) + WriteSignature(lobby_match_ptr, lobby_match_org); + } +} +void l4dtoolz::OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, float flOldValue ) +{ + if(chuman_limit == NULL){ + Msg( "sv_removehumanlimit init error\n"); + return; + } + if( ((ConVar*)var)->GetInt() == 1){ + WriteSignature(chuman_limit, human_limit_new); + }else{ + WriteSignature(chuman_limit, human_limit_org); + } +} + + +void l4dtoolz::OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue ) +{ + if(tmp_player == NULL || tmp_player2 == NULL){ + Msg("L4DToolZ init error\n"); + return; + } + WriteSignature(tmp_player, players_org); + WriteSignature(tmp_player2, players_org2); +} +void l4dtoolz::OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue ) +{ + if(unreserved_ptr == NULL ){ + Msg("unreserved_ptr init error\n"); + return; + } + if( ((ConVar*)var)->GetInt() == 1){ + WriteSignature(unreserved_ptr, unreserved_new); + engine->ServerCommand("sv_allow_lobby_connect_only 0\n"); + }else{ + WriteSignature(unreserved_ptr, unreserved_org); + } + +} + +class BaseAccessor : public IConCommandBaseAccessor +{ +public: + bool RegisterConCommandBase(ConCommandBase *pCommandBase) + { + return META_REGCVAR(pCommandBase); + } +} s_BaseAccessor; + +PLUGIN_EXPOSE(l4dtoolz, g_l4dtoolz); + +void l4dtoolz::get_org_sig(const char* offset, const char* new_sig, char*& org_sig){ + if(!offset) + return; + if(org_sig) + delete org_sig; + org_sig = new char[new_sig[0] + 2]; + org_sig[0] = new_sig[0]; + org_sig[1] = new_sig[1]; + ReadSignature(offset, org_sig); +} +bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) +{ +#ifdef WIN32 + hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, GetCurrentProcessId()); +#endif + PLUGIN_SAVEVARS(); + + GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); + GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION); + + +#if defined METAMOD_PLAPI_VERSION + if ((vsp_callbacks = ismm->GetVSPInfo(NULL)) == NULL) +#endif + { + ismm->AddListener(this, this); + ismm->EnableVSPListener(); + } + + +#if !defined METAMOD_PLAPI_VERSION + m_EngineCC = SH_GET_CALLCLASS(engine); +#endif + +#if SOURCE_ENGINE >= SE_ORANGEBOX + g_pCVar = icvar; + ConVar_Register(0, &s_BaseAccessor); +#else + ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor); +#endif + + char* base_addr = NULL; + size_t base_len = 0; + + find_base(matchmaking_dll, base_addr, base_len); + +#ifdef WIN32 + if(base_addr == NULL) + find_base("matchmaking.dll", base_addr, base_len); +#endif + + if(lobby_match_ptr == NULL){ + lobby_match_ptr = (char*)FindSignature(lobby_match, base_addr, base_len, true); + get_org_sig(lobby_match, (const char*)lobby_match_new, lobby_match_org); + } + + find_base(engine_dll, base_addr, base_len); + if(max_players_friend_lobby == NULL){ + max_players_friend_lobby = (char*)FindSignature(friends_lobby, base_addr, base_len); + get_org_sig(max_players_friend_lobby, (const char*)friends_lobby_new, friends_lobby_org); + } + if(max_players_connect == NULL){ + max_players_connect = (char*)FindSignature(max_players, base_addr, base_len); + if(max_players_connect != NULL){ + get_org_sig(max_players_connect, (const char*)max_players_new, max_players_org); + } + } + if(lobby_sux_ptr==NULL){ + +#ifdef WIN32 + lobby_sux_ptr = max_players_connect; +#else + lobby_sux_ptr = (char*)FindSignature(lobby_sux, base_addr, base_len); +#endif + if(lobby_sux_ptr!=NULL){ + get_org_sig(lobby_sux_ptr, lobby_sux_new, lobby_sux_org); + } + } +#ifdef WIN32 + if(max_players_server_browser == NULL){ + max_players_server_browser = (char*)FindSignature(server_bplayers, base_addr, base_len); + get_org_sig(max_players_server_browser, (const char*)server_bplayers_new, server_bplayers_org); + } +#endif + if(tmp_player == NULL){ + tmp_player = (char*)FindSignature(players, base_addr, base_len); + if(tmp_player != NULL){ +#ifdef WIN32 + tmp_player2 = (char*)FindSignature(players2, base_addr, base_len); +#else +#ifdef L4D1 + tmp_player2 = (char*)FindSignature(players2, base_addr, base_len); +#else + tmp_player2 = tmp_player; +#endif +#endif + if(tmp_player2 != NULL){ + get_org_sig(tmp_player, players_new, players_org); + WriteSignature(tmp_player, players_new); + get_org_sig(tmp_player2, players_new2, players_org2); + WriteSignature(tmp_player2, players_new2); + engine->ServerCommand("maxplayers 32\n"); + engine->ServerCommand("L4DToolZ ivailosp@abv.bg\n"); + } + } + } + if(unreserved_ptr==NULL){ + unreserved_ptr = (char*)FindSignature(unreserved, base_addr, base_len); + get_org_sig(unreserved_ptr, unreserved_new, unreserved_org); + } + + find_base(server_dll, base_addr, base_len); + + if(chuman_limit == NULL){ + chuman_limit = (char*)FindSignature(human_limit, base_addr, base_len); + get_org_sig(chuman_limit, human_limit_new, human_limit_org); + } + +#ifndef WIN32 + if(max_players_server_browser == NULL){ + max_players_server_browser = (char*)FindSignature(server_bplayers, base_addr, base_len); + get_org_sig(max_players_server_browser, (const char*)server_bplayers_new, server_bplayers_org); + } +#endif + + return true; +} + +bool l4dtoolz::Unload(char *error, size_t maxlen) +{ + +#if !defined METAMOD_PLAPI_VERSION + SH_RELEASE_CALLCLASS(m_EngineCC); +#endif + + if(max_players_friend_lobby != NULL) + WriteSignature(max_players_friend_lobby, friends_lobby_org); + if(max_players_connect != NULL) + WriteSignature(max_players_connect, max_players_org); + if(lobby_sux_ptr != NULL) + WriteSignature(lobby_sux_ptr, lobby_sux_org); + if(max_players_server_browser != NULL) + WriteSignature(max_players_server_browser, server_bplayers_org); + if(chuman_limit != NULL) + WriteSignature(chuman_limit, human_limit_org); + + if(tmp_player != NULL) + WriteSignature(tmp_player, players_org); + if(tmp_player2 != NULL) + WriteSignature(tmp_player2, players_org2); + if(unreserved_ptr != NULL) + WriteSignature(unreserved_ptr, unreserved_org); + if(lobby_match_ptr != NULL) + WriteSignature(lobby_match_ptr, lobby_match_org); + +#ifdef WIN32 + CloseHandle(hProcess); +#endif + + delete[] friends_lobby_org; + delete[] max_players_org; + delete[] lobby_sux_org; + delete[] server_bplayers_org; + delete[] human_limit_org; + delete[] players_org; + delete[] players_org2; + delete[] unreserved_org; + return true; +} + +void l4dtoolz::OnVSPListening(IServerPluginCallbacks *iface) +{ + vsp_callbacks = iface; +} + + +bool l4dtoolz::Pause(char *error, size_t maxlen) +{ + return true; +} + +bool l4dtoolz::Unpause(char *error, size_t maxlen) +{ + return true; +} + +const char *l4dtoolz::GetLicense() +{ + return ""; +} + +const char *l4dtoolz::GetVersion() +{ + return "1.0.0.9f"; +} + +const char *l4dtoolz::GetDate() +{ + return __DATE__; +} + +const char *l4dtoolz::GetLogTag() +{ + return "L4DToolZ"; +} + +const char *l4dtoolz::GetAuthor() +{ + return "Ivailosp"; +} + +const char *l4dtoolz::GetDescription() +{ + return "Ivailosp plugin"; +} + +const char *l4dtoolz::GetName() +{ + return "L4DToolZ"; +} + +const char *l4dtoolz::GetURL() +{ + return "n/a"; +} diff --git a/l4dtoolz_mm.h b/l4dtoolz_mm.h new file mode 100644 index 0000000..6a60d4a --- /dev/null +++ b/l4dtoolz_mm.h @@ -0,0 +1,65 @@ +#ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ +#define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ + +#include + + +class l4dtoolz : public ISmmPlugin, public IMetamodListener +{ +public: + bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); + bool Unload(char *error, size_t maxlen); + bool Pause(char *error, size_t maxlen); + bool Unpause(char *error, size_t maxlen); + + void OnVSPListening(IServerPluginCallbacks *iface); +public: + const char *GetAuthor(); + const char *GetName(); + const char *GetDescription(); + const char *GetURL(); + const char *GetLicense(); + const char *GetVersion(); + const char *GetDate(); + const char *GetLogTag(); +public: + + static void OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float flOldValue ); + static void OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, float flOldValue ); + static void OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue ); + static void OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue ); + + static char* max_players_friend_lobby; + static char* max_players_connect; + static char* max_players_server_browser; + static char* lobby_sux_ptr; + static char* chuman_limit; + static char* tmp_player; + static char* tmp_player2; + static char* unreserved_ptr; + static char* lobby_match_ptr; + +public: + static bool find_base(const char* name, char*& base_addr, size_t& base_len); + static void* FindSignature(const char* mask, const char* base_addr, size_t base_len, bool pure_sign = false); + static void get_org_sig(const char* offset, const char* new_sig, char*& org_sig); + static void WriteSignature(char* addr, const char* signature); + static void ReadSignature(const char* addr, char* signature); +private: + +#if !defined METAMOD_PLAPI_VERSION + SourceHook::CallClass *m_EngineCC; +#endif + +#ifdef WIN32 +private: + static HANDLE hProcess; +#endif +}; + + +extern l4dtoolz g_l4dtoolz; + +PLUGIN_GLOBALVARS(); + +#endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ diff --git a/msvc8/l4dtoolz_mm.sln b/msvc8/l4dtoolz_mm.sln new file mode 100644 index 0000000..3812f8f --- /dev/null +++ b/msvc8/l4dtoolz_mm.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "l4dtoolz_mm", "l4dtoolz_mm.vcproj", "{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug - Left 4 Dead 2|Win32 = Debug - Left 4 Dead 2|Win32 + Debug - Left 4 Dead|Win32 = Debug - Left 4 Dead|Win32 + Release - Left 4 Dead 2|Win32 = Release - Left 4 Dead 2|Win32 + Release - Left 4 Dead|Win32 = Release - Left 4 Dead|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead 2|Win32.ActiveCfg = Debug - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead 2|Win32.Build.0 = Debug - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead|Win32.ActiveCfg = Debug - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead|Win32.Build.0 = Debug - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead 2|Win32.ActiveCfg = Release - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead 2|Win32.Build.0 = Release - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead|Win32.ActiveCfg = Release - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead|Win32.Build.0 = Release - Left 4 Dead|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc8/l4dtoolz_mm.vcproj b/msvc8/l4dtoolz_mm.vcproj new file mode 100644 index 0000000..ce32cf9 --- /dev/null +++ b/msvc8/l4dtoolz_mm.vcproj @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +