mirror of
https://github.com/ION606/selmerBot.git
synced 2026-05-15 05:36:54 +00:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a190a250a6 | |||
| fcd96c930a | |||
| 52d1119842 | |||
| 08a49e6149 | |||
| d3f2085813 | |||
| 27fecfffcb | |||
| af8f9f69ae | |||
| 07f41f5ece | |||
| 1cd968b9e2 | |||
| 3f2e9c6c53 | |||
| 62ea3ecec8 | |||
| 9de7eecdd9 | |||
| b7d51c2d14 | |||
| d8d4bbea56 | |||
| a596d18eeb | |||
| 14dd4e002a | |||
| 6d8aa991b6 | |||
| b55e669df2 | |||
| 23f91591cd | |||
| fb87d33bd9 | |||
| 0b13f6db29 | |||
| 4e1214a312 | |||
| 03d0b136e1 | |||
| 34bbd823ab | |||
| b9c4caa608 | |||
| 5a17e3811f | |||
| 6ceb8cb381 | |||
| 373d57de2e | |||
| 919a7f62dc | |||
| e03b689d6d | |||
| 1d30414304 | |||
| 0d3935d5c6 | |||
| af5b206652 | |||
| 3b464aecbf | |||
| 374ecbffea | |||
| d8ca1d5055 | |||
| ae63a93940 | |||
| f122f84a0c | |||
| 29e42c745e | |||
| 388c65c6dc | |||
| eb828a59c0 | |||
| a1df043f86 | |||
| e23f238c89 |
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"cookie": {
|
|
||||||
"GPS": "1",
|
|
||||||
"Domain": ".youtube.com",
|
|
||||||
"Expires": "Thu, 27-Oct-2022 17:51:25 GMT",
|
|
||||||
"Path": "/",
|
|
||||||
"YSC": "AlW2Krsd2Ek",
|
|
||||||
"SameSite": "none",
|
|
||||||
"VISITOR_INFO1_LIVE": "_eP8T2zceRQ"
|
|
||||||
},
|
|
||||||
"file": true
|
|
||||||
}
|
|
||||||
+2
-2
@@ -4,5 +4,5 @@ config.json
|
|||||||
*.sqlite
|
*.sqlite
|
||||||
*.txt
|
*.txt
|
||||||
!spec/LevelsXP.txt
|
!spec/LevelsXP.txt
|
||||||
database.sqlite
|
*.sqlite
|
||||||
temp.js
|
temp.js
|
||||||
+151
-144
@@ -2,150 +2,157 @@ let d = new Date();
|
|||||||
const START = d.getTime();
|
const START = d.getTime();
|
||||||
|
|
||||||
|
|
||||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
resetShop = false;
|
||||||
const mongouri = process.env.MONGODB_URI; //DO NOT RUN LOCALLY (no process.env)
|
|
||||||
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
|
||||||
let collectiontemp;
|
|
||||||
client.connect(err => {
|
|
||||||
collectiontemp = client.db("main").collection("shop");
|
|
||||||
// perform actions on the collection object
|
|
||||||
collectiontemp.insertMany(
|
|
||||||
[
|
|
||||||
{ name: 'Grapes', cost: 2, icon: '🍇', sect: 'Food' },
|
|
||||||
{ name: 'Melon', cost: 5, icon: '🍈', sect: 'Food' },
|
|
||||||
{ name: 'Watermelon', cost: 5, icon: '🍉', sect: 'Food' },
|
|
||||||
{ name: 'Tangerine', cost: 3, icon: '🍊', sect: 'Food' },
|
|
||||||
{ name: 'Lemon', cost: 3, icon: '🍋', sect: 'Food' },
|
|
||||||
{ name: 'Banana', cost: 4, icon: '🍌', sect: 'Food' },
|
|
||||||
{ name: 'Pineapple', cost: 4, icon: '🍍', sect: 'Food' },
|
|
||||||
{ name: 'Mango', cost: 3, icon: '🥭', sect: 'Food' },
|
|
||||||
{ name: 'Red Apple', cost: 3, icon: '🍎', sect: 'Food' },
|
|
||||||
{ name: 'Green Apple', cost: 3, icon: '🍏', sect: 'Food' },
|
|
||||||
{ name: 'Pear', cost: 3, icon: '🍐', sect: 'Food' },
|
|
||||||
{ name: 'Peach', cost: 3, icon: '🍑', sect: 'Food' },
|
|
||||||
{ name: 'Cherries', cost: 4, icon: '🍒', sect: 'Food' },
|
|
||||||
{ name: 'Strawberry', cost: 3, icon: '🍓', sect: 'Food' },
|
|
||||||
{ name: 'Blueberries', cost: 3, icon: '🫐', sect: 'Food' },
|
|
||||||
{ name: 'Kiwi', cost: 3, icon: '🥝', sect: 'Food' },
|
|
||||||
{ name: 'Tomato', cost: 4, icon: '🍅', sect: 'Food' },
|
|
||||||
{ name: 'Olive', cost: 4, icon: '🫒', sect: 'Food' },
|
|
||||||
{ name: 'Coconut', cost: 3, icon: '🥥', sect: 'Food' },
|
|
||||||
{ name: 'Avocado', cost: 3, icon: '🥑', sect: 'Food' },
|
|
||||||
{ name: 'Eggplant', cost: 10, icon: '🍆', sect: 'Food' },
|
|
||||||
{ name: 'Potato', cost: 3, icon: '🥔', sect: 'Food' },
|
|
||||||
{ name: 'Carrot', cost: 3, icon: '🥕', sect: 'Food' },
|
|
||||||
{ name: 'Ear of Corn', cost: 3, icon: '🌽', sect: 'Food' },
|
|
||||||
{ name: 'Hot Pepper', cost: 3, icon: '🌶️', sect: 'Food' },
|
|
||||||
{ name: 'Bell Pepper', cost: 3, icon: '🫑', sect: 'Food' },
|
|
||||||
{ name: 'Cucumber', cost: 3, icon: '🥒', sect: 'Food' },
|
|
||||||
{ name: 'Leafy Green', cost: 3, icon: '🥬', sect: 'Food' },
|
|
||||||
{ name: 'Broccoli', cost: 2, icon: '🥦', sect: 'Food' },
|
|
||||||
{ name: 'Garlic', cost: 3, icon: '🧄', sect: 'Food' },
|
|
||||||
{ name: 'Onion', cost: 3, icon: '🧅', sect: 'Food' },
|
|
||||||
{ name: 'Mushroom', cost: 3, icon: '🍄', sect: 'Food' },
|
|
||||||
{ name: 'Peanuts', cost: 4, icon: '🥜', sect: 'Food' },
|
|
||||||
{ name: 'Chestnut', cost: 3, icon: '🌰', sect: 'Food' },
|
|
||||||
{ name: 'Bread', cost: 5, icon: '🍞', sect: 'Food' },
|
|
||||||
{ name: 'Croissant', cost: 7, icon: '🥐', sect: 'Food' },
|
|
||||||
{ name: 'Baguette Bread', cost: 10, icon: '🥖', sect: 'Food' },
|
|
||||||
{ name: 'Flatbread', cost: 9, icon: '🫓', sect: 'Food' },
|
|
||||||
{ name: 'Pretzel', cost: 5, icon: '🥨', sect: 'Food' },
|
|
||||||
{ name: 'Bagel', cost: 4, icon: '🥯', sect: 'Food' },
|
|
||||||
{ name: 'Pancakes', cost: 5, icon: '🥞', sect: 'Food' },
|
|
||||||
{ name: 'Waffle', cost: 5, icon: '🧇', sect: 'Food' },
|
|
||||||
{ name: 'Cheese Wedge', cost: 3, icon: '🧀', sect: 'Food' },
|
|
||||||
{ name: 'Meat on the Bone', cost: 5, icon: '🍖', sect: 'Food' },
|
|
||||||
{ name: 'Checken Leg', cost: 5, icon: '🍗', sect: 'Food' },
|
|
||||||
{ name: 'Cut of Meat', cost: 4, icon: '🥩', sect: 'Food' },
|
|
||||||
{ name: 'Bacon', cost: 4, icon: '🥓', sect: 'Food' },
|
|
||||||
{ name: 'Hamburger', cost: 5, icon: '🍔', sect: 'Food' },
|
|
||||||
{ name: 'French Fries', cost: 3, icon: '🍟', sect: 'Food' },
|
|
||||||
{ name: 'Pizza', cost: 6, icon: '🍕', sect: 'Food' },
|
|
||||||
{ name: 'Hot Dog', cost: 3, icon: '🌭', sect: 'Food' },
|
|
||||||
{ name: 'Sandwich', cost: 3, icon: '🥪', sect: 'Food' },
|
|
||||||
{ name: 'Taco', cost: 3, icon: '🌮', sect: 'Food' },
|
|
||||||
{ name: 'Burrito', cost: 5, icon: '🌯', sect: 'Food' },
|
|
||||||
{ name: 'Tamale', cost: 5, icon: '🫔', sect: 'Food' },
|
|
||||||
{ name: 'Stuffed Flatbread', cost: 5, icon: '🥙', sect: 'Food' },
|
|
||||||
{ name: 'Falafel', cost: 4, icon: '🧆', sect: 'Food' },
|
|
||||||
{ name: 'Egg', cost: 3, icon: '🥚', sect: 'Food' },
|
|
||||||
{ name: 'Hot Pot', cost: 12, icon: '🍲', sect: 'Food' },
|
|
||||||
{ name: 'Fondue', cost: 8, icon: '🫕', sect: 'Food' },
|
|
||||||
{ name: 'Green Salad', cost: 3, icon: '🥗', sect: 'Food' },
|
|
||||||
{ name: 'Popcorn', cost: 3, icon: '🍿', sect: 'Food' },
|
|
||||||
{ name: 'Butter', cost: 2, icon: '🧈', sect: 'Food' },
|
|
||||||
{ name: 'Salt', cost: 2, icon: '🧂', sect: 'Food' },
|
|
||||||
{ name: 'Canned Food', cost: 3, icon: '🥫', sect: 'Food' },
|
|
||||||
{ name: 'Bento Box', cost: 7, icon: '🍱', sect: 'Food' },
|
|
||||||
{ name: 'Rice Cracker', cost: 1, icon: '🍘', sect: 'Food' },
|
|
||||||
{ name: 'Rice Ball', cost: 3, icon: '🍙', sect: 'Food' },
|
|
||||||
{ name: 'Cooked Rice', cost: 3, icon: '🍚', sect: 'Food' },
|
|
||||||
{ name: 'Curry Rice', cost: 4, icon: '🍛', sect: 'Food' },
|
|
||||||
{ name: 'Ramen', cost: 4, icon: '🍜', sect: 'Food' },
|
|
||||||
{ name: 'Spaghetti', cost: 5, icon: '🍝', sect: 'Food' },
|
|
||||||
{ name: 'Roasted Sweet Potato', cost: 3, icon: '🍠', sect: 'Food' },
|
|
||||||
{ name: 'Oden', cost: 3, icon: '🍢', sect: 'Food' },
|
|
||||||
{ name: 'Sushi', cost: 4, icon: '🍣', sect: 'Food' },
|
|
||||||
{ name: 'Fried Shrimp', cost: 3, icon: '🍤', sect: 'Food' },
|
|
||||||
{ name: 'Fish Cake', cost: 3, icon: '🍥', sect: 'Food' },
|
|
||||||
{ name: 'Moon Cake', cost: 3, icon: '🥮', sect: 'Food' },
|
|
||||||
{ name: 'Dango', cost: 3, icon: '🍡', sect: 'Food' },
|
|
||||||
{ name: 'Dumpling', cost: 3, icon: '🥟', sect: 'Food' },
|
|
||||||
{ name: 'Fortune Cookie', cost: 3, icon: '🥠', sect: 'Food' },
|
|
||||||
{ name: 'Oyster', cost: 4, icon: '🦪', sect: 'Food' },
|
|
||||||
{ name: 'Ice Cream Cone', cost: 3, icon: '🍦', sect: 'Food' },
|
|
||||||
{ name: 'Shaved Ice', cost: 3, icon: '🍧', sect: 'Food' },
|
|
||||||
{ name: 'Ice Cream', cost: 3, icon: '🍨', sect: 'Food' },
|
|
||||||
{ name: 'Doughnut', cost: 3, icon: '🍩', sect: 'Food' },
|
|
||||||
{ name: 'Cookie', cost: 3, icon: '🍪', sect: 'Food' },
|
|
||||||
{ name: 'Birthday Cake', cost: 7, icon: '🎂', sect: 'Food' },
|
|
||||||
{ name: 'Shortcake', cost: 4, icon: '🍰', sect: 'Food' },
|
|
||||||
{ name: 'Cupcake', cost: 3, icon: '🧁', sect: 'Food' },
|
|
||||||
{ name: 'Pie', cost: 4, icon: '🥧', sect: 'Food' },
|
|
||||||
{ name: 'Chocolate Bar', cost: 2, icon: '🍫', sect: 'Food' },
|
|
||||||
{ name: 'Candy', cost: 1, icon: '🍬', sect: 'Food' },
|
|
||||||
{ name: 'Lollipop', cost: 1, icon: '🍭', sect: 'Food' },
|
|
||||||
{ name: 'Custard', cost: 3, icon: '🍮', sect: 'Food' },
|
|
||||||
{ name: 'Honey Pot', cost: 3, icon: '🍯', sect: 'Food' },
|
|
||||||
{ name: 'Baby Bottle', cost: 3, icon: '🍼', sect: 'Food' },
|
|
||||||
{ name: 'Glass of Milk', cost: 3, icon: '🥛', sect: 'Food' },
|
|
||||||
{ name: 'Coffee', cost: 3, icon: '☕', sect: 'Food' },
|
|
||||||
{ name: 'Teapot', cost: 3, icon: '🫖', sect: 'Food' },
|
|
||||||
{ name: 'Tea', cost: 3, icon: '🍵', sect: 'Food' },
|
|
||||||
{ name: 'Sake', cost: 3, icon: '🍶', sect: 'Food' },
|
|
||||||
{ name: 'Champagne', cost: 3, icon: '🍾', sect: 'Food' },
|
|
||||||
{ name: 'Wine Glass', cost: 3, icon: '🍷', sect: 'Food' },
|
|
||||||
{ name: 'Cocktail Glass', cost: 3, icon: '🍸', sect: 'Food' },
|
|
||||||
{ name: 'Tropical Drink', cost: 3, icon: '🍹', sect: 'Food' },
|
|
||||||
{ name: 'Beer Mug', cost: 3, icon: '🍺', sect: 'Food' },
|
|
||||||
{ name: 'Tumbler', cost: 3, icon: '🥃', sect: 'Food' },
|
|
||||||
{ name: 'Soda', cost: 3, icon: '🥤', sect: 'Food' },
|
|
||||||
{ name: 'Bubble Tea', cost: 3, icon: '🧋', sect: 'Food' },
|
|
||||||
{ name: 'Beverage Box', cost: 30, icon: '🧃', sect: 'Food' },
|
|
||||||
{ name: 'Mate', cost: 3, icon: '🧉', sect: 'Food' },
|
|
||||||
|
|
||||||
//Weapons
|
|
||||||
{ name: 'Swords_special', cost: 3, icon: '⚔️', sect: 'Weapons' },
|
|
||||||
{ name: 'Boomerang', cost: 300, icon: '🪃', sect: 'Weapons' },
|
|
||||||
{ name: 'Boomerang', cost: 200, icon: '🏹', sect: 'Weapons' },
|
|
||||||
{ name: 'Knife', cost: 20, icon: '🔪', sect: 'Weapons' },
|
|
||||||
{ name: 'Dagger', cost: 60, icon: '🗡', sect: 'Weapons' },
|
|
||||||
{ name: 'Shield', cost: 100, icon: '🛡', sect: 'Weapons' },
|
|
||||||
{ name: 'Axe', cost: 40, icon: '🪓', sect: 'Weapons' },
|
|
||||||
{ name: 'Trident', cost: 140, icon: '🔱', sect: 'Weapons' },
|
|
||||||
{ name: 'Scissors', cost: 10, icon: '✂️', sect: 'Weapons' },
|
|
||||||
|
|
||||||
//Potions (of varying sections)
|
if (resetShop) {
|
||||||
{ name: 'HP Potion', cost: 20, icon: 'CUSTOM|healing_potion', sect: 'HP' },
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
{ name: 'MP Potion', cost: 15, icon: 'CUSTOM|mana_potion', sect: 'MP' },
|
const mongouri = process.env.MONGODB_URI; //DO NOT RUN LOCALLY (no process.env)
|
||||||
{ name: 'Super HP Potion', cost: 50, icon: 'CUSTOM|superior_healing_potion', sect: 'HP' },
|
|
||||||
{ name: 'Super MP Potion', cost: 40, icon: 'CUSTOM|superior_mana_potion', sect: 'MP' }
|
|
||||||
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.close().then(function() {
|
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
const END = d.getTime();
|
let collectiontemp;
|
||||||
console.log(`Total time in SECONDS: ${(((END - START) % 60000) / 1000).toFixed(0)} ms!`);
|
client.connect(err => {
|
||||||
});
|
collectiontemp = client.db("main").collection("shop");
|
||||||
|
// perform actions on the collection object
|
||||||
|
collectiontemp.insertMany(
|
||||||
|
[
|
||||||
|
{ name: 'Grapes', cost: 2, icon: '🍇', sect: 'Food' },
|
||||||
|
{ name: 'Melon', cost: 5, icon: '🍈', sect: 'Food' },
|
||||||
|
{ name: 'Watermelon', cost: 5, icon: '🍉', sect: 'Food' },
|
||||||
|
{ name: 'Tangerine', cost: 3, icon: '🍊', sect: 'Food' },
|
||||||
|
{ name: 'Lemon', cost: 3, icon: '🍋', sect: 'Food' },
|
||||||
|
{ name: 'Banana', cost: 4, icon: '🍌', sect: 'Food' },
|
||||||
|
{ name: 'Pineapple', cost: 4, icon: '🍍', sect: 'Food' },
|
||||||
|
{ name: 'Mango', cost: 3, icon: '🥭', sect: 'Food' },
|
||||||
|
{ name: 'Red Apple', cost: 3, icon: '🍎', sect: 'Food' },
|
||||||
|
{ name: 'Green Apple', cost: 3, icon: '🍏', sect: 'Food' },
|
||||||
|
{ name: 'Pear', cost: 3, icon: '🍐', sect: 'Food' },
|
||||||
|
{ name: 'Peach', cost: 3, icon: '🍑', sect: 'Food' },
|
||||||
|
{ name: 'Cherries', cost: 4, icon: '🍒', sect: 'Food' },
|
||||||
|
{ name: 'Strawberry', cost: 3, icon: '🍓', sect: 'Food' },
|
||||||
|
{ name: 'Blueberries', cost: 3, icon: '🫐', sect: 'Food' },
|
||||||
|
{ name: 'Kiwi', cost: 3, icon: '🥝', sect: 'Food' },
|
||||||
|
{ name: 'Tomato', cost: 4, icon: '🍅', sect: 'Food' },
|
||||||
|
{ name: 'Olive', cost: 4, icon: '🫒', sect: 'Food' },
|
||||||
|
{ name: 'Coconut', cost: 3, icon: '🥥', sect: 'Food' },
|
||||||
|
{ name: 'Avocado', cost: 3, icon: '🥑', sect: 'Food' },
|
||||||
|
{ name: 'Eggplant', cost: 10, icon: '🍆', sect: 'Food' },
|
||||||
|
{ name: 'Potato', cost: 3, icon: '🥔', sect: 'Food' },
|
||||||
|
{ name: 'Carrot', cost: 3, icon: '🥕', sect: 'Food' },
|
||||||
|
{ name: 'Ear of Corn', cost: 3, icon: '🌽', sect: 'Food' },
|
||||||
|
{ name: 'Hot Pepper', cost: 3, icon: '🌶️', sect: 'Food' },
|
||||||
|
{ name: 'Bell Pepper', cost: 3, icon: '🫑', sect: 'Food' },
|
||||||
|
{ name: 'Cucumber', cost: 3, icon: '🥒', sect: 'Food' },
|
||||||
|
{ name: 'Leafy Green', cost: 3, icon: '🥬', sect: 'Food' },
|
||||||
|
{ name: 'Broccoli', cost: 2, icon: '🥦', sect: 'Food' },
|
||||||
|
{ name: 'Garlic', cost: 3, icon: '🧄', sect: 'Food' },
|
||||||
|
{ name: 'Onion', cost: 3, icon: '🧅', sect: 'Food' },
|
||||||
|
{ name: 'Mushroom', cost: 3, icon: '🍄', sect: 'Food' },
|
||||||
|
{ name: 'Peanuts', cost: 4, icon: '🥜', sect: 'Food' },
|
||||||
|
{ name: 'Chestnut', cost: 3, icon: '🌰', sect: 'Food' },
|
||||||
|
{ name: 'Bread', cost: 5, icon: '🍞', sect: 'Food' },
|
||||||
|
{ name: 'Croissant', cost: 7, icon: '🥐', sect: 'Food' },
|
||||||
|
{ name: 'Baguette Bread', cost: 10, icon: '🥖', sect: 'Food' },
|
||||||
|
{ name: 'Flatbread', cost: 9, icon: '🫓', sect: 'Food' },
|
||||||
|
{ name: 'Pretzel', cost: 5, icon: '🥨', sect: 'Food' },
|
||||||
|
{ name: 'Bagel', cost: 4, icon: '🥯', sect: 'Food' },
|
||||||
|
{ name: 'Pancakes', cost: 5, icon: '🥞', sect: 'Food' },
|
||||||
|
{ name: 'Waffle', cost: 5, icon: '🧇', sect: 'Food' },
|
||||||
|
{ name: 'Cheese Wedge', cost: 3, icon: '🧀', sect: 'Food' },
|
||||||
|
{ name: 'Meat on the Bone', cost: 5, icon: '🍖', sect: 'Food' },
|
||||||
|
{ name: 'Checken Leg', cost: 5, icon: '🍗', sect: 'Food' },
|
||||||
|
{ name: 'Cut of Meat', cost: 4, icon: '🥩', sect: 'Food' },
|
||||||
|
{ name: 'Bacon', cost: 4, icon: '🥓', sect: 'Food' },
|
||||||
|
{ name: 'Hamburger', cost: 5, icon: '🍔', sect: 'Food' },
|
||||||
|
{ name: 'French Fries', cost: 3, icon: '🍟', sect: 'Food' },
|
||||||
|
{ name: 'Pizza', cost: 6, icon: '🍕', sect: 'Food' },
|
||||||
|
{ name: 'Hot Dog', cost: 3, icon: '🌭', sect: 'Food' },
|
||||||
|
{ name: 'Sandwich', cost: 3, icon: '🥪', sect: 'Food' },
|
||||||
|
{ name: 'Taco', cost: 3, icon: '🌮', sect: 'Food' },
|
||||||
|
{ name: 'Burrito', cost: 5, icon: '🌯', sect: 'Food' },
|
||||||
|
{ name: 'Tamale', cost: 5, icon: '🫔', sect: 'Food' },
|
||||||
|
{ name: 'Stuffed Flatbread', cost: 5, icon: '🥙', sect: 'Food' },
|
||||||
|
{ name: 'Falafel', cost: 4, icon: '🧆', sect: 'Food' },
|
||||||
|
{ name: 'Egg', cost: 3, icon: '🥚', sect: 'Food' },
|
||||||
|
{ name: 'Hot Pot', cost: 12, icon: '🍲', sect: 'Food' },
|
||||||
|
{ name: 'Fondue', cost: 8, icon: '🫕', sect: 'Food' },
|
||||||
|
{ name: 'Green Salad', cost: 3, icon: '🥗', sect: 'Food' },
|
||||||
|
{ name: 'Popcorn', cost: 3, icon: '🍿', sect: 'Food' },
|
||||||
|
{ name: 'Butter', cost: 2, icon: '🧈', sect: 'Food' },
|
||||||
|
{ name: 'Salt', cost: 2, icon: '🧂', sect: 'Food' },
|
||||||
|
{ name: 'Canned Food', cost: 3, icon: '🥫', sect: 'Food' },
|
||||||
|
{ name: 'Bento Box', cost: 7, icon: '🍱', sect: 'Food' },
|
||||||
|
{ name: 'Rice Cracker', cost: 1, icon: '🍘', sect: 'Food' },
|
||||||
|
{ name: 'Rice Ball', cost: 3, icon: '🍙', sect: 'Food' },
|
||||||
|
{ name: 'Cooked Rice', cost: 3, icon: '🍚', sect: 'Food' },
|
||||||
|
{ name: 'Curry Rice', cost: 4, icon: '🍛', sect: 'Food' },
|
||||||
|
{ name: 'Ramen', cost: 4, icon: '🍜', sect: 'Food' },
|
||||||
|
{ name: 'Spaghetti', cost: 5, icon: '🍝', sect: 'Food' },
|
||||||
|
{ name: 'Roasted Sweet Potato', cost: 3, icon: '🍠', sect: 'Food' },
|
||||||
|
{ name: 'Oden', cost: 3, icon: '🍢', sect: 'Food' },
|
||||||
|
{ name: 'Sushi', cost: 4, icon: '🍣', sect: 'Food' },
|
||||||
|
{ name: 'Fried Shrimp', cost: 3, icon: '🍤', sect: 'Food' },
|
||||||
|
{ name: 'Fish Cake', cost: 3, icon: '🍥', sect: 'Food' },
|
||||||
|
{ name: 'Moon Cake', cost: 3, icon: '🥮', sect: 'Food' },
|
||||||
|
{ name: 'Dango', cost: 3, icon: '🍡', sect: 'Food' },
|
||||||
|
{ name: 'Dumpling', cost: 3, icon: '🥟', sect: 'Food' },
|
||||||
|
{ name: 'Fortune Cookie', cost: 3, icon: '🥠', sect: 'Food' },
|
||||||
|
{ name: 'Oyster', cost: 4, icon: '🦪', sect: 'Food' },
|
||||||
|
{ name: 'Ice Cream Cone', cost: 3, icon: '🍦', sect: 'Food' },
|
||||||
|
{ name: 'Shaved Ice', cost: 3, icon: '🍧', sect: 'Food' },
|
||||||
|
{ name: 'Ice Cream', cost: 3, icon: '🍨', sect: 'Food' },
|
||||||
|
{ name: 'Doughnut', cost: 3, icon: '🍩', sect: 'Food' },
|
||||||
|
{ name: 'Cookie', cost: 3, icon: '🍪', sect: 'Food' },
|
||||||
|
{ name: 'Birthday Cake', cost: 7, icon: '🎂', sect: 'Food' },
|
||||||
|
{ name: 'Shortcake', cost: 4, icon: '🍰', sect: 'Food' },
|
||||||
|
{ name: 'Cupcake', cost: 3, icon: '🧁', sect: 'Food' },
|
||||||
|
{ name: 'Pie', cost: 4, icon: '🥧', sect: 'Food' },
|
||||||
|
{ name: 'Chocolate Bar', cost: 2, icon: '🍫', sect: 'Food' },
|
||||||
|
{ name: 'Candy', cost: 1, icon: '🍬', sect: 'Food' },
|
||||||
|
{ name: 'Lollipop', cost: 1, icon: '🍭', sect: 'Food' },
|
||||||
|
{ name: 'Custard', cost: 3, icon: '🍮', sect: 'Food' },
|
||||||
|
{ name: 'Honey Pot', cost: 3, icon: '🍯', sect: 'Food' },
|
||||||
|
{ name: 'Baby Bottle', cost: 3, icon: '🍼', sect: 'Food' },
|
||||||
|
{ name: 'Glass of Milk', cost: 3, icon: '🥛', sect: 'Food' },
|
||||||
|
{ name: 'Coffee', cost: 3, icon: '☕', sect: 'Food' },
|
||||||
|
{ name: 'Teapot', cost: 3, icon: '🫖', sect: 'Food' },
|
||||||
|
{ name: 'Tea', cost: 3, icon: '🍵', sect: 'Food' },
|
||||||
|
{ name: 'Sake', cost: 3, icon: '🍶', sect: 'Food' },
|
||||||
|
{ name: 'Champagne', cost: 3, icon: '🍾', sect: 'Food' },
|
||||||
|
{ name: 'Wine Glass', cost: 3, icon: '🍷', sect: 'Food' },
|
||||||
|
{ name: 'Cocktail Glass', cost: 3, icon: '🍸', sect: 'Food' },
|
||||||
|
{ name: 'Tropical Drink', cost: 3, icon: '🍹', sect: 'Food' },
|
||||||
|
{ name: 'Beer Mug', cost: 3, icon: '🍺', sect: 'Food' },
|
||||||
|
{ name: 'Tumbler', cost: 3, icon: '🥃', sect: 'Food' },
|
||||||
|
{ name: 'Soda', cost: 3, icon: '🥤', sect: 'Food' },
|
||||||
|
{ name: 'Bubble Tea', cost: 3, icon: '🧋', sect: 'Food' },
|
||||||
|
{ name: 'Beverage Box', cost: 30, icon: '🧃', sect: 'Food' },
|
||||||
|
{ name: 'Mate', cost: 3, icon: '🧉', sect: 'Food' },
|
||||||
|
|
||||||
|
//Weapons
|
||||||
|
// { name: 'Swords_special', cost: 3, icon: '⚔️', sect: 'Weapons', double: false },
|
||||||
|
{ name: 'Boomerang', cost: 300, icon: '🪃', sect: 'Weapons', double: false, def: false },
|
||||||
|
{ name: 'Crossbow', cost: 200, icon: '🏹', sect: 'Weapons', double: true, def: false },
|
||||||
|
{ name: 'Knife', cost: 20, icon: '🔪', sect: 'Weapons', double: false, def: false },
|
||||||
|
{ name: 'Dagger', cost: 60, icon: '🗡', sect: 'Weapons', double: false, def: false },
|
||||||
|
{ name: 'Shield', cost: 100, icon: '🛡', sect: 'Weapons', double: false, def: true },
|
||||||
|
{ name: 'Axe', cost: 40, icon: '🪓', sect: 'Weapons', double: false, def: false },
|
||||||
|
{ name: 'Trident', cost: 140, icon: '🔱', sect: 'Weapons', double: false, def: false },
|
||||||
|
{ name: 'Scissors', cost: 10, icon: '✂️', sect: 'Weapons', double: false, def: false },
|
||||||
|
|
||||||
|
//Potions (of varying sections)
|
||||||
|
{ name: 'HP Potion', cost: 20, icon: 'CUSTOM|healing_potion', sect: 'HP' },
|
||||||
|
{ name: 'MP Potion', cost: 15, icon: 'CUSTOM|mana_potion', sect: 'MP' },
|
||||||
|
{ name: 'Super HP Potion', cost: 50, icon: 'CUSTOM|superior_healing_potion', sect: 'HP' },
|
||||||
|
{ name: 'Super MP Potion', cost: 40, icon: 'CUSTOM|superior_mana_potion', sect: 'MP' }
|
||||||
|
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
client.close().then(function() {
|
||||||
|
const END = d.getTime();
|
||||||
|
console.log(`Total time in SECONDS: ${(((END - START) % 60000) / 1000).toFixed(0)} ms!`);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('To reset the main shop, please change the variable "resetShop" in the "COMPLETE_INIT.js" file to true');
|
||||||
|
}
|
||||||
@@ -2,5 +2,10 @@
|
|||||||
|
|
||||||
Authors: ION606, MajorDrools
|
Authors: ION606, MajorDrools
|
||||||
|
|
||||||
Description:
|
### Node Packages Installation Instructions
|
||||||
This is a bot modeled after Selmer Bringsjord of RPI and all the wonderful things he says
|
Download the _package.json_ file from the repo
|
||||||
|
`npm install`
|
||||||
|
|
||||||
|
|
||||||
|
### Run Selmer Bot Locally
|
||||||
|
Set the entry point to `main.js`, then run using `node .`
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 862 KiB After Width: | Height: | Size: 862 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
@@ -0,0 +1,82 @@
|
|||||||
|
// @ts-check
|
||||||
|
const { MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('discord.js');
|
||||||
|
|
||||||
|
//Intro, setup/logging, Econ, Moderation, anime/manga, games, Selmer Specific, Misc, DMS/Premium
|
||||||
|
const tutoText = [
|
||||||
|
"__**Hello, and welcome to the Selmer Bot tutorial!**__\nIn this tutorial, I will walk you through the various commands and features of Selmer Bot!\n\nTo progress to the next page, click the right arrow at the bottom of this message.\nTo go back to the previous page, click the left arrow",
|
||||||
|
"__**SETUP AND LOGGING**__\nSet up your server to take full advantage of Selmer Bot's features, this includes moderation logging, custom welcome messages, calendar event pings and more!\n_Note: Most of these commands are only available to the server owner_\n\n__***COMMANDS***__\n!setup help welcome, !setup help logs, !setup help announcement, !setup welcome_channel, !setup welcome_message, !setup keep_logs, !setup log_channel, !setup log_severity, !setup announcement_channel, !setup announcement_role",
|
||||||
|
"__**ECONOMY**__\nThese commands have to do with the inventory and currency system Selmer Bot uses, although I should note that as of now Selmer Coin holds no IRL value ;-;\n\n__***COMMANDS***__\n!inventory, !buy, !sell, !shop, !work, !rank, !balance",
|
||||||
|
"__**MODERATION**__\nI mean....\n\n***__COMMANDS__***\n!help admin, !warn, !mute, !unmute, !kick, !ban, !unban, !lock, !unlock, !serverlock",
|
||||||
|
"__**AMIME AND MANGA**__\nGet info on your favorite Anime or Manga as a stat-sheet, a fancy embed, or have Selmer Bot describe it to you!\n\n__***COMMANDS***__\n!asearch, !msearch",
|
||||||
|
"__**GAMES**__\nAt the moment Selmer Bot only offers two games: Trivia and Tic Tac Toe. Both games can be played with other people, but only Trivia can be played solo. Selmer Bot also has a battle game where you can use weapons, potions, attack and defend, but this is still in beta\n\n__***COMMANDS***__\n!help game, !game battle !game tictactoe, !game trivia, !game equip, !game status, !game hp, !game classes, !game quit",
|
||||||
|
"__**SELMER SPECIFIC**__\nThese commands will probably be found nowhere else!\nThese include quotes (For legal reasons I have to state they aren't real quotes, mostly), as well as varius other things I based on good old Selmer\n\n__***COMMANDS***__\n!arrow, !extracredit, !tuto, !profile, !quotes",
|
||||||
|
"__**MISCELLANEOUS**__\nThese are the commands that are not really in any of the other categories. Don't be fooled, these are actually some of the most useful commands Selmer Bot has to offer. From playing music to web scraping to memes, I'm sure Selmer Bot has what you're looking for!\n\n__***COMMANDS***__\n!help, !kareoke, !link, !meme, !pickupline, !audio, !react, !scrape, !stocks, !crypto",
|
||||||
|
"__**DM COMMANDS**__\nThese commands will only work in DM's. All these commands will only work with Selmer Bot Premium (it's on the next page).\nThese features include Reminders (AKA a calendar) and Selmer Bot's own chat AI!\n\n__***COMMANDS***__\n!chat, !startconvo, !endconvo, !premium",
|
||||||
|
"__**SELMER BOT PREMIUM**__\nUse an AI chat, complete with semi-accurate IRL data, have Selmer Bot remind you of events with an easy-to-use interface and even a clickable calendar on the Selmer Bot website (_www.selmerbot.com_)\n\n__***COMMANDS***__\n!premium, !premium buy, !premium manage, !reminders",
|
||||||
|
"__**Thank you for completing the Selmer Bot Tutorial!**__\n\nTry out Selmer Bot's features, play the games and most importantly, have fun!\n\n-The Selmer Bot Team AKA ION606"
|
||||||
|
];
|
||||||
|
|
||||||
|
//If the page number == 0 and refered == false, then interaction will be a Message
|
||||||
|
function postEmbd(bot, interaction, page, refered) {
|
||||||
|
const author = {
|
||||||
|
name: "Selmer Bot",
|
||||||
|
url: "",
|
||||||
|
iconURL: bot.user.displayAvatarURL()
|
||||||
|
};
|
||||||
|
|
||||||
|
//Tutorial Embed
|
||||||
|
const te = new MessageEmbed();
|
||||||
|
te.setAuthor(author)
|
||||||
|
.setTitle("Selmer Bot Tutorial")
|
||||||
|
.setDescription(tutoText[page])
|
||||||
|
.setURL('https://www.selmerbot.com/')
|
||||||
|
.setFooter({ text: `Page ${page + 1}` });
|
||||||
|
|
||||||
|
|
||||||
|
if (tutoText[page].indexOf('Thank you for completing the Selmer Bot Tutorial') != -1) {
|
||||||
|
te.setImage('https://github.com/ION606/selmerBot/blob/main/assets/Sleemer_Bringsjorgend.png?raw=true');
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = new MessageActionRow();
|
||||||
|
//Make sure the page is never < 1
|
||||||
|
const prevbtn = new MessageButton()
|
||||||
|
.setCustomId(`tutoQueue|`)
|
||||||
|
.setLabel('⬅️')
|
||||||
|
.setStyle('SECONDARY');
|
||||||
|
|
||||||
|
if (page <= 0) {
|
||||||
|
prevbtn.customId += `0`;
|
||||||
|
prevbtn.setDisabled(true);
|
||||||
|
} else {
|
||||||
|
prevbtn.customId += `${page - 1}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextbtn = new MessageButton()
|
||||||
|
.setCustomId(`tutoQueue|`)
|
||||||
|
.setLabel('➡️')
|
||||||
|
.setStyle('SECONDARY');
|
||||||
|
|
||||||
|
if ((page + 1) >= tutoText.length) {
|
||||||
|
nextbtn.customId += `${tutoText.length}`;
|
||||||
|
nextbtn.setDisabled(true);
|
||||||
|
} else {
|
||||||
|
nextbtn.customId += `${page + 1}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
row.addComponents(prevbtn, nextbtn);
|
||||||
|
|
||||||
|
if (page > 0 || refered) {
|
||||||
|
interaction.update({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [te], components: [row] });
|
||||||
|
} else {
|
||||||
|
interaction.reply({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [te], components: [row] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'tuto',
|
||||||
|
description: 'An introduction command to Selmer Bot',
|
||||||
|
async execute(message, args, Discord, Client, bot) {
|
||||||
|
postEmbd(bot, message, 0, false);
|
||||||
|
}, postEmbd
|
||||||
|
}
|
||||||
@@ -7,11 +7,11 @@ module.exports = {
|
|||||||
.setTitle('My professional resume')
|
.setTitle('My professional resume')
|
||||||
//.setURL('https://discordjs.guide/popular-topics/embeds.html#embed-preview')
|
//.setURL('https://discordjs.guide/popular-topics/embeds.html#embed-preview')
|
||||||
//.setDescription('My professional resume')
|
//.setDescription('My professional resume')
|
||||||
.setImage('https://github.com/ION606/selmerBot/blob/main/Sleemer_Bringsjorgend.png?raw=true')
|
.setImage('https://github.com/ION606/selmerBot/blob/main/assets/Sleemer_Bringsjorgend.png?raw=true')
|
||||||
.addFields(
|
.addFields(
|
||||||
{name: 'My Epithets:', value: "Pearls of Wisdom"},
|
{name: 'My Epithets:', value: "~~Pearls of Wisdom~~"},
|
||||||
{name: '\t1. ', value: "Negative money is the best money"},
|
{name: '\t__Epithet 1__', value: "_Negative money is the best money_"},
|
||||||
{name: '\t2. ', value: "There is no god, only logic"}
|
{name: '\t__Epithet 2__', value: "_There is no god, only logic_"}
|
||||||
);
|
);
|
||||||
|
|
||||||
message.channel.send({ embeds: [newEmbed] });
|
message.channel.send({ embeds: [newEmbed] });
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
const { MessageEmbed, MessageActionRow, MessageButton, Interaction } = require('discord.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'code',
|
||||||
|
description: 'See where Selmer bot\'s code is stored! (you can also use _!repo_)',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
const embd = new MessageEmbed()
|
||||||
|
.setAuthor({ name: "Selmer Bot", url: bot.inviteLink, iconURL: bot.user.displayAvatarURL() })
|
||||||
|
.setThumbnail("https://github.com/ION606/selmer-bot-website/blob/main/assets/Selmer-icon.png?raw=true") // .setThumbnail('https://repository-images.githubusercontent.com/460670550/43932b23-d795-4334-838f-f33ee8f795c4')
|
||||||
|
.setDescription("Selmer Bot was created by ION606");
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents([
|
||||||
|
new MessageButton()
|
||||||
|
.setStyle("LINK")
|
||||||
|
.setURL("https://github.com/ION606/selmerBot")
|
||||||
|
.setLabel("Github Repo"),
|
||||||
|
|
||||||
|
new MessageButton()
|
||||||
|
.setStyle("LINK")
|
||||||
|
.setURL("https://www.selmerbot.com/")
|
||||||
|
.setLabel("Website"),
|
||||||
|
|
||||||
|
new MessageButton()
|
||||||
|
.setStyle("PRIMARY")
|
||||||
|
.setLabel("Tutorial")
|
||||||
|
.setCustomId("sbtutorial")
|
||||||
|
]);
|
||||||
|
|
||||||
|
message.reply({ embeds: [embd], components: [row] })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const { checkRole } = require('./verify.js');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'lock',
|
||||||
|
description: 'Lock a channel',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
const guild = bot.guilds.cache.get(message.guild.id);
|
||||||
|
|
||||||
|
if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||||
|
|
||||||
|
var channel;
|
||||||
|
if (args[0]) {
|
||||||
|
channel = guild.channels.cache.find(channel => channel.name.toLowerCase() === args[0]);
|
||||||
|
} else {
|
||||||
|
channel = message.channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel) { return message.reply("This channel does not exist!"); }
|
||||||
|
|
||||||
|
channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||||
|
VIEW_CHANNEL: true,
|
||||||
|
SEND_MESSAGES: false,
|
||||||
|
READ_MESSAGE_HISTORY: true,
|
||||||
|
ATTACH_FILES: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
//@ts-check
|
||||||
|
const { log, SEVCODES } = require('../log.js');
|
||||||
|
const { checkRole } = require('./verify.js');
|
||||||
|
|
||||||
|
|
||||||
|
function modHelp() {
|
||||||
|
const l = ['lock', 'unlock', 'kick', 'ban', 'unban', 'mute', 'unmute'];
|
||||||
|
|
||||||
|
return l.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function kick(guild, user) {
|
||||||
|
guild.members.kick(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function toggle_ban(guild, message, args, ban, reason) {
|
||||||
|
|
||||||
|
if (ban) {
|
||||||
|
guild.members.ban(args);
|
||||||
|
} else {
|
||||||
|
var user = args[0];
|
||||||
|
let i = 0;
|
||||||
|
while (user.indexOf('#') == -1) {
|
||||||
|
user += args[i];
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
message.guild.bans.fetch().then((users) => {
|
||||||
|
const userObj = users.filter((u) => {
|
||||||
|
return (`${u.user.username}#${u.user.discriminator}` == user);
|
||||||
|
}).first();
|
||||||
|
|
||||||
|
if (userObj && userObj.user) {
|
||||||
|
guild.members.unban(userObj.user.id, reason).then(() => {
|
||||||
|
resolve(userObj.user);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject("This user is not in the server!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// //Check if the user is banned or not
|
||||||
|
// message.guild.invites.fetch().then((invites) => {
|
||||||
|
// const u = guild.members.cache.get(id);
|
||||||
|
// u.send(`You have been unbanned from ${guild.name}, you can rejoin using the following link!\nhttps://discord.gg/${invites.first().code}`);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function toggle_mute(bot, guild, command, message, user, reason, mute) {
|
||||||
|
const mutedRole = guild.roles.cache.find((role) => role.name.toLowerCase() === 'muted');
|
||||||
|
const guser = guild.members.cache.get(user.id);
|
||||||
|
// if there is no `Muted` role, send an error
|
||||||
|
if (!mutedRole) { return message.channel.send('There is no "muted" role on this server. Please create one then try again'); }
|
||||||
|
|
||||||
|
if (mute) {
|
||||||
|
if (guser.roles.cache.get(mutedRole.id) == undefined) {
|
||||||
|
guser.roles.add(mutedRole);
|
||||||
|
log(bot, message, command, user, reason, SEVCODES.low);
|
||||||
|
} else { message.reply("This user is already muted!"); }
|
||||||
|
} else {
|
||||||
|
if (guser.roles.cache.get(mutedRole.id) != undefined) {
|
||||||
|
guser.roles.remove(mutedRole);
|
||||||
|
log(bot, message, command, user, reason, SEVCODES.none);
|
||||||
|
} else { message.reply("This user is not muted!"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOTE: use the following function for a "time out" type thing?
|
||||||
|
setTimeout(() => {
|
||||||
|
target.roles.remove(mutedRole); // remove the role
|
||||||
|
}, <time>)
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function timeOut(bot, user, message, args, command, reason) {
|
||||||
|
|
||||||
|
let num = Number(args[1]);
|
||||||
|
if (!args[1] && !Number.isSafeInteger(num)) { return message.reply(`Please use the following format ${bot.repfix}timeout <user> <amount of time> [*hours* **or** *minutes (default)*]`)}
|
||||||
|
let ms = num * 60 * 1000;
|
||||||
|
let timeAsSt = '';
|
||||||
|
|
||||||
|
if (args[2] == 'hours') { ms *= 60; timeAsSt = `${args[1]} hours`; }
|
||||||
|
else { timeAsSt = `${args[2]} minutes`; }
|
||||||
|
|
||||||
|
user.timeout(ms, reason);
|
||||||
|
|
||||||
|
log(bot, message, command, user, reason, timeAsSt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function moderation_handler(bot, message, args, command) {
|
||||||
|
const guild = message.guild;
|
||||||
|
|
||||||
|
//Verify
|
||||||
|
if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permission!'); }
|
||||||
|
|
||||||
|
let mentioned = message.mentions.users.first();
|
||||||
|
if (mentioned && mentioned.id == message.author.id) { return message.reply(`You can't ${command} yourself!`); }
|
||||||
|
|
||||||
|
const reason = args.slice(1).join(' ');
|
||||||
|
|
||||||
|
if (message.mentions.members.first() && (message.mentions.members.first().roles.highest.position > message.guild.members.resolve(bot.user).roles.highest.position)) {
|
||||||
|
return message.reply("I'm not high enough in the role hierarchy to do that!\n_To raise my place, go to **Server Settings -> Roles** then drag me up!_");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command != 'unban' && !mentioned || !reason) { return message.channel.send(`Please use the following format: _!<command> <user> <reason>`); }
|
||||||
|
if (command == 'unban' && !args[0] && !reason) { return message.channel.send("Please use the following format: _!unban <user_tag>#<user_discriminator> <reason>\nExample: _!unban John#1122_"); }
|
||||||
|
// if (command == 'ban' && guild.members.cache.get(mentioned.id).bannable) { message.reply("This user is not bannable!"); } //Broken
|
||||||
|
// if (command == 'ban' && !message.guild.members.cache.get(mentioned.id)) { message.reply("This user is not in the server"); }
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case 'kick': kick(guild, mentioned);
|
||||||
|
log(bot, message, command, mentioned, reason, SEVCODES.medium);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ban': toggle_ban(guild, message, mentioned, true, reason);
|
||||||
|
log(bot, message, command, mentioned, reason, SEVCODES.high);
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Leave the then() catch() thing, it needs to be async
|
||||||
|
case 'unban': toggle_ban(guild, message, args, false, reason).then((user) => { log(bot, message, command, user, reason, SEVCODES.none)}).catch((note) => { message.reply(note); });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'mute': toggle_mute(bot, guild, command, message, mentioned, reason, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'unmute': toggle_mute(bot, guild, command, message, mentioned, reason, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// case 'timeout': timeOut(bot, mentioned, message, args, command, reason);
|
||||||
|
// shouldIlog = false;
|
||||||
|
// break;
|
||||||
|
|
||||||
|
default: console.log(`ERROR! Moderation Command "${command}" has somehow been used!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'moderation',
|
||||||
|
moderation_handler, modHelp
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
module.exports = {
|
||||||
|
name: 'serverLock',
|
||||||
|
description: 'Lock ***ALL CHANNELS*** for everyone with the "everyone" role - ***SERVER OWNER ONLY. FOR EMERGENCY USE ONLY***',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
const guild = bot.guilds.cache.get(message.guild.id);
|
||||||
|
|
||||||
|
if (guild.ownerId != message.author.id) { return message.reply('Insufficient Permissions!'); }
|
||||||
|
|
||||||
|
message.guild.channels.cache.forEach(ch => {
|
||||||
|
channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||||
|
VIEW_CHANNEL: false,
|
||||||
|
SEND_MESSAGES: false,
|
||||||
|
READ_MESSAGE_HISTORY: false,
|
||||||
|
ATTACH_FILES: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// const { checkRole } = require('./verify.js');
|
||||||
|
|
||||||
|
|
||||||
|
// module.exports = {
|
||||||
|
// name: 'serverUnlock',
|
||||||
|
// description: 'unlocks ***ALL CHANNELS*** for everyone except the those with the "Selmer Bot Commands" role',
|
||||||
|
// execute(message, args, Discord, Client, bot) {
|
||||||
|
// const guild = bot.guilds.cache.get(message.guild.id);
|
||||||
|
|
||||||
|
// if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||||
|
|
||||||
|
// message.guild.channels.cache.forEach(ch => {
|
||||||
|
// channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||||
|
// VIEW_CHANNEL: true,
|
||||||
|
// SEND_MESSAGES: false,
|
||||||
|
// READ_MESSAGE_HISTORY: false,
|
||||||
|
// ATTACH_FILES: false
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
+89
-30
@@ -15,46 +15,105 @@ async function execute(bot, message, args, command, Discord, mongouri, items, xp
|
|||||||
const owner = message.guild.members.cache.get(message.guild.ownerId);
|
const owner = message.guild.members.cache.get(message.guild.ownerId);
|
||||||
|
|
||||||
if (message.author.id != message.guild.ownerId) {
|
if (message.author.id != message.guild.ownerId) {
|
||||||
return message.reply('Only the server owner can do this!')
|
return message.reply('Only the server owner can do this!');
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// // @ts-ignore
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
if (client.writeConcern || client.writeConcern) {
|
// if (client.writeConcern || client.writeConcern) {
|
||||||
client.close();
|
// client.close();
|
||||||
return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
// return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
||||||
}
|
// }
|
||||||
|
|
||||||
//Initialize
|
bot.mongoconnection.then(async (client) => {
|
||||||
CreateNewCollection(message, client, server, owner.user.id);
|
// if (err) { return console.log(err); }
|
||||||
|
try {
|
||||||
|
//Initialize
|
||||||
|
CreateNewCollection(message, client, server, owner.user.id);
|
||||||
|
|
||||||
client.connect(err => {
|
const db = client.db(server);
|
||||||
if (err) { return console.log(err); }
|
const dbo = db.collection('SETUP');
|
||||||
|
|
||||||
const db = client.db(server);
|
//Chose the appropriate command
|
||||||
const dbo = db.collection('SETUP');
|
command = args[0];
|
||||||
|
|
||||||
//Chose the appropriate command
|
if (!command) {
|
||||||
command = args[0];
|
message.channel.send('Please use the following format _!setup help <welcome, logs>_');
|
||||||
|
} else if (command == 'welcome_channel') {
|
||||||
|
if (args.length != 2) { return message.reply('The command format is _!setup welcome_channel <channel name>_'); }
|
||||||
|
// setWelcomeChannel(dbo, message, args[1]);
|
||||||
|
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
||||||
|
if (!channel) { return message.reply('The specified channel does not exist!'); }
|
||||||
|
|
||||||
if (command == 'welcome_channel') {
|
dbo.updateOne({welcomechannel: {$exists: true}}, {$set: {welcomechannel: `${channel.id}`}});
|
||||||
if (args.length != 2) { return message.reply('The command format is _!setup welcome_channel <channel name>_'); }
|
message.reply(`Set ${channel} as the new welcome channel`)
|
||||||
// setWelcomeChannel(dbo, message, args[1]);
|
} else if (command == 'welcome_message') {
|
||||||
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
if (args.length < 2) { return message.reply('The command format is _!setup welcome\\_message_\nUse _{sn}_ to insert the server name, _{un}_ to insert the user name, and _{ut}_ to insert the user tag\nExample: _!setup welcome\\_message Welcome to {sn} Sir {un}#{ut}_'); }
|
||||||
dbo.updateOne({welcomechannel: {$exists: true}}, {$set: {welcomechannel: `${channel.id}`}});
|
let msg = "";
|
||||||
} else if (command == 'welcome_message') {
|
for (let i = 1; i < args.length; i ++ ) {
|
||||||
if (args.length < 2) { return message.reply('The command format is _!setup welcome\\_message_\nUse _{sn}_ to insert the server name, _{un}_ to insert the user name, and _{ut}_ to insert the user tag\nExample: _!setup welcome\\_message Welcome to {sn} Sir {un}#{ut}_'); }
|
msg += args[i] + ' ';
|
||||||
let msg = "";
|
}
|
||||||
for (let i = 1; i < args.length; i ++ ) {
|
|
||||||
msg += args[i] + ' ';
|
if (msg.length > 30) { return message.reply('Please specify a welcome message under 30 characters!'); }
|
||||||
|
dbo.updateOne({welcomemessage: {$exists: true}}, {$set: {welcomemessage: msg}})
|
||||||
|
} else if (command == 'keep_logs') {
|
||||||
|
if (args.length != 2) { return message.reply('Please specify a parameter\nExample: _!setup keep\\_logs true'); }
|
||||||
|
|
||||||
|
let keeplogs = false;
|
||||||
|
if (args[1] == 'true') { keeplogs = true; }
|
||||||
|
|
||||||
|
dbo.updateOne({ _id: 'LOG'}, {$set: {keepLogs: keeplogs}});
|
||||||
|
|
||||||
|
message.reply(`Toggled log keeping to ${keeplogs}. Please use _!setup log_channel_ to choose the log channel`);
|
||||||
|
} else if (command == 'log_channel') {
|
||||||
|
if (args.length != 2) { return message.reply('Please specify a parameter\nExample: _!setup log\\_channel true_'); }
|
||||||
|
|
||||||
|
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
||||||
|
if (!channel) { return message.reply('The specified channel does not exist!'); }
|
||||||
|
|
||||||
|
dbo.updateOne({_id: 'LOG'}, {$set: {logchannel: `${channel.id}`}});
|
||||||
|
message.reply(`Made ${channel} the new Selmer Bot Logs channel!`);
|
||||||
|
} else if (command == 'log_severity') {
|
||||||
|
const tier = args[1];
|
||||||
|
const l = ['none', 'low', 'medium', 'high'];
|
||||||
|
if (!l.includes(tier)) { return message.reply("Please select an existing tier ('none', 'low', 'medium', 'high')"); }
|
||||||
|
|
||||||
|
dbo.updateOne({_id: 'LOG'}, {$set: {severity: tier}})
|
||||||
|
|
||||||
|
message.reply("Severity updated!");
|
||||||
|
} else if (command == 'announcement_role') {
|
||||||
|
if (message.mentions.roles.first() == undefined) {
|
||||||
|
return message.reply("Please mention a role (_!setup announcement\\_role **@role**_)\n_Note: Selmer Bot does NOT ping the @everyone role_");
|
||||||
|
}
|
||||||
|
const role = message.mentions.roles.first().id;
|
||||||
|
dbo.updateOne({_id: 'announcement'}, { $set: { 'role': role } });
|
||||||
|
|
||||||
|
message.reply("Role updated!");
|
||||||
|
} else if (command == "announcement_channel") {
|
||||||
|
const channel = message.guild.channels.cache.find(ch => ch.name === args[1]);
|
||||||
|
if (!channel) { return message.reply('The specified channel does not exist!'); }
|
||||||
|
|
||||||
|
dbo.updateOne({_id: 'announcement'}, { $set: { 'channel': channel.id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (command == 'help') {
|
||||||
|
let temp;
|
||||||
|
if (args[1] == 'welcome') {
|
||||||
|
temp = 'Use _!setup welcome\\_channel [channel name]_ to set the welcome channel and _!setup welcome\\_message [message]_ to set a welcome message!\n';
|
||||||
|
} else if (args[1] == 'logs') {
|
||||||
|
temp = 'To enable logging, use the command _!setup keep\\_logs true_ and _!setup log\\_channel_ [channel name] to set the logging channel!\n';
|
||||||
|
temp += 'Use _!setup keep\\_logs false_ to disable logging and _!setup log\\_severity [none, low, medium, high]_ to set the threshold\n';
|
||||||
|
temp += '__Severities:__\n*none* - unmute, unban\n*low* - mute\n*medium* - kick\n*high* - ban\nEvery tier also includes all notifs for ***higher*** tiers (AKA _!setup log\\_severity none_ will log everything from every severity)\n';
|
||||||
|
} else if (args[1] == 'announcement') {
|
||||||
|
temp = "To pick the announcement channel, use _!setup announcement\\_channel_\nTo pick the announcement role, use _!setup announcement\\_role_";
|
||||||
|
} else { temp = 'Use _!setup Please use the following format: _!setup help [welcome, logs, announcement]_\nExample: _!setup help welcome_'; }
|
||||||
|
|
||||||
if (msg.length > 30) { return message.reply('Please specify a welcome message under 30 characters!'); }
|
message.reply(temp);
|
||||||
dbo.updateOne({welcomemessage: {$exists: true}}, {$set: {welcomemessage: msg}})
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -63,6 +122,6 @@ async function execute(bot, message, args, command, Discord, mongouri, items, xp
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'setup',
|
name: 'setup',
|
||||||
description: 'N/A',
|
description: 'Set up server features',
|
||||||
execute
|
execute
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
const { checkRole } = require('./verify.js');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'unlock',
|
||||||
|
description: 'Unlock a channel',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
const guild = bot.guilds.cache.get(message.guild.id);
|
||||||
|
|
||||||
|
if (!checkRole(bot, guild, message.author.id)) { return message.reply('Insufficient Permissions!'); }
|
||||||
|
|
||||||
|
var channel;
|
||||||
|
if (args[0]) {
|
||||||
|
channel = guild.channels.cache.find(channel => channel.name.toLowerCase() === args[0]);
|
||||||
|
} else {
|
||||||
|
channel = message.channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channel) { return message.reply("This channel does not exist!"); }
|
||||||
|
|
||||||
|
channel.permissionOverwrites.edit(message.guild.roles.everyone.id, {
|
||||||
|
VIEW_CHANNEL: true,
|
||||||
|
SEND_MESSAGES: true,
|
||||||
|
READ_MESSAGE_HISTORY: true,
|
||||||
|
ATTACH_FILES: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
function checkRole(message, args) {
|
function checkRole(bot, guild, userId, cal = false) {
|
||||||
let role = args[0];
|
var roleName;
|
||||||
if (message.member.hasPermission('ADMINISTRATOR')) { return true; }
|
|
||||||
|
if (cal) {
|
||||||
|
roleName = "Selmer Bot Calendar";
|
||||||
|
} else {
|
||||||
|
roleName = "Selmer Bot Commands";
|
||||||
|
}
|
||||||
|
|
||||||
|
const role = guild.roles.cache.find((role) => { return (role.name == roleName); })
|
||||||
|
const user = guild.members.cache.get(userId);
|
||||||
|
|
||||||
|
return (role != undefined && user.roles.cache.has(role.id)); // || user.id == guild.ownerId || bot.inDebugMode
|
||||||
|
|
||||||
|
|
||||||
/*Maybe implement this later, useless for now
|
/*Maybe implement this later, useless for now
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
@@ -20,4 +31,4 @@ function checkRole(message, args) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {name: 'verify', checkRole}
|
module.exports = { checkRole }
|
||||||
@@ -22,6 +22,7 @@ async function welcome(member, welcomechannel, welcomemessage = null, welcomeban
|
|||||||
|
|
||||||
// const background = new CanvasImport.Image();
|
// const background = new CanvasImport.Image();
|
||||||
// background.src = arrayBufferToBuffer(data);
|
// background.src = arrayBufferToBuffer(data);
|
||||||
|
|
||||||
|
|
||||||
// This uses the canvas dimensions to stretch the image onto the entire canvas
|
// This uses the canvas dimensions to stretch the image onto the entire canvas
|
||||||
// context.drawImage(background, 0, 0, canvas.width, canvas.height);
|
// context.drawImage(background, 0, 0, canvas.width, canvas.height);
|
||||||
|
|||||||
+47
-31
@@ -11,39 +11,55 @@ module.exports = {
|
|||||||
name += args[i] + " ";
|
name += args[i] + " ";
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
} else { name = args[0]; }
|
||||||
|
|
||||||
scraper.getInfoFromName(name).then((data) => {
|
if (args[args.length - 1] != '~fancy' && args[args.length - 1] != '~summary' && args[args.length - 1] != '~stats') { args.push('~stats'); }
|
||||||
if (args[args.length - 1] == '~stats') {
|
|
||||||
const newEmbed = new Discord.MessageEmbed()
|
|
||||||
.setColor('#002eff')
|
|
||||||
.setTitle(data.title)
|
|
||||||
//.setURL('https://discordjs.guide/popular-topics/embeds.html#embed-preview')
|
|
||||||
//.setDescription('My professional resume')
|
|
||||||
.setImage(data.picture)
|
|
||||||
.addFields(
|
|
||||||
{name: 'Genres:', value: data.genres.join(", ")},
|
|
||||||
{name: 'Score:', value: data.score},
|
|
||||||
{name: 'Episode:', value: data.episodes}
|
|
||||||
).setURL(data.trailer);
|
|
||||||
|
|
||||||
message.channel.send({ embeds: [newEmbed] });
|
|
||||||
} else if (args[args.length - 1] == '~fancy') {
|
|
||||||
let temp = `The ${data.genres.join(", ")} anime _${data.title}_ first aired on ${data.premiered}`;
|
|
||||||
if (data.aired) { temp += `. This anime ran for ${data.aired} for a total of ${data.episodes} episodes.`}
|
|
||||||
else { temp += ` and is still airing with ${data.episodes} so far!`}
|
|
||||||
|
|
||||||
temp += ` This anime has a score of ${data.score} and is ${data.popularity} on MyAnimeList!\n`;
|
//When set to true, getInfoFromName.getBestMatch did not, in fact, return the best results
|
||||||
temp += `You can see a trailer for ${data.title} here: ${data.trailer}`;
|
scraper.getInfoFromName(name, false).then((data) => {
|
||||||
temp += `\n\n(to see a summary of the anime, use '${bot.prefix}asearch <anime name> ~summary')`;
|
try {
|
||||||
|
if (args[args.length - 1] == '~stats') {
|
||||||
message.channel.send({ embeds: [new Discord.MessageEmbed().setImage(data.picture)]});
|
const newEmbed = new Discord.MessageEmbed()
|
||||||
message.channel.send(temp);
|
.setColor('#002eff')
|
||||||
} else if (args[args.length - 1] == '~summary') {
|
.setTitle(data.title)
|
||||||
let temp = data.synopsis;
|
//.setURL('https://discordjs.guide/popular-topics/embeds.html#embed-preview')
|
||||||
message.channel.send(temp);
|
//.setDescription('My professional resume')
|
||||||
} else {
|
.setImage(data.picture)
|
||||||
message.reply(`Unknown command, try using the format '${bot.prefix}asearch <anime name> [~stats or ~fancy or ~summary]`);
|
.addFields(
|
||||||
|
{name: 'Genres:', value: data.genres.join(", ")},
|
||||||
|
{name: 'Score:', value: data.score},
|
||||||
|
{name: 'Episode:', value: data.episodes}
|
||||||
|
).setURL(data.trailer);
|
||||||
|
|
||||||
|
message.channel.send({ embeds: [newEmbed] });
|
||||||
|
} else if (args[args.length - 1] == '~fancy') {
|
||||||
|
let temp = `The ${data.genres.join(", ")} anime _${data.title}_ first aired on ${data.premiered}`;
|
||||||
|
if (data.aired) { temp += `. This anime ran for ${data.aired} for a total of ${data.episodes} episodes.`}
|
||||||
|
else { temp += ` and is still airing with ${data.episodes} so far!`}
|
||||||
|
|
||||||
|
temp += ` This anime has a score of ${data.score} and is ${data.popularity} on MyAnimeList!\n`;
|
||||||
|
temp += `You can see a trailer for ${data.title} here: ${data.trailer}`;
|
||||||
|
temp += `\n\n(to see a summary of the anime, use '${bot.prefix}asearch <anime name> ~summary')`;
|
||||||
|
|
||||||
|
message.channel.send({ embeds: [new Discord.MessageEmbed().setImage(data.picture)]});
|
||||||
|
message.channel.send(temp);
|
||||||
|
} else if (args[args.length - 1] == '~summary') {
|
||||||
|
let temp = data.synopsis;
|
||||||
|
message.channel.send(temp);
|
||||||
|
} else {
|
||||||
|
message.reply(`Unknown command, try using the format '${bot.prefix}asearch <anime name> [~stats or ~fancy or ~summary]`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.indexOf('MessageEmbed field values must be non-empty strings') != -1) {
|
||||||
|
message.reply(`Insufficient information on website!\nThe page can be found here: ${data.url}`);
|
||||||
|
} else {
|
||||||
|
message.reply("Uh oh, an unknown error occured, click the ✅ to report this!");
|
||||||
|
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
addComplaintButton(bot, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+47
-30
@@ -6,6 +6,8 @@ module.exports = {
|
|||||||
description: 'Selmer bot gives you info on a manga',
|
description: 'Selmer bot gives you info on a manga',
|
||||||
async execute(message, args, Discord, Client, bot) {
|
async execute(message, args, Discord, Client, bot) {
|
||||||
if (args.length < 1) { return message.reply("Please specify a manga!"); }
|
if (args.length < 1) { return message.reply("Please specify a manga!"); }
|
||||||
|
if (args[args.length - 1] != '~fancy' && args[args.length - 1] != '~summary' && args[args.length - 1] != '~stats') { args.push('~stats'); }
|
||||||
|
|
||||||
let name = "";
|
let name = "";
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@@ -16,37 +18,52 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let cmd = args[args.length - 1];
|
let cmd = args[args.length - 1];
|
||||||
search.search(type, {
|
|
||||||
maxResults: 1,
|
|
||||||
term: name
|
|
||||||
}).then((data1) => {
|
|
||||||
let data = data1[0];
|
|
||||||
if (cmd == "~stats") {
|
|
||||||
const newEmbed = new Discord.MessageEmbed()
|
|
||||||
.setColor('#ff9900')
|
|
||||||
.setTitle(data.title)
|
|
||||||
.setURL(data.url)
|
|
||||||
.setImage(data.thumbnail)
|
|
||||||
//.setDescription('My professional resume')
|
|
||||||
.addFields(
|
|
||||||
{name: 'Type:', value: data.type},
|
|
||||||
{name: 'Score:', value: data.score},
|
|
||||||
{name: 'Volumes:', value: data.vols}
|
|
||||||
);
|
|
||||||
|
|
||||||
message.channel.send({ embeds: [newEmbed] });
|
|
||||||
} else if (cmd == "~fancy") {
|
|
||||||
let temp = `The ${data.type} _${data.title}_ currently has ${data.vols} volumes with ${data.nbChapters} chapters, `;
|
|
||||||
temp += `running from _${data.startDate.replace(/-/g, "/")}_ to _${data.endDate.replace(/-/g, "/")}_, and has a score of ${data.score} on MyAnimeList!\n`;
|
|
||||||
temp += `You can read more about _${data.title}_ at ${data.url}`;
|
|
||||||
|
|
||||||
message.channel.send(temp);
|
try {
|
||||||
} else if (cmd == "~summary") {
|
search.search(type, {
|
||||||
//Remove the "read more." at the end
|
maxResults: 1,
|
||||||
let temp = data.shortDescription.slice(0, -10);
|
term: name
|
||||||
temp += ` _read more at_ ${data.url}`;
|
}).then((data1) => {
|
||||||
return message.channel.send(temp);
|
let data = data1[0];
|
||||||
|
if (cmd == "~stats") {
|
||||||
|
const newEmbed = new Discord.MessageEmbed()
|
||||||
|
.setColor('#ff9900')
|
||||||
|
.setTitle(data.title)
|
||||||
|
.setURL(data.url)
|
||||||
|
.setImage(data.thumbnail)
|
||||||
|
//.setDescription('My professional resume')
|
||||||
|
.addFields(
|
||||||
|
{name: 'Type:', value: data.type},
|
||||||
|
{name: 'Score:', value: data.score},
|
||||||
|
{name: 'Volumes:', value: data.vols}
|
||||||
|
);
|
||||||
|
|
||||||
|
message.channel.send({ embeds: [newEmbed] });
|
||||||
|
} else if (cmd == "~fancy") {
|
||||||
|
let temp = `The ${data.type} _${data.title}_ currently has ${data.vols} volumes with ${data.nbChapters} chapters, `;
|
||||||
|
temp += `running from _${data.startDate.replace(/-/g, "/")}_ to _${data.endDate.replace(/-/g, "/")}_, and has a score of ${data.score} on MyAnimeList!\n`;
|
||||||
|
temp += `You can read more about _${data.title}_ at ${data.url}`;
|
||||||
|
|
||||||
|
message.channel.send(temp);
|
||||||
|
} else if (cmd == "~summary") {
|
||||||
|
//Remove the "read more." at the end
|
||||||
|
let temp = data.shortDescription.slice(0, -10);
|
||||||
|
temp += ` _read more at_ ${data.url}`;
|
||||||
|
return message.channel.send(temp);
|
||||||
|
} else {
|
||||||
|
message.reply(`Unknown command, try using the format '${bot.prefix}msearch <manga name> [~stats or ~fancy or ~summary]`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message.indexOf('MessageEmbed field values must be non-empty strings') != -1) {
|
||||||
|
message.reply(`Insufficient information on website!\nThe page can be found here: ${data.url}`);
|
||||||
|
} else {
|
||||||
|
message.reply("Uh oh, an unknown error occured, click the ✅ to report this!");
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
addComplaintButton(bot, message);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,27 +12,31 @@ function convertSnowflakeToDate(snowflake, epoch = DISCORD_EPOCH) {
|
|||||||
|
|
||||||
// Validates a snowflake ID string and returns a JS Date object if valid
|
// Validates a snowflake ID string and returns a JS Date object if valid
|
||||||
function validateSnowflake(snowflake, epoch) {
|
function validateSnowflake(snowflake, epoch) {
|
||||||
if (!Number.isInteger(+snowflake)) {
|
try {
|
||||||
throw new Error(
|
if (!Number.isInteger(+snowflake)) {
|
||||||
"That doesn't look like a snowflake. Snowflakes contain only numbers."
|
throw new Error(
|
||||||
)
|
"That doesn't look like a snowflake. Snowflakes contain only numbers."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snowflake < 4194304) {
|
||||||
|
throw new Error(
|
||||||
|
"That doesn't look like a snowflake. Snowflakes are much larger numbers."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestamp = convertSnowflakeToDate(snowflake, epoch)
|
||||||
|
|
||||||
|
if (Number.isNaN(timestamp.getTime())) {
|
||||||
|
throw new Error(
|
||||||
|
"That doesn't look like a snowflake. Snowflakes have fewer digits."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return timestamp
|
||||||
|
} catch(err) {
|
||||||
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snowflake < 4194304) {
|
|
||||||
throw new Error(
|
|
||||||
"That doesn't look like a snowflake. Snowflakes are much larger numbers."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const timestamp = convertSnowflakeToDate(snowflake, epoch)
|
|
||||||
|
|
||||||
if (Number.isNaN(timestamp.getTime())) {
|
|
||||||
throw new Error(
|
|
||||||
"That doesn't look like a snowflake. Snowflakes have fewer digits."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return timestamp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { convertSnowflakeToDate, validateSnowflake }
|
module.exports = { convertSnowflakeToDate, validateSnowflake }
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
//@ts-check
|
|
||||||
const { MessageActionRow, MessageButton, MessageSelectMenu } = require('discord.js');
|
|
||||||
const { STATE } = require('./econ');
|
|
||||||
const { winGame, getCustomEmoji } = require('./external_game_functions.js');
|
|
||||||
const { changeTurn } = require('../turnManager.js');
|
|
||||||
|
|
||||||
|
|
||||||
function postActionBar(thread, user_dbo) {
|
|
||||||
const row = new MessageActionRow()
|
|
||||||
.addComponents(
|
|
||||||
new MessageButton()
|
|
||||||
.setCustomId('ATTACK')
|
|
||||||
.setLabel('ATTACK')
|
|
||||||
.setStyle('DANGER'),
|
|
||||||
new MessageButton()
|
|
||||||
.setCustomId('HEAL')
|
|
||||||
.setLabel('HEAL')
|
|
||||||
.setStyle('SUCCESS'),
|
|
||||||
new MessageButton()
|
|
||||||
.setCustomId('DEFEND')
|
|
||||||
.setLabel('DEFEND')
|
|
||||||
.setStyle('PRIMARY'),
|
|
||||||
new MessageButton()
|
|
||||||
.setCustomId('ITEMS')
|
|
||||||
.setLabel('ITEMS')
|
|
||||||
.setStyle('SECONDARY')
|
|
||||||
);
|
|
||||||
|
|
||||||
thread.send({ content: `Your turn <@${user_dbo.s.namespace.collection}>!`, components: [row] });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by "attack"
|
|
||||||
*/
|
|
||||||
function attack_special() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Bow special phrase: Σ>―(´・ω・`)→
|
|
||||||
function attack(client, user_dbo, other_dbo, bot, thread, command, mongouri, items, xp_collection, interaction) {
|
|
||||||
//Get the weapon
|
|
||||||
user_dbo.find({'equipped': {$exists: true}}).toArray(function(err, docs) {
|
|
||||||
const doc = docs[0];
|
|
||||||
const all_weapons = doc.equipped.weapons;
|
|
||||||
const weapon = all_weapons.main;
|
|
||||||
|
|
||||||
var dmg = 0;
|
|
||||||
|
|
||||||
//No weapons (punch)
|
|
||||||
if (weapon == null) {
|
|
||||||
dmg = doc.rank;
|
|
||||||
} else {
|
|
||||||
dmg = (doc.rank - 1) + Math.round(weapon.cost/5);
|
|
||||||
}
|
|
||||||
|
|
||||||
other_dbo.find({'equipped': {$exists: true}}).toArray(function (err, docs) {
|
|
||||||
const odoc = docs[0];
|
|
||||||
|
|
||||||
//Handle defending
|
|
||||||
if (odoc.state == STATE.DEFENDING) {
|
|
||||||
var def = odoc.rank - doc.rank;
|
|
||||||
//Make sure we don't go negative
|
|
||||||
if (def < 0) { def = 0; }
|
|
||||||
|
|
||||||
dmg /= 2 + def;
|
|
||||||
}
|
|
||||||
|
|
||||||
var new_hp = odoc.hpmp.hp -= dmg;
|
|
||||||
if (new_hp <= 0) {
|
|
||||||
winGame(client, bot, client.db(user_dbo.s.namespace.db), user_dbo, xp_collection, interaction.message);
|
|
||||||
} else {
|
|
||||||
other_dbo.updateOne({'equipped': {$exists: true}}, { $set: { 'hpmp.hp' :new_hp }});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
//Check for a "special" animation
|
|
||||||
|
|
||||||
|
|
||||||
//Change turns
|
|
||||||
changeTurn(client, bot, interaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by "item"
|
|
||||||
*/
|
|
||||||
async function heal(interaction, client, user_dbo, bot, thread, command, mongouri, items) {
|
|
||||||
if (interaction.message.content.toLowerCase().indexOf('Which item would you like to use?') != -1) {
|
|
||||||
// The person picked out an item
|
|
||||||
}
|
|
||||||
//Get the 'healing' items (stored in "{item}: num" format)
|
|
||||||
user_dbo.find({'equipped': {$exists: true}}).toArray(async function(err, docs) {
|
|
||||||
const doc = docs[0];
|
|
||||||
const rawitems = doc.equipped.items;
|
|
||||||
const items = rawitems.filter(function(f) { return (f.sect.toLowerCase() == 'hp') });
|
|
||||||
|
|
||||||
|
|
||||||
if (JSON.stringify(items) == '[]') {
|
|
||||||
postActionBar(thread, user_dbo);
|
|
||||||
return interaction.editReply("You don't have any items!");
|
|
||||||
} else { console.log(JSON.stringify(items))}
|
|
||||||
|
|
||||||
var itemlist = [];
|
|
||||||
|
|
||||||
items.forEach(function(item) {
|
|
||||||
let n = item.name;
|
|
||||||
|
|
||||||
let h = (doc.rank - 1) + Math.round(item.cost/10);
|
|
||||||
|
|
||||||
itemlist.push({label: n, description: `Restores ${h} health (${item.num})`, value: `${n}`});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//Find something to heal with
|
|
||||||
const row = new MessageActionRow()
|
|
||||||
.addComponents(
|
|
||||||
new MessageSelectMenu()
|
|
||||||
.setCustomId(`${interaction.user.id}|heal`)
|
|
||||||
.setPlaceholder('Nothing selected')
|
|
||||||
.addOptions(itemlist),
|
|
||||||
// .addOptions([
|
|
||||||
// {
|
|
||||||
// label: 'Select me',
|
|
||||||
// description: 'This is a description',
|
|
||||||
// value: 'first_option',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// label: 'You can select me too',
|
|
||||||
// description: 'This is also a description',
|
|
||||||
// value: 'second_option',
|
|
||||||
// },
|
|
||||||
// ])
|
|
||||||
);
|
|
||||||
|
|
||||||
await interaction.editReply({ content: 'Please choose a health potion!', components: [row] });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Gets items by section/name, reacts with them to the message, when pressed, trigger a response
|
|
||||||
function item() {
|
|
||||||
throw 'THE "ITEM" COMMAND HAS NOT BEEN SET UP YET!';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function defend(user_dbo, bot, thread, command, mongouri, items) {
|
|
||||||
user_dbo.find({'equipped': {$exists: true}}).toArray(function(err, docs) {
|
|
||||||
const doc = docs[0];
|
|
||||||
const all_weapons = doc.get('weapons');
|
|
||||||
const shield = all_weapons.get('secondary');
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function usePotion(interaction, client, user_dbo, bot, thread, command, mongouri) {
|
|
||||||
const name = interaction.values[0];
|
|
||||||
const cursor = user_dbo.find({'equipped.items': {$exists: true}});
|
|
||||||
|
|
||||||
let doc = cursor.next().then((result) => {
|
|
||||||
var allitems = Array.from(result.equipped.items);
|
|
||||||
let items = allitems.filter((it) => { return it.name == name; })[0];
|
|
||||||
let ind = allitems.findIndex((it) => { return it.name == name; })
|
|
||||||
|
|
||||||
//Apply the item's effects
|
|
||||||
if (name.toLowerCase().indexOf('hp') != -1) {
|
|
||||||
let h = (result.rank - 1) + Math.round(items.cost/10);
|
|
||||||
user_dbo.updateOne({"game": {$exists: true}}, { $set: {'hpmp.hp': (result.hpmp.hp + h)}})
|
|
||||||
}
|
|
||||||
|
|
||||||
//Deal with the item itself
|
|
||||||
//If there's more than 1, subtract 1
|
|
||||||
if (items.num > 1) { items.num -= 1; allitems[ind] = items; }
|
|
||||||
else { allitems.splice(ind, 1) }
|
|
||||||
|
|
||||||
user_dbo.updateOne({'equipped.items': {$exists: true}}, {$set: {'equipped.items': allitems}});
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
changeTurn(client, bot, interaction);
|
|
||||||
postActionBar(thread, user_dbo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function cast() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function handle(client, user_dbo, other_dbo, bot, thread, command, mongouri, items, interaction, xp_collection) {
|
|
||||||
if (command == 'initalize') {
|
|
||||||
return postActionBar(thread, user_dbo);
|
|
||||||
} else if (command == 'attack') {
|
|
||||||
attack(client, user_dbo, other_dbo, bot, thread, command, mongouri, items, xp_collection, interaction);
|
|
||||||
postActionBar(thread, other_dbo);
|
|
||||||
} else if (command == 'items') {
|
|
||||||
item();
|
|
||||||
} else if (command == 'heal') {
|
|
||||||
heal(interaction, client, user_dbo, bot, thread, command, mongouri, items); //.then(() => {postActionBar(thread, other_dbo)});
|
|
||||||
} else if (command == 'usepotion') {
|
|
||||||
usePotion(interaction, client, user_dbo, bot, thread, command, mongouri);
|
|
||||||
}
|
|
||||||
|
|
||||||
// initiate(user_dbo, other_dbo, command, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { handle, postActionBar }
|
|
||||||
+73
-66
@@ -2,6 +2,9 @@ const { MongoClient, ServerApiVersion } = require('mongodb');
|
|||||||
// const { update } = require('apt');
|
// const { update } = require('apt');
|
||||||
const { Collection, Client, Formatters, Intents } = require('discord.js');
|
const { Collection, Client, Formatters, Intents } = require('discord.js');
|
||||||
const { CLIENT_ODBC } = require('mysql/lib/protocol/constants/client');
|
const { CLIENT_ODBC } = require('mysql/lib/protocol/constants/client');
|
||||||
|
const { time } = require('@discordjs/builders');
|
||||||
|
|
||||||
|
let currencySymbol = '$';
|
||||||
|
|
||||||
//Declair an "enum" to help with BASE calculations
|
//Declair an "enum" to help with BASE calculations
|
||||||
const BASE = {
|
const BASE = {
|
||||||
@@ -29,22 +32,17 @@ function isNum(arg) {
|
|||||||
|
|
||||||
|
|
||||||
function CreateNewCollection(message, client, server, id, opponent = null, game = null) {
|
function CreateNewCollection(message, client, server, id, opponent = null, game = null) {
|
||||||
client.connect(err => {
|
const db = client.db(String(server));
|
||||||
const db = client.db(String(server) + "[ECON]");
|
const dbo = db.collection(id);
|
||||||
const dbo = db.collection(id);
|
|
||||||
if (err) { return console.log(err); }
|
|
||||||
db.listCollections({name: id})
|
|
||||||
.next(function(err, collinfo) {
|
|
||||||
if (err) { return console.log(err); }
|
|
||||||
if (!collinfo) {
|
|
||||||
message.reply("You didn't have a place in my databases, so I created one for you!\nPlease try your command again!")
|
|
||||||
let hp_mp = {maxhp: BASE.HP, hp: BASE.HP, maxmp: BASE.MP, mp: BASE.MP}
|
|
||||||
dbo.insertOne({balance: 10, rank: 1, lastdayworked: 0, xp: 0, hpmp: hp_mp, game: game, opponent: opponent, state: STATE.IDLE, equipped: { weapons: {main: null, secondary: null}, items: {}}});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
client.close();
|
db.listCollections({name: id})
|
||||||
|
.next(function(err, collinfo) {
|
||||||
|
if (!collinfo) {
|
||||||
|
message.reply("You didn't have a place in my databases, so I created one for you!\nPlease try your command again!")
|
||||||
|
let hp_mp = {maxhp: BASE.HP, hp: BASE.HP, maxmp: BASE.MP, mp: BASE.MP}
|
||||||
|
dbo.insertOne({balance: 10, rank: 1, lastdayworked: 0, xp: 0, hpmp: hp_mp, game: game, gamesettings: {battle: {class: 'none', ultimate: true}}, opponent: opponent, state: STATE.IDLE, equipped: { weapons: {main: null, secondary: null}, items: {}}});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +89,11 @@ function addxp(message, dbo, amt, xp_list) {
|
|||||||
|
|
||||||
function getBalance(dbo, message) {
|
function getBalance(dbo, message) {
|
||||||
dbo.find({"balance": {$exists: true}}).toArray(function(err, doc) {
|
dbo.find({"balance": {$exists: true}}).toArray(function(err, doc) {
|
||||||
return message.reply('Your current balance is $' + String(doc[0].balance));
|
let bal = 0;
|
||||||
|
if (doc[0] && doc[0].balance) {
|
||||||
|
bal = doc[0].balance;
|
||||||
|
}
|
||||||
|
return message.reply(`<@${message.author.id}>, your current balance is ${currencySymbol}${bal}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,26 +116,25 @@ function convertCurrency(id, amt, dbo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkAndUpdateBal(dbo, item, message, args) {
|
function checkAndUpdateBal(dbo, item, message, args) {
|
||||||
let b = false;
|
return new Promise(function(resolve, reject) {
|
||||||
dbo.find({"balance": {$exists: true}}).toArray(b = function(err, doc) {
|
dbo.find({"balance": {$exists: true}}).toArray(b = function(err, doc) {
|
||||||
if (!String(doc)) {
|
if (!String(doc)) {
|
||||||
message.reply("Your account doesn't exist, please contact the mods for support");
|
message.reply("Your account doesn't exist, please contact the mods for support");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const icost = args[0] * item.cost;
|
const icost = args[0] * item.cost;
|
||||||
if (doc[0].balance < icost) {
|
if (doc[0].balance < icost) {
|
||||||
message.reply("Insufficient funds!");
|
message.reply("Insufficient funds!");
|
||||||
return false;
|
resolve(false);
|
||||||
} else {
|
} else {
|
||||||
let temp = doc[0];
|
let temp = doc[0];
|
||||||
dbo.updateOne({balance: temp.balance, rank: temp.rank, lastdayworked: temp.lastdayworked}, { $set: { balance: doc[0].balance -= icost }});
|
dbo.updateOne({balance: temp.balance, rank: temp.rank, lastdayworked: temp.lastdayworked}, { $set: { balance: doc[0].balance -= icost }});
|
||||||
message.reply("You have bought " + item.name + " for $" + icost + "!");
|
message.reply(`You have bought ${item.name} for ${currencySymbol}${icost}!`);
|
||||||
return true;
|
resolve(true);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -142,25 +143,29 @@ function buy(id, message, args, dbo, shop, xp_list) {
|
|||||||
if (!isNum(args[0])) { return message.reply("Please enter a number for query 2"); }
|
if (!isNum(args[0])) { return message.reply("Please enter a number for query 2"); }
|
||||||
|
|
||||||
let query = args[1];
|
let query = args[1];
|
||||||
let item = shop.filter(function (item) { return item.name.toLowerCase() == query.toLowerCase(); });
|
let item = shop.filter(function (item) { return item.name.toLowerCase() == query.toLowerCase(); })[0];
|
||||||
|
|
||||||
if (!String(item)) { return message.reply("This item does not exist!"); }
|
if (!String(item)) { return message.reply("This item does not exist!"); }
|
||||||
|
|
||||||
let success = Boolean(checkAndUpdateBal(dbo, item[0], message, args));
|
// let success = Boolean(checkAndUpdateBal(dbo, item, message, args));
|
||||||
if (!success) { return; }
|
checkAndUpdateBal(dbo, item, message, args).then((success) => {
|
||||||
|
if (!success) { return } //The message is handled in the CheckAndUpdateBal() function
|
||||||
|
|
||||||
var newObj = { name: item[0].name, cost: item[0].cost, icon: item[0].icon, sect: item[0].sect};
|
var newObj = { name: item.name, cost: item.cost, icon: item.icon, sect: item.sect};
|
||||||
|
|
||||||
addxp(message, dbo, Math.ceil(item[0].cost * 1.2), xp_list);
|
addxp(message, dbo, Math.ceil(item.cost * 1.2), xp_list);
|
||||||
|
|
||||||
dbo.find(newObj, {$exists: true}).toArray(function(err, doc) {
|
dbo.find(newObj, {$exists: true}).toArray(function(err, doc) {
|
||||||
if(String(doc)) {
|
if(String(doc)) {
|
||||||
let newnum = doc[0].num + Number(args[0]);
|
let newnum = doc[0].num + Number(args[0]);
|
||||||
dbo.updateOne({ name: item[0].name }, {$set: {num: newnum}});
|
dbo.updateOne({ name: item.name }, {$set: {num: newnum}});
|
||||||
} else {
|
} else {
|
||||||
dbo.insertOne({ name: item[0].name, cost: item[0].cost, icon: item[0].icon, sect: item[0].sect, num: Number(args[0])});
|
// dbo.insertOne({ name: item.name, cost: item.cost, icon: item.icon, sect: item.sect, num: Number(args[0])}); //Causes "cyclic dependancy"
|
||||||
}
|
dbo.insertOne(item);
|
||||||
});
|
dbo.updateOne(item, { $set: {num: Number(args[0]) }});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -201,7 +206,7 @@ function sell(id, message, args, dbo, shop, xp_list) {
|
|||||||
|
|
||||||
addxp(message, dbo, Math.ceil(functional_item.cost * 1.2), xp_list);
|
addxp(message, dbo, Math.ceil(functional_item.cost * 1.2), xp_list);
|
||||||
|
|
||||||
message.reply(`You've sold ${num} ${String(functional_item.name)} for $${amountSoldFor}`);
|
message.reply(`You've sold ${num} ${String(functional_item.name)} for ${currencySymbol}${amountSoldFor}`);
|
||||||
} else {
|
} else {
|
||||||
message.reply("You don't own this item!");
|
message.reply("You don't own this item!");
|
||||||
}
|
}
|
||||||
@@ -214,7 +219,7 @@ function work(dbo, message, xp_list) {
|
|||||||
let date = fulldate.getDate();
|
let date = fulldate.getDate();
|
||||||
dbo.find({"lastdayworked": {$exists: true}}).toArray(function(err, doc) {
|
dbo.find({"lastdayworked": {$exists: true}}).toArray(function(err, doc) {
|
||||||
if (!String(doc)) { return message.reply("Your account doesn't exist, please contact the mods for support"); }
|
if (!String(doc)) { return message.reply("Your account doesn't exist, please contact the mods for support"); }
|
||||||
if (doc[0].lastdayworked == 111111) {//date
|
if (doc[0].lastdayworked == date) {//date
|
||||||
message.reply("You've already worked today, try again tomorrow!");
|
message.reply("You've already worked today, try again tomorrow!");
|
||||||
} else {
|
} else {
|
||||||
//Amount to be paid
|
//Amount to be paid
|
||||||
@@ -225,7 +230,7 @@ function work(dbo, message, xp_list) {
|
|||||||
//Update the amount to the new TOTAL balance
|
//Update the amount to the new TOTAL balance
|
||||||
dbo.updateOne({"balance": {$exists: true}}, { $set: { balance: doc[0].balance + amt, lastdayworked: date }});
|
dbo.updateOne({"balance": {$exists: true}}, { $set: { balance: doc[0].balance + amt, lastdayworked: date }});
|
||||||
addxp(message, dbo, xp_earned, xp_list);
|
addxp(message, dbo, xp_earned, xp_list);
|
||||||
message.channel.send('<@' + message.author.id + '> worked and earned $' + amt +' and ' + String(xp_earned) + ' xp!');
|
message.channel.send(`<@${message.author.id}> worked and earned ${currencySymbol}${amt} and ${xp_earned} xp!`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -235,10 +240,11 @@ function printInventory(dbo, message) {
|
|||||||
let tempstring = "";
|
let tempstring = "";
|
||||||
dbo.find().toArray(function(err, docs){
|
dbo.find().toArray(function(err, docs){
|
||||||
docs.forEach(val => {
|
docs.forEach(val => {
|
||||||
if (!val.balance) {
|
if (!val.balance && val.name != undefined) {
|
||||||
tempstring += String(val.num) + " " + val.name + " (" + val.icon + ")\n";
|
tempstring += String(val.num) + " " + val.name + " (" + val.icon + ")\n";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tempstring == "") { tempstring += "You have nothing in your inventory!"; }
|
if (tempstring == "") { tempstring += "You have nothing in your inventory!"; }
|
||||||
message.reply(tempstring);
|
message.reply(tempstring);
|
||||||
});
|
});
|
||||||
@@ -266,7 +272,7 @@ function getShop(message, args, items, bot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const items2 = items.filter(function(f) { return (f.sect.toLowerCase() == args[0].toLowerCase()) }).slice((ind - 1)*10, (ind - 1)*10+10);
|
const items2 = items.filter(function(f) { return (f.sect.toLowerCase() == args[0].toLowerCase()) }).slice((ind - 1)*10, (ind - 1)*10+10);
|
||||||
newText = Formatters.codeBlock(items2.map(i => `${i.icon} (${i.name}): \$${i.cost}`).join('\n'));
|
newText = Formatters.codeBlock(items2.map(i => `${i.icon} (${i.name}): $${i.cost}`).join('\n')); //${currencySymbol} doesn't owrk for some reason
|
||||||
|
|
||||||
if (noinp) {
|
if (noinp) {
|
||||||
newText += `(Use ${bot.prefix}shop [type] [page number] to access other pages)`;
|
newText += `(Use ${bot.prefix}shop [type] [page number] to access other pages)`;
|
||||||
@@ -292,18 +298,22 @@ module.exports = {
|
|||||||
const id = message.author.id;
|
const id = message.author.id;
|
||||||
const server = message.guild.id;
|
const server = message.guild.id;
|
||||||
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
if (client.writeConcern || client.writeConcern) {
|
// if (client.writeConcern || client.writeConcern) {
|
||||||
client.close();
|
// client.close();
|
||||||
return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
// return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
||||||
}
|
// }
|
||||||
//Initialize if necessary
|
|
||||||
CreateNewCollection(message, client, server, id);
|
|
||||||
|
|
||||||
client.connect(err => {
|
|
||||||
const db = client.db(String(server) + "[ECON]");
|
bot.mongoconnection.then(async (client) => {
|
||||||
|
|
||||||
|
//Initialize if necessary
|
||||||
|
CreateNewCollection(message, client, server, id);
|
||||||
|
|
||||||
|
const db = client.db(String(server));
|
||||||
const dbo = db.collection(id);
|
const dbo = db.collection(id);
|
||||||
if (err) { return console.log(err); }
|
|
||||||
|
currencySymbol = bot.currencysymbolmmain;
|
||||||
|
|
||||||
//test area
|
//test area
|
||||||
if (command == 'xp' || command == 'adbal') {
|
if (command == 'xp' || command == 'adbal') {
|
||||||
@@ -339,9 +349,6 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Close the database
|
|
||||||
client.close();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
//Battle Updating stuff
|
//Battle Updating stuff
|
||||||
|
|||||||
@@ -1,308 +0,0 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
|
||||||
let ecoimport = require("./econ.js");
|
|
||||||
let { handle } = require("./battle.js"); //PROBLEM (CIRCULAR DEPENDANCY)
|
|
||||||
let snowflake = require("./addons/snowflake.js");
|
|
||||||
const STATE = ecoimport.STATE;
|
|
||||||
const BASE = ecoimport.BASE;
|
|
||||||
|
|
||||||
const { winGame, loseGame, equipItem } = require('./external_game_functions.js');
|
|
||||||
|
|
||||||
//Has a list of all games (used to change player state)
|
|
||||||
const allGames = ['battle'];
|
|
||||||
// const { NULL } = require('mysql/lib/protocol/constants/types');
|
|
||||||
|
|
||||||
|
|
||||||
//#region functions (NOT GAME SPECIFIC)
|
|
||||||
|
|
||||||
/** Adds the game type tag to the user(s) so the system can tell what game they're playing
|
|
||||||
* @param other_dbo optional, include if the game has two players
|
|
||||||
*/
|
|
||||||
async function Initialize(bot, user_dbo, command, message, first, second, other_dbo = null) {
|
|
||||||
return new Promise(async function(resolve, reject) {
|
|
||||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
|
||||||
let doc = docs[0];
|
|
||||||
if (allGames.indexOf(command) != -1) {
|
|
||||||
if (other_dbo != null) {
|
|
||||||
user_dbo.updateOne( { "game": {$exists: true} }, { $set: { game: command, opponent: other_dbo.s.namespace.collection, state: STATE.FIGHTING }});
|
|
||||||
other_dbo.updateOne({ "game": {$exists: true} }, { $set: { game: command, opponent: user_dbo.s.namespace.collection, state: STATE.FIGHTING }});
|
|
||||||
} else {
|
|
||||||
user_dbo.updateOne({ "game": {$exists: true} }, { $set: { game: command, state: STATE.FIGHTING }});
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { message.reply(`ERROR! ${command} IS NOT A GAME!`); }
|
|
||||||
});
|
|
||||||
|
|
||||||
//Create a new thread for the game (maybe uneccesary???) - done before initialize
|
|
||||||
let name_first = await bot.users.cache.get(first);
|
|
||||||
let name_second = await bot.users.cache.get(second);
|
|
||||||
|
|
||||||
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
|
|
||||||
const threadname = `${name_first.username} VS ${name_second.username} [${command.toUpperCase()}]`;
|
|
||||||
|
|
||||||
const thread = await message.channel.threads.create({
|
|
||||||
name: threadname,
|
|
||||||
// type: 'GUILD_PRIVATE_THREAD',
|
|
||||||
autoArchiveDuration: 60,
|
|
||||||
reason: `N/A`,
|
|
||||||
});
|
|
||||||
|
|
||||||
//Need lvl 2 boost for this
|
|
||||||
// thread.add(first);
|
|
||||||
// thread.add(second);
|
|
||||||
|
|
||||||
message.channel.send(`<@${first}> and <@${second}> have started a game of ***${command.toUpperCase()}!***`);
|
|
||||||
|
|
||||||
resolve(thread);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//replies to the message with current game specifics
|
|
||||||
function getGame(message, args, db) {
|
|
||||||
let id;
|
|
||||||
var temp;
|
|
||||||
|
|
||||||
if (args.length == 1 && String(args[0]).startsWith('<')) { id = args[0].substr(2, args[0].length - 3)}
|
|
||||||
else { id = message.author.id; }
|
|
||||||
var user_dbo = db.collection(message.author.id);
|
|
||||||
|
|
||||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
|
||||||
const doc = docs[0];
|
|
||||||
if (doc.game == null) {
|
|
||||||
return message.reply(`<@${id}> is not currently playing a game!`);
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = `<@${id}> is currently playing "${doc.game}"`;
|
|
||||||
|
|
||||||
if (doc.opponent != null) {
|
|
||||||
temp += ` with <@${doc.opponent}>`
|
|
||||||
}
|
|
||||||
|
|
||||||
message.reply(temp);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function acceptIsValid(bot, other_discord, message, msg, tag_len) {
|
|
||||||
|
|
||||||
if (other_discord == undefined) {
|
|
||||||
message.reply("This is not a valid invite!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Make sure the bot was the one creating the invite
|
|
||||||
let check0 = msg.author.bot;
|
|
||||||
|
|
||||||
//Author
|
|
||||||
let tag = msg.content.substr(2, tag_len);
|
|
||||||
let check1 = Number(tag) == Number(message.author.id);
|
|
||||||
|
|
||||||
//Time (within the last 5 min)
|
|
||||||
let prev = snowflake.convertSnowflakeToDate(msg.id);
|
|
||||||
let now = snowflake.convertSnowflakeToDate(message.id);
|
|
||||||
// @ts-ignore
|
|
||||||
let diff = now - prev;
|
|
||||||
var minutes = Math.floor((diff/1000)/60);
|
|
||||||
let check2 = minutes <= 5 || bot.inDebugMode;
|
|
||||||
|
|
||||||
if (!check0) { message.reply("really?"); }
|
|
||||||
else if (!check1 && check2) { message.reply("_INVALID USER_"); }
|
|
||||||
else if (check1 && !check2) { message.reply("_THIS INVITE EXPIRED!_"); }
|
|
||||||
else if (!check1 && !check2) { message.reply("_THIS MESSAGE HAS AN INVALID USER AND HAS EXPIRED_")}
|
|
||||||
|
|
||||||
return (check0 && check1 && check2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function hpmp(message, command, dbo) {
|
|
||||||
// throw 'THIS HAS NOT BEEN UPDATED WITH THE MOST RECENT VERSION OF THE MONGODB STRUCTURE!';
|
|
||||||
if (command == 'hp') {
|
|
||||||
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
|
||||||
return message.reply(`You have ${String(doc[0].hpmp.hp)} hp left!`);
|
|
||||||
});
|
|
||||||
} else if (command == 'mp') {
|
|
||||||
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
|
||||||
return message.reply(`You have ${String(doc[0].hpmp.hp)} mp left!`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function equip(client, message, command, dbo, bot) {
|
|
||||||
//Check if the user is already in a game
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
|
|
||||||
//#region GAME SPECIFIC
|
|
||||||
function in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection) {
|
|
||||||
|
|
||||||
//Maybe fix this later......
|
|
||||||
let turn = doc.turn;
|
|
||||||
const user1 = doc[turn];
|
|
||||||
const user2 = doc[Number(!turn)];
|
|
||||||
const db = client.db(interaction.guildId + "[ECON]");
|
|
||||||
const dbo = db.collection(user1);
|
|
||||||
const other = db.collection(user2);
|
|
||||||
const thread = interaction.channel;
|
|
||||||
|
|
||||||
dbo.find({'game': {$exists: true}}).toArray(function (err, docs) {
|
|
||||||
const game = docs[0].game
|
|
||||||
|
|
||||||
switch (game) {
|
|
||||||
case 'battle': handle(client, dbo, other, bot, thread, interaction.customId.toLowerCase(), mongouri, items, interaction, xp_collection);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports ={
|
|
||||||
name: "game",
|
|
||||||
description: "Play a game using Selmer Bot!",
|
|
||||||
async execute(bot, message, args, command, Discord, mongouri, items, xp_collection) {
|
|
||||||
|
|
||||||
if (!bot.inDebugMode) { return message.reply("This command is currently in development!"); }
|
|
||||||
|
|
||||||
|
|
||||||
//#region Setup
|
|
||||||
const id = message.author.id;
|
|
||||||
const server = message.guild.id;
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
|
||||||
if (client.writeConcern || client.writeConcern) {
|
|
||||||
client.close();
|
|
||||||
return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
|
||||||
}
|
|
||||||
|
|
||||||
const botdb = client.db('B|S' + bot.user.id);
|
|
||||||
const serverinbotdb = botdb.collection(server);
|
|
||||||
|
|
||||||
//Initialize if necessary
|
|
||||||
ecoimport.CreateNewCollection(message, client, server, id);
|
|
||||||
command = args[0];
|
|
||||||
|
|
||||||
//Check for a second person and create a second database entry if neccessary
|
|
||||||
if (message.mentions.users.first() != undefined) {
|
|
||||||
//#TODO //FIX THIS (NOT THE RIGHT CLIENT 100% OF THE TIME!!!!!!!)
|
|
||||||
ecoimport.CreateNewCollection(message, client, server, message.mentions.users.first().id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
client.connect(err => {
|
|
||||||
const db = client.db(String(server) + "[ECON]");
|
|
||||||
const dbo = db.collection(id);
|
|
||||||
if (err) { return console.log(err); }
|
|
||||||
|
|
||||||
//Check if the client is currently in a game and act accordingly
|
|
||||||
//#region Check Game
|
|
||||||
dbo.find({"game": {$exists: true}}).toArray(async function(err, docs){
|
|
||||||
if (err) { return console.log(err); }
|
|
||||||
let doc = docs[0];
|
|
||||||
let game = null;
|
|
||||||
if (doc) { game = doc.game; }
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region non-game-specific commands
|
|
||||||
//For TWO+ PLAYER games only!!!
|
|
||||||
if (command == 'accept') {
|
|
||||||
//Handle the messages
|
|
||||||
if (message.reference == null) { return message.reply("Please reply to a valid battle request message!"); }
|
|
||||||
let mid = message.reference.messageId;
|
|
||||||
let msg = await message.channel.messages.fetch(mid);
|
|
||||||
|
|
||||||
//Check if the person actually challenged you
|
|
||||||
//Get the length of any user tag
|
|
||||||
let mentioned = msg.mentions.users.keys();
|
|
||||||
|
|
||||||
let tag_len = String(mentioned.next().value).length;
|
|
||||||
|
|
||||||
//<@tage_len>, <@ --2+tag_len+2+3 = 7+tag_len
|
|
||||||
let other_tag = msg.content.substr(7+tag_len, tag_len);
|
|
||||||
|
|
||||||
const other_discord = msg.mentions.users.get(other_tag);
|
|
||||||
|
|
||||||
//Should also check if the player is already playing a game!!!
|
|
||||||
if (!acceptIsValid(bot, other_discord, message, msg, tag_len)) { return; }
|
|
||||||
|
|
||||||
//Get the opponent
|
|
||||||
const other = db.collection(other_discord.id);
|
|
||||||
let startPos = msg.content.indexOf('"') + 1;
|
|
||||||
let newCommand = msg.content.substr(startPos, msg.content.lastIndexOf('"') - startPos);
|
|
||||||
|
|
||||||
|
|
||||||
//#region BOT SECTION
|
|
||||||
|
|
||||||
//Store both IDs in the database (for turns)
|
|
||||||
let name_first = await bot.users.cache.get(id);
|
|
||||||
let name_second = await bot.users.cache.get(other_discord.id);
|
|
||||||
|
|
||||||
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
|
|
||||||
const threadname = `${name_first.username} VS ${name_second.username} [${newCommand.toUpperCase()}]`;
|
|
||||||
var newObj = {0: id, 1: other_discord.id, turn: 0, thread: threadname};
|
|
||||||
serverinbotdb.insertOne(newObj);
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
|
|
||||||
if (newCommand == 'battle') {
|
|
||||||
const result = Initialize(bot, dbo, newCommand, msg, id, other_discord.id, other);
|
|
||||||
result.then(function (thread) {
|
|
||||||
handle(client, dbo, other, bot, thread, 'initalize', mongouri, items, null, xp_collection);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (command == 'quit') {
|
|
||||||
|
|
||||||
const channel = bot.channels.cache.get(message.channel.parentId);
|
|
||||||
//Remove the turn counter from the bot's database
|
|
||||||
serverinbotdb.deleteOne({0: id} || {1: id});
|
|
||||||
if (doc.opponent != null) {
|
|
||||||
// let other = message.guild.members.cache.get(doc.opponent);
|
|
||||||
let other = db.collection(doc.opponent);
|
|
||||||
channel.send(`<@${message.author.id}> has quit a game of "${game}" with <@${doc.opponent}>!`);
|
|
||||||
winGame(client, bot, db, other, xp_collection, message);
|
|
||||||
} else {
|
|
||||||
loseGame(dbo, xp_collection, message, bot);
|
|
||||||
channel.send(`<@${message.author.id}> has quit a game of "${game}"!`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (command == 'status') {
|
|
||||||
getGame(message, args, db);
|
|
||||||
} else if (command == 'hp' || command == 'mp') {
|
|
||||||
hpmp(message, command, dbo);
|
|
||||||
} else if (command == 'equip') {
|
|
||||||
equipItem(client, bot, db, dbo, message);
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region game-specific commands
|
|
||||||
else {
|
|
||||||
if (game == 'battle' || command == 'battle') {
|
|
||||||
//Handle sending the request and making sure the user exists here
|
|
||||||
let other_discord = message.mentions.users.first();
|
|
||||||
if (other_discord == undefined) {
|
|
||||||
return message.reply(`${args[1]} is not a valid user!`);
|
|
||||||
}
|
|
||||||
|
|
||||||
message.channel.send(`${other_discord}, <@${message.author.id}> has invited you to play "battle", to accept, please reply to this message with _!game accept_`);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Catch statement (invalid command)
|
|
||||||
else {
|
|
||||||
if (command == undefined) { message.reply("Please specify a game or use _!game help_"); }
|
|
||||||
else { message.reply(`'!game ${command}' is not a command!`); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
client.close();
|
|
||||||
}, allGames, in_game_redirector
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
const { cleardb } = require('./spam_collection.js');
|
||||||
|
|
||||||
|
function devCheck(message, bot) {
|
||||||
|
const command = message.content.split(' ')[0].slice(1);
|
||||||
|
const args = message.content.split(' ')[1];
|
||||||
|
const member = bot.guilds.cache.get(bot.home_server).members.cache.get(message.author.id);
|
||||||
|
console.log(command);
|
||||||
|
//Check if they have the "Selmer Dev" role
|
||||||
|
if (member.roles.cache.has('944048889038774302')) {
|
||||||
|
switch (command) {
|
||||||
|
case 'spam_collection': if (args[0] != undefined) { cleardb(args[0]); }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { devCheck }
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
// EVERYTHING IN THIS FILE SHOULD BE ABLE TO RUN INDEPENDANTLY OF THE BOT
|
||||||
|
|
||||||
|
|
||||||
|
const Stripe = require('stripe');
|
||||||
|
const APIKey = process.env.APIKey // require('./config.json').APIKey;
|
||||||
|
const stripe = Stripe(APIKey);
|
||||||
|
const mongouri = process.env.APIKey // require('./config.json').mongooseURI;
|
||||||
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
|
|
||||||
|
|
||||||
|
function cleardb(db) {
|
||||||
|
//Triggers about a week before the end of the month and clears out all the "spam" entries
|
||||||
|
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
|
new Promise(async function(resolve, reject) {
|
||||||
|
client.connect(async (err) => {
|
||||||
|
const dbo = client.db('main').collection(db);
|
||||||
|
dbo.find({paid: false, tier: 0}).toArray((err, docs) => {
|
||||||
|
if (err) { return console.log(err); }
|
||||||
|
|
||||||
|
if (docs[0] != undefined) {
|
||||||
|
//Add them all to an array and resolve because deleting in a find() causes cyclic dependancies
|
||||||
|
resolve(docs);
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).then((docs) => {
|
||||||
|
const dbo = client.db('main').collection(db);
|
||||||
|
const d = new Date().toUTCString();
|
||||||
|
|
||||||
|
//Keep track of what was collected (chack later?)
|
||||||
|
var newObj = {db: db, date: d, count: 0, results: []};
|
||||||
|
|
||||||
|
docs.forEach(i => {
|
||||||
|
//{discord id, stripe id}
|
||||||
|
newObj.results.push({did: i.discordID, sid: i.stripeID});
|
||||||
|
newObj.count ++;
|
||||||
|
|
||||||
|
try {
|
||||||
|
//For some reason, these aren't deleted in Stripe, just archived so they can't do anything new
|
||||||
|
//See https://stripe.com/docs/api/customers/delete
|
||||||
|
stripe.customers.del(i.stripeID);
|
||||||
|
} catch (err) { console.log("err"); }
|
||||||
|
});
|
||||||
|
|
||||||
|
dbo.deleteMany({paid: false, tier: 0});
|
||||||
|
|
||||||
|
//Add the newObj to another collection (ordered by date?)
|
||||||
|
const spam_coll = client.db('main').collection("spam_collection_results");
|
||||||
|
|
||||||
|
spam_coll.insertOne(newObj);
|
||||||
|
}).catch((err) => { console.log('none'); });
|
||||||
|
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { cleardb }
|
||||||
|
|
||||||
|
//Does not include the day check, see the "selmer-bot-listener" app for that
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
const { MessageActionRow, MessageButton, MessageEmbed, DiscordAPIError, Message } = require('discord.js');
|
||||||
|
const complaintRow = new MessageActionRow();
|
||||||
|
const green = '#00f035';
|
||||||
|
const red = '#f30000';
|
||||||
|
|
||||||
|
|
||||||
|
complaintRow.setComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('SUBMITCOMPLAINT')
|
||||||
|
.setLabel('Submit Complaint')
|
||||||
|
.setStyle('DANGER') //Maybe change this to 'PRIMARY'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
function submitComplaint(message, bot) {
|
||||||
|
const complaint = message.content;
|
||||||
|
const channel = bot.guilds.cache.get(bot.home_server).channels.cache.get('998899306671124501');
|
||||||
|
|
||||||
|
const author = {
|
||||||
|
name: "Selmer Bot",
|
||||||
|
url: "",
|
||||||
|
iconURL: bot.user.displayAvatarURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
const newEmbed = new MessageEmbed()
|
||||||
|
.setColor(red)
|
||||||
|
.setTitle(`Submitted by _${message.author.username}#${message.author.discriminator} ${message.author}_ in *${message.guild}* (OPEN)`)
|
||||||
|
.setAuthor(author)
|
||||||
|
.setDescription(`Content: ${complaint}`)
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('DEBUGDONE')
|
||||||
|
.setLabel('Done')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('DEBUGURGENT')
|
||||||
|
.setLabel('Mark as Urgent')
|
||||||
|
.setStyle('DANGER'),
|
||||||
|
);
|
||||||
|
|
||||||
|
channel.send({ embeds: [newEmbed], components: [row] });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function resolveComplaint(interaction) {
|
||||||
|
if (interaction.customId == 'DEBUGDONE') {
|
||||||
|
var embd = new MessageEmbed(interaction.message.embeds[0]);
|
||||||
|
embd.setColor(green);
|
||||||
|
embd.title = embd.title.replace('(OPEN)', '(CLOSED)').replace('(URGENT)', '(CLOSED)');
|
||||||
|
interaction.update({ embeds: [embd], components: [] });
|
||||||
|
interaction.message.unpin();
|
||||||
|
} else {
|
||||||
|
var embd = new MessageEmbed(interaction.message.embeds[0]);
|
||||||
|
const row = new MessageActionRow();
|
||||||
|
row.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('DEBUGDONE')
|
||||||
|
.setLabel('Done')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
);
|
||||||
|
|
||||||
|
embd.title = embd.title.replace('(OPEN)', '(URGENT)');
|
||||||
|
interaction.update({ embeds: [embd], components: [row] });
|
||||||
|
const m = interaction.message.pin();
|
||||||
|
// m.then((msg) => {
|
||||||
|
// msg.delete();
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Complaints',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Message} message
|
||||||
|
*/
|
||||||
|
async addComplaintButton(bot, message) {
|
||||||
|
try {
|
||||||
|
function filter(reaction) {
|
||||||
|
return (reaction.emoji.name == '✅');
|
||||||
|
}
|
||||||
|
message.react('✅').then(() => {
|
||||||
|
message.awaitReactions({ filter, max: 1, time: 60000, errors: ['time'] })
|
||||||
|
.then(collected => {
|
||||||
|
const reaction = collected.first();
|
||||||
|
submitComplaint(message, bot);
|
||||||
|
})
|
||||||
|
.catch(collected => { message.reactions.cache.get('✅').remove(); });
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, submitComplaint, resolveComplaint
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
addComplaintButton(bot, message);
|
||||||
|
*/
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
const { convoManager } = require('./premium/chat.js');
|
||||||
|
const { handleInp } = require('./premium/stripe');
|
||||||
|
const reminders = require('./premium/reminders.js');
|
||||||
|
const repo = require('./Selmer Specific/repo.js');
|
||||||
|
const { MongoClient, ServerApiVersion, ConnectionClosedEvent } = require('mongodb');
|
||||||
|
|
||||||
|
function handle_dm(message, bot) {
|
||||||
|
if (message.author.bot) { return; }
|
||||||
|
|
||||||
|
if (!message.content.startsWith('!') || message.content.split(' ')[0] == '!startconvo' || message.content.split(' ')[0] == '!endconvo') {
|
||||||
|
const member = bot.guilds.cache.get(bot.home_server).members.cache.get(message.author.id);
|
||||||
|
|
||||||
|
bot.mongoconnection.then(async (client) => {
|
||||||
|
const dbo = client.db('main').collection('authorized');
|
||||||
|
dbo.find({ discordID: message.author.id }).toArray((err, docs) => {
|
||||||
|
|
||||||
|
//Only available to Selmer Bot devs, testers and "authorized" users
|
||||||
|
if (docs[0] != undefined || member.roles.cache.has('944048889038774302') || member.roles.cache.has('946610800418762792')) {
|
||||||
|
convoManager(client, bot, message);
|
||||||
|
} else {
|
||||||
|
message.reply("You have to be a premium subscriber to use this feature!\n_support coming soon_");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (message.content.indexOf('!premium') != -1) {
|
||||||
|
handleInp(bot, message);
|
||||||
|
} else if (message.content.indexOf('!reminders') != -1) {
|
||||||
|
reminders.execute(message, null, null, null, bot);
|
||||||
|
} else if (message.content.indexOf('!repo') != -1 || message.content.indexOf('!code') != -1) {
|
||||||
|
repo.execute(message, null, null, null, bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return message.reply('UNUSABLE DM COMMAND DETECTED');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Selmer Bot is conversing with them
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { handle_dm }
|
||||||
@@ -0,0 +1,328 @@
|
|||||||
|
//@ts-check
|
||||||
|
const { MessageActionRow, MessageButton, MessageSelectMenu, Client, CommandInteractionOptionResolver } = require('discord.js');
|
||||||
|
const { STATE } = require('../db/econ');
|
||||||
|
const { winGame, getCustomEmoji } = require('./external_game_functions.js');
|
||||||
|
const { changeTurn } = require('../turnManager.js');
|
||||||
|
const { game_class_battle } = require('./game_classes');
|
||||||
|
const { MongoClient } = require('mongodb');
|
||||||
|
const { convertSnowflakeToDate } = require('../db/addons/snowflake');
|
||||||
|
|
||||||
|
|
||||||
|
function postActionBar(thread, user_dbo) {
|
||||||
|
user_dbo.find({'hpmp.hp': {$exists: true}}).toArray((err, docs) => {
|
||||||
|
const hp = docs[0].hpmp.hp;
|
||||||
|
const mp = docs[0].hpmp.mp;
|
||||||
|
let row;
|
||||||
|
|
||||||
|
if (docs[0].gamesettings.battle.class != 'none' && docs[0].gamesettings.battle.ultimate) {
|
||||||
|
row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('ATTACK')
|
||||||
|
.setLabel('ATTACK')
|
||||||
|
.setStyle('DANGER'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('HEAL')
|
||||||
|
.setLabel('HEAL')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('DEFEND')
|
||||||
|
.setLabel('DEFEND')
|
||||||
|
.setStyle('PRIMARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('ULTIMATE')
|
||||||
|
.setLabel('ULTIMATE')
|
||||||
|
.setStyle('DANGER')
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//If the ultimate can't be used, change the menu
|
||||||
|
row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('ATTACK')
|
||||||
|
.setLabel('ATTACK')
|
||||||
|
.setStyle('DANGER'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('HEAL')
|
||||||
|
.setLabel('HEAL')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('DEFEND')
|
||||||
|
.setLabel('DEFEND')
|
||||||
|
.setStyle('PRIMARY'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
//UNDER DEVELOPMENT
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('ITEMS')
|
||||||
|
.setLabel('ITEMS')
|
||||||
|
.setStyle('SECONDARY')
|
||||||
|
*/
|
||||||
|
|
||||||
|
thread.send({ content: `Your turn <@${user_dbo.s.namespace.collection}>!\nHP: ${hp}\t|\tMP: ${mp}`, components: [row] });
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by "attack"
|
||||||
|
* @param {game_class_battle} gclass
|
||||||
|
*/
|
||||||
|
function attack_special(client, user_dbo, other_dbo, bot, thread, xp_collection, interaction, gclass) {
|
||||||
|
const atk = gclass.specialAttack;
|
||||||
|
if (!atk) { return thread.send("You don't have a class, and so can't use an ultimate!"); }
|
||||||
|
|
||||||
|
user_dbo.find({'rank': {$exists: true}}).toArray((err, docs) => {
|
||||||
|
const doc = docs[0];
|
||||||
|
|
||||||
|
//Check if the user can use ultimate
|
||||||
|
if (atk.dmg.split('*')[0] == 'r') {
|
||||||
|
const rank = doc.rank;
|
||||||
|
const dmg = Number(atk.dmg.split('*')[1]) * rank;
|
||||||
|
attack(client, user_dbo, other_dbo, bot, thread, xp_collection, interaction, dmg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Apply a "stunned" effect
|
||||||
|
if (atk.prone == true) {
|
||||||
|
other_dbo.updateOne({'state': {$exists: true}}, {$set: {state: STATE.PRONE}});
|
||||||
|
thread.send(`<@${interaction.user.id}> was knocked prone and lost 1 turn!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeTurn(client, bot, interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Bow special phrase: Σ>―(´・ω・`)→
|
||||||
|
function attack(client, user_dbo, other_dbo, bot, thread, xp_collection, interaction, preset_damage = 0) {
|
||||||
|
//Get the weapon
|
||||||
|
user_dbo.find({'equipped': {$exists: true}}).toArray(function(err, docs) {
|
||||||
|
const doc = docs[0];
|
||||||
|
const all_weapons = doc.equipped.weapons;
|
||||||
|
const weapon = all_weapons.main;
|
||||||
|
|
||||||
|
var dmg = 0;
|
||||||
|
|
||||||
|
//No weapons (punch)
|
||||||
|
if (preset_damage > 0) {
|
||||||
|
dmg = preset_damage;
|
||||||
|
} else {
|
||||||
|
if (weapon == null) {
|
||||||
|
dmg = doc.rank;
|
||||||
|
} else {
|
||||||
|
dmg = (doc.rank - 1) + Math.round(weapon.cost/5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
other_dbo.find({'equipped': {$exists: true}}).toArray(function (err, docs) {
|
||||||
|
const odoc = docs[0];
|
||||||
|
|
||||||
|
//Handle defending
|
||||||
|
if (odoc.state == STATE.DEFENDING) {
|
||||||
|
var def = odoc.rank - doc.rank;
|
||||||
|
//Make sure we don't go negative
|
||||||
|
if (def < 0) { def = 0; }
|
||||||
|
|
||||||
|
dmg /= 2 + def;
|
||||||
|
}
|
||||||
|
|
||||||
|
var new_hp = odoc.hpmp.hp -= dmg;
|
||||||
|
if (new_hp <= 0) {
|
||||||
|
winGame(client, bot, client.db(user_dbo.s.namespace.db), user_dbo, xp_collection, interaction.message);
|
||||||
|
} else {
|
||||||
|
other_dbo.updateOne({'equipped': {$exists: true}}, { $set: { 'hpmp.hp': new_hp, state: STATE.FIGHTING }});
|
||||||
|
|
||||||
|
//Change turns
|
||||||
|
changeTurn(client, bot, interaction);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
//Check for a "special" animation
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function heal(interaction, client, user_dbo, bot, thread, command, mongouri, items) {
|
||||||
|
if (interaction.message.content.toLowerCase().indexOf('Which item would you like to use?') != -1) {
|
||||||
|
// The person picked out an item
|
||||||
|
//I think this is unecessary
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the 'healing' items (stored in "{item}: num" format)
|
||||||
|
user_dbo.find({'equipped': {$exists: true}}).toArray(async function(err, docs) {
|
||||||
|
const doc = docs[0];
|
||||||
|
const rawitems = doc.equipped.items;
|
||||||
|
if (JSON.stringify(rawitems) == '{}') {
|
||||||
|
interaction.editReply("You don't have any items!");
|
||||||
|
return postActionBar(thread, user_dbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(rawitems);
|
||||||
|
const items = rawitems.filter(function(f) { return (f.sect.toLowerCase() == 'hp') });
|
||||||
|
|
||||||
|
if (JSON.stringify(items) == '[]') {
|
||||||
|
interaction.editReply("You don't have any healing items!");
|
||||||
|
return postActionBar(thread, user_dbo);
|
||||||
|
} else { console.log(JSON.stringify(items))}
|
||||||
|
|
||||||
|
var itemlist = [];
|
||||||
|
|
||||||
|
items.forEach(function(item) {
|
||||||
|
let n = item.name;
|
||||||
|
|
||||||
|
let h = (doc.rank - 1) + Math.round(item.cost/10);
|
||||||
|
|
||||||
|
itemlist.push({label: n, description: `Restores ${h} health (${item.num})`, value: `${n}`});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//Find something to heal with
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageSelectMenu()
|
||||||
|
.setCustomId(`${interaction.user.id}|heal`)
|
||||||
|
.setPlaceholder('Nothing selected')
|
||||||
|
.addOptions(itemlist),
|
||||||
|
);
|
||||||
|
|
||||||
|
await interaction.editReply({ content: 'Please choose a health potion!', components: [row] });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Gets items by section/name, reacts with them to the message, when pressed, trigger a response
|
||||||
|
function presentItems(interaction, client, user_dbo, bot, thread) {
|
||||||
|
// throw 'THE "ITEM" COMMAND HAS NOT BEEN SET UP YET!';
|
||||||
|
user_dbo.find({'equipped': {$exists: true}}).toArray(async function(err, docs) {
|
||||||
|
const doc = docs[0];
|
||||||
|
const items = doc.equipped.items;
|
||||||
|
// const items = rawitems.filter(function(f) { return (f.sect.toLowerCase() == 'hp') });
|
||||||
|
|
||||||
|
|
||||||
|
if (JSON.stringify(items) == '[]' || JSON.stringify(items) == '{}') {
|
||||||
|
interaction.editReply("You don't have any items!");
|
||||||
|
return postActionBar(thread, user_dbo);
|
||||||
|
} else { console.log(JSON.stringify(items))}
|
||||||
|
|
||||||
|
var itemlist = [];
|
||||||
|
|
||||||
|
items.forEach(function(item) {
|
||||||
|
let n = item.name;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
itemlist.push({label: n, description: `${item.num} equipped!`, value: `${n}`});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//Find something to heal with
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageSelectMenu()
|
||||||
|
.setCustomId(`${interaction.user.id}|item`)
|
||||||
|
.setPlaceholder('Nothing selected')
|
||||||
|
.addOptions(itemlist)
|
||||||
|
);
|
||||||
|
|
||||||
|
await interaction.editReply({ content: 'Please choose an item!', components: [row] });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function defend(client, interaction, user_dbo, bot, thread) {
|
||||||
|
user_dbo.find({'equipped': {$exists: true}}).toArray(function(err, docs) {
|
||||||
|
const doc = docs[0];
|
||||||
|
const all_weapons = doc.equipped.weapons;
|
||||||
|
|
||||||
|
//They don't have a shield
|
||||||
|
if (all_weapons == undefined) {
|
||||||
|
thread.send("You don't have a shield equipped!");
|
||||||
|
}
|
||||||
|
const shield = all_weapons.secondary;
|
||||||
|
|
||||||
|
//Change state
|
||||||
|
user_dbo.updateOne({state: {$exists: true}}, {$set: {state: STATE.DEFENDING}});
|
||||||
|
|
||||||
|
changeTurn(client, bot, interaction);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function usePotion(interaction, client, user_dbo, bot, thread) {
|
||||||
|
const name = interaction.values[0];
|
||||||
|
const cursor = user_dbo.find({'equipped.items': {$exists: true}});
|
||||||
|
|
||||||
|
let doc = cursor.next().then((result) => {
|
||||||
|
var allitems = Array.from(result.equipped.items);
|
||||||
|
let items = allitems.filter((it) => { return it.name == name; })[0];
|
||||||
|
let ind = allitems.findIndex((it) => { return it.name == name; })
|
||||||
|
|
||||||
|
//Apply the item's effects
|
||||||
|
if (name.toLowerCase().indexOf('hp') != -1) {
|
||||||
|
let h = (result.rank - 1) + Math.round(items.cost/10);
|
||||||
|
user_dbo.updateOne({"game": {$exists: true}}, { $set: {'hpmp.hp': (result.hpmp.hp + h)}})
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deal with the item itself
|
||||||
|
//If there's more than 1, subtract 1
|
||||||
|
if (items.num > 1) { items.num -= 1; allitems[ind] = items; }
|
||||||
|
else { allitems.splice(ind, 1) }
|
||||||
|
|
||||||
|
user_dbo.updateOne({'equipped.items': {$exists: true}}, {$set: {'equipped.items': allitems}});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
changeTurn(client, bot, interaction);
|
||||||
|
postActionBar(thread, user_dbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cast() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {MongoClient} client
|
||||||
|
* @param {*} user_dbo
|
||||||
|
* @param {*} other_dbo
|
||||||
|
* @param {Client} bot
|
||||||
|
* @param {*} thread
|
||||||
|
* @param {String} command
|
||||||
|
* @param {String} mongouri
|
||||||
|
* @param {String[]} items
|
||||||
|
* @param {*} interaction
|
||||||
|
* @param {Map<string, Map>} xp_collection
|
||||||
|
*/
|
||||||
|
async function handle(client, user_dbo, other_dbo, bot, thread, command, mongouri, items, interaction, xp_collection) {
|
||||||
|
|
||||||
|
if (command == 'initalize') {
|
||||||
|
return postActionBar(thread, user_dbo);
|
||||||
|
} else if (command == 'attack') {
|
||||||
|
attack(client, user_dbo, other_dbo, bot, thread, xp_collection, interaction);
|
||||||
|
postActionBar(thread, other_dbo);
|
||||||
|
} else if (command == 'items') {
|
||||||
|
presentItems(interaction, client, user_dbo, bot, thread); //Maybe like wands?
|
||||||
|
} else if (command == 'heal') {
|
||||||
|
heal(interaction, client, user_dbo, bot, thread, command, mongouri, items); //.then(() => {postActionBar(thread, other_dbo)});
|
||||||
|
} else if (command == 'usepotion') {
|
||||||
|
usePotion(interaction, client, user_dbo, bot, thread);
|
||||||
|
} else if (command == 'defend') {
|
||||||
|
defend(client, interaction, user_dbo, bot, thread);
|
||||||
|
postActionBar(thread, user_dbo);
|
||||||
|
} else if (command == 'ultimate') {
|
||||||
|
user_dbo.find({'gamesettings': {$exists: true}}).toArray((err, docs) => {
|
||||||
|
var gclass = new game_class_battle(docs[0].gamesettings.battle.class);
|
||||||
|
attack_special(client, user_dbo, other_dbo, bot, thread, xp_collection, interaction, gclass);
|
||||||
|
postActionBar(thread, user_dbo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { handle, postActionBar }
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
//@ts-check
|
//@ts-check
|
||||||
const { addxp, STATE, BASE } = require("./econ.js");
|
const { addxp, STATE, BASE } = require("../db/econ");
|
||||||
const turnManger = require('../turnManager.js');
|
const turnManger = require('../turnManager.js');
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
|
||||||
|
|
||||||
//#region game lose/win
|
//#region game lose/win
|
||||||
@@ -8,13 +9,18 @@ function loseGame(user_dbo, xp_collection, message, bot = null) {
|
|||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
||||||
const doc = docs[0];
|
const doc = docs[0];
|
||||||
if (doc == undefined) { return message.reply("Oops! There's been an error! Please contact support if this problem persists!"); }
|
if (doc == undefined) {
|
||||||
|
message.reply("Oops! There's been an error, click the ✅ to report this!");
|
||||||
|
addComplaintButton(bot, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (doc.game == null) { return message.reply("You're not even in a game and you're trying to quit! Sad..."); }
|
if (doc.game == null) { return message.reply("You're not even in a game and you're trying to quit! Sad..."); }
|
||||||
|
|
||||||
|
var addbal;
|
||||||
//If this function was called from "winGame", return
|
//If this function was called from "winGame", return
|
||||||
if (doc.opponent) {
|
if (doc.opponent) {
|
||||||
//If remove some money (looting) [maybe implement a "friendly" game setting later with no looting]
|
//If remove some money (looting) [maybe implement a "friendly" game setting later with no looting]
|
||||||
var addbal = doc.rank * 2;
|
addbal = doc.rank * 2;
|
||||||
if (doc.balance - addbal < 5) { addbal = addbal - doc.balance; }
|
if (doc.balance - addbal < 5) { addbal = addbal - doc.balance; }
|
||||||
if (doc.balance > 5) {
|
if (doc.balance > 5) {
|
||||||
user_dbo.updateOne(doc, { $set: { balance: doc.balance - addbal}});
|
user_dbo.updateOne(doc, { $set: { balance: doc.balance - addbal}});
|
||||||
@@ -32,7 +38,7 @@ function loseGame(user_dbo, xp_collection, message, bot = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function winGame(client, bot, db, user_dbo, xp_collection, message) {
|
function winGame(client, bot, db, user_dbo, xp_collection, message, singlePlayer = false) {
|
||||||
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
||||||
const doc = docs[0];
|
const doc = docs[0];
|
||||||
|
|
||||||
@@ -48,24 +54,35 @@ function winGame(client, bot, db, user_dbo, xp_collection, message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Delete the bot's record of the game
|
//Delete the bot's record of the game
|
||||||
client.db('B|S' + bot.user.id).collection(user_dbo.s.namespace.db.substr(0, user_dbo.s.namespace.db.length - 6)).drop();
|
if (!singlePlayer) {
|
||||||
|
client.db('B|S' + bot.user.id).collection(message.guild.id).drop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Update the player with xp
|
//Update the player with xp
|
||||||
user_dbo.updateOne({"game": {$exists: true}}, { $set: { game: null, opponent: null, state: STATE.IDLE, xp: doc.xp + (BASE.XP * doc.rank), 'hpmp.hp': doc.hpmp.maxhp, 'hpmp.mp': doc.hpmp.maxmp }});
|
user_dbo.updateOne({"game": {$exists: true}}, { $set: { game: null, opponent: null, state: STATE.IDLE, xp: doc.xp + (BASE.XP * doc.rank), 'hpmp.hp': doc.hpmp.maxhp, 'hpmp.mp': doc.hpmp.maxmp }});
|
||||||
|
|
||||||
|
if (!singlePlayer) {
|
||||||
|
const channel = bot.channels.cache.get(message.channel.parentId);
|
||||||
|
channel.send(`<@${user_dbo.s.namespace.collection}> just won a game of "${docs[0].game}"!`);
|
||||||
|
}
|
||||||
message.channel.delete();
|
message.channel.delete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function equipItem(client, bot, db, dbo, message) {
|
function equipItem(client, bot, db, dbo, message) {
|
||||||
|
|
||||||
if (!bot.inDebugMode) { return; }
|
if (!bot.inDebugMode) { return; }
|
||||||
let items = [
|
let items = [
|
||||||
{ name: 'HP Potion', cost: 20, icon: 'CUSTOM|healing_potion', sect: 'HP', num: 2 },
|
{ name: 'HP Potion', cost: 20, icon: 'CUSTOM|healing_potion', sect: 'HP', num: 2 },
|
||||||
{ name: 'Super HP Potion', cost: 50, icon: 'CUSTOM|super_healing_potion', sect: 'HP', num: 2 },
|
{ name: 'Super HP Potion', cost: 50, icon: 'CUSTOM|super_healing_potion', sect: 'HP', num: 2 },
|
||||||
{ name: 'MP Potion', cost: 15, icon: 'CUSTOM|mana_potion', sect: 'MP', num: 2 }
|
{ name: 'MP Potion', cost: 15, icon: 'CUSTOM|mana_potion', sect: 'MP', num: 2 }
|
||||||
]
|
]
|
||||||
|
for (let i = 1; i <= 10; i ++) {
|
||||||
|
|
||||||
|
items.push({ name: `${String.fromCharCode(i + 64)}`, cost: i * 10, icon: 'N/A', sect: 'N/A', num: i })
|
||||||
|
}
|
||||||
|
|
||||||
dbo.updateMany({}, {$set: {'equipped.items': items}});
|
dbo.updateMany({}, {$set: {'equipped.items': items}});
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,412 @@
|
|||||||
|
// // @ts-check //Disabled
|
||||||
|
|
||||||
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
|
let ecoimport = require("../db/econ.js");
|
||||||
|
|
||||||
|
//#region Game Imports
|
||||||
|
const battle = require("./battle.js");
|
||||||
|
const ttt = require('./tictactoe.js');
|
||||||
|
const trivia = require('./trivia.js');
|
||||||
|
const mnswpr = require('./minesweeper.js');
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
let snowflake = require("../db/addons/snowflake.js");
|
||||||
|
const STATE = ecoimport.STATE;
|
||||||
|
const BASE = ecoimport.BASE;
|
||||||
|
|
||||||
|
const { winGame, loseGame, equipItem } = require('./external_game_functions.js');
|
||||||
|
const { chooseClass, presentClasses } = require('./game_classes.js');
|
||||||
|
|
||||||
|
//Has a list of all games (used to change player state)
|
||||||
|
const allGames = ['battle', 'Tic Tac Toe'];
|
||||||
|
// const { NULL } = require('mysql/lib/protocol/constants/types');
|
||||||
|
|
||||||
|
|
||||||
|
//#region functions (NOT GAME SPECIFIC)
|
||||||
|
|
||||||
|
/** Adds the game type tag to the user(s) so the system can tell what game they're playing
|
||||||
|
* @param other_dbo optional, include if the game has two players
|
||||||
|
*/
|
||||||
|
async function Initialize(bot, user_dbo, command, message, first, second, other_dbo = null) {
|
||||||
|
return new Promise(async function(resolve, reject) {
|
||||||
|
user_dbo.findOne({"game": {$exists: true}}).then(function(doc){
|
||||||
|
if (allGames.indexOf(command) != -1) {
|
||||||
|
if (other_dbo != null) {
|
||||||
|
user_dbo.updateOne( { "game": {$exists: true} }, { $set: { game: command, opponent: other_dbo.s.namespace.collection, state: STATE.FIGHTING }});
|
||||||
|
other_dbo.updateOne({ "game": {$exists: true} }, { $set: { game: command, opponent: user_dbo.s.namespace.collection, state: STATE.FIGHTING }});
|
||||||
|
} else {
|
||||||
|
user_dbo.updateOne({ "game": {$exists: true} }, { $set: { game: command, state: STATE.FIGHTING }});
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { message.reply(`ERROR! ${command} IS NOT A GAME!`); }
|
||||||
|
});
|
||||||
|
|
||||||
|
//Create a new thread for the game (maybe uneccesary???) - done before initialize
|
||||||
|
let name_first = await bot.users.cache.get(first);
|
||||||
|
let name_second = await bot.users.cache.get(second);
|
||||||
|
|
||||||
|
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
|
||||||
|
const threadname = `${name_first.username} VS ${name_second.username} [${command.toUpperCase()}]`;
|
||||||
|
|
||||||
|
const thread = await message.channel.threads.create({
|
||||||
|
name: threadname,
|
||||||
|
// type: 'GUILD_PRIVATE_THREAD',
|
||||||
|
autoArchiveDuration: 60,
|
||||||
|
reason: `N/A`,
|
||||||
|
});
|
||||||
|
|
||||||
|
//Need lvl 2 boost for this
|
||||||
|
// thread.add(first);
|
||||||
|
// thread.add(second);
|
||||||
|
|
||||||
|
message.channel.send(`<@${first}> and <@${second}> have started a game of ***${command.toUpperCase()}!***`);
|
||||||
|
|
||||||
|
resolve(thread);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//replies to the message with current game specifics
|
||||||
|
function getGame(message, args, db) {
|
||||||
|
let id;
|
||||||
|
var temp;
|
||||||
|
|
||||||
|
if (args.length == 1 && String(args[0]).startsWith('<')) { id = args[0].substr(2, args[0].length - 3)}
|
||||||
|
else { id = message.author.id; }
|
||||||
|
var user_dbo = db.collection(message.author.id);
|
||||||
|
|
||||||
|
user_dbo.find({"game": {$exists: true}}).toArray(function(err, docs){
|
||||||
|
const doc = docs[0];
|
||||||
|
if (doc.game == null) {
|
||||||
|
return message.reply(`<@${id}> is not currently playing a game!`);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = `<@${id}> is currently playing "${doc.game}"`;
|
||||||
|
|
||||||
|
if (doc.opponent != null) {
|
||||||
|
temp += ` with <@${doc.opponent}>`
|
||||||
|
}
|
||||||
|
|
||||||
|
message.reply(temp);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function acceptIsValid(bot, other_discord, message, msg, tag_len) {
|
||||||
|
|
||||||
|
if (other_discord == undefined) {
|
||||||
|
message.reply("This is not a valid invite!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure the bot was the one creating the invite
|
||||||
|
let check0 = msg.author.bot;
|
||||||
|
|
||||||
|
//Author
|
||||||
|
let tag = msg.content.substr(2, tag_len);
|
||||||
|
let check1 = Number(tag) == Number(message.author.id);
|
||||||
|
|
||||||
|
//Time (within the last 5 min)
|
||||||
|
let prev = snowflake.convertSnowflakeToDate(msg.id);
|
||||||
|
let now = snowflake.convertSnowflakeToDate(message.id);
|
||||||
|
// @ts-ignore
|
||||||
|
let diff = now - prev;
|
||||||
|
var minutes = Math.floor((diff/1000)/60);
|
||||||
|
let check2 = minutes <= 5 || bot.inDebugMode;
|
||||||
|
|
||||||
|
if (!check0) { message.reply("really?"); }
|
||||||
|
else if (!check1 && check2) { message.reply("_INVALID USER_"); }
|
||||||
|
else if (check1 && !check2) { message.reply("_THIS INVITE EXPIRED!_"); }
|
||||||
|
else if (!check1 && !check2) { message.reply("_THIS MESSAGE HAS AN INVALID USER AND HAS EXPIRED_")}
|
||||||
|
|
||||||
|
return (check0 && check1 && check2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function hpmp(message, command, dbo) {
|
||||||
|
// throw 'THIS HAS NOT BEEN UPDATED WITH THE MOST RECENT VERSION OF THE MONGODB STRUCTURE!';
|
||||||
|
if (command == 'hp') {
|
||||||
|
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
||||||
|
return message.reply(`You have ${String(doc[0].hpmp.hp)} hp left!`);
|
||||||
|
});
|
||||||
|
} else if (command == 'mp') {
|
||||||
|
dbo.find({"hpmp": {$exists: true}}).toArray(function(err, doc) {
|
||||||
|
return message.reply(`You have ${String(doc[0].hpmp.hp)} mp left!`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function equip(message, args, command, dbo, bot, shop) {
|
||||||
|
const inp = args[1];
|
||||||
|
if (!inp) { return message.reply("Please provide input (either a weapon for main or shield for secondary)")}
|
||||||
|
|
||||||
|
//Check if the user is already in a game
|
||||||
|
dbo.find({'game': {$exists: true}}).toArray(function(err, docs) {
|
||||||
|
const doc = docs[0];
|
||||||
|
|
||||||
|
if (doc.game != null) {
|
||||||
|
ret = true;
|
||||||
|
// console.log(doc.game);
|
||||||
|
return message.reply('You can\'t equip while in a game!');
|
||||||
|
}
|
||||||
|
|
||||||
|
//If the thing is a shield, add it to secondary
|
||||||
|
if (inp.toLowerCase().indexOf('shield') != -1) {
|
||||||
|
dbo.find({def: true}).toArray(function(err, docs) {
|
||||||
|
if (docs[0] != undefined) {
|
||||||
|
dbo.updateOne({}, {$set: {'equipped.weapons.secondary': docs[0]}});
|
||||||
|
} else {
|
||||||
|
message.reply("You don't own a shield!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//Else, equip the weapon(s)
|
||||||
|
|
||||||
|
dbo.find({name: inp, sect: 'Weapons'}).toArray(function(err, docs) {
|
||||||
|
if (docs[0] != undefined) {
|
||||||
|
//Equip the weapon
|
||||||
|
dbo.updateOne({}, {$set: {'equipped.weapons.main': docs[0]}});
|
||||||
|
} else {
|
||||||
|
message.reply(`You don't own any ${inp}s!`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#region Game Handlers
|
||||||
|
|
||||||
|
function in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection) {
|
||||||
|
|
||||||
|
//Maybe fix this later......
|
||||||
|
let turn = doc.turn;
|
||||||
|
const user1 = doc[turn];
|
||||||
|
const user2 = doc[Number(!turn)];
|
||||||
|
const db = client.db(interaction.guildId);
|
||||||
|
const dbo = db.collection(user1);
|
||||||
|
const other = db.collection(user2);
|
||||||
|
const thread = interaction.channel;
|
||||||
|
|
||||||
|
dbo.find({'game': {$exists: true}}).toArray(function (err, docs) {
|
||||||
|
const game = docs[0].game
|
||||||
|
|
||||||
|
switch (game) {
|
||||||
|
case 'battle': battle.handle(client, dbo, other, bot, thread, interaction.customId.toLowerCase(), mongouri, items, interaction, xp_collection);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Tic Tac Toe': ttt.handle(client, db, dbo, other, bot, thread, null, doc, interaction, xp_collection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports ={
|
||||||
|
name: "game",
|
||||||
|
description: "Play a game using Selmer Bot!",
|
||||||
|
async execute(bot, message, args, command, Discord, mongouri, items, xp_collection) {
|
||||||
|
|
||||||
|
|
||||||
|
//#region Setup
|
||||||
|
const id = message.author.id;
|
||||||
|
const server = message.guild.id;
|
||||||
|
|
||||||
|
// // @ts-ignore
|
||||||
|
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
|
// if (client.writeConcern || client.writeConcern) {
|
||||||
|
// client.close();
|
||||||
|
// return message.reply("Something went wrong with the database, please try again later and contact support if this problem persists!");
|
||||||
|
// }
|
||||||
|
var client;
|
||||||
|
await bot.mongoconnection.then((client1) => {
|
||||||
|
client = client1;
|
||||||
|
});
|
||||||
|
|
||||||
|
const botdb = client.db('B|S' + bot.user.id);
|
||||||
|
const serverinbotdb = botdb.collection(server);
|
||||||
|
|
||||||
|
//Initialize if necessary
|
||||||
|
ecoimport.CreateNewCollection(message, client, server, id);
|
||||||
|
command = args[0];
|
||||||
|
|
||||||
|
//Check for a second person and create a second database entry if neccessary
|
||||||
|
if (message.mentions.users.first() != undefined) {
|
||||||
|
ecoimport.CreateNewCollection(message, client, server, message.mentions.users.first().id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
const db = client.db(String(server));
|
||||||
|
const dbo = db.collection(id);
|
||||||
|
|
||||||
|
//Check if the client is currently in a game and act accordingly
|
||||||
|
//#region Check Game
|
||||||
|
dbo.find({"game": {$exists: true}}).toArray(async function(err, docs) {
|
||||||
|
if (err) { return console.log(err); }
|
||||||
|
let doc = docs[0];
|
||||||
|
let game = null;
|
||||||
|
if (doc) { game = doc.game; }
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region non-game-specific commands
|
||||||
|
//For TWO+ PLAYER games only!!!
|
||||||
|
if (command == 'accept') {
|
||||||
|
//Handle the messages
|
||||||
|
if (message.reference == null) { return message.reply("Please reply to a valid battle request message!"); }
|
||||||
|
let mid = message.reference.messageId;
|
||||||
|
let msg = await message.channel.messages.fetch(mid);
|
||||||
|
|
||||||
|
//Check if the person actually challenged you
|
||||||
|
//Get the length of any user tag
|
||||||
|
let mentioned = msg.mentions.users.keys();
|
||||||
|
|
||||||
|
let tag_len = String(mentioned.next().value).length;
|
||||||
|
|
||||||
|
//<@tage_len>, <@ --2+tag_len+2+3 = 7+tag_len
|
||||||
|
let other_tag = msg.content.substr(7+tag_len, tag_len);
|
||||||
|
|
||||||
|
const other_discord = msg.mentions.users.get(other_tag);
|
||||||
|
|
||||||
|
//Should also check if the player is already playing a game!!!
|
||||||
|
if (!acceptIsValid(bot, other_discord, message, msg, tag_len)) { return; }
|
||||||
|
|
||||||
|
//Get the opponent
|
||||||
|
const other = db.collection(other_discord.id);
|
||||||
|
let startPos = msg.content.indexOf('"') + 1;
|
||||||
|
let newCommand = msg.content.substr(startPos, msg.content.lastIndexOf('"') - startPos);
|
||||||
|
|
||||||
|
|
||||||
|
//#region BOT SECTION
|
||||||
|
|
||||||
|
//Store both IDs in the database (for turns)
|
||||||
|
let name_first = await bot.users.cache.get(id);
|
||||||
|
let name_second = await bot.users.cache.get(other_discord.id);
|
||||||
|
|
||||||
|
// message.reply(`${first} [${name_first}], ${second} [${name_second}]`); throw 'ERR';
|
||||||
|
const threadname = `${name_first.username} VS ${name_second.username} [${newCommand.toUpperCase()}]`;
|
||||||
|
var newObj = {0: id, 1: other_discord.id, turn: 0, thread: threadname};
|
||||||
|
|
||||||
|
if (newCommand.replaceAll(" ", "").toLowerCase() == 'tictactoe') { newCommand = 'Tic Tac Toe'; }
|
||||||
|
|
||||||
|
if (newCommand === 'Tic Tac Toe') {
|
||||||
|
//Create the new board
|
||||||
|
let newboard = ["", "", "", "", "", "", "", "", ""];
|
||||||
|
newObj.board = newboard;
|
||||||
|
let symbols;
|
||||||
|
|
||||||
|
/*DOES NOT WORK
|
||||||
|
if (msg.content.lastIndexOf('>') == msg.content.lenth) {
|
||||||
|
symbols = ['X', 'O'];
|
||||||
|
} else {
|
||||||
|
symbols = msg.content.substring(msg.content.lastIndexOf('>') + 2).split(' ');
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
newObj.symbols = ['X', 'O'];
|
||||||
|
}
|
||||||
|
|
||||||
|
serverinbotdb.insertOne(newObj);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Need this for all 2 player games
|
||||||
|
const result = Initialize(bot, dbo, newCommand, msg, id, other_discord.id, other);
|
||||||
|
|
||||||
|
if (newCommand == 'battle') {
|
||||||
|
result.then(function (thread) {
|
||||||
|
battle.handle(client, dbo, other, bot, thread, 'initalize', mongouri, items, null, xp_collection);
|
||||||
|
});
|
||||||
|
} else if (newCommand == 'Tic Tac Toe') {
|
||||||
|
result.then(function (thread) {
|
||||||
|
ttt.handle(client, db, dbo, other, bot, thread, 'initalize', mongouri, null, xp_collection);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (command == 'quit') {
|
||||||
|
|
||||||
|
const channel = bot.channels.cache.get(message.channel.parentId);
|
||||||
|
//Remove the turn counter from the bot's database
|
||||||
|
serverinbotdb.deleteOne({0: id} || {1: id});
|
||||||
|
if (doc.opponent != null) {
|
||||||
|
// let other = message.guild.members.cache.get(doc.opponent);
|
||||||
|
let other = db.collection(doc.opponent);
|
||||||
|
channel.send(`<@${message.author.id}> has quit a game of "${game}" with <@${doc.opponent}>!`);
|
||||||
|
winGame(client, bot, db, other, xp_collection, message);
|
||||||
|
} else {
|
||||||
|
loseGame(dbo, xp_collection, message, bot);
|
||||||
|
channel.send(`<@${message.author.id}> has quit a game of "${game}"!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == 'status') {
|
||||||
|
getGame(message, args, db);
|
||||||
|
} else if (command == 'hp' || command == 'mp') {
|
||||||
|
hpmp(message, command, dbo);
|
||||||
|
} else if (command == 'equip') {
|
||||||
|
// equipItem(client, bot, db, dbo, message);
|
||||||
|
equip(message, args, command, dbo, bot, items);
|
||||||
|
} else if (command == 'classes') {
|
||||||
|
presentClasses(message, args[1]);
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region game-specific commands
|
||||||
|
else {
|
||||||
|
if (command == undefined) { return message.reply("Please specify a game or use _!game help_"); }
|
||||||
|
|
||||||
|
//Make change to new name if necessary
|
||||||
|
if (command.replaceAll(" ", "").toLowerCase() == 'tictactoe') { command = 'Tic Tac Toe'; }
|
||||||
|
|
||||||
|
if (game == 'battle' || command == 'battle') {
|
||||||
|
if (!bot.inDebugMode) { return message.reply("This command is currently in development!"); }
|
||||||
|
|
||||||
|
//Handle sending the request and making sure the user exists here
|
||||||
|
let other_discord = message.mentions.users.first();
|
||||||
|
if (other_discord == undefined) {
|
||||||
|
return message.reply(`"${args[1]}" is not a valid user (use _!game battle @user_)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.channel.send(`${other_discord}, <@${message.author.id}> has invited you to play _"battle"_. To accept, please reply to this message with _!game accept_`);
|
||||||
|
} else if (game == 'Tic Tac Toe' || command == 'Tic Tac Toe') {
|
||||||
|
let other_discord = message.mentions.users.first();
|
||||||
|
if (other_discord == undefined) {
|
||||||
|
return message.reply(`"${args[1]}" is not a valid user (use _!game tictactoe @user_)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.channel.send(`${other_discord}, <@${message.author.id}> has invited you to play _"Tic Tac Toe"_. To accept, please reply to this message with _!game accept_`);
|
||||||
|
} else if (game == 'trivia' || command == 'trivia') {
|
||||||
|
trivia.execute(message, args, Discord, client, bot);
|
||||||
|
} else if (game == "minesweeper" || command == 'minesweeper') {
|
||||||
|
if (game == "minesweeper" && command == 'minesweeper') {
|
||||||
|
return message.reply("You're already in a game!");
|
||||||
|
}
|
||||||
|
const threadname = `${message.author.username} has started a solo game of Minesweeper`;
|
||||||
|
const thread = await message.channel.threads.create({
|
||||||
|
name: threadname,
|
||||||
|
// type: 'GUILD_PRIVATE_THREAD',
|
||||||
|
autoArchiveDuration: 60,
|
||||||
|
reason: `N/A`,
|
||||||
|
});
|
||||||
|
mnswpr.handle(bot, null, thread, message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Catch statement (invalid command)
|
||||||
|
else {
|
||||||
|
message.reply(`'${bot.prefix}game ${command}' is not a command!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
});
|
||||||
|
}, allGames, in_game_redirector
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//#endregion
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
//Leave this as it's own file in case I want to expand the classes in the future
|
||||||
|
|
||||||
|
const { MessageActionRow, MessageSelectMenu } = require("discord.js");
|
||||||
|
|
||||||
|
|
||||||
|
//#region multiplayer games
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A temporary container to keep track of what abilities each class has
|
||||||
|
* @param {string} name - the name of the class ('fighter', 'wizard', etc.)
|
||||||
|
* @property { Boolean } canUseWeapons
|
||||||
|
* @property { Boolean } canUseSpells
|
||||||
|
* @example var myClass = new game_class('wizard');
|
||||||
|
*/
|
||||||
|
class game_class_battle {
|
||||||
|
constructor(name = 'none') {
|
||||||
|
if (name == 'fighter') {
|
||||||
|
this.canUseWeapons = true;
|
||||||
|
this.canUseSpells = false;
|
||||||
|
this.specialAttack = {
|
||||||
|
icon: 'spatkfight',
|
||||||
|
dmg: 'r*2.5',
|
||||||
|
prone: false
|
||||||
|
};
|
||||||
|
this.description = 'More damage, less effects!';
|
||||||
|
} else if (name == 'wizard') {
|
||||||
|
this.canUseWeapons = false;
|
||||||
|
this.canUseSpells = true;
|
||||||
|
this.specialAttack = {
|
||||||
|
icon: 'spatkwiz',
|
||||||
|
dmg: 'r*2.0',
|
||||||
|
prone: true
|
||||||
|
}
|
||||||
|
this.description = 'Less damage, more effects!';
|
||||||
|
} else if (name == 'none') {
|
||||||
|
//The player doesn't have a class
|
||||||
|
this.canUseSpells = undefined;
|
||||||
|
this.canUseWeapons = undefined;
|
||||||
|
this.specialAttack = undefined;
|
||||||
|
this.description = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.className = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#region functions
|
||||||
|
function presentClasses(message, game) {
|
||||||
|
let classes;
|
||||||
|
|
||||||
|
if (game == 'battle') {
|
||||||
|
classes = [new game_class_battle('fighter'), new game_class_battle('wizard')];
|
||||||
|
} else {
|
||||||
|
return message.reply('Please use the following format for this command: _!game class [game name]_');
|
||||||
|
}
|
||||||
|
|
||||||
|
var classList = [];
|
||||||
|
|
||||||
|
classes.forEach(function(c) {
|
||||||
|
let n = c.className;
|
||||||
|
|
||||||
|
classList.push({label: n, description: `${c.description}`, value: `${n}`});
|
||||||
|
});
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageSelectMenu()
|
||||||
|
.setCustomId(`${message.author.id}|class`)
|
||||||
|
.setPlaceholder('none')
|
||||||
|
.addOptions(classList)
|
||||||
|
)
|
||||||
|
|
||||||
|
message.reply({ content: `Please choose your class <@${message.author.id}>`, components: [row] });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function chooseClass(user_dbo, message, game) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
module.exports = { game_class_battle, presentClasses, chooseClass }
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
const { MessageActionRow, MessageButton, Interaction } = require('discord.js');
|
||||||
|
const { winGame, loseGame, equipItem } = require('./external_game_functions.js');
|
||||||
|
const wait = require('node:timers/promises').setTimeout;
|
||||||
|
const { STATE } = require('../db/econ.js')
|
||||||
|
|
||||||
|
function startGame(bot, channel, message, args) {
|
||||||
|
let componentlist = [];
|
||||||
|
var diff;
|
||||||
|
|
||||||
|
if (args.length < 1 || args[0] == 'easy') {
|
||||||
|
diff = 0;
|
||||||
|
} else if (args[0] == 'medium') {
|
||||||
|
diff = 0.1;
|
||||||
|
} else if (args[0] == 'hard') {
|
||||||
|
diff = 0.2;
|
||||||
|
} else {
|
||||||
|
diff = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let user = '';
|
||||||
|
if (args.length < 2 || args[1] == 'solo') {
|
||||||
|
user = message.author.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i ++) {
|
||||||
|
const row = new MessageActionRow();
|
||||||
|
|
||||||
|
for (let j = 0; j < 5; j ++) {
|
||||||
|
//customId = (spot in row)|(spot in column)
|
||||||
|
const btn = new MessageButton();
|
||||||
|
const isbmb = (Math.random() > (0.70 - diff));
|
||||||
|
|
||||||
|
if (isbmb) {
|
||||||
|
btn.setCustomId(`mswpr|${i}|${j}|t|${user}`);
|
||||||
|
} else {
|
||||||
|
btn.setCustomId(`mswpr|${i}|${j}|f|${user}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.setLabel('?')
|
||||||
|
.setStyle('SECONDARY')
|
||||||
|
row.addComponents(btn);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add the row to the list of rows
|
||||||
|
componentlist.push(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.send({ content: `SCORE: \`0\`\nTILES LEFT: \`25\``, components: componentlist });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function gameOver(interaction, won = false) {
|
||||||
|
var components = interaction.message.components;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
for (i in components) {
|
||||||
|
for (j in components[i].components) {
|
||||||
|
if (components[i].components[j].customId.split("|")[3] === 't') {
|
||||||
|
components[i].components[j].label = "💣";
|
||||||
|
components[i].components[j].style = "DANGER";
|
||||||
|
} else {
|
||||||
|
components[i].components[j].style = "SUCCESS";
|
||||||
|
components[i].components[j].label = "5";
|
||||||
|
}
|
||||||
|
|
||||||
|
components[i].components[j].setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (won) {
|
||||||
|
resolve(components);
|
||||||
|
} else {
|
||||||
|
interaction.message.edit({ components: components });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Interaction} interaction
|
||||||
|
*/
|
||||||
|
async function changeBoard(bot, interaction, xp_collection) {
|
||||||
|
interaction.deferUpdate();
|
||||||
|
const id = interaction.customId.split('|');
|
||||||
|
|
||||||
|
//"mswpr|y|x|<t/f>|[user]"
|
||||||
|
const col = id[1];
|
||||||
|
const row = id[2];
|
||||||
|
const isbmb = (id[3] === 't');
|
||||||
|
const user = id[4];
|
||||||
|
if (user && user != '') {
|
||||||
|
if (interaction.user.id != user) {
|
||||||
|
interaction.user.send(`Message from a Minesweeper game in <#${interaction.channel.id}>: ***It's not your turn!***`);
|
||||||
|
return; // interaction.reply({ content: "It's not your turn!", ephemeral: true }); //Can only reply once
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var components = interaction.message.components;
|
||||||
|
var btn = components[col].components[row];
|
||||||
|
|
||||||
|
if (isbmb) {
|
||||||
|
gameOver(interaction);
|
||||||
|
bot.mongoconnection.then((client) => { client.db(interaction.guildId).collection(interaction.user.id).updateOne({ game: {$exists: true} }, { $set: { game: null } }); });
|
||||||
|
const channel = bot.channels.cache.get(interaction.message.channel.parentId);
|
||||||
|
channel.send(`${interaction.user} found a bomb in Minesweeper!`);
|
||||||
|
interaction.channel.send(`\`Thread closing\` <t:${Math.floor((new Date()).getTime()/1000) + 8}:R>`);
|
||||||
|
|
||||||
|
await wait(7000);
|
||||||
|
interaction.channel.delete();
|
||||||
|
} else {
|
||||||
|
btn.setDisabled(true);
|
||||||
|
btn.label = "1";
|
||||||
|
btn.style = "SUCCESS";
|
||||||
|
components[col].components[row] = btn;
|
||||||
|
|
||||||
|
let content = interaction.message.content;
|
||||||
|
let score = Number(content.split('`')[1]);
|
||||||
|
let tLeft = Number(content.split('`')[3]);
|
||||||
|
|
||||||
|
//Win the game (just clicked the last tile)
|
||||||
|
if (tLeft <= 1) {
|
||||||
|
gameOver(interaction, true).then(async (newComp) => {
|
||||||
|
interaction.message.edit({ content: `GAME WON!!!\nSCORE: \`${score + 1}\``, components: newComp });
|
||||||
|
const channel = bot.channels.cache.get(interaction.message.channel.parentId);
|
||||||
|
channel.send(`${interaction.user} won a game of Minesweeper with a score of ${score + 1}!`);
|
||||||
|
interaction.channel.send(`\`Thread closing\` <t:${Math.floor((new Date()).getTime()/1000) + 8}:R>`);
|
||||||
|
|
||||||
|
await wait(7000);
|
||||||
|
// interaction.channel.delete();
|
||||||
|
bot.mongoconnection.then(client => {
|
||||||
|
const db = client.db(interaction.guildId);
|
||||||
|
const dbo = db.collection(interaction.user.id);
|
||||||
|
winGame(client, bot, db, dbo, xp_collection, interaction.message, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
interaction.message.edit({ content: `SCORE: \`${score + 1}\`\nTILES LEFT: \`${tLeft - 1}\``, components: components });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkAndStartGame(bot, message, channel, args) {
|
||||||
|
bot.mongoconnection.then(client => {
|
||||||
|
const db = client.db(message.guild.id);
|
||||||
|
const dbo = db.collection(message.author.id);
|
||||||
|
dbo.findOne({game: {$exists: true}}).then((doc) => {
|
||||||
|
try {
|
||||||
|
if (doc.game != null) { return message.reply("You're already in a game!"); }
|
||||||
|
|
||||||
|
dbo.updateOne({ "game": {$exists: true} }, { $set: { game: "minesweeper", state: STATE.FIGHTING }});
|
||||||
|
startGame(bot, channel, message, args);
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint.js');
|
||||||
|
addComplaintButton(bot, message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handle(bot, interaction, channel = null, message = null, args = null, xp_collection = null) {
|
||||||
|
if (channel != null && args != null) {
|
||||||
|
checkAndStartGame(bot, message, channel, args);
|
||||||
|
} else {
|
||||||
|
//Maybe add player checking later?
|
||||||
|
changeBoard(bot, interaction, xp_collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { handle }
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
const wait = require('node:timers/promises').setTimeout;
|
||||||
|
const { MessageActionRow, MessageButton, MessageSelectMenu, Client, CommandInteractionOptionResolver } = require('discord.js');
|
||||||
|
const { STATE } = require('../db/econ');
|
||||||
|
const { winGame, getCustomEmoji } = require('./external_game_functions.js');
|
||||||
|
const { changeTurn } = require('../turnManager.js');
|
||||||
|
const { game_class_battle } = require('./game_classes');
|
||||||
|
const { MongoClient } = require('mongodb');
|
||||||
|
const { convertSnowflakeToDate } = require('../db/addons/snowflake');
|
||||||
|
|
||||||
|
//This function is blatantly stolen from https://alialaa.com/blog/tic-tac-toe-js
|
||||||
|
function isTerminal(board) {
|
||||||
|
//Return False if board in empty
|
||||||
|
if (board.every(cell => !cell)) return false;
|
||||||
|
let nums = [0, 0, 0]
|
||||||
|
|
||||||
|
//Checking Horizontal Wins
|
||||||
|
if (board[0] === board[1] && board[0] === board[2] && board[0]) {
|
||||||
|
nums = [0, 1, 2];
|
||||||
|
return {'winner': board[0], 'direction': 'H', 'row': 1, 'nums': nums};
|
||||||
|
}
|
||||||
|
if (board[3] === board[4] && board[3] === board[5] && board[3]) {
|
||||||
|
nums = [3, 4, 5];
|
||||||
|
return {'winner': board[3], 'direction': 'H', 'row': 2, 'nums': nums};
|
||||||
|
}
|
||||||
|
if (board[6] === board[7] && board[6] === board[8] && board[6]) {
|
||||||
|
nums = [6, 7, 8];
|
||||||
|
return {'winner': board[6], 'direction': 'H', 'row': 3, 'nums': nums};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Checking Vertical Wins
|
||||||
|
if (board[0] === board[3] && board[0] === board[6] && board[0]) {
|
||||||
|
nums = [0, 3, 6];
|
||||||
|
return {'winner': board[0], 'direction': 'V', 'column': 1, 'nums': nums};
|
||||||
|
}
|
||||||
|
if (board[1] === board[4] && board[1] === board[7] && board[1]) {
|
||||||
|
nums = [1, 4, 7];
|
||||||
|
return {'winner': board[1], 'direction': 'V', 'column': 2, 'nums': nums};
|
||||||
|
}
|
||||||
|
if (board[2] === board[5] && board[2] === board[8] && board[2]) {
|
||||||
|
nums = [2, 5, 8];
|
||||||
|
return {'winner': board[2], 'direction': 'V', 'column': 3, 'nums': nums};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Checking Diagonal Wins
|
||||||
|
if (board[0] === board[4] && board[0] === board[8] && board[0]) {
|
||||||
|
nums = [0, 4, 8];
|
||||||
|
return {'winner': board[0], 'direction': 'D', 'diagonal': 'main', 'nums': nums};
|
||||||
|
}
|
||||||
|
if (board[2] === board[4] && board[2] === board[6] && board[2]) {
|
||||||
|
nums = [2, 4, 6];
|
||||||
|
return {'winner': board[2], 'direction': 'D', 'diagonal': 'counter', 'nums': nums};
|
||||||
|
}
|
||||||
|
|
||||||
|
//If no winner but the board is full, then it's a draw
|
||||||
|
if (board.every(cell => cell)) {
|
||||||
|
return {'winner': 'draw'};
|
||||||
|
}
|
||||||
|
|
||||||
|
//return false otherwise
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//I know it's sloppy, but when 'initial' is true, 'interaction' will actually be 'thread'
|
||||||
|
function postActionBar(interaction, user_dbo, board, won, initial = false) {
|
||||||
|
let componentlist = [];
|
||||||
|
let newRow = new MessageActionRow();
|
||||||
|
|
||||||
|
for (let i = 0; i < 9; i ++) {
|
||||||
|
let button;
|
||||||
|
|
||||||
|
if (!won) {
|
||||||
|
if (!board[i]) {
|
||||||
|
button = new MessageButton()
|
||||||
|
.setCustomId(`ttt|${i}`)
|
||||||
|
.setLabel('-')
|
||||||
|
.setStyle('SUCCESS')
|
||||||
|
} else {
|
||||||
|
button = new MessageButton()
|
||||||
|
.setCustomId(`ttt|${i}`)
|
||||||
|
.setLabel(board[i])
|
||||||
|
.setStyle('DANGER')
|
||||||
|
.setDisabled(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i in won.nums) {
|
||||||
|
button = new MessageButton()
|
||||||
|
.setCustomId(`ttt|${i}`)
|
||||||
|
.setLabel('W')
|
||||||
|
.setStyle('SUCCESS')
|
||||||
|
} else {
|
||||||
|
button = new MessageButton()
|
||||||
|
.setCustomId(`ttt|${i}`)
|
||||||
|
.setLabel('F')
|
||||||
|
.setStyle('DANGER')
|
||||||
|
.setDisabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newRow.addComponents(button);
|
||||||
|
|
||||||
|
if ((i + 1) % 3 == 0) {
|
||||||
|
//Add the row to the list of rows
|
||||||
|
componentlist.push(newRow);
|
||||||
|
newRow = new MessageActionRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(componentlist);
|
||||||
|
|
||||||
|
if (initial) {
|
||||||
|
interaction.send({ content: `Your turn <@${user_dbo.s.namespace.collection}>!`, components: componentlist });
|
||||||
|
} else {
|
||||||
|
interaction.update({ content: `Your turn <@${user_dbo.s.namespace.collection}>!`, components: componentlist });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function handle(client, db, dbo, other, bot, thread, command, doc, interaction, xp_collection) {
|
||||||
|
|
||||||
|
if (command == 'initalize') {
|
||||||
|
let board = ["", "", "", "", "", "", "", "", ""];
|
||||||
|
postActionBar(thread, dbo, board, false,true);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
//Change the board
|
||||||
|
let square = Number(interaction.customId.split('|')[1]);
|
||||||
|
let symbol = doc.symbols[doc.turn];
|
||||||
|
let board = doc.board;
|
||||||
|
board[square] = symbol;
|
||||||
|
const gamedbo = client.db('B|S' + bot.user.id).collection(interaction.guildId);
|
||||||
|
|
||||||
|
gamedbo.updateOne({$or: [ {0: interaction.user.id}, {1: interaction.user.id} ], 'board': {$exists: true}}, {$set: {board: board}});
|
||||||
|
|
||||||
|
//Check if the game is over
|
||||||
|
let won = isTerminal(board);
|
||||||
|
|
||||||
|
if (!won) {
|
||||||
|
changeTurn(client, bot, interaction);
|
||||||
|
postActionBar(interaction, other, board, false);
|
||||||
|
changeTurn(client, bot, interaction);
|
||||||
|
} else {
|
||||||
|
postActionBar(interaction, dbo, board, won);
|
||||||
|
await wait(7000);
|
||||||
|
winGame(client, bot, db, dbo, xp_collection, interaction.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { handle }
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
const request = require('request');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const categoriesJSON = require('./trivia_categories.json').trivia_categories;
|
||||||
|
const { decode } = require('html-entities');
|
||||||
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
|
|
||||||
|
|
||||||
|
const categories = new Map();
|
||||||
|
for (i in categoriesJSON) {
|
||||||
|
categories.set(categoriesJSON[i].name, categoriesJSON[i].id);
|
||||||
|
}
|
||||||
|
// const { jsonToMapRecursive, mapToTableRecursive } = require('../utils/jsonFormatters.js');
|
||||||
|
|
||||||
|
|
||||||
|
function changeDB(bot, message, m) {
|
||||||
|
try {
|
||||||
|
bot.mongoconnection.then(client => {
|
||||||
|
const dbo = client.db(message.guild.id).collection('trivia');
|
||||||
|
//Game Over
|
||||||
|
if (m == null) {
|
||||||
|
return dbo.deleteOne({ channel: message.channel.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
dbo.findOne({ channel: message.channel.id }).then((doc) => {
|
||||||
|
if (doc) {
|
||||||
|
dbo.updateOne({ channel: message.channel.id }, {$set: { m: Object.fromEntries(m) }});
|
||||||
|
} else{
|
||||||
|
dbo.insertOne({ channel: message.channel.id, m: Object.fromEntries(m) });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} message
|
||||||
|
* @param {Map<string, object>} m
|
||||||
|
* @param {int} time
|
||||||
|
*/
|
||||||
|
function startTrivia(message, m, time, bot) {
|
||||||
|
var iter = m.values().next();
|
||||||
|
var obj = iter.value;
|
||||||
|
|
||||||
|
//Get rid of the "answers required" ones
|
||||||
|
while (obj.question.toLowerCase().indexOf('which of these') != -1 && obj.question.toLowerCase().indexOf('which of the following') != -1) {
|
||||||
|
iter = iter.next();
|
||||||
|
obj = iter.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const question = obj.question;
|
||||||
|
const answer = obj.answer;
|
||||||
|
|
||||||
|
const filter = (response) => {
|
||||||
|
// return item.answers.some(answer => answer.toLowerCase() === response.content.toLowerCase());
|
||||||
|
return (response.content.toLowerCase() == answer.toLowerCase());
|
||||||
|
};
|
||||||
|
|
||||||
|
message.reply({ content: `${question}\n(Type your answers below!)`, fetchReply: true })
|
||||||
|
.then(() => {
|
||||||
|
const timeList = ['🔟', '9️⃣', '8️⃣', '7️⃣', '6️⃣', '5️⃣', '4️⃣', '3️⃣', '2️⃣', '1️⃣', '0️⃣' ];
|
||||||
|
var i = 0;
|
||||||
|
const intId = setInterval(() => { if (i < timeList.length) { message.react(timeList[i]); i++ } }, Math.round(time/11));
|
||||||
|
//time: 1000 = 1 second
|
||||||
|
message.channel.awaitMessages({ filter, max: 10, time: time }) // , errors: ['time']
|
||||||
|
.then((collected) => {
|
||||||
|
if (collected.size > 0) {
|
||||||
|
message.reply(`${collected.first().author} got the correct answer (${answer})!`);
|
||||||
|
} else {
|
||||||
|
message.reply('Tsk Tsk, looks like nobody got the answer this time.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// changeDB(bot, message, null);
|
||||||
|
clearInterval(intId);
|
||||||
|
})
|
||||||
|
.catch((collected) => {
|
||||||
|
console.log(collected);
|
||||||
|
message.reply('Tsk Tsk, looks like nobody got the answer this time.');
|
||||||
|
// changeDB(bot, message, null);
|
||||||
|
clearInterval(intId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Add shuffle button?
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'trivia',
|
||||||
|
async execute(message, args, Discord, Client, bot) {
|
||||||
|
const difficult = ['easy', 'medium', 'hard'];
|
||||||
|
let inputs = ['easy', ''];
|
||||||
|
|
||||||
|
if (args[0] && difficult.includes(args[0].toLowerCase())) {
|
||||||
|
inputs[0] = args[0].toLowerCase();
|
||||||
|
} else if (args[0] == 'help') {
|
||||||
|
let temp = `Use ${bot.prefix}trivia [difficulty (easy, medium, hard)] [topic] [time]\n`;
|
||||||
|
temp += '**__Trivia Categories__**\n';
|
||||||
|
categories.forEach((val, key) => {
|
||||||
|
temp += `_${key}_\n`;
|
||||||
|
})
|
||||||
|
temp += '_Please copy and paste the FULL NAME if you want to use a category';
|
||||||
|
|
||||||
|
return message.reply(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args[1] && Array.from(categories.keys()).includes(args[1])) {
|
||||||
|
inputs[1] = categories.get(args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all categories mapped to their ids
|
||||||
|
// const a = await fetch('https://opentdb.com/api_category.php');
|
||||||
|
// const json = await a.json();
|
||||||
|
// console.log(json);
|
||||||
|
|
||||||
|
var url = `https://opentdb.com/api.php?amount=${3}&difficulty=${inputs[0]}&type=multiple`;
|
||||||
|
if (inputs[1] != '') {
|
||||||
|
url += `&category=${inputs[1]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
request(url, function (error, response, body) {
|
||||||
|
if (!error && response.statusCode == 200) {
|
||||||
|
// const m = new Map(body);
|
||||||
|
let s = body.replace('{"response_code":0,"results":[', '');
|
||||||
|
s = s.substring(0, s.length - 2);
|
||||||
|
let queries = s.split('},');
|
||||||
|
|
||||||
|
const m = new Map();
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
queries.forEach((query, ind) => {
|
||||||
|
query = query.substring(1, s.length - 2);
|
||||||
|
if (query.endsWith('}')) { query = query.substring(0, s.length - 2); }
|
||||||
|
|
||||||
|
// console.log(decode(query));
|
||||||
|
query = decode(query);
|
||||||
|
|
||||||
|
//Get the answer (may have "" in it)
|
||||||
|
const question = query.substring(query.indexOf('question":') + 10, query.indexOf('","correct_answer'));
|
||||||
|
// console.log(`Q: ${question}\n\nActual: ${query}\n---------------------------------------`);
|
||||||
|
|
||||||
|
let q = query.split('","');
|
||||||
|
// queries[ind] = q;
|
||||||
|
|
||||||
|
q[5] = q[5].split(':[')[1];
|
||||||
|
|
||||||
|
let obj = { question: q[3].split(':"')[1], answer: q[4].split(':"')[1], incorrect: [ q[5].replaceAll('"', ''), q[6].replaceAll('"', ''), q[7].replaceAll(']}', '').replaceAll(']', '').replaceAll('"', '') ] }
|
||||||
|
m.set(i, obj);
|
||||||
|
i ++;
|
||||||
|
});
|
||||||
|
|
||||||
|
const time = args[2] || (difficult.indexOf(inputs[0]) + 1) * 10000;
|
||||||
|
|
||||||
|
// console.log(m, time);
|
||||||
|
// changeDB(bot, message, m);
|
||||||
|
startTrivia(message, m, time, bot);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"trivia_categories": [
|
||||||
|
{ "id": 9, "name": "General Knowledge" },
|
||||||
|
{ "id": 10, "name": "Entertainment: Books" },
|
||||||
|
{ "id": 11, "name": "Entertainment: Film" },
|
||||||
|
{ "id": 12, "name": "Entertainment: Music" },
|
||||||
|
{ "id": 13, "name": "Entertainment: Musicals & Theatres" },
|
||||||
|
{ "id": 14, "name": "Entertainment: Television" },
|
||||||
|
{ "id": 15, "name": "Entertainment: Video Games" },
|
||||||
|
{ "id": 16, "name": "Entertainment: Board Games" },
|
||||||
|
{ "id": 17, "name": "Science & Nature" },
|
||||||
|
{ "id": 18, "name": "Science: Computers" },
|
||||||
|
{ "id": 19, "name": "Science: Mathematics" },
|
||||||
|
{ "id": 20, "name": "Mythology" },
|
||||||
|
{ "id": 21, "name": "Sports" },
|
||||||
|
{ "id": 22, "name": "Geography" },
|
||||||
|
{ "id": 23, "name": "History" },
|
||||||
|
{ "id": 24, "name": "Politics" },
|
||||||
|
{ "id": 25, "name": "Art" },
|
||||||
|
{ "id": 26, "name": "Celebrities" },
|
||||||
|
{ "id": 27, "name": "Animals" },
|
||||||
|
{ "id": 28, "name": "Vehicles" },
|
||||||
|
{ "id": 29, "name": "Entertainment: Comics" },
|
||||||
|
{ "id": 30, "name": "Science: Gadgets" },
|
||||||
|
{ "id": 31, "name": "Entertainment: Japanese Anime & Manga" },
|
||||||
|
{ "id": 32, "name": "Entertainment: Cartoon & Animations" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
|
const { createSubscriptionManual } = require('./premium/stripe.js');
|
||||||
|
const { pause_start_stop, playNext, showQueue } = require('./misc/playAudio.js');
|
||||||
|
const { resolveComplaint } = require('./dev only/submitcomplaint.js');
|
||||||
|
const reminders = require('./premium/reminders.js');
|
||||||
|
const tuto = require('../commands/Selmer Specific/intro');
|
||||||
|
const mswpr = require('./games/minesweeper.js');
|
||||||
|
// const { RSSInteractionHandler } = require('./premium/rssFeed.js');
|
||||||
|
const { Interaction } = require('discord.js')
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Interaction} interaction
|
||||||
|
*/
|
||||||
|
async function handle_interaction(interaction, mongouri, turnManager, bot, STATE, items, xp_collection) {
|
||||||
|
if (interaction.isButton()) {
|
||||||
|
const battlecommandlist = ['ATTACK', 'HEAL', 'DEFEND', 'ITEMS', 'ULTIMATE'];
|
||||||
|
const singleCommandGames = ['ttt']; // Use when you have more single-player games
|
||||||
|
const musicCommandList = ['PLAY', 'PAUSE', 'RESUME', 'STOP', 'SKIP'];
|
||||||
|
|
||||||
|
bot.mongoconnection.then(async (client) => {
|
||||||
|
|
||||||
|
if (battlecommandlist.indexOf(interaction.customId) != -1) {
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
let current_user = turnManager.getTurn(client, bot, interaction);
|
||||||
|
|
||||||
|
current_user.then(function (result) {
|
||||||
|
const id = result[0];
|
||||||
|
const doc = result[1];
|
||||||
|
const threadname = doc.thread;
|
||||||
|
const dbo = client.db(interaction.guildId).collection(id);
|
||||||
|
|
||||||
|
dbo.find({ 'state': {$exists: true} }).toArray(async function (err, docs) {
|
||||||
|
if (interaction.user.id == id) {
|
||||||
|
|
||||||
|
//Check State
|
||||||
|
if (docs[0].state != STATE.IDLE) {
|
||||||
|
//Do turn stuff
|
||||||
|
bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove the old interation message
|
||||||
|
await interaction.message.delete();
|
||||||
|
|
||||||
|
if (interaction.customId.toLowerCase() != 'heal') {
|
||||||
|
interaction.editReply(`<@${interaction.user.id}> used _${interaction.customId.toLowerCase()}_!`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("It's not your turn!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (interaction.customId.split('|')[0] == 'ttt') {
|
||||||
|
let current_user = turnManager.getTurn(client, bot, interaction);
|
||||||
|
current_user.then(function (result) {
|
||||||
|
const id = result[0];
|
||||||
|
|
||||||
|
if (interaction.user.id == id) {
|
||||||
|
const doc = result[1];
|
||||||
|
const threadname = doc.thread;
|
||||||
|
|
||||||
|
let board = result.board;
|
||||||
|
|
||||||
|
bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection, board);
|
||||||
|
} else {
|
||||||
|
console.log("It's not your turn!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (musicCommandList.indexOf(interaction.customId) != -1 || interaction.customId.indexOf('audioQueue|') != -1) {
|
||||||
|
if (interaction.customId == 'SKIP') {
|
||||||
|
playNext(interaction, bot);
|
||||||
|
} else if (interaction.customId.indexOf('audioQueue|') != -1) {
|
||||||
|
const page = Number(interaction.customId.split('|')[1]);
|
||||||
|
showQueue(bot, interaction.message, interaction, page);
|
||||||
|
} else {
|
||||||
|
pause_start_stop(interaction, bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (interaction.customId == 'DEBUGURGENT' || interaction.customId == 'DEBUGDONE') {
|
||||||
|
resolveComplaint(interaction);
|
||||||
|
} else if (interaction.customId.indexOf('newEvent') != -1 || interaction.customId.indexOf('getEvents') != -1) {
|
||||||
|
reminders.modalHandle(bot, interaction);
|
||||||
|
} else if (interaction.customId.indexOf('reminderQueue') != -1) {
|
||||||
|
reminders.turnPage(bot, interaction);
|
||||||
|
} else if (interaction.customId.indexOf("tutoQueue") != -1){
|
||||||
|
const page = Number(interaction.customId.split('|')[1]);
|
||||||
|
tuto.postEmbd(bot, interaction, page, true);
|
||||||
|
} else if (interaction.customId.indexOf("mswpr|") != -1) {
|
||||||
|
mswpr.handle(bot, interaction, interaction.channel, interaction.message, null, xp_collection);
|
||||||
|
} else if (interaction.customId.indexOf("sbtutorial") != -1) {
|
||||||
|
interaction.deferUpdate();
|
||||||
|
tuto.execute(interaction.message, null, null, null, bot);
|
||||||
|
} //Button else ifs here
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Menu Selection
|
||||||
|
else if (interaction.isSelectMenu()) {
|
||||||
|
const id = interaction.customId.substring(0, interaction.customId.indexOf('|'))
|
||||||
|
// const command = interaction.customId.substring(interaction.customId.indexOf('|'), interaction.customId.length - interaction.customId.indexOf('|'))
|
||||||
|
|
||||||
|
if (interaction.customId.toLowerCase().indexOf('|heal') != -1) {
|
||||||
|
bot.mongoconnection.then(client => {
|
||||||
|
if (id != interaction.user.id) { return; }
|
||||||
|
|
||||||
|
let current_user = turnManager.getTurn(client, bot, interaction);
|
||||||
|
current_user.then(function(result) {
|
||||||
|
const doc = result[1];
|
||||||
|
const threadname = doc.thread;
|
||||||
|
const dbo = client.db(interaction.guildId).collection(id);
|
||||||
|
|
||||||
|
dbo.find({ 'state': {$exists: true} }).toArray(async function (err, docs) {
|
||||||
|
if (interaction.user.id == id) {
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
//Check State
|
||||||
|
if (docs[0].state == STATE.FIGHTING) {
|
||||||
|
interaction.customId = 'usepotion';
|
||||||
|
//Do turn stuff
|
||||||
|
bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
interaction.editReply(`<@${interaction.user.id}> used a _${interaction.values[0]}_!`);
|
||||||
|
|
||||||
|
//remove the old interation message
|
||||||
|
await interaction.message.delete();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log("It's not your turn!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//Get all chars from after "CUSTOM|" to the end of the str
|
||||||
|
// let name = item.icon.substr(7, item.icon.length - 6);
|
||||||
|
});
|
||||||
|
} else if (interaction.customId.toLowerCase().indexOf('|item') != -1) {
|
||||||
|
|
||||||
|
} else if (interaction.customId.split('|')[1] == 'premium') {
|
||||||
|
//Check if the person subscribing and the person clicking are the same (group DM catch)
|
||||||
|
const user = interaction.customId.split('|')[0];
|
||||||
|
if (interaction.user.id == user) {
|
||||||
|
// await interaction.deferReply();
|
||||||
|
await interaction.update({ content: 'TIER SELECTED PLEASE HOLD', components: [] });
|
||||||
|
await createSubscriptionManual(bot, interaction, user, interaction.values[0]);
|
||||||
|
|
||||||
|
//Handle the interaction here
|
||||||
|
}
|
||||||
|
} /*else if (interaction.customId.indexOf('RSS') != -1) {
|
||||||
|
RSSInteractionHandler(bot, interaction);
|
||||||
|
}*/ //menu else ifs here
|
||||||
|
}
|
||||||
|
|
||||||
|
//Forms
|
||||||
|
else if (interaction.isModalSubmit()) {
|
||||||
|
reminders.modalHandle(bot, interaction);
|
||||||
|
} //other selection types here
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { handle_interaction }
|
||||||
|
|
||||||
|
//values: [ 'price_1LI5pzFtuywsbrwdlY1gWMkV' ]
|
||||||
|
//values: [ 'price_1LIpROFtuywsbrwdmxOb8Baj' ]
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
|
const Discord = require('discord.js');
|
||||||
|
const SEVCODES = {
|
||||||
|
none: 0,
|
||||||
|
low: 1,
|
||||||
|
medium: 2,
|
||||||
|
high: 3
|
||||||
|
}
|
||||||
|
const col_list = {0: '0ed300', 1: 'f6ff00', 2: 'ffa100', 3: 'FF0000'}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} bot
|
||||||
|
* @param {*} message the message the mod sent (AKA a DISCORD MESSAGE OBJECT)
|
||||||
|
*/
|
||||||
|
function log(bot, message, command, mentioned, reason, severity) {
|
||||||
|
bot.mongoconnection.then(client => {
|
||||||
|
// if (err) { return console.log(err); }
|
||||||
|
|
||||||
|
|
||||||
|
client.db(message.guild.id).collection('SETUP').findOne({_id: 'LOG'}).then((doc) => {
|
||||||
|
if (!doc) { return message.channel.send("Server logs not set up yet!"); }
|
||||||
|
const channel = message.guild.channels.cache.get(doc.logchannel);
|
||||||
|
|
||||||
|
if (!channel) { return console.log("There is no specified log channel!"); }
|
||||||
|
//Check severity threshold
|
||||||
|
if (SEVCODES[doc.severity] < severity) { return; }
|
||||||
|
|
||||||
|
let action;
|
||||||
|
if (command.endsWith('e')) { action = (command + 'd'); }
|
||||||
|
else if (command.endsWith('n')) { action = (command + 'ned'); }
|
||||||
|
else { action = (command + 'ed'); }
|
||||||
|
|
||||||
|
const newEmbed = new Discord.MessageEmbed()
|
||||||
|
.setColor(col_list[severity])
|
||||||
|
.setTitle(`User ${mentioned.username}#${mentioned.discriminator} has been ${action}`)
|
||||||
|
//.setURL('https://discordjs.guide/popular-topics/embeds.html#embed-preview')
|
||||||
|
.setDescription(`Reason: ${reason}\n Responsible Mod: ${message.author.username}#${message.author.discriminator}`)
|
||||||
|
.setThumbnail(mentioned.displayAvatarURL())
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
channel.send({ embeds: [newEmbed] });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { log, SEVCODES }
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
const { Formatters, MessageEmbed } = require('discord.js');
|
||||||
|
const CoinGecko = require('coingecko-api');
|
||||||
|
const CoinGeckoClient = new CoinGecko();
|
||||||
|
|
||||||
|
//#region Runs at the start to store all coins
|
||||||
|
const coinlist = new Map();
|
||||||
|
async function getAllCoins() {
|
||||||
|
const coinlistraw = await CoinGeckoClient.coins.all();
|
||||||
|
coinlistraw.data.forEach((coin) => {
|
||||||
|
const obj = { id: coin.id, symbol: coin.symbol, name: coin.name, img: coin.image.small };
|
||||||
|
coinlist.set(coin.symbol.toLowerCase(), obj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getAllCoins();
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
// Formatters.codeBlock
|
||||||
|
module.exports = {
|
||||||
|
name: 'crypto',
|
||||||
|
description: 'Get the prices for most cryptocurrencies!',
|
||||||
|
async execute(message, args, Discord, Client, bot) {
|
||||||
|
if (args.length < 1 || args[0] == 'help') {
|
||||||
|
return message.reply("Please specify at least one cryptocurrency (_ex: !crypto BTC_) or list all currencies (_!crypto list_)");
|
||||||
|
} else if (args[0] == 'list') {
|
||||||
|
try {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let temp = "```Name --> Symbol\n\n";
|
||||||
|
coinlist.forEach((val, key) => {
|
||||||
|
temp += `${val.name} --> ${key.toUpperCase()}\n`;
|
||||||
|
});
|
||||||
|
temp += "```";
|
||||||
|
|
||||||
|
resolve(temp);
|
||||||
|
}).then((temp) => {
|
||||||
|
message.reply(temp);
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return message.reply("Uh Oh! There's been an error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let data = await CoinGeckoClient.exchanges.fetchTickers('bitfinex', {
|
||||||
|
coin_ids: ['bitcoin', 'ethereum', 'ripple', 'litecoin', 'stellar']
|
||||||
|
});
|
||||||
|
|
||||||
|
var datacc = data.data.tickers.filter(t => t.target == 'USD');
|
||||||
|
|
||||||
|
const temp = datacc.filter(t => t.base == args[0]);
|
||||||
|
const res = temp.length == 0 ? [] : temp[0];
|
||||||
|
|
||||||
|
//price: res.last, symbol: base, trust score: trust_score
|
||||||
|
var obj = coinlist.get(res.base.toLowerCase());
|
||||||
|
obj.price = res.last;
|
||||||
|
obj.score = res.trust_score || "N/A";
|
||||||
|
|
||||||
|
const embd = new MessageEmbed()
|
||||||
|
.setTitle(obj.name)
|
||||||
|
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||||
|
.setFields(
|
||||||
|
{name: "Price", value: `$${obj.price}`},
|
||||||
|
{name: "Symbol", value: `${obj.symbol}`},
|
||||||
|
{name: "Trust Score", value: `${obj.score}`},
|
||||||
|
)
|
||||||
|
.setThumbnail(obj.img)
|
||||||
|
.setTimestamp()
|
||||||
|
.setFooter({ text: 'Selmer Bot uses CoinGecko for cryptocurrency information'});
|
||||||
|
|
||||||
|
message.reply({ embeds: [embd] });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return message.reply("Uh Oh! There's been an error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+45
-7
@@ -1,40 +1,78 @@
|
|||||||
|
const { modHelp } = require('../admin/moderation.js');
|
||||||
|
|
||||||
|
//CHANGE THIS TO FORMS?
|
||||||
module.exports ={
|
module.exports ={
|
||||||
name: "help",
|
name: "help",
|
||||||
description: "Gets help for all of Selmer Bot's commands",
|
description: "Gets help for all of Selmer Bot's commands",
|
||||||
execute(message, args, Discord, Client, bot) {
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
|
||||||
|
const groups = new Map([['SBspec', ['arrow', 'extracredit', 'profile', 'quotes', 'code']], ['adminCommands', [ 'setup', 'lock', 'unlock', 'serverlock' ]]]);
|
||||||
|
|
||||||
if (args[0] == 'econ') {
|
if (args[0] == 'econ') {
|
||||||
let temp = "***Selmer Bot Commands (Econ):***\n";
|
let temp = "***Selmer Bot Commands (Econ):***\n";
|
||||||
temp += bot.commands.get('econ').econHelp();
|
temp += bot.commands.get('econ').econHelp();
|
||||||
temp += `\n\n(remember to use '${bot.prefix}' before the command!)`;
|
temp += `\n\n(remember to use _'${bot.prefix}'_ before the command!)`;
|
||||||
return message.channel.send(temp);
|
return message.channel.send(temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (args[0] == 'game') {
|
else if (args[0] == 'game') {
|
||||||
let temp = "***Selmer Bot Commands (Games):***\n";
|
let temp = "***Selmer Bot Commands (Games):***\n";
|
||||||
temp += bot.commands.get('game').allGames.join(", ");
|
temp += bot.commands.get('game').allGames.join(", ");
|
||||||
temp += `\n\n(remember to use '${bot.prefix}' before the command!)`;
|
temp += `\n\n(remember to use _'${bot.prefix}game'_ before the command!)`;
|
||||||
|
return message.channel.send(temp);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (args[0] == 'admin') {
|
||||||
|
let temp = `__**Selmer Bot Admin Commands**__\n`
|
||||||
|
Array.from(groups.get('adminCommands')).forEach(commName => {
|
||||||
|
let comm = bot.commands.get(commName);
|
||||||
|
temp += `${comm.name.toLowerCase()} - _${comm.description}_\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
temp += `__**Selmer Bot Moderation Commands**__\n`
|
||||||
|
temp += modHelp();
|
||||||
|
|
||||||
|
//Uses a different format, only the server owner can use it
|
||||||
|
temp += '\n_setup_ - ***SERVER OWNER ONLY*** - use _!setup help_\n';
|
||||||
|
temp += `\n\n(remember to use _'${bot.prefix}'_ before the command!)`;
|
||||||
|
|
||||||
return message.channel.send(temp);
|
return message.channel.send(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
let temp = "***Selmer Bot Commands:***\n";
|
let temp = "***Selmer Bot Commands:***\n";
|
||||||
|
|
||||||
bot.commands.sort((a, b) => {a.name[0] < b.name[0]});
|
bot.commands.sort((a, b) => {if (a.name && b.name) { return a.name[0] < b.name[0]} else {return false;} });
|
||||||
|
|
||||||
bot.commands.forEach((comm) => {
|
const noPostList = Array.from(groups.values()).flat();
|
||||||
|
const sList = groups.get('SBspec');
|
||||||
|
|
||||||
|
bot.commands.forEach((comm) => {
|
||||||
if (comm.name != 'verify') {
|
if (comm.name != 'verify') {
|
||||||
if (comm.name == 'econ') {
|
if (comm.name == 'econ') {
|
||||||
temp += `econ - use _!help econ_\n`;
|
temp += `**econ** - use _!help econ_\n`;
|
||||||
}
|
}
|
||||||
else if (comm.name == 'game') {
|
else if (comm.name == 'game') {
|
||||||
temp += `game - use _!help game_\n`;
|
temp += `**games** - use _!help game_\n`;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
temp += `${comm.name.toLowerCase()} - _${comm.description}_\n`;
|
if (comm.name && comm.description && !noPostList.includes(comm.name)) {
|
||||||
|
temp += `${comm.name.toLowerCase()} - _${comm.description}_\n`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
temp += '**admin/moderation commands** - use !help admin\n';
|
||||||
|
|
||||||
|
//Selmer Specific
|
||||||
|
temp += '\n__**Selmer\'s \\*Special\\* Commands**__\n'
|
||||||
|
sList.forEach((commName) => {
|
||||||
|
const comm = bot.commands.get(commName);
|
||||||
|
temp += `${comm.name.toLowerCase()} - _${comm.description}_\n`;
|
||||||
|
})
|
||||||
|
|
||||||
temp += `\n_(remember to use '${bot.prefix}' before the command!)_`;
|
temp += `\n_(remember to use '${bot.prefix}' before the command!)_`;
|
||||||
|
|
||||||
message.channel.send(temp);
|
message.channel.send(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,311 @@
|
|||||||
|
// https://ponly.com/200-pick-up-lines/
|
||||||
|
|
||||||
|
const cheesy = [
|
||||||
|
'If I said you had a good body would you hold it against me?',
|
||||||
|
'Do you believe in love at first sight, or should I walk past again?',
|
||||||
|
'Are you a magician? Because you just cast a spell on me.',
|
||||||
|
'You’re so sweet you must be made out of chocolate.',
|
||||||
|
'Did you hurt yourself when you fell from Heaven?',
|
||||||
|
'Are you a cat? Because you look purrrfect!',
|
||||||
|
'Are you tired? Because you’ve been running through my mind all day.',
|
||||||
|
'Hold out hand: “Hey I’m going for a walk. Will you hold this for me?”',
|
||||||
|
'I’m not a photographer, but I can picture me and you together.”',
|
||||||
|
'Are you a cake, “Because I want a piece of that.”',
|
||||||
|
'Are you a bank loan? Well, you’ve certainly got my interest. ',
|
||||||
|
'If you were a triangle, you’d be acute one!',
|
||||||
|
'Your hand looks heavy, let me hold it for you.',
|
||||||
|
'I think you are suffering from a lack of Vitamin Me.',
|
||||||
|
'On a scale of 1 to 10, you’re a 9 and I’m the 1 you lack.',
|
||||||
|
'Do you like Harry Potter? Because I adumbledore you.',
|
||||||
|
'Was your dad a boxer? Because damn, you’re a knockout!',
|
||||||
|
'Your lips look lonely. Would they like to meet mine?',
|
||||||
|
'I was wondering if you had an extra heart. Mine was just stolen.',
|
||||||
|
'Your phone has GPS, right? Because I’m totally going to get lost in those *insert color* eyes.',
|
||||||
|
'Would you grab my arm, so I can tell my friends I’ve been touched by an angel?',
|
||||||
|
'Can I have your picture so I can show Santa what I want for Christmas?',
|
||||||
|
'Your body is 65% water and I’m thirsty.',
|
||||||
|
'Excuse me, do you have a band-aid? Cause I scraped my knee falling for you.',
|
||||||
|
'Do I know you? Cause you look a lot like my next girlfriend/boyfriend.',
|
||||||
|
'Do you know what my shirt is made of? Boyfriend/girlfriend material?',
|
||||||
|
'They say Disneyland is the happiest place on earth. Well apparently, no one has ever been standing next to you.',
|
||||||
|
'You look cold. Want to use me as a blanket?',
|
||||||
|
'Are you an alien? Because you just abducted my heart.',
|
||||||
|
'Did your license get suspended for driving all these guys crazy?',
|
||||||
|
'For some reason, I was feeling a little off today. But when you came along, you definitely turned me on.',
|
||||||
|
'Can I borrow your phone? I need to call God and tell him I’ve found his missing angel.',
|
||||||
|
'Hey, you’re pretty and I’m cute. Together we’d be Pretty Cute.',
|
||||||
|
'Can I follow you home? Cause my parents always told me to follow my dreams.',
|
||||||
|
'What’s a smart, attractive man like myself doing without your phone number?',
|
||||||
|
'I seem to have lost my phone number. Can I have yours?',
|
||||||
|
'I’m lost. Can you give me directions to your heart?',
|
||||||
|
'I would say God bless you, but it looks like he already did.',
|
||||||
|
'Are you a parking ticket? Cause you’ve got fine written all over you.',
|
||||||
|
'Is your name Google? Because you got everything I am searching for.',
|
||||||
|
'Are you sure you’re not tired? You’ve been running through my mind all day.',
|
||||||
|
'Did I tell you I’m writing a book? It’s a phone book and it’s missing your number.',
|
||||||
|
'Is there an airport nearby or is it my heart taking off?',
|
||||||
|
'Life without you would be like a broken pencil… pointless.',
|
||||||
|
'Are you from Tennessee? Because you’re the only ten I see!',
|
||||||
|
'I must be in a museum because you truly are a work of art.',
|
||||||
|
'I’m not stalking you, I’m doing research!',
|
||||||
|
'If I could rearrange the alphabet, I’d put U and I together.',
|
||||||
|
'I’m no mathematician, but I’m pretty good with numbers. Tell you what, give me yours and watch what I can do with it.',
|
||||||
|
'Aside from being sexy, what do you do for a living?'
|
||||||
|
];
|
||||||
|
|
||||||
|
const funny = [
|
||||||
|
'Are you wi-fi? Cause I’m totally feeling a connection.',
|
||||||
|
'If I had a nickel for every time I saw someone as beautiful as you, I’d have five cents.',
|
||||||
|
'I’d like to take you to the movies, but they don’t let you bring in your own snacks.',
|
||||||
|
'Are you Australian? Because you meet all of my koalafications.',
|
||||||
|
'Know what’s on the menu? Me-N-U.',
|
||||||
|
'Your middle name must be Gillette. Because you’re the best a man can get!',
|
||||||
|
'You look so familiar. Didn’t we take a class together? I could’ve sworn we had chemistry.',
|
||||||
|
'You and I are like nachos with jalapeños. I’m super cheesy, you’re super hot, and we belong together.',
|
||||||
|
'Knock-knock. (Who’s there?) When where? (When where who?) Tomorrow night, my house, you.',
|
||||||
|
'Do you like Star Wars? Cause Yoda only one for me.',
|
||||||
|
'Go ahead, feel my shirt. It’s made of boyfriend material!',
|
||||||
|
'If you were a Transformer you’d be Optimus Fine!',
|
||||||
|
'Do you believe in love at first sight, or should I walk past you again?',
|
||||||
|
'I’m learning about important dates in history. Wanna be one of them?',
|
||||||
|
'I seem to have lost my phone number. Can I have yours?',
|
||||||
|
'Are you a parking ticket? Cause you’ve got fine written all over you!',
|
||||||
|
'Did you invent the airplane? Because you seem just Wright for me!',
|
||||||
|
'I was wondering if you had an extra heart…because mine was just stolen.',
|
||||||
|
'Are you Siri? Because you autocomplete me!',
|
||||||
|
'I hope you know CPR, because you are taking my breath away!',
|
||||||
|
'If I had four quarters to give to the four prettiest women in the world, you would have a dollar!',
|
||||||
|
'Let me guess, your middle name is Gillette, right? Because you’re the best a man can get!',
|
||||||
|
'Your eyes are bluer than the Atlantic Ocean, and I don’t mind being lost at sea.',
|
||||||
|
'If you were a burger at McDonald’s, you’d be the McGorgeous.',
|
||||||
|
'Are you a camera? Because every time I look at you, I smile.',
|
||||||
|
'Is there an airport nearby, or was that just my heart taking off?',
|
||||||
|
'Are you a loan? ‘Cause you’ve got my interest!',
|
||||||
|
'I’m in the mood for pizza. A pizza you, that is!',
|
||||||
|
'Are you a 45-degree angle? Because you’re a-cutie!',
|
||||||
|
'You’re so sweet, you could put Hershey’s out of business!',
|
||||||
|
'I’m good at algebra; I can replace your X and you wouldn’t need to figure out Y.',
|
||||||
|
'I’m really glad I just bought life insurance, because when I saw you, my heart stopped.',
|
||||||
|
'If I had to rate you from 1 to 10, I’d give you a 9, because I’m the 1 you’re missing.',
|
||||||
|
'You must be jelly, cause jam don’t shake like that.',
|
||||||
|
'You must be a bank loan, cause you’ve got my interest.',
|
||||||
|
'I’ve got 1-ply, I’ve got 2-ply, but all I really want is your re-ply.',
|
||||||
|
'If nothing lasts forever, will you be my nothing?',
|
||||||
|
'If you were a phaser on Star Trek, you’d be set to stun!',
|
||||||
|
'Is your name Google? Because you have everything I’ve been searching for.',
|
||||||
|
'Have you been covered in bees recently? I just assumed, because you look sweeter than honey.',
|
||||||
|
'There must be something wrong with my eyes. I can’t take them off you.',
|
||||||
|
'Are you from Tennessee? Because you’re the only Ten I See.',
|
||||||
|
'You must be a campfire. Because you’re super hot and I want s’more.',
|
||||||
|
'My buddies bet me that I wouldn’t be able to start a conversation with the most beautiful person here. How should we spend their money?',
|
||||||
|
'Well, here I am. What are your other two wishes?',
|
||||||
|
'Remember me? Oh, that’s right, I’ve only met you in my dreams.',
|
||||||
|
'You must be made of cheese. Because you’re looking Gouda tonight!',
|
||||||
|
'I’m glad I remembered to bring my library card. ‘Cause I am totally checking you out!',
|
||||||
|
'If you were a vegetable, you would be a cute-cumber!',
|
||||||
|
'I’m no mathematician, but I’m pretty good with numbers. Tell you what, give me yours and watch what I can do with it.'
|
||||||
|
];
|
||||||
|
|
||||||
|
const smooth = [
|
||||||
|
'Girl are those space pants? Because your butt is out of this world!',
|
||||||
|
'I think you’re suffering from a lack of vitamin me.',
|
||||||
|
'Kiss me if I’m wrong, but dinosaurs still exist, right?',
|
||||||
|
'Excuse me, is your name Earl Grey? Because you look like a hot-tea!',
|
||||||
|
'Can I borrow a kiss? I swear I’ll give it back!',
|
||||||
|
'If you were a vegetable you’d be a cute cumber.',
|
||||||
|
'Is summer over? Because I’m about to “fall” for you!',
|
||||||
|
'There’s a massive clothes sale in my bedroom – everything is 100% off',
|
||||||
|
'I lost my number…can I have yours?',
|
||||||
|
'Are you a baker? ‘Cause those buns look TASTY.',
|
||||||
|
'I’m not a hoarder but I really want to keep you forever.',
|
||||||
|
'Is your name google? Because you’re everything I’ve been searching for.',
|
||||||
|
'Are you an onion cos I want to remove your layers.',
|
||||||
|
'Even if there wasn’t gravity on earth, I’d still fall for you.',
|
||||||
|
'I’m glad I brought my library card because I’m checking you out.',
|
||||||
|
'You don’t need keys to drive me crazy.',
|
||||||
|
'Do you know what my shirt is made of? Girlfriend material?',
|
||||||
|
'Do you smoke pot? Because weed be cute together.',
|
||||||
|
'Are those mirrors in your pants? Because I can see myself in them!',
|
||||||
|
'I was wondering if you had an extra heart? Mine was just stolen.',
|
||||||
|
'Are those space pants? Because your butt looks out of this world.',
|
||||||
|
'Is your name Chapstick? Because you’re da-balm.',
|
||||||
|
'Do you have a map? Because I’m getting lost in your eyes.',
|
||||||
|
'Do you have a bandaid? Cause I hurt my knee falling for you!',
|
||||||
|
'Are you my phone charger? Because without you, I’d die.',
|
||||||
|
'Like a broken pencil, life without you is pointless.',
|
||||||
|
'We’re not socks. But I think we’d make a great pair.',
|
||||||
|
'This may be cheesy, but I think you’re grate.',
|
||||||
|
'Did it hurt? When you fell from heaven.',
|
||||||
|
'I wish I could select all of your clothes and press delete.',
|
||||||
|
'If you were a booger I’d pick you first ',
|
||||||
|
'Did you sit in sugar? Because you have a sweet ass.',
|
||||||
|
'We’re you born a mermaid, because you were a mermaid for me.',
|
||||||
|
'Your hand looks heavy; can I hold it for you?',
|
||||||
|
'Is your name honey? Cuz I’d love to drizzle you on my bland day.',
|
||||||
|
'Of all the beautiful curves on your body, your smile is my favorite.',
|
||||||
|
'I’m finding it really hard to breathe. U just keep on taking my breath away.',
|
||||||
|
'Have you got the time… I’ve got the time if you’ve got the place!',
|
||||||
|
'Are you glitter because you add sparkle to my life?',
|
||||||
|
'Are you sitting on the F5 key? ‘Cause your ass is refreshing!',
|
||||||
|
'Let’s commit the perfect crime- I’ll steal your heart, you steal mine.',
|
||||||
|
'Do you wanna grab a coffee because I like you a latte?',
|
||||||
|
'Hello! I guess you are looking for Mr. Right. Well, that’s me!',
|
||||||
|
'My mom said she found a beautiful and intelligent girl for me. Is that you?',
|
||||||
|
'How does it feel to be so gorgeous?',
|
||||||
|
'What does it feel like to be the most beautiful girl in the room?',
|
||||||
|
'If you were a transformer, you’d be Optimus Fine.',
|
||||||
|
' Do you know what’s on today’s menu? It’s Me ‘n’ U.',
|
||||||
|
'Are you a doctor? Because my heart beats faster when I see you.',
|
||||||
|
'Are you Australian? Because you meet all of my koalafications.'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const best = [
|
||||||
|
'Let me tie your shoes, cause I don’t want you falling for anyone else.',
|
||||||
|
' Are you an omelette? Because you’re making me egg-cited!',
|
||||||
|
'Did you sit in a pile of sugar? Cause you have a pretty sweet butt.',
|
||||||
|
'Do you have a pencil? Cause I want to erase your past and write our future.',
|
||||||
|
'Are you my Appendix? Because I have a funny feeling in my stomach that makes me feel like I should take you out.',
|
||||||
|
'Are you a florist? Cause ever since I met you, my life has been Rosey.',
|
||||||
|
'I wanna live in your socks so I can be with you every step of the way.',
|
||||||
|
'If God made anything more beautiful than you, I’m sure he’d keep it for himself.',
|
||||||
|
'Do you have a map? I’m getting lost in your eyes.',
|
||||||
|
'I don’t have a library card, but do you mind if I check you out?',
|
||||||
|
'Are you an orphanage? Cause I wanna give you kids.',
|
||||||
|
'Do you have a sunburn, or are you always this hot?',
|
||||||
|
'I was feeling a little off today, but you definitely turned me on.',
|
||||||
|
'Are you a fruit, because Honeydew you know how fine you look right now?',
|
||||||
|
'Do you live in a corn field, cause I’m stalking you.',
|
||||||
|
'Sorry, but you owe me a drink. [Why?] Because when I looked at you, I dropped mine.',
|
||||||
|
'Excuse me, is your name Earl Grey? Because you look like a hot-tea!',
|
||||||
|
'I’m not a hoarder but I really want to keep you forever.',
|
||||||
|
'Do you have a Band-Aid? Because I just scraped my knee falling for you.',
|
||||||
|
'Are you a parking ticket? ‘Cause you’ve got fine written all over you.',
|
||||||
|
'Are you mexican? Because you’re my juan and only!',
|
||||||
|
'Do you drink Pepsi? Because you’re so-da-licious!',
|
||||||
|
'Do I know you? Cause you look exactly like my next girlfriend.',
|
||||||
|
'I’m no organ donor but I’d be happy to give you my heart.',
|
||||||
|
'I seem to have lost my phone number. Can I have yours?',
|
||||||
|
'Is your nickname Chapstick? Because you’re da balm!',
|
||||||
|
'I’m not staring at your b00bs. I’m staring at your heart.',
|
||||||
|
'Can I take your picture to prove to all my friends that angels do exist?',
|
||||||
|
'I’ll give up my morning cereal to spoon you instead.',
|
||||||
|
'Do you want to see a picture of a beautiful person? (hold up a mirror)',
|
||||||
|
'I’m not drunk, I’m just intoxicated by YOU.',
|
||||||
|
'I was blinded by your beauty… I’m going to need your name and number for insurance purposes.',
|
||||||
|
'Is there an airport nearby or is that just my heart taking off?',
|
||||||
|
'There must be a lightswitch on my forehead because everytime I see you, you turn me on!',
|
||||||
|
'Hi, I’m writing a term paper on the finer things in life, and I was wondering if I could interview you?',
|
||||||
|
'Have you been to the doctor lately? Cause I think you’re lacking some Vitamin Me.',
|
||||||
|
'Can I follow you home? Cause my parents always told me to follow my dreams.',
|
||||||
|
'You look so familiar… didn’t we take a class together? I could’ve sworn we had chemistry.',
|
||||||
|
'Hi, I’m Mr. Right. Someone said you were looking for me?',
|
||||||
|
'Do you like Nintendo? Because Wii would look good together.',
|
||||||
|
'If you were a flower you’d be a damnnn-delion',
|
||||||
|
'If you were ground coffee, you’d be Espresso cause you’re so fine.',
|
||||||
|
'If I had a star for every time you brightened my day, I’d have a galaxy in my hand.',
|
||||||
|
'Damn, if being sexy was a crime, you’d be guilty as charged!',
|
||||||
|
'I was wondering if you had an extra heart? Mine seems to have been stolen',
|
||||||
|
'Do you smoke pot? Because weed be cute together.',
|
||||||
|
'I thought happiness started with an H. Why does mine start with U?',
|
||||||
|
'Are you a campfire? Cause you are hot and I want s’more.',
|
||||||
|
'If you were a tropical fruit, you’d be a Fine-apple!',
|
||||||
|
'Are you a banana? Because I find you a-peeling'
|
||||||
|
]
|
||||||
|
|
||||||
|
const anime = [
|
||||||
|
'Hey darling, I must be in Infinite Tsukuyomi, cause you’re like a dream come true. (Naruto)',
|
||||||
|
'Do you have a pen? So I can write your virginity in my death note. (Death Note)',
|
||||||
|
'Our love is over 9000. Know what I am Saiyan? (Dragon Ball)',
|
||||||
|
'Do you believe in fate? How about you stay the night? (Fate)',
|
||||||
|
'Are you a trap card? Because I’ve Fallen for you. (Yu-Gi-Oh)',
|
||||||
|
'Baby, you can call me Luffy, because I’ll bend anyway you want me to. (One Piece)',
|
||||||
|
'I don’t need 99 souls. All I need is yours. (Soul Eater)',
|
||||||
|
'Did you like Ghostory? How about making our story? (Ghostory)',
|
||||||
|
'You’re hotter than the Amaterasu. (Naruto)',
|
||||||
|
'I know a mystery even Detective Conan can’t solve: The mystery of how you got so damn beautiful! (Case Closed)',
|
||||||
|
'Girl have you mastered the Rasengan? Because every time your hand touches me you make me dizzy. (Naruto)',
|
||||||
|
'Zoro has the three sword style. But I’m really good with my one sword. (One Piece)',
|
||||||
|
'You must be better than Kuuhaku. Because when I first saw you, you already won my heart. (No Game No Life)',
|
||||||
|
'If I just had a Geass, I’d command you to be mine. (Code Geass)',
|
||||||
|
'Call me All Might cause I’m just looking to Texas Smash. (My Hero Academia)',
|
||||||
|
'Something is rising and it isn’t the shield hero. (The Rising of the Shield Hero)',
|
||||||
|
'I wish I was a demon because I really want you to slay me tonight. (Demon Slayer)',
|
||||||
|
'Are you a Wing Spiker? Cause you make my pulse spike too! (Haikyuu)',
|
||||||
|
'Are you a part of the phantom thieves? Because you just stole my heart. (Persona 5)',
|
||||||
|
'Is your name Erza? Cause my cheeks go Scarlet when I think of you. (Fairy Tale)',
|
||||||
|
'Do you have the Byakugaan, because it feels like you can see right through my Heart. (Naruto)',
|
||||||
|
'Is your name Levi? Because I love you GAJEEL-ION times more than Jet and Droy. (Fairy Tale)',
|
||||||
|
'Jeagar on the streets, Titan in the bed. (Attack on Titan )',
|
||||||
|
'You’re the hospital bed for my Deku. (My Hero Academia)',
|
||||||
|
'I was just checking you out from across the room with my Sharingan. (Naruto)',
|
||||||
|
'Are you Chisaki? Because I wanna Detroit smash you. (My Hero Academia)',
|
||||||
|
'Are you Nezuko? Because I want to be in your box. (Demon Slayer)',
|
||||||
|
'Just say yes and I’ll give you more than seven eurekas. (Eureka Seven)',
|
||||||
|
'You remind me of Menma. Because even when I can’t see you, I still feel you inside my heart. (Anohana)',
|
||||||
|
'Are you Gaara? Because love is written all over your face. (Naruto)',
|
||||||
|
'Are you Karasuno’s Captain? Because you’re my number one. (Haikyuu)',
|
||||||
|
'Orochimaru: Be my vessel, I want to be inside you. (Naruto)',
|
||||||
|
'Are you Kikyo? Because I think you shot an arrow through my heart. (Inuyasha)',
|
||||||
|
'Are you from dragon ball, because I wanna blow my Picciload in you. (Dragon Ball)',
|
||||||
|
'Are you Makise Kurisu? Because I will travel world lines to be with you. (Steins;Gate)',
|
||||||
|
'Is your name Cana? Um, Cana call you mine? (Fairy Tail Guild)',
|
||||||
|
'Let’s have a future diary. A diary of the future of you and me. (Future Diary)',
|
||||||
|
'You’re so sexy and that’s a deadly sin! (The Seven Deadly Sins)',
|
||||||
|
'Don’t need to be a phantom thief to steal your heart.',
|
||||||
|
'Show me your Bankai, big boy. (Bleach)',
|
||||||
|
'Did Buu attack you? Because you’re as sweet as candy. (Dragon Ball)',
|
||||||
|
'Lelouch Vi Britannia commands you to give me your number. (Code Geass)',
|
||||||
|
'Are you a tuner monster? Because you’re powering up my Syncro. (Yu-Gi-Oh!)',
|
||||||
|
'Damn girl, Are you Kira Yoshikage? Cause you blow me away. (JoJo’s Bizarre Adventure)',
|
||||||
|
'I’d trade an arm and a leg to get a piece of your philosopher’s stone. (Fullmetal Alchemist)',
|
||||||
|
'Are you a pokemon? Because I wanna Peak-at-you? (Pokemon)',
|
||||||
|
'Roses are red, Light is dead, will you be the butter to my bread? (Death Note)',
|
||||||
|
'Hey Girl, you Bulma mind. (Dragon Ball)',
|
||||||
|
'Are you Saitama? Because you got me down in one move. (One-Punch Man)',
|
||||||
|
'Hey! Are you the railgun? Because I can feel a spark. (A Certain Scientific Railgun)',
|
||||||
|
'Are you a loli? Because you’re worth going to jail for. (A lolicon)',
|
||||||
|
'Are you from Howl’s Moving Castle? Because you take my spirit away. (Howl’s Moving Castle)',
|
||||||
|
'I can be the Aizawa to your sleeping bag. (My Hero Academia)',
|
||||||
|
'Equivalent exchange. I’ll give you half of my life, so give me half of yours! (Fullmetal Alchemist)',
|
||||||
|
'Even if it means risking my existence, I’ll cross different world lines just to find you. (Steins;Gate)',
|
||||||
|
'Can I touch your Pikacheeks? (Pokemon)',
|
||||||
|
'Better wear my sunglasses because you Meiko my day so bright. (Prison School)',
|
||||||
|
'Are you Hiro? Because I want you to be my darling. (Darling in the Franxx)',
|
||||||
|
'Are you a death note? Because you make my heart stop. (Death Note)',
|
||||||
|
'I’ll love you longer than all the One Piece episodes. (One Piece)'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'pickupline',
|
||||||
|
description: 'Get a pickup line from our selection of 200 lines!',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
const nameList = new Map([['cheesy', cheesy], ['funny', funny], ['smooth', smooth], ['best', best], ['anime', anime]]);
|
||||||
|
|
||||||
|
if (args[0] == 'sources') {
|
||||||
|
message.reply("The normal lines are from https://ponly.com/200-pick-up-lines/\nThe anime lines are from https://thoughtcatalog.com/january-nelson/2021/06/anime-pick-up-lines/")
|
||||||
|
.then((msg) => { msg.suppressEmbeds(true); })
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length < 1 || (!nameList.get(args[0]) && args[0] != 'random')) { return message.reply("Please use the following format !pickupline <'cheesy', 'funny', 'smooth', 'best', 'anime', 'random', 'sources'>"); }
|
||||||
|
|
||||||
|
var key;
|
||||||
|
if (args[0] == 'random') {
|
||||||
|
let keyInd = Math.floor(Math.random() * nameList.size);
|
||||||
|
key = Array.from(nameList.keys())[keyInd];
|
||||||
|
} else {
|
||||||
|
key = args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const arr = nameList.get(key);
|
||||||
|
keyInd = Math.floor(Math.random() * arr.length);
|
||||||
|
try {
|
||||||
|
message.reply(arr[keyInd]);
|
||||||
|
} catch {
|
||||||
|
message.channel.send(arr[keyInd]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+417
-62
@@ -1,29 +1,381 @@
|
|||||||
const pathToFfmpeg = require('ffmpeg-static');
|
const pathToFfmpeg = require('ffmpeg-static');
|
||||||
const { joinVoiceChannel, createAudioResource } = require('@discordjs/voice');
|
// const { joinVoiceChannel, createAudioResource } = require('@discordjs/voice');
|
||||||
const { generateDependencyReport } = require('@discordjs/voice');
|
const { VoiceConnectionStatus, AudioPlayerStatus, createAudioPlayer, StreamType, joinVoiceChannel, createAudioResource, getVoiceConnection } = require('@discordjs/voice');
|
||||||
const { VoiceConnectionStatus, AudioPlayerStatus, createAudioPlayer, StreamType } = require('@discordjs/voice');
|
const { MessageActionRow, MessageButton, MessageEmbed, MessageSelectMenu, Message } = require('discord.js');
|
||||||
const play = require('play-dl');
|
const play = require('play-dl');
|
||||||
|
|
||||||
// Leave here to be initialized at the program's start
|
|
||||||
const player = createAudioPlayer();
|
|
||||||
|
|
||||||
// Note: Unsure of what this does , but may be related to the play-dl lib (my notes are inconsistent)
|
// Note: Unsure of what this does , but may be related to the play-dl lib (my notes are inconsistent)
|
||||||
// play.authorization();
|
// play.authorization();
|
||||||
|
|
||||||
|
function playStopEmbed(bot, interaction, yt_info, stopped, message = null) {
|
||||||
|
if (stopped) {
|
||||||
|
var em = interaction.message.embeds[0];
|
||||||
|
rows = [];
|
||||||
|
em.description = new String;
|
||||||
|
em.description = 'IS NOW STOPPED';
|
||||||
|
|
||||||
|
interaction.update({embeds: [em], components: rows});
|
||||||
|
} else {
|
||||||
|
const author = {
|
||||||
|
name: "Selmer Bot",
|
||||||
|
url: "",
|
||||||
|
iconURL: bot.user.displayAvatarURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
const newEmbed = new MessageEmbed()
|
||||||
|
.setColor('#0F00F0')
|
||||||
|
.setTitle(`${yt_info.video_details.title}`)
|
||||||
|
.setAuthor(author)
|
||||||
|
.setDescription('IS NOW PLAYING')
|
||||||
|
.setURL(yt_info.video_details.url)
|
||||||
|
.setThumbnail(yt_info.video_details.thumbnails[0].url);
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('PAUSE')
|
||||||
|
.setLabel('⏸️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('STOP')
|
||||||
|
.setLabel('⏹️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('SKIP')
|
||||||
|
.setLabel('⏭️')
|
||||||
|
.setStyle('SECONDARY')
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
const m = message.reply({ embeds: [newEmbed], components: [row] });
|
||||||
|
m.then((msg) => {
|
||||||
|
const data = bot.audioData.get(message.guild.id);
|
||||||
|
data[2] = msg.id;
|
||||||
|
bot.audioData.set(message.guild.id, data);
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
interaction.update({embeds: [newEmbed], components: [row]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function pause_start_stop(interaction, bot, message = null, command = null) {
|
||||||
|
try {
|
||||||
|
var player, em;
|
||||||
|
|
||||||
|
if (interaction) {
|
||||||
|
player = bot.audioData.get(interaction.guildId)[0];
|
||||||
|
command = interaction.customId.toLowerCase();
|
||||||
|
em = interaction.message.embeds[0];
|
||||||
|
} else {
|
||||||
|
player = bot.audioData.get(message.guild.id)[0];
|
||||||
|
em = message.embeds[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var rows = [new MessageActionRow()];
|
||||||
|
|
||||||
|
if (command == "pause") {
|
||||||
|
rows[0].addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('RESUME')
|
||||||
|
.setLabel('▶️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('STOP')
|
||||||
|
.setLabel('⏹️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('SKIP')
|
||||||
|
.setLabel('⏭️')
|
||||||
|
.setStyle('SECONDARY')
|
||||||
|
);
|
||||||
|
|
||||||
|
em.description = 'IS NOW PAUSED';
|
||||||
|
player.pause();
|
||||||
|
|
||||||
|
} else if (command == "resume") {
|
||||||
|
rows[0].addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('PAUSE')
|
||||||
|
.setLabel('⏸️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('STOP')
|
||||||
|
.setLabel('⏹️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('SKIP')
|
||||||
|
.setLabel('⏭️')
|
||||||
|
.setStyle('SECONDARY')
|
||||||
|
);
|
||||||
|
|
||||||
|
em.description = 'IS NOW PLAYING';
|
||||||
|
|
||||||
|
player.unpause();
|
||||||
|
} else if (command == "stop") {
|
||||||
|
playStopEmbed(bot, interaction, null, true);
|
||||||
|
|
||||||
|
const connection = getVoiceConnection(interaction.guild.id);
|
||||||
|
|
||||||
|
player.stop();
|
||||||
|
|
||||||
|
//Remove everything from queue
|
||||||
|
bot.audioData.delete(interaction.guildId);
|
||||||
|
|
||||||
|
if (connection) { connection.destroy(); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction) { interaction.update({embeds: [em], components: rows}); }
|
||||||
|
else {
|
||||||
|
const data = bot.audioData.get(message.guild.id);
|
||||||
|
|
||||||
|
// var msg = message.channel.messages.cache.get(data[2]);
|
||||||
|
const newEmbed = message.embeds[0];
|
||||||
|
newEmbed.description = "Has been deferred";
|
||||||
|
message.edit({ embeds: [ newEmbed ], components: []});
|
||||||
|
|
||||||
|
const m = message.reply({embeds: [em], components: rows});
|
||||||
|
m.then((msg) => {
|
||||||
|
const data = bot.audioData.get(message.guild.id);
|
||||||
|
data[2] = msg.id;
|
||||||
|
bot.audioData.set(message.guild.id, data);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
rows = [];
|
||||||
|
em.description = new String('IS NOW STOPPED');
|
||||||
|
interaction.update({embeds: [em], components: rows});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function playNext(interaction, bot, message = null) {
|
||||||
|
// https://discordjs.guide/voice/audio-player.html#taking-action-within-the-error-handler
|
||||||
|
|
||||||
|
//Setup data[1] = {info: yt_info, resource: resource}
|
||||||
|
var guildId;
|
||||||
|
if (message != null) { guildId = message.guild.id; }
|
||||||
|
else { guildId = interaction.guildId; }
|
||||||
|
|
||||||
|
let data = bot.audioData.get(guildId);
|
||||||
|
const player = data[0];
|
||||||
|
|
||||||
|
//Check if the queue is empty
|
||||||
|
if (data[1].length <= 0) {
|
||||||
|
player.stop();
|
||||||
|
bot.audioData.delete(guildId);
|
||||||
|
if (message) { return true; }
|
||||||
|
else { return playStopEmbed(bot, interaction, null, true); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const resource = data[1][0].resource;
|
||||||
|
const yt_info = data[1][0].yt_info;
|
||||||
|
player.stop();
|
||||||
|
|
||||||
|
//Play the thing
|
||||||
|
player.play(resource);
|
||||||
|
|
||||||
|
//remove the song from queue
|
||||||
|
delete data[1][0];
|
||||||
|
data[1] = data[1].filter(n => n);
|
||||||
|
|
||||||
|
bot.audioData.set(guildId, data);
|
||||||
|
|
||||||
|
//Add the embed
|
||||||
|
var msg = message;
|
||||||
|
if (!message) {
|
||||||
|
msg = interaction.message;
|
||||||
|
interaction.update({ embeds: [ new MessageEmbed(interaction.message.embeds[0]).setDescription("IS NOW STOPPED") ], components: []});
|
||||||
|
}
|
||||||
|
|
||||||
|
playStopEmbed(bot, interaction, yt_info, false, msg);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fromMessage(bot, command, msg) {
|
||||||
|
//Setup data[1] = {info: yt_info, resource: resource}
|
||||||
|
const guildId = msg.guild.id;
|
||||||
|
let data = bot.audioData.get(guildId);
|
||||||
|
if (!data) { return msg.reply("No music is currently playing!"); }
|
||||||
|
|
||||||
|
const player = data[0];
|
||||||
|
const message = msg.channel.messages.cache.get(data[2]);
|
||||||
|
// console.log(message);
|
||||||
|
|
||||||
|
var em;
|
||||||
|
if (message.embeds) { em = message.embeds[0]; }
|
||||||
|
var rows;
|
||||||
|
|
||||||
|
if (command == 'stop') {
|
||||||
|
em = message.embeds[0];
|
||||||
|
rows = [];
|
||||||
|
em.description = new String;
|
||||||
|
em.description = 'IS NOW STOPPED';
|
||||||
|
|
||||||
|
player.stop();
|
||||||
|
const connection = getVoiceConnection(guildId);
|
||||||
|
if (connection) { connection.destroy(); }
|
||||||
|
|
||||||
|
bot.audioData.delete(guildId);
|
||||||
|
msg.reply("Audio stopped!");
|
||||||
|
|
||||||
|
} else if (command == 'skip') {
|
||||||
|
if (playNext(null, bot, message)) {
|
||||||
|
rows = [];
|
||||||
|
em = message.embeds[0];
|
||||||
|
em.description = new String;
|
||||||
|
em.description = 'IS NOW STOPPED';
|
||||||
|
|
||||||
|
msg.reply("Audio stopped!");
|
||||||
|
}
|
||||||
|
} else if (command == 'pause' || command == 'resume') {
|
||||||
|
pause_start_stop(null, bot, message, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
message.edit({embeds: [em], components: rows});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function showQueue(bot, message, interaction = null, page = 0) {
|
||||||
|
const guild = message.guild.id;
|
||||||
|
const data = bot.audioData.get(guild);
|
||||||
|
if (!data) { return message.reply("The audio queue is empty!"); }
|
||||||
|
|
||||||
|
const rawQueue = data[1];
|
||||||
|
if (!rawQueue || rawQueue.length <= 0) { return message.reply("The audio queue is empty!"); }
|
||||||
|
|
||||||
|
const songList = [];
|
||||||
|
var fiveSongs = '';
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
rawQueue.forEach(function (rawSong) {
|
||||||
|
const songDetails = rawSong.yt_info.video_details;
|
||||||
|
fiveSongs += `${i + 1}. ${songDetails.title}\n`;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
//Split the songs into pages of 10
|
||||||
|
if (i % 10 == 0) { songList.push(fiveSongs); fiveSongs = ''; }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (page >= songList.length) { page = songList.length - 1 }
|
||||||
|
if (page < 0) { page = 0; } //LEAVE AS TWO IF's AS THE LENGTH MIGHT BE 0
|
||||||
|
|
||||||
|
if (songList.length == 0) { songList.push(fiveSongs); }
|
||||||
|
|
||||||
|
//Create the embed
|
||||||
|
const author = {
|
||||||
|
name: "Selmer Bot",
|
||||||
|
url: "",
|
||||||
|
iconURL: bot.user.displayAvatarURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
const newEmbed = new MessageEmbed()
|
||||||
|
.setTitle("SONG QUEUE")
|
||||||
|
.setAuthor(author)
|
||||||
|
.setDescription(songList[page])
|
||||||
|
.setFooter({ text: `Page ${page + 1}` })
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId(`audioQueue|${page - 1}`)
|
||||||
|
.setLabel('⬅️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId(`audioQueue|${page + 1}`)
|
||||||
|
.setLabel('➡️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
if (interaction) {
|
||||||
|
interaction.update({embeds: [newEmbed], components: [row]});
|
||||||
|
} else {
|
||||||
|
message.reply({ embeds: [newEmbed], components: [row] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function removeFromQueue(bot, message, posStr) {
|
||||||
|
const guildId = message.guild.id;
|
||||||
|
let data = bot.audioData.get(guildId);
|
||||||
|
if (!data) { return message.reply("The audio queue is empty!"); }
|
||||||
|
|
||||||
|
const rawQueue = data[1];
|
||||||
|
if (!rawQueue || rawQueue.length <= 0) { return message.reply("The audio queue is empty!"); }
|
||||||
|
else if (isNaN(posStr) || Number(posStr) > rawQueue.length) { return message.reply("Please specify a number within queue bounds!"); }
|
||||||
|
|
||||||
|
const pos = Number(posStr) - 1;
|
||||||
|
const details = rawQueue[pos].yt_info.video_details;
|
||||||
|
|
||||||
|
delete data[1][pos];
|
||||||
|
data[1] = data[1].filter(n => n);
|
||||||
|
|
||||||
|
bot.audioData.set(guildId, data);
|
||||||
|
|
||||||
|
const newEmbed = new MessageEmbed()
|
||||||
|
.setColor('#0F00F0')
|
||||||
|
.setTitle(`${details.title}`)
|
||||||
|
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||||
|
.setDescription( `has been removed from position ${pos + 1} in queue!`)
|
||||||
|
.setThumbnail(details.thumbnails[0].url);
|
||||||
|
|
||||||
|
message.reply({ embeds: [newEmbed] });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function shuffleQueue(bot, message) {
|
||||||
|
const guildId = message.guild.id;
|
||||||
|
let data = bot.audioData.get(guildId);
|
||||||
|
if (!data) { return message.reply("The audio queue is empty!"); }
|
||||||
|
|
||||||
|
let rawQueue = data[1];
|
||||||
|
if (!rawQueue || rawQueue.length <= 0) { return message.reply("The audio queue is empty!"); }
|
||||||
|
|
||||||
|
//Shuffle the queue
|
||||||
|
rawQueue = rawQueue.sort(() => Math.random()-0.5);
|
||||||
|
|
||||||
|
data[1] = rawQueue;
|
||||||
|
|
||||||
|
bot.audioData.set(guildId, data);
|
||||||
|
|
||||||
|
message.reply("The queue has been shuffled!\nThe new queue is:");
|
||||||
|
showQueue(bot, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: "audio",
|
name: "audio",
|
||||||
async execute(message, args, Discord, Client, bot) {
|
description: 'Play a song from YouTube, add free!',
|
||||||
// message.channel.send("This command has not been set up yet\nSorry!");
|
async execute(message, args, Discord, Client, bot, interaction = null) {
|
||||||
// return;
|
const commandList = ['stop', 'skip', 'pause', 'resume'];
|
||||||
if (args[0] == "play") {
|
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
message.reply("Please specify a function (play, pause, unpause or stop)");
|
message.reply("Please use the following format _!audio [song name or URL]_ **or** _!audio queue_");
|
||||||
return;
|
return;
|
||||||
} else if (args.length < 2) {
|
} else if (args[0] == 'queue') {
|
||||||
message.reply("Please provide a song url");
|
return showQueue(bot, message);
|
||||||
return;
|
} else if (commandList.indexOf(args[0]) != -1) {
|
||||||
}
|
return fromMessage(bot, args[0], message);
|
||||||
|
} else if (args[0] == 'remove') {
|
||||||
|
if (args.length < 2) { return message.reply("Please specify a position in queue!"); }
|
||||||
|
return removeFromQueue(bot, message, args[1]);
|
||||||
|
} else if (args[0] == 'shuffle') {
|
||||||
|
return shuffleQueue(bot, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -36,69 +388,72 @@ module.exports = {
|
|||||||
message.reply("Please join a voice channel before you try this!");
|
message.reply("Please join a voice channel before you try this!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Test 930148609406685227
|
|
||||||
const channel = bot.channels.cache.get(message.member.voice.channel.id);
|
const channel = bot.channels.cache.get(message.member.voice.channel.id);
|
||||||
console.log(message.member.voice.channel.id);
|
// console.log(message.member.voice.channel.id);
|
||||||
|
|
||||||
const connection = joinVoiceChannel({
|
const connection = joinVoiceChannel({
|
||||||
channelId: channel.id,
|
channelId: channel.id,
|
||||||
guildId: channel.guild.id,
|
guildId: channel.guild.id,
|
||||||
adapterCreator: channel.guild.voiceAdapterCreator,
|
adapterCreator: channel.guild.voiceAdapterCreator,
|
||||||
});
|
});
|
||||||
|
|
||||||
connection.on(VoiceConnectionStatus.Ready, () => {
|
connection.on(VoiceConnectionStatus.Ready, () => {
|
||||||
console.log('Connected to the voice channel!');
|
// console.log('Connected to the voice channel!');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (args[0] == "play") {
|
let stream;
|
||||||
let stream;
|
let yt_info;
|
||||||
let info = "Playing __***";
|
if (args[0].startsWith("https://")) {
|
||||||
let yt_info;
|
if (!args[0].startsWith("https://www.youtube.com/") &&
|
||||||
if (args[1].startsWith("https://")) {
|
!args[0].startsWith("https://music.youtube.com/")) {
|
||||||
if (!args[1].startsWith("https://www.youtube.com/") &&
|
message.reply("This is not a valid YouTube URL");
|
||||||
!args[1].startsWith("https://music.youtube.com/")) {
|
return;
|
||||||
message.reply("This is not a valid YouTube URL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
yt_info = await play.video_info(args[1]);
|
|
||||||
// let stream = await play.stream_from_info(yt_info)
|
|
||||||
stream = await play.stream(args[1]);
|
|
||||||
|
|
||||||
console.log("Playing from a URL!");
|
|
||||||
} else {
|
|
||||||
yt_info = await play.search(args.slice(1).join(' '), {
|
|
||||||
limit: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
stream = await play.stream(yt_info[0].url);
|
|
||||||
yt_info = await play.video_info(yt_info[0].url);
|
|
||||||
}
|
}
|
||||||
|
yt_info = await play.video_info(args[0]);
|
||||||
|
// let stream = await play.stream_from_info(yt_info)
|
||||||
|
stream = await play.stream(args[0]);
|
||||||
|
|
||||||
//Add the video info to the return message
|
// console.log("Playing from a URL!");
|
||||||
info += yt_info.video_details.title + "***__\n";
|
} else {
|
||||||
info += "Check it out at " + yt_info.video_details.url + "\n";
|
yt_info = await play.search(args.join(' '), {
|
||||||
|
limit: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
stream = await play.stream(yt_info[0].url);
|
||||||
|
yt_info = await play.video_info(yt_info[0].url);
|
||||||
|
}
|
||||||
|
|
||||||
let resource = createAudioResource(stream.stream, {
|
let resource = createAudioResource(stream.stream, {
|
||||||
inputType: stream.type
|
inputType: stream.type
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// let audio = "em.mp3";
|
||||||
|
// let resource = createAudioResource(join(__dirname, audio));
|
||||||
|
|
||||||
|
const data = bot.audioData.get(channel.guild.id);
|
||||||
|
|
||||||
|
if (data && data[1]) {
|
||||||
|
//[player, [queue Array]]
|
||||||
|
data[1].push({yt_info: yt_info, resource: resource});
|
||||||
|
bot.audioData.set(message.guild.id, data);
|
||||||
|
message.reply(`_"${yt_info.video_details.title}" added to queue!_`);
|
||||||
|
} else {
|
||||||
|
const player = createAudioPlayer();
|
||||||
connection.subscribe(player);
|
connection.subscribe(player);
|
||||||
|
|
||||||
let audio = "em.mp3";
|
bot.audioData.set(message.guild.id, [player, new Array(), null]);
|
||||||
// let resource = createAudioResource(join(__dirname, audio));
|
|
||||||
player.play(resource);
|
player.play(resource);
|
||||||
|
|
||||||
|
|
||||||
player.on(AudioPlayerStatus.Playing, () => {
|
player.on(AudioPlayerStatus.Playing, () => {
|
||||||
console.log('The audio player has started playing!');
|
//Check maybe?
|
||||||
});
|
});
|
||||||
message.reply(info);
|
|
||||||
} else if (args[0] == "pause") {
|
playStopEmbed(bot, interaction, yt_info, false, message);
|
||||||
player.pause();
|
|
||||||
} else if (args[0] == "unpause") {
|
|
||||||
player.unpause();
|
|
||||||
} else if (args[0] == "stop") {
|
|
||||||
player.stop();
|
|
||||||
connection.destroy();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
}, pause_start_stop, playNext, showQueue
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
const { MessageEmbed } = require('discord.js');
|
||||||
|
|
||||||
|
|
||||||
|
//!poll <name> <option 1, option 2> [option 3...option 10]
|
||||||
|
module.exports = {
|
||||||
|
name: "poll",
|
||||||
|
description: "Create a cool poll embed (with time up to 1 hour!)",
|
||||||
|
async execute(message, args, Discord, Client, bot) {
|
||||||
|
if (args.length < 3) { return message.reply("Please provide a poll name, time (like 1:25 or 0 for not timed) and 1 - 10 options!"); }
|
||||||
|
if (args.length > 12) { return message.reply("Please specify less than 10 options!"); }
|
||||||
|
|
||||||
|
const timeList = [ '1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣', '6️⃣', '7️⃣', '8️⃣', '9️⃣', '🔟' ];
|
||||||
|
const author = {
|
||||||
|
name: "Selmer Bot",
|
||||||
|
url: "",
|
||||||
|
iconURL: bot.user.displayAvatarURL()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var time = 0;
|
||||||
|
var temp;
|
||||||
|
var isTimed = !Number.isNaN(Number(args[1].split(":")[0]));
|
||||||
|
|
||||||
|
if (!isTimed) {
|
||||||
|
temp = `This poll was created by ${message.author} and has no time limit!\n`;
|
||||||
|
} else {
|
||||||
|
time += (Number(args[1].split(':')[0]) * 60) + Number(args[1].split(':')[1]);
|
||||||
|
temp = `This poll was created by ${message.author} and ends <t:${Math.floor((new Date()).getTime()/1000) + time}:R>!\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//args[0] is the poll name
|
||||||
|
for(let i = 2; i < args.length; i ++) {
|
||||||
|
// complist.push({ name: `${timeList[i - 1]}: ${args[i]}`, value: "" });
|
||||||
|
temp += `\n${timeList[i - 2]}: ${args[i]}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const embd = new MessageEmbed()
|
||||||
|
.setTimestamp()
|
||||||
|
.setTitle(`${args[0]}`)
|
||||||
|
.setDescription(temp)
|
||||||
|
.setAuthor(author)
|
||||||
|
|
||||||
|
message.channel.send({ embeds: [embd] }).then((msg) => {
|
||||||
|
for(let i = 0; i < args.length - 2; i ++) {
|
||||||
|
msg.react(timeList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isTimed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filter = (reaction, user) => {
|
||||||
|
return timeList.includes(reaction.emoji.name);
|
||||||
|
};
|
||||||
|
let embd = msg.embeds[0];
|
||||||
|
|
||||||
|
//Replace the "and ends in <t:timestamp:R>" part with "has ended"
|
||||||
|
const collector = msg.createReactionCollector({ filter, time: time * 1000 });
|
||||||
|
collector.on('end', collected => {
|
||||||
|
let winnerC = 0;
|
||||||
|
let winners = [];
|
||||||
|
const col = Array.from(collected);
|
||||||
|
|
||||||
|
for (let i = 0; i < col.length; i++) {
|
||||||
|
const key = col[i][0];
|
||||||
|
const val = col[i][1];
|
||||||
|
|
||||||
|
if (val.count > winnerC) {
|
||||||
|
winners = [key];
|
||||||
|
winnerC = val.count;
|
||||||
|
} else if (val.count == winnerC) {
|
||||||
|
winners.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let temp;
|
||||||
|
if (winners.length > 1) {
|
||||||
|
temp = `The winners are: \`${winners.join(", ")}\` with \`${winnerC}\` votes each!`;
|
||||||
|
} else {
|
||||||
|
temp = `The winner is: \`${winners.join(", ")}\` with \`${winnerC}\` votes!`;
|
||||||
|
}
|
||||||
|
|
||||||
|
embd.description = embd.description.substr(0, 50) + ` has ended!\n${temp}` + embd.description.substr(embd.description.indexOf("!") + 1);
|
||||||
|
msg.edit({ embeds: [embd] });
|
||||||
|
msg.reply(temp);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
const hastebin = require("hastebin-gen");
|
const hastebin = require("hastebin-gen");
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
|
||||||
module.exports ={
|
module.exports ={
|
||||||
name: "scrape",
|
name: "scrape",
|
||||||
@@ -12,18 +13,21 @@ module.exports ={
|
|||||||
const html = response.data;
|
const html = response.data;
|
||||||
const $ = cheerio.load(html);
|
const $ = cheerio.load(html);
|
||||||
//lyrics = $('.para_row').text();
|
//lyrics = $('.para_row').text();
|
||||||
|
|
||||||
const haste = await hastebin(html, { extension: "txt" });
|
const haste = await hastebin(html, { extension: "txt" });
|
||||||
message.channel.send(haste);
|
message.channel.send(haste);
|
||||||
// console.log(lyrics);
|
// console.log(lyrics);
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
if (err.message.indexOf('The "url" argument must be of type string') != -1) {
|
if (err.message.indexOf('The "url" argument must be of type string') != -1) {
|
||||||
message.reply("The URL should be a string!");
|
message.reply("The URL should be a string!");
|
||||||
|
} else if (err.code == 'ERR_BAD_REQUEST') {
|
||||||
|
message.reply("404 link not valid!")
|
||||||
} else {
|
} else {
|
||||||
message.reply("Oops! There's been an error");
|
message.reply("Oops! There's been an error, click the ✅ to report this!");
|
||||||
|
addComplaintButton(bot, message);
|
||||||
|
console.log(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(err);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
const { Modal, TextInputComponent, MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('discord.js');
|
||||||
|
|
||||||
|
const dateFns = require('date-fns');
|
||||||
|
const { formatToTimeZone } = require('date-fns-timezone');
|
||||||
|
const Alpaca = require('@alpacahq/alpaca-trade-api');
|
||||||
|
const apiKeyId = process.env.alpKey || require('../../config.json').alpKey;
|
||||||
|
const secretKey = process.env.alpSec || require('../../config.json').alpSec;
|
||||||
|
const alpaca = new Alpaca({
|
||||||
|
keyId: apiKeyId,
|
||||||
|
secretKey: secretKey,
|
||||||
|
paper: true,
|
||||||
|
usePolygon: false
|
||||||
|
});
|
||||||
|
|
||||||
|
//This is the same as making the following request: https://data.alpaca.markets/v2/stocks/snapshots?symbols={stock_symbols_here}
|
||||||
|
async function getStockData(bot, message, args, stock) {
|
||||||
|
try {
|
||||||
|
const snapshotPromise = alpaca.getSnapshot(stock);
|
||||||
|
|
||||||
|
snapshotPromise.then(snapshot => {
|
||||||
|
const embd = new MessageEmbed()
|
||||||
|
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||||
|
.setFooter({ text: 'Selmer Bot uses Alpaca for stock information'})
|
||||||
|
|
||||||
|
if (args[1] == 'trade') {
|
||||||
|
const lt = snapshot.LatestTrade;
|
||||||
|
embd.setTitle(`${stock} Latest Trade`)
|
||||||
|
.setTimestamp(lt.Timestamp)
|
||||||
|
.addFields(
|
||||||
|
{name: 'Price', value: `${lt.Price}`},
|
||||||
|
{name: 'Size', value: `${lt.Size}`},
|
||||||
|
|
||||||
|
//This will always be IEX, as it is the only exchange the free version offers
|
||||||
|
{name: 'Exchange', value: `IEX (${lt.Exchange})`},
|
||||||
|
)
|
||||||
|
} else if (args[1] == 'quote') {
|
||||||
|
if (args[2] == 'after') {
|
||||||
|
return message.reply("Due to the markets not being open, there is no quote data available!");
|
||||||
|
}
|
||||||
|
const lq = snapshot.LatestQuote;
|
||||||
|
embd.setTitle(`${stock} Latest Quote`)
|
||||||
|
.setTimestamp(lq.Timestamp)
|
||||||
|
.addFields(
|
||||||
|
{name: 'Ask Price', value: `${lq.AskPrice}`},
|
||||||
|
{name: 'Ask Size', value: `${lq.AskSize}`},
|
||||||
|
{name: 'Bid price', value: `${lq.BidPrice}`},
|
||||||
|
{name: 'Bid Size', value: `${lq.BidSize}`},
|
||||||
|
|
||||||
|
//This will always be IEX, as it is the only exchange the free version offers
|
||||||
|
{name: 'Exchange', value: `IEX (${lq.Exchange})`},
|
||||||
|
)
|
||||||
|
} else if (args[1] == 'bars') {
|
||||||
|
const mb = snapshot.MinuteBar;
|
||||||
|
const db = snapshot.DailyBar;
|
||||||
|
const pdb = snapshot.PrevDailyBar;
|
||||||
|
embd.setTitle(`${stock} Bars`)
|
||||||
|
.setTimestamp(mb.Timestamp)
|
||||||
|
.addFields(
|
||||||
|
{name: 'Minute Bar', value: `Open Price: ${mb.OpenPrice},\nClose Price: ${mb.ClosePrice},\nHigh Price: ${mb.HighPrice},\nLow Price: ${mb.LowPrice},\nVolume: ${mb.Volume},\nCount: ${mb.TradeCount},\nVWAP: ${mb.VWAP}`},
|
||||||
|
{name: 'Day Bar (Today)', value: `Open Price: ${db.OpenPrice},\nClose Price: ${db.ClosePrice},\nHigh Price: ${db.HighPrice},\nLow Price: ${db.LowPrice},\nVolume: ${db.Volume},\nCount: ${db.TradeCount},\nVWAP: ${db.VWAP}`},
|
||||||
|
{name: 'Day Bar (Yesterday)', value: `Open Price: ${pdb.OpenPrice},\nClose Price: ${pdb.ClosePrice},\nHigh Price: ${pdb.HighPrice},\nLow Price: ${pdb.LowPrice},\nVolume: ${pdb.Volume},\nCount: ${pdb.TradeCount},\nVWAP: ${pdb.VWAP}`},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return message.reply("The command format is: _!stocks <stock_name, 'hours'> <trade, quote, bars> [after]_");
|
||||||
|
}
|
||||||
|
|
||||||
|
message.reply({embeds: [embd]});
|
||||||
|
})
|
||||||
|
} catch(err) {
|
||||||
|
console.error(err);
|
||||||
|
message.reply("Uh Oh, there's been an error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData(bot, message, args) {
|
||||||
|
var stock;
|
||||||
|
if (args.length < 1) {
|
||||||
|
return message.reply("Please specify a stock (ex: AAPL, GOOG, etc)")
|
||||||
|
} else { stock = args[0];}
|
||||||
|
|
||||||
|
|
||||||
|
const format = `yyyy-MM-dd HH:mm:ss`;
|
||||||
|
const date = dateFns.format(new Date(), format);
|
||||||
|
|
||||||
|
alpaca.getClock().then((clock) => {
|
||||||
|
// var txt = `The market is currently ${clock.is_open ? 'open.' : 'closed.'}`;
|
||||||
|
|
||||||
|
alpaca.getCalendar({
|
||||||
|
start: date,
|
||||||
|
end: date
|
||||||
|
}).then((calendars) => {
|
||||||
|
let temp;
|
||||||
|
if (clock.is_open || args[2] == 'after') {
|
||||||
|
if (args[0] == 'hours') {
|
||||||
|
temp = `The markets opened at ${calendars[0].open} and will close at ${calendars[0].close} on ${date}.`;
|
||||||
|
return message.reply(temp);
|
||||||
|
}
|
||||||
|
getStockData(bot, message, args, stock);
|
||||||
|
} else {
|
||||||
|
// `The market is currently ${clock.is_open ? 'open.' : 'closed.'}`
|
||||||
|
//May be innacurate?
|
||||||
|
temp = `_The markets closed at \`${calendars[0].close}\` and will open again at \`${calendars[0].open}\` on \`${dateFns.format((new Date()).setDate(new Date().getDate() + 1), 'yyyy-MM-dd')}\`.\nTo get the last snapshot before market closure, add the \`after\` keyword to the end of your command (trade and bars ONLY), ex: !stocks GOOG bars after_`;
|
||||||
|
return message.reply(temp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//!stocks <stock_name, "hours"> <trade, quote, bars> [after]
|
||||||
|
module.exports = {
|
||||||
|
name: 'stocks',
|
||||||
|
description: "Have Selmer Bot give you \"current\" stock prices",
|
||||||
|
async execute(message, args, Discord, Client, bot) {
|
||||||
|
if (args[0] == 'help' || args.length < 1) {
|
||||||
|
return message.reply("The command format is: _!stocks <stock_name, 'hours'> <trade, quote, bars> [after]_");
|
||||||
|
}
|
||||||
|
getData(bot, message, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
const { MongoClient, ServerApiVersion, ConnectionClosedEvent } = require('mongodb');
|
||||||
|
const { exit } = require('process');
|
||||||
|
const { checkResponses } = require('./wordlist.js');
|
||||||
|
|
||||||
|
|
||||||
|
//Error checking function (message deleted error fix, workaround already applied but...)
|
||||||
|
//message.channel.send("Oops, there's been an error, please contact support!");
|
||||||
|
async function messageExists(message) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
message.channel.messages.fetch(message.id)
|
||||||
|
.then((fetchedMessage) => {
|
||||||
|
resolve(true);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
resolve(false);
|
||||||
|
})
|
||||||
|
} catch (err) { resolve(false); }
|
||||||
|
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function getResponse(convo, bot) {
|
||||||
|
const response = await bot.openai.createCompletion({
|
||||||
|
model: "text-davinci-002",
|
||||||
|
prompt: convo,
|
||||||
|
temperature: 0.9,
|
||||||
|
max_tokens: 150,
|
||||||
|
top_p: 1,
|
||||||
|
frequency_penalty: 0,
|
||||||
|
presence_penalty: 0.6,
|
||||||
|
stop: [" Human:", " AI:"],
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function convoManager(clientinp, bot, message) {
|
||||||
|
|
||||||
|
//Just in case, make sure it can't be changed
|
||||||
|
const client = clientinp;
|
||||||
|
const dbo = client.db("DM").collection(message.author.id);
|
||||||
|
|
||||||
|
if (message.content.startsWith('!')) {
|
||||||
|
if (message.content.split(' ')[0] == '!startconvo') {
|
||||||
|
//Check if a conversation already exists
|
||||||
|
dbo.find({'_id': {$exists: true}}).toArray((err, docs) => {
|
||||||
|
if (docs[0] != undefined) {
|
||||||
|
return message.channel.send("You're already in a conversation");
|
||||||
|
} else {
|
||||||
|
dbo.insertOne({convo: 'Human: Hello\nAI: Hello'});
|
||||||
|
return message.channel.send('-----Started Conversation-----\nuse _!endconvo_ to end the conversation!\n\n_Disclaimer: Your conversation data is stored for the duration of the conversation to help Selmer Bot better understand what you are saying *then deleted*_\n\n');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (message.content.split(' ')[0] == '!endconvo') {
|
||||||
|
dbo.drop();
|
||||||
|
return message.channel.send('-----Ended Conversation-----\nSee you next time!');
|
||||||
|
} else {
|
||||||
|
return message.channel.send('UNUSABLE DM COMMAND DETECTED');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dbo.find({convo: {$exists: true}}).toArray(async function (err, docs) {
|
||||||
|
const doc = docs[0];
|
||||||
|
if (!doc) { return message.reply('You aren\'t currently in a conversation\nUse _!startconvo_ to start one!'); }
|
||||||
|
|
||||||
|
//Checking Section
|
||||||
|
const check = checkResponses(message.content, "I'm sorry, I can't do that");
|
||||||
|
if (check != null) { return message.reply(check); }
|
||||||
|
|
||||||
|
|
||||||
|
let convo = doc.convo;
|
||||||
|
convo += `\nHuman: ${message.content}\n`;;
|
||||||
|
|
||||||
|
//Get the response
|
||||||
|
const r = await getResponse(convo, bot);
|
||||||
|
|
||||||
|
let response = r.data.choices[0].text;
|
||||||
|
|
||||||
|
convo += (response + '\n');
|
||||||
|
|
||||||
|
dbo.updateOne(doc, {$set: {convo: convo}});
|
||||||
|
response = response.replaceAll('AI: ', '').replaceAll('AI:\n', '');
|
||||||
|
|
||||||
|
//Very buggy so I'm adding this for now
|
||||||
|
message.channel.send(response);
|
||||||
|
|
||||||
|
//Note: Work with the following later
|
||||||
|
/* messageExists(message).then((e) => {
|
||||||
|
console.log(e);
|
||||||
|
if (e) { return message.reply(response); }
|
||||||
|
message.channel.send(response);
|
||||||
|
}) */
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//"Hello! discord_user:"
|
||||||
|
module.exports = {
|
||||||
|
name: 'chat',
|
||||||
|
description: 'chat',
|
||||||
|
convoManager,
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
message.reply("Please DM Selmer bot to use this command!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,414 @@
|
|||||||
|
const { Modal, TextInputComponent, MessageActionRow, MessageButton, MessageEmbed, Interaction } = require('discord.js');
|
||||||
|
const { checkRole } = require('../admin/verify');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Interaction} interaction
|
||||||
|
*/
|
||||||
|
function postEmbd(bot, desc, interaction, page, isGuild, id, refered) {
|
||||||
|
try {
|
||||||
|
const author = {
|
||||||
|
name: "Selmer Bot",
|
||||||
|
url: "",
|
||||||
|
iconURL: bot.user.displayAvatarURL()
|
||||||
|
};
|
||||||
|
|
||||||
|
const newEmbed = new MessageEmbed()
|
||||||
|
.setTitle("REMINDERS")
|
||||||
|
.setAuthor(author)
|
||||||
|
.setDescription(desc[page])
|
||||||
|
.setFooter({ text: `Page ${page + 1}` });
|
||||||
|
|
||||||
|
|
||||||
|
const row = new MessageActionRow();
|
||||||
|
//Make sure the page is never < 1
|
||||||
|
const prevbtn = new MessageButton()
|
||||||
|
.setCustomId(`reminderQueue|${isGuild}-${id}|`)
|
||||||
|
.setLabel('⬅️')
|
||||||
|
.setStyle('SECONDARY')
|
||||||
|
|
||||||
|
if (page <= 0) {
|
||||||
|
prevbtn.customId += `0`;
|
||||||
|
// prevbtn.setCustomId(`reminderQueue|${isGuild}-${id}|0`);
|
||||||
|
prevbtn.setDisabled(true);
|
||||||
|
} else {
|
||||||
|
prevbtn.customId += `${page - 1}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextbtn = new MessageButton()
|
||||||
|
.setCustomId(`reminderQueue|${isGuild}-${id}|`)
|
||||||
|
.setLabel('➡️')
|
||||||
|
.setStyle('SECONDARY');
|
||||||
|
|
||||||
|
if ((page + 1) >= desc.length) {
|
||||||
|
nextbtn.customId += `${desc.length}`;
|
||||||
|
// nextbtn.setCustomId(`reminderQueue|`);
|
||||||
|
nextbtn.setDisabled(true);
|
||||||
|
} else {
|
||||||
|
nextbtn.customId += `${page + 1}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
row.addComponents(prevbtn, nextbtn);
|
||||||
|
|
||||||
|
if (page > 0 || refered) {
|
||||||
|
interaction.update({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [newEmbed], components: [row] });
|
||||||
|
} else {
|
||||||
|
interaction.reply({ content: '_Note: To see a full list of reminder stats visit www.selmerbot.com _', embeds: [newEmbed], components: [row] });
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return interaction.reply("Uh Oh! There's been an error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function postForm(interaction, isGuild = false) {
|
||||||
|
// Create the modal
|
||||||
|
const modal = new Modal();
|
||||||
|
|
||||||
|
if (!isGuild) {
|
||||||
|
modal.setTitle('Creating a New Personal Reminder')
|
||||||
|
.setCustomId('newEventModal|user');
|
||||||
|
} else {
|
||||||
|
modal.setTitle('Creating a New Guild Reminder')
|
||||||
|
.setCustomId('newEventModal|guild');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add components to modal
|
||||||
|
// Create the text input components
|
||||||
|
// The label is the prompt the user sees for this input
|
||||||
|
// Short means only a single line of text
|
||||||
|
// Paragraph means multiple lines of text
|
||||||
|
|
||||||
|
const nameInp = new TextInputComponent()
|
||||||
|
.setCustomId('name')
|
||||||
|
.setLabel("What is the Event's name?")
|
||||||
|
.setStyle('SHORT');
|
||||||
|
|
||||||
|
const descInp = new TextInputComponent()
|
||||||
|
.setCustomId('description')
|
||||||
|
.setLabel("What's the event's description?")
|
||||||
|
.setStyle('PARAGRAPH');
|
||||||
|
|
||||||
|
const dateInp = new TextInputComponent()
|
||||||
|
.setCustomId('date')
|
||||||
|
.setLabel("What's the event's date?")
|
||||||
|
.setPlaceholder('1/1/2020')
|
||||||
|
.setStyle('SHORT');
|
||||||
|
|
||||||
|
const timeInp = new TextInputComponent()
|
||||||
|
.setCustomId('time')
|
||||||
|
.setLabel("What's the event's time?")
|
||||||
|
.setPlaceholder("2:00 PM or 14:00")
|
||||||
|
.setStyle('SHORT');
|
||||||
|
|
||||||
|
|
||||||
|
const locurlinp = new TextInputComponent()
|
||||||
|
.setCustomId('locationwurl')
|
||||||
|
.setLabel("Where is the event happening?")
|
||||||
|
.setPlaceholder('To add a URL, simply use location;url (the seperator is a semi-colon)')
|
||||||
|
.setStyle('SHORT');
|
||||||
|
|
||||||
|
// An action row only holds one text input,
|
||||||
|
// so you need one action row per text input.
|
||||||
|
const name = new MessageActionRow().addComponents(nameInp);
|
||||||
|
const desc = new MessageActionRow().addComponents(descInp);
|
||||||
|
const date = new MessageActionRow().addComponents(dateInp);
|
||||||
|
const time = new MessageActionRow().addComponents(timeInp);
|
||||||
|
const offset = new MessageActionRow().addComponents(locurlinp);
|
||||||
|
|
||||||
|
// Add inputs to the modal
|
||||||
|
modal.addComponents(name, desc, date, time, offset);
|
||||||
|
|
||||||
|
// Show the modal to the user
|
||||||
|
interaction.showModal(modal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#region DATABASE PROCESSING
|
||||||
|
|
||||||
|
function addEvent(obj, connection, interaction, embd) {
|
||||||
|
try {
|
||||||
|
var Id;
|
||||||
|
if (obj.event.userId != null) { Id = obj.event.userId }
|
||||||
|
else { Id = obj.event.guildId; }
|
||||||
|
connection.then((client) => {
|
||||||
|
// Update the Key object first to check if the time is already there
|
||||||
|
const kbo = client.db('main').collection('reminderKeys');
|
||||||
|
kbo.findOne(({ 'userId': Id })).then((doc) => {
|
||||||
|
const t = obj.time.toString();
|
||||||
|
try {
|
||||||
|
if (doc) {
|
||||||
|
if (doc.times.indexOf(obj.time) == -1) {
|
||||||
|
kbo.updateOne({ 'userId': Id }, { $push: { times: t } })
|
||||||
|
} else {
|
||||||
|
//Event already exists at this time
|
||||||
|
return interaction.reply("An event already exists at this time!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
doc = { userId: Id, times: [t] }
|
||||||
|
kbo.insertOne(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Update the Time object
|
||||||
|
const dbo = client.db('main').collection('reminders');
|
||||||
|
dbo.findOne({ time: t }).then((doc) => {
|
||||||
|
let n = 0;
|
||||||
|
if (doc) {
|
||||||
|
n = doc.amt;
|
||||||
|
doc.amt ++;
|
||||||
|
|
||||||
|
doc[`${n}`] = obj.event;
|
||||||
|
dbo.findOneAndReplace({ time: t }, doc);
|
||||||
|
} else {
|
||||||
|
const d = new Date(Number(obj.time));
|
||||||
|
doc = { "0": obj.event, "time": t, "month": d.getMonth(), "amt": 1 }; //Month used for clearing when the calendar month begins (maybe modify the garbage collection with an `else if (day == 1? clear last month)` )
|
||||||
|
dbo.insertOne(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Reply with the reminder in correct format
|
||||||
|
interaction.reply({ content: "REMINDER SAVED!", embeds: [embd], ephemeral: true });
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log("ERR");
|
||||||
|
console.error(err);
|
||||||
|
interaction.reply("Uh Oh! An error has occured!");
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err); interaction.reply("Uh Oh! An error has occured!");
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log("ERR");
|
||||||
|
console.error(err);
|
||||||
|
interaction.reply("Uh Oh! An error has occured!");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return interaction.reply("Uh Oh! An error has occured!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getEvents(bot, interaction, id, jpage = 0, isGuild = false, refered = false) {
|
||||||
|
var userId = false;
|
||||||
|
var guildId = false;
|
||||||
|
const numperpage = 5;
|
||||||
|
|
||||||
|
if (isGuild) {
|
||||||
|
guildId = id;
|
||||||
|
} else {
|
||||||
|
userId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.mongoconnection.then((client) => {
|
||||||
|
try {
|
||||||
|
var times;
|
||||||
|
const dbo = client.db('main').collection('reminderKeys');
|
||||||
|
|
||||||
|
//ReminderKeys are all stored as userId, the reminders themselves are not
|
||||||
|
dbo.findOne({$or: [ {userId: userId}, {userId: guildId} ]}).then((doc) => {
|
||||||
|
if (!doc) { return interaction.reply("No events exist!"); }
|
||||||
|
times = doc.times;
|
||||||
|
const tbo = client.db('main').collection('reminders');
|
||||||
|
|
||||||
|
tbo.find({time: {$in: times}}).toArray((err, docs) => {
|
||||||
|
//There's gotta be a better way
|
||||||
|
var temp = [""];
|
||||||
|
var page = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < docs.length; i ++) {
|
||||||
|
if (i != 0 && i % numperpage == 0) {
|
||||||
|
page ++;
|
||||||
|
temp[page] = '';
|
||||||
|
}
|
||||||
|
// temp += `__***Events On ${new Date(Number(docs[i].time))}***__\n\n`;
|
||||||
|
for (let j in docs[i]) {
|
||||||
|
if (!isNaN(j) && (docs[i][j].userId == userId || docs[i][j].guildId == guildId)) {
|
||||||
|
const obj = docs[i][j];
|
||||||
|
temp[page] += `Name: ${obj.name}\nDescription: ${obj.description}\nDate/Time: ${new Date(Number(docs[i].time))}\nOffset: ${obj.offset}\nLink: ${obj.link}\nLocation: ${obj.location}\n------------------------------\n`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create the embed
|
||||||
|
postEmbd(bot, temp, interaction, jpage, isGuild, id, refered);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return interaction.reply("Uh Oh! There's been an error!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//fields: [<name>, <description>, <date>, <time>, [offset], [url], [location]]
|
||||||
|
function processForm(bot, interaction) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
var guildId = null;
|
||||||
|
var userId = null;
|
||||||
|
var isGuild = false;
|
||||||
|
if (interaction.customId.toLowerCase().indexOf('user') != -1) {
|
||||||
|
userId = interaction.user.id;
|
||||||
|
} else {
|
||||||
|
guildId = interaction.guildId;
|
||||||
|
isGuild = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Get the values
|
||||||
|
const name = interaction.fields.getTextInputValue('name');
|
||||||
|
const desc = interaction.fields.getTextInputValue('description');
|
||||||
|
const date = new Date(interaction.fields.getTextInputValue('date'));
|
||||||
|
const timeTemp = interaction.fields.getTextInputValue('time');
|
||||||
|
const locurl = interaction.fields.getTextInputValue('locationwurl');
|
||||||
|
|
||||||
|
var loc = "N/A";
|
||||||
|
var url = "N/A";
|
||||||
|
if (locurl.indexOf(';') != -1) {
|
||||||
|
let temp = locurl.split(';');
|
||||||
|
loc = temp[0];
|
||||||
|
url = temp[1];
|
||||||
|
} else if (locurl.indexOf('http') != -1) {
|
||||||
|
//Set the URL
|
||||||
|
url = locurl;
|
||||||
|
} else if (locurl != "") {
|
||||||
|
//Set the location
|
||||||
|
loc = locurl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Process time
|
||||||
|
var timesplit = timeTemp.split(' ').filter((inp) => { return(inp.indexOf(':') != -1); });
|
||||||
|
if (timesplit.length == 0) { return interaction.reply("Please enter a date in one of the following formats: _2:00 PM or 14:00_"); }
|
||||||
|
|
||||||
|
timesplit = timesplit[0].split(":");
|
||||||
|
timesplit[0] = Number(timesplit[0]);
|
||||||
|
timesplit[1] = Number(timesplit[1]);
|
||||||
|
|
||||||
|
if (timeTemp.toLowerCase().indexOf('pm') != -1) { timesplit[0] += 12; }
|
||||||
|
//else if (timeTemp.toLowerCase().indexOf('am') != -1) {
|
||||||
|
|
||||||
|
date.setHours(timesplit[0]);
|
||||||
|
date.setMinutes(timesplit[1]);
|
||||||
|
|
||||||
|
const timeUTC = date.getTime();
|
||||||
|
|
||||||
|
//Make sure the reminder is at least 5 minutes into the future
|
||||||
|
var currentDate = new Date();
|
||||||
|
currentDate.setMinutes(currentDate.getMinutes() + 5);
|
||||||
|
|
||||||
|
if (currentDate.getTime() >= (timeUTC)) {
|
||||||
|
return interaction.reply("Please enter a date at least 5 minutes in the future!");
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = `***${name}*** is coming up in <t:${timeUTC/1000}:R> on <t:${timeUTC/1000}:F>`;
|
||||||
|
const embd = new MessageEmbed()
|
||||||
|
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||||
|
.setTitle(temp)
|
||||||
|
.setDescription(`Description: ${desc}`)
|
||||||
|
.addFields(
|
||||||
|
{ name: 'Time', value: `<t:${timeUTC/1000}:F>` },
|
||||||
|
{ name: 'Location', value: `${loc}` },
|
||||||
|
{ name: 'Link', value: `${url}` },
|
||||||
|
{ name: 'Offset', value: `Available on Website` }
|
||||||
|
);
|
||||||
|
|
||||||
|
const obj = { time: timeUTC, event: { guildId: guildId, userId: userId, name: name, description: desc, offset: 0, link: url, location: loc } }
|
||||||
|
addEvent(obj, bot.mongoconnection, interaction, embd, isGuild);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function modalHandle(bot, interaction) {
|
||||||
|
try {
|
||||||
|
//If the person selected "add" post the form
|
||||||
|
if (interaction.customId.indexOf('newEvent|User') != -1) {
|
||||||
|
if (interaction.user.id == interaction.customId.split('|')[2]) {
|
||||||
|
postForm(interaction);
|
||||||
|
}
|
||||||
|
} else if (interaction.customId == 'newEvent|Guild') {
|
||||||
|
postForm(interaction, true);
|
||||||
|
} else if (interaction.isModalSubmit()) {
|
||||||
|
//The user is submitting a form
|
||||||
|
processForm(bot, interaction);
|
||||||
|
} else if (interaction.customId == 'getEvents') {
|
||||||
|
if (interaction.channel.type === "DM") {
|
||||||
|
getEvents(bot, interaction, interaction.user.id, 0, false);
|
||||||
|
} else {
|
||||||
|
getEvents(bot, interaction, interaction.guildId, 0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reminderQueue
|
||||||
|
function turnPage(bot, interaction) {
|
||||||
|
const isplit = interaction.customId.split('|');
|
||||||
|
const isGuild = (isplit[1].split('-')[0] === 'true');
|
||||||
|
const id = isplit[1].split('-')[1];
|
||||||
|
const page = Number(isplit[2]);
|
||||||
|
getEvents(bot, interaction, id, page, isGuild, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: "reminders",
|
||||||
|
description: "Have Selmer Bot remind you - premium feature",
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
//Check if the user has premium
|
||||||
|
bot.mongoconnection.then(async (client) => {
|
||||||
|
const dbo = client.db('main').collection('authorized');
|
||||||
|
dbo.find({ discordID: message.author.id }).toArray((err, docs) => {
|
||||||
|
|
||||||
|
//Only available to Selmer Bot devs, testers and "authorized" users
|
||||||
|
if (docs[0] != undefined) {
|
||||||
|
//Execute the command
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
|
||||||
|
if (message.channel.type == 'DM') {
|
||||||
|
row.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId(`newEvent|User|${message.author.id}`)
|
||||||
|
.setLabel('New Personal Reminder')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('getEvents')
|
||||||
|
.setLabel('See Personal Reminders')
|
||||||
|
.setStyle('PRIMARY'),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
row.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId(`newEvent|User|${message.author.id}`)
|
||||||
|
.setLabel('New Personal Reminder')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('newEvent|Guild')
|
||||||
|
.setLabel('New Guild Reminder')
|
||||||
|
.setStyle('SUCCESS'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('getEvents')
|
||||||
|
.setLabel('See Guild Reminders')
|
||||||
|
.setStyle('PRIMARY'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.channel.send({ content: 'Please select an action\n_Notes: Adding offset to an event is only supported on the website and personal reminders can be viewed in DM\'s_', components: [row] });
|
||||||
|
} else {
|
||||||
|
message.reply("You have to be a premium subscriber to use this feature!\n_support coming soon_");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, modalHandle, turnPage
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
-----WEBHOOKS ARE MONITORED AND PROCESSED HERE-----
|
||||||
|
https://selmer-bot-listener.ion606.repl.co
|
||||||
|
--------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
|
const { MessageActionRow, MessageSelectMenu } = require('discord.js');
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
|
||||||
|
|
||||||
|
//Called from the dropdown menu
|
||||||
|
async function createSubscriptionManual(bot, interaction, id, priceID) {
|
||||||
|
const stripe = bot.stripe;
|
||||||
|
const mongouri = bot.mongouri;
|
||||||
|
|
||||||
|
//Error Checking (unlikely, but just in case)
|
||||||
|
if (!id) { console.log('....What? How?'); return interaction.editReply("Uh oh, something happened with the Stripe Discord ID check, please contact support!"); }
|
||||||
|
|
||||||
|
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
|
new Promise(async function(resolve, reject) {
|
||||||
|
bot.mongoconnection.then(async (client) => {
|
||||||
|
// if (err) { return console.log(err); }
|
||||||
|
|
||||||
|
const dbo = client.db('main').collection('authorized');
|
||||||
|
await dbo.findOne({'discordID': id}).then(async (doc) => {
|
||||||
|
var userID;
|
||||||
|
|
||||||
|
if (doc != undefined) {
|
||||||
|
// client.close();
|
||||||
|
|
||||||
|
reject(`An account with the tag <@${id}> already exists!`);
|
||||||
|
} else {
|
||||||
|
const stripeUser = await stripe.customers.create({
|
||||||
|
metadata: { 'discordID': id }
|
||||||
|
});
|
||||||
|
userID = stripeUser.id;
|
||||||
|
|
||||||
|
//Add to the database (I have to wait for the insertion)
|
||||||
|
await dbo.insertOne({stripeID: userID, discordID: id, paid: false, startDateUTC: null, tier: 0}).then(() => { /*client.close();*/ resolve(userID); });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}).then(async (userID) => {
|
||||||
|
|
||||||
|
//Deal with the session
|
||||||
|
const billingPortalSession = await stripe.billingPortal.sessions.create({
|
||||||
|
customer: userID,
|
||||||
|
return_url: "https://linktr.ee/selmerbot",
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const session = await stripe.checkout.sessions.create(
|
||||||
|
{
|
||||||
|
payment_method_types: ["card"],
|
||||||
|
line_items: [
|
||||||
|
{
|
||||||
|
price: priceID,
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
customer: userID,
|
||||||
|
mode: "subscription",
|
||||||
|
success_url: billingPortalSession.url,
|
||||||
|
cancel_url: "https://linktr.ee/selmerbot"
|
||||||
|
});
|
||||||
|
|
||||||
|
interaction.editReply(session.url);
|
||||||
|
}).catch((err) => {
|
||||||
|
if (String(typeof(err)) == 'string') {
|
||||||
|
interaction.editReply(err);
|
||||||
|
} else {
|
||||||
|
console.log(err);
|
||||||
|
interaction.editReply("A Stripe error occured! Please click the ✅ to report this ASAP!");
|
||||||
|
addComplaintButton(bot, interaction.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function changeSubscriptionManual(bot, message) {
|
||||||
|
const stripe = bot.stripe;
|
||||||
|
const mongouri = bot.mongouri;
|
||||||
|
const id = message.author.id;
|
||||||
|
|
||||||
|
//Just in case
|
||||||
|
if (!id) { return console.log('....What? How?'); }
|
||||||
|
|
||||||
|
// const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
|
new Promise(async function(resolve, reject) {
|
||||||
|
bot.mongoconnection.then(async (client) => {
|
||||||
|
// if (err) { return console.log(err); }
|
||||||
|
|
||||||
|
const dbo = client.db('main').collection('authorized');
|
||||||
|
await dbo.findOne({'discordID': id}).then(async (doc) => {
|
||||||
|
var userID;
|
||||||
|
|
||||||
|
if (doc != undefined) {
|
||||||
|
userID = doc.stripeID;
|
||||||
|
// client.close();
|
||||||
|
resolve(userID);
|
||||||
|
} else {
|
||||||
|
// client.close();
|
||||||
|
reject(`No user with the ID of <@${message.author.id}>`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}).then(async (userID) => {
|
||||||
|
await stripe.billingPortal.sessions.create({
|
||||||
|
customer: userID,
|
||||||
|
return_url: "https://linktr.ee/selmerbot",
|
||||||
|
}).then((session) => {
|
||||||
|
message.reply(session.url);
|
||||||
|
})
|
||||||
|
}).catch((err) => {
|
||||||
|
|
||||||
|
if (String(typeof(err)) == 'string') {
|
||||||
|
message.reply(err);
|
||||||
|
} else {
|
||||||
|
console.log(err);
|
||||||
|
message.reply("A Stripe error occured! Please click the ✅ to report this ASAP!");
|
||||||
|
addComplaintButton(bot, interaction.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createDropDown(bot, message) {
|
||||||
|
const stripe = bot.stripe;
|
||||||
|
|
||||||
|
const pl = [];
|
||||||
|
const vl = [];
|
||||||
|
stripe.products.list({
|
||||||
|
limit: 3,
|
||||||
|
}).then((prod) => {
|
||||||
|
prod.data.forEach((obj) => {
|
||||||
|
const pricePromise = stripe.prices.retrieve(obj.default_price);
|
||||||
|
var newObj = {label: obj.name, description: null, value: `${obj.default_price}`}
|
||||||
|
pl.push(pricePromise);
|
||||||
|
vl.push(newObj);
|
||||||
|
});
|
||||||
|
|
||||||
|
let n = Promise.all(pl);
|
||||||
|
let i = 0;
|
||||||
|
n.then((t) => {
|
||||||
|
t.forEach(data => {
|
||||||
|
let price = data.unit_amount/100;
|
||||||
|
vl[i].description = `The $${price} tier`;
|
||||||
|
i++;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageSelectMenu()
|
||||||
|
.setCustomId(`${message.author.id}|premium`)
|
||||||
|
.setPlaceholder('Nothing selected')
|
||||||
|
.addOptions(vl)
|
||||||
|
);
|
||||||
|
|
||||||
|
message.channel.send({ content: `Please choose a tier`, components: [row] });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleInp(bot, message) {
|
||||||
|
if (message.content == '!premium' || message.content == '!premium help') {
|
||||||
|
message.reply('Use _!premium buy_ to get premium or use _!premium manage_ to change or cancel your subscription\n\n_Disclaimer: Selmer Bot uses Stripe to manage payments. Read more at *https://stripe.com/ *_');
|
||||||
|
} else if (message.content == '!premium buy') {
|
||||||
|
createDropDown(bot, message);
|
||||||
|
} else if (message.content == '!premium manage') {
|
||||||
|
changeSubscriptionManual(bot, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'premium',
|
||||||
|
description: 'everything payment',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
message.reply("Please DM Selmer bot to use this command!");
|
||||||
|
}, handleInp, createSubscriptionManual
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
/* TODO
|
||||||
|
1) Save by streamer id, with the users to ping inside
|
||||||
|
2) Check the streamers every 5 min or so
|
||||||
|
*/
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
//Remember to strip all non-alpha chars from string (including ' )
|
||||||
|
|
||||||
|
wordlist = {
|
||||||
|
pay: ['pay me', 'give me money', 'send money', 'send me money', 'send cash', 'PayPal me', 'venmo me', 'cashapp me', 'cash app me'],
|
||||||
|
name: ['what is your name', 'whats your name', 'what are you called']
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function checkResponses(convoOG, answer) {
|
||||||
|
if (answer.indexOf("I'm sorry, I can't do that") == -1) { console.log('what?'); return 'none'}
|
||||||
|
// remove all uneccesary chars
|
||||||
|
convo = convoOG.replace(/\W/g, ' ').toLowerCase();
|
||||||
|
|
||||||
|
var b = 'none';
|
||||||
|
wordlist.name.forEach((w) => { if (convo.includes(w)) { b = 'name'; return }})
|
||||||
|
wordlist.pay.forEach((w) => { if (convo.includes(w)) { b = 'pay'; return }})
|
||||||
|
|
||||||
|
if (b === 'pay') {
|
||||||
|
//Exctract the number
|
||||||
|
// var amt = convoOG.match(/(\d+)/)[0];
|
||||||
|
// currency = convoOG[convoOG.indexOf(amt) - 1];
|
||||||
|
|
||||||
|
return ('Use _!premium_ to get Selmer Bot Premium now!');
|
||||||
|
} else if (b == 'name') {
|
||||||
|
return ('My name is Selmer Bot!');
|
||||||
|
} else { return null; }
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { checkResponses }
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
//TODO -- Maybe use https://console.cloud.google.com/apis/api/youtube.googleapis.com
|
||||||
+28
-3
@@ -1,5 +1,7 @@
|
|||||||
//THESE STRUCTURES SUPPORTS TWO PLAYERS ONLY!!!!
|
//THESE STRUCTURES SUPPORTS TWO PLAYERS ONLY!!!!
|
||||||
|
|
||||||
|
const { STATE } = require("./db/econ");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Determines who's turn it currently is
|
//Determines who's turn it currently is
|
||||||
@@ -38,10 +40,33 @@ function getTurn(client, bot, interaction) {
|
|||||||
function changeTurn(client, bot, interaction) {
|
function changeTurn(client, bot, interaction) {
|
||||||
const db = client.db('B|S' + bot.user.id);
|
const db = client.db('B|S' + bot.user.id);
|
||||||
const dbo = db.collection(interaction.member.guild.id);
|
const dbo = db.collection(interaction.member.guild.id);
|
||||||
|
|
||||||
dbo.find({turn: {$exists: true}}).toArray(function (err, docs) {
|
dbo.find({turn: {$exists: true}}).toArray(function (err, docs) {
|
||||||
let turn = docs[0].turn;
|
let turnnumer = docs[0].turn;
|
||||||
turn = Number(!turn);
|
turnnumer = Number(!turnnumer);
|
||||||
dbo.updateOne(docs[0], {$set: {turn: turn}});
|
|
||||||
|
//Check for prone, and change it if necessary
|
||||||
|
let turnInfo = getTurn(client, bot, interaction);
|
||||||
|
|
||||||
|
turnInfo.then(id = (turn => {
|
||||||
|
var id;
|
||||||
|
// console.log(turn); throw 1;
|
||||||
|
for (const [key, value] of Object.entries(turn[1])) {
|
||||||
|
if (key == turnnumer) { id = value; break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const other_dbo = client.db(interaction.member.guild.id).collection(id);
|
||||||
|
|
||||||
|
other_dbo.find({'state': {$exists: true}}).toArray((err, docs) => {
|
||||||
|
//If the person was prone, skip their turn
|
||||||
|
if (docs[0].state == STATE.PRONE) {
|
||||||
|
dbo.updateOne({'turn': {$exists: true}}, {$set: {state: STATE.FIGHTING}});
|
||||||
|
} else {
|
||||||
|
dbo.updateOne({'turn': {$exists: true}}, {$set: {turn: turnnumer}});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/**
|
||||||
|
* @param {JSON} inp
|
||||||
|
* @returns {Map<String, Map>}
|
||||||
|
*/
|
||||||
|
function jsonToMapRecursive(inp) {
|
||||||
|
if (typeof(inp) != 'object') {
|
||||||
|
return inp;
|
||||||
|
}
|
||||||
|
|
||||||
|
let m2 = new Map();
|
||||||
|
Object.entries(inp).forEach((key) => { m2.set(key[0], jsonToMapRecursive(inp[key[0]])); });
|
||||||
|
return m2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Map} inp
|
||||||
|
* @param {int} layer
|
||||||
|
* @returns The map in string format
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* {"key1": "val1", "key2": "key3": {"key4": "Val4"}} ==>>
|
||||||
|
* `
|
||||||
|
* |-- key1
|
||||||
|
* | |-- val1
|
||||||
|
* |
|
||||||
|
* |-- key2
|
||||||
|
* | |-- val3
|
||||||
|
* | | |-- key4
|
||||||
|
* | | | |--val4
|
||||||
|
* `
|
||||||
|
*/
|
||||||
|
function mapToTableRecursive(inp, layer = 1) {
|
||||||
|
var temp = '';
|
||||||
|
|
||||||
|
if (typeof(inp) != 'object') {
|
||||||
|
// return `?[${inp}]`;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.from(inp.keys()).forEach((key) => {
|
||||||
|
var keyTemp = ('| ').repeat(layer);
|
||||||
|
temp += `${keyTemp}- - ${key}\n`.replaceAll(' - -', '- -');
|
||||||
|
temp += mapToTable(inp.get(key), layer + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
temp += ('| ').repeat(layer - 1) + '\n';
|
||||||
|
|
||||||
|
if (layer == 1) {
|
||||||
|
var links = new Array();
|
||||||
|
|
||||||
|
//Post-processing
|
||||||
|
var l = temp.split('\n')
|
||||||
|
|
||||||
|
l = l.filter((entry, ind) => {
|
||||||
|
return entry.trim() == '|' || !((/[^A-Za-z0-9 ]+$/).test(entry.trim()) && (/[^A-Za-z0-9 ]+$/).test(l[ind + 1].trim()));
|
||||||
|
});
|
||||||
|
|
||||||
|
temp = l.join('\n')
|
||||||
|
|
||||||
|
//Get the links
|
||||||
|
Array.from(inp.keys()).forEach((key) => {
|
||||||
|
links.push(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
return [temp, links];
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { jsonToMapRecursive, mapToTableRecursive }
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<title>Selmer Bot Directory</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webBtn {
|
||||||
|
margin: 50px;
|
||||||
|
font-family:'Comic Sans MS';
|
||||||
|
font-size:20px;
|
||||||
|
line-height:20px;
|
||||||
|
color:#ffffff;
|
||||||
|
background-color:#4d4d4d;
|
||||||
|
padding:20px;
|
||||||
|
border-radius:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webBtn:hover {
|
||||||
|
color: #000000;
|
||||||
|
background-color: #9b9999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="row">
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<button onclick="window.open('https://www.selmerbot.com/', target='_blank')" class="webBtn">selmerbot.com</button>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.buymeacoffee.com/1.0.0/button.prod.min.js" data-name="bmc-button" data-slug="ion606" data-color="#FFDD00" data-emoji="" data-font="Cookie" data-text="Buy me a coffee" data-outline-color="#000000" data-font-color="#000000" data-coffee-color="#ffffff"></script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="text-align: center; position: absolute; bottom: 5px; color: white;">Copyright @ION606 2022</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,31 +1,55 @@
|
|||||||
|
//#region imports
|
||||||
const { Client, Intents, MessageActionRow, MessageButton, MessageSelectMenu } = require('discord.js');
|
const { Client, Intents, MessageActionRow, MessageButton, MessageSelectMenu } = require('discord.js');
|
||||||
const Discord = require('discord.js');
|
const Discord = require('discord.js');
|
||||||
const { MongoClient, ServerApiVersion } = require('mongodb');
|
const { MongoClient, ServerApiVersion } = require('mongodb');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
// const OpenAI = require('openai-api')
|
||||||
|
const { Configuration, OpenAIApi } = require("openai");
|
||||||
|
const Stripe = require('stripe');
|
||||||
|
|
||||||
const turnManager = require('./commands/turnManager.js');
|
const turnManager = require('./commands/turnManager.js');
|
||||||
const { welcome } = require('./commands/admin/welcome.js');
|
const { welcome } = require('./commands/admin/welcome.js');
|
||||||
|
const { handle_interaction } = require('./commands/interactionhandler.js');
|
||||||
|
const { handle_dm } = require('./commands/dm_handler');
|
||||||
|
const { devCheck } = require('./commands/dev only/devcheck.js');
|
||||||
|
const { moderation_handler } = require('./commands/admin/moderation.js');
|
||||||
const { exit } = require('process');
|
const { exit } = require('process');
|
||||||
|
//#endregion
|
||||||
|
|
||||||
const BASE_LVL_XP = 20;
|
const BASE_LVL_XP = 20;
|
||||||
|
|
||||||
|
|
||||||
//Token area
|
//#region Token area
|
||||||
|
|
||||||
//Adding integration for development mode
|
//Adding integration for development mode
|
||||||
let token;
|
let token;
|
||||||
let IDM = false;
|
let IDM = false;
|
||||||
let home_server;
|
let home_server;
|
||||||
|
let debug_channel;
|
||||||
|
|
||||||
|
let MLAIKEY;
|
||||||
|
let StripeAPIKey;
|
||||||
|
|
||||||
if (process.env.token != undefined) {
|
if (process.env.token != undefined) {
|
||||||
//Use "setx NAME VALUE" in the local powershell terminal to set
|
//Use "setx NAME VALUE" in the local powershell terminal to set
|
||||||
token = process.env.token;
|
token = process.env.token;
|
||||||
home_server = process.env.home_server;
|
home_server = process.env.home_server;
|
||||||
|
debug_channel = process.env.debug_channel;
|
||||||
|
MLAIKEY = process.env.MLAIKEY;
|
||||||
|
StripeAPIKey = process.env.StripeAPIKey;
|
||||||
} else {
|
} else {
|
||||||
token = require('./config.json').token;
|
token = require('./config.json').token;
|
||||||
home_server = require('./config.json').home_server;
|
home_server = require('./config.json').home_server;
|
||||||
|
debug_channel = require('./config.json').debug_channel;
|
||||||
|
|
||||||
|
MLAIKEY = require('./config.json').MLAIKEY;
|
||||||
|
StripeAPIKey = require('./config.json').StripeAPIKey;
|
||||||
|
|
||||||
|
// { token, home_server, debug_channel, MLAIKEY, StripeAPIKey } = require('./config.json'); // Doesn't work
|
||||||
IDM = true;
|
IDM = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const { token } = require('./config.json');
|
//#endregion
|
||||||
//Heroku part
|
|
||||||
// const { token } = process.env.token;
|
|
||||||
|
|
||||||
const bot = new Client({
|
const bot = new Client({
|
||||||
intents: [
|
intents: [
|
||||||
@@ -35,8 +59,12 @@ const bot = new Client({
|
|||||||
Intents.FLAGS.GUILD_VOICE_STATES,
|
Intents.FLAGS.GUILD_VOICE_STATES,
|
||||||
Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS,
|
Intents.FLAGS.GUILD_EMOJIS_AND_STICKERS,
|
||||||
Intents.FLAGS.GUILD_PRESENCES,
|
Intents.FLAGS.GUILD_PRESENCES,
|
||||||
Intents.FLAGS.GUILD_MEMBERS
|
Intents.FLAGS.GUILD_MEMBERS,
|
||||||
|
Intents.FLAGS.DIRECT_MESSAGES,
|
||||||
|
Intents.FLAGS.DIRECT_MESSAGE_REACTIONS,
|
||||||
|
Intents.FLAGS.DIRECT_MESSAGE_TYPING,
|
||||||
],
|
],
|
||||||
|
partials: [ 'CHANNEL' ]
|
||||||
});
|
});
|
||||||
|
|
||||||
const prefix = '!';
|
const prefix = '!';
|
||||||
@@ -44,75 +72,80 @@ bot.prefix = new String;
|
|||||||
bot.prefix = prefix;
|
bot.prefix = prefix;
|
||||||
bot.inDebugMode = IDM;
|
bot.inDebugMode = IDM;
|
||||||
bot.home_server = home_server;
|
bot.home_server = home_server;
|
||||||
|
bot.debug_channel = debug_channel;
|
||||||
|
bot.inviteLink = 'https://discord.com/oauth2/authorize?client_id=944046902415093760&scope=applications.commands+bot&permissions=549755289087';
|
||||||
|
|
||||||
|
const configuration = new Configuration({
|
||||||
|
apiKey: MLAIKEY,
|
||||||
|
});
|
||||||
|
bot.openai = new OpenAIApi(configuration);
|
||||||
|
bot.temptext = '';
|
||||||
|
bot.stripe = Stripe(StripeAPIKey);
|
||||||
|
|
||||||
|
//The first thing will be an audioPlayer(), the second a queue
|
||||||
|
bot.audioData = new Map();
|
||||||
|
|
||||||
|
|
||||||
//MongoDB integration
|
//#region MongoDB integration
|
||||||
//Development support
|
//Development support
|
||||||
let mongouritemp;
|
let mongouritemp;
|
||||||
if (process.env.MONGODB_URI) {
|
if (process.env.MONGODB_URI) {
|
||||||
mongouritemp = process.env.MONGODB_URI;
|
mongouritemp = process.env.MONGODB_URI;
|
||||||
} else {
|
} else {
|
||||||
mongouritemp = require('./config.json');
|
mongouritemp = require('./config.json').mongooseURI;
|
||||||
}
|
}
|
||||||
const mongouri = mongouritemp;
|
const mongouri = mongouritemp;
|
||||||
|
bot.mongouri = mongouri;
|
||||||
|
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
||||||
|
bot.mongoconnection = client.connect();
|
||||||
|
|
||||||
const { connect } = require('mongoose');
|
const { connect } = require('mongoose');
|
||||||
|
|
||||||
bot.on("guildCreate", guild => {
|
//#endregion MongoDB Integration end
|
||||||
guild.roles.create({ name: 'Selmer Bot Mod' });
|
|
||||||
|
|
||||||
//const role = guild.roles.cache.find((role) => role.name === 'Selmer Bot Mod'); // member.roles.cache.has('role-id-here');
|
|
||||||
const server = bot.guilds.cache.get(guild.id);
|
|
||||||
const owner = server.members.fetch(guild.ownerId).then(function(owner) {
|
|
||||||
owner.send('Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the "_Selmer Bot Mod_" role.');
|
|
||||||
owner.send('To help set up Selmer Bot to work better with your server, use _!setup help_ in a channel Selmer Bot is in!');
|
|
||||||
});
|
|
||||||
|
|
||||||
//Set up the server
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
|
||||||
client.connect(err => {
|
|
||||||
if (err) { return console.log(err); }
|
|
||||||
|
|
||||||
const dbo = client.db(guild.id).collection('SETUP');
|
|
||||||
dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomemessage': null, 'welcomebanner': null}]);
|
|
||||||
});
|
|
||||||
|
|
||||||
client.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//MongoDB Integration end
|
//#region set up bot commands
|
||||||
// let item = items.filter(function (item) { return item.name.toLowerCase() == 'grapes'; });
|
|
||||||
|
// const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js')); // Obsolete?
|
||||||
|
|
||||||
bot.commands = new Discord.Collection();
|
bot.commands = new Discord.Collection();
|
||||||
|
const forbiddenFolders = ['db', 'dev only']; //premium,
|
||||||
|
|
||||||
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
|
|
||||||
|
|
||||||
|
|
||||||
bot.commands = new Discord.Collection();
|
|
||||||
fs.readdirSync('./commands')
|
fs.readdirSync('./commands')
|
||||||
.forEach(dir => {
|
.forEach(dir => {
|
||||||
if (dir != 'db' && !dir.endsWith('.js')) {
|
if (!forbiddenFolders.includes(dir) && !dir.endsWith('.js')) {
|
||||||
fs.readdirSync(`./commands/${dir}`)
|
fs.readdirSync(`./commands/${dir}`)
|
||||||
.filter(file => file.endsWith('.js'))
|
.filter(file => file.endsWith('.js'))
|
||||||
.forEach(file => {
|
.forEach(file => {
|
||||||
const command = require(`./commands/${dir}/${file}`);
|
const command = require(`./commands/${dir}/${file}`);
|
||||||
bot.commands.set(command.name, command);
|
if (command.name && command.description) {
|
||||||
|
bot.commands.set(command.name.toLowerCase(), command);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//Set these two manually because all the seperate games can't be included in the command list (all managed by the 'game' file)
|
//Set these two manually because all the seperate games can't be included in the command list (all managed by the 'game' file)
|
||||||
let temp_command = require("./commands/db/econ.js");
|
let temp_command = require("./commands/db/econ.js");
|
||||||
const { STATE } = require('./commands/db/econ.js');
|
const { STATE } = require('./commands/db/econ.js');
|
||||||
bot.commands.set('econ', temp_command);
|
bot.commands.set('econ', temp_command);
|
||||||
temp_command = require('./commands/db/game.js');
|
temp_command = require('./commands/games/game.js');
|
||||||
bot.commands.set('game', temp_command);
|
bot.commands.set('game', temp_command);
|
||||||
|
|
||||||
// const econFiles = fs.readdirSync('./commands/inventory').filter(file => file.endsWith('.js'));;
|
//Everything in the API should be handled by specific handler functions
|
||||||
// const currency = new Discord.Collection();
|
// const chat = require('./commands/premium/chat.js');
|
||||||
// const { Users } = require('./commands/currency/dbObjects.js');
|
// bot.commands.set('chat', chat);
|
||||||
// i++;
|
// const stripeCommands = require('./commands/premium/stripe.js');
|
||||||
|
// bot.commands.set('premium', stripeCommands);
|
||||||
|
// const
|
||||||
|
// bot.commands.set('RSS', )
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#region bot.[anything] section
|
||||||
|
|
||||||
//XP Table section
|
//XP Table section
|
||||||
let xp_collection = new Map();
|
let xp_collection = new Map();
|
||||||
@@ -120,15 +153,12 @@ let items;
|
|||||||
|
|
||||||
bot.on('ready', async () => {
|
bot.on('ready', async () => {
|
||||||
//Make then copy the shop
|
//Make then copy the shop
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
bot.mongoconnection.then(client => {
|
||||||
client.connect(err => {
|
|
||||||
const shop = client.db("main").collection("shop");
|
const shop = client.db("main").collection("shop");
|
||||||
shop.find().toArray(function(err, itemstemp) {
|
shop.find().toArray(function(err, itemstemp) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
items = [...itemstemp];
|
items = [...itemstemp];
|
||||||
|
|
||||||
client.close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Srt status and Activity (idle and listening to !help)
|
//Srt status and Activity (idle and listening to !help)
|
||||||
@@ -151,122 +181,108 @@ bot.on('ready', async () => {
|
|||||||
} else {
|
} else {
|
||||||
console.log("Testing testing 1 2 5...");
|
console.log("Testing testing 1 2 5...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Add the money symbol
|
||||||
|
let srv = bot.guilds.cache.get(bot.home_server).emojis.cache;
|
||||||
|
emj = srv.find((g) => { return g.name == 'selmer_coin' });
|
||||||
|
bot.currencysymbolmmain = `${emj}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//Button Section
|
//Button Section
|
||||||
bot.on('interactionCreate', async interaction => {
|
bot.on('interactionCreate', async interaction => {
|
||||||
|
handle_interaction(interaction, mongouri, turnManager, bot, STATE, items, xp_collection);
|
||||||
if (interaction.isButton()) {
|
|
||||||
const battlecommandlist = ['ATTACK', 'HEAL', 'DEFEND', 'ITEMS'];
|
|
||||||
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
|
||||||
client.connect(err => {
|
|
||||||
|
|
||||||
if (battlecommandlist.indexOf(interaction.customId) != -1) {
|
|
||||||
let current_user = turnManager.getTurn(client, bot, interaction);
|
|
||||||
|
|
||||||
current_user.then(function (result) {
|
|
||||||
const id = result[0];
|
|
||||||
const doc = result[1];
|
|
||||||
const threadname = doc.thread;
|
|
||||||
const dbo = client.db(interaction.guildId + '[ECON]').collection(id);
|
|
||||||
|
|
||||||
dbo.find({ 'state': {$exists: true} }).toArray(async function (err, docs) {
|
|
||||||
if (interaction.user.id == id) {
|
|
||||||
await interaction.deferReply();
|
|
||||||
|
|
||||||
//Check State
|
|
||||||
if (docs[0].state == STATE.FIGHTING) {
|
|
||||||
//Do turn stuff
|
|
||||||
bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection);
|
|
||||||
}
|
|
||||||
|
|
||||||
//remove the old interation message
|
|
||||||
await interaction.message.delete();
|
|
||||||
|
|
||||||
if (interaction.customId.toLowerCase() != 'heal') {
|
|
||||||
interaction.editReply(`<@${interaction.user.id}> used _${interaction.customId.toLowerCase()}_!`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("It's not your turn!");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}//else ifs here
|
|
||||||
});
|
|
||||||
|
|
||||||
client.close();
|
|
||||||
}
|
|
||||||
else if (interaction.isSelectMenu()) {
|
|
||||||
if (interaction.customId.toLowerCase().indexOf('|heal') != -1) {
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
|
||||||
client.connect(err => {
|
|
||||||
const id = interaction.customId.substring(0, interaction.customId.indexOf('|'))
|
|
||||||
|
|
||||||
if (id != interaction.user.id) { return; }
|
|
||||||
|
|
||||||
let current_user = turnManager.getTurn(client, bot, interaction);
|
|
||||||
current_user.then(function(result) {
|
|
||||||
const doc = result[1];
|
|
||||||
const threadname = doc.thread;
|
|
||||||
const dbo = client.db(interaction.guildId + '[ECON]').collection(id);
|
|
||||||
|
|
||||||
dbo.find({ 'state': {$exists: true} }).toArray(async function (err, docs) {
|
|
||||||
if (interaction.user.id == id) {
|
|
||||||
await interaction.deferReply();
|
|
||||||
|
|
||||||
//Check State
|
|
||||||
if (docs[0].state == STATE.FIGHTING) {
|
|
||||||
interaction.customId = 'usepotion';
|
|
||||||
//Do turn stuff
|
|
||||||
bot.commands.get('game').in_game_redirector(bot, interaction, threadname, doc, client, mongouri, items, xp_collection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
let srv = bot.guilds.cache.get(bot.home_server).emojis.cache;
|
|
||||||
let sname;
|
|
||||||
|
|
||||||
if (interaction.customId.toLowerCase() == 'heal' || interaction.customId.toLowerCase() == 'mp') {
|
|
||||||
if (interaction.values[0] == 'HP Potion') { sname = 'healing_potion' }
|
|
||||||
else if (interaction.values[0] == 'MP Potion') { sname = 'mana_potion' }
|
|
||||||
else if (interaction.values[0] == 'Super HP Potion') { sname = 'superior_healing_potion' }
|
|
||||||
else if (interaction.values[0] == 'Super MP Potion') { sname = 'superior_mana_potion' }
|
|
||||||
}
|
|
||||||
|
|
||||||
// emj = srv.find((g) => { return g.name == sname });
|
|
||||||
// console.log(sname, srv);*/
|
|
||||||
|
|
||||||
interaction.editReply(`<@${interaction.user.id}> used a _${interaction.values[0]}_!`);
|
|
||||||
|
|
||||||
|
|
||||||
//remove the old interation message
|
|
||||||
await interaction.message.delete();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
console.log("It's not your turn!");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//Get all chars from after "CUSTOM|" to the end of the str
|
|
||||||
// let name = item.icon.substr(7, item.icon.length - 6);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Add the bot to a server setup
|
||||||
|
bot.on("guildCreate", guild => {
|
||||||
|
if (guild.roles.cache.find((role) => { return (role.name == 'Selmer Bot Commands'); }) == undefined) {
|
||||||
|
guild.roles.create({ name: 'Selmer Bot Commands' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guild.roles.cache.find((role) => { return (role.name == 'Selmer Bot Calendar'); }) == undefined) {
|
||||||
|
guild.roles.create({ name: 'Selmer Bot Calendar' });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//const role = guild.roles.cache.find((role) => role.name === 'Selmer Bot Mod'); // member.roles.cache.has('role-id-here');
|
||||||
|
const server = bot.guilds.cache.get(guild.id);
|
||||||
|
const owner = server.members.fetch(guild.ownerId).then(function(owner) {
|
||||||
|
owner.send('Thank you for adding Selmer Bot to your server!\nPlease give people you want to have access to Selmer Bot\'s restricted commands the "_Selmer Bot Commands_" role and people you want to access set the calendar the "Selmer Bot Calendar" role');
|
||||||
|
owner.send('To help set up Selmer Bot to work better with your server, use _!setup help_ in a channel Selmer Bot is in!');
|
||||||
|
});
|
||||||
|
|
||||||
|
//Set up the server
|
||||||
|
bot.mongoconnection.then(client => {
|
||||||
|
|
||||||
|
const dbo = client.db(guild.id).collection('SETUP');
|
||||||
|
dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomemessage': null, 'welcomebanner': null}, {_id: 'LOG', 'keepLogs': false, 'logchannel': null, 'severity': 0}, {_id: 'announcement', channel: null, role: null}]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
bot.on("guildDelete", guild => {
|
||||||
|
bot.mongoconnection.then((client) => {
|
||||||
|
//Insufficient Permission????
|
||||||
|
// db.dropDatabase();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const db = client.db(guild.id);
|
||||||
|
db.listCollections().forEach(function(x) { db.collection(x.name).drop(); });
|
||||||
|
|
||||||
|
var times;
|
||||||
|
const dbo = client.db('main').collection('reminderKeys');
|
||||||
|
|
||||||
|
//ReminderKeys are all stored as userId, the reminders themselves are not
|
||||||
|
dbo.findOne({userId: guild.id}).then((doc) => {
|
||||||
|
if (!doc || !doc.times) { return; }
|
||||||
|
|
||||||
|
times = doc.times;
|
||||||
|
const tbo = client.db('main').collection('reminders');
|
||||||
|
|
||||||
|
tbo.find({time: {$in: times}}).toArray((err, docs) => {
|
||||||
|
try {
|
||||||
|
for (let i = 0; i < docs.length; i ++) {
|
||||||
|
for (let j in docs[i]) {
|
||||||
|
if (!isNaN(j) && (docs[i][j].guildId == guild.id)) {
|
||||||
|
delete docs[i][j];
|
||||||
|
docs[i].amt --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (docs.amt > 0) {
|
||||||
|
tbo.replaceOne({ time: docs[i].time }, docs[i]);
|
||||||
|
} else {
|
||||||
|
tbo.deleteOne({ time: docs[i].time });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
dbo.deleteOne({ userId: guild.id });
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Welcome new members
|
//Welcome new members
|
||||||
bot.on('guildMemberAdd', async (member) => {
|
bot.on('guildMemberAdd', async (member) => {
|
||||||
|
|
||||||
//Check for impartial data
|
//Check for impartial data
|
||||||
if(member.partial) await member.fetch();
|
if(member.partial) await member.fetch();
|
||||||
|
|
||||||
const client = new MongoClient(mongouri, { useNewUrlParser: true, useUnifiedTopology: true, serverApi: ServerApiVersion.v1 });
|
|
||||||
|
|
||||||
const guild = bot.guilds.cache.get(member.guild.id);
|
const guild = bot.guilds.cache.get(member.guild.id);
|
||||||
|
|
||||||
client.connect(err => {
|
bot.mongoconnection.then(client => {
|
||||||
const dbo = client.db(member.guild.id).collection('SETUP');
|
const dbo = client.db(member.guild.id).collection('SETUP');
|
||||||
|
|
||||||
dbo.find({_id: 'WELCOME'}).toArray(async (err, docs) => {
|
dbo.find({_id: 'WELCOME'}).toArray(async (err, docs) => {
|
||||||
@@ -283,13 +299,25 @@ bot.on('guildMemberAdd', async (member) => {
|
|||||||
|
|
||||||
await welcome(member, welcomechannel, docs[0].welcomemessage);
|
await welcome(member, welcomechannel, docs[0].welcomemessage);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
bot.on('messageCreate', (message) => {
|
bot.on('messageCreate', (message) => {
|
||||||
|
//DM SECTION
|
||||||
|
if (message.channel.type === "DM") {
|
||||||
|
return handle_dm(message, bot);
|
||||||
|
} else if (message.content.indexOf('!spam_collection') != -1) {
|
||||||
|
//Handle spam collection/Dev commands
|
||||||
|
return devCheck(message, bot);
|
||||||
|
} else if (message.type === "CHANNEL_PINNED_MESSAGE") {
|
||||||
|
//Debug log stuff
|
||||||
|
if (message.guild.id == bot.home_server && message.channel.id == bot.debug_channel) {
|
||||||
|
message.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Special case, testing server (still need the emojis)
|
//Special case, testing server (still need the emojis and error logging)
|
||||||
if (!bot.inDebugMode && message.guild.id == bot.home_server) { return; }
|
if (!bot.inDebugMode && message.guild.id == bot.home_server) { return; }
|
||||||
|
|
||||||
//COMMAND AREA
|
//COMMAND AREA
|
||||||
@@ -299,32 +327,15 @@ bot.on('messageCreate', (message) => {
|
|||||||
const args = message.content.slice(prefix.length).split(' ');
|
const args = message.content.slice(prefix.length).split(' ');
|
||||||
const command = args.shift().toLowerCase();
|
const command = args.shift().toLowerCase();
|
||||||
|
|
||||||
|
//Log logable commands then execute them
|
||||||
if (command == 'welcome') {
|
const logable = ['kick', 'ban', 'unban', 'mute', 'unmute', 'timeout'];
|
||||||
const row = new MessageActionRow()
|
if (logable.includes(command)) {
|
||||||
.addComponents(
|
moderation_handler(bot, message, args, command);
|
||||||
new MessageButton()
|
|
||||||
.setCustomId('WELCOME')
|
|
||||||
.setLabel('WELCOME')
|
|
||||||
.setStyle('PRIMARY')
|
|
||||||
);
|
|
||||||
|
|
||||||
message.channel.send({ components: [row] });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TEMP
|
|
||||||
if (command == 'emj') {
|
|
||||||
let srv = bot.guilds.cache.get(bot.home_server).emojis.cache;
|
|
||||||
// console.log(srv);
|
|
||||||
emj = srv.find((g) => { return g.name == 'healing_potion' });
|
|
||||||
// console.log(emj); exit();
|
|
||||||
message.channel.send(`${emj}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check if the user has sufficient permission
|
|
||||||
//Performes the command
|
//Performes the command
|
||||||
//Admin section
|
//Admin section
|
||||||
if (command == 'reactionrole') { bot.commands.get(command).execute(message, args, Discord, bot); }
|
else if (command == 'reactionrole') { bot.commands.get(command).execute(message, args, Discord, bot); }
|
||||||
|
|
||||||
else if(bot.commands.has(command) && command != 'ECON') {
|
else if(bot.commands.has(command) && command != 'ECON') {
|
||||||
//Database access is required, change the inputs
|
//Database access is required, change the inputs
|
||||||
@@ -339,9 +350,7 @@ bot.on('messageCreate', (message) => {
|
|||||||
else { bot.commands.get('econ').execute(bot, message, args, command, Discord, mongouri, items, xp_collection); }
|
else { bot.commands.get('econ').execute(bot, message, args, command, Discord, mongouri, items, xp_collection); }
|
||||||
})
|
})
|
||||||
|
|
||||||
//Look into integrating MySQL into SelmerBot instead of SQLite
|
//#endregion
|
||||||
|
|
||||||
//Last Line(s)
|
//Last Line(s)
|
||||||
// bot.login(token);
|
|
||||||
|
|
||||||
bot.login(token);
|
bot.login(token);
|
||||||
@@ -1 +1,3 @@
|
|||||||
VS stuff: https://dbotmaker.io/forums/threads/make-bot-join-vc.95/
|
VS stuff: https://dbotmaker.io/forums/threads/make-bot-join-vc.95/
|
||||||
|
|
||||||
|
selmer-bot-listener watcher https://uptimerobot.com/dashboard
|
||||||
|
|||||||
Generated
+7062
-953
File diff suppressed because it is too large
Load Diff
+19
-1
@@ -1,27 +1,45 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@alpacahq/alpaca-trade-api": "^2.16.1",
|
||||||
"@discordjs/opus": "github:discordjs/opus",
|
"@discordjs/opus": "github:discordjs/opus",
|
||||||
|
"@discordjs/rest": "^1.0.1",
|
||||||
"@discordjs/voice": "^0.8.0",
|
"@discordjs/voice": "^0.8.0",
|
||||||
"@napi-rs/canvas": "^0.1.22",
|
"@napi-rs/canvas": "^0.1.22",
|
||||||
"apt": "^0.0.2",
|
"apt": "^0.0.2",
|
||||||
"arraybuffer-to-buffer": "^0.0.7",
|
"arraybuffer-to-buffer": "^0.0.7",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"canvas": "^2.9.1",
|
"body-parser": "^1.20.0",
|
||||||
|
"canvas": "^2.9.3",
|
||||||
"cheerio": "^1.0.0-rc.10",
|
"cheerio": "^1.0.0-rc.10",
|
||||||
|
"coingecko-api": "^1.0.10",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"date-fns": "^2.29.2",
|
||||||
|
"date-fns-timezone": "^0.1.4",
|
||||||
"discord-reply": "^0.1.2",
|
"discord-reply": "^0.1.2",
|
||||||
"discord.js": "^13.6.0",
|
"discord.js": "^13.6.0",
|
||||||
|
"dotenv": "^16.0.1",
|
||||||
|
"express": "^4.18.1",
|
||||||
|
"feedparser": "^2.2.10",
|
||||||
"ffmpeg": "^0.0.4",
|
"ffmpeg": "^0.0.4",
|
||||||
"ffmpeg-static": "^5.0.0",
|
"ffmpeg-static": "^5.0.0",
|
||||||
"hastebin-gen": "^2.0.5",
|
"hastebin-gen": "^2.0.5",
|
||||||
|
"html-entities": "^2.3.3",
|
||||||
"libsodium-wrappers": "^0.7.10",
|
"libsodium-wrappers": "^0.7.10",
|
||||||
"mal-scraper": "^2.11.4",
|
"mal-scraper": "^2.11.4",
|
||||||
"mongoose": "^6.3.2",
|
"mongoose": "^6.3.2",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"node.js": "^0.0.1-security",
|
"node.js": "^0.0.1-security",
|
||||||
|
"npm": "^8.13.2",
|
||||||
|
"openai": "^3.0.0",
|
||||||
"play-dl": "^1.9.4",
|
"play-dl": "^1.9.4",
|
||||||
|
"pusher": "^5.1.1-beta",
|
||||||
"random-memes": "^3.1.0",
|
"random-memes": "^3.1.0",
|
||||||
|
"request": "^2.88.2",
|
||||||
|
"robinhood": "^1.8.0",
|
||||||
|
"rss-parser": "^3.12.0",
|
||||||
"sequelize": "^6.19.0",
|
"sequelize": "^6.19.0",
|
||||||
"sqlite3": "^5.0.3",
|
"sqlite3": "^5.0.3",
|
||||||
|
"stripe": "^9.11.0",
|
||||||
"sudo": "^1.0.3",
|
"sudo": "^1.0.3",
|
||||||
"undici": "^5.4.0",
|
"undici": "^5.4.0",
|
||||||
"youtube-mp3-downloader": "^0.7.10",
|
"youtube-mp3-downloader": "^0.7.10",
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"News": {
|
||||||
|
"NYTimes": {
|
||||||
|
"world": "https://rss.nytimes.com/services/xml/rss/nyt/World.xml",
|
||||||
|
"US": "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml",
|
||||||
|
"econ": "https://rss.nytimes.com/services/xml/rss/nyt/Economy.xml",
|
||||||
|
"business": "https://rss.nytimes.com/services/xml/rss/nyt/Business.xml",
|
||||||
|
"tech": "https://rss.nytimes.com/services/xml/rss/nyt/Technology.xml",
|
||||||
|
"obituaries": "https://rss.nytimes.com/services/xml/rss/nyt/Obituaries.xml"
|
||||||
|
},
|
||||||
|
"Fox": {
|
||||||
|
"LatestHeadlines": "https://moxie.foxnews.com/feedburner/latest.xml",
|
||||||
|
"World": "https://moxie.foxnews.com/feedburner/world.xml",
|
||||||
|
"US": "https://moxie.foxnews.com/feedburner/national.xml",
|
||||||
|
"Tech": "https://moxie.foxnews.com/feedburner/scitech.xml",
|
||||||
|
"Politics": "https://moxie.foxnews.com/feedburner/politics.xml"
|
||||||
|
},
|
||||||
|
"NPR": "https://feeds.npr.org/1001/rss.xml"
|
||||||
|
},
|
||||||
|
"Crime": {
|
||||||
|
"DateLine_NBC": "https://podcastfeeds.nbcnews.com/HL4TzgYC",
|
||||||
|
"CrimeJunkie": "https://feeds.simplecast.com/qm_9xx0g"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,322 @@
|
|||||||
|
const { MessageActionRow, MessageButton, MessageEmbed, MessageSelectMenu, CommandInteractionOptionResolver } = require('discord.js');
|
||||||
|
const axios = require('axios');
|
||||||
|
const cheerio = require('cheerio');
|
||||||
|
var FeedParser = require('feedparser');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const { VoiceConnectionStatus, AudioPlayerStatus, createAudioPlayer, StreamType, joinVoiceChannel, createAudioResource, getVoiceConnection } = require('@discordjs/voice');
|
||||||
|
const play = require('play-dl');
|
||||||
|
const { addComplaintButton } = require('../dev only/submitcomplaint');
|
||||||
|
|
||||||
|
const hastebin = require("hastebin-gen");
|
||||||
|
const { simpleCast } = require('./simplecast.js')
|
||||||
|
|
||||||
|
let Parser = require('rss-parser');
|
||||||
|
let parser = new Parser();
|
||||||
|
const allFeedsJSON = require('./feeds.json');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {JSON} inp
|
||||||
|
* @returns {Map<String, Map>}
|
||||||
|
*/
|
||||||
|
function jsonToMapRecursive(inp) {
|
||||||
|
if (typeof(inp) != 'object') {
|
||||||
|
return inp;
|
||||||
|
}
|
||||||
|
|
||||||
|
let m2 = new Map();
|
||||||
|
Object.entries(inp).forEach((key) => { m2.set(key[0], jsonToMapRecursive(inp[key[0]])); });
|
||||||
|
return m2;
|
||||||
|
}
|
||||||
|
|
||||||
|
const allFeeds = jsonToMapRecursive(allFeedsJSON);
|
||||||
|
|
||||||
|
|
||||||
|
function mapToTable(inp, layer) {
|
||||||
|
var temp = '';
|
||||||
|
|
||||||
|
if (typeof(inp) != 'object') {
|
||||||
|
// return `?[${inp}]`;
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.from(inp.keys()).forEach((key) => {
|
||||||
|
var keyTemp = ('| ').repeat(layer);
|
||||||
|
temp += `${keyTemp}- - ${key}\n`.replaceAll(' - -', '- -');
|
||||||
|
temp += mapToTable(inp.get(key), layer + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
temp += ('| ').repeat(layer - 1) + '\n';
|
||||||
|
|
||||||
|
if (layer == 1) {
|
||||||
|
var links = new Array();
|
||||||
|
|
||||||
|
//Post-processing
|
||||||
|
var l = temp.split('\n')
|
||||||
|
|
||||||
|
l = l.filter((entry, ind) => {
|
||||||
|
return entry.trim() == '|' || !((/[^A-Za-z0-9 ]+$/).test(entry.trim()) && (/[^A-Za-z0-9 ]+$/).test(l[ind + 1].trim()));
|
||||||
|
});
|
||||||
|
|
||||||
|
temp = l.join('\n')
|
||||||
|
|
||||||
|
//Get the links
|
||||||
|
Array.from(inp.keys()).forEach((key) => {
|
||||||
|
links.push(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
return [temp, links];
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {simpleCast} obj
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function playAudio(bot, message, user, obj) {
|
||||||
|
const member = message.guild.members.cache.get(user.id);
|
||||||
|
if (!member.voice.channel) {
|
||||||
|
message.reply("Please join a voice channel before you try this!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const channel = bot.channels.cache.get(member.voice.channel.id);
|
||||||
|
|
||||||
|
const connection = joinVoiceChannel({
|
||||||
|
channelId: channel.id,
|
||||||
|
guildId: channel.guild.id,
|
||||||
|
adapterCreator: channel.guild.voiceAdapterCreator,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const resource = createAudioResource(obj.audioLink /*, { inlineVolume: true }*/ );
|
||||||
|
|
||||||
|
const data = bot.audioData.get(message.channel.guild.id);
|
||||||
|
if (data && data[1]) {
|
||||||
|
return message.reply("No podcast queue support yet!");
|
||||||
|
}
|
||||||
|
const player = createAudioPlayer();
|
||||||
|
connection.subscribe(player);
|
||||||
|
bot.audioData.set(message.guild.id, [player, new Array(), null]);
|
||||||
|
player.play(resource);
|
||||||
|
|
||||||
|
//Create the embed
|
||||||
|
const newEmbed = new MessageEmbed()
|
||||||
|
.setColor('#0F00F0')
|
||||||
|
.setTitle(`${obj.title}`)
|
||||||
|
.setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||||
|
.setDescription('IS NOW PLAYING')
|
||||||
|
.setURL(obj.url)
|
||||||
|
.setThumbnail(obj.thumbnal);
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.addComponents(
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('PAUSE')
|
||||||
|
.setLabel('⏸️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
new MessageButton()
|
||||||
|
.setCustomId('STOP')
|
||||||
|
.setLabel('⏹️')
|
||||||
|
.setStyle('SECONDARY'),
|
||||||
|
// new MessageButton()
|
||||||
|
// .setCustomId('SKIP')
|
||||||
|
// .setLabel('⏭️')
|
||||||
|
// .setStyle('SECONDARY')
|
||||||
|
);
|
||||||
|
console.log(obj.audioLink);
|
||||||
|
const m = message.reply({ embeds: [newEmbed], components: [row] });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function getAndFormatRSS(bot, message, user, inp) {
|
||||||
|
|
||||||
|
var req = fetch(inp)
|
||||||
|
const feedparser = new FeedParser();
|
||||||
|
|
||||||
|
req.then(function (res) {
|
||||||
|
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw new Error('Bad status code');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The response `body` -- res.body -- is a stream
|
||||||
|
res.body.pipe(feedparser);
|
||||||
|
}
|
||||||
|
}, function (err) {
|
||||||
|
// handle any request errors
|
||||||
|
});
|
||||||
|
|
||||||
|
feedparser.on('error', function (error) {
|
||||||
|
// always handle errors
|
||||||
|
addComplaintButton(bot, message);
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
const items = new Array();
|
||||||
|
feedparser.on('readable', async function () {
|
||||||
|
// This is where the action is!
|
||||||
|
var stream = this; // `this` is `feedparser`, which is a stream
|
||||||
|
var meta = this.meta; // **NOTE** the "meta" is always available in the context of the feedparser instance
|
||||||
|
var item;
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
while (item = stream.read()) {
|
||||||
|
items.push(item);
|
||||||
|
i ++;
|
||||||
|
if (i >= 100) { break; }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
feedparser.addListener('end', () => {
|
||||||
|
const item = items[Math.round(Math.random() * items.length)];
|
||||||
|
|
||||||
|
if (inp.indexOf('simplecast') != -1) {
|
||||||
|
var s = new simpleCast(item, inp);
|
||||||
|
s.audioLink = 'https://download.samplelib.com/mp3/sample-15s.mp3';
|
||||||
|
playAudio(bot, message, user, s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
//Get the feed
|
||||||
|
const feed = await parser.parseURL(inp);
|
||||||
|
// const items = feed.items;
|
||||||
|
const item = items[Math.round(Math.random() * items.length)];
|
||||||
|
|
||||||
|
var url;
|
||||||
|
try {
|
||||||
|
url = item.link || item.guid;
|
||||||
|
axios(url).then(async response => {
|
||||||
|
const html = response.data;
|
||||||
|
const $ = cheerio.load(html);
|
||||||
|
// console.log(html);
|
||||||
|
const haste = await hastebin(html, { extension: "txt" });
|
||||||
|
console.log(url, '\n', haste);
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return console.log(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const newEmbed = new MessageEmbed()
|
||||||
|
// .setTitle(feed.title)
|
||||||
|
// .setAuthor({ name: "Selmer Bot", url: "", iconURL: bot.user.displayAvatarURL() })
|
||||||
|
// .setTimestamp()
|
||||||
|
|
||||||
|
// console.log(feed.items);
|
||||||
|
|
||||||
|
/*
|
||||||
|
creator?: 'Ben Casselman and Jeanna Smialek',
|
||||||
|
title: 'Income and Spending Rose Less Than Prices in May',
|
||||||
|
link: 'https://www.nytimes.com/2022/06/30/business/economy/income-spending-may.html',
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function presentFeeds(bot, message, commands, interaction) {
|
||||||
|
|
||||||
|
var r;
|
||||||
|
var url;
|
||||||
|
if (commands[0] == 'all') {
|
||||||
|
r = mapToTable(allFeeds, 1);
|
||||||
|
} else {
|
||||||
|
var r2 = allFeeds.get(commands[0]);
|
||||||
|
// commands = commands.slice(1);
|
||||||
|
commands.slice(1).forEach((key) => {
|
||||||
|
r2 = r2.get(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
r = mapToTable(r2, 1);
|
||||||
|
|
||||||
|
if(!r[1]) { url = r2; }
|
||||||
|
|
||||||
|
//Array.from(r2.keys())
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if we have a feed (no more paths)
|
||||||
|
if (!r[1]) {
|
||||||
|
// console.log("Commands:", commands, "\nR: ", r); throw 1;
|
||||||
|
let path = ''
|
||||||
|
commands.forEach((com) => { path += `${com} --> `});
|
||||||
|
path = path.slice(0, path.length - 5);
|
||||||
|
|
||||||
|
interaction.update({ content: `You have chosen ${path}!`, components: []});
|
||||||
|
|
||||||
|
return getAndFormatRSS(bot, interaction.message, interaction.user, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
var keyList = new Array();
|
||||||
|
r[1].forEach((key) => {
|
||||||
|
const listEntry = {
|
||||||
|
label: `${key}`,
|
||||||
|
description: `Choose a feed from this category!`,
|
||||||
|
value: `${key}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
keyList.push(listEntry);
|
||||||
|
});
|
||||||
|
|
||||||
|
const row = new MessageActionRow()
|
||||||
|
.setComponents(
|
||||||
|
new MessageSelectMenu()
|
||||||
|
.setCustomId(`RSS|${commands.join('|')}`)
|
||||||
|
.setPlaceholder('Nothing selected')
|
||||||
|
.addOptions(keyList)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (interaction) { return interaction.update({content: r[0], components: [ row ]}); }
|
||||||
|
message.reply({ content: r[0], components: [ row ] });
|
||||||
|
|
||||||
|
/*else if (commands[0].length = 1) {
|
||||||
|
const data = allFeeds.get(commands[0]).get(commands[1]).get(commands[2]);
|
||||||
|
interaction.update({ content: `You have chosen ${commands[1]} from the ${commands[0]} section!`, components: []});
|
||||||
|
return getAndFormatRSS(bot, interaction.message, data);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function RSSInteractionHandler(bot, interaction) {
|
||||||
|
let commands = interaction.values[0].split('|');
|
||||||
|
let temp = interaction.customId.split('|').slice(1);
|
||||||
|
if (temp[0] != 'all') { commands = temp.concat(commands); }
|
||||||
|
// console.log(interaction.customId, interaction.values);
|
||||||
|
|
||||||
|
presentFeeds(bot, null, commands, interaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// getAndFormatRSS(null, null, imp[0]);
|
||||||
|
|
||||||
|
// presentFeeds(null, ['all']);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'RSS',
|
||||||
|
description: 'Selmer Bot will present a list of RSS feeds to read from *EXPERAMENTAL*',
|
||||||
|
execute(message, args, Discord, Client, bot) {
|
||||||
|
if (!bot.inDebugMode) { return message.reply('Command under development!'); }
|
||||||
|
if (!args[0]) {
|
||||||
|
presentFeeds(bot, message, [ 'all' ], null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RSSInteractionHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
REMOVED
|
||||||
|
"ABC": "https://abcnews.go.com/abcnews/topstories"
|
||||||
|
"FBI": "https://www.fbi.gov/feeds/national-press-releases/rss.xml" (Uhhhh......maybe I should't use this one.....)
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
class simpleCast {
|
||||||
|
constructor(data, url) {
|
||||||
|
this.title = data.title;
|
||||||
|
|
||||||
|
if (data['itunes:summary']) {
|
||||||
|
this.description = data['itunes:summary']['#'];
|
||||||
|
} else {
|
||||||
|
//<p>......<p>
|
||||||
|
this.description = data.description.substring(3, s.indexOf('<p>', 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
var audio = data.enclosures.filter((entry) => { return (entry.type.indexOf('audio') != -1) });
|
||||||
|
if (audio.length > 0) {
|
||||||
|
this.audioLink = audio[0].url;
|
||||||
|
} else { console.log("What?"); }
|
||||||
|
this.url = url;
|
||||||
|
|
||||||
|
this.thumbnal = data.meta.image.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = { simpleCast }
|
||||||
Reference in New Issue
Block a user