Installation
Guide for installing ps-housing
Setup Video by Kamaryn
Installation Instructions
Pay Attention to each step, Don't skip any of them.
1. Find the following events inside qb-multicharacter
and change in server/main.lua event to:
qb-multicharacter
and change in server/main.lua event to:qb-multicharacter > server > main.lua
RegisterNetEvent('qb-multicharacter:server:loadUserData', function(cData)
local src = source
if QBCore.Player.Login(src, cData.citizenid) then
repeat
Wait(10)
until hasDonePreloading[src]
print('^2[qb-core]^7 '..GetPlayerName(src)..' (Citizen ID: '..cData.citizenid..') has succesfully loaded!')
QBCore.Commands.Refresh(src)
TriggerClientEvent('ps-housing:client:setupSpawnUI', src, cData)
TriggerEvent("qb-log:server:CreateLog", "joinleave", "Loaded", "green", "**".. GetPlayerName(src) .. "** (<@"..(QBCore.Functions.GetIdentifier(src, 'discord'):gsub("discord:", "") or "unknown").."> | ||" ..(QBCore.Functions.GetIdentifier(src, 'ip') or 'undefined') .. "|| | " ..(QBCore.Functions.GetIdentifier(src, 'license') or 'undefined') .." | " ..cData.citizenid.." | "..src..") loaded..")
end
end)
qb-multicharacter > server > main.lua
RegisterNetEvent('qb-multicharacter:server:createCharacter', function(data)
local src = source
local newData = {}
newData.cid = data.cid
newData.charinfo = data
if QBCore.Player.Login(src, false, newData) then
repeat
Wait(10)
until hasDonePreloading[src]
print('^2[qb-core]^7 '..GetPlayerName(src)..' has succesfully loaded!')
QBCore.Commands.Refresh(src)
TriggerClientEvent("qb-multicharacter:client:closeNUI", src)
newData.citizenid = QBCore.Functions.GetPlayer(src).PlayerData.citizenid
TriggerClientEvent('ps-housing:client:setupSpawnUI', src, newData)
GiveStarterItems(src)
end
end)
2. Find the following events in qb-spawn
and change in client/client.lua event to:
qb-spawn
and change in client/client.lua event to:qb-spawn > client.lua > line 51 > 'qb-spawn:client:setupSpawns' event
RegisterNetEvent('qb-spawn:client:setupSpawns', function(cData, new, apps)
if not new then
QBCore.Functions.TriggerCallback('qb-spawn:server:getOwnedHouses', function(houses)
local myHouses = {}
if houses ~= nil then
for i = 1, (#houses), 1 do
local house = houses[i]
myHouses[#myHouses+1] = {
house = house,
label = (house.apartment or house.street) .. " " .. house.property_id,
}
end
end
Wait(500)
SendNUIMessage({
action = "setupLocations",
locations = QB.Spawns,
houses = myHouses,
isNew = new
})
end, cData.citizenid)
elseif new then
SendNUIMessage({
action = "setupAppartements",
locations = apps,
isNew = new
})
end
end)
qb-spawn > client.lua > line 134 > 'chooseAppa' NUI Callback
RegisterNUICallback('chooseAppa', function(data, cb)
local ped = PlayerPedId()
local appaYeet = data.appType
SetDisplay(false)
DoScreenFadeOut(500)
Wait(100)
FreezeEntityPosition(ped, false)
RenderScriptCams(false, true, 0, true, true)
SetCamActive(cam, false)
DestroyCam(cam, true)
SetCamActive(cam2, false)
DestroyCam(cam2, true)
SetEntityVisible(ped, true)
Wait(500)
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
TriggerEvent('QBCore:Client:OnPlayerLoaded')
Wait(100)
TriggerServerEvent("ps-housing:server:createNewApartment", appaYeet)
cb('ok')
end)
qb-spawn > client > client.lua > line 169 'spawnplayer' NUI Callback
RegisterNUICallback('spawnplayer', function(data, cb)
local location = tostring(data.spawnloc)
local type = tostring(data.typeLoc)
local ped = PlayerPedId()
local PlayerData = QBCore.Functions.GetPlayerData()
local insideMeta = PlayerData.metadata["inside"]
if type == "current" then
PreSpawnPlayer()
QBCore.Functions.GetPlayerData(function(pd)
ped = PlayerPedId()
SetEntityCoords(ped, pd.position.x, pd.position.y, pd.position.z)
SetEntityHeading(ped, pd.position.a)
FreezeEntityPosition(ped, false)
end)
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
TriggerEvent('QBCore:Client:OnPlayerLoaded')
if insideMeta.property_id ~= nil then
local property_id = insideMeta.property_id
TriggerServerEvent('ps-housing:server:enterProperty', tostring(property_id))
end
PostSpawnPlayer()
elseif type == "house" then
PreSpawnPlayer()
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
TriggerEvent('QBCore:Client:OnPlayerLoaded')
local property_id = data.spawnloc.property_id
TriggerServerEvent('ps-housing:server:enterProperty', tostring(property_id))
PostSpawnPlayer()
elseif type == "normal" then
local pos = QB.Spawns[location].coords
PreSpawnPlayer()
SetEntityCoords(ped, pos.x, pos.y, pos.z)
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
TriggerEvent('QBCore:Client:OnPlayerLoaded')
TriggerServerEvent('ps-housing:server:resetMetaData')
SetEntityCoords(ped, pos.x, pos.y, pos.z)
SetEntityHeading(ped, pos.w)
PostSpawnPlayer()
end
cb('ok')
end)
qb-spawn > server.lua > line 3
QBCore.Functions.CreateCallback('qb-spawn:server:getOwnedHouses', function(_, cb, cid)
if cid ~= nil then
local houses = MySQL.query.await('SELECT * FROM properties WHERE owner_citizenid = ?', {cid})
if houses[1] ~= nil then
cb(houses)
else
cb({})
end
else
cb({})
end
end)
3. Find the following events in qb-garages
and change:
qb-garages
and change:qb-garages > server > main.lua > around line 120 on event qb-garage:server:checkOwnership
Replace
local hasHouseKey = exports['qb-houses']:hasKey(result[1].license, result[1].citizenid, house)
With
local hasHouseKey = exports['ps-housing']:IsOwner(src, house)
qb-garages > client > main.lua > around line 451 add under event qb-garages:client:addHouseGarage
RegisterNetEvent('qb-garages:client:removeHouseGarage', function(house)
Config.HouseGarages[house] = nil
end)
For qb-garages V2:
Replace
if type == 'house' and not exports['qb-houses']:hasKey(Player.PlayerData.license, Player.PlayerData.citizenid, Config.HouseGarages[garage].label) then
With
if type == 'house' and not exports['ps-housing']:IsOwner(source, garage) then
qb-garages > client > main.lua > around line 392 add under event qb-garages:client:addHouseGarage
RegisterNetEvent('qb-garages:client:removeHouseGarage', function(house)
Config.Garages[house] = nil
end
4. Run the properties.sql
file, but be cautious. If a table named properties
already exists in your database, this operation will drop it, resulting in the loss of all its data.
properties.sql
file, but be cautious. If a table named properties
already exists in your database, this operation will drop it, resulting in the loss of all its data.5. Delete default qb-apartments
6. Delete default qb-houses
7. Delete qb-apartments/config.lua
references in qb-spawn
, qb-multicharacter
and qb-phone
fxmanifest.lua (and any other scripts that may reference it).
qb-apartments/config.lua
references in qb-spawn
, qb-multicharacter
and qb-phone
fxmanifest.lua (and any other scripts that may reference it).8. Install the dependencies.
Server.cfg Resource Order
ensure ox_lib
ensure ps-housing
ensure ps-realtor
ensure fivem-freecam
Notes
If a player is in their apartment/house and an admin does a "Bring to me" function, they will not see the player nor will the player see anyone else. This is because the player is still in their own unique routing bucket. Workaround: To fix this, the player must go back into their apartment and leave on their own.
Likewise, if an admin tries to "Go to" or "Spectate" a player that is in their apartment/house, the admin will not be able to see the apartment or player because it is in a different routing bucket.
We highly recommend making a folder named [ps-housing] and adding
ps-realtor
,fivem-freecam
,ox_lib
,ps-housing
inside the folder.
Logs System Setup
Go to
qb-smallresources/server/logs.lua
and add this:
['pshousing'] = 'yourdiscordwebhookhere',
Create a webhook for the channel you want the logs to show up in.
Replace the placeholder with your webhook link.
This system only supports qb-core for now.
Item Limits System
Choose an item you want to limit under
Config.Furniture
in undershared/config.lua
Add
["max"] = 3
or the number of your choice to the item (see example below)
{ ["object"] = "v_res_r_figcat", ["price"] = 300, ["max"] = 2, ["label"] = "Fig Cat" },
Resolving the "Foreign key constraint is incorrectly formed" Issue
If you come across an error such as Foreign key constraint is incorrectly formed
while importing the properties.sql
into your database, follow these steps to fix it.
Open your database in HeidiSQL.
Right-click on your database name and select "Edit."
Locate the database collation setting and take note of it.
You will need to format the
properties.sql
file to match your database collation.
If your database collation is set to utf8mb4_general_ci
, modify the last line of the properties.sql
file using VSCode or in HeidiSQL's query tab to the following:
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
This adjustment ensures that properties.sql
file's character set and collation match that of your database, effectively resolving the issue.
Last updated