-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsv.lua
More file actions
202 lines (185 loc) · 7.07 KB
/
sv.lua
File metadata and controls
202 lines (185 loc) · 7.07 KB
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
local botToken <const> = "YOUR_BOT_TOKEN" -- Add your discord bot with admin perms token here.
local insert = table.insert
local sort = table.sort
local playersData = {}
local TOKEN <const> = "Bot " .. botToken --Concatenated token
local DEFAULT_ID <const> = '903150326155182151' -- Just in case the player doesn't have discord open
--#region Functions
---Gets the discord id and cuts it
---@param playerId number
---@return string
---@return boolean
local function getDiscordId(playerId)
local identifiers = GetPlayerIdentifiers(playerId)
for i=1, #identifiers do
if identifiers[i]:match('discord:') then
return identifiers[i]:gsub('discord:', '')
end
end
return DEFAULT_ID
end
---Gets the license of a player
---@param playerId number
---@return string
---@return boolean
local function getLicense(playerId)
local identifiers = GetPlayerIdentifiers(playerId)
for i=1, #identifiers do
if identifiers[i]:match('license:') then
return identifiers[i]
end
end
return false
end
---Fetches the discord api for an user.
---If discord id is not nil, then it returns avatar
---@param discordId number
---@return string
local function getPlayerFromDiscord(discordId)
if not discordId then
return false
end
local p = promise.new()
PerformHttpRequest(('https://discordapp.com/api/users/%s'):format(discordId), function(err, result, headers)
p:resolve({data=result, code=err, headers = headers})
end, "GET", "", {["Content-Type"] = "application/json", ["Authorization"] = TOKEN})
local result = Citizen.Await(p)
if result then
if result.code ~= 200 then
return print('Error: Something went wrong with error code - ' .. result.code)
end
local data = json.decode(result.data)
if data and data.avatar then
return ('https://cdn.discordapp.com/avatars/%s/%s'):format(discordId, data.avatar)
end
end
end
---Fetches the discord api for an user.
---If discord id is not nil, then it returns avatar
---@param discordId number
---@return string
local function getDiscordName(discordId)
if not discordId then
return false
end
local p = promise.new()
PerformHttpRequest(('https://discordapp.com/api/users/%s'):format(discordId), function(err, result, headers)
p:resolve({data=result, code=err, headers = headers})
end, "GET", "", {["Content-Type"] = "application/json", ["Authorization"] = TOKEN})
local result = Citizen.Await(p)
if result then
if result.code ~= 200 then
return print('Error: Something went wrong with error code - ' .. result.code)
end
local data = json.decode(result.data)
if data and data.username then
return data.username
end
end
end
AddEventHandler('onResourceStart', function(name)
if GetCurrentResourceName() == name then
local p = promise.new()
exports.oxmysql:execute('SELECT * FROM ev_leaderboard', {}, function(result)
if result and result[1] then
return p:resolve(result)
else
return p:resolve({})
end
end)
local result = Citizen.Await(p)
for i = 1, #result, 1 do
playersData[result[i].license] = result[i]
end
end
end)
AddEventHandler('playerDropped', function()
local playerId <const> = source
local playerData = playersData[getLicense(playerId)]
if playerData then
exports.oxmysql:updateSync('UPDATE ev_leaderboard SET kills = ?, deaths = ?, headshots = ? WHERE license = ? ', {playerData.kills, playerData.deaths, playerData.headshots, playerData.license})
end
end)
RegisterNetEvent('ev:playerSet', function()
local playerId <const> = source
local license = getLicense(playerId)
local discordId = getDiscordId(playerId)
if license then
local playerData = playersData[license]
local name = getDiscordName(discordId)
local avatar = getPlayerFromDiscord(discordId)
if playerData then
return
end
local p = promise.new()
exports.oxmysql:insert('INSERT INTO ev_leaderboard (license, kills, deaths, headshots, avatar, name) VALUES (?, ?, ?, ?, ?, ?) ', {license, '0', '0', '0', avatar, name}, function(id)
if id then
p:resolve({license = license, kills = 0, deaths = 0, headshots = 0, avatar = avatar, name = name})
end
end)
local result = Citizen.Await(p)
playersData[result.license] = result
end
end)
RegisterNetEvent('ev:updateKillerData', function(data)
if data then
if type(data) ~= "table" then
return print('Sus')
else
if type(data[1]) ~= "string" and type(data[2]) ~= "string" and type(data[3]) == "number" then
return print('sus')
end
local playerId = tonumber(data[1])
local targetId = tonumber(data[2])
local headshot = tonumber(data[3]) == 31086 and 1 or 0
if playerId ~= targetId then
local playerData = playersData[getLicense(playerId)]
local targetData = playersData[getLicense(targetId)]
if playerData and targetData then
if playerData.license and targetData.license then
playerData.kills = playerData.kills + 1
targetData.deaths = targetData.deaths + 1
playerData.headshots = playerData.headshots + headshot
end
end
end
end
end
end)
RegisterCommand('score', function(source)
local playerId <const> = source
local playerData = playersData[getLicense(playerId)]
if playerData then
local kd = 1.0
if playerData.deaths > 0 then
kd = playerData.kills / playerData.deaths
end
TriggerClientEvent('ev:showLeaderboard', playerId, false, {avatar = playerData.avatar, discord = playerData.name, kills = playerData.kills, deaths = playerData.deaths, kd = kd, headshots = playerData.headshots})
end
end)
RegisterCommand('showLeaderboard', function(source)
local playerId <const> = source
local data = {}
for _, v in pairs(playersData) do
insert(data, {discord = v.avatar, kills = tonumber(v.kills), name = v.name})
end
sort(data, function(a, b)
return a.kills > b.kills
end)
TriggerClientEvent('ev:showLeaderboard', playerId, true, data)
end)
RegisterCommand('updateavatar', function(source, args)
local targetSource = tonumber(args[1])
local targetLicense = getLicense(targetSource)
local playerData = playersData[targetLicense]
if not playerData then
return print('Player not found')
end
local discordId = getDiscordId(targetSource)
local discordAvatar = getPlayerFromDiscord(discordId)
if not discordAvatar then
return print('Avatar not found')
end
playerData.avatar = discordAvatar
exports.oxmysql:updateSync('UPDATE ev_leaderboard SET avatar = ? WHERE license = ? ', {discordAvatar, targetLicense})
end, true)