Synchronize the client and select installed language packs #3
@@ -98,6 +98,8 @@ or local-only API URLs.
|
||||
plus legacy `WoW.exe` and DLLs directly in the installation root or `WoW`.
|
||||
Remove unused Data subdirectories only after their children, without recursive
|
||||
deletion. Preserve unrelated files and user state outside these areas.
|
||||
- Language archives under `Data/ruRU` or `WoW/Data/ruRU` use the regular manifest sync.
|
||||
Pass `WOW_LOCALE=auto` to the game so its selected install determines the locale.
|
||||
- Downloads must write to `*.moonwell.part`, verify size and SHA-256, then
|
||||
replace the destination file only after successful verification.
|
||||
- Local scans should ignore volatile client directories and launcher metadata:
|
||||
|
||||
@@ -73,6 +73,12 @@ folder. For builds that pin an endpoint, set
|
||||
`--dart-define=MOONWELL_AUTH_ADDRESS=login.example:3724` instead. This endpoint is
|
||||
the vMaNGOS auth server, separate from the realm's world port and the Web API.
|
||||
|
||||
Russian 1.12.1 language archives are regular manifest files under `Data/ruRU`
|
||||
(or `WoW/Data/ruRU` for a nested install). They are downloaded and verified with
|
||||
the same size and SHA-256 checks as the base client. The launcher passes
|
||||
`WOW_LOCALE=auto` to the game: an installed pack selects Russian, and a base-only
|
||||
install selects English, regardless of the launcher's inherited environment.
|
||||
|
||||
Example run command:
|
||||
|
||||
```powershell
|
||||
|
||||
@@ -286,6 +286,8 @@ When the user presses `Play`:
|
||||
- `WOW_HOST=<auth-address>`
|
||||
- `WOW_DATA=<absolute-data-directory>`
|
||||
- `BENILLA_HOME=<install-root>/benilla-config`
|
||||
- `WOW_LOCALE=auto` (select the installed `Data/ruRU` or `WoW/Data/ruRU` language pack,
|
||||
otherwise English; override any locale inherited from the launcher's parent)
|
||||
6. launcher retains a process handle; while the process is alive, it disables repeated game launches
|
||||
and client synchronization
|
||||
7. when the process exits, the launcher returns to the ready-to-play state
|
||||
@@ -297,6 +299,10 @@ If the executable, data directory, or auth endpoint is missing or invalid,
|
||||
launch fails with an error. A consumed ticket cannot authenticate again; close
|
||||
the client and press Play for a fresh ticket after a session ends.
|
||||
|
||||
Language archives are ordinary client-manifest entries, including their nested paths,
|
||||
sizes and SHA-256 hashes. Synchronization verifies and retains required `ruRU` files
|
||||
and removes obsolete archives under the same manifest-authoritative Data policy.
|
||||
|
||||
## Error Behavior
|
||||
|
||||
The launcher surfaces errors for:
|
||||
|
||||
@@ -304,6 +304,8 @@ class GameInstallationService {
|
||||
'WOW_PASS': authorization.ticket,
|
||||
'WOW_HOST': authAddress,
|
||||
'WOW_DATA': dataPath,
|
||||
// Let the client select Data/ruRU independently of the launcher's parent environment.
|
||||
'WOW_LOCALE': 'auto',
|
||||
'BENILLA_HOME': p.join(rootPath, 'benilla-config'),
|
||||
},
|
||||
);
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.5+8
|
||||
version: 1.0.7+10
|
||||
|
||||
environment:
|
||||
sdk: ">=3.10.0"
|
||||
|
||||
@@ -421,6 +421,7 @@ void main() {
|
||||
'WOW_PASS': 'A1B2C3D4E5F6G7H8',
|
||||
'WOW_HOST': '127.0.0.1:3724',
|
||||
'WOW_DATA': '${rootDirectory.path}${Platform.pathSeparator}Data',
|
||||
'WOW_LOCALE': 'auto',
|
||||
'BENILLA_HOME':
|
||||
'${rootDirectory.path}${Platform.pathSeparator}benilla-config',
|
||||
});
|
||||
@@ -479,6 +480,46 @@ void main() {
|
||||
expect(recordingService.environment?['WOW_DATA'], nestedData.path);
|
||||
});
|
||||
|
||||
test('verifies and retains Russian archives before launching', () async {
|
||||
final paths = [
|
||||
'MoonWell.exe',
|
||||
'Data/common.MPQ',
|
||||
'Data/ruRU/patch-1.MPQ',
|
||||
'Data/ruRU/patch-2.MPQ',
|
||||
'Data/ruRU/patch-3.MPQ',
|
||||
];
|
||||
for (final path in paths.skip(2)) {
|
||||
final file = File(service.resolveClientPath(rootDirectory.path, path));
|
||||
await file.parent.create(recursive: true);
|
||||
await file.writeAsString('localized archive: $path');
|
||||
}
|
||||
final manifest = await _manifestForPaths(service, rootDirectory, paths);
|
||||
final snapshot = await service.scanInstallation(
|
||||
rootDirectory.path,
|
||||
manifest: manifest,
|
||||
);
|
||||
expect(snapshot.buildHash, manifest.buildHash);
|
||||
expect(snapshot.stalePaths, isEmpty);
|
||||
final recordingService = _RecordingGameInstallationService();
|
||||
await recordingService.launchGame(
|
||||
rootDirectory.path,
|
||||
authorization: _validTicket(),
|
||||
);
|
||||
expect(recordingService.environment?['WOW_LOCALE'], 'auto');
|
||||
expect(
|
||||
recordingService.environment?['WOW_DATA'],
|
||||
'${rootDirectory.path}${Platform.pathSeparator}Data',
|
||||
);
|
||||
for (final path in paths.skip(2)) {
|
||||
expect(
|
||||
await File(
|
||||
service.resolveClientPath(rootDirectory.path, path),
|
||||
).readAsString(),
|
||||
'localized archive: $path',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('configured auth address overrides the install realmlist', () async {
|
||||
final configured = _RecordingGameInstallationService(
|
||||
authAddress: 'login.example:3725',
|
||||
|
||||
Reference in New Issue
Block a user