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.
 
 
 
 
 
 

476 lines
17 KiB

  1. /datum/admins/proc/stickyban(action,data)
  2. if(!check_rights(R_BAN))
  3. return
  4. switch (action)
  5. if ("show")
  6. stickyban_show()
  7. if ("add")
  8. var/list/ban = list()
  9. var/ckey
  10. ban["admin"] = usr.ckey
  11. ban["type"] = list("sticky")
  12. ban["reason"] = "(InGameBan)([usr.key])" //this will be displayed in dd only
  13. if (data["ckey"])
  14. ckey = ckey(data["ckey"])
  15. else
  16. ckey = input(usr,"Ckey","Ckey","") as text|null
  17. if (!ckey)
  18. return
  19. ckey = ckey(ckey)
  20. ban["ckey"] = ckey
  21. if (get_stickyban_from_ckey(ckey))
  22. to_chat(usr, "<span class='adminnotice'>Error: Can not add a stickyban: User already has a current sticky ban</span>", confidential = TRUE)
  23. return
  24. if (data["reason"])
  25. ban["message"] = data["reason"]
  26. else
  27. var/reason = input(usr,"Reason","Reason","Ban Evasion") as text|null
  28. if (!reason)
  29. return
  30. ban["message"] = "[reason]"
  31. if(SSdbcore.Connect())
  32. var/datum/DBQuery/query_create_stickyban = SSdbcore.NewQuery("INSERT INTO [format_table_name("stickyban")] (ckey, reason, banning_admin) VALUES ('[sanitizeSQL(ckey)]', '[sanitizeSQL(ban["message"])]', '[sanitizeSQL(usr.ckey)]')")
  33. if (query_create_stickyban.warn_execute())
  34. ban["fromdb"] = TRUE
  35. qdel(query_create_stickyban)
  36. world.SetConfig("ban",ckey,list2stickyban(ban))
  37. ban = stickyban2list(list2stickyban(ban))
  38. ban["matches_this_round"] = list()
  39. ban["existing_user_matches_this_round"] = list()
  40. ban["admin_matches_this_round"] = list()
  41. ban["pending_matches_this_round"] = list()
  42. SSstickyban.cache[ckey] = ban
  43. log_admin_private("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]")
  44. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]</span>")
  45. if ("remove")
  46. if (!data["ckey"])
  47. return
  48. var/ckey = data["ckey"]
  49. var/ban = get_stickyban_from_ckey(ckey)
  50. if (!ban)
  51. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  52. return
  53. if (alert("Are you sure you want to remove the sticky ban on [ckey]?","Are you sure","Yes","No") == "No")
  54. return
  55. if (!get_stickyban_from_ckey(ckey))
  56. to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
  57. return
  58. world.SetConfig("ban",ckey, null)
  59. SSstickyban.cache -= ckey
  60. if (SSdbcore.Connect())
  61. SSdbcore.QuerySelect(list(
  62. SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban")] WHERE ckey = '[sanitizeSQL(ckey)]'"),
  63. SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ckey")] WHERE stickyban = '[sanitizeSQL(ckey)]'"),
  64. SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_cid")] WHERE stickyban = '[sanitizeSQL(ckey)]'"),
  65. SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ip")] WHERE stickyban = '[sanitizeSQL(ckey)]'")
  66. ), warn = TRUE, qdel = TRUE)
  67. log_admin_private("[key_name(usr)] removed [ckey]'s stickyban")
  68. message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed [ckey]'s stickyban</span>")
  69. if ("remove_alt")
  70. if (!data["ckey"])
  71. return
  72. var/ckey = data["ckey"]
  73. if (!data["alt"])
  74. return
  75. var/alt = ckey(data["alt"])
  76. var/ban = get_stickyban_from_ckey(ckey)
  77. if (!ban)
  78. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  79. return
  80. var/key = LAZYACCESS(ban["keys"], alt)
  81. if (!key)
  82. to_chat(usr, "<span class='adminnotice'>Error: [alt] is not linked to [ckey]'s sticky ban!</span>", confidential = TRUE)
  83. return
  84. if (alert("Are you sure you want to disassociate [alt] from [ckey]'s sticky ban? \nNote: Nothing stops byond from re-linking them, Use \[E] to exempt them","Are you sure","Yes","No") == "No")
  85. return
  86. //we have to do this again incase something changes
  87. ban = get_stickyban_from_ckey(ckey)
  88. if (!ban)
  89. to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
  90. return
  91. key = LAZYACCESS(ban["keys"], alt)
  92. if (!key)
  93. to_chat(usr, "<span class='adminnotice'>Error: [alt] link to [ckey]'s sticky ban disappeared.</span>", confidential = TRUE)
  94. return
  95. LAZYREMOVE(ban["keys"], alt)
  96. world.SetConfig("ban",ckey,list2stickyban(ban))
  97. SSstickyban.cache[ckey] = ban
  98. if (SSdbcore.Connect())
  99. var/datum/DBQuery/query_remove_stickyban_alt = SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ckey")] WHERE stickyban = '[sanitizeSQL(ckey)]' AND matched_ckey = '[sanitizeSQL(alt)]'")
  100. query_remove_stickyban_alt.warn_execute()
  101. qdel(query_remove_stickyban_alt)
  102. log_admin_private("[key_name(usr)] has disassociated [alt] from [ckey]'s sticky ban")
  103. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has disassociated [alt] from [ckey]'s sticky ban</span>")
  104. if ("edit")
  105. if (!data["ckey"])
  106. return
  107. var/ckey = data["ckey"]
  108. var/ban = get_stickyban_from_ckey(ckey)
  109. if (!ban)
  110. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  111. return
  112. var/oldreason = ban["message"]
  113. var/reason = input(usr,"Reason","Reason","[ban["message"]]") as text|null
  114. if (!reason || reason == oldreason)
  115. return
  116. //we have to do this again incase something changed while we waited for input
  117. ban = get_stickyban_from_ckey(ckey)
  118. if (!ban)
  119. to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
  120. return
  121. ban["message"] = "[reason]"
  122. world.SetConfig("ban",ckey,list2stickyban(ban))
  123. SSstickyban.cache[ckey] = ban
  124. if (SSdbcore.Connect())
  125. var/datum/DBQuery/query_edit_stickyban = SSdbcore.NewQuery("UPDATE [format_table_name("stickyban")] SET reason = '[sanitizeSQL(reason)]' WHERE ckey = '[sanitizeSQL(ckey)]'")
  126. query_edit_stickyban.warn_execute()
  127. qdel(query_edit_stickyban)
  128. log_admin_private("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")
  129. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]</span>")
  130. if ("exempt")
  131. if (!data["ckey"])
  132. return
  133. var/ckey = data["ckey"]
  134. if (!data["alt"])
  135. return
  136. var/alt = ckey(data["alt"])
  137. var/ban = get_stickyban_from_ckey(ckey)
  138. if (!ban)
  139. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  140. return
  141. var/key = LAZYACCESS(ban["keys"], alt)
  142. if (!key)
  143. to_chat(usr, "<span class='adminnotice'>Error: [alt] is not linked to [ckey]'s sticky ban!</span>", confidential = TRUE)
  144. return
  145. if (alert("Are you sure you want to exempt [alt] from [ckey]'s sticky ban?","Are you sure","Yes","No") == "No")
  146. return
  147. //we have to do this again incase something changes
  148. ban = get_stickyban_from_ckey(ckey)
  149. if (!ban)
  150. to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
  151. return
  152. key = LAZYACCESS(ban["keys"], alt)
  153. if (!key)
  154. to_chat(usr, "<span class='adminnotice'>Error: [alt]'s link to [ckey]'s sticky ban disappeared.</span>", confidential = TRUE)
  155. return
  156. LAZYREMOVE(ban["keys"], alt)
  157. key["exempt"] = TRUE
  158. LAZYSET(ban["whitelist"], alt, key)
  159. world.SetConfig("ban",ckey,list2stickyban(ban))
  160. SSstickyban.cache[ckey] = ban
  161. if (SSdbcore.Connect())
  162. var/datum/DBQuery/query_exempt_stickyban_alt = SSdbcore.NewQuery("UPDATE [format_table_name("stickyban_matched_ckey")] SET exempt = 1 WHERE stickyban = '[sanitizeSQL(ckey)]' AND matched_ckey = '[sanitizeSQL(alt)]'")
  163. query_exempt_stickyban_alt.warn_execute()
  164. qdel(query_exempt_stickyban_alt)
  165. log_admin_private("[key_name(usr)] has exempted [alt] from [ckey]'s sticky ban")
  166. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has exempted [alt] from [ckey]'s sticky ban</span>")
  167. if ("unexempt")
  168. if (!data["ckey"])
  169. return
  170. var/ckey = data["ckey"]
  171. if (!data["alt"])
  172. return
  173. var/alt = ckey(data["alt"])
  174. var/ban = get_stickyban_from_ckey(ckey)
  175. if (!ban)
  176. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  177. return
  178. var/key = LAZYACCESS(ban["whitelist"], alt)
  179. if (!key)
  180. to_chat(usr, "<span class='adminnotice'>Error: [alt] is not exempt from [ckey]'s sticky ban!</span>", confidential = TRUE)
  181. return
  182. if (alert("Are you sure you want to unexempt [alt] from [ckey]'s sticky ban?","Are you sure","Yes","No") == "No")
  183. return
  184. //we have to do this again incase something changes
  185. ban = get_stickyban_from_ckey(ckey)
  186. if (!ban)
  187. to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
  188. return
  189. key = LAZYACCESS(ban["whitelist"], alt)
  190. if (!key)
  191. to_chat(usr, "<span class='adminnotice'>Error: [alt]'s exemption from [ckey]'s sticky ban disappeared.</span>", confidential = TRUE)
  192. return
  193. LAZYREMOVE(ban["whitelist"], alt)
  194. key["exempt"] = FALSE
  195. LAZYSET(ban["keys"], alt, key)
  196. world.SetConfig("ban",ckey,list2stickyban(ban))
  197. SSstickyban.cache[ckey] = ban
  198. if (SSdbcore.Connect())
  199. var/datum/DBQuery/query_unexempt_stickyban_alt = SSdbcore.NewQuery("UPDATE [format_table_name("stickyban_matched_ckey")] SET exempt = 0 WHERE stickyban = '[sanitizeSQL(ckey)]' AND matched_ckey = '[sanitizeSQL(alt)]'")
  200. query_unexempt_stickyban_alt.warn_execute()
  201. qdel(query_unexempt_stickyban_alt)
  202. log_admin_private("[key_name(usr)] has unexempted [alt] from [ckey]'s sticky ban")
  203. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has unexempted [alt] from [ckey]'s sticky ban</span>")
  204. if ("timeout")
  205. if (!data["ckey"])
  206. return
  207. if (!SSdbcore.Connect())
  208. to_chat(usr, "<span class='adminnotice'>No database connection!</span>", confidential = TRUE)
  209. return
  210. var/ckey = data["ckey"]
  211. if (alert("Are you sure you want to put [ckey]'s stickyban on timeout until next round (or removed)?","Are you sure","Yes","No") == "No")
  212. return
  213. var/ban = get_stickyban_from_ckey(ckey)
  214. if (!ban)
  215. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  216. return
  217. ban["timeout"] = TRUE
  218. world.SetConfig("ban", ckey, null)
  219. var/cachedban = SSstickyban.cache[ckey]
  220. if (cachedban)
  221. cachedban["timeout"] = TRUE
  222. log_admin_private("[key_name(usr)] has put [ckey]'s sticky ban on timeout.")
  223. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has put [ckey]'s sticky ban on timeout.</span>")
  224. if ("untimeout")
  225. if (!data["ckey"])
  226. return
  227. if (!SSdbcore.Connect())
  228. to_chat(usr, "<span class='adminnotice'>No database connection!</span>", confidential = TRUE)
  229. return
  230. var/ckey = data["ckey"]
  231. if (alert("Are you sure you want to lift the timeout on [ckey]'s stickyban?","Are you sure","Yes","No") == "No")
  232. return
  233. var/ban = get_stickyban_from_ckey(ckey)
  234. var/cachedban = SSstickyban.cache[ckey]
  235. if (cachedban)
  236. cachedban["timeout"] = FALSE
  237. if (!ban)
  238. if (!cachedban)
  239. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  240. return
  241. ban = cachedban
  242. ban["timeout"] = FALSE
  243. world.SetConfig("ban",ckey,list2stickyban(ban))
  244. log_admin_private("[key_name(usr)] has taken [ckey]'s sticky ban off of timeout.")
  245. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has taken [ckey]'s sticky ban off of timeout.</span>")
  246. if ("revert")
  247. if (!data["ckey"])
  248. return
  249. var/ckey = data["ckey"]
  250. if (alert("Are you sure you want to revert the sticky ban on [ckey] to its state at round start (or last edit)?","Are you sure","Yes","No") == "No")
  251. return
  252. var/ban = get_stickyban_from_ckey(ckey)
  253. if (!ban)
  254. to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
  255. return
  256. var/cached_ban = SSstickyban.cache[ckey]
  257. if (!cached_ban)
  258. to_chat(usr, "<span class='adminnotice'>Error: No cached sticky ban for [ckey] found!</span>", confidential = TRUE)
  259. world.SetConfig("ban",ckey,null)
  260. log_admin_private("[key_name(usr)] has reverted [ckey]'s sticky ban to its state at round start.")
  261. message_admins("<span class='adminnotice'>[key_name_admin(usr)] has reverted [ckey]'s sticky ban to its state at round start.</span>")
  262. //revert is mostly used when shit goes rouge, so we have to set it to null
  263. // and wait a byond tick before assigning it to ensure byond clears its shit.
  264. sleep(world.tick_lag)
  265. world.SetConfig("ban",ckey,list2stickyban(cached_ban))
  266. /datum/admins/proc/stickyban_gethtml(ckey)
  267. var/ban = get_stickyban_from_ckey(ckey)
  268. if (!ban)
  269. return
  270. var/timeout
  271. if (SSdbcore.Connect())
  272. timeout = "<a href='?_src_=holder;[HrefToken()];stickyban=[(ban["timeout"] ? "untimeout" : "timeout")]&ckey=[ckey]'>\[[(ban["timeout"] ? "untimeout" : "timeout" )]\]</a>"
  273. else
  274. timeout = "<a href='?_src_=holder;[HrefToken()];stickyban=revert&ckey=[ckey]'>\[revert\]</a>"
  275. . = list({"
  276. <a href='?_src_=holder;[HrefToken()];stickyban=remove&ckey=[ckey]'>\[-\]</a>
  277. [timeout]
  278. <b>[ckey]</b>
  279. <br />"
  280. [ban["message"]] <b><a href='?_src_=holder;[HrefToken()];stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />
  281. "})
  282. if (ban["admin"])
  283. . += "[ban["admin"]]<br />"
  284. else
  285. . += "LEGACY<br />"
  286. . += "Caught keys<br />\n<ol>"
  287. for (var/key in ban["keys"])
  288. if (ckey(key) == ckey)
  289. continue
  290. . += "<li><a href='?_src_=holder;[HrefToken()];stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]<a href='?_src_=holder;[HrefToken()];stickyban=exempt&ckey=[ckey]&alt=[ckey(key)]'>\[E\]</a></li>"
  291. for (var/key in ban["whitelist"])
  292. if (ckey(key) == ckey)
  293. continue
  294. . += "<li><a href='?_src_=holder;[HrefToken()];stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]<a href='?_src_=holder;[HrefToken()];stickyban=unexempt&ckey=[ckey]&alt=[ckey(key)]'>\[UE\]</a></li>"
  295. . += "</ol>\n"
  296. /datum/admins/proc/stickyban_show()
  297. if(!check_rights(R_BAN))
  298. return
  299. var/list/bans = sticky_banned_ckeys()
  300. var/list/banhtml = list()
  301. for(var/key in bans)
  302. var/ckey = ckey(key)
  303. banhtml += "<br /><hr />\n"
  304. banhtml += stickyban_gethtml(ckey)
  305. var/html = {"
  306. <head>
  307. <title>Sticky Bans</title>
  308. </head>
  309. <body>
  310. <h2>All Sticky Bans:</h2> <a href='?_src_=holder;[HrefToken()];stickyban=add'>\[+\]</a><br>
  311. [banhtml.Join("")]
  312. </body>
  313. "}
  314. usr << browse(html,"window=stickybans;size=700x400")
  315. /proc/sticky_banned_ckeys()
  316. if (SSdbcore.Connect() || length(SSstickyban.dbcache))
  317. if (SSstickyban.dbcacheexpire < world.time)
  318. SSstickyban.Populatedbcache()
  319. if (SSstickyban.dbcacheexpire)
  320. return SSstickyban.dbcache.Copy()
  321. return sortList(world.GetConfig("ban"))
  322. /proc/get_stickyban_from_ckey(var/ckey)
  323. . = list()
  324. if (!ckey)
  325. return null
  326. if (SSdbcore.Connect() || length(SSstickyban.dbcache))
  327. if (SSstickyban.dbcacheexpire < world.time)
  328. SSstickyban.Populatedbcache()
  329. if (SSstickyban.dbcacheexpire)
  330. . = SSstickyban.dbcache[ckey]
  331. //reset the cache incase its a newer ban (but only if we didn't update the cache recently)
  332. if (!. && SSstickyban.dbcacheexpire != world.time+STICKYBAN_DB_CACHE_TIME)
  333. SSstickyban.dbcacheexpire = 1
  334. SSstickyban.Populatedbcache()
  335. . = SSstickyban.dbcache[ckey]
  336. if (.)
  337. var/list/cachedban = SSstickyban.cache["[ckey]"]
  338. if (cachedban)
  339. .["timeout"] = cachedban["timeout"]
  340. .["fromdb"] = TRUE
  341. return
  342. . = stickyban2list(world.GetConfig("ban", ckey)) || stickyban2list(world.GetConfig("ban", ckey(ckey))) || list()
  343. if (!length(.))
  344. return null
  345. /proc/stickyban2list(ban, strictdb = TRUE)
  346. if (!ban)
  347. return null
  348. . = params2list(ban)
  349. if (.["keys"])
  350. var/keys = splittext(.["keys"], ",")
  351. var/ckeys = list()
  352. for (var/key in keys)
  353. var/ckey = ckey(key)
  354. ckeys[ckey] = ckey //to make searching faster.
  355. .["keys"] = ckeys
  356. if (.["whitelist"])
  357. var/keys = splittext(.["whitelist"], ",")
  358. var/ckeys = list()
  359. for (var/key in keys)
  360. var/ckey = ckey(key)
  361. ckeys[ckey] = ckey //to make searching faster.
  362. .["whitelist"] = ckeys
  363. .["type"] = splittext(.["type"], ",")
  364. .["IP"] = splittext(.["IP"], ",")
  365. .["computer_id"] = splittext(.["computer_id"], ",")
  366. . -= "fromdb"
  367. /proc/list2stickyban(list/ban)
  368. if (!ban || !islist(ban))
  369. return null
  370. . = ban.Copy()
  371. if (.["keys"])
  372. .["keys"] = jointext(.["keys"], ",")
  373. if (.["IP"])
  374. .["IP"] = jointext(.["IP"], ",")
  375. if (.["computer_id"])
  376. .["computer_id"] = jointext(.["computer_id"], ",")
  377. if (.["whitelist"])
  378. .["whitelist"] = jointext(.["whitelist"], ",")
  379. if (.["type"])
  380. .["type"] = jointext(.["type"], ",")
  381. . -= "reverting"
  382. . -= "matches_this_round"
  383. . -= "existing_user_matches_this_round"
  384. . -= "admin_matches_this_round"
  385. . -= "pending_matches_this_round"
  386. . = list2params(.)
  387. /client/proc/stickybanpanel()
  388. set name = "Sticky Ban Panel"
  389. set category = "Admin"
  390. if (!holder)
  391. return
  392. holder.stickyban_show()