forked from JaredScar/Badger_Discord_API
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.lua
465 lines (434 loc) · 17.2 KB
/
server.lua
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
local FormattedToken = "Bot " .. Config.Bot_Token
local error_codes_defined = {
[200] = 'OK - The request was completed successfully..!',
[400] = "Error - The request was improperly formatted, or the server couldn't understand it..!",
[401] = 'Error - The Authorization header was missing or invalid..! Your Discord Token is probably wrong or does not have correct permissions attributed to it.',
[403] = 'Error - The Authorization token you passed did not have permission to the resource..! Your Discord Token is probably wrong or does not have correct permissions attributed to it.',
[404] = "Error - The resource at the location specified doesn't exist.",
[429] = 'Error - Too many requests, you hit the Discord rate limit. https://discord.com/developers/docs/topics/rate-limits',
[502] = 'Error - Discord API may be down?...'
};
Citizen.CreateThread(function()
if (GetCurrentResourceName() ~= "Badger_Discord_API") then
--StopResource(GetCurrentResourceName());
print("[" .. GetCurrentResourceName() .. "] " .. "IMPORTANT: This resource must be named Badger_Discord_API for it to work properly with other scripts...");
end
--print("[Badger_Discord_API] For support, make sure to join Badger's official Discord server: discord.gg/WjB5VFz");
--print('^7[^2Zap-Hosting^7] ^3Use code ^5TheWolfBadger-4765 ^3at checkout for ^220% ^3off of selected services. Visit ^5https://zap-hosting.com/badger ^3to get started!');
end)
tracked = {}
RegisterNetEvent('Badger_Discord_API:PlayerLoaded')
AddEventHandler('Badger_Discord_API:PlayerLoaded', function()
if (GetCurrentResourceName() ~= "Badger_Discord_API") then
--TriggerClientEvent('chatMessage', -1, '^1[^5SCRIPT ERROR^1] ^3The script ^1' .. GetCurrentResourceName() .. ' ^3will not work properly... You must '
--.. 'rename the resource to ^1Badger_Discord_API');
end
local license = ExtractIdentifiers(source).license;
if (tracked[license] == nil) then
tracked[license] = true;
--TriggerClientEvent('chatMessage', source,
--'^1[^5Badger_Discord_API^1] ^3The Discord API script was created by Badger. You may join his Discord at: ^6discord.gg/WjB5VFz')
end
--TriggerClientEvent('chatMessage', source,
--'^7[^2Zap-Hosting^7] ^3Use code ^5TheWolfBadger-4765 ^3at checkout for ^220% ^3off of selected services. Visit ^5https://zap-hosting.com/badger ^3to get started!');
end)
card = '{"type":"AdaptiveCard","$schema":"http://adaptivecards.io/schemas/adaptive-card.json","version":"1.3","body":[{"type":"Image","url":"' .. Config.Splash.Header_IMG .. '","horizontalAlignment":"Center"},{"type":"Container","items":[{"type":"TextBlock","text":"Badger_Discord_API","wrap":true,"fontType":"Default","size":"ExtraLarge","weight":"Bolder","color":"Light","horizontalAlignment":"Center"},{"type":"TextBlock","text":"' .. Config.Splash.Heading1 .. '","wrap":true,"size":"Large","weight":"Bolder","color":"Light","horizontalAlignment":"Center"},{"type":"TextBlock","text":"' .. Config.Splash.Heading2 .. '","wrap":true,"color":"Light","size":"Medium","horizontalAlignment":"Center"},{"type":"ColumnSet","height":"stretch","minHeight":"100px","bleed":true,"horizontalAlignment":"Center","columns":[{"type":"Column","width":"stretch","items":[{"type":"ActionSet","actions":[{"type":"Action.OpenUrl","title":"Discord","url":"' .. Config.Splash.Discord_Link .. '","style":"positive"}]}],"height":"stretch"},{"type":"Column","width":"stretch","items":[{"type":"ActionSet","actions":[{"type":"Action.OpenUrl","title":"Website","style":"positive","url":"' .. Config.Splash.Website_Link .. '"}]}]}]},{"type":"ActionSet","actions":[{"type":"Action.OpenUrl","title":'..Config.Splash.button..',"style":"destructive","iconUrl":'..Config.Splash.IconLink..',"url":'..Config.Splash.buttonLink..'}]}],"style":"default","bleed":true,"height":"stretch"},{"type":"Image","url":'..Config.Splash.Icon2..',"selectAction":{"type":"Action.OpenUrl","url":'..Config.Splash.buttonLink2..'},"horizontalAlignment":"Center"}]}'
if Config.Splash.Enabled then
AddEventHandler('playerConnecting', function(name, setKickReason, deferrals)
-- Player is connecting
deferrals.defer();
local src = source;
local toEnd = false;
local count = 0;
while not toEnd do
deferrals.presentCard(card,
function(data, rawData)
end)
Wait((1000))
count = count + 1;
if count == Config.Splash.Wait then
toEnd = true;
end
end
deferrals.done();
end)
end
function ExtractIdentifiers(src)
local identifiers = {
steam = "",
ip = "",
discord = "",
license = "",
xbl = "",
live = ""
}
--Loop over all identifiers
for i = 0, GetNumPlayerIdentifiers(src) - 1 do
local id = GetPlayerIdentifier(src, i)
--Convert it to a nice table.
if string.find(id, "steam") then
identifiers.steam = id
elseif string.find(id, "ip") then
identifiers.ip = id
elseif string.find(id, "discord") then
identifiers.discord = id
elseif string.find(id, "license") then
identifiers.license = id
elseif string.find(id, "xbl") then
identifiers.xbl = id
elseif string.find(id, "live") then
identifiers.live = id
end
end
return identifiers
end
function DiscordRequest(method, endpoint, jsondata)
local data = nil
PerformHttpRequest("https://discordapp.com/api/"..endpoint, function(errorCode, resultData, resultHeaders)
data = {data=resultData, code=errorCode, headers=resultHeaders}
end, method, #jsondata > 0 and json.encode(jsondata) or "", {["Content-Type"] = "application/json", ["Authorization"] = FormattedToken})
while data == nil do
Citizen.Wait(0)
end
return data
end
function GetRoleIdFromRoleName(name)
if (Caches.RoleList ~= nil) then
return tonumber(Caches.RoleList[name]);
else
local roles = GetGuildRoleList();
return tonumber(roles[name]);
end
end
function CheckEqual(role1, role2)
local checkStr1 = false;
local checkStr2 = false;
local roleID1 = role1;
local roleID2 = role2;
local searchGuild1 = true;
local searchGuild2 = true;
if type(role1) == "string" then checkStr1 = true end;
if type(role2) == "string" then checkStr2 = true end;
if checkStr1 then
local roles2 = Config.RoleList;
for roleRef, roleID in pairs(roles2) do
if roleRef == role1 then
roleID1 = roleID;
searchGuild1 = false;
end
end
if searchGuild1 then
local roles = GetGuildRoleList();
for roleName, roleID in pairs(roles) do
if roleName == role1 then
roleID1 = roleID;
end
end
end
end
if checkStr2 then
local roles2 = Config.RoleList;
for roleRef, roleID in pairs(roles2) do
if roleRef == role2 then
roleID2 = roleID;
searchGuild2 = false;
end
end
if searchGuild2 then
local roles = GetGuildRoleList();
for roleName, roleID in pairs(roles) do
if roleName == role2 then
roleID2 = roleID;
end
end
end
end
if tonumber(roleID1) == tonumber(roleID2) then
return true;
end
return false;
end
function IsDiscordEmailVerified(user)
local discordId = nil
local isVerified = false;
for _, id in ipairs(GetPlayerIdentifiers(user)) do
if string.match(id, "discord:") then
discordId = string.gsub(id, "discord:", "")
break
end
end
if discordId then
local endpoint = ("users/%s"):format(discordId)
local member = DiscordRequest("GET", endpoint, {})
if member.code == 200 then
local data = json.decode(member.data)
if data ~= nil then
-- It is valid data
--print("The data for User " .. GetPlayerName(user) .. " is: ");
--print(data.avatar);
isVerified = data.verified;
--print("---")
end
else
print("[Badger_Perms] ERROR: Code 200 was not reached. DETAILS: " .. error_codes_defined[member.code]);
end
end
return isVerified;
end
function GetDiscordEmail(user)
local discordId = nil
local emailData = nil;
for _, id in ipairs(GetPlayerIdentifiers(user)) do
if string.match(id, "discord:") then
discordId = string.gsub(id, "discord:", "")
break
end
end
if discordId then
local endpoint = ("users/%s"):format(discordId)
local member = DiscordRequest("GET", endpoint, {})
if member.code == 200 then
local data = json.decode(member.data)
if data ~= nil then
-- It is valid data
--print("The data for User " .. GetPlayerName(user) .. " is: ");
--print(data.avatar);
emailData = data.email;
--print("---")
end
else
print("[Badger_Perms] ERROR: Code 200 was not reached. DETAILS: " .. error_codes_defined[member.code])
end
end
return emailData;
end
function GetDiscordName(user)
local discordId = nil
local nameData = nil;
for _, id in ipairs(GetPlayerIdentifiers(user)) do
if string.match(id, "discord:") then
discordId = string.gsub(id, "discord:", "")
break
end
end
if discordId then
local endpoint = ("users/%s"):format(discordId)
local member = DiscordRequest("GET", endpoint, {})
if member.code == 200 then
local data = json.decode(member.data)
if data ~= nil then
-- It is valid data
--print("The data for User " .. GetPlayerName(user) .. " is: ");
--print(data.avatar);
nameData = data.username .. "#" .. data.discriminator;
--print("---")
end
else
print("[Badger_Perms] ERROR: Code 200 was not reached. DETAILS: " .. error_codes_defined[member.code])
end
end
return nameData;
end
function GetGuildIcon()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID, {})
if guild.code == 200 then
local data = json.decode(guild.data)
if (data.icon:sub(1, 1) and data.icon:sub(2, 2) == "_") then
-- It's a gif
return 'https://cdn.discordapp.com/icons/' .. Config.Guild_ID .. "/" .. data.icon .. ".gif";
else
-- Image
return 'https://cdn.discordapp.com/icons/' .. Config.Guild_ID .. "/" .. data.icon .. ".png";
end
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
return nil;
end
function GetGuildSplash()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID, {})
if guild.code == 200 then
local data = json.decode(guild.data)
-- Image
return 'https://cdn.discordapp.com/splashes/' .. Config.Guild_ID .. "/" .. data.icon .. ".png";
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
return nil;
end
function GetGuildName()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID, {})
if guild.code == 200 then
local data = json.decode(guild.data)
-- Image
return data.name;
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
return nil;
end
function GetGuildDescription()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID, {})
if guild.code == 200 then
local data = json.decode(guild.data)
-- Image
return data.description;
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
return nil;
end
function GetGuildMemberCount()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID.."?with_counts=true", {})
if guild.code == 200 then
local data = json.decode(guild.data)
-- Image
return data.approximate_member_count;
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
return nil;
end
function GetGuildOnlineMemberCount()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID.."?with_counts=true", {})
if guild.code == 200 then
local data = json.decode(guild.data)
return data.approximate_presence_count;
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
return nil;
end
function GetDiscordAvatar(user)
local discordId = nil
local imgURL = nil;
for _, id in ipairs(GetPlayerIdentifiers(user)) do
if string.match(id, "discord:") then
discordId = string.gsub(id, "discord:", "")
break
end
end
if discordId then
if Caches.Avatars[discordId] == nil then
local endpoint = ("users/%s"):format(discordId)
local member = DiscordRequest("GET", endpoint, {})
if member.code == 200 then
local data = json.decode(member.data)
if data ~= nil and data.avatar ~= nil then
-- It is valid data
--print("The data for User " .. GetPlayerName(user) .. " is: ");
--print(data.avatar);
if (data.avatar:sub(1, 1) and data.avatar:sub(2, 2) == "_") then
--print("IMG URL: " .. "https://cdn.discordapp.com/avatars/" .. discordId .. "/" .. data.avatar .. ".gif")
imgURL = "https://cdn.discordapp.com/avatars/" .. discordId .. "/" .. data.avatar .. ".gif";
else
--print("IMG URL: " .. "https://cdn.discordapp.com/avatars/" .. discordId .. "/" .. data.avatar .. ".png")
imgURL = "https://cdn.discordapp.com/avatars/" .. discordId .. "/" .. data.avatar .. ".png"
end
--print("---")
end
else
print("[Badger_Perms] ERROR: Code 200 was not reached. DETAILS: " .. error_codes_defined[member.code])
end
Caches.Avatars[discordId] = imgURL;
else
imgURL = Caches.Avatars[discordId];
end
else
print("[Badger_Perms] ERROR: Discord ID was not found...")
end
return imgURL;
end
Caches = {
Avatars = {}
}
function ResetCaches()
Caches = {};
end
function GetGuildRoleList()
if (Caches.RoleList == nil) then
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID, {})
if guild.code == 200 then
local data = json.decode(guild.data)
-- Image
local roles = data.roles;
local roleList = {};
for i = 1, #roles do
roleList[roles[i].name] = roles[i].id;
end
Caches.RoleList = roleList;
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
Caches.RoleList = nil;
end
end
return Caches.RoleList;
end
local recent_role_cache = {}
function GetDiscordRoles(user)
local discordId = nil
for _, id in ipairs(GetPlayerIdentifiers(user)) do
if string.match(id, "discord:") then
discordId = string.gsub(id, "discord:", "")
break;
end
end
if discordId then
if Config.CacheDiscordRoles and recent_role_cache[discordId] then
return recent_role_cache[discordId]
end
local endpoint = ("guilds/%s/members/%s"):format(Config.Guild_ID, discordId)
local member = DiscordRequest("GET", endpoint, {})
if member.code == 200 then
local data = json.decode(member.data)
local roles = data.roles
local found = true
if Config.CacheDiscordRoles then
recent_role_cache[discordId] = roles
Citizen.SetTimeout(((Config.CacheDiscordRolesTime or 60)*1000), function() recent_role_cache[discordId] = nil end)
end
return roles
else
print("[Badger_Perms] ERROR: Code 200 was not reached... Returning false. [Member Data NOT FOUND] DETAILS: " .. error_codes_defined[member.code])
return false
end
else
print("[Badger_Perms] ERROR: Discord was not connected to user's Fivem account...")
return false
end
return false
end
function GetDiscordNickname(user)
local discordId = nil
for _, id in ipairs(GetPlayerIdentifiers(user)) do
if string.match(id, "discord:") then
discordId = string.gsub(id, "discord:", "")
break
end
end
if discordId then
local endpoint = ("guilds/%s/members/%s"):format(Config.Guild_ID, discordId)
local member = DiscordRequest("GET", endpoint, {})
if member.code == 200 then
local data = json.decode(member.data)
local nickname = data.nick
return nickname;
else
print("[Badger_Perms] ERROR: Code 200 was not reached. Error Code: " .. error_codes_defined[member.code])
return nil;
end
else
print("[Badger_Perms] ERROR: Discord was not connected to user's Fivem account...")
return nil;
end
return nil;
end
Citizen.CreateThread(function()
local guild = DiscordRequest("GET", "guilds/"..Config.Guild_ID, {})
if guild.code == 200 then
local data = json.decode(guild.data)
print("[Badger_Perms] Permission system guild set to: "..data.name.." ("..data.id..")")
else
print("[Badger_Perms] An error occured, please check your config and ensure everything is correct. Error: "..(guild.data or guild.code))
end
end)