This commit is contained in:
Huoji's
2023-10-08 05:28:41 +08:00
parent 037969a06d
commit 876b4b28f4
8 changed files with 287 additions and 9 deletions

View File

@@ -1,6 +1,83 @@
#include "events.h"
namespace events {
auto OnPlayerHurtEvent(IGameEvent* event) -> void {
/*
auto luaCall_onPlayerHurt(int userid, int attacker, int health, int armor,
const char* weapon, int dmg_health, int dmg_armor,
int hitgroup) -> void
*/
UnkGameEventStruct_t userIdNameParams{ "userid" };
UnkGameEventStruct_t attackerNameParams{ "attacker" };
UnkGameEventStruct_t healthNameParams{0};
UnkGameEventStruct_t armorNameParams{0};
UnkGameEventStruct_t weaponNameParams{0};
UnkGameEventStruct_t dmg_healthNameParams{0};
UnkGameEventStruct_t dmg_armorNameParams{0};
UnkGameEventStruct_t hitgroupNameParams{0};
static const auto healthStr = "health";
static const auto armorStr = "armor";
static const auto weaponStr = "weapon";
static const auto dmg_healthStr = "dmg_health";
static const auto dmg_armorStr = "dmg_armor";
static const auto hitgroupStr = "hitgroup";
healthNameParams.m_Unk = Offset::FnServerHashFunction(
healthStr, sizeof healthStr, SERVER_HASH_FUCNTION_KEY);
healthNameParams.m_Key = healthStr;
armorNameParams.m_Unk = Offset::FnServerHashFunction(
armorStr, sizeof armorStr, SERVER_HASH_FUCNTION_KEY);
armorNameParams.m_Key = armorStr;
weaponNameParams.m_Unk = Offset::FnServerHashFunction(
weaponStr, sizeof weaponStr, SERVER_HASH_FUCNTION_KEY);
weaponNameParams.m_Key = weaponStr;
dmg_healthNameParams.m_Unk = Offset::FnServerHashFunction(
dmg_healthStr, sizeof dmg_healthStr, SERVER_HASH_FUCNTION_KEY);
dmg_healthNameParams.m_Key = dmg_healthStr;
dmg_armorNameParams.m_Unk = Offset::FnServerHashFunction(
dmg_armorStr, sizeof dmg_armorStr, SERVER_HASH_FUCNTION_KEY);
dmg_armorNameParams.m_Key = dmg_armorStr;
hitgroupNameParams.m_Unk = Offset::FnServerHashFunction(
hitgroupStr, sizeof hitgroupStr, SERVER_HASH_FUCNTION_KEY);
hitgroupNameParams.m_Key = hitgroupStr;
const auto victimPawn = reinterpret_cast<CCSPlayerPawn*>(
event->GetPlayerPawn(&userIdNameParams));
const auto attackerPawn = reinterpret_cast<CCSPlayerPawn*>(
event->GetPlayerPawn(&attackerNameParams));
if (victimPawn == nullptr || attackerPawn == nullptr) {
return;
}
if (victimPawn->IsBasePlayerController() == false ||
attackerPawn->IsBasePlayerController() == false) {
return;
}
const auto victim = victimPawn->GetPlayerController();
const auto attacker = attackerPawn->GetPlayerController();
if (victim == nullptr || attacker == nullptr) {
return;
}
const auto victimIndex = victim->GetRefEHandle().GetEntryIndex();
const auto attackerIndex = attacker->GetRefEHandle().GetEntryIndex();
auto health = event->GetInt(&healthNameParams);
auto armor = event->GetInt(&armorNameParams);
auto weapon = event->GetString(&weaponNameParams);
auto dmg_health = event->GetInt(&dmg_healthNameParams);
auto dmg_armor = event->GetInt(&dmg_armorNameParams);
auto hitgroup = event->GetInt(&hitgroupNameParams);
ScriptCallBacks::luaCall_onPlayerHurt(victimIndex, attackerIndex, health, armor,
weapon, dmg_health, dmg_armor,
hitgroup);
}
auto OnRoundEndEvent(IGameEvent* event) -> void {
/*
"winner" "byte" // winner team/user i

View File

@@ -13,4 +13,5 @@ auto OnPlayerDisconnect(int slot, const char* pszName, uint64_t xuid,
auto OnPlayerSpawnEvent(IGameEvent* event) -> void;
auto OnRoundStartEvent(IGameEvent* event) -> void;
auto OnRoundEndEvent(IGameEvent* event) -> void;
auto OnPlayerHurtEvent(IGameEvent* event) -> void;
} // namespace events

View File

@@ -16,9 +16,12 @@ CCSWeaponBase_Spawn_t origin_CCSWeaponBase_Spawn = NULL;
void __fastcall hook_CCSWeaponBase_Spawn(CBaseEntity* pThis, void* a2) {
const char* pszClassName = pThis->m_pEntity()->m_designerName;
LOG("Weapon spawn: %s\n", pszClassName);
origin_CCSWeaponBase_Spawn(pThis, a2);
if (pszClassName == nullptr) {
return;
}
LOG("Weapon spawn: %s\n", pszClassName);
do {
auto pWeapon = reinterpret_cast<CCSWeaponBase*>(pThis);
@@ -165,6 +168,7 @@ bool __fastcall hook_FireEventServerSide(CGameEventManager* rcx,
hash_32_fnv1a_const("player_spawn");
static constexpr auto round_start = hash_32_fnv1a_const("round_start");
static constexpr auto round_end = hash_32_fnv1a_const("round_end");
static constexpr auto player_hurt = hash_32_fnv1a_const("player_hurt");
switch (hash_32_fnv1a_const(eventName)) {
case player_death:
@@ -179,6 +183,9 @@ bool __fastcall hook_FireEventServerSide(CGameEventManager* rcx,
case round_end:
events::OnRoundEndEvent(event);
break;
case player_hurt:
events::OnPlayerHurtEvent(event);
break;
// V<><56>bug,<2C><EFBFBD><E2B2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/*
case player_chat:

View File

@@ -152,6 +152,7 @@ class SchemaClassInfoData_t {
return m_schema_parent->m_class;
}
private:
char pad_0x0000[0x8]; // 0x0000
@@ -206,7 +207,6 @@ class CUtlVector_NativeSdk {
class CBaseEntity;
class CEntityIdentity {
public:
CBaseEntity* entity; // 0
@@ -332,6 +332,7 @@ class CBaseEntity : public CEntityInstance {
SCHEMA_FIELD(int, m_iTeamNum)
// SCHEMA_FIELD(Vector, m_vecBaseVelocity)
SCHEMA_FIELD(CCollisionProperty*, m_pCollision)
SCHEMA_FIELD(Vector, m_vecBaseVelocity)
auto IsBasePlayerController() -> bool;
auto SpawnClientEntity() -> void;
};
@@ -425,9 +426,8 @@ class CEconEntity {
PSCHEMA_FIELD(CAttributeContainer, m_AttributeManager);
};
class CCSWeaponBase : public CEconEntity
{
public:
class CCSWeaponBase : public CEconEntity {
public:
DECLARE_CLASS(CCSWeaponBase)
};
class CBasePlayerWeapon : public CEconEntity {
@@ -461,7 +461,24 @@ class CPlayer_MovementServices {
public:
DECLARE_CLASS(CPlayer_MovementServices);
};
class CGlowProperty {
public:
DECLARE_SCHEMA_CLASS_INLINE(CGlowProperty)
SCHEMA_FIELD(Vector, m_fGlowColor)
SCHEMA_FIELD(int, m_iGlowType)
SCHEMA_FIELD(int, m_nGlowRange)
SCHEMA_FIELD(Color, m_glowColorOverride)
SCHEMA_FIELD(bool, m_bFlashing)
SCHEMA_FIELD(bool, m_bGlowing)
};
class CBaseModelEntity {
public:
DECLARE_CLASS(CBaseModelEntity);
SCHEMA_FIELD(CCollisionProperty, m_Collision)
SCHEMA_FIELD(CGlowProperty, m_Glow)
};
class CBasePlayerPawn : public CBaseEntity {
public:
DECLARE_CLASS(CBasePlayerPawn);

View File

@@ -149,7 +149,7 @@ auto luaApi_GetPlayerHealth(lua_State* luaVm) -> int {
const auto playerIndex = lua_tointeger(luaVm, 1);
int playerHealth = 0;
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
auto playerPawn = playerController->m_hPawn().Get<CCSPlayerPawn>();
auto playerPawn = playerController->m_hPawn().Get<CCSPlayerPawnBase>();
playerHealth = playerPawn->m_iHealth();
});
lua_pop(luaVm, 1);
@@ -509,6 +509,31 @@ auto luaApi_MakePlayerWeaponDrop(lua_State* luaVm) -> int {
lua_pushboolean(luaVm, isSuccess);
return 1;
}
auto luaApi_MakePlayerCurrentWeaponDrop(lua_State* luaVm) -> int {
// param: playerIndex:int, itemClass:string
const auto playerIndex = lua_tointeger(luaVm, 1);
auto isSuccess = false;
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
do {
const auto weaponServices = playerController->m_hPawn()
.Get<CCSPlayerPawn>()
->m_pWeaponServices();
if (weaponServices == nullptr) {
break;
}
const auto activeWeapon =
weaponServices->m_hActiveWeapon().Get<CBasePlayerWeapon>();
if (activeWeapon == nullptr) {
return;
}
weaponServices->RemoveWeapon(activeWeapon);
isSuccess = true;
} while (false);
});
lua_pop(luaVm, 1);
lua_pushboolean(luaVm, isSuccess);
return 1;
}
auto luaApi_RemovePlayerWeapon(lua_State* luaVm) -> int {
// param: playerIndex:int, itemClass:string
const auto playerIndex = lua_tointeger(luaVm, 1);
@@ -577,6 +602,116 @@ auto luaApi_SentToAllPlayerChat(lua_State* luaVm) -> int {
lua_pop(luaVm, 2);
return 0;
}
auto luaApi_ChangePlayeriAccount(lua_State* luaVm) -> int {
// param: playerIndex:int, x:float, y:float, z:float
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto number = lua_tonumber(luaVm, 2);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
playerController->m_pInGameMoneyServices()->m_iAccount(number);
});
lua_pop(luaVm, 2);
return 0;
}
auto luaApi_GetPlayeriAccount(lua_State* luaVm) -> int {
// param: playerIndex:int, x:float, y:float, z:float
const auto playerIndex = lua_tointeger(luaVm, 1);
auto number = 0;
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
number = playerController->m_pInGameMoneyServices()->m_iAccount();
});
lua_pop(luaVm, 1);
lua_pushinteger(luaVm, number);
return 1;
}
auto luaApi_GetPlayerVecBaseVelocity(lua_State* luaVm) -> int {
// param: playerIndex:int, x:float, y:float, z:float
const auto playerIndex = lua_tointeger(luaVm, 1);
Vector number;
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
number = playerController->m_hPawn()
.Get<CCSPlayerPawnBase>()
->m_vecBaseVelocity();
});
lua_pop(luaVm, 1);
lua_pushnumber(luaVm, number.x);
lua_pushnumber(luaVm, number.y);
lua_pushnumber(luaVm, number.z);
return 3;
}
auto luaApi_ChangePlayerVecBaseVelocity(lua_State* luaVm) -> int {
// param: playerIndex:int, x:float, y:float, z:float
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto x = lua_tonumber(luaVm, 2);
const auto y = lua_tonumber(luaVm, 3);
const auto z = lua_tonumber(luaVm, 4);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
playerController->m_hPawn().Get<CCSPlayerPawnBase>()->m_vecBaseVelocity(
Vector(x, y, z));
});
lua_pop(luaVm, 4);
return 0;
}
auto luaApi_SetPlayerGlowColor(lua_State* luaVm) -> int {
// param: playerIndex:int, r:float, g:float, b:float, a:float
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto r = lua_tonumber(luaVm, 2);
const auto g = lua_tonumber(luaVm, 3);
const auto b = lua_tonumber(luaVm, 4);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
playerController->m_hPawn()
.Get<CBaseModelEntity>()
->m_Glow()
.m_fGlowColor(Vector(r, g, b));
playerController->m_hPawn()
.Get<CBaseModelEntity>()
->m_Glow()
.m_glowColorOverride(Color(r, g, b, 230));
});
lua_pop(luaVm, 4);
return 0;
}
auto luaApi_SetPlayerGlowEnable(lua_State* luaVm) -> int {
// param: playerIndex:int, isEnable:int
const auto playerIndex = lua_tointeger(luaVm, 1);
const auto isEnable = lua_toboolean(luaVm, 2);
ExcutePlayerAction(playerIndex, [&](CCSPlayerController* playerController) {
playerController->m_hPawn()
.Get<CBaseModelEntity>()
->m_Glow()
.m_bGlowing(isEnable);
playerController->m_hPawn()
.Get<CBaseModelEntity>()
->m_Glow()
.m_iGlowType(3);
});
lua_pop(luaVm, 2);
return 0;
}
auto luaApi_GetAllPlayerIndex(lua_State* luaVm) -> int {
// param: playerIndex:int, style:int
lua_newtable(luaVm);
CGameEntitySystem* EntitySystem = global::EntitySystem;
do {
if (EntitySystem == nullptr) {
break;
}
int index = 1; // Lua tables start at index 1
for (size_t i = 0; i < global::MaxPlayers; i++) {
auto player = EntitySystem->GetBaseEntity(i);
if (player == nullptr) {
break;
}
if (player->IsBasePlayerController() == false) {
break;
}
lua_pushinteger(luaVm, player->GetRefEHandle().GetEntryIndex());
lua_rawseti(luaVm, -2, index++);
}
} while (false);
return 1;
}
auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "ListenToGameEvent", luaApi_ListenToGameEvent);
lua_register(luaVm, "luaApi_SetPlayerCurrentWeaponAmmo",
@@ -602,9 +737,22 @@ auto initFunciton(lua_State* luaVm) -> void {
lua_register(luaVm, "luaApi_RemovePlayerWeapon", luaApi_RemovePlayerWeapon);
lua_register(luaVm, "luaApi_MakePlayerWeaponDrop",
luaApi_MakePlayerWeaponDrop);
lua_register(luaVm, "luaApi_MakePlayerCurrentWeaponDrop",
luaApi_MakePlayerCurrentWeaponDrop);
lua_register(luaVm, "luaApi_SendToPlayerChat", luaApi_SendToPlayerChat);
lua_register(luaVm, "luaApi_SentToAllPlayerChat",
luaApi_SentToAllPlayerChat);
lua_register(luaVm, "luaApi_ChangePlayerVecBaseVelocity",
luaApi_ChangePlayerVecBaseVelocity);
lua_register(luaVm, "luaApi_GetPlayerVecBaseVelocity",
luaApi_GetPlayerVecBaseVelocity);
lua_register(luaVm, "luaApi_ChangePlayeriAccount",
luaApi_ChangePlayeriAccount);
lua_register(luaVm, "luaApi_GetPlayeriAccount", luaApi_GetPlayeriAccount);
lua_register(luaVm, "luaApi_SetPlayerGlowEnable",
luaApi_SetPlayerGlowEnable);
lua_register(luaVm, "luaApi_SetPlayerGlowColor", luaApi_SetPlayerGlowColor);
lua_register(luaVm, "luaApi_GetAllPlayerIndex", luaApi_GetAllPlayerIndex);
luabridge::getGlobalNamespace(luaVm)
.beginClass<_luaApi_WeaponInfo>("WeaponInfo")

View File

@@ -13,7 +13,7 @@ std::unordered_map<uint32_t, _CallbackNames> callbackNameWithEnumMap{
{hash_32_fnv1a_const("player_spawn"), _CallbackNames::kOnPlayerSpawn},
{hash_32_fnv1a_const("round_start"), _CallbackNames::kOnRoundStart},
{hash_32_fnv1a_const("round_end"), _CallbackNames::kOnRoundEnd},
{hash_32_fnv1a_const("player_hurt"), _CallbackNames::kOnPlayerHurt},
};
auto CallBackNameToEnum(const char* name) -> _CallbackNames {
if (name == nullptr) {
@@ -181,4 +181,28 @@ auto luaCall_onRoundEnd(int winnerTeam, int reason, const char* message)
}
});
}
auto luaCall_onPlayerHurt(int userid, int attacker, int health, int armor,
const char* weapon, int dmg_health, int dmg_armor,
int hitgroup) -> void {
ExcuteCallbackInAllLuaVm(_CallbackNames::kOnPlayerHurt,
[&](lua_State* luaVm, int refIndex) -> void {
lua_rawgeti(luaVm, LUA_REGISTRYINDEX,
refIndex);
if (lua_isfunction(luaVm, -1)) {
lua_pushinteger(luaVm, userid);
lua_pushinteger(luaVm, attacker);
lua_pushinteger(luaVm, health);
lua_pushinteger(luaVm, armor);
lua_pushstring(luaVm, weapon);
lua_pushinteger(luaVm, dmg_health);
lua_pushinteger(luaVm, dmg_armor);
lua_pushinteger(luaVm, hitgroup);
if (lua_pcall(luaVm, 8, 0, 0) != LUA_OK) {
LOG("Error calling Lua callback: %s\n",
lua_tostring(luaVm, -1));
lua_pop(luaVm, 1);
}
}
});
}
} // namespace ScriptCallBacks

View File

@@ -10,7 +10,8 @@ enum class _CallbackNames {
kOnPlayerSpeak,
kOnPlayerSpawn,
kOnRoundStart,
kOnRoundEnd
kOnRoundEnd,
kOnPlayerHurt
};
extern std::unordered_map<lua_State*, std::unordered_map<_CallbackNames, int>>
callbackList;
@@ -29,4 +30,7 @@ auto luaCall_onPlayerSpawn(int player) -> void;
auto luaCall_onRoundStart(int timeLimit) -> void;
auto luaCall_onRoundEnd(int winnerTeam, int reason, const char* message)
-> void;
auto luaCall_onPlayerHurt(int userid, int attacker, int health, int armor,
const char* weapon, int dmg_health, int dmg_armor,
int hitgroup) -> void;
} // namespace ScriptCallBacks

View File

@@ -47,7 +47,7 @@ auto initLuaScripts() -> void {
ScriptApis::initFunciton(L);
pluginEnvs[dirName] = L;
if (dirPath.starts_with("disable_")) {
if (dirPath.find("disable_") != std::string::npos) {
continue;
}
std::string file = dirPath + "\\main.lua";