Skip to content

Commit 29409c1

Browse files
authored
Merge branch 'master' into startstop
2 parents 478a808 + e36e109 commit 29409c1

File tree

81 files changed

+100054
-98591
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+100054
-98591
lines changed

.github/workflows/dockerimage.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Docker Image
22

33
on:
4+
workflow_dispatch:
45
push:
56
branches:
67
- master

Client/core/CClientVariables.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ void CClientVariables::LoadDefaults()
358358
DEFAULT("discord_rpc_share_data_firsttime", false); // Display the user data sharing consent dialog box - for the first time
359359
DEFAULT("browser_enable_gpu", true); // Enable GPU in CEF? (allows stuff like WebGL to function)
360360
DEFAULT("process_cpu_affinity", true); // Set CPU 0 affinity to improve game performance and fix the known issue in single-threaded games
361+
DEFAULT("ask_before_disconnect", true); // Ask before disconnecting from a server
361362

362363
if (!Exists("locale"))
363364
{

Client/core/CMainMenu.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,14 @@ bool CMainMenu::OnMenuClick(CGUIMouseEventArgs Args)
842842
case MENU_ITEM_MAP_EDITOR:
843843
AskUserIfHeWantsToDisconnect(m_pHoveredItem->menuType);
844844
return true;
845+
case MENU_ITEM_DISCONNECT:
846+
if (g_pCore->GetCVars()->GetValue("ask_before_disconnect", true))
847+
{
848+
AskUserIfHeWantsToDisconnect(m_pHoveredItem->menuType);
849+
return true;
850+
}
851+
852+
break;
845853
default:
846854
break;
847855
}
@@ -863,7 +871,7 @@ bool CMainMenu::OnMenuClick(CGUIMouseEventArgs Args)
863871
switch (m_pHoveredItem->menuType)
864872
{
865873
case MENU_ITEM_DISCONNECT:
866-
OnDisconnectButtonClick(pElement);
874+
OnDisconnectButtonClick();
867875
break;
868876
case MENU_ITEM_QUICK_CONNECT:
869877
OnQuickConnectButtonClick(pElement, Args.button == LeftButton);
@@ -948,7 +956,7 @@ void CMainMenu::HideServerInfo()
948956
m_ServerInfo.Hide();
949957
}
950958

951-
bool CMainMenu::OnDisconnectButtonClick(CGUIElement* pElement)
959+
bool CMainMenu::OnDisconnectButtonClick()
952960
{
953961
// Return if we haven't faded in yet
954962
if (m_ucFade != FADE_VISIBLE)
@@ -1251,6 +1259,9 @@ void CMainMenu::WantsToDisconnectCallBack(void* pData, uint uiButton)
12511259
case MENU_ITEM_MAP_EDITOR:
12521260
OnEditorButtonClick();
12531261
break;
1262+
case MENU_ITEM_DISCONNECT:
1263+
OnDisconnectButtonClick();
1264+
break;
12541265
default:
12551266
break;
12561267
}

Client/core/CMainMenu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class CMainMenu
8989
bool OnResumeButtonClick(CGUIElement* pElement);
9090
bool OnBrowseServersButtonClick(CGUIElement* pElement);
9191
bool OnHostGameButtonClick();
92-
bool OnDisconnectButtonClick(CGUIElement* pElement);
92+
bool OnDisconnectButtonClick();
9393
bool OnEditorButtonClick();
9494
bool OnSettingsButtonClick(CGUIElement* pElement);
9595
bool OnAboutButtonClick(CGUIElement* pElement);

Client/core/CSettings.cpp

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ void CSettings::CreateGUI()
411411
m_pPhotoSavingCheckbox->GetPosition(vecTemp, false);
412412
m_pPhotoSavingCheckbox->AutoSize(NULL, 20.0f);
413413

