Skip to content

Commit 208ae41

Browse files
authored
Merge branch 'master' into fix/skip_av_wine
2 parents 0afefae + c757a89 commit 208ae41

File tree

63 files changed

+3130
-796
lines changed

Some content is hidden

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

63 files changed

+3130
-796
lines changed

.git-blame-ignore-revs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,9 @@ b42518e64803762d27fe6277b36044d1a71fc2c4
247247
# Date: Mon Jun 12 19:01:59 2023 +0300
248248
#
249249
# Apply win-apply-clang-format.bat
250+
251+
466c162fbd1af45b290849cc0771fab66f55ba34
252+
# Author: Dutchman101 <mcak105@outlook.com>
253+
# Date: Wed April 9 19:01:39 2025 +0300
254+
#
255+
# Eliminate the use of http:// across whole project

Client/cefweb/CAjaxResourceHandler.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "CAjaxResourceHandler.h"
1414
#undef min
1515

16-
CAjaxResourceHandler::CAjaxResourceHandler(std::vector<SString>& vecGet, std::vector<SString>& vecPost, const CefString& strMime)
16+
CAjaxResourceHandler::CAjaxResourceHandler(std::vector<std::string> vecGet, std::vector<std::string> vecPost, const CefString& strMime)
1717
: m_vecGetData(std::move(vecGet)), m_vecPostData(std::move(vecPost)), m_strMime(strMime)
1818
{
1919
}
@@ -27,13 +27,13 @@ CAjaxResourceHandler::~CAjaxResourceHandler()
2727
m_callback = nullptr;
2828
}
2929

