From 5479aea9f0f5f38be0aa300aed804b86bbb5f116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Tue, 26 Apr 2022 14:40:54 +0200 Subject: [PATCH] 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. --- front/src/Api/IframeListener.ts | 15 +++++++++++---- front/src/Api/ScriptUtils.ts | 4 ++-- front/src/Stores/ChatStore.ts | 7 +++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 345f3b41..f9f2b634 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -239,7 +239,7 @@ class IframeListener { } else if (iframeEvent.type === "cameraFollowPlayer") { this._cameraFollowPlayerStream.next(iframeEvent.data); } else if (iframeEvent.type === "chat") { - scriptUtils.sendAnonymousChat(iframeEvent.data); + scriptUtils.sendAnonymousChat(iframeEvent.data, iframe.contentWindow ?? undefined); } else if (iframeEvent.type === "openPopup") { this._openPopupStream.next(iframeEvent.data); } else if (iframeEvent.type === "closePopup") { @@ -399,13 +399,17 @@ class IframeListener { 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({ type: "userInputChat", data: { message: message, } as UserInputChatEvent, - }); + }, exceptOrigin); } sendEnterEvent(name: string) { @@ -521,8 +525,11 @@ class IframeListener { /** * Sends the message... to all allowed iframes. */ - public postMessage(message: IframeResponseEvent) { + public postMessage(message: IframeResponseEvent, exceptOrigin?: Window) { for (const iframe of this.iframes) { + if (exceptOrigin === iframe.contentWindow) { + continue; + } iframe.contentWindow?.postMessage(message, "*"); } } diff --git a/front/src/Api/ScriptUtils.ts b/front/src/Api/ScriptUtils.ts index f0a0625a..d6d70e81 100644 --- a/front/src/Api/ScriptUtils.ts +++ b/front/src/Api/ScriptUtils.ts @@ -11,9 +11,9 @@ class ScriptUtils { window.location.href = url; } - public sendAnonymousChat(chatEvent: ChatEvent) { + public sendAnonymousChat(chatEvent: ChatEvent, origin?: Window) { const userId = playersStore.addFacticePlayer(chatEvent.author); - chatMessagesStore.addExternalMessage(userId, chatEvent.message); + chatMessagesStore.addExternalMessage(userId, chatEvent.message, origin); } } diff --git a/front/src/Stores/ChatStore.ts b/front/src/Stores/ChatStore.ts index b8d4ea7b..9dfe7e42 100644 --- a/front/src/Stores/ChatStore.ts +++ b/front/src/Stores/ChatStore.ts @@ -87,7 +87,10 @@ function createChatMessagesStore() { 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) => { const lastMessage = list[list.length - 1]; if ( @@ -106,7 +109,7 @@ function createChatMessagesStore() { }); } - iframeListener.sendUserInputChat(text); + iframeListener.sendUserInputChat(text, origin); return list; }); chatVisibilityStore.set(true);