push time
This commit is contained in:
parent
07029ffc52
commit
c7b55b1aae
41 changed files with 1150 additions and 96 deletions
157
package-lock.json
generated
157
package-lock.json
generated
|
@ -232,6 +232,21 @@
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"base64-js": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"bl": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "^2.3.5",
|
||||||
|
"safe-buffer": "^5.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"boxen": {
|
"boxen": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz",
|
||||||
|
@ -346,9 +361,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bson": {
|
"bson": {
|
||||||
"version": "1.1.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/bson/-/bson-4.0.3.tgz",
|
||||||
"integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg=="
|
"integrity": "sha512-7uBjjxwOSuGLmoqGI1UXWpDGc0K2WjR7dC6iaOg4iriNZo6M2EEBb8co4dEPJ5ArYCebPMie0ecgX0TWF+ZUrQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer": "^5.1.0",
|
||||||
|
"long": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer": {
|
||||||
|
"version": "5.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
|
||||||
|
"integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"base64-js": "^1.0.2",
|
||||||
|
"ieee754": "^1.1.4"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"builtin-modules": {
|
"builtin-modules": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
@ -519,6 +549,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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="
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||||
|
@ -595,6 +630,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||||
},
|
},
|
||||||
|
"denque": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
|
||||||
|
},
|
||||||
"diff": {
|
"diff": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
|
||||||
|
@ -602,7 +642,7 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"discord.js": {
|
"discord.js": {
|
||||||
"version": "github:discordjs/discord.js#ee0b7c155a1767ed42e2756e53d56368e8b69929",
|
"version": "github:discordjs/discord.js#030d263a9e018a766c5f399624fe4f8ec2b7349c",
|
||||||
"from": "github:discordjs/discord.js",
|
"from": "github:discordjs/discord.js",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@discordjs/collection": "^0.1.1",
|
"@discordjs/collection": "^0.1.1",
|
||||||
|
@ -854,6 +894,12 @@
|
||||||
"safer-buffer": ">= 2.1.2 < 3"
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ieee754": {
|
||||||
|
"version": "1.1.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
||||||
|
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"import-lazy": {
|
"import-lazy": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
|
||||||
|
@ -885,8 +931,7 @@
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
|
@ -1049,6 +1094,11 @@
|
||||||
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
|
"integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||||
|
},
|
||||||
"isexe": {
|
"isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
@ -1129,6 +1179,12 @@
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"long": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"loud-rejection": {
|
"loud-rejection": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
|
||||||
|
@ -1252,15 +1308,29 @@
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"module-alias": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q=="
|
||||||
|
},
|
||||||
"mongodb": {
|
"mongodb": {
|
||||||
"version": "3.4.1",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.2.tgz",
|
||||||
"integrity": "sha512-juqt5/Z42J4DcE7tG7UdVaTKmUC6zinF4yioPfpeOSNBieWSK6qCY+0tfGQcHLKrauWPDdMZVROHJOa8q2pWsA==",
|
"integrity": "sha512-Lxt4th2tK2MxmkDBR5cMik+xEnkvhwg0BC5kGcHm9RBwaNEsrIryvV5istGXOHbnif5KslMpY1FbX6YbGJ/Trg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"bl": "^2.2.0",
|
||||||
"bson": "^1.1.1",
|
"bson": "^1.1.1",
|
||||||
|
"denque": "^1.4.1",
|
||||||
"require_optional": "^1.0.1",
|
"require_optional": "^1.0.1",
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"saslprep": "^1.0.0"
|
"saslprep": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bson": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz",
|
||||||
|
"integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mute-stream": {
|
"mute-stream": {
|
||||||
|
@ -1455,9 +1525,14 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prism-media": {
|
"prism-media": {
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.0.tgz",
|
||||||
"integrity": "sha512-W+oxjRyjtd7hw3pefNZuc7YEZ6VICORJvVNfCPs0+7CsJ43CqMjGAYGjPL3hQ82vw03EVra+CiX4zisqOBUUGw=="
|
"integrity": "sha512-zjcO/BLVlfxWqFpEUlDyL1R9XXMquasNP4xpeYDPPZi/Zcz0i6OXoqcvxOLgbRVPsJXVd29vlYmRx2bts+hzEw=="
|
||||||
|
},
|
||||||
|
"process-nextick-args": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||||
},
|
},
|
||||||
"pseudomap": {
|
"pseudomap": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
|
@ -1522,6 +1597,27 @@
|
||||||
"read-pkg": "^3.0.0"
|
"read-pkg": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||||
|
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.3",
|
||||||
|
"isarray": "~1.0.0",
|
||||||
|
"process-nextick-args": "~2.0.0",
|
||||||
|
"safe-buffer": "~5.1.1",
|
||||||
|
"string_decoder": "~1.1.1",
|
||||||
|
"util-deprecate": "~1.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"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=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"redent": {
|
"redent": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
|
||||||
|
@ -1749,6 +1845,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"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=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||||
|
@ -1930,9 +2041,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tweetnacl": {
|
"tweetnacl": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.2.tgz",
|
||||||
"integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A=="
|
"integrity": "sha512-+8aPRjmXgf1VqvyxSlBUzKzeYqVS9Ai8vZ28g+mL7dNQl1jlUTCMDZnvNQdAS1xTywMkIXwJsfipsR/6s2+syw=="
|
||||||
},
|
},
|
||||||
"type-fest": {
|
"type-fest": {
|
||||||
"version": "0.8.1",
|
"version": "0.8.1",
|
||||||
|
@ -1950,11 +2061,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "3.7.4",
|
"version": "3.7.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz",
|
||||||
"integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==",
|
"integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"typy": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/typy/-/typy-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-Du53deMF9X9pSM3gVXDjLBq14BUfZWSGKfmmR1kTlg953RaIZehfc8fQuoAiW+SRO6bJsP+59mv1tsH8vwKghg=="
|
||||||
|
},
|
||||||
"unique-string": {
|
"unique-string": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
|
||||||
|
@ -2045,6 +2161,11 @@
|
||||||
"prepend-http": "^2.0.0"
|
"prepend-http": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
|
},
|
||||||
"validate-npm-package-license": {
|
"validate-npm-package-license": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
|
||||||
|
|
23
package.json
23
package.json
|
@ -7,10 +7,12 @@
|
||||||
"author": "Rauf",
|
"author": "Rauf",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/bson": "^4.0.1",
|
||||||
|
"@types/node": "^10.17.13",
|
||||||
|
"@types/ws": "^6.0.4",
|
||||||
|
"bson": "^4.0.3",
|
||||||
"gts": "^1.1.2",
|
"gts": "^1.1.2",
|
||||||
"typescript": "~3.7.0",
|
"typescript": "^3.7.5"
|
||||||
"@types/node": "^10.0.3",
|
|
||||||
"@types/ws": "^6.0.4"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"check": "gts check",
|
"check": "gts check",
|
||||||
|
@ -25,6 +27,19 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/mongodb": "^3.3.14",
|
"@types/mongodb": "^3.3.14",
|
||||||
"discord.js": "github:discordjs/discord.js",
|
"discord.js": "github:discordjs/discord.js",
|
||||||
"mongodb": "^3.4.1"
|
"module-alias": "^2.2.2",
|
||||||
|
"mongodb": "^3.5.2",
|
||||||
|
"typy": "^3.3.0"
|
||||||
|
},
|
||||||
|
"_moduleAliases": {
|
||||||
|
"@lifeguard": "./build/src",
|
||||||
|
"@lifeguard/base": "./",
|
||||||
|
"@assertions": "./build/src/assertions",
|
||||||
|
"@config": "./build/src/config",
|
||||||
|
"@events": "./build/src/events",
|
||||||
|
"@models": "./build/src/models",
|
||||||
|
"@plugins": "./build/src/plugins",
|
||||||
|
"@structures": "./build/src/structures",
|
||||||
|
"@util": "./build/src/util"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
import { name, url } from '@config/mongodb';
|
||||||
|
import { Plugin } from '@plugins/Plugin';
|
||||||
|
import { Database } from '@util/Database';
|
||||||
import { Client, ClientOptions, Collection } from 'discord.js';
|
import { Client, ClientOptions, Collection } from 'discord.js';
|
||||||
import { Plugin } from './plugins/Plugin';
|
|
||||||
import { Database } from './util/Database';
|
|
||||||
import { name, url } from './config/mongodb';
|
|
||||||
|
|
||||||
export class PluginClient extends Client {
|
export class PluginClient extends Client {
|
||||||
plugins!: Collection<string, Plugin>;
|
plugins!: Collection<string, Plugin>;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { GuildMember, Guild } from 'discord.js';
|
import { GuildMember, Guild } from 'discord.js';
|
||||||
import { developers } from '../config/bot';
|
import { developers } from '@config/bot';
|
||||||
|
|
||||||
export function calcUserLevel(user: GuildMember, guild: Guild) {
|
export function calcUserLevel(user: GuildMember, guild: Guild) {
|
||||||
if (developers.includes(user.id)) {
|
if (developers.includes(user.id)) {
|
||||||
|
|
35
src/events/channelCreate.ts
Normal file
35
src/events/channelCreate.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { Event } from '@events/Event';
|
||||||
|
import { GuildStructure } from '@structures/GuildStructure';
|
||||||
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
|
import { GuildChannel, TextChannel } from 'discord.js';
|
||||||
|
|
||||||
|
export const event = new Event(
|
||||||
|
'channelCreate',
|
||||||
|
async (lifeguard, channel: GuildChannel) => {
|
||||||
|
const dbGuild = await (channel.guild as GuildStructure).db;
|
||||||
|
if (dbGuild?.config.channels?.logging) {
|
||||||
|
const modlog = channel.guild.channels.get(
|
||||||
|
dbGuild.config.channels.logging
|
||||||
|
) as TextChannel;
|
||||||
|
|
||||||
|
const auditLog = await channel.guild.fetchAuditLogs({
|
||||||
|
type: 'CHANNEL_CREATE',
|
||||||
|
});
|
||||||
|
const auditLogEntry = auditLog.entries.last();
|
||||||
|
|
||||||
|
// const embed = defaultEmbed()
|
||||||
|
// .setDescription(
|
||||||
|
// `:pencil: Channel ${channel.toString()} (${channel.id}) was created`
|
||||||
|
// )
|
||||||
|
// .setTitle('Channel Create');
|
||||||
|
|
||||||
|
// if (auditLogEntry) {
|
||||||
|
// embed.setAuthor(`${auditLogEntry.executor.tag}`);
|
||||||
|
// }
|
||||||
|
|
||||||
|
const embed = defaultEmbed();
|
||||||
|
|
||||||
|
modlog.send(embed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
|
@ -1,7 +1,7 @@
|
||||||
|
import { Event } from '@events/Event';
|
||||||
|
import { PluginClient } from '@lifeguard/PluginClient';
|
||||||
import { readdir } from 'fs';
|
import { readdir } from 'fs';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
import { Event } from './Event';
|
|
||||||
import { PluginClient } from '../PluginClient';
|
|
||||||
|
|
||||||
const readDir = promisify(readdir);
|
const readDir = promisify(readdir);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import { Event } from './Event';
|
import { Event } from '@events/Event';
|
||||||
|
import { Guild } from 'discord.js';
|
||||||
|
|
||||||
export const event = new Event('guildCreate', lifeguard => {
|
export const event = new Event(
|
||||||
if (lifeguard.user) {
|
'guildCreate',
|
||||||
lifeguard.user.setPresence({
|
async (lifeguard, guild: Guild) => {
|
||||||
activity: {
|
await lifeguard.db.guilds.insertOne({ id: guild.id, config: {} });
|
||||||
name: `${lifeguard.users.size} people in the pool`,
|
if (lifeguard.user) {
|
||||||
type: 'WATCHING',
|
lifeguard.user.setPresence({
|
||||||
},
|
activity: {
|
||||||
status: 'online',
|
name: `${lifeguard.users.size} people in the pool`,
|
||||||
});
|
type: 'WATCHING',
|
||||||
|
},
|
||||||
|
status: 'online',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Event } from './Event';
|
import { calcUserLevel } from '@assertions/userLevel';
|
||||||
|
import { prefix } from '@config/bot';
|
||||||
|
import { Event } from '@events/Event';
|
||||||
|
import { PluginClient } from '@lifeguard/PluginClient';
|
||||||
|
import { UserDoc } from '@models/User';
|
||||||
import { Message } from 'discord.js';
|
import { Message } from 'discord.js';
|
||||||
import { prefix } from '../config/bot';
|
|
||||||
import { PluginClient } from '../PluginClient';
|
|
||||||
import { calcUserLevel } from '../assertions/userLevel';
|
|
||||||
import { UserDoc } from '../models/User';
|
|
||||||
|
|
||||||
function parseContent(content: string) {
|
function parseContent(content: string) {
|
||||||
const split = content.split(' ');
|
const split = content.split(' ');
|
||||||
|
@ -14,8 +14,15 @@ function parseContent(content: string) {
|
||||||
|
|
||||||
function getCommandFromPlugin(lifeguard: PluginClient, cmdName: string) {
|
function getCommandFromPlugin(lifeguard: PluginClient, cmdName: string) {
|
||||||
const plugin = lifeguard.plugins.find(p => p.has(cmdName));
|
const plugin = lifeguard.plugins.find(p => p.has(cmdName));
|
||||||
const command = plugin?.get(cmdName);
|
if (plugin) {
|
||||||
return command;
|
return plugin?.get(cmdName);
|
||||||
|
} else {
|
||||||
|
const plugins = [...lifeguard.plugins.values()];
|
||||||
|
const cmds = plugins
|
||||||
|
.map(p => [...p.values()])
|
||||||
|
.reduce((acc, val) => acc.concat(val), []);
|
||||||
|
return cmds.find(cmd => cmd.options.alias?.includes(cmdName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const event = new Event(
|
export const event = new Event(
|
||||||
|
|
|
@ -1,20 +1,42 @@
|
||||||
import { Event } from './Event';
|
import { prefix } from '@config/bot';
|
||||||
|
import { Event } from '@events/Event';
|
||||||
|
import { Guild } from '@models/Guild';
|
||||||
|
import { User } from '@models/User';
|
||||||
|
import { GuildStructure } from '@structures/GuildStructure';
|
||||||
import { Message } from 'discord.js';
|
import { Message } from 'discord.js';
|
||||||
import { prefix } from '../config/bot';
|
|
||||||
import { User, UserDoc } from '../models/User';
|
|
||||||
|
|
||||||
export const event = new Event('message', async (lifeguard, msg: Message) => {
|
export const event = new Event('message', async (lifeguard, msg: Message) => {
|
||||||
let dbUser = (await lifeguard.db.users.findOne({
|
let dbUser = await lifeguard.db.users.findOne({
|
||||||
id: msg.author.id,
|
id: msg.author.id,
|
||||||
})) as UserDoc;
|
});
|
||||||
if (!dbUser) {
|
if (!dbUser) {
|
||||||
await lifeguard.db.users.insertOne(
|
await lifeguard.db.users.insertOne(new User({ id: msg.author.id }));
|
||||||
new User({ id: msg.author.id, infractions: [] })
|
dbUser = await lifeguard.db.users.findOne({
|
||||||
);
|
|
||||||
dbUser = (await lifeguard.db.users.findOne({
|
|
||||||
id: msg.author.id,
|
id: msg.author.id,
|
||||||
})) as UserDoc;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg.guild) {
|
||||||
|
const dbGuild = await (msg.guild as GuildStructure).db;
|
||||||
|
if (!dbGuild) {
|
||||||
|
await lifeguard.db.guilds.insertOne(new Guild({ id: msg.guild.id }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dbUser) {
|
||||||
|
dbUser.stats.totalSentMessages++;
|
||||||
|
dbUser.stats.totalSentCharacters += msg.content.length;
|
||||||
|
dbUser.stats.totalCustomEmojisUsed +=
|
||||||
|
msg.content.match(/<.[^ ]*>/)?.length ?? 0;
|
||||||
|
dbUser.stats.totalTimesMentionedAUser += msg.mentions.users.size;
|
||||||
|
dbUser.stats.totalSentAttachments += msg.attachments.size;
|
||||||
|
|
||||||
|
await lifeguard.db.users.updateOne(
|
||||||
|
{ id: dbUser.id },
|
||||||
|
{ $set: { stats: dbUser.stats } }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.content.startsWith(prefix)) {
|
if (msg.content.startsWith(prefix)) {
|
||||||
lifeguard.emit('lifeguardCommandUsed', msg, dbUser);
|
lifeguard.emit('lifeguardCommandUsed', msg, dbUser);
|
||||||
}
|
}
|
||||||
|
|
20
src/events/messageReactionAdd.ts
Normal file
20
src/events/messageReactionAdd.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { Event } from '@events/Event';
|
||||||
|
import { GuildStructure } from '@structures/GuildStructure';
|
||||||
|
import { MessageReaction, User } from 'discord.js';
|
||||||
|
|
||||||
|
export const event = new Event(
|
||||||
|
'messageReactionAdd',
|
||||||
|
async (lifeguard, reaction: MessageReaction, user: User) => {
|
||||||
|
await lifeguard.db.users.updateOne(
|
||||||
|
{ id: user.id },
|
||||||
|
{ $inc: { 'stats.totalTimesReacted': 1 } }
|
||||||
|
);
|
||||||
|
const dbGuild = await (reaction.message.guild as GuildStructure).db;
|
||||||
|
if (
|
||||||
|
dbGuild?.config.channels?.starboard &&
|
||||||
|
reaction.emoji.name === dbGuild?.config.starboard?.emoji
|
||||||
|
) {
|
||||||
|
lifeguard.emit('starboardReactionAdd', reaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
|
@ -1,4 +1,4 @@
|
||||||
import { Event } from './Event';
|
import { Event } from '@events/Event';
|
||||||
|
|
||||||
export const event = new Event('ready', lifeguard => {
|
export const event = new Event('ready', lifeguard => {
|
||||||
console.log('Connected to Discord');
|
console.log('Connected to Discord');
|
||||||
|
|
64
src/events/starboardReactionAdd.ts
Normal file
64
src/events/starboardReactionAdd.ts
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import { Event } from '@events/Event';
|
||||||
|
import { GuildStructure } from '@structures/GuildStructure';
|
||||||
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
|
import { TextChannel, MessageReaction } from 'discord.js';
|
||||||
|
|
||||||
|
export const event = new Event(
|
||||||
|
'starboardReactionAdd',
|
||||||
|
async (lifeguard, reaction: MessageReaction) => {
|
||||||
|
const dbGuild = await (reaction.message.guild as GuildStructure).db;
|
||||||
|
if (dbGuild?.config.starboard && dbGuild.config.channels?.starboard) {
|
||||||
|
const starboardChannel = reaction.message.guild?.channels.get(
|
||||||
|
dbGuild.config.channels.starboard
|
||||||
|
) as TextChannel;
|
||||||
|
const starboard = dbGuild.config.starboard;
|
||||||
|
if (
|
||||||
|
starboardChannel &&
|
||||||
|
!starboard.ignoredChannels.includes(reaction.message.channel.id)
|
||||||
|
) {
|
||||||
|
if (reaction.count ?? 0 >= starboard.minCount) {
|
||||||
|
const starboardMessage = starboard.messages.find(
|
||||||
|
m => m.id === reaction.message.id
|
||||||
|
);
|
||||||
|
if (starboardMessage) {
|
||||||
|
const starboardMessageInChannel = starboardChannel.messages.get(
|
||||||
|
starboardMessage.starboardID
|
||||||
|
);
|
||||||
|
starboardMessage.count = reaction.count ?? starboardMessage.count;
|
||||||
|
const embed = defaultEmbed()
|
||||||
|
.setAuthor(
|
||||||
|
starboardMessageInChannel?.author.tag,
|
||||||
|
starboardMessageInChannel?.author.avatarURL() ?? ''
|
||||||
|
)
|
||||||
|
.setDescription(reaction.message.content);
|
||||||
|
starboardMessageInChannel?.edit(
|
||||||
|
`${starboard.emoji} ${reaction.count} ${reaction.message.channel} (${reaction.message.id})`,
|
||||||
|
embed
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const embed = defaultEmbed()
|
||||||
|
.setAuthor(
|
||||||
|
reaction.message.author.tag,
|
||||||
|
reaction.message.author.avatarURL() ?? ''
|
||||||
|
)
|
||||||
|
.setDescription(reaction.message.content);
|
||||||
|
const starboardMessage = await starboardChannel.send(
|
||||||
|
`${starboard.emoji} ${reaction.count} ${reaction.message.channel} (${reaction.message.id})`,
|
||||||
|
embed
|
||||||
|
);
|
||||||
|
starboard.messages.push({
|
||||||
|
id: reaction.message.id,
|
||||||
|
starboardID: starboardMessage.id,
|
||||||
|
content: reaction.message.content,
|
||||||
|
count: reaction.count ?? 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await lifeguard.db.guilds.updateOne(
|
||||||
|
{ id: dbGuild.id },
|
||||||
|
{ $set: { 'config.starboard': starboard } }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
13
src/index.ts
13
src/index.ts
|
@ -1,7 +1,12 @@
|
||||||
import { token } from './config/bot';
|
import 'module-alias/register';
|
||||||
import { EventLoader } from './events/eventLoader';
|
|
||||||
import { PluginLoader } from './plugins/pluginLoader';
|
import { token } from '@config/bot';
|
||||||
import { PluginClient } from './PluginClient';
|
import { EventLoader } from '@events/eventLoader';
|
||||||
|
import { PluginClient } from '@lifeguard/PluginClient';
|
||||||
|
import { PluginLoader } from '@plugins/pluginLoader';
|
||||||
|
import { StructureLoader } from '@structures/structureLoader';
|
||||||
|
|
||||||
|
StructureLoader();
|
||||||
|
|
||||||
const lifeguard = new PluginClient();
|
const lifeguard = new PluginClient();
|
||||||
|
|
||||||
|
|
52
src/models/Guild.ts
Normal file
52
src/models/Guild.ts
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import { ObjectId } from 'bson';
|
||||||
|
|
||||||
|
export interface GuildChannels {
|
||||||
|
logging?: string;
|
||||||
|
starboard?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GuildRoles {
|
||||||
|
[key: string]: string | string[] | undefined;
|
||||||
|
muted?: string;
|
||||||
|
moderator?: string;
|
||||||
|
groupRoles?: string[];
|
||||||
|
lockedRoles?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GuildStarboardMessage {
|
||||||
|
id: string;
|
||||||
|
starboardID: string;
|
||||||
|
count: number;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GuildStarboard {
|
||||||
|
emoji: string;
|
||||||
|
minCount: number;
|
||||||
|
ignoredChannels: string[];
|
||||||
|
messages: GuildStarboardMessage[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GuildConfig {
|
||||||
|
blacklisted?: boolean;
|
||||||
|
channels?: GuildChannels;
|
||||||
|
roles?: GuildRoles;
|
||||||
|
starboard?: GuildStarboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GuildDoc {
|
||||||
|
id: string;
|
||||||
|
config?: GuildConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Guild implements GuildDoc {
|
||||||
|
_id: ObjectId;
|
||||||
|
id: string;
|
||||||
|
config: GuildConfig;
|
||||||
|
constructor(data: GuildDoc) {
|
||||||
|
this._id = new ObjectId();
|
||||||
|
this.id = data.id;
|
||||||
|
this.config = data.config ?? {};
|
||||||
|
this.config.blacklisted = data.config?.blacklisted ?? false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,8 @@
|
||||||
interface UserInfraction {
|
import { ObjectId } from 'bson';
|
||||||
action: 'Warn' | 'Mute' | 'Tempban' | 'Ban';
|
import { PermissionOverwriteOption } from 'discord.js';
|
||||||
|
|
||||||
|
export interface UserInfraction {
|
||||||
|
action: 'Warn' | 'Kick' | 'Mute' | 'Ban';
|
||||||
active: boolean;
|
active: boolean;
|
||||||
guild: string;
|
guild: string;
|
||||||
id: number;
|
id: number;
|
||||||
|
@ -8,19 +11,68 @@ interface UserInfraction {
|
||||||
time: Date;
|
time: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserBackup {
|
||||||
|
guild: string;
|
||||||
|
id: number;
|
||||||
|
roles: string[];
|
||||||
|
nickname: string;
|
||||||
|
channelOverrides: UserBackupChannelOverride[];
|
||||||
|
deafened: boolean;
|
||||||
|
muted: boolean;
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserBackupChannelOverride {
|
||||||
|
channelId: number;
|
||||||
|
overrides: PermissionOverwriteOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserStats {
|
||||||
|
totalSentMessages: number;
|
||||||
|
totalSentCharacters: number;
|
||||||
|
totalDeletedMessages: number;
|
||||||
|
totalCustomEmojisUsed: number;
|
||||||
|
totalTimesMentionedAUser: number;
|
||||||
|
totalSentAttachments: number;
|
||||||
|
totalTimesReacted: number;
|
||||||
|
mostUsedReaction: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserReactions {
|
||||||
|
[name: string]: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserDoc {
|
export interface UserDoc {
|
||||||
blacklisted?: boolean;
|
blacklisted?: boolean;
|
||||||
id: string;
|
id: string;
|
||||||
infractions: UserInfraction[];
|
infractions?: UserInfraction[];
|
||||||
|
backups?: UserBackup[];
|
||||||
|
stats?: UserStats;
|
||||||
|
reactions?: UserReactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class User implements UserDoc {
|
export class User implements UserDoc {
|
||||||
|
_id: ObjectId;
|
||||||
blacklisted: boolean;
|
blacklisted: boolean;
|
||||||
id: string;
|
id: string;
|
||||||
infractions: UserInfraction[];
|
infractions: UserInfraction[];
|
||||||
|
backups: UserBackup[];
|
||||||
|
stats: UserStats;
|
||||||
constructor(data: UserDoc) {
|
constructor(data: UserDoc) {
|
||||||
|
this._id = new ObjectId();
|
||||||
this.blacklisted = data.blacklisted ?? false;
|
this.blacklisted = data.blacklisted ?? false;
|
||||||
this.id = data.id;
|
this.id = data.id;
|
||||||
this.infractions = data.infractions;
|
this.infractions = data.infractions ?? [];
|
||||||
|
this.backups = data.backups ?? [];
|
||||||
|
this.stats = data.stats ?? {
|
||||||
|
totalSentMessages: 0,
|
||||||
|
totalSentCharacters: 0,
|
||||||
|
totalDeletedMessages: 0,
|
||||||
|
totalCustomEmojisUsed: 0,
|
||||||
|
totalTimesMentionedAUser: 0,
|
||||||
|
totalSentAttachments: 0,
|
||||||
|
totalTimesReacted: 0,
|
||||||
|
mostUsedReaction: '',
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { Message, PermissionString } from 'discord.js';
|
import { Message, PermissionString } from 'discord.js';
|
||||||
import { PluginClient } from '../PluginClient';
|
import { PluginClient } from '@lifeguard/PluginClient';
|
||||||
import { UserDoc } from '../models/User';
|
import { UserDoc } from '@models/User';
|
||||||
|
|
||||||
type CommandFunction = (
|
type CommandFunction = (
|
||||||
lifeguard: PluginClient,
|
lifeguard: PluginClient,
|
||||||
msg: Message,
|
msg: Message,
|
||||||
args: string[],
|
args: string[],
|
||||||
dbUser: UserDoc
|
dbUser?: UserDoc
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
interface CommandOptions {
|
interface CommandOptions {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Collection } from 'discord.js';
|
import { Collection } from 'discord.js';
|
||||||
import { Command } from './Command';
|
import { Command } from '@plugins/Command';
|
||||||
|
|
||||||
export class Plugin extends Collection<string, Command> {
|
export class Plugin extends Collection<string, Command> {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
46
src/plugins/admin/config.ts
Normal file
46
src/plugins/admin/config.ts
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { t as typy } from 'typy';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'config',
|
||||||
|
async (lifeguard, msg, [cmd, ...args]) => {
|
||||||
|
const path = args[0];
|
||||||
|
switch (cmd) {
|
||||||
|
case 'get':
|
||||||
|
const guild = await lifeguard.db.guilds.findOne({ id: msg.guild?.id });
|
||||||
|
if (guild) {
|
||||||
|
const config = guild['config'];
|
||||||
|
if (path) {
|
||||||
|
msg.channel.send(`${path} - ${typy(config, path).safeObject}`);
|
||||||
|
} else {
|
||||||
|
msg.channel.send(
|
||||||
|
`\`\`\`json\n${JSON.stringify(config, null, 2)}\`\`\``
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'set':
|
||||||
|
const res = await lifeguard.db.guilds.findOneAndUpdate(
|
||||||
|
{
|
||||||
|
id: msg.guild?.id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$set: { [`config.${path}`]: JSON.parse(args[1]) },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.ok) {
|
||||||
|
msg.channel.send('Value has been set successfully');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 3,
|
||||||
|
usage: ['config get', 'config get {key}', 'config set {key} {value}'],
|
||||||
|
hidden: true,
|
||||||
|
}
|
||||||
|
);
|
|
@ -1,5 +1,5 @@
|
||||||
import { Command } from '../Command';
|
import { Command } from '@plugins/Command';
|
||||||
import { parseUser } from '../../util/parseUser';
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
export const command = new Command(
|
export const command = new Command(
|
||||||
'role',
|
'role',
|
31
src/plugins/admin/roles.ts
Normal file
31
src/plugins/admin/roles.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'roles',
|
||||||
|
async (lifeguard, msg) => {
|
||||||
|
const roleList = msg.guild?.roles
|
||||||
|
?.sort((ra, rb) => rb.position - ra.position)
|
||||||
|
.map(r => `${r.id} - ${r.name} (${r.members.size} members)`);
|
||||||
|
const blocks: string[] = [''];
|
||||||
|
|
||||||
|
roleList?.forEach(r => {
|
||||||
|
let currentBlockIndex: number = blocks.length - 1;
|
||||||
|
|
||||||
|
if (
|
||||||
|
blocks[currentBlockIndex].length > 1990 ||
|
||||||
|
blocks[currentBlockIndex].concat(`\n${r}`).length > 1990
|
||||||
|
) {
|
||||||
|
blocks.push('');
|
||||||
|
currentBlockIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks[currentBlockIndex] += `\n${r}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
blocks.forEach(b => msg.channel.send(`\`\`\`dns${b}\`\`\``));
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['roles'],
|
||||||
|
}
|
||||||
|
);
|
33
src/plugins/admin/slowmode.ts
Normal file
33
src/plugins/admin/slowmode.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { TextChannel } from 'discord.js';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'slowmode',
|
||||||
|
async (lifeguard, msg, args) => {
|
||||||
|
const [cmd, time] = args;
|
||||||
|
switch (cmd) {
|
||||||
|
case 'set':
|
||||||
|
if (msg.guild) {
|
||||||
|
(msg.channel as TextChannel).setRateLimitPerUser(+time);
|
||||||
|
msg.channel.send(
|
||||||
|
`Slowmode has been set to 1 message every ${time} seconds`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'off':
|
||||||
|
if (msg.guild) {
|
||||||
|
(msg.channel as TextChannel).setRateLimitPerUser(0);
|
||||||
|
msg.channel.send(`Slowmode has been turned off`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['slowmode set {time}', 'slowmode off'],
|
||||||
|
}
|
||||||
|
);
|
|
@ -1,5 +1,5 @@
|
||||||
import { Command } from '../Command';
|
import { Command } from '@plugins/Command';
|
||||||
import { defaultEmbed } from '../../util/DefaultEmbed';
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
|
|
||||||
export const command = new Command(
|
export const command = new Command(
|
||||||
'ping',
|
'ping',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Command } from '../Command';
|
import { Command } from '@plugins/Command';
|
||||||
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
import { inspect } from 'util';
|
import { inspect } from 'util';
|
||||||
import { runInNewContext } from 'vm';
|
import { runInNewContext } from 'vm';
|
||||||
import { defaultEmbed } from '../../util/DefaultEmbed';
|
|
||||||
|
|
||||||
function parseBlock(script: string) {
|
function parseBlock(script: string) {
|
||||||
const cbr = /^(([ \t]*`{3,4})([^\n]*)([\s\S]+?)(^[ \t]*\2))/gm;
|
const cbr = /^(([ \t]*`{3,4})([^\n]*)([\s\S]+?)(^[ \t]*\2))/gm;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Command } from '../Command';
|
import { Command } from '@plugins/Command';
|
||||||
import { parseUser } from '../../util/parseUser';
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
export const command = new Command(
|
export const command = new Command(
|
||||||
'blacklist',
|
'blacklist',
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Command } from '../Command';
|
import { Command } from '@plugins/Command';
|
||||||
import { promisify } from 'util';
|
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
import { resolve } from 'path';
|
|
||||||
import { MessageEmbed } from 'discord.js';
|
import { MessageEmbed } from 'discord.js';
|
||||||
|
import { resolve } from 'path';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
export const command = new Command(
|
export const command = new Command(
|
||||||
'about',
|
'about',
|
||||||
|
@ -23,7 +23,9 @@ export const command = new Command(
|
||||||
const { version: discordjsVersion } = require('discord.js/package.json');
|
const { version: discordjsVersion } = require('discord.js/package.json');
|
||||||
|
|
||||||
// Get Lifeguard Version
|
// Get Lifeguard Version
|
||||||
const { version: lifeguardVersion } = require('../../../../package.json');
|
const {
|
||||||
|
version: lifeguardVersion,
|
||||||
|
} = require('@lifeguard/base/package.json');
|
||||||
|
|
||||||
const embed = new MessageEmbed()
|
const embed = new MessageEmbed()
|
||||||
.setTitle('About Lifeguard')
|
.setTitle('About Lifeguard')
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { Command } from '../Command';
|
import { calcUserLevel } from '@assertions/userLevel';
|
||||||
import { MessageEmbed, Collection, GuildMember, Guild } from 'discord.js';
|
import { Command } from '@plugins/Command';
|
||||||
import { Plugin } from '../Plugin';
|
import { Plugin } from '@plugins/Plugin';
|
||||||
import { calcUserLevel } from '../../assertions/userLevel';
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
import { defaultEmbed } from '../../util/DefaultEmbed';
|
import { Collection, Guild, GuildMember } from 'discord.js';
|
||||||
|
|
||||||
function convertPlugins(
|
function convertPlugins(
|
||||||
plugins: Collection<string, Plugin>,
|
plugins: Collection<string, Plugin>,
|
||||||
|
@ -39,8 +39,6 @@ export const command = new Command(
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const plugin of plugins) {
|
for (const plugin of plugins) {
|
||||||
// console.log(plugin)
|
|
||||||
// embed.addField(plugin.name, plugin.cmds.join('\n'));
|
|
||||||
if (plugin.cmds.length > 0) {
|
if (plugin.cmds.length > 0) {
|
||||||
embed.addField(plugin.name, plugin.cmds.join('\n'));
|
embed.addField(plugin.name, plugin.cmds.join('\n'));
|
||||||
}
|
}
|
||||||
|
|
55
src/plugins/moderation/ban.ts
Normal file
55
src/plugins/moderation/ban.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { UserInfraction } from '@models/User';
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'ban',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Create Infraction
|
||||||
|
const inf: UserInfraction = {
|
||||||
|
action: 'Ban',
|
||||||
|
active: true,
|
||||||
|
guild: msg.guild?.id as string,
|
||||||
|
id: (await lifeguard.db.users.findOne({ id: u }))?.infractions
|
||||||
|
.length as number,
|
||||||
|
moderator: msg.author.id,
|
||||||
|
reason: reason.join(' '),
|
||||||
|
time: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update User in Database
|
||||||
|
await lifeguard.db.users.findOneAndUpdate(
|
||||||
|
{ id: u },
|
||||||
|
{ $push: { infractions: inf } },
|
||||||
|
{ returnOriginal: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
const member = await msg.guild?.members.get(u);
|
||||||
|
// Notify User about Action
|
||||||
|
member?.send(
|
||||||
|
`You have been banned from **${msg.guild?.name}** for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
// Ban User
|
||||||
|
member?.ban({ reason: reason.join(' ') });
|
||||||
|
|
||||||
|
// Tell moderator action was successful
|
||||||
|
msg.channel.send(
|
||||||
|
`${member?.user.tag} was banned by ${msg.author.tag} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['ban {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
60
src/plugins/moderation/forceban.ts
Normal file
60
src/plugins/moderation/forceban.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { UserInfraction } from '@models/User';
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
import { GuildMember, User } from 'discord.js';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'forceban',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Create Infraction
|
||||||
|
const inf: UserInfraction = {
|
||||||
|
action: 'Ban',
|
||||||
|
active: true,
|
||||||
|
guild: msg.guild?.id as string,
|
||||||
|
id: (await lifeguard.db.users.findOne({ id: u }))?.infractions
|
||||||
|
.length as number,
|
||||||
|
moderator: msg.author.id,
|
||||||
|
reason: reason.join(' '),
|
||||||
|
time: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update User in Database
|
||||||
|
await lifeguard.db.users.findOneAndUpdate(
|
||||||
|
{ id: u },
|
||||||
|
{ $push: { infractions: inf } },
|
||||||
|
{ returnOriginal: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ban user from guild
|
||||||
|
const member = await msg.guild?.members.ban(u, {
|
||||||
|
reason: reason.join(' '),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Retreive user tag
|
||||||
|
let tag;
|
||||||
|
if (member instanceof GuildMember) {
|
||||||
|
tag = member.user.tag;
|
||||||
|
} else if (member instanceof User) {
|
||||||
|
tag = member.tag;
|
||||||
|
} else {
|
||||||
|
tag = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell moderator ban was successful
|
||||||
|
msg.channel.send(
|
||||||
|
`${tag} was force-banned by ${msg.author.toString()} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['forceban {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
54
src/plugins/moderation/infractions.ts
Normal file
54
src/plugins/moderation/infractions.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
import { MessageAttachment } from 'discord.js';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'infractions',
|
||||||
|
async (lifeguard, msg, [cmd, ...args], dbUser) => {
|
||||||
|
switch (cmd) {
|
||||||
|
case 'archive':
|
||||||
|
// Get users from Database that have infractions
|
||||||
|
const dbUsers = lifeguard.db.users.find({
|
||||||
|
infractions: { $elemMatch: { guild: msg.guild?.id } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const guildInfractions = (
|
||||||
|
await dbUsers
|
||||||
|
// Filter out infractions not from current guild
|
||||||
|
.map(u => u.infractions.filter(inf => inf.guild === msg.guild?.id))
|
||||||
|
.toArray()
|
||||||
|
)
|
||||||
|
// Flatten Array
|
||||||
|
.reduce((acc, val) => acc.concat(val), []);
|
||||||
|
|
||||||
|
// Send archive as JSON file
|
||||||
|
msg.channel.send(
|
||||||
|
new MessageAttachment(
|
||||||
|
Buffer.from(JSON.stringify(guildInfractions, null, 2)),
|
||||||
|
`${msg.guild?.id}.infractions.json`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'info':
|
||||||
|
const [user, infID] = args;
|
||||||
|
const u = parseUser(user);
|
||||||
|
const dbUser = await lifeguard.db.users.findOne({ id: u });
|
||||||
|
const inf = dbUser?.infractions.find(inf => inf.id === +infID);
|
||||||
|
msg.channel.send(`\`\`\`json\n${JSON.stringify(inf, null, 2)}\n\`\`\``);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: [
|
||||||
|
'infractions archive',
|
||||||
|
'infractions search {user}',
|
||||||
|
'infractions info {user} {id}',
|
||||||
|
],
|
||||||
|
alias: ['inf'],
|
||||||
|
}
|
||||||
|
);
|
55
src/plugins/moderation/kick.ts
Normal file
55
src/plugins/moderation/kick.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { UserInfraction } from '@models/User';
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'kick',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Create Infraction
|
||||||
|
const inf: UserInfraction = {
|
||||||
|
action: 'Kick',
|
||||||
|
active: true,
|
||||||
|
guild: msg.guild?.id as string,
|
||||||
|
id: (await lifeguard.db.users.findOne({ id: u }))?.infractions
|
||||||
|
.length as number,
|
||||||
|
moderator: msg.author.id,
|
||||||
|
reason: reason.join(' '),
|
||||||
|
time: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update User in Database
|
||||||
|
await lifeguard.db.users.findOneAndUpdate(
|
||||||
|
{ id: u },
|
||||||
|
{ $push: { infractions: inf } },
|
||||||
|
{ returnOriginal: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
const member = await msg.guild?.members.get(u);
|
||||||
|
// Notify User about Action
|
||||||
|
member?.send(
|
||||||
|
`You have been kicked from **${msg.guild?.name}** for \`${reason.join(
|
||||||
|
' '
|
||||||
|
)}\``
|
||||||
|
);
|
||||||
|
// Ban the User
|
||||||
|
member?.kick(reason.join(' '));
|
||||||
|
|
||||||
|
// Tell moderator action was successful
|
||||||
|
msg.channel.send(
|
||||||
|
`${member?.user.tag} was kicked by ${msg.author.tag} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['kick {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
20
src/plugins/moderation/mban.ts
Normal file
20
src/plugins/moderation/mban.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { command as ban } from '@plugins/moderation/ban';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'mban',
|
||||||
|
async (lifeguard, msg, args) => {
|
||||||
|
// Find where '-r' is in the args
|
||||||
|
const reasonFlagIndex = args.indexOf('-r') || args.length;
|
||||||
|
// Get users from args
|
||||||
|
const users = args.slice(0, reasonFlagIndex);
|
||||||
|
// Get reason from args
|
||||||
|
const reason = args.slice(reasonFlagIndex + 1).join(' ');
|
||||||
|
// Run ban command for each user
|
||||||
|
users.forEach(user => ban.func(lifeguard, msg, [user, reason]));
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['mban {users} -r [reason]'],
|
||||||
|
}
|
||||||
|
);
|
20
src/plugins/moderation/mkick.ts
Normal file
20
src/plugins/moderation/mkick.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { command as kick } from '@plugins/moderation/kick';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'mkick',
|
||||||
|
async (lifeguard, msg, args) => {
|
||||||
|
// Find where '-r' is in the args
|
||||||
|
const reasonFlagIndex = args.indexOf('-r');
|
||||||
|
// Get users from args
|
||||||
|
const uids = args.slice(0, reasonFlagIndex);
|
||||||
|
// Get reason from args
|
||||||
|
const reason = args.slice(reasonFlagIndex + 1).join(' ');
|
||||||
|
// Run ban command for each user
|
||||||
|
uids.forEach(uid => kick.func(lifeguard, msg, [uid, reason]));
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['mkick {users} -r [reason]'],
|
||||||
|
}
|
||||||
|
);
|
59
src/plugins/moderation/mute.ts
Normal file
59
src/plugins/moderation/mute.ts
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import { UserInfraction } from '@models/User';
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'mute',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Get guild from db
|
||||||
|
const guild = await lifeguard.db.guilds.findOne({ id: msg.guild?.id });
|
||||||
|
// Check if muted role exists
|
||||||
|
if (guild?.config.roles?.muted) {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Create Infracrion
|
||||||
|
const inf: UserInfraction = {
|
||||||
|
action: 'Mute',
|
||||||
|
active: true,
|
||||||
|
guild: msg.guild?.id as string,
|
||||||
|
id: (await lifeguard.db.users.findOne({ id: u }))?.infractions
|
||||||
|
.length as number,
|
||||||
|
moderator: msg.author.id,
|
||||||
|
reason: reason.join(' '),
|
||||||
|
time: new Date(),
|
||||||
|
};
|
||||||
|
// Update User in Database
|
||||||
|
await lifeguard.db.users.findOneAndUpdate(
|
||||||
|
{ id: u },
|
||||||
|
{ $push: { infractions: inf } },
|
||||||
|
{ returnOriginal: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
const member = msg.guild?.members.get(u);
|
||||||
|
// Add role to user
|
||||||
|
await member?.roles.add(guild.config.roles.muted);
|
||||||
|
|
||||||
|
// Tell moderator action was successfull
|
||||||
|
msg.channel.send(
|
||||||
|
`${member?.user.tag} was muted by ${msg.author.tag} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const embed = defaultEmbed()
|
||||||
|
.setTitle(':rotating_light: Error! :rotating_light:')
|
||||||
|
.setDescription('No mute role configured!');
|
||||||
|
msg.channel.send(embed);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['mute {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
57
src/plugins/moderation/softban.ts
Normal file
57
src/plugins/moderation/softban.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { UserInfraction } from '@models/User';
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'softban',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Create Infraction
|
||||||
|
const inf: UserInfraction = {
|
||||||
|
action: 'Ban',
|
||||||
|
active: true,
|
||||||
|
guild: msg.guild?.id as string,
|
||||||
|
id: (await lifeguard.db.users.findOne({ id: u }))?.infractions
|
||||||
|
.length as number,
|
||||||
|
moderator: msg.author.id,
|
||||||
|
reason: reason.join(' '),
|
||||||
|
time: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update User in Database
|
||||||
|
await lifeguard.db.users.findOneAndUpdate(
|
||||||
|
{ id: u },
|
||||||
|
{ $push: { infractions: inf } },
|
||||||
|
{ returnOriginal: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
const member = await msg.guild?.members.get(u);
|
||||||
|
// Notify user of action
|
||||||
|
member?.send(
|
||||||
|
`You have been soft-banned from **${msg.guild?.name}** for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
// Ban User
|
||||||
|
member?.ban({ reason: reason.join(' '), days: 7 });
|
||||||
|
// Unban User
|
||||||
|
await msg.guild?.members.unban(u, reason.join(' '));
|
||||||
|
|
||||||
|
// Tell moderator action was successfull
|
||||||
|
msg.channel.send(
|
||||||
|
`${member?.user.tag} was soft-banned by ${msg.author.tag} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['softban {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
39
src/plugins/moderation/unmute.ts
Normal file
39
src/plugins/moderation/unmute.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { defaultEmbed } from '@util/DefaultEmbed';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'unmute',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Get guild from database
|
||||||
|
const guild = await lifeguard.db.guilds.findOne({ id: msg.guild?.id });
|
||||||
|
// Check if muted role exists
|
||||||
|
if (guild?.config.roles?.muted) {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Get User
|
||||||
|
const member = msg.guild?.members.get(u);
|
||||||
|
// Remove Role
|
||||||
|
await member?.roles.remove(guild.config.roles.muted);
|
||||||
|
// Tell moderator action was successfull
|
||||||
|
msg.channel.send(
|
||||||
|
`${member?.user.tag} was unmuted by ${msg.author.tag} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const embed = defaultEmbed()
|
||||||
|
.setTitle(':rotating_light: Error! :rotating_light:')
|
||||||
|
.setDescription('No mute role configured!');
|
||||||
|
msg.channel.send(embed);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['unmute {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
47
src/plugins/moderation/warn.ts
Normal file
47
src/plugins/moderation/warn.ts
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import { UserInfraction } from '@models/User';
|
||||||
|
import { Command } from '@plugins/Command';
|
||||||
|
import { parseUser } from '@util/parseUser';
|
||||||
|
|
||||||
|
export const command = new Command(
|
||||||
|
'warn',
|
||||||
|
async (lifeguard, msg, [uid, ...reason]) => {
|
||||||
|
// Parse user id from mention
|
||||||
|
const u = parseUser(uid);
|
||||||
|
try {
|
||||||
|
// Create Infracion
|
||||||
|
const inf: UserInfraction = {
|
||||||
|
action: 'Warn',
|
||||||
|
active: true,
|
||||||
|
guild: msg.guild?.id as string,
|
||||||
|
id: (await lifeguard.db.users.findOne({ id: u }))?.infractions
|
||||||
|
.length as number,
|
||||||
|
moderator: msg.author.id,
|
||||||
|
reason: reason.join(' '),
|
||||||
|
time: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update User in Database
|
||||||
|
await lifeguard.db.users.findOneAndUpdate(
|
||||||
|
{ id: u },
|
||||||
|
{ $push: { infractions: inf } },
|
||||||
|
{ returnOriginal: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get User
|
||||||
|
const member = msg.guild?.members.get(u);
|
||||||
|
|
||||||
|
// Tell moderator action was sucessfull
|
||||||
|
msg.channel.send(
|
||||||
|
`${member?.user.tag} was warned by ${msg.author.tag} for \`${
|
||||||
|
reason.length > 0 ? reason.join(' ') : 'No Reason Specified'
|
||||||
|
}\``
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
msg.channel.send(err.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
level: 1,
|
||||||
|
usage: ['warn {user} [reason]'],
|
||||||
|
}
|
||||||
|
);
|
29
src/structures/GuildMember.ts
Normal file
29
src/structures/GuildMember.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { Structures, Guild, GuildMember } from 'discord.js';
|
||||||
|
import { PluginClient } from 'PluginClient';
|
||||||
|
import { inspect } from 'util';
|
||||||
|
|
||||||
|
Structures.extend('GuildMember', guildMember => {
|
||||||
|
return class extends guildMember {
|
||||||
|
_client: PluginClient;
|
||||||
|
constructor(client: PluginClient, data: object, guild: Guild) {
|
||||||
|
super(client, data, guild);
|
||||||
|
this._client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
get db() {
|
||||||
|
return this._client.db.users.findOne({ id: this.user.id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export class GuildMemberStructure extends GuildMember {
|
||||||
|
_client: PluginClient;
|
||||||
|
constructor(client: PluginClient, data: object, guild: Guild) {
|
||||||
|
super(client, data, guild);
|
||||||
|
this._client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
get db() {
|
||||||
|
return this._client.db.users.findOne({ id: this.user.id });
|
||||||
|
}
|
||||||
|
}
|
29
src/structures/GuildStructure.ts
Normal file
29
src/structures/GuildStructure.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { Structures, Guild } from 'discord.js';
|
||||||
|
import { PluginClient } from 'PluginClient';
|
||||||
|
import { inspect } from 'util';
|
||||||
|
|
||||||
|
Structures.extend('Guild', guildClass => {
|
||||||
|
return class extends guildClass {
|
||||||
|
_client: PluginClient;
|
||||||
|
constructor(client: PluginClient, data: object) {
|
||||||
|
super(client, data);
|
||||||
|
this._client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
get db() {
|
||||||
|
return this._client.db.guilds.findOne({ id: this.id });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export class GuildStructure extends Guild {
|
||||||
|
_client: PluginClient;
|
||||||
|
constructor(client: PluginClient, data: object) {
|
||||||
|
super(client, data);
|
||||||
|
this._client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
get db() {
|
||||||
|
return this._client.db.guilds.findOne({ id: this.id });
|
||||||
|
}
|
||||||
|
}
|
11
src/structures/structureLoader.ts
Normal file
11
src/structures/structureLoader.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { readdirSync } from 'fs';
|
||||||
|
|
||||||
|
export function StructureLoader() {
|
||||||
|
const structureFiles = readdirSync('./build/src/structures');
|
||||||
|
|
||||||
|
for (const file of structureFiles) {
|
||||||
|
if (file !== 'structureLoader.js' && file.endsWith('js')) {
|
||||||
|
require(`./${file}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
import { connect, Db, MongoClientOptions } from 'mongodb';
|
import { connect, Db, MongoClientOptions, Collection } from 'mongodb';
|
||||||
|
import { User } from '../models/User';
|
||||||
|
import { Guild } from '../models/Guild';
|
||||||
|
|
||||||
interface DatabaseConfig {
|
interface DatabaseConfig {
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -20,11 +22,11 @@ export class Database {
|
||||||
this.db = client.db(this.config.name);
|
this.db = client.db(this.config.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
get guilds() {
|
get guilds(): Collection<Guild> {
|
||||||
return this.db.collection('guilds');
|
return this.db.collection('guilds');
|
||||||
}
|
}
|
||||||
|
|
||||||
get users() {
|
get users(): Collection<User> {
|
||||||
return this.db.collection('users');
|
return this.db.collection('users');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,19 @@
|
||||||
"extends": "./node_modules/gts/tsconfig-google.json",
|
"extends": "./node_modules/gts/tsconfig-google.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": ".",
|
"rootDir": ".",
|
||||||
"outDir": "build"
|
"outDir": "build",
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"paths": {
|
||||||
|
"@lifeguard/*": ["./*"],
|
||||||
|
"@lifegaurd/base/*": ["../*"],
|
||||||
|
"@assertions/*": ["./assertions/*"],
|
||||||
|
"@config/*": ["./config/*"],
|
||||||
|
"@events/*": ["./events/*"],
|
||||||
|
"@models/*": ["./models/*"],
|
||||||
|
"@plugins/*": ["./plugins/*"],
|
||||||
|
"@structures/*": ["./structures/*"],
|
||||||
|
"@util/*": ["./util/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src/**/*.ts", "test/**/*.ts"]
|
||||||
"src/**/*.ts",
|
|
||||||
"test/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue