Skip to content

Commit 9358996

Browse files
committed
Push from Red's repository with bot token taken out
0 parents  commit 9358996

39 files changed

+2937
-0
lines changed

.eslintrc.yml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
parserOptions:
2+
ecmaVersion: 9
3+
4+
env:
5+
node: true
6+
es6: true
7+
8+
extends:
9+
- 'eslint:recommended'
10+
11+
rules:
12+
# Disable some rules from eslint:recommended.
13+
no-console: 'off'
14+
no-empty: ['error', { 'allowEmptyCatch': true }]
15+
16+
# Allow unused parameters. In callbacks, removing them seems to obscure what the functions are doing.
17+
no-unused-vars: ['error', {'args': 'none'}]
18+
19+
# Use semicolons. (may change later)
20+
semi: ['error', 'always']
21+
22+
# Preferences
23+
arrow-body-style: ['error', 'as-needed']
24+
func-style: ['error', 'declaration', { 'allowArrowFunctions': true }]
25+
no-var: 'error'
26+
quotes: ['error', 'single', { 'avoidEscape': true }]
27+
no-useless-concat: 'error'
28+
prefer-const: ['error', {'destructuring': 'all'}]
29+
prefer-template: 'error'
30+
template-curly-spacing: ['error', 'never']
31+
brace-style: 'error'
32+
comma-dangle: ['error', { 'arrays': 'always-multiline', 'objects': 'always-multiline', 'imports': 'always-multiline', 'exports': 'always-multiline' }]
33+
34+
# Keep whitespace cleaned up.
35+
no-trailing-spaces: ['error', { 'skipBlankLines': true }]
36+
eol-last: 'error'
37+
indent: ['error', 2, { 'SwitchCase': 1 }]
38+
no-tabs: 'error'
39+
array-bracket-newline: ['error', { 'multiline': true }]