414+
m_pCheckBoxAskBeforeDisconnect = reinterpret_cast<CGUICheckBox*>(pManager->CreateCheckBox(pTabMultiplayer, _("Ask before disconnecting from server using main menu"), true));
415+
m_pCheckBoxAskBeforeDisconnect->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f));
416+
m_pCheckBoxAskBeforeDisconnect->GetPosition(vecTemp, false);
417+
m_pCheckBoxAskBeforeDisconnect->AutoSize(NULL, 20.0f);
418+
414419
m_pCheckBoxCustomizedSAFiles = reinterpret_cast<CGUICheckBox*>(pManager->CreateCheckBox(pTabMultiplayer, _("Use customized GTA:SA files"), true));
415420
m_pCheckBoxCustomizedSAFiles->SetPosition(CVector2D(vecTemp.fX, vecTemp.fY + 20.0f));
416421
m_pCheckBoxCustomizedSAFiles->GetPosition(vecTemp, false);
@@ -3080,6 +3085,10 @@ void CSettings::LoadData()
30803085
CVARS_GET("allow_discord_rpc", bAllowDiscordRPC);
30813086
m_pCheckBoxAllowDiscordRPC->SetSelected(bAllowDiscordRPC);
30823087

3088+
bool bAskBeforeDisconnect;
3089+
CVARS_GET("ask_before_disconnect", bAskBeforeDisconnect);
3090+
m_pCheckBoxAskBeforeDisconnect->SetSelected(bAskBeforeDisconnect);
3091+
30833092
// Customized sa files
30843093
m_pCheckBoxCustomizedSAFiles->SetSelected(GetApplicationSettingInt("customized-sa-files-request") != 0);
30853094
m_pCheckBoxCustomizedSAFiles->SetVisible(GetApplicationSettingInt("customized-sa-files-show") != 0);
@@ -3557,6 +3566,9 @@ void CSettings::SaveData()
35573566
}
35583567
}
35593568

3569+
bool bAskBeforeDisconnect = m_pCheckBoxAskBeforeDisconnect->GetSelected();
3570+
CVARS_SET("ask_before_disconnect", bAskBeforeDisconnect);
3571+
35603572
// Grass
35613573
bool bGrassEnabled = m_pCheckBoxGrass->GetSelected();
35623574
CVARS_SET("grass", bGrassEnabled);
@@ -4765,34 +4777,39 @@ static void CPUAffinityQuestionCallBack(void* userdata, unsigned int button)
47654777
{
47664778
CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow()->Reset();
47674779

4768-
if (button == 0)
4769-
{
4770-
auto const checkBox = reinterpret_cast<CGUICheckBox*>(userdata);
4771-
checkBox->SetSelected(false);
4772-
}
4780+
auto* checkbox = static_cast<CGUICheckBox*>(userdata);
4781+
4782+
if (!checkbox)
4783+
return;
4784+
4785+
if (button != 0)
4786+
return;
4787+
4788+
checkbox->SetSelected(true);
47734789
}
47744790

