a52c81e270
**Before merging: Please test on a real Windows installation if possible!**
I tested this on Linux as well as inside a Windows VM hosted on Linux, but wasn't able to test it on a real Windows installation.
This commit fixes an issue with loading bundles from a native Linux server:
When compiling the server natively for Linux & installing some mods, everything works except for mods trying to load bundles from the server. Reason is a malformed path to the bundle:
```ts
2024-07-30 23:48:16.968 +02:00|0.14.9.1.30626|Error|Default|
EXCEPTION: System.IO.DirectoryNotFoundException: Could not find a part of the path "C:\home\USER\Games\escape-from-tarkov\drive_c\SPTarkov\user\mods\Bloody-Bullet-Wounds\bundles\assets\systems\effects\particlesystems\effects.bundle".
```
`process.cwd()` returns the linux-agnostic path of course, but for some reason it also returns `C:`.
Changing the line to `modpath.slice(0, -1).replace(/\\/g, "/");` seems to work and the bundles seem to get loaded without issues (did a quick test raid), even without passing the absolute path to the mod.
I tried to check why that is, and I think node is able to [get the cwd and resolve the relative path](4d1d88118b/src/path.cc (L101)
) by itself..
Reviewed-on: https://dev.sp-tarkov.com/SPT/Server/pulls/389
Co-authored-by: MadByte <madbyte@noreply.dev.sp-tarkov.com>
Co-committed-by: MadByte <madbyte@noreply.dev.sp-tarkov.com>
(cherry picked from commit 6f010acfca8ec57105a3cd3bc959ed61be206e13)
84 lines
2.6 KiB
TypeScript
84 lines
2.6 KiB
TypeScript
import path from "node:path";
|
|
import { HttpServerHelper } from "@spt/helpers/HttpServerHelper";
|
|
import { BundleHashCacheService } from "@spt/services/cache/BundleHashCacheService";
|
|
import { JsonUtil } from "@spt/utils/JsonUtil";
|
|
import { VFS } from "@spt/utils/VFS";
|
|
import { ICloner } from "@spt/utils/cloners/ICloner";
|
|
import { inject, injectable } from "tsyringe";
|
|
|
|
export class BundleInfo {
|
|
modpath: string;
|
|
filename: string;
|
|
crc: number;
|
|
dependencies: string[];
|
|
|
|
constructor(modpath: string, bundle: BundleManifestEntry, bundleHash: number) {
|
|
this.modpath = modpath;
|
|
this.filename = bundle.key;
|
|
this.crc = bundleHash;
|
|
this.dependencies = bundle.dependencyKeys || [];
|
|
}
|
|
}
|
|
|
|
@injectable()
|
|
export class BundleLoader {
|
|
protected bundles: Record<string, BundleInfo> = {};
|
|
|
|
constructor(
|
|
@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper,
|
|
@inject("VFS") protected vfs: VFS,
|
|
@inject("JsonUtil") protected jsonUtil: JsonUtil,
|
|
@inject("BundleHashCacheService") protected bundleHashCacheService: BundleHashCacheService,
|
|
@inject("PrimaryCloner") protected cloner: ICloner,
|
|
) {}
|
|
|
|
/**
|
|
* Handle singleplayer/bundles
|
|
*/
|
|
public getBundles(): BundleInfo[] {
|
|
const result: BundleInfo[] = [];
|
|
|
|
for (const bundle in this.bundles) {
|
|
result.push(this.getBundle(bundle));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public getBundle(key: string): BundleInfo {
|
|
return this.cloner.clone(this.bundles[key]);
|
|
}
|
|
|
|
public addBundles(modpath: string): void {
|
|
const bundleManifestArr = this.jsonUtil.deserialize<BundleManifest>(
|
|
this.vfs.readFile(`${modpath}bundles.json`),
|
|
).manifest;
|
|
|
|
for (const bundleManifest of bundleManifestArr) {
|
|
const relativeModPath = modpath.slice(0, -1).replace(/\\/g, "/");
|
|
const bundleLocalPath = `${modpath}bundles/${bundleManifest.key}`.replace(/\\/g, "/");
|
|
|
|
if (!this.bundleHashCacheService.calculateAndMatchHash(bundleLocalPath)) {
|
|
this.bundleHashCacheService.calculateAndStoreHash(bundleLocalPath);
|
|
}
|
|
|
|
const bundleHash = this.bundleHashCacheService.getStoredValue(bundleLocalPath);
|
|
|
|
this.addBundle(bundleManifest.key, new BundleInfo(relativeModPath, bundleManifest, bundleHash));
|
|
}
|
|
}
|
|
|
|
public addBundle(key: string, b: BundleInfo): void {
|
|
this.bundles[key] = b;
|
|
}
|
|
}
|
|
|
|
export interface BundleManifest {
|
|
manifest: BundleManifestEntry[];
|
|
}
|
|
|
|
export interface BundleManifestEntry {
|
|
key: string;
|
|
dependencyKeys: string[];
|
|
}
|