├── Execute.sql
├── LICENSE
├── README.md
├── ban.json
├── client.lua
├── config.lua
├── fxmanifest.lua
├── server.lua
├── server_config.lua
└── web
├── css
└── style.css
├── fonts
└── proxima_nova.otf
├── img
├── admin_online.png
├── adminjail.png
├── announce.png
├── ban.png
├── banhistory.png
├── bg_color.png
├── bring.png
├── cleararea.png
├── clearinventory.png
├── clearped.png
├── copy.png
├── dashboard.png
├── freeze.png
├── giveadmin.png
├── giveitem.png
├── givemoney.png
├── goto.png
├── heal.png
├── invincible.png
├── invisibility.png
├── jailhistory.png
├── kick.png
├── kickhistory.png
├── kill.png
├── lista_ban.png
├── lista_player.png
├── logout.png
├── menu_personale.png
├── noclip.png
├── nomiplayer.png
├── player_online.png
├── repairveh.png
├── revive.png
├── reviveall.png
├── sendmessage.png
├── setjob.png
├── setped.png
├── skinmenu.png
├── spectate.png
├── total_ban.png
├── total_kick.png
├── warn.png
├── warnhistory.png
└── wipe.png
├── index.html
└── js
└── script.js
/Execute.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS `ricky_admin` (
2 | `identifier` varchar(46) NOT NULL,
3 | `warn` longtext DEFAULT NULL,
4 | `kick` longtext DEFAULT NULL,
5 | `ban` longtext DEFAULT NULL,
6 | `jail` longtext DEFAULT NULL,
7 | `inJail` int(11) DEFAULT 0,
8 | `jailCoords` longtext DEFAULT NULL,
9 | PRIMARY KEY (`identifier`)
10 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
11 |
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # **Nova Admin Menu**
2 | An advanced Admin Menu for your FiveM server, intuitive interface with tools for full management of your server.
3 | [Support](https://discord.gg/HNhCsR9cHU)
4 |
5 |
6 |
7 |
8 | ## **Dependencies**
9 | - oxmysql
10 | - esx
11 |
12 | ## **Features**
13 | - Custom UI
14 | - 20+ Action
15 | - Configurable
16 | - Discord Logs
17 | - Optimized (0.0ms idle)
18 |
19 | ## **Installation**
20 | 1. Download / Clone Admin Menu
21 | 2. Insert Admin Menu in server resources
22 | 3. Execute SQL
23 | 4. Set up config.lua and server_config.lua
24 | 5. Put `ensure nova_adminmenu` in `server.cfg`
25 | 6. Start the server
26 |
--------------------------------------------------------------------------------
/ban.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "reason": "yest",
4 | "labelScadenza": "17/08/2023 18:18:32",
5 | "ip": "109.115.117.198",
6 | "name": "Top G",
7 | "xbl": "2535410314708963",
8 | "identifier": "char1:fbfc8d25e2e89ece995cdd8c7147bfb58082f34f",
9 | "dataBan": "16/08/2023 18:18:32",
10 | "license": "fbfc8d25e2e89ece995cdd8c7147bfb58082f34f",
11 | "idBan": 23357,
12 | "valido": false,
13 | "discord": "754332358848807012",
14 | "liveid": "844425555339879",
15 | "staff": {
16 | "name": "Top G",
17 | "identifier": "fbfc8d25e2e89ece995cdd8c7147bfb58082f34f"
18 | },
19 | "time": 1692289112
20 | }
21 | ]
--------------------------------------------------------------------------------
/client.lua:
--------------------------------------------------------------------------------
1 | -- Attento a quello che tocchi
2 | -- Nova Scripts
3 |
4 | local ESX = exports.es_extended:getSharedObject()
5 | local inJail = false
6 | local setJailCoords = false
7 | local spectating = false
8 | local idSpectate = 0
9 | local nomiTesta = false
10 |
11 |
12 | Citizen.CreateThread(function()
13 | while ESX.IsPlayerLoaded() == false do
14 | Citizen.Wait(100)
15 | end
16 | local jail = nil
17 | ESX.TriggerServerCallback('ricky-admin:getInJail', function(jail1)
18 | jail = jail1
19 | end)
20 | while jail == nil do
21 | Citizen.Wait(0)
22 | end
23 | inJail = jail
24 | if inJail then
25 | setJailCoords = true
26 | end
27 | end)
28 |
29 | RegisterCommand(Config.CommandName, function(source, args, rawCommand)
30 | if SonoStaff() == false then return end
31 | OpenAdminMenu()
32 | end)
33 |
34 | if Config.Keybinds.adminmenu.enable then
35 | RegisterKeyMapping(Config.CommandName, 'Admin Menu', 'keyboard', Config.Keybinds.adminmenu.key)
36 | end
37 |
38 | if Config.Keybinds.nomitesta.enable then
39 | RegisterKeyMapping('-+nomitesta', 'Nomi Sopra la Testa', 'keyboard', Config.Keybinds.nomitesta.key)
40 | TriggerEvent('chat:removeSuggestion', '/-+nomitesta')
41 | RegisterCommand('-+nomitesta', function(source, args, rawCommand)
42 | if SonoStaff() == false then return end
43 | nomiTesta = not nomiTesta
44 | if nomiTesta then
45 | ESX.ShowNotification(Config.Lang[Config.Language]["nomitesta_a"])
46 | fields = {
47 | {
48 | name = Config.Lang[Config.Language]['nome_staff'],
49 | value = GetPlayerName(PlayerId()),
50 | inline = true
51 | },
52 | {
53 | name = Config.Lang[Config.Language]["stato_nomitesta"],
54 | value = Config.Lang[Config.Language]["attivo"],
55 | inline = true
56 | },
57 | }
58 | else
59 | ESX.ShowNotification(Config.Lang[Config.Language]["nomitesta_b"])
60 | fields = {
61 | {
62 | name = Config.Lang[Config.Language]['nome_staff'],
63 | value = GetPlayerName(PlayerId()),
64 | inline = true
65 | },
66 | {
67 | name = Config.Lang[Config.Language]["stato_nomitesta"],
68 | value = Config.Lang[Config.Language]["inattivo"],
69 | inline = true
70 | },
71 | }
72 | end
73 |
74 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["nomitesta"], fields, "nomiplayer")
75 | end)
76 | end
77 |
78 | RegisterNUICallback('deletewarn', function(data)
79 | local id = data.id
80 | local index = data.index
81 | ESX.ShowNotification(Config.Lang[Config.Language]["delete_warn"])
82 | TriggerServerEvent('ricky-admin:deletewarn', id, index)
83 | end)
84 |
85 | SonoStaff = function()
86 | local staff1 = nil
87 | ESX.TriggerServerCallback('ricky-admin:sonoStaff', function(staff)
88 | staff1 = staff
89 | end)
90 | while staff1 == nil do
91 | Citizen.Wait(0)
92 | end
93 | return staff1
94 | end
95 |
96 | postMessage = function(data)
97 | SendNUIMessage(data)
98 | end
99 |
100 | CreateThread(function()
101 | while true do
102 | ESX.TriggerServerCallback('ricky-admin:getPlayers', function(t)
103 | players = t
104 | end)
105 | postMessage({
106 | type = "UPDATE_PLAYERS",
107 | players = players
108 | })
109 | Wait(5000)
110 | end
111 | end)
112 |
113 | OpenAdminMenu = function()
114 | ESX.TriggerServerCallback('ricky-admin:getPlayers', function(t)
115 | ESX.TriggerServerCallback('ricky-admin:getData', function(data)
116 | if SonoStaff() == false then return end
117 | SetNuiFocus(true, true)
118 | players = t
119 | postMessage({
120 | type = "SET_RADIUS",
121 | radius = Config.ClearAreaRadius
122 | })
123 | postMessage({
124 | type = "SET_ADMIN_ONLINE",
125 | admin = data.adminOnline
126 | })
127 | postMessage({
128 | type = "SET_KICKS",
129 | kicks = data.kicks
130 | })
131 | postMessage({
132 | type = "SET_CONFIG",
133 | config = Config
134 | })
135 | postMessage({
136 | type = "SET_BAN",
137 | ban = data.bans
138 | })
139 | postMessage({
140 | type = "SET_INFO_STAFF",
141 | info = data.infoStaff
142 | })
143 | postMessage({
144 | type = "SET_JOBS",
145 | jobs = data.jobs
146 | })
147 | postMessage({
148 | type = "SET_ADMIN_GROUPS",
149 | groups = Config.AdminGroup
150 | })
151 | postMessage({
152 | type = "SET_ORARIO",
153 | orario = data.orario
154 | })
155 | postMessage({
156 | type = "SET_AZIONI",
157 | azioni = Config.Azioni
158 | })
159 | postMessage({
160 | type = "SET_AZIONI_PERSONALE",
161 | azioni = Config.AzioniPersonale
162 | })
163 | postMessage({
164 | type = "OPEN",
165 | players = players
166 | })
167 | postMessage({
168 | type = "SET_SERVER_LOGO",
169 | logo = Config.LogoServer
170 | })
171 | end)
172 | end)
173 | end
174 |
175 | RegisterNUICallback('close', function(data, cb)
176 | SetNuiFocus(false, false)
177 | end)
178 |
179 | RegisterNUICallback('skinmenu', function(data, cb)
180 | local id = data.id
181 | TriggerServerEvent('ricky-admin:skinmenu', id)
182 | end)
183 |
184 | local lastCoords = nil
185 | local lastHeading = nil
186 | RegisterNUICallback('spectate', function(data)
187 | idSpectate = tonumber(data.id)
188 | SetNuiFocus(false, false)
189 | lastCoords = GetEntityCoords(PlayerPedId())
190 | lastHeading = GetEntityHeading(PlayerPedId())
191 | spectating = true
192 | ESX.ShowHelpNotification(Config.Lang[Config.Language]['esci_spectate'])
193 | local fields = {
194 | {
195 | name = Config.Lang[Config.Language]['nome_staff'],
196 | value = GetPlayerName(PlayerId()),
197 | inline = true
198 | },
199 | {
200 | name = Config.Lang[Config.Language]["nome_player"],
201 | value = GetPlayerName(GetPlayerFromServerId(idSpectate)),
202 | inline = true
203 | },
204 | }
205 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["inizio_spectate"], fields, "spectate")
206 | end)
207 |
208 | RegisterNetEvent('ricky-admin:dm')
209 | AddEventHandler('ricky-admin:dm', function(text)
210 | SendDMMessage(text)
211 | end)
212 |
213 | RegisterNUICallback('repairvehicle', function()
214 | local veh = GetVehiclePedIsIn(PlayerPedId(), false)
215 | if veh ~= 0 then
216 | SetVehicleFixed(veh)
217 | SetVehicleDirtLevel(veh, 0.0)
218 | local fields = {
219 | {
220 | name = Config.Lang[Config.Language]['nome_staff'],
221 | value = GetPlayerName(PlayerId()),
222 | inline = true
223 | },
224 | {
225 | name = Config.Lang[Config.Language]["veicolo"],
226 | value = GetDisplayNameFromVehicleModel(GetEntityModel(veh)),
227 | inline = true
228 | },
229 | }
230 |
231 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["ripara_veicolo"], fields, "repairvehicle")
232 | ESX.ShowNotification(Config.Lang[Config.Language]["repair_vehicle2"])
233 | end
234 | end)
235 |
236 | RegisterNetEvent('ricky-admin:cleararea')
237 | AddEventHandler('ricky-admin:cleararea', function(radius)
238 | local ped = PlayerPedId()
239 | local pos = GetEntityCoords(ped)
240 | local vehicles = ESX.Game.GetVehiclesInArea(pos, tonumber(radius))
241 | for k,v in pairs(vehicles) do
242 | ESX.Game.DeleteVehicle(v)
243 | end
244 |
245 | ClearAreaOfVehicles(pos.x, pos.y, pos.z, radius, false, false, false, false, false)
246 | ClearAreaOfPeds(pos.x, pos.y, pos.z, radius, 1)
247 | ClearAreaOfObjects(pos.x, pos.y, pos.z, radius, 1)
248 | ClearAreaOfCops(pos.x, pos.y, pos.z, radius, 1)
249 | ClearAreaOfProjectiles(pos.x, pos.y, pos.z, radius, 1)
250 | ClearAreaOfEverything(pos.x, pos.y, pos.z, radius, 1)
251 |
252 |
253 | local fields = {
254 | {
255 | name = Config.Lang[Config.Language]['nome_staff'],
256 | value = GetPlayerName(PlayerId()),
257 | inline = true
258 | }
259 | }
260 |
261 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["clear_area"], fields, "cleararea")
262 | ESX.ShowNotification(Config.Lang[Config.Language]["clear_area2"])
263 | end)
264 |
265 | RegisterNUICallback('clearped', function(data)
266 | local id = data.id
267 | TriggerServerEvent('ricky-admin:clearped', id)
268 | ESX.ShowNotification(Config.Lang[Config.Language]["clear_ped2"])
269 | end)
270 |
271 | RegisterNetEvent('ricky-admin:clearped')
272 | AddEventHandler('ricky-admin:clearped', function()
273 | local ped = PlayerPedId()
274 | ClearPedTasksImmediately(ped)
275 | ClearPedBloodDamage(ped)
276 | ESX.ShowNotification(Config.Lang[Config.Language]["clear_ped"])
277 | end)
278 |
279 | Citizen.CreateThread(function()
280 | while true do
281 | if spectating then
282 | Wait(0)
283 | if IsControlJustPressed(0, 38) then
284 | spectating = false
285 | postMessage({
286 | type = "RESUME"
287 | })
288 | SetNuiFocus(true, true)
289 | NetworkSetInSpectatorMode(false, PlayerPedId())
290 | DetachEntity(PlayerPedId(), true, true)
291 | SetEntityVisible(PlayerPedId(), true, 0)
292 | SetEntityCoords(PlayerPedId(), lastCoords)
293 | SetEntityHeading(PlayerPedId(), lastHeading)
294 | local fields = {
295 | {
296 | name = Config.Lang[Config.Language]['nome_staff'],
297 | value = GetPlayerName(PlayerId()),
298 | inline = true
299 | },
300 | {
301 | name = Config.Lang[Config.Language]["nome_player"],
302 | value = GetPlayerName(GetPlayerFromServerId(idSpectate)),
303 | inline = true
304 | },
305 | }
306 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["fine_spectate"], fields, "spectate")
307 | end
308 | ESX.TriggerServerCallback('ricky-admin:getCoordsPlayer', function(coords, coords2)
309 | if not spectating then return end
310 | SetEntityVisible(PlayerPedId(), false, 0)
311 | AttachEntityToEntity(PlayerPedId(), GetPlayerPed(GetPlayerFromServerId(idSpectate)), 4103, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, false, false, true, false, 0, true)
312 | SetEntityCoords(PlayerPedId(), coords2.x, coords2.y, coords2.z)
313 | NetworkSetInSpectatorMode(true, GetPlayerPed(GetPlayerFromServerId(idSpectate)))
314 | end, idSpectate)
315 | else
316 | Wait(1000)
317 | end
318 |
319 | end
320 | end)
321 |
322 | RegisterNUICallback('unjail', function(data, cb)
323 | local id = data.id
324 | TriggerServerEvent('ricky-admin:unjail', id)
325 | end)
326 |
327 | function getCamDirection()
328 | local heading = GetGameplayCamRelativeHeading() + GetEntityPhysicsHeading(plyPed)
329 | local pitch = GetGameplayCamRelativePitch()
330 | local coords = vector3(-math.sin(heading * math.pi / 180.0), math.cos(heading * math.pi / 180.0), math.sin(pitch * math.pi / 180.0))
331 | local len = math.sqrt((coords.x * coords.x) + (coords.y * coords.y) + (coords.z * coords.z))
332 |
333 | if len ~= 0 then
334 | coords = coords / len
335 | end
336 |
337 | return coords
338 | end
339 |
340 |
341 | local noclipEnabled = false
342 |
343 | Citizen.CreateThread(function()
344 | while true do
345 | if noclipEnabled then
346 | Wait(0)
347 | local playerCoords = GetEntityCoords(PlayerPedId(), false)
348 | local camCoords = direzione_cam()
349 | SetEntityVelocity(PlayerPedId(), 0.01, 0.01, 0.01)
350 |
351 | if IsControlPressed(0, 32) then
352 | playerCoords = playerCoords + (1.0 * camCoords)
353 | end
354 |
355 | if IsControlPressed(0, 269) then
356 | playerCoords = playerCoords - (1.0 * camCoords)
357 | end
358 |
359 | SetEntityCoordsNoOffset(PlayerPedId(), playerCoords, true, true, true)
360 | else
361 | Wait(1000)
362 | end
363 | end
364 | end)
365 |
366 | direzione_cam = function()
367 | local heading = GetGameplayCamRelativeHeading() + GetEntityPhysicsHeading(PlayerPedId())
368 | local pitch = GetGameplayCamRelativePitch()
369 | local coords = vector3(-math.sin(heading * math.pi / 180.0), math.cos(heading * math.pi / 180.0), math.sin(pitch * math.pi / 180.0))
370 | local len = math.sqrt((coords.x * coords.x) + (coords.y * coords.y) + (coords.z * coords.z))
371 |
372 | if len ~= 0 then
373 | coords = coords / len
374 | end
375 | return coords
376 | end
377 |
378 |
379 | RegisterNUICallback('heal', function(data, cb)
380 | local id = data.id
381 | TriggerServerEvent('ricky-admin:heal', id)
382 | ESX.ShowNotification(Config.Lang[Config.Language]['heal'])
383 | end)
384 |
385 | RegisterNUICallback('revive', function(data, cb)
386 | local id = data.id
387 | TriggerServerEvent('ricky-admin:revive', id)
388 | ESX.ShowNotification(Config.Lang[Config.Language]['revive'])
389 | end)
390 |
391 | RegisterCommand('noclip', function(source, args, rawCommand)
392 | if SonoStaff() == false then return end
393 | noclipEnabled = not noclipEnabled
394 | local ped = PlayerPedId()
395 | if noclipEnabled then
396 | ESX.ShowNotification(Config.Lang[Config.Language]['noclip_attivato'])
397 | ESX.ShowHelpNotification(Config.Lang[Config.Language]['exit_noclip'])
398 | FreezeEntityPosition(ped, true)
399 | SetEntityInvincible(ped, true)
400 | SetEntityCollision(ped, false, false)
401 | SetEntityVisible(ped, false, false)
402 | SetEveryoneIgnorePlayer(PlayerId(), true)
403 | SetPoliceIgnorePlayer(PlayerId(), true)
404 | local fields = {
405 | {
406 | name = Config.Lang[Config.Language]['nome_staff'],
407 | value = GetPlayerName(PlayerId()),
408 | inline = true
409 | },
410 | {
411 | name = Config.Lang[Config.Language]["stato_noclip"],
412 | value = Config.Lang[Config.Language]["attivo"],
413 | inline = true
414 | },
415 | }
416 | TriggerServerEvent('ricky-admin:webhook', 'NoClip', fields, "noclip")
417 | else
418 | ESX.ShowNotification(Config.Lang[Config.Language]['noclip_disattivato'])
419 | FreezeEntityPosition(ped, false)
420 | SetEntityInvincible(ped, false)
421 | SetEntityCollision(ped, true, true)
422 | SetEntityVisible(ped, true, false)
423 | SetEveryoneIgnorePlayer(PlayerId(), false)
424 | SetPoliceIgnorePlayer(PlayerId(), false)
425 | local fields = {
426 | {
427 | name = Config.Lang[Config.Language]['nome_staff'],
428 | value = GetPlayerName(PlayerId()),
429 | inline = true
430 | },
431 | {
432 | name = Config.Lang[Config.Language]["stato_noclip"],
433 | value = Config.Lang[Config.Language]["inattivo"],
434 | inline = true
435 | },
436 | }
437 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["noclip"], fields, "noclip")
438 | end
439 | end)
440 |
441 | if Config.Keybinds.noclip.enable then
442 | RegisterKeyMapping('noclip', 'Noclip', 'keyboard', Config.Keybinds.noclip.key)
443 | end
444 |
445 | RegisterNUICallback('noclip', function(data, cb)
446 | SetNuiFocus(false, false)
447 | ExecuteCommand('noclip')
448 | end)
449 |
450 | RegisterNUICallback('revocaban', function(data)
451 | local id = data.id
452 | TriggerServerEvent('ricky-admin:revocaban', GetPlayerServerId(PlayerId()), id)
453 | ESX.ShowNotification(Config.Lang[Config.Language]['revoca_ban'])
454 | end)
455 |
456 | RegisterNUICallback('kill', function(data, cb)
457 | local id = data.id
458 | TriggerServerEvent('ricky-admin:kill', id)
459 | ESX.ShowNotification(Config.Lang[Config.Language]['kill'])
460 | end)
461 |
462 | RegisterNUICallback('goto', function(data, cb)
463 | local id = data.id
464 | TriggerServerEvent('ricky-admin:goto', id)
465 | end)
466 |
467 | RegisterNUICallback('bring', function(data, cb)
468 | local id = data.id
469 | TriggerServerEvent('ricky-admin:bring', id)
470 | end)
471 |
472 | RegisterNUICallback('wipe', function(data, cb)
473 | local id = data.id
474 | TriggerServerEvent('ricky-admin:wipe', id)
475 | ESX.ShowNotification(Config.Lang[Config.Language]['wipe'])
476 | end)
477 |
478 | RegisterNUICallback('clearinv', function(data, cb)
479 | local id = data.id
480 | TriggerServerEvent('ricky-admin:clearInv', id)
481 | ESX.ShowNotification(Config.Lang[Config.Language]['clear_inv2'])
482 | end)
483 |
484 | RegisterNetEvent('ricky-admin:kill')
485 | AddEventHandler('ricky-admin:kill', function()
486 | local ped = PlayerPedId()
487 | SetEntityHealth(ped, 0)
488 | end)
489 |
490 | RegisterNUICallback('action', function(data, cb)
491 | TriggerServerEvent('ricky-admin:action', data)
492 | end)
493 |
494 | RegisterNetEvent('ricky-admin:updatePlayers')
495 | AddEventHandler('ricky-admin:updatePlayers', function()
496 | ESX.TriggerServerCallback('ricky-admin:getPlayers', function(players)
497 | ESX.TriggerServerCallback('ricky-admin:getData', function(data)
498 | if SonoStaff() == false then return end
499 | postMessage({
500 | type = "UPDATE_PLAYERS",
501 | players = players
502 | })
503 |
504 | postMessage({
505 | type = "SET_BAN",
506 | ban = data.bans
507 | })
508 |
509 | postMessage({
510 | type = "SET_INFO_STAFF",
511 | info = data.infoStaff
512 | })
513 |
514 | end)
515 | end)
516 | end)
517 |
518 | RegisterNetEvent('ricky-admin:setped')
519 | AddEventHandler('ricky-admin:setped', function(model)
520 | if IsModelInCdimage(model) and IsModelValid(model) then
521 | RequestModel(model)
522 | while not HasModelLoaded(model) do
523 | Citizen.Wait(0)
524 | end
525 | SetPlayerModel(PlayerId(), model)
526 | SetModelAsNoLongerNeeded(model)
527 | end
528 | end)
529 |
530 | RegisterNetEvent('ricky-admin:resetped')
531 | AddEventHandler('ricky-admin:resetped', function()
532 | local maschio = 'mp_m_freemode_01'
533 | local femmina = 'mp_f_reemode_01'
534 | TriggerEvent('skinchanger:getSkin', function(skin)
535 | if skin.sex == 0 then
536 | RequestModel(maschio)
537 | while not HasModelLoaded(maschio) do
538 | Citizen.Wait(0)
539 | end
540 | SetPlayerModel(PlayerId(), maschio)
541 | TriggerEvent('skinchanger:getSkin', function(skin)
542 | TriggerEvent('skinchanger:loadSkin', skin)
543 | end)
544 | else
545 | RequestModel(femmina)
546 | while not HasModelLoaded(femmina) do
547 | Citizen.Wait(0)
548 | end
549 | SetPlayerModel(PlayerId(), femmina)
550 | TriggerEvent('skinchanger:getSkin', function(skin)
551 | TriggerEvent('skinchanger:loadSkin', skin)
552 | end)
553 | end
554 | end)
555 | end)
556 |
557 | RegisterNetEvent('ricky-admin:adminjail')
558 | AddEventHandler('ricky-admin:adminjail', function()
559 | inJail = true
560 | setJailCoords = true
561 | end)
562 |
563 | Citizen.CreateThread(function()
564 | while true do
565 | if inJail then
566 | Wait(0)
567 | local ped = PlayerPedId()
568 | FreezeEntityPosition(ped, true)
569 | if setJailCoords then
570 | SetEntityCoords(ped, Config.AdminJailCoords)
571 | end
572 | DisableAllControlActions(0)
573 | else
574 | Wait(1000)
575 | end
576 | end
577 | end)
578 |
579 |
580 |
581 | RegisterNetEvent('ricky-admin:unjail')
582 | AddEventHandler('ricky-admin:unjail', function()
583 | local ped = PlayerPedId()
584 | setJailCoords = false
585 | inJail = false
586 | Wait(1000)
587 | FreezeEntityPosition(ped, false)
588 | end)
589 |
590 | RegisterNUICallback('freeze', function(data)
591 | local id = tonumber(data.id)
592 | TriggerServerEvent('ricky-admin:freeze', id)
593 | end)
594 |
595 | RegisterNUICallback('sfreeze', function(data)
596 | local id = tonumber(data.id)
597 | TriggerServerEvent('ricky-admin:sfreeze', id)
598 | end)
599 |
600 | RegisterNetEvent('ricky-admin:freeze')
601 | AddEventHandler('ricky-admin:freeze', function()
602 | FreezeEntityPosition(PlayerPedId(), true)
603 | end)
604 |
605 | RegisterNetEvent('ricky-admin:sfreeze')
606 | AddEventHandler('ricky-admin:sfreeze', function()
607 | FreezeEntityPosition(PlayerPedId(), false)
608 | end)
609 |
610 | local invisible = false
611 | RegisterNUICallback('invisibilita', function()
612 | invisible = not invisible
613 | SetNuiFocus(false, false)
614 | if not invisible then
615 | ESX.ShowNotification(Config.Lang[Config.Language]['invisibilita_b'])
616 | SetEntityVisible(PlayerPedId(), true, 0)
617 | fields = {
618 | {
619 | name = Config.Lang[Config.Language]['nome_staff'],
620 | value = GetPlayerName(PlayerId()),
621 | inline = true
622 | },
623 | {
624 | name = Config.Lang[Config.Language]["stato_invisible"],
625 | value = Config.Lang[Config.Language]["inattivo"],
626 | inline = true
627 | },
628 | }
629 | else
630 | ESX.ShowNotification(Config.Lang[Config.Language]['invisibilita_a'])
631 | SetEntityVisible(PlayerPedId(), false, 0)
632 | fields = {
633 | {
634 | name = Config.Lang[Config.Language]['nome_staff'],
635 | value = GetPlayerName(PlayerId()),
636 | inline = true
637 | },
638 | {
639 | name = Config.Lang[Config.Language]["stato_invisible"],
640 | value = Config.Lang[Config.Language]["attivo"],
641 | inline = true
642 | },
643 | }
644 | end
645 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["invisibilita"], fields, "invisibilita")
646 | end)
647 |
648 | local godmode = false
649 | RegisterNUICallback('godmode', function()
650 | godmode = not godmode
651 | if godmode then
652 | ESX.ShowNotification(Config.Lang[Config.Language]['godmode_a'])
653 | fields = {
654 | {
655 | name = Config.Lang[Config.Language]['nome_staff'],
656 | value = GetPlayerName(PlayerId()),
657 | inline = true
658 | },
659 | {
660 | name = Config.Lang[Config.Language]["stato_godmode"],
661 | value = Config.Lang[Config.Language]["attivo"],
662 | inline = true
663 | },
664 | }
665 | else
666 | ESX.ShowNotification(Config.Lang[Config.Language]['godmode_b'])
667 | fields = {
668 | {
669 | name = Config.Lang[Config.Language]['nome_staff'],
670 | value = GetPlayerName(PlayerId()),
671 | inline = true
672 | },
673 | {
674 | name = Config.Lang[Config.Language]["stato_godmode"],
675 | value = Config.Lang[Config.Language]["inattivo"],
676 | inline = true
677 | },
678 | }
679 | end
680 |
681 | TriggerServerEvent('ricky-admin:webhook', "Godmode", fields, "godmode")
682 | SetNuiFocus(false, false)
683 | end)
684 |
685 | RegisterNUICallback('reviveall', function(data, cb)
686 | SetNuiFocus(false, false)
687 | TriggerServerEvent('ricky-admin:reviveall')
688 | ESX.ShowNotification(Config.Lang[Config.Language]['revive_all'])
689 | end)
690 |
691 | RegisterNetEvent('ricky-admin:announce')
692 | AddEventHandler('ricky-admin:announce', function(text)
693 | Announce(text)
694 | end)
695 |
696 | Citizen.CreateThread(function()
697 | while true do
698 | if godmode then
699 | Wait(0)
700 | SetEntityInvincible(PlayerPedId(), true)
701 | else
702 | Wait(1000)
703 | SetEntityInvincible(PlayerPedId(), false)
704 | end
705 | end
706 | end)
707 |
708 | -- Citizen.CreateThread(function()
709 | -- while true do
710 | -- if invisible or noclipEnabled then
711 | -- Wait(0)
712 | -- SetEntityVisible(PlayerPedId(), false, 0)
713 | -- else
714 | -- Wait(1000)
715 | -- SetEntityVisible(PlayerPedId(), true, 0)
716 | -- end
717 | -- end
718 | -- end)
719 |
720 | Citizen.CreateThread(function()
721 | while true do
722 | Citizen.Wait(1000)
723 | TriggerServerEvent('ricky-admin:addvariable', 'freeze', IsEntityPositionFrozen(PlayerPedId()))
724 | ESX.TriggerServerCallback('ricky-admin:getOrario', function(orario)
725 | postMessage({
726 | type = "SET_ORARIO",
727 | orario = orario
728 | })
729 | end)
730 | end
731 | end)
732 |
733 | DrawText3D = function(x,y,z, text)
734 | local onScreen,_x,_y=World3dToScreen2d(x,y,z)
735 | local px,py,pz=table.unpack(GetGameplayCamCoords())
736 | local dist = GetDistanceBetweenCoords(px,py,pz, x,y,z, 1)
737 | local scale = (1/dist)*2
738 | local fov = (1/GetGameplayCamFov())*100
739 | local scale = scale*fov
740 | if onScreen then
741 | SetTextScale(0.0*scale, 0.55*scale)
742 | SetTextFont(4)
743 | SetTextProportional(1)
744 | SetTextColour(255, 255, 255, 215)
745 | SetTextDropshadow(0, 0, 0, 0, 255)
746 | SetTextEdge(2, 0, 0, 0, 150)
747 | SetTextDropShadow()
748 | SetTextOutline()
749 | SetTextEntry("STRING")
750 | SetTextCentre(1)
751 | AddTextComponentString(text)
752 | DrawText(_x,_y)
753 | end
754 | end
755 |
756 | RegisterNUICallback('nomiplayer', function()
757 | nomiTesta = not nomiTesta
758 | if nomiTesta then
759 | ESX.ShowNotification(Config.Lang[Config.Language]["nomitesta_a"])
760 | fields = {
761 | {
762 | name = Config.Lang[Config.Language]['nome_staff'],
763 | value = GetPlayerName(PlayerId()),
764 | inline = true
765 | },
766 | {
767 | name = Config.Lang[Config.Language]["stato_nomitesta"],
768 | value = Config.Lang[Config.Language]["attivo"],
769 | inline = true
770 | },
771 | }
772 | else
773 | ESX.ShowNotification(Config.Lang[Config.Language]["nomitesta_b"])
774 | fields = {
775 | {
776 | name = Config.Lang[Config.Language]['nome_staff'],
777 | value = GetPlayerName(PlayerId()),
778 | inline = true
779 | },
780 | {
781 | name = Config.Lang[Config.Language]["stato_nomitesta"],
782 | value = Config.Lang[Config.Language]["inattivo"],
783 | inline = true
784 | },
785 | }
786 | end
787 |
788 | TriggerServerEvent('ricky-admin:webhook', Config.Lang[Config.Language]["nomitesta"], fields, "nomiplayer")
789 | end)
790 |
791 | Citizen.CreateThread(function()
792 | while true do
793 | if nomiTesta then
794 | Wait(0)
795 | for k,v in pairs(GetActivePlayers()) do
796 | if NetworkIsPlayerActive(v) then
797 | local ped = GetPlayerPed(v)
798 | local coords = GetEntityCoords(ped)
799 | if IsPedInAnyVehicle(ped, false) then
800 | DrawText3D(coords.x, coords.y, coords.z + 1.5, GetPlayerName(v).." | Vita: "..GetEntityHealth(ped).." | ID: "..GetPlayerServerId(v))
801 | else
802 | DrawText3D(coords.x, coords.y, coords.z + 1.0, GetPlayerName(v).." | Vita: "..GetEntityHealth(ped).." | ID: "..GetPlayerServerId(v))
803 | end
804 | end
805 | end
806 | else
807 | Wait(1000)
808 | end
809 | end
810 | end)
811 |
--------------------------------------------------------------------------------
/config.lua:
--------------------------------------------------------------------------------
1 | Config = {}
2 |
3 | Config.NomeServer = "Nova Scripts"
4 |
5 | Config.LogoServer = "https://cdn.discordapp.com/attachments/944572269202640946/1140062557068075028/nova.png"
6 |
7 | Config.DiscordServer = "https://discord.gg/tHAbhd94vS"
8 |
9 | Config.Language = "it"
10 |
11 | Config.AdminJailCoords = vector3(1641.6, 2571.0, 44.5)
12 |
13 | Config.GroupUser = 'user'
14 |
15 | Config.CommandName = 'admin'
16 |
17 | Config.Keybinds = {
18 | adminmenu = {
19 | enable = true,
20 | key = 'M'
21 | },
22 | noclip = {
23 | enable = true,
24 | key = 'HOME'
25 | },
26 | nomitesta = {
27 | enable = true,
28 | key = 'F9'
29 | },
30 | }
31 |
32 |
33 | Config.AdminGroup = {
34 |
35 | -- ['GROUP_NAME'] = {
36 | -- rank = 0,
37 | -- label = "GROUP_LABEL",
38 | -- id = "GROUP_ID",
39 | -- }
40 |
41 | ['helper'] = {
42 | rank = 1,
43 | label = "Helper",
44 | id = "helper",
45 | },
46 | ['mod'] = {
47 | rank = 2,
48 | label = "Moderatore",
49 | id = "mod",
50 | },
51 | ['admin'] = {
52 | rank = 3,
53 | label = "Admin",
54 | id = "admin",
55 | },
56 | ['superadmin'] = {
57 | rank = 4,
58 | label = "Super Admin",
59 | id = "superadmin",
60 | },
61 | ['owner'] = {
62 | rank = 5,
63 | label = "Owner",
64 | id = "owner",
65 | }
66 | }
67 |
68 | Config.ClearAreaRadius = {
69 | {
70 | label = "100",
71 | value = 100
72 | },
73 | {
74 | label = "250",
75 | value = 250
76 | },
77 | {
78 | label = "500",
79 | value = 500
80 | }
81 | }
82 |
83 | Config.Trigger = {
84 | skin = 'esx_skin:openSaveableMenu',
85 | revive = "esx_ambulancejob:revive",
86 | heal = "esx_basicneeds:healPlayer",
87 | }
88 |
89 | Config.WipeSettings = { -- !!
90 |
91 | -- [TABLE_NAME] = {
92 | -- COLUMN_NAME
93 | -- }
94 |
95 | ['identifier'] = {
96 | 'users'
97 | }
98 | }
99 |
100 | Config.BanTime = {
101 | {
102 | label = "12 Ore",
103 | value = 43200
104 | },
105 | {
106 | label = "1 Giorno",
107 | value = 86400
108 | },
109 | {
110 | label = "2 Giorni",
111 | value = 172800
112 | },
113 | {
114 | label = "3 Giorni",
115 | value = 259200
116 | },
117 | {
118 | label = "1 Settimana",
119 | value = 604800
120 | },
121 | {
122 | label = "2 Settimane",
123 | value = 1209600
124 | },
125 | {
126 | label = "Permanente",
127 | value = 999999999
128 | }
129 | }
130 |
131 |
132 | -- Non modificare l'id delle azioni
133 | Config.Azioni = {
134 | {
135 | label = 'Ban',
136 | id = 'ban',
137 | image = 'ban.png',
138 | rank = 1 -- Grado minimo
139 | },
140 | {
141 | label = 'Kick',
142 | id = 'kick',
143 | image = 'kick.png',
144 | rank = 1
145 | },
146 | {
147 | label = 'Admin Jail',
148 | id = 'adminjail',
149 | image = 'adminjail.png',
150 | rank = 1
151 | },
152 | {
153 | label = 'Warn',
154 | id = 'warn',
155 | image = 'warn.png',
156 | rank = 1
157 | },
158 | {
159 | label = 'Skin Menu',
160 | id = 'skinmenu',
161 | image = 'skinmenu.png',
162 | rank = 1
163 | },
164 | {
165 | label = 'Spectate',
166 | id = 'spectate',
167 | image = 'spectate.png',
168 | rank = 1
169 | },
170 | {
171 | label = 'Revive',
172 | id = 'revive',
173 | image = 'revive.png',
174 | rank = 1
175 | },
176 | {
177 | label = 'Heal',
178 | id = 'heal',
179 | image = 'heal.png',
180 | rank = 1
181 | },
182 | {
183 | label = 'Kill',
184 | id = 'kill',
185 | image = 'kill.png',
186 | rank = 1
187 | },
188 | {
189 | label = 'Wipe',
190 | id = 'wipe',
191 | image = 'wipe.png',
192 | rank = 1
193 | },
194 | {
195 | label = 'Go To',
196 | id = 'goto',
197 | image = 'goto.png',
198 | rank = 1
199 | },
200 | {
201 | label = 'Bring',
202 | id = 'bring',
203 | image = 'bring.png',
204 | rank = 1
205 | },
206 | {
207 | label = 'Give Item',
208 | id = 'giveitem',
209 | image = 'giveitem.png',
210 | rank = 1
211 | },
212 | {
213 | label = 'Give Money',
214 | id = 'givemoney',
215 | image = 'givemoney.png',
216 | rank = 1
217 | },
218 | {
219 | label = 'Set Job',
220 | id = 'setjob',
221 | image = 'setjob.png',
222 | rank = 1
223 | },
224 | {
225 | label = 'Clear Inv.',
226 | id = 'clearinventory',
227 | image = 'clearinventory.png',
228 | rank = 1
229 | },
230 | {
231 | label = 'Give Admin',
232 | id = 'giveadmin',
233 | image = 'giveadmin.png',
234 | rank = 1
235 | },
236 | {
237 | label = 'Clear Ped',
238 | id = 'clearped',
239 | image = 'clearped.png',
240 | rank = 1
241 | },
242 | {
243 | label = 'DM',
244 | id = 'sendmessage',
245 | image = 'sendmessage.png',
246 | rank = 1
247 | },
248 | {
249 | label = 'Freeze',
250 | id = 'freeze',
251 | image = 'freeze.png',
252 | rank = 1
253 | }
254 | }
255 |
256 | -- Non modificare l'id delle azioni
257 | Config.AzioniPersonale = {
258 | {
259 | label = 'Revive',
260 | id = 'revive',
261 | image = 'revive.png',
262 | rank = 1
263 | },
264 | {
265 | label = 'Heal',
266 | id = 'heal',
267 | image = 'heal.png',
268 | rank = 1
269 | },
270 | {
271 | label = 'NoClip',
272 | id = 'noclip',
273 | image = 'noclip.png',
274 | rank = 1
275 | },
276 | {
277 | label = "Invisibilità",
278 | id = 'invisibilita',
279 | image = 'invisibility.png',
280 | rank = 1
281 | },
282 | {
283 | label = "God Mode",
284 | id = 'godmode',
285 | image = 'invincible.png',
286 | rank = 1
287 | },
288 | {
289 | label = "Nomi Player",
290 | id = 'nomiplayer',
291 | image = 'nomiplayer.png',
292 | rank = 1
293 | },
294 | {
295 | label = "Annuncio",
296 | id = "annuncio",
297 | image = 'announce.png',
298 | rank = 1
299 | },
300 | {
301 | label = 'Give Item',
302 | id = 'giveitem',
303 | image = 'giveitem.png',
304 | rank = 1
305 | },
306 | {
307 | label = "Revive All",
308 | id = "reviveall",
309 | image = "reviveall.png",
310 | rank = 1
311 | },
312 | {
313 | label = "Dai Soldi a Tutti",
314 | id = "givemoneyall",
315 | image = "givemoney.png",
316 | rank = 1
317 | },
318 | {
319 | label = "Ripara Veicolo",
320 | id = "repairvehicle",
321 | image = "repairveh.png",
322 | rank = 1
323 | },
324 | {
325 | label = "Clear Area",
326 | id = "cleararea",
327 | image = "cleararea.png",
328 | rank = 1
329 | },
330 | {
331 | label = "Clear Inv.",
332 | id = "clearinventory",
333 | image = "clearinventory.png",
334 | rank = 1
335 | },
336 | {
337 | label = "Clear Ped",
338 | id = "clearped",
339 | image = "clearped.png",
340 | rank = 1
341 | },
342 | {
343 | label = "Skin Menu",
344 | id = "skinmenu",
345 | image = "skinmenu.png",
346 | rank = 1
347 | }
348 | }
349 |
350 | Config.Lang = {
351 | ['it'] = {
352 | ['dashboard'] = "Dashboard",
353 | ['lista_player'] = "Lista Player",
354 | ['menu_personale'] = "Menu Personale",
355 | ['lista_ban'] = "Lista Ban",
356 | ['esci'] = "Esci",
357 | ['benvenuto'] = "Benvenuto,",
358 | ['search_name'] = "Cerca dal Nome",
359 | ['search_id'] = "Cerca dall\'ID",
360 | ['lista_kick'] = "Lista Kick",
361 | ['lista_jail'] = "Lista Jail",
362 | ['lista_warn'] = "Lista Warn",
363 | ['nome_staff'] = "Nome Staff",
364 | ['nome_player'] = "Nome Utente",
365 | ['motivo'] = "Motivo",
366 | ['data'] = "Data",
367 | ['azioni'] = "Azioni",
368 | ['scadenza'] = "Scadenza",
369 | ['valido'] = "Valido",
370 | ['scaduto'] = "Scaduto",
371 | ['stato'] = "Stato",
372 | ['id_ban'] = "ID Ban",
373 | ['seleziona_opzione'] = "Seleziona un Opzione",
374 | ['confirm'] = "Conferma",
375 | ['cancel'] = "Cancella",
376 | ['utente'] = "Utente",
377 | ['revoca'] = "Revoca",
378 | ['no_azione'] = "Nessun Azione",
379 | ['discord'] = "Discord ID: ",
380 | ['steam'] = "Steam ID: ",
381 | ['license'] = "License ID: ",
382 | ['elimina'] = "Elimina",
383 | ['seleziona_opzione'] = "Seleziona un Opzione",
384 | ['ban_totali'] = "Ban Totali",
385 | ['kick_totali'] = "Kick Totali",
386 | ['staff_online'] = "Admin Online",
387 | ['player_online'] = "Player Online",
388 | ['unfreeze'] = "Unfreeze",
389 | ['unjail'] = "Unjail",
390 | ['job_grade'] = "Grado Lavoro",
391 | ['ban'] = "BAN",
392 | ['kick'] = "KICK",
393 | ['jail'] = "ADMIN JAIL",
394 | ['warn'] = "WARN",
395 | ['giveitem'] = "GIVE ITEM",
396 | ['givemoney'] = "GIVE MONEY",
397 | ['setjob'] = "SET JOB",
398 | ['sendmessage'] = "MANDA MESSAGGIO IN DM",
399 | ['giveadmin'] = "DAI PERMESSI",
400 | ['setped'] = "SET PED",
401 | ['item_name'] = "Nome Item",
402 | ['item_count'] = "Quantità Item",
403 | ['cash'] = "Contanti",
404 | ['bank'] = "Banca",
405 | ['black_money'] = "Soldi Sporchi",
406 | ['count'] = "Quantità",
407 | ['text'] = "Messaggio",
408 | ['ped_name'] = "Nome Ped",
409 | ['annuncio'] = "ANNUNCIO",
410 | ['dmmessage'] = "MESSAGGIO PRIVATO",
411 | ['give_money_all'] = "DAI SOLDI A TUTTI",
412 | ['stato_nomitesta'] = "Stato Nomi Testa",
413 | ['stato_noclip'] = "Stato NoClip",
414 | ['stato_invisible'] = "Stato Invisibilità",
415 | ['stato_godmode'] = "Stato Godmode",
416 | ['godmode'] = "Godmode",
417 | ['noclip'] = "NoClip",
418 | ['invisibilita'] = "Invisibilità",
419 | ['nomitesta'] = "Nomi Testa",
420 | ['attivo'] = "Attivo",
421 | ['inattivo'] = "Inattivo",
422 | ['esci_spectate'] = "Premi ~INPUT_PICKUP~ per uscire dalla modalità spettatore",
423 | ['inizio_spectate'] = "Inizio Spectate",
424 | ['fine_spectate'] = "Fine Spectate",
425 | ['veicolo'] = "Veicolo",
426 | ['ripara_veicolo'] = "Ripara Veicolo",
427 | ['clear_area'] = "Clear Area",
428 | ['exit_noclip'] = "Premi ~INPUT_23B4087C~ per uscire dal noclip",
429 |
430 | ['noclip_attivato'] = "NoClip Attivato",
431 | ['noclip_disattivato'] = "NoClip Disattivato",
432 | ['revive'] = "Hai rianimato con successo!",
433 | ['heal'] = "Hai curato con successo!",
434 | ['clear_ped'] = "Il tuo ped è stato pulito con successo",
435 | ['clear_ped2'] = "Hai pulito il ped con successo",
436 | ['clear_area2'] = "Hai pulito la zona con successo",
437 | ['repair_vehicle2'] = "Hai riparato il veicolo con successo",
438 | ['delete_warn'] = "Hai eliminato il warn",
439 | ['nomitesta_a'] = "Hai attivato i nomi sulla testa",
440 | ['nomitesta_b'] = "Hai disattivato i nomi sulla testa",
441 | ['revoca_ban'] = "Hai revocato il ban",
442 | ['kill'] = "Hai ucciso il player",
443 | ['wipe'] = "Hai wipato il player",
444 | ['clear_inv2'] = "Hai pulito l\'inventario del player",
445 | ['jailato'] = "Hai messo in carcere il player",
446 | ['unjailato'] = "Hai scarcerato il player",
447 | ['invisibilita_a'] = "Hai attivato l\'invisibilità",
448 | ['invisibilita_b'] = "Hai disattivato l\'invisibilità",
449 | ['godmode_a'] = "Hai attivato la godmode",
450 | ['godmode_b'] = "Hai disattivato la godmode",
451 | ['revive_all'] = "Hai curato tutti"
452 | },
453 | ['en'] = {
454 | ['dashboard'] = "Dashboard",
455 | ['lista_player'] = "Player List",
456 | ['menu_personale'] = "Personal Menu",
457 | ['lista_ban'] = "Ban List",
458 | ['esci'] = "Exit",
459 | ['benvenuto'] = "Welcome,",
460 | ['search_name'] = "Search by Name",
461 | ['search_id'] = "Search by ID",
462 | ['lista_kick'] = "Kick List",
463 | ['lista_jail'] = "Jail List",
464 | ['lista_warn'] = "List Warn",
465 | ['nome_staff'] = "Staff Name",
466 | ['nome_player'] = "User",
467 | ['motivo'] = "reason",
468 | ['data'] = "Date",
469 | ['azioni'] = "Actions",
470 | ['scadenza'] = "Expire",
471 | ['valido'] = "Valid",
472 | ['scaduto'] = "Expired",
473 | ['stato'] = "Status",
474 | ['id_ban'] = "ID Ban",
475 | ['seleziona_opzione'] = "Select an Option",
476 | ['confirm'] = "Confirm",
477 | ['cancel'] = "Cancel",
478 | ['utente'] = "User",
479 | ['revoca'] = "Revoke",
480 | ['no_azione'] = "No Action",
481 | ['discord'] = "Discord ID: ",
482 | ['steam'] = "Steam ID: ",
483 | ['license'] = "License ID: ",
484 | ['elimina'] = "Delete",
485 | ['ban_totali'] = "Total Bans",
486 | ['kick_totali'] = "Total Kicks",
487 | ['staff_online'] = "Admin Online",
488 | ['player_online'] = "Player Online",
489 | ['unfreeze'] = "Unfreeze",
490 | ['unjail'] = "Unjail",
491 | ['job_grade'] = "Job Grade",
492 | ['ban'] = "BAN",
493 | ['kick'] = "KICK",
494 | ['jail'] = "ADMIN JAIL",
495 | ['warn'] = "WARN",
496 | ['giveitem'] = "GIVE ITEM",
497 | ['givemoney'] = "GIVE MONEY",
498 | ['setjob'] = "SET JOB",
499 | ['sendmessage'] = "DM MESSAGE",
500 | ['giveadmin'] = "GIVE PERMISSIONS",
501 | ['setped'] = "SET PED",
502 | ['item_name'] = "Item Name",
503 | ['item_count'] = "Item Quantity",
504 | ['cash'] = "Cash",
505 | ['bank'] = "Bank",
506 | ['black_money'] = "Dirty Money",
507 | ['count'] = "Amount",
508 | ['text'] = "Message",
509 | ['ped_name'] = "Ped Name",
510 | ['annuncio'] = "ANNOUNCE",
511 | ['dmmessage'] = "DM MESSAGE",
512 | ['give_money_all'] = "GIVE MONEY TO ALL",
513 | ['stato_nomitesta'] = "Head Names Status",
514 | ['stato_noclip'] = "NoClip state",
515 | ['stato_invisible'] = "Invisibility Status",
516 | ['stato_godmode'] = "Godmode state",
517 | ['godmode'] = "Godmode",
518 | ['noclip'] = "NoClip",
519 | ['invisibilita'] = "Invisibility",
520 | ['nomitesta'] = "Head Names",
521 | ['attivo'] = "Active",
522 | ['inattivo'] = "Inactive",
523 | ['esci_spectate'] = "Press ~INPUT_PICKUP~ to exit spectator mode",
524 | ['inizio_spectate'] = "Start Spectate",
525 | ['fine_spectate'] = "End Spectate",
526 | ['veicolo'] = "Vehicle",
527 | ['ripara_veicolo'] = "Repair Vehicle",
528 | ['clear_area'] = "Clear Area",
529 | ['exit_noclip'] = "Press ~INPUT_23B4087C~ to exit noclip",
530 |
531 | ['noclip_attivato'] = "NoClip Activated",
532 | ['noclip_disattivato'] = "NoClip Disabled",
533 | ['revive'] = "You have successfully revived!",
534 | ['heal'] = "You have successfully healed!",
535 | ['clear_ped'] = "Your ped has been cleared successfully",
536 | ['clear_ped2'] = "You have cleared the ped successfully",
537 | ['clear_area2'] = "You have cleared the area successfully",
538 | ['repair_vehicle2'] = "You have successfully repaired the vehicle",
539 | ['delete_warn'] = "You have deleted the warn",
540 | ['nomitesta_a'] = "You have activated headnames",
541 | ['nomitesta_b'] = "You have deactivated the names on the head",
542 | ['revoca_ban'] = "You have revoked the ban",
543 | ['kill'] = "You have killed the player",
544 | ['wipe'] = "You have wiped the player",
545 | ['clear_inv2'] = "You have cleared the player\'s inventory",
546 | ['jailato'] = "You have jailed the player",
547 | ['unjailato'] = "You have released the player",
548 | ['invisibilita_a'] = "You have invisibility activated",
549 | ['invisibilita_b'] = "You have disabled invisibility",
550 | ['godmode_a'] = "You have activated godmode",
551 | ['godmode_b'] = "You have disabled godmode",
552 | ['revive_all'] = "You have cured all"
553 | }
554 | }
555 |
556 | -- Functions --
557 |
558 | SonoStaff = function(xPlayer)
559 | local group = xPlayer.getGroup()
560 | for k, v in pairs(Config.AdminGroup) do
561 | if group == k then
562 | return true
563 | end
564 | end
565 | return false
566 | end
567 |
568 | SendDMMessage = function(text)
569 | postMessage({
570 | type = "SHOW_DM_MESSAGE",
571 | text = text
572 | })
573 | end
574 |
575 | Announce = function(text)
576 | postMessage({
577 | type = "SHOW_ANNOUNCE",
578 | text = text
579 | })
580 | end
581 |
--------------------------------------------------------------------------------
/fxmanifest.lua:
--------------------------------------------------------------------------------
1 | fx_version 'bodacious'
2 | lua54 'yes'
3 | game 'gta5'
4 |
5 | author 'R1CKY®#2220'
6 | description 'Admin Menu - Staff System'
7 | version '1.0'
8 |
9 |
10 | client_scripts {
11 | 'client.lua'
12 | }
13 |
14 | shared_scripts {
15 | 'config.lua',
16 | }
17 | server_scripts {
18 | '@mysql-async/lib/MySQL.lua',
19 | 'server_config.lua',
20 | 'server.lua'
21 | }
22 |
23 | ui_page 'web/index.html'
24 |
25 | files {
26 | 'web/*.html',
27 | 'web/css/*.css',
28 | 'web/js/*.js',
29 | 'web/fonts/*.otf',
30 | 'web/img/*.png',
31 | }
32 |
--------------------------------------------------------------------------------
/server.lua:
--------------------------------------------------------------------------------
1 | -- Attento a quello che tocchi
2 | -- Nova Scripts
3 |
4 | local ESX = exports.es_extended:getSharedObject()
5 |
6 | local client_var = {}
7 |
8 | RegisterServerEvent('ricky-admin:addvariable')
9 | AddEventHandler('ricky-admin:addvariable', function(type, value)
10 | client_var[source] = {}
11 | client_var[source][type] = value
12 | end)
13 |
14 | GetLicense = function(source, type)
15 | local steamid = false
16 | local license = false
17 | local discord = false
18 | local xbl = false
19 | local liveid = false
20 | local ip = false
21 |
22 | for k,v in pairs(GetPlayerIdentifiers(source))do
23 |
24 | if string.sub(v, 1, string.len("steam:")) == "steam:" then
25 | steamid = string.gsub(v, "steam:", "")
26 | elseif string.sub(v, 1, string.len("license:")) == "license:" then
27 | license = string.gsub(v, "license:", "")
28 | elseif string.sub(v, 1, string.len("xbl:")) == "xbl:" then
29 | xbl = string.gsub(v, "xbl:", "")
30 | elseif string.sub(v, 1, string.len("ip:")) == "ip:" then
31 | ip = string.gsub(v, "ip:", "")
32 | elseif string.sub(v, 1, string.len("discord:")) == "discord:" then
33 | discord = string.gsub(v, "discord:", "")
34 | elseif string.sub(v, 1, string.len("live:")) == "live:" then
35 | liveid = string.gsub(v, "live:", "")
36 | end
37 |
38 | end
39 |
40 | if type == "steam" then
41 | return steamid
42 | elseif type == "license" then
43 | return license
44 | elseif type == "discord" then
45 | return discord
46 | elseif type == "xbl" then
47 | return xbl
48 | elseif type == "liveid" then
49 | return liveid
50 | elseif type == "ip" then
51 | return ip
52 | end
53 |
54 | end
55 |
56 | function DiscordRequest(method, endpoint, jsondata, reason)
57 | local data = nil
58 | PerformHttpRequest("https://discordapp.com/api/"..endpoint, function(errorCode, resultData, resultHeaders)
59 | data = {data=resultData, code=errorCode, headers=resultHeaders}
60 | end, method, #jsondata > 0 and jsondata or "", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..ConfigServer.Token, ['X-Audit-Log-Reason'] = reason})
61 |
62 | while data == nil do
63 | Citizen.Wait(0)
64 | end
65 |
66 | return data
67 | end
68 |
69 | GetPlayerAvatar = function(id)
70 | local idDiscord = tonumber(GetLicense(id, "discord"))
71 | local url = nil
72 | PerformHttpRequest("https://discord.com/api/v8/users/"..idDiscord, function (errorCode, resultData, resultHeaders)
73 | if errorCode == 200 then
74 | local userData = json.decode(resultData)
75 | local username = userData.display_name
76 | local avatar = userData.avatar
77 |
78 | url = "https://cdn.discordapp.com/avatars/" .. userData.id .. "/" .. avatar .. ".png"
79 | else
80 | print("Errore nella richiesta HTTP: "..errorCode)
81 | url = ""
82 | end
83 | end, "GET", "", {Authorization = "Bot "..ConfigServer.Token})
84 |
85 | while url == nil do Wait(0) end
86 | return url
87 | end
88 |
89 | GetWarn = function(xPlayer)
90 | local identifier = GetLicense(xPlayer.source, "license")
91 | CheckSql(xPlayer.source)
92 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
93 | ['@identifier'] = identifier,
94 | })
95 | if result[1] == nil then
96 | return {}
97 | end
98 | if result[1].warn == nil then
99 | return {}
100 | else
101 | return json.decode(result[1].warn)
102 | end
103 | end
104 |
105 | GetKick = function(xPlayer)
106 | local identifier = GetLicense(xPlayer.source, "license")
107 | CheckSql(xPlayer.source)
108 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
109 | ['@identifier'] = identifier,
110 | })
111 | if result[1].kick == nil then
112 | return {}
113 | else
114 | return json.decode(result[1].kick)
115 | end
116 | end
117 |
118 | GetBan = function(xPlayer)
119 | local identifier = GetLicense(xPlayer.source, "license")
120 | CheckSql(xPlayer.source)
121 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
122 | ['@identifier'] = identifier,
123 | })
124 | if result[1].ban == nil then
125 | return {}
126 | else
127 | return json.decode(result[1].ban)
128 | end
129 | end
130 |
131 | GetJail = function(xPlayer)
132 | local identifier = GetLicense(xPlayer.source, "license")
133 | CheckSql(xPlayer.source)
134 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
135 | ['@identifier'] = identifier,
136 | })
137 | if result[1].jail == nil then
138 | return {}
139 | else
140 | return json.decode(result[1].jail)
141 | end
142 | end
143 |
144 | local function getBans()
145 | local ban = LoadResourceFile(GetCurrentResourceName(), 'ban.json')
146 | if ban == nil then
147 | return {}
148 | end
149 |
150 | local ban2 = json.decode(ban)
151 |
152 | return ban2
153 | end
154 |
155 | getPlayers = function()
156 | local xPlayers = ESX.GetExtendedPlayers()
157 | local players = {}
158 | for k, xPlayer in pairs(xPlayers) do
159 | local rankLabel = Config.AdminGroup[xPlayer.getGroup()]
160 | if rankLabel == nil then
161 | rankLabel = Config.Lang[Config.Language]['utente']
162 | else
163 | rankLabel = rankLabel.label
164 | end
165 |
166 | local freezed = false
167 | if client_var[xPlayer.source] ~= nil then
168 | freezed = client_var[xPlayer.source].freeze
169 | end
170 | table.insert(players, {
171 | name = GetPlayerName(xPlayer.source),
172 | id = xPlayer.source,
173 | staff = SonoStaff(xPlayer),
174 | job = xPlayer.job,
175 | rankLabel = rankLabel,
176 | freezed = freezed,
177 | license = {
178 | discord = GetLicense(xPlayer.source, "discord") or "N/A",
179 | steam = GetLicense(xPlayer.source, "steam") or "N/A",
180 | license = GetLicense(xPlayer.source, "license") or "N/A",
181 | },
182 | warn = GetWarn(xPlayer),
183 | kick = GetKick(xPlayer),
184 | avatar = GetPlayerAvatar(xPlayer.source),
185 | ban = GetBan(xPlayer),
186 | jail = GetJail(xPlayer),
187 | inJail = InJail(xPlayer.source),
188 | })
189 | end
190 | return players
191 | end
192 |
193 | GetStaffBan = function(xPlayer)
194 | local identifier = GetLicense(xPlayer.source, "license")
195 | CheckSql(xPlayer.source)
196 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin")
197 | local bans = {}
198 | for i=1, #result, 1 do
199 | local ban = json.decode(result[i].ban)
200 | if ban ~= nil then
201 | for a=1, #ban, 1 do
202 | if ban[a].staff.identifier == identifier then
203 | table.insert(bans, ban[a])
204 | end
205 | end
206 | end
207 | end
208 | return bans
209 | end
210 |
211 | GetStaffKick = function(xPlayer)
212 | local identifier = GetLicense(xPlayer.source, "license")
213 | CheckSql(xPlayer.source)
214 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin")
215 | local kicks = {}
216 | for i=1, #result, 1 do
217 | local kick = json.decode(result[i].kick)
218 | if kick ~= nil then
219 | for a=1, #kick, 1 do
220 | if kick[a].staff.identifier == identifier then
221 | table.insert(kicks, kick[a])
222 | end
223 | end
224 | end
225 | end
226 | return kicks
227 | end
228 |
229 | GetStaffJail = function(xPlayer)
230 | local identifier = GetLicense(xPlayer.source, "license")
231 | CheckSql(xPlayer.source)
232 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin")
233 | local jails = {}
234 | for i=1, #result, 1 do
235 | local jail = json.decode(result[i].jail)
236 | if jail ~= nil then
237 | for a=1, #jail, 1 do
238 | if jail[a].staff.identifier == identifier then
239 | table.insert(jails, jail[a])
240 | end
241 | end
242 | end
243 | end
244 | return jails
245 | end
246 |
247 | GetStaffWarn = function(xPlayer)
248 | local identifier = GetLicense(xPlayer.source, "license")
249 | CheckSql(xPlayer.source)
250 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin")
251 | local warns = {}
252 | for i=1, #result, 1 do
253 | local warn = json.decode(result[i].warn)
254 | if warn ~= nil then
255 | for a=1, #warn, 1 do
256 | if warn[a].staff.identifier == identifier then
257 | table.insert(warns, warn[a])
258 | end
259 | end
260 | end
261 | end
262 | return warns
263 | end
264 |
265 | local function getJobs()
266 | local jobs = {}
267 | local esxJobs = ESX.GetJobs()
268 | for k, v in pairs(esxJobs) do
269 | table.insert(jobs, {
270 | label = v.label,
271 | value = v.name,
272 | })
273 | end
274 |
275 | return jobs
276 | end
277 |
278 |
279 | local function getInfoStaff(source)
280 | local xPlayer = ESX.GetPlayerFromId(source)
281 | local rankLabel = Config.AdminGroup[xPlayer.getGroup()]
282 | if rankLabel == nil then
283 | rankLabel = Config.Lang[Config.Language]['utente']
284 | else
285 | rankLabel = rankLabel.label
286 | end
287 | local info = {
288 | name = GetPlayerName(xPlayer.source),
289 | id = xPlayer.source,
290 | staff = SonoStaff(xPlayer),
291 | job = xPlayer.getJob(),
292 | rank = getRank(xPlayer.source),
293 | rankLabel = rankLabel,
294 | avatar = GetPlayerAvatar(xPlayer.source),
295 | ban = GetStaffBan(xPlayer),
296 | kick = GetStaffKick(xPlayer),
297 | jail = GetStaffJail(xPlayer),
298 | warn = GetStaffWarn(xPlayer),
299 | license = {
300 | discord = GetLicense(xPlayer.source, "discord") or "N/A",
301 | steam = GetLicense(xPlayer.source, "steam") or "N/A",
302 | license = GetLicense(xPlayer.source, "license") or "N/A",
303 | },
304 | }
305 | return info
306 | end
307 |
308 | local function getBans()
309 | local ban = LoadResourceFile(GetCurrentResourceName(), 'ban.json')
310 | if ban == nil then
311 | return {}
312 | end
313 |
314 | local ban2 = json.decode(ban)
315 |
316 | return ban2
317 | end
318 |
319 | local function getAdminOnline()
320 | local xPlayers = ESX.GetExtendedPlayers()
321 | local adminOnline = 0
322 |
323 | for _, xPlayer in pairs(xPlayers) do
324 | for a, b in pairs(Config.AdminGroup) do
325 | if xPlayer.getGroup() == a then
326 | adminOnline = adminOnline + 1
327 | end
328 | end
329 | end
330 |
331 | return adminOnline
332 | end
333 |
334 | local function getKicks()
335 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin")
336 | local counterKicks = 0
337 | for i = 1, #result, 1 do
338 | local kick = json.decode(result[i].kick)
339 | if kick ~= nil then
340 | for a = 1, #kick, 1 do
341 | counterKicks = counterKicks + 1
342 | end
343 | end
344 | end
345 |
346 | return counterKicks
347 | end
348 |
349 | getPlayers = function()
350 | local xPlayers = ESX.GetExtendedPlayers()
351 | local players = {}
352 | for k, xPlayer in pairs(xPlayers) do
353 | local rankLabel = Config.AdminGroup[xPlayer.getGroup()]
354 | if rankLabel == nil then
355 | rankLabel = Config.Lang[Config.Language]['utente']
356 | else
357 | rankLabel = rankLabel.label
358 | end
359 |
360 | local freezed = false
361 | if client_var[xPlayer.source] ~= nil then
362 | freezed = client_var[xPlayer.source].freeze
363 | end
364 | table.insert(players, {
365 | name = GetPlayerName(xPlayer.source),
366 | id = xPlayer.source,
367 | staff = SonoStaff(xPlayer),
368 | job = xPlayer.job,
369 | rankLabel = rankLabel,
370 | freezed = freezed,
371 | license = {
372 | discord = GetLicense(xPlayer.source, "discord") or "N/A",
373 | steam = GetLicense(xPlayer.source, "steam") or "N/A",
374 | license = GetLicense(xPlayer.source, "license") or "N/A",
375 | },
376 | warn = GetWarn(xPlayer),
377 | kick = GetKick(xPlayer),
378 | avatar = GetPlayerAvatar(xPlayer.source),
379 | ban = GetBan(xPlayer),
380 | jail = GetJail(xPlayer),
381 | inJail = InJail(xPlayer.source),
382 | })
383 | end
384 | return players
385 | end
386 |
387 | ESX.RegisterServerCallback('ricky-admin:getPlayers', function(source, cb)
388 | cb(getPlayers())
389 | end)
390 |
391 | ESX.RegisterServerCallback('ricky-admin:getData', function(source, cb)
392 | local data = {}
393 |
394 | data.jobs = getJobs()
395 | data.infoStaff = getInfoStaff(source)
396 | data.orario = os.date("%H:%M")
397 | data.bans = getBans()
398 | data.adminOnline = getAdminOnline()
399 | data.kicks = getKicks()
400 |
401 |
402 | cb(data)
403 | end)
404 |
405 | ESX.RegisterServerCallback('ricky-admin:getInfoStaff', function(source, cb)
406 | local xPlayer = ESX.GetPlayerFromId(source)
407 | local rankLabel = Config.AdminGroup[xPlayer.getGroup()]
408 | if rankLabel == nil then
409 | rankLabel = Config.Lang[Config.Language]['utente']
410 | else
411 | rankLabel = rankLabel.label
412 | end
413 | local info = {
414 | name = GetPlayerName(xPlayer.source),
415 | id = xPlayer.source,
416 | staff = SonoStaff(xPlayer),
417 | job = xPlayer.getJob(),
418 | rank = getRank(xPlayer.source),
419 | rankLabel = rankLabel,
420 | avatar = GetPlayerAvatar(xPlayer.source),
421 | ban = GetStaffBan(xPlayer),
422 | kick = GetStaffKick(xPlayer),
423 | jail = GetStaffJail(xPlayer),
424 | warn = GetStaffWarn(xPlayer),
425 | license = {
426 | discord = GetLicense(xPlayer.source, "discord") or "N/A",
427 | steam = GetLicense(xPlayer.source, "steam") or "N/A",
428 | license = GetLicense(xPlayer.source, "license") or "N/A",
429 | },
430 | }
431 | cb(info)
432 | end)
433 |
434 | getRank = function(source)
435 | local group = ESX.GetPlayerFromId(source).getGroup()
436 | for k,v in pairs(Config.AdminGroup) do
437 | if group == k then
438 | return v.rank
439 | end
440 | end
441 | end
442 |
443 | ESX.RegisterServerCallback('ricky-admin:sonoStaff', function(source, cb)
444 | cb(SonoStaff(ESX.GetPlayerFromId(source)))
445 | end)
446 |
447 |
448 | CheckSql = function(id)
449 | local xPlayer = ESX.GetPlayerFromId(id)
450 | if xPlayer == nil then return end
451 |
452 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
453 | ['@identifier'] = GetLicense(xPlayer.source, "license"),
454 | })
455 |
456 | if result[1] == nil then
457 | MySQL.Async.execute("INSERT INTO ricky_admin (identifier) VALUES (@identifier)", {
458 | ['@identifier'] = GetLicense(xPlayer.source, "license"),
459 | })
460 | Wait(1000)
461 | end
462 | end
463 |
464 | InJail = function(source)
465 | local xPlayer = ESX.GetPlayerFromId(source)
466 | if xPlayer == nil then return end
467 |
468 | CheckSql(xPlayer.source)
469 |
470 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
471 | ['@identifier'] = GetLicense(xPlayer.source, "license")
472 | })
473 |
474 | if result[1].inJail == nil or result[1].inJail == 0 then
475 | return false
476 | else
477 | return true
478 | end
479 | end
480 |
481 | RegisterServerEvent('ricky-admin:action')
482 | AddEventHandler('ricky-admin:action', function(data)
483 | local staff = ESX.GetPlayerFromId(source)
484 | local target = ESX.GetPlayerFromId(data.id)
485 | local value1 = data.value1
486 | local value2 = data.value2
487 |
488 | if data.action == 'warn' then
489 | local reason = value1
490 | if target then
491 | CheckSql(target.source)
492 | local warn = GetWarn(target)
493 |
494 | table.insert(warn, {
495 | reason = reason,
496 | name = GetPlayerName(target.source),
497 | staff = {
498 | name = GetPlayerName(staff.source),
499 | identifier = GetLicense(staff.source, "license")
500 | },
501 | date = os.date("%d/%m/%Y %H:%M:%S")
502 | })
503 |
504 | MySQL.Async.execute("UPDATE ricky_admin SET warn = @warn WHERE identifier = @identifier", {
505 | ['@warn'] = json.encode(warn),
506 | ['@identifier'] = GetLicense(target.source, "license"),
507 | })
508 | local fields = {
509 | {
510 | name = Config.Lang[Config.Language]['nome_staff'],
511 | value = GetPlayerName(staff.source),
512 | inline = true
513 | },
514 | {
515 | name = Config.Lang[Config.Language]["nome_player"],
516 | value = GetPlayerName(target.source),
517 | inline = true
518 | },
519 | {
520 | name = Config.Lang[Config.Language]["motivo"],
521 | value = reason,
522 | inline = true
523 | },
524 | }
525 | sendWebhook("WARN", fields, ConfigServer.Webhook.warn)
526 | end
527 | elseif data.action == 'kick' then
528 | local reason = value1
529 | if target then
530 | CheckSql(target.source)
531 |
532 | local kick = GetKick(target)
533 |
534 | table.insert(kick, {
535 | reason = reason,
536 | name = GetPlayerName(target.source),
537 | staff = {
538 | name = GetPlayerName(staff.source),
539 | identifier = GetLicense(staff.source, "license")
540 | },
541 | date = os.date("%d/%m/%Y %H:%M:%S")
542 | })
543 |
544 | MySQL.Async.execute("UPDATE ricky_admin SET kick = @kick WHERE identifier = @identifier", {
545 | ['@kick'] = json.encode(kick),
546 | ['@identifier'] = GetLicense(target.source, "license"),
547 | })
548 |
549 | DropPlayer(target.source, reason)
550 | local fields = {
551 | {
552 | name = Config.Lang[Config.Language]['nome_staff'],
553 | value = GetPlayerName(staff.source),
554 | inline = true
555 | },
556 | {
557 | name = Config.Lang[Config.Language]["nome_player"],
558 | value = GetPlayerName(target.source),
559 | inline = true
560 | },
561 | {
562 | name = Config.Lang[Config.Language]["motivo"],
563 | value = reason,
564 | inline = true
565 | },
566 | }
567 | sendWebhook("KICK", fields, ConfigServer.Webhook.kick)
568 | end
569 | elseif data.action == 'ban' then
570 | local time = value1
571 | local reason = value2
572 | local futuroBanId = math.random(1000, 99999)
573 | time = time + os.time()
574 | local myBan = GetBan(target)
575 |
576 |
577 |
578 | table.insert(myBan, {
579 | reason = reason,
580 | name = GetPlayerName(target.source),
581 | staff = {
582 | name = GetPlayerName(staff.source),
583 | identifier = GetLicense(staff.source, "license"),
584 | },
585 | scadenzaLabel = os.date("%d/%m/%Y %H:%M:%S", time),
586 | scadenza = time,
587 | idBan = futuroBanId,
588 | date = os.date("%d/%m/%Y %H:%M:%S")
589 | })
590 |
591 | MySQL.Async.execute("UPDATE ricky_admin SET ban = @ban WHERE identifier = @identifier", {
592 | ['@ban'] = json.encode(myBan),
593 | ['@identifier'] = GetLicense(target.source, "license"),
594 | })
595 |
596 |
597 |
598 |
599 |
600 | local ban = LoadResourceFile(GetCurrentResourceName(), 'ban.json')
601 | if ban == nil then
602 | return
603 | end
604 |
605 | local ban = json.decode(ban)
606 |
607 | table.insert(ban, {
608 | identifier = target.identifier,
609 | name = GetPlayerName(target.source),
610 | time = time,
611 | reason = reason,
612 | labelScadenza = os.date("%d/%m/%Y %H:%M:%S", time),
613 | time = time,
614 | staff = {
615 | name = GetPlayerName(staff.source),
616 | identifier = GetLicense(staff.source, "license"),
617 | },
618 | idBan = futuroBanId,
619 | dataBan = os.date("%d/%m/%Y %H:%M:%S"),
620 | })
621 |
622 | local discord = GetLicense(target.source, "discord")
623 | local steam = GetLicense(target.source, "steam")
624 | local license = GetLicense(target.source, "license")
625 | local xbl = GetLicense(target.source, "xbl")
626 | local liveid = GetLicense(target.source, "liveid")
627 | local ip = GetLicense(target.source, "ip")
628 | if discord then
629 | ban[#ban].discord = discord
630 | end
631 | if steam then
632 | ban[#ban].steam = steam
633 | end
634 | if license then
635 | ban[#ban].license = license
636 | end
637 | if xbl then
638 | ban[#ban].xbl = xbl
639 | end
640 | if liveid then
641 | ban[#ban].liveid = liveid
642 | end
643 | if ip then
644 | ban[#ban].ip = ip
645 | end
646 |
647 |
648 |
649 | SaveResourceFile(GetCurrentResourceName(), 'ban.json', json.encode(ban, {indent = true}), -1)
650 | local fields = {
651 | {
652 | name = Config.Lang[Config.Language]['nome_staff'],
653 | value = GetPlayerName(staff.source),
654 | inline = true
655 | },
656 | {
657 | name = Config.Lang[Config.Language]["nome_player"],
658 | value = GetPlayerName(target.source),
659 | inline = true
660 | },
661 | {
662 | name = Config.Lang[Config.Language]["motivo"],
663 | value = reason,
664 | inline = true
665 | },
666 | {
667 | name = "Scadenza",
668 | value = os.date('%d/%m/%Y %H:%M:%S', time),
669 | inline = true
670 | },
671 | }
672 | sendWebhook("BAN", fields, ConfigServer.Webhook.ban)
673 | DropPlayer(target.source, 'Sei stato bannato dal server per: '..reason..' - Scadenza: '..os.date('%d/%m/%Y %H:%M:%S', time))
674 | elseif data.action == 'giveitem' then
675 | local item = value1
676 | local count = value2
677 | if target then
678 | target.addInventoryItem(item, count)
679 | local fields = {
680 | {
681 | name = Config.Lang[Config.Language]['nome_staff'],
682 | value = GetPlayerName(staff.source),
683 | inline = true
684 | },
685 | {
686 | name = Config.Lang[Config.Language]["nome_player"],
687 | value = GetPlayerName(target.source),
688 | inline = true
689 | },
690 | {
691 | name = "Oggetto",
692 | value = item,
693 | inline = true
694 | },
695 | {
696 | name = "Quantità",
697 | value = count,
698 | inline = true
699 | },
700 | }
701 | sendWebhook("GIVE ITEM", fields, ConfigServer.Webhook.giveitem)
702 | end
703 |
704 | elseif data.action == 'givemoney' then
705 | local account = value1
706 | local count = value2
707 | if target then
708 | target.addAccountMoney(account, tonumber(count))
709 | local fields = {
710 | {
711 | name = Config.Lang[Config.Language]['nome_staff'],
712 | value = GetPlayerName(staff.source),
713 | inline = true
714 | },
715 | {
716 | name = Config.Lang[Config.Language]["nome_player"],
717 | value = GetPlayerName(target.source),
718 | inline = true
719 | },
720 | {
721 | name = "Account",
722 | value = account,
723 | inline = true
724 | },
725 | {
726 | name = "Quantità",
727 | value = count,
728 | inline = true
729 | },
730 | }
731 | sendWebhook("GIVE MONEY", fields, ConfigServer.Webhook.givemoney)
732 | end
733 | elseif data.action == 'setjob' then
734 | local job = value1
735 | local grade = value2
736 | if target then
737 | target.setJob(job, grade)
738 | local fields = {
739 | {
740 | name = Config.Lang[Config.Language]['nome_staff'],
741 | value = GetPlayerName(staff.source),
742 | inline = true
743 | },
744 | {
745 | name = Config.Lang[Config.Language]["nome_player"],
746 | value = GetPlayerName(target.source),
747 | inline = true
748 | },
749 | {
750 | name = "Lavoro",
751 | value = job,
752 | inline = true
753 | },
754 | {
755 | name = "Grado",
756 | value = grade,
757 | inline = true
758 | },
759 | }
760 | sendWebhook("SET JOB", fields, ConfigServer.Webhook.setjob)
761 | end
762 | elseif data.action == 'adminjail' then
763 | local reason = value1
764 |
765 | print(target)
766 |
767 | if target then
768 |
769 | MySQL.Sync.execute("UPDATE ricky_admin SET jailCoords = @jailCoords WHERE identifier = @identifier", {
770 | ['@identifier'] = GetLicense(target.source, "license"),
771 | ['@jailCoords'] = json.encode(target.getCoords(true))
772 | })
773 |
774 | target.setCoords(Config.AdminJailCoords)
775 | local myJail = GetJail(target)
776 |
777 | table.insert(myJail, {
778 | reason = reason,
779 | name = GetPlayerName(target.source),
780 | staff = {
781 | name = GetPlayerName(staff.source),
782 | identifier = GetLicense(staff.source, "license"),
783 | },
784 | date = os.date("%d/%m/%Y %H:%M:%S")
785 | })
786 |
787 | MySQL.Async.execute("UPDATE ricky_admin SET jail = @jail WHERE identifier = @identifier", {
788 | ['@jail'] = json.encode(myJail),
789 | ['@identifier'] = GetLicense(target.source, "license"),
790 | })
791 |
792 | MySQL.Sync.execute("UPDATE ricky_admin SET inJail = @inJail WHERE identifier = @identifier", {
793 | ['@identifier'] = GetLicense(target.source, "license"),
794 | ['@inJail'] = 1
795 | })
796 |
797 | TriggerClientEvent('ricky-admin:adminjail', target.source)
798 | local fields = {
799 | {
800 | name = Config.Lang[Config.Language]['nome_staff'],
801 | value = GetPlayerName(staff.source),
802 | inline = true
803 | },
804 | {
805 | name = Config.Lang[Config.Language]["nome_player"],
806 | value = GetPlayerName(target.source),
807 | inline = true
808 | },
809 | {
810 | name = Config.Lang[Config.Language]["motivo"],
811 | value = reason,
812 | inline = true
813 | },
814 | }
815 | sendWebhook("ADMIN JAIL", fields, ConfigServer.Webhook.adminjail)
816 | end
817 | elseif data.action == 'giveadmin' then
818 | local group = value1
819 | if target then
820 | target.setGroup(group)
821 | local fields = {
822 | {
823 | name = Config.Lang[Config.Language]['nome_staff'],
824 | value = GetPlayerName(staff.source),
825 | inline = true
826 | },
827 | {
828 | name = Config.Lang[Config.Language]["nome_player"],
829 | value = GetPlayerName(target.source),
830 | inline = true
831 | },
832 | {
833 | name = "Gruppo",
834 | value = group,
835 | inline = true
836 | },
837 | }
838 | sendWebhook("GIVE ADMIN", fields, ConfigServer.Webhook.giveadmin)
839 | end
840 | elseif data.action == 'setped' then
841 | local ped = value1
842 | if target then
843 | TriggerClientEvent('ricky-admin:setped', target.source, ped)
844 | end
845 | elseif data.action == 'dm' then
846 | local msg = value1
847 | if target then
848 | TriggerClientEvent('ricky-admin:dm', target.source, msg)
849 | local fields = {
850 | {
851 | name = Config.Lang[Config.Language]['nome_staff'],
852 | value = GetPlayerName(staff.source),
853 | inline = true
854 | },
855 | {
856 | name = Config.Lang[Config.Language]["nome_player"],
857 | value = GetPlayerName(target.source),
858 | inline = true
859 | },
860 | {
861 | name = "Messaggio",
862 | value = msg,
863 | inline = true
864 | },
865 | }
866 | sendWebhook("MESSAGGIO PRIVATO", fields, ConfigServer.Webhook.sendmessage)
867 | end
868 | elseif data.action == 'annuncio' then
869 | TriggerClientEvent('ricky-admin:announce', -1, value1)
870 | local fields = {
871 | {
872 | name = Config.Lang[Config.Language]['nome_staff'],
873 | value = GetPlayerName(staff.source),
874 | inline = true
875 | },
876 | {
877 | name = "Messaggio",
878 | value = value1,
879 | inline = true
880 | },
881 | }
882 | sendWebhook("ANNUNCIO", fields, ConfigServer.Webhook.annuncio)
883 | elseif data.action == "givemoneyall" then
884 | local account = value1
885 | local count = value2
886 | local xPlayers = ESX.GetExtendedPlayers()
887 | for k,v in pairs(xPlayers) do
888 | v.addAccountMoney(account, tonumber(count))
889 | end
890 | local fields = {
891 | {
892 | name = Config.Lang[Config.Language]['nome_staff'],
893 | value = GetPlayerName(staff.source),
894 | inline = true
895 | },
896 | {
897 | name = "Account",
898 | value = account,
899 | inline = true
900 | },
901 | {
902 | name = "Quantità",
903 | value = count,
904 | inline = true
905 | },
906 | }
907 | sendWebhook("DAI SOLDI A TUTTI", fields, ConfigServer.Webhook.givemoneyall)
908 | elseif data.action == "cleararea" then
909 | local radius = value1
910 | TriggerClientEvent('ricky-admin:cleararea', -1, radius)
911 | local fields = {
912 | {
913 | name = Config.Lang[Config.Language]['nome_staff'],
914 | value = GetPlayerName(staff.source),
915 | inline = true
916 | },
917 | {
918 | name = "Raggio",
919 | value = radius,
920 | inline = true
921 | },
922 | }
923 | sendWebhook("CLEAR AREA", fields, ConfigServer.Webhook.cleararea)
924 | end
925 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
926 | end)
927 |
928 | GetInfoBanFromId = function(source)
929 | local nomeRisorsa = GetCurrentResourceName()
930 | local file = LoadResourceFile(nomeRisorsa, 'ban.json')
931 | local data = json.decode(file)
932 |
933 | for k,v in pairs(data) do
934 | if v.idBan == source then
935 | return v
936 | end
937 | end
938 | return false
939 | end
940 |
941 | GetInfoBan = function(source)
942 | local nomeRisorsa = GetCurrentResourceName()
943 | local file = LoadResourceFile(nomeRisorsa, 'ban.json')
944 | local data = json.decode(file)
945 |
946 | local steam = GetLicense(source, 'steam') or 'N/A'
947 | local discord = GetLicense(source, 'discord')or 'N/A'
948 | local license = GetLicense(source, 'license')or 'N/A'
949 | local xbl = GetLicense(source, 'xbl')or 'N/A'
950 | local live = GetLicense(source, 'live')or 'N/A'
951 | local ip = GetLicense(source, 'ip')or 'N/A'
952 |
953 | for k,v in pairs(data) do
954 | if v.steam == steam or v.discord == discord or v.license == license or v.xbl == xbl or v.live == live or v.ip == ip then
955 | return v
956 | end
957 | end
958 | return false
959 | end
960 |
961 | GetBanFromIdentifier = function(identifier)
962 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
963 | ['@identifier'] = identifier,
964 | })
965 | if result[1].ban == nil then
966 | return {}
967 | else
968 | return json.decode(result[1].ban)
969 | end
970 | end
971 |
972 | UnBan = function(idBan)
973 | local nomeRisorsa = GetCurrentResourceName()
974 | local file = LoadResourceFile(nomeRisorsa, 'ban.json')
975 | local data = json.decode(file)
976 |
977 | for k,v in pairs(data) do
978 | if v.idBan == idBan then
979 | v.valido = false
980 | SaveResourceFile(nomeRisorsa, 'ban.json', json.encode(data, {indent = true}), -1)
981 |
982 | local myBan = GetBanFromIdentifier(v.license)
983 | for a,b in pairs(myBan) do
984 | if b.idBan == idBan then
985 | b.valido = false
986 | end
987 | end
988 |
989 | MySQL.Async.execute("UPDATE ricky_admin SET ban = @ban WHERE identifier = @identifier", {
990 | ['@ban'] = json.encode(myBan),
991 | ['@identifier'] = v.license,
992 | })
993 | end
994 | end
995 |
996 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
997 | end
998 |
999 | CheckBanned = function(source)
1000 | local nomeRisorsa = GetCurrentResourceName()
1001 | local file = LoadResourceFile(nomeRisorsa, 'ban.json')
1002 | local data = json.decode(file)
1003 |
1004 | local steam = GetLicense(source, 'steam') or 'N/A'
1005 | local discord = GetLicense(source, 'discord') or 'N/A'
1006 | local license = GetLicense(source, 'license') or 'N/A'
1007 | local xbl = GetLicense(source, 'xbl') or 'N/A'
1008 | local live = GetLicense(source, 'live') or 'N/A'
1009 | local ip = GetLicense(source, 'ip') or 'N/A'
1010 |
1011 | for k,v in pairs(data) do
1012 | if v.steam == steam or v.discord == discord or v.license == license or v.xbl == xbl or v.live == live or v.ip == ip then
1013 | if v.valido == nil then
1014 | if v.time > os.time() then
1015 | return true
1016 | else
1017 | UnBan(v.idBan)
1018 | return false
1019 | end
1020 | end
1021 | end
1022 | end
1023 | return false
1024 | end
1025 |
1026 |
1027 | AddEventHandler('playerConnecting', function(name, skr, d)
1028 | local src = source
1029 | d.defer()
1030 | Wait(50)
1031 | d.update('Controllando la lista ban')
1032 | if CheckBanned(src) == false then
1033 | d.done()
1034 | return
1035 | end
1036 | Wait(150)
1037 | local ban = GetInfoBan(src)
1038 | d.presentCard([==[{
1039 | "type": "AdaptiveCard",
1040 | "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
1041 | "version": "1.5",
1042 | "body": [
1043 | {
1044 | "type": "TextBlock",
1045 | "text": "]==]..Config.NomeServer..[==[",
1046 | "wrap": true,
1047 | "horizontalAlignment": "Center"
1048 | },
1049 | {
1050 | "type": "TextBlock",
1051 | "text": "Sei stato bannato da questo server",
1052 | "wrap": true,
1053 | "size": "Medium",
1054 | "horizontalAlignment": "Center"
1055 | },
1056 | {
1057 | "type": "ActionSet",
1058 | "actions": [
1059 | {
1060 | "type": "Action.Execute",
1061 | "title": "BAN ID : ]==]..ban.idBan..[==["
1062 | }
1063 | ],
1064 | "horizontalAlignment": "Center"
1065 | },
1066 | {
1067 | "type": "TextBlock",
1068 | "text": "Scadenza prevista per il ban: ]==]..os.date('%d/%m/%Y %H:%M:%S', ban.time)..[==[",
1069 | "wrap": true,
1070 | "horizontalAlignment": "Center"
1071 | },
1072 | {
1073 | "type": "TextBlock",
1074 | "text": "Se ritieni che il tuo ban sia stato un errore, contatta l'amministrazione del server (unisciti al server discord di seguito)",
1075 | "wrap": true,
1076 | "size": "Large",
1077 | "color": "Warning",
1078 | "horizontalAlignment": "Center"
1079 | },
1080 | {
1081 | "type": "ActionSet",
1082 | "actions": [
1083 | {
1084 | "type": "Action.OpenUrl",
1085 | "title": "]==]..Config.NomeServer..[==[",
1086 | "url": "]==]..Config.DiscordServer..[==["
1087 | }
1088 | ],
1089 | "horizontalAlignment": "Center"
1090 | }
1091 | ]
1092 | }]==])
1093 | end)
1094 |
1095 | RegisterServerEvent('ricky-admin:skinmenu')
1096 | AddEventHandler('ricky-admin:skinmenu', function(id)
1097 | local src = source
1098 | local staff = ESX.GetPlayerFromId(src)
1099 | TriggerClientEvent(Config.Trigger.skin, id)
1100 | local target = ESX.GetPlayerFromId(id)
1101 |
1102 | local fields = {
1103 | {
1104 | name = Config.Lang[Config.Language]['nome_staff'],
1105 | value = GetPlayerName(staff.source),
1106 | inline = true
1107 | },
1108 | {
1109 | name = Config.Lang[Config.Language]["nome_player"],
1110 | value = GetPlayerName(target.source),
1111 | inline = true
1112 | },
1113 | }
1114 | sendWebhook("SKIN MENU", fields, ConfigServer.Webhook.skinmenu)
1115 | end)
1116 |
1117 | RegisterServerEvent('ricky-admin:heal')
1118 | AddEventHandler('ricky-admin:heal', function(id)
1119 | local src = source
1120 | local staff = ESX.GetPlayerFromId(src)
1121 | local target = ESX.GetPlayerFromId(id)
1122 | local fields = {
1123 | {
1124 | name = Config.Lang[Config.Language]['nome_staff'],
1125 | value = GetPlayerName(staff.source),
1126 | inline = true
1127 | },
1128 | {
1129 | name = Config.Lang[Config.Language]["nome_player"],
1130 | value = GetPlayerName(target.source),
1131 | inline = true
1132 | },
1133 | }
1134 | sendWebhook("HEAL", fields, ConfigServer.Webhook.heal)
1135 | TriggerClientEvent(Config.Trigger.heal, id)
1136 | end)
1137 |
1138 | RegisterServerEvent('ricky-admin:revive')
1139 | AddEventHandler('ricky-admin:revive', function(id)
1140 | local src = source
1141 | local staff = ESX.GetPlayerFromId(src)
1142 |
1143 | local target = ESX.GetPlayerFromId(id)
1144 | local fields = {
1145 | {
1146 | name = Config.Lang[Config.Language]['nome_staff'],
1147 | value = GetPlayerName(staff.source),
1148 | inline = true
1149 | },
1150 | {
1151 | name = Config.Lang[Config.Language]["nome_player"],
1152 | value = GetPlayerName(target.source),
1153 | inline = true
1154 | },
1155 | }
1156 | sendWebhook("REVIVE", fields, ConfigServer.Webhook.revive)
1157 | TriggerClientEvent(Config.Trigger.revive, id)
1158 | end)
1159 |
1160 | RegisterServerEvent('ricky-admin:kill')
1161 | AddEventHandler('ricky-admin:kill', function(id)
1162 | local src = source
1163 | local staff = ESX.GetPlayerFromId(src)
1164 |
1165 | local target = ESX.GetPlayerFromId(id)
1166 | local fields = {
1167 | {
1168 | name = Config.Lang[Config.Language]['nome_staff'],
1169 | value = GetPlayerName(staff.source),
1170 | inline = true
1171 | },
1172 | {
1173 | name = Config.Lang[Config.Language]["nome_player"],
1174 | value = GetPlayerName(target.source),
1175 | inline = true
1176 | },
1177 | }
1178 | sendWebhook("KILL", fields, ConfigServer.Webhook.kill)
1179 | TriggerClientEvent('ricky-admin:kill', id)
1180 | end)
1181 |
1182 |
1183 | RegisterServerEvent('ricky-admin:goto')
1184 | AddEventHandler('ricky-admin:goto', function(id)
1185 | local src = source
1186 | local staff = ESX.GetPlayerFromId(src)
1187 | local target = ESX.GetPlayerFromId(id)
1188 | if target == nil then
1189 | return
1190 | end
1191 |
1192 | local fields = {
1193 | {
1194 | name = Config.Lang[Config.Language]['nome_staff'],
1195 | value = GetPlayerName(staff.source),
1196 | inline = true
1197 | },
1198 | {
1199 | name = Config.Lang[Config.Language]["nome_player"],
1200 | value = GetPlayerName(target.source),
1201 | inline = true
1202 | },
1203 | }
1204 | sendWebhook("GOTO", fields, ConfigServer.Webhook.goto1)
1205 | local coords = target.getCoords(true)
1206 | staff.setCoords(coords)
1207 | end)
1208 |
1209 |
1210 | RegisterServerEvent('ricky-admin:bring')
1211 | AddEventHandler('ricky-admin:bring', function(id)
1212 | local src = source
1213 | local staff = ESX.GetPlayerFromId(src)
1214 | local target = ESX.GetPlayerFromId(id)
1215 | if target == nil then
1216 | return
1217 | end
1218 |
1219 | local fields = {
1220 | {
1221 | name = Config.Lang[Config.Language]['nome_staff'],
1222 | value = GetPlayerName(staff.source),
1223 | inline = true
1224 | },
1225 | {
1226 | name = Config.Lang[Config.Language]["nome_player"],
1227 | value = GetPlayerName(target.source),
1228 | inline = true
1229 | },
1230 | }
1231 | sendWebhook("BRING", fields, ConfigServer.Webhook.bring)
1232 | local coords = staff.getCoords(true)
1233 | target.setCoords(coords)
1234 | end)
1235 |
1236 |
1237 | RegisterServerEvent('ricky-admin:clearInv')
1238 | AddEventHandler('ricky-admin:clearInv', function(id)
1239 | local src = source
1240 | local staff = ESX.GetPlayerFromId(src)
1241 |
1242 | local target = ESX.GetPlayerFromId(id)
1243 | if target == nil then
1244 | return
1245 | end
1246 |
1247 | local itemsTarget = target.getInventory()
1248 | for k,v in pairs(itemsTarget) do
1249 | target.removeInventoryItem(v.name, v.count)
1250 | end
1251 | local fields = {
1252 | {
1253 | name = Config.Lang[Config.Language]['nome_staff'],
1254 | value = GetPlayerName(staff.source),
1255 | inline = true
1256 | },
1257 | {
1258 | name = Config.Lang[Config.Language]["nome_player"],
1259 | value = GetPlayerName(target.source),
1260 | inline = true
1261 | },
1262 | }
1263 | sendWebhook("CLEAR INV.", fields, ConfigServer.Webhook.clearinventory)
1264 | end)
1265 |
1266 |
1267 | ESX.RegisterServerCallback('ricky-admin:getInJail', function(source, cb)
1268 | cb(InJail(source))
1269 | end)
1270 |
1271 | RegisterServerEvent('ricky-admin:unjail')
1272 | AddEventHandler('ricky-admin:unjail', function(id)
1273 | local src = source
1274 | local staff = ESX.GetPlayerFromId(src)
1275 |
1276 | local target = ESX.GetPlayerFromId(id)
1277 | if target == nil then
1278 | return
1279 | end
1280 |
1281 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin WHERE identifier = @identifier", {
1282 | ['@identifier'] = GetLicense(target.source, "license"),
1283 | })
1284 |
1285 | MySQL.Sync.execute("UPDATE ricky_admin SET inJail = @inJail WHERE identifier = @identifier", {
1286 | ['@identifier'] = GetLicense(target.source, "license"),
1287 | ['@inJail'] = 0
1288 | })
1289 |
1290 |
1291 | local coords = json.decode(result[1].jailCoords)
1292 |
1293 | target.setCoords(coords)
1294 |
1295 | local fields = {
1296 | {
1297 | name = Config.Lang[Config.Language]['nome_staff'],
1298 | value = GetPlayerName(staff.source),
1299 | inline = true
1300 | },
1301 | {
1302 | name = Config.Lang[Config.Language]["nome_player"],
1303 | value = GetPlayerName(target.source),
1304 | inline = true
1305 | },
1306 | }
1307 | sendWebhook("UNJAIL", fields, ConfigServer.Webhook.adminjail)
1308 |
1309 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
1310 | TriggerClientEvent('ricky-admin:unjail', target.source)
1311 |
1312 | end)
1313 |
1314 |
1315 | RegisterServerEvent('ricky-admin:wipe')
1316 | AddEventHandler('ricky-admin:wipe', function(id)
1317 | local src = source
1318 | local staff = ESX.GetPlayerFromId(src)
1319 | local target = ESX.GetPlayerFromId(id)
1320 | if target == nil then
1321 | return
1322 | end
1323 |
1324 | for k,v in pairs(Config.WipeSettings) do
1325 | for a,b in pairs(v) do
1326 |
1327 | MySQL.Sync.execute('DELETE FROM '..b..' WHERE '..k..' = @identifier',{
1328 | ['@identifier'] = target.identifier,
1329 | })
1330 | end
1331 | end
1332 | local fields = {
1333 | {
1334 | name = Config.Lang[Config.Language]['nome_staff'],
1335 | value = GetPlayerName(staff.source),
1336 | inline = true
1337 | },
1338 | {
1339 | name = Config.Lang[Config.Language]["nome_player"],
1340 | value = GetPlayerName(target.source),
1341 | inline = true
1342 | },
1343 | }
1344 | sendWebhook("WIPE", fields, ConfigServer.Webhook.wipe)
1345 | DropPlayer(target.source, 'Sei stato wipato dal server')
1346 | end)
1347 |
1348 | RegisterServerEvent('ricky-admin:deletewarn')
1349 | AddEventHandler('ricky-admin:deletewarn', function(id, index)
1350 | local src = source
1351 | local staff = ESX.GetPlayerFromId(src)
1352 |
1353 | local target = ESX.GetPlayerFromId(id)
1354 |
1355 | if target == nil then
1356 | return
1357 | end
1358 |
1359 | if index == 0 then
1360 | index = 1
1361 | end
1362 |
1363 | local warn = GetWarn(target)
1364 | table.remove(warn, index)
1365 |
1366 | MySQL.Async.execute("UPDATE ricky_admin SET warn = @warn WHERE identifier = @identifier", {
1367 | ['@warn'] = json.encode(warn),
1368 | ['@identifier'] = GetLicense(target.source, "license"),
1369 | })
1370 |
1371 |
1372 | local fields = {
1373 | {
1374 | name = Config.Lang[Config.Language]['nome_staff'],
1375 | value = GetPlayerName(staff.source),
1376 | inline = true
1377 | },
1378 | {
1379 | name = Config.Lang[Config.Language]["nome_player"],
1380 | value = GetPlayerName(target.source),
1381 | inline = true
1382 | },
1383 | }
1384 | sendWebhook("WARN ELIMINATO", fields, ConfigServer.Webhook.warn)
1385 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
1386 | end)
1387 |
1388 |
1389 | local function getJobs()
1390 | local jobs = {}
1391 | local esxJobs = ESX.GetJobs()
1392 | for k, v in pairs(esxJobs) do
1393 | table.insert(jobs, {
1394 | label = v.label,
1395 | value = v.name,
1396 | })
1397 | end
1398 |
1399 | return jobs
1400 | end
1401 |
1402 | ESX.RegisterServerCallback('ricky-admin:getOrario', function(source, cb)
1403 | local hour = os.date("%H:%M")
1404 | cb(hour)
1405 | end)
1406 |
1407 |
1408 | RegisterCommand('unban', function(source, args, rawCommand)
1409 | if source == 0 or SonoStaff(ESX.GetPlayerFromId(source)) then
1410 | local idBan = tonumber(args[1])
1411 | if not GetInfoBanFromId(idBan) then
1412 | if source == 0 then
1413 | print("ID Ban non valido")
1414 | else
1415 | ESX.GetPlayerFromId(source).showNotification("ID Ban non valido", "error")
1416 | end
1417 | return
1418 | end
1419 | UnBan(idBan)
1420 | if source == 0 then
1421 | print("Unban effettuato con successo")
1422 | else
1423 | ESX.GetPlayerFromId(source).showNotification("Unban effettuato con successo", "success")
1424 | end
1425 | end
1426 | end)
1427 |
1428 | ESX.RegisterServerCallback('ricky-admin:getCoordsPlayer', function(source,cb,id)
1429 | local xPlayer = ESX.GetPlayerFromId(id)
1430 | if xPlayer == nil then return end
1431 | cb(xPlayer.getCoords(true), xPlayer.getCoords(false))
1432 | end)
1433 |
1434 | RegisterServerEvent('ricky-admin:freeze')
1435 | AddEventHandler('ricky-admin:freeze', function(id)
1436 | local src = source
1437 | local staff = ESX.GetPlayerFromId(src)
1438 |
1439 | local target = ESX.GetPlayerFromId(id)
1440 |
1441 | if target == nil then
1442 | return
1443 | end
1444 |
1445 | TriggerClientEvent('ricky-admin:freeze', target.source)
1446 | if client_var[target.source].freeze == 1 then
1447 | client_var[target.source].freeze = false
1448 | else
1449 | client_var[target.source].freeze = 1
1450 | end
1451 |
1452 | local fields = {
1453 | {
1454 | name = Config.Lang[Config.Language]['nome_staff'],
1455 | value = GetPlayerName(staff.source),
1456 | inline = true
1457 | },
1458 | {
1459 | name = Config.Lang[Config.Language]["nome_player"],
1460 | value = GetPlayerName(target.source),
1461 | inline = true
1462 | },
1463 | }
1464 | sendWebhook("FREEZE", fields, ConfigServer.Webhook.freeze)
1465 |
1466 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
1467 | end)
1468 |
1469 | RegisterServerEvent('ricky-admin:sfreeze')
1470 | AddEventHandler('ricky-admin:sfreeze', function(id)
1471 | local src = source
1472 | local staff = ESX.GetPlayerFromId(src)
1473 |
1474 | local target = ESX.GetPlayerFromId(id)
1475 |
1476 | if target == nil then
1477 | return
1478 | end
1479 |
1480 | TriggerClientEvent('ricky-admin:sfreeze', target.source)
1481 | if client_var[target.source].freeze == 1 then
1482 | client_var[target.source].freeze = false
1483 | else
1484 | client_var[target.source].freeze = 1
1485 | end
1486 |
1487 | local fields = {
1488 | {
1489 | name = Config.Lang[Config.Language]['nome_staff'],
1490 | value = GetPlayerName(staff.source),
1491 | inline = true
1492 | },
1493 | {
1494 | name = Config.Lang[Config.Language]["nome_player"],
1495 | value = GetPlayerName(target.source),
1496 | inline = true
1497 | },
1498 | }
1499 | sendWebhook("SFREEZE", fields, ConfigServer.Webhook.freeze)
1500 |
1501 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
1502 | end)
1503 |
1504 | RegisterServerEvent('ricky-admin:revocaban')
1505 | AddEventHandler('ricky-admin:revocaban', function(staffId, id)
1506 | UnBan(id)
1507 | TriggerClientEvent('ricky-admin:updatePlayers', -1)
1508 |
1509 | local ban = GetInfoBanFromId(id)
1510 |
1511 | local fields = {
1512 | {
1513 | name = Config.Lang[Config.Language]['nome_staff'],
1514 | value = GetPlayerName(staffId),
1515 | inline = true
1516 | },
1517 | {
1518 | name = Config.Lang[Config.Language]["nome_player"],
1519 | value = ban.name,
1520 | inline = true
1521 | },
1522 | {
1523 | name = "Motivo Ban",
1524 | value = ban.reason,
1525 | inline = true
1526 | },
1527 | {
1528 | name = "Scadenza Ban",
1529 | value = ban.labelScadenza,
1530 | inline = true
1531 | }
1532 | }
1533 |
1534 | sendWebhook("REVOCA BAN", fields, ConfigServer.Webhook.ban)
1535 | end)
1536 |
1537 | local function getAdminOnline()
1538 | local xPlayers = ESX.GetExtendedPlayers()
1539 | local adminOnline = 0
1540 |
1541 | for _, xPlayer in pairs(xPlayers) do
1542 | for a, b in pairs(Config.AdminGroup) do
1543 | if xPlayer.getGroup() == a then
1544 | adminOnline = adminOnline + 1
1545 | end
1546 | end
1547 | end
1548 |
1549 | return adminOnline
1550 | end
1551 |
1552 | RegisterServerEvent('ricky-admin:reviveall')
1553 | AddEventHandler('ricky-admin:reviveall', function()
1554 |
1555 | local staff = ESX.GetPlayerFromId(source)
1556 | local fields = {
1557 | {
1558 | name = Config.Lang[Config.Language]['nome_staff'],
1559 | value = GetPlayerName(staff.source),
1560 | inline = true
1561 | },
1562 | }
1563 | sendWebhook("REVIVE ALL", fields, ConfigServer.Webhook.revive)
1564 |
1565 | TriggerClientEvent(Config.Trigger.revive, -1)
1566 | end)
1567 |
1568 |
1569 | ESX.RegisterServerCallback('ricky-admin:getAllKicks', function(source, cb)
1570 | local result = MySQL.Sync.fetchAll("SELECT * FROM ricky_admin")
1571 | local counterKicks = 0
1572 | for i=1, #result, 1 do
1573 | local kick = json.decode(result[i].kick)
1574 | if kick ~= nil then
1575 | for a=1, #kick, 1 do
1576 | counterKicks = counterKicks + 1
1577 | end
1578 | end
1579 | end
1580 | cb(counterKicks)
1581 | end)
1582 |
1583 | RegisterServerEvent('ricky-admin:clearped')
1584 | AddEventHandler('ricky-admin:clearped', function(id)
1585 | local src = source
1586 | local staff = ESX.GetPlayerFromId(src)
1587 |
1588 | local target = ESX.GetPlayerFromId(id)
1589 | if target == nil then
1590 | return
1591 | end
1592 |
1593 | local fields = {
1594 | {
1595 | name = Config.Lang[Config.Language]['nome_staff'],
1596 | value = GetPlayerName(staff.source),
1597 | inline = true
1598 | },
1599 | {
1600 | name = Config.Lang[Config.Language]["nome_player"],
1601 | value = GetPlayerName(target.source),
1602 | inline = true
1603 | }
1604 | }
1605 | sendWebhook("CLEAR PED", fields, ConfigServer.Webhook.clearped)
1606 | TriggerClientEvent('ricky-admin:clearped', target.source)
1607 | end)
1608 |
1609 |
1610 | GenerateRandomColor = function()
1611 | local red = math.random(0, 255)
1612 | local green = math.random(0, 255)
1613 | local blue = math.random(0, 255)
1614 | return red, green, blue
1615 | end
1616 |
1617 | RegisterServerEvent('ricky-admin:webhook')
1618 | AddEventHandler('ricky-admin:webhook', function(title, fields, webhook)
1619 | if type(webhook) == "string" then
1620 | webhook = ConfigServer.Webhook[webhook]
1621 | end
1622 | sendWebhook(title, fields, webhook)
1623 | end)
1624 |
1625 | sendWebhook = function(title, fields, webhook)
1626 | local colorRed, colorGreen, colorBlue = GenerateRandomColor()
1627 | local embed = {
1628 | {
1629 | ["title"] = title,
1630 | ["type"] = "rich",
1631 | ["color"] = colorRed * 65536 + colorGreen * 256 + colorBlue,
1632 | ["fields"] = fields,
1633 | ["footer"] = {
1634 | ["text"] = os.date("%d/%m/%Y %H:%M:%S"),
1635 | },
1636 | ['thumbnail'] = {
1637 | ['url'] = Config.LogoServer,
1638 | }
1639 | }
1640 | }
1641 | PerformHttpRequest(webhook, function(err, text, headers) end, 'POST', json.encode({username = Config.NomeServer, avatar_url=Config.LogoServer, embeds = embed}), { ['Content-Type'] = 'application/json' })
1642 | end
1643 |
--------------------------------------------------------------------------------
/server_config.lua:
--------------------------------------------------------------------------------
1 | ConfigServer = {}
2 |
3 | ConfigServer.Token = ""
4 |
5 | ConfigServer.Webhook = {
6 | ban = "",
7 | kick = "",
8 | adminjail = "",
9 | warn = "",
10 | skinmenu = "",
11 | spectate = "",
12 | revive = "",
13 | heal = "",
14 | kill = "",
15 | wipe = "",
16 | goto1 = "",
17 | bring = "",
18 | giveitem = "",
19 | givemoney = "",
20 | setjob = "",
21 | clearinventory = "",
22 | giveadmin = "",
23 | clearped = "",
24 | sendmessage = "",
25 | freeze = "",
26 | noclip = "",
27 | invisibilita = "",
28 | godmode = "",
29 | nomiplayer = "",
30 | annuncio = "",
31 | reviveall = "",
32 | givemoneyall = "",
33 | repairvehicle = "",
34 | cleararea = "",
35 | }
--------------------------------------------------------------------------------
/web/css/style.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Proxima Nova';
3 | src: url(../fonts/proxima_nova.otf);
4 | }
5 |
6 | * {
7 | margin: 0;
8 | padding: 0;
9 | user-select: none;
10 | font-family: 'Proxima Nova';
11 | color: white;
12 | font-style: normal;
13 | font-weight: 600;
14 | letter-spacing: 0.11em;
15 | overflow: hidden;
16 | }
17 |
18 | .opzione:hover,
19 | i:hover,
20 | .info:hover,
21 | .player:hover,
22 | .azione:hover,
23 | .confirm:hover,
24 | .cancel:hover,
25 | .lista:hover,
26 | .warn:hover,
27 | .logo2:hover {
28 | cursor: pointer;
29 | }
30 |
31 | #app {
32 | display: none;
33 | position: absolute;
34 | height: 100%;
35 | width: 100%;
36 | background: radial-gradient(63.56% 152.1% at 51.88% 65.97%, #000000 0%, rgba(0, 0, 0, 0.9) 100%);
37 | }
38 |
39 | @keyframes opacity {
40 | 0% {
41 | opacity: 0;
42 | }
43 | 100% {
44 | opacity: 1;
45 | }
46 | }
47 |
48 | input::-webkit-outer-spin-button,
49 | input::-webkit-inner-spin-button {
50 | -webkit-appearance: none;
51 | margin: 0;
52 | }
53 |
54 |
55 | .opacity-enter-active {
56 | animation: opacity 0.3s ease forwards;
57 | }
58 |
59 | .opacity-leave-active {
60 | animation: opacity 0.3s ease forwards reverse;
61 | }
62 |
63 | .containerMenu {
64 | position: absolute;
65 | left: 50%;
66 | top: 50%;
67 | height: 92.7778vh;
68 | width: 168.7963vh;
69 | transform: translate(-50%, -50%);
70 | background: rgba(216, 216, 216, 0.05);
71 | border-radius: 2.7778vh;
72 | border: 0.2778vh solid #464646;
73 | }
74 |
75 | .bgcolor {
76 | position: absolute;
77 | height: 100%;
78 | width: 100%;
79 | background-size: 100% 100%;
80 | background-repeat: no-repeat;
81 | background-image: url('../img/bg_color.png');
82 | }
83 |
84 | .leftBar {
85 | position: absolute;
86 | height: 92.7778vh;
87 | width: 31.7593vh;
88 | border-right: 0.2778vh solid #464646;
89 | }
90 |
91 | .serverLogo {
92 | position: absolute;
93 | left: 50%;
94 | transform: translate(-50%);
95 | top: -1.537vh;
96 | height: 19.4444vh;
97 | width: 19.4444vh;
98 | background-size: contain;
99 | background-repeat: no-repeat;
100 | background-image: url('../img/logoServer.png');
101 | }
102 |
103 | .containerOpzioni {
104 | position: absolute;
105 | overflow-y: auto;
106 | top: 17.2222vh;
107 | left: 0.8333vh;
108 | height: 40.1667vh;
109 | width: 30vh;
110 | }
111 |
112 | .containerOpzioni .opzione {
113 | position: relative;
114 | height: 4.1667vh;
115 | width: 30vh;
116 | border-radius: 0.463vh;
117 | margin-bottom: 1.2037vh;
118 | transition: 0.5s;
119 | }
120 |
121 | .opzione .logoOpzione {
122 | position: absolute;
123 | top: 50%;
124 | transform: translate(0, -50%);
125 | left: 1.6667vh;
126 | height: 2.2222vh;
127 | width: 2.2222vh;
128 | background-size: contain;
129 | background-repeat: no-repeat;
130 | }
131 |
132 | .opzione .nomeOpzione {
133 | position: absolute;
134 | top: 50%;
135 | transform: translate(0, -50%);
136 | left: 7.7778vh;
137 | font-size: 2.3148vh;
138 | }
139 |
140 | .paginaDestra {
141 | position: absolute;
142 | left: 31.7593vh;
143 | height: 92.5vh;
144 | width: 137.037vh;
145 | }
146 |
147 | .line {
148 | position: absolute;
149 | height: 8.3333vh;
150 | width: 0.6481vh;
151 | left: 1.5741vh;
152 | top: 2.4074vh;
153 | background: #FFF;
154 | box-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
155 | }
156 |
157 |
158 | .welcome {
159 | position: absolute;
160 | left: 3.6111vh;
161 | top: 1.1519vh;
162 | font-size: 4.6296vh;
163 | text-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
164 | }
165 |
166 | .name {
167 | position: absolute;
168 | left: 3.6111vh;
169 | top: 6.37vh;
170 | font-size: 4.6296vh;
171 | text-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
172 | }
173 |
174 | .hour {
175 | position: absolute;
176 | left: 50%;
177 | transform: translate(-50%);
178 | top: 1.8519vh;
179 | font-size: 8.3333vh;
180 | text-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
181 | }
182 |
183 | .containerInfo {
184 | position: absolute;
185 | top: 16.2963vh;
186 | left: 23.0556vh;
187 | height: 69.9074vh;
188 | width: 124vh;
189 | }
190 |
191 | .info {
192 | position: relative;
193 | float: left;
194 | margin-right: 26.2037vh;
195 | margin-bottom: 4.7222vh !important;
196 | width: 32.1296vh;
197 | height: 32.4074vh;
198 | background-size: contain;
199 | background-repeat: no-repeat;
200 | }
201 |
202 | .info .name {
203 | position: absolute;
204 | left: 50%;
205 | transform: translate(-50%);
206 | text-align: center;
207 | width: 100%;
208 | top: 15.3704vh;
209 | font-size: 3.2407vh;
210 | text-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
211 | }
212 |
213 | .info .number {
214 | position: absolute;
215 | left: 50%;
216 | transform: translate(-50%);
217 | text-align: center;
218 | width: 100%;
219 | font-size: 4.6296vh;
220 | top: 22.5926vh;
221 | text-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
222 | }
223 |
224 | input:focus {
225 | outline: none;
226 | }
227 |
228 | .search_name {
229 | position: absolute;
230 | left: 50%;
231 | transform: translate(-50%);
232 | top: 4.0741vh;
233 | height: 5.5556vh;
234 | width: 46.1111vh;
235 | background: rgba(216, 216, 216, 0.05);
236 | border-radius: 0.9259vh;
237 | border: 0.1852vh solid #464646;
238 | font-size: 2.3148vh;
239 | padding: 1vh;
240 | }
241 |
242 | .containerPlayer {
243 | position: absolute;
244 | left: 39.8148vh;
245 | top: 14.2593vh;
246 | width: 57.4074vh;
247 | height: 75vh;
248 | overflow-y: auto;
249 | }
250 |
251 | .containerPlayer .player {
252 | position: relative;
253 | height: 6.2037vh;
254 | width: 56.4074vh;
255 | border-radius: 0.9259vh;
256 | border: 0.1852vh solid #464646;
257 | margin-bottom: 1vh;
258 | }
259 |
260 | .player .name {
261 | position: absolute;
262 | top: 50%;
263 | transform: translate(0, -50%);
264 | left: 1.2963vh;
265 | font-size: 2.3148vh;
266 | }
267 |
268 | .containerInfoPlayer {
269 | position: absolute;
270 | top: 1.4815vh;
271 | left: 2.3148vh;
272 | height: 18.4259vh;
273 | width: 132.3148vh;
274 | background: rgba(216, 216, 216, 0.05);
275 | border-radius: 0.9259vh;
276 | border: 0.1852vh solid #464646;
277 | }
278 |
279 | .containerInfoPlayer .logo {
280 | position: absolute;
281 | height: 18.4481vh;
282 | width: 18.1481vh;
283 | border-right: 0.1852vh solid #464646;
284 | }
285 |
286 |
287 | .logo .logo2 {
288 | position: absolute;
289 | height: 100%;
290 | width: 100%;
291 | background-size: contain;
292 | background-repeat: no-repeat;
293 | }
294 |
295 | .containerInfoPlayer .info {
296 | position: absolute;
297 | left: 20.1296vh;
298 | top: 0.4111vh;
299 | height: 17vh;
300 | width: 95vh;
301 | }
302 |
303 | .info span {
304 | position: relative;
305 | display: flex;
306 | flex-direction: column;
307 | font-size: 1.8519vh;
308 | margin-bottom: 0.0159vh;
309 | }
310 |
311 | .info span i {
312 | position: absolute;
313 | right: 1;
314 | height: 1.8519vh;
315 | width: 1.8519vh;
316 | background-size: contain;
317 | background-repeat: no-repeat;
318 | background-image: url('../img/copy.png');
319 | }
320 |
321 | .containerAzioniPlayer {
322 | position: absolute;
323 | top: 21.2963vh;
324 | left: 2.3148vh;
325 | width: 132.3148vh;
326 | height: 69.7222vh;
327 | background: rgba(216, 216, 216, 0.05);
328 | border-radius: 0.9259vh;
329 | border: 0.1852vh solid #464646;
330 | }
331 |
332 | ::-webkit-scrollbar {
333 | display: none;
334 | }
335 |
336 | .containerAzioniPlayer .containerAzioni {
337 | position: absolute;
338 | left: 3.2407vh;
339 | top: 2.3148vh;
340 | height: 50.6481vh;
341 | width: 130.9259vh;
342 | overflow-y: auto;
343 | }
344 |
345 | .containerAzioni .azione {
346 | position: relative;
347 | height: 23.2407vh;
348 | width: 21.4815vh;
349 | float: left;
350 | margin-bottom: 4.1667vh;
351 | margin-right: 4.6296vh;
352 | border-radius: 1.8519vh;
353 | background-size: contain;
354 | background-repeat: no-repeat;
355 | box-shadow: 0vh 0.3704vh 0.3704vh 0vh rgba(0, 0, 0, 0.25);
356 | }
357 |
358 | .azione .nomeAzione {
359 | position: absolute;
360 | font-size: 2.2vh;
361 | left: 50%;
362 | transform: translate(-50%);
363 | width: 100%;
364 | text-align: center;
365 | top: 16.5741vh;
366 | }
367 |
368 | @keyframes question {
369 | 0% {
370 | transform: translateY(-70vh);
371 | }
372 | 100% {
373 | transform: translateY(0);
374 | }
375 | }
376 |
377 | .question-enter-active {
378 | animation: question 1s ease forwards;
379 | }
380 |
381 | .question-leave-active {
382 | animation: question 1s ease forwards reverse;
383 | }
384 |
385 | .value1 {
386 | position: absolute;
387 | left: 35.6481vh;
388 | top: 26.2963vh;
389 | height: 5vh;
390 | width: 32.8704vh;
391 | background: rgba(216, 216, 216, 0.05);
392 | border-radius: 0.463vh;
393 | border: 0.0926vh solid #FFF;
394 | padding: 1vh;
395 | font-size: 2.7778vh;
396 | }
397 |
398 | .value2 {
399 | position: absolute;
400 | left: 69.6296vh;
401 | top: 26.2963vh;
402 | height: 5vh;
403 | width: 32.8704vh;
404 | background: rgba(216, 216, 216, 0.05);
405 | border-radius: 0.463vh;
406 | border: 0.0926vh solid #FFF;
407 | padding: 1vh;
408 | font-size: 2.7778vh;
409 | }
410 |
411 | .value1::placeholder,
412 | .value2::placeholder {
413 | color: #c2bebe !important;
414 | }
415 |
416 | .confirm {
417 | position: absolute;
418 | left: 35.6481vh;
419 | top: 34.537vh;
420 | height: 5vh;
421 | width: 32.8704vh;
422 | border-radius: 0.463vh;
423 | border: 0.0926vh solid #FFF;
424 | background: rgba(216, 216, 216, 0.54);
425 | }
426 |
427 | .cancel {
428 | position: absolute;
429 | left: 69.6296vh;
430 | top: 34.537vh;
431 | height: 5vh;
432 | width: 32.8704vh;
433 | border-radius: 0.463vh;
434 | border: 0.0926vh solid #FFF;
435 | background: rgba(216, 216, 216, 0.54);
436 | }
437 |
438 | .confirm span,
439 | .cancel span {
440 | position: absolute;
441 | height: 100%;
442 | width: 100%;
443 | display: flex;
444 | justify-content: center;
445 | align-items: center;
446 | font-size: 2.7778vh;
447 | }
448 |
449 |
450 | select {
451 | border: 0;
452 | outline-offset: -0.0926vh;
453 | }
454 |
455 | select:focus {
456 | outline: none;
457 | }
458 |
459 |
460 | option {
461 | border-radius: 0;
462 | color: white;
463 | background: #464646;
464 | }
465 |
466 | .question .title {
467 | position: absolute;
468 | top: 3.7963vh;
469 | width: 100%;
470 | display: flex;
471 | justify-content: center;
472 | align-items: center;
473 | font-size: 5.5556vh;
474 | }
475 |
476 | .containerListe {
477 | position: absolute;
478 | bottom: 0;
479 | height: 14.4444vh;
480 | width: 100%;
481 | justify-content: center;
482 | display: flex;
483 | align-items: flex-start;
484 | border-top: 0.1852vh solid #464646;
485 | }
486 |
487 | .containerListe .lista {
488 | position: relative;
489 | height: 9.1667vh;
490 | width: 21.3889vh;
491 | display: flex;
492 | justify-content: center;
493 | align-items: center;
494 | background-repeat: no-repeat;
495 | background-size: contain;
496 | border-radius: 0.9259vh;
497 | top: 50%;
498 | transform: translate(0, -50%);
499 | margin-right: 4.7222vh;
500 | }
501 |
502 | .lista span {
503 | position: absolute;
504 | height: 100%;
505 | width: 100%;
506 | display: flex;
507 | justify-content: center;
508 | align-items: center;
509 | font-size: 2.7778vh;
510 | }
511 | .message {
512 | display: none;
513 | position: absolute;
514 | left: 50%;
515 | transform: translate(-50%);
516 | top: 2vh;
517 | width: 35vh;
518 | height: 7vh;
519 | background-color: rgb(255, 153, 0);
520 | border-radius: 0.463vh;
521 | }
522 |
523 | .titleMsg {
524 | position: absolute;
525 | display: flex;
526 | justify-content: center;
527 | align-items: center;
528 | width: 100%;
529 | font-size: 2vh;
530 | color: black;
531 | }
532 |
533 | .subtitleMsg {
534 | position: absolute;
535 | left: 50%;
536 | transform: translate(-50%);
537 | top: 2vh;
538 | color: black;
539 | }
--------------------------------------------------------------------------------
/web/fonts/proxima_nova.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/fonts/proxima_nova.otf
--------------------------------------------------------------------------------
/web/img/admin_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/admin_online.png
--------------------------------------------------------------------------------
/web/img/adminjail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/adminjail.png
--------------------------------------------------------------------------------
/web/img/announce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/announce.png
--------------------------------------------------------------------------------
/web/img/ban.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/ban.png
--------------------------------------------------------------------------------
/web/img/banhistory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/banhistory.png
--------------------------------------------------------------------------------
/web/img/bg_color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/bg_color.png
--------------------------------------------------------------------------------
/web/img/bring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/bring.png
--------------------------------------------------------------------------------
/web/img/cleararea.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/cleararea.png
--------------------------------------------------------------------------------
/web/img/clearinventory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/clearinventory.png
--------------------------------------------------------------------------------
/web/img/clearped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/clearped.png
--------------------------------------------------------------------------------
/web/img/copy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/copy.png
--------------------------------------------------------------------------------
/web/img/dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/dashboard.png
--------------------------------------------------------------------------------
/web/img/freeze.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/freeze.png
--------------------------------------------------------------------------------
/web/img/giveadmin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/giveadmin.png
--------------------------------------------------------------------------------
/web/img/giveitem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/giveitem.png
--------------------------------------------------------------------------------
/web/img/givemoney.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/givemoney.png
--------------------------------------------------------------------------------
/web/img/goto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/goto.png
--------------------------------------------------------------------------------
/web/img/heal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/heal.png
--------------------------------------------------------------------------------
/web/img/invincible.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/invincible.png
--------------------------------------------------------------------------------
/web/img/invisibility.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/invisibility.png
--------------------------------------------------------------------------------
/web/img/jailhistory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/jailhistory.png
--------------------------------------------------------------------------------
/web/img/kick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/kick.png
--------------------------------------------------------------------------------
/web/img/kickhistory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/kickhistory.png
--------------------------------------------------------------------------------
/web/img/kill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/kill.png
--------------------------------------------------------------------------------
/web/img/lista_ban.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/lista_ban.png
--------------------------------------------------------------------------------
/web/img/lista_player.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/lista_player.png
--------------------------------------------------------------------------------
/web/img/logout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/logout.png
--------------------------------------------------------------------------------
/web/img/menu_personale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/menu_personale.png
--------------------------------------------------------------------------------
/web/img/noclip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/noclip.png
--------------------------------------------------------------------------------
/web/img/nomiplayer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/nomiplayer.png
--------------------------------------------------------------------------------
/web/img/player_online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/player_online.png
--------------------------------------------------------------------------------
/web/img/repairveh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/repairveh.png
--------------------------------------------------------------------------------
/web/img/revive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/revive.png
--------------------------------------------------------------------------------
/web/img/reviveall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/reviveall.png
--------------------------------------------------------------------------------
/web/img/sendmessage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/sendmessage.png
--------------------------------------------------------------------------------
/web/img/setjob.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/setjob.png
--------------------------------------------------------------------------------
/web/img/setped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/setped.png
--------------------------------------------------------------------------------
/web/img/skinmenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/skinmenu.png
--------------------------------------------------------------------------------
/web/img/spectate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/spectate.png
--------------------------------------------------------------------------------
/web/img/total_ban.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/total_ban.png
--------------------------------------------------------------------------------
/web/img/total_kick.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/total_kick.png
--------------------------------------------------------------------------------
/web/img/warn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/warn.png
--------------------------------------------------------------------------------
/web/img/warnhistory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/warnhistory.png
--------------------------------------------------------------------------------
/web/img/wipe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/212studio/nova_adminmenu/a4ad2a5bbd5de8c36f2a5a637cc4f5644841eea2/web/img/wipe.png
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
--------------------------------------------------------------------------------
/web/js/script.js:
--------------------------------------------------------------------------------
1 | const app = new Vue({
2 | el: '#app',
3 |
4 | data: {
5 |
6 | nomeRisorsa : GetParentResourceName(),
7 |
8 | findbyname : '',
9 |
10 | findbyidban : '',
11 |
12 | questionInfo : {},
13 |
14 | kickTotali : 0,
15 |
16 | radius : [],
17 |
18 | viewTwoQuestionInput : false,
19 | viewOneQuestionInput : false,
20 |
21 | listaBan : [],
22 |
23 | labelAdminJail : false,
24 | labelFreeze : false,
25 |
26 | orario : "",
27 |
28 | config : [],
29 |
30 | viewList : false,
31 |
32 | listType : false,
33 |
34 | adminOnline : 0,
35 |
36 | infoStaff : [],
37 |
38 | azioni : [],
39 |
40 | jobs : [],
41 |
42 | adminGroups : [],
43 |
44 | azioniPersonale : [],
45 |
46 | infoDashboard : [
47 | {
48 | label : '',
49 | img : 'admin_online.png',
50 | id : 'adminonline',
51 | value : 0
52 | },
53 | {
54 | label : '',
55 | img : 'player_online.png',
56 | id : 'playeronline',
57 | value : 3
58 | },
59 | {
60 | label : '',
61 | img : 'total_ban.png',
62 | id : 'totalban',
63 | value : 3
64 | },
65 | {
66 | label : '',
67 | img : 'total_kick.png',
68 | id : 'totalkick',
69 | value : 3
70 | },
71 | ],
72 |
73 | listaPlayer : [],
74 |
75 | optionSelected : 'dashboard',
76 |
77 | playerSelected : false,
78 |
79 | test : false,
80 | },
81 |
82 | methods: {
83 |
84 | postMessage(name, table) {
85 | $.post(`https://${this.nomeRisorsa}/${name}`, JSON.stringify(table))
86 | },
87 |
88 | updateSelectedOption(option) {
89 | this.optionSelected = option;
90 |
91 | var elements = document.getElementsByClassName("opzione");
92 | for (var i = 0; i < elements.length; i++) {
93 | elements[i].style.background = "none"
94 | }
95 |
96 | var element = document.getElementById("opzione"+option);
97 | element.style.backgroundColor = "#4B4B4B";
98 | this.viewList = false
99 | this.listType = false
100 | },
101 |
102 | updateOptionSelected(option) {
103 | this.optionSelected = option;
104 | },
105 |
106 | setBgFromInfo(img) {
107 | return {
108 | backgroundImage: 'url("img/'+img+'")'
109 | }
110 | },
111 |
112 | setLogoServer() {
113 | return {
114 | backgroundImage: url(this.config.LogoServer)
115 | }
116 | },
117 |
118 | setPlayerBg(player) {
119 | if(player.staff) {
120 | return {
121 | background: "linear-gradient(90deg, rgba(255, 12, 12, 0.40) 0%, rgba(0, 0, 0, 0.00) 100%), rgba(216, 216, 216, 0.05)"
122 | }
123 | } else {
124 | return {
125 | background: 'linear-gradient(90deg, rgba(236, 236, 236, 0.40) 0%, rgba(0, 0, 0, 0.00) 100%), rgba(216, 216, 216, 0.05)'
126 | }
127 | }
128 | },
129 |
130 | filterByName() {
131 | if(this.findbyname != '') {
132 | return this.listaPlayer.filter(player => {
133 | return (
134 | player.name.toLowerCase().includes(this.findbyname.toLowerCase()) ||
135 | player.id.toString().includes(this.findbyname.toLowerCase()) ||
136 | player.job.name.toLowerCase().includes(this.findbyname.toLowerCase()) ||
137 | player.job.label.toLowerCase().includes(this.findbyname.toLowerCase())
138 | )
139 | })
140 | } else {
141 | return this.listaPlayer
142 | }
143 | },
144 |
145 | filterByIdBan() {
146 | if(this.findbyidban != '') {
147 | return this.listaBan.filter(ban => {
148 | return (
149 | ban.idBan.toString().includes(this.findbyidban.toLowerCase()) ||
150 | ban.name.toLowerCase().includes(this.findbyidban.toLowerCase()) ||
151 | ban.staff.name.toLowerCase().includes(this.findbyidban.toLowerCase())
152 | )
153 | })
154 | } else {
155 | return this.listaBan
156 | }
157 | },
158 |
159 | infoUser(id) {
160 |
161 |
162 |
163 | this.viewList = false
164 | this.updateOptionSelected('infopersona');
165 | for(const[k,v] of Object.entries(this.listaPlayer)) {
166 | if(v.id == id) {
167 | this.playerSelected = v
168 | }
169 | }
170 |
171 | for(const[k,v] of Object.entries(this.azioni)) {
172 | if(v.id == 'adminjail' && this.playerSelected.inJail) {
173 | v.label = this.config.lang.unjail
174 | v.id = 'unjail'
175 | } else if(v.id == 'unjail' && !this.playerSelected.inJail) {
176 | v.label = this.labelAdminJail
177 | v.id = 'adminjail'
178 | }
179 |
180 | if(v.id == 'freeze' && this.playerSelected.freezed) {
181 | v.label = this.config.lang.unfreeze
182 | v.id = 'sfreeze'
183 | } else if(v.id == 'sfreeze' && !this.playerSelected.freezed) {
184 | v.label = this.labelFreeze
185 | v.id = 'freeze'
186 | }
187 | }
188 | },
189 |
190 | revocaBan(idban) {
191 | this.postMessage('revocaban', {
192 | id : idban
193 | })
194 | },
195 |
196 | setImageLogo(bool) {
197 | if(bool) {
198 | var link = this.infoStaff.avatar
199 | } else {
200 | var link = this.playerSelected.avatar
201 | }
202 | return {
203 | backgroundImage: 'url("'+link+'")'
204 | }
205 | },
206 |
207 | copy(type, bool) {
208 | if(type == 'discord') {
209 | if(bool) {
210 | string = this.infoStaff.license.discord
211 | } else {
212 | string = this.playerSelected.license.discord
213 | }
214 | } else if(type == 'steam') {
215 | if(bool) {
216 | string = this.infoStaff.license.steam
217 | } else {
218 | string = this.playerSelected.license.steam
219 | }
220 | } else if(type == 'license') {
221 | if(bool) {
222 | string = this.infoStaff.license.license
223 | } else {
224 | string = this.playerSelected.license.license
225 | }
226 | }
227 |
228 | var $temp = $("");
229 | $("body").append($temp);
230 | $temp.val(string).select();
231 | document.execCommand("copy");
232 | $temp.remove();
233 |
234 |
235 | },
236 |
237 | viewDoubleInput(bool) {
238 | this.viewTwoQuestionInput = bool
239 | },
240 |
241 | viewOneInput(bool) {
242 | this.viewOneQuestionInput = bool
243 | },
244 |
245 | setQuestionInformation(type) {
246 | return {
247 | background: 'radial-gradient(951.28% 203.42% at 6.89% 114.21%, '+this.questionInfo.color+' 0%, rgba(255, 255, 255, 0.82) 100%)'
248 | }
249 | },
250 |
251 | closeQuestion() {
252 | if(this.viewTwoQuestionInput) {
253 | this.viewTwoQuestionInput = false
254 | } else if(this.viewOneQuestionInput) {
255 | this.viewOneQuestionInput = false
256 | }
257 | },
258 |
259 | azione(id) {
260 | if(!this.playerSelected.id) {
261 | this.playerSelected = {}
262 | this.playerSelected.id = this.infoStaff.id
263 | }
264 | if(id == 'ban') {
265 | this.questionInfo = {
266 | title : this.config.lang.ban,
267 | color : '#fc1703',
268 | action : 'ban',
269 | input1 : {
270 | type : 'select',
271 | options : this.config.BanTime
272 | },
273 | input2 : {
274 | placeholder : this.config.lang.motivo,
275 | type : 'text'
276 | }
277 | }
278 | this.viewDoubleInput(true)
279 | } else if(id == 'kick') {
280 | this.questionInfo = {
281 | title : this.config.lang.kick,
282 | color : '#cfab1b',
283 | action : 'kick',
284 | input1 : {
285 | placeholder : this.config.lang.motivo,
286 | type : 'text',
287 | },
288 | }
289 | this.viewOneInput(true)
290 | } else if(id == 'adminjail') {
291 | this.questionInfo = {
292 | title : this.config.lang.jail,
293 | color : '#12a675',
294 | action : 'adminjail',
295 | input1 : {
296 | placeholder : this.config.lang.motivo,
297 | type : 'text'
298 | }
299 | }
300 | this.viewOneInput(true)
301 | } else if(id == 'warn') {
302 | this.questionInfo = {
303 | title : this.config.lang.warn,
304 | color : '#1250a6',
305 | action : 'warn',
306 | input1 : {
307 | placeholder : this.config.lang.motivo,
308 | type : 'text'
309 | }
310 | }
311 | this.viewOneInput(true)
312 | } else if(id == 'giveitem') {
313 | this.questionInfo = {
314 | title : this.config.lang.giveitem,
315 | color : 'green',
316 | action : 'giveitem',
317 | input1 : {
318 | placeholder : this.config.lang.item_name,
319 | type : 'text'
320 | },
321 | input2 : {
322 | placeholder : this.config.lang.item_count,
323 | type : 'number'
324 | }
325 | }
326 | this.viewDoubleInput(true)
327 | } else if(id == 'givemoney') {
328 | this.questionInfo = {
329 | title : this.config.lang.givemoney,
330 | color : 'grey',
331 | action : 'givemoney',
332 | input1 : {
333 | type : 'select',
334 | options : [
335 | {
336 | label : this.config.lang.cash,
337 | value : 'money'
338 | },
339 | {
340 | label : this.config.lang.bank,
341 | value : 'bank'
342 | },
343 | {
344 | label : this.config.lang.black_money,
345 | value : 'black_money'
346 | }
347 | ]
348 | },
349 | input2 : {
350 | placeholder : this.config.lang.count,
351 | type : 'number'
352 | }
353 | }
354 | this.viewDoubleInput(true)
355 | } else if(id == 'setjob') {
356 | this.questionInfo = {
357 | title : this.config.lang.setjob,
358 | color : '#09AA70',
359 | action : 'setjob',
360 | input1 : {
361 | options : this.jobs,
362 | type : 'select',
363 | },
364 | input2 : {
365 | placeholder : this.config.lang.job_grade,
366 | type : 'number'
367 | }
368 | }
369 | this.viewDoubleInput(true)
370 | } else if(id == 'sendmessage') {
371 | this.questionInfo = {
372 | title : this.config.lang.sendmessage,
373 | color : '#12c42f',
374 | action : 'dm',
375 | input1 : {
376 | placeholder : this.config.lang.text,
377 | type : 'text',
378 | },
379 | }
380 | this.viewOneInput(true)
381 | } else if(id == 'skinmenu') {
382 | this.postMessage('skinmenu', {
383 | id : this.playerSelected.id
384 | })
385 | if(this.playerSelected.id == this.infoStaff.id) {
386 | this.playerSelected = false
387 | this.postMessage('close')
388 | $("#app").fadeOut(500)
389 | }
390 | } else if(id == 'revive') {
391 | this.postMessage('revive', {
392 | id : this.playerSelected.id
393 | })
394 | $("#app").fadeOut(500)
395 | this.playerSelected = false
396 | this.postMessage('close')
397 | } else if(id == 'heal') {
398 | this.postMessage('heal', {
399 | id : this.playerSelected.id
400 | })
401 | $("#app").fadeOut(500)
402 | this.playerSelected = false
403 | this.postMessage('close')
404 | } else if(id == 'kill') {
405 | this.postMessage('kill', {
406 | id : this.playerSelected.id
407 | })
408 | $("#app").fadeOut(500)
409 | this.playerSelected = false
410 | this.postMessage('close')
411 | } else if(id == 'goto') {
412 | this.postMessage('goto', {
413 | id : this.playerSelected.id
414 | })
415 | $("#app").fadeOut(500)
416 | this.playerSelected = false
417 | this.postMessage('close')
418 | } else if(id == 'bring') {
419 | this.postMessage('bring', {
420 | id : this.playerSelected.id
421 | })
422 | $("#app").fadeOut(500)
423 | this.playerSelected = false
424 | this.postMessage('close')
425 | } else if(id == 'clearinventory') {
426 | this.postMessage('clearinv', {
427 | id : this.playerSelected.id
428 | })
429 | $("#app").fadeOut(500)
430 | this.playerSelected = false
431 | this.postMessage('close')
432 | } else if(id == 'unjail') {
433 | this.postMessage('unjail', {
434 | id : this.playerSelected.id
435 | })
436 | $("#app").fadeOut(500)
437 | this.playerSelected = false
438 | this.postMessage('close')
439 | } else if(id == 'wipe') {
440 | this.postMessage('wipe', {
441 | id : this.playerSelected.id
442 | })
443 | $("#app").fadeOut(500)
444 | this.playerSelected = false
445 | this.postMessage('close')
446 | } else if(id == "giveadmin") {
447 | this.questionInfo = {
448 | title : this.config.lang.giveadmin,
449 | color : '#78e827',
450 | action : 'giveadmin',
451 | input1 : {
452 | options : this.adminGroups,
453 | type : 'select',
454 | },
455 | }
456 | this.viewOneInput(true)
457 | } else if(id == "spectate") {
458 | if(this.playerSelected.id == this.infoStaff.id) {
459 | return
460 | }
461 | $("#app").fadeOut(500)
462 | this.postMessage('spectate', {
463 | id : this.playerSelected.id
464 | })
465 | } else if(id == "setped") {
466 | this.questionInfo = {
467 | title : this.config.lang.setped,
468 | color : '#621cbd',
469 | action : 'setped',
470 | input1 : {
471 | placeholder : this.config.lang.ped_name,
472 | type : 'text',
473 | },
474 | }
475 | this.viewOneInput(true)
476 | } else if(id == "freeze") {
477 | this.postMessage('freeze', {
478 | id : this.playerSelected.id
479 | })
480 | $("#app").fadeOut(500)
481 | this.playerSelected = false
482 | this.postMessage('close')
483 | } else if(id == "sfreeze") {
484 | this.postMessage('sfreeze', {
485 | id : this.playerSelected.id
486 | })
487 | $("#app").fadeOut(500)
488 | this.playerSelected = false
489 | this.postMessage('close')
490 | } else if(id == "noclip") {
491 | this.playerSelected = false
492 | $("#app").fadeOut(500)
493 | this.postMessage('noclip')
494 | } else if(id == "invisibilita") {
495 | this.playerSelected = false
496 | $("#app").fadeOut(500)
497 | this.postMessage('invisibilita')
498 | } else if(id== "godmode") {
499 | this.playerSelected = false
500 | $("#app").fadeOut(500)
501 | this.postMessage('godmode')
502 | } else if(id == "reviveall") {
503 | this.playerSelected = false
504 | $("#app").fadeOut(500)
505 | this.postMessage('reviveall')
506 | } else if(id == "annuncio") {
507 | this.questionInfo = {
508 | title : this.config.lang.annuncio,
509 | color : '#a84432',
510 | action : 'annuncio',
511 | input1 : {
512 | placeholder : this.config.lang.text,
513 | type : 'text',
514 | },
515 | }
516 | this.viewOneInput(true)
517 | } else if(id == "givemoneyall") {
518 | this.questionInfo = {
519 | title : this.config.lang.give_money_all,
520 | color : 'grey',
521 | action : 'givemoneyall',
522 | input1 : {
523 | type : 'select',
524 | options : [
525 | {
526 | label : this.config.lang.cash,
527 | value : 'money'
528 | },
529 | {
530 | label : this.config.lang.bank,
531 | value : 'bank'
532 | },
533 | {
534 | label : this.config.lang.black_money,
535 | value : 'black_money'
536 | }
537 | ]
538 | },
539 | input2 : {
540 | placeholder : this.config.lang.count,
541 | type : 'text',
542 | }
543 | }
544 | this.viewDoubleInput(true)
545 | } else if(id == "repairvehicle") {
546 | this.postMessage('repairvehicle')
547 | $("#app").fadeOut(500)
548 | this.playerSelected = false
549 | this.postMessage('close')
550 | }else if(id == "clearped") {
551 | this.postMessage('clearped', {
552 | id : this.playerSelected.id
553 | })
554 | $("#app").fadeOut(500)
555 | this.playerSelected = false
556 | this.postMessage('close')
557 | } else if(id =="nomiplayer") {
558 | $("#app").fadeOut(500)
559 | this.postMessage("close")
560 | this.postMessage("nomiplayer")
561 | } else if(id =="cleararea") {
562 | this.questionInfo = {
563 | title : this.config.lang.clear_area,
564 | color : '#f569e5',
565 | action : 'cleararea',
566 | input1 : {
567 | type : 'select',
568 | options : this.radius
569 | }
570 | }
571 | this.viewOneInput(true)
572 | }
573 | },
574 |
575 | confirmAction() {
576 | var action = this.questionInfo.action
577 | var value1 = $(".value1").val()
578 | var value2 = $(".value2").val()
579 |
580 | this.postMessage('action', {
581 | action : action,
582 | value1 : value1,
583 | value2 : value2,
584 | id : this.playerSelected.id
585 | })
586 | this.closeQuestion()
587 | $("#app").fadeOut(500)
588 | this.playerSelected = false
589 | this.postMessage('close')
590 | },
591 |
592 | updatePlayers(players) {
593 | this.listaPlayer = players
594 | if(this.playerSelected != false) {
595 | for(const[k,v] of Object.entries(players)) {
596 | if(v.id == this.playerSelected.id) {
597 | this.playerSelected = v
598 | }
599 | }
600 | }
601 |
602 | for(const[k,v] of Object.entries(this.azioni)) {
603 | if(v.id == 'adminjail' && this.playerSelected.inJail) {
604 | v.label = this.config.lang.unjail
605 | v.id = 'unjail'
606 | } else if(v.id == 'unjail' && !this.playerSelected.inJail) {
607 | v.label = this.labelAdminJail
608 | v.id = 'adminjail'
609 | }
610 |
611 |
612 | if(v.id == 'freeze' && this.playerSelected.freezed) {
613 | v.label = this.config.lang.unfreeze
614 | v.id = 'sfreeze'
615 | } else if(v.id == 'sfreeze' && !this.playerSelected.freezed) {
616 | v.label = this.labelFreeze
617 | v.id = 'freeze'
618 | }
619 | }
620 | },
621 |
622 |
623 | viewList1(id) {
624 | this.listType = id
625 | this.viewList = true
626 | },
627 |
628 | deleteWarn(index) {
629 | this.postMessage('deletewarn', {
630 | id : this.playerSelected.id,
631 | index : index
632 | })
633 | },
634 |
635 | setConfig(config) {
636 | this.config = config
637 | this.config.lang = config.Lang[config.Language]
638 |
639 | for(const[k,v] of Object.entries(this.infoDashboard)) {
640 | if(v.id == 'adminonline') {
641 | v.label = this.config.lang['staff_online']
642 | }
643 | if(v.id == 'playeronline') {
644 | v.label = this.config.lang['player_online']
645 | }
646 | if(v.id == 'totalban') {
647 | v.label = this.config.lang['ban_totali']
648 | }
649 | if(v.id == 'totalkick') {
650 | v.label = this.config.lang['kick_totali']
651 | }
652 | }
653 | },
654 |
655 | setAzioni(azioni) {
656 | this.azioni = azioni
657 |
658 | for(const[k,v] of Object.entries(this.azioni)) {
659 | if(v.id == 'adminjail') {
660 | this.labelAdminJail = v.label
661 | }
662 | if(v.id == 'freeze') {
663 | this.labelFreeze = v.label
664 | }
665 | }
666 | },
667 |
668 | setAzioniPersonale(azioni) {
669 | this.azioniPersonale = azioni
670 | },
671 |
672 | close() {
673 | $("#app").fadeOut(500)
674 | this.postMessage('close')
675 | },
676 |
677 | redirectPage(url) {
678 | window.invokeNative('openUrl', url)
679 | },
680 |
681 | getValue(id) {
682 | if(id == 'totalban') {
683 | return this.listaBan.length
684 | } else if(id == 'adminonline') {
685 | return this.adminOnline
686 | } else if(id == 'playeronline') {
687 | return this.listaPlayer.length
688 | } else if(id == 'totalkick') {
689 | return this.kickTotali
690 | }
691 | }
692 | }
693 |
694 | });
695 |
696 | window.addEventListener('message', function(event) {
697 | var data = event.data;
698 | if (data.type === "OPEN") {
699 | app.updateSelectedOption('dashboard')
700 | app.updatePlayers(data.players)
701 | $("#app").fadeIn(500)
702 | } else if(data.type === "UPDATE_PLAYERS") {
703 | app.updatePlayers(data.players)
704 | } else if(data.type === "SET_CONFIG") {
705 | app.setConfig(data.config)
706 | } else if(data.type === "SET_AZIONI") {
707 | app.setAzioni(data.azioni)
708 | } else if(data.type === "SET_AZIONI_PERSONALE") {
709 | app.setAzioniPersonale(data.azioni)
710 | } else if(data.type === "SET_INFO_STAFF") {
711 | app.infoStaff = data.info
712 | } else if(data.type === "SET_JOBS") {
713 | app.jobs = data.jobs
714 | } else if(data.type === "SET_ORARIO") {
715 | app.orario = data.orario
716 | } else if(data.type === "SET_ADMIN_GROUPS") {
717 | app.adminGroups = []
718 | app.adminGroups.push({
719 | label : app.config.lang['utente'],
720 | value : app.config.GroupUser
721 | })
722 | for(const[k,v] of Object.entries(data.groups)) {
723 | v.value = v.id
724 | if(v.rank <= app.infoStaff.rank) {
725 | app.adminGroups.push(v)
726 | }
727 | }
728 | } else if(data.type === "RESUME") {
729 | $("#app").fadeIn(500)
730 | } else if(data.type === "SET_BAN") {
731 | app.listaBan = data.ban
732 | } else if(data.type === "SET_ADMIN_ONLINE") {
733 | app.adminOnline = data.admin
734 | } else if(data.type === "SHOW_ANNOUNCE") {
735 | $(".message").fadeIn(500)
736 | $(".titleMsg").html(app.config.lang.annuncio)
737 | $(".subtitleMsg").html(data.text)
738 | setTimeout(function() {
739 | $(".message").fadeOut(500)
740 | }, 9000)
741 | } else if(data.type === "SHOW_DM_MESSAGE") {
742 | $(".message").fadeIn(500)
743 | $(".titleMsg").html(app.config.lang.dmmessage)
744 | $(".subtitleMsg").html(data.text)
745 | setTimeout(function() {
746 | $(".message").fadeOut(500)
747 | }, 9000)
748 | } else if(data.type === "SET_KICKS") {
749 | app.kickTotali = data.kicks
750 | } else if(data.type === "SET_SERVER_LOGO") {
751 | var logo = document.getElementsByClassName("serverLogo")[0]
752 | logo.style.backgroundImage= 'url("'+data.logo+'")'
753 | } else if(data.type === "SET_RADIUS") {
754 | app.radius = data.radius
755 | }
756 | })
757 |
758 |
759 | document.onkeyup = function (data) {
760 | if (data.key == 'Escape' && app.optionSelected == 'infopersona' && !app.viewList) {
761 | app.updateSelectedOption('listaplayer')
762 | app.playerSelected = false
763 | } else if(data.key == 'Escape' && app.viewList) {
764 | app.viewList = false
765 | } else if(data.key == 'Escape') {
766 | app.close()
767 | }
768 |
769 | };
770 |
--------------------------------------------------------------------------------