Skip to content

Commit

Permalink
blacklist fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ThirteenAG committed Jul 14, 2024
1 parent 3389b14 commit 2afd7de
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 26 deletions.
15 changes: 8 additions & 7 deletions .github/docs/scb.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,20 @@ NewConfig\

```
[EXTRACTION]
ExtractionWaveConfigs = NewConfig // Default | Random
ExtractionWaveEnemyMultiplier = 2 // Multiplies the number of enemies in each wave, with Random config, acts as a range [1;ExtractionWaveEnemyMultiplier]
ExtractionWaveConfigs = NewConfig
```

# Hunter Mode
Demo: https://youtu.be/su47XbCcVyw

Plugin adds an ability to modify the number of reinforcements for the Hunter game mode with `ReinforcementsEnemyMultiplier` option.
# Hunter Mode and Coop

New config for the Hunter game mode: Random, which randomizes the total number of reinforcements between minimum and maximum values defined in the INI file.
Plugin adds an ability to modify the number of reinforcements for the Hunter game mode and coop campaign with `ReinforcementsEnemyMultiplier` option.

# Ghost Mode
New config for the Hunter game mode and coop campaign: Random, which randomizes the total number of reinforcements between minimum and maximum values defined in the INI file.

Plugin adds an ability to disable mission failure on detection in Ghost mode.
# Ghost Mode and Campaign

Plugin adds an ability to disable mission failure on detection in Ghost mode and Campaign (SP and COOP).

# Ultrawide Screenshot

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,17 @@ ReinforcementsEnemyRandomRangeMin = 1 // With the Random config, specifies
ReinforcementsEnemyRandomRangeMax = 100 // reinforcements between Min and Max

[GHOST] // Grim Missions
DisableMissionFailOnDetection = 1 // If set to 1, the mission will not fail when the player is detected
DisableMissionFailOnDetection = 1 // If set to 1, the mission will not fail when the player is detected (where applicable)

[COOP] // Briggs Missions
ReinforcementsNumber = Default // Default | Random
ReinforcementsEnemyMultiplier = 1 // Multiplies the number of reinforcements with the Default config
ReinforcementsEnemyRandomRangeMin = 1 // With the Random config, specifies the total number of
ReinforcementsEnemyRandomRangeMax = 10 // reinforcements between Min and Max. Setting this value too high can make the final mission impossible to complete
DisableMissionFailOnDetection = 0 // If set to 1, the mission will not fail when the player is detected

[CAMPAIGN] // Story Missions
DisableMissionFailOnDetection = 0 // If set to 1, the mission will not fail when the player is detected (where applicable)

[LOGITECH]
LightSyncRGB = 1 // Mouse and keyboard will have selected suit indicators color. Only Logitech hardware is supported, requires Logitech G HUB app
Expand Down
97 changes: 79 additions & 18 deletions source/SplinterCellBlacklist.FusionMod/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
return TRUE;
}

enum eGameMode
{
CAMPAIGN,
PALADIN,
HUNTER,
GHOST,
EXTRACTION,
COOP,
};

int CurrentGameMode = -1;
SafetyHookInline shLead_SetCurrentGameMode{};
void __cdecl Lead_SetCurrentGameMode(int gameMode, int a2)
{
CurrentGameMode = gameMode;
return shLead_SetCurrentGameMode.ccall(gameMode, a2);
}

std::string sExtractionWaveConfigs = "Default";
int nExtractionWaveEnemyMultiplier = 1;
int nExtractionWaveEnemyRandomRangeMin = 0;
Expand Down Expand Up @@ -211,12 +229,10 @@ void Init()
nExtractionWaveEnemyRandomRangeMin = std::clamp(iniReader.ReadInteger("EXTRACTION", "ExtractionWaveEnemyRandomRangeMin", 0), 0, 9999);
nExtractionWaveEnemyRandomRangeMax = std::clamp(iniReader.ReadInteger("EXTRACTION", "ExtractionWaveEnemyRandomRangeMax", 4), 1, 9999);

static auto sReinforcementsNumber = iniReader.ReadString("HUNTER", "ReinforcementsNumber", "Default");
static auto nReinforcementsEnemyMultiplier = std::clamp(iniReader.ReadInteger("HUNTER", "ReinforcementsEnemyMultiplier", 1), 1, 9999);
static auto nReinforcementsEnemyRandomRangeMin = std::clamp(iniReader.ReadInteger("HUNTER", "ReinforcementsEnemyRandomRangeMin", 1), 1, 9999);
static auto nReinforcementsEnemyRandomRangeMax = std::clamp(iniReader.ReadInteger("HUNTER", "ReinforcementsEnemyRandomRangeMax", 1), 1, 9999);

