simply-xp 1.1.5-beta → 1.1.5
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 +16 -10
- package/package.json +1 -1
- package/src/rank.js +287 -285
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p align="center"><img align="center" style="
|
|
1
|
+
<p align="center"><img align="center" style="width: 128px" src="https://user-images.githubusercontent.com/71836991/173240203-ca92976f-2e5e-4a85-ba5e-155796eac889.png"></p>
|
|
2
2
|
|
|
3
3
|
<h2 style="font-size:2.5rem;" align="center">Simply-XP</h2>
|
|
4
4
|
|
|
@@ -28,7 +28,12 @@ yarn add simply-xp
|
|
|
28
28
|
|
|
29
29
|
<br>
|
|
30
30
|
|
|
31
|
-
#
|
|
31
|
+
# 👋 Goodbye XP 👋
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
> We are deprecating, Because making an XP system is already easy. And working on a package which not much people uses is an time waste. We are not deleting the package whatsoever !
|
|
35
|
+
|
|
36
|
+
# 👋 Last Update log
|
|
32
37
|
|
|
33
38
|
- Fixed bugs
|
|
34
39
|
- New `addLevel(), setLevel(), reset()`
|
|
@@ -38,15 +43,16 @@ yarn add simply-xp
|
|
|
38
43
|
- Re-coded to squeeze bugs
|
|
39
44
|
- Bug Fixes
|
|
40
45
|
|
|
41
|
-
# But Why
|
|
46
|
+
# ~~But Why ?~~
|
|
47
|
+
## We do not recommend using this package as you can encounter bugs.
|
|
42
48
|
|
|
43
|
-
- Easiest XP System in Discord.js
|
|
44
|
-
- Fastest Support ever
|
|
45
|
-
- Rank Card Maker
|
|
46
|
-
- Beginner Friendly
|
|
47
|
-
- Easier than other XP Systems
|
|
48
|
-
- Inbuilt Auto Roles system
|
|
49
|
-
- Flexible and simple at the same time
|
|
49
|
+
- ~~Easiest XP System in Discord.js~~
|
|
50
|
+
- ~~Fastest Support ever~~
|
|
51
|
+
- ~~Rank Card Maker~~
|
|
52
|
+
- ~~Beginner Friendly~~
|
|
53
|
+
- ~~Easier than other XP Systems~~
|
|
54
|
+
- ~~Inbuilt Auto Roles system~~
|
|
55
|
+
- ~~Flexible and simple at the same time~~
|
|
50
56
|
|
|
51
57
|
`Reconstructed discord-xp to give you things simpler ;)`
|
|
52
58
|
|
package/package.json
CHANGED
package/src/rank.js
CHANGED
|
@@ -1,285 +1,287 @@
|
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const
|
|
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
|
-
ctx.
|
|
109
|
-
ctx.
|
|
110
|
-
ctx.lineTo(0 + 1080
|
|
111
|
-
ctx.quadraticCurveTo(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
0 + 1080
|
|
115
|
-
0 + 400
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
ctx.lineTo(0
|
|
121
|
-
ctx.quadraticCurveTo(0, 0, 0 + Number(BackgroundRadius)
|
|
122
|
-
ctx.
|
|
123
|
-
ctx.
|
|
124
|
-
ctx.
|
|
125
|
-
ctx.
|
|
126
|
-
|
|
127
|
-
ctx.
|
|
128
|
-
|
|
129
|
-
ctx.
|
|
130
|
-
|
|
131
|
-
ctx.
|
|
132
|
-
|
|
133
|
-
ctx.
|
|
134
|
-
ctx.globalAlpha =
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
ctx.
|
|
140
|
-
ctx.
|
|
141
|
-
ctx.lineTo(x + width
|
|
142
|
-
ctx.quadraticCurveTo(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
x + width
|
|
146
|
-
y + height
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
ctx.lineTo(x, y +
|
|
151
|
-
ctx.quadraticCurveTo(x, y, x + radius
|
|
152
|
-
ctx.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
ctx.
|
|
161
|
-
ctx
|
|
162
|
-
ctx.
|
|
163
|
-
ctx.
|
|
164
|
-
ctx.
|
|
165
|
-
ctx.
|
|
166
|
-
|
|
167
|
-
ctx.
|
|
168
|
-
|
|
169
|
-
ctx.
|
|
170
|
-
ctx
|
|
171
|
-
ctx.
|
|
172
|
-
ctx.
|
|
173
|
-
ctx.
|
|
174
|
-
ctx.
|
|
175
|
-
ctx.globalAlpha = 1
|
|
176
|
-
ctx.
|
|
177
|
-
ctx.
|
|
178
|
-
ctx.
|
|
179
|
-
ctx.
|
|
180
|
-
ctx.
|
|
181
|
-
|
|
182
|
-
ctx.
|
|
183
|
-
|
|
184
|
-
ctx.
|
|
185
|
-
ctx
|
|
186
|
-
ctx.
|
|
187
|
-
ctx.
|
|
188
|
-
ctx.
|
|
189
|
-
ctx.
|
|
190
|
-
ctx.globalAlpha = 1
|
|
191
|
-
ctx.
|
|
192
|
-
ctx.
|
|
193
|
-
ctx.
|
|
194
|
-
ctx.
|
|
195
|
-
ctx.
|
|
196
|
-
|
|
197
|
-
ctx.
|
|
198
|
-
|
|
199
|
-
ctx.
|
|
200
|
-
ctx.
|
|
201
|
-
ctx.
|
|
202
|
-
ctx.
|
|
203
|
-
ctx.
|
|
204
|
-
ctx.
|
|
205
|
-
ctx.
|
|
206
|
-
ctx.
|
|
207
|
-
|
|
208
|
-
ctx.
|
|
209
|
-
|
|
210
|
-
ctx.
|
|
211
|
-
ctx.
|
|
212
|
-
ctx.
|
|
213
|
-
ctx.
|
|
214
|
-
ctx.
|
|
215
|
-
ctx.
|
|
216
|
-
ctx.
|
|
217
|
-
ctx.
|
|
218
|
-
|
|
219
|
-
ctx.
|
|
220
|
-
|
|
221
|
-
ctx.
|
|
222
|
-
ctx
|
|
223
|
-
ctx.
|
|
224
|
-
ctx.
|
|
225
|
-
ctx.
|
|
226
|
-
ctx.
|
|
227
|
-
ctx.
|
|
228
|
-
ctx.
|
|
229
|
-
ctx.
|
|
230
|
-
ctx.
|
|
231
|
-
|
|
232
|
-
ctx.
|
|
233
|
-
|
|
234
|
-
ctx.
|
|
235
|
-
ctx
|
|
236
|
-
ctx.
|
|
237
|
-
ctx.
|
|
238
|
-
ctx.
|
|
239
|
-
ctx.
|
|
240
|
-
ctx.
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
ctx.
|
|
248
|
-
ctx
|
|
249
|
-
ctx.
|
|
250
|
-
ctx.
|
|
251
|
-
ctx.
|
|
252
|
-
ctx.
|
|
253
|
-
ctx.
|
|
254
|
-
|
|
255
|
-
ctx.
|
|
256
|
-
|
|
257
|
-
ctx.
|
|
258
|
-
ctx.
|
|
259
|
-
ctx.
|
|
260
|
-
ctx.
|
|
261
|
-
ctx.
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
ctx.
|
|
270
|
-
ctx.
|
|
271
|
-
ctx.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
|
|
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
|
+
lvlbar: options.lvlbar,
|
|
44
|
+
lvlbarBg: options.lvlbarBg,
|
|
45
|
+
member: message.guild.members.cache.get(userID)?.user
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
async function rankCard(message, options = []) {
|
|
49
|
+
try {
|
|
50
|
+
const Canvas = require('canvas')
|
|
51
|
+
const { registerFont } = require('canvas')
|
|
52
|
+
registerFont(join(__dirname, 'Fonts', 'Poppins-SemiBold.ttf'), {
|
|
53
|
+
family: 'Poppins-Regular'
|
|
54
|
+
})
|
|
55
|
+
registerFont(join(__dirname, 'Fonts', 'Poppins-SemiBold.ttf'), {
|
|
56
|
+
family: 'Poppins-Bold'
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
function shortener(count) {
|
|
60
|
+
const COUNT_ABBRS = ['', 'k', 'M', 'T']
|
|
61
|
+
|
|
62
|
+
const i =
|
|
63
|
+
0 === count ? count : Math.floor(Math.log(count) / Math.log(1000))
|
|
64
|
+
let result = parseFloat((count / Math.pow(1000, i)).toFixed(2))
|
|
65
|
+
result += `${COUNT_ABBRS[i]}`
|
|
66
|
+
return result
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const member = options.member
|
|
70
|
+
|
|
71
|
+
const canvas = Canvas.createCanvas(1080, 400),
|
|
72
|
+
ctx = canvas.getContext('2d')
|
|
73
|
+
|
|
74
|
+
const name = member.tag
|
|
75
|
+
const noSymbols = (string) => string.replace(/[\u007f-\uffff]/g, '')
|
|
76
|
+
|
|
77
|
+
let fsiz = '45px'
|
|
78
|
+
if (message.guild.name.length >= 23) {
|
|
79
|
+
fsiz = '38px'
|
|
80
|
+
}
|
|
81
|
+
if (message.guild.name.length >= 40) {
|
|
82
|
+
fsiz = '28px'
|
|
83
|
+
}
|
|
84
|
+
if (message.guild.name.length >= 63) {
|
|
85
|
+
fsiz = '22px'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let BackgroundRadius = '20',
|
|
89
|
+
BackGroundImg =
|
|
90
|
+
options.background ||
|
|
91
|
+
'https://media.discordapp.net/attachments/868506665102762034/876750913866461185/photo-1579546929518-9e396f3cc809.png?width=640&height=427',
|
|
92
|
+
AttachmentName = 'rank.png',
|
|
93
|
+
Username = noSymbols(name),
|
|
94
|
+
AvatarRoundRadius = '50',
|
|
95
|
+
DrawLayerColor = '#000000',
|
|
96
|
+
DrawLayerOpacity = '0.4',
|
|
97
|
+
BoxColor = options.color || '#096DD1',
|
|
98
|
+
LevelBarFill = options.lvlbar || '#ffffff',
|
|
99
|
+
LevelBarBackground = options.lvlbarBg || '#ffffff',
|
|
100
|
+
Rank = options.rank,
|
|
101
|
+
TextEXP = shortener(options.currentXP) + ' xp',
|
|
102
|
+
LvlText = `Level ${shortener(options.level)}`,
|
|
103
|
+
BarRadius = '20',
|
|
104
|
+
TextXpNeded = '{current}/{needed}',
|
|
105
|
+
CurrentXP = options.currentXP,
|
|
106
|
+
NeededXP = options.neededXP
|
|
107
|
+
|
|
108
|
+
ctx.beginPath()
|
|
109
|
+
ctx.moveTo(0 + Number(BackgroundRadius), 0)
|
|
110
|
+
ctx.lineTo(0 + 1080 - Number(BackgroundRadius), 0)
|
|
111
|
+
ctx.quadraticCurveTo(0 + 1080, 0, 0 + 1080, 0 + Number(BackgroundRadius))
|
|
112
|
+
ctx.lineTo(0 + 1080, 0 + 400 - Number(BackgroundRadius))
|
|
113
|
+
ctx.quadraticCurveTo(
|
|
114
|
+
0 + 1080,
|
|
115
|
+
0 + 400,
|
|
116
|
+
0 + 1080 - Number(BackgroundRadius),
|
|
117
|
+
0 + 400
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
ctx.lineTo(0 + Number(BackgroundRadius), 0 + 400)
|
|
121
|
+
ctx.quadraticCurveTo(0, 0 + 400, 0, 0 + 400 - Number(BackgroundRadius))
|
|
122
|
+
ctx.lineTo(0, 0 + Number(BackgroundRadius))
|
|
123
|
+
ctx.quadraticCurveTo(0, 0, 0 + Number(BackgroundRadius), 0)
|
|
124
|
+
ctx.closePath()
|
|
125
|
+
ctx.clip()
|
|
126
|
+
ctx.fillStyle = '#000000'
|
|
127
|
+
ctx.fillRect(0, 0, 1080, 400)
|
|
128
|
+
let background = await Canvas.loadImage(BackGroundImg)
|
|
129
|
+
ctx.globalAlpha = 0.7
|
|
130
|
+
ctx.drawImage(background, 0, 0, 1080, 400)
|
|
131
|
+
ctx.restore()
|
|
132
|
+
|
|
133
|
+
ctx.fillStyle = DrawLayerColor
|
|
134
|
+
ctx.globalAlpha = DrawLayerOpacity
|
|
135
|
+
ctx.fillRect(40, 0, 240, canvas.height)
|
|
136
|
+
ctx.globalAlpha = 1
|
|
137
|
+
|
|
138
|
+
function RoundedBox(ctx, x, y, width, height, radius) {
|
|
139
|
+
ctx.beginPath()
|
|
140
|
+
ctx.moveTo(x + radius, y)
|
|
141
|
+
ctx.lineTo(x + width - radius, y)
|
|
142
|
+
ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
|
|
143
|
+
ctx.lineTo(x + width, y + height - radius)
|
|
144
|
+
ctx.quadraticCurveTo(
|
|
145
|
+
x + width,
|
|
146
|
+
y + height,
|
|
147
|
+
x + width - radius,
|
|
148
|
+
y + height
|
|
149
|
+
)
|
|
150
|
+
ctx.lineTo(x + radius, y + height)
|
|
151
|
+
ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
|
|
152
|
+
ctx.lineTo(x, y + radius)
|
|
153
|
+
ctx.quadraticCurveTo(x, y, x + radius, y)
|
|
154
|
+
ctx.closePath()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let avatar = await Canvas.loadImage(
|
|
158
|
+
member.displayAvatarURL({ dynamic: true, format: 'png' })
|
|
159
|
+
)
|
|
160
|
+
ctx.save()
|
|
161
|
+
RoundedBox(ctx, 40 + 30, 30, 180, 180, Number(AvatarRoundRadius))
|
|
162
|
+
ctx.strokeStyle = BoxColor
|
|
163
|
+
ctx.lineWidth = '10'
|
|
164
|
+
ctx.stroke()
|
|
165
|
+
ctx.clip()
|
|
166
|
+
ctx.drawImage(avatar, 40 + 30, 30, 180, 180)
|
|
167
|
+
ctx.restore()
|
|
168
|
+
|
|
169
|
+
ctx.save()
|
|
170
|
+
RoundedBox(ctx, 40 + 30, 30 + 180 + 30 + 50 + 30, 180, 50, 20)
|
|
171
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
172
|
+
ctx.stroke()
|
|
173
|
+
ctx.clip()
|
|
174
|
+
ctx.fillStyle = BoxColor
|
|
175
|
+
ctx.globalAlpha = '1'
|
|
176
|
+
ctx.fillRect(40 + 30, 30 + 180 + 30 + 50 + 30, 180, 50)
|
|
177
|
+
ctx.globalAlpha = 1
|
|
178
|
+
ctx.fillStyle = '#ffffff'
|
|
179
|
+
ctx.font = '32px "Poppins-Bold"'
|
|
180
|
+
ctx.textAlign = 'center'
|
|
181
|
+
ctx.fillText(TextEXP, 40 + 30 + 180 / 2, 30 + 180 + 30 + 30 + 50 + 38)
|
|
182
|
+
ctx.restore()
|
|
183
|
+
|
|
184
|
+
ctx.save()
|
|
185
|
+
RoundedBox(ctx, 40 + 30, 30 + 180 + 30, 180, 50, 20)
|
|
186
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
187
|
+
ctx.stroke()
|
|
188
|
+
ctx.clip()
|
|
189
|
+
ctx.fillStyle = BoxColor
|
|
190
|
+
ctx.globalAlpha = '1'
|
|
191
|
+
ctx.fillRect(40 + 30, 30 + 180 + 30, 180, 50, 50)
|
|
192
|
+
ctx.globalAlpha = 1
|
|
193
|
+
ctx.fillStyle = '#ffffff'
|
|
194
|
+
ctx.font = '32px "Poppins-Bold"'
|
|
195
|
+
ctx.textAlign = 'center'
|
|
196
|
+
ctx.fillText(LvlText, 40 + 30 + 180 / 2, 30 + 180 + 30 + 38)
|
|
197
|
+
ctx.restore()
|
|
198
|
+
|
|
199
|
+
ctx.save()
|
|
200
|
+
ctx.textAlign = 'left'
|
|
201
|
+
ctx.fillStyle = '#ffffff'
|
|
202
|
+
ctx.shadowColor = '#000000'
|
|
203
|
+
ctx.shadowBlur = 15
|
|
204
|
+
ctx.shadowOffsetX = 1
|
|
205
|
+
ctx.shadowOffsetY = 1
|
|
206
|
+
ctx.font = '39px "Poppins-Bold"'
|
|
207
|
+
ctx.fillText(Username, 390, 80)
|
|
208
|
+
ctx.restore()
|
|
209
|
+
|
|
210
|
+
ctx.save()
|
|
211
|
+
ctx.textAlign = 'right'
|
|
212
|
+
ctx.fillStyle = '#ffffff'
|
|
213
|
+
ctx.shadowColor = '#000000'
|
|
214
|
+
ctx.shadowBlur = 15
|
|
215
|
+
ctx.shadowOffsetX = 1
|
|
216
|
+
ctx.shadowOffsetY = 1
|
|
217
|
+
ctx.font = '55px "Poppins-Bold"'
|
|
218
|
+
ctx.fillText('#' + Rank, canvas.width - 50 - 5, 80)
|
|
219
|
+
ctx.restore()
|
|
220
|
+
|
|
221
|
+
ctx.save()
|
|
222
|
+
RoundedBox(ctx, 390, 305, 660, 70, Number(20))
|
|
223
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
224
|
+
ctx.stroke()
|
|
225
|
+
ctx.clip()
|
|
226
|
+
ctx.fillStyle = '#ffffff'
|
|
227
|
+
ctx.font = `${fsiz} "Poppins-Bold"`
|
|
228
|
+
ctx.textAlign = 'center'
|
|
229
|
+
ctx.fillText(message.guild.name, 60 + 660, 355)
|
|
230
|
+
ctx.globalAlpha = '0.2'
|
|
231
|
+
ctx.fillRect(390, 305, 660, 70)
|
|
232
|
+
ctx.restore()
|
|
233
|
+
|
|
234
|
+
ctx.save()
|
|
235
|
+
RoundedBox(ctx, 390, 145, 660, 50, Number(BarRadius))
|
|
236
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
237
|
+
ctx.stroke()
|
|
238
|
+
ctx.clip()
|
|
239
|
+
ctx.fillStyle = LevelBarBackground
|
|
240
|
+
ctx.globalAlpha = '0.2'
|
|
241
|
+
ctx.fillRect(390, 145, 660, 50, 50)
|
|
242
|
+
ctx.restore()
|
|
243
|
+
|
|
244
|
+
const percent = (100 * CurrentXP) / NeededXP
|
|
245
|
+
const progress = (percent * 660) / 100
|
|
246
|
+
|
|
247
|
+
ctx.save()
|
|
248
|
+
RoundedBox(ctx, 390, 145, progress, 50, Number(BarRadius))
|
|
249
|
+
ctx.strokeStyle = '#BFC85A22'
|
|
250
|
+
ctx.stroke()
|
|
251
|
+
ctx.clip()
|
|
252
|
+
ctx.fillStyle = LevelBarFill
|
|
253
|
+
ctx.globalAlpha = '0.5'
|
|
254
|
+
ctx.fillRect(390, 145, progress, 50, 50)
|
|
255
|
+
ctx.restore()
|
|
256
|
+
|
|
257
|
+
ctx.save()
|
|
258
|
+
ctx.textAlign = 'left'
|
|
259
|
+
ctx.fillStyle = '#ffffff'
|
|
260
|
+
ctx.globalAlpha = '0.8'
|
|
261
|
+
ctx.font = '30px "Poppins-Bold"'
|
|
262
|
+
ctx.fillText('Next Level: ' + shortener(NeededXP) + ' xp', 390, 230)
|
|
263
|
+
ctx.restore()
|
|
264
|
+
|
|
265
|
+
const latestXP = Number(CurrentXP) - Number(NeededXP)
|
|
266
|
+
const textXPEdited = TextXpNeded.replace(/{needed}/g, shortener(NeededXP))
|
|
267
|
+
.replace(/{current}/g, shortener(CurrentXP))
|
|
268
|
+
.replace(/{latest}/g, latestXP)
|
|
269
|
+
ctx.textAlign = 'center'
|
|
270
|
+
ctx.fillStyle = '#474747'
|
|
271
|
+
ctx.globalAlpha = 1
|
|
272
|
+
ctx.font = '30px "Poppins-Bold"'
|
|
273
|
+
ctx.fillText(textXPEdited, 730, 180)
|
|
274
|
+
|
|
275
|
+
const attachment = new Discord.MessageAttachment(
|
|
276
|
+
canvas.toBuffer(),
|
|
277
|
+
AttachmentName
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
return attachment
|
|
281
|
+
} catch (err) {
|
|
282
|
+
console.log(`[XP] Error Occured. | rankCard | Error: ${err.stack}`)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
module.exports = rank
|