simply-xp 1.1.0 → 1.1.5-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -25
- package/index.d.ts +66 -1
- package/package.json +1 -2
- package/simplyxp.js +31 -837
- package/{Fonts → src/Fonts}/Poppins-Regular.ttf +0 -0
- package/{Fonts → src/Fonts}/Poppins-SemiBold.ttf +0 -0
- package/src/addLevel.js +71 -0
- package/src/addXP.js +112 -0
- package/src/charts.js +83 -0
- package/src/connect.js +20 -0
- package/src/create.js +28 -0
- package/src/fetch.js +74 -0
- package/src/leaderboard.js +70 -0
- package/src/lvlRole.js +54 -0
- package/{models → src/models}/level.js +1 -1
- package/{models → src/models}/lvlrole.js +0 -0
- package/src/rank.js +285 -0
- package/src/reset.js +28 -0
- package/src/roleSetup.js +124 -0
- package/src/setLevel.js +71 -0
- package/src/setXP.js +51 -0
package/src/rank.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
let Discord = require('discord.js')
|
|
2
|
+
const levels = require('../src/models/level.js')
|
|
3
|
+
const { join } = require('path')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {Discord.Message} message
|
|
7
|
+
* @param {string} userID
|
|
8
|
+
* @param {string} guildID
|
|
9
|
+
* @param {import('../index').rankOptions} options
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
async function rank(message, userID, guildID, options = []) {
|
|
13
|
+
if (!userID) throw new Error('[XP] User ID was not provided.')
|
|
14
|
+
|
|
15
|
+
if (!guildID) throw new Error('[XP] Guild ID was not provided.')
|
|
16
|
+
|
|
17
|
+
const user = await levels.findOne({
|
|
18
|
+
user: userID,
|
|
19
|
+
guild: guildID
|
|
20
|
+
})
|
|
21
|
+
if (!user) console.error('[XP] NO_DATA | User has no XP data.')
|
|
22
|
+
|
|
23
|
+
const leaderboard = await levels
|
|
24
|
+
.find({
|
|
25
|
+
guild: guildID
|
|
26
|
+
})
|
|
27
|
+
.sort([['xp', 'descending']])
|
|
28
|
+
.exec()
|
|
29
|
+
|
|
30
|
+
user.position = leaderboard.findIndex((i) => i.user === userID) + 1
|
|
31
|
+
|
|
32
|
+
let targetxp = user.level + 1
|
|
33
|
+
|
|
34
|
+
let target = targetxp * targetxp * 100
|
|
35
|
+
|
|
36
|
+
return rankCard(message, {
|
|
37
|
+
level: user.level,
|
|
38
|
+
currentXP: user.xp,
|
|
39
|
+
neededXP: target,
|
|
40
|
+
rank: user.position,
|
|
41
|
+
background: options.background,
|
|
42
|
+
color: options.color,
|
|
43
|
+
member: message.guild.members.cache.get(userID)?.user
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
async function rankCard(message, options = []) {
|
|
47
|
+
try {
|
|
48
|
+
const Canvas = require('canvas')
|
|
49
|
+
const { registerFont } = require('canvas')
|
|
50
|
+
registerFont(join(__dirname, 'Fonts', 'Poppins-SemiBold.ttf'), {
|
|
51
|
+
family: 'Poppins-Regular'
|
|
52
|
+
})
|
|
53
|
+
registerFont(join(__dirname, 'Fonts', 'Poppins-SemiBold.ttf'), {
|
|
54
|
+
family: 'Poppins-Bold'
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
function shortener(count) {
|
|
58
|
+
const COUNT_ABBRS = ['', 'k', 'M', 'T']
|
|
59
|
+
|
|
60
|
+
const i =
|
|
61
|
+
0 === count ? count : Math.floor(Math.log(count) / Math.log(1000))
|
|
62
|
+
let result = parseFloat((count / Math.pow(1000, i)).toFixed(2))
|
|
63
|
+
result += `${COUNT_ABBRS[i]}`
|
|
64
|
+
return result
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const member = options.member
|
|
68
|
+
|
|
69
|
+
const canvas = Canvas.createCanvas(1080, 400),
|
|
70
|
+
ctx = canvas.getContext('2d')
|
|
71
|
+
|
|
72
|
+
const name = member.tag
|
|
73
|
+
const noSymbols = (string) => string.replace(/[\u007f-\uffff]/g, '')
|
|
74
|
+
|
|
75
|
+
let fsiz = '45px'
|
|
76
|
+
if (message.guild.name.length >= 23) {
|
|
77
|
+
fsiz = '38px'
|
|
78
|
+
}
|
|
79
|
+
if (message.guild.name.length >= 40) {
|
|
80
|
+
fsiz = '28px'
|
|
81
|
+
}
|
|
82
|
+
if (message.guild.name.length >= 63) {
|
|
83
|
+
fsiz = '22px'
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let BackgroundRadius = '20',
|
|
87
|
+
BackGroundImg =
|
|
88
|
+
options.background ||
|
|
89
|
+
'https://media.discordapp.net/attachments/868506665102762034/876750913866461185/photo-1579546929518-9e396f3cc809.png?width=640&height=427',
|
|
90
|
+
AttachmentName = 'rank.png',
|
|
91
|
+
Username = noSymbols(name),
|
|
92
|
+
AvatarRoundRadius = '50',
|
|
93
|
+
DrawLayerColor = '#000000',
|
|
94
|
+
DrawLayerOpacity = '0.4',
|
|
95
|
+
BoxColor = options.color || '#096DD1',
|
|
96
|
+
LevelBarFill = options.lvlbar || '#ffffff',
|
|
97
|
+
LevelBarBackground = options.lvlbarBg || '#ffffff',
|
|
98
|
+
Rank = options.rank,
|
|
99
|
+
TextEXP = shortener(options.currentXP) + ' xp',
|
|
100
|
+
LvlText = `Level ${shortener(options.level)}`,
|
|
101
|
+
BarRadius = '20',
|
|
102
|
+
TextXpNeded = '{current}/{needed}',
|
|
103
|
+
CurrentXP = options.currentXP,
|
|
104
|
+
NeededXP = options.neededXP
|
|
105
|
+
|
|
106
|
+
ctx.beginPath()
|
|
107
|
+
ctx.moveTo(0 + Number(BackgroundRadius), 0)
|
|
108
|
+
ctx.lineTo(0 + 1080 - Number(BackgroundRadius), 0)
|
|
109
|
+
ctx.quadraticCurveTo(0 + 1080, 0, 0 + 1080, 0 + Number(BackgroundRadius))
|
|
110
|
+
ctx.lineTo(0 + 1080, 0 + 400 - Number(BackgroundRadius))
|
|
111
|
+
ctx.quadraticCurveTo(
|
|
112
|
+
0 + 1080,
|
|
113
|
+
0 + 400,
|
|
114
|
+
0 + 1080 - Number(BackgroundRadius),
|
|
115
|
+
0 + 400
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
ctx.lineTo(0 + Number(BackgroundRadius), 0 + 400)
|
|
119
|
+
ctx.quadraticCurveTo(0, 0 + 400, 0, 0 + 400 - Number(BackgroundRadius))
|
|
120
|
+
ctx.lineTo(0, 0 + Number(BackgroundRadius))
|
|
121
|
+
ctx.quadraticCurveTo(0, 0, 0 + Number(BackgroundRadius), 0)
|
|
122
|
+
ctx.closePath()
|
|
123
|
+
ctx.clip()
|
|
124
|
+
ctx.fillStyle = '#000000'
|
|
125
|
+
ctx.fillRect(0, 0, 1080, 400)
|
|
126
|
+
let background = await Canvas.loadImage(BackGroundImg)
|
|
127
|
+
ctx.globalAlpha = 0.7
|
|
128
|
+
ctx.drawImage(background, 0, 0, 1080, 400)
|
|
129
|
+
ctx.restore()
|
|
130
|
+
|
|
131
|
+
ctx.fillStyle = DrawLayerColor
|
|
132
|
+
ctx.globalAlpha = DrawLayerOpacity
|
|
133
|
+
ctx.fillRect(40, 0, 240, canvas.height)
|
|
134
|
+
ctx.globalAlpha = 1
|
|
135
|
+
|
|
136
|
+
function RoundedBox(ctx, x, y, width, height, radius) {
|
|
137
|
+
ctx.beginPath()
|
|
138
|
+
ctx.moveTo(x + radius, y)
|
|
139
|
+
ctx.lineTo(x + width - radius, y)
|
|
140
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
|
|
141
|
+
ctx.lineTo(x + width, y + height - radius)
|
|
142
|
+
ctx.quadraticCurveTo(
|
|
143
|
+
x + width,
|
|
144
|
+
y + height,
|
|
145
|
+
x + width - radius,
|
|
146
|
+
y + height
|
|
147
|
+
)
|
|
148
|
+
ctx.lineTo(x + radius, y + height)
|
|
149
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
|
|
150
|
+
ctx.lineTo(x, y + radius)
|
|
151
|
+
ctx.quadraticCurveTo(x, y, x + radius, y)
|
|
152
|
+
ctx.closePath()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let avatar = await Canvas.loadImage(
|
|
156
|
+
member.displayAvatarURL({ dynamic: true, format: 'png' })
|
|
157
|
+
)
|
|
158
|
+
ctx.save()
|
|
159
|
+
RoundedBox(ctx, 40 + 30, 30, 180, 180, Number(AvatarRoundRadius))
|
|
160
|
+
ctx.strokeStyle = BoxColor
|
|
161
|
+
ctx.lineWidth = '10'
|
|
162
|
+
ctx.stroke()
|
|
163
|
+
ctx.clip()
|
|
164
|
+
ctx.drawImage(avatar, 40 + 30, 30, 180, 180)
|
|
165
|
+
ctx.restore()
|
|
166
|
+
|
|
167
|
+
ctx.save()
|
|
168
|
+
RoundedBox(ctx, 40 + 30, 30 + 180 + 30 + 50 + 30, 180, 50, 20)
|
|
169
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
170
|
+
ctx.stroke()
|
|
171
|
+
ctx.clip()
|
|
172
|
+
ctx.fillStyle = BoxColor
|
|
173
|
+
ctx.globalAlpha = '1'
|
|
174
|
+
ctx.fillRect(40 + 30, 30 + 180 + 30 + 50 + 30, 180, 50)
|
|
175
|
+
ctx.globalAlpha = 1
|
|
176
|
+
ctx.fillStyle = '#ffffff'
|
|
177
|
+
ctx.font = '32px "Poppins-Bold"'
|
|
178
|
+
ctx.textAlign = 'center'
|
|
179
|
+
ctx.fillText(TextEXP, 40 + 30 + 180 / 2, 30 + 180 + 30 + 30 + 50 + 38)
|
|
180
|
+
ctx.restore()
|
|
181
|
+
|
|
182
|
+
ctx.save()
|
|
183
|
+
RoundedBox(ctx, 40 + 30, 30 + 180 + 30, 180, 50, 20)
|
|
184
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
185
|
+
ctx.stroke()
|
|
186
|
+
ctx.clip()
|
|
187
|
+
ctx.fillStyle = BoxColor
|
|
188
|
+
ctx.globalAlpha = '1'
|
|
189
|
+
ctx.fillRect(40 + 30, 30 + 180 + 30, 180, 50, 50)
|
|
190
|
+
ctx.globalAlpha = 1
|
|
191
|
+
ctx.fillStyle = '#ffffff'
|
|
192
|
+
ctx.font = '32px "Poppins-Bold"'
|
|
193
|
+
ctx.textAlign = 'center'
|
|
194
|
+
ctx.fillText(LvlText, 40 + 30 + 180 / 2, 30 + 180 + 30 + 38)
|
|
195
|
+
ctx.restore()
|
|
196
|
+
|
|
197
|
+
ctx.save()
|
|
198
|
+
ctx.textAlign = 'left'
|
|
199
|
+
ctx.fillStyle = '#ffffff'
|
|
200
|
+
ctx.shadowColor = '#000000'
|
|
201
|
+
ctx.shadowBlur = 15
|
|
202
|
+
ctx.shadowOffsetX = 1
|
|
203
|
+
ctx.shadowOffsetY = 1
|
|
204
|
+
ctx.font = '39px "Poppins-Bold"'
|
|
205
|
+
ctx.fillText(Username, 390, 80)
|
|
206
|
+
ctx.restore()
|
|
207
|
+
|
|
208
|
+
ctx.save()
|
|
209
|
+
ctx.textAlign = 'right'
|
|
210
|
+
ctx.fillStyle = '#ffffff'
|
|
211
|
+
ctx.shadowColor = '#000000'
|
|
212
|
+
ctx.shadowBlur = 15
|
|
213
|
+
ctx.shadowOffsetX = 1
|
|
214
|
+
ctx.shadowOffsetY = 1
|
|
215
|
+
ctx.font = '55px "Poppins-Bold"'
|
|
216
|
+
ctx.fillText('#' + Rank, canvas.width - 50 - 5, 80)
|
|
217
|
+
ctx.restore()
|
|
218
|
+
|
|
219
|
+
ctx.save()
|
|
220
|
+
RoundedBox(ctx, 390, 305, 660, 70, Number(20))
|
|
221
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
222
|
+
ctx.stroke()
|
|
223
|
+
ctx.clip()
|
|
224
|
+
ctx.fillStyle = '#ffffff'
|
|
225
|
+
ctx.font = `${fsiz} "Poppins-Bold"`
|
|
226
|
+
ctx.textAlign = 'center'
|
|
227
|
+
ctx.fillText(message.guild.name, 60 + 660, 355)
|
|
228
|
+
ctx.globalAlpha = '0.2'
|
|
229
|
+
ctx.fillRect(390, 305, 660, 70)
|
|
230
|
+
ctx.restore()
|
|
231
|
+
|
|
232
|
+
ctx.save()
|
|
233
|
+
RoundedBox(ctx, 390, 145, 660, 50, Number(BarRadius))
|
|
234
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
235
|
+
ctx.stroke()
|
|
236
|
+
ctx.clip()
|
|
237
|
+
ctx.fillStyle = LevelBarBackground
|
|
238
|
+
ctx.globalAlpha = '0.2'
|
|
239
|
+
ctx.fillRect(390, 145, 660, 50, 50)
|
|
240
|
+
ctx.restore()
|
|
241
|
+
|
|
242
|
+
const percent = (100 * CurrentXP) / NeededXP
|
|
243
|
+
const progress = (percent * 660) / 100
|
|
244
|
+
|
|
245
|
+
ctx.save()
|
|
246
|
+
RoundedBox(ctx, 390, 145, progress, 50, Number(BarRadius))
|
|
247
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
248
|
+
ctx.stroke()
|
|
249
|
+
ctx.clip()
|
|
250
|
+
ctx.fillStyle = LevelBarFill
|
|
251
|
+
ctx.globalAlpha = '0.5'
|
|
252
|
+
ctx.fillRect(390, 145, progress, 50, 50)
|
|
253
|
+
ctx.restore()
|
|
254
|
+
|
|
255
|
+
ctx.save()
|
|
256
|
+
ctx.textAlign = 'left'
|
|
257
|
+
ctx.fillStyle = '#ffffff'
|
|
258
|
+
ctx.globalAlpha = '0.8'
|
|
259
|
+
ctx.font = '30px "Poppins-Bold"'
|
|
260
|
+
ctx.fillText('Next Level: ' + shortener(NeededXP) + ' xp', 390, 230)
|
|
261
|
+
ctx.restore()
|
|
262
|
+
|
|
263
|
+
const latestXP = Number(CurrentXP) - Number(NeededXP)
|
|
264
|
+
const textXPEdited = TextXpNeded.replace(/{needed}/g, shortener(NeededXP))
|
|
265
|
+
.replace(/{current}/g, shortener(CurrentXP))
|
|
266
|
+
.replace(/{latest}/g, latestXP)
|
|
267
|
+
ctx.textAlign = 'center'
|
|
268
|
+
ctx.fillStyle = '#474747'
|
|
269
|
+
ctx.globalAlpha = 1
|
|
270
|
+
ctx.font = '30px "Poppins-Bold"'
|
|
271
|
+
ctx.fillText(textXPEdited, 730, 180)
|
|
272
|
+
|
|
273
|
+
const attachment = new Discord.MessageAttachment(
|
|
274
|
+
canvas.toBuffer(),
|
|
275
|
+
AttachmentName
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
return attachment
|
|
279
|
+
} catch (err) {
|
|
280
|
+
console.log(`[XP] Error Occured. | rankCard | Error: ${err.stack}`)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
module.exports = rank
|
package/src/reset.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const levels = require('../src/models/level.js')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} userID
|
|
5
|
+
* @param {string} guildID
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
async function reset(userID, guildID) {
|
|
9
|
+
if (!userID) throw new Error('[XP] User ID was not provided.')
|
|
10
|
+
|
|
11
|
+
if (!guildID) throw new Error('[XP] User ID was not provided.')
|
|
12
|
+
|
|
13
|
+
let uzer = await levels.findOne({ user: userID, guild: guildID })
|
|
14
|
+
|
|
15
|
+
uzer = new levels({
|
|
16
|
+
user: userID,
|
|
17
|
+
guild: guildID,
|
|
18
|
+
xp: 0,
|
|
19
|
+
lvl: 0
|
|
20
|
+
})
|
|
21
|
+
await uzer
|
|
22
|
+
.save()
|
|
23
|
+
.catch((e) => console.log(`[XP] Failed to save new use to database`))
|
|
24
|
+
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = reset
|
package/src/roleSetup.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
let Discord = require('discord.js')
|
|
2
|
+
const lrole = require('../src/models/lvlrole.js')
|
|
3
|
+
|
|
4
|
+
class roleSetup {
|
|
5
|
+
/**
|
|
6
|
+
* @param {Discord.Client} client
|
|
7
|
+
* @param {string} guildID
|
|
8
|
+
* @param {import('../index').lvladdOptions} options
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
static async add(client, guildID, options = []) {
|
|
12
|
+
let rol = await lrole.findOne({
|
|
13
|
+
gid: guildID,
|
|
14
|
+
lvlrole: {
|
|
15
|
+
lvl: options.level,
|
|
16
|
+
role: options.role
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
let g = client.guilds.cache.get(guildID)
|
|
21
|
+
|
|
22
|
+
let roll = g.roles.cache.find((r) => r.id === options.role)
|
|
23
|
+
|
|
24
|
+
if (roll) {
|
|
25
|
+
if (rol) throw new Error('Level Already Exist. Use delete')
|
|
26
|
+
else if (!rol) {
|
|
27
|
+
let newrol = await lrole.findOne({
|
|
28
|
+
gid: guildID
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
if (!newrol) {
|
|
32
|
+
newrol = new lrole({
|
|
33
|
+
gid: guildID,
|
|
34
|
+
lvlrole: []
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
await newrol.save()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
newrol.lvlrole.push({ lvl: options.level, role: options.role })
|
|
41
|
+
|
|
42
|
+
await newrol
|
|
43
|
+
.save()
|
|
44
|
+
.catch((e) =>
|
|
45
|
+
console.log(`[XP] Failed to add lvlrole to database | ${e}`)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return true
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
throw new Error(
|
|
52
|
+
'Role ID is invalid. | ' +
|
|
53
|
+
`Guild ID: ${guildID} | Role ID: ${options.role}`
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {Discord.Client} client
|
|
60
|
+
* @param {string} guildID
|
|
61
|
+
* @param {import('../index').lvlremoveOptions} options
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
static async remove(client, guildID, options = []) {
|
|
65
|
+
let rol = await lrole.find({
|
|
66
|
+
gid: guildID
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
if (!rol || rol.length === 0)
|
|
70
|
+
throw new Error('Level role with this level does not exist')
|
|
71
|
+
rol = rol[0].lvlrole.find((item) => item.lvl === options.level) || undefined
|
|
72
|
+
|
|
73
|
+
if (rol) {
|
|
74
|
+
let newrol = await lrole.findOneAndUpdate(
|
|
75
|
+
{
|
|
76
|
+
gid: guildID
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
$pull: { lvlrole: { lvl: options.level } }
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
return true
|
|
84
|
+
} else throw new Error('Level role with this level does not exist')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @param {Discord.Client} client
|
|
89
|
+
* @param {string} guildID
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
static async fetch(client, guildID) {
|
|
93
|
+
let rol = await lrole.find({
|
|
94
|
+
gid: guildID
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
if (!rol || rol.length === 0)
|
|
98
|
+
throw new Error('There is no levelRole in this guild')
|
|
99
|
+
|
|
100
|
+
return rol[0].lvlrole
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {Discord.Client} client
|
|
105
|
+
* @param {string} guildID
|
|
106
|
+
* @param {string} level
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
static async find(client, guildID, level) {
|
|
110
|
+
let rol = await lrole.find({
|
|
111
|
+
gid: guildID
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
if (!rol || rol.length === 0)
|
|
115
|
+
throw new Error('There is no levelRole in this guild')
|
|
116
|
+
rol = rol[0].lvlrole.find((item) => item.lvl === level) || undefined
|
|
117
|
+
|
|
118
|
+
if (rol) {
|
|
119
|
+
return rol
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = roleSetup
|
package/src/setLevel.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
let Discord = require('discord.js')
|
|
2
|
+
const levels = require('../src/models/level.js')
|
|
3
|
+
let { roleSetup } = require('../simplyxp')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {Discord.Message} message
|
|
7
|
+
* @param {string} userID
|
|
8
|
+
* @param {string} guildID
|
|
9
|
+
* @param {string} level
|
|
10
|
+
*/
|
|
11
|
+
async function setLevel(message, userID, guildID, level) {
|
|
12
|
+
if (!userID) throw new Error('[XP] User ID was not provided.')
|
|
13
|
+
|
|
14
|
+
if (!guildID) throw new Error('[XP] Guild ID was not provided.')
|
|
15
|
+
|
|
16
|
+
if (!level) throw new Error('[XP] Level amount is not provided.')
|
|
17
|
+
|
|
18
|
+
let { client } = message
|
|
19
|
+
|
|
20
|
+
const user = await levels.findOne({ user: userID, guild: guildID })
|
|
21
|
+
|
|
22
|
+
if (!user) {
|
|
23
|
+
const newUser = new levels({
|
|
24
|
+
user: userID,
|
|
25
|
+
guild: guildID,
|
|
26
|
+
xp: 0,
|
|
27
|
+
level: 0
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
await newUser
|
|
31
|
+
.save()
|
|
32
|
+
.catch((e) => console.log(`[XP] Failed to save new user to database`))
|
|
33
|
+
|
|
34
|
+
let xp = (level * 10) ** 2
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
level: level,
|
|
38
|
+
exp: xp
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
let level1 = user.level
|
|
42
|
+
|
|
43
|
+
user.xp = (level * 10) ** 2
|
|
44
|
+
user.level = Math.floor(0.1 * Math.sqrt(user.xp))
|
|
45
|
+
|
|
46
|
+
await user
|
|
47
|
+
.save()
|
|
48
|
+
.catch((e) =>
|
|
49
|
+
console.log(`[XP] Failed to set Level | User: ${userID} | Err: ${e}`)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
if (level1 !== level) {
|
|
53
|
+
let data = {
|
|
54
|
+
xp: user.xp,
|
|
55
|
+
level: user.level,
|
|
56
|
+
userID,
|
|
57
|
+
guildID
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let role = await roleSetup.find(client, guildID, level)
|
|
61
|
+
|
|
62
|
+
client.emit('levelUp', message, data, role)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
level: user.level,
|
|
67
|
+
xp: user.xp
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = setLevel
|
package/src/setXP.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const levels = require('../src/models/level.js')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {string} userID
|
|
5
|
+
* @param {string} guildID
|
|
6
|
+
* @param {string} xp
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
async function setXP(userID, guildID, xp) {
|
|
10
|
+
if (!userID) throw new Error('[XP] User ID was not provided.')
|
|
11
|
+
|
|
12
|
+
if (!guildID) throw new Error('[XP] Guild ID was not provided.')
|
|
13
|
+
|
|
14
|
+
if (!xp) throw new Error('[XP] XP amount is not provided.')
|
|
15
|
+
|
|
16
|
+
if (Number(xp).toString() === 'NaN')
|
|
17
|
+
throw new Error('[XP] XP amount is not a number.')
|
|
18
|
+
|
|
19
|
+
const user = await levels.findOne({ user: userID, guild: guildID })
|
|
20
|
+
|
|
21
|
+
let lvl = Math.floor(0.1 * Math.sqrt(xp))
|
|
22
|
+
|
|
23
|
+
if (!user) {
|
|
24
|
+
const newUser = new levels({
|
|
25
|
+
user: userID,
|
|
26
|
+
guild: guildID,
|
|
27
|
+
xp: xp,
|
|
28
|
+
level: lvl
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
await newUser
|
|
32
|
+
.save()
|
|
33
|
+
.catch((e) => console.log(`[XP] Failed to save new use to database`))
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
xp: 0
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
user.xp = xp
|
|
40
|
+
user.level = Math.floor(0.1 * Math.sqrt(user.xp))
|
|
41
|
+
|
|
42
|
+
await user
|
|
43
|
+
.save()
|
|
44
|
+
.catch((e) =>
|
|
45
|
+
console.log(`[XP] Failed to set XP | User: ${userID} | Err: ${e}`)
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return { xp }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = setXP
|