var fs = require('fs'); var minify = require('html-minifier').minify; var escape = require('escape-html'); // Minify at runtime to save data on slow connections, but still allow editing the unminified file easily // Is that a bad idea? // Templates for viewing the channels in a server const server_template = minify(fs.readFileSync('pages/templates/server.html', 'utf-8')); const text_channel_template = minify(fs.readFileSync('pages/templates/channellist/textchannel.html', 'utf-8')); const category_channel_template = minify(fs.readFileSync('pages/templates/channellist/categorychannel.html', 'utf-8')); const server_icon_template = minify(fs.readFileSync('pages/templates/server/server_icon.html', 'utf-8')); const invalid_server_template = minify(fs.readFileSync('pages/templates/server/invalid_server.html', 'utf-8')); const cachedMembers = {}; // TODO: Find a better way function strReplace(string, needle, replacement) { return string.split(needle).join(replacement||""); }; // https://stackoverflow.com/questions/1967119/why-does-javascript-replace-only-first-instance-when-using-replace exports.processServer = async function (bot, req, res, args, discordID) { guestServers = ["439461201731387392"]; guestChannels = ["608958017366654986"]; var isGuest = false; if (typeof(discordID) == "object") { isGuest = true; } serverList = ""; for (var server of bot.client.guilds.cache) { server = server[1]; if (cachedMembers[discordID] && cachedMembers[discordID][server.id] !== undefined) { member = cachedMembers[discordID][server.id]; } else if (!(isGuest && guestServers.includes(server.id))) { try { member = await server.members.fetch(discordID); } catch (err) { member = null; } if (!cachedMembers[discordID]) { cachedMembers[discordID] = {}; } cachedMembers[discordID][server.id] = member; } if ((isGuest && guestServers.includes(server.id)) || (member && member.user)) { serverHTML = strReplace(server_icon_template, "{$SERVER_ICON_URL}", server.iconURL()); serverHTML = strReplace(serverHTML, "{$SERVER_URL}", "./" + server.id); serverList += serverHTML; } } response = server_template.replace("{$SERVER_LIST}", serverList); server = bot.client.guilds.cache.get(args[2]); try { if (!(isGuest && guestServers.includes(server.id))) { member = await server.members.fetch(discordID); user = member.user; username = user.tag; if (member.displayName != user.username) { username = member.displayName + " (@" + user.tag + ")"; } } //} else { // username = "Guest"; //} // username = if (!((isGuest && guestServers.includes(server.id)) || member.user)) { server = undefined; } } catch (err) { // If they aren't in the server // console.log(err); TODO: Only ignore TypeError: Cannot read property 'members' of undefined server = undefined; // Act like it doesn't exist } if (server) { categories = server.channels.cache.filter(channel => channel.type == "category"); categoriesSorted = categories.sort((a, b) => (a.calculatedPosition - b.calculatedPosition)); channelsSorted = server.channels.cache.filter(channel => channel.type != "category" && channel.type != "voice" && !channel.parent).array(); // Start with lone channels (no category) channelsSorted = channelsSorted.sort((a, b) => (a.calculatedPosition - b.calculatedPosition)); categoriesSorted.forEach(function(category) { channelsSorted.push(category); channelsSorted = channelsSorted.concat( category.children.sort((a, b) => (a.calculatedPosition - b.calculatedPosition)) .array() .filter(channel => channel.type != "voice") ); }); channelList = ""; channelsSorted.forEach(function(item) { if ((isGuest && guestChannels.includes(item.id)) || (member.permissionsIn && member.permissionsIn(item).has("VIEW_CHANNEL", true))) { if (item.type == "category") { channelList += category_channel_template.replace("{$CHANNEL_NAME}", escape(item.name)); } else { channelList += text_channel_template.replace("{$CHANNEL_NAME}", escape(item.name)).replace("{$CHANNEL_LINK}", "../channels/" + item.id + "#end"); } } }); } else { channelList = invalid_server_template; } response = response.replace("{$CHANNEL_LIST}", channelList); res.writeHead(200, { "Content-Type": "text/html" }); res.write(response); res.end(); }