Compare commits

...

1 Commits

Author SHA1 Message Date
Lamp 9d72e59b20 update 2022-06-24 13:14:52 -07:00
10 changed files with 1342 additions and 1301 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules
config.js
config.json

View File

@ -1,5 +0,0 @@
// based on https://piano.ourworldofpixels.com/antiswear.js, update as necessary
module.exports = function (msg) {
var a = ['eldit', 'infraraven', 'kit', 'dimden', 'BOT', '5h1t', '5hit', 'a55', 'anal', 'anus', 'ar5e', 'arrse', 'arse', 'ass', 'ass-fucker', 'asses', 'assfucker', 'assfukka', 'asshole', 'assholes', 'asswhole', 'a_s_s', 'b00bs', 'b17ch', 'b1tch', 'ballbag', 'balls', 'ballsack', 'bastard', 'beastial', 'beastiality', 'bellend', 'bestial', 'bestiality', 'bi+ch', 'biatch', 'bitch', 'bitcher', 'bitchers', 'bitches', 'bitchin', 'bitching', 'bloody', 'blowjob', 'blowjobs', 'boiolas', 'bollock', 'bollok', 'boner', 'boob', 'boobs', 'booobs', 'boooobs', 'booooobs', 'breasts', 'buceta', 'bugger', 'bum', 'butt', 'butthole', 'buttmuch', 'buttplug', 'c0ck', 'c0cksucker', 'cawk', 'chink', 'cipa', 'cl1t', 'clit', 'clitoris', 'clits', 'cnut', 'cock', 'cock-sucker', 'cockface', 'cockhead', 'cockmunch', 'cockmuncher', 'cocks', 'cocksuck', 'cocksucked', 'cocksucker', 'cocksucking', 'cocksucks', 'cocksuka', 'cocksukka', 'cok', 'cokmuncher', 'coksucka', 'coon', 'cox', 'cum', 'cummer', 'cumming', 'cums', 'cumshot', 'cunilingus', 'cunillingus', 'cunnilingus', 'cunt', 'cuntlick', 'cuntlicker', 'cuntlicking', 'cunts', 'cyalis', 'cyberfuc', 'cyberfuck', 'cyberfucked', 'cyberfucker', 'cyberfuckers', 'cyberfucking', 'd1ck', 'damn', 'dick', 'dickhead', 'dildo', 'dildos', 'dink', 'dinks', 'dirsa', 'dlck', 'doggin', 'dogging', 'donkeyribber', 'doosh', 'duche', 'dyke', 'ejaculate', 'ejaculated', 'ejaculates', 'ejaculating', 'ejaculatings', 'ejaculation', 'ejakulate', 'f4nny', 'fag', 'fagging', 'faggitt', 'faggot', 'faggs', 'fagot', 'fagots', 'fags', 'fanny', 'fannyflaps', 'fannyfucker', 'fanyy', 'fatass', 'fcuk', 'fcuker', 'fcuking', 'feck', 'fecker', 'felching', 'fellate', 'fellatio', 'fingerfuck', 'fingerfucked', 'fingerfucker', 'fingerfuckers', 'fingerfucking', 'fingerfucks', 'fistfuck', 'fistfucked', 'fistfucker', 'fistfuckers', 'fistfucking', 'fistfuckings', 'fistfucks', 'flange', 'fook', 'fooker', 'fuck', 'fucka', 'fucked', 'fucker', 'fuckers', 'fuckhead', 'fuckheads', 'fuckin', 'fucking', 'fuckings', 'fuckingshitmotherfucker', 'fuckme', 'fucks', 'fuckwhit', 'fuckwit', 'fudgepacker', 'fuk', 'fuker', 'fukker', 'fukkin', 'fuks', 'fukwhit', 'fukwit', 'fux', 'fux0r', 'f_u_c_k', 'gangbang', 'gangbanged', 'gangbangs', 'gaylord', 'gaysex', 'goatse', 'hardcoresex', 'heshe', 'hoar', 'hoare', 'hoer', 'homo', 'hore', 'horniest', 'horny', 'hotsex', 'jackoff', 'jap', 'jism', 'jiz', 'jizm', 'jizz', 'kawk', 'knob', 'knobead', 'knobed', 'knobend', 'knobhead', 'knobjocky', 'knobjokey', 'kock', 'kondum', 'kondums', 'kum', 'kummer', 'kumming', 'kums', 'kunilingus', 'l3i+ch', 'l3itch', 'labia', 'lmfao', 'lust', 'lusting', 'm0f0', 'm0fo', 'm45terbate', 'ma5terb8', 'ma5terbate', 'masochist', 'masterb8', 'masterbat*', 'masterbat3', 'masterbate', 'masterbation', 'masterbations', 'masturbate', 'mof0', 'mofo', 'mothafuck', 'mothafucka', 'mothafuckas', 'mothafuckaz', 'mothafucked', 'mothafucker', 'mothafuckers', 'mothafuckin', 'mothafucking', 'mothafuckings', 'mothafucks', 'mother fucker', 'motherfuck', 'motherfucked', 'motherfucker', 'motherfuckers', 'motherfuckin', 'motherfucking', 'motherfuckings', 'motherfuckka', 'motherfucks', 'muff', 'mutha', 'muthafecker', 'muthafuckker', 'muther', 'mutherfucker', 'n1gga', 'n1gger', 'nazi', 'nigg3r', 'nigg4h', 'nigga', 'niggah', 'niggas', 'niggaz', 'nigger', 'niggers', 'nob', 'nobhead', 'nobjocky', 'nobjokey', 'numbnuts', 'nutsack', 'orgasim', 'orgasims', 'orgasm', 'orgasms', 'p0rn', 'pawn', 'pecker', 'penis', 'penisfucker', 'phonesex', 'phuck', 'phuk', 'phuked', 'phuking', 'phukked', 'phukking', 'phuks', 'phuq', 'pigfucker', 'pimpis', 'piss', 'pissed', 'pisser', 'pissers', 'pisses', 'pissflaps', 'pissin', 'pissing', 'pissoff', 'poop', 'porn', 'porno', 'pornography', 'pornos', 'prick', 'pricks', 'pron', 'pube', 'pusse', 'pussi', 'pussies', 'pussy', 'pussys', 'rectum', 'retard', 'rimjaw', 'rimming', 'sadist', 'schlong', 'screwing', 'scroat', 'scrote', 'scrotum', 'semen', 'sex', 'sh1t', 'shag', 'shagger', 'shaggin', 'shagging', 'shemale', 'shi+', 'shit', 'shitdick', 'shite', 'shited', 'shitey', 'shitfuck', 'shitfull', 'shithead', 'shiting', 'shitings', 'shits', 'shitted', 'shitter', 'shitters', 'shitting', 'shittings', 'shitty', 'skank', 'slut', 'sluts', 'smegma', 'smut', 'snatch', 'spac', 'spunk', 's_h_i_t', 't1tt1e5', 't1tties', 'teets', 'teez', 'testical', 'testicle', 'tit', 'titfuck', 'tits', 'titt', 'tittie5', 'tittiefucker', 'titties', 'tittyfuck', 'tittywank', 'titwank', 'tosser', 'turd', 'tw4t', 'twat', 'twathead', 'twatty', 'twunt', 'twunter', 'v14gra', 'v1gra', 'vagina', 'viagra', 'vulva', 'w00se', 'wang', 'wank', 'wanker', 'wanky', 'whoar', 'whore', 'willies', 'willy', 'xrated', 'xxx'];
return msg.replace(/\b\w+\b/g, w => a.includes(w.toLowerCase()) ? '~~' + w + '~~' : w);
}