47754791
bool CSettings::OnAffinityClick(CGUIElement* pElement)
47764792
{
4777-
static bool shownWarning = false;
4793+
static bool shown = false;
47784794

4779-
if (m_pProcessAffinityCheckbox->GetSelected() && !shownWarning)
4780-
{
4781-
shownWarning = true;
4795+
if (m_pProcessAffinityCheckbox->GetSelected() || shown)
4796+
return true;
47824797

4783-
std::string message = std::string(
4784-
_("This option should only be changed if you experience performance issues.\n"
4785-
"\nAre you sure you want to enable this option?"));
4798+
shown = true;
47864799

4787-
CQuestionBox* pQuestionBox = CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow();
4788-
pQuestionBox->Reset();
4789-
pQuestionBox->SetTitle(_("EXPERIMENTAL FEATURE"));
4790-
pQuestionBox->SetMessage(message);
4791-
pQuestionBox->SetButton(0, _("No"));
4792-
pQuestionBox->SetButton(1, _("Yes"));
4793-
pQuestionBox->SetCallback(CPUAffinityQuestionCallBack, m_pProcessAffinityCheckbox);
4794-
pQuestionBox->Show();
4795-
}
4800+
std::string title = _("EXPERIMENTAL FEATURE");
4801+
std::string message =
4802+
std::string(_("Disabling this option is not recommended unless you are experiencing performance issues.\n\n"
4803+
"Are you sure you want to disable it?"));
4804+
4805+
CQuestionBox* pQuestionBox = CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->GetQuestionWindow();
4806+
pQuestionBox->Reset();
4807+
pQuestionBox->SetTitle(title);
4808+
pQuestionBox->SetMessage(message);
4809+
pQuestionBox->SetButton(0, _("No"));
4810+
pQuestionBox->SetButton(1, _("Yes"));
4811+
pQuestionBox->SetCallback(CPUAffinityQuestionCallBack, m_pProcessAffinityCheckbox);
4812+
pQuestionBox->Show();
47964813

47974814
return true;
47984815
}
@@ -4961,7 +4978,7 @@ bool CSettings::OnShowAdvancedSettingDescription(CGUIElement* pElement)
49614978
else if (pCheckBox && pCheckBox == m_pWin8MouseCheckBox)
49624979
strText = std::string(_("Mouse fix:")) + " " + std::string(_("Mouse movement fix - May need PC restart"));
49634980
else if (pCheckBox && pCheckBox == m_pProcessAffinityCheckbox)
4964-
strText = std::string(_("CPU affinity:")) + " " + std::string(_("Experimental feature - Change only if you experience performance issues"));
4981+
strText = std::string(_("CPU affinity:")) + " " + std::string(_("Only change if you're having stability issues."));
49654982

49664983
if (strText != "")
49674984
m_pAdvancedSettingDescriptionLabel->SetText(strText.c_str());

Client/core/CSettings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class CSettings
216216
CGUICheckBox* m_pWin8ColorCheckBox;
217217
CGUICheckBox* m_pWin8MouseCheckBox;
218218
CGUICheckBox* m_pPhotoSavingCheckbox;
219+
CGUICheckBox* m_pCheckBoxAskBeforeDisconnect;
219220
CGUICheckBox* m_pProcessAffinityCheckbox;
220221
CGUILabel* m_pUpdateBuildTypeLabel;
221222
CGUIComboBox* m_pUpdateBuildTypeCombo;

Client/game_sa/CAnimManagerSA.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,12 +874,18 @@ const char* CAnimManagerSA::GetGateWayAnimationName() const
874874

875875
bool CAnimManagerSA::IsValidGroup(std::uint32_t uiAnimGroup) const
876876
{
877+
if ((eAnimGroup)uiAnimGroup <= eAnimGroup::ANIM_GROUP_NONE || (eAnimGroup)uiAnimGroup >= eAnimGroup::ANIM_TOTAL_GROUPS)
878+
return false;
879+
877880
const auto pGroup = GetAnimBlendAssoc(uiAnimGroup);
878881
return pGroup && pGroup->IsCreated();
879882
}
880883

