-
Notifications
You must be signed in to change notification settings - Fork 0
/
db.ts
220 lines (197 loc) · 8.06 KB
/
db.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// tslint:disable-next-line:no-var-requires
import {CommandInteraction, GuildMember, Message, MessageReaction, PermissionsBitField} from "discord.js";
import {randomUUID} from "crypto";
import {myLog} from "./index";
// tslint:disable-next-line:no-var-requires
const sqlite3 = require('sqlite3').verbose();
export const db = new sqlite3.Database('./database.db', (err: Error) => {
if (err) {
console.error(err.message);
}
myLog('Connected to the database.');
});
// from https://blog.pagesd.info/2019/10/29/use-sqlite-node-async-await/
// Hack to look like node-postgres
// (and handle async / await operation)
db.query = function (sql: string, params: any[]) {
const that = this;
return new Promise((resolve, reject) => {
that.all(sql, params, (error: Error, rows: object[]) => {
if (error)
reject(error);
else
resolve({ rows });
});
});
};
// someone used addrole command for a role that isn't auto approved and requires someone with manage roles permission to approve it
export function addRolePending (messageID: string, interaction: CommandInteraction) {
const data = [messageID, (interaction.member as GuildMember).id, interaction.options.get('target')!.user!.id, interaction.options.get('role')!.role!.id, interaction.commandName];
const sql = `INSERT INTO
pending_roles (messageID, submitter, target, role, add_remove)
VALUES(?, ?, ?, ?, ?)`;
db.run(sql, data, (err: Error) => {
if (err) {
console.error(err.message);
}
});
}
// a member with manage roles permission reacted to a message, let's see if it's in the pending role requests table
export function checkPendingReactions (reaction: MessageReaction, member: GuildMember) {
if (!member.permissions.has(PermissionsBitField.Flags.ManageRoles)) return;
const sql = `SELECT * FROM pending_roles WHERE messageID = ${reaction.message.id}`;
db.get(sql, [], (err: Error, row: any) => {
if (err) {
throw err;
}
if (row) {
reaction.message.channel.messages.fetch(reaction.message.id)
.then((message: Message) => {
if (message.guild) {
let approved = 'rejected';
const role = message.guild.roles.cache.get(row.role);
if (role) {
if (reaction.emoji.name === '✅') {
approved = 'approved';
message.guild.members.fetch(row.target)
.then(target => {
switch (row.add_remove) {
case 'addrole':
target.roles.add(role)
.then(() => {
resolvePending(message, member, true);
}).catch(myLog)
break;
case 'removerole':
target.roles.remove(role)
.then(() => {
resolvePending(message, member, true);
}).catch(myLog)
break;
default:
break;
}
}).catch(myLog)
}
}
if (reaction.emoji.name === '🚫') {
resolvePending(message, member, false);
}
message.guild.members.fetch(row.submitter)
.then(submitter => {
submitter.send(`Your role request for ${message.guild!.members.cache.get(row.target)!.displayName} has been ${approved} - ${message.url}`).catch(myLog)
})
}
})
}
});
}
// update embed of pending role requests
function resolvePending (message: Message, member: GuildMember, approved = false) {
let color = 15141120;
const footer = (approved ? "Approved" : "Rejected") + ` by ${member.displayName}`;
if (approved) {
color = 59136;
}
const embed = [
{
"title": "Completed Access Request",
"description": message.embeds[0].description as string,
"color": color,
"footer": {
"text": footer
}
}
]
message.edit({content: "_ _", embeds: embed }).catch(myLog)
message.reactions.removeAll()
.then(() => {
db.run("DELETE FROM pending_roles WHERE messageID=(?)", message.id, (err: Error) => {
if (err) {
myLog(err)
}
});
}).catch(myLog)
}
// add newly submitted keystone data to database
export function uploadKeystones (entry: any) {
// check timestamp on key entry and only update if newer
const sql = `SELECT timestamp FROM keystones WHERE character = '${entry.character}'`;
db.get(sql, [], (err: Error, row: any) => {
if (err) {
throw err;
}
const timestamp = (typeof row === 'undefined') ? 0 : row.timestamp;
if (Math.sign(entry.timestamp - timestamp)) {
myLog(`Updating ${entry.character}`);
const sql2 = `REPLACE INTO
keystones (character, name, class, spec, role, score_all, score_tank, score_healer, score_dps, guild, key_level, dungeon_name, timestamp, uploader)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
db.run(sql2, Object.values(entry), (err2: Error) => {
if (err2) {
return myLog(err2.message);
}
});
}
});
}
// get keystone data from database
export async function getKeystones (min?: number|null, max?: number|null, dungeon?: string|null) {
// base sql query
let sql = `SELECT * FROM keystones`;
if (min || max || dungeon ) {
sql = sql + ` WHERE `;
if (min) {
sql = sql + `key_level >= ${min} AND `
}
if (max) {
sql = sql + `key_level <= ${max} AND `
}
if (dungeon) {
sql = sql + `dungeon_name = '${dungeon.replace("'", "''")}' AND `
}
sql = sql.substring(0, sql.length-5)
}
try {
const result = await db.query(sql, []);
return result.rows;
} catch (err) {
return myLog((err as Error).message);
}
}
// remove all keys from db at weekly reset
export function truncateKeystones (timestamp: number) {
const sql = `DELETE FROM keystones WHERE timestamp < ?`;
db.run(sql, [timestamp], (err: object) => {
if (err) myLog(err)
});
}
export async function userLogin (userData: any) {
let uuid = randomUUID();
const sql = "SELECT * FROM users WHERE id = ?";
const result = await db.query(sql, [userData.id])
myLog(result)
if (result.rows.length === 0){
// insert
const sql2 = "INSERT INTO users (uuid, id, username, discriminator, avatar) VALUES (?, ?, ?, ?, ?)"
db.run(sql2, [uuid, userData.id, userData.username, userData.discriminator, userData.avatar], (err:object) => {
if (err){
myLog (err);
return(err);
}
})
}
else {
uuid = result.rows[0].uuid;
}
return uuid;
}
export async function getAuthorizedUsers () {
const sql = "SELECT uuid,id FROM users";
const result = await db.query(sql, []);
return result.rows;
}
process.on('SIGINT', () => {
db.close();
process.exit();
});