View File

@ -1,45 +0,0 @@
#!/usr/bin/env node
var Discord = require('discord.js');
var puppeteer = require("puppeteer");
var config = require("./config");
var archive_webhook = new Discord.WebhookClient(config.archive_webhook.id, config.archive_webhook.token);
(async function archive() {
console.log("Archive started @", Date());
var browser = await puppeteer.launch({args:['--no-sandbox']});
var page = await browser.newPage();
page.on("console", function(consoleMsg){
console.log("[Web Console]", consoleMsg.text());
});
await page.setViewport({width:2048, height:2048});
console.log("Page opened");
await page.goto("https://ourworldofpixels.com");
console.log("OWOP Loaded");
await page.evaluate(async function (captcha_password) {
OWOP.camera.zoom = 1;
OWOP.options.noUi = true;
localStorage.owopOptions = '{"defaultZoom": 1, "noUi": true}';
localStorage.owopcaptcha = captcha_password;
for (let butt of document.getElementsByTagName('button')) {
if (butt.innerText == 'OK') {butt.click();break}
}
await new Promise(resolve => {
OWOP.once(OWOP.events.allChunksLoaded, () => {
resolve();
});
setTimeout(resolve, 1800000);
});
}, config.captcha_password);
console.log("Saving screenshot");
let screenshot = await page.screenshot({ type: 'png' });
let filename = `OWOP archive ${new Date().toISOString()}.png`;
let attachment = new Discord.Attachment(screenshot, filename);
await archive_webhook.send(attachment);
console.log("Archive finished");
await browser.close();
})();
process.on("unhandledRejection", error => {
console.error(error);
process.exit(1);
});

