Added natives for changing team score and mvp stars on CSS/CSGO (bug 5295, r=psychonic).
Added natives for changing team score and mvp stars on CSS/CSGO (
bug 5295, r=psychonic).
1.1 --- a/extensions/cstrike/natives.cpp Sun May 27 18:48:54 2012 -0400
1.2 +++ b/extensions/cstrike/natives.cpp Sun May 27 19:07:44 2012 -0400
1.3 @@ -460,6 +460,210 @@
1.4 return GetFakeWeaponID(AliasToWeaponID(weapon));
1.5 }
1.6
1.7 +static cell_t CS_SetTeamScore(IPluginContext *pContext, const cell_t *params)
1.8 +{
1.9 + if (g_pSDKTools == NULL)
1.10 + {
1.11 + smutils->LogError(myself, "SDKTools interface not found. CS_SetTeamScore native disabled.");
1.12 + }
1.13 + else if (g_pSDKTools->GetInterfaceVersion() < 2)
1.14 + {
1.15 + //<psychonic> THIS ISN'T DA LIMBO STICK. LOW IS BAD
1.16 + return pContext->ThrowNativeError("SDKTools interface is outdated. CS_SetTeamScore native disabled.");
1.17 + }
1.18 +
1.19 + static void *addr;
1.20 + if (!addr)
1.21 + {
1.22 + if (!g_pGameConf->GetMemSig("CheckWinLimit", &addr) || !addr)
1.23 + {
1.24 + return pContext->ThrowNativeError("Failed to locate CheckWinLimit function");
1.25 + }
1.26 + }
1.27 +
1.28 + static int ctTeamOffsetOffset = -1;
1.29 + static int ctTeamOffset;
1.30 +
1.31 + static int tTeamOffsetOffset = -1;
1.32 + static int tTeamOffset;
1.33 +
1.34 + if (ctTeamOffsetOffset == -1)
1.35 + {
1.36 + if (!g_pGameConf->GetOffset("CTTeamScoreOffset", &ctTeamOffsetOffset))
1.37 + {
1.38 + ctTeamOffsetOffset = -1;
1.39 + return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
1.40 + }
1.41 +
1.42 + ctTeamOffset = *(int *)((intptr_t)addr + ctTeamOffsetOffset);
1.43 + }
1.44 +
1.45 + if (tTeamOffsetOffset == -1)
1.46 + {
1.47 + if (!g_pGameConf->GetOffset("TTeamScoreOffset", &tTeamOffsetOffset))
1.48 + {
1.49 + tTeamOffsetOffset = -1;
1.50 + return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
1.51 + }
1.52 +
1.53 + tTeamOffset = *(int *)((intptr_t)addr + tTeamOffsetOffset);
1.54 + }
1.55 +
1.56 + void *gamerules = g_pSDKTools->GetGameRules();
1.57 + if (gamerules == NULL)
1.58 + {
1.59 + return pContext->ThrowNativeError("GameRules not available. CS_SetTeamScore native disabled.");
1.60 + }
1.61 +
1.62 + if (params[1] == 3)
1.63 + {
1.64 + *(int16_t *)((intptr_t)gamerules+ctTeamOffset) = params[2];
1.65 + return 1;
1.66 + }
1.67 + else if (params[1] == 2)
1.68 + {
1.69 + *(int16_t *)((intptr_t)gamerules+tTeamOffset) = params[2];
1.70 + return 1;
1.71 + }
1.72 + return pContext->ThrowNativeError("Invalid team index passed (%i).", params[1]);
1.73 +}
1.74 +
1.75 +static cell_t CS_GetTeamScore(IPluginContext *pContext, const cell_t *params)
1.76 +{
1.77 + if (g_pSDKTools == NULL)
1.78 + {
1.79 + smutils->LogError(myself, "SDKTools interface not found. CS_GetTeamScore native disabled.");
1.80 + }
1.81 + else if (g_pSDKTools->GetInterfaceVersion() < 2)
1.82 + {
1.83 + //<psychonic> THIS ISN'T DA LIMBO STICK. LOW IS BAD
1.84 + return pContext->ThrowNativeError("SDKTools interface is outdated. CS_GetTeamScore native disabled.");
1.85 + }
1.86 +
1.87 + static void *addr;
1.88 + if (!addr)
1.89 + {
1.90 + if (!g_pGameConf->GetMemSig("CheckWinLimit", &addr) || !addr)
1.91 + {
1.92 + return pContext->ThrowNativeError("Failed to locate CheckWinLimit function");
1.93 + }
1.94 + }
1.95 +
1.96 + static int ctTeamOffsetOffset = -1;
1.97 + static int ctTeamOffset;
1.98 +
1.99 + static int tTeamOffsetOffset = -1;
1.100 + static int tTeamOffset;
1.101 +
1.102 + if (ctTeamOffsetOffset == -1)
1.103 + {
1.104 + if (!g_pGameConf->GetOffset("CTTeamScoreOffset", &ctTeamOffsetOffset))
1.105 + {
1.106 + ctTeamOffsetOffset = -1;
1.107 + return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
1.108 + }
1.109 +
1.110 + ctTeamOffset = *(int *)((intptr_t)addr + ctTeamOffsetOffset);
1.111 + }
1.112 +
1.113 + if (tTeamOffsetOffset == -1)
1.114 + {
1.115 + if (!g_pGameConf->GetOffset("TTeamScoreOffset", &tTeamOffsetOffset))
1.116 + {
1.117 + tTeamOffsetOffset = -1;
1.118 + return pContext->ThrowNativeError("Unable to find CTTeamOffset gamedata");
1.119 + }
1.120 +
1.121 + tTeamOffset = *(int *)((intptr_t)addr + tTeamOffsetOffset);
1.122 + }
1.123 +
1.124 + void *gamerules = g_pSDKTools->GetGameRules();
1.125 + if (gamerules == NULL)
1.126 + {
1.127 + return pContext->ThrowNativeError("GameRules not available. CS_GetTeamScore native disabled.");
1.128 + }
1.129 +
1.130 + if (params[1] == 3)
1.131 + {
1.132 + return *(int16_t *)((intptr_t)gamerules+ctTeamOffset);
1.133 + }
1.134 + else if (params[1] == 2)
1.135 + {
1.136 + return *(int16_t *)((intptr_t)gamerules+tTeamOffset);
1.137 + }
1.138 + return pContext->ThrowNativeError("Invalid team index passed (%i).", params[1]);
1.139 +}
1.140 +
1.141 +static cell_t CS_SetMVPCount(IPluginContext *pContext, const cell_t *params)
1.142 +{
1.143 + static void *addr;
1.144 + if (!addr)
1.145 + {
1.146 + if (!g_pGameConf->GetMemSig("IncrementNumMVPs", &addr) || !addr)
1.147 + {
1.148 + return pContext->ThrowNativeError("Failed to locate IncrementNumMVPs function");
1.149 + }
1.150 + }
1.151 +
1.152 + CBaseEntity *pEntity;
1.153 + if (!(pEntity = GetCBaseEntity(params[1], true)))
1.154 + {
1.155 + return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
1.156 + }
1.157 +
1.158 + static int mvpOffsetOffset = -1;
1.159 + static int mvpOffset;
1.160 +
1.161 + if (mvpOffsetOffset == -1)
1.162 + {
1.163 + if (!g_pGameConf->GetOffset("MVPCountOffset", &mvpOffsetOffset))
1.164 + {
1.165 + mvpOffsetOffset = -1;
1.166 + return pContext->ThrowNativeError("Unable to find MVPCountOffset gamedata");
1.167 + }
1.168 +
1.169 + mvpOffset = *(int *)((intptr_t)addr + mvpOffsetOffset);
1.170 + }
1.171 +
1.172 + *(int *)((intptr_t)pEntity + mvpOffset) = params[2];
1.173 +
1.174 + return 1;
1.175 +}
1.176 +
1.177 +static cell_t CS_GetMVPCount(IPluginContext *pContext, const cell_t *params)
1.178 +{
1.179 + static void *addr;
1.180 + if (!addr)
1.181 + {
1.182 + if (!g_pGameConf->GetMemSig("IncrementNumMVPs", &addr) || !addr)
1.183 + {
1.184 + return pContext->ThrowNativeError("Failed to locate IncrementNumMVPs function");
1.185 + }
1.186 + }
1.187 +
1.188 + CBaseEntity *pEntity;
1.189 + if (!(pEntity = GetCBaseEntity(params[1], true)))
1.190 + {
1.191 + return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
1.192 + }
1.193 +
1.194 + static int mvpOffsetOffset = -1;
1.195 + static int mvpOffset;
1.196 +
1.197 + if (mvpOffsetOffset == -1)
1.198 + {
1.199 + if (!g_pGameConf->GetOffset("MVPCountOffset", &mvpOffsetOffset))
1.200 + {
1.201 + mvpOffsetOffset = -1;
1.202 + return pContext->ThrowNativeError("Unable to find MVPCountOffset gamedata");
1.203 + }
1.204 +
1.205 + mvpOffset = *(int *)((intptr_t)addr + mvpOffsetOffset);
1.206 + }
1.207 +
1.208 + return *(int *)((intptr_t)pEntity + mvpOffset);
1.209 +}
1.210 +
1.211 sp_nativeinfo_t g_CSNatives[] =
1.212 {
1.213 {"CS_RespawnPlayer", CS_RespawnPlayer},
1.214 @@ -471,6 +675,10 @@
1.215 {"CS_GetClientClanTag", CS_GetClientClanTag},
1.216 {"CS_SetClientClanTag", CS_SetClientClanTag},
1.217 {"CS_AliasToWeaponID", CS_AliasToWeaponID},
1.218 + {"CS_GetTeamScore", CS_GetTeamScore},
1.219 + {"CS_SetTeamScore", CS_SetTeamScore},
1.220 + {"CS_GetMVPCount", CS_GetMVPCount},
1.221 + {"CS_SetMVPCount", CS_SetMVPCount},
1.222 {NULL, NULL}
1.223 };
1.224
2.1 --- a/gamedata/sm-cstrike.games/game.csgo.txt Sun May 27 18:48:54 2012 -0400
2.2 +++ b/gamedata/sm-cstrike.games/game.csgo.txt Sun May 27 19:07:44 2012 -0400
2.3 @@ -27,6 +27,27 @@
2.4 "windows" "2700"
2.5 "linux" "2700"
2.6 }
2.7 + //Offset into CheckRestartRound
2.8 + //Only Windows/Linux for now.
2.9 + "CTTeamScoreOffset"
2.10 + {
2.11 + "windows" "82"
2.12 + "linux" "117"
2.13 + }
2.14 + //Offset into CheckRestartRound
2.15 + //Only Windows/Linux for now.
2.16 + "TTeamScoreOffset"
2.17 + {
2.18 + "windows" "107"
2.19 + "linux" "152"
2.20 + }
2.21 + //Offset into IncrementNumMVPs to find MVP count offset from player
2.22 + //Only Windows/Linux for now.
2.23 + "MVPCountOffset"
2.24 + {
2.25 + "windows" "42"
2.26 + "linux" "46"
2.27 + }
2.28 }
2.29 "Signatures"
2.30 {
2.31 @@ -72,6 +93,19 @@
2.32 "windows" "\x55\x8B\xEC\x8B\x4D\x2A\x33\xC0\x85\xC9\x74"
2.33 "linux" "@_Z13GetWeaponInfo10CSWeaponID"
2.34 }
2.35 + //In CS:GO this is actually CCSGameRules::CheckRestartRound(void) but to keep same gamedata as cs:s.
2.36 + "CheckWinLimit"
2.37 + {
2.38 + "library" "server"
2.39 + "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x2A\x57\x8B\xF9\x85\xC0\x0F\x84\x2A\x2A\x00\x00"
2.40 + "linux" "@_ZN12CCSGameRules17CheckRestartRoundEv"
2.41 + }
2.42 + "IncrementNumMVPs"
2.43 + {
2.44 + "library" "server"
2.45 + "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x57\x8B\xF9\x85\x2A\x74\x2A\x83\x2A\x2A\x00\x74\x2A\x68\x50"
2.46 + "linux" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
2.47 + }
2.48 "AliasToWeaponID"
2.49 {
2.50 "library" "server"
3.1 --- a/gamedata/sm-cstrike.games/game.css.txt Sun May 27 18:48:54 2012 -0400
3.2 +++ b/gamedata/sm-cstrike.games/game.css.txt Sun May 27 19:07:44 2012 -0400
3.3 @@ -35,6 +35,27 @@
3.4 "linux" "42"
3.5 "mac" "29"
3.6 }
3.7 + //Offset into CheckWinLimit to find CT team score offset from gamerules. For mac this is an offset into CCSGameRules::Think
3.8 + "CTTeamScoreOffset"
3.9 + {
3.10 + "windows" "18"
3.11 + "linux" "46"
3.12 + "mac" "466"
3.13 + }
3.14 + //Offset into CheckWinLimit to find T team score offset from gamerules. For mac this is an offset into CCSGameRules::Think
3.15 + "TTeamScoreOffset"
3.16 + {
3.17 + "windows" "40"
3.18 + "linux" "57"
3.19 + "mac" "481"
3.20 + }
3.21 + //Offset into IncrementNumMVPs to find MVP count offset from player
3.22 + "MVPCountOffset"
3.23 + {
3.24 + "windows" "60"
3.25 + "linux" "49"
3.26 + "mac" "62"
3.27 + }
3.28 }
3.29 "Signatures"
3.30 {
3.31 @@ -108,6 +129,22 @@
3.32 "linux" "@_Z15AliasToWeaponIDPKc"
3.33 "mac" "@_Z15AliasToWeaponIDPKc"
3.34 }
3.35 +
3.36 + //For mac we use think since CheckWinLimit dosnt exist on mac.
3.37 + "CheckWinLimit"
3.38 + {
3.39 + "library" "server"
3.40 + "windows" "\xA1\x2A\x2A\x2A\x2A\x8B\x40\x2A\x85\xC0\x56\x8B\xF1\x74"
3.41 + "linux" "@_ZN12CCSGameRules13CheckWinLimitEv"
3.42 + "mac" "@_ZN12CCSGameRules5ThinkEv"
3.43 + }
3.44 + "IncrementNumMVPs"
3.45 + {
3.46 + "library" "server"
3.47 + "windows" "\x55\x8B\xEC\x83\xEC\x2A\x89\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x8B\x48\x2A\x89\x2A\x2A\x33\xD2\x83\x7D\x2A\x00\x0F\x95\xC2\x0F\xB6\xC2\x85\xC0\x74\x2A\x68"
3.48 + "linux" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
3.49 + "mac" "@_ZN9CCSPlayer16IncrementNumMVPsE13CSMvpReason_t"
3.50 + }
3.51 }
3.52 }
3.53 }
4.1 --- a/plugins/include/cstrike.inc Sun May 27 18:48:54 2012 -0400
4.2 +++ b/plugins/include/cstrike.inc Sun May 27 19:07:44 2012 -0400
4.3 @@ -264,7 +264,46 @@
4.4 * @note Only supported on CS:S. Has no effect on CS:GO.
4.5 */
4.6 native CS_SetClientClanTag(client, const String:tag[]);
4.7 -
4.8 +
4.9 +/**
4.10 + * Gets a team's score
4.11 + * @param team Team index to get score for.
4.12 + * @return Returns the internal team score.
4.13 + *
4.14 + * @error Invalid team index.
4.15 + */
4.16 +native CS_GetTeamScore(team);
4.17 +
4.18 +/**
4.19 + * Sets a team's score
4.20 + * @param team Team index to set score for.
4.21 + * @param value Value to set teams score as.
4.22 + * @noreturn
4.23 + *
4.24 + * @error Invalid team index.
4.25 + * @note This will update the scoreboard only after the scoreboard update function is called. Use SetTeamScore plus this to update the scoreboard instantly and save values correctly.
4.26 + */
4.27 +native CS_SetTeamScore(team, value);
4.28 +
4.29 +/**
4.30 + * Gets a client's mvp count
4.31 + * @param client Client index to set mvp count for.
4.32 + * @return Returns the clients internal MVP count.
4.33 + *
4.34 + * @error Invalid client.
4.35 + */
4.36 +native CS_GetMVPCount(client);
4.37 +
4.38 +/**
4.39 + * Sets a client's mvp count
4.40 + * @param client Client index to set mvp count for.
4.41 + * @param value Value to set clients mvp count as.
4.42 + * @noreturn
4.43 + *
4.44 + * @error Invalid client.
4.45 + */
4.46 +native CS_SetMVPCount(client, value);
4.47 +
4.48 /**
4.49 * Gets a weaponID from a alias
4.50 * @param alias Weapon alias to attempt to get an id for.
4.51 @@ -300,6 +339,10 @@
4.52 MarkNativeAsOptional("CS_GetWeaponPrice");
4.53 MarkNativeAsOptional("CS_GetClientClanTag");
4.54 MarkNativeAsOptional("CS_SetClientClanTag");
4.55 + MarkNativeAsOptional("CS_GetTeamScore");
4.56 + MarkNativeAsOptional("CS_SetTeamScore");
4.57 + MarkNativeAsOptional("CS_GetMVPCount");
4.58 + MarkNativeAsOptional("CS_SetMVPCount");
4.59 MakrNativeAsOptional("CS_AliasToWeaponID");
4.60 }
4.61 #endif