Formatting for utils.
This commit is contained in:
parent
8576929404
commit
4479f68388
@ -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()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
});
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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",
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
)
|
||||
{}
|
||||
}
|
@ -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)
|
||||
|
@ -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])
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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}`;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user