.gitignore

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (https://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
node_modules/*
38+
jspm_packages/
39+
40+
# TypeScript v1 declaration files
41+
typings/
42+
43+
# Optional npm cache directory
44+
.npm
45+
46+
# Optional eslint cache
47+
.eslintcache
48+
49+
# Optional REPL history
50+
.node_repl_history
51+
52+
# Output of 'npm pack'
53+
*.tgz
54+
55+
# Yarn Integrity file
56+
.yarn-integrity
57+
58+
# dotenv environment variables file
59+
.env
60+
61+
# next.js build output
62+
.next
63+
db/*.sqlite

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#2009scape Discord bot
2+
3+
Installation & Running
4+
5+
1. Create a .env file and enter DISCORD_TOKEN=<your discord bot token>
6+
2. Run `npm i`
7+
3. Run `npm start`

commands/client.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = {
2+
name : 'client',
3+
aliases : [],
4+
description : 'Get the latest client download link(s)',
5+
args : [],
6+
guildOnly : false,
7+
cooldown : 3,
8+
botperms : ['SEND_MESSAGES'],
9+
userperms : [],
10+
execute : async (msg, args) => msg.channel.send('Download the latest client here:\nhttps://github.com/dginovker/2009Scape/releases/latest/download/2009Scape.jar'),
11+
};

commands/credits.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const { error } = require('../helpers.js');
2+
const { connection } = require('../database.js');
3+
4+
module.exports = {
5+
name : 'credits',
6+
aliases : ['get_credits', 'getcredits'],
7+
description : 'Get a players in-game credits via username',
8+
args : ['username'],
9+
guildOnly : true,
10+
cooldown : 3,
11+
botperms : ['SEND_MESSAGES'],
12+
userperms : ['ADMINISTRATOR'],
13+
execute : async (msg, args) => {
14+
const player_name = args.join(' ').trim().toLowerCase();
15+
16+
if (!/^([\sA-Z()+.\-_\d]{1,12})$/i.test(player_name))
17+
return msg.channel.send('Invalid characters in username.');
18+
19+
if (player_name.length > 12)
20+
return msg.channel.send('Invalid arguments specified, Username too long.');
21+
22+
const results = await connection.query('SELECT credits FROM members WHERE username = ?', [player_name]).catch(error);
23+
24+
if (!results.length)
25+
return msg.channel.send([
26+
`Failed to fetch credits for **${player_name}**..`,
27+
'Double check the username exist and try again.',
28+
]);
29+
30+
return msg.channel.send([
31+
`__***${player_name}***__`,
32+
`Total credits: **${results[0].credits}**`,
33+
]);
34+
},
35+
};

commands/exit.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
name : 'exit',
3+
aliases : ['kill'],
4+
description : 'Make the bot shutdown',
5+
args : [],
6+
guildOnly : true,
7+
cooldown : 3,
8+
botperms : ['SEND_MESSAGES'],
9+
userperms : ['ADMINISTRATOR'],
10+
execute : async (msg, args) => {
11+
msg.channel.send('Exiting...').then(()=>process.exit(0));
12+
},
13+
};

commands/ge.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const { error, tablePages, postPages } = require('../helpers.js');
2+
const { connection, connection_server } = require('../database.js');
3+
4+
module.exports = {
5+
name : 'grandexchange',
6+
aliases : ['grand_exchange', 'ge'],
7+
description : 'Get a list of items in the Grand Exchange',
8+
args : ['buying|selling', 'page?'],
9+
guildOnly : true,
10+
cooldown : 3,
11+
botperms : ['SEND_MESSAGES'],
12+
userperms : [],
13+
execute : async (msg, args) => {
14+
let [type, page = 1] = args;
15+
16+
if (!['buying', 'selling'].includes(type))
17+
return msg.channel.send('First argument must be `buying` or `selling`.');
18+
19+
page = isNaN(page) ? 1 : +page;
20+
21+
const results = await connection.query('SELECT ge FROM `members` WHERE ge IS NOT NULL AND ge <> ""').catch(error);
22+
23+
if (!results.length)
24+
return msg.channel.send('No items in the Grand Exchange');
25+
26+
let grand_exchange = [];
27+
results.forEach(r=>{
28+
const list = r.ge.split('|').filter(i=>type == 'selling' ? i.includes('true') : i.includes('false')).map(i=>i.split(',').map(JSON.parse));
29+
list.forEach(item=>{
30+
const ge_item = grand_exchange.find(ge_item=>ge_item[0] == item[0]);
31+
if (!ge_item) return grand_exchange.push(item);
32+
ge_item[1] += item[1];
33+
});
34+
});
35+
36+
const items = await connection_server.query(`SELECT id, name FROM \`item_configs\` WHERE id IN(${grand_exchange.map(d=>d[0]).join(',')})`);
37+
38+
grand_exchange = grand_exchange.map(ge_item=>[
39+
(items.find(item=>item.id == ge_item[0]) || {name: ge_item[0]}).name.toString().toLowerCase(),
40+
ge_item[1],
41+
]);
42+
43+
const pages = await tablePages(['Item Name', 'Amount'], grand_exchange, `__***Current items in Grand Exchange for ${type.toLowerCase()}:***__`);
44+
45+
postPages(msg, pages, page);
46+
},
47+
};

commands/getplayeritems.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const { error, RuneScape, tablePages, postPages } = require('../helpers.js');
2+
const { connection, connection_server } = require('../database.js');
3+
4+
module.exports = {
5+
name : 'getplayeritems',
6+
aliases : [],
7+
description : 'Get a list of players items from bank, inventory or equipment',
8+
args : ['player name', 'item location', 'page?'],
9+
guildOnly : true,
10+
cooldown : 3,
11+
botperms : ['SEND_MESSAGES'],
12+
userperms : ['MANAGE_GUILD'],
13+
execute : async (msg, args) => {
14+
const match = args.join(' ').trim().match(/^([\sA-Z()+.\-_\d]{1,12})\s+(bank|inventory|equipment)\s*(\d*)$/i);
15+
16+
if (!match)
17+
return msg.channel.send('Invalid arguments specified.');
18+
19+
let [,player_name, type, page = 1] = match.map(m=>m.trim().toLowerCase());
20+
21+
if (player_name.length > 12)
22+
return msg.channel.send('Invalid arguments specified, Username too long.');
23+
24+
page = isNaN(page) ? 1 : +page;
25+
26+
const results = await connection.query(`SELECT username, ${type} FROM members WHERE username = ?`, [player_name]).catch(error);
27+
28+
if (!results.length)
29+
return msg.channel.send('No player found with specified name.');
30+
31+
let drops = results[0][type].split('|').map(d=>d.split(',')).filter(d=>d[0] > 0);
32+
33+
if (!drops.length)
34+
return msg.channel.send(`No items in ${type}.`);
35+
36+
let items = [...new Set(drops.map(i=>i[0]))].filter(d=>d[0] > 0).join(',');
37+
items = await connection_server.query(`SELECT id, name, tradeable, shop_price, grand_exchange_price FROM \`item_configs\` WHERE id IN(${items})`);
38+
39+
drops = drops.map(i=>{
40+
let item = items.find(i2=>i2.id==i[0]);
41+
42+
if (!item)
43+
item = {id: i[0], name: '------', tradeable: null, shop_price: null, grand_exchange_price: null};
44+
45+
item.amount = i[1];
46+
return item;
47+
});
48+
49+
drops = drops.map(item=>[
50+
item.id,
51+
item.name.toLowerCase(),
52+
RuneScape.formatNumber(item.amount || 0),
53+
item.tradeable ? 'yes' : 'no',
54+
item.shop_price != null ? RuneScape.formatMoney(item.shop_price) : '---',
55+
item.grand_exchange_price != null ? RuneScape.formatMoney(item.grand_exchange_price) : '---',
56+
]);
57+
58+
const pages = await tablePages(['ID', 'Name', 'Amount', 'Tradeable', 'Shop Price', 'GE Price'], drops, `__***${results[0].username} ${type}:***__`);
59+
60+
postPages(msg, pages, page);
61+
},
62+
};

commands/givecredits.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const { error } = require('../helpers.js');
2+
const { connection } = require('../database.js');
3+
4+
module.exports = {
5+
name : 'givecredits',
6+
aliases : ['give_credits'],
7+
description : 'Give a player in-game credits via username',
8+
args : ['username', 'amount'],
9+
guildOnly : true,
10+
cooldown : 3,
11+
botperms : ['SEND_MESSAGES'],
12+
userperms : ['ADMINISTRATOR'],
13+
execute : async (msg, args) => {
14+
const match = args.join(' ').trim().match(/^([\sA-Z()+.\-_\d]{1,12})\s+(-?\d+)$/i);
15+
16+
if (!match)
17+
return msg.channel.send('Invalid arguments specified.');
18+
19+
const [,player_name, amount] = match.map(m=>m.trim().toLowerCase());
20+
21+
if (player_name.length > 12)
22+
return msg.channel.send('Invalid arguments specified, Username too long.');
23+
24+
if (isNaN(amount))
25+
return msg.channel.send('No amount specified.');
26+
27+
const update = await connection.query('UPDATE members SET credits = credits + ? WHERE username = ?', [+amount, player_name]).catch(error);
28+
29+
if (!update.affectedRows)
30+
return msg.channel.send([
31+
`Failed to give **${amount} credits** to **${player_name}**..`,
32+
'Double check the username exist and try again.',
33+
]);
34+
35+
const results = await connection.query('SELECT credits FROM members WHERE username = ?', [player_name]).catch(error);
36+
37+
if (!results.length)
38+
return msg.channel.send([
39+
`Failed to give **${amount} credits** to **${player_name}**..`,
40+
'Double check the username exist and try again.',
41+
]);
42+
43+
return msg.channel.send([
44+
`Gave **${amount} credits** to **${player_name}**..`,
45+
`Total credits: **${results[0].credits}**`,
46+
]);
47+
},
48+
};

commands/help.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const Discord = require('discord.js');
2+
const { prefix } = require('../config.json');
3+
4+
module.exports = {
5+
name : 'help',
6+
aliases : ['commands', 'h'],
7+
description : 'List all of my commands or info about a specific command.',
8+
args : ['command_name?'],
9+
guildOnly : false,
10+
cooldown : 3,
11+
botperms : ['SEND_MESSAGES', 'EMBED_LINKS'],
12+
userperms : ['SEND_MESSAGES'],
13+
execute : async (msg, args) => {
14+
const data = [];
15+
let commands = msg.client.commands;
16+
if (msg.channel.type === 'dm'){
17+
commands = commands.filter(command => !command.guildOnly);
18+
} else if (msg.channel.type === 'text'){
19+
commands = commands.filter(command => !msg.channel.memberPermissions(msg.member).missing(command.userperms).length);
20+
}
21+
22+
if (!args.length) {
23+
commands.forEach(command => data.push(`${prefix}${command.name}${command.args.map(arg=>` [${arg}]`).join('')}: ${command.description}`));
24+
return msg.channel.send(data, { code: 'http', split: true });
25+
}
26+
27+
const name = args[0].toLowerCase();
28+
const command = commands.get(name) || commands.find(c => c.aliases && c.aliases.includes(name));
29+
30+
if (!command) {
31+
return msg.channel.send('That is not a valid command!');
32+
}
33+
34+
const embed = new Discord.RichEmbed()
35+
.setTitle(`***\`${prefix}help ${command.name}\`***`)
36+
.setColor('#3498db')
37+
.addField('❯ Description', `\`${command.description}\``)
38+
.addField('❯ Usage', `\`\`\`css\n${prefix}${command.name}${command.args.map(arg=>` [${arg}]`).join('')}\`\`\``)
39+
.addField('❯ Aliases', `\`${command.aliases.join('`, `') || '-'}\``, true)
40+
.addField('❯ Cooldown', `\`${command.cooldown || 3} second(s)\``, true)
41+
.addField('❯ Guild Only', `\`${command.guildOnly}\``, true);
42+
msg.channel.send({ embed });
43+
},
44+
};

0 commit comments

Comments
 (0)