auto bDisableMissionFailOnDetection = iniReader.ReadInteger("GHOST", "DisableMissionFailOnDetection", 1) != 0;
static auto sHUNTERReinforcementsNumber = iniReader.ReadString("HUNTER", "ReinforcementsNumber", "Default");
static auto nHUNTERReinforcementsEnemyMultiplier = std::clamp(iniReader.ReadInteger("HUNTER", "ReinforcementsEnemyMultiplier", 1), 1, 9999);
static auto nHUNTERReinforcementsEnemyRandomRangeMin = std::clamp(iniReader.ReadInteger("HUNTER", "ReinforcementsEnemyRandomRangeMin", 1), 1, 9999);
static auto nHUNTERReinforcementsEnemyRandomRangeMax = std::clamp(iniReader.ReadInteger("HUNTER", "ReinforcementsEnemyRandomRangeMax", 1), 1, 9999);

auto bUnlockDLC = iniReader.ReadInteger("UNLOCKS", "UnlockDLC", 1) != 0;
static auto bUnlockAllNonCampaignMissions = iniReader.ReadInteger("UNLOCKS", "UnlockAllNonCampaignMissions", 1) != 0;
Expand All @@ -226,6 +242,16 @@ void Init()

auto sDedicatedServerExePath = iniReader.ReadString("STARTUP", "DedicatedServerExePath", "");

static auto bGHOSTDisableMissionFailOnDetection = iniReader.ReadInteger("GHOST", "DisableMissionFailOnDetection", 1) != 0;

static auto bCOOPDisableMissionFailOnDetection = iniReader.ReadInteger("COOP", "DisableMissionFailOnDetection", 0) != 0;
static auto sCOOPReinforcementsNumber = iniReader.ReadString("COOP", "ReinforcementsNumber", "Default");
static auto nCOOPReinforcementsEnemyMultiplier = std::clamp(iniReader.ReadInteger("COOP", "ReinforcementsEnemyMultiplier", 1), 1, 9999);
static auto nCOOPReinforcementsEnemyRandomRangeMin = std::clamp(iniReader.ReadInteger("COOP", "ReinforcementsEnemyRandomRangeMin", 1), 1, 9999);
static auto nCOOPReinforcementsEnemyRandomRangeMax = std::clamp(iniReader.ReadInteger("COOP", "ReinforcementsEnemyRandomRangeMax", 1), 1, 9999);

static auto bCAMPAIGNDisableMissionFailOnDetection = iniReader.ReadInteger("CAMPAIGN", "DisableMissionFailOnDetection", 0) != 0;

if (!sDedicatedServerExePath.empty())
{
std::error_code ec;
Expand Down Expand Up @@ -271,7 +297,7 @@ void Init()
}
}

// Resolution
//Resolution
auto pattern = hook::pattern("A3 ? ? ? ? 8B 8E ? ? ? ? 89 0D");
static int* pViewportResolutionWidth = *pattern.get_first<int*>(1);
static int* pViewportResolutionHeight = *pattern.get_first<int*>(13);
Expand All @@ -280,6 +306,10 @@ void Init()
pattern = hook::pattern("0F 84 ? ? ? ? 56 56 56 68 ? ? ? ? 68 ? ? ? ? 68 ? ? ? ? E8 ? ? ? ? 83 C4 18 50 8D 8D");
injector::WriteMemory<uint16_t>(pattern.get_first(), 0xE990, true); //jz -> jmp

//GameMode
pattern = hook::pattern("55 8B EC 83 3D ? ? ? ? ? 75 55");
shLead_SetCurrentGameMode = safetyhook::create_inline(pattern.get_first(), Lead_SetCurrentGameMode);

if (bSkipIntro)
{
//InitBootVideos
Expand Down Expand Up @@ -309,12 +339,14 @@ void Init()
}
}).detach();

static auto kbd = safetyhook::create_mid(0x164A351, [](SafetyHookContext& regs)
pattern = hook::pattern("8B 86 ? ? ? ? 8B 8E ? ? ? ? 89 86 ? ? ? ? 89 86");
static auto kbd = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
{
nOnce = 1;
});

