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",
"license": "WTFPL",
"dependencies": {
"cuffeo": "^1.0.5",
"cuffeo": "^1.0.5-2",
"flumm-fetch-cookies": "^1.3.4-1",
"pg": "^7.14.0",
"stringify-object": "^3.3.0"

View File

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

View File

@ -8,5 +8,11 @@ export default async bot => {
f: 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 fetch from "flumm-fetch-cookies";
import user from "../user.mjs";
import vm from "vm";
@ -9,6 +10,7 @@ let context = vm.createContext({
bot: null,
admins: null,
fetch: fetch,
user: user,
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 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=`;
@ -14,9 +15,19 @@ export default async bot => {
usage: "[b].np[/b] [i]<user>[/i]"
},*/
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)
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 user from "../user.mjs";
export default async bot => {
@ -6,14 +7,17 @@ export default async bot => {
name: "rape",
call: /^(\.|\/)rape/i,
set: "nxy",
active: false,
active: true,
help: {
text: "Rapes a nick and eventually charge for it",
usage: "[b].rape[/b] [i](<nick>)[/i]"
},
f: e => {
const nick = e.args[0] || e.user.nick;
f: async e => {
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 u = user.get(new RegExp(`${nick}!.*@${e.network}`, "i")) || { fines: 0 };
if(rand !== 1)
e.replyAction(`rapes [b]${nick}[/b].`)
@ -22,13 +26,15 @@ export default async bot => {
const fined = [e.user.nick, nick][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 => {
e.replyAction(`fines [b]${nick}[/b] [b]$${fine}[/b] for ${reason}. You owe: [b]$${rows[0].fines}[/b].`);
})
.catch(err => {
console.log(err);
});
});*/
}
}
}, {

View File

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

View File

@ -1,4 +1,5 @@
import sql from "../sql.mjs";
import user from "../user.mjs";
import fetch from "flumm-fetch-cookies";
const data = {
@ -167,33 +168,22 @@ export default async bot => {
name: "waifu_husbando",
call: /^(\.|\/)(waifu|husbando)/i,
set: "nxy",
f: e => {
let nick = e.args[0] || (e.type === "tg"?e.user.username || e.user.nick:e.user.nick)
let mode = e.cmd;
nick = nick.split("@").join("");
f: async e => {
const nick = (e.args[0] || (e.type === "tg" ? e.user.username || e.user.nick : e.user.nick)).split("@").join("");
const mode = e.cmd;
if(e.args.length > 0 && e.args[0].charAt(0) === "=") {
let tmp = e.args[0].slice(1);
sql.any(
`insert into nxy_users (prefix, nick, ${mode}) values ($1, lower($2), $3) on conflict (prefix) do update set ${mode} = excluded.${mode}, nick = $2`, [
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));
await user.set(e.user.prefix, { [mode]: tmp });
return e.reply(`${mode.charAt(0).toUpperCase() + mode.slice(1)} set to: [b]${tmp}[/b]`);
}
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",

View File

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