Skip to content

Commit

Permalink
fix(game/cli): use correct build with interned shortcut
Browse files Browse the repository at this point in the history
Followup fix for:
ebdb92d

Reported in: #3015

After changing the build flag parsing startegy, build flag in internet
shortcut started to get ignored. This is because we replaced general
search through the CLI string with exact arcgument match.

Parse internet stortcut flags and append the build flag as a separate
argument to CLI. If at some point we decide to refactor parsing for all
CLI flags (not just build and pure mode) - we should extract those flags
from internet shortcut string as well.
  • Loading branch information
Nobelium-cfx committed Dec 18, 2024
1 parent c970038 commit c8c2815
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 14 deletions.
56 changes: 42 additions & 14 deletions code/client/launcher/CrossBuildLaunch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,75 @@
#include <CrossBuildRuntime.h>

#include <shellapi.h>
#include <string>
#include <sstream>

void XBR_EarlySelect()
{
// we *can't* call xbr:: APIs here since they'll `static`-initialize and break GameCache later
uint32_t builds[] = {
#define EXPAND(_, __, x) x,
std::wstring_view builds[] = {
#define EXPAND(_, __, x) \
BOOST_PP_WSTRINGIZE(BOOST_PP_CAT(-b, x)),

BOOST_PP_SEQ_FOR_EACH(EXPAND, , GAME_BUILDS)
#undef EXPAND
};

bool buildFlagFound = false;

auto state = CfxState::Get();
const auto realCli = (state->initCommandLine[0]) ? state->initCommandLine : GetCommandLineW();

bool buildFlagFound = false;
std::wstring connectionBuildArg;

int argc;
wchar_t** wargv = CommandLineToArgvW(realCli, &argc);
for (int i = 1; i < argc; i++)
{
std::wstring_view arg = wargv[i];

for (uint32_t build : builds)
if (arg.find(L"://connect/") != std::wstring_view::npos)
{
std::wstringstream ss(arg.data());
std::wstring connectionArg;
while (std::getline(ss, connectionArg, L'?'))
{
if (connectionArg.find(L"-b") == 0)
{
connectionBuildArg = connectionArg;
}
}
}

for (auto build : builds)
{
if (arg == fmt::sprintf(L"-b%d", build).c_str())
if (arg == build)
{
buildFlagFound = true;
break;
}
}
}
LocalFree(wargv);

if (!buildFlagFound && state->IsMasterProcess())
if (buildFlagFound || !state->IsMasterProcess())
{
std::wstring fpath = MakeRelativeCitPath(L"CitizenFX.ini");
auto retainedBuild = GetPrivateProfileInt(L"Game", L"SavedBuildNumber", xbr::GetDefaultGameBuild(), fpath.c_str());
return;
}

// If there is no explicit build flag and retained build is not default - add flag to command line.
if (retainedBuild != xbr::GetDefaultGameBuild())
{
wcscat(state->initCommandLine, va(L" -b%d", retainedBuild));
}
if (!connectionBuildArg.empty())
{
wcscat(state->initCommandLine, L" ");
wcscat(state->initCommandLine, connectionBuildArg.c_str());
return;
}

std::wstring fpath = MakeRelativeCitPath(L"CitizenFX.ini");
auto retainedBuild = GetPrivateProfileInt(L"Game", L"SavedBuildNumber", xbr::GetDefaultGameBuild(), fpath.c_str());

// If there is no explicit build flag and retained build is not default - add flag to command line.
if (retainedBuild != xbr::GetDefaultGameBuild())
{
wcscat(state->initCommandLine, va(L" -b%d", retainedBuild));
}
}
#endif
1 change: 1 addition & 0 deletions code/client/shared/PureModeState.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ inline int GetPureLevel()
break;
}
}
LocalFree(wargv);

return pureLevel;
}
Expand Down
1 change: 1 addition & 0 deletions code/client/shared/XBRInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ int GetRequestedGameBuildInit()
}
}
}
LocalFree(wargv);

return buildNumber;
}
Expand Down

0 comments on commit c8c2815

Please sign in to comment.