diff --git a/client/actions.lua b/client/actions.lua index 5f152c5e..00eb9144 100644 --- a/client/actions.lua +++ b/client/actions.lua @@ -1,8 +1,32 @@ QBCore = exports['qb-core']:GetCoreObject() -- Admin Car +local function getVehicleFromVehList(hash) + for _, v in pairs(QBCore.Shared.Vehicles) do + if hash == v.hash then + return v.model + end + end +end RegisterNetEvent('ps-adminmenu:client:Admincar', function(data) print("AdminCarTriggerd") + local ped = PlayerPedId() + local veh = GetVehiclePedIsIn(ped) + + if veh ~= nil and veh ~= 0 then + local plate = QBCore.Functions.GetPlate(veh) + local props = QBCore.Functions.GetVehicleProperties(veh) + local hash = props.model + local vehname = getVehicleFromVehList(hash) + if QBCore.Shared.Vehicles[vehname] ~= nil and next(QBCore.Shared.Vehicles[vehname]) ~= nil then + TriggerServerEvent('ps-adminmenu:server:SaveCar', props, QBCore.Shared.Vehicles[vehname], GetHashKey(veh), plate) + else + QBCore.Functions.Notify(Lang:t("error.cannot_store_veh"), 'error') + + end + else + QBCore.Functions.Notify(Lang:t("error.not_in_veh"), 'error') + end end) -- Invisible @@ -10,9 +34,164 @@ RegisterNetEvent('ps-adminmenu:client:ToggleInvisible', function(data) local ped = PlayerPedId() if not invisible then invisible = true + QBCore.Functions.Notify(Lang:t("info.invisible", {value = "on"}), 'inform') SetEntityVisible(ped, false, 0) else invisible = false SetEntityVisible(ped, true, 0) + QBCore.Functions.Notify(Lang:t("info.invisible", {value = "off"}), 'inform') + end +end) + +-- godmode +local Godmode = false +RegisterNetEvent('ps-adminmenu:client:ToggleGodmode', function(data) + godmode = not godmode + + if godmode then + QBCore.Functions.Notify(Lang:t("info.godmode", {value = "enabled"}), 'inform') + while godmode do + Wait(0) + SetPlayerInvincible(PlayerId(), true) + end + SetPlayerInvincible(PlayerId(), false) + QBCore.Functions.Notify(Lang:t("info.godmode", {value = "disabled"}), 'inform') end -end) \ No newline at end of file +end) + + + +-- Time +RegisterNetEvent('ps-adminmenu:client:ChangeTime', function(inputData) + local time = inputData["Time"] + print(time) + TriggerServerEvent('qb-weathersync:server:setTime', time) +end) + +-- weather +RegisterNetEvent('ps-adminmenu:client:ChangeWeather', function(inputData) + local weatherType = inputData["Weather"] + -- print(weatherType) + TriggerServerEvent('qb-weathersync:server:setWeather', weatherType) + QBCore.Functions.Notify(Lang:t("info.weatherType", {value = weatherType})) +end) + +-- Teleport back +local function teleport(vehicle, x, y, z) + local ped = PlayerPedId() + if vehicle then + return SetPedCoordsKeepVehicle(ped, x, y, z) + end + SetEntityCoords(ped, x, y, z, false, false, false, false) +end + +local lastCoords +RegisterNetEvent('ps-adminmenu:client:TeleportBack', function(coords) + local ped = PlayerPedId() + local vehicle = GetVehiclePedIsIn(ped, false) + if lastCoords then + local currentCoords = GetEntityCoords(ped) + teleport(vehicle, lastCoords.x, lastCoords.y, lastCoords.z) + lastCoords = currentCoords + end +end) +-- tp to player +RegisterNetEvent('ps-adminmenu:client:TeleportToPlayer', function(coords) + local ped = PlayerPedId() + lastCoords = GetEntityCoords(ped) + SetPedCoordsKeepVehicle(ped, coords.x, coords.y, coords.z) +end) +-- tp to coords +RegisterNetEvent('ps-adminmenu:client:TeleportToCoords', function(x, y, z, h) + local ped = PlayerPedId() + lastCoords = GetEntityCoords(ped) + SetPedCoordsKeepVehicle(ped, x, y, z) + SetEntityHeading(ped, h or GetEntityHeading(ped)) +end) +-- tp to marker +RegisterNetEvent('ps-adminmenu:client:TeleportToMarker', function() + local PlayerPedId = PlayerPedId + local GetEntityCoords = GetEntityCoords + local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord + + local blipMarker = GetFirstBlipInfoId(8) + if not DoesBlipExist(blipMarker) then + QBCore.Functions.Notify(Lang:t("error.no_waypoint"), "error", 5000) + return 'marker' + end + + -- Fade screen to hide how clients get teleported. + DoScreenFadeOut(650) + while not IsScreenFadedOut() do + Wait(0) + end + + local ped, coords = PlayerPedId(), GetBlipInfoIdCoord(blipMarker) + local vehicle = GetVehiclePedIsIn(ped, false) + local oldCoords = GetEntityCoords(ped) + lastCoords = GetEntityCoords(ped) + + -- Unpack coords instead of having to unpack them while iterating. + -- 825.0 seems to be the max a player can reach while 0.0 being the lowest. + local x, y, groundZ, Z_START = coords['x'], coords['y'], 850.0, 950.0 + local found = false + if vehicle > 0 then + FreezeEntityPosition(vehicle, true) + else + FreezeEntityPosition(ped, true) + end + + for i = Z_START, 0, -25.0 do + local z = i + if (i % 2) ~= 0 then + z = Z_START - i + end + + NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0) + local curTime = GetGameTimer() + while IsNetworkLoadingScene() do + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + NewLoadSceneStop() + SetPedCoordsKeepVehicle(ped, x, y, z) + + while not HasCollisionLoadedAroundEntity(ped) do + RequestCollisionAtCoord(x, y, z) + if GetGameTimer() - curTime > 1000 then + break + end + Wait(0) + end + + -- Get ground coord. As mentioned in the natives, this only works if the client is in render distance. + found, groundZ = GetGroundZFor_3dCoord(x, y, z, false); + if found then + Wait(0) + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + break + end + Wait(0) + end + + -- Remove black screen once the loop has ended. + DoScreenFadeIn(650) + if vehicle > 0 then + FreezeEntityPosition(vehicle, false) + else + FreezeEntityPosition(ped, false) + end + + if not found then + -- If we can't find the coords, set the coords to the old ones. + -- We don't unpack them before since they aren't in a loop and only called once. + SetPedCoordsKeepVehicle(ped, oldCoords['x'], oldCoords['y'], oldCoords['z'] - 1.0) + QBCore.Functions.Notify(Lang:t("error.tp_error"), "error", 5000) + end + + -- If Z coord was found, set coords in found coords. + SetPedCoordsKeepVehicle(ped, x, y, groundZ) + QBCore.Functions.Notify(Lang:t("success.teleported_waypoint"), "success", 5000) +end) diff --git a/fxmanifest.lua b/fxmanifest.lua index 27a313b0..f1376bcf 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -14,15 +14,18 @@ ui_page 'html/index.html' -- ui_page 'http://localhost:3000/' --for dev client_script { - 'client/**', + 'client/**', +} +server_scripts { + "@oxmysql/lib/MySQL.lua", + "server/**", } -server_script { - "server/**", - } shared_script { - "shared/**", - } + '@qb-core/shared/locale.lua', + 'locales/en.lua', + "shared/**", +} files { - 'html/**', + 'html/**', } diff --git a/locales/en.lua b/locales/en.lua new file mode 100644 index 00000000..12b70bfa --- /dev/null +++ b/locales/en.lua @@ -0,0 +1,31 @@ +local Translations = { + error = { + ["u_veh_owner"] = "This vehicle is already yours..", + ['cannot_store_veh'] = "Cannot store this car in your garage", + ["not_in_veh"] = "You are not in a vehicle..", + ["no_perms"] = "You do not have permission to do this", + ["missing_args"] = 'Not every argument has been entered (x, y, z)', + ["not_online"] = 'Player not online', + ['no_waypoint'] = 'No Waypoint Set.', + ["tp_error"] = 'Error While Teleporting.', + }, + success = { + ["veh_owner"] = "The vehicle is now yours!", + ["teleported_waypoint"] = 'Teleported To Waypoint.', + }, + info = { + ["godmode"] = "Godmode is %{value}", + ["invisible"] = "Invisible: %{value}", + ["banreason"] = 'Reason: %{reason}, until %{lenght}', + ["weatherType"] = "Weather is changed to: %{value}", + ["ban_perm"] = "\n\nYour ban is permanent.\n🔸 Check our Discord for more information: ", + ["ban_expires"] = "\n\nBan expires: ", + ["banned"] = "You have been banned:", + }, + +} + +Lang = Locale:new({ + phrases = Translations, + warnOnMissing = true +}) diff --git a/server/server.lua b/server/server.lua index 9ec0d1dd..12737482 100644 --- a/server/server.lua +++ b/server/server.lua @@ -1,5 +1,9 @@ QBCore = exports['qb-core']:GetCoreObject() +local function NoPerms(source) + QBCore.Functions.Notify(source, Lang:t('error.no_perms'), 'error') +end + RegisterNetEvent('ps-adminmenu:client:Getresources', function(data) local totalResources = GetNumResources() -- print("total " .. totalResources) @@ -35,3 +39,123 @@ RegisterNetEvent('ps-adminmenu:server:changeResourceState', function(name, state StartResource(name) end end) +--admincar +RegisterNetEvent('ps-adminmenu:server:SaveCar', function(mods, vehicle, _, plate) + local src = source + if not QBCore.Functions.HasPermission(src, "mod") then NoPerms(src) return end + local Player = QBCore.Functions.GetPlayer(src) + local result = MySQL.query.await('SELECT plate FROM player_vehicles WHERE plate = ?', { plate }) + if result[1] == nil then + MySQL.insert('INSERT INTO player_vehicles (license, citizenid, vehicle, hash, mods, plate, state) VALUES (?, ?, ?, ?, ?, ?, ?)', { + Player.PlayerData.license, + Player.PlayerData.citizenid, + vehicle.model, + vehicle.hash, + json.encode(mods), + plate, + 0 + }) + TriggerClientEvent('QBCore:Notify', src, Lang:t("success.veh_owner"), 'success', 5000) + else + TriggerClientEvent('QBCore:Notify', src, Lang:t("error.u_veh_owner"), 'error', 3000) + end + +end) + +--ban player +RegisterNetEvent('ps-adminmenu:server:BanPlayer', function(inputData) + local src = source + local playerid = inputData["Player ID"] + local reason = inputData["Reason"] + local time = inputData["Time"] + if not QBCore.Functions.HasPermission(src, "admin") then NoPerms(src) return end + time = tonumber(time) + local banTime = tonumber(os.time() + time) + if banTime > 2147483647 then + banTime = 2147483647 + end + local timeTable = os.date('*t', banTime) + MySQL.insert('INSERT INTO bans (name, license, discord, ip, reason, expire, bannedby) VALUES (?, ?, ?, ?, ?, ?, ?)', { + GetPlayerName(playerid), + QBCore.Functions.GetIdentifier(playerid, 'license'), + QBCore.Functions.GetIdentifier(playerid, 'discord'), + QBCore.Functions.GetIdentifier(playerid, 'ip'), + reason, + banTime, + GetPlayerName(src) + }) + if banTime >= 2147483647 then + DropPlayer(playerid, Lang:t("info.banned") .. '\n' .. reason .. Lang:t("info.ban_perm") .. QBCore.Config.Server.Discord) + else + DropPlayer(playerid, Lang:t("info.banned") .. '\n' .. reason .. Lang:t("info.ban_expires") .. timeTable['day'] .. '/' .. timeTable['month'] .. '/' .. timeTable['year'] .. ' ' .. timeTable['hour'] .. ':' .. timeTable['min'] .. '\n🔸 Check our Discord for more information: ' .. QBCore.Config.Server.Discord) + end + +end) + +-- bring player +RegisterNetEvent('ps-adminmenu:server:BringPlayer', function(inputData) + local src = source + local targetPed = inputData["Player ID"] + + if not QBCore.Functions.HasPermission(src, "mod") then NoPerms(src) return end + local admin = GetPlayerPed(src) + local coords = GetEntityCoords(admin) + local target = GetPlayerPed(targetPed) + SetEntityCoords(target, coords) + +end) + +-- teleport to player +RegisterNetEvent('ps-adminmenu:server:TeleportToPlayer', function(inputData) + local src = source + + if not QBCore.Functions.HasPermission(src, "mod") then NoPerms(src) return end + local target = GetPlayerPed(tonumber(inputData["Player ID"])) + if target ~= 0 then + local coords = GetEntityCoords(target) + TriggerClientEvent('ps-adminmenu:client:TeleportToPlayer', src, coords) + else + TriggerClientEvent('QBCore:Notify', src, Lang:t('error.not_online'), 'error') + end +end) + +-- teleport to coords +RegisterNetEvent('ps-adminmenu:server:TeleportToCoords', function(inputData) + local src = source + local xdata = inputData["X"] + local ydata = inputData["Y"] + local zdata = inputData["Z"] + + if not QBCore.Functions.HasPermission(src, "mod") then NoPerms(src) return end + if xdata and ydata and zdata then + local x = tonumber((xdata:gsub(",",""))) + .0 + local y = tonumber((ydata:gsub(",",""))) + .0 + local z = tonumber((zdata:gsub(",",""))) + .0 + TriggerClientEvent('ps-adminmenu:client:TeleportToCoords', src, x, y, z) + + else + TriggerClientEvent('QBCore:Notify', src, Lang:t('error.missing_args'), 'error') + end + +end) + +-- heal player +RegisterNetEvent('ps-adminmenu:server:Revive', function(inputData) + local src = source + print(inputData) + local id = inputData["Player ID"] + if not QBCore.Functions.HasPermission(src, "mod") then NoPerms(src) return end + if type(id) ~= 'string' and type(id) ~= 'number' then + return + end + id = tonumber(id) + + TriggerClientEvent('hospital:client:Revive', id) +end) + +-- heal all players +RegisterNetEvent('ps-adminmenu:server:ReviveAll', function() + local src = source + if not QBCore.Functions.HasPermission(src, "admin") then NoPerms(src) return end + TriggerClientEvent('hospital:client:Revive', -1) +end) diff --git a/shared/config.lua b/shared/config.lua index be8abacb..e412bcf5 100644 --- a/shared/config.lua +++ b/shared/config.lua @@ -14,28 +14,65 @@ Config.Actions = { dropdown = { { label = "Player ID", type = "input", inputtype = "normal" }, { label = "Reason", type = "input", inputtype = "normal" }, - { label = "Time", type = "input", inputtype = "normal" }, - { label = "Ban", type = "button", event = "ps-adminmenu:client:banplayer" }, + { label = "Time", type = "options", + options = { + { label = "10 Minutes", value = "600"}, + { label = "30 Minutes", value = "1800"}, + { label = "1 Hour", value = "3600"}, + { label = "6 Hours", value = "21600"}, + { label = "12 Hours", value = "43200"}, + { label = "1 Day", value = "86400"}, + { label = "3 Days", value = "259200"}, + { label = "1 Week", value = "604800"}, + { label = "Permanent", value = "315360000"}, + }, + }, + { label = "Ban", type = "button", event = "ps-adminmenu:server:BanPlayer" }, }, }, { label = "Bring Player", - event = "ps-adminmenu:client:BringPlayer", - type = "client", + type = "server", perms = "mod", dropdown = { { label = "Player ID", type = "input", inputtype = "normal" }, - { label = "Bring", type = "button", event = "" }, + { label = "Bring", type = "button", event = "ps-adminmenu:server:BringPlayer" }, }, }, { label = "Change Weather", - event = "ps-adminmenu:client:ChangeWeather", type = "client", perms = "mod", dropdown = { - { label = "Wheather", type = "input", inputtype = "normal" }, - { label = "Change", type = "button", event = "" }, + { label = "Weather", type = "options", + options = { + { label = "Extrasunny", value = "Extrasunny"}, + { label = "Clear", value = "Clear"}, + { label = "Neutral", value = "Neutral"}, + { label = "Smog", value = "Smog"}, + { label = "Foggy", value = "Foggy"}, + { label = "Overcast", value = "Overcast"}, + { label = "Clouds", value = "Clouds"}, + { label = "Clearing", value = "Clearing"}, + { label = "Rain", value = "Rain"}, + { label = "Thunder", value = "Thunder"}, + { label = "Snow", value = "Snow"}, + { label = "Blizzard", value = "Blizzard"}, + { label = "Snowlight", value = "Snowlight"}, + { label = "Xmas", value = "Xmas"}, + { label = "Halloween", value = "Halloween"}, + }, + }, + { label = "Change", type = "button", event = "ps-adminmenu:client:ChangeWeather" }, + }, + }, + { + label = "Change Time", + type = "client", + perms = "mod", + dropdown = { + { label = "Time", type = "input", inputtype = "normal" }, + { label = "Change", type = "button", event = "ps-adminmenu:client:ChangeTime" }, }, }, { @@ -152,18 +189,17 @@ Config.Actions = { }, { label = "Revive Player", - event = "ps-adminmenu:client:Revive Player", - type = "client", + type = "server", perms = "mod", dropdown = { { label = "Player ID", type = "input", inputtype = "normal" }, - { label = "Revive", type = "button", event = "ps-adminmenu:client:banplayer" }, + { label = "Revive", type = "button", event = "ps-adminmenu:server:Revive" }, }, }, { label = "Revive All", - event = "ps-adminmenu:client:ReviveAll", - type = "client" + event = "ps-adminmenu:server:ReviveAll", + type = "server" }, { label = "Revive Radius", @@ -204,22 +240,22 @@ Config.Actions = { }, { label = "Teleport To Player", - event = "ps-adminmenu:client:TeleportToPlayer", - type = "client", + type = "server", perms = "mod", dropdown = { { label = "Player ID", type = "input", inputtype = "normal" }, - { label = "Teleport", type = "button", event = "ps-adminmenu:client:banplayer" }, + { label = "Teleport", type = "button", event = "ps-adminmenu:server:TeleportToPlayer" }, }, }, { - label = "Teleport To Coordinates", - event = "ps-adminmenu:client:TeleportToCoords", - type = "client", + label = "Teleport To Coordinates", + type = "server", perms = "mod", dropdown = { - { label = "Coordinates", type = "input", inputtype = "normal" }, - { label = "Teleport", type = "button", event = "ps-adminmenu:client:banplayer" }, + { label = "X", type = "input", inputtype = "normal" }, + { label = "Y", type = "input", inputtype = "normal" }, + { label = "Z", type = "input", inputtype = "normal" }, + { label = "Teleport", type = "button", event = "ps-adminmenu:server:TeleportToCoords" }, }, }, { @@ -227,6 +263,11 @@ Config.Actions = { event = "ps-adminmenu:client:TeleportToMarker", type = "client" }, + { + label = "Teleport Back", + event = "ps-adminmenu:client:TeleportBack", + type = "client" + }, { label = "Unban Player", event = "ps-adminmenu:client:UnbanPlayer",