Formatting for utils.

This commit is contained in:
Refringe 2023-11-13 11:14:58 -05:00
parent 8576929404
commit 4479f68388
No known key found for this signature in database
GPG Key ID: 64E03E5F892C6F9E
21 changed files with 354 additions and 284 deletions

View File

@ -19,9 +19,9 @@ export class App
@inject("LocalisationService") protected localisationService: LocalisationService,
@inject("EncodingUtil") protected encodingUtil: EncodingUtil,
@injectAll("OnLoad") protected onLoadComponents: OnLoad[],
@injectAll("OnUpdate") protected onUpdateComponents: OnUpdate[]
@injectAll("OnUpdate") protected onUpdateComponents: OnUpdate[],
)
{ }
{}
public async load(): Promise<void>
{
@ -73,7 +73,9 @@ export class App
if (success === void 0 && !(secondsSinceLastRun % warnTime))
{
this.logger.debug(this.localisationService.getText("route_onupdate_no_response", updateable.getRoute()));
this.logger.debug(
this.localisationService.getText("route_onupdate_no_response", updateable.getRoute()),
);
}
}
}

View File

@ -20,7 +20,7 @@ export class AsyncQueue implements IAsyncQueue
// eslint-disable-next-line no-constant-condition
while (this.commandsQueue[0].uuid !== command.uuid)
{
await new Promise<void>(resolve =>
await new Promise<void>((resolve) =>
{
setTimeout(resolve, 100);
});

View File

@ -33,7 +33,7 @@ export class DatabaseImporter implements OnLoad
@inject("EncodingUtil") protected encodingUtil: EncodingUtil,
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("ImporterUtil") protected importerUtil: ImporterUtil,
@inject("ConfigServer") protected configServer: ConfigServer
@inject("ConfigServer") protected configServer: ConfigServer,
)
{
this.httpConfig = this.configServer.getConfig(ConfigTypes.HTTP);
@ -45,9 +45,9 @@ export class DatabaseImporter implements OnLoad
*/
public getSptDataPath(): string
{
return (globalThis.G_RELEASE_CONFIGURATION)
? "Aki_Data/Server/"
: "./assets/";
return (globalThis.G_RELEASE_CONFIGURATION) ?
"Aki_Data/Server/" :
"./assets/";
}
public async onLoad(): Promise<void>
@ -63,7 +63,10 @@ export class DatabaseImporter implements OnLoad
const fileWithPath = `${this.filepath}${file}`;
if (this.vfs.exists(fileWithPath))
{
this.hashedFile = this.jsonUtil.deserialize(this.encodingUtil.fromBase64(this.vfs.readFile(fileWithPath)), file);
this.hashedFile = this.jsonUtil.deserialize(
this.encodingUtil.fromBase64(this.vfs.readFile(fileWithPath)),
file,
);
}
else
{
@ -88,7 +91,7 @@ export class DatabaseImporter implements OnLoad
"/files/Hideout/",
"/files/launcher/",
"/files/quest/icon/",
"/files/trader/avatar/"
"/files/trader/avatar/",
]);
}
@ -103,10 +106,12 @@ export class DatabaseImporter implements OnLoad
const dataToImport = await this.importerUtil.loadAsync<IDatabaseTables>(
`${filepath}database/`,
this.filepath,
(fileWithPath: string, data: string) => this.onReadValidate(fileWithPath, data)
(fileWithPath: string, data: string) => this.onReadValidate(fileWithPath, data),
);
const validation = (this.valid === VaildationResult.FAILED || this.valid === VaildationResult.NOT_FOUND) ? "." : "";
const validation = (this.valid === VaildationResult.FAILED || this.valid === VaildationResult.NOT_FOUND) ?
"." :
"";
this.logger.info(`${this.localisationService.getText("importing_database_finish")}${validation}`);
this.databaseServer.setTables(dataToImport);
}
@ -115,7 +120,9 @@ export class DatabaseImporter implements OnLoad
{
// Validate files
if (globalThis.G_RELEASE_CONFIGURATION && this.hashedFile && !this.validateFile(fileWithPath, data))
{
this.valid = VaildationResult.FAILED;
}
}
public getRoute(): string
@ -132,9 +139,13 @@ export class DatabaseImporter implements OnLoad
for (const prop of finalPath.split("/"))
{
if (!tempObject)
{
tempObject = this.hashedFile[prop];
}
else
{
tempObject = tempObject[prop];
}
}
if (tempObject !== this.hashUtil.generateSha1ForData(fileData))
@ -196,9 +207,9 @@ export class DatabaseImporter implements OnLoad
}
enum VaildationResult
{
{
SUCCESS = 0,
FAILED = 1,
NOT_FOUND = 2,
UNDEFINED = 3
UNDEFINED = 3,
}

View File

@ -3,7 +3,6 @@ import { injectable } from "tsyringe";
@injectable()
export class EncodingUtil
{
public encode(value: string, encode: EncodeType): string
{
return Buffer.from(value).toString(encode);
@ -33,14 +32,13 @@ export class EncodingUtil
{
return this.encode(value, EncodeType.HEX);
}
}
export enum EncodeType
{
{
BASE64 = "base64",
HEX = "hex",
ASCII = "ascii",
BINARY = "binary",
UTF8 = "utf8"
UTF8 = "utf8",
}

View File

@ -7,9 +7,9 @@ import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export class HashUtil
{
constructor(
@inject("TimeUtil") protected timeUtil: TimeUtil
@inject("TimeUtil") protected timeUtil: TimeUtil,
)
{ }
{}
/**
* Create a 24 character id using the sha256 algorithm + current timestamp

View File

@ -8,7 +8,7 @@ import { HttpServerHelper } from "@spt-aki/helpers/HttpServerHelper";
export class HttpFileUtil
{
constructor(
@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper
@inject("HttpServerHelper") protected httpServerHelper: HttpServerHelper,
)
{
}
@ -16,10 +16,11 @@ export class HttpFileUtil
public sendFile(resp: ServerResponse, file: any): void
{
const pathSlic = file.split("/");
const type = this.httpServerHelper.getMimeText(pathSlic[pathSlic.length - 1].split(".").at(-1)) || this.httpServerHelper.getMimeText("txt");
const type = this.httpServerHelper.getMimeText(pathSlic[pathSlic.length - 1].split(".").at(-1)) ||
this.httpServerHelper.getMimeText("txt");
const fileStream = fs.createReadStream(file);
fileStream.on("open", function ()
fileStream.on("open", function()
{
resp.setHeader("Content-Type", type);
fileStream.pipe(resp);

View File

@ -10,12 +10,11 @@ import { JsonUtil } from "@spt-aki/utils/JsonUtil";
@injectable()
export class HttpResponseUtil
{
constructor(
@inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("LocalisationService") protected localisationService: LocalisationService
@inject("LocalisationService") protected localisationService: LocalisationService,
)
{ }
{}
protected clearString(s: string): any
{
@ -47,7 +46,7 @@ export class HttpResponseUtil
return this.jsonUtil.serialize({
err: err,
errmsg: errmsg,
data: data
data: data,
});
}
@ -66,12 +65,16 @@ export class HttpResponseUtil
return this.getBody([]);
}
public appendErrorToOutput(output: IItemEventRouterResponse, message = this.localisationService.getText("http-unknown_error"), errorCode = BackendErrorCodes.NONE): IItemEventRouterResponse
public appendErrorToOutput(
output: IItemEventRouterResponse,
message = this.localisationService.getText("http-unknown_error"),
errorCode = BackendErrorCodes.NONE,
): IItemEventRouterResponse
{
output.warnings = [{
index: 0,
errmsg: message,
code: errorCode.toString()
code: errorCode.toString(),
}];
return output;

View File

@ -11,7 +11,7 @@ export class ImporterUtil
{
constructor(
@inject("VFS") protected vfs: VFS,
@inject("JsonUtil") protected jsonUtil: JsonUtil
@inject("JsonUtil") protected jsonUtil: JsonUtil,
)
{}
@ -22,8 +22,10 @@ export class ImporterUtil
*/
public async loadRecursiveAsync<T>(
filepath: string,
onReadCallback: (fileWithPath: string, data: string) => void = () => {},
onObjectDeserialized: (fileWithPath: string, object: any) => void = () => {}
onReadCallback: (fileWithPath: string, data: string) => void = () =>
{},
onObjectDeserialized: (fileWithPath: string, object: any) => void = () =>
{},
): Promise<T>
{
const result = {} as T;
@ -39,7 +41,7 @@ export class ImporterUtil
{
const filename = this.vfs.stripExtension(file);
const filePathAndName = `${filepath}${file}`;
await this.vfs.readFileAsync(filePathAndName).then(fileData =>
await this.vfs.readFileAsync(filePathAndName).then((fileData) =>
{
onReadCallback(filePathAndName, fileData);
const fileDeserialized = this.jsonUtil.deserializeWithCacheCheck(fileData, filePathAndName);
@ -57,7 +59,7 @@ export class ImporterUtil
// set all loadRecursive to be executed asynchronously
const resEntries = Object.entries(result);
const resResolved = await Promise.all(resEntries.map(ent => ent[1]));
const resResolved = await Promise.all(resEntries.map((ent) => ent[1]));
for (let resIdx = 0; resIdx < resResolved.length; resIdx++)
{
resEntries[resIdx][1] = resResolved[resIdx];
@ -67,7 +69,6 @@ export class ImporterUtil
return Object.fromEntries(resEntries) as T;
}
/**
* Load files into js objects recursively (synchronous)
* @param filepath Path to folder with files
@ -75,8 +76,10 @@ export class ImporterUtil
*/
public loadRecursive<T>(
filepath: string,
onReadCallback: (fileWithPath: string, data: string) => void = () => {},
onObjectDeserialized: (fileWithPath: string, object: any) => void = () => {}
onReadCallback: (fileWithPath: string, data: string) => void = () =>
{},
onObjectDeserialized: (fileWithPath: string, object: any) => void = () =>
{},
): T
{
const result = {} as T;
@ -112,8 +115,10 @@ export class ImporterUtil
public async loadAsync<T>(
filepath: string,
strippablePath = "",
onReadCallback: (fileWithPath: string, data: string) => void = () => {},
onObjectDeserialized: (fileWithPath: string, object: any) => void = () => {}
onReadCallback: (fileWithPath: string, data: string) => void = () =>
{},
onObjectDeserialized: (fileWithPath: string, object: any) => void = () =>
{},
): Promise<T>
{
const directoriesToRead = new Queue<string>();
@ -126,14 +131,14 @@ export class ImporterUtil
const files = this.vfs.getFiles(filepath);
const directories = this.vfs.getDirs(filepath);
directoriesToRead.enqueueAll(directories.map(d => `${filepath}${d}`));
filesToProcess.enqueueAll(files.map(f => new VisitNode(filepath, f)));
directoriesToRead.enqueueAll(directories.map((d) => `${filepath}${d}`));
filesToProcess.enqueueAll(files.map((f) => new VisitNode(filepath, f)));
while (!directoriesToRead.isEmpty())
{
const directory = directoriesToRead.dequeue();
filesToProcess.enqueueAll(this.vfs.getFiles(directory).map(f => new VisitNode(`${directory}/`, f)));
directoriesToRead.enqueueAll(this.vfs.getDirs(directory).map(d => `${directory}/${d}`));
filesToProcess.enqueueAll(this.vfs.getFiles(directory).map((f) => new VisitNode(`${directory}/`, f)));
directoriesToRead.enqueueAll(this.vfs.getDirs(directory).map((d) => `${directory}/${d}`));
}
while (!filesToProcess.isEmpty())
@ -144,25 +149,28 @@ export class ImporterUtil
const filePathAndName = `${fileNode.filePath}${fileNode.fileName}`;
promises.push(
this.vfs.readFileAsync(filePathAndName)
.then(async fileData => {
.then(async (fileData) =>
{
onReadCallback(filePathAndName, fileData);
return this.jsonUtil.deserializeWithCacheCheckAsync<any>(fileData, filePathAndName);
})
.then(async fileDeserialized => {
.then(async (fileDeserialized) =>
{
onObjectDeserialized(filePathAndName, fileDeserialized);
const strippedFilePath = this.vfs.stripExtension(filePathAndName).replace(filepath, "");
this.placeObject(fileDeserialized, strippedFilePath, result, strippablePath);
})
}),
);
}
}
await Promise.all(promises).catch(e => console.error(e));
await Promise.all(promises).catch((e) => console.error(e));
return result;
}
protected placeObject<T>(fileDeserialized: any, strippedFilePath: string, result: T, strippablePath: string):void {
protected placeObject<T>(fileDeserialized: any, strippedFilePath: string, result: T, strippablePath: string): void
{
const strippedFinalPath = strippedFilePath.replace(strippablePath, "");
let temp = result;
const propertiesToVisit = strippedFinalPath.split("/");
@ -177,7 +185,9 @@ export class ImporterUtil
else
{
if (!temp[property])
{
temp[property] = {};
}
temp = temp[property];
}
}
@ -188,7 +198,7 @@ class VisitNode
{
constructor(
public filePath: string,
public fileName: string
){}
public fileName: string,
)
{}
}

View File

@ -18,9 +18,9 @@ export class JsonUtil
constructor(
@inject("VFS") protected vfs: VFS,
@inject("HashUtil") protected hashUtil: HashUtil,
@inject("WinstonLogger") protected logger: ILogger
@inject("WinstonLogger") protected logger: ILogger,
)
{ }
{}
/**
* From object to string
@ -47,23 +47,27 @@ export class JsonUtil
* @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.
* @returns string
*/
public serializeAdvanced(data: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string
public serializeAdvanced(
data: any,
replacer?: (this: any, key: string, value: any) => any,
space?: string | number,
): string
{
return JSON.stringify(data, replacer, space);
}
/**
* From object to string
* @param data object to turn into JSON
* @param filename Name of file being serialized
* @param options Stringify options or a replacer.
* @returns The string converted from the JavaScript value
* @param filename Name of file being serialized
* @param options Stringify options or a replacer.
* @returns The string converted from the JavaScript value
*/
public serializeJsonC(
data: any,
filename?: string | null,
options?: IStringifyOptions | Reviver): string
options?: IStringifyOptions | Reviver,
): string
{
try
{
@ -71,14 +75,17 @@ export class JsonUtil
}
catch (error)
{
this.logger.error(`unable to stringify jsonC file: ${filename} message: ${error.message}, stack: ${error.stack}`);
this.logger.error(
`unable to stringify jsonC file: ${filename} message: ${error.message}, stack: ${error.stack}`,
);
}
}
public serializeJson5(
data: any,
filename?: string | null,
prettify = false): string
prettify = false,
): string
{
try
{
@ -93,7 +100,9 @@ export class JsonUtil
}
catch (error)
{
this.logger.error(`unable to stringify json5 file: ${filename} message: ${error.message}, stack: ${error.stack}`);
this.logger.error(
`unable to stringify json5 file: ${filename} message: ${error.message}, stack: ${error.stack}`,
);
}
}
@ -111,7 +120,9 @@ export class JsonUtil
}
catch (error)
{
this.logger.error(`unable to parse json file: ${filename} message: ${error.message}, stack: ${error.stack}`);
this.logger.error(
`unable to parse json file: ${filename} message: ${error.message}, stack: ${error.stack}`,
);
}
}
@ -130,7 +141,9 @@ export class JsonUtil
}
catch (error)
{
this.logger.error(`unable to parse jsonC file: ${filename} message: ${error.message}, stack: ${error.stack}`);
this.logger.error(
`unable to parse jsonC file: ${filename} message: ${error.message}, stack: ${error.stack}`,
);
}
}
@ -142,7 +155,9 @@ export class JsonUtil
}
catch (error)
{
this.logger.error(`unable to parse json file: ${filename} message: ${error.message}, stack: ${error.stack}`);
this.logger.error(
`unable to parse json file: ${filename} message: ${error.message}, stack: ${error.stack}`,
);
}
}
@ -174,9 +189,9 @@ export class JsonUtil
{
try
{
const { data, changed } = fixJson(jsonString);
if (changed) // data invalid, return it
{
const {data, changed} = fixJson(jsonString);
if (changed)
{ // data invalid, return it
this.logger.error(`${filePath} - Detected faulty json, please fix your json file using VSCodium`);
}
else
@ -206,7 +221,6 @@ export class JsonUtil
return this.deserialize<T>(jsonString);
}
/**
* Create file if nothing found
* @param jsonCachePath path to cache
@ -228,7 +242,7 @@ export class JsonUtil
* Read contents of json cache and add to class field
* @param jsonCachePath Path to cache
*/
protected hydrateJsonCache(jsonCachePath: string) : void
protected hydrateJsonCache(jsonCachePath: string): void
{
// Get all file hashes
if (!this.fileHashes)

View File

@ -5,9 +5,9 @@ export class MathUtil
{
/**
* Helper to create the sum of all array elements
* @param {array} values The array with numbers of which to calculate the sum
* @return {number} sum(values)
*/
* @param {array} values The array with numbers of which to calculate the sum
* @return {number} sum(values)
*/
public arraySum(values: number[]): number
{
// sum with initial value being 0
@ -24,7 +24,7 @@ export class MathUtil
{
// curried function for cumulative sum: (cum, x) => cum += x
// and 0 being the initial value for the map
return values.map((cum => x => cum += x)(0));
return values.map(((cum) => (x) => cum += x)(0));
}
/**
@ -34,7 +34,7 @@ export class MathUtil
*/
public arrayProd(values: number[], factor: number): number[]
{
return values.map(x => x * factor);
return values.map((x) => x * factor);
}
/**
@ -44,7 +44,7 @@ export class MathUtil
*/
public arrayAdd(values: number[], summand: number): number[]
{
return values.map(x => x + summand);
return values.map((x) => x + summand);
}
/**
@ -72,14 +72,14 @@ export class MathUtil
}
/**
* Linear interpolation
* e.g. used to do a continuous integration for quest rewards which are defined for specific support centers of pmcLevel
*
* @param {string} xp the point of x at which to interpolate
* @param {array} x support points in x (of same length as y)
* @param {array} y support points in y (of same length as x)
* @return {number} y(xp)
*/
* Linear interpolation
* e.g. used to do a continuous integration for quest rewards which are defined for specific support centers of pmcLevel
*
* @param {string} xp the point of x at which to interpolate
* @param {array} x support points in x (of same length as y)
* @param {array} y support points in y (of same length as x)
* @return {number} y(xp)
*/
public interp1(xp: number, x: number[], y: number[]): number
{
if (xp > x[x.length - 1])

View File

@ -7,9 +7,9 @@ import { TimeUtil } from "@spt-aki/utils/TimeUtil";
export class ObjectId
{
constructor(
@inject("TimeUtil") protected timeUtil: TimeUtil
@inject("TimeUtil") protected timeUtil: TimeUtil,
)
{ }
{}
protected randomBytes = crypto.randomBytes(5);
protected constglobalCounter = 0;

View File

@ -99,7 +99,7 @@ export class RagfairOfferHolder
*/
public getStaleOffers(time: number): Array<IRagfairOffer>
{
return this.getOffers().filter(o => this.isStale(o, time));
return this.getOffers().filter((o) => this.isStale(o, time));
}
protected addOfferByTemplates(template: string, offer: IRagfairOffer): void

View File

@ -5,32 +5,35 @@ import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { MathUtil } from "@spt-aki/utils/MathUtil";
/**
* Array of ProbabilityObjectArray which allow to randomly draw of the contained objects
* based on the relative probability of each of its elements.
* The probabilities of the contained element is not required to be normalized.
*
* Example:
* po = new ProbabilityObjectArray(
* new ProbabilityObject("a", 5),
* new ProbabilityObject("b", 1),
* new ProbabilityObject("c", 1)
* );
* res = po.draw(10000);
* // count the elements which should be distributed according to the relative probabilities
* res.filter(x => x==="b").reduce((sum, x) => sum + 1 , 0)
*/
export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObject<K, V>>
* Array of ProbabilityObjectArray which allow to randomly draw of the contained objects
* based on the relative probability of each of its elements.
* The probabilities of the contained element is not required to be normalized.
*
* Example:
* po = new ProbabilityObjectArray(
* new ProbabilityObject("a", 5),
* new ProbabilityObject("b", 1),
* new ProbabilityObject("c", 1)
* );
* res = po.draw(10000);
* // count the elements which should be distributed according to the relative probabilities
* res.filter(x => x==="b").reduce((sum, x) => sum + 1 , 0)
*/
export class ProbabilityObjectArray<K, V = undefined> extends Array<ProbabilityObject<K, V>>
{
constructor(
private mathUtil: MathUtil,
private jsonUtil: JsonUtil,
...items: ProbabilityObject<K, V>[])
...items: ProbabilityObject<K, V>[]
)
{
super();
this.push(...items);
}
filter(callbackfn: (value: ProbabilityObject<K, V>, index: number, array: ProbabilityObject<K, V>[]) => any): ProbabilityObjectArray<K, V>
filter(
callbackfn: (value: ProbabilityObject<K, V>, index: number, array: ProbabilityObject<K, V>[]) => any,
): ProbabilityObjectArray<K, V>
{
return new ProbabilityObjectArray(this.mathUtil, this.jsonUtil, ...super.filter(callbackfn));
}
@ -71,7 +74,7 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
*/
drop(key: K): ProbabilityObjectArray<K, V>
{
return this.filter(r => r.key !== key);
return this.filter((r) => r.key !== key);
}
/**
@ -81,7 +84,7 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
*/
data(key: K): V
{
return this.filter(r => r.key === key)[0]?.data;
return this.filter((r) => r.key === key)[0]?.data;
}
/**
@ -96,7 +99,7 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
*/
probability(key: K): number
{
return this.filter(r => r.key === key)[0].relativeProbability;
return this.filter((r) => r.key === key)[0].relativeProbability;
}
/**
@ -110,7 +113,7 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
*/
maxProbability(): number
{
return Math.max(...this.map(x => x.relativeProbability));
return Math.max(...this.map((x) => x.relativeProbability));
}
/**
@ -124,7 +127,7 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
*/
minProbability(): number
{
return Math.min(...this.map(x => x.relativeProbability));
return Math.min(...this.map((x) => x.relativeProbability));
}
/**
@ -149,7 +152,7 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
for (let i = 0; i < count; i++)
{
const rand = Math.random();
const randomIndex = probCumsum.findIndex(x => x > rand);
const randomIndex = probCumsum.findIndex((x) => x > rand);
// We cannot put Math.random() directly in the findIndex because then it draws anew for each of its iteration
if (replacement || locklist.includes(keyArray[randomIndex]))
{
@ -176,20 +179,20 @@ export class ProbabilityObjectArray<K, V=undefined> extends Array<ProbabilityObj
}
/**
* A ProbabilityObject which is use as an element to the ProbabilityObjectArray array
* It contains a key, the relative probability as well as optional data.
*/
export class ProbabilityObject<K,V=undefined>
* A ProbabilityObject which is use as an element to the ProbabilityObjectArray array
* It contains a key, the relative probability as well as optional data.
*/
export class ProbabilityObject<K, V = undefined>
{
key: K;
relativeProbability: number;
data: V;
/**
* Constructor for the ProbabilityObject
* @param {string} key The key of the element
* @param {number} relativeProbability The relative probability of this element
* @param {any} data Optional data attached to the element
*/
* Constructor for the ProbabilityObject
* @param {string} key The key of the element
* @param {number} relativeProbability The relative probability of this element
* @param {any} data Optional data attached to the element
*/
constructor(key: K, relativeProbability: number, data: V = null)
{
this.key = key;
@ -201,9 +204,9 @@ export class ProbabilityObject<K,V=undefined>
@injectable()
export class RandomUtil
{
constructor (
constructor(
@inject("JsonUtil") protected jsonUtil: JsonUtil,
@inject("WinstonLogger") protected logger: ILogger
@inject("WinstonLogger") protected logger: ILogger,
)
{
}
@ -261,7 +264,7 @@ export class RandomUtil
return this.getArrayValue(Object.keys(node));
}
public getKeyValue(node: { [x: string]: any; }): any
public getKeyValue(node: {[x: string]: any;}): any
{
return node[this.getKey(node)];
}
@ -276,8 +279,14 @@ export class RandomUtil
{
let u = 0;
let v = 0;
while (u === 0) u = Math.random(); //Converting [0,1) to (0,1)
while (v === 0) v = Math.random();
while (u === 0)
{
u = Math.random(); // Converting [0,1) to (0,1)
}
while (v === 0)
{
v = Math.random();
}
const w = Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
return mu + w * sigma;
}
@ -366,7 +375,7 @@ export class RandomUtil
{
throw {
name: "Invalid arguments",
message: `Bounded random number generation max is smaller than min (${max} < ${min})`
message: `Bounded random number generation max is smaller than min (${max} < ${min})`,
};
}
@ -374,7 +383,7 @@ export class RandomUtil
{
throw {
name: "Invalid argument",
message: `'n' must be 1 or greater (received ${n})`
message: `'n' must be 1 or greater (received ${n})`,
};
}
@ -390,7 +399,9 @@ export class RandomUtil
* A shift that is equal to the available range only has a 50% chance of rolling correctly, theoretically halving performance.
* Shifting even further drops the success chance very rapidly - so we want to warn against that */
this.logger.warning("Bias shift for random number generation is greater than the range of available numbers.\nThis can have a very severe performance impact!");
this.logger.warning(
"Bias shift for random number generation is greater than the range of available numbers.\nThis can have a very severe performance impact!",
);
this.logger.info(`min -> ${min}; max -> ${max}; shift -> ${shift}`);
}
@ -443,7 +454,9 @@ export class RandomUtil
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
array[randomIndex],
array[currentIndex],
];
}
return array;

View File

@ -1,5 +1,5 @@
import { injectable } from "tsyringe";
import { formatInTimeZone } from "date-fns-tz";
import { injectable } from "tsyringe";
/**
* Utility class to handle time related operations.

View File

@ -1,30 +1,33 @@
import "reflect-metadata";
import { inject, injectable } from "tsyringe";
import fs from "node:fs";
import crypto from "node:crypto";
import { promisify } from "node:util";
import path, { resolve } from "node:path";
import { writeFileSync } from "atomically";
import lockfile from "proper-lockfile";
import { IAsyncQueue } from "@spt-aki/models/spt/utils/IAsyncQueue";
import { writeFileSync } from "atomically";
import crypto from "node:crypto";
import fs from "node:fs";
import path, { resolve } from "node:path";
import { promisify } from "node:util";
import lockfile from "proper-lockfile";
@injectable()
export class VFS
{
accessFilePromisify: (path: fs.PathLike, mode?: number) => Promise<void>;
copyFilePromisify: (src: fs.PathLike, dst: fs.PathLike, flags?: number) => Promise<void>;
mkdirPromisify: (path: fs.PathLike, options: fs.MakeDirectoryOptions & { recursive: true; }) => Promise<string>;
mkdirPromisify: (path: fs.PathLike, options: fs.MakeDirectoryOptions & {recursive: true;}) => Promise<string>;
readFilePromisify: (path: fs.PathLike) => Promise<Buffer>;
writeFilePromisify: (path: fs.PathLike, data: string, options?: any) => Promise<void>;
readdirPromisify: (path: fs.PathLike, options?: BufferEncoding | { encoding: BufferEncoding; withFileTypes?: false; }) => Promise<string[]>;
statPromisify: (path: fs.PathLike, options?: fs.StatOptions & { bigint?: false; }) => Promise<fs.Stats>;
readdirPromisify: (
path: fs.PathLike,
options?: BufferEncoding | {encoding: BufferEncoding; withFileTypes?: false;},
) => Promise<string[]>;
statPromisify: (path: fs.PathLike, options?: fs.StatOptions & {bigint?: false;}) => Promise<fs.Stats>;
unlinkPromisify: (path: fs.PathLike) => Promise<void>;
rmdirPromisify: (path: fs.PathLike) => Promise<void>;
renamePromisify: (oldPath: fs.PathLike, newPath: fs.PathLike) => Promise<void>;
constructor(
@inject("AsyncQueue") protected asyncQueue: IAsyncQueue
@inject("AsyncQueue") protected asyncQueue: IAsyncQueue,
)
{
this.accessFilePromisify = promisify(fs.access);
@ -51,7 +54,7 @@ export class VFS
// Create the command to add to the queue
const command = {
uuid: crypto.randomUUID(),
cmd: async () => await this.accessFilePromisify(filepath)
cmd: async () => await this.accessFilePromisify(filepath),
};
// Wait for the command completion
await this.asyncQueue.waitFor(command);
@ -75,21 +78,22 @@ export class VFS
{
const command = {
uuid: crypto.randomUUID(),
cmd: async () => await this.copyFilePromisify(filepath, target)
cmd: async () => await this.copyFilePromisify(filepath, target),
};
await this.asyncQueue.waitFor(command);
}
public createDir(filepath: string): void
{
fs.mkdirSync(filepath.substr(0, filepath.lastIndexOf("/")), { recursive: true });
fs.mkdirSync(filepath.substr(0, filepath.lastIndexOf("/")), {recursive: true});
}
public async createDirAsync(filepath: string): Promise<void>
{
const command = {
uuid: crypto.randomUUID(),
cmd: async () => await this.mkdirPromisify(filepath.substr(0, filepath.lastIndexOf("/")), { recursive: true })
cmd: async () =>
await this.mkdirPromisify(filepath.substr(0, filepath.lastIndexOf("/")), {recursive: true}),
};
await this.asyncQueue.waitFor(command);
}
@ -148,7 +152,9 @@ export class VFS
{
const read = fs.readFileSync(...args);
if (this.isBuffer(read))
{
return read.toString();
}
return read;
}
@ -156,7 +162,9 @@ export class VFS
{
const read = await this.readFilePromisify(path);
if (this.isBuffer(read))
{
return read.toString();
}
return read;
}
@ -167,7 +175,7 @@ export class VFS
public writeFile(filepath: any, data = "", append = false, atomic = true): void
{
const options = append ? { flag: "a" } : { flag: "w" };
const options = append ? {flag: "a"} : {flag: "w"};
if (!this.exists(filepath))
{
@ -194,7 +202,7 @@ export class VFS
public async writeFileAsync(filepath: any, data = "", append = false, atomic = true): Promise<void>
{
const options = append ? { flag: "a" } : { flag: "w" };
const options = append ? {flag: "a"} : {flag: "w"};
if (!await this.exists(filepath))
{
@ -230,7 +238,6 @@ export class VFS
});
}
public getDirs(filepath: string): string[]
{
return fs.readdirSync(filepath).filter((item) =>
@ -377,7 +384,7 @@ export class VFS
return files;
}
const dirents = fs.readdirSync(directory, { encoding: "utf-8", withFileTypes: true });
const dirents = fs.readdirSync(directory, {encoding: "utf-8", withFileTypes: true});
for (const dirent of dirents)
{
const res = resolve(directory, dirent.name);

View File

@ -15,7 +15,7 @@ export class WatermarkLocale
protected modding: string[];
constructor(
@inject("LocalisationService") protected localisationService: LocalisationService
@inject("LocalisationService") protected localisationService: LocalisationService,
)
{
this.description = [
@ -23,7 +23,7 @@ export class WatermarkLocale
"",
this.localisationService.getText("watermark-free_of_charge"),
this.localisationService.getText("watermark-paid_scammed"),
this.localisationService.getText("watermark-commercial_use_prohibited")
this.localisationService.getText("watermark-commercial_use_prohibited"),
];
this.warning = [
"",
@ -33,14 +33,14 @@ export class WatermarkLocale
`${this.localisationService.getText("watermark-report_issues_to")}:`,
this.localisationService.getText("watermark-issue_tracker_url"),
"",
this.localisationService.getText("watermark-use_at_own_risk")
this.localisationService.getText("watermark-use_at_own_risk"),
];
this.modding = [
"",
this.localisationService.getText("watermark-modding_disabled"),
"",
this.localisationService.getText("watermark-not_an_issue"),
this.localisationService.getText("watermark-do_not_report")
this.localisationService.getText("watermark-do_not_report"),
];
}
@ -71,7 +71,7 @@ export class Watermark
@inject("WinstonLogger") protected logger: ILogger,
@inject("ConfigServer") protected configServer: ConfigServer,
@inject("LocalisationService") protected localisationService: LocalisationService,
@inject("WatermarkLocale") protected watermarkLocale?: WatermarkLocale
@inject("WatermarkLocale") protected watermarkLocale?: WatermarkLocale,
)
{
this.akiConfig = this.configServer.getConfig<ICoreConfig>(ConfigTypes.CORE);
@ -110,9 +110,9 @@ export class Watermark
*/
public getVersionTag(withEftVersion = false): string
{
const versionTag = (globalThis.G_DEBUG_CONFIGURATION)
? `${this.akiConfig.akiVersion} - ${this.localisationService.getText("bleeding_edge_build")}`
: this.akiConfig.akiVersion;
const versionTag = (globalThis.G_DEBUG_CONFIGURATION) ?
`${this.akiConfig.akiVersion} - ${this.localisationService.getText("bleeding_edge_build")}` :
this.akiConfig.akiVersion;
if (withEftVersion)
{
@ -130,9 +130,9 @@ export class Watermark
*/
public getInGameVersionLabel(): string
{
const versionTag = (globalThis.G_DEBUG_CONFIGURATION)
? `${this.akiConfig.akiVersion} - BLEEDINGEDGE`
: this.akiConfig.akiVersion;
const versionTag = (globalThis.G_DEBUG_CONFIGURATION) ?
`${this.akiConfig.akiVersion} - BLEEDINGEDGE` :
this.akiConfig.akiVersion;
return `${this.akiConfig.projectName} ${versionTag}`;
}

View File

@ -63,7 +63,10 @@ export class LinkedList<T>
public removeFirst(): LinkedListNode<T>
{
if (!this.head) return undefined;
if (!this.head)
{
return undefined;
}
const node = this.head;
if (this.head.getNextNode())
@ -80,7 +83,10 @@ export class LinkedList<T>
public removeLast(): LinkedListNode<T>
{
if (!this.tail) return undefined;
if (!this.tail)
{
return undefined;
}
const node = this.tail;
if (this.tail.getPreviousNode())
@ -95,7 +101,7 @@ export class LinkedList<T>
return node;
}
public indexOf(func: (t:T) => boolean): number
public indexOf(func: (t: T) => boolean): number
{
const node = this.head;
let index = 0;
@ -110,7 +116,7 @@ export class LinkedList<T>
return undefined;
}
public contains(func: (t:T) => boolean): boolean
public contains(func: (t: T) => boolean): boolean
{
let node = this.head;
while (node)
@ -124,7 +130,7 @@ export class LinkedList<T>
return false;
}
public forEachNode(func: (t:LinkedListNode<T>) => void): void
public forEachNode(func: (t: LinkedListNode<T>) => void): void
{
let node = this.head;
while (node)
@ -134,7 +140,7 @@ export class LinkedList<T>
}
}
public forEachValue(func: (t:T) => void): void
public forEachValue(func: (t: T) => void): void
{
let node = this.head;
while (node)
@ -144,7 +150,7 @@ export class LinkedList<T>
}
}
public findFirstNode(func: (t:LinkedListNode<T>) => boolean): LinkedListNode<T>
public findFirstNode(func: (t: LinkedListNode<T>) => boolean): LinkedListNode<T>
{
let node = this.head;
while (node)
@ -158,7 +164,7 @@ export class LinkedList<T>
return undefined;
}
public findFirstValue(func: (t:T) => boolean): T
public findFirstValue(func: (t: T) => boolean): T
{
let node = this.head;
while (node)

View File

@ -4,7 +4,6 @@ export class Queue<T>
private head: number;
private tail: number;
constructor()
{
this.elements = {};
this.head = 0;
@ -33,7 +32,7 @@ export class Queue<T>
return item;
}
public peek():T
public peek(): T
{
return this.elements[this.head];
}

View File

@ -1,5 +1,5 @@
import fs from "node:fs";
import crypto from "node:crypto";
import fs from "node:fs";
import { promisify } from "node:util";
import winston, { createLogger, format, transports } from "winston";
import DailyRotateFile from "winston-daily-rotate-file";
@ -23,7 +23,7 @@ export abstract class AbstractWinstonLogger implements ILogger
succ: 2,
info: 3,
custom: 4,
debug: 5
debug: 5,
},
colors: {
error: "red",
@ -31,7 +31,7 @@ export abstract class AbstractWinstonLogger implements ILogger
succ: "green",
info: "white",
custom: "black",
debug: "gray"
debug: "gray",
},
bgColors: {
default: "",
@ -42,14 +42,14 @@ export abstract class AbstractWinstonLogger implements ILogger
blueBG: "blueBG",
magentaBG: "magentaBG",
cyanBG: "cyanBG",
whiteBG: "whiteBG"
}
whiteBG: "whiteBG",
},
};
protected logger: winston.Logger & SptLogger;
protected writeFilePromisify: (path: fs.PathLike, data: string, options?: any) => Promise<void>;
constructor(
protected asyncQueue: IAsyncQueue
protected asyncQueue: IAsyncQueue,
)
{
this.filePath = `${this.getFilePath()}${this.getFileName()}`;
@ -57,7 +57,7 @@ export abstract class AbstractWinstonLogger implements ILogger
this.showDebugInConsole = globalThis.G_DEBUG_CONFIGURATION;
if (!fs.existsSync(this.getFilePath()))
{
fs.mkdirSync(this.getFilePath(), { recursive: true });
fs.mkdirSync(this.getFilePath(), {recursive: true});
}
const transportsList: winston.transport[] = [];
@ -68,13 +68,13 @@ export abstract class AbstractWinstonLogger implements ILogger
new transports.Console({
level: this.showDebugInConsole ? "debug" : "custom",
format: format.combine(
format.colorize({ all: true, colors: this.logLevels.colors }),
format.printf(({ message }) =>
format.colorize({all: true, colors: this.logLevels.colors}),
format.printf(({message}) =>
{
return `${message}`;
})
)
})
}),
),
}),
);
}
if (this.isLogToFile())
@ -91,19 +91,19 @@ export abstract class AbstractWinstonLogger implements ILogger
format.timestamp(),
format.align(),
format.json(),
format.printf(({ timestamp, level, message }) =>
format.printf(({timestamp, level, message}) =>
{
return `[${timestamp}] ${level}: ${message}`;
})
)
})
}),
),
}),
);
}
winston.addColors(this.logLevels.colors);
this.logger = createLogger({
levels: this.logLevels.levels,
transports: [...transportsList]
transports: [...transportsList],
});
if (this.isLogExceptions())
@ -140,39 +140,41 @@ export abstract class AbstractWinstonLogger implements ILogger
{
const command: ICommand = {
uuid: crypto.randomUUID(),
cmd: async () => await this.writeFilePromisify(this.filePath, `${data}\n`, true)
cmd: async () => await this.writeFilePromisify(this.filePath, `${data}\n`, true),
};
await this.asyncQueue.waitFor(command);
}
public async log(data: string | Error | Record<string, unknown>, color: string, backgroundColor = "" ): Promise<void>
public async log(data: string | Error | Record<string, unknown>, color: string, backgroundColor = ""): Promise<void>
{
const textColor = `${color} ${backgroundColor}`.trimEnd();
const tmpLogger = createLogger({
levels: { custom: 0 },
levels: {custom: 0},
level: "custom",
transports: [new transports.Console({
format: format.combine(
format.colorize({ all: true, colors: { custom: textColor } }),
format.printf(({ message }) => message)
)
})]
transports: [
new transports.Console({
format: format.combine(
format.colorize({all: true, colors: {custom: textColor}}),
format.printf(({message}) => message),
),
}),
],
});
let command: ICommand;
if (typeof (data) === "string")
if (typeof data === "string")
{
command = {
uuid: crypto.randomUUID(),
cmd: async () => await tmpLogger.log("custom", data)
cmd: async () => await tmpLogger.log("custom", data),
};
}
else
{
command = {
uuid: crypto.randomUUID(),
cmd: async () => await tmpLogger.log("custom", JSON.stringify(data, null, 4))
cmd: async () => await tmpLogger.log("custom", JSON.stringify(data, null, 4)),
};
}
@ -183,7 +185,7 @@ export abstract class AbstractWinstonLogger implements ILogger
{
const command: ICommand = {
uuid: crypto.randomUUID(),
cmd: async () => await this.logger.error(data)
cmd: async () => await this.logger.error(data),
};
await this.asyncQueue.waitFor(command);
}
@ -192,7 +194,7 @@ export abstract class AbstractWinstonLogger implements ILogger
{
const command: ICommand = {
uuid: crypto.randomUUID(),
cmd: async () => await this.logger.warn(data)
cmd: async () => await this.logger.warn(data),
};
await this.asyncQueue.waitFor(command);
}
@ -201,7 +203,7 @@ export abstract class AbstractWinstonLogger implements ILogger
{
const command: ICommand = {
uuid: crypto.randomUUID(),
cmd: async () => await this.logger.succ(data)
cmd: async () => await this.logger.succ(data),
};
await this.asyncQueue.waitFor(command);
}
@ -210,7 +212,7 @@ export abstract class AbstractWinstonLogger implements ILogger
{
const command: ICommand = {
uuid: crypto.randomUUID(),
cmd: async () => await this.logger.info(data)
cmd: async () => await this.logger.info(data),
};
await this.asyncQueue.waitFor(command);
}
@ -221,11 +223,15 @@ export abstract class AbstractWinstonLogger implements ILogger
* @param textColor color of text
* @param backgroundColor color of background
*/
public async logWithColor(data: string | Record<string, unknown>, textColor: LogTextColor, backgroundColor = LogBackgroundColor.DEFAULT): Promise<void>
public async logWithColor(
data: string | Record<string, unknown>,
textColor: LogTextColor,
backgroundColor = LogBackgroundColor.DEFAULT,
): Promise<void>
{
const command: ICommand = {
uuid: crypto.randomUUID(),
cmd: async () => await this.log(data, textColor.toString(), backgroundColor.toString())
cmd: async () => await this.log(data, textColor.toString(), backgroundColor.toString()),
};
await this.asyncQueue.waitFor(command);
@ -239,14 +245,14 @@ export abstract class AbstractWinstonLogger implements ILogger
{
command = {
uuid: crypto.randomUUID(),
cmd: async () => await this.log(data, this.logLevels.colors.debug)
cmd: async () => await this.log(data, this.logLevels.colors.debug),
};
}
else
{
command = {
uuid: crypto.randomUUID(),
cmd: async () => await this.logger.debug(data)
cmd: async () => await this.logger.debug(data),
};
}

View File

@ -7,7 +7,7 @@ import { AbstractWinstonLogger } from "@spt-aki/utils/logging/AbstractWinstonLog
export class WinstonMainLogger extends AbstractWinstonLogger
{
constructor(
@inject("AsyncQueue") protected asyncQueue: IAsyncQueue
@inject("AsyncQueue") protected asyncQueue: IAsyncQueue,
)
{
super(asyncQueue);

View File

@ -7,7 +7,7 @@ import { AbstractWinstonLogger } from "@spt-aki/utils/logging/AbstractWinstonLog
export class WinstonRequestLogger extends AbstractWinstonLogger
{
constructor(
@inject("AsyncQueue") protected asyncQueue: IAsyncQueue
@inject("AsyncQueue") protected asyncQueue: IAsyncQueue,
)
{
super(asyncQueue);