cssdm_ffa.cpp
author Ruben Gonzalez <drifter01620@gmail.com>
Wed Oct 01 11:50:24 2014 -0400 (2014-10-01)
changeset 193 277c856152b0
parent 51 341eeeedf724
permissions -rw-r--r--
Update linix CS:GO gamedata
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * CS:S DM, Copyright (C) 2004-2007 AlliedModders LLC. 
     5  * By David "BAILOPAN" Anderson
     6  * All rights reserved.
     7  * ===============================================================
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or (at
    12  * your option) any later version.
    13  * 
    14  * This program is distributed in the hope that it will be useful, but
    15  * WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    17  * General Public License for more details.
    18  * 
    19  * You should have received a copy of the GNU General Public License
    20  * along with this program; see the file COPYING; if not, write to the
    21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
    22  * MA 02110-1301 USA
    23  * 
    24  * Version: $Id$
    25  */
    26 
    27 #include "cssdm_headers.h"
    28 #include "cssdm_utils.h"
    29 #include "sm_platform.h"
    30 #include "cssdm_includesdk.h"
    31 
    32 SH_DECL_MANUALHOOK2(CGameRules_IPointsForKill, 62+EXTRA_VTBL_OFFSET, 0, 0, int, CBasePlayer *, CBasePlayer *);
    33 
    34 #if defined PLATFORM_WINDOWS
    35 #define PLATFORM_NAME	"Windows"
    36 #elif defined PLATFORM_LINUX
    37 #define PLATFORM_NAME	"Linux"
    38 #elif defined __APPLE__
    39 #define PLATFORM_NAME	"Mac"
    40 #endif
    41 
    42 bool g_FFA_Patched = false;
    43 bool g_FFA_Prepared = false;
    44 
    45 void **g_gamerules_addr = NULL;
    46 
    47 /* Lagcomp */
    48 static int g_lagcomp_offset = 0;
    49 static void *g_lagcomp_addr = NULL;
    50 static dmpatch_t g_lagcomp_patch;
    51 static dmpatch_t g_lagcomp_restore;
    52 
    53 /* Takedamage */
    54 static int g_takedmg_offset[5] = {0};
    55 static void *g_takedmg_addr = NULL;
    56 static dmpatch_t g_takedmg_patch[2];
    57 static dmpatch_t g_takedmg_restore[2];
    58 
    59 /* Calc domination and revenge */
    60 static int g_domrev_offset = 0;
    61 static void *g_domrev_addr = NULL;
    62 static dmpatch_t g_domrev_patch;
    63 static dmpatch_t g_domrev_restore;
    64 
    65 int OnIPointsForKill(CBasePlayer *pl1, CBasePlayer *pl2)
    66 {
    67 	/* If we're hooked, FFA is always on. */
    68 	RETURN_META_VALUE(MRES_SUPERCEDE, 1);
    69 }
    70 
    71 bool DM_FFA_LoadPatch(const char *name, dmpatch_t *patch, char *error, size_t maxlength)
    72 {
    73 	char fullname[255];
    74 	snprintf(fullname, sizeof(fullname), "%s_%s", name, PLATFORM_NAME);
    75 
    76 	const char *str = g_pDmConf->GetKeyValue(fullname);
    77 	if (!str)
    78 	{
    79 		snprintf(error, maxlength, "Could not find signature value for \"%s\"", fullname);
    80 		return false;
    81 	}
    82 
    83 	patch->bytes = DM_StringToBytes(str, patch->patch, sizeof(patch->patch));
    84 	if (!patch->bytes)
    85 	{
    86 		snprintf(error, maxlength, "Invalid signature detected for \"%s\"", fullname);
    87 		return false;
    88 	}
    89 
    90 	return true;
    91 }
    92 
    93 bool DM_Prepare_FFA(char *error, size_t maxlength)
    94 {
    95 	void *gamerules = NULL;
    96 	if (!g_pDmConf->GetMemSig("OnTakeDamage", &g_takedmg_addr) || !g_takedmg_addr)
    97 	{
    98 		snprintf(error, maxlength, "Could not find \"OnTakeDamage\" signature!");
    99 		return false;
   100 	}
   101 	if (!g_pDmConf->GetMemSig("WantsLagComp", &g_lagcomp_addr) || !g_lagcomp_addr)
   102 	{
   103 		snprintf(error, maxlength, "Could not find \"WantsLagComp\" signature!");
   104 		return false;
   105 	}
   106 	if (!g_pDmConf->GetMemSig("CalcDominationAndRevenge", &g_domrev_addr) || !g_domrev_addr)
   107 	{
   108 		snprintf(error, maxlength, "Could not find \"CalcDominationAndRevenge\" signature!");
   109 		return false;
   110 	}
   111 	if (!g_pDmConf->GetMemSig("CGameRules", &gamerules) || !gamerules)
   112 	{
   113 		snprintf(error, maxlength, "Could not find \"CGameRules\" signature!");
   114 		return false;
   115 	}
   116 	
   117 	if (!g_pDmConf->GetOffset("LagCompPatch", &g_lagcomp_offset)
   118 		|| !g_lagcomp_offset)
   119 	{
   120 		snprintf(error, maxlength, "Could not find LagCompPatch offset");
   121 		return false;
   122 	}
   123 	if (!DM_FFA_LoadPatch("LagCompPatch", &g_lagcomp_patch, error, maxlength))
   124 	{
   125 		return false;
   126 	}
   127 
   128 	if (!g_pDmConf->GetOffset("CalcDomRevPatch", &g_domrev_offset)
   129 		|| !g_domrev_offset)
   130 	{
   131 		snprintf(error, maxlength, "Could not find CalcDomRevPatch offset");
   132 		return false;
   133 	}
   134 	if (!DM_FFA_LoadPatch("CalcDomRevPatch", &g_domrev_patch, error, maxlength))
   135 	{
   136 		return false;
   137 	}
   138 
   139 	if (!g_pDmConf->GetOffset("TakeDmgPatch1", &g_takedmg_offset[0])
   140 		|| !g_takedmg_offset[0])
   141 	{
   142 		snprintf(error, maxlength, "Could not find TakeDmgPatch1 offset");
   143 		return false;
   144 	}
   145 	if (!DM_FFA_LoadPatch("TakeDmgPatch1", &g_takedmg_patch[0], error, maxlength))
   146 	{
   147 		return false;
   148 	}
   149 
   150 #if SOURCE_ENGINE == SE_CSGO
   151 	if (!g_pDmConf->GetOffset("TakeDmgPatch2", &g_takedmg_offset[1])
   152 		|| !g_takedmg_offset[1])
   153 	{
   154 		snprintf(error, maxlength, "Could not find TakeDmgPatch1 offset");
   155 		return false;
   156 	}
   157 	if (!DM_FFA_LoadPatch("TakeDmgPatch2", &g_takedmg_patch[1], error, maxlength))
   158 	{
   159 		return false;
   160 	}
   161 #endif
   162 
   163 	/* Load the GameRules pointer */
   164 	int offset;
   165 #ifdef _MSC_VER
   166 	if (!g_pDmConf->GetOffset("g_pGameRules", &offset)
   167 		|| !offset)
   168 	{
   169 		snprintf(error, maxlength, "Could not find g_pGameRules offset");
   170 		return false;
   171 	}
   172 	g_gamerules_addr = (void **)*(void **)((unsigned char *)gamerules + offset);
   173 #else
   174 	g_gamerules_addr = reinterpret_cast<void **>(gamerules);
   175 #endif
   176 
   177 	/* Get the "IPointsForKill" offset */
   178 	if (!g_pDmConf->GetOffset("IPointsForKill", &offset)
   179 		|| !offset)
   180 	{
   181 		snprintf(error, maxlength, "Could not find IPointsForKills offset");
   182 		return false;
   183 	}
   184 	SH_MANUALHOOK_RECONFIGURE(CGameRules_IPointsForKill, offset, 0, 0);
   185 
   186 	g_FFA_Prepared = true;
   187 
   188 	return true;
   189 }
   190 
   191 bool DM_Patch_FFA()
   192 {
   193 	if (g_FFA_Patched || !g_FFA_Prepared || *g_gamerules_addr == NULL)
   194 	{
   195 		return false;
   196 	}
   197 
   198 	DM_ApplyPatch(g_lagcomp_addr, g_lagcomp_offset, &g_lagcomp_patch, &g_lagcomp_restore);
   199 	DM_ApplyPatch(g_takedmg_addr, g_takedmg_offset[0], &g_takedmg_patch[0], &g_takedmg_restore[0]);
   200 #if SOURCE_ENGINE == SE_CSGO
   201 	DM_ApplyPatch(g_takedmg_addr, g_takedmg_offset[1], &g_takedmg_patch[1], &g_takedmg_restore[1]);
   202 #endif
   203 	DM_ApplyPatch(g_domrev_addr, g_domrev_offset, &g_domrev_patch, &g_domrev_restore);
   204 
   205 	SH_ADD_MANUALHOOK_STATICFUNC(CGameRules_IPointsForKill, *g_gamerules_addr, OnIPointsForKill, false);
   206 
   207 	g_FFA_Patched = true;
   208 
   209 	return true;
   210 }
   211 
   212 bool DM_Unpatch_FFA()
   213 {
   214 	if (!g_FFA_Patched)
   215 	{
   216 		return false;
   217 	}
   218 
   219 	if (!g_IsInGlobalShutdown)
   220 	{
   221 		SH_REMOVE_MANUALHOOK_STATICFUNC(CGameRules_IPointsForKill, *g_gamerules_addr, OnIPointsForKill, false);
   222 	}
   223 
   224 	DM_ApplyPatch(g_lagcomp_addr, g_lagcomp_offset, &g_lagcomp_restore, NULL);
   225 	DM_ApplyPatch(g_takedmg_addr, g_takedmg_offset[0], &g_takedmg_restore[0], NULL);
   226 #if SOURCE_ENGINE == SE_CSGO
   227 	DM_ApplyPatch(g_takedmg_addr, g_takedmg_offset[1], &g_takedmg_restore[1], NULL);
   228 #endif
   229 	DM_ApplyPatch(g_domrev_addr, g_domrev_offset, &g_domrev_restore, NULL);
   230 
   231 	g_FFA_Patched = false;
   232 
   233 	return true;
   234 }
   235 
   236 bool DM_FFA_IsPatched()
   237 {
   238 	return g_FFA_Patched;
   239 }
   240 
   241 bool DM_FFA_IsPrepared()
   242 {
   243 	return g_FFA_Prepared;
   244 }