Skip to content

Commit 906e6ef

Browse files
committed
fix(core): fix custom locale.json broken by the sandboxed ScRT
1 parent 7bd5f0e commit 906e6ef

5 files changed

Lines changed: 56 additions & 22 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ monitor-*.zip
1111
bundle_size_report.html
1212
.github/.cienv
1313
scripts/**/*.local.*
14+
.runtime/
1415

1516
# IDE Specific
1617
.idea

core/modules/FxRunner/index.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { resolveCFGFilePath, validateFixServerConfig } from '@lib/fxserver/fxsCo
88
import { msToShortishDuration } from '@lib/misc';
99
import { SYM_SYSTEM_AUTHOR } from '@lib/symbols';
1010
import { UpdateConfigKeySet } from '@modules/ConfigStore/utils';
11-
import { childProcessEventBlackHole, getFxSpawnVariables, getMutableConvars, isValidChildProcess, mutableConvarConfigDependencies, stringifyConsoleArgs } from './utils';
11+
import { childProcessEventBlackHole, getFxSpawnVariables, getMutableConvars, isValidChildProcess, mutableConvarConfigDependencies, setupCustomLocaleFile, stringifyConsoleArgs } from './utils';
1212
import ProcessManager, { ChildProcessStateInfo } from './ProcessManager';
1313
import handleFd3Messages from './handleFd3Messages';
1414
import ConsoleLineEnum from '@modules/Logger/FXServerLogger/ConsoleLineEnum';
@@ -41,7 +41,7 @@ export default class FxRunner {
4141
* Triggers a convar update
4242
*/
4343
public handleConfigUpdate(updatedConfigs: UpdateConfigKeySet) {
44-
this.updateMutableConvars();
44+
this.updateMutableConvars().catch(() => { });
4545
}
4646

4747

@@ -116,7 +116,7 @@ export default class FxRunner {
116116
return msg;
117117
}
118118

119-
//Setup spawn variables
119+
//Setup spawn variables & locale file
120120
let fxSpawnVars;
121121
const newServerMutex = genMutex();
122122
try {
@@ -128,6 +128,13 @@ export default class FxRunner {
128128
console.error(errMsg);
129129
return errMsg;
130130
}
131+
try {
132+
await setupCustomLocaleFile();
133+
} catch (error) {
134+
const errMsg = `Error copying custom locale: ${(error as any).message}`;
135+
console.error(errMsg);
136+
return errMsg;
137+
}
131138

132139
//If there is any FXServer configuration missing
133140
if (!this.isConfigured) {
@@ -355,9 +362,10 @@ export default class FxRunner {
355362
* Useful for when we change txAdmin settings and want it to reflect on the server.
356363
* This will also fire the `txAdmin:event:configChanged`
357364
*/
358-
private updateMutableConvars() {
365+
private async updateMutableConvars() {
359366
console.log('Updating FXServer ConVars.');
360367
try {
368+
await setupCustomLocaleFile();
361369
const convarList = getMutableConvars(false);
362370
for (const [set, convar, value] of convarList) {
363371
this.sendCommand(set, [convar, value], SYM_SYSTEM_AUTHOR);

core/modules/FxRunner/utils.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import fsp from 'node:fs/promises';
12
import type { ChildProcessWithoutNullStreams } from "node:child_process";
23
import { Readable, Writable } from "node:stream";
34
import { txEnv, txHostConfig } from "@core/globalData";
@@ -28,7 +29,6 @@ export const getMutableConvars = (isCmdLine = false) => {
2829
const checkPlayerJoin = txConfig.banlist.enabled || txConfig.whitelist.mode !== 'disabled';
2930
const convars: RawConvarSetTuple[] = [
3031
['setr', 'locale', txConfig.general.language ?? 'en'],
31-
['set', 'localeFile', txCore.translator.customLocalePath],
3232
['set', 'serverName', txConfig.general.serverName ?? 'txAdmin'],
3333
['set', 'checkPlayerJoin', checkPlayerJoin],
3434
['set', 'menuAlignRight', txConfig.gameFeatures.menuAlignRight],
@@ -220,3 +220,28 @@ export const stringifyConsoleArgs = (args: (string | number | object)[]) => {
220220

221221
return cleanArgs.join(' ');
222222
}
223+
224+
225+
/**
226+
* Copies the custom locale file from txData to the 'monitor' path, due to sandboxing.
227+
*/
228+
export const setupCustomLocaleFile = async () => {
229+
const srcPath = txCore.translator.customLocalePath;
230+
const destRuntimePath = path.resolve(txEnv.txaPath, '.runtime');
231+
const destFilePath = path.resolve(destRuntimePath, 'locale.json');
232+
const isCustomLocale = txConfig.general.language === 'custom';
233+
const action = isCustomLocale ? 'copy' : 'remove';
234+
try {
235+
if (txConfig.general.language === 'custom') {
236+
await fsp.mkdir(destRuntimePath, { recursive: true });
237+
await fsp.copyFile(srcPath, destFilePath);
238+
} else {
239+
await fsp.unlink(destFilePath);
240+
}
241+
} catch (error) {
242+
const logger = isCustomLocale
243+
? console.tag('FXRunner').error
244+
: console.tag('FXRunner').verbose.warn;
245+
logger(`Failed to ${action} custom locale file: ${(error as any).message}`);
246+
}
247+
}

docs/dev-notes.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,10 @@ Legend:
109109
## Other stuff
110110
- [x] new env vars
111111
- [x] remove dynamicAds from the modules
112+
- [x] fix custom locale
112113
- [!] add stats tracking for the framework team (ask them, idk)
113114
- [!] package updates - test radix stuff
114115
- [!] commit stashed stuff
115-
- [!] fix custom locale
116-
- see if it's viable to use `fsp.link()` or `fsp.symlink()`
117-
- https://nodejs.org/docs/latest-v16.x/api/fs.html#fspromiseslinkexistingpath-newpath
118-
- https://nodejs.org/docs/latest-v16.x/api/fs.html#fspromisessymlinktarget-path-type
119116
- [!] check txAdmin-private
120117
- [ ] implement `cleanFullPath.ts` in settings save ui & api for comparison consistency
121118
- [ ] add it to `setup/save.js -> handleValidateLocalDataFolder()` as well

resource/sv_ctx.lua

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ local ServerCtxObj = {
1919
announceNotiPos = '', -- top-center, top-right, top-left, bottom-center, bottom-right, bottom-left
2020
}
2121

22-
local function getCustomLocaleData()
23-
--Get convar
24-
local filePath = GetConvar('txAdmin-localeFile', 'false')
25-
if filePath == 'false' then
26-
return false
27-
end
22+
-- local function getRawCustomLocaleData()
23+
-- LoadResourceFile('monitor', '.runtime/locale.json', function(fileData)
24+
-- if not fileData then
25+
-- txPrint('^2Loaded custom locale file.')
26+
-- else
27+
-- txPrint('^1WARNING: failed to load custom locale from path: '..filePath)
28+
-- end
29+
-- end)
30+
31+
-- return fileData
32+
-- end
2833

29-
-- Get file data
30-
local fileHandle = io.open(filePath, "rb")
31-
if not fileHandle then
32-
txPrint('^1WARNING: failed to load custom locale from path: '..filePath)
34+
local function getCustomLocaleData()
35+
local fileData = LoadResourceFile('monitor', '.runtime/locale.json')
36+
if type(fileData) ~="string" then
37+
txPrint('^1WARNING: failed to load custom \'locale.json\' file.')
3338
return false
3439
end
35-
local fileData = fileHandle:read "*a"
36-
fileHandle:close()
3740

3841
-- Parse and validate data
3942
local locale = json.decode(fileData)
@@ -43,7 +46,7 @@ local function getCustomLocaleData()
4346
or type(locale['nui_warning']) ~= "table"
4447
or type(locale['nui_menu']) ~= "table"
4548
then
46-
txPrint('^1WARNING: load or validate custom locale JSON data from path: '..filePath)
49+
txPrint('^1WARNING: failed to validate custom locale JSON.')
4750
return false
4851
end
4952

0 commit comments

Comments
 (0)