From d39acb5e7259b116841988e3dc577117dfd5fa9a Mon Sep 17 00:00:00 2001 From: Beelzebub <34854689+Be1zebub@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:17:20 +0700 Subject: [PATCH 1/6] Isolate PreferredJobModel --- gamemode/modules/base/cl_jobmodels.lua | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/gamemode/modules/base/cl_jobmodels.lua b/gamemode/modules/base/cl_jobmodels.lua index 3a8b5d8e4..8dfb33ff7 100644 --- a/gamemode/modules/base/cl_jobmodels.lua +++ b/gamemode/modules/base/cl_jobmodels.lua @@ -4,6 +4,8 @@ sql.Query([[CREATE TABLE IF NOT EXISTS darkp_playermodels( model VARCHAR(140) NOT NULL );]]) +sql.Query("ALTER TABLE darkp_playermodels ADD COLUMN IF NOT EXISTS server VARCHAR(21);") + local preferredModels = {} @@ -14,7 +16,7 @@ function DarkRP.setPreferredJobModel(teamNr, model) local job = RPExtraTeams[teamNr] if not job then return end preferredModels[job.command] = model - sql.Query(string.format([[REPLACE INTO darkp_playermodels VALUES(%s, %s);]], sql.SQLStr(job.command), sql.SQLStr(model))) + sql.Query(string.format([[REPLACE INTO darkp_playermodels VALUES(%s, %s, %s);]], sql.SQLStr(job.command), sql.SQLStr(model), sql.SQLStr(game.GetIPAddress()))) net.Start("DarkRP_preferredjobmodel") net.WriteUInt(teamNr, 8) @@ -31,7 +33,7 @@ end --[[--------------------------------------------------------------------------- Load the preferred models ---------------------------------------------------------------------------]] -local function sendModels() -- run after the jobs have loaded +local function sendModels() net.Start("DarkRP_preferredjobmodels") for _, job in pairs(RPExtraTeams) do if not preferredModels[job.command] then net.WriteBit(false) continue end @@ -42,11 +44,22 @@ local function sendModels() -- run after the jobs have loaded net.SendToServer() end -do - local models = sql.Query([[SELECT jobcmd, model FROM darkp_playermodels;]]) +local function jobHasModel(job, model) + return istable(job.model) and table.HasValue(job.model, model) or job.model == model +end + +timer.Simple(0, function() + -- run after the jobs have loaded + local models = sql.Query([[SELECT jobcmd, model, server FROM darkp_playermodels;]]) + for _, v in ipairs(models or {}) do + if v.server and v.server ~= game.GetIPAddress() then continue end + + local job = DarkRP.getJobByCommand(v.jobcmd) + if job == nil or jobHasModel(job, v.model) == false then continue end + preferredModels[v.jobcmd] = v.model end - timer.Simple(0, sendModels) -end + sendModels() +end) From 0c28f94fbca2558c73bf2d62b6ee6d7a2cd19d7f Mon Sep 17 00:00:00 2001 From: Beelzebub <34854689+Be1zebub@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:23:55 +0700 Subject: [PATCH 2/6] == false > not Co-authored-by: Falco Peijnenburg --- gamemode/modules/base/cl_jobmodels.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamemode/modules/base/cl_jobmodels.lua b/gamemode/modules/base/cl_jobmodels.lua index 8dfb33ff7..5dd6ebaa3 100644 --- a/gamemode/modules/base/cl_jobmodels.lua +++ b/gamemode/modules/base/cl_jobmodels.lua @@ -56,7 +56,7 @@ timer.Simple(0, function() if v.server and v.server ~= game.GetIPAddress() then continue end local job = DarkRP.getJobByCommand(v.jobcmd) - if job == nil or jobHasModel(job, v.model) == false then continue end + if job == nil or not jobHasModel(job, v.model) then continue end preferredModels[v.jobcmd] = v.model end From 78ea72393a8948c13f32b436d99e1d15ab41e936 Mon Sep 17 00:00:00 2001 From: Beelzebub <34854689+Be1zebub@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:02:10 +0700 Subject: [PATCH 3/6] lua condition > sql condition --- gamemode/modules/base/cl_jobmodels.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gamemode/modules/base/cl_jobmodels.lua b/gamemode/modules/base/cl_jobmodels.lua index 5dd6ebaa3..7bcc07861 100644 --- a/gamemode/modules/base/cl_jobmodels.lua +++ b/gamemode/modules/base/cl_jobmodels.lua @@ -50,11 +50,9 @@ end timer.Simple(0, function() -- run after the jobs have loaded - local models = sql.Query([[SELECT jobcmd, model, server FROM darkp_playermodels;]]) + local models = sql.Query(string.format([[SELECT jobcmd, model FROM darkp_playermodels WHERE server IS NULL OR server = %s;]], sql.SQLStr(game.GetIPAddress()))) for _, v in ipairs(models or {}) do - if v.server and v.server ~= game.GetIPAddress() then continue end - local job = DarkRP.getJobByCommand(v.jobcmd) if job == nil or not jobHasModel(job, v.model) then continue end From cf48e5a1ccace9fda98467f429df2d29ba1d1c90 Mon Sep 17 00:00:00 2001 From: Falco Peijnenburg Date: Sat, 21 Sep 2024 13:38:11 +0200 Subject: [PATCH 4/6] Only create server column if exists --- gamemode/modules/base/cl_jobmodels.lua | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/gamemode/modules/base/cl_jobmodels.lua b/gamemode/modules/base/cl_jobmodels.lua index 7bcc07861..40169d525 100644 --- a/gamemode/modules/base/cl_jobmodels.lua +++ b/gamemode/modules/base/cl_jobmodels.lua @@ -1,10 +1,31 @@ -- Create a table for the preferred playermodels +-- +-- Note: the server column wasn't always there, so players may not have a value +-- for it, even though the code in this file always adds it. That is why it is +-- added as a NULLable column. sql.Query([[CREATE TABLE IF NOT EXISTS darkp_playermodels( jobcmd VARCHAR(45) NOT NULL PRIMARY KEY, - model VARCHAR(140) NOT NULL + model VARCHAR(140) NOT NULL, + server TEXT NULL );]]) -sql.Query("ALTER TABLE darkp_playermodels ADD COLUMN IF NOT EXISTS server VARCHAR(21);") + +-- Migration: the `server` column was added in 2024-09. With the above query +-- only creating the table if not exists, the table may not have the `server` +-- column if it was created earlier. This will add it in retrospect. +local tableInfo = sql.Query("PRAGMA table_info(darkp_playermodels)") +local serverColumnExists = false + +for _, info in ipairs(tableInfo) do + if info.name == "server" then + serverColumnExists = true + break + end +end + +if not serverColumnExists then + sql.Query("ALTER TABLE darkp_playermodels ADD COLUMN server TEXT;") +end local preferredModels = {} From aff96d93b57bc21cc0c5e0485ca9f36a90486ab5 Mon Sep 17 00:00:00 2001 From: Falco Peijnenburg Date: Sat, 21 Sep 2024 14:09:35 +0200 Subject: [PATCH 5/6] Create entirely new table to avoid conflicts --- gamemode/modules/base/cl_jobmodels.lua | 42 ++++++++++---------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/gamemode/modules/base/cl_jobmodels.lua b/gamemode/modules/base/cl_jobmodels.lua index 40169d525..6c07293e8 100644 --- a/gamemode/modules/base/cl_jobmodels.lua +++ b/gamemode/modules/base/cl_jobmodels.lua @@ -1,32 +1,22 @@ -- Create a table for the preferred playermodels -- --- Note: the server column wasn't always there, so players may not have a value --- for it, even though the code in this file always adds it. That is why it is --- added as a NULLable column. -sql.Query([[CREATE TABLE IF NOT EXISTS darkp_playermodels( - jobcmd VARCHAR(45) NOT NULL PRIMARY KEY, - model VARCHAR(140) NOT NULL, - server TEXT NULL +-- Note: in DarkRP before 2024-09, there was a different table called +-- `darkp_playermodels` (note the misspelling of "darkp"). This table was +-- missing the server column, meaning that preferred job models would persist +-- across multiple servers. To make preferred job models store per server, this +-- new table (without the spelling mistake) was created. +-- +-- See the original issue to create the player model preference feature: +-- https://github.com/FPtje/DarkRP/issues/979 and the subsequent refactor at +-- https://github.com/FPtje/DarkRP/pull/3266 +sql.Query([[CREATE TABLE IF NOT EXISTS darkrp_playermodels( + server TEXT NOT NULL, + jobcmd TEXT NOT NULL, + model TEXT NOT NULL, + PRIMARY KEY (server, jobcmd) );]]) --- Migration: the `server` column was added in 2024-09. With the above query --- only creating the table if not exists, the table may not have the `server` --- column if it was created earlier. This will add it in retrospect. -local tableInfo = sql.Query("PRAGMA table_info(darkp_playermodels)") -local serverColumnExists = false - -for _, info in ipairs(tableInfo) do - if info.name == "server" then - serverColumnExists = true - break - end -end - -if not serverColumnExists then - sql.Query("ALTER TABLE darkp_playermodels ADD COLUMN server TEXT;") -end - local preferredModels = {} @@ -37,7 +27,7 @@ function DarkRP.setPreferredJobModel(teamNr, model) local job = RPExtraTeams[teamNr] if not job then return end preferredModels[job.command] = model - sql.Query(string.format([[REPLACE INTO darkp_playermodels VALUES(%s, %s, %s);]], sql.SQLStr(job.command), sql.SQLStr(model), sql.SQLStr(game.GetIPAddress()))) + sql.Query(string.format([[REPLACE INTO darkrp_playermodels(server, jobcmd, model) VALUES(%s, %s, %s);]], sql.SQLStr(game.GetIPAddress()), sql.SQLStr(job.command), sql.SQLStr(model))) net.Start("DarkRP_preferredjobmodel") net.WriteUInt(teamNr, 8) @@ -71,7 +61,7 @@ end timer.Simple(0, function() -- run after the jobs have loaded - local models = sql.Query(string.format([[SELECT jobcmd, model FROM darkp_playermodels WHERE server IS NULL OR server = %s;]], sql.SQLStr(game.GetIPAddress()))) + local models = sql.Query(string.format([[SELECT jobcmd, model FROM darkrp_playermodels WHERE server = %s;]], sql.SQLStr(game.GetIPAddress()))) for _, v in ipairs(models or {}) do local job = DarkRP.getJobByCommand(v.jobcmd) From 289c07bdd9de90c3b8e653d2a33cca2b10b99420 Mon Sep 17 00:00:00 2001 From: Falco Peijnenburg Date: Sun, 22 Sep 2024 19:26:35 +0200 Subject: [PATCH 6/6] Also load from the old table --- gamemode/modules/base/cl_jobmodels.lua | 36 ++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/gamemode/modules/base/cl_jobmodels.lua b/gamemode/modules/base/cl_jobmodels.lua index 6c07293e8..bbca1449c 100644 --- a/gamemode/modules/base/cl_jobmodels.lua +++ b/gamemode/modules/base/cl_jobmodels.lua @@ -59,16 +59,42 @@ local function jobHasModel(job, model) return istable(job.model) and table.HasValue(job.model, model) or job.model == model end -timer.Simple(0, function() - -- run after the jobs have loaded - local models = sql.Query(string.format([[SELECT jobcmd, model FROM darkrp_playermodels WHERE server = %s;]], sql.SQLStr(game.GetIPAddress()))) - - for _, v in ipairs(models or {}) do +local function setPreferredModels(models) + for _, v in ipairs(models) do local job = DarkRP.getJobByCommand(v.jobcmd) if job == nil or not jobHasModel(job, v.model) then continue end preferredModels[v.jobcmd] = v.model end +end + +-- The old table, darkp_playermodels, acts as a global mapping of preferred +-- models for jobs. +local function setModelsFromOldTable() + local oldTableExists = tobool(sql.QueryValue([[SELECT 1 FROM sqlite_master WHERE type='table' AND name='darkp_playermodels']])) + if not oldTableExists then return end + + local models = sql.Query([[SELECT jobcmd, model FROM darkp_playermodels;]]) + + if not models then return end + setPreferredModels(models) +end + +-- The newer table is server specific. +local function setModelsFromNewTable() + local models = sql.Query(string.format([[SELECT jobcmd, model FROM darkrp_playermodels WHERE server = %s;]], sql.SQLStr(game.GetIPAddress()))) + + if not models then return end + setPreferredModels(models) +end + +timer.Simple(0, function() + -- Run after the jobs have loaded, to make sure the jobs can be looked up. + + -- Set models from the old table, before overriding them with data from the + -- new table. That way, server specific preferences always have precedence. + setModelsFromOldTable() + setModelsFromNewTable() sendModels() end)