From 47ccf527ee6cf1f9dce03d9dfb33ed206c59d220 Mon Sep 17 00:00:00 2001 From: Flummi Date: Sun, 2 Sep 2018 12:07:40 +0200 Subject: [PATCH] Initial commit --- .gitignore | 4 + package-lock.json | 631 ++++++++++++++++++++++++++++++++++++ package.json | 22 ++ src/clients/irc.mjs | 195 +++++++++++ src/clients/irc/cap.mjs | 21 ++ src/clients/irc/index.mjs | 19 ++ src/clients/irc/invite.mjs | 13 + src/clients/irc/join.mjs | 5 + src/clients/irc/motd.mjs | 14 + src/clients/irc/msg.mjs | 9 + src/clients/irc/nick.mjs | 8 + src/clients/irc/part.mjs | 5 + src/clients/irc/ping.mjs | 5 + src/clients/irc/pwdreq.mjs | 6 + src/clients/irc/welcome.mjs | 6 + src/clients/irc/who.mjs | 27 ++ src/clients/irc/whois.mjs | 95 ++++++ src/clients/tg.mjs | 159 +++++++++ src/inc/admin.mjs | 42 +++ src/inc/cfg.mjs | 37 +++ src/inc/events/ctcp.mjs | 12 + src/inc/events/index.mjs | 6 + src/inc/events/message.mjs | 45 +++ src/inc/log.mjs | 26 ++ src/inc/sql.mjs | 5 + src/inc/trigger/debug.mjs | 37 +++ src/inc/trigger/index.mjs | 4 + src/inc/trigger/parser.mjs | 241 ++++++++++++++ src/inc/wrapper.mjs | 41 +++ src/index.mjs | 28 ++ 30 files changed, 1768 insertions(+) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/clients/irc.mjs create mode 100644 src/clients/irc/cap.mjs create mode 100644 src/clients/irc/index.mjs create mode 100644 src/clients/irc/invite.mjs create mode 100644 src/clients/irc/join.mjs create mode 100644 src/clients/irc/motd.mjs create mode 100644 src/clients/irc/msg.mjs create mode 100644 src/clients/irc/nick.mjs create mode 100644 src/clients/irc/part.mjs create mode 100644 src/clients/irc/ping.mjs create mode 100644 src/clients/irc/pwdreq.mjs create mode 100644 src/clients/irc/welcome.mjs create mode 100644 src/clients/irc/who.mjs create mode 100644 src/clients/irc/whois.mjs create mode 100644 src/clients/tg.mjs create mode 100644 src/inc/admin.mjs create mode 100644 src/inc/cfg.mjs create mode 100644 src/inc/events/ctcp.mjs create mode 100644 src/inc/events/index.mjs create mode 100644 src/inc/events/message.mjs create mode 100644 src/inc/log.mjs create mode 100644 src/inc/sql.mjs create mode 100644 src/inc/trigger/debug.mjs create mode 100644 src/inc/trigger/index.mjs create mode 100644 src/inc/trigger/parser.mjs create mode 100644 src/inc/wrapper.mjs create mode 100644 src/index.mjs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65c926d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +logs/*.log +cfg/*.json +b/* \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..80bfeb1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,631 @@ +{ + "name": "f0ckv2", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "cloudscraper": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cloudscraper/-/cloudscraper-1.5.0.tgz", + "integrity": "sha512-bZagLhj59+N6Z6lD9zRksYu87GthLwXdKARULi4RZ6UVpotH39ruSFN3UQmw3uuqoj00iDxkGrapAvxeurmlQA==", + "requires": { + "request": "^2.49.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + }, + "combined-stream": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "denque": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.3.0.tgz", + "integrity": "sha512-4SRaSj+PqmrS1soW5/Avd7eJIM2JJIqLLmwhRqIGleZM/8KwZq80njbSS2Iqas+6oARkSkLDHEk4mm78q3JlIg==" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "optional": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "m3u8stream": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.3.0.tgz", + "integrity": "sha512-0tvjXDIa6BolPEGo9zioQiPqfQhjopZXN3L7vZH/rZQCOLd4rPXNZc1UBMdW3TRpjNBoD0+F1X41/f0iY23rlQ==", + "requires": { + "miniget": "^1.1.0" + } + }, + "mime-db": { + "version": "1.36.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", + "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" + }, + "mime-types": { + "version": "2.1.20", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", + "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "requires": { + "mime-db": "~1.36.0" + } + }, + "miniget": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/miniget/-/miniget-1.3.0.tgz", + "integrity": "sha512-qvj5v1gbTvK6iVt1DqYrF0B9Lm6VAPNCa930TmTDQp6i1svDzzV8geu+e87XA14OBWDsWENptnP6BO9iJJOD9Q==" + }, + "mysql2": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-1.6.1.tgz", + "integrity": "sha512-BNrJH5HavPqskXEy8oVz7ucRbkhegKQ7VD8rNGFwvTuk0WiUSi1wXFOg67NjCGquZnim8nKgHdDiih6LqG5knA==", + "requires": { + "cardinal": "2.1.1", + "denque": "1.3.0", + "generate-function": "^2.0.0", + "iconv-lite": "^0.4.18", + "long": "^4.0.0", + "lru-cache": "4.1.1", + "named-placeholders": "1.1.1", + "object-assign": "^4.1.1", + "seq-queue": "0.0.5", + "sqlstring": "2.3.1" + } + }, + "named-placeholders": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.1.tgz", + "integrity": "sha1-O3oNJiA910s6nfTJz7gnsvuQfmQ=", + "requires": { + "lru-cache": "2.5.0" + }, + "dependencies": { + "lru-cache": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", + "integrity": "sha1-2COIrpyWC+y+oMc7uet5tsbOmus=" + } + } + }, + "nodejs-mysql2": { + "version": "git+https://gitfap.de/Flummi/nodejs-mysql2.git#981d9f0946d25937675cb21a94099ad11a45d9fb", + "from": "git+https://gitfap.de/Flummi/nodejs-mysql2.git", + "requires": { + "bluebird": "^3.4.6", + "mysql2": "^1.5.3" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.0.tgz", + "integrity": "sha512-zrSP/KDf9DH3K3VePONoCstgPiYJy9z0SCatZuTpOc7YdnWIqwkWdXOuwlr4uDc7em8QZRsFWsT/685x5InjYg==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "read-chunk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.0.0.tgz", + "integrity": "sha512-8lBUVPjj9TC5bKLBacB+rpexM03+LWiYbv6ma3BeWmUYXGxqA1WNNgIZHq/iIsCrbFMzPhFbkOqdsyOFRnuoXg==", + "requires": { + "pify": "^4.0.0", + "with-open-file": "^0.1.3" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "requires": { + "esprima": "~4.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "requires": { + "lodash": "^4.13.1" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, + "sshpk": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", + "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "winston": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.4.tgz", + "integrity": "sha512-NBo2Pepn4hK4V01UfcWcDlmiVTs7VTB1h7bgnB0rgP146bYhMxX0ypCz3lBOfNxCO4Zuek7yeT+y/zM1OfMw4Q==", + "requires": { + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + } + }, + "with-open-file": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.3.tgz", + "integrity": "sha512-sPUMcyWU0wde5lnHuDeEgAOIV4y77GpGmh9ktxb5HBfA2OwyWY7JtQYbBxuUFf/yv8Sbfrkxk+QbQwAyurvgXQ==", + "requires": { + "p-finally": "^1.0.0", + "p-try": "^2.0.0", + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "ytdl-core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-0.24.0.tgz", + "integrity": "sha512-VwCe+uhKz2M1cH0UEnNxVQyLwGK8DIJgbUPF9svEh0zxUl2DP7LORCDIloLqDUxR6JnC3s01GU0YPxiOmjcqVA==", + "requires": { + "html-entities": "^1.1.3", + "m3u8stream": "^0.3.0", + "miniget": "^1.1.0", + "sax": "^1.1.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c838522 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "f0ckv2", + "version": "2.0.0", + "description": "f0ck, kennste?", + "main": "index.mjs", + "scripts": { + "start": "node --experimental-modules src/" + }, + "author": "Flummi", + "license": "ISC", + "dependencies": { + "cloudscraper": "^1.5.0", + "file-type": "^9.0.0", + "nodejs-mysql2": "git+https://gitfap.de/Flummi/nodejs-mysql2.git", + "read-chunk": "^3.0.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "uuid": "^3.3.2", + "winston": "^2.4.0", + "ytdl-core": "^0.24.0" + } +} diff --git a/src/clients/irc.mjs b/src/clients/irc.mjs new file mode 100644 index 0000000..67fb78e --- /dev/null +++ b/src/clients/irc.mjs @@ -0,0 +1,195 @@ +import { logger } from "../inc/log"; +import { getLevel } from "../inc/admin"; + +import modules from "./irc/index"; + +import net from "net"; +import tls from "tls"; +import EventEmitter from "events"; + +const colors = { + red: "\x0304$1\x0304", + blue: "\x0312$1\x0312", + yellow: "\x0308$1\x0308" +}; +const msgmodes = { + normal: "PRIVMSG {recipient} :{msg}", + action: "PRIVMSG {recipient} :\u0001ACTION {msg}\u0001", + notice: "NOTICE {recipient} :{msg}" +}; + +const replaceColor = (match, color, text) => { + if (colors.hasOwnProperty(color)) + return colors[color].replace("\$1", text); + return text; +}; + +export class irc extends EventEmitter { + constructor(options) { + super(); + this.options = options || {}; + this.options.channels = this.options.channels || []; + this.options.host = this.options.host || "127.0.0.1"; + this.options.port = this.options.port || 6667; + this.options.ssl = this.options.ssl || false; + this.options.selfSigned = this.options.selfSigned || false; + this.options.sasl = this.options.sasl || false; + this.network = this.options.network || "test"; + this.nickname = this.options.nickname || "test"; + this.username = this.options.username || "test"; + this.realname = this.options.realname || "test"; + this.channels = this.options.channels || []; + this.set = this.options.set || "all"; + this._recachetime = 60 * 30; // 30 minutes + this._cmd = new Map(); + + modules.forEach(mod => mod(this)); + + this.server = { + set: this.set, + motd: "", + me: {}, + channel: [], + user: new Map() + }; + this.socket = (this.options.ssl ? tls : net).connect({ + host: this.options.host, + port: this.options.port, + rejectUnauthorized: !this.options.selfSigned + }, () => { + this.send(`NICK ${this.nickname}`); + this.send(`USER ${this.username} 0 * : ${this.realname}`); + if(this.options.sasl) + this.send("CAP LS"); + }); + this.socket.setEncoding("utf-8"); + this.socket.on("data", msg => { + msg.split(/\r?\n|\r/).filter(tmp => tmp.length > 0).forEach(tmp => { + const cmd = this.parse(tmp); + if (this._cmd.has(cmd.command)) + this._cmd.get(cmd.command)(cmd); + }) + }); + } + send(data) { + this.socket.write(`${data}\n`); + logger.debug(`(${this.network}) out: ${data}`); + } + sendmsg(mode, recipient, msg) { + msg = msg.split(/\r?\n/); + if(msg.length > 6) + return false; + msg.forEach(e => { + this.send( msgmodes[mode].replace("{recipient}", recipient).replace("{msg}", e) ); + }); + } + parse(data, [a, ...b] = data.split(/ +:/)) { + let tmp = a.split(" ").concat(b); + logger.debug(`(${this.network}) in: ${[...tmp]}`); + return data.charAt(0) === ":" ? { + prefix: tmp.shift(), + command: tmp.shift(), + params: tmp + } : { + prefix: null, + command: tmp.shift(), + params: tmp + }; + } + reply(tmp) { + return { + type: "irc", + network: this.network, + channel: tmp.params[0], + channelid: tmp.params[0], + user: Object.assign(this.parsePrefix(tmp.prefix), { + account: this.server.user.geti(this.parsePrefix(tmp.prefix).nick).account, + prefix: tmp.prefix.charAt(0) === ":" ? tmp.prefix.substring(1) : tmp.prefix, + level: getLevel(this.network, Object.assign(this.parsePrefix(tmp.prefix), { + account: this.server.user.geti(this.parsePrefix(tmp.prefix).nick).account, + prefix: tmp.prefix.charAt(0) === ":" ? tmp.prefix.substring(1) : tmp.prefix + })) + }), + message: tmp.params[1], + time: ~~(Date.now() / 1000), + raw: tmp, + reply: msg => this.sendmsg("normal", tmp.params[0], this.format(""+msg)), + replyAction: msg => this.sendmsg("action", tmp.params[0], this.format(""+msg)), + replyNotice: msg => this.sendmsg("notice", tmp.params[0], this.format(""+msg)), + self: this.server, + _chan: this.server.channel[tmp.params[0]], + _user: this.server.user, + _cmd: this._cmd, + join: chan => this.join(chan), + part: (chan, msg) => this.part(chan, msg), + whois: user => this.whois(user), + write: msg => this.send(msg), + socket: this.socket + }; + } + join(channel) { + this.send(`JOIN ${(typeof channel === "object") ? channel.join(",") : channel}`); + } + part(channel, msg=false) { + this.send(`PART ${(typeof channel === "object") ? channel.join(",") : channel}${msg ? " " + msg : " part"}`); + } + whois(user, force = false) { + user = user.toLowerCase(); + let tmpuser = {}; + if(this.server.user.hasi(user) && !force) { + tmpuser = this.server.user.geti(user); + if(tmpuser.cached >= ~~(Date.now() / 1000) - this._recachetime) + return; + } + + tmpuser = { + nickname: tmpuser.nickname || false, + username: tmpuser.username || false, + hostname: tmpuser.hostname || false, + realname: tmpuser.realname || false, + account: tmpuser.account || false, + prefix: tmpuser.prefix || false, + registered: tmpuser.registered || false, + oper: tmpuser.oper || false, + channels: tmpuser.channels || [], + cached: ~~(Date.now() / 1000) + }; + this.server.user.set(user, tmpuser); + this.send(`WHOIS ${user}`); + } + parsePrefix(prefix) { + prefix = /:?(.*)\!(.*)@(.*)/.exec(prefix); + if(!prefix) + return false; //this.parsePrefix(arguments); + return { + nick: prefix[1], + username: prefix[2], + hostname: prefix[3] + }; + } + format(msg) { + return msg + .replace(/\[b\](.*?)\[\/b\]/g, "\x02$1\x02") // bold + .replace(/\[i\](.*?)\[\/i\]/g, "\x1D$1\x1D") // italic + .replace(/\[color=(.*?)](.*?)\[\/color\]/g, replaceColor) // colors + ; + } +} + +Map.prototype.hasi = function(val) { + for (let [key] of this) + if(key.toLowerCase() === val.toLowerCase()) + return true; + return false; +}; +Map.prototype.geti = function(val) { + for (let [key, value] of this) + if(key.toLowerCase() === val.toLowerCase()) + return value; + return false; +}; +Map.prototype.deli = function(val) { + for (let [key] of this) + if(key.toLowerCase() === val.toLowerCase()) + this.delete(key); +}; \ No newline at end of file diff --git a/src/clients/irc/cap.mjs b/src/clients/irc/cap.mjs new file mode 100644 index 0000000..b29ca52 --- /dev/null +++ b/src/clients/irc/cap.mjs @@ -0,0 +1,21 @@ +export default client => { + client._cmd.set("CAP", function (msg) { // capkram + switch (msg.params[1]) { + case "LS": // list + this.send(`CAP REQ :${msg.params[2]}`); + break; + case "ACK": // success + this.send("AUTHENTICATE PLAIN"); + break; + } + }.bind(client)); + + client._cmd.set("AUTHENTICATE", function (msg) { // auth + if (msg.params[0].match(/\+/)) + this.send(`AUTHENTICATE ${new Buffer(this.username + "\u0000" + this.username + "\u0000" + this.options.password).toString("base64")}`); + }.bind(client)); + + client._cmd.set("900", function (msg) { // cap end + this.send("CAP END"); + }.bind(client)); +}; diff --git a/src/clients/irc/index.mjs b/src/clients/irc/index.mjs new file mode 100644 index 0000000..cf38e7a --- /dev/null +++ b/src/clients/irc/index.mjs @@ -0,0 +1,19 @@ +import cap from "./cap"; +import invite from "./invite"; +import join from "./join"; +import motd from "./motd"; +import msg from "./msg"; +import nick from "./nick"; +import part from "./part"; +import ping from "./ping"; +import pwdreq from "./pwdreq"; +import welcome from "./welcome"; +import who from "./who"; +import whois from "./whois"; + +export default [ + cap, invite, join, + motd, msg, nick, + part, ping, pwdreq, + welcome, who, whois +]; \ No newline at end of file diff --git a/src/clients/irc/invite.mjs b/src/clients/irc/invite.mjs new file mode 100644 index 0000000..e42db27 --- /dev/null +++ b/src/clients/irc/invite.mjs @@ -0,0 +1,13 @@ +export default client => { + client._cmd.set("INVITE", function (msg) { // invite + const user = this.parsePrefix(msg.prefix); + const channel = msg.params[1]; + + if(!this.server.channel.includes(channel)) { + this.join(channel); + setTimeout(() => { + this.send(`PRIVMSG ${channel} :Hi. Wurde von ${user.nick} eingeladen.`); + }, 1000); + } + }.bind(client)); +}; \ No newline at end of file diff --git a/src/clients/irc/join.mjs b/src/clients/irc/join.mjs new file mode 100644 index 0000000..592098e --- /dev/null +++ b/src/clients/irc/join.mjs @@ -0,0 +1,5 @@ +export default client => { + client._cmd.set("JOIN", function (msg) { // join + this.send(`WHO ${msg.params[0]}`); + }.bind(client)); +}; diff --git a/src/clients/irc/motd.mjs b/src/clients/irc/motd.mjs new file mode 100644 index 0000000..ac1232d --- /dev/null +++ b/src/clients/irc/motd.mjs @@ -0,0 +1,14 @@ +export default client => { + client._cmd.set("372", function (msg) { // motd_entry + this.server.motd += `${msg.params[1]}\n`; + }.bind(client)); + + client._cmd.set("375", function (msg) { // motd_start + this.server.motd = `${msg.params[1]}\n`; + }.bind(client)); + + client._cmd.set("376", function (msg) { // motd_end + this.server.motd += `${msg.params[1]}\n`; + this.emit("data", ["motd", this.server.motd]); + }.bind(client)); +}; diff --git a/src/clients/irc/msg.mjs b/src/clients/irc/msg.mjs new file mode 100644 index 0000000..8fcd0ca --- /dev/null +++ b/src/clients/irc/msg.mjs @@ -0,0 +1,9 @@ +export default client => { + client._cmd.set("PRIVMSG", function (msg) { // privmsg + this.emit("data", msg.params[1] === "\u0001VERSION\u0001" ? ["ctcp:version", this.reply(msg)] : ["message", this.reply(msg)]); + }.bind(client)); + + client._cmd.set("NOTICE", function (msg) { // notice + this.emit("data", ["notice", msg.params[1]]); + }.bind(client)); +}; diff --git a/src/clients/irc/nick.mjs b/src/clients/irc/nick.mjs new file mode 100644 index 0000000..70e4fbb --- /dev/null +++ b/src/clients/irc/nick.mjs @@ -0,0 +1,8 @@ +export default client => { + client._cmd.set("NICK", function (msg) { // nickchange + let prefix = this.parsePrefix(msg.prefix); + if (this.server.user.hasi(prefix.nick)) + this.server.user.deli(prefix.nick); + this.whois(msg.params[0], true); // force + }.bind(client)); +}; diff --git a/src/clients/irc/part.mjs b/src/clients/irc/part.mjs new file mode 100644 index 0000000..f4745a9 --- /dev/null +++ b/src/clients/irc/part.mjs @@ -0,0 +1,5 @@ +export default client => { + client._cmd.set("PART", function (msg) { // part + //delete this.server.user[msg.params[0]]; + }.bind(client)); +}; diff --git a/src/clients/irc/ping.mjs b/src/clients/irc/ping.mjs new file mode 100644 index 0000000..0d0608d --- /dev/null +++ b/src/clients/irc/ping.mjs @@ -0,0 +1,5 @@ +export default client => { + client._cmd.set("PING", function (msg) { // ping + this.send(`PONG ${msg.params.join``}`); + }.bind(client)); +}; diff --git a/src/clients/irc/pwdreq.mjs b/src/clients/irc/pwdreq.mjs new file mode 100644 index 0000000..2a28108 --- /dev/null +++ b/src/clients/irc/pwdreq.mjs @@ -0,0 +1,6 @@ +export default client => { + client._cmd.set("464", function (msg) { // motd_entry + if (this.options.password.length > 0 && !this.options.sasl) + this.send(`PASS ${this.options.password}`); + }.bind(client)); +}; diff --git a/src/clients/irc/welcome.mjs b/src/clients/irc/welcome.mjs new file mode 100644 index 0000000..800cc65 --- /dev/null +++ b/src/clients/irc/welcome.mjs @@ -0,0 +1,6 @@ +export default client => { + client._cmd.set("001", function (msg) { // welcome + this.join(this.options.channels); + this.emit("data", ["connected", msg.params[1]]); + }.bind(client)); +}; diff --git a/src/clients/irc/who.mjs b/src/clients/irc/who.mjs new file mode 100644 index 0000000..bfba569 --- /dev/null +++ b/src/clients/irc/who.mjs @@ -0,0 +1,27 @@ +const max = 400; +let whois = []; + +export default client => { + client._cmd.set("352", function (msg) { // who_entry + if (!this.server.channel[msg.params[1]]) + this.server.channel[msg.params[1]] = new Map(); + this.server.channel[msg.params[1]].set(msg.params[5], { // chan + nick: msg.params[5], + username: msg.params[2], + hostname: msg.params[3] + }); + whois.push(msg.params[5]); + }.bind(client)); + + client._cmd.set("315", function (msg) { // who_end + this.whois(whois.reduce((a, b) => { + a += `${b},`; + if(a.length >= max) { + this.whois(a.slice(0, -1)); + a = ""; + } + return a; + }, "").slice(0, -1)); + whois = []; + }.bind(client)); +}; diff --git a/src/clients/irc/whois.mjs b/src/clients/irc/whois.mjs new file mode 100644 index 0000000..082c7ae --- /dev/null +++ b/src/clients/irc/whois.mjs @@ -0,0 +1,95 @@ +export default client => { + client._cmd.set("307", function (msg) { // whois_identified (ircd-hybrid) + let tmpuser = {}; + if (this.server.user.hasi(msg.params[1])) + tmpuser = this.server.user.geti(msg.params[1]); + tmpuser.account = msg.params[1]; + tmpuser.registered = true; + this.server.user.set(msg.params[1], tmpuser); + }.bind(client)); + + client._cmd.set("311", function (msg) { // whois_userdata + let tmpuser = {}; + if (this.server.user.hasi(msg.params[1])) + tmpuser = this.server.user.geti(msg.params[1]); + tmpuser.nickname = msg.params[1]; + tmpuser.username = msg.params[2]; + tmpuser.hostname = msg.params[3]; + tmpuser.realname = msg.params[5]; + tmpuser.prefix = `${msg.params[1]}!${msg.params[2]}@${msg.params[3]}`; + this.server.user.set(msg.params[1], tmpuser); + }.bind(client)); + + client._cmd.set("313", function (msg) { // whois_oper + let tmpuser = {}; + if (this.server.user.hasi(msg.params[1])) + tmpuser = this.server.user.geti(msg.params[1]); + tmpuser.oper = true; + this.server.user.set(msg.params[1], tmpuser); + }.bind(client)); + + client._cmd.set("318", function (msg) { // whois_end + let tmpuser = {}; + if (this.server.user.hasi(msg.params[1])) + tmpuser = this.server.user.geti(msg.params[1]); + tmpuser = { + nickname: tmpuser.nickname || false, + username: tmpuser.username || false, + hostname: tmpuser.hostname || false, + realname: tmpuser.realname || false, + account: tmpuser.account || false, + prefix: tmpuser.prefix || false, + registered: tmpuser.registered || false, + oper: tmpuser.oper || false, + channels: tmpuser.channels || [], + cached: ~~(Date.now() / 1000) + }; + if(msg.params[0] === msg.params[1]) + this.server.me = tmpuser; + this.server.user.set(msg.params[1], tmpuser); + }.bind(client)); + + client._cmd.set("319", function (msg) { // whois_chanlist + let tmpchan = new Map() + , tmpuser = {}; + if (this.server.user.hasi(msg.params[1])) { + tmpuser = this.server.user.geti(msg.params[1]); + if (tmpuser.channels) + tmpchan = new Map(tmpuser.channels); + } + let chans = msg.params[2].trim().split(" "); + for (let chan in chans) { + chan = chans[chan].split("#"); + tmpchan.set(`#${chan[1]}`, chan[0]); + } + tmpuser.channels = tmpchan; + this.server.user.set(msg.params[1], tmpuser); + }.bind(client)); + + client._cmd.set("330", function (msg) { // whois_authed_as (snircd) + let tmpuser = {}; + if (this.server.user.hasi(msg.params[1])) + tmpuser = this.server.user.geti(msg.params[1]); + tmpuser.account = msg.params[2]; + tmpuser.registered = true; + this.server.user.set(msg.params[1], tmpuser); + }.bind(client)); +}; + +Map.prototype.hasi = function (val) { + for (let [key] of this) + if (key.toLowerCase() === val.toLowerCase()) + return true; + return false; +}; +Map.prototype.geti = function (val) { + for (let [key, value] of this) + if (key.toLowerCase() === val.toLowerCase()) + return value; + return false; +}; +Map.prototype.deli = function (val) { + for (let [key] of this) + if (key.toLowerCase() === val.toLowerCase()) + this.delete(key); +}; \ No newline at end of file diff --git a/src/clients/tg.mjs b/src/clients/tg.mjs new file mode 100644 index 0000000..00d867e --- /dev/null +++ b/src/clients/tg.mjs @@ -0,0 +1,159 @@ +import { logger } from "../inc/log"; +import { getLevel } from "../inc/admin"; + +import rp from "request-promise-native"; +import EventEmitter from "events"; + +export class tg extends EventEmitter { + constructor(options) { + super(); + this.options = options || {}; + this.token = options.token || null; + this.options.pollrate = options.pollrate || 1000; + this.set = this.options.set || "all"; + this.network = "Telegram"; + this.api = `https://api.telegram.org/bot${this.token}`; + this.lastUpdate = 0; + this.lastMessage = 0; + this.server = { + set: this.set, + channel: new Map(), + user: new Map(), + me: {} + }; + this.connect().then(() => { + this.poller = setInterval(() => { this.poll(); }, this.options.pollrate); + }); + } + connect() { + return new Promise((resolve, reject) => { + rp(`${this.api}/getMe`, { json: true }) + .then(res => { + if(res.ok) { + this.me = res.result; + this.server.me = { + nickname: res.result.first_name, + username: res.result.username, + account: res.result.id.toString(), + prefix: `${res.result.username}!${res.result.id.toString()}`, + id: res.result.id.toString() + }; + resolve(); + } + else { + logger.error(`(${this.network}) ${res}`); + reject(); + } + }) + .catch(err => { + logger.error(`(${this.network}) ${err.message}`); + reject(); + }); + }); + } + poll() { + rp(`${this.api}/getUpdates?offset=${this.lastUpdate}&allowed_updates=message`, { json:true }) + .then(res => { + if(res.ok && res.result.length > 0) { + res = res.result[res.result.length-1]; + this.lastUpdate = res.update_id + 1; + if (res.message.date >= ~~(Date.now() / 1000) - 10 && res.message.message_id !== this.lastMessage) { + this.lastMessage = res.message.message_id; + if(!this.server.user.has(res.message.from.username || res.message.from.first_name)) { + this.server.user.set(res.message.from.username || res.message.from.first_name, { + nick: res.message.from.first_name, + username: res.message.from.username, + account: res.message.from.id.toString(), + prefix: `${res.message.from.username}!${res.message.from.id.toString()}`, + id: res.message.from.id + }); + } + this.emit("data", ["message", this.reply(res.message)]); + } + } + }) + .catch(err => { + if(err.statusCode !== 409) + logger.error(`(${this.network}) ${err.message}`); + }); + } + send(chatid, msg, reply = null) { + if(msg.length === 0 || msg.length > 2048) + return false; + const opts = { + method: 'POST', + uri: `${this.api}/sendMessage`, + body: { + chat_id: chatid, + text: msg, + parse_mode: "HTML" + }, + json: true + }; + if(reply) + opts.body.reply_to_message_id = reply; + rp(opts) + .then(res => {}) + .catch(err => { + logger.error(`(${this.network}) ${err.message}`); + }); + } + sendmsg(mode, recipient, msg) { + this.send(recipient, msg); + } + reply(tmp) { + return { + type: "tg", + network: "Telegram", + channel: tmp.chat.title, + channelid: tmp.chat.id, + user: { + prefix: `${tmp.from.username}!${tmp.from.id}`, + nick: tmp.from.first_name, + username: tmp.from.username, + account: tmp.from.id.toString(), + level: getLevel("Telegram", { + prefix: `${tmp.from.username}!${tmp.from.id}`, + nick: tmp.from.first_name, + username: tmp.from.username, + account: tmp.from.id.toString() + }) + }, + self: this.server, + message: tmp.text, + time: tmp.date, + raw: tmp, + reply: msg => this.send(tmp.chat.id, this.format(msg), tmp.message_id), + replyAction: msg => this.send(tmp.chat.id, this.format(`f0ck ${msg}`), tmp.message_id), + replyNotice: msg => this.send(tmp.chat.id, this.format(msg), tmp.message_id), + _user: this.server.user + }; + } + format(msg) { + return msg.toString() + .split("<").join("<") + .split(">").join(">") + .replace(/\[b\](.*?)\[\/b\]/g, "$1") // bold + .replace(/\[i\](.*?)\[\/i\]/g, "$1") // italic + .replace(/\[color=(.*?)](.*?)\[\/color\]/g, "$2") + ; + } +} + +Map.prototype.hasi = function(val) { + for (let [key] of this) + if(key.toLowerCase() === val.toLowerCase()) + return true; + return false; +}; +Map.prototype.geti = function(val) { + for (let [key, value] of this) + if(key.toLowerCase() === val.toLowerCase()) + return value; + return false; +}; +Map.prototype.deli = function(val) { + for (let [key] of this) + if(key.toLowerCase() === val.toLowerCase()) + this.delete(key); +}; \ No newline at end of file diff --git a/src/inc/admin.mjs b/src/inc/admin.mjs new file mode 100644 index 0000000..33b2f4a --- /dev/null +++ b/src/inc/admin.mjs @@ -0,0 +1,42 @@ +import sql from "./sql"; + +export let admins = []; +export const loadAdmins = () => { + admins = []; + sql.exec(`select * from admins`) + .then(rows => { + rows.forEach(row => { + admins.push({ + id: row.id, + prefix: row.prefix, + account: row.account, + network: row.network, + level: row.level + }); + }); + }) + .catch(err => { + console.log("keine Admins vorhanden"); + }); +}; +loadAdmins(); + +export const getLevel = (network, user) => { + let ret = { + level: 0, + verified: false + }; + if (typeof user !== "object") + return "user has to be an object!"; + if (!user.account || !user.prefix) + return ret; + for(let admin of admins) { + if (admin.account === user.account.toLowerCase() && admin.network === network.toLowerCase()) { + ret = { + level: admin.level, + verified: user.prefix.toLowerCase() === admin.prefix + }; + } + }; + return ret; +}; \ No newline at end of file diff --git a/src/inc/cfg.mjs b/src/inc/cfg.mjs new file mode 100644 index 0000000..ddab593 --- /dev/null +++ b/src/inc/cfg.mjs @@ -0,0 +1,37 @@ +import sql from "./sql"; + +let cfg = { + client: {}, + main: {}, + websrv: {}, + trigger: {} +}; + +const read = () => new Promise((resolve, reject) => { + sql.exec("select * from cfg").then(rows => { + for (let row in rows) { + cfg[rows[row].class][rows[row].key] = { + val: ((type, value) => { + switch (type) { + case "string": + return value; + case "int": + return parseInt(value); + case "bool": + return value === "true"; + case "json": + return JSON.parse(value); + } + })(rows[row].type, rows[row].value), + hidden: rows[row].hidden === 1, + type: rows[row].type + } + } + resolve(); + }) + .catch(err => { + reject("no cfg"); + }) +}); + +export { cfg, read }; diff --git a/src/inc/events/ctcp.mjs b/src/inc/events/ctcp.mjs new file mode 100644 index 0000000..e3d5c0c --- /dev/null +++ b/src/inc/events/ctcp.mjs @@ -0,0 +1,12 @@ +import { logger } from "../log"; + +const versions = [ + "AmIRC.1 (8 Bit) for Commodore Amiga 500", + "HexChat 0.72 [x86] / Windows 95c [500MHz]" +]; + +export default self => { + self.bot.on("ctcp:version", e => { + e.write(`notice ${e.user.nick} :\u0001VERSION ${versions[~~(Math.random() * versions.length)]}\u0001`); + }); +}; \ No newline at end of file diff --git a/src/inc/events/index.mjs b/src/inc/events/index.mjs new file mode 100644 index 0000000..b41801e --- /dev/null +++ b/src/inc/events/index.mjs @@ -0,0 +1,6 @@ +import ctcp from "./ctcp"; +import message from "./message"; + +export default [ + ctcp, message +]; \ No newline at end of file diff --git a/src/inc/events/message.mjs b/src/inc/events/message.mjs new file mode 100644 index 0000000..553ffdf --- /dev/null +++ b/src/inc/events/message.mjs @@ -0,0 +1,45 @@ +import { logger } from "../log"; +import { cfg } from "../cfg"; + +const parseArgs = msg => { + let args = msg.trim().split(" "); + let cmd = args.shift(); + return { + cmd: cmd.replace(/^(\.|\/|\!)/, ""), + args: args + }; +}; + +export default self => { + self.bot.on("message", e => { + for (var [name, trigger] of self._trigger.entries()) { + if (!trigger.call.exec(e.message)) + continue; + if (!trigger.clients.includes(e.type)) + continue; + + /*let active = false; + if (e.type === "irc" && cfg.trigger[e.network + e.channel]) { + if (cfg.trigger[e.network + e.channel].val[trigger.name]) + active = true; + } + else + active = trigger.active;*/ + + //if (!active) + // continue; + + if ((e.self.set !== "all" && e.self.set !== trigger.set) && trigger.set !== "all") + continue; + + if (trigger.level > e.user.level.level) { + e.reply(`no permission, min level ${trigger.level} required`); + break; + } + + e = Object.assign(e, parseArgs(e.message)); + trigger.f(e); + } + logger.info(`${e.network} -> ${e.channel} -> ${e.user.nick}: ${e.message}`); + }); +}; \ No newline at end of file diff --git a/src/inc/log.mjs b/src/inc/log.mjs new file mode 100644 index 0000000..e9a0662 --- /dev/null +++ b/src/inc/log.mjs @@ -0,0 +1,26 @@ +import winston from "winston"; + +const logger = new (winston.Logger)({ + transports: [ + new (winston.transports.File)({ + name: "debug-file", + filename: `./logs/${~~(Date.now() / 1000)}_debug.log`, + level: "debug" + }), + new (winston.transports.File)({ + name: "info-file", + filename: `./logs/${~~(Date.now() / 1000)}_info.log`, + level: "info" + }), + new (winston.transports.File)({ + name: "error-file", + filename: `./logs/${~~(Date.now() / 1000)}_error.log`, + level: "error" + }), + new (winston.transports.Console)({ + level: "info" + }) + ] +}); + +export { logger }; diff --git a/src/inc/sql.mjs b/src/inc/sql.mjs new file mode 100644 index 0000000..90a1d17 --- /dev/null +++ b/src/inc/sql.mjs @@ -0,0 +1,5 @@ +import mysql from "nodejs-mysql2"; +import { default as cfg } from "../../cfg/sql.json"; + +const sql = mysql.default.getInstance(cfg); +export default sql; diff --git a/src/inc/trigger/debug.mjs b/src/inc/trigger/debug.mjs new file mode 100644 index 0000000..e0bd146 --- /dev/null +++ b/src/inc/trigger/debug.mjs @@ -0,0 +1,37 @@ +import { admins, getLevel } from "../admin"; + +import vm from "vm"; + +const maxoutput = 750; +let context = vm.createContext({ + e: null, + bot: null, + admins: null, +}); +export default bot => { + bot._trigger.set("sandbox_debug", new bot.trigger({ + call: /^\!debug (.*)/i, + level: 100, + active: true, + f: e => { + const args = e.message.trim().substring(7); + try { + context.admins = admins; + context.e = e; + context.bot = bot; + context.level = getLevel; + let output = vm.runInContext(args, vm.createContext(context)); + if (typeof output !== undefined && output) { + output = JSON.stringify(output); + if (output.length > maxoutput) + return e.reply(`holy fuck, Ausgabe wäre viel zu lang! (${output.length} Zeichen :DDDDDD)`); + else + return e.reply(output); + } + } + catch (err) { + e.reply(err.message); + } + } + })); +}; \ No newline at end of file diff --git a/src/inc/trigger/index.mjs b/src/inc/trigger/index.mjs new file mode 100644 index 0000000..984ebe4 --- /dev/null +++ b/src/inc/trigger/index.mjs @@ -0,0 +1,4 @@ +import debug from "./debug"; +import parser from "./parser"; + +export default [ debug, parser ]; diff --git a/src/inc/trigger/parser.mjs b/src/inc/trigger/parser.mjs new file mode 100644 index 0000000..7c4a0de --- /dev/null +++ b/src/inc/trigger/parser.mjs @@ -0,0 +1,241 @@ +import { cfg } from "../cfg"; +import sql from "../sql"; +import fs from "fs"; +import path from "path"; +import crypto from "crypto"; + +import uuid from "uuid"; +import cloudscraper from "cloudscraper"; +import readChunk from "read-chunk"; +import ytdl from "ytdl-core"; +import request from "request"; +import fileType from "file-type"; + +import { Readable } from "stream"; + +const checkRepost = (url, cbcr) => { + sql.exec("select count(id) as count, id from `f0ck`.`items` where `src` = ?", url).then(rows => { + cbcr((rows[0].count == 0)?true:rows[0].id); + }); +}; + +const checkRepostCheckSum = (cs, cbcrcs) => { + sql.exec("select count(id) as count, id from `f0ck`.`items` where `checksum` = ?", cs).then(rows => { + cbcrcs((rows[0].count == 0)?true:rows[0].id); + }); +}; +const formatSize = (size) => { + const i = ~~(Math.log(size) / Math.log(1024)); + return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]; +}; +const getCheckSum = (file, cbcs) => { + var sha256sum = crypto.createHash('sha256'); + fs.ReadStream(file) + .on('data', d => sha256sum.update(d)) + .on('end', () => cbcs(sha256sum.digest('hex'))); +}; + + +export default bot => { + bot._trigger.set("parser", new bot.trigger({ + call: /https?:\/\/[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?/gi, + f: e => { + if(e.channel === "#kbot-dev" || e.message.match(/(!|-)f0ck/i)) { + if(!e.message.match(/(!|-)ignore/)) { + const tmp = e.message.match(/https?:\/\/[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?/gi); // get links + tmp.forEach((entry,i,a) => { + if(!entry.match(/f0ck\.me/i) && !entry.match(/\.onion/i)) { + getLink(entry, ((e.message.match(/(!|-)force/i) && e.user.level.level >= 100)?true:false), e.user.level.level, cb => { + if(cb.success === true) { + fs.rename(cb.file, cb.file + '.' + cb.info.ext, (err) => { + if(!err) { + sql.exec("insert into `f0ck`.`items` (`src`,`dest`,`mime`,`size`,`checksum`,`username`,`userchannel`,`usernetwork`,`stamp`,`active`,`thumb`) values (?,?,?,?,?,?,?,?,?,?,?)", [ + entry, + cb.file + '.' + cb.info.ext, + cb.info.mime, + cb.size, + cb.checksum, + e.user.nick, + e.channel, + e.network, + ~~(new Date() / 1000), + 0, + cb.info.thumb ? cb.info.thumb : '' + ]).then(result => { + //lib.generateThumbs(); + e.reply(cfg.main.url.val+"/"+result.insertId+" - "+cb.info.title+" ("+cb.info.mime+", ~"+formatSize(cb.size)+") by "+e.user.nick+" ("+e.user.prefix+")"); + }).catch(msg => { + e.reply("ups", msg); + }); + } + else { + e.reply("Datei konnte nicht verschoben werden D:"); + e.reply(`${cb.file} -> ${cb.file}.${cb.info.ext}`); + } + }); + } + else { + e.reply(JSON.stringify(cb)); + fs.stat(process.cwd() + '/b/' + cb.file, (err, stat) => { + if(cb.msg !== '') + e.reply(cb.msg); + if(!err && stat.isFile()) + fs.unlinkSync(process.cwd() + '/b/' + cb.file); + }); + } + }); + } + }); + } + else + e.reply("ignored"); + } + else + e.reply("ignore"); + } + })); +}; + +const getLink = (url, force, userlevel, cb) => { + const yt = /https?:\/\/(www\.)?youtu(\.be\/|be\.com\/)((.+\/)?(watch(\?v=|.+&v=))?(v=)?)([\w_-]{11})(&.+)?/gi; + const sc = /https?:\/\/(www\.)?(soundcloud\.com|snd\.sc)(\/\S*)(\/\S*)/gi; + checkRepost(url, cbcr => { + var tmpdest = uuid.v1().split('-')[0]; + if(cbcr === true) { + var dat = fs.createWriteStream(process.cwd() + '/b/' + tmpdest); + var info; + if(url.match(yt)) { // ytdl + ytdl.getInfo(url, (err, inf) => { + if(!err) { + var title = inf.title; + var iurl = inf.thumbnail_url; //JSON.parse(inf.player_response).videoDetails.thumbnail.thumbnails[0].url.split('?')[0]; + try { + dlformat = { filter: (format) => { return format.container === 'webm'; } }; + ytdl.downloadFromInfo(inf, dlformat) + .on('response', (res) => { + if( ( res.headers['content-length'] <= cfg.main.maxFileSize.val ) || force || ( userlevel >= 60 && res.headers['content-length'] <= (cfg.main.maxFileSize.val * 2) ) ) { + info = { + type: 'youtube', + title: title, + mime: 'video/webm', + ext: 'webm', + thumb: iurl + }; + } + else { + res.destroy(); + dat.end(); + return cb({ success: false, file: tmpdest, msg: 'f0ck! your file is too big (~'+formatSize(res.headers['content-length'])+'), max '+formatSize( ( userlevel >= 60?(cfg.main.maxFileSize.val*2):cfg.main.maxFileSize.val ) )+' allowed' }); + } + }) + .on('error', (err) => { + dat.end(); + return cb({ success: false, file: tmpdest, msg: err.message }); + }) + .pipe(dat); + } + catch(ex) { + dat.end(); + return cb({ success: false, file: tmpdest, msg: ex.message }); + } + } + }); + } + else if(url.match(sc)) { // scdl + request('https://api.soundcloud.com/resolve.json?client_id=' + cfg.main.scclientid.val + '&url=' + url, (err, res, body) => { + if(!err && res.statusCode === 200) { + var data = JSON.parse(body); + request(data.stream_url + ((data.stream_url.indexOf('?') === -1)?'?':'&') + 'client_id=' + cfg.main.scclientid.val) + .pipe(dat); + info = { + type: 'soundcloud', + title: data.title, + mime: 'audio/mpeg', + ext: 'mp3', + thumb: (data.artwork_url !== null)?data.artwork_url.replace('large.jpg', 't300x300.jpg'):null + }; + } + else { + dat.end(); + return cb({ success: false, file: tmpdest, msg: 'f0ck sc-api' }); + } + }); + } + else { // various + cloudscraper.request({ + method: 'GET', + url: url, + encoding: null, + }, + (err, res, data) => { + if(!err) { + var type = res.headers['content-type'].split(";")[0]; + if(cfg.main.allowedMimes.val.hasOwnProperty(type)) { + if( ( data.length <= cfg.main.maxFileSize.val ) || force || ( userlevel >= 60 && data.length <= (cfg.main.maxFileSize.val * 2) ) ) { + var s = new Readable; + s.push(data); + s.push(null); + s.pipe(dat); + info = { + type: 'other', + title: path.parse(url).base, + mime: type, + ext: cfg.main.allowedMimes[type], + thumb: null + }; + } + else { + dat.end(); + return cb({ success: false, file: tmpdest, msg: 'f0ck! your file is too big (~'+formatSize(data.length)+'), max '+formatSize( ( userlevel >= 60?(cfg.main.maxFileSize.val*2):cfg.main.maxFileSize.val ) )+' allowed' }); + } + } + else { + dat.end(); + return cb({ success: false, file: tmpdest, msg: 'irgendwas mit mime oder so.' }); + } + } + else { + dat.end(); + return cb({ success: false, file: tmpdest, msg: 'nope.' }); + } + }); + } + + dat + .on('finish', () => { + var size = dat.bytesWritten; + dat.end(); + if( ( size <= cfg.main.maxFileSize.val ) || force || ( userlevel >= 60 && size <= (cfg.main.maxFileSize.val * 2) ) ) { + fs.stat(process.cwd() + '/b/' + tmpdest, (err, stat) => { + if(!err && stat.isFile() && stat.size > 300) { + getCheckSum(process.cwd() + '/b/' + tmpdest, (cbcs) => { + checkRepostCheckSum(cbcs, (cbcrcs) => { + if(cbcrcs === true) { + var mime = fileType(readChunk.sync(process.cwd() + '/b/' + tmpdest, 0, 262)); + info.ext = mime.ext; + info.mime = mime.mime; + if(cfg.main.allowedMimes.val.hasOwnProperty(mime.mime) || info.type === 'soundcloud') + return cb({ success: true, info: info, size: size, file: process.cwd() + '/b/' + tmpdest, checksum: cbcs }); + else + return cb({ success: false, file: tmpdest, msg: 'lol, go f0ck yourself ('+mime.mime+')' }); + } + else + return cb({ success: false, file: tmpdest, msg: 'repost motherf0cker: '+cfg.main.url.val+'/'+cbcrcs }); + }); + }); + } + else + return cb({ success: false, file: tmpdest, msg: 'nope' }); + }); + } + else + return cb({ success: false, file: tmpdest, msg: 'f0ck! your file is too big (~'+formatSize(size)+'), max '+formatSize( ( userlevel >= 60?(cfg.main.maxFileSize.val*2):cfg.main.maxFileSize.val ) )+' allowed' }); + }) + .on('error', err => { + return cb({ success: false, file: tmpdest, msg: err }); + }); + } + else + return cb({ success: false, file: tmpdest, msg: 'repost motherf0cker: '+cfg.main.url.val+'/'+cbcr }); + }); +}; diff --git a/src/inc/wrapper.mjs b/src/inc/wrapper.mjs new file mode 100644 index 0000000..629420c --- /dev/null +++ b/src/inc/wrapper.mjs @@ -0,0 +1,41 @@ +import { cfg } from "./cfg"; +import { irc as irclib } from "../clients/irc"; +import { tg as tglib } from "../clients/tg"; + +import EventEmitter from "events"; + +const clients = []; + +const wrapper = class wrapper extends EventEmitter { + constructor() { + super(); + for (let srv in cfg.client) { + if(cfg.client[srv].val.enabled) { + switch (cfg.client[srv].val.type) { + case "irc": + clients.push({ + name: cfg.client[srv].val.network, + type: "irc", + client: new irclib(cfg.client[srv].val) + }); + break; + case "tg": + clients.push({ + name: "tg", + type: "tg", + client: new tglib(cfg.client[srv].val) + }); + break; + } + } + } + + clients.forEach(client => { + client.client.on("data", e => { + this.emit(e[0], e[1]); + }); + }); + } +}; + +export { wrapper, clients }; diff --git a/src/index.mjs b/src/index.mjs new file mode 100644 index 0000000..bfa9573 --- /dev/null +++ b/src/index.mjs @@ -0,0 +1,28 @@ +import { logger } from "./inc/log"; +import { read, cfg } from "./inc/cfg"; +import { wrapper } from "./inc/wrapper"; + +import triggers from "./inc/trigger"; +import events from "./inc/events"; + +read().then(() => { + const self = { + _trigger: new Map(), + trigger: function trigger(args) { + this.call = args.call; + this.help = args.help || false; + this.level = args.level || 0; + this.active = args.hasOwnProperty("active") ? args.active : true; + this.set = args.set || "all"; // uwe, nxy, f0ck, all + this.clients = args.clients || ["irc", "tg", "discord"]; + this.f = args.f; + }, + bot: new wrapper() + }; + + triggers.forEach(mod => { + console.log(mod); + mod(self); + }); + events.forEach(event => event(self)); +}).catch(err => logger.error(`(main) ${err.message}`));