完成复活
This commit is contained in:
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user