Skip to content

Commit 0d1f798

Browse files
committed
standardised how optionalCheats lockOrThrow weak ptrs in trycatch blocks. They also all now hold non-weak ptrs to RuntimeExceptionHandler
1 parent 4a120cf commit 0d1f798

29 files changed

+549
-354
lines changed

HCMInternal/AIFreeze.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ class AIFreezeImpl : public AIFreezeImplUntemplated {
88
ScopedCallback <ToggleEvent> mAIFreezeCallbackHandle;
99

1010
// injected services
11-
std::weak_ptr<IMCCStateHook> mccStateHook;
12-
std::weak_ptr<IMessagesGUI> messagesGUI;
13-
std::weak_ptr<RuntimeExceptionHandler> runtimeExceptions;
11+
std::weak_ptr<IMCCStateHook> mccStateHookWeak;
12+
std::weak_ptr<IMessagesGUI> messagesGUIWeak;
13+
std::shared_ptr<RuntimeExceptionHandler> runtimeExceptions;
1414

1515
//data
1616
static inline std::shared_ptr<ModuleMidHook> aiFreezeHook;
@@ -30,24 +30,35 @@ class AIFreezeImpl : public AIFreezeImplUntemplated {
3030
// primary event callback
3131
void onToggleChange(bool& newValue)
3232
{
33-
aiFreezeHook->setWantsToBeAttached(newValue);
34-
PLOG_DEBUG << "onToggleChange: newval: " << newValue;
33+
try
34+
{
35+
lockOrThrow(mccStateHookWeak, mccStateHook);
36+
lockOrThrow(messagesGUIWeak, messagesGUI)
37+
38+
aiFreezeHook->setWantsToBeAttached(newValue);
39+
PLOG_DEBUG << "onToggleChange: newval: " << newValue;
3540

3641

37-
if (mccStateHook.lock()->isGameCurrentlyPlaying(mGame))
42+
if (mccStateHook->isGameCurrentlyPlaying(mGame))
43+
{
44+
messagesGUI->addMessage(newValue ? "AI frozen." : "AI unfrozen.");
45+
}
46+
}
47+
catch (HCMRuntimeException ex)
3848
{
39-
messagesGUI.lock()->addMessage(newValue ? "AI frozen." : "AI unfrozen.");
49+
runtimeExceptions->handleMessage(ex);
4050
}
4151

52+
4253
}
4354

4455

4556

4657
public:
4758
AIFreezeImpl(IDIContainer& dicon) :
4859
mAIFreezeCallbackHandle(dicon.Resolve<SettingsStateAndEvents>().lock()->aiFreezeToggle->valueChangedEvent, [this](bool& n) { onToggleChange(n); }),
49-
mccStateHook(dicon.Resolve<IMCCStateHook>()),
50-
messagesGUI(dicon.Resolve<IMessagesGUI>()),
60+
mccStateHookWeak(dicon.Resolve<IMCCStateHook>()),
61+
messagesGUIWeak(dicon.Resolve<IMessagesGUI>()),
5162
runtimeExceptions(dicon.Resolve<RuntimeExceptionHandler>())
5263
{
5364
auto ptr = dicon.Resolve<PointerManager>().lock();

HCMInternal/AdvanceTicks.cpp

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ class AdvanceTicksImpl
3030

3131

3232
// injected services
33-
std::weak_ptr<IMessagesGUI> messagesGUI;
34-
std::weak_ptr<RuntimeExceptionHandler> runtimeExceptions;
35-
std::weak_ptr<PauseGame> pauseService;
36-
std::weak_ptr<GameTickEventHook> gameTickEventHook;
37-
std::weak_ptr<SettingsStateAndEvents> settings;
38-
std::weak_ptr<IMCCStateHook> mccStateHook;
33+
std::weak_ptr<IMessagesGUI> messagesGUIWeak;
34+
std::shared_ptr<RuntimeExceptionHandler> runtimeExceptions;
35+
std::weak_ptr<PauseGame> pauseServiceWeak;
36+
std::weak_ptr<GameTickEventHook> gameTickEventHookWeak;
37+
std::weak_ptr<SettingsStateAndEvents> settingsWeak;
38+
std::weak_ptr<IMCCStateHook> mccStateHookWeak;
3939

4040

4141
int advanceTicksCount = 0;
@@ -63,47 +63,59 @@ class AdvanceTicksImpl
6363
// primary event callback
6464
void onAdvanceTicksEvent()
6565
{
66-
if (!mccStateHook.lock()->isGameCurrentlyPlaying(mGame))
66+
try
6767
{
68+
lockOrThrow(mccStateHookWeak, mccStateHook);
69+
lockOrThrow(gameTickEventHookWeak, gameTickEventHook);
70+
lockOrThrow(settingsWeak, settings);
71+
lockOrThrow(pauseServiceWeak, pauseService);
72+
lockOrThrow(messagesGUIWeak, messagesGUI);
73+
74+
if (!mccStateHook->isGameCurrentlyPlaying(mGame))
75+
{
76+
mGameTickEventCallback.reset();
77+
pauseOverrideRequest.reset();
78+
return;
79+
}
80+
81+
// need to destroy old ones BEFORE constructing new ones
6882
mGameTickEventCallback.reset();
6983
pauseOverrideRequest.reset();
70-
return;
71-
}
72-
73-
auto gameTickEvent = gameTickEventHook.lock();
74-
if (!gameTickEvent) { messagesGUI.lock()->addMessage("Advance ticks failed: bad gameTickEventHook weak ptr."); return; }
7584

76-
// need to destroy old ones BEFORE constructing new ones
77-
mGameTickEventCallback.reset();
78-
pauseOverrideRequest.reset();
85+
// something is going wrong here. on any call but the first the mGameTIckEventCallback binding fails, somehow
86+
// why? the event is absolutely firing. Why is the binding failing?
87+
// I mean I could fix this by only binding once but I really don't want to have to do that
88+
// it looks like the scoped call back is just instantly auto-destructing
7989

80-
// something is going wrong here. on any call but the first the mGameTIckEventCallback binding fails, somehow
81-
// why? the event is absolutely firing. Why is the binding failing?
82-
// I mean I could fix this by only binding once but I really don't want to have to do that
83-
// it looks like the scoped call back is just instantly auto-destructing
90+
advanceTicksCount = settings->advanceTicksCount->GetValue();
91+
mGameTickEventCallback = std::make_unique<ScopedCallback<eventpp::CallbackList<void(int)>>>(gameTickEventHook->getGameTickEvent(), [this](int i) {onGameTickEvent(i); });
92+
pauseOverrideRequest = pauseService->scopedOverrideRequest(nameof(AdvanceTicks::AdvanceTicksImpl));
8493

85-
advanceTicksCount = settings.lock()->advanceTicksCount->GetValue();
86-
mGameTickEventCallback = std::make_unique<ScopedCallback<eventpp::CallbackList<void(int)>>>(gameTickEvent->getGameTickEvent(), [this](int i) {onGameTickEvent(i); });
87-
pauseOverrideRequest = pauseService.lock()->scopedOverrideRequest(nameof(AdvanceTicks::AdvanceTicksImpl));
8894

95+
messagesGUI->addMessage(std::format("Advancing {} tick{}.", advanceTicksCount, advanceTicksCount == 1 ? "" : "s"));
96+
}
97+
catch (HCMRuntimeException ex)
98+
{
99+
runtimeExceptions->handleMessage(ex);
100+
}
89101

90-
messagesGUI.lock()->addMessage(std::format("Advancing {} tick{}.", advanceTicksCount, advanceTicksCount == 1 ? "" : "s"));
102+
91103
}
92104
public:
93105
AdvanceTicksImpl(GameState gameImpl, IDIContainer& dicon)
94106
: mGame(gameImpl),
95107
mAdvanceTicksCallbackHandle(dicon.Resolve<SettingsStateAndEvents>().lock()->advanceTicksEvent, [this]() { onAdvanceTicksEvent(); }),
96-
mccStateHook(dicon.Resolve<IMCCStateHook>()),
97-
messagesGUI(dicon.Resolve<IMessagesGUI>()),
108+
mccStateHookWeak(dicon.Resolve<IMCCStateHook>()),
109+
messagesGUIWeak(dicon.Resolve<IMessagesGUI>()),
98110
runtimeExceptions(dicon.Resolve<RuntimeExceptionHandler>()),
99-
settings(dicon.Resolve<SettingsStateAndEvents>())
111+
settingsWeak(dicon.Resolve<SettingsStateAndEvents>())
100112
{
101113
auto csc = dicon.Resolve<ControlServiceContainer>().lock();
102114

103115
if (!csc->pauseGameService.has_value()) throw HCMInitException("Cannot advance ticks without pause service");
104-
pauseService = csc->pauseGameService.value();
116+
pauseServiceWeak = csc->pauseGameService.value();
105117

106-
gameTickEventHook = std::dynamic_pointer_cast<GameTickEventHook>(dicon.Resolve<IMakeOrGetCheat>().lock()->getOrMakeCheat(std::make_pair(gameImpl, OptionalCheatEnum::GameTickEventHook), dicon));
118+
gameTickEventHookWeak = std::dynamic_pointer_cast<GameTickEventHook>(dicon.Resolve<IMakeOrGetCheat>().lock()->getOrMakeCheat(std::make_pair(gameImpl, OptionalCheatEnum::GameTickEventHook), dicon));
107119

108120

109121
}

HCMInternal/BottomlessClip.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class BottomlessClipImplSetFlag : public IBottomlessClipImpl
2121
// injected services
2222
std::weak_ptr<IMCCStateHook> mccStateHookWeak;
2323
std::weak_ptr<IMessagesGUI> messagesGUIWeak;
24-
std::weak_ptr<RuntimeExceptionHandler> runtimeExceptionsWeak;
24+
std::shared_ptr<RuntimeExceptionHandler> runtimeExceptions;
2525

2626
//data
2727
std::shared_ptr<MultilevelPointer> bottomlessClipFlag;
@@ -46,7 +46,7 @@ class BottomlessClipImplSetFlag : public IBottomlessClipImpl
4646
}
4747
catch (HCMRuntimeException ex)
4848
{
49-
runtimeExceptionsWeak.lock()->handleMessage(ex);
49+
runtimeExceptions->handleMessage(ex);
5050
}
5151

5252
}
@@ -58,7 +58,7 @@ class BottomlessClipImplSetFlag : public IBottomlessClipImpl
5858
mBottomlessClipCallbackHandle(dicon.Resolve<SettingsStateAndEvents>().lock()->bottomlessClipToggle->valueChangedEvent, [this](bool& n) {onBottomlessClipToggle(n); }),
5959
mccStateHookWeak(dicon.Resolve<IMCCStateHook>()),
6060
messagesGUIWeak(dicon.Resolve<IMessagesGUI>()),
61-
runtimeExceptionsWeak(dicon.Resolve<RuntimeExceptionHandler>())
61+
runtimeExceptions(dicon.Resolve<RuntimeExceptionHandler>())
6262
{
6363

6464
auto ptr = dicon.Resolve<PointerManager>().lock();

HCMInternal/ConsoleCommand.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ class ConsoleCommand : public IOptionalCheat
2222
ScopedCallback<ActionEvent> mConsoleCommandEventCallbackHandle;
2323

2424
// injected services
25-
std::weak_ptr<IMCCStateHook> mccStateHook;
26-
std::weak_ptr<IMessagesGUI> messagesGUI;
27-
std::weak_ptr<RuntimeExceptionHandler> runtimeExceptions;
28-
std::weak_ptr<SettingsStateAndEvents> mSettings;
25+
std::weak_ptr<IMCCStateHook> mccStateHookWeak;
26+
std::weak_ptr<IMessagesGUI> messagesGUIWeak;
27+
std::shared_ptr<RuntimeExceptionHandler> runtimeExceptions;
28+
std::weak_ptr<SettingsStateAndEvents> mSettingsWeak;
2929

3030

3131
//data
@@ -35,12 +35,18 @@ class ConsoleCommand : public IOptionalCheat
3535
// primary event callback
3636
void onSendCommand()
3737
{
38-
if (mccStateHook.lock()->isGameCurrentlyPlaying(mGame) == false) return;
38+
3939

4040
try
4141
{
42+
lockOrThrow(mccStateHookWeak, mccStateHook);
43+
lockOrThrow(mSettingsWeak, mSettings);
44+
lockOrThrow(messagesGUIWeak, messagesGUI);
45+
4246
PLOG_DEBUG << "onSendCommand called for game: " << mGame.toString();
4347

48+
if (mccStateHook->isGameCurrentlyPlaying(mGame) == false) return;
49+
4450
uintptr_t pCommand;
4551
if (!sendCommandPointer->resolve(&pCommand)) throw HCMRuntimeException("Could not resolve pointer to sendCommand function");
4652

@@ -53,17 +59,17 @@ class ConsoleCommand : public IOptionalCheat
5359
engine_command_vptr = static_cast<EngineCommand_t>((void*)pCommand);
5460

5561

56-
std::string command = "HS: " + mSettings.lock()->consoleCommandString->GetValue();
62+
std::string command = "HS: " + mSettings->consoleCommandString->GetValue();
5763

5864

59-
messagesGUI.lock()->addMessage(std::format("Sending command: {}", mSettings.lock()->consoleCommandString->GetValue()));
65+
messagesGUI->addMessage(std::format("Sending command: {}", mSettings->consoleCommandString->GetValue()));
6066
auto commandResult = engine_command_vptr((void*)pEngine, command.c_str());
61-
messagesGUI.lock()->addMessage(std::format("Result: 0x{:X}", commandResult));
67+
messagesGUI->addMessage(std::format("Result: 0x{:X}", commandResult));
6268

6369
}
6470
catch (HCMRuntimeException ex)
6571
{
66-
runtimeExceptions.lock()->handleMessage(ex);
72+
runtimeExceptions->handleMessage(ex);
6773
}
6874

6975
}
@@ -75,10 +81,10 @@ class ConsoleCommand : public IOptionalCheat
7581
ConsoleCommand(GameState gameImpl, IDIContainer& dicon)
7682
: mGame(gameImpl),
7783
mConsoleCommandEventCallbackHandle(dicon.Resolve<SettingsStateAndEvents>().lock()->consoleCommandEvent, [this]() {onSendCommand(); }),
78-
mccStateHook(dicon.Resolve<IMCCStateHook>()),
79-
messagesGUI(dicon.Resolve<IMessagesGUI>()),
84+
mccStateHookWeak(dicon.Resolve<IMCCStateHook>()),
85+
messagesGUIWeak(dicon.Resolve<IMessagesGUI>()),
8086
runtimeExceptions(dicon.Resolve<RuntimeExceptionHandler>()),
81-
mSettings(dicon.Resolve<SettingsStateAndEvents>())
87+
mSettingsWeak(dicon.Resolve<SettingsStateAndEvents>())
8288

8389
{
8490
PLOG_VERBOSE << "constructing ConsoleCommand OptionalCheat for game: " << mGame.toString();

HCMInternal/DIContainer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class IDIContainer {
151151
}
152152

153153

154+
154155
};
155156

156157
template <class... T>

HCMInternal/DumpCheckpoint.h

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ class DumpCheckpoint : public IOptionalCheat {
2626
ScopedCallback<ActionEvent> mDumpCheckpointEventCallback;
2727

2828
// injected services
29-
std::weak_ptr<IMCCStateHook> mccStateHook;
30-
std::weak_ptr<IMessagesGUI> messagesGUI;
31-
std::weak_ptr<RuntimeExceptionHandler> runtimeExceptions;
32-
std::weak_ptr<IGetMCCVersion> getMCCVer;
33-
std::weak_ptr<ISharedMemory> sharedMem;
34-
std::weak_ptr<IModalDialogRenderer> modalDialogs;
35-
std::weak_ptr<SettingsStateAndEvents> settings;
29+
std::weak_ptr<IMCCStateHook> mccStateHookWeak;
30+
std::weak_ptr<IMessagesGUI> messagesGUIWeak;
31+
std::shared_ptr<RuntimeExceptionHandler> runtimeExceptions;
32+
std::weak_ptr<IGetMCCVersion> getMCCVerWeak;
33+
std::weak_ptr<ISharedMemory> sharedMemWeak;
34+
std::weak_ptr<IModalDialogRenderer> modalDialogsWeak;
35+
std::weak_ptr<SettingsStateAndEvents> settingsWeak;
3636

3737

3838
// data
@@ -46,14 +46,24 @@ class DumpCheckpoint : public IOptionalCheat {
4646

4747
// primary event callback
4848
void onDump() {
49-
if (!mccStateHook.lock()->isGameCurrentlyPlaying(mImplGame)) return;
49+
5050

5151
try
5252
{
53+
lockOrThrow(mccStateHookWeak, mccStateHook);
54+
lockOrThrow(messagesGUIWeak, messagesGUI);
55+
lockOrThrow(getMCCVerWeak, getMCCVer);
56+
lockOrThrow(sharedMemWeak, sharedMem);
57+
lockOrThrow(modalDialogsWeak, modalDialogs);
58+
lockOrThrow(settingsWeak, settings);
59+
60+
61+
if (!mccStateHook->isGameCurrentlyPlaying(mImplGame)) return;
62+
PLOG_DEBUG << "onDump called " << mImplGame.toString();
5363
// Automatically force checkpoint beforehand if user wants that
54-
if (settings.lock()->dumpCheckpointForcesSave->GetValue())
64+
if (settings->dumpCheckpointForcesSave->GetValue())
5565
{
56-
settings.lock()->forceCheckpointEvent->operator()();
66+
settings->forceCheckpointEvent->operator()();
5767
Sleep(10);
5868
}
5969

@@ -65,10 +75,10 @@ class DumpCheckpoint : public IOptionalCheat {
6575
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
6676

6777
// ask the user what they want to call it, if they want that. Otherwise we use the default checkpoint name
68-
if (settings.lock()->autonameCheckpoints->GetValue() == false)
78+
if (settings->autonameCheckpoints->GetValue() == false)
6979
{
7080
PLOG_DEBUG << "calling blocking func showSaveDumpNameDialog";
71-
auto modalReturn = modalDialogs.lock()->showSaveDumpNameDialog("Name dumped checkpoint", checkpointName); // this is a blocking call
81+
auto modalReturn = modalDialogs->showSaveDumpNameDialog("Name dumped checkpoint", checkpointName); // this is a blocking call
7282
PLOG_DEBUG << "showSaveDumpNameDialog returned! ";
7383

7484
if (!std::get<bool>(modalReturn)) { PLOG_DEBUG << "User cancelled dump"; return; } // user cancelled dump
@@ -77,7 +87,7 @@ class DumpCheckpoint : public IOptionalCheat {
7787

7888

7989
int64_t checkpointLength = *mCheckpointLength.get();
80-
auto currentSaveFolder = sharedMem.lock()->getDumpInfo(mImplGame);
90+
auto currentSaveFolder = sharedMem->getDumpInfo(mImplGame);
8191
PLOG_DEBUG << "Attempting checkpoint dump for game: " << mImplGame.toString();;
8292

8393
auto dumpPath = currentSaveFolder.selectedFolderPath + "\\" + checkpointName + ".bin";
@@ -108,7 +118,7 @@ class DumpCheckpoint : public IOptionalCheat {
108118
if (err) throw HCMRuntimeException(std::format("error storing checkpointData from memory! code: {}", err));
109119

110120
// add version information to last 10 bytes of file
111-
std::string versionString = getMCCVer.lock()->getMCCVersionAsString().data();
121+
std::string versionString = getMCCVer->getMCCVersionAsString().data();
112122
if (versionString.size() != 10) throw HCMRuntimeException(std::format("Version string was the wrong size somehow?! Expected: 10, Actual: {}", versionString.size()));
113123
std::copy(std::begin(versionString), std::end(versionString), std::end(checkpointData) - 10);
114124

@@ -128,14 +138,14 @@ class DumpCheckpoint : public IOptionalCheat {
128138
throw HCMRuntimeException(std::format("Failed to write checkpoint file to location {}: error: {}", dumpPath, e.what()));
129139
}
130140

131-
messagesGUI.lock()->addMessage(std::format("Dumped checkpoint: {}.bin to {}", checkpointName, currentSaveFolder.selectedFolderName));
141+
messagesGUI->addMessage(std::format("Dumped checkpoint: {}.bin to {}", checkpointName, currentSaveFolder.selectedFolderName));
132142

133143
PLOG_INFO << std::format("successfully dumped checkpoint from 0x{:X} to path: {}", (uint64_t)checkpointLoc, dumpPath);
134144

135145
}
136146
catch (HCMRuntimeException ex)
137147
{
138-
runtimeExceptions.lock()->handleMessage(ex);
148+
runtimeExceptions->handleMessage(ex);
139149
}
140150
}
141151

@@ -144,13 +154,13 @@ class DumpCheckpoint : public IOptionalCheat {
144154
DumpCheckpoint(GameState game, IDIContainer& dicon)
145155
: mImplGame(game),
146156
mDumpCheckpointEventCallback(dicon.Resolve<SettingsStateAndEvents>().lock()->dumpCheckpointEvent, [this]() { onDump(); }),
147-
getMCCVer(dicon.Resolve<IGetMCCVersion>()),
148-
mccStateHook(dicon.Resolve<IMCCStateHook>()),
149-
sharedMem(dicon.Resolve<ISharedMemory>()),
157+
getMCCVerWeak(dicon.Resolve<IGetMCCVersion>()),
158+
mccStateHookWeak(dicon.Resolve<IMCCStateHook>()),
159+
sharedMemWeak(dicon.Resolve<ISharedMemory>()),
150160
runtimeExceptions(dicon.Resolve<RuntimeExceptionHandler>()),
151-
messagesGUI(dicon.Resolve<IMessagesGUI>()),
152-
modalDialogs(dicon.Resolve<IModalDialogRenderer>()),
153-
settings(dicon.Resolve<SettingsStateAndEvents>())
161+
messagesGUIWeak(dicon.Resolve<IMessagesGUI>()),
162+
modalDialogsWeak(dicon.Resolve<IModalDialogRenderer>()),
163+
settingsWeak(dicon.Resolve<SettingsStateAndEvents>())
154164
{
155165
auto ptr = dicon.Resolve<PointerManager>().lock();
156166
mInjectRequirements = ptr->getData<std::shared_ptr<InjectRequirements>>("injectRequirements", game);

0 commit comments

Comments
 (0)