This commit is contained in:
Flummi 2020-02-20 18:01:09 +01:00
parent ee798c0c6a
commit d437b580f3
12 changed files with 238 additions and 46 deletions

View File

@ -11,7 +11,7 @@
"author": "Flummi & jkhsjdhjs", "author": "Flummi & jkhsjdhjs",
"license": "WTFPL", "license": "WTFPL",
"dependencies": { "dependencies": {
"cuffeo": "^1.0.5", "cuffeo": "^1.0.5-2",
"flumm-fetch-cookies": "^1.3.4-1", "flumm-fetch-cookies": "^1.3.4-1",
"pg": "^7.14.0", "pg": "^7.14.0",
"stringify-object": "^3.3.0" "stringify-object": "^3.3.0"

View File

@ -2,11 +2,13 @@ import _fs from "fs";
import cuffeo from "cuffeo"; import cuffeo from "cuffeo";
import config from "../cfg/config.json"; import config from "../cfg/config.json";
import logger from "./inc/log.mjs"; import logger from "./inc/log.mjs";
import user from "./inc/user.mjs";
const fs = _fs.promises; const fs = _fs.promises;
const timeout = 1000; const timeout = 1000;
(async () => { (async () => {
await user.initUser();
const self = { const self = {
_trigger: new Map(), _trigger: new Map(),
trigger: function trigger(args) { trigger: function trigger(args) {

View File

@ -8,5 +8,11 @@ export default async bot => {
f: e => { f: e => {
logger.debug(e); logger.debug(e);
} }
}, {
name: "debug",
listener: "debug",
f: e => {
logger.debug(e);
}
}]; }];
}; };

View File

@ -1,5 +1,6 @@
import { getLevel } from "../admin.mjs"; import { getLevel } from "../admin.mjs";
import fetch from "flumm-fetch-cookies"; import fetch from "flumm-fetch-cookies";
import user from "../user.mjs";
import vm from "vm"; import vm from "vm";
@ -9,6 +10,7 @@ let context = vm.createContext({
bot: null, bot: null,
admins: null, admins: null,
fetch: fetch, fetch: fetch,
user: user,
console: console console: console
}); });

View File

@ -0,0 +1,35 @@
import fetch from "flumm-fetch-cookies";
const regex = /<tr><td width=\"110\"><div class=\"(btn btn-primary tooltip)?\">(<div class=\"top\">.*<\/div>)?(?<region>.*)<\/div><\/td><td>(?<name>.*)<\/td>.*<b>(?<percent>.*)<\/b>/gm;
export default async bot => {
return [{
name: "fw_shops",
call: /^(\.|\/)fwshop/i,
active: true,
f: async e => {
const shopsite = await (await fetch("https://freewar.zocker.eu/")).text();
const shops = [...shopsite.matchAll(regex)].map(e => {
const [ name, tmp ] = e.groups.name.split(/\<.*\>/);
const [ x, y ] = tmp.split("/");
return {
region: e.groups.region.replace(/\<.*/m, ""),
name: name,
coords: {
x: +x,
y: +y
},
percent: e.groups.percent
};
});
e.reply([
"Die besten drei Shops:",
JSON.stringify(shops.slice(0, 3))
]);
}
}];
};

View File

@ -1,5 +1,6 @@
import fetch from "flumm-fetch-cookies"; import fetch from "flumm-fetch-cookies";
import config from "../../../cfg/config.json"; import config from "../../../cfg/config.json";
import user from "../user.mjs";
const api = `http://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&limit=1&api_key=${config.apis.lastfm.key}&format=json&user=`; const api = `http://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&limit=1&api_key=${config.apis.lastfm.key}&format=json&user=`;
@ -14,9 +15,19 @@ export default async bot => {
usage: "[b].np[/b] [i]<user>[/i]" usage: "[b].np[/b] [i]<user>[/i]"
},*/ },*/
f: async e => { f: async e => {
const nick = e.args[0] || e.user.nick; if(e.args.length > 0 && e.args[0].charAt(0) === "=") {
const tmp = e.args[0].slice(1);
await user.set(e.user.prefix, { lastfm: tmp });
return e.reply(`lastfm account set to: [b]${tmp}[/b]`);
}
let res = await (await fetch(`${api}${nick}`)).json(); if(!user.has(e.user.prefix))
return e.reply("nope");
const u = user.get(e.user.prefix);
if(u.lastfm === null || u.lastfm === "")
return e.reply("nope");
let res = await (await fetch(`${api}${u.lastfm}`)).json();
if(res.error) if(res.error)
return e.reply("User not found"); return e.reply("User not found");

View File

@ -0,0 +1,76 @@
export default new class serialize {
FUNCFLAG = "_$$ND_FUNC$$_";
CIRCULARFLAG = "_$$ND_CC$$_";
KEYPATHSEPARATOR = "_$$.$$_";
getKeyPath(obj, path) {
let currentObj = obj;
path.split(this.KEYPATHSEPARATOR).forEach((p, index) => {
if (index)
currentObj = currentObj[p];
});
return currentObj;
}
serialize(obj, outputObj, cache, path) {
path = path || "$";
cache = cache || {};
cache[path] = obj;
outputObj = outputObj || {};
if(Array.isArray(obj))
return JSON.stringify(obj);
for(let key in obj) {
if(obj.hasOwnProperty(key)) {
if(Array.isArray(obj[key]))
outputObj[key] = obj[key];
else if(typeof obj[key] === "object" && obj[key] !== null) {
let found = false;
for(let subKey in cache) {
if (cache.hasOwnProperty(subKey)) {
if (cache[subKey] === obj[key]) {
outputObj[key] = this.CIRCULARFLAG + subKey;
found = true;
}
}
}
if (!found)
outputObj[key] = this.serialize(obj[key], outputObj[key], cache, path + this.KEYPATHSEPARATOR + key);
}
else if(typeof obj[key] === "function")
outputObj[key] = this.FUNCFLAG + obj[key].toString();
else
outputObj[key] = obj[key];
}
}
return (path === "$") ? JSON.stringify(outputObj) : outputObj;
}
unserialize(obj, originObj) {
let isIndex;
if (typeof obj === "string") {
obj = JSON.parse(obj);
isIndex = true;
}
originObj = originObj || obj;
let circularTasks = [];
for(let key in obj) {
if(obj.hasOwnProperty(key)) {
if(typeof obj[key] === "object")
obj[key] = this.unserialize(obj[key], originObj);
else if(typeof obj[key] === "string") {
if(obj[key].indexOf(this.FUNCFLAG) === 0)
obj[key] = eval("(" + obj[key].substring(this.FUNCFLAG.length) + ")");
else if(obj[key].indexOf(this.CIRCULARFLAG) === 0) {
obj[key] = obj[key].substring(this.CIRCULARFLAG.length);
circularTasks.push({obj: obj, key: key});
}
}
}
}
if (isIndex)
circularTasks.forEach(task => task.obj[task.key] = this.getKeyPath(originObj, task.obj[task.key]));
return obj;
}
};

View File

@ -1,4 +1,5 @@
import sql from "../sql.mjs"; import sql from "../sql.mjs";
import user from "../user.mjs";
export default async bot => { export default async bot => {
@ -6,14 +7,17 @@ export default async bot => {
name: "rape", name: "rape",
call: /^(\.|\/)rape/i, call: /^(\.|\/)rape/i,
set: "nxy", set: "nxy",
active: false, active: true,
help: { help: {
text: "Rapes a nick and eventually charge for it", text: "Rapes a nick and eventually charge for it",
usage: "[b].rape[/b] [i](<nick>)[/i]" usage: "[b].rape[/b] [i](<nick>)[/i]"
}, },
f: e => { f: async e => {
const nick = e.args[0] || e.user.nick; const nick = (e.args[0] || (e.type === "tg" ? e.user.username || e.user.nick : e.user.nick)).split("@").join("");
return e.replyAction(`rapes [b]${nick}[/b].`);
const rand = Math.round(Math.random()); const rand = Math.round(Math.random());
//const u = user.get(new RegExp(`${nick}!.*@${e.network}`, "i")) || { fines: 0 };
if(rand !== 1) if(rand !== 1)
e.replyAction(`rapes [b]${nick}[/b].`) e.replyAction(`rapes [b]${nick}[/b].`)
@ -22,13 +26,15 @@ export default async bot => {
const fined = [e.user.nick, nick][rand]; const fined = [e.user.nick, nick][rand];
const reason = ["raping", "being too lewd and getting raped"][rand]; const reason = ["raping", "being too lewd and getting raped"][rand];
sql.query("insert into nxy_users (nick, fines) values (lower($1), $2) on conflict (nick) do update set fines = nxy_users.fines + excluded.fines returning fines", [fined, fine]) await user.set(e.user.prefix, { fines: u.fines += fine })
/*sql.query("insert into nxy_users (nick, fines) values (lower($1), $2) on conflict (nick) do update set fines = nxy_users.fines + excluded.fines returning fines", [fined, fine])
.then(rows => { .then(rows => {
e.replyAction(`fines [b]${nick}[/b] [b]$${fine}[/b] for ${reason}. You owe: [b]$${rows[0].fines}[/b].`); e.replyAction(`fines [b]${nick}[/b] [b]$${fine}[/b] for ${reason}. You owe: [b]$${rows[0].fines}[/b].`);
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
}); });*/
} }
} }
}, { }, {

View File

@ -1,46 +1,43 @@
import sql from "../sql.mjs";
import { maxoutput, sandbox, bfgen } from "./lib/sandbox.mjs"; import { maxoutput, sandbox, bfgen } from "./lib/sandbox.mjs";
import user from "../user.mjs";
import vm from "vm"; import vm from "vm";
import util from "util";
import fetch from "flumm-fetch-cookies"; import fetch from "flumm-fetch-cookies";
import stringify from "stringify-object"; import serialize from "./lib/serialize.mjs";
let _contexts = new Map(); let _contexts = new Map();
export default async bot => { export default async bot => {
sql.query("select prefix, sandbox from nxy_users where sandbox != 'NULL'") if(user.size > 0)
.then(rows => rows.forEach(row => eval(`_contexts.set(row.prefix, ${JSON.parse(row.sandbox)});`))) user.forEach((v, prefix) => eval(`_contexts.set(prefix, serialize.unserialize(v.sandbox));`));
.catch(err => console.log("nichts vorhanden lol", err));
return [{ return [{
name: "sandbox_js", name: "sandbox_js",
call: /^(\.|\/)js (.*)/i, call: /^(\.|\/)js (.*)/i,
set: "uwe", set: "uwe",
f: e => { f: async e => {
const args = e.message.trim().substring(4); const args = e.message.trim().substring(4);
if (!_contexts.has(e.user.prefix)) if (!_contexts.has(e.user.prefix))
_contexts.set(e.user.prefix, vm.createContext({ })); _contexts.set(e.user.prefix, vm.createContext({ }));
if (args.match(/^reset$/)) { if (args.match(/^reset$/)) {
_contexts.set(e.user.prefix, vm.createContext({ })); _contexts.set(e.user.prefix, vm.createContext({ }));
await user.set(e.user.prefix, { sandbox: "{}" });
return e.reply("Sandbox resetted!"); return e.reply("Sandbox resetted!");
} }
let context = vm.createContext(_contexts.get(e.user.prefix)); let context = vm.createContext(_contexts.get(e.user.prefix));
try { try {
let output = vm.runInContext(args, context, { timeout: 2000 }); let output = vm.runInContext(args, context, { timeout: 2000 });
if (typeof output !== undefined && output) { if (typeof output !== undefined && output) {
output = JSON.stringify(output); output = util.inspect(output);
if (output.length > maxoutput) if (output.length > maxoutput)
return e.reply(`${e.user.nick}: holy fuck, Ausgabe wäre viel zu lang! (${output.length} Zeichen :DDDDDD)`); return e.reply(`${e.user.nick}: holy fuck, Ausgabe wäre viel zu lang! (${output.length} Zeichen :DDDDDD)`);
else { else {
_contexts.set(e.user.prefix, context); _contexts.set(e.user.prefix, context);
let tmp = JSON.stringify(stringify(_contexts.get(e.user.prefix)) await user.set(e.user.prefix, { sandbox: serialize.serialize(_contexts.get(e.user.prefix)) });
.replace(/\n/g, "") e.reply(`${e.user.nick}: ${output}`);
.replace(/\t/g, "")
.split("[native code]").join(""));
sql.query("insert into nxy_users (nick, prefix, sandbox) values (lower($1), $3, $2) on conflict (prefix) do update set sandbox = $2, nick = lower($1)", [
(e.type === "tg" ? e.user.username || e.user.nick : e.user.nick), tmp, e.user.prefix
]).then(() => e.reply(e.user.nick + ": " + output))
.catch(err => console.log(err));
} }
} }
else else

View File

@ -1,4 +1,5 @@
import sql from "../sql.mjs"; import sql from "../sql.mjs";
import user from "../user.mjs";
import fetch from "flumm-fetch-cookies"; import fetch from "flumm-fetch-cookies";
const data = { const data = {
@ -167,33 +168,22 @@ export default async bot => {
name: "waifu_husbando", name: "waifu_husbando",
call: /^(\.|\/)(waifu|husbando)/i, call: /^(\.|\/)(waifu|husbando)/i,
set: "nxy", set: "nxy",
f: e => { f: async e => {
let nick = e.args[0] || (e.type === "tg"?e.user.username || e.user.nick:e.user.nick) const nick = (e.args[0] || (e.type === "tg" ? e.user.username || e.user.nick : e.user.nick)).split("@").join("");
let mode = e.cmd; const mode = e.cmd;
nick = nick.split("@").join("");
if(e.args.length > 0 && e.args[0].charAt(0) === "=") { if(e.args.length > 0 && e.args[0].charAt(0) === "=") {
let tmp = e.args[0].slice(1); let tmp = e.args[0].slice(1);
sql.any( await user.set(e.user.prefix, { [mode]: tmp });
`insert into nxy_users (prefix, nick, ${mode}) values ($1, lower($2), $3) on conflict (prefix) do update set ${mode} = excluded.${mode}, nick = $2`, [ return e.reply(`${mode.charAt(0).toUpperCase() + mode.slice(1)} set to: [b]${tmp}[/b]`);
e.user.prefix,
(e.type === "tg"?e.user.username || e.user.nick:e.user.nick),
tmp
])
.then(rows => {
e.reply(`${mode.charAt(0).toUpperCase()+mode.slice(1)} set to: [b]${tmp}[/b]`)
})
.catch(err => console.log(err));
}
else {
sql.any(`select ${mode} from nxy_users where lower(nick) = lower($1) limit 1`, [nick])
.then(rows => {
if(!rows[0])
return e.reply(`[b]${mode.charAt(0).toUpperCase() + mode.slice(1)}[/b]: none`);
e.reply(`${mode.charAt(0).toUpperCase() + mode.slice(1)}: [b]${rows[0][mode]}[/b]`);
})
.catch(err => console.log(err));
} }
let tmp, ret;
if(!(tmp = user.get(new RegExp(`${nick}!.*@${e.network}`, "i"))))
ret = "none";
else
ret = tmp[mode] === null || tmp[mode] === "" ? "none" : tmp[mode];
return e.reply(`[b]${mode.charAt(0).toUpperCase() + mode.slice(1)}[/b]: ${ret}`);
} }
}, { }, {
name: "asshole", name: "asshole",

View File

@ -186,6 +186,13 @@ export default async bot => {
f: e => { f: e => {
e.reply("[b]GET HYPER![/b]"); e.reply("[b]GET HYPER![/b]");
} }
}, {
name: "F",
call: /^f$/i,
set: "uwe",
f: e => {
e.reply(e.message);
}
}, { }, {
name: "bark", name: "bark",
call: /^(\.|\/)bark$/i, call: /^(\.|\/)bark$/i,

60
src/inc/user.mjs Normal file
View File

@ -0,0 +1,60 @@
import sql from "./sql.mjs";
export default new class user {
constructor() {
this.user = new Map();
}
async initUser() {
const users = await sql.query("select * from nxy_users");
if(users.rowCount === 0)
return false;
users.rows.forEach(user => this.user.set(user.prefix, user));
return true;
}
async load(prefix) {
let user = await sql.query("select * from nxy_users where prefix = $1", [ prefix ]);
if(user.rowCount === 0) {
await sql.query("insert into nxy_users (prefix) values ($1)", [ prefix ]);
user = await sql.query("select * from nxy_users where prefix = $1", [ prefix ]);
this.user.set(prefix, user.rows[0]);
}
return user.rows[0];
}
async set(prefix, data) {
const keys = Object.keys(data);
const values = keys.map((e, i) => `$${i + 2}`).join(", ");
let query = `insert into nxy_users (prefix, ${keys.join(", ")}) values ($1, ${values}) on conflict (prefix) do update set `;
query += keys.map((e, i) => `${e} = $${i + 2}`).join(", ");
await sql.query(query, [ prefix, ...Object.values(data) ]);
this.user.delete(prefix);
this.user.set(prefix, await this.load(prefix));
return this.user.get(prefix);
}
get(user) {
if(typeof user === "object") { // regex
for(let [k, v] of this.user.entries())
if(user.test(k))
return v;
}
else
return this.user.get(user);
return false;
}
has(...args) {
return this.user.has(...args);
}
forEach(...args) {
return this.user.forEach(...args);
}
get size() {
return this.user.size;
}
};