View File

@ -1,122 +0,0 @@
module.exports = function (discordBot) {
let commands = {
"help": {
description: "Guess what it does",
usage: "b!help (<command>)",
use: function (args, message) {
if (args.length == 1 && args[0].toLowerCase() in commands) {
message.channel.send("**" + args[0].toLowerCase() + " usage:** `" + commands[args[0].toLowerCase()].usage + "`");
} else {
var output = "**Command List**\n```markdown";
for (var i in commands) {
output += "\n[ " + i + " ](" + commands[i].description + ")";
}
output += "```";
message.channel.send(output);
}
return true;
}
},
"eval": {
whitelist: ["350303014944505866", "330499035419115522"], // admins, lamp2
description: "Runs a snippet of javascript code on the server",
usage: "b!eval <javascipt>",
use: function (args, message) {
if (args.length === 0) {
return false;
} else {
var result;
try {
result = eval(args.join(" "));
} catch (e) {
message.channel.send(e.toString());
return true;
}
if (typeof result == "undefined") {
message.channel.send("`undefined`");
} else if (typeof result == "number") {
message.channel.send("`" + result + "`");
} else if (typeof result == "string") {
message.channel.send("`\"" + result + "\"`");
} else if (Array.isArray(result)) {
message.channel.send("`" + JSON.stringify(result) + "`");
} else {
message.channel.send("`" + result.toString() + "`");
}
return true;
}
}.bind(this)
},
"scale": {
description: "Scale an image using nearest-neighbor.",
usage: "b!scale (<url> | [image attachment]) (<scale>)",
use: async function(args, message) {
var request = require("request-promise-native"), sharp = require("sharp");
var imageURL = (message.attachments.first() && message.attachments.first().url) || args[0];
var scaleFactor = (message.attachments.first() ? args[0] : args[1]) || 2;
if (scaleFactor > 10) return message.channel.send("Scale factor too large!");
try {
var image = await request.get(imageURL, {encoding: null});
} catch(e) {
console.error(e);
message.channel.send("Request: " + e.message);
return false;
}
try {
var s = sharp(image);
var {width, height} = await s.metadata();
s.resize(Math.round(width * scaleFactor), Math.round(height * scaleFactor), {kernel: "nearest"});
var rsz_image = await s.toBuffer();
} catch(e) {
console.error(e);
message.channel.send("Sharp: " + e.message);
return false;
}
message.channel.send({files:[{
attachment: rsz_image,
name: `rsz_${scaleFactor}_${(message.attachments.first() && message.attachments.first().filename) || imageURL.split("/").pop()}`
}]});
return true;
}
}
};
discordBot.on("message", async function (message) {
if (!message.author.bot) {
if (message.content.startsWith("b!")) {
if (message.guild.members.has("652830079763611668")) return;
var content = message.content.slice(2).split(" ");
let command = content[0].toLowerCase();
if (command in commands) {
let canUse = true;
if (commands[command].whitelist) {
canUse = false;
for (let id of commands[command].whitelist) {
if (message.author.id == id || (message.member && message.member.roles.keyArray().includes(id))) {
canUse = true;
break;
}
}
}
if (canUse) {
try {
var result = commands[command].use(content.slice(1), message);
if (result.then) result = await result;
} catch(e) {
message.channel.send("error");
console.error(e);
}
if (!result) {
message.channel.send("**:x: " + command + " usage:** `" + commands[command].usage + "`");
}
} else {
message.channel.send(":x: You don't have permission to use this command!");
}
}
}
}
});
}