static auto kbd2 = safetyhook::create_mid(0x1648E97, [](SafetyHookContext& regs)
pattern = hook::pattern("89 9E ? ? ? ? C7 86 ? ? ? ? ? ? ? ? 88 9E ? ? ? ? 88 9E");
static auto kbd2 = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
{
nOnce = 2;
});
Expand Down Expand Up @@ -369,24 +401,53 @@ void Init()
auto pattern = hook::pattern("85 5E 08 75 29 8B 06 8B 50 0C 6A 04 8D 8F ? ? ? ? 51 8B CE FF D2 85 5E 08 75 12 8B 06 8B 50 0C 6A 04 8D 8F ? ? ? ? 51 8B CE FF D2 F6 46 08 02");
static auto FCheckpointPackReaderHook = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
{
if (iequals(sReinforcementsNumber, "Random"))
*(uint32_t*)(regs.edi + 0x370) = GetRandomInt(nReinforcementsEnemyRandomRangeMin, nReinforcementsEnemyRandomRangeMax);
if (CurrentGameMode == HUNTER)
{
if (iequals(sHUNTERReinforcementsNumber, "Random"))
*(uint32_t*)(regs.edi + 0x370) = GetRandomInt(nHUNTERReinforcementsEnemyRandomRangeMin, nHUNTERReinforcementsEnemyRandomRangeMax);
}
else if (CurrentGameMode == COOP)
{
if (iequals(sHUNTERReinforcementsNumber, "Random"))
*(uint32_t*)(regs.edi + 0x370) = GetRandomInt(nCOOPReinforcementsEnemyRandomRangeMin, nCOOPReinforcementsEnemyRandomRangeMax);
}
});

pattern = hook::pattern("8B 16 8B 82 ? ? ? ? 8B CE FF D0 8B 16 8B 82 ? ? ? ? 8B CE FF D0 C6 86");
static auto AECoopHunterSpawnerHook = safetyhook::create_mid(pattern.get_first(), [](SafetyHookContext& regs)
{
if (iequals(sReinforcementsNumber, "Random"))
*(uint32_t*)(regs.esi + 0x370) = GetRandomInt(nReinforcementsEnemyRandomRangeMin, nReinforcementsEnemyRandomRangeMax);
else
*(uint32_t*)(regs.esi + 0x370) *= nReinforcementsEnemyMultiplier;
if (CurrentGameMode == HUNTER)
{
if (iequals(sHUNTERReinforcementsNumber, "Random"))
*(uint32_t*)(regs.esi + 0x370) = GetRandomInt(nHUNTERReinforcementsEnemyRandomRangeMin, nHUNTERReinforcementsEnemyRandomRangeMax);
else
*(uint32_t*)(regs.esi + 0x370) *= nHUNTERReinforcementsEnemyMultiplier;
}
else if (CurrentGameMode == COOP)
{
if (iequals(sCOOPReinforcementsNumber, "Random"))
*(uint32_t*)(regs.esi + 0x370) = GetRandomInt(nCOOPReinforcementsEnemyRandomRangeMin, nCOOPReinforcementsEnemyRandomRangeMax);
else
*(uint32_t*)(regs.esi + 0x370) *= nCOOPReinforcementsEnemyMultiplier;
}
});
}

if (bDisableMissionFailOnDetection)
{
auto pattern = hook::pattern("0F 86 ? ? ? ? 0F B6 8E");
injector::WriteMemory<uint16_t>(pattern.get_first(), 0xE990, true); // jbe -> jmp
pattern = hook::pattern("F6 86 ? ? ? ? ? 0F 84 ? ? ? ? 8B 96 ? ? ? ? 52");
static auto loc_F1D09C = (uintptr_t)pattern.get_first(0);

pattern = hook::pattern("0F 86 ? ? ? ? 0F B6 8E");
struct AECooperativeMatchManager__TickSpecial
{
void operator()(injector::reg_pack& regs)
{
if ((bGHOSTDisableMissionFailOnDetection && CurrentGameMode == GHOST) ||
(bCOOPDisableMissionFailOnDetection && CurrentGameMode == COOP) ||
(bCAMPAIGNDisableMissionFailOnDetection && CurrentGameMode == CAMPAIGN))
*(uintptr_t*)(regs.esp - 4) = loc_F1D09C;
}
}; injector::MakeInline<AECooperativeMatchManager__TickSpecial>(pattern.get_first(0), pattern.get_first(6));
}

if (bUnlockDLC)
Expand Down

0 comments on commit 2afd7de

Please sign in to comment.