30-
void CAjaxResourceHandler::SetResponse(const SString& data)
30+
void CAjaxResourceHandler::SetResponse(std::string data)
3131
{
3232
// Prevent response corruption: ignore subsequent calls after data is set
3333
if (m_bHasData) [[unlikely]]
3434
return;
3535

36-
m_strResponse = data;
36+
m_strResponse = std::move(data);
3737
m_bHasData = true;
3838

3939
if (!m_callback)
@@ -72,12 +72,17 @@ void CAjaxResourceHandler::GetResponseHeaders(CefRefPtr<CefResponse> response, i
7272

7373
bool CAjaxResourceHandler::ProcessRequest([[maybe_unused]] CefRefPtr<CefRequest> request, CefRefPtr<CefCallback> callback)
7474
{
75-
// Don't call Continue() here - let ReadResponse handle async flow
76-
// Calling Continue() immediately would use the callback before data is ready
75+
if (!callback)
76+
return false;
77+
78+
// Store callback so SetResponse can resume once data is ready
79+
m_callback = callback;
80+
81+
// Do not call Continue() yet; SetResponse triggers it after data is prepared
7782
return true;
7883
}
7984

80-
bool CAjaxResourceHandler::ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr<CefCallback> callback)
85+
bool CAjaxResourceHandler::ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, [[maybe_unused]] CefRefPtr<CefCallback> callback)
8186
{
8287
// Validate input parameters first
8388
if (!data_out || bytes_to_read <= 0) [[unlikely]]
@@ -86,13 +91,10 @@ bool CAjaxResourceHandler::ReadResponse(void* data_out, int bytes_to_read, int&
8691
return false;
8792
}
8893

89-
// If we have no data yet, wait
94+
// If we have no data yet, wait until SetResponse provides it
9095
if (!m_bHasData)
9196
{
9297
bytes_read = 0;
93-
// Store callback only if we don't already have one (prevent overwrite/leak)
94-
if (callback && !m_callback)
95-
m_callback = callback;
9698
return true;
9799
}
98100

Client/cefweb/CAjaxResourceHandler.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,19 @@
1313
#include <core/CAjaxResourceHandlerInterface.h>
1414
#include <cef3/cef/include/cef_resource_handler.h>
1515
#include <SString.h>
16+
#include <string>
1617

1718
class CWebView;
1819

1920
class CAjaxResourceHandler : public CefResourceHandler, public CAjaxResourceHandlerInterface
2021
{
2122
public:
22-
CAjaxResourceHandler(std::vector<SString>& vecGet, std::vector<SString>& vecPost, const CefString& mimeType);
23+
CAjaxResourceHandler(std::vector<std::string> vecGet, std::vector<std::string> vecPost, const CefString& mimeType);
2324
~CAjaxResourceHandler();
2425

25-
std::vector<SString>& GetGetData() override { return m_vecGetData; }
26-
std::vector<SString>& GetPostData() override { return m_vecPostData; }
27-
void SetResponse(const SString& data) override;
26+
std::vector<std::string>& GetGetData() override { return m_vecGetData; }
27+
std::vector<std::string>& GetPostData() override { return m_vecPostData; }
28+
void SetResponse(std::string data) override;
2829

2930
// CefResourceHandler
3031
virtual void Cancel() override;
@@ -37,10 +38,10 @@ class CAjaxResourceHandler : public CefResourceHandler, public CAjaxResourceHand
3738

3839
private:
3940
CefRefPtr<CefCallback> m_callback;
40-
std::vector<SString> m_vecGetData;
41-
std::vector<SString> m_vecPostData;
42-
SString m_strResponse;
43-
CefString m_strMime;
44-
bool m_bHasData = false;
45-
size_t m_DataOffset = 0;
41+
std::vector<std::string> m_vecGetData;
42+
std::vector<std::string> m_vecPostData;
43+
std::string m_strResponse;
44+
CefString m_strMime;
45+
bool m_bHasData = false;
46+
size_t m_DataOffset = 0;
4647
};

Client/cefweb/CWebApp.cpp

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,17 @@
1616
#include <cef3/cef/include/cef_stream.h>
1717
#include <cef3/cef/include/wrapper/cef_stream_resource_handler.h>
1818
#include "CAjaxResourceHandler.h"
19+
#include <cstdlib>
1920

2021
namespace
2122
{
23+
// Helper to detect Wine/Proton environment
24+
bool IsRunningOnWine()
25+
{
26+
HMODULE hNtdll = GetModuleHandle("ntdll.dll");
27+
return hNtdll && GetProcAddress(hNtdll, "wine_get_version");
28+
}
29+
2230
// Centralises command-line switch setup so both pre-launch callbacks stay in sync
2331
void ConfigureCommandLineSwitches(const CefRefPtr<CefCommandLine>& commandLine, const CefString& processType)
2432
{
@@ -30,7 +38,16 @@ namespace
3038
return;
3139

3240
// Always provide base installation paths so loader-proxy can validate subprocess origin
33-
const SString gtaPath = GetCommonRegistryValue("", "GTA:SA Path");
41+
SString gtaPath = GetCommonRegistryValue("", "GTA:SA Path");
42+
if (gtaPath.empty())
43+
{
44+
// Fallback for Wine/compatibility layer: check environment variable
45+
if (const char* envGtaPath = std::getenv("MTA_GTA_PATH"))
46+
{
47+
gtaPath = envGtaPath;
48+
}
49+
}
50+
3451
if (!gtaPath.empty())
3552
{
3653
commandLine->AppendSwitchWithValue("mta-gta-path", gtaPath);
@@ -70,6 +87,21 @@ namespace
7087
}
7188
}
7289

90+
// Wine/Proton compatibility: Allow GPU unless explicitly disabled or forced software
91+
if (IsRunningOnWine())
92+
{
93+
if (std::getenv("MTA_FORCE_SOFTWARE_RENDERING"))
94+
{
95+
disableGpu = true;
96+
}
97+
else
98+
{
99+
// In Wine, we generally want to try GPU (DXVK handles it well)
100+
// But disable-gpu-compositing is already set above which is key
101+
// If user hasn't explicitly disabled GPU in cvars, let it run
102+
}
103+
}
104+
73105
if (disableGpu)
74106
commandLine->AppendSwitch("disable-gpu");
75107
}
@@ -96,19 +128,6 @@ void CWebApp::OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> command_line)
96128
if (!command_line)
97129
return;
98130