View File

@ -1,15 +0,0 @@
module.exports = {
apps: [
{
name: "OWOP Bot",
script: "index.js"
},
{
name: "OWOP Bot Archive",
script: "archive.js",
cron_restart: "0 * * * *", // @hourly
autorestart: false
}
]
};

View File

@ -1,13 +1,13 @@
"use strict";
var Discord = require("discord.js");
var WebSocket = require("ws");
const Discord = require("discord.js");
const WebSocket = require("ws");
var config = require("./config");
const config = require("./config");
var discordBot = new Discord.Client({disableEveryone:true});
var discordBot = new Discord.Client({
intents: 32767,
allowedMentions: {parse: []}
});
discordBot.login(config.discord_token);
var banlist;
var bridges = {}; // owop websockets to discord channels
discordBot.once("ready", function(){
@ -16,16 +16,13 @@ discordBot.once("ready", function(){
var b = createOWOPbridge(owopWorld, discordChannels, password);
if (b) bridges[b.owopSocket] = b.discordChannels;
}
banlist = require("./banlist")(discordBot);
});
function createOWOPbridge(owopWorld, configDiscordChannels, password) {
var discordChannels = configDiscordChannels.map(configDiscordChannel => {
var c = discordBot.channels.get(configDiscordChannel.id);
var c = discordBot.channels.resolve(configDiscordChannel.id);
if (!c) return console.error(`Could not find discord channel ${configDiscordChannel.id} to bridge to owop world "${owopWorld}"`);
// attach webhook to channel object for webhook inter-discord-channel broadcast method
if (configDiscordChannel.webhook) c.webhook = new Discord.WebhookClient(configDiscordChannel.webhook.id, configDiscordChannel.webhook.token, {disableEveryone: true});
return c;
}).filter(x => x);
if (!configDiscordChannels.length) return console.error("Could not find any of the discord channels:", configDiscordChannels.map(x => x.id));
@ -37,8 +34,9 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
owopSocket.on("open", function () {
console.log("owop", owopWorld, "open");
});
owopSocket.on("message", function (data) {
if (typeof data == "string") {
owopSocket.on("message", function (data, isBinary) {
if (!isBinary) {
data = data.toString();
// owop to discord
console.log(`[${owopWorld}]`, data);
if (data.startsWith(botId) || data.startsWith(`[${botId}]`)) return; // ignore self if regular user
@ -58,19 +56,18 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
//if (msg.startsWith("(M)")) msg = msg.replace("(M)", "**(M)**");
//{ let x = msg.split(':'); x[0] = `**${x[0]}**`; msg = x.join(':'); } // bold prefix to distinguish from newline fakes
if (msg.includes(':')) msg = '**' + msg.replace(':', ':**'); // simpler version of above, to include the colon in bold
if (owopWorld == "main") msg = require('./antiswear')(msg);
for (let discordChannel of discordChannels) {
if (discordChannel.guild.id != "350296414720491530" && data == "You are banned. Appeal on the OWOP discord server, (https://discord.io/owop)") return;
let lastMessage = discordChannel.messages.last();
let lastMessage = discordChannel.messages.cache.last();
if (lastMessage && lastMessage.originalMsg && lastMessage.originalMsg == msg && lastMessage.author.id == discordBot.user.id) {
// if this owop message is same as source of last message and last message was sent by this bot
// edit last message with incremented number of repetitions
let postfix = ` [x${++lastMessage.repetitions}]`;
lastMessage.edit(msg.substr(0, 2000-postfix.length) + postfix).catch(error => console.error(`Could not edit message ${lastMessage.id}`, error.message));
lastMessage.edit(msg.substring(0, 2000-postfix.length) + postfix).catch(error => console.error(`Could not edit message ${lastMessage.id}`, error.message));
lastMessage.realmsg = msg; // attach actual message to Message object because now the message content has been edited
} else {
// send new message
discordChannel.send(msg, { split: { char: '' } }).then(message => {
discordChannel.send(msg).then(message => {
message.originalMsg = msg; // attach original owop message to Message object so we can edit for repetitions
message.repetitions = 1; // keep track of number of repetitions
}).catch(error => console.error(`Failed to send OWOP message to discordChannel ${[discordChannel.id, '#'+discordChannel.name, discordChannel.guild.name]}:`, error.message));
@ -109,7 +106,7 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
})();
function sendMove() {
if (owopSocket.readyState == WebSocket.OPEN) owopSocket.send(new Buffer([127, 255, 255, 255, 127, 255, 255, 255, 0, 0, 0, 0]));
if (owopSocket.readyState == WebSocket.OPEN) owopSocket.send(new Buffer.from([127, 255, 255, 255, 127, 255, 255, 255, 0, 0, 0, 0]));
}
setInterval(sendMove, 600000);
function joinWorld(name) {
@ -138,44 +135,24 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
return [ints, fstring];
}
discordBot.on("message", function (message) {
discordBot.on("messageCreate", function (message) {
if (!configDiscordChannels.map(x => x.id).includes(message.channel.id)) return; // only listen to the bridged channels
if (message.author.id == discordBot.user.id) return; // ignore self of course
if (discordChannels.filter(x => x.webhook).map(x => x.webhook.id).includes(message.author.id)) return; // ignore any of our webhooks
if (banlist().includes(message.author.id)) return message.react("🚫"); // block users banned from owop discord //TODO only main world
// broadcast message to other discord channels bridged to the same owop world
discordChannels.forEach(discordChannel => {
// probably never gonna be used anymore
//TODO update code if it's ever actually needed
/*discordChannels.forEach(discordChannel => {
if (discordChannel.id == message.channel.id) return;
if (discordChannel.webhook) {
// send using webhook if available, to save visual space
let username = message.member && message.member.displayName || message.author.username;
if (message.guild) username += ' @ ' + message.guild.name;
if (username.length > 32) username = username.substring(0, 31) + '…';
discordChannel.webhook.send(message.cleanContent, {
username,
avatarURL: message.author.avatarURL,
embeds: message.embeds,
files: message.attachments.map(x => new Discord.Attachment(x.url, x.filename))
}).catch(error => {
console.error(`Failed to send Discord broadcast via webhook to discordChannel ${[discordChannel.id, '#'+discordChannel.name, discordChannel.guild.name]}:`, error.message);
// fallback to embed if webhook fails
regularBroadcast();
});
} else regularBroadcast();
// send as embed
function regularBroadcast() {
discordChannel.send(
new Discord.RichEmbed()
.setAuthor(message.member && message.member.displayName || message.author.username, message.author.avatarURL)
.setColor(message.member && message.member.displayColor)
.setDescription(message.content)
.setFooter(`from ${message.guild.name}`, message.guild.iconURL)
.setImage(message.attachments.first() && message.attachments.first().width && message.attachments.first().url)
).catch(error => console.error(`Failed to send Discord broadcast embed to discordChannel ${[discordChannel.id, '#'+discordChannel.name, discordChannel.guild.name]}:`, error.message));
}
});
discordChannel.send(
new Discord.RichEmbed()
.setAuthor(message.member && message.member.displayName || message.author.username, message.author.avatarURL)
.setColor(message.member && message.member.displayColor)
.setDescription(message.content)
.setFooter(`from ${message.guild.name}`, message.guild.iconURL)
.setImage(message.attachments.first() && message.attachments.first().width && message.attachments.first().url)
).catch(error => console.error(`Failed to send Discord broadcast embed to discordChannel ${[discordChannel.id, '#'+discordChannel.name, discordChannel.guild.name]}:`, error.message));
});*/
// discord to owop
if (owopSocket.readyState != WebSocket.OPEN) return;
@ -187,7 +164,7 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
} else {
nickname = `[D] ${authorname}`;
}
if (owopWorld != "main") if (nickname.length > 16) nickname = nickname.substr(0,15) + '…';
if (owopWorld != "main") if (nickname.length > 16) nickname = nickname.substring(0,15) + '…';
} else {
prefix = `[D] ${authorname}: `;
}
@ -195,7 +172,7 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
let msg = prefix + message.cleanContent;
if (msg.startsWith('/')) msg = ' ' + msg;
if (message.attachments.size > 0) msg += ' ' + message.attachments.map(a => a.url).join(' ');
if (msg.length > 128) msg = msg.substr(0,127) + '…';
if (msg.length > 128) msg = msg.substring(0,127) + '…';
owopSocket.send(msg + String.fromCharCode(10));
});
@ -204,5 +181,4 @@ function createOWOPbridge(owopWorld, configDiscordChannels, password) {
}
if (config.enable_commands) require("./commands")(discordBot);
if (config.reddit) require("./pixelart2reddit&facebook")(discordBot);

2351
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,7 @@
{
"dependencies": {
"discord.js": "^11.5.1",
"request": "^2.88.0",
"request-promise-native": "^1.0.7",
"sharp": "^0.22.0",
"snoowrap": "^1.15.2",
"ws": ""
"discord.js": "^13.8.1",
"snoowrap": "^1.23.0",
"ws": "^8.8.0"
}
}

View File

@ -3,17 +3,17 @@ module.exports = function(discordBot) {
var Snoowrap = require("snoowrap");
var config = require('./config');
var r = new Snoowrap({
userAgent: 'wat',
userAgent: 'cock',
clientId: config.reddit.client_id,
clientSecret: config.reddit.client_secret,
username: config.reddit.user_name,
password: config.reddit.user_pass
});
discordBot.on("message", async message => {
discordBot.on("messageCreate", async message => {
if (message.channel.id == "350437018989363211" && !message.content.startsWith("b!") && message.attachments.first() && message.attachments.first().width) {
console.log("submitting pixel art to reddit:", message.attachments.first().url);
r.getSubreddit("OurWorldOfPixels").submitLink({
"title": `[OWOP Bot|#pixel-art] from ${message.author.tag}${message.content ? ": " + message.cleanContent : ""}`.substr(0,300),
"title": `[OWOP Bot|#pixel-art] from ${message.author.tag}${message.content ? ": " + message.cleanContent : ""}`.substring(0,300),
"url": message.attachments.first().url
});
}

5
readme.txt Normal file
View File

@ -0,0 +1,5 @@
daydun made original owop bot but quit
lamp resurrected and improved it as owop bot 2
dimdem made better owop bot 3 which took over for main
owop bot 2 has been stripped down and remains for bridging other worlds due to connection limit bs. also reddit thing
owop bot 4 is same as owop bot 3.