Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(skymp5-client): hide notifications for unnamed items #1760

Merged
merged 1 commit into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion skymp5-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { DeathService } from "./services/services/deathService";
import { ContainersService } from "./services/services/containersService";
import { NetworkingService } from "./services/services/networkingService";
import { RemoteServer } from "./services/services/remoteServer";
import { SpSnippetService } from "./services/services/spSnippetService";

browser.main();

Expand Down Expand Up @@ -112,7 +113,8 @@ const main = () => {
new DeathService(sp, controller),
new ContainersService(sp, controller),
new NetworkingService(sp, controller),
new RemoteServer(sp, controller)
new RemoteServer(sp, controller),
new SpSnippetService(sp, controller)
];
SpApiInteractor.setup(listeners);
listeners.forEach(listener => SpApiInteractor.registerListenerForLookup(listener.constructor.name, listener));
Expand Down
9 changes: 6 additions & 3 deletions skymp5-client/src/services/messages/spSnippetMessage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Snippet } from "../../spSnippet";

export type SpSnippetMessage = {
type: "spSnippet";
} & Snippet;
class: string;
function: string;
arguments: any[];
selfId: number;
snippetIdx: number;
};
42 changes: 8 additions & 34 deletions skymp5-client/src/services/services/remoteServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import * as updateOwner from '../../gamemodeApi/updateOwner';
import * as messages from '../../messages';

/* eslint-disable @typescript-eslint/no-empty-function */
import * as networking from './networkingService';
import * as spSnippet from '../../spSnippet';
import { ObjectReferenceEx } from '../../extensions/objectReferenceEx';
import { AuthGameData } from '../../features/authModel';
import { IdManager } from '../../lib/idManager';
Expand All @@ -32,12 +30,6 @@ import { Inventory, applyInventory } from '../../sync/inventory';
import { Movement } from '../../sync/movement';
import { learnSpells, removeAllSpells } from '../../sync/spell';
import { ModelApplyUtils } from '../../view/modelApplyUtils';
import {
getObjectReference,
getViewFromStorage,
localIdToRemoteId,
remoteIdToLocalId,
} from '../../view/worldViewMisc';
import { FormModel, WorldModel } from '../../modelSource/model';
import { ModelSource } from '../../modelSource/modelSource';
import { SpApiInteractor } from '../spApiInteractor';
Expand All @@ -48,7 +40,6 @@ import { UpdateAnimationMessage } from '../messages/updateAnimationMessage';
import { UpdateEquipmentMessage } from '../messages/updateEquipmentMessage';
import { CustomPacketMessage } from '../messages/customPacketMessage';
import { CustomEventMessage } from '../messages/customEventMessage';
import { FinishSpSnippetMessage } from '../messages/finishSpSnippetMessage';
import { RagdollService } from './ragdollService';
import { UpdateAppearanceMessage } from '../messages/updateAppearanceMessage';
import { TeleportMessage } from '../messages/teleportMessage';
Expand All @@ -64,13 +55,20 @@ import { ConnectionMessage } from '../events/connectionMessage';
import { SetInventoryMessage } from '../messages/setInventoryMessage';
import { CreateActorMessage } from '../messages/createActorMessage';
import { UpdateGamemodeDataMessage } from '../messages/updateGameModeDataMessage';
import { SpSnippetMessage } from '../messages/spSnippetMessage';
import { CustomPacketMessage2 } from '../messages/customPacketMessage2';
import { DestroyActorMessage } from '../messages/destroyActorMessage';
import { SetRaceMenuOpenMessage } from '../messages/setRaceMenuOpenMessage';
import { UpdatePropertyMessage } from '../messages/updatePropertyMessage';
import { TeleportMessage2 } from '../messages/teleportMessage2';

// TODO: refactor worldViewMisc into service
import {
getObjectReference,
getViewFromStorage,
localIdToRemoteId,
remoteIdToLocalId,
} from '../../view/worldViewMisc';

