Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion backend/subsystems/chat_mgr.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,49 @@ async function chatDatabaseClock(serverExit) {
}
}

var muted_ips_by_world_id = {}; // id 0 = global
function getMuteInfo(world_id, ip) {
var worldChatMutes = muted_ips_by_world_id[world_id];

if(worldChatMutes) {
return worldChatMutes[ip];
}

return null;
}

function mute(world_id, ip, date) {
if(!muted_ips_by_world_id[world_id]) muted_ips_by_world_id[world_id] = {};
muted_ips_by_world_id[world_id][ip] = [date];
}

function clearMutes(world_id) {
var cnt = 0;

if(muted_ips_by_world_id[world_id]) {
cnt = Object.keys(muted_ips_by_world_id[world_id]).length;
delete muted_ips_by_world_id[world_id];
}

return cnt;
}

function unmute(world_id, ip) {
var worldChatMutes = muted_ips_by_world_id[world_id];

if(worldChatMutes) {
delete worldChatMutes[ip];
}
}

var tell_blocks = {};

module.exports.retrieveChatHistory = retrieveChatHistory;
module.exports.add_to_chatlog = add_to_chatlog;
module.exports.remove_from_chatlog = remove_from_chatlog;
module.exports.clearChatlog = clearChatlog;
module.exports.clearChatlog = clearChatlog;
module.exports.getMuteInfo = getMuteInfo;
module.exports.mute = mute;
module.exports.clearMutes = clearMutes;
module.exports.unmute = unmute;
module.exports.tell_blocks = tell_blocks;
34 changes: 33 additions & 1 deletion backend/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,37 @@ function checkURLParam(mask, url) {
return values;
}

function getClientIPByChatID(server, world_id, id, isGlobal) {
var client_ips = server.client_ips;

if(isGlobal) {
// since this is global, there is the potential for duplicate IDs.
// pick the one that has chatted the most recently.
var latestGCli = null;
var latestGCliTime = -1;
for(var cw in client_ips) {
var worldClients = client_ips[cw];
if(worldClients[id]) {
var gCli = worldClients[id];
if(gCli[3] != -1 && gCli[3] >= latestGCliTime) {
latestGCliTime = gCli[3];
latestGCli = gCli;
}
}
}
if(latestGCli) {
return latestGCli[0];
}
} else {
if(client_ips[world_id]) {
if(client_ips[world_id][id]) {
return client_ips[world_id][id][0];
}
}
}
return null;
}

module.exports = {
trimHTML,
create_date,
Expand Down Expand Up @@ -851,5 +882,6 @@ module.exports = {
trimSlash,
checkDuplicateCookie,
toHex64,
toInt64
toInt64,
getClientIPByChatID
};
69 changes: 69 additions & 0 deletions backend/websockets/block_id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
var utils = require("../utils/utils.js");
var san_nbr = utils.san_nbr;
var getClientIPByChatID = utils.getClientIPByChatID;

module.exports = async function(ws, data, send, broadcast, server, ctx) {
var world = ctx.world
var chat_mgr = server.chat_mgr;
var tell_blocks = chat_mgr.tell_blocks;

var ipHeaderAddr = ws.sdata.ipAddress;
var blocks = ws.sdata.chat_blocks;

var id = san_nbr(data.id);
if(id < 0) {
if(data.block) {
send({
success: false,
error: "bad_id"
});
}

return;
}

var location = "";
if(!(data.location == "global" || data.location == "page")) data.location = "page";
location = data.location;

if(data.block) {
if ((blocks.id.length + blocks.user.length) >= 1280) {
send({
success: false,
error: "too_many"
});
return;
}

if (blocks.id.indexOf(id) > -1) return;
blocks.id.push(id);

var blocked_ip = getClientIPByChatID(server, world.id, id, location == "global");
if(blocked_ip) {
var blist = tell_blocks[ipHeaderAddr];
if(!blist) {
blist = {};
tell_blocks[ipHeaderAddr] = blist;
}
if(!blist[blocked_ip]) {
blist[blocked_ip] = Date.now();
}
}

send({
success: true
});
} else {
var idx = blocks.id.indexOf(id);
if(idx == -1) return;
blocks.id.splice(idx, 1);

var unblocked_ip = getClientIPByChatID(server, world.id, id, location == "global");
if(unblocked_ip) {
var blist = tell_blocks[ipHeaderAddr];
if(blist) {
delete blist[unblocked_ip];
}
}
}
}
8 changes: 8 additions & 0 deletions backend/websockets/block_special.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = async function(ws, data, send, broadcast, server, ctx) {
var blocks = ws.sdata.chat_blocks;

if (typeof data.all == "boolean") blocks.block_all = data.all;
if (typeof data.tell == "boolean") blocks.no_tell = data.tell;
if (typeof data.anon == "boolean") blocks.no_anon = data.anon;
if (typeof data.reg == "boolean") blocks.no_reg = data.reg;
}
41 changes: 41 additions & 0 deletions backend/websockets/block_user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module.exports = async function(ws, data, send, broadcast, server, ctx) {
var blocks = ws.sdata.chat_blocks;

var username = data.username;
if(typeof username != "string" || !username) {
send({
success: false,
error: "bad_username"
});
return;
}

if(data.block) {
if (!/^[^\s\x00-\x20]+$/.test(username)) return;

// The case-insensitive value to be stored in chat_blocks.
var username_value = username.toUpperCase();

// Ensure maximum block count not exceeded, and check if it already exists.
if ((blocks.id.length + blocks.user.length) >= 1280) {
send({
success: false,
error: "too_many"
});
return;
}

if (blocks.user.indexOf(username_value) > -1) return;
blocks.user.push(username_value);

send({
success: true
});
} else {
var username_value = username.toUpperCase();

var idx = blocks.user.indexOf(username_value);
if(idx == -1) return;
blocks.user.splice(idx, 1);
}
}
Loading