Preventing a loop from occuring with chat API

When sending a chat message from the Scripting API, the chat message is no longer sent back to the chat listener.
This makes it easier to avoid infinite loops.
This commit is contained in:
David Négrier 2022-04-26 14:40:54 +02:00
parent 44778f51f8
commit 5479aea9f0
3 changed files with 18 additions and 8 deletions

View File

@ -239,7 +239,7 @@ class IframeListener {
} else if (iframeEvent.type === "cameraFollowPlayer") { } else if (iframeEvent.type === "cameraFollowPlayer") {
this._cameraFollowPlayerStream.next(iframeEvent.data); this._cameraFollowPlayerStream.next(iframeEvent.data);
} else if (iframeEvent.type === "chat") { } else if (iframeEvent.type === "chat") {
scriptUtils.sendAnonymousChat(iframeEvent.data); scriptUtils.sendAnonymousChat(iframeEvent.data, iframe.contentWindow ?? undefined);
} else if (iframeEvent.type === "openPopup") { } else if (iframeEvent.type === "openPopup") {
this._openPopupStream.next(iframeEvent.data); this._openPopupStream.next(iframeEvent.data);
} else if (iframeEvent.type === "closePopup") { } else if (iframeEvent.type === "closePopup") {
@ -399,13 +399,17 @@ class IframeListener {
this.scripts.delete(scriptUrl); this.scripts.delete(scriptUrl);
} }
sendUserInputChat(message: string) { /**
* @param message The message to dispatch
* @param exceptOrigin Don't dispatch the message to exceptOrigin (to avoid infinite loops)
*/
sendUserInputChat(message: string, exceptOrigin?: Window) {
this.postMessage({ this.postMessage({
type: "userInputChat", type: "userInputChat",
data: { data: {
message: message, message: message,
} as UserInputChatEvent, } as UserInputChatEvent,
}); }, exceptOrigin);
} }
sendEnterEvent(name: string) { sendEnterEvent(name: string) {
@ -521,8 +525,11 @@ class IframeListener {
/** /**
* Sends the message... to all allowed iframes. * Sends the message... to all allowed iframes.
*/ */
public postMessage(message: IframeResponseEvent<keyof IframeResponseEventMap>) { public postMessage(message: IframeResponseEvent<keyof IframeResponseEventMap>, exceptOrigin?: Window) {
for (const iframe of this.iframes) { for (const iframe of this.iframes) {
if (exceptOrigin === iframe.contentWindow) {
continue;
}
iframe.contentWindow?.postMessage(message, "*"); iframe.contentWindow?.postMessage(message, "*");
} }
} }

View File

@ -11,9 +11,9 @@ class ScriptUtils {
window.location.href = url; window.location.href = url;
} }
public sendAnonymousChat(chatEvent: ChatEvent) { public sendAnonymousChat(chatEvent: ChatEvent, origin?: Window) {
const userId = playersStore.addFacticePlayer(chatEvent.author); const userId = playersStore.addFacticePlayer(chatEvent.author);
chatMessagesStore.addExternalMessage(userId, chatEvent.message); chatMessagesStore.addExternalMessage(userId, chatEvent.message, origin);
} }
} }

View File

@ -87,7 +87,10 @@ function createChatMessagesStore() {
return list; return list;
}); });
}, },
addExternalMessage(authorId: number, text: string) { /**
* @param origin The iframe that originated this message (if triggered from the Scripting API), or undefined otherwise.
*/
addExternalMessage(authorId: number, text: string, origin?: Window) {
update((list) => { update((list) => {
const lastMessage = list[list.length - 1]; const lastMessage = list[list.length - 1];
if ( if (
@ -106,7 +109,7 @@ function createChatMessagesStore() {
}); });
} }
iframeListener.sendUserInputChat(text); iframeListener.sendUserInputChat(text, origin);
return list; return list;
}); });
chatVisibilityStore.set(true); chatVisibilityStore.set(true);