2026-04-14 17:41:39 +02:00

773 lines
28 KiB
Lua

SetMapName("San Andreas")
SetGameType("ESX Legacy")
local oneSyncState = GetConvar("onesync", "off")
local newPlayer = "INSERT INTO `users` SET `accounts` = ?, `identifier` = ?, `ssn` = ?, `group` = ?"
local loadPlayer = "SELECT `accounts`, `ssn`, `job`, `job_grade`, `group`, `position`, `inventory`, `skin`, `loadout`, `metadata`"
if Config.Multichar then
newPlayer = newPlayer .. ", `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?"
end
if Config.StartingInventoryItems then
newPlayer = newPlayer .. ", `inventory` = ?"
end
if Config.Multichar or Config.Identity then
loadPlayer = loadPlayer .. ", `firstname`, `lastname`, `dateofbirth`, `sex`, `height`"
end
loadPlayer = loadPlayer .. " FROM `users` WHERE identifier = ?"
local function createESXPlayer(identifier, playerId, data)
local accounts = {}
for account, money in pairs(Config.StartingAccountMoney) do
accounts[account] = money
end
local defaultGroup = "user"
if Core.IsPlayerAdmin(playerId) then
print(("[^2INFO^0] Player ^5%s^0 Has been granted admin permissions via ^5Ace Perms^7."):format(playerId))
defaultGroup = "admin"
end
local parameters = Config.Multichar and
{ json.encode(accounts), identifier, Core.generateSSN(), defaultGroup, data.firstname, data.lastname, data.dateofbirth, data.sex, data.height }
or { json.encode(accounts), identifier, Core.generateSSN(), defaultGroup }
if Config.StartingInventoryItems then
table.insert(parameters, json.encode(Config.StartingInventoryItems))
end
MySQL.prepare(newPlayer, parameters, function()
loadESXPlayer(identifier, playerId, true)
end)
end
local function onPlayerJoined(playerId)
local identifier = ESX.GetIdentifier(playerId)
if not identifier then
return DropPlayer(playerId, "there was an error loading your character!\nError code: identifier-missing-ingame\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.")
end
if ESX.GetPlayerFromIdentifier(identifier) then
DropPlayer(
playerId,
("there was an error loading your character!\nError code: identifier-active-ingame\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same Rockstar account.\n\nYour Rockstar identifier: %s"):format(
identifier
)
)
else
local result = MySQL.scalar.await("SELECT 1 FROM users WHERE identifier = ?", { identifier })
if result then
loadESXPlayer(identifier, playerId, false)
else
createESXPlayer(identifier, playerId)
end
end
end
---@param playerId number
---@param reason string
---@param cb function?
local function onPlayerDropped(playerId, reason, cb)
local p = not cb and promise:new()
local function resolve()
if cb then
return cb()
elseif(p) then
return p:resolve()
end
end
local xPlayer = ESX.GetPlayerFromId(playerId)
if not xPlayer then
return resolve()
end
TriggerEvent("esx:playerDropped", playerId, reason)
local job = xPlayer.getJob().name
local currentJob = Core.JobsPlayerCount[job]
Core.JobsPlayerCount[job] = ((currentJob and currentJob > 0) and currentJob or 1) - 1
GlobalState[("%s:count"):format(job)] = Core.JobsPlayerCount[job]
Core.SavePlayer(xPlayer, function()
GlobalState["playerCount"] = GlobalState["playerCount"] - 1
ESX.Players[playerId] = nil
Core.playersByIdentifier[xPlayer.identifier] = nil
resolve()
end)
if p then
return Citizen.Await(p)
end
end
AddEventHandler("esx:onPlayerDropped", onPlayerDropped)
if Config.Multichar then
AddEventHandler("esx:onPlayerJoined", function(src, char, data)
while not next(ESX.Jobs) do
Wait(50)
end
if not ESX.Players[src] then
local identifier = char .. ":" .. ESX.GetIdentifier(src)
if data then
createESXPlayer(identifier, src, data)
else
loadESXPlayer(identifier, src, false)
end
end
end)
else
RegisterNetEvent("esx:onPlayerJoined", function()
local _source = source
while not next(ESX.Jobs) do
Wait(50)
end
if not ESX.Players[_source] then
onPlayerJoined(_source)
end
end)
end
if not Config.Multichar then
AddEventHandler("playerConnecting", function(_, _, deferrals)
local playerId = source
deferrals.defer()
Wait(0) -- Required
local identifier
local correctLicense, _ = pcall(function ()
identifier = ESX.GetIdentifier(playerId)
end)
-- luacheck: ignore
if not SetEntityOrphanMode then
return deferrals.done(("[ESX] ESX Requires a minimum Artifact version of 10188, Please update your server."))
end
if oneSyncState == "off" or oneSyncState == "legacy" then
return deferrals.done(("[ESX] ESX Requires Onesync Infinity to work. This server currently has Onesync set to: %s"):format(oneSyncState))
end
if not Core.DatabaseConnected then
return deferrals.done("[ESX] OxMySQL Was Unable To Connect to your database. Please make sure it is turned on and correctly configured in your server.cfg")
end
if not identifier or not correctLicense then
if GetResourceState("esx_identity") ~= "started" then
return deferrals.done("[ESX] There was an error loading your character!\nError code: identifier-missing\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.")
end
end
local xPlayer = ESX.GetPlayerFromIdentifier(identifier)
if not xPlayer then
return deferrals.done()
end
if GetPlayerPing(xPlayer.source --[[@as string]]) > 0 then
return deferrals.done(
("[ESX] There was an error loading your character!\nError code: identifier-active\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same account.\n\nYour identifier: %s"):format(identifier)
)
end
deferrals.update(("[ESX] Cleaning stale player entry..."):format(identifier))
onPlayerDropped(xPlayer.source, "esx_stale_player_obj")
deferrals.done()
end)
end
function loadESXPlayer(identifier, playerId, isNew)
local userData = {
accounts = {},
inventory = {},
loadout = {},
weight = 0,
name = GetPlayerName(playerId),
identifier = identifier,
firstName = "John",
lastName = "Doe",
dateofbirth = "01/01/2000",
height = 120,
dead = false,
}
local result = MySQL.prepare.await(loadPlayer, { identifier })
-- Accounts
local accounts = result.accounts
accounts = (accounts and accounts ~= "") and json.decode(accounts) or {}
for account, data in pairs(Config.Accounts) do
data.round = data.round or data.round == nil
local index = #userData.accounts + 1
userData.accounts[index] = {
name = account,
money = accounts[account] or Config.StartingAccountMoney[account] or 0,
label = data.label,
round = data.round,
index = index,
}
end
-- Job
local job, grade = result.job, tostring(result.job_grade)
if not ESX.DoesJobExist(job, grade) then
print(("[^3WARNING^7] Ignoring invalid job for ^5%s^7 [job: ^5%s^7, grade: ^5%s^7]"):format(identifier, job, grade))
job, grade = "unemployed", "0"
end
local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade]
userData.job = {
id = jobObject.id,
name = jobObject.name,
label = jobObject.label,
grade = tonumber(grade),
grade_name = gradeObject.name,
grade_label = gradeObject.label,
grade_salary = gradeObject.salary,
skin_male = gradeObject.skin_male and json.decode(gradeObject.skin_male) or {},
skin_female = gradeObject.skin_female and json.decode(gradeObject.skin_female) or {},
}
-- Group
if result.group then
if result.group == "superadmin" then
userData.group = "admin"
print("[^3WARNING^7] ^5Superadmin^7 detected, setting group to ^5admin^7")
else
userData.group = result.group
end
else
userData.group = "user"
end
-- Loadout
if result.loadout and result.loadout ~= "" then
local loadout = json.decode(result.loadout)
for name, weapon in pairs(loadout) do
local label = ESX.GetWeaponLabel(name)
if label then
userData.loadout[#userData.loadout + 1] = {
name = name,
ammo = weapon.ammo,
label = label,
components = weapon.components or {},
tintIndex = weapon.tintIndex or 0,
}
end
end
end
-- Position
userData.coords = json.decode(result.position) or Config.DefaultSpawns[ESX.Math.Random(1, #Config.DefaultSpawns)]
-- Skin
userData.skin = (result.skin and result.skin ~= "") and json.decode(result.skin) or { sex = userData.sex == "f" and 1 or 0 }
-- Metadata
userData.metadata = (result.metadata and result.metadata ~= "") and json.decode(result.metadata) or {}
-- xPlayer Creation
local xPlayer = CreateExtendedPlayer(
playerId,
identifier,
nil,
userData.group,
userData.accounts,
userData.inventory,
userData.weight,
userData.job,
userData.loadout,
GetPlayerName(playerId),
userData.coords,
userData.metadata
)
GlobalState["playerCount"] = GlobalState["playerCount"] + 1
ESX.Players[playerId] = xPlayer
Core.playersByIdentifier[identifier] = xPlayer
-- Identity
if result.firstname and result.firstname ~= "" then
userData.firstName = result.firstname
userData.lastName = result.lastname
local name = ("%s %s"):format(result.firstname, result.lastname)
userData.name = name
xPlayer.set("firstName", result.firstname)
xPlayer.set("lastName", result.lastname)
xPlayer.setName(name)
if result.dateofbirth then
userData.dateofbirth = result.dateofbirth
xPlayer.set("dateofbirth", result.dateofbirth)
end
if result.sex then
userData.sex = result.sex
xPlayer.set("sex", result.sex)
end
if result.height then
userData.height = result.height
xPlayer.set("height", result.height)
end
end
local inventory = exports['codem-inventory']:LoadInventory(playerId)
xPlayer.set('inv', inventory)
userData.inventory = inventory
TriggerEvent("esx:playerLoaded", playerId, xPlayer, isNew)
userData.money = xPlayer.getMoney()
userData.maxWeight = xPlayer.getMaxWeight()
userData.variables = xPlayer.variables or {}
xPlayer.triggerEvent("esx:playerLoaded", userData, isNew, userData.skin)
xPlayer.triggerEvent("esx:registerSuggestions", Core.RegisteredCommands)
print(('[^2INFO^0] Player ^5"%s"^0 has connected to the server. ID: ^5%s^7'):format(xPlayer.getName(), playerId))
end
AddEventHandler("chatMessage", function(playerId, _, message)
local xPlayer = ESX.GetPlayerFromId(playerId)
if xPlayer and message:sub(1, 1) == "/" and playerId > 0 then
CancelEvent()
local commandName = message:sub(1):gmatch("%w+")()
xPlayer.showNotification(TranslateCap("commanderror_invalidcommand", commandName))
end
end)
---@param reason string
AddEventHandler("playerDropped", function(reason)
onPlayerDropped(source --[[@as number]], reason)
end)
AddEventHandler("esx:playerLoaded", function(_, xPlayer, isNew)
local job = xPlayer.getJob().name
local jobKey = ("%s:count"):format(job)
Core.JobsPlayerCount[job] = (Core.JobsPlayerCount[job] or 0) + 1
GlobalState[jobKey] = Core.JobsPlayerCount[job]
if isNew then
Player(xPlayer.source).state:set('isNew', true, false)
end
end)
AddEventHandler("esx:setJob", function(_, job, lastJob)
local lastJobKey = ("%s:count"):format(lastJob.name)
local jobKey = ("%s:count"):format(job.name)
local currentLastJob = Core.JobsPlayerCount[lastJob.name]
Core.JobsPlayerCount[lastJob.name] = ((currentLastJob and currentLastJob > 0) and currentLastJob or 1) - 1
Core.JobsPlayerCount[job.name] = (Core.JobsPlayerCount[job.name] or 0) + 1
GlobalState[lastJobKey] = Core.JobsPlayerCount[lastJob.name]
GlobalState[jobKey] = Core.JobsPlayerCount[job.name]
end)
AddEventHandler("esx:playerLogout", function(playerId, cb)
onPlayerDropped(playerId, "esx_player_logout", cb)
TriggerClientEvent("esx:onPlayerLogout", playerId)
end)
if not Config.CustomInventory then
RegisterNetEvent("esx:updateWeaponAmmo", function(weaponName, ammoCount)
local xPlayer = ESX.GetPlayerFromId(source)
if xPlayer then
xPlayer.updateWeaponAmmo(weaponName, ammoCount)
end
end)
RegisterNetEvent("esx:giveInventoryItem", function(target, itemType, itemName, itemCount)
local playerId = source
local sourceXPlayer = ESX.GetPlayerFromId(playerId)
local targetXPlayer = ESX.GetPlayerFromId(target)
local distance = #(GetEntityCoords(GetPlayerPed(playerId)) - GetEntityCoords(GetPlayerPed(target)))
if not sourceXPlayer or not targetXPlayer or distance > Config.DistanceGive then
print(("[^3WARNING^7] Player Detected Cheating: ^5%s^7"):format(GetPlayerName(playerId)))
return
end
if itemType == "item_standard" then
local sourceItem = sourceXPlayer.getInventoryItem(itemName)
if not sourceItem then
return
end
if itemCount < 1 or sourceItem.count < itemCount then
return sourceXPlayer.showNotification(TranslateCap("imp_invalid_quantity"))
end
if not targetXPlayer.canCarryItem(itemName, itemCount) then
return sourceXPlayer.showNotification(TranslateCap("ex_inv_lim", targetXPlayer.name))
end
sourceXPlayer.removeInventoryItem(itemName, itemCount)
targetXPlayer.addInventoryItem(itemName, itemCount)
sourceXPlayer.showNotification(TranslateCap("gave_item", itemCount, sourceItem.label, targetXPlayer.name))
targetXPlayer.showNotification(TranslateCap("received_item", itemCount, sourceItem.label, sourceXPlayer.name))
elseif itemType == "item_account" then
if itemCount < 1 or sourceXPlayer.getAccount(itemName).money < itemCount then
return sourceXPlayer.showNotification(TranslateCap("imp_invalid_amount"))
end
sourceXPlayer.removeAccountMoney(itemName, itemCount, "Gave to " .. targetXPlayer.name)
targetXPlayer.addAccountMoney(itemName, itemCount, "Received from " .. sourceXPlayer.name)
sourceXPlayer.showNotification(TranslateCap("gave_account_money", ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName].label, targetXPlayer.name))
targetXPlayer.showNotification(TranslateCap("received_account_money", ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName].label, sourceXPlayer.name))
elseif itemType == "item_weapon" then
if not sourceXPlayer.hasWeapon(itemName) then
return
end
local weaponLabel = ESX.GetWeaponLabel(itemName)
if targetXPlayer.hasWeapon(itemName) then
sourceXPlayer.showNotification(TranslateCap("gave_weapon_hasalready", targetXPlayer.name, weaponLabel))
targetXPlayer.showNotification(TranslateCap("received_weapon_hasalready", sourceXPlayer.name, weaponLabel))
return
end
local _, weapon = sourceXPlayer.getWeapon(itemName)
if not weapon then
return
end
local _, weaponObject = ESX.GetWeapon(itemName)
itemCount = weapon.ammo
local weaponComponents = ESX.Table.Clone(weapon.components)
local weaponTint = weapon.tintIndex
if weaponTint then
targetXPlayer.setWeaponTint(itemName, weaponTint)
end
if weaponComponents then
for _, v in pairs(weaponComponents) do
targetXPlayer.addWeaponComponent(itemName, v)
end
end
sourceXPlayer.removeWeapon(itemName)
targetXPlayer.addWeapon(itemName, itemCount)
if weaponObject.ammo and itemCount > 0 then
local ammoLabel = weaponObject.ammo.label
sourceXPlayer.showNotification(TranslateCap("gave_weapon_withammo", weaponLabel, itemCount, ammoLabel, targetXPlayer.name))
targetXPlayer.showNotification(TranslateCap("received_weapon_withammo", weaponLabel, itemCount, ammoLabel, sourceXPlayer.name))
else
sourceXPlayer.showNotification(TranslateCap("gave_weapon", weaponLabel, targetXPlayer.name))
targetXPlayer.showNotification(TranslateCap("received_weapon", weaponLabel, sourceXPlayer.name))
end
elseif itemType == "item_ammo" then
if not sourceXPlayer.hasWeapon(itemName) then
return
end
local _, weapon = sourceXPlayer.getWeapon(itemName)
if not weapon then
return
end
if not targetXPlayer.hasWeapon(itemName) then
sourceXPlayer.showNotification(TranslateCap("gave_weapon_noweapon", targetXPlayer.name))
targetXPlayer.showNotification(TranslateCap("received_weapon_noweapon", sourceXPlayer.name, weapon.label))
return
end
local _, weaponObject = ESX.GetWeapon(itemName)
if not weaponObject.ammo then return end
local ammoLabel = weaponObject.ammo.label
if weapon.ammo >= itemCount then
sourceXPlayer.removeWeaponAmmo(itemName, itemCount)
targetXPlayer.addWeaponAmmo(itemName, itemCount)
sourceXPlayer.showNotification(TranslateCap("gave_weapon_ammo", itemCount, ammoLabel, weapon.label, targetXPlayer.name))
targetXPlayer.showNotification(TranslateCap("received_weapon_ammo", itemCount, ammoLabel, weapon.label, sourceXPlayer.name))
end
end
end)
RegisterNetEvent("esx:removeInventoryItem", function(itemType, itemName, itemCount)
local playerId = source
local xPlayer = ESX.GetPlayerFromId(playerId)
if not xPlayer then
return
end
if itemType == "item_standard" then
if not itemCount or itemCount < 1 then
return xPlayer.showNotification(TranslateCap("imp_invalid_quantity"))
end
local xItem = xPlayer.getInventoryItem(itemName)
if not xItem then
return
end
if itemCount > xItem.count or xItem.count < 1 then
return xPlayer.showNotification(TranslateCap("imp_invalid_quantity"))
end
xPlayer.removeInventoryItem(itemName, itemCount)
local pickupLabel = ("%s [%s]"):format(xItem.label, itemCount)
ESX.CreatePickup("item_standard", itemName, itemCount, pickupLabel, playerId)
xPlayer.showNotification(TranslateCap("threw_standard", itemCount, xItem.label))
elseif itemType == "item_account" then
if itemCount == nil or itemCount < 1 then
return xPlayer.showNotification(TranslateCap("imp_invalid_amount"))
end
local account = xPlayer.getAccount(itemName)
if not account then
return
end
if itemCount > account.money or account.money < 1 then
return xPlayer.showNotification(TranslateCap("imp_invalid_amount"))
end
xPlayer.removeAccountMoney(itemName, itemCount, "Threw away")
local pickupLabel = ("%s [%s]"):format(account.label, TranslateCap("locale_currency", ESX.Math.GroupDigits(itemCount)))
ESX.CreatePickup("item_account", itemName, itemCount, pickupLabel, playerId)
xPlayer.showNotification(TranslateCap("threw_account", ESX.Math.GroupDigits(itemCount), string.lower(account.label)))
elseif itemType == "item_weapon" then
itemName = string.upper(itemName)
if not xPlayer.hasWeapon(itemName) then return end
local _, weapon = xPlayer.getWeapon(itemName)
if not weapon then
return
end
local _, weaponObject = ESX.GetWeapon(itemName)
-- luacheck: ignore weaponPickupLabel
local weaponPickupLabel = ""
local components = ESX.Table.Clone(weapon.components)
xPlayer.removeWeapon(itemName)
if weaponObject.ammo and weapon.ammo > 0 then
local ammoLabel = weaponObject.ammo.label
weaponPickupLabel = ("%s [%s %s]"):format(weapon.label, weapon.ammo, ammoLabel)
xPlayer.showNotification(TranslateCap("threw_weapon_ammo", weapon.label, weapon.ammo, ammoLabel))
else
weaponPickupLabel = ("%s"):format(weapon.label)
xPlayer.showNotification(TranslateCap("threw_weapon", weapon.label))
end
ESX.CreatePickup("item_weapon", itemName, weapon.ammo, weaponPickupLabel, playerId, components, weapon.tintIndex)
end
end)
RegisterNetEvent("esx:useItem", function(itemName)
local source = source
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then
return
end
local count = xPlayer.getInventoryItem(itemName).count
if count < 1 then
return xPlayer.showNotification(TranslateCap("act_imp"))
end
ESX.UseItem(source, itemName)
end)
RegisterNetEvent("esx:onPickup", function(pickupId)
local pickup, xPlayer, success = Core.Pickups[pickupId], ESX.GetPlayerFromId(source)
if not xPlayer then
return
end
if not pickup then return end
local playerPickupDistance = #(pickup.coords - xPlayer.getCoords(true))
if playerPickupDistance > 5.0 then
print(("[^3WARNING^7] Player Detected Cheating (Out of range pickup): ^5%s^7"):format(xPlayer.getIdentifier()))
return
end
if pickup.type == "item_standard" then
if not xPlayer.canCarryItem(pickup.name, pickup.count) then
return xPlayer.showNotification(TranslateCap("threw_cannot_pickup"))
end
xPlayer.addInventoryItem(pickup.name, pickup.count)
success = true
elseif pickup.type == "item_account" then
success = true
xPlayer.addAccountMoney(pickup.name, pickup.count, "Picked up")
elseif pickup.type == "item_weapon" then
if xPlayer.hasWeapon(pickup.name) then
return xPlayer.showNotification(TranslateCap("threw_weapon_already"))
end
success = true
xPlayer.addWeapon(pickup.name, pickup.count)
xPlayer.setWeaponTint(pickup.name, pickup.tintIndex)
for _, v in ipairs(pickup.components) do
xPlayer.addWeaponComponent(pickup.name, v)
end
end
if success then
Core.Pickups[pickupId] = nil
TriggerClientEvent("esx:removePickup", -1, pickupId)
end
end)
end
ESX.RegisterServerCallback("esx:getPlayerData", function(source, cb)
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then
return
end
cb({
identifier = xPlayer.identifier,
accounts = xPlayer.getAccounts(),
inventory = xPlayer.getInventory(),
job = xPlayer.getJob(),
loadout = xPlayer.getLoadout(),
money = xPlayer.getMoney(),
position = xPlayer.getCoords(true),
metadata = xPlayer.getMeta(),
})
end)
ESX.RegisterServerCallback("esx:isUserAdmin", function(source, cb)
cb(Core.IsPlayerAdmin(source))
end)
ESX.RegisterServerCallback("esx:getGameBuild", function(_, cb)
cb(tonumber(GetConvar("sv_enforceGameBuild", "1604")))
end)
ESX.RegisterServerCallback("esx:getOtherPlayerData", function(_, cb, target)
local xPlayer = ESX.GetPlayerFromId(target)
if not xPlayer then
return
end
cb({
identifier = xPlayer.identifier,
accounts = xPlayer.getAccounts(),
inventory = xPlayer.getInventory(),
job = xPlayer.getJob(),
loadout = xPlayer.getLoadout(),
money = xPlayer.getMoney(),
position = xPlayer.getCoords(true),
metadata = xPlayer.getMeta(),
})
end)
ESX.RegisterServerCallback("esx:getPlayerNames", function(source, cb, players)
players[source] = nil
for playerId, _ in pairs(players) do
local xPlayer = ESX.GetPlayerFromId(playerId)
if xPlayer then
players[playerId] = xPlayer.getName()
else
players[playerId] = nil
end
end
cb(players)
end)
ESX.RegisterServerCallback("esx:spawnVehicle", function(source, cb, vehData)
local ped = GetPlayerPed(source)
ESX.OneSync.SpawnVehicle(vehData.model or `ADDER`, vehData.coords or GetEntityCoords(ped), vehData.coords.w or 0.0, vehData.props or {}, function(id)
if vehData.warp then
local vehicle = NetworkGetEntityFromNetworkId(id)
local timeout = 0
while GetVehiclePedIsIn(ped, false) ~= vehicle and timeout <= 15 do
Wait(0)
TaskWarpPedIntoVehicle(ped, vehicle, -1)
timeout += 1
end
end
cb(id)
end)
end)
AddEventHandler("txAdmin:events:scheduledRestart", function(eventData)
if eventData.secondsRemaining == 60 then
CreateThread(function()
Wait(50000)
Core.SavePlayers()
end)
end
end)
AddEventHandler("txAdmin:events:serverShuttingDown", function()
Core.SavePlayers()
end)
local DoNotUse = {
["essentialmode"] = true,
["es_admin2"] = true,
["basic-gamemode"] = true,
["mapmanager"] = true,
["fivem-map-skater"] = true,
["fivem-map-hipster"] = true,
["qb-core"] = true,
["default_spawnpoint"] = true,
}
AddEventHandler("onResourceStart", function(key)
if DoNotUse[string.lower(key)] then
while GetResourceState(key) ~= "started" do
Wait(0)
end
StopResource(key)
error(("WE STOPPED A RESOURCE THAT WILL BREAK ^1ESX^1, PLEASE REMOVE ^5%s^1"):format(key))
end
-- luacheck: ignore
if not SetEntityOrphanMode then
CreateThread(function()
while true do
error("ESX Requires a minimum Artifact version of 10188, Please update your server.")
Wait(60 * 1000)
end
end)
end
end)
for key in pairs(DoNotUse) do
if GetResourceState(key) == "started" or GetResourceState(key) == "starting" then
StopResource(key)
error(("WE STOPPED A RESOURCE THAT WILL BREAK ^1ESX^1, PLEASE REMOVE ^5%s^1"):format(key))
end
end