commit
a01a2933df
|
@ -1,2 +1,5 @@
|
|||
/local/
|
||||
node_modules/
|
||||
node_modules/
|
||||
.DS_Store
|
||||
test.sh
|
||||
.vscode
|
||||
|
|
10
index.js
10
index.js
|
@ -1,10 +0,0 @@
|
|||
(async function(){
|
||||
global.dbClient = new (require('pg').Client)({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
ssl: true,
|
||||
});
|
||||
await dbClient.connect();
|
||||
|
||||
require('./src/main');
|
||||
|
||||
})().catch(error => {console.error(error.stack); process.exit(1);});
|
|
@ -0,0 +1,544 @@
|
|||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
|
||||
"integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"async-exit-hook": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
|
||||
"integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz",
|
||||
"integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg=="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
|
||||
"integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ=="
|
||||
},
|
||||
"buffer-writer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz",
|
||||
"integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg="
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.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="
|
||||
},
|
||||
"discord.js": {
|
||||
"version": "github:hydrabolt/discord.js#7d2744be89f90fa16b77b6fbad95902e26f4564a",
|
||||
"from": "github:hydrabolt/discord.js",
|
||||
"requires": {
|
||||
"form-data": "^2.3.2",
|
||||
"node-fetch": "^2.1.2",
|
||||
"pako": "^1.0.0",
|
||||
"prism-media": "github:hydrabolt/prism-media#ead016c69b1f341898cb264746c355b982502c62",
|
||||
"tweetnacl": "^1.0.0",
|
||||
"ws": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ws": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
|
||||
"integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
|
||||
"integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ=="
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"requires": {
|
||||
"es6-promise": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
|
||||
"integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
|
||||
"requires": {
|
||||
"concat-stream": "1.6.2",
|
||||
"debug": "2.6.9",
|
||||
"mkdirp": "0.5.1",
|
||||
"yauzl": "2.4.1"
|
||||
}
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
|
||||
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
|
||||
"requires": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
|
||||
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
|
||||
"requires": {
|
||||
"agent-base": "^4.1.0",
|
||||
"debug": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.33.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
||||
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.18",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
||||
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
||||
"requires": {
|
||||
"mime-db": "~1.33.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.1.tgz",
|
||||
"integrity": "sha512-GU9oWK4pi8PC7NyGiwjFMwZyMqwGWoMEMvM0LZh7UKW/FFAqgmZKjjriD+5MEOCDUJE2dtHX93/K5UtDxO0otg==",
|
||||
"requires": {
|
||||
"mongodb-core": "3.1.0"
|
||||
}
|
||||
},
|
||||
"mongodb-core": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.0.tgz",
|
||||
"integrity": "sha512-qRjG62Fu//CZhkgn0jA/k8jh5MhACIq8cOJUryH6sck87pgt+C222MSD02tsCq5zNo/B6ZFHtNodZ2qpf8E86g==",
|
||||
"requires": {
|
||||
"bson": "~1.0.4",
|
||||
"require_optional": "^1.0.1",
|
||||
"saslprep": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
|
||||
"integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"packet-reader": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz",
|
||||
"integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc="
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
||||
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg=="
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
},
|
||||
"pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
|
||||
},
|
||||
"pg": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-7.4.3.tgz",
|
||||
"integrity": "sha1-97b5P1NA7MJZavu5ShPj1rYJg0s=",
|
||||
"requires": {
|
||||
"buffer-writer": "1.0.1",
|
||||
"packet-reader": "0.3.1",
|
||||
"pg-connection-string": "0.1.3",
|
||||
"pg-pool": "~2.0.3",
|
||||
"pg-types": "~1.12.1",
|
||||
"pgpass": "1.x",
|
||||
"semver": "4.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
|
||||
"integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c="
|
||||
}
|
||||
}
|
||||
},
|
||||
"pg-connection-string": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz",
|
||||
"integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc="
|
||||
},
|
||||
"pg-pool": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.3.tgz",
|
||||
"integrity": "sha1-wCIDLIlJ8xKk+R+2QJzgQHa+Mlc="
|
||||
},
|
||||
"pg-types": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.12.1.tgz",
|
||||
"integrity": "sha1-1kCH45A7WP+q0nnnWVxSIIoUw9I=",
|
||||
"requires": {
|
||||
"postgres-array": "~1.0.0",
|
||||
"postgres-bytea": "~1.0.0",
|
||||
"postgres-date": "~1.0.0",
|
||||
"postgres-interval": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"pgpass": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz",
|
||||
"integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=",
|
||||
"requires": {
|
||||
"split": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"postgres-array": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz",
|
||||
"integrity": "sha1-jgsy6wO/d6XAp4UeBEHBaaJWojg="
|
||||
},
|
||||
"postgres-bytea": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
|
||||
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
|
||||
},
|
||||
"postgres-date": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.3.tgz",
|
||||
"integrity": "sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g="
|
||||
},
|
||||
"postgres-interval": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.2.tgz",
|
||||
"integrity": "sha512-fC3xNHeTskCxL1dC8KOtxXt7YeFmlbTYtn7ul8MkVERuTmf7pI4DrkAxcw3kh1fQ9uz4wQmd03a1mRiXUZChfQ==",
|
||||
"requires": {
|
||||
"xtend": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"prism-media": {
|
||||
"version": "github:hydrabolt/prism-media#ead016c69b1f341898cb264746c355b982502c62",
|
||||
"from": "github:hydrabolt/prism-media"
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
},
|
||||
"progress": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
|
||||
"integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8="
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
|
||||
"integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4="
|
||||
},
|
||||
"puppeteer": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-0.13.0.tgz",
|
||||
"integrity": "sha512-M52SA/WmW54YMLzFtCLGslhr9tntzfTgJIZnx3QnaDXn9F5q2BlTosywSBEKj8aVVd6al0WNfiu14MUQW3wjaw==",
|
||||
"requires": {
|
||||
"debug": "^2.6.8",
|
||||
"extract-zip": "^1.6.5",
|
||||
"https-proxy-agent": "^2.1.0",
|
||||
"mime": "^1.3.4",
|
||||
"progress": "^2.0.0",
|
||||
"proxy-from-env": "^1.0.0",
|
||||
"rimraf": "^2.6.1",
|
||||
"ws": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"require_optional": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
|
||||
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
|
||||
"requires": {
|
||||
"resolve-from": "^2.0.0",
|
||||
"semver": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
|
||||
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"requires": {
|
||||
"glob": "^7.0.5"
|
||||
}
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"saslprep": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.0.tgz",
|
||||
"integrity": "sha512-5lvKUEQ7lAN5/vPl5d3k8FQeDbEamu9kizfATfLLWV5h6Mkh1xcieR1FSsJkcSRUk49lF2tAW8gzXWVwtwZVhw==",
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
|
||||
},
|
||||
"split": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
|
||||
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
|
||||
"requires": {
|
||||
"through": "2"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.0.tgz",
|
||||
"integrity": "sha1-cT2LgY2kIGh0C/aDhtBHnmb8ins="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"ultron": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
|
||||
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0",
|
||||
"safe-buffer": "~5.1.0",
|
||||
"ultron": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
|
||||
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
|
||||
"requires": {
|
||||
"fd-slicer": "~1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ global.colorRoles = { // TODO clean up this, adsfhaiusdhgaisuhg
|
|||
name:"[]",
|
||||
permissions:[],
|
||||
color:"RANDOM",
|
||||
//position: member.guild.roles.get('346754988023873546').position
|
||||
}});
|
||||
return role;
|
||||
},
|
||||
|
|
|
@ -38,11 +38,11 @@ global.commands = {
|
|||
usage: "<name>",
|
||||
description: "Creates a generic text channel in this server and gives you full permissions for it.",
|
||||
exec: async function (msg) {
|
||||
if (!msg.args[0]) return false;
|
||||
if (!msg.args[0]) return "EBADUSG";
|
||||
//var name = msg.txt(1).replace(/[^a-zA-Z0-9]/g, '-').substr(0,100).toLowerCase();
|
||||
var name = msg.txt(1);
|
||||
msg.guild.channels.create(name, {
|
||||
parent: '399735134061985792',
|
||||
parent: config.channels.user_channels,
|
||||
overwrites: [
|
||||
{
|
||||
id: msg,
|
||||
|
@ -79,7 +79,7 @@ global.commands = {
|
|||
var channel = msg.channel;
|
||||
}
|
||||
if (!channel.permissionsFor(msg.member).has('MANAGE_CHANNELS')) return msg.react('🚫');
|
||||
await channel.setParent('425054198699261953');
|
||||
await channel.setParent(config.channels.deleted_channels);
|
||||
await channel.lockPermissions();
|
||||
msg.react('🆗');
|
||||
}
|
||||
|
@ -106,6 +106,24 @@ global.commands = {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
"exec": {
|
||||
op: true,
|
||||
usage: "<command>",
|
||||
aliases: ["$"],
|
||||
exec: async function (msg) {
|
||||
require("child_process").exec(msg.txt(1), function(error, stdout, stderr){
|
||||
if (error) msg.channel.send(error, {split:{char:''}});
|
||||
else {
|
||||
var str = ""
|
||||
if (stdout) msg.channel.send(stdout, {split:{char:''}});
|
||||
if (stderr) msg.channel.send(stderr, {split:{char:''}});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
"query": {
|
||||
description: "Queries the Heroku PostgreSQL database",
|
||||
usage: "<query>",
|
||||
|
@ -145,35 +163,26 @@ dClient.on('message', message => {
|
|||
if (!message.guild) message.guild = dClient.guilds.get(config.guildID);
|
||||
if (!message.member) message.member = dClient.guilds.get(config.guildID).members.get(message.author.id);
|
||||
|
||||
/*if (commands.hasOwnProperty(cmd)) {
|
||||
var command = commands[cmd];
|
||||
if (command.op && message.author.id !== op) return message.react('🚫');
|
||||
try {
|
||||
command.exec(message, args, txt);
|
||||
} catch(e) {
|
||||
message.reply(`:warning: An error occured while processing your command.`);
|
||||
console.error(e.stack);
|
||||
}
|
||||
}*/
|
||||
|
||||
Object.keys(commands).forEach(commandName => {
|
||||
var command = commands[commandName];
|
||||
if (!(commandName === cmd || (command.aliases && command.aliases.includes(cmd)))) return;
|
||||
if (command.op && message.author.id !== config.opID) return message.react('🚫');
|
||||
/*try {
|
||||
var d = command.exec(message, args, txt);
|
||||
if (d === false) message.channel.send(`**Usage:** \`!${commandName} ${command.usage}\``);
|
||||
} catch(e) {
|
||||
message.reply(`:warning: An error occured while processing your command.`);
|
||||
console.error(e.stack);
|
||||
}*/
|
||||
|
||||
command.exec(message, args, txt).then(
|
||||
(res) => {
|
||||
if (res === false) message.channel.send(`**Usage:** \`!${commandName} ${command.usage}\``);
|
||||
switch (res) {
|
||||
case "ENOTBRIDGE":
|
||||
message.channel.send([
|
||||
`This is not a bridged channel.`,
|
||||
`You can only use this command in a bridged channel.`
|
||||
].random());
|
||||
break;
|
||||
case "EBADUSG":
|
||||
message.channel.send(`**Usage:** \`!${commandName} ${command.usage}\``);
|
||||
break;
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
message.reply(`:warning: An error occured: \`\`\`\n${err.stack}\n\`\`\``);
|
||||
message.reply(`:warning: An error occured: \`\`\`\n${err.stack}\n\`\`\`<@281134216115257344>`);
|
||||
console.error(err.stack);
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,25 +1,42 @@
|
|||
global.testmode = process.env.TEST ? true : false;
|
||||
|
||||
module.exports = {
|
||||
"testmode": false,
|
||||
|
||||
"token": process.env.DISCORD_TOKEN,
|
||||
|
||||
|
||||
"DISCORD_TOKEN": process.env.DISCORD_TOKEN,
|
||||
"DATABASE_URL": testmode ? "postgres://localhost/k4t" : process.env.DATABASE_URL,
|
||||
"MONGODB_URI": testmode ? "mongodb://localhost/k4t" : process.env.MONGODB_URI,
|
||||
|
||||
"webhooks": {
|
||||
"console": process.env.TOKEN_WEBHOOK_CONSOLE,
|
||||
"welcome": process.env.TOKEN_WEBHOOK_WELCOME,
|
||||
"welcome": process.env.WEBHOOK_WELCOME.split("/"),
|
||||
},
|
||||
|
||||
"opID": "281134216115257344",
|
||||
"guildID": "321819041348190249",
|
||||
"channels": {
|
||||
"main": "321819041348190249"
|
||||
"guildID": testmode ? "467473467634089985" : "321819041348190249",
|
||||
|
||||
"channels": { // includes voice channels & category channels
|
||||
"main": testmode ? "467473467634089987" : "321819041348190249",
|
||||
"voice": testmode ? "467473467634089989" : "425060452129701889",
|
||||
"name_collection": testmode ? "467481952728121345" : '379738469511069698',
|
||||
"mpp_bridges": testmode ? "467481904707534850" : '360557444952227851',
|
||||
"user_channels": testmode ? "467482031157149709" : '399735134061985792',
|
||||
"deleted_channels": testmode ? "467482085657935872" : '425054198699261953',
|
||||
"deleted_bridges": testmode ? "467482121657778176" : '451838300068511745',
|
||||
"mpp_screenshot": testmode ? "467482164611514388" : '383773548810076163',
|
||||
"owop_screenshot": testmode ? "467482202217906226" : '399079481161023492'
|
||||
},
|
||||
|
||||
"roles": {
|
||||
"viewing_deleted_channels": testmode ? "467473718353068042" : "425060792455397376",
|
||||
},
|
||||
|
||||
|
||||
|
||||
"mppname": "[discord.gg/k44Eqha]",
|
||||
"disabledRooms": [
|
||||
"RP Room",
|
||||
"Legends of Alorgon {RP Room}",
|
||||
"Legends of Alorgon",
|
||||
"Breastmilk ♥ 7:45 AM"
|
||||
]
|
||||
],
|
||||
|
||||
}
|
|
@ -17,10 +17,9 @@ function mixin(obj1, obj2) {
|
|||
};
|
||||
|
||||
|
||||
function Client(uri, arrayBuffer) {
|
||||
function Client(uri) {
|
||||
EventEmitter.call(this);
|
||||
this.uri = uri;
|
||||
this.arrayBuffer = arrayBuffer;
|
||||
this.ws = undefined;
|
||||
this.serverTimeOffset = 0;
|
||||
this.user = undefined;
|
||||
|
@ -85,7 +84,7 @@ Client.prototype.connect = function() {
|
|||
// browseroni
|
||||
this.ws = new WebSocket(this.uri);
|
||||
}
|
||||
if (this.arrayBuffer) this.ws.binaryType = "arraybuffer";
|
||||
this.ws.binaryType = "arraybuffer";
|
||||
this.emit("ws created");
|
||||
var self = this;
|
||||
this.ws.addEventListener("close", function(evt) {
|
||||
|
|
56
src/main.js
56
src/main.js
|
@ -1,51 +1,33 @@
|
|||
require('./util');
|
||||
global.config = require('./config');
|
||||
if (config.testmode) console.log('TEST MODE');
|
||||
global.exitHook = require('async-exit-hook');
|
||||
global.Discord = require('discord.js');
|
||||
global.fs = require('fs');
|
||||
global.config = require('./config');
|
||||
global.dClient = new Discord.Client({ disableEveryone: true });
|
||||
|
||||
console._log = console.log;
|
||||
console.log = function(){
|
||||
console._log.apply(console, arguments);
|
||||
log2discord(arguments);
|
||||
}
|
||||
console._error = console.error;
|
||||
console.error = function(){
|
||||
console._error.apply(console, arguments);
|
||||
log2discord(arguments);
|
||||
}
|
||||
console.warn = console.error;
|
||||
console.info = console.log;
|
||||
|
||||
var webhook = new Discord.WebhookClient('405445543536623627', config.webhooks.console);
|
||||
function log2discord(str){
|
||||
str = Array.from(str);
|
||||
str = str.map(require('util').inspect);
|
||||
str = str.join(' ');
|
||||
webhook.send(str, {split:{char:''}});
|
||||
}
|
||||
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
console.error(promise);
|
||||
global.dbClient = new (require('pg').Client)({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
ssl: !testmode,
|
||||
});
|
||||
process.on('uncaughtException', error => {
|
||||
console.error(error.stack);
|
||||
});
|
||||
|
||||
|
||||
(require('mongodb').MongoClient).connect(process.env.MONGODB_URI).then(client=>{
|
||||
global.mdbClient = client;
|
||||
dClient.login(config.token);
|
||||
console.log("Connecting to Postgres…")
|
||||
dbClient.connect().then(function(){
|
||||
console.log("Connecting to MongoDB…");
|
||||
(require('mongodb').MongoClient).connect(config.MONGODB_URI).then(client=>{
|
||||
global.mdbClient = client;
|
||||
console.log("Connecting to Discord…");
|
||||
dClient.login(config.DISCORD_TOKEN);
|
||||
});
|
||||
});
|
||||
|
||||
dClient.once('ready', () => {
|
||||
console.log('Discord Client Ready');
|
||||
|
||||
require('./commands.js');
|
||||
require('./colorroles.js');
|
||||
require('./mppbridger.js');
|
||||
require('./screenshotter.js');
|
||||
require('./misc.js');
|
||||
require('./commands');
|
||||
require('./colorroles');
|
||||
require('./mppbridger');
|
||||
require('./screenshotter');
|
||||
require('./misc');
|
||||
|
||||
});
|
||||
dClient.on('error', console.error);
|
||||
|
|
16
src/misc.js
16
src/misc.js
|
@ -1,22 +1,22 @@
|
|||
|
||||
|
||||
// join/leave
|
||||
(function(){
|
||||
var webhook = new Discord.WebhookClient('404736784354770958', config.webhooks.welcome);
|
||||
dClient.on('guildMemberAdd', member => {
|
||||
(async function(){
|
||||
var webhook = new Discord.WebhookClient(config.webhooks.welcome[0], config.webhooks.welcome[1]);
|
||||
dClient.on('guildMemberAdd', async member => {
|
||||
webhook.send(`${member} joined.`, {username: member.user.username, avatarURL: member.user.displayAvatarURL(), disableEveryone:true});
|
||||
});
|
||||
dClient.on('guildMemberRemove', member => {
|
||||
dClient.on('guildMemberRemove', async member => {
|
||||
webhook.send(`${member.user.tag} left.`, {username: member.user.username, avatarURL: member.user.displayAvatarURL(), disableEveryone:true});
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
// view deleted channels
|
||||
(function(){
|
||||
var vcid = '425060452129701889';
|
||||
var rid = '425060792455397376';
|
||||
dClient.on('voiceStateUpdate', (oldMember, newMember) => {
|
||||
(async function(){
|
||||
var vcid = config.channels.voice;
|
||||
var rid = config.roles.viewing_deleted_channels;
|
||||
dClient.on('voiceStateUpdate', async (oldMember, newMember) => {
|
||||
if (oldMember.voiceChannelID != vcid && newMember.voiceChannelID == vcid) {
|
||||
// member joined the channel
|
||||
newMember.roles.add(newMember.guild.roles.get(rid));
|
||||
|
|
|
@ -1,500 +0,0 @@
|
|||
var Client = require('./lib/Client.js');
|
||||
global.clients = {};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*function reconnectClients() {
|
||||
for (let site in clients) {
|
||||
site = clients[site];
|
||||
let i = 0;
|
||||
for (let client in site) {
|
||||
client = site[client];
|
||||
if (client.reconnectTimeout) clearTimeout(client.reconnectTimeout);
|
||||
client.reconnectTimeout = setTimeout(()=>{
|
||||
client.connect();
|
||||
client.reconnectTimeout = undefined;
|
||||
}, i += 2000);
|
||||
}
|
||||
}
|
||||
} //TODO BETTAH*/
|
||||
|
||||
|
||||
global.clientConnector = {
|
||||
queue: [],
|
||||
enqueue: function(client) {
|
||||
if (this.queue.includes(client)) return;
|
||||
this.queue.push(client);
|
||||
},
|
||||
interval: setInterval(function(){
|
||||
var client = clientConnector.queue.shift();
|
||||
if (client) client.connect();
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
|
||||
|
||||
global.createMPPbridge = function (room, DiscordChannelID, site = 'MPP', webhookID, webhookToken) {
|
||||
var DiscordChannel = dClient.channels.get(DiscordChannelID);
|
||||
if (!DiscordChannel) return console.error(`Couldn't bridge ${site} ${room} because Discord Channel ${DiscordChannelID} is missing!`);
|
||||
if (webhookID && webhookToken) var webhook = new Discord.WebhookClient(webhookID, webhookToken, {disableEveryone:true});
|
||||
|
||||
var msgBuffer = [];
|
||||
function _dSend(msg, embed) {
|
||||
if (webhook && !config.testmode) {
|
||||
let username = gClient.channel && gClient.channel._id || room;
|
||||
if (username.length > 32) username = username.substr(0,31) + '…';
|
||||
else if (username.length < 2) username = undefined;
|
||||
webhook.send(msg, {username, embed, split:{char:''}}).catch(e => {
|
||||
console.error(e);
|
||||
DiscordChannel.send(msg, {embed, split:{char:''}}).catch(console.error);
|
||||
});
|
||||
}
|
||||
else DiscordChannel.send(msg, {embed, split:{char:''}}).catch(console.error);
|
||||
}
|
||||
function dSend(msg) {
|
||||
msgBuffer.push(msg);
|
||||
}
|
||||
setInterval(()=>{
|
||||
if (msgBuffer.length == 0) return;
|
||||
_dSend(msgBuffer.join('\n'));
|
||||
msgBuffer = [];
|
||||
}, 2000); //TODO make changeable
|
||||
|
||||
const gClient = site == "MPP" ? new Client("ws://www.multiplayerpiano.com:443") : site == "WOPP" ? new Client("ws://ourworldofpixels.com:1234", true) : site == "MPT" ? new Client("ws://ts.terrium.net:8080", true) : site == "VFDP" ? new Client("ws://www.visualfiredev.com:8080") : undefined;
|
||||
if (!gClient) return console.error(`Invalid site ${site}`);
|
||||
gClient.setChannel(/*(site == "MPP" && room == "lobby") ? "lolwutsecretlobbybackdoor" : */room);
|
||||
gClient.canConnect = true;
|
||||
clientConnector.enqueue(gClient);
|
||||
|
||||
|
||||
|
||||
var isConnected = false;
|
||||
gClient.on('connect', () => {
|
||||
console.log(`Connected to room ${room} of ${site} server`);
|
||||
dSend(`**Connected**`); // TODO say what room it actually connected to ?
|
||||
gClient.sendArray([{m: "userset", set: {name: config.mppname}}])
|
||||
isConnected = true;
|
||||
});
|
||||
gClient.on('disconnect', () => {
|
||||
if (isConnected) {
|
||||
console.log(`Disconnected from room ${room} of ${site} server`);
|
||||
dSend(`**Disconnected**`);
|
||||
isConnected = false;
|
||||
}
|
||||
clientConnector.enqueue(gClient);
|
||||
});
|
||||
/*gClient.on('status', status => {
|
||||
console.log(`[${site}] [${room}] ${status}`);
|
||||
});*/
|
||||
|
||||
let lastCh = room;
|
||||
gClient.on('ch', msg => {
|
||||
if (lastCh && msg.ch._id !== lastCh) {
|
||||
dSend(`**Channel changed from \`${lastCh}\` to \`${msg.ch._id}\`**`);
|
||||
console.log(`[${site}][${room}] Channel changed from ${lastCh} to ${msg.ch._id}`);
|
||||
lastCh = msg.ch._id;
|
||||
}
|
||||
(async function(){
|
||||
// catch dropped crown
|
||||
if (msg.ch.crown && !msg.ch.crown.hasOwnProperty('participantId')) {
|
||||
gClient.sendArray([{m:'chown', id: gClient.getOwnParticipant().id}]); // if possible
|
||||
var avail_time = msg.ch.crown.time + 15000 - gClient.serverTimeOffset;
|
||||
var ms = avail_time - Date.now();
|
||||
setTimeout(()=> gClient.sendArray([{m:'chown', id: gClient.getOwnParticipant().id}]) , ms);
|
||||
}
|
||||
// transfer crown to owner
|
||||
if (msg.ppl && msg.ch.crown && msg.ch.crown.participantId == gClient.getOwnParticipant().id) {
|
||||
var res = await dbClient.query("SELECT owner_mpp__id FROM bridges WHERE mpp_room = $1 AND site = $2;", [room, site]);
|
||||
if (res.rows.length == 0) return;
|
||||
var owner = res.rows[0].owner_mpp__id;
|
||||
if (!owner) return;
|
||||
msg.ppl.some(part => {
|
||||
if (part._id == owner) {
|
||||
gClient.sendArray([{m:'chown', id: part.id}]);
|
||||
return true;
|
||||
} else return false;
|
||||
});
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
// MPP to Discord
|
||||
gClient.on('a', msg => {
|
||||
if (msg.p._id == gClient.getOwnParticipant()._id) return;
|
||||
var id = msg.p._id.substr(0,6);
|
||||
var name = msg.p.name.replace(/discord.gg\//g, 'discord.gg\\/');
|
||||
var str = `\`${id}\` **${name}:** ${msg.a}`;
|
||||
str = str.replace(/<@/g, "<\\@");
|
||||
dSend(str);
|
||||
});
|
||||
|
||||
// Discord to MPP
|
||||
dClient.on('message', message => {
|
||||
if (message.channel.id !== DiscordChannelID || message.author.bot || message.content.startsWith('!')) return;
|
||||
var str = message.cleanContent;
|
||||
var arr = [];
|
||||
if (str.startsWith('/') || str.startsWith('\\')) {
|
||||
arr.push({m:"a", message:
|
||||
`⤹ ${message.member.displayName}`
|
||||
});
|
||||
} else str = message.member.displayName + ': ' + str;
|
||||
if (str.startsWith('\\')) str = str.slice(1);
|
||||
if (message.attachments.first()) str += ' '+message.attachments.first().url;
|
||||
if (str.length > 512) str = str.substr(0,511) + '…';
|
||||
arr.push({m:"a", message:str});
|
||||
gClient.sendArray(arr);
|
||||
});
|
||||
|
||||
// announce join/leave
|
||||
gClient.on('participant added', participant => { //TODO universal way of filtering names
|
||||
dSend(`**\`${participant._id.substr(0,6)}\` ${participant.name.replace(/<@/g, "<\\@")} entered the room.**`);
|
||||
});
|
||||
gClient.on('participant removed', participant => {
|
||||
dSend(`**\`${participant._id.substr(0,6)}\` ${participant.name.replace(/<@/g, "<\\@")} left the room.**`);
|
||||
});
|
||||
|
||||
|
||||
/*// autoban banned participants
|
||||
gClient.on('participant added', part => {
|
||||
if (PS.banned_ppl.hasOwnProperty(part._id) && gClient.isOwner())
|
||||
gClient.sendArray([{m: "kickban", _id: part._id, ms: 60*60*1000}]);
|
||||
});*/
|
||||
|
||||
|
||||
gClient.on('notification', async msg => {
|
||||
|
||||
// show notification
|
||||
_dSend(undefined, {
|
||||
title: msg.title,
|
||||
description: msg.text || msg.html
|
||||
});
|
||||
|
||||
// ban handling
|
||||
if (msg.text && (msg.text.startsWith('Banned from') || msg.text.startsWith('Currently banned from'))) {
|
||||
// Banned from "{room}" for {n} minutes.
|
||||
// Currently banned from "{room}" for {n} minutes.
|
||||
let arr = msg.text.split(' ');
|
||||
arr.pop();
|
||||
let minutes = arr.pop();
|
||||
|
||||
gClient.stop();
|
||||
setTimeout(()=>{
|
||||
gClient.setChannel(room);
|
||||
gClient.start();
|
||||
}, minutes*60*1000+3000);
|
||||
dSend(`**Attempting to rejoin in ${minutes} minutes.**`);
|
||||
}
|
||||
});
|
||||
|
||||
gClient.on("ch", function(msg){
|
||||
if (gClient.isOwner()) {
|
||||
if (gClient.countParticipants() <= 1) {
|
||||
gClient.sendArray([{m:'chset', set: { visible: false }}])
|
||||
} else {
|
||||
gClient.sendArray([{m:'chset', set: { visible: true }}])
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// addons
|
||||
gClient.on('participant update', function(participant){
|
||||
nameCollector.collect(participant);
|
||||
});
|
||||
//if (site == 'MPP' && room == 'lobby') MPPrecorder.start(gClient);//TODO too much memory
|
||||
|
||||
// collect data
|
||||
(async function(){
|
||||
var filename = `${site} ${room} .txt`.replace(/\//g, ':');
|
||||
var size = 0;
|
||||
var startDate = new Date();
|
||||
gClient.on('ws created', function(){
|
||||
gClient.ws.addEventListener('message', msg => {
|
||||
var data = msg.data;
|
||||
if (data instanceof ArrayBuffer) data = Buffer.from(data).toString('base64');
|
||||
var line = `${Date.now()} ${data}\n`;
|
||||
size += line.length;
|
||||
fs.appendFile(filename, line, ()=>{});
|
||||
if (size > 8000000) {save(); size = 0;}
|
||||
});
|
||||
});
|
||||
async function save(callback){
|
||||
console.log(`saving data recording`, filename)
|
||||
fs.readFile(filename, (err, file) => {
|
||||
if (err) return console.error(err);
|
||||
require('zlib').gzip(file, async function(err, gzip){
|
||||
if (err) return console.error(err);
|
||||
var attachmentName = `${site} ${room} raw data recording from ${startDate.toISOString()} to ${new Date().toISOString()} .txt.gz`;
|
||||
await DiscordChannel.send(new Discord.MessageAttachment(gzip, attachmentName));
|
||||
fs.writeFileSync(filename, '');
|
||||
size = 0;
|
||||
startDate = new Date();
|
||||
console.log(`saved raw data recording`, attachmentName);
|
||||
if (callback) callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
exitHook(callback => {
|
||||
save(()=>callback());
|
||||
});
|
||||
gClient.dataCollectorSave = function(){save()}; // test
|
||||
})();
|
||||
|
||||
if (!clients[site]) clients[site] = {};
|
||||
clients[site][room] = gClient;
|
||||
|
||||
|
||||
|
||||
/*// EXPERIMENTAL
|
||||
gClient.on('ls', msg => {
|
||||
msg.u.forEach(async r => {
|
||||
if (clients[site][r._id]) return;
|
||||
for (let client of clientConnector.queue) {if (client.desiredChannelId == r._id) return} // ugg
|
||||
var discordChannelName = r._id.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();
|
||||
var categoryID = '409079939501916160';
|
||||
var channel = await dClient.guilds.get(config.guildID).createChannel(discordChannelName, {parent: categoryID});
|
||||
channel.setTopic(`Bridged to http://www.multiplayerpiano.com/${encodeURIComponent(r._id)}`);
|
||||
var webhook = await channel.createWebhook('Webhook');
|
||||
createMPPbridge(r._id, channel.id, site, webhook.id, webhook.token);
|
||||
})
|
||||
})*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
global.nameCollector = {
|
||||
collection: mdbClient.db('heroku_jrtfvpd9').collection('ppl'),
|
||||
collect: async function (participant) {
|
||||
if (config.testmode) return;
|
||||
if (participant.name == "Anonymous" || participant.name == "Anonymoose") return;
|
||||
|
||||
var newMsg = function(continued){
|
||||
var str = `__**${participant._id}**__${continued ? ' (continued)' : ''}\n${participant.name}`;
|
||||
return dClient.channels.get('379738469511069698').send(str);
|
||||
}
|
||||
|
||||
var document = await this.collection.findOne({_id: participant._id});
|
||||
|
||||
if (document) {
|
||||
// update person
|
||||
if (document.names.includes(participant.name)) return;
|
||||
document.names.push(participant.name);
|
||||
this.collection.updateOne({_id: participant._id}, {$set:{names: document.names}});
|
||||
|
||||
let message = await dClient.channels.get('379738469511069698').messages.fetch(document.discord_msg_id);
|
||||
try {
|
||||
await message.edit(message.content + ', ' + participant.name);
|
||||
} catch(e) {
|
||||
let message = await newMsg(true);
|
||||
this.collection.updateOne({_id: participant._id}, {$set:{discord_msg_id: message.id}});
|
||||
}
|
||||
} else {
|
||||
// add new person
|
||||
let message = await newMsg();
|
||||
nameCollector.collection.insertOne({
|
||||
_id: participant._id,
|
||||
discord_msg_id: message.id,
|
||||
names: [participant.name]
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
global.MPPrecorder = {
|
||||
start: function(client) {
|
||||
var recorder = (require('./lib/mpprecorder-module.js'))(undefined, client);
|
||||
this.save = async function () {
|
||||
var startDate = new Date(recorder.startTime), endDate = new Date();
|
||||
var filename = `www.multiplayerpiano.com lobby recording from ${startDate.toISOString()} to ${endDate.toISOString()} .mid.gz`;
|
||||
var file = recorder.save();
|
||||
file = Buffer.from(file, 'binary');
|
||||
file = require('zlib').gzipSync(file);
|
||||
var attachment = new Discord.MessageAttachment(file, filename);
|
||||
await dClient.channels.get('394967426133000193').send(attachment);
|
||||
}
|
||||
this.interval = setInterval(() => {
|
||||
this.save();
|
||||
}, 10*60*1000);
|
||||
exitHook(callback => {
|
||||
this.save().then(callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// start
|
||||
(async function () {
|
||||
var res = await dbClient.query('SELECT * FROM bridges;');
|
||||
|
||||
var sites = {};
|
||||
res.rows.forEach(row => {
|
||||
if (row.disabled) return;
|
||||
if (!sites[row.site]) sites[row.site] = [];
|
||||
sites[row.site].push(row);
|
||||
});
|
||||
|
||||
for (let site in sites) {
|
||||
let arr = sites[site];
|
||||
arr.sort((a, b) => {return a.position - b.position});
|
||||
let i = 0;
|
||||
arr.forEach(bridge => {
|
||||
setTimeout(function(){
|
||||
createMPPbridge(bridge.mpp_room, bridge.discord_channel_id, bridge.site, bridge.webhook_id, bridge.webhook_token, bridge.owner_mpp__id);
|
||||
}, i);
|
||||
i = i + 2000;
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// commands
|
||||
|
||||
commands.bridge = {
|
||||
usage: "<MPP room>",
|
||||
description: "Creates a bridge to the specified MPP room.",
|
||||
exec: async function (msg) {
|
||||
var site = 'MPP';
|
||||
var room = msg.txt(1);
|
||||
if (!room) return false;
|
||||
var existingBridge = (await dbClient.query('SELECT * FROM bridges WHERE mpp_room = $1;', [room])).rows[0];
|
||||
if (existingBridge) {
|
||||
if (!existingBridge.disabled) {
|
||||
return msg.reply(`${site} room ${room} is already bridged.`);
|
||||
} else {
|
||||
if (config.disabledRooms.includes(room)) {
|
||||
return msg.reply(`You cannot bridge this room.`);
|
||||
} else /* rebridge */ {
|
||||
let channel = dClient.guilds.get(config.guildID).channels.get(existingBridge.discord_channel_id);
|
||||
await dbClient.query("UPDATE bridges SET disabled = false WHERE mpp_room = $1", [room]);
|
||||
await channel.setParent('360557444952227851');
|
||||
await channel.lockPermissions();
|
||||
createMPPbridge(room, existingBridge.mpp_room, existingBridge.site, existingBridge.webhook_id, existingBridge.webhook_token);
|
||||
await msg.reply(`${site} room ${room} has been re-bridged.`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* new bridge */
|
||||
var discordChannelName = room.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();
|
||||
var categoryID = '360557444952227851';
|
||||
var channel = await dClient.guilds.get(config.guildID).channels.create(discordChannelName, {parent: categoryID});
|
||||
channel.setTopic(`http://www.multiplayerpiano.com/${encodeURIComponent(room)}`);
|
||||
var webhook = await channel.createWebhook('Webhook');
|
||||
createMPPbridge(room, channel.id, site, webhook.id, webhook.token);
|
||||
dbClient.query('INSERT INTO bridges (site, mpp_room, discord_channel_id, webhook_id, webhook_token, owner_discord_user_id) VALUES ($1, $2, $3, $4, $5, $6)', [
|
||||
site, room, channel.id, webhook.id, webhook.token, msg.author.id,
|
||||
]);
|
||||
msg.reply(`${site} room ${room} is now bridged to ${channel}.`);
|
||||
}
|
||||
};
|
||||
|
||||
commands.unbridge = {
|
||||
usage: "[MPP Room]",
|
||||
description: "Deletes a bridge to the specified MPP room.",
|
||||
exec: async function (msg) {
|
||||
var bridge = (await dbClient.query("SELECT * FROM bridges WHERE mpp_room = $1 OR discord_channel_id = $2", [msg.txt(1), msg.channel.id])).rows[0];
|
||||
if (!bridge) {
|
||||
//msg.react('⚠️');
|
||||
msg.reply(`That room is not bridged. Make sure you type the MPP room name correctly.`);
|
||||
return;
|
||||
}
|
||||
if (bridge.disabled) {
|
||||
msg.reply(`That room has already been unbridged.`);
|
||||
return;
|
||||
}
|
||||
if (!(bridge.owner_discord_user_id == msg.author.id || msg.author.id == config.opID)) {
|
||||
//msg.react('🚫');
|
||||
msg.reply(`You do not own that bridge.`);
|
||||
return;
|
||||
}
|
||||
await dbClient.query("UPDATE bridges SET disabled = 'true' WHERE mpp_room = $1", [bridge.mpp_room]);
|
||||
clients.MPP[bridge.mpp_room].stop();
|
||||
var channel = dClient.channels.get(bridge.discord_channel_id)
|
||||
await channel.setParent('451838300068511745');
|
||||
await channel.lockPermissions();
|
||||
msg.reply(`${bridge.mpp_room} has been unbridged.`);
|
||||
}
|
||||
}
|
||||
|
||||
commands.chown = {
|
||||
usage: "<'mpp'/'discord'> <Discord User ID or mention, or MPP _id>",
|
||||
description: "Changes the MPP or Discord owner of a private bridge. The first argument must be either `mpp` or `discord`.",
|
||||
aliases: ['changeowner', 'setowner'],
|
||||
exec: async function (msg) {
|
||||
if (msg.args.length < 3 || !['mpp','discord'].includes(msg.args[1])) return false;
|
||||
var res = await dbClient.query('SELECT * FROM bridges WHERE discord_channel_id = $1;', [msg.channel.id]);
|
||||
if (res.rows.length == 0) return msg.react('🚫');
|
||||
var bridge = res.rows[0];
|
||||
if (!(bridge.owner_discord_user_id == msg.author.id || msg.author.id == config.opID)) return msg.react('🚫');
|
||||
|
||||
if (msg.args[1] == 'discord') {
|
||||
let selectedUser = dClient.users.get(msg.args[2]) || msg.mentions.users.first();
|
||||
if (!selectedUser) return msg.react('⚠️');
|
||||
msg.channel.overwritePermissions(selectedUser, {
|
||||
MANAGE_CHANNELS: true,
|
||||
MANAGE_ROLES: true,
|
||||
MANAGE_WEBHOOKS: true,
|
||||
MANAGE_MESSAGES: true
|
||||
});
|
||||
let po = msg.channel.permissionOverwrites.find(x => x.id == msg.author.id);
|
||||
if (po) po.delete();
|
||||
await dbClient.query('UPDATE bridges SET owner_discord_user_id = $1 WHERE discord_channel_id = $2;', [selectedUser.id, msg.channel.id]);
|
||||
msg.channel.send(`Ownership of ${msg.channel} has been transferred to ${selectedUser}`);
|
||||
} else if (msg.args[1] == 'mpp') {
|
||||
let _id = msg.args[2];
|
||||
await dbClient.query('UPDATE bridges SET owner_mpp__id = $1 WHERE discord_channel_id = $2;', [_id, msg.channel.id]);
|
||||
msg.channel.send(`MPP user \`${_id}\` has been assigned as owner of the MPP room, and the crown will be transferred to them whenever possible.`);
|
||||
//todo give crown if owner there
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
commands.list = {
|
||||
description: "Lists online participants",
|
||||
aliases: ['ppl', 'online'],
|
||||
exec: async function (message) {
|
||||
var row = (await dbClient.query("SELECT mpp_room, site FROM bridges WHERE discord_channel_id = $1;", [message.channel.id])).rows[0];
|
||||
if (!row) {
|
||||
//message.react('🚫');
|
||||
message.reply(`Use this in a bridged room to see who is at the other side.`);
|
||||
return;
|
||||
}
|
||||
var ppl = clients[row.site][row.mpp_room].ppl;
|
||||
|
||||
var numberOfPpl = Object.keys(ppl).length;
|
||||
var str = `__**Participants Online (${numberOfPpl})**__\n`;
|
||||
var names = [];
|
||||
for (let person in ppl) {
|
||||
person = ppl[person];
|
||||
names.push(`\`${person._id.substr(0,6)}\` ${person.name.replace(/<@/g, "<\\@")}`);
|
||||
}
|
||||
str += names.join(', ');
|
||||
message.channel.send(str, {split:{char:''}});
|
||||
}
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
module.exports = {
|
||||
usage: "<MPP user id>",
|
||||
description: "Adds a perma-ban on the user",
|
||||
aliases: ["permaban"],
|
||||
exec: async function (msg) {
|
||||
if (!msg.args[1]) return "EBADUSG";
|
||||
var res = await dbClient.query('SELECT * FROM bridges WHERE discord_channel_id = $1;', [msg.channel.id]);
|
||||
if (!res.rows.length) return "ENOTBRIDGE"
|
||||
var bridge = res.rows[0];
|
||||
if (bridge.owner_discord_user_id != msg.author.id) return msg.reply(`You are not the owner of this bridge.`);
|
||||
var _id = msg.txt(1);
|
||||
await dbClient.query("UPDATE bridges SET bans = array_append(bans, $1) WHERE discord_channel_id = $2", [_id, msg.channel.id]);
|
||||
await msg.reply(`OK, I'll ban anyone whose user ID equals or starts with \`${_id}\` from this room, whenever possible.`);
|
||||
|
||||
var client = clients.MPP[bridge.mpp_room]
|
||||
for (let p in client.ppl) {
|
||||
p = client.ppl[p]
|
||||
if (p._id.startsWith(_id))
|
||||
client.sendArray([{m:'kickban', _id, ms: 60*60*1000}])
|
||||
}
|
||||
|
||||
if (_id.length != 24) await msg.reply(":warning: The ID you gave me does not look like a full user ID (it is not 24 chars long). If it's a truncated ID it will still work, however it could possibly ban someone else whose user ID starts with those chars.")
|
||||
|
||||
},
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
module.exports = {
|
||||
usage: "<MPP room>",
|
||||
description: "Creates a bridge to the specified MPP room.",
|
||||
exec: async function (msg) {
|
||||
var site = 'MPP';
|
||||
var room = msg.txt(1);
|
||||
if (!room) return "EBADUSG";
|
||||
var existingBridge = (await dbClient.query('SELECT * FROM bridges WHERE mpp_room = $1;', [room])).rows[0];
|
||||
if (existingBridge) {
|
||||
if (!existingBridge.disabled) {
|
||||
return msg.reply(`${site} room ${room} is already bridged.`);
|
||||
} else {
|
||||
if (config.disabledRooms.includes(room)) {
|
||||
return msg.reply(`You cannot bridge this room.`);
|
||||
} else /* rebridge */ {
|
||||
let channel = dClient.guilds.get(config.guildID).channels.get(existingBridge.discord_channel_id);
|
||||
await dbClient.query("UPDATE bridges SET disabled = false WHERE mpp_room = $1", [room]);
|
||||
await channel.setParent();
|
||||
await channel.lockPermissions();
|
||||
createMPPbridge(room, existingBridge.mpp_room, existingBridge.site, existingBridge.webhook_id, existingBridge.webhook_token);
|
||||
await msg.reply(`${site} room ${room} has been re-bridged.`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* new bridge */
|
||||
var discordChannelName = room.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();
|
||||
var categoryID = config.channels.mpp_bridges;
|
||||
var channel = await dClient.guilds.get(config.guildID).channels.create(discordChannelName, {parent: categoryID});
|
||||
channel.setTopic(`http://www.multiplayerpiano.com/${encodeURIComponent(room)}`);
|
||||
var webhook = await channel.createWebhook('Webhook');
|
||||
createMPPbridge(room, channel.id, site, webhook.id, webhook.token);
|
||||
dbClient.query('INSERT INTO bridges (site, mpp_room, discord_channel_id, webhook_id, webhook_token, owner_discord_user_id) VALUES ($1, $2, $3, $4, $5, $6)', [
|
||||
site, room, channel.id, webhook.id, webhook.token, msg.author.id,
|
||||
]);
|
||||
msg.reply(`${site} room ${room} is now bridged to ${channel}.`);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
module.exports = {
|
||||
usage: "<'mpp'/'discord'> <Discord User ID or mention, or MPP _id>",
|
||||
description: "Changes the MPP or Discord owner of a private bridge. The first argument must be either `mpp` or `discord`.",
|
||||
aliases: ['changeowner', 'setowner'],
|
||||
exec: async function (msg) {
|
||||
if (msg.args.length < 3 || !['mpp','discord'].includes(msg.args[1])) return "EBADUSG";
|
||||
var res = await dbClient.query('SELECT * FROM bridges WHERE discord_channel_id = $1;', [msg.channel.id]);
|
||||
if (res.rows.length == 0) return msg.react('🚫');
|
||||
var bridge = res.rows[0];
|
||||
if (!(bridge.owner_discord_user_id == msg.author.id || msg.author.id == config.opID)) return msg.react('🚫');
|
||||
|
||||
if (msg.args[1] == 'discord') {
|
||||
let selectedUser = dClient.users.get(msg.args[2]) || msg.mentions.users.first();
|
||||
if (!selectedUser) return msg.react('⚠️');
|
||||
msg.channel.overwritePermissions(selectedUser, {
|
||||
MANAGE_CHANNELS: true,
|
||||
MANAGE_ROLES: true,
|
||||
MANAGE_WEBHOOKS: true,
|
||||
MANAGE_MESSAGES: true
|
||||
});
|
||||
let po = msg.channel.permissionOverwrites.find(x => x.id == msg.author.id);
|
||||
if (po) po.delete();
|
||||
await dbClient.query('UPDATE bridges SET owner_discord_user_id = $1 WHERE discord_channel_id = $2;', [selectedUser.id, msg.channel.id]);
|
||||
msg.channel.send(`Ownership of ${msg.channel} has been transferred to ${selectedUser}`);
|
||||
} else if (msg.args[1] == 'mpp') {
|
||||
let _id = msg.args[2];
|
||||
await dbClient.query('UPDATE bridges SET owner_mpp__id = $1 WHERE discord_channel_id = $2;', [_id, msg.channel.id]);
|
||||
msg.channel.send(`MPP user \`${_id}\` has been assigned as owner of the MPP room, and the crown will be transferred to them whenever possible.`);
|
||||
//todo give crown if owner there
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
module.exports = {
|
||||
description: "Lists online participants",
|
||||
aliases: ['ppl', 'online'],
|
||||
exec: async function (message) {
|
||||
var row = (await dbClient.query("SELECT mpp_room, site FROM bridges WHERE discord_channel_id = $1;", [message.channel.id])).rows[0];
|
||||
if (!row) {
|
||||
//message.react('🚫');
|
||||
message.reply(`Use this in a bridged room to see who is at the other side.`);
|
||||
return;
|
||||
}
|
||||
var ppl = clients[row.site][row.mpp_room].ppl;
|
||||
|
||||
var numberOfPpl = Object.keys(ppl).length;
|
||||
var str = `__**Participants Online (${numberOfPpl})**__\n`;
|
||||
var names = [];
|
||||
for (let person in ppl) {
|
||||
person = ppl[person];
|
||||
names.push(`\`${person._id.substr(0,6)}\` ${person.name.replace(/<@/g, "<\\@")}`);
|
||||
}
|
||||
str += names.join(', ');
|
||||
message.channel.send(str, {split:{char:''}});
|
||||
}
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
module.exports = {
|
||||
usage: "[MPP Room]",
|
||||
description: "Deletes a bridge to the specified MPP room.",
|
||||
exec: async function (msg) {
|
||||
var bridge = (await dbClient.query("SELECT * FROM bridges WHERE mpp_room = $1 OR discord_channel_id = $2", [msg.txt(1), msg.channel.id])).rows[0];
|
||||
if (!bridge) {
|
||||
//msg.react('⚠️');
|
||||
msg.reply(`That room is not bridged. Make sure you type the MPP room name correctly.`);
|
||||
return;
|
||||
}
|
||||
if (bridge.disabled) {
|
||||
msg.reply(`That room has already been unbridged.`);
|
||||
return;
|
||||
}
|
||||
if (!(bridge.owner_discord_user_id == msg.author.id || msg.author.id == config.opID)) {
|
||||
//msg.react('🚫');
|
||||
msg.reply(`You do not own that bridge.`);
|
||||
return;
|
||||
}
|
||||
await dbClient.query("UPDATE bridges SET disabled = 'true' WHERE mpp_room = $1", [bridge.mpp_room]);
|
||||
clients.MPP[bridge.mpp_room].stop();
|
||||
var channel = dClient.channels.get(bridge.discord_channel_id)
|
||||
await channel.setParent(config.channels.deleted_bridges);
|
||||
await channel.lockPermissions();
|
||||
msg.reply(`${bridge.mpp_room} has been unbridged.`);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
module.exports = async function(gClient, site, room, DiscordChannel) {
|
||||
var path = require('os').tmpdir();
|
||||
var filename = `${site} ${room} .txt`.replace(/\//g, ':');
|
||||
var filepath = path + "/" + filename;
|
||||
var size = 0;
|
||||
var startDate = new Date();
|
||||
gClient.on('ws created', function(){
|
||||
gClient.ws.addEventListener('message', msg => {
|
||||
var data = msg.data;
|
||||
if (data instanceof ArrayBuffer) data = Buffer.from(data).toString('base64');
|
||||
var line = `${Date.now()} ${data}\n`;
|
||||
size += line.length;
|
||||
fs.appendFile(filepath, line, ()=>{});
|
||||
if (size > 8000000) {save(); size = 0;}
|
||||
});
|
||||
});
|
||||
async function save(callback){
|
||||
console.log(`saving data recording`, filename)
|
||||
fs.readFile(filepath, (err, file) => {
|
||||
if (err) return console.error(err);
|
||||
require('zlib').gzip(file, async function(err, gzip){
|
||||
if (err) return console.error(err);
|
||||
var attachmentName = `${site} ${room} raw data recording from ${startDate.toISOString()} to ${new Date().toISOString()} .txt.gz`;
|
||||
await DiscordChannel.send(new Discord.MessageAttachment(gzip, attachmentName));
|
||||
fs.writeFileSync(filepath, '');
|
||||
size = 0;
|
||||
startDate = new Date();
|
||||
console.log(`saved raw data recording`, attachmentName);
|
||||
if (callback) callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
exitHook(callback => {
|
||||
save(()=>callback());
|
||||
});
|
||||
gClient.dataCollectorSave = function(){save()}; // test
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
var Client = require('../lib/Client.js');
|
||||
global.clients = {};
|
||||
|
||||
|
||||
|
||||
global.clientConnector = {
|
||||
queue: [],
|
||||
enqueue: function(client) {
|
||||
if (this.queue.includes(client)) return;
|
||||
this.queue.push(client);
|
||||
},
|
||||
interval: setInterval(function(){
|
||||
var client = clientConnector.queue.shift();
|
||||
if (client) client.connect();
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
|
||||
|
||||
global.createMPPbridge = function createMPPbridge(room, DiscordChannelID, site = 'MPP', webhookID, webhookToken) {
|
||||
var DiscordChannel = dClient.channels.get(DiscordChannelID);
|
||||
if (!DiscordChannel) return console.error(`Couldn't bridge ${site} ${room} because Discord Channel ${DiscordChannelID} is missing!`);
|
||||
if (webhookID && webhookToken) var webhook = new Discord.WebhookClient(webhookID, webhookToken, {disableEveryone:true});
|
||||
|
||||
|
||||
// discord message sending
|
||||
var msgBuffer = [];
|
||||
function _dSend(msg, embed) {
|
||||
if (webhook && !config.testmode) {
|
||||
let username = gClient.channel && gClient.channel._id || room;
|
||||
if (username.length > 32) username = username.substr(0,31) + '…';
|
||||
else if (username.length < 2) username = undefined;
|
||||
webhook.send(msg, {username, embed, split:{char:''}}).catch(e => {
|
||||
console.error(e);
|
||||
DiscordChannel.send(msg, {embed, split:{char:''}}).catch(console.error);
|
||||
});
|
||||
}
|
||||
else DiscordChannel.send(msg, {embed, split:{char:''}}).catch(console.error);
|
||||
}
|
||||
function dSend(msg) {
|
||||
msgBuffer.push(msg);
|
||||
}
|
||||
setInterval(()=>{
|
||||
if (msgBuffer.length == 0) return;
|
||||
_dSend(msgBuffer.join('\n'));
|
||||
msgBuffer = [];
|
||||
}, 2000); //TODO make changeable
|
||||
|
||||
|
||||
|
||||
|
||||
const gClient =
|
||||
site == "MPP" ? new Client("ws://www.multiplayerpiano.com:443") :
|
||||
site == "WOPP" ? new Client("ws://ourworldofpixels.com:1234") :
|
||||
site == "MPT" ? new Client("ws://ts.terrium.net:8080") :
|
||||
site == "VFDP" ? new Client("ws://www.visualfiredev.com:8080") :
|
||||
undefined;
|
||||
if (!gClient) return console.error(`Invalid site ${site}`);
|
||||
gClient.setChannel(/*(site == "MPP" && room == "lobby") ? "lolwutsecretlobbybackdoor" : */room);
|
||||
gClient.canConnect = true;
|
||||
clientConnector.enqueue(gClient);
|
||||
|
||||
|
||||
|
||||
|
||||
var isConnected = false;
|
||||
gClient.on('connect', () => {
|
||||
console.log(`Connected to room ${room} of ${site} server`);
|
||||
dSend(`**Connected**`); // TODO say what room it actually connected to ?
|
||||
isConnected = true;
|
||||
});
|
||||
gClient.on('hi', ()=>{
|
||||
if (!testmode) gClient.sendArray([{m: "userset", set: {name: config.mppname}}])
|
||||
});
|
||||
gClient.on('disconnect', () => {
|
||||
if (isConnected) {
|
||||
console.log(`Disconnected from room ${room} of ${site} server`);
|
||||
dSend(`**Disconnected**`);
|
||||
isConnected = false;
|
||||
}
|
||||
clientConnector.enqueue(gClient);
|
||||
});
|
||||
/*gClient.on('status', status => {
|
||||
console.log(`[${site}] [${room}] ${status}`);
|
||||
});*/
|
||||
|
||||
|
||||
|
||||
|
||||
let lastCh = room;
|
||||
gClient.on('ch', msg => {
|
||||
// announce channel change
|
||||
if (lastCh && msg.ch._id !== lastCh) {
|
||||
dSend(`**Channel changed from \`${lastCh}\` to \`${msg.ch._id}\`**`);
|
||||
console.log(`[${site}][${room}] Channel changed from ${lastCh} to ${msg.ch._id}`);
|
||||
lastCh = msg.ch._id;
|
||||
}
|
||||
(async function(){
|
||||
// catch dropped crown
|
||||
if (msg.ch.crown && !msg.ch.crown.hasOwnProperty('participantId')) {
|
||||
gClient.sendArray([{m:'chown', id: gClient.getOwnParticipant().id}]); // if possible
|
||||
var avail_time = msg.ch.crown.time + 15000 - gClient.serverTimeOffset;
|
||||
var ms = avail_time - Date.now();
|
||||
setTimeout(()=> gClient.sendArray([{m:'chown', id: gClient.getOwnParticipant().id}]) , ms);
|
||||
}
|
||||
// transfer crown to owner
|
||||
if (msg.ppl && msg.ch.crown && msg.ch.crown.participantId == gClient.getOwnParticipant().id) {
|
||||
var res = await dbClient.query("SELECT owner_mpp__id FROM bridges WHERE mpp_room = $1 AND site = $2;", [room, site]);
|
||||
if (res.rows.length == 0) return;
|
||||
var owner = res.rows[0].owner_mpp__id;
|
||||
if (!owner) return;
|
||||
msg.ppl.some(part => {
|
||||
if (part._id == owner) {
|
||||
gClient.sendArray([{m:'chown', id: part.id}]);
|
||||
return true;
|
||||
} else return false;
|
||||
});
|
||||
}
|
||||
})();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// MPP to Discord
|
||||
gClient.on('a', msg => {
|
||||
if (msg.p._id == gClient.getOwnParticipant()._id) return;
|
||||
var id = msg.p._id.substr(0,6);
|
||||
var name = msg.p.name.replace(/discord.gg\//g, 'discord.gg\\/');
|
||||
var str = `\`${id}\` **${name}:** ${msg.a}`;
|
||||
str = str.replace(/<@/g, "<\\@");
|
||||
dSend(str);
|
||||
});
|
||||
|
||||
// Discord to MPP
|
||||
dClient.on('message', message => {
|
||||
if (message.channel.id !== DiscordChannelID || message.author.bot || message.content.startsWith('!')) return;
|
||||
var str = message.cleanContent;
|
||||
var arr = [];
|
||||
if (str.startsWith('/') || str.startsWith('\\')) {
|
||||
arr.push({m:"a", message:
|
||||
`⤹ ${message.member.displayName}`
|
||||
});
|
||||
} else str = message.member.displayName + ': ' + str;
|
||||
if (str.startsWith('\\')) str = str.slice(1);
|
||||
if (message.attachments.first()) str += ' '+message.attachments.first().url;
|
||||
if (str.length > 512) str = str.substr(0,511) + '…';
|
||||
arr.push({m:"a", message:str});
|
||||
gClient.sendArray(arr);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// announce join/leave
|
||||
gClient.on('participant added', participant => {
|
||||
dSend(`**\`${participant._id.substr(0,6)}\` ${participant.name.replace(/<@/g, "<\\@")} entered the room.**`);
|
||||
});
|
||||
gClient.on('participant removed', participant => {
|
||||
dSend(`**\`${participant._id.substr(0,6)}\` ${participant.name.replace(/<@/g, "<\\@")} left the room.**`);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
gClient.on('notification', async msg => {
|
||||
// show notification
|
||||
_dSend(undefined, {
|
||||
title: msg.title,
|
||||
description: msg.text || msg.html
|
||||
});
|
||||
|
||||
// handle bans
|
||||
if (msg.text && (msg.text.startsWith('Banned from') || msg.text.startsWith('Currently banned from'))) {
|
||||
// Banned from "{room}" for {n} minutes.
|
||||
// Currently banned from "{room}" for {n} minutes.
|
||||
let arr = msg.text.split(' ');
|
||||
arr.pop();
|
||||
let minutes = arr.pop();
|
||||
|
||||
gClient.stop();
|
||||
setTimeout(()=>{
|
||||
gClient.setChannel(room);
|
||||
gClient.start();
|
||||
}, minutes*60*1000+3000);
|
||||
dSend(`**Attempting to rejoin in ${minutes} minutes.**`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// autoban perma-banned users
|
||||
gClient.on("participant added", async part => {
|
||||
var bans = (await dbClient.query("SELECT bans FROM bridges WHERE discord_channel_id = $1", [DiscordChannelID])).rows[0].bans;
|
||||
if (!bans) return;
|
||||
for (let b of bans)
|
||||
if (part._id.startsWith(b))
|
||||
gClient.sendArray([{m: "kickban", _id: part._id, ms: 60*60*1000}]);
|
||||
})
|
||||
|
||||
|
||||
|
||||
// make room invisible when nobody else is in it
|
||||
gClient.on("ch", function(msg){
|
||||
if (gClient.isOwner()) {
|
||||
if (gClient.countParticipants() <= 1) {
|
||||
gClient.sendArray([{m:'chset', set: { visible: false }}])
|
||||
} else {
|
||||
gClient.sendArray([{m:'chset', set: { visible: true }}])
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// addons
|
||||
{
|
||||
// collect names
|
||||
gClient.on('participant update', function(participant){
|
||||
require('./namecollector').collect(participant);
|
||||
});
|
||||
// record raw data
|
||||
require('./datacollector')(gClient, site, room, DiscordChannel);
|
||||
}
|
||||
|
||||
if (!clients[site]) clients[site] = {};
|
||||
clients[site][room] = gClient;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// start
|
||||
(async function () {
|
||||
var res = await dbClient.query('SELECT * FROM bridges;');
|
||||
|
||||
var sites = {};
|
||||
res.rows.forEach(row => {
|
||||
if (row.disabled) return;
|
||||
if (!sites[row.site]) sites[row.site] = [];
|
||||
sites[row.site].push(row);
|
||||
});
|
||||
|
||||
for (let site in sites) {
|
||||
let arr = sites[site];
|
||||
arr.sort((a, b) => {return a.position - b.position});
|
||||
let i = 0;
|
||||
arr.forEach(bridge => {
|
||||
setTimeout(function(){
|
||||
createMPPbridge(bridge.mpp_room, bridge.discord_channel_id, bridge.site, bridge.webhook_id, bridge.webhook_token, bridge.owner_mpp__id);
|
||||
}, i);
|
||||
i = i + 2000;
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// commands
|
||||
commands.bridge = require('./commands/bridge');
|
||||
commands.unbridge = require('./commands/unbridge');
|
||||
commands.chown = require('./commands/chown');
|
||||
commands.list = require('./commands/list');
|
||||
commands.ban = require('./commands/ban');
|
|
@ -0,0 +1,37 @@
|
|||
var nameCollector = module.exports = {
|
||||
collection: mdbClient.db('heroku_jrtfvpd9').collection('ppl'),
|
||||
collect: async function (participant) {
|
||||
if (config.testmode) return;
|
||||
if (participant.name == "Anonymous" || participant.name == "Anonymoose") return;
|
||||
|
||||
var newMsg = function(continued){
|
||||
var str = `__**${participant._id}**__${continued ? ' (continued)' : ''}\n${participant.name}`;
|
||||
return dClient.channels.get(config.channels.name_collection).send(str);
|
||||
}
|
||||
|
||||
var document = await this.collection.findOne({_id: participant._id});
|
||||
|
||||
if (document) {
|
||||
// update person
|
||||
if (document.names.includes(participant.name)) return;
|
||||
document.names.push(participant.name);
|
||||
this.collection.updateOne({_id: participant._id}, {$set:{names: document.names}});
|
||||
|
||||
let message = await dClient.channels.get(config.channels.name_collection).messages.fetch(document.discord_msg_id);
|
||||
try {
|
||||
await message.edit(message.content + ', ' + participant.name);
|
||||
} catch(e) {
|
||||
let message = await newMsg(true);
|
||||
this.collection.updateOne({_id: participant._id}, {$set:{discord_msg_id: message.id}});
|
||||
}
|
||||
} else {
|
||||
// add new person
|
||||
let message = await newMsg();
|
||||
nameCollector.collection.insertOne({
|
||||
_id: participant._id,
|
||||
discord_msg_id: message.id,
|
||||
names: [participant.name]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,14 +11,14 @@ global.screenshotter = {
|
|||
var screenshot = await page.screenshot({type: 'png'});
|
||||
var filename = `Screenshot of www.multiplayerpiano.com/lobby @ ${new Date().toISOString()}.png`;
|
||||
var attachment = new Discord.MessageAttachment(screenshot, filename);
|
||||
await dClient.channels.get('383773548810076163').send(attachment);
|
||||
await dClient.channels.get(config.channels.mpp_screenshot).send(attachment);
|
||||
await page.goto('http://ourworldofpixels.com');
|
||||
await page.evaluate(function(){OWOP.camera.zoom = 1;});
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
var screenshot = await page.screenshot({type: 'png'});
|
||||
var filename = `Screenshot of ourworldofpixels.com/main @ ${new Date().toISOString()}.png`;
|
||||
var attachment = new Discord.MessageAttachment(screenshot, filename);
|
||||
await dClient.channels.get('399079481161023492').send(attachment);
|
||||
await dClient.channels.get(config.channels.owop_screenshot).send(attachment);
|
||||
await browser.close();
|
||||
console.log('Finished screen captures');
|
||||
},
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
process.on('unhandledRejection', error => {
|
||||
console.error(error.stack);
|
||||
});
|
||||
process.on('uncaughtException', error => {
|
||||
console.error(error.stack);
|
||||
});
|
||||
|
||||
Array.prototype.random = function () {
|
||||
return this[Math.floor(Math.random() * this.length)]
|
||||
}
|
Loading…
Reference in New Issue