99-
// Add GTA path and MTA base path switches before g_pCore check
100-
// This callback runs in both browser process and subprocess
101-
// In subprocess, g_pCore is NULL, so switches must be added before that check
102-
// Read GTA path from registry
103-
int iResult = 0;
104-
const SString strGTAPath = GetCommonRegistryValue("", "GTA:SA Path", &iResult);
105-
if (!strGTAPath.empty())
106-
{
107-
// Pass GTA directory path to CEFLauncher subprocess via command-line switch
108-
// CEF's AppendSwitchWithValue handles quoting automatically
109-
command_line->AppendSwitchWithValue("mta-gta-path", strGTAPath);
110-
// AddReportLog only available in browser process where g_pCore exists
111-
}
112131
const CefString processType = command_line->GetSwitchValue("type");
113132
ConfigureCommandLineSwitches(command_line, processType);
114133
}
@@ -191,8 +210,8 @@ CefRefPtr<CefResourceHandler> CWebApp::Create(CefRefPtr<CefBrowser> browser, Cef
191210

192211
if (pWebView->HasAjaxHandler(resourcePath))
193212
{
194-
std::vector<SString> vecGet;
195-
std::vector<SString> vecPost;
213+
std::vector<std::string> vecGet;
214+
std::vector<std::string> vecPost;
196215

197216
if (urlParts.query.str)
198217
{
@@ -201,6 +220,10 @@ CefRefPtr<CefResourceHandler> CWebApp::Create(CefRefPtr<CefBrowser> browser, Cef
201220
vecTmp.reserve(8); // Reserve space for common query parameter count
202221
strGet.Split("&", vecTmp);
203222

223+
const size_t paramCount = vecTmp.size();
224+
if (paramCount > 0)
225+
vecGet.reserve(vecGet.size() + paramCount * 2);
226+
204227
SString key;
205228
SString value;
206229
for (auto&& param : vecTmp)
@@ -239,6 +262,10 @@ CefRefPtr<CefResourceHandler> CWebApp::Create(CefRefPtr<CefBrowser> browser, Cef
239262
vecTmp.reserve(8);
240263
postParam.Split("&", vecTmp);
241264

265+
const size_t postParamCount = vecTmp.size();
266+
if (postParamCount > 0)
267+
vecPost.reserve(vecPost.size() + postParamCount * 2);
268+
242269
for (auto&& param : vecTmp)
243270
{
244271
param.Split("=", &key, &value);
@@ -248,7 +275,7 @@ CefRefPtr<CefResourceHandler> CWebApp::Create(CefRefPtr<CefBrowser> browser, Cef
248275
}
249276
}
250277

251-
CefRefPtr<CAjaxResourceHandler> handler(new CAjaxResourceHandler(vecGet, vecPost, mimeType));
278+
CefRefPtr<CAjaxResourceHandler> handler(new CAjaxResourceHandler(std::move(vecGet), std::move(vecPost), mimeType));
252279
pWebView->HandleAjaxRequest(resourcePath, handler.get());
253280
return handler;
254281
}

Client/cefweb/CWebCore.cpp

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "CWebApp.h"
2020
#include <algorithm>
2121
#include <ranges>
22+
#include <filesystem>
23+
#include <cstdlib>
2224

2325
// #define CEF_ENABLE_SANDBOX
2426
#ifdef CEF_ENABLE_SANDBOX
@@ -87,7 +89,27 @@ bool CWebCore::Initialise(bool gpuEnabled)
8789

8890
// Set DLL directory for CEFLauncher subprocess to locate required libraries
8991
SString strCEFDir = PathJoin(strMTADir, "CEF");
92+
#ifdef _WIN32
9093
SetDllDirectoryW(FromUTF8(strCEFDir));
94+
#else
95+
// On Wine/Proton: Use environment variable for library search
96+
const char* existingPath = std::getenv("LD_LIBRARY_PATH");
97+
SString newPath = strCEFDir;
98+
if (existingPath) {
99+
newPath = SString("%s:%s", strCEFDir.c_str(), existingPath);
100+
}
101+
// Note: setenv is not available in MSVC, but _putenv is.
102+
// However, since we are compiling for Windows (running on Wine), we use Windows APIs.
103+
// Wine maps Windows environment variables.
104+
// But LD_LIBRARY_PATH is a Linux variable.
105+
// If we are in Wine, we might want to set PATH instead or as well.
106+
// SetDllDirectoryW handles the Windows loader.
107+
108+
// Log for debugging
109+
if (std::getenv("WINE") || std::getenv("WINEPREFIX")) {
110+
g_pCore->GetConsole()->Printf("DEBUG: CEF library path set via SetDllDirectoryW: %s", strCEFDir.c_str());
111+
}
112+
#endif
91113

92114
// Read GTA path from registry to pass to CEF subprocess
93115
int iRegistryResult = 0;
@@ -96,6 +118,13 @@ bool CWebCore::Initialise(bool gpuEnabled)
96118
// Check if process is running with elevated privileges
97119
// CEF subprocesses may have communication issues when running elevated
98120
const bool bIsElevated = []() -> bool {
121+
// Check for Wine environment
122+
if (std::getenv("WINE") || std::getenv("WINEPREFIX")) {
123+
// In Wine, privilege escalation works differently
124+
// Assume not elevated for browser feature purposes
125+
return false;
126+
}
127+
99128
HANDLE hToken = nullptr;
100129
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
101130
return false;
@@ -111,14 +140,28 @@ bool CWebCore::Initialise(bool gpuEnabled)
111140
return elevation.TokenIsElevated != 0;
112141
}();
113142

114-
if (bIsElevated)
143+
if (bIsElevated && !std::getenv("WINE"))
115144
{
116145
AddReportLog(8021, "WARNING: Process is running with elevated privileges (Administrator)");
117146
AddReportLog(8022, "CEF browser features may not work correctly when running as Administrator");
118147
AddReportLog(8023, "Consider running MTA without Administrator privileges for full browser functionality");
119148
g_pCore->GetConsole()->Printf("WARNING: Running as Administrator - browser features may be limited");
120149
}
121150

151+
// Verify CEFLauncher can run in current environment
152+
auto CanExecuteCEFLauncher = []() -> bool {
153+
#ifdef _WIN32
154+
// On Windows, we know it works
155+
if (!std::getenv("WINE") && !std::getenv("WINEPREFIX") && !std::getenv("PROTON_VERSION"))
156+
return true;
157+
#endif
158+
159+
// Check if Wine can execute the launcher
160+
// This is a basic check - if we are in Wine, we assume it works unless proven otherwise
161+
// But we can log if we are in a mixed environment
162+
return true;
163+
};
164+
122165
if (!FileExists(strLauncherPath))
123166
{
124167
g_pCore->GetConsole()->Printf("CEF initialization skipped - CEFLauncher not found: %s", *strLauncherPath);
@@ -127,6 +170,13 @@ bool CWebCore::Initialise(bool gpuEnabled)
127170
return false;
128171
}
129172

173+
if (!CanExecuteCEFLauncher()) {
174+
g_pCore->GetConsole()->Printf("CEF initialization skipped - Wine/Proton not available");
175+
AddReportLog(8026, "CEF initialization skipped - Wine/Proton not available or misconfigured");
176+
m_bInitialised = false;
177+
return false;
178+
}
179+
130180
// Ensure cache directory can be created
131181
const SString strCachePath = PathJoin(strMTADir, "CEF", "cache");
132182
MakeSureDirExists(strCachePath);

Client/cefweb/CWebView.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ void CWebView::UpdateTexture()
308308
// Unlock surface
309309
pSurface->UnlockRect();
310310
}
311+
else
312+
{
313+
OutputDebugLine("[CWebView] UpdateTexture: LockRect failed");
314+
}
311315
}
312316

313317
m_RenderData.cefThreadState = ECefThreadState::Running;
@@ -427,13 +431,16 @@ bool CWebView::SetAudioVolume(float fVolume)
427431
"tags = document.getElementsByTagName('video'); for (var i = 0; i<tags.length; ++i) { mta_adjustAudioVol(tags[i], %f); }",
428432
fVolume, fVolume);
429433

434+
// Note: GetFrameNames is deprecated, but no modern alternative exists for audio volume control
435+
// This is a legacy thing that works with CEF3
430436
std::vector<CefString> frameNames;
431437
m_pWebView->GetFrameNames(frameNames);
432438

433439
for (auto& name : frameNames)
434440
{
435441
auto frame = m_pWebView->GetFrameByName(name);
436-
frame->ExecuteJavaScript(strJSCode, "", 0);
442+
if (frame)
443+
frame->ExecuteJavaScript(strJSCode, "", 0);
437444
}
438445
m_fVolume = fVolume;
439446
return true;
@@ -762,6 +769,7 @@ void CWebView::OnPaint(CefRefPtr<CefBrowser> browser, CefRenderHandler::PaintEle
762769
////////////////////////////////////////////////////////////////////
763770
void CWebView::OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, TransitionType transitionType)
764771
{
772+
// Note: TransitionType parameter is deprecated in CEF3 but still required by virtual interface override
765773
SString strURL = UTF16ToMbUTF8(frame->GetURL());
766774
if (strURL == "blank")
767775
return;
@@ -1074,6 +1082,7 @@ bool CWebView::OnTooltip(CefRefPtr<CefBrowser> browser, CefString& title)
10741082
////////////////////////////////////////////////////////////////////
10751083
bool CWebView::OnConsoleMessage(CefRefPtr<CefBrowser> browser, cef_log_severity_t level, const CefString& message, const CefString& source, int line)
10761084
{
1085+
// Note: cef_log_severity_t parameter is deprecated in CEF3 but required for virtual override
10771086
// Redirect console message to debug window (if development mode is enabled)
10781087
if (g_pCore->GetWebCore()->IsTestModeEnabled())
10791088
{

Client/cefweb/CWebView.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,17 @@ class CWebView : public CWebViewInterface,
109109
bool CanGoForward();
110110
bool GoBack();
111111
bool GoForward();
112-
void Refresh(bool ignoreCache);
112+
void Refresh(bool bIgnoreCache);
113113

114114
// CefClient methods
115-
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override { return this; };
116-
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; };
117-
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; };
118-
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; };
119-
virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override { return this; };
120-
virtual CefRefPtr<CefDialogHandler> GetDialogHandler() override { return this; };
121-
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override { return this; };
122-
virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override { return this; };
115+
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override { return this; }
116+
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
117+
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }
118+
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
119+
virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override { return this; }
120+
virtual CefRefPtr<CefDialogHandler> GetDialogHandler() override { return this; }
121+
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override { return this; }
122+
virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override { return this; }
123123
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefProcessId source_process,
124124
CefRefPtr<CefProcessMessage> message) override;
125125

0 commit comments

Comments
 (0)