Skip to content

Commit c277e3c

Browse files
committed
Merge branch 'main' into feat/overhaul-mod-loading-locations
2 parents d8ba5e4 + c7e2d7e commit c277e3c

File tree

10 files changed

+211
-167
lines changed

10 files changed

+211
-167
lines changed

.github/workflows/release.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ jobs:
3232
- name: Build
3333
run: cmake --build build/
3434
- name: Upload launcher build as artifact
35-
uses: actions/upload-artifact@v3
35+
uses: actions/upload-artifact@v4
3636
with:
3737
name: northstar-launcher
3838
path: |
3939
build/game/*.exe
4040
build/game/*.dll
4141
build/game/bin/x64_retail/*.dll
4242
- name: Upload debug build artifact
43-
uses: actions/upload-artifact@v3
43+
uses: actions/upload-artifact@v4
4444
with:
4545
name: launcher-debug-files
4646
path: |
@@ -53,12 +53,12 @@ jobs:
5353
runs-on: ubuntu-22.04
5454
steps:
5555
- name: Download compiled launcher
56-
uses: actions/download-artifact@v3
56+
uses: actions/download-artifact@v4
5757
with:
5858
name: northstar-launcher
5959
path: northstar-launcher
6060
- name: Download compiled launcher
61-
uses: actions/download-artifact@v3
61+
uses: actions/download-artifact@v4
6262
with:
6363
name: launcher-debug-files
6464
path: launcher-debug-files

primedev/mods/autodownload/moddownloader.cpp

+39-18
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ int ModDownloader::ModFetchingProgressCallback(
176176
return 0;
177177
}
178178

179-
std::optional<fs::path> ModDownloader::FetchModFromDistantStore(std::string_view modName, VerifiedModVersion version)
179+
std::tuple<fs::path, bool> ModDownloader::FetchModFromDistantStore(std::string_view modName, VerifiedModVersion version)
180180
{
181181
std::string url = version.downloadLink;
182182
std::string archiveName = fs::path(url).filename().generic_string();
@@ -190,7 +190,7 @@ std::optional<fs::path> ModDownloader::FetchModFromDistantStore(std::string_view
190190
modState.state = DOWNLOADING;
191191

192192
// Download the actual archive
193-
bool failed = false;
193+
bool success = false;
194194
FILE* fp = fopen(downloadPath.generic_string().c_str(), "wb");
195195
CURLcode result;
196196
CURL* easyhandle;
@@ -219,13 +219,14 @@ std::optional<fs::path> ModDownloader::FetchModFromDistantStore(std::string_view
219219
if (result == CURLcode::CURLE_OK)
220220
{
221221
spdlog::info("Mod archive successfully fetched.");
222-
return std::optional<fs::path>(downloadPath);
222+
success = true;
223223
}
224224
else
225225
{
226226
spdlog::error("Fetching mod archive failed: {}", curl_easy_strerror(result));
227-
return std::optional<fs::path>();
228227
}
228+
229+
return {downloadPath, success};
229230
}
230231

231232
bool ModDownloader::IsModLegit(fs::path modPath, std::string_view expectedChecksum)
@@ -399,11 +400,9 @@ int GetModArchiveSize(unzFile file, unz_global_info64 info)
399400
return totalSize;
400401
}
401402

402-
void ModDownloader::ExtractMod(fs::path modPath, VerifiedModPlatform platform)
403+
void ModDownloader::ExtractMod(fs::path modPath, fs::path destinationPath, VerifiedModPlatform platform)
403404
{
404405
unzFile file;
405-
std::string name;
406-
fs::path modDirectory;
407406

408407
file = unzOpen(modPath.generic_string().c_str());
409408
ScopeGuard cleanup(
@@ -445,11 +444,6 @@ void ModDownloader::ExtractMod(fs::path modPath, VerifiedModPlatform platform)
445444
return;
446445
}
447446

448-
// Mod directory name (removing the ".zip" fom the archive name)
449-
name = modPath.filename().string();
450-
name = name.substr(0, name.length() - 4);
451-
modDirectory = GetRemoteModFolderPath() / name;
452-
453447
for (int i = 0; i < gi.number_entry; i++)
454448
{
455449
char zipFilename[256];
@@ -459,7 +453,7 @@ void ModDownloader::ExtractMod(fs::path modPath, VerifiedModPlatform platform)
459453
// Extract file
460454
{
461455
std::error_code ec;
462-
fs::path fileDestination = modDirectory / zipFilename;
456+
fs::path fileDestination = destinationPath / zipFilename;
463457
spdlog::info("=> {}", fileDestination.generic_string());
464458

465459
// Create parent directory if needed
@@ -589,6 +583,9 @@ void ModDownloader::ExtractMod(fs::path modPath, VerifiedModPlatform platform)
589583
}
590584
}
591585
}
586+
587+
// Mod extraction went fine
588+
modState.state = DONE;
592589
}
593590

594591
void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
@@ -603,11 +600,14 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
603600
std::thread requestThread(
604601
[this, modName, modVersion]()
605602
{
603+
std::string name;
606604
fs::path archiveLocation;
605+
fs::path modDirectory;
607606

608607
ScopeGuard cleanup(
609608
[&]
610609
{
610+
// Remove downloaded archive
611611
try
612612
{
613613
remove(archiveLocation);
@@ -617,14 +617,31 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
617617
spdlog::error("Error while removing downloaded archive: {}", a.what());
618618
}
619619

620+
// Remove mod if auto-download process failed
621+
if (modState.state != DONE)
622+
{
623+
try
624+
{
625+
remove_all(modDirectory);
626+
}
627+
catch (const std::exception& e)
628+
{
629+
spdlog::error("Error while removing downloaded mod: {}", e.what());
630+
}
631+
}
632+
620633
spdlog::info("Done cleaning after downloading {}.", modName);
621634
});
622635

623636
// Download mod archive
624637
VerifiedModVersion fullVersion = verifiedMods[modName].versions[modVersion];
625638
std::string expectedHash = fullVersion.checksum;
626-
std::optional<fs::path> fetchingResult = FetchModFromDistantStore(std::string_view(modName), fullVersion);
627-
if (!fetchingResult.has_value())
639+
640+
const std::tuple<fs::path, bool> downloadResult = FetchModFromDistantStore(std::string_view(modName), fullVersion);
641+
archiveLocation = get<0>(downloadResult);
642+
bool downloadSuccessful = get<1>(downloadResult);
643+
644+
if (!downloadSuccessful)
628645
{
629646
spdlog::error("Something went wrong while fetching archive, aborting.");
630647
if (modState.state != ABORTED)
@@ -633,17 +650,21 @@ void ModDownloader::DownloadMod(std::string modName, std::string modVersion)
633650
}
634651
return;
635652
}
636-
archiveLocation = fetchingResult.value();
653+
637654
if (!IsModLegit(archiveLocation, std::string_view(expectedHash)))
638655
{
639656
spdlog::warn("Archive hash does not match expected checksum, aborting.");
640657
modState.state = MOD_CORRUPTED;
641658
return;
642659
}
643660

661+
// Mod directory name (removing the ".zip" fom the archive name)
662+
name = archiveLocation.filename().string();
663+
name = name.substr(0, name.length() - 4);
664+
modDirectory = GetRemoteModFolderPath() / name;
665+
644666
// Extract downloaded mod archive
645-
ExtractMod(archiveLocation, fullVersion.platform);
646-
modState.state = DONE;
667+
ExtractMod(archiveLocation, modDirectory, fullVersion.platform);
647668
});
648669

649670
requestThread.detach();

primedev/mods/autodownload/moddownloader.h

+7-7
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,12 @@ class ModDownloader
4343
* input mod name as mod dependency string if bypass flag is set up; fetched
4444
* archive is then stored in a temporary location.
4545
*
46-
* If something went wrong during archive download, this will return an empty
47-
* optional object.
4846
*
4947
* @param modName name of the mod to be downloaded
5048
* @param modVersion version of the mod to be downloaded
51-
* @returns location of the downloaded archive
49+
* @returns tuple containing location of the downloaded archive and whether download completed successfully
5250
*/
53-
std::optional<fs::path> FetchModFromDistantStore(std::string_view modName, VerifiedModVersion modVersion);
51+
std::tuple<fs::path, bool> FetchModFromDistantStore(std::string_view modName, VerifiedModVersion modVersion);
5452

5553
/**
5654
* Tells if a mod archive has not been corrupted.
@@ -69,14 +67,16 @@ class ModDownloader
6967
/**
7068
* Extracts a mod archive to the game folder.
7169
*
72-
* This extracts a downloaded mod archive from its original location to the
73-
* current game profile; the install folder is defined by the platform parameter.
70+
* This extracts a downloaded mod archive from its original location, `modPath`,
71+
* to the specified `destinationPath`; the way to decompress the archive is
72+
* defined by the `platform` parameter.
7473
*
7574
* @param modPath location of the downloaded archive
75+
* @param destinationPath destination of the extraction
7676
* @param platform origin of the downloaded archive
7777
* @returns nothing
7878
*/
79-
void ExtractMod(fs::path modPath, VerifiedModPlatform platform);
79+
void ExtractMod(fs::path modPath, fs::path destinationPath, VerifiedModPlatform platform);
8080

8181
public:
8282
ModDownloader();

0 commit comments

Comments
 (0)