Skip to content

Commit

Permalink
refact(skymp5-client): refactor logging (skyrim-multiplayer#1899)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Mar 31, 2024
1 parent 3caff33 commit 3a1ef6c
Show file tree
Hide file tree
Showing 24 changed files with 215 additions and 176 deletions.
12 changes: 12 additions & 0 deletions skymp5-client/src/logging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { printConsole } from "@skyrim-platform/skyrim-platform";
import { ClientListener } from "./services/services/clientListener";

// TODO: redirect this to spdlog
export function logError(service: ClientListener, ...rest: unknown[]) {
printConsole(`Error in ${service.constructor.name}:`, ...rest);
}

// TODO: redirect this to spdlog
export function logTrace(service: ClientListener, ...rest: unknown[]) {
printConsole(`Trace in ${service.constructor.name}:`, ...rest);
}
9 changes: 5 additions & 4 deletions skymp5-client/src/services/services/activationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getInventory } from "../../sync/inventory";
import { localIdToRemoteId } from "../../view/worldViewMisc";

import { LastInvService } from "./lastInvService";
import { logError, logTrace } from "../../logging";

export class ActivationService extends ClientListener {
constructor(private sp: Sp, private controller: CombinedController) {
Expand All @@ -28,12 +29,12 @@ export class ActivationService extends ClientListener {

target = localIdToRemoteId(target);
if (!target) {
return this.logError('localIdToRemoteId returned 0 (target) in on(\'activate\')');
return logError(this, 'localIdToRemoteId returned 0 (target) in on(\'activate\')');
}

caster = localIdToRemoteId(caster);
if (!caster) {
return this.logError('localIdToRemoteId returned 0 (caster) in on(\'activate\')');
return logError(this, 'localIdToRemoteId returned 0 (caster) in on(\'activate\')');
}

const openState = e.target.getOpenState();
Expand All @@ -48,7 +49,7 @@ export class ActivationService extends ClientListener {
}

if (openState === OpenState.Opening || openState === OpenState.Closing) {
return this.logTrace("Ignoring activation of door because it's already opening or closing");
return logTrace(this, "Ignoring activation of door because it's already opening or closing");
}

this.controller.emitter.emit("sendMessage", {
Expand All @@ -59,6 +60,6 @@ export class ActivationService extends ClientListener {
reliability: "reliable"
});

this.logTrace(`Sent activation for caster=${caster.toString(16)} and target=${target.toString(16)}`);
logTrace(this, `Sent activation for caster=`, caster.toString(16), `and target=`, target.toString(16));
}
};
5 changes: 3 additions & 2 deletions skymp5-client/src/services/services/animDebugService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logTrace, logError } from "../../logging";
import { ClientListener, CombinedController, Sp } from "./clientListener";
import { ButtonEvent } from "skyrimPlatform";

Expand All @@ -9,12 +10,12 @@ export class AnimDebugService extends ClientListener {

// clear previous texts in case of hotreload
if (this.sp.storage[AnimQueueCollection.Name] && (this.sp.storage[AnimQueueCollection.Name] as AnimQueueCollection).clearSPText) {
this.logTrace(`Destroying old AnimQueueCollection`);
logTrace(this, `Destroying old AnimQueueCollection`);
try {
(this.sp.storage[AnimQueueCollection.Name] as AnimQueueCollection).clearSPText();
}
catch (e) {
this.logError(`Failed to destroy old AnimQueueCollection: ${e}`);
logError(this, `Failed to destroy old AnimQueueCollection:`, e);
}
}

Expand Down
39 changes: 20 additions & 19 deletions skymp5-client/src/services/services/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AuthNeededEvent } from "../events/authNeededEvent";
import { BrowserWindowLoadedEvent } from "../events/browserWindowLoadedEvent";
import { TimersService } from "./timersService";
import { MasterApiAuthStatus } from "../messages_http/masterApiAuthStatus";
import { logTrace, logError } from "../../logging";

// for browsersideWidgetSetter
declare const window: any;
Expand Down Expand Up @@ -36,15 +37,15 @@ export class AuthService extends ClientListener {
}

private onAuthNeeded(e: AuthNeededEvent) {
this.logTrace(`Received authNeeded event`);
logTrace(this, `Received authNeeded event`);

const settingsGameData = this.sp.settings["skymp5-client"]["gameData"] as any;
const isOfflineMode = Number.isInteger(settingsGameData?.profileId);
if (isOfflineMode) {
this.logTrace(`Offline mode detected in settings, emitting auth event with authGameData.local`);
logTrace(this, `Offline mode detected in settings, emitting auth event with authGameData.local`);
this.controller.emitter.emit("auth", { authGameData: { local: { profileId: settingsGameData.profileId } } });
} else {
this.logTrace(`No offline mode detectted in settings, regular auth needed`);
logTrace(this, `No offline mode detectted in settings, regular auth needed`);
this.isListenBrowserMessage = true;

this.trigger.authNeededFired = true;
Expand All @@ -55,7 +56,7 @@ export class AuthService extends ClientListener {
}

private onBrowserWindowLoaded(e: BrowserWindowLoadedEvent) {
this.logTrace(`Received browserWindowLoaded event`);
logTrace(this, `Received browserWindowLoaded event`);

this.trigger.browserWindowLoadedFired = true;
if (this.trigger.conditionMet) {
Expand All @@ -65,11 +66,11 @@ export class AuthService extends ClientListener {

private onBrowserWindowLoadedAndOnlineAuthNeeded() {
if (!this.isListenBrowserMessage) {
this.logError(`isListenBrowserMessage was false for some reason, aborting auth`);
logError(this, `isListenBrowserMessage was false for some reason, aborting auth`);
return;
}

this.logTrace(`Showing widgets and starting loop`);
logTrace(this, `Showing widgets and starting loop`);

authData = this.readAuthDataFromDisk();
this.refreshWidgets();
Expand All @@ -78,14 +79,14 @@ export class AuthService extends ClientListener {

const timersService = this.controller.lookupListener(TimersService);

this.logTrace("Calling setTimeout for testing");
logTrace(this, "Calling setTimeout for testing");
try {
timersService.setTimeout(() => {
this.logTrace("Test timeout fired");
logTrace(this, "Test timeout fired");
}, 1);
}
catch (e) {
this.logError("Failed to call setTimeout");
logError(this, "Failed to call setTimeout");
}

// Launch checkLoginState loop
Expand All @@ -94,11 +95,11 @@ export class AuthService extends ClientListener {

private onBrowserMessage(e: BrowserMessageEvent) {
if (!this.isListenBrowserMessage) {
this.logTrace(`onBrowserMessage: isListenBrowserMessage was false, ignoring message ${JSON.stringify(e.arguments)}`);
logTrace(this, `onBrowserMessage: isListenBrowserMessage was false, ignoring message`, JSON.stringify(e.arguments));
return;
}

this.logTrace(`onBrowserMessage: ${JSON.stringify(e.arguments)}`);
logTrace(this, `onBrowserMessage:`, JSON.stringify(e.arguments));

const eventKey = e.arguments[0];
switch (eventKey) {
Expand Down Expand Up @@ -140,7 +141,7 @@ export class AuthService extends ClientListener {

const route = `/api/users/me/play/${masterKey}`;

this.logTrace(`Creating play session ${route}`);
logTrace(this, `Creating play session ${route}`);

client.post(route, {
body: '{}',
Expand All @@ -162,7 +163,7 @@ export class AuthService extends ClientListener {

private checkLoginState() {
if (!this.isListenBrowserMessage) {
this.logTrace(`checkLoginState: isListenBrowserMessage was false, aborting check`);
logTrace(this, `checkLoginState: isListenBrowserMessage was false, aborting check`);
return;
}

Expand Down Expand Up @@ -220,33 +221,33 @@ export class AuthService extends ClientListener {

private refreshWidgets() {
if (browserState.failCount) {
this.logError(`Auth check fail: ${browserState.comment}`);
logError(this, `Auth check fail:`, browserState.comment);
}
this.sp.browser.executeJavaScript(new FunctionInfo(this.browsersideWidgetSetter).getText({ events, browserState, authData: authData }));
};

private readAuthDataFromDisk(): RemoteAuthGameData | null {
this.logTrace(`Reading ${this.pluginAuthDataName} from disk`);
logTrace(this, `Reading`, this.pluginAuthDataName, `from disk`);

try {
const data = this.sp.getPluginSourceCode(this.pluginAuthDataName);

if (!data) {
this.logTrace(`Read empty ${this.pluginAuthDataName}, returning null`);
logTrace(this, `Read empty`, this.pluginAuthDataName, `returning null`);
return null;
}

return JSON.parse(data.slice(2)) || null;
} catch (e) {
this.logError(`Error reading ${this.pluginAuthDataName} from disk: ${e}, falling back to null`);
logError(this, `Error reading`, this.pluginAuthDataName, `from disk:`, e, `, falling back to null`);
return null;
}
}

private writeAuthDataToDisk(data: RemoteAuthGameData | null) {
const content = "//" + (data ? JSON.stringify(data) : "null");

this.logTrace(`Writing ${this.pluginAuthDataName} to disk: ${content}`);
logTrace(this, `Writing`, this.pluginAuthDataName, `to disk:`, content);

try {
this.sp.writePlugin(
Expand All @@ -255,7 +256,7 @@ export class AuthService extends ClientListener {
);
}
catch (e) {
this.logError(`Error writing ${this.pluginAuthDataName} to disk: ${e}, will not remember user`);
logError(this, `Error writing`, this.pluginAuthDataName, `to disk:`, e, `, will not remember user`);
}
};

Expand Down
19 changes: 6 additions & 13 deletions skymp5-client/src/services/services/clientListener.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import * as sp from "skyrimPlatform";
import { EventEmitterType } from "../events/events";

export interface ClientListenerEvents {
on: typeof sp.on,
once: typeof sp.once
export interface ClientListenerEvents {
on: typeof sp.on,
once: typeof sp.once
};

export type Sp = Omit<typeof sp, "on" | "once">;

export abstract class ClientListener {
// TODO: redirect this to spdlog
protected logError(error: string) {
sp.printConsole(`Error in ${this.constructor.name}:`, error);
}

// TODO: redirect this to spdlog
protected logTrace(trace: string) {
sp.printConsole(`Trace in ${this.constructor.name}:`, trace);
}
// Don't let TypeScript treat this class as empty
private _nonEmptyClassMark = '';
}

export type ClientListenerConstructor<T> = {
Expand All @@ -30,7 +23,7 @@ export type ListenerLookupController = {
};

export type EventsController = {
readonly on: typeof sp.on,
readonly on: typeof sp.on,
readonly once: typeof sp.once,
readonly emitter: EventEmitterType
};
Expand Down
15 changes: 8 additions & 7 deletions skymp5-client/src/services/services/consoleCommandsService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { logError, logTrace } from "../../logging";
import { MsgType } from "../../messages";

// TODO: refactor this out
Expand Down Expand Up @@ -34,7 +35,7 @@ export class ConsoleCommandsService extends ClientListener {
private setupMpCommand() {
const command = this.sp.findConsoleCommand(" ConfigureUM") || this.sp.findConsoleCommand("test");
if (command === null) {
return this.logError("command was null in setupMpCommand");
return logError(this, "command was null in setupMpCommand");
}

command.shortName = "mp";
Expand All @@ -45,10 +46,10 @@ export class ConsoleCommandsService extends ClientListener {
this.schemas.forEach((_, commandName) => {
const command = this.sp.findConsoleCommand(commandName);
if (command === null) {
return this.logError(`command '${commandName}' was null in setupVanilaCommands`);
return logError(this, `command`, commandName, `was null in setupVanilaCommands`);
}
if (this.nonVanilaCommands.includes(commandName)) {
return this.logTrace(`command '${commandName}' is non-vanila command`);
return logTrace(this, `command`, commandName, ` is non-vanila command`);
}
command.execute = this.getCommandExecutor(commandName);
});
Expand All @@ -59,12 +60,12 @@ export class ConsoleCommandsService extends ClientListener {
// TODO: handle possible exceptions in this function
const schema = this.schemas.get(commandName);
if (schema === undefined) {
this.logError(`Schema not found for command '${commandName}'`);
logError(this, `Schema not found for command`, commandName);
return false;
}

if (args.length !== schema.length && !this.immuneSchema.includes(commandName)) {
this.logError(`Mismatch found in the schema of '${commandName}' command`);
logError(this, `Mismatch found in the schema of`, commandName, `command`);
return false;
}
for (let i = 0; i < args.length; ++i) {
Expand All @@ -77,8 +78,8 @@ export class ConsoleCommandsService extends ClientListener {

this.controller.emitter.emit("sendMessage", {
message: {
t: MsgType.ConsoleCommand,
data: {
t: MsgType.ConsoleCommand,
data: {
commandName,
args
}
Expand Down
12 changes: 7 additions & 5 deletions skymp5-client/src/services/services/craftService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Actor, ContainerChangedEvent } from "skyrimPlatform";
import { ClientListener, CombinedController, Sp } from "./clientListener";
import { Inventory } from "../../sync/inventory";
import { MsgType } from "../../messages";
import { logTrace, logError } from "../../logging";

type FurnitureId = number;

Expand Down Expand Up @@ -35,22 +36,23 @@ export class CraftService extends ClientListener {
count: e.numItems,
});
this.furnitureStreak.set(furnitureId, craftInputObjects);
this.logTrace(
`Adding baseObjId=${baseObjId.toString(16)}, numItems=${e.numItems} to craft`,
logTrace(this,
`Adding baseObjId`, baseObjId.toString(16), `numItems`, e.numItems, `to craft`,
);
} else if (oldContainerId === 0 && newContainerId === 0x14) {
this.logTrace('Finishing craft');
logTrace(this, 'Finishing craft');
const craftInputObjects = this.furnitureStreak.get(furnitureId);
if (craftInputObjects && craftInputObjects.entries.length) {
this.furnitureStreak.delete(furnitureId);
const workbench = localIdToRemoteId(furnitureId);
if (!workbench) {
return this.logError(`localIdToRemoteId returned 0 for furnitureId=${furnitureId}`);
logError(this, `localIdToRemoteId returned 0 for furnitureId`, furnitureId);
return;
}

const resultObjectId = baseObjId;

this.logTrace(`Sending craft workbench=${workbench}, resultObjectId=${resultObjectId}, craftInputObjects=${JSON.stringify(craftInputObjects.entries)}`);
logTrace(this, `Sending craft workbench`, workbench, `resultObjectId`, resultObjectId, `craftInputObjects`, JSON.stringify(craftInputObjects.entries));

this.controller.emitter.emit("sendMessage", {
message: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ActorValue } from "skyrimPlatform";
import { ClientListener, Sp, CombinedController } from "./clientListener";
import { logError } from "../../logging";

export class DisableSkillAdvanceService extends ClientListener {
constructor(private sp: Sp, private controller: CombinedController) {
Expand Down Expand Up @@ -35,7 +36,7 @@ export class DisableSkillAdvanceService extends ClientListener {
private turnOffSkillLocalExp(av: ActorValue): void {
const avi = this.sp.ActorValueInfo.getActorValueInfoByID(av);
if (avi === null) {
this.logError(`Not found ActorValueInfo for actor value ${av}`);
logError(this, `Not found ActorValueInfo for actor value`, av);
return;
}
avi.setSkillUseMult(0);
Expand Down
7 changes: 4 additions & 3 deletions skymp5-client/src/services/services/dropItemService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ClientListener, CombinedController, Sp } from "./clientListener";
import { MsgType } from "../../messages";
import { SweetTaffySweetCantDropService } from "./sweetTaffySweetCantDropService";
import { WorldCleanerService } from "./worldCleanerService";
import { logTrace } from "../../logging";

export class DropItemService extends ClientListener {
constructor(private sp: Sp, private controller: CombinedController) {
Expand Down Expand Up @@ -64,15 +65,15 @@ export class DropItemService extends ClientListener {
if (worldCleanerService.getWcProtection(refrId) === 0) {
ref.delete();
++numFound;
this.logTrace("Found and deleted reference " + refrId.toString(16));
logTrace(this, "Found and deleted reference " + refrId.toString(16));
}
else
this.logTrace("Found reference " + refrId.toString(16) + " but it's protected");
logTrace(this, "Found reference " + refrId.toString(16) + " but it's protected");
}
});

if (!numFound) {
return this.logTrace("Ignoring item drop as false positive");
return logTrace(this, "Ignoring item drop as false positive");
}

const t = MsgType.DropItem;
Expand Down
Loading

0 comments on commit 3a1ef6c

Please sign in to comment.