完成复活

This commit is contained in:
Huoji's
2023-10-04 22:49:16 +08:00
parent 06acf8b24d
commit dd0456b064
9 changed files with 162 additions and 43 deletions

View File

@@ -386,9 +386,6 @@
<ClCompile Include="script_engine.cpp">
<Filter>源文件\script_engine</Filter>
</ClCompile>
<ClCompile Include="tools.cpp">
<Filter>头文件</Filter>
</ClCompile>
<ClCompile Include="interface.cpp">
<Filter>源文件\native_sdk</Filter>
</ClCompile>
@@ -503,6 +500,9 @@
<ClCompile Include="timer.cpp">
<Filter>源文件\game_time_system</Filter>
</ClCompile>
<ClCompile Include="tools.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />

View File

@@ -16,19 +16,25 @@ auto WatchExitThread(void *ctx) -> void {
unload();
}
auto init(void* ctx) -> bool {
AllocConsole();
SetConsoleTitleA("huoji debug console");
freopen_s(reinterpret_cast<FILE**> stdout, "CONOUT$", "w", stdout);
CreateThread(NULL, 0,
reinterpret_cast<LPTHREAD_START_ROUTINE>(WatchExitThread),
NULL, 0, NULL);
uint64_t serverHandle{};
uint64_t localizeHandle{};
while (Offset::Module_tier0 == 0)
while (Offset::Module_tier0 == 0 || serverHandle == 0 || localizeHandle == 0)
{
if (global::Exit) {
return false;
}
Offset::Module_tier0 = reinterpret_cast<uint64_t>(GetModuleHandleA("tier0"));
serverHandle = reinterpret_cast<uint64_t>(GetModuleHandleA("server.dll"));
localizeHandle = reinterpret_cast<uint64_t>(GetModuleHandleA("localize.dll"));
Sleep(200);
}
if (Offset::Init() == false) {
@@ -40,6 +46,10 @@ auto init(void* ctx) -> bool {
isSuccess = hooks::init();
if (isSuccess) {
LOG("plugin install success !\n");
while (Offset::InitOffsetSuccess == false)
{
Sleep(200);
}
ScriptEngine::Init();
}
return isSuccess;

View File

@@ -36,6 +36,7 @@ void __fastcall hook_GameFrame(void* rcx, bool simulating, bool bFirstTick,
}
GameTimer::ExcuteTimers();
GameTickRunTime::ExcuteTickFunctions();
return origin_GameFrame(rcx, simulating, bFirstTick, bLastTick);
}
void __fastcall hook_StartServer(void* rcx,

View File

@@ -459,6 +459,9 @@ class CCSPlayerPawn : public CCSPlayerPawnBase {
DECLARE_CLASS(CCSPlayerPawn);
SCHEMA_FIELD(const char*, m_szLastPlaceName)
auto GetPlayerController() -> CCSPlayerController*;
auto ForceRespawnPlayer() {
return CALL_VIRTUAL(void, 324, this);
}
};
class CGameEntitySystem;
@@ -491,4 +494,7 @@ class CCSGameRules {
public:
DECLARE_CLASS(CCSGameRules)
SCHEMA_FIELD(bool, m_bForceTeamChangeSilent)
auto PlayerRespawn(CCSPlayerPawn* PlayerPawn) {
return CALL_VIRTUAL(void, 110, this, PlayerPawn);
}
};

View File

@@ -11,8 +11,10 @@ uint64_t MaxPlayerNumsPtr;
HashFunction_t FnServerHashFunction;
StateChanged_t FnStateChanged;
NetworkStateChanged_t FnNetworkStateChanged;
//CreateGameRuleInterFace_t FnCreateCCSGameRulesInterFace;
RespawnPlayer_t FnRespawnPlayer;
//CreateGameRuleInterFace_t FnCreateCCSGameRulesInterFace;
bool InitOffsetSuccess = false;
namespace InterFaces {
CSchemaSystem* SchemaSystem;
IGameEventManager2* GameEventManager;
@@ -25,7 +27,24 @@ CLocalize* ILocalize;
INetworkServerService* INetworkServerServiceInteFace;
CCSGameRules* CCSGameRulesInterFace;
}; // namespace InterFaces
auto SafeDelayInit(void* ctx) -> void {
// <20><>Ҫ<EFBFBD><D2AA>Ϸ<EFBFBD><CFB7><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
InterFaces::CCSGameRulesInterFace =
reinterpret_cast<CCSGameRules*>(Memory::read<CCSGameRules*>(CCSGameRulesInterFacePtr));
while (InterFaces::CCSGameRulesInterFace == 0)
{
InterFaces::CCSGameRulesInterFace =
reinterpret_cast<CCSGameRules*>(Memory::read<CCSGameRules*>(CCSGameRulesInterFacePtr));
Sleep(100);
}
InitOffsetSuccess = true;
LOG("[huoji]InterFaces::CCSGameRulesInterFace : %llx \n", InterFaces::CCSGameRulesInterFace);
LOG("[huoji]InterFaces::CCSGameRulesInterFace->respawnPlayer : %llx \n", ((void**)InterFaces::CCSGameRulesInterFace)[110]);
LOG("m_bForceTeamChangeSilent: %d \n", InterFaces::CCSGameRulesInterFace->m_bForceTeamChangeSilent());
}
auto Init() -> bool {
CModule server("server.dll");
CModule schemasystem("schemasystem.dll");
@@ -46,8 +65,10 @@ auto Init() -> bool {
.ToAbsolute(3, 0)
.Get(CGameEventManagerPtr);
server.FindPattern(pattern_CreateCCSGameRulesInterFacePtr)
.ToAbsolute(10, 0)
.ToAbsolute(3, 0)
.Get(CCSGameRulesInterFacePtr);
server.FindPattern(pattern_FnRespawnPlayer)
.Get(FnRespawnPlayer);
server.FindPattern(pattern_fnHost_SayPtr).Get(Host_SayPtr);
server.FindPattern(pattern_ServerHashFunctionPtr).Get(FnServerHashFunction);
@@ -78,8 +99,7 @@ auto Init() -> bool {
}
InterFaces::CGameEventManger =
reinterpret_cast<CGameEventManager*>(CGameEventManagerPtr);
InterFaces::CCSGameRulesInterFace =
reinterpret_cast<CCSGameRules*>(CCSGameRulesInterFacePtr + (8 * 2));
// global::MaxPlayers = *(int*)((char*)MaxPlayerNumsPtr + 2);
// client.FindPattern(pattern_FireEventServerSide).Get(FireEventServerSidePtr);
global::MaxPlayers = 64;
@@ -104,12 +124,11 @@ auto Init() -> bool {
InterFaces::IVEngineServer);
LOG("[huoji]InterFaces::ISource2ServerInterFace : %llx \n",
InterFaces::ISource2ServerInterFace);
LOG("[huoji]InterFaces::CCSGameRulesInterFace : %llx \n", InterFaces::CCSGameRulesInterFace);
//LOG("m_bForceTeamChangeSilent: %d \n", InterFaces::CCSGameRulesInterFace->m_bForceTeamChangeSilent());
LOG("init offset success !\n");
CreateThread(NULL, 0,
reinterpret_cast<LPTHREAD_START_ROUTINE>(SafeDelayInit),
NULL, 0, NULL);
// LOG("FnServerHashFunction: %llx \n", FnServerHashFunction("here",
// sizeof("here") - 1, 0x31415926));
return FnServerHashFunction && Host_SayPtr && InterFaces::IVEngineServer &&

View File

@@ -2,6 +2,7 @@
#include "head.h"
#define SERVER_HASH_FUCNTION_KEY 0x31415926
class CEntityInstance;
class CCSPlayerPawn;
typedef uint64_t(__fastcall* HashFunction_t)(const char*, unsigned int,
unsigned int);
typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent,
@@ -10,6 +11,8 @@ typedef void(__fastcall* StateChanged_t)(void* networkTransmitComponent,
typedef void(__fastcall* NetworkStateChanged_t)(uintptr_t chainEntity,
uintptr_t offset, uintptr_t a3);
typedef void*(__fastcall* CreateGameRuleInterFace_t)();
typedef bool(__fastcall* RespawnPlayer_t)(CCSPlayerPawn* player);
class CSchemaSystem;
class CGameResourceService;
class CLocalize;
@@ -55,9 +58,8 @@ static const auto pattern_ServerHashFunctionPtr = THE_GAME_SIG(
static const auto pattern_MaxPlayerNumsPtr =
THE_GAME_SIG("41 3B 87 ?? ?? ?? ?? 0F 8E ?? ?? ?? ?? 8B 0D ?? ?? ?? ??");
static const auto pattern_CreateCCSGameRulesInterFacePtr = THE_GAME_SIG(
"40 53 48 ?? ?? ?? B9 ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 D2 41 ?? ?? ?? ?? ?? "
"48 8B C8 48 8B D8 E8 ?? ?? ?? ?? 48 85 DB");
"48 ?? ?? ?? ?? ?? ?? 48 8B 01 FF ?? ?? ?? ?? ?? 48 8D ?? ?? ?? E8 ?? ?? ?? ?? 4C 8D ?? ?? ?? 49 8B ?? ?? 49 8B ?? ?? 49 8B ?? ?? 49 8B E3 41 5F 41 5E 5F C3");
static const auto pattern_FnRespawnPlayer = THE_GAME_SIG("48 89 ?? ?? ?? 57 48 ?? ?? ?? 48 8D ?? ?? ?? 48 8B F9 E8 ?? ?? ?? ?? 83 ?? ?? 74 ?? 48 ?? ?? ?? ?? ?? ?? 48 8B CF 48 8B 10 48 8B ?? ?? ?? ?? ?? 48 8D ?? ?? ?? E8 ?? ?? ?? ?? 48 ?? ?? ?? ?? ?? ??");
extern uint64_t GameResourceServicePtr;
extern uint64_t FireEventServerSidePtr;
extern uint64_t Module_tier0;
@@ -66,6 +68,7 @@ extern uint64_t MaxPlayerNumsPtr;
extern HashFunction_t FnServerHashFunction;
extern StateChanged_t FnStateChanged;
extern NetworkStateChanged_t FnNetworkStateChanged;
extern RespawnPlayer_t FnRespawnPlayer;
extern bool InitOffsetSuccess;
auto Init() -> bool;
}; // namespace Offset

View File

@@ -12,8 +12,18 @@ struct _luaApi_WeaponInfo {
int weaponType;
};
namespace ScriptApis {
auto RunTickCallBack(_GameTickRunTime* timer) -> void {
LOG("excute tick function: %d %d \n", timer->m_iLuaCallBackFn,
timer->m_iParamIndex);
lua_rawgeti(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iLuaCallBackFn);
lua_rawgeti(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iParamIndex);
lua_pcall(timer->m_luaVm, 1, 0, 0);
luaL_unref(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iLuaCallBackFn);
luaL_unref(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iParamIndex);
}
auto TimerCallBack(_GameTimer* timer) -> void {
LOG("excute timer: %d %d m_bRepeat: %d\n", timer->m_iLuaCallBackFn, timer->m_iParamIndex, timer->m_bRepeat);
LOG("excute timer: %d %d m_bRepeat: %d\n", timer->m_iLuaCallBackFn,
timer->m_iParamIndex, timer->m_bRepeat);
lua_rawgeti(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iLuaCallBackFn);
lua_rawgeti(timer->m_luaVm, LUA_REGISTRYINDEX, timer->m_iParamIndex);
lua_pcall(timer->m_luaVm, 1, 0, 0);
@@ -109,8 +119,9 @@ auto luaApi_RespawnPlayer(lua_State* luaVm) -> int {
}
auto playerController = reinterpret_cast<CCSPlayerController*>(player);
auto playerPawn = playerController->m_hPawn().Get<CCSPlayerPawn>();
playerPawn->m_bRespawning(false);
LOG("respawn player: %llx \n", playerPawn);
Offset::FnRespawnPlayer(playerPawn);
//playerPawn->ForceRespawnPlayer();
} while (false);
lua_pop(luaVm, 1);
return 0;
@@ -269,26 +280,57 @@ auto luaApi_GetPlayerCurrentWeaponInfo(lua_State* luaVm) -> _luaApi_WeaponInfo {
} while (false);
return info;
}
auto luaApi_CreateTickRunFunction(lua_State* luaVm) -> int {
// params:lua_table, callback:function
if (!lua_istable(luaVm, 1)) {
luaL_error(luaVm, "Parameter 'params' must be a table");
return 0;
}
lua_pushvalue(luaVm, 1); // Duplicate the table for luaL_ref
const auto params = luaL_ref(luaVm, LUA_REGISTRYINDEX);
if (!lua_isfunction(luaVm, 2)) {
luaL_error(luaVm, "Parameter 'callback' must be a function");
return 0;
}
lua_pushvalue(luaVm, 2); // Duplicate the function for luaL_ref
const auto callback = luaL_ref(luaVm, LUA_REGISTRYINDEX);
GameTickRunTime::AddTickFunction(new _GameTickRunTime{
.m_luaVm = luaVm,
.m_iParamIndex = params,
.m_iLuaCallBackFn = callback,
});
return 0;
}
auto luaApi_CreateTimer(lua_State* luaVm) -> int {
// param: time:float, callback:function, params:lua_table
const auto time = lua_tonumber(luaVm, 1);
// param: time:float,repeat:bool,preservermapchange:bool,params:lua_table,
// callback:function
const auto time = luaL_checknumber(luaVm, 1);
const auto repeat = lua_toboolean(luaVm, 2);
const auto preserveMapChange = lua_toboolean(luaVm, 3);
auto timerHandle = 0;
do {
const auto params = lua_gettable(luaVm, 4);
const auto callback = luaL_ref(luaVm, LUA_REGISTRYINDEX);
LOG("luaApi_CreateTimer: params: %d callback: %d \n", params, callback);
timerHandle = GameTimer::AddTimer(new _GameTimer{
.m_flTime = (float)time,
.m_bRepeat = (bool)repeat,
.m_bPreserveMapChange = (bool)preserveMapChange,
.m_luaVm = luaVm,
.m_iParamIndex = params,
.m_iLuaCallBackFn = callback
});
} while (false);
lua_pop(luaVm, 5);
if (!lua_istable(luaVm, 4)) {
luaL_error(luaVm, "Parameter 'params' must be a table");
return 0;
}
lua_pushvalue(luaVm, 4); // Duplicate the table for luaL_ref
const auto params = luaL_ref(luaVm, LUA_REGISTRYINDEX);
if (!lua_isfunction(luaVm, 5)) {
luaL_error(luaVm, "Parameter 'callback' must be a function");
return 0;
}
lua_pushvalue(luaVm, 5); // Duplicate the function for luaL_ref
const auto callback = luaL_ref(luaVm, LUA_REGISTRYINDEX);
auto timerHandle = GameTimer::AddTimer(
new _GameTimer{.m_flTime = (float)time,
.m_bRepeat = (bool)repeat,
.m_bPreserveMapChange = (bool)preserveMapChange,
.m_luaVm = luaVm,
.m_iParamIndex = params,
.m_iLuaCallBackFn = callback});
lua_pushinteger(luaVm, timerHandle);
return 1;
}
@@ -359,7 +401,7 @@ auto luaApi_SetPlayerTeam(lua_State* luaVm) -> int {
break;
}
auto playerController = reinterpret_cast<CCSPlayerController*>(player);
playerController->m_iTeamNum() = team;
playerController->m_iTeamNum(team);
isSuccess = true;
} while (false);
lua_pop(luaVm, 2);
@@ -401,6 +443,8 @@ auto initFunciton(lua_State* luaVm) -> void {
luaApi_SetPlayerArmorValue);
lua_register(luaVm, "luaApi_RespawnPlayer", luaApi_RespawnPlayer);
lua_register(luaVm, "luaApi_CreateTimer", luaApi_CreateTimer);
lua_register(luaVm, "luaApi_CreateTickRunFunction",
luaApi_CreateTickRunFunction);
lua_register(luaVm, "luaApi_CheckPlayerIsAlive", luaApi_CheckPlayerIsAlive);
lua_register(luaVm, "luaApi_GetPlayerTeam", luaApi_GetPlayerTeam);
lua_register(luaVm, "luaApi_SetPlayerTeam", luaApi_SetPlayerTeam);

View File

@@ -1,7 +1,8 @@
#include "timer.h"
namespace ScriptApis {
extern auto TimerCallBack(_GameTimer* timer) -> void;
};
extern auto TimerCallBack(_GameTimer* timer) -> void;
extern auto RunTickCallBack(_GameTickRunTime* timer) -> void;
}; // namespace ScriptApis
namespace GameTimer {
std::shared_mutex mutex_timerList;
std::vector<_GameTimer*> timerList;
@@ -27,7 +28,8 @@ auto ExcuteTimers() -> void {
if ((*it)->m_flLastExecute == -1) {
(*it)->m_flLastExecute = global::m_flUniversalTime;
}
if ((*it)->m_flLastExecute + (*it)->m_flTime <= global::m_flUniversalTime) {
if ((*it)->m_flLastExecute + (*it)->m_flTime <=
global::m_flUniversalTime) {
ScriptApis::TimerCallBack(*it);
if ((*it)->m_bRepeat) {
(*it)->m_flLastExecute = global::m_flUniversalTime;
@@ -41,3 +43,26 @@ auto ExcuteTimers() -> void {
}
}
}; // namespace GameTimer
namespace GameTickRunTime {
std::shared_mutex mutex_tickRunList;
std::vector<_GameTickRunTime*> tickRunList;
auto AddTickFunction(_GameTickRunTime* timer) -> void {
std::unique_lock<std::shared_mutex> lock(mutex_tickRunList);
tickRunList.push_back(timer);
};
auto CleanUpTickFunctions() -> void {
std::unique_lock<std::shared_mutex> lock(mutex_tickRunList);
for (auto it = tickRunList.begin(); it != tickRunList.end();) {
delete (*it);
it = tickRunList.erase(it);
}
};
auto ExcuteTickFunctions() -> void {
std::shared_lock<std::shared_mutex> lock(mutex_tickRunList);
for (auto it = tickRunList.begin(); it != tickRunList.end();) {
ScriptApis::RunTickCallBack(*it);
delete (*it);
it = tickRunList.erase(it);
}
}
}; // namespace GameTickRunTime

View File

@@ -1,18 +1,29 @@
#pragma once
#include "head.h"
class _GameTimer {
public:
public:
float m_flTime;
float m_flLastExecute = -1;
bool m_bRepeat;
bool m_bPreserveMapChange;
lua_State* m_luaVm;
lua_State* m_luaVm;
int m_iParamIndex;
int m_iLuaCallBackFn;
};
class _GameTickRunTime {
public:
lua_State* m_luaVm;
int m_iParamIndex;
int m_iLuaCallBackFn;
};
namespace GameTimer {
auto AddTimer(_GameTimer* timer) -> int;
auto CleanUpTimers() -> void;
auto ExcuteTimers() -> void;
}; // namespace GameTimer
namespace GameTickRunTime {
auto AddTickFunction(_GameTickRunTime* timer) -> void;
auto CleanUpTickFunctions() -> void;
auto ExcuteTickFunctions() -> void;
}; // namespace GameTickRunTime