From 1294c03679cb672d7229215d2338ad97f6e1b449 Mon Sep 17 00:00:00 2001 From: KKosty4ka <49340075+KKosty4ka@users.noreply.github.com> Date: Thu, 23 Jul 2026 19:36:10 +0700 Subject: [PATCH 1/3] add /unmuteuser --- backend/websockets/chat.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/backend/websockets/chat.js b/backend/websockets/chat.js index a2cd460b..edaa3dcb 100644 --- a/backend/websockets/chat.js +++ b/backend/websockets/chat.js @@ -237,6 +237,7 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { [0, "unblockall", null, "unblock all users", null], [0, "mute", ["id", "seconds", "[h/d/w/m/y]"], "mute a user completely", "1220 9999"], // check for permission [0, "muteuser", ["username", "seconds", "[h/d/w/m/y]"], "mute a user by their username completely", "JohnDoe 9999"], // check for permission + [0, "unmuteuser", ["username"], "unmute a user muted by their username", "JohnDoe"], // check for permission [0, "clearmutes", null, "unmute all clients"], // check for permission [0, "delete", ["id", "timestamp"], "delete a chat message", "1220 1693147307895"], // check for permission [0, "tell", ["id", "message"], "tell someone a secret message", "1220 The coordinates are (392, 392)"], @@ -273,7 +274,7 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { var desc = row[3]; var example = row[4]; - if(command == "mute" || command == "muteuser" || command == "clearmutes" || command == "delete") { + if(["mute", "muteuser", "unmuteuser", "clearmutes", "delete"].includes(command)) { if(!user.staff && !is_owner) { continue; } @@ -650,6 +651,27 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { serverChatResponse("Muted client by username until " + create_date(muteDate), location); } }, + unmuteuser: async function(username) { + if(!is_owner && !user.staff) return; + if(location == "global" && !user.staff) { + return serverChatResponse("You do not have permission to unmute on global", location); + } + + var username_value = sanitize_username(username); + if (username_value == null) { + serverChatResponse("Invalid username", location); + return; + } + + var user_id = await getUserIdFromUsername(username_value); + if(!user_id) { + serverChatResponse("Could not resolve username to account", location); + return; + } + + chat_mgr.unmuteByUserID(effectiveWorldID, user_id); + serverChatResponse("Unmuted client", location); + }, clearmutes: function() { if(!is_owner && !user.staff) return; var ipCnt = 0; @@ -817,6 +839,9 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { case "muteuser": com.muteuser(commandArgs[1], commandArgs[2], commandArgs[3]); return; + case "unmuteuser": + com.unmuteuser(commandArgs[1]); + return; case "clearmutes": com.clearmutes(); return; From 120b2f78ec31382a3f832190c802dee4b53fe8c3 Mon Sep 17 00:00:00 2001 From: KKosty4ka <49340075+KKosty4ka@users.noreply.github.com> Date: Thu, 23 Jul 2026 20:13:52 +0700 Subject: [PATCH 2/3] add /unmute --- backend/websockets/chat.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/backend/websockets/chat.js b/backend/websockets/chat.js index edaa3dcb..7aca981f 100644 --- a/backend/websockets/chat.js +++ b/backend/websockets/chat.js @@ -236,6 +236,7 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { [0, "unblockuser", ["username"], "unblock someone by username", "JohnDoe"], [0, "unblockall", null, "unblock all users", null], [0, "mute", ["id", "seconds", "[h/d/w/m/y]"], "mute a user completely", "1220 9999"], // check for permission + [0, "unmute", ["id"], "unmute a user muted by id", "1220"], // check for permission [0, "muteuser", ["username", "seconds", "[h/d/w/m/y]"], "mute a user by their username completely", "JohnDoe 9999"], // check for permission [0, "unmuteuser", ["username"], "unmute a user muted by their username", "JohnDoe"], // check for permission [0, "clearmutes", null, "unmute all clients"], // check for permission @@ -274,7 +275,7 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { var desc = row[3]; var example = row[4]; - if(["mute", "muteuser", "unmuteuser", "clearmutes", "delete"].includes(command)) { + if(["mute", "unmute", "muteuser", "unmuteuser", "clearmutes", "delete"].includes(command)) { if(!user.staff && !is_owner) { continue; } @@ -615,6 +616,22 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { serverChatResponse("Client not found", location); } }, + unmute: function(id) { + if(!is_owner && !user.staff) return; + if(location == "global" && !user.staff) { + return serverChatResponse("You do not have permission to unmute on global", location); + } + + id = san_nbr(id); + var muted_ip = getClientIPByChatID(id, location == "global"); + + if(muted_ip) { + chat_mgr.unmuteByIP(effectiveWorldID, muted_ip); + serverChatResponse("Unmuted client", location); + } else { + serverChatResponse("Client not found", location); + } + }, muteuser: async function(username, time, flag) { if(!is_owner && !user.staff) return; if(location == "global" && !user.staff) { @@ -836,6 +853,9 @@ module.exports = async function(ws, data, send, broadcast, server, ctx) { case "mute": com.mute(commandArgs[1], commandArgs[2], commandArgs[3]); return; + case "unmute": + com.unmute(commandArgs[1]); + return; case "muteuser": com.muteuser(commandArgs[1], commandArgs[2], commandArgs[3]); return; From 318f52720a07e606769b82cb6cb5d11671ba7619 Mon Sep 17 00:00:00 2001 From: KKosty4ka <49340075+KKosty4ka@users.noreply.github.com> Date: Thu, 23 Jul 2026 20:16:59 +0700 Subject: [PATCH 3/3] properly remove unmuted users from muteDB --- backend/subsystems/chat_mgr.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/backend/subsystems/chat_mgr.js b/backend/subsystems/chat_mgr.js index 755c5f46..2468fce3 100644 --- a/backend/subsystems/chat_mgr.js +++ b/backend/subsystems/chat_mgr.js @@ -200,18 +200,14 @@ function unmuteByIP(world_id, ip) { if(mutedIPsByWorldID[world_id]) { delete mutedIPsByWorldID[world_id][ip]; } - if(muteDBUpdates.mute_ip[world_id]) { - muteDBUpdates.mute_ip[world_id][ip] = {expiration_date: 0, issuer_user_id: null}; - } + (muteDBUpdates.mute_ip[world_id] ??= {})[ip] = {expiration_date: 0, issuer_user_id: null}; } function unmuteByUserID(world_id, user_id) { if(mutedUsersByWorldID[world_id]) { delete mutedUsersByWorldID[world_id][user_id]; } - if(muteDBUpdates.mute_user_id[world_id]) { - muteDBUpdates.mute_user_id[world_id][user_id] = {expiration_date: 0, issuer_user_id: null}; - } + (muteDBUpdates.mute_user_id[world_id] ??= {})[user_id] = {expiration_date: 0, issuer_user_id: null}; } function getMuteByIP(world_id, ip) {