const onceLoad = (
refrId: number,
callback: (refr: ObjectReference) => void,
Expand Down Expand Up @@ -243,7 +241,6 @@ export class RemoteServer extends ClientListener implements ModelSource {
this.controller.emitter.on("customPacketMessage2", (e) => this.onCustomPacketMessage2(e));
this.controller.emitter.on("destroyActorMessage", (e) => this.onDestroyActorMessage(e));
this.controller.emitter.on("setRaceMenuOpenMessage", (e) => this.onSetRaceMenuOpenMessage(e));
this.controller.emitter.on("spSnippetMessage", (e) => this.onSpSnippetMessage(e));
this.controller.emitter.on("updateGamemodeDataMessage", (e) => this.onUpdateGamemodeDataMessage(e));
this.controller.emitter.on("updatePropertyMessage", (e) => this.onUpdatePropertyMessage(e));
this.controller.emitter.on("deathStateContainerMessage", (e) => this.onDeathStateContainerMessage(e));
Expand Down Expand Up @@ -811,29 +808,6 @@ export class RemoteServer extends ClientListener implements ModelSource {
}
}

private onSpSnippetMessage(event: ConnectionMessage<SpSnippetMessage>): void {
const msg = event.message;

once('update', async () => {
spSnippet
.run(msg)
.then((res) => {
if (res === undefined) res = null;
const message: FinishSpSnippetMessage = {
t: messages.MsgType.FinishSpSnippet,
returnValue: res,
snippetIdx: msg.snippetIdx,
}

SpApiInteractor.makeController().emitter.emit("sendMessage", {
message: message,
reliability: "reliable"
});
})
.catch((e) => printConsole('!!! SpSnippet ' + msg.class + ' ' + msg.function + ' failed', e));
});
}

private updateGamemodeUpdateFunctions(
storageVar: string,
functionSources: Record<string, string>,
Expand Down
128 changes: 128 additions & 0 deletions skymp5-client/src/services/services/spSnippetService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { MsgType } from "../../messages";
import { ConnectionMessage } from "../events/connectionMessage";
import { FinishSpSnippetMessage } from "../messages/finishSpSnippetMessage";
import { SpSnippetMessage } from "../messages/spSnippetMessage";
import { ClientListener, CombinedController, Sp } from "./clientListener";

// TODO: refactor worldViewMisc into service
import { remoteIdToLocalId } from '../../view/worldViewMisc';

export class SpSnippetService extends ClientListener {
constructor(private sp: Sp, private controller: CombinedController) {
super();
this.controller.emitter.on("spSnippetMessage", (e) => this.onSpSnippetMessage(e));
this.spAny = sp as Record<string, any>;
}

private onSpSnippetMessage(event: ConnectionMessage<SpSnippetMessage>): void {
const msg = event.message;

this.controller.once('update', async () => {
this.run(msg)
.then((res) => {
if (res === undefined) {
res = null;
}

const message: FinishSpSnippetMessage = {
t: MsgType.FinishSpSnippet,
returnValue: res,
snippetIdx: msg.snippetIdx,
}

this.controller.emitter.emit("sendMessage", {
message: message,
reliability: "reliable"
});
})
.catch((e) => this.logError('SpSnippet ' + msg.class + ' ' + msg.function + ' failed ' + e));
});
}

private async run(snippet: SpSnippetMessage): Promise<any> {
if (snippet.class === "SkympHacks") {
if (snippet.function === "AddItem" || snippet.function === "RemoveItem") {
const form = this.sp.Form.from(this.deserializeArg(snippet.arguments[0]));
if (form === null) {
return this.logError("Unable to find form with id " + snippet.arguments[0].formId.toString(16));
}

const sign = snippet.function === "AddItem" ? "+" : "-";
const count = snippet.arguments[1];

let soundId = 0x334ab;
if (form.getFormID() !== 0xf) {
soundId = 0x14115;
}

const sound = this.sp.Sound.from(this.sp.Game.getFormEx(soundId));
if (sound !== null) {
const name = form.getName();
if (name.trim() === "") {
this.logTrace("Sound will not be played because item has no name")
}
else {
sound.play(this.sp.Game.getPlayer());
}
}
else {
this.logError("Unable to find sound with id " + soundId.toString(16));
}

if (count <= 0) {
this.logError("Positive count expected, got " + count.toString());
}
else {
const name = form.getName();
if (name.trim() === "") {
this.logTrace("Notification will not be shown because item has no name")
}
else {
this.sp.Debug.notification(sign + " " + name + " (" + count + ")");
}
this.logTrace(sign + " " + name + " (" + count + ")");
}
} else throw new Error("Unknown SkympHack - " + snippet.function);
return;
}
return snippet.selfId ? this.runMethod(snippet) : this.runStatic(snippet);
};

private deserializeArg(arg: any) {
if (typeof arg === "object") {
const formId = remoteIdToLocalId(arg.formId);
const form = this.sp.Game.getFormEx(formId);
const gameObject = this.spAny[arg.type].from(form);
return gameObject;
}
return arg;
};

private async runMethod(snippet: SpSnippetMessage): Promise<any> {
const selfId = remoteIdToLocalId(snippet.selfId);
const self = this.sp.Game.getFormEx(selfId);
if (!self)
throw new Error(
`Unable to find form with id ${selfId.toString(16)}`
);
const selfCasted = this.spAny[snippet.class].from(self);
if (!selfCasted)
throw new Error(
`Form ${selfId.toString(16)} is not instance of ${snippet.class}, form type is ${self.getType()}`
);
const f = selfCasted[snippet.function];
return await f.apply(
selfCasted,
snippet.arguments.map((arg) => this.deserializeArg(arg))
);
};

private async runStatic(snippet: SpSnippetMessage): Promise<any> {
const papyrusClass = this.spAny[snippet.class];
return await papyrusClass[snippet.function](
...snippet.arguments.map((arg) => this.deserializeArg(arg))
);
};

private spAny: Record<string, any>;
};
69 changes: 0 additions & 69 deletions skymp5-client/src/spSnippet.ts

This file was deleted.

Loading