From d68e12f4bc2859b9bec747b3e621dfbb046356b4 Mon Sep 17 00:00:00 2001 From: Viet Dinh <54ckb0y789@gmail.com> Date: Tue, 21 Jul 2026 19:56:52 -0400 Subject: [PATCH 1/3] Add chat age warning popup --- chat.js | 19 +++++++++++++++++-- index.php | 28 ++++++++++++++++++++++++++-- play.css | 2 +- play.js | 56 +++++++++++++++++++++++++++++++------------------------ 4 files changed, 76 insertions(+), 29 deletions(-) diff --git a/chat.js b/chat.js index 129b45245..afb41d49c 100644 --- a/chat.js +++ b/chat.js @@ -456,7 +456,9 @@ function updateGameChatMessageVisibility() { } } -function chatInputActionFired() { +async function chatInputActionFired() { + if (!await ensurePlayerConfirmedChatAgeWarning()) return; + const chatInput = document.getElementById("chatInput"); if (!chatInput?.value.trim().length) return; @@ -563,7 +565,7 @@ function initChat() { document.getSelection().collapseToEnd(); }; gameChatInput.onblur = () => gameChatContainer.classList.remove('focused'); - gameChatInput.onkeydown = function (e) { + gameChatInput.onkeydown = async function (e) { if (e.key === 'Tab') { e.preventDefault(); cycleGameChatMode(); @@ -576,6 +578,7 @@ function initChat() { e.preventDefault(); if (!playerName) return; + if (!await ensurePlayerConfirmedChatAgeWarning()) return; switch (gameChatModeIndex) { case 0: if (!trySendMapMessage(chatMessageContent)) @@ -654,6 +657,18 @@ function trySendGlobalMessage(content) { return false; } +async function ensurePlayerConfirmedChatAgeWarning() { + if (globalConfig.chatAgeWarningConfirmed) return true; + + return new Promise(resolve => { + showConfirmLikeModal('chatAgeWarningModal', () => { + resolve(true); + globalConfig.chatAgeWarningConfirmed = true; + updateConfig(globalConfig, true); + }, () => resolve(false)); + }) +} + function addChatTip() { const tips = localizedMessages.chatTips.tips; if (++globalConfig.chatTipIndex >= Object.keys(tips).length) diff --git a/index.php b/index.php index e37bc727e..c4e5008d6 100644 --- a/index.php +++ b/index.php @@ -2201,6 +2201,30 @@ class="joystickBase" />
+ diff --git a/play.css b/play.css index 97eb07aa0..337a08750 100644 --- a/play.css +++ b/play.css @@ -345,7 +345,7 @@ body { flex-wrap: wrap; } -.uiControl { +.uiControl, .chatRulesInfo { text-align: center; } diff --git a/play.js b/play.js index 4a7a7fae8..35a0c0bff 100644 --- a/play.js +++ b/play.js @@ -96,6 +96,7 @@ let globalConfig = { questionablePreloads: false, rulesReviewed: false, warningsReviewed: false, + chatAgeWarningConfirmed: false, badgeToolsData: null, pushNotificationToastDismissed: false, unicodeFont: false, @@ -804,8 +805,6 @@ function closeModal() { } function showConfirmModal(message, okCallback, cancelCallback) { - const modalContainer = document.getElementById('confirmModalContainer'); - const modal = document.getElementById('confirmModal'); if (!modal.classList.contains('hidden')) { @@ -813,13 +812,39 @@ function showConfirmModal(message, okCallback, cancelCallback) { return; } + modal.querySelector('.confirmMessage').innerHTML = getMassagedLabel(message, true); + showConfirmLikeModal('confirmModal', okCallback, cancelCallback); +} + +function showConfirmLikeModal(modalId, okCallback, cancelCallback) { + const modal = document.getElementById(modalId); + if (!modal.classList.contains('hidden')) { + setTimeout(() => showConfirmLikeModal(modalId, okCallback, cancelCallback), modalTransitionDuration); + return; + } + + const modalContainer = modal.parentElement; + + function closeConfirmModal(callback) { + modalContainer.classList.add('fadeOut'); + modal.classList.add('fadeOut'); + + setTimeout(() => { + modal.classList.add('hidden'); + modal.classList.remove('fadeOut'); + modalContainer.classList.add('hidden'); + modalContainer.classList.remove('fadeOut'); + }, modalTransitionDuration); + + if (callback) + callback(); + } + modalContainer.classList.remove('fadeOut', 'hidden'); modalContainer.classList.add('fadeIn'); - modal.querySelector('.confirmMessage').innerHTML = getMassagedLabel(message, true); - - modal.querySelector('.confirmOkButton').onclick = () => closeConfirmModal(okCallback); - modal.querySelector('.confirmCancelButton').onclick = () => closeConfirmModal(cancelCallback); + modal.querySelector('.jsConfirm').onclick = () => closeConfirmModal(okCallback); + modal.querySelector('.jsCancel').onclick = () => closeConfirmModal(cancelCallback); modal.classList.add('fadeIn'); modal.classList.remove('hidden'); @@ -833,29 +858,12 @@ function showConfirmModal(message, okCallback, cancelCallback) { }, modalTransitionDuration); } -function closeConfirmModal(callback) { - const modalContainer = document.getElementById('confirmModalContainer'); - const modal = document.getElementById('confirmModal'); - - modalContainer.classList.add('fadeOut'); - modal.classList.add('fadeOut'); - - setTimeout(() => { - modal.classList.add('hidden'); - modal.classList.remove('fadeOut'); - modalContainer.classList.add('hidden'); - modalContainer.classList.remove('fadeOut'); - }, modalTransitionDuration); - - if (callback) - callback(); -} - document.getElementById('enterNameForm').onsubmit = function () { setName(document.getElementById('nameInput').value); }; { + /** @this {HTMLInputElement} */ function oninputYnomoji() { const ynomojiPattern = /:([a-z0-9_\-]+(?::|$)|$)/gi; const ynomojiContainer = document.getElementById('ynomojiContainer'); From e4ef4d16bc4e33e32e7f9885e7f9f72e02833769 Mon Sep 17 00:00:00 2001 From: Viet Dinh <54ckb0y789@gmail.com> Date: Tue, 21 Jul 2026 22:15:13 -0400 Subject: [PATCH 2/3] Add translations --- index.php | 2 +- lang/ar.json | 8 ++++++++ lang/de.json | 8 ++++++++ lang/en.json | 8 ++++++++ lang/eo.json | 8 ++++++++ lang/es.json | 8 ++++++++ lang/fr.json | 8 ++++++++ lang/id.json | 8 ++++++++ lang/it.json | 8 ++++++++ lang/ja.json | 10 +++++++++- lang/ko.json | 8 ++++++++ lang/pl.json | 8 ++++++++ lang/pt.json | 8 ++++++++ lang/ro.json | 8 ++++++++ lang/ru.json | 10 +++++++++- lang/tr.json | 8 ++++++++ lang/uk.json | 8 ++++++++ lang/vi.json | 8 ++++++++ lang/zh.json | 8 ++++++++ play.js | 5 ++++- 20 files changed, 151 insertions(+), 4 deletions(-) diff --git a/index.php b/index.php index c4e5008d6..b26990576 100644 --- a/index.php +++ b/index.php @@ -2214,7 +2214,7 @@ class="joystickBase" />By participating in the chat, you confirm that you are 16 or older.
-+
Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.
diff --git a/lang/ar.json b/lang/ar.json index fea22ba3d..df766e3f6 100644 --- a/lang/ar.json +++ b/lang/ar.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/de.json b/lang/de.json index 93007fd65..74b777090 100644 --- a/lang/de.json +++ b/lang/de.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/en.json b/lang/en.json index 844ef6865..6ec80f701 100644 --- a/lang/en.json +++ b/lang/en.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/eo.json b/lang/eo.json index f8af9103f..4c398d74b 100644 --- a/lang/eo.json +++ b/lang/eo.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/es.json b/lang/es.json index 90b6c8a95..f81cbb669 100644 --- a/lang/es.json +++ b/lang/es.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/fr.json b/lang/fr.json index e4b79a52d..5ba13461b 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/id.json b/lang/id.json index ae38a9d4f..18cba3cff 100644 --- a/lang/id.json +++ b/lang/id.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/it.json b/lang/it.json index 02a254093..9e8401fca 100644 --- a/lang/it.json +++ b/lang/it.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/ja.json b/lang/ja.json index c62f05e84..5d1e9a75c 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { @@ -1251,4 +1259,4 @@ } } } -} +} \ No newline at end of file diff --git a/lang/ko.json b/lang/ko.json index 377ad629b..a4013240b 100644 --- a/lang/ko.json +++ b/lang/ko.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/pl.json b/lang/pl.json index bd3809826..fb221ae2e 100644 --- a/lang/pl.json +++ b/lang/pl.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/pt.json b/lang/pt.json index 97f07a453..dcd0c1b0c 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/ro.json b/lang/ro.json index f157c6b13..6c688c95f 100644 --- a/lang/ro.json +++ b/lang/ro.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/ru.json b/lang/ru.json index 363342b04..dcae989c3 100644 --- a/lang/ru.json +++ b/lang/ru.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { @@ -1251,4 +1259,4 @@ } } } -} +} \ No newline at end of file diff --git a/lang/tr.json b/lang/tr.json index f96fd7ab5..857c62007 100644 --- a/lang/tr.json +++ b/lang/tr.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/uk.json b/lang/uk.json index 11e08e90b..3c7f1f020 100644 --- a/lang/uk.json +++ b/lang/uk.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/vi.json b/lang/vi.json index 9d21ed088..a7236fbca 100644 --- a/lang/vi.json +++ b/lang/vi.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/lang/zh.json b/lang/zh.json index bd054dc5c..db7d7e032 100644 --- a/lang/zh.json +++ b/lang/zh.json @@ -619,6 +619,14 @@ } } } + }, + "chatAgeWarning": { + "1": "Game chat is reserved for players of ages 16 and older.", + "2": "By participating in the chat, you confirm that you are 16 or older.", + "3": "Players found to be in violation of this rule are subject to moderation actions, up to and including permanent bans from multiplayer interactions.", + "title": "Before you chat...", + "ok": "Confirm", + "cancel": "Do not participate in chat" } }, "tooltips": { diff --git a/play.js b/play.js index 35a0c0bff..190e4e7fb 100644 --- a/play.js +++ b/play.js @@ -55,6 +55,8 @@ let gameMapHandle = new WeakRef({}); const modalTransitionDuration = 230; +const confirmLikeModals = ['confirmModal', 'chatAgeWarningModal']; + const langLabelMassageFunctions = { 'ja': (value, isUI) => { if (typeof value === 'string' && /<[^>]+>/.test(value)) { @@ -783,7 +785,8 @@ function closeModal() { updateFullscreenPolling(); } - setModalUiTheme('confirmModal', config.uiTheme === 'auto' ? systemName : config.uiTheme); + for (const modal of confirmLikeModals) + setModalUiTheme(modal, config.uiTheme === 'auto' ? systemName : config.uiTheme); if (modalContainer.dataset.lastModalId) { const lastModalIdSeparatorIndex = modalContainer.dataset.lastModalId.lastIndexOf(','); From 1be0ca23d7c43b9a747da8be3a4954d930f34757 Mon Sep 17 00:00:00 2001 From: Viet Dinh <54ckb0y789@gmail.com> Date: Tue, 21 Jul 2026 22:54:16 -0400 Subject: [PATCH 3/3] Add report modal reminder --- index.php | 1 + lang/ar.json | 3 ++- lang/de.json | 3 ++- lang/en.json | 1 + lang/eo.json | 3 ++- lang/es.json | 3 ++- lang/fr.json | 3 ++- lang/id.json | 3 ++- lang/it.json | 3 ++- lang/ja.json | 3 ++- lang/ko.json | 3 ++- lang/pl.json | 3 ++- lang/pt.json | 3 ++- lang/ro.json | 3 ++- lang/ru.json | 3 ++- lang/tr.json | 3 ++- lang/uk.json | 3 ++- lang/vi.json | 3 ++- lang/zh.json | 3 ++- 19 files changed, 36 insertions(+), 17 deletions(-) diff --git a/index.php b/index.php index b26990576..fce75fcd8 100644 --- a/index.php +++ b/index.php @@ -1755,6 +1755,7 @@ class="joystickBase" /> ✖