diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index b0e76bbcf3..870bd730f0 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -504,7 +504,7 @@
/datum/controller/subsystem/ticker/proc/save_admin_data()
if(CONFIG_GET(flag/admin_legacy_system)) //we're already using legacy system so there's nothing to save
return
- else if(load_admins()) //returns true if there was a database failure and the backup was loaded from
+ else if(load_admins(TRUE)) //returns true if there was a database failure and the backup was loaded from
return
var/datum/DBQuery/query_admin_rank_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] p INNER JOIN [format_table_name("admin")] a ON p.ckey = a.ckey SET p.lastadminrank = a.rank")
query_admin_rank_update.Execute()
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index 0608baea8c..a0fb41ed12 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -129,6 +129,9 @@
/datum/config_entry/flag/enable_localhost_rank //Gives the !localhost! rank to any client connecting from 127.0.0.1 or ::1
protection = CONFIG_ENTRY_LOCKED
+/datum/config_entry/flag/load_legacy_ranks_only //Loads admin ranks only from legacy admin_ranks.txt, while enabled ranks are mirrored to the database
+ protection = CONFIG_ENTRY_LOCKED
+
/datum/config_entry/string/hostedby
/datum/config_entry/flag/norespawn
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index be54715215..c850340c78 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -113,7 +113,7 @@ GLOBAL_PROTECT(protected_ranks)
return ((rank.rights & flag) == flag) //true only if right has everything in flag
//load our rank - > rights associations
-/proc/load_admin_ranks(dbfail)
+/proc/load_admin_ranks(dbfail, no_update)
if(IsAdminAdvancedProcCall())
to_chat(usr, "Admin Reload blocked: Advanced ProcCall detected.")
return
@@ -137,27 +137,38 @@ GLOBAL_PROTECT(protected_ranks)
prev = next
previous_rights = R.rights
if(!CONFIG_GET(flag/admin_legacy_system) || dbfail)
- var/datum/DBQuery/query_load_admin_ranks = SSdbcore.NewQuery("SELECT rank, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")]")
- if(!query_load_admin_ranks.Execute())
- message_admins("Error loading admin ranks from database. Loading from backup.")
- log_sql("Error loading admin ranks from database. Loading from backup.")
- dbfail = 1
- else
- while(query_load_admin_ranks.NextRow())
- var/skip
- var/rank_name = query_load_admin_ranks.item[1]
+ if(CONFIG_GET(flag/load_legacy_ranks_only))
+ if(!no_update)
+ var/list/sql_ranks = list()
for(var/datum/admin_rank/R in GLOB.admin_ranks)
- if(R.name == rank_name) //this rank was already loaded from txt override
- skip = 1
- break
- if(!skip)
- var/rank_flags = text2num(query_load_admin_ranks.item[2])
- var/rank_exclude_flags = text2num(query_load_admin_ranks.item[3])
- var/rank_can_edit_flags = text2num(query_load_admin_ranks.item[4])
- var/datum/admin_rank/R = new(rank_name, rank_flags, rank_exclude_flags, rank_can_edit_flags)
- if(!R)
- continue
- GLOB.admin_ranks += R
+ var/sql_rank = sanitizeSQL(R.name)
+ var/sql_flags = sanitizeSQL(R.include_rights)
+ var/sql_exclude_flags = sanitizeSQL(R.exclude_rights)
+ var/sql_can_edit_flags = sanitizeSQL(R.can_edit_rights)
+ sql_ranks += list(list("rank" = "'[sql_rank]'", "flags" = "[sql_flags]", "exclude_flags" = "[sql_exclude_flags]", "can_edit_flags" = "[sql_can_edit_flags]"))
+ SSdbcore.MassInsert(format_table_name("admin_ranks"), sql_ranks, duplicate_key = TRUE)
+ else
+ var/datum/DBQuery/query_load_admin_ranks = SSdbcore.NewQuery("SELECT rank, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")]")
+ if(!query_load_admin_ranks.Execute())
+ message_admins("Error loading admin ranks from database. Loading from backup.")
+ log_sql("Error loading admin ranks from database. Loading from backup.")
+ dbfail = 1
+ else
+ while(query_load_admin_ranks.NextRow())
+ var/skip
+ var/rank_name = query_load_admin_ranks.item[1]
+ for(var/datum/admin_rank/R in GLOB.admin_ranks)
+ if(R.name == rank_name) //this rank was already loaded from txt override
+ skip = 1
+ break
+ if(!skip)
+ var/rank_flags = text2num(query_load_admin_ranks.item[2])
+ var/rank_exclude_flags = text2num(query_load_admin_ranks.item[3])
+ var/rank_can_edit_flags = text2num(query_load_admin_ranks.item[4])
+ var/datum/admin_rank/R = new(rank_name, rank_flags, rank_exclude_flags, rank_can_edit_flags)
+ if(!R)
+ continue
+ GLOB.admin_ranks += R
//load ranks from backup file
if(dbfail)
var/backup_file = file("data/admins_backup.json")
@@ -184,7 +195,7 @@ GLOBAL_PROTECT(protected_ranks)
testing(msg)
#endif
-/proc/load_admins()
+/proc/load_admins(no_update)
var/dbfail
if(!CONFIG_GET(flag/admin_legacy_system) && !SSdbcore.Connect())
message_admins("Failed to connect to database while loading admins. Loading from backup.")
@@ -198,7 +209,7 @@ GLOBAL_PROTECT(protected_ranks)
GLOB.admins.Cut()
GLOB.protected_admins.Cut()
GLOB.deadmins.Cut()
- dbfail = load_admin_ranks(dbfail)
+ dbfail = load_admin_ranks(dbfail, no_update)
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm
index b6d8c11e67..eb3969ce3a 100644
--- a/code/modules/admin/permissionedit.dm
+++ b/code/modules/admin/permissionedit.dm
@@ -82,6 +82,10 @@
if(D.rank in GLOB.protected_ranks)
to_chat(usr, "Editing the flags of this rank is blocked by server configuration.")
return
+ if(CONFIG_GET(flag/load_legacy_ranks_only) && (task == "rank" || task == "permissions"))
+ to_chat(usr, "Database rank loading is disabled, only temporary changes can be made to an admin's rank or permissions.")
+ use_db = FALSE
+ skip = TRUE
if(check_rights(R_DBRANKS, FALSE))
if(!skip)
if(!SSdbcore.Connect())
diff --git a/config/config.txt b/config/config.txt
index a8c9cf13de..290052308a 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -35,6 +35,7 @@ ROUND_END_COUNTDOWN 90
## This flag is automatically enabled if SQL_ENABLED isn't
ADMIN_LEGACY_SYSTEM
+<<<<<<< HEAD
## Comment this out if you want to use the SQL based mentor system, the legacy system uses mentors.txt.
## You need to set up your database to use the SQL based system.
## This flag is automatically enabled if SQL_ENABLED isn't
@@ -42,6 +43,17 @@ MENTOR_LEGACY_SYSTEM
#Mentors only see ckeys by default. Uncomment to have them only see mob name
#MENTORS_MOBNAME_ONLY
+=======
+##Uncomment this to stop any admins loaded by the legacy system from having their rank edited by the permissions panel
+#PROTECT_LEGACY_ADMINS
+
+##Uncomment this to stop any ranks loaded by the legacy system from having their flags edited by the permissions panel
+#PROTECT_LEGACY_RANKS
+>>>>>>> feb9290... Merge pull request #36554 from Jordie0608/tbhthisisntreallyalegacysystemanymore
+
+##Uncomment this to have admin ranks only loaded from the legacy admin_ranks.txt
+##If enabled, each time admins are loaded ranks the database will be updated with the current ranks and their flags
+#LOAD_LEGACY_RANKS_ONLY
## Comment this out if you want to use the SQL based banning system. The legacy systems use the files in the data folder. You need to set up your database to use the SQL based system.
BAN_LEGACY_SYSTEM