You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

297 lines
10 KiB

  1. GLOBAL_LIST_EMPTY(admin_ranks) //list of all admin_rank datums
  2. GLOBAL_PROTECT(admin_ranks)
  3. GLOBAL_LIST_EMPTY(protected_ranks) //admin ranks loaded from txt
  4. GLOBAL_PROTECT(protected_ranks)
  5. /datum/admin_rank
  6. var/name = "NoRank"
  7. var/rights = R_DEFAULT
  8. var/exclude_rights = 0
  9. var/include_rights = 0
  10. var/can_edit_rights = 0
  11. /datum/admin_rank/New(init_name, init_rights, init_exclude_rights, init_edit_rights)
  12. if(IsAdminAdvancedProcCall())
  13. var/msg = " has tried to elevate permissions!"
  14. message_admins("[key_name_admin(usr)][msg]")
  15. log_admin("[key_name(usr)][msg]")
  16. if (name == "NoRank") //only del if this is a true creation (and not just a New() proc call), other wise trialmins/coders could abuse this to deadmin other admins
  17. QDEL_IN(src, 0)
  18. CRASH("Admin proc call creation of admin datum")
  19. return
  20. name = init_name
  21. if(!name)
  22. qdel(src)
  23. CRASH("Admin rank created without name.")
  24. if(init_rights)
  25. rights = init_rights
  26. include_rights = rights
  27. if(init_exclude_rights)
  28. exclude_rights = init_exclude_rights
  29. rights &= ~exclude_rights
  30. if(init_edit_rights)
  31. can_edit_rights = init_edit_rights
  32. /datum/admin_rank/Destroy()
  33. if(IsAdminAdvancedProcCall())
  34. var/msg = " has tried to elevate permissions!"
  35. message_admins("[key_name_admin(usr)][msg]")
  36. log_admin("[key_name(usr)][msg]")
  37. return QDEL_HINT_LETMELIVE
  38. . = ..()
  39. /datum/admin_rank/vv_edit_var(var_name, var_value)
  40. return FALSE
  41. // Adds/removes rights to this admin_rank
  42. /datum/admin_rank/proc/process_keyword(group, group_count, datum/admin_rank/previous_rank)
  43. if(IsAdminAdvancedProcCall())
  44. var/msg = " has tried to elevate permissions!"
  45. message_admins("[key_name_admin(usr)][msg]")
  46. log_admin("[key_name(usr)][msg]")
  47. return
  48. var/list/keywords = splittext(group, " ")
  49. var/flag = 0
  50. for(var/k in keywords)
  51. switch(k)
  52. if("BUILD")
  53. flag = R_BUILD
  54. if("ADMIN")
  55. flag = R_ADMIN
  56. if("BAN")
  57. flag = R_BAN
  58. if("FUN")
  59. flag = R_FUN
  60. if("SERVER")
  61. flag = R_SERVER
  62. if("DEBUG")
  63. flag = R_DEBUG
  64. if("PERMISSIONS")
  65. flag = R_PERMISSIONS
  66. if("POSSESS")
  67. flag = R_POSSESS
  68. if("STEALTH")
  69. flag = R_STEALTH
  70. if("POLL")
  71. flag = R_POLL
  72. if("VAREDIT")
  73. flag = R_VAREDIT
  74. if("EVERYTHING")
  75. flag = R_EVERYTHING
  76. if("SOUND")
  77. flag = R_SOUND
  78. if("SPAWN")
  79. flag = R_SPAWN
  80. if("AUTOADMIN")
  81. flag = R_AUTOADMIN
  82. if("DBRANKS")
  83. flag = R_DBRANKS
  84. if("@")
  85. if(previous_rank)
  86. switch(group_count)
  87. if(1)
  88. flag = previous_rank.include_rights
  89. if(2)
  90. flag = previous_rank.exclude_rights
  91. if(3)
  92. flag = previous_rank.can_edit_rights
  93. else
  94. continue
  95. switch(group_count)
  96. if(1)
  97. rights |= flag
  98. include_rights |= flag
  99. if(2)
  100. rights &= ~flag
  101. exclude_rights |= flag
  102. if(3)
  103. can_edit_rights |= flag
  104. /proc/sync_ranks_with_db()
  105. set waitfor = FALSE
  106. if(IsAdminAdvancedProcCall())
  107. to_chat(usr, "<span class='admin prefix'>Admin rank DB Sync blocked: Advanced ProcCall detected.</span>", confidential = TRUE)
  108. return
  109. var/list/sql_ranks = list()
  110. for(var/datum/admin_rank/R in GLOB.protected_ranks)
  111. var/sql_rank = sanitizeSQL(R.name)
  112. var/sql_flags = sanitizeSQL(R.include_rights)
  113. var/sql_exclude_flags = sanitizeSQL(R.exclude_rights)
  114. var/sql_can_edit_flags = sanitizeSQL(R.can_edit_rights)
  115. sql_ranks += list(list("rank" = "'[sql_rank]'", "flags" = "[sql_flags]", "exclude_flags" = "[sql_exclude_flags]", "can_edit_flags" = "[sql_can_edit_flags]"))
  116. SSdbcore.MassInsert(format_table_name("admin_ranks"), sql_ranks, duplicate_key = TRUE)
  117. //load our rank - > rights associations
  118. /proc/load_admin_ranks(dbfail, no_update)
  119. if(IsAdminAdvancedProcCall())
  120. to_chat(usr, "<span class='admin prefix'>Admin Reload blocked: Advanced ProcCall detected.</span>", confidential = TRUE)
  121. return
  122. GLOB.admin_ranks.Cut()
  123. GLOB.protected_ranks.Cut()
  124. //load text from file and process each entry
  125. var/ranks_text = file2text("[global.config.directory]/admin_ranks.txt")
  126. var/datum/admin_rank/previous_rank
  127. var/regex/admin_ranks_regex = new(@"^Name\s*=\s*(.+?)\s*\n+Include\s*=\s*([\l @]*?)\s*\n+Exclude\s*=\s*([\l @]*?)\s*\n+Edit\s*=\s*([\l @]*?)\s*\n*$", "gm")
  128. while(admin_ranks_regex.Find(ranks_text))
  129. var/datum/admin_rank/R = new(admin_ranks_regex.group[1])
  130. if(!R)
  131. continue
  132. var/count = 1
  133. for(var/i in admin_ranks_regex.group - admin_ranks_regex.group[1])
  134. if(i)
  135. R.process_keyword(i, count, previous_rank)
  136. count++
  137. GLOB.admin_ranks += R
  138. GLOB.protected_ranks += R
  139. previous_rank = R
  140. if(!CONFIG_GET(flag/admin_legacy_system) || dbfail)
  141. if(CONFIG_GET(flag/load_legacy_ranks_only))
  142. if(!no_update)
  143. sync_ranks_with_db()
  144. else
  145. var/datum/DBQuery/query_load_admin_ranks = SSdbcore.NewQuery("SELECT `rank`, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")]")
  146. if(!query_load_admin_ranks.Execute())
  147. message_admins("Error loading admin ranks from database. Loading from backup.")
  148. log_sql("Error loading admin ranks from database. Loading from backup.")
  149. dbfail = 1
  150. else
  151. while(query_load_admin_ranks.NextRow())
  152. var/skip
  153. var/rank_name = query_load_admin_ranks.item[1]
  154. for(var/datum/admin_rank/R in GLOB.admin_ranks)
  155. if(R.name == rank_name) //this rank was already loaded from txt override
  156. skip = 1
  157. break
  158. if(!skip)
  159. var/rank_flags = text2num(query_load_admin_ranks.item[2])
  160. var/rank_exclude_flags = text2num(query_load_admin_ranks.item[3])
  161. var/rank_can_edit_flags = text2num(query_load_admin_ranks.item[4])
  162. var/datum/admin_rank/R = new(rank_name, rank_flags, rank_exclude_flags, rank_can_edit_flags)
  163. if(!R)
  164. continue
  165. GLOB.admin_ranks += R
  166. qdel(query_load_admin_ranks)
  167. //load ranks from backup file
  168. if(dbfail)
  169. var/backup_file = file2text("data/admins_backup.json")
  170. if(backup_file == null)
  171. log_world("Unable to locate admins backup file.")
  172. return FALSE
  173. var/list/json = json_decode(backup_file)
  174. for(var/J in json["ranks"])
  175. var/skip
  176. for(var/datum/admin_rank/R in GLOB.admin_ranks)
  177. if(R.name == "[J]") //this rank was already loaded from txt override
  178. skip = TRUE
  179. if(skip)
  180. continue
  181. var/datum/admin_rank/R = new("[J]", json["ranks"]["[J]"]["include rights"], json["ranks"]["[J]"]["exclude rights"], json["ranks"]["[J]"]["can edit rights"])
  182. if(!R)
  183. continue
  184. GLOB.admin_ranks += R
  185. return json
  186. #ifdef TESTING
  187. var/msg = "Permission Sets Built:\n"
  188. for(var/datum/admin_rank/R in GLOB.admin_ranks)
  189. msg += "\t[R.name]"
  190. var/rights = rights2text(R.rights,"\n\t\t")
  191. if(rights)
  192. msg += "\t\t[rights]\n"
  193. testing(msg)
  194. #endif
  195. /proc/load_admins(no_update)
  196. var/dbfail
  197. if(!CONFIG_GET(flag/admin_legacy_system) && !SSdbcore.Connect())
  198. message_admins("Failed to connect to database while loading admins. Loading from backup.")
  199. log_sql("Failed to connect to database while loading admins. Loading from backup.")
  200. dbfail = 1
  201. //clear the datums references
  202. GLOB.admin_datums.Cut()
  203. for(var/client/C in GLOB.admins)
  204. C.remove_admin_verbs()
  205. C.holder = null
  206. GLOB.admins.Cut()
  207. GLOB.protected_admins.Cut()
  208. GLOB.deadmins.Cut()
  209. var/list/backup_file_json = load_admin_ranks(dbfail, no_update)
  210. dbfail = backup_file_json != null
  211. //Clear profile access
  212. for(var/A in world.GetConfig("admin"))
  213. world.SetConfig("APP/admin", A, null)
  214. var/list/rank_names = list()
  215. for(var/datum/admin_rank/R in GLOB.admin_ranks)
  216. rank_names[R.name] = R
  217. //ckeys listed in admins.txt are always made admins before sql loading is attempted
  218. var/admins_text = file2text("[global.config.directory]/admins.txt")
  219. var/regex/admins_regex = new(@"^(?!#)(.+?)\s+=\s+(.+)", "gm")
  220. while(admins_regex.Find(admins_text))
  221. new /datum/admins(rank_names[admins_regex.group[2]], ckey(admins_regex.group[1]), FALSE, TRUE)
  222. if(!CONFIG_GET(flag/admin_legacy_system) || dbfail)
  223. var/datum/DBQuery/query_load_admins = SSdbcore.NewQuery("SELECT ckey, `rank` FROM [format_table_name("admin")] ORDER BY `rank`")
  224. if(!query_load_admins.Execute())
  225. message_admins("Error loading admins from database. Loading from backup.")
  226. log_sql("Error loading admins from database. Loading from backup.")
  227. dbfail = 1
  228. else
  229. while(query_load_admins.NextRow())
  230. var/admin_ckey = ckey(query_load_admins.item[1])
  231. var/admin_rank = query_load_admins.item[2]
  232. var/skip
  233. if(rank_names[admin_rank] == null)
  234. message_admins("[admin_ckey] loaded with invalid admin rank [admin_rank].")
  235. skip = 1
  236. if(GLOB.admin_datums[admin_ckey] || GLOB.deadmins[admin_ckey])
  237. skip = 1
  238. if(!skip)
  239. new /datum/admins(rank_names[admin_rank], admin_ckey)
  240. qdel(query_load_admins)
  241. //load admins from backup file
  242. if(dbfail)
  243. if(!backup_file_json)
  244. if(backup_file_json != null)
  245. //already tried
  246. return
  247. var/backup_file = file2text("data/admins_backup.json")
  248. if(backup_file == null)
  249. log_world("Unable to locate admins backup file.")
  250. return
  251. backup_file_json = json_decode(backup_file)
  252. for(var/J in backup_file_json["admins"])
  253. var/skip
  254. for(var/A in GLOB.admin_datums + GLOB.deadmins)
  255. if(A == "[J]") //this admin was already loaded from txt override
  256. skip = TRUE
  257. if(skip)
  258. continue
  259. new /datum/admins(rank_names[backup_file_json["admins"]["[J]"]], ckey("[J]"))
  260. #ifdef TESTING
  261. var/msg = "Admins Built:\n"
  262. for(var/ckey in GLOB.admin_datums)
  263. var/datum/admins/D = GLOB.admin_datums[ckey]
  264. msg += "\t[ckey] - [D.rank.name]\n"
  265. testing(msg)
  266. #endif
  267. return dbfail
  268. #ifdef TESTING
  269. /client/verb/changerank(newrank in GLOB.admin_ranks)
  270. if(holder)
  271. holder.rank = newrank
  272. else
  273. holder = new /datum/admins(newrank, ckey)
  274. remove_admin_verbs()
  275. holder.associate(src)
  276. /client/verb/changerights(newrights as num)
  277. if(holder)
  278. holder.rank.rights = newrights
  279. else
  280. holder = new /datum/admins("testing", newrights, ckey)
  281. remove_admin_verbs()
  282. holder.associate(src)
  283. #endif