-
-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
145 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
skymp5-client/src/services/services/spSnippetService.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>; | ||
}; |
This file was deleted.
Oops, something went wrong.