881884
bool CAnimManagerSA::IsValidAnim(std::uint32_t uiAnimGroup, std::uint32_t uiAnimID) const
882885
{
886+
if ((eAnimID)uiAnimID <= eAnimID::ANIM_ID_UNDEFINED || (eAnimID)uiAnimID >= eAnimID::ANIM_ID_MAX)
887+
return false;
888+
883889
// We get an animation for the checks
884890
const auto pAnim = GetAnimStaticAssociation((eAnimGroup)uiAnimGroup, (eAnimID)uiAnimID);
885891
if (!pAnim)

Client/game_sa/CFireSA.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "CFireSA.h"
1515
#include "CGameSA.h"
1616
#include "CPoolsSA.h"
17+
#include <game/CTaskManager.h>
18+
#include <game/TaskTypes.h>
1719

1820
extern CGameSA* pGame;
1921

@@ -209,3 +211,49 @@ void CFireSA::SetNumGenerationsAllowed(char generations)
209211
{
210212
internalInterface->nNumGenerationsAllowed = generations;
211213
}
214+
215+
////////////////////////////////////////////////////////////////////////
216+
// CFire::Extinguish
217+
//
218+
// Fix GH #3249 (PLAYER_ON_FIRE task is not aborted after the fire is extinguished)
219+
////////////////////////////////////////////////////////////////////////
220+
static void AbortFireTask(CEntitySAInterface* entityOnFire, DWORD returnAddress)
221+
{
222+
// We can't and shouldn't remove the task if we're in CTaskSimplePlayerOnFire::ProcessPed. Otherwise we will crash.
223+
if (returnAddress == 0x633783)
224+
return;
225+
226+
auto* ped = pGame->GetPools()->GetPed(reinterpret_cast<DWORD*>(entityOnFire));
227+
if (!ped || !ped->pEntity)
228+
return;
229+
230+
CTaskManager* taskManager = ped->pEntity->GetPedIntelligence()->GetTaskManager();
231+
if (!taskManager)
232+
return;
233+
234+
taskManager->RemoveTaskSecondary(TASK_SECONDARY_PARTIAL_ANIM, TASK_SIMPLE_PLAYER_ON_FIRE);
235+
}
236+
237+
#define HOOKPOS_CFire_Extinguish 0x539429
238+
#define HOOKSIZE_CFire_Extinguish 6
239+
static constexpr std::uintptr_t CONTINUE_CFire_Extinguish = 0x53942F;
240+
static void _declspec(naked) HOOK_CFire_Extinguish()
241+
{
242+
_asm
243+
{
244+
mov [eax+730h], edi
245+
mov ebx, [esp+8]
246+
247+
push ebx
248+
push eax
249+
call AbortFireTask
250+
add esp, 8
251+
252+
jmp CONTINUE_CFire_Extinguish
253+
}
254+
}
255+
256+
void CFireSA::StaticSetHooks()
257+
{
258+
EZHookInstall(CFire_Extinguish);
259+
}

Client/game_sa/CFireSA.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,6 @@ class CFireSA : public CFire
6464
void SetStrength(float fStrength);
6565
void SetNumGenerationsAllowed(char generations);
6666
CFireSAInterface* GetInterface() { return internalInterface; }
67+
68+
static void StaticSetHooks();
6769
};

Client/game_sa/CGameSA.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ CGameSA::CGameSA()
247247
CVehicleSA::StaticSetHooks();
248248
CCheckpointSA::StaticSetHooks();
249249
CHudSA::StaticSetHooks();
250+
CFireSA::StaticSetHooks();
250251
CPtrNodeSingleLinkPoolSA::StaticSetHooks();
251252
CVehicleAudioSettingsManagerSA::StaticSetHooks();
252253
}
@@ -889,6 +890,9 @@ void CGameSA::SetIgnoreFireStateEnabled(bool isEnabled)
889890
MemSet((void*)0x64F3DB, 0x90, 14); // CCarEnterExit::IsPlayerToQuitCarEnter
890891

891892
MemSet((void*)0x685A7F, 0x90, 14); // CTaskSimplePlayerOnFoot::ProcessPlayerWeapon
893+
894+
MemSet((void*)0x53A899, 0x90, 5); // CFire::ProcessFire
895+
MemSet((void*)0x53A990, 0x90, 5); // CFire::ProcessFire
892896
}
893897
else
894898
{
@@ -899,6 +903,9 @@ void CGameSA::SetIgnoreFireStateEnabled(bool isEnabled)
899903
MemCpy((void*)0x64F3DB, "\x8B\x85\x90\x04\x00\x00\x85\xC0\x0F\x85\x1B\x01\x00\x00", 14);
900904

901905
MemCpy((void*)0x685A7F, "\x8B\x86\x30\x07\x00\x00\x85\xC0\x0F\x85\x1D\x01\x00\x00", 14);
906+
907+
MemCpy((void*)0x53A899, "\xE8\x82\xF7\x0C\x00", 5);
908+
MemCpy((void*)0x53A990, "\xE8\x8B\xF6\x0C\x00", 5);
902909
}
903910

904911
m_isIgnoreFireStateEnabled = isEnabled;

0 commit comments

Comments
 (0)