156 lines
5.4 KiB
SourcePawn
156 lines
5.4 KiB
SourcePawn
#pragma semicolon 1
|
|
#pragma newdecls required
|
|
|
|
#include <sourcemod>
|
|
#include <sdktools>
|
|
#include <dhooks>
|
|
|
|
#define NAV_CANT_ACCESS_FILE 0
|
|
|
|
Handle hLoad;
|
|
Handle hBeginGeneration;
|
|
|
|
bool g_bEnabledAutoNavGenerate = false;
|
|
|
|
public Plugin myinfo = {
|
|
name = "Nav Generate Blocker",
|
|
author = "SHUFEN from POSSESSION.tokyo",
|
|
description = "",
|
|
version = "0.1",
|
|
url = "https://possession.tokyo"
|
|
};
|
|
|
|
public void OnPluginStart() {
|
|
Handle hGameData = LoadGameConfigFile("NavGenerateBlocker.games");
|
|
if (hGameData == null) {
|
|
SetFailState("Couldn't find NavGenerateBlocker.games gamedata.");
|
|
}
|
|
|
|
hLoad = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Int, ThisPointer_Address);
|
|
if (!hLoad) {
|
|
delete hGameData;
|
|
SetFailState("Failed to setup detour for CNavMesh::Load.");
|
|
}
|
|
if (!DHookSetFromConf(hLoad, hGameData, SDKConf_Signature, "CNavMesh::Load")) {
|
|
delete hGameData;
|
|
SetFailState("Failed to load CNavMesh::Load signature from gamedata.");
|
|
}
|
|
if (!DHookEnableDetour(hLoad, false, Detour_OnLoad)) {
|
|
delete hGameData;
|
|
SetFailState("Failed to detour CNavMesh::Load.");
|
|
}
|
|
|
|
hBeginGeneration = DHookCreateDetour(Address_Null, CallConv_THISCALL, ReturnType_Void, ThisPointer_Address);
|
|
if (!hBeginGeneration) {
|
|
delete hGameData;
|
|
SetFailState("Failed to setup detour for CNavMesh::BeginGeneration.");
|
|
}
|
|
if (!DHookSetFromConf(hBeginGeneration, hGameData, SDKConf_Signature, "CNavMesh::BeginGeneration")) {
|
|
delete hGameData;
|
|
SetFailState("Failed to load CNavMesh::BeginGeneration signature from gamedata.");
|
|
}
|
|
DHookAddParam(hBeginGeneration, HookParamType_Bool);
|
|
if (!DHookEnableDetour(hBeginGeneration, false, Detour_OnBeginGeneration)) {
|
|
delete hGameData;
|
|
SetFailState("Failed to detour CNavMesh::BeginGeneration.");
|
|
}
|
|
delete hGameData;
|
|
|
|
RegAdminCmd("sm_navgenerate", Command_NavGenerate, ADMFLAG_ROOT, "Generate a blank .nav file for current map");
|
|
RegAdminCmd("sm_navgeneratenextmap", Command_NavGenerateNextMap, ADMFLAG_ROOT, "Generate a blank .nav file for next map");
|
|
|
|
ConVar hConVar;
|
|
|
|
(hConVar = CreateConVar("sm_navgenerate_autogenerate", "1", "Enable/Disable auto generate a blank .nav file for next map", _, true, 0.0, true, 1.0)).AddChangeHook(OnAutoGenerateChanged);
|
|
g_bEnabledAutoNavGenerate = hConVar.BoolValue;
|
|
|
|
delete hConVar;
|
|
}
|
|
|
|
public void OnAutoGenerateChanged(ConVar cvar, const char[] oldVal, const char[] newVal) {
|
|
g_bEnabledAutoNavGenerate = cvar.BoolValue;
|
|
}
|
|
|
|
public void OnMapEnd() {
|
|
if (g_bEnabledAutoNavGenerate) {
|
|
char szNextMap[PLATFORM_MAX_PATH];
|
|
if (GetNextMap(szNextMap, sizeof(szNextMap))) {
|
|
GenerateBlankNavFile(szNextMap);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Action OnLogAction(Handle source, Identity ident, int client, int target, const char[] message) {
|
|
if (g_bEnabledAutoNavGenerate) {
|
|
if (StrContains(message, "changed map to") != -1) {
|
|
char buffer[PLATFORM_MAX_PATH];
|
|
strcopy(buffer, sizeof(buffer), message);
|
|
buffer[FindCharInString(buffer, '\"', true)] = '\0';
|
|
GenerateBlankNavFile(buffer[FindCharInString(buffer, '\"', true) + 1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public MRESReturn Detour_OnLoad(Address pThis, Handle hReturn, Handle hParams) {
|
|
char szMapName[PLATFORM_MAX_PATH], szNavFilePath[PLATFORM_MAX_PATH];
|
|
GetCurrentMap(szMapName, sizeof(szMapName));
|
|
FormatEx(szNavFilePath, sizeof(szNavFilePath), "maps/%s.nav", szMapName);
|
|
if (FileExists(szNavFilePath, false))
|
|
return MRES_Ignored;
|
|
|
|
LogMessage("NavGenerateBlocker -> Superseded \"CNavMesh::Load\" Function: return NAV_CANT_ACCESS_FILE;");
|
|
DHookSetReturn(hReturn, NAV_CANT_ACCESS_FILE);
|
|
return MRES_Supercede;
|
|
}
|
|
|
|
public MRESReturn Detour_OnBeginGeneration(Address pThis, Handle hReturn, Handle hParams) {
|
|
LogMessage("NavGenerateBlocker -> Skipped \"CNavMesh::BeginGeneration\" Function");
|
|
return MRES_Supercede;
|
|
}
|
|
|
|
public Action Command_NavGenerate(int client, int args) {
|
|
char szMapName[PLATFORM_MAX_PATH];
|
|
GetCurrentMap(szMapName, sizeof(szMapName));
|
|
|
|
GenerateBlankNavFile(szMapName);
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public Action Command_NavGenerateNextMap(int client, int args) {
|
|
char szNextMap[PLATFORM_MAX_PATH];
|
|
if (GetNextMap(szNextMap, sizeof(szNextMap))) {
|
|
GenerateBlankNavFile(szNextMap);
|
|
}
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
int NAV_BLANKFILE_DATA[] = {206, 250, 237, 254, 16, 0, 0, 0, 1, 0, 0, 0, 14, 238, 118, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 168, 119, 198, 0, 160, 240, 68, 0, 254, 63, 196, 0, 204, 113, 198, 0, 0, 22, 69, 0, 254, 63, 196, 0, 254, 63, 196, 0, 254, 63, 196,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 118, 119, 198, 0, 48, 242, 68, 0, 254, 63,
|
|
196, 8, 1, 0, 0, 0, 0, 254, 113, 198, 0, 48, 242, 68, 0, 254, 63, 196, 8, 2, 0, 0, 0, 0, 254, 113, 198, 0, 56, 21, 69, 0,
|
|
254, 63, 196, 8, 3, 0, 0, 0, 0, 118, 119, 198, 0, 56, 21, 69, 0, 254, 63, 196, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 139, 187, 111, 61, 212, 233, 139, 62, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
bool GenerateBlankNavFile(const char[] map) {
|
|
char szNavFilePath[PLATFORM_MAX_PATH];
|
|
FormatEx(szNavFilePath, sizeof(szNavFilePath), "maps/%s.nav", map);
|
|
|
|
if (FileExists(szNavFilePath, false)) {
|
|
LogMessage("File \"%s\" has already exist.", szNavFilePath);
|
|
return false;
|
|
}
|
|
|
|
File hFile = OpenFile(szNavFilePath, "wb");
|
|
if (hFile == null) {
|
|
LogMessage("Couldn't create file \"%s\" for writing.", szNavFilePath);
|
|
return false;
|
|
}
|
|
|
|
for (int x = 0; x < sizeof(NAV_BLANKFILE_DATA); x++)
|
|
hFile.WriteInt8(NAV_BLANKFILE_DATA[x]);
|
|
|
|
hFile.Close();
|
|
return true;
|
|
}
|