mirror of
https://github.com/ND-Framework/ND_Core.git
synced 2026-08-17 22:06:02 +01:00
Updated 2.1.0
Updated everything to new format, N1K0 is about to work on some more stuff.
This commit is contained in:
85
ND_Core/client/main.lua
Normal file
85
ND_Core/client/main.lua
Normal file
@@ -0,0 +1,85 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
NDCore = {}
|
||||
NDCore.selectedCharacter = nil
|
||||
NDCore.characters = {}
|
||||
NDCore.functions = {}
|
||||
NDCore.config = config
|
||||
|
||||
function GetCoreObject()
|
||||
return NDCore
|
||||
end
|
||||
|
||||
function NDCore.functions:getSelectedCharacter(cb)
|
||||
if not cb then return NDCore.selectedCharacter end
|
||||
cb(NDCore.selectedCharacter)
|
||||
end
|
||||
|
||||
function NDCore.functions:getCharacters(cb)
|
||||
if not cb then return NDCore.selectedCharacter end
|
||||
cb(NDCore.characters)
|
||||
end
|
||||
|
||||
-- discord rich precense will show on a users profile.
|
||||
if config.enableRichPrecence then
|
||||
Citizen.CreateThread(function()
|
||||
SetDiscordAppId(config.appId)
|
||||
while true do
|
||||
if NDCore.selectedCharacter then
|
||||
SetRichPresence(" Playing : " .. config.serverName .. " as " .. NDCore.selectedCharacter.firstName .. " " .. NDCore.selectedCharacter.lastName)
|
||||
SetDiscordRichPresenceAsset(config.largeLogo)
|
||||
SetDiscordRichPresenceAssetText("Playing: " .. config.serverName)
|
||||
SetDiscordRichPresenceAssetSmall(config.smallLogo)
|
||||
SetDiscordRichPresenceAssetSmallText("Playing as: " .. NDCore.selectedCharacter.firstName .. " " .. NDCore.selectedCharacter.lastName)
|
||||
SetDiscordRichPresenceAction(0, config.firstButtonName, config.firstButtonLink)
|
||||
SetDiscordRichPresenceAction(1, config.secondButtonName, config.secondButtonLink)
|
||||
end
|
||||
Citizen.Wait(config.updateIntervall * 1000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- show server name, first name, last name, and the amount of money the character has in the pause menu.
|
||||
if config.customPauseMenu then
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(0)
|
||||
if NDCore.selectedCharacter then
|
||||
if IsPauseMenuActive() then
|
||||
BeginScaleformMovieMethodOnFrontendHeader("SET_HEADING_DETAILS")
|
||||
AddTextEntry("FE_THDR_GTAO", config.serverName)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(NDCore.selectedCharacter.firstName .. " " .. NDCore.selectedCharacter.lastName)
|
||||
PushScaleformMovieFunctionParameterString("Cash: $" .. tostring(NDCore.selectedCharacter.cash))
|
||||
PushScaleformMovieFunctionParameterString("Bank: $" .. tostring(NDCore.selectedCharacter.bank))
|
||||
EndScaleformMovieMethod()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
RegisterNetEvent("ND:returnCharacters")
|
||||
AddEventHandler("ND:returnCharacters", function(characters)
|
||||
NDCore.characters = characters
|
||||
end)
|
||||
|
||||
-- updates the money on the client.
|
||||
RegisterNetEvent("ND:updateMoney")
|
||||
AddEventHandler("ND:updateMoney", function(cash, bank)
|
||||
NDCore.selectedCharacter.cash = cash
|
||||
NDCore.selectedCharacter.bank = bank
|
||||
end)
|
||||
|
||||
RegisterNetEvent("ND:setCharacter")
|
||||
AddEventHandler("ND:setCharacter", function(character)
|
||||
NDCore.selectedCharacter = character
|
||||
end)
|
||||
|
||||
-- Enables pvp if it's selected in the config.
|
||||
AddEventHandler("playerSpawned", function()
|
||||
if config.enablePVP then
|
||||
SetCanAttackFriendly(PlayerPedId(), true, false)
|
||||
NetworkSetFriendlyFireOption(true)
|
||||
end
|
||||
print("^0This framework is created by ^5Andyyy#7666 ^0for support you can join the ^5discord: ^0https://discord.gg/Z9Mxu72zZ6")
|
||||
end)
|
||||
@@ -2,63 +2,20 @@
|
||||
|
||||
config = {
|
||||
serverName = "Andy's Development",
|
||||
characterLimit = 15,
|
||||
changeCharacterCommand = "changecharacter", -- this is the command to open the ui again and change your character.
|
||||
customPauseMenu = true, -- this will create a custom pause menu. It will display your money, characters name and the server name in the pause menu.
|
||||
|
||||
-- set your backgrounds, if you have more than 1 then it will randomly change everytime you open the ui.
|
||||
backgrounds = {
|
||||
"https://i.imgur.com/E51ckFx.png", -- Credits: Fuzzman270#0270
|
||||
"https://i.imgur.com/SeZD7TP.png", -- Credits: Fuzzman270#0270
|
||||
"https://i.imgur.com/ZWKfYD9.png" -- Credits: 2XRondo#6374
|
||||
},
|
||||
|
||||
departments = {
|
||||
["CIV"] = {"872921520719142932"},
|
||||
["SAHP"] = {"872921520719142932"},
|
||||
["LSPD"] = {"872921520719142932"},
|
||||
["BCSO"] = {"872921520719142932"},
|
||||
["LSFD"] = {"872921520719142932"}
|
||||
},
|
||||
|
||||
-- set up the spawn buttons for each department.
|
||||
spawns = {
|
||||
["CIV"] = {
|
||||
{x = -102.78, y = 6336.28, z = 31.49, name = "Dream View Motel (Paleto Bay)"},
|
||||
{x = 343.53, y = 2636.94, z = 43.94, name = "Eastern Motel (Sandy Shores)"},
|
||||
{x = 196.96, y = -934.54, z = 29.69, name = "Legion Square"},
|
||||
{x = -1616.69, y = -1073.81, z = 12.15, name = "Del Perro Pier"},
|
||||
{x = -1039.65, y = -2741.02, z = 12.89, name = "LSIA"}
|
||||
},
|
||||
["SAHP"] = {
|
||||
{x = -447.2, y = 6009.4, z = 30.72, name = "Paleto Bay Sheriff"},
|
||||
{x = 1849.4, y = 3688.6, z = 33.27, name = "Sandy Shores Sheriff"},
|
||||
{x = 437.6, y = -986.6, z = 29.69, name = "Mission Row PD"}
|
||||
},
|
||||
["LSPD"] = {
|
||||
{x = -447.2, y = 6009.4, z = 30.72, name = "Paleto Bay Sheriff"},
|
||||
{x = 1849.4, y = 3688.6, z = 33.27, name = "Sandy Shores Sheriff"},
|
||||
{x = 437.6, y = -986.6, z = 29.69, name = "Mission Row PD"}
|
||||
},
|
||||
["BCSO"] = {
|
||||
{x = -447.2, y = 6009.4, z = 30.72, name = "Paleto Bay Sheriff"},
|
||||
{x = 1849.4, y = 3688.6, z = 33.27, name = "Sandy Shores Sheriff"},
|
||||
{x = 437.6, y = -986.6, z = 29.69, name = "Mission Row Police "}
|
||||
},
|
||||
["LSFD"] = {
|
||||
{x = -384.07, y = 6117.9, z = 30.48, name = "Fire Station No1 (Paleto Bay)"},
|
||||
{x = 1691.5, y = 3597.95, z = 34.56, name = "Fire Station No2 (Sandy Shores)"},
|
||||
{x = 1194.71, y = -1474.14, z = 33.86, name = "Fire Station No7 (Los Santos)"}
|
||||
},
|
||||
},
|
||||
|
||||
-- Money related
|
||||
enableMoneySystem = true,
|
||||
maxStartingCash = 2500,
|
||||
maxStartingBank = 8000,
|
||||
payCommand = "pay", -- Command to transfer money from your bank to another persons.
|
||||
giveCommand = "give", -- Command to give someone near you cash.
|
||||
characterLimit = 15, -- How many characters can a player create.
|
||||
customPauseMenu = true, -- A custom pause menu will display your money, characters name and the server name in the pause menu.
|
||||
enablePVP = true, -- pvp allows doing damage to other players.
|
||||
|
||||
-- Money related
|
||||
startingCash = 2500, -- default cash the character will start with if the character creator doesn't specify it.
|
||||
startingBank = 8000,-- default money in the bank account the character will start with if the character creator doesn't specify it.
|
||||
|
||||
-- If you'd like to whitelist certain roles on discord then set this to true and add role ids.
|
||||
enableDiscordWhitelist = false,
|
||||
whitelistRoles = {
|
||||
"0"
|
||||
},
|
||||
|
||||
-- Discord Rich presence
|
||||
enableRichPresence = true,
|
||||
updateIntervall = 60, -- how many seconds of delay until it updates status.
|
||||
@@ -69,4 +26,4 @@ config = {
|
||||
firstButtonLink = "https://discord.gg/Z9Mxu72zZ6",
|
||||
secondButtonName = "TEBEX",
|
||||
secondButtonLink = "https://andyyy.tebex.io/category/fivem-scripts"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
server_config = {
|
||||
discordServerToken = "", -- discord bot token for permissions
|
||||
guildId = "", -- discord guild id
|
||||
}
|
||||
discordServerToken = "OTAwODg1MDMxMDQ2Nzc0ODQ1.GU1TSC.Ed8D2_wcU-UQ1vZhe1khahgV8J3hLahOp4N1D8", -- discord bot token for permissions
|
||||
guildId = "872496972454592523", -- discord guild id
|
||||
}
|
||||
@@ -1,57 +1,29 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
author "Andyyy#7666"
|
||||
description "ND-Core"
|
||||
version "2.0.0"
|
||||
description "ND Framework Core"
|
||||
version "3.0.0"
|
||||
|
||||
fx_version "cerulean"
|
||||
game "gta5"
|
||||
lua54 "yes"
|
||||
|
||||
files {
|
||||
"source/ui/index.html",
|
||||
"source/ui/script.js",
|
||||
"source/ui/style.css"
|
||||
}
|
||||
ui_page "source/ui/index.html"
|
||||
|
||||
shared_script "config_client.lua"
|
||||
client_script "source/client.lua"
|
||||
client_script "client/main.lua"
|
||||
server_scripts {
|
||||
"@oxmysql/lib/MySQL.lua",
|
||||
"config_server.lua",
|
||||
"source/server.lua"
|
||||
"server/main.lua",
|
||||
"server/functions.lua",
|
||||
"server/events.lua"
|
||||
}
|
||||
|
||||
exports {
|
||||
"getCharacterInfo",
|
||||
"GetCoreObject"
|
||||
}
|
||||
|
||||
server_exports {
|
||||
"transferBank", -- exports["ND_Core"]:transferBank(amount, player, target)
|
||||
"giveCashToClosestTarget", -- exports["ND_Core"]:giveCashToClosestTarget(amount, player)
|
||||
"withdrawMoney", -- exports["ND_Core"]:withdrawMoney(amount, player)
|
||||
"depositMoney", -- exports["ND_Core"]:depositMoney(amount, player)
|
||||
"deductMoney", -- exports["ND_Core"]:deductMoney(amount, player, from)
|
||||
"addMoney", -- exports["ND_Core"]:addMoney(amount, player, to)
|
||||
"getCharacterTable" -- exports["ND_Core"]:getCharacterTable() this will return a table with all the online players and their info. View below on how to use this.
|
||||
"GetCoreObject"
|
||||
}
|
||||
|
||||
dependency "oxmysql"
|
||||
|
||||
--[[
|
||||
Keys in the getCharacterTable:
|
||||
|
||||
characterId
|
||||
firstName
|
||||
lastName
|
||||
dob
|
||||
gender
|
||||
twt
|
||||
dept
|
||||
cash
|
||||
bank
|
||||
|
||||
Usage:
|
||||
players = exports["ND_Core"]:getCharacterTable()
|
||||
print(players[3].bank) this will print the bank account of the player with id 3.
|
||||
]]
|
||||
dependency "oxmysql"
|
||||
@@ -6,7 +6,7 @@ CREATE TABLE `characters` (
|
||||
`dob` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`gender` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`twt` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`department` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`job` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`cash` INT(10) NULL DEFAULT '0',
|
||||
`bank` INT(10) NULL DEFAULT '0',
|
||||
PRIMARY KEY (`character_id`) USING BTREE
|
||||
|
||||
49
ND_Core/server/events.lua
Normal file
49
ND_Core/server/events.lua
Normal file
@@ -0,0 +1,49 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
-- Getting all the characters the player has and returning them to the client.
|
||||
RegisterNetEvent("ND:getCharacters")
|
||||
AddEventHandler("ND:getCharacters", function()
|
||||
local player = source
|
||||
TriggerClientEvent("ND:returnCharacters", player, NDCore.functions:getPlayerCharacters(player))
|
||||
end)
|
||||
|
||||
-- Creating a new character.
|
||||
RegisterNetEvent("ND:newCharacter")
|
||||
AddEventHandler("ND:newCharacter", function(newCharacter)
|
||||
local player = source
|
||||
NDCore.functions:createCharacter(player, newCharacter.firstName, newCharacter.lastName, newCharacter.dob, newCharacter.gender, newCharacter.twt, newCharacter.job, newCharacter.cash, newCharacter.bank)
|
||||
end)
|
||||
|
||||
-- Update the character info when edited.
|
||||
RegisterNetEvent("ND:editCharacter")
|
||||
AddEventHandler("ND:editCharacter", function(newCharacter)
|
||||
local player = source
|
||||
NDCore.functions:updateCharacterData(newCharacter.id, newCharacter.firstName, newCharacter.lastName, newCharacter.dob, newCharacter.gender, newCharacter.twt, newCharacter.job)
|
||||
end)
|
||||
|
||||
-- Delete character from database.
|
||||
RegisterNetEvent("ND:deleteCharacter")
|
||||
AddEventHandler("ND:deleteCharacter", function(characterId)
|
||||
local player = source
|
||||
NDCore.functions:deleteCharacter(characterId)
|
||||
end)
|
||||
|
||||
-- add a player to the table.
|
||||
RegisterNetEvent("ND:setCharacterOnline")
|
||||
AddEventHandler("ND:setCharacterOnline", function(id)
|
||||
local player = source
|
||||
NDCore.functions:setActiveCharacter(player, id)
|
||||
end)
|
||||
|
||||
-- Disconnecting a player
|
||||
RegisterNetEvent("ND:exitGame")
|
||||
AddEventHandler("ND:exitGame", function()
|
||||
local player = source
|
||||
DropPlayer(player, "Disconnected.")
|
||||
end)
|
||||
|
||||
-- Remove player from NDCore.players table when they leave.
|
||||
AddEventHandler("playerDropped", function()
|
||||
local player = source
|
||||
NDCore.players[player] = nil
|
||||
end)
|
||||
309
ND_Core/server/functions.lua
Normal file
309
ND_Core/server/functions.lua
Normal file
@@ -0,0 +1,309 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
-- Callback to update each selected character on the server.
|
||||
function NDCore.functions:getPlayers(players)
|
||||
if not cb then return NDCore.players end
|
||||
cb(NDCore.players)
|
||||
end
|
||||
|
||||
-- Used to retrive the players discord server nickname, discord name and tag, and the roles.
|
||||
function NDCore.functions:getUserDiscordInfo(discordUserId)
|
||||
local data
|
||||
PerformHttpRequest("https://discordapp.com/api/guilds/" .. server_config.guildId .. "/members/" .. discordUserId, function(errorCode, resultData, resultHeaders)
|
||||
if errorCode ~= 200 then
|
||||
print("Error: " .. errorCode .. ", discord token might be missing.")
|
||||
return
|
||||
end
|
||||
local result = json.decode(resultData)
|
||||
local roles = {}
|
||||
for _, roleId in pairs(result.roles) do
|
||||
roles[roleId] = roleId
|
||||
end
|
||||
data = {
|
||||
nickname = result.nick,
|
||||
discordTag = tostring(result.user.username) .. "#" .. tostring(result.user.discriminator),
|
||||
roles = roles
|
||||
}
|
||||
end, "GET", "", {["Content-Type"] = "application/json", ["Authorization"] = "Bot " .. server_config.discordServerToken})
|
||||
while not data do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
-- Get player any identifier, available types: steam, license, xbl, ip, discord, live.
|
||||
function NDCore.functions:GetPlayerIdentifierFromType(type, player)
|
||||
local identifierCount = GetNumPlayerIdentifiers(player)
|
||||
for count = 0, identifierCount do
|
||||
local identifier = GetPlayerIdentifier(player, count)
|
||||
if identifier and string.find(identifier, type) then
|
||||
return identifier
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- This will return the server id and ND player data of a nearby player.
|
||||
function NDCore.functions:getNearbyPedToPlayer(player)
|
||||
local pedCoords = GetEntityCoords(GetPlayerPed(player))
|
||||
for targetId, targetInfo in pairs(NDCore.players) do
|
||||
local targetCoords = GetEntityCoords(GetPlayerPed(targetId))
|
||||
if #(pedCoords - targetCoords) < 2.0 and targetId ~= player then
|
||||
return targetId, targetInfo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- update the players money on the client kinda like a refresh.
|
||||
function NDCore.functions:updateMoney(player)
|
||||
local player = tonumber(player)
|
||||
MySQL.query("SELECT cash, bank FROM characters WHERE character_id = ?", {NDCore.players[player].id}, function(result)
|
||||
if result then
|
||||
local cash = result[1].cash
|
||||
local bank = result[1].bank
|
||||
NDCore.players[player].cash = cash
|
||||
NDCore.players[player].bank = bank
|
||||
TriggerClientEvent("ND:updateMoney", player, cash, bank)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Transfer money from one players bank account to another.
|
||||
function NDCore.functions:transferBank(amount, player, target)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
local target = tonumber(target)
|
||||
if player == target then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You can't send money to yourself."}
|
||||
})
|
||||
return false
|
||||
elseif GetPlayerPing(target) == 0 then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "That player does not exist."}
|
||||
})
|
||||
return false
|
||||
elseif amount <= 0 then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You can't send that amount."}
|
||||
})
|
||||
return false
|
||||
elseif NDCore.players[player].bank < amount then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You don't have enough money."}
|
||||
})
|
||||
return false
|
||||
else
|
||||
MySQL.query.await("UPDATE characters SET bank = bank - ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
NDCore.functions:updateMoney(player)
|
||||
MySQL.query.await("UPDATE characters SET bank = bank + ? WHERE character_id = ?", {amount, NDCore.players[target].id})
|
||||
NDCore.functions:updateMoney(target)
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {0, 255, 0},
|
||||
args = {"Success", "You paid " .. NDCore.players[target].firstName .. " " .. NDCore.players[target].lastName .. " $" .. amount .. "."}
|
||||
})
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Give cash from one players wallet to another.
|
||||
function NDCore.functions:giveCash(amount, player, target)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
local target = tonumber(target)
|
||||
if player == target then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You can't give money to yourself."}
|
||||
})
|
||||
return false
|
||||
elseif GetPlayerPing(target) == 0 then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "That player does not exist."}
|
||||
})
|
||||
return false
|
||||
elseif amount <= 0 then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You can't give that amount."}
|
||||
})
|
||||
return false
|
||||
elseif NDCore.players[player].cash < amount then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You don't have enough money."}
|
||||
})
|
||||
return false
|
||||
else
|
||||
MySQL.query.await("UPDATE characters SET cash = cash - ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
NDCore.functions:updateMoney(player)
|
||||
MySQL.query.await("UPDATE characters SET cash = cash + ? WHERE character_id = ?", {amount, NDCore.players[target].id})
|
||||
NDCore.functions:updateMoney(target)
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {0, 255, 0},
|
||||
args = {"Success", "You gave " .. NDCore.players[target].firstName .. " " .. NDCore.players[target].lastName .. " $" .. amount .. "."}
|
||||
})
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Give money from a players wallet to a nearby player.
|
||||
function NDCore.functions:giveCashToNearbyPlayer(player, amount)
|
||||
local targetId = NDCore.functions:getNearbyPedToPlayer(player)
|
||||
if targetId then
|
||||
NDCore.functions:giveCash(amount, player, targetId)
|
||||
return true
|
||||
end
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "No players nearby."}
|
||||
})
|
||||
return false
|
||||
end
|
||||
|
||||
-- withdraws money from a players bank account to their wallet/cash.
|
||||
function NDCore.functions:withdrawMoney(amount, player)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if amount <= 0 then return false end
|
||||
if NDCore.players[player].bank < amount then return false end
|
||||
MySQL.query.await("UPDATE characters SET bank = bank - ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
MySQL.query.await("UPDATE characters SET cash = cash + ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
NDCore.functions:updateMoney(player)
|
||||
return true
|
||||
end
|
||||
|
||||
-- deposits money from a players wallet/cash to their bank account.
|
||||
function NDCore.functions:depositMoney(amount, player)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if amount <= 0 then return false end
|
||||
if NDCore.players[player].cash < amount then return false end
|
||||
MySQL.query.await("UPDATE characters SET cash = cash - ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
MySQL.query.await("UPDATE characters SET bank = bank + ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
NDCore.functions:updateMoney(player)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Deducts money from the player, "bank" or "cash" needs to be specified.
|
||||
function NDCore.functions:deductMoney(amount, player, from)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if from == "bank" then
|
||||
MySQL.query.await("UPDATE characters SET bank = bank - ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
elseif from == "cash" then
|
||||
MySQL.query.await("UPDATE characters SET cash = cash - ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
end
|
||||
NDCore.functions:updateMoney(player)
|
||||
end
|
||||
|
||||
-- Adds money from the player, "bank" or "cash" needs to be specified.
|
||||
function NDCore.functions:addMoney(amount, player, to)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if to == "bank" then
|
||||
MySQL.query.await("UPDATE characters SET bank = bank + ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
elseif to == "cash" then
|
||||
MySQL.query.await("UPDATE characters SET cash = cash + ? WHERE character_id = ?", {amount, NDCore.players[player].id})
|
||||
end
|
||||
NDCore.functions:updateMoney(player)
|
||||
end
|
||||
|
||||
-- Adds the players character to the NDCore.players table, this table consists of every players selected character.
|
||||
function NDCore.functions:setActiveCharacter(player, characterId)
|
||||
local result = MySQL.query.await("SELECT * FROM characters WHERE character_id = ?", {characterId})
|
||||
if result then
|
||||
local i = result[1]
|
||||
NDCore.players[player] = {
|
||||
id = characterId,
|
||||
firstName = i.first_name,
|
||||
lastName = i.last_name,
|
||||
dob = i.dob,
|
||||
gender = i.gender,
|
||||
twt = i.twt,
|
||||
job = i.job,
|
||||
cash = i.cash,
|
||||
bank = i.bank
|
||||
}
|
||||
end
|
||||
TriggerClientEvent("ND:setCharacter", player, NDCore.players[player])
|
||||
end
|
||||
|
||||
-- This returns all the characters the player has.
|
||||
function NDCore.functions:getPlayerCharacters(player)
|
||||
local characters = {}
|
||||
local result = MySQL.query.await("SELECT * FROM characters WHERE license = ?", {NDCore.functions:GetPlayerIdentifierFromType("license", player)})
|
||||
for i = 1, #result do
|
||||
local temp = result[i]
|
||||
characters[temp.character_id] = {id = temp.character_id, firstName = temp.first_name, lastName = temp.last_name, dob = temp.dob, gender = temp.gender, twt = temp.twt, job = temp.job, cash = temp.cash, bank = temp.bank}
|
||||
end
|
||||
return characters
|
||||
end
|
||||
|
||||
-- Creates a new character for the player and returns all their characters to the client.
|
||||
function NDCore.functions:createCharacter(player, firstName, lastName, dob, gender, twt, job, cash, bank)
|
||||
local license = NDCore.functions:GetPlayerIdentifierFromType("license", player)
|
||||
if not cash or not bank or tonumber(cash) > config.startingCash or tonumber(bank) > config.startingBank then
|
||||
cash = config.startingCash
|
||||
bank = config.startingBank
|
||||
end
|
||||
local result = MySQL.query.await("SELECT character_id FROM characters WHERE license = ?", {license})
|
||||
if result and config.characterLimit > #result then
|
||||
MySQL.query.await("INSERT INTO characters (license, first_name, last_name, dob, gender, twt, job, cash, bank) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", {license, firstName, lastName, dob, gender, twt, job, cash, bank})
|
||||
TriggerClientEvent("ND:returnCharacters", player, NDCore.functions:getPlayerCharacters(player))
|
||||
end
|
||||
end
|
||||
|
||||
-- Update/edit a character by character id.
|
||||
function NDCore.functions:updateCharacterData(characterId, firstName, lastName, dob, gender, twt, job)
|
||||
MySQL.query("UPDATE characters SET first_name = ?, last_name = ?, dob = ?, gender = ?, twt = ?, job = ? WHERE character_id = ?", {firstName, lastName, dob, gender, twt, job, characterId})
|
||||
end
|
||||
|
||||
-- Delete a character by character id.
|
||||
function NDCore.functions:deleteCharacter(characterId)
|
||||
MySQL.query("DELETE FROM characters WHERE character_id = ?", {characterId})
|
||||
end
|
||||
|
||||
function NDCore.functions:versionChecker(expectedResourceName, resourceName, downloadLink, rawGithubLink)
|
||||
if expectedResourceName ~= resourceName then
|
||||
print("^1[^4" .. expectedResourceName .. "^1] WARNING^0")
|
||||
print("Change the resource name to ^4" .. expectedResourceName .. " ^0or else it won't work properly!")
|
||||
StopResource(resourceName)
|
||||
return
|
||||
end
|
||||
PerformHttpRequest(rawGithubLink, function(errorCode, resultData, resultHeaders)
|
||||
local i, j = string.find(tostring(resultData), "version")
|
||||
local resultData = string.sub(tostring(resultData), i, j + 12)
|
||||
local resultData = string.gsub(resultData, "version \"", "")
|
||||
local i, j = string.find(resultData, "\"")
|
||||
local resultData = string.sub(resultData, 1, i - 1)
|
||||
local githubVersion = string.gsub(resultData, "%.", "")
|
||||
local fileVersion = string.gsub(GetResourceMetadata(expectedResourceName, "version", 0), "%.", "")
|
||||
local githubVersion = tonumber(githubVersion)
|
||||
local fileVersion = tonumber(fileVersion)
|
||||
|
||||
if not githubVersion and not fileVersion then
|
||||
print("^1[^4" .. expectedResourceName .. "^1] WARNING^0")
|
||||
print("You may not have the latest version of ^4" .. expectedResourceName .. "^0. A newer, improved version may be present at ^5" .. downloadLink .. "^0")
|
||||
elseif githubVersion > fileVersion then
|
||||
local oldVersion = string.sub(fileVersion, 1, 1) .. "." .. string.sub(fileVersion, 2, 2) .. "." .. string.sub(fileVersion, 3, 3)
|
||||
local newVersion = string.sub(githubVersion, 1, 1) .. "." .. string.sub(githubVersion, 2, 2) .. "." .. string.sub(githubVersion, 3, 3)
|
||||
print("^1[^4" .. expectedResourceName .. "^1] WARNING^0")
|
||||
print("^4" .. expectedResourceName .. " ^0is outdated. Please update it from ^5" .. downloadLink .. " ^0| Current Version: ^1" .. oldVersion .. " ^0| New Version: ^2" .. newVersion .. " ^0|")
|
||||
elseif githubVersion < fileVersion then
|
||||
local oldVersion = string.sub(fileVersion, 1, 1) .. "." .. string.sub(fileVersion, 2, 2) .. "." .. string.sub(fileVersion, 3, 3)
|
||||
local newVersion = string.sub(githubVersion, 1, 1) .. "." .. string.sub(githubVersion, 2, 2) .. "." .. string.sub(githubVersion, 3, 3)
|
||||
print("^1[^4" .. expectedResourceName .. "^1] WARNING^0")
|
||||
print("^4" .. expectedResourceName .. " ^0version number is higher than expected | Current Version: ^3" .. oldVersion .. " ^0| Expected Version: ^2" .. newVersion .. " ^0|")
|
||||
else
|
||||
local newVersion = string.sub(githubVersion, 1, 1) .. "." .. string.sub(githubVersion, 2, 2) .. "." .. string.sub(githubVersion, 3, 3)
|
||||
print("^4" .. expectedResourceName .. " ^0is up to date | Current Version: ^2" .. newVersion .. " ^0|")
|
||||
end
|
||||
end)
|
||||
end
|
||||
NDCore.functions:versionChecker("ND_Core", GetCurrentResourceName(), "https://github.com/Andyyy7666/ND_Framework", "https://raw.githubusercontent.com/Andyyy7666/ND_Framework/main/ND_Core/fxmanifest.lua")
|
||||
10
ND_Core/server/main.lua
Normal file
10
ND_Core/server/main.lua
Normal file
@@ -0,0 +1,10 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
NDCore = {}
|
||||
NDCore.players = {}
|
||||
NDCore.functions = {}
|
||||
NDCore.config = config
|
||||
|
||||
function GetCoreObject()
|
||||
return NDCore
|
||||
end
|
||||
@@ -1,266 +0,0 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
local selectedCharacter
|
||||
local characterAmount = 0
|
||||
|
||||
function SetDisplay(bool, typeName, bg)
|
||||
if not bg then
|
||||
background = config.backgrounds[math.random(1, #config.backgrounds)]
|
||||
end
|
||||
SetNuiFocus(bool, bool)
|
||||
SendNUIMessage({
|
||||
type = typeName,
|
||||
background = background,
|
||||
status = bool,
|
||||
serverName = config.serverName,
|
||||
characterAmount = characterAmount .. "/" .. config.characterLimit
|
||||
})
|
||||
end
|
||||
|
||||
function getCharacterInfo()
|
||||
return selectedCharacter
|
||||
end
|
||||
|
||||
function start(switch)
|
||||
TriggerServerEvent("checkPerms")
|
||||
TriggerServerEvent("getCharacters")
|
||||
TriggerServerEvent("getAop")
|
||||
Citizen.Wait(100)
|
||||
if switch then
|
||||
local ped = PlayerPedId()
|
||||
SwitchOutPlayer(ped, 0, 1)
|
||||
FreezeEntityPosition(ped, true)
|
||||
SetEntityVisible(ped, false, 0)
|
||||
end
|
||||
SendNUIMessage({
|
||||
type = "onStart",
|
||||
enableMoneySystem = config.enableMoneySystem,
|
||||
maxStartingBank = config.maxStartingBank,
|
||||
maxStartingCash = config.maxStartingCash
|
||||
})
|
||||
end
|
||||
|
||||
AddEventHandler("onResourceStart", function(resourceName)
|
||||
if (GetCurrentResourceName() ~= resourceName) then
|
||||
return
|
||||
end
|
||||
Citizen.Wait(1000)
|
||||
start(false)
|
||||
end)
|
||||
|
||||
AddEventHandler("playerSpawned", function()
|
||||
print("^0This framework is created by ^5Andyyy#7666 ^0for support you can join the ^5discord: ^0https://discord.gg/Z9Mxu72zZ6")
|
||||
start(true)
|
||||
end)
|
||||
|
||||
-- This is used to add department drop down on the ui.
|
||||
RegisterNetEvent("permsChecked")
|
||||
AddEventHandler("permsChecked", function(allowedRoles)
|
||||
for _, dept in pairs(allowedRoles) do
|
||||
SendNUIMessage({
|
||||
type = "givePerms",
|
||||
deptRole = dept
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- Notification when you recieve money.
|
||||
RegisterNetEvent("receiveBank")
|
||||
AddEventHandler("receiveBank", function(amount, playerSending, playerId)
|
||||
BeginTextCommandThefeedPost("STRING")
|
||||
AddTextComponentSubstringPlayerName("Received $" .. amount .. " from " .. playerSending .. " [".. playerId .."]")
|
||||
EndTextCommandThefeedPostMessagetext("CHAR_BANK_FLEECA", "CHAR_BANK_FLEECA", true, 9,"FleecaBank", "")
|
||||
end)
|
||||
|
||||
-- Notification when you receive cash.
|
||||
RegisterNetEvent("receiveCash")
|
||||
AddEventHandler("receiveCash", function(amount, playerSending, playerId)
|
||||
BeginTextCommandThefeedPost("STRING")
|
||||
AddTextComponentSubstringPlayerName(playerSending .. " gave you $" .. amount .. ".")
|
||||
EndTextCommandThefeedPostMessagetext("CHAR_DEFAULT", "CHAR_DEFAULT", true, 9, playerSending .. " [".. playerId .."]", "")
|
||||
end)
|
||||
|
||||
RegisterNetEvent("updateMoney")
|
||||
AddEventHandler("updateMoney", function(cash, bank)
|
||||
selectedCharacter.cash = cash
|
||||
selectedCharacter.bank = bank
|
||||
end)
|
||||
|
||||
-- Gets all the characters and displays them on the ui.
|
||||
RegisterNetEvent("returnCharacters")
|
||||
AddEventHandler("returnCharacters", function(characters)
|
||||
characterAmount = 0
|
||||
SendNUIMessage({
|
||||
type = "refresh"
|
||||
})
|
||||
for _, character in pairs(characters) do
|
||||
SendNUIMessage({
|
||||
type = "character",
|
||||
id = character.id,
|
||||
firstName = character.firstName,
|
||||
lastName = character.lastName,
|
||||
dateOfBirth = character.dob,
|
||||
gender = character.gender,
|
||||
twtName = character.twt,
|
||||
department = character.department,
|
||||
startingCash = character.cash,
|
||||
startingBank = character.bank
|
||||
})
|
||||
characterAmount = characterAmount + 1
|
||||
end
|
||||
SetDisplay(true, "ui", background)
|
||||
end)
|
||||
|
||||
-- Selecting a player from the iu.
|
||||
RegisterNUICallback("setMainCharacter", function(data)
|
||||
selectedCharacter = {
|
||||
firstName = data.firstName,
|
||||
lastName = data.lastName,
|
||||
dob = data.dateOfBirth,
|
||||
gender = data.gender,
|
||||
twt = data.twtName,
|
||||
department = data.department,
|
||||
cash = data.startingCash,
|
||||
bank = data.startingBank,
|
||||
id = data.character
|
||||
}
|
||||
|
||||
for _, spawn in pairs(config.spawns[selectedCharacter.department]) do
|
||||
SendNUIMessage({
|
||||
type = "setSpawns",
|
||||
x = spawn.x,
|
||||
y = spawn.y,
|
||||
z = spawn.z,
|
||||
name = spawn.name
|
||||
})
|
||||
end
|
||||
|
||||
TriggerServerEvent("characterOnline", selectedCharacter.id)
|
||||
TriggerEvent("characterChanged", selectedCharacter)
|
||||
end)
|
||||
|
||||
-- Creating a character from the ui.
|
||||
RegisterNUICallback("newCharacter", function(data)
|
||||
if characterAmount < config.characterLimit then
|
||||
TriggerServerEvent("newCharacter", {
|
||||
firstName = data.firstName,
|
||||
lastName = data.lastName,
|
||||
dateOfBirth = data.dateOfBirth,
|
||||
gender = data.gender,
|
||||
twtName = data.twtName,
|
||||
department = data.department,
|
||||
startingCash = data.startingCash,
|
||||
startingBank = data.startingBank
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
-- editing a character from the ui.
|
||||
RegisterNUICallback("editCharacter", function(data)
|
||||
TriggerServerEvent("editCharacter", {
|
||||
firstName = data.firstName,
|
||||
lastName = data.lastName,
|
||||
dateOfBirth = data.dateOfBirth,
|
||||
gender = data.gender,
|
||||
twtName = data.twtName,
|
||||
department = data.department,
|
||||
id = data.id
|
||||
})
|
||||
end)
|
||||
|
||||
-- deleting a character from the ui.
|
||||
RegisterNUICallback("delCharacter", function(data)
|
||||
TriggerServerEvent("delCharacter", data.character)
|
||||
characterAmount = characterAmount -1
|
||||
SendNUIMessage({
|
||||
characterAmount = characterAmount .. "/" .. config.characterLimit
|
||||
})
|
||||
end)
|
||||
|
||||
-- Quit button from ui.
|
||||
RegisterNUICallback("exitGame", function(data)
|
||||
TriggerServerEvent("exitGame")
|
||||
end)
|
||||
|
||||
-- Teleporting using ui.
|
||||
RegisterNUICallback("tpToLocation", function(data)
|
||||
local ped = PlayerPedId()
|
||||
FreezeEntityPosition(ped, false)
|
||||
SetEntityCoords(ped, tonumber(data.x), tonumber(data.y), tonumber(data.z), false, false, false, false)
|
||||
FreezeEntityPosition(ped, true)
|
||||
SwitchInPlayer(ped)
|
||||
Citizen.Wait(500)
|
||||
SetDisplay(false, "ui")
|
||||
Citizen.Wait(500)
|
||||
FreezeEntityPosition(ped, false)
|
||||
SetEntityVisible(ped, true, 0)
|
||||
TriggerServerEvent("getMoney", selectedCharacter.id)
|
||||
end)
|
||||
|
||||
-- Choosing the do not tp button.
|
||||
RegisterNUICallback("tpDoNot", function()
|
||||
local ped = PlayerPedId()
|
||||
SwitchInPlayer(ped)
|
||||
Citizen.Wait(500)
|
||||
SetDisplay(false, "ui")
|
||||
Citizen.Wait(500)
|
||||
SetEntityVisible(ped, true, 0)
|
||||
FreezeEntityPosition(ped, false)
|
||||
TriggerServerEvent("getMoney", selectedCharacter.id)
|
||||
end)
|
||||
|
||||
-- discord rich presence will show on a users profile.
|
||||
if config.enableRichPresence then
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
SetDiscordAppId(config.appId)
|
||||
if selectedCharacter then
|
||||
SetRichPresence(" Playing : " .. config.serverName .. " as " .. selectedCharacter.firstName .. " " .. selectedCharacter.lastName)
|
||||
SetDiscordRichPresenceAsset(config.largeLogo)
|
||||
SetDiscordRichPresenceAssetText("Playing: " .. config.serverName)
|
||||
SetDiscordRichPresenceAssetSmall(config.smallLogo)
|
||||
SetDiscordRichPresenceAssetSmallText("Playing as: " .. selectedCharacter.firstName .. " " .. selectedCharacter.lastName)
|
||||
SetDiscordRichPresenceAction(0, config.firstButtonName, config.firstButtonLink)
|
||||
SetDiscordRichPresenceAction(1, config.secondButtonName, config.secondButtonLink)
|
||||
end
|
||||
Citizen.Wait(config.updateIntervall * 1000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- show server name, first name, last name, and the amount of money the character has in the pause menu.
|
||||
if config.customPauseMenu then
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(0)
|
||||
if selectedCharacter then
|
||||
if IsPauseMenuActive() then
|
||||
BeginScaleformMovieMethodOnFrontendHeader("SET_HEADING_DETAILS")
|
||||
AddTextEntry("FE_THDR_GTAO", config.serverName)
|
||||
ScaleformMovieMethodAddParamPlayerNameString(selectedCharacter.firstName .. " " .. selectedCharacter.lastName)
|
||||
if config.enableMoneySystem then
|
||||
PushScaleformMovieFunctionParameterString("Cash: $" .. tostring(selectedCharacter.cash))
|
||||
PushScaleformMovieFunctionParameterString("Bank: $" .. tostring(selectedCharacter.bank))
|
||||
end
|
||||
EndScaleformMovieMethod()
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Change character command
|
||||
RegisterCommand(config.changeCharacterCommand, function()
|
||||
SwitchOutPlayer(PlayerPedId(), 0, 1)
|
||||
Citizen.Wait(2000)
|
||||
FreezeEntityPosition(ped, true)
|
||||
SetEntityVisible(ped, false, 0)
|
||||
SetDisplay(true, "ui")
|
||||
end, false)
|
||||
|
||||
-- chat suggestions
|
||||
TriggerEvent("chat:addSuggestion", "/" .. config.changeCharacterCommand, "Switch your framework character.")
|
||||
if config.enableMoneySystem then
|
||||
TriggerEvent("chat:addSuggestion", "/" .. config.payCommand, "Transfer money to player", {{name="id", help="Player server id" }, {name="amount", help="amount to pay"}})
|
||||
TriggerEvent("chat:addSuggestion", "/" .. config.giveCommand, "Give money to closeby player", {{name="amount", help="amount to give"}})
|
||||
end
|
||||
@@ -1,404 +0,0 @@
|
||||
-- For support join my discord: https://discord.gg/Z9Mxu72zZ6
|
||||
|
||||
expectedName = "ND_Core" -- This is the resource and is not suggested to be changed.
|
||||
resource = GetCurrentResourceName()
|
||||
|
||||
-- check if resource is renamed
|
||||
if resource ~= expectedName then
|
||||
print("^1[^4" .. expectedName .. "^1] WARNING^0")
|
||||
print("Change the resource name to ^4" .. expectedName .. " ^0or else it won't work!")
|
||||
end
|
||||
|
||||
-- add dots to version.
|
||||
function fixVersion(version)
|
||||
return string.sub(version, 1, 1) .. "." .. string.sub(version, 2, 2) .. "." .. string.sub(version, 3, 3)
|
||||
end
|
||||
|
||||
-- check if resource version is up to date
|
||||
PerformHttpRequest("https://raw.githubusercontent.com/Andyyy7666/ND_Framework/main/ND_Core/fxmanifest.lua", function(errorCode, resultData, resultHeaders)
|
||||
i, j = string.find(tostring(resultData), "version")
|
||||
resultData = string.sub(tostring(resultData), i, j + 12)
|
||||
resultData = string.gsub(resultData, "version \"", "")
|
||||
i, j = string.find(resultData, "\"")
|
||||
resultData = string.sub(resultData, 1, i - 1)
|
||||
local githubVersion = string.gsub(resultData, "%.", "")
|
||||
local fileVersion = string.gsub(GetResourceMetadata(expectedName, "version", 0), "%.", "")
|
||||
githubVersion = tonumber(githubVersion)
|
||||
fileVersion = tonumber(fileVersion)
|
||||
|
||||
if githubVersion and fileVersion then
|
||||
if githubVersion > fileVersion then
|
||||
print("^1[^4" .. expectedName .. "^1] WARNING^0")
|
||||
print("^4" .. expectedName .. " ^0is outdated. Please update it from ^5https://github.com/Andyyy7666/ND_Framework ^0| Current Version: ^1" .. fixVersion(fileVersion) .. " ^0| New Version: ^2" .. fixVersion(githubVersion) .. " ^0|")
|
||||
elseif githubVersion < fileVersion then
|
||||
print("^1[^4" .. expectedName .. "^1] WARNING^0")
|
||||
print("^4" .. expectedName .. " ^0version number is higher than expected | Current Version: ^3" .. fixVersion(fileVersion) .. " ^0| Expected Version: ^2" .. fixVersion(githubVersion) .. " ^0|")
|
||||
else
|
||||
print("^4" .. expectedName .. " ^0is up to date | Current Version: ^2" .. fixVersion(fileVersion) .. " ^0|")
|
||||
end
|
||||
else
|
||||
print("^1[^4" .. expectedName .. "^1] WARNING^0")
|
||||
print("You may not have the latest version of ^4" .. expectedName .. "^0. A newer, improved version may be present at ^5https://github.com/Andyyy7666/ND_Framework^0")
|
||||
end
|
||||
end)
|
||||
|
||||
-- Used to retrive the players discord server nickname, discord name and tag, and the roles.
|
||||
function getUserDiscordInfo(discordUserId)
|
||||
local data
|
||||
PerformHttpRequest("https://discordapp.com/api/guilds/" .. server_config.guildId .. "/members/" .. discordUserId, function(errorCode, resultData, resultHeaders)
|
||||
if errorCode ~= 200 then
|
||||
return
|
||||
end
|
||||
local result = json.decode(resultData)
|
||||
local roles = {}
|
||||
for _, roleId in pairs(result.roles) do
|
||||
roles[roleId] = roleId
|
||||
end
|
||||
data = {
|
||||
nickname = result.nick,
|
||||
discordTag = tostring(result.user.username) .. "#" .. tostring(result.user.discriminator),
|
||||
roles = roles
|
||||
}
|
||||
end, "GET", "", {["Content-Type"] = "application/json", ["Authorization"] = "Bot " .. server_config.discordServerToken})
|
||||
while not data do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
-- Get player any identifier, available types: steam, license, xbl, ip, discord, live.
|
||||
function GetPlayerIdentifierFromType(type, source)
|
||||
local identifierCount = GetNumPlayerIdentifiers(source)
|
||||
for count = 0, identifierCount do
|
||||
local identifier = GetPlayerIdentifier(source, count)
|
||||
if identifier and string.find(identifier, type) then
|
||||
return identifier
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function validateMoney(cash, bank)
|
||||
if tonumber(cash) > config.maxStartingCash or tonumber(bank) > config.maxStartingBank then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function validateDepartment(player, department)
|
||||
local departmentExists = config.departments[department]
|
||||
if departmentExists then
|
||||
local discordUserId = string.gsub(GetPlayerIdentifierFromType("discord", player), "discord:", "")
|
||||
local roles = getUserDiscordInfo(discordUserId).roles
|
||||
|
||||
for _, roleId in pairs(departmentExists) do
|
||||
if roles[roleId] or roleId == 0 or roleId == "0" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
RegisterNetEvent("checkPerms")
|
||||
AddEventHandler("checkPerms", function()
|
||||
local player = source
|
||||
local discordUserId = string.gsub(GetPlayerIdentifierFromType("discord", player), "discord:", "")
|
||||
local allowedRoles = {}
|
||||
local roles = getUserDiscordInfo(discordUserId).roles
|
||||
|
||||
for dept, roleTable in pairs(config.departments) do
|
||||
for _, roleId in pairs(roleTable) do
|
||||
if roles[roleId] or roleId == 0 or roleId == "0" then
|
||||
table.insert(allowedRoles, dept)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TriggerClientEvent("permsChecked", player, allowedRoles)
|
||||
end)
|
||||
|
||||
-- Inserting the players characters into characters table
|
||||
RegisterNetEvent("getCharacters")
|
||||
AddEventHandler("getCharacters", function()
|
||||
local player = source
|
||||
local characters = {}
|
||||
exports.oxmysql:query("SELECT * FROM characters WHERE license = ?", {GetPlayerIdentifierFromType("license", player)}, function(result)
|
||||
if result then
|
||||
for i = 1, #result do
|
||||
temp = result[i]
|
||||
characters[temp.character_id] = {id = temp.character_id, firstName = temp.first_name, lastName = temp.last_name, dob = temp.dob, gender = temp.gender, twt = temp.twt, department = temp.department, cash = temp.cash, bank = temp.bank}
|
||||
end
|
||||
TriggerClientEvent("returnCharacters", player, characters)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Creating a new character and increasing the character id.
|
||||
RegisterNetEvent("newCharacter")
|
||||
AddEventHandler("newCharacter", function(newCharacter)
|
||||
local player = source
|
||||
local license = GetPlayerIdentifierFromType("license", player)
|
||||
|
||||
-- validate that the person has permission to use the department.
|
||||
local departmentCheck = validateDepartment(player, newCharacter.department)
|
||||
if not departmentCheck then return end
|
||||
|
||||
local startingCash = newCharacter.startingCash
|
||||
local startingBank = newCharacter.startingBank
|
||||
|
||||
if config.enableMoneySystem then
|
||||
-- Don't trust the client, validate maximum amounts.
|
||||
local moneyCheck = validateMoney(startingCash, startingBank)
|
||||
|
||||
-- Set money to maximum amount in the config .
|
||||
-- Only triggers if the client is sending an amount that exceeds the maximum.
|
||||
if not moneyCheck then
|
||||
startingCash = config.maxStartingCash
|
||||
startingBank = config.maxStartingBank
|
||||
end
|
||||
end
|
||||
|
||||
exports.oxmysql:query("SELECT character_id FROM characters WHERE license = ?", {GetPlayerIdentifierFromType("license", player)}, function(result)
|
||||
if (result) and (config.characterLimit > #result) then
|
||||
exports.oxmysql:query("INSERT INTO characters (license, first_name, last_name, dob, gender, twt, department, cash, bank) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", {license, newCharacter.firstName, newCharacter.lastName, newCharacter.dateOfBirth, newCharacter.gender, newCharacter.twtName, newCharacter.department, startingCash, startingBank}, function(id)
|
||||
if id then
|
||||
exports.oxmysql:query("SELECT * FROM characters WHERE license = ?", {GetPlayerIdentifierFromType("license", player)}, function(result)
|
||||
if result then
|
||||
characters = {}
|
||||
for i = 1, #result do
|
||||
temp = result[i]
|
||||
characters[temp.character_id] = {id = temp.character_id, firstName = temp.first_name, lastName = temp.last_name, dob = temp.dob, gender = temp.gender, twt = temp.twt, department = temp.department, cash = temp.cash, bank = temp.bank}
|
||||
end
|
||||
TriggerClientEvent("returnCharacters", player, characters)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Delete character from database.
|
||||
RegisterNetEvent("delCharacter")
|
||||
AddEventHandler("delCharacter", function(character_id)
|
||||
local player = source
|
||||
local license = GetPlayerIdentifierFromType("license", player)
|
||||
exports.oxmysql:query("DELETE FROM characters WHERE license = ? AND character_id = ?", {license, character_id})
|
||||
end)
|
||||
|
||||
-- Update the character info when edited.
|
||||
RegisterNetEvent("editCharacter")
|
||||
AddEventHandler("editCharacter", function(newCharacter)
|
||||
local player = source
|
||||
|
||||
-- validate that the person has permission to use the department.
|
||||
local departmentCheck = validateDepartment(player, newCharacter.department)
|
||||
if not departmentCheck then return end
|
||||
|
||||
exports.oxmysql:query("UPDATE characters SET first_name = ?, last_name = ?, dob = ?, gender = ?, twt = ?, department = ? WHERE license = ? AND character_id = ?", {newCharacter.firstName, newCharacter.lastName, newCharacter.dateOfBirth, newCharacter.gender, newCharacter.twtName, newCharacter.department, GetPlayerIdentifierFromType("license", player), newCharacter.id})
|
||||
end)
|
||||
|
||||
-- onlinePlayers table, this is used to store all the players current character info on the server.
|
||||
onlinePlayers = {}
|
||||
|
||||
-- add a player to the table.
|
||||
RegisterNetEvent("characterOnline")
|
||||
AddEventHandler("characterOnline", function(id)
|
||||
local player = source
|
||||
local license = GetPlayerIdentifierFromType("license", player)
|
||||
exports.oxmysql:query("SELECT * FROM characters WHERE license = ? AND character_id = ?", {license, id}, function(result)
|
||||
if result then
|
||||
local i = result[1]
|
||||
onlinePlayers[player] = {
|
||||
characterId = id,
|
||||
firstName = i.first_name,
|
||||
lastName = i.last_name,
|
||||
dob = i.dob,
|
||||
gender = i.gender,
|
||||
twt = i.twt,
|
||||
dept = i.department,
|
||||
cash = i.cash,
|
||||
bank = i.bank
|
||||
}
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Remove player from onlinePlayers table when they leave.
|
||||
AddEventHandler("playerDropped", function(reason)
|
||||
local player = source
|
||||
onlinePlayers[player] = nil
|
||||
end)
|
||||
|
||||
-- Disconnecting a player
|
||||
RegisterNetEvent("exitGame")
|
||||
AddEventHandler("exitGame", function()
|
||||
local player = source
|
||||
DropPlayer(player, "Disconnected using framework.")
|
||||
end)
|
||||
|
||||
-- this is for the exports
|
||||
function getCharacterTable()
|
||||
return onlinePlayers
|
||||
end
|
||||
|
||||
function updateMoney(player)
|
||||
local player = tonumber(player)
|
||||
local license = GetPlayerIdentifierFromType("license", player)
|
||||
exports.oxmysql:query("SELECT cash, bank FROM characters WHERE license = ? AND character_id = ?", {license, onlinePlayers[player].characterId}, function(result)
|
||||
if result then
|
||||
local cash = result[1].cash
|
||||
local bank = result[1].bank
|
||||
onlinePlayers[player].cash = cash
|
||||
onlinePlayers[player].bank = bank
|
||||
TriggerClientEvent("updateMoney", player, cash, bank)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function transferBank(amount, player, target)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
local target = tonumber(target)
|
||||
if player == target then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You can't send money to yourself."}
|
||||
})
|
||||
return false
|
||||
elseif GetPlayerPing(target) == 0 then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "That player does not exist."}
|
||||
})
|
||||
return false
|
||||
elseif onlinePlayers[player].bank < amount then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You don't have enough money."}
|
||||
})
|
||||
return false
|
||||
else
|
||||
exports.oxmysql:query("UPDATE characters SET bank = bank - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
updateMoney(player)
|
||||
exports.oxmysql:query("UPDATE characters SET bank = bank + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", target), onlinePlayers[target].characterId})
|
||||
updateMoney(target)
|
||||
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {0, 255, 0},
|
||||
args = {"Success", "You paid " .. onlinePlayers[target].firstName .. " " .. onlinePlayers[target].lastName .. " $" .. amount .. "."}
|
||||
})
|
||||
TriggerClientEvent("receiveBank", target, amount, onlinePlayers[player].firstName .. " " .. onlinePlayers[player].lastName, player)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function giveCashToClosestTarget(amount, player)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
local playerFound = false
|
||||
local playerCoords = GetEntityCoords(GetPlayerPed(player))
|
||||
if onlinePlayers[player].cash < amount then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "You don't have enough money."}
|
||||
})
|
||||
return false
|
||||
else
|
||||
for targetId, targetInfo in pairs(onlinePlayers) do
|
||||
local targetCoords = GetEntityCoords(GetPlayerPed(targetId))
|
||||
if (#(playerCoords - targetCoords) < 2.0) and (targetId ~= player) and not playerFound then
|
||||
exports.oxmysql:query("UPDATE characters SET cash = cash - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
updateMoney(player)
|
||||
exports.oxmysql:query("UPDATE characters SET cash = cash + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", targetId), tonumber(targetInfo.characterId)})
|
||||
updateMoney(targetId)
|
||||
playerFound = true
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {0, 255, 0},
|
||||
args = {"Success", "You gave " .. onlinePlayers[targetId].firstName .. " " .. onlinePlayers[targetId].lastName .. " $" .. amount .. "."}
|
||||
})
|
||||
TriggerClientEvent("receiveCash", targetId, amount, onlinePlayers[player].firstName .. " " .. onlinePlayers[player].lastName, player)
|
||||
break
|
||||
end
|
||||
end
|
||||
if not playerFound then
|
||||
TriggerClientEvent("chat:addMessage", player, {
|
||||
color = {255, 0, 0},
|
||||
args = {"Error", "No players nearby."}
|
||||
})
|
||||
return false
|
||||
end
|
||||
playerFound = false
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function withdrawMoney(amount, player)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if onlinePlayers[player].bank >= amount then
|
||||
exports.oxmysql:query("UPDATE characters SET bank = bank - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
exports.oxmysql:query("UPDATE characters SET cash = cash + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
Citizen.Wait(500)
|
||||
updateMoney(player)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function depositMoney(amount, player)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if onlinePlayers[player].cash >= amount then
|
||||
exports.oxmysql:query("UPDATE characters SET cash = cash - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
exports.oxmysql:query("UPDATE characters SET bank = bank + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
Citizen.Wait(500)
|
||||
updateMoney(player)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function deductMoney(amount, player, from)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if from == "bank" then
|
||||
exports.oxmysql:query("UPDATE characters SET bank = bank - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
Citizen.Wait(500)
|
||||
updateMoney(player)
|
||||
elseif from == "cash" then
|
||||
exports.oxmysql:query("UPDATE characters SET cash = cash - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
Citizen.Wait(500)
|
||||
updateMoney(player)
|
||||
end
|
||||
end
|
||||
|
||||
function addMoney(amount, player, to)
|
||||
local amount = tonumber(amount)
|
||||
local player = tonumber(player)
|
||||
if to == "bank" then
|
||||
exports.oxmysql:query("UPDATE characters SET bank = bank + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
Citizen.Wait(500)
|
||||
updateMoney(player)
|
||||
elseif to == "cash" then
|
||||
exports.oxmysql:query("UPDATE characters SET cash = cash + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), onlinePlayers[player].characterId})
|
||||
Citizen.Wait(500)
|
||||
updateMoney(player)
|
||||
end
|
||||
end
|
||||
|
||||
-- paying command.
|
||||
RegisterCommand(config.payCommand, function(source, args, raw)
|
||||
local player = source
|
||||
local target = tonumber(args[1])
|
||||
local amount = math.floor(tonumber(args[2]))
|
||||
transferBank(amount, player, target)
|
||||
end)
|
||||
|
||||
-- Give money command.
|
||||
RegisterCommand(config.giveCommand, function(source, args, raw)
|
||||
local player = source
|
||||
local amount = math.floor(tonumber(args[1]))
|
||||
giveCashToClosestTarget(amount, player)
|
||||
end)
|
||||
@@ -1,172 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="https://use.fontawesome.com/releases/v5.15.4/js/all.js" data-auto-a11y="true"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
||||
<script src="script.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!--Main page design-->
|
||||
<section id="overlay">
|
||||
<div id="logoContainer">
|
||||
<img src="https://i.imgur.com/02A5Cgl.png" id="logo">
|
||||
</div>
|
||||
|
||||
<h1 id="serverName"></h1>
|
||||
<p id="aop" class="mainPage" style="margin-bottom: -1vh;"></p>
|
||||
<p class="mainPage">Select or create a character:</p>
|
||||
|
||||
<button class="homeScreenButton" id="newCharacterButton"><a class="fas fa-plus-circle" style="color:white;"></a> Create New Character <a id="playerAmount"></a></button>
|
||||
<br>
|
||||
<button class="homeScreenButton" id="quitGameButton"><a class="fas fa-sign-out-alt" style="color:white;"></a> Quit Game</button>
|
||||
|
||||
<div id="charactersSection">
|
||||
<!--Characters will be added here-->
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--Create character menu design-->
|
||||
<form id="characterCreator" class="characterMenu">
|
||||
<p id="characterCreatorTopText"><a class="fas fa-user-edit" style="color:white;"></a> Character Creation</p>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<div id="characterInfoContainer">
|
||||
<div id="characterInfoContainerLeft">
|
||||
<!--First name-->
|
||||
<label class="firstRowText" for="firstname">First Name</label>
|
||||
<br>
|
||||
<input id="firstName" class="firstRowInput" type="text" placeholder="First Name" name="firstname" required>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Dob-->
|
||||
<label class="secondRowText" for="dob">Date of Birth</label>
|
||||
<br>
|
||||
<input id="dateOfBirth" class="secondRowInput" type="date" name="dob" required>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Twotter name-->
|
||||
<label class="thirdRowText" for="twotter">Twotter Name</label>
|
||||
<br>
|
||||
<input id="twtName" class="thirdRowInput" type="text" placeholder="Twotter Name" name="twotter" required>
|
||||
</div>
|
||||
<div id="characterInfoContainerRight">
|
||||
<!--Last name-->
|
||||
<label class="firstRowText" for="lastname">Last Name</label>
|
||||
<br>
|
||||
<input id="lastName" style="width: 93%;" class="firstRowInput" type="text" placeholder="Last Name" name="lastname" required>
|
||||
|
||||
<br>
|
||||
|
||||
<!--gender-->
|
||||
<label class="secondRowText" for="gender">Gender</label>
|
||||
<br>
|
||||
<select id="gender" class="secondRowInput" name="gender" required>
|
||||
<option class="secondRowInput">Male</option>
|
||||
<option class="secondRowInput">Female</option>
|
||||
</select>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Department-->
|
||||
<label class="thirdRowText" for="department">Department</label>
|
||||
<br>
|
||||
<select id="department" class="thirdRowInput departments" name="department" required></select>
|
||||
</div>
|
||||
</div>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<button id="submitCharacterCreation" class="characterSubmitButton" type="submit" form="characterCreator"><a class="fas fa-plus-circle" style="color:white;"></a> Create Character</button>
|
||||
<button id="cancelCharacterCreation" class="characterResetButton" type="reset"><a class="fas fa-times-circle" style="color:white;"></a> Cancel</button>
|
||||
</form>
|
||||
|
||||
<!--Edit character menu design-->
|
||||
<form id="characterEditor" class="characterMenu">
|
||||
<p id="characterCreatorTopText"><a class="fas fa-user-edit" style="color:white;"></a> Character Editor</p>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<div id="characterInfoContainer">
|
||||
<div id="characterInfoContainerLeft">
|
||||
<!--First name-->
|
||||
<label class="firstRowText" for="firstname">First Name</label>
|
||||
<br>
|
||||
<input id="newFirstName" class="firstRowInput" type="text" placeholder="First Name" name="firstname" required>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Dob-->
|
||||
<label class="secondRowText" for="dob">Date of Birth</label>
|
||||
<br>
|
||||
<input id="newDateOfBirth" class="secondRowInput" type="date" name="dob" required>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Twotter name-->
|
||||
<label class="thirdRowText" for="twotter">Twotter Name</label>
|
||||
<br>
|
||||
<input id="newTwtName" class="thirdRowInput" type="text" placeholder="Twotter Name" name="twotter" required>
|
||||
</div>
|
||||
<div id="characterInfoContainerRight">
|
||||
<!--Last name-->
|
||||
<label class="firstRowText" for="lastname">Last Name</label>
|
||||
<br>
|
||||
<input id="newLastName" style="width: 93%;" class="firstRowInput" type="text" placeholder="Last Name" name="lastname" required>
|
||||
|
||||
<br>
|
||||
|
||||
<!--gender-->
|
||||
<label class="secondRowText" for="gender">Gender</label>
|
||||
<br>
|
||||
<select id="newGender" class="secondRowInput" name="gender" required>
|
||||
<option class="secondRowInput">Male</option>
|
||||
<option class="secondRowInput">Female</option>
|
||||
</select>
|
||||
|
||||
<br>
|
||||
|
||||
<!--Department-->
|
||||
<label class="thirdRowText" for="department">Department</label>
|
||||
<br>
|
||||
<select id="newDepartment" class="thirdRowInput departments" name="department" required></select>
|
||||
</div>
|
||||
</div>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<button id="submitCharacterEditing" class="characterSubmitButton" type="submit" form="characterEditor"><a class="fas fa-plus-circle" style="color:white;"></a> Save Changes</button>
|
||||
<button id="cancelCharacterEditing" class="characterResetButton" type="reset"><a class="fas fa-times-circle" style="color:white;"></a> Cancel</button>
|
||||
</form>
|
||||
|
||||
<!--Character Spawn options-->
|
||||
<section id="spawnLocation" class="spawnMenu">
|
||||
<p id="characterCreatorTopText"><a class="fas fa-map-marker-alt" style="color:white;"></a> Spawn Location</p>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<div id="spawnMenuContainer">
|
||||
<!--Spawn locations will be added here-->
|
||||
</div>
|
||||
<hr id="characterCreatorTopTextLine" style="margin-top: 3vh;">
|
||||
<button id="tpDoNot" class="characterSubmitButton" style="margin-left: 26vw; margin-bottom: 2vh;"><a class="fas fa-compass" style="color:white;"></a> Do not teleport</button>
|
||||
<button id="tpCancel" class="characterResetButton"><a class="fas fa-times-circle" style="color:white;"></a> Cancel</button>
|
||||
</section>
|
||||
|
||||
<!--Confirm exit game menu design-->
|
||||
<section id="exitGameMenu" class="confirmationScreen">
|
||||
<p id="characterCreatorTopText">Are you sure you'd like to quit the game?</p>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<button id="exitGameConfirm" class="confirmationScreenConfirm"><a class="fas fa-check-circle" style="color:white;"></a> Confirm</button>
|
||||
<button id="exitGameCancel" class="confirmationScreenCancel"><a class="fas fa-times-circle" style="color:white;"></a> Cancel</button>
|
||||
</section>
|
||||
|
||||
<!--Confirm delete character button-->
|
||||
<section id="deleteCharacterMenu" class="confirmationScreen">
|
||||
<p id="characterCreatorTopText">Are you sure you'd like to delete this character?</p>
|
||||
<hr id="characterCreatorTopTextLine">
|
||||
<button id="deleteCharacterConfirm" class="confirmationScreenConfirm"><a class="fas fa-check-circle" style="color:white;"></a> Confirm</button>
|
||||
<button id="deleteCharacterCancel" class="confirmationScreenCancel"><a class="fas fa-times-circle" style="color:white;"></a> Cancel</button>
|
||||
</section>
|
||||
|
||||
<!--Money hud-->
|
||||
<div id="money">
|
||||
<p id="cash" class="text"></p>
|
||||
<p id="bank" class="text"></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,275 +0,0 @@
|
||||
$(function() {
|
||||
let displayOn = true
|
||||
|
||||
// Hide/show ui function
|
||||
function display(bool) {
|
||||
if (bool) {
|
||||
displayOn = true;
|
||||
$("body").show();
|
||||
Money(false)
|
||||
} else {
|
||||
displayOn = false;
|
||||
$("body").hide();
|
||||
}
|
||||
}
|
||||
function characterCreatorMenu(bool) {
|
||||
if (bool) {
|
||||
$("#characterCreator").fadeIn("slow");
|
||||
$("#characterEditor, #exitGameMenu, #deleteCharacterMenu, #spawnLocation").hide();
|
||||
return;
|
||||
}
|
||||
$("#characterCreator").fadeOut("slow");
|
||||
}
|
||||
function characterEditorMenu(bool) {
|
||||
if (bool) {
|
||||
$("#characterEditor").fadeIn("slow");
|
||||
$("#characterCreator, #exitGameMenu, #deleteCharacterMenu, #spawnLocation").hide();
|
||||
return;
|
||||
}
|
||||
$("#characterEditor").fadeOut("slow");
|
||||
}
|
||||
function exitGameMenu(bool) {
|
||||
if (bool) {
|
||||
$("#exitGameMenu").fadeIn("slow");
|
||||
$("#characterCreator, #characterEditor, #deleteCharacterMenu, #spawnLocation").hide();
|
||||
return;
|
||||
}
|
||||
$("#exitGameMenu").fadeOut("slow");
|
||||
}
|
||||
function confirmDeleteMenu(bool) {
|
||||
if (bool) {
|
||||
$("#deleteCharacterMenu").fadeIn("slow");
|
||||
$("#characterCreator, #characterEditor, #exitGameMenu, #spawnLocation").hide();
|
||||
return;
|
||||
}
|
||||
$("#deleteCharacterMenu").fadeOut("slow");
|
||||
}
|
||||
function spawnMenu(bool) {
|
||||
if (bool) {
|
||||
$("#spawnLocation").fadeIn("slow");
|
||||
$("#characterCreator, #characterEditor, #exitGameMenu, #deleteCharacterMenu").hide();
|
||||
return;
|
||||
}
|
||||
$("#spawnLocation").fadeOut("slow");
|
||||
}
|
||||
function Money(bool) {
|
||||
if (bool) {
|
||||
$("#money").show();
|
||||
$("body").css("background-image", "none");
|
||||
$("body").show();
|
||||
if (displayOn === false) {
|
||||
$("#overlay").hide();
|
||||
}
|
||||
} else {
|
||||
$("#money").hide();
|
||||
$("#overlay").show();
|
||||
}
|
||||
}
|
||||
display(false);
|
||||
characterCreatorMenu(false);
|
||||
characterEditorMenu(false);
|
||||
exitGameMenu(false);
|
||||
confirmDeleteMenu(false);
|
||||
spawnMenu(false);
|
||||
Money(false);
|
||||
|
||||
window.addEventListener('message', function(event) {
|
||||
const item = event.data;
|
||||
if (item.type === "ui") {
|
||||
if (item.status) {
|
||||
$('#serverName').text(item.serverName);
|
||||
$("body").css("background-image", "url(" + item.background + ")");
|
||||
display(true);
|
||||
} else {
|
||||
display(false);
|
||||
}
|
||||
}
|
||||
|
||||
$('#playerAmount').text(item.characterAmount);
|
||||
|
||||
if (item.type === "character") {
|
||||
characterCreatorMenu(false);
|
||||
createCharacter(item.firstName, item.lastName, item.dateOfBirth, item.gender, item.twtName, item.department, item.startingCash, item.startingBank, item.id);
|
||||
}
|
||||
|
||||
if (item.type === "setSpawns") {
|
||||
$("#spawnMenuContainer").empty();
|
||||
setTimeout(function(){
|
||||
$("#spawnMenuContainer").append(`<button class="spawnButtons" data-x="${item.x}" data-y="${item.y}" data-z="${item.z}">${item.name}</button>`);
|
||||
$(".spawnButtons").click(function() {
|
||||
$.post(`https://${GetParentResourceName()}/tpToLocation`, JSON.stringify({
|
||||
x: $(this).data("x"),
|
||||
y: $(this).data("y"),
|
||||
z: $(this).data("z")
|
||||
}));
|
||||
spawnMenu(false);
|
||||
setTimeout(function(){
|
||||
$("#spawnMenuContainer").empty();
|
||||
}, 550);
|
||||
return;
|
||||
});
|
||||
}, 10);
|
||||
}
|
||||
|
||||
if (item.type === "givePerms") {
|
||||
$('.departments').append($('<option>', {
|
||||
text: item.deptRole
|
||||
}));
|
||||
}
|
||||
|
||||
if (item.type === "aop") {
|
||||
$("#aop").text(item.aop);
|
||||
}
|
||||
|
||||
if (item.type === "Money") {
|
||||
Money(true)
|
||||
$("#cash").text(item.cash);
|
||||
$("#bank").text(item.bank);
|
||||
}
|
||||
|
||||
if (item.type === "onStart" && item.enableMoneySystem) {
|
||||
$("#characterInfoContainerLeft").append('<label class="fourthRowText" for="startingcash">Cash</label><br><input id="startingCash" class="fourthRowInput" type="number" pattern="[0-9]+" placeholder="$2500" name="startingcash" required>');
|
||||
$("#characterInfoContainerRight").append('<label class="fourthRowText" for="startingbank">Bank</label><br><input id="startingBank" class="fourthRowInput" type="number" pattern="[0-9]+" placeholder="$8000" name="startingbank" style="width: 93%;" required>');
|
||||
$("#startingBank").attr({
|
||||
"max": item.maxStartingBank,
|
||||
});
|
||||
$("#startingCash").attr({
|
||||
"max": item.maxStartingCash,
|
||||
});
|
||||
}
|
||||
|
||||
if (item.type === "refresh") {
|
||||
$("#charactersSection").empty();
|
||||
}
|
||||
})
|
||||
|
||||
function createCharacter(firstName, lastName, dateOfBirth, gender, twtName, department, startingCash, startingBank, id) {
|
||||
$("#charactersSection").append(`<button id="characterButton${id}" class="createdButton">${firstName} ${lastName} (${department})</button><button id="characterButtonEdit${id}" class="createdButtonEdit"><a class="fas fa-edit"></a> Edit</button><button id="characterButtonDelete${id}" class="createdButtonDelete"><a class="fas fa-trash-alt"></a> Delete</button>`);
|
||||
$(`#characterButton${id}`).click(function() {
|
||||
spawnMenu(true)
|
||||
$.post(`https://${GetParentResourceName()}/setMainCharacter`, JSON.stringify({
|
||||
firstName: firstName,
|
||||
lastName: lastName,
|
||||
dateOfBirth: dateOfBirth,
|
||||
gender: gender,
|
||||
twtName: twtName,
|
||||
department: department,
|
||||
startingCash: startingCash,
|
||||
startingBank: startingBank,
|
||||
character: id
|
||||
}));
|
||||
return;
|
||||
});
|
||||
$(`#characterButtonEdit${id}`).click(function() {
|
||||
characterEditorMenu(true)
|
||||
$("#newFirstName").val(firstName);
|
||||
$("#newLastName").val(lastName);
|
||||
$("#newDateOfBirth").val(dateOfBirth);
|
||||
$("#newGender").val(gender);
|
||||
$("#newTwtName").val(twtName);
|
||||
$("#newDepartment").val(department);
|
||||
characterEdited = id
|
||||
return;
|
||||
});
|
||||
$(`#characterButtonDelete${id}`).click(function() {
|
||||
confirmDeleteMenu(true)
|
||||
characterDeleting = id
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
$("#characterCreator").submit(function() {
|
||||
$.post(`https://${GetParentResourceName()}/newCharacter`, JSON.stringify({
|
||||
firstName: $("#firstName").val(),
|
||||
lastName: $("#lastName").val(),
|
||||
dateOfBirth: $("#dateOfBirth").val(),
|
||||
gender: $("#gender").val(),
|
||||
twtName: $("#twtName").val(),
|
||||
department: $("#department").val(),
|
||||
startingCash: $("#startingCash").val(),
|
||||
startingBank: $("#startingBank").val()
|
||||
}));
|
||||
characterCreatorMenu(false)
|
||||
$("#firstName, #lastName, #dateOfBirth, #twtName, #startingCash, #startingBank").val("")
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#characterEditor").submit(function() {
|
||||
characterEditorMenu(false)
|
||||
$.post(`https://${GetParentResourceName()}/editCharacter`, JSON.stringify({
|
||||
firstName: $("#newFirstName").val(),
|
||||
lastName: $("#newLastName").val(),
|
||||
dateOfBirth: $("#newDateOfBirth").val(),
|
||||
gender: $("#newGender").val(),
|
||||
twtName: $("#newTwtName").val(),
|
||||
department: $("#newDepartment").val(),
|
||||
id: characterEdited
|
||||
}));
|
||||
$("#characterButton" + characterEdited).text($("#newFirstName").val() + " " + $("#newLastName").val() + " (" + $("#newDepartment").val() + ")");
|
||||
return false;
|
||||
});
|
||||
|
||||
$("#deleteCharacterConfirm").click(function() {
|
||||
confirmDeleteMenu(false)
|
||||
$("#characterButton" + characterDeleting).fadeOut("slow",function(){
|
||||
$("#characterButton" + characterDeleting).remove();
|
||||
})
|
||||
$("#characterButtonEdit" + characterDeleting).fadeOut("slow",function(){
|
||||
$("#characterButtonEdit" + characterDeleting).remove();
|
||||
})
|
||||
$("#characterButtonDelete" + characterDeleting).fadeOut("slow",function(){
|
||||
$("#characterButtonDelete" + characterDeleting).remove();
|
||||
})
|
||||
$.post(`https://${GetParentResourceName()}/delCharacter`, JSON.stringify({
|
||||
character: characterDeleting
|
||||
}));
|
||||
return;
|
||||
});
|
||||
|
||||
$("#newCharacterButton").click(function() {
|
||||
characterCreatorMenu(true)
|
||||
return;
|
||||
});
|
||||
|
||||
$("#deleteCharacterCancel").click(function() {
|
||||
confirmDeleteMenu(false)
|
||||
return;
|
||||
});
|
||||
$("#cancelCharacterCreation").click(function() {
|
||||
characterCreatorMenu(false)
|
||||
return;
|
||||
});
|
||||
$("#cancelCharacterEditing").click(function() {
|
||||
characterEditorMenu(false)
|
||||
return;
|
||||
});
|
||||
|
||||
$("#tpCancel").click(function() {
|
||||
spawnMenu(false)
|
||||
setTimeout(function(){
|
||||
$("#spawnMenuContainer").empty();
|
||||
}, 550);
|
||||
return;
|
||||
});
|
||||
$("#tpDoNot").click(function() {
|
||||
$.post(`https://${GetParentResourceName()}/tpDoNot`);
|
||||
spawnMenu(false)
|
||||
setTimeout(function(){
|
||||
$("#spawnMenuContainer").empty();
|
||||
}, 550);
|
||||
return;
|
||||
});
|
||||
|
||||
$("#quitGameButton").click(function() {
|
||||
exitGameMenu(true)
|
||||
return;
|
||||
});
|
||||
$("#exitGameCancel").click(function() {
|
||||
exitGameMenu(false)
|
||||
return;
|
||||
});
|
||||
$("#exitGameConfirm").click(function() {
|
||||
$.post(`https://${GetParentResourceName()}/exitGame`);
|
||||
return;
|
||||
});
|
||||
});
|
||||
@@ -1,287 +0,0 @@
|
||||
body {
|
||||
background-size: 105%;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
/* Main page */
|
||||
#overlay {
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100vh;
|
||||
width: 30vw;
|
||||
background-color: rgba(2, 2, 2, 0.911);
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#charactersSection {
|
||||
height: 50%;
|
||||
margin: none;
|
||||
padding: none;
|
||||
width: 83%;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: rgba(2, 2, 2, 0);
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(99, 99, 99, 0.575);
|
||||
border-radius: 10px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgb(128, 128, 128);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#logoContainer {
|
||||
margin-top: 3vh;
|
||||
margin-left: 10vw;
|
||||
}
|
||||
#logo {
|
||||
height: 10vw;
|
||||
width: 10vw;
|
||||
}
|
||||
|
||||
#serverName {
|
||||
color: white;
|
||||
font-size: 130%;
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
text-align: center;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.mainPage {
|
||||
color: white;
|
||||
font-size: 95%;
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
text-align: center;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.homeScreenButton, .createdButton, .createdButtonEdit, .createdButtonDelete {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
border: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#newCharacterButton {
|
||||
margin-left: 9vw;
|
||||
margin-bottom: 0.8vh;
|
||||
height: 4.5vh;
|
||||
width: 12vw;
|
||||
background: rgb(95,141,254);
|
||||
background-image: linear-gradient(90deg, rgba(95,141,254,1) 0%, rgba(142,104,219,1) 100%);
|
||||
border-radius: 5vw;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
#quitGameButton {
|
||||
margin-left: 10vw;
|
||||
margin-bottom: 5vh;
|
||||
height: 4.5vh;
|
||||
width: 10vw;
|
||||
background: rgb(255,110,100);
|
||||
background: linear-gradient(90deg, rgb(255, 100, 208) 0%, rgb(255, 60, 109) 100%);
|
||||
border-radius: 5vw;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.createdButton {
|
||||
display: inline-block;
|
||||
margin-bottom: 1vh;
|
||||
margin-left: 5.5vw;
|
||||
height: 3vh;
|
||||
width: 10vw;
|
||||
background-color: rgb(17, 113, 238);
|
||||
border: none;
|
||||
border-radius: 0.5vh;
|
||||
transition: 0.3s;
|
||||
white-space: nowrap;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.createdButtonEdit {
|
||||
margin-left: 0.2vw;
|
||||
height: 3vh;
|
||||
width: 4vw;
|
||||
background-color: rgb(128, 128, 128);
|
||||
border: none;
|
||||
border-radius: 0.5vh;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.createdButtonDelete {
|
||||
margin-left: 0.2vw;
|
||||
height: 3vh;
|
||||
width: 4vw;
|
||||
background-color: rgb(236, 19, 19);
|
||||
border: none;
|
||||
border-radius: 0.5vh;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* Button transitions */
|
||||
#newCharacterButton:hover, #quitGameButton:hover, .characterSubmitButton:hover, .characterResetButton:hover, .confirmationScreenConfirm:hover, .confirmationScreenCancel:hover, .createdButton:hover, .createdButtonEdit:hover, .createdButtonDelete:hover, .spawnButtons:hover {
|
||||
transition: 0.3s;
|
||||
opacity: 0.7;
|
||||
}
|
||||
#newCharacterButton:active, #quitGameButton:active, .characterSubmitButton:active, .characterResetButton:active, .confirmationScreenConfirm:active, .confirmationScreenCancel:active, .createdButton:active, .createdButtonEdit:active, .createdButtonDelete:active, .spawnButtons:active {
|
||||
transition: none;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Character creator and Editor menu */
|
||||
.characterMenu {
|
||||
height: 60%;
|
||||
width: 50vw;
|
||||
margin: auto 0 auto 40vw;
|
||||
background-color: rgba(2, 2, 2, 0.911);
|
||||
border-radius: 3vh;
|
||||
}
|
||||
|
||||
#characterCreatorTopText {
|
||||
padding-top: 2vh;
|
||||
margin-left: 3vw;
|
||||
color: white;
|
||||
font-size: 120%;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#characterCreatorTopTextLine {
|
||||
background: rgb(255, 255, 255);
|
||||
background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(255,255,255,1) 15%, rgba(255,255,255,1) 85%, rgba(0, 0, 0, 0.014) 100%);
|
||||
height: 0.1vh;
|
||||
width: 95%;
|
||||
border: none;
|
||||
border-radius: 2vh;
|
||||
}
|
||||
|
||||
/* character info */
|
||||
#characterInfoContainer {
|
||||
padding: 2vh 3vw;
|
||||
}
|
||||
#characterInfoContainerLeft {
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
#characterInfoContainerRight {
|
||||
width: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.firstRowText, .secondRowText, .thirdRowText, .fourthRowText {
|
||||
color: white;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.firstRowInput, .secondRowInput, .thirdRowInput, .fourthRowInput {
|
||||
background: white;
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 0.2vw;
|
||||
height: 3vh;
|
||||
width: 95%;
|
||||
margin-top: 0.5vh;
|
||||
margin-bottom: 2vh;
|
||||
padding: 0 0 0 0.5vw;
|
||||
}
|
||||
|
||||
.characterSubmitButton {
|
||||
margin-top: 1vh;
|
||||
margin-left: 33.7vw;
|
||||
margin-bottom: 2vh;
|
||||
width: 8vw;
|
||||
background-color: rgb(17, 113, 238);
|
||||
}
|
||||
|
||||
.characterResetButton {
|
||||
width: 4vw;
|
||||
background-color: rgb(231, 50, 50);
|
||||
}
|
||||
|
||||
.characterSubmitButton, .characterResetButton, .confirmationScreenConfirm, .confirmationScreenCancel, .spawnButtons {
|
||||
height: 4vh;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
border: none;
|
||||
border-radius: 1vh;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* confirmation Screen */
|
||||
.confirmationScreen {
|
||||
height: 25vh;
|
||||
width: 30vw;
|
||||
margin-top: 20vh;
|
||||
margin-left: 45vw;
|
||||
background-color: rgba(2, 2, 2, 0.911);
|
||||
border-radius: 3vh;
|
||||
}
|
||||
|
||||
.confirmationScreenConfirm {
|
||||
margin-top: 5vh;
|
||||
margin-left: 19%;
|
||||
margin-right: 5%;
|
||||
width: 8vw;
|
||||
background-color: rgb(17, 113, 238);
|
||||
}
|
||||
|
||||
.confirmationScreenCancel {
|
||||
width: 8vw;
|
||||
background-color: rgb(231, 50, 50);
|
||||
}
|
||||
|
||||
.spawnMenu {
|
||||
height: 39%;
|
||||
width: 40vw;
|
||||
margin: auto 0 auto 40vw;
|
||||
background-color: rgba(2, 2, 2, 0.911);
|
||||
border-radius: 3vh;
|
||||
}
|
||||
|
||||
#spawnMenuContainer {
|
||||
margin-top: 3vh;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.spawnButtons {
|
||||
display: block;
|
||||
margin-left: 0;
|
||||
margin-bottom: 1vh;
|
||||
text-align: center;
|
||||
width: 95%;
|
||||
height: 4vh;
|
||||
background-color: rgb(17, 113, 238);
|
||||
}
|
||||
|
||||
.text {
|
||||
font-family: "Pricedown Bl", sans-serif;
|
||||
position: absolute;
|
||||
font-size: 1vw;
|
||||
color: rgba(255, 255, 255, 0.925);
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
padding: 0.15% 1.1%;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 10vw;
|
||||
}
|
||||
|
||||
#cash {
|
||||
top: 5.5vh;
|
||||
right: 1.5vw;
|
||||
}
|
||||
|
||||
#bank {
|
||||
top: 9vh;
|
||||
right: 1.5vw;
|
||||
}
|
||||
Reference in New Issue
Block a user