diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm
index 5d63e777087..49ef7a72855 100644
--- a/code/__DEFINES/admin.dm
+++ b/code/__DEFINES/admin.dm
@@ -19,6 +19,8 @@
#define BANTYPE_JOB_TEMP 4
#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban.
#define BANTYPE_APPEARANCE 6
+#define BANTYPE_ADMIN_PERMA 7
+#define BANTYPE_ADMIN_TEMP 8
//Please don't edit these values without speaking to Errorage first ~Carn
//Admin Permissions
diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm
index 8cd511a3c9a..72cee4a7b4c 100644
--- a/code/modules/admin/DB ban/functions.dm
+++ b/code/modules/admin/DB ban/functions.dm
@@ -1,3 +1,4 @@
+#define MAX_ADMIN_BANS_PER_ADMIN 1
datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null, var/banip = null, var/bancid = null)
@@ -10,14 +11,22 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
var/serverip = "[world.internet_address]:[world.port]"
var/bantype_pass = 0
var/bantype_str
+ var/maxadminbancheck //Used to limit the number of active bans of a certein type that each admin can give. Used to protect against abuse or mutiny.
+ var/announceinirc //When set, it announces the ban in irc. Intended to be a way to raise an alarm, so to speak.
+ var/blockselfban //Used to prevent the banning of yourself.
+ var/kickbannedckey //Defines whether this proc should kick the banned person, if they are connected (if banned_mob is defined).
+ //some ban types kick players after this proc passes (tempban, permaban), but some are specific to db_ban, so
+ //they should kick within this proc.
switch(bantype)
if(BANTYPE_PERMA)
bantype_str = "PERMABAN"
duration = -1
bantype_pass = 1
+ blockselfban = 1
if(BANTYPE_TEMP)
bantype_str = "TEMPBAN"
bantype_pass = 1
+ blockselfban = 1
if(BANTYPE_JOB_PERMA)
bantype_str = "JOB_PERMABAN"
duration = -1
@@ -29,6 +38,21 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
bantype_str = "APPEARANCE_BAN"
duration = -1
bantype_pass = 1
+ if(BANTYPE_ADMIN_PERMA)
+ bantype_str = "ADMIN_PERMABAN"
+ duration = -1
+ bantype_pass = 1
+ maxadminbancheck = 1
+ announceinirc = 1
+ blockselfban = 1
+ kickbannedckey = 1
+ if(BANTYPE_ADMIN_TEMP)
+ bantype_str = "ADMIN_TEMPBAN"
+ bantype_pass = 1
+ maxadminbancheck = 1
+ announceinirc = 1
+ blockselfban = 1
+ kickbannedckey = 1
if( !bantype_pass ) return
if( !istext(reason) ) return
@@ -66,6 +90,11 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
a_ckey = src.owner:ckey
a_computerid = src.owner:computer_id
a_ip = src.owner:address
+
+ if(blockselfban)
+ if(a_ckey == ckey)
+ usr << "You cannot apply this ban type on yourself."
+ return
var/who
for(var/client/C in clients)
@@ -82,6 +111,15 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
adminwho += ", [C]"
reason = sql_sanitize_text(reason)
+
+ if(maxadminbancheck)
+ var/DBQuery/adm_query = dbcon.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
+ adm_query.Execute()
+ if(adm_query.NextRow())
+ var/adm_bans = text2num(adm_query.item[1])
+ if(adm_bans >= MAX_ADMIN_BANS_PER_ADMIN)
+ usr << "You already logged [MAX_ADMIN_BANS_PER_ADMIN] admin ban(s) or more. Do not abuse this function!"
+ return
var/sql = "INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`) VALUES (null, Now(), '[serverip]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], [(rounds)?"[rounds]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', '[ip]', '[a_ckey]', '[a_computerid]', '[a_ip]', '[who]', '[adminwho]', '', null, null, null, null, null)"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
@@ -89,7 +127,12 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
usr << "\blue Ban saved to database."
message_admins("[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database.",1)
+ if(announceinirc)
+ send2irc("BAN ALERT","[a_ckey] applied a [bantype_str] on [ckey]")
+ if(kickbannedckey)
+ if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey)
+ del(banned_mob.client)
datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
@@ -114,6 +157,12 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_BAN"
bantype_pass = 1
+ if(BANTYPE_ADMIN_PERMA)
+ bantype_str = "ADMIN_PERMABAN"
+ bantype_pass = 1
+ if(BANTYPE_ADMIN_TEMP)
+ bantype_str = "ADMIN_TEMPBAN"
+ bantype_pass = 1
if(BANTYPE_ANY_FULLBAN)
bantype_str = "ANY"
bantype_pass = 1
@@ -300,6 +349,8 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
output += ""
output += ""
output += ""
+ output += ""
+ output += ""
output += ""
output += "
Ckey: | "
output += "| IP: | "
@@ -339,6 +390,8 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
output += ""
output += ""
output += ""
+ output += ""
+ output += ""
output += "
"
output += "
"
output += " Match(min. 3 characters to search by key or ip, and 7 to search by cid)
"
@@ -406,6 +459,10 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
bantypesearch += "'JOB_TEMPBAN' "
if(BANTYPE_APPEARANCE)
bantypesearch += "'APPEARANCE_BAN' "
+ if(BANTYPE_ADMIN_PERMA)
+ bantypesearch = "'ADMIN_PERMABAN' "
+ if(BANTYPE_ADMIN_TEMP)
+ bantypesearch = "'ADMIN_TEMPBAN' "
else
bantypesearch += "'PERMABAN' "
@@ -448,6 +505,10 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
typedesc = "TEMP JOBBAN
([job])
([duration] minutes
Expires [expiration]"
if("APPEARANCE_BAN")
typedesc = "APPEARANCE/NAME BAN"
+ if("ADMIN_PERMABAN")
+ typedesc = "ADMIN PERMABAN"
+ if("ADMIN_TEMPBAN")
+ typedesc = "ADMIN TEMPBAN
([duration] minutes [(unbanned) ? "" : "(Edit))"]
Expires [expiration]"
output += ""
output += "| [typedesc] | "
diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm
index 158f7ed1916..44027257bee 100644
--- a/code/modules/admin/IsBanned.dm
+++ b/code/modules/admin/IsBanned.dm
@@ -2,7 +2,7 @@
world/IsBanned(key,address,computer_id)
if (!key || !address || !computer_id)
log_access("Failed Login (invalid data): [key] [address]-[computer_id]")
- return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)")
+ return list("reason"="invalid login data", "desc"="Error: Could not check ban status, please try again. Error message: Your computer provided invalid or blank information to the server on connection (BYOND username, IP, and Computer ID). Provided information for reference: Username: '[key]' IP: '[address]' Computer ID: '[computer_id]'. If you continue to get this error, please restart byond or contact byond support.")
var/admin = 0
var/ckey = ckey(key)
if((ckey in admin_datums) || (ckey in deadmins))
@@ -10,23 +10,25 @@ world/IsBanned(key,address,computer_id)
//Guest Checking
if(!guests_allowed && IsGuestKey(key))
- log_access("Failed Login: [key] - Guests not allowed")
+ log_access("Failed Login: [key] [computer_id] [address] - Guests not allowed")
// message_admins("\blue Failed Login: [key] - Guests not allowed")
- return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
+ return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.")
- //check if the IP address is a known TOR node
- if(config && config.ToRban && ToRban_isbanned(address))
- log_access("Failed Login: [src] - Banned: ToR")
- message_admins("\blue Failed Login: [src] - Banned: ToR")
+ //check if the IP address is a known Tor node
+ if(config.ToRban && ToRban_isbanned(address))
+ log_access("Failed Login: [key] [computer_id] [address] - Banned: Tor")
+ message_admins("Failed Login: [key] - Banned: Tor")
//ban their computer_id and ckey for posterity
- AddBan(ckey(key), computer_id, "Use of ToR", "Automated Ban", 0, 0)
- return list("reason"="Using ToR", "desc"="\nReason: The network you are using to connect has been banned.\nIf you believe this is a mistake, please request help at [config.banappeals]")
+ AddBan(ckey(key), computer_id, "Use of Tor", "Automated Ban", 0, 0)
+ var/mistakemessage = ""
+ if(config.banappeals)
+ mistakemessage = "\nIf you believe this is a mistake, please request help at [config.banappeals]."
+ return list("reason"="using Tor", "desc"="\nReason: The network you are using to connect has been banned.[mistakemessage]")
if(config.ban_legacy_system)
-
//Ban Checking
- . = CheckBan( ckey(key), computer_id, address )
+ . = CheckBan(ckey(key), computer_id, address)
if(.)
if (admin)
log_admin("The admin [key] has been allowed to bypass a matching ban on [.["key"]]")
@@ -35,9 +37,7 @@ world/IsBanned(key,address,computer_id)
else
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
return .
-
else
-
var/ckeytext = ckey(key)
if(!establish_db_connection())
@@ -86,7 +86,7 @@ world/IsBanned(key,address,computer_id)
expires = "The ban is for [duration] minutes and expires on [expiration] (server time)."
else
var/appealmessage = ""
- if(config && config.banappeals)
+ if(config.banappeals)
appealmessage = " You may appeal it at [config.banappeals]."
expires = " The is a permanent ban.[appealmessage]"
@@ -94,7 +94,6 @@ world/IsBanned(key,address,computer_id)
. = list("reason"="[bantype]", "desc"="[desc]")
-
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
return .
@@ -107,7 +106,7 @@ world/IsBanned(key,address,computer_id)
if (admin)
log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban")
message_admins("The admin [key] has been allowed to bypass a matching host/sticky ban")
- addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban")
+ addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban")
return null
else
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["message"]]")
diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm
index ce8a756b7af..072cad1acf7 100644
--- a/code/modules/admin/stickyban.dm
+++ b/code/modules/admin/stickyban.dm
@@ -5,6 +5,7 @@
switch (action)
if ("show")
stickyban_show()
+ return
if ("add")
var/list/ban = list()
var/ckey
@@ -30,7 +31,7 @@
return
ban["message"] = "[reason]"
- world.SetConfig("ban",ckey,list2stickyban(ban))
+ world.SetConfig("ban", ckey, list2stickyban(ban))
log_admin("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]")
message_admins("[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]")
@@ -49,7 +50,7 @@
if (!get_stickyban_from_ckey(ckey))
usr << "Error: The ban disappeared."
return
- world.SetConfig("ban",ckey, null)
+ world.SetConfig("ban", ckey, null)
log_admin("[key_name(usr)] removed [ckey]'s stickyban")
message_admins("[key_name_admin(usr)] removed [ckey]'s stickyban")
@@ -125,6 +126,8 @@
log_admin("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")
message_admins("[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")
+
+ stickyban_show()
/datum/admins/proc/stickyban_gethtml(ckey, ban)
. = "\[-\][ckey]
"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index cc34e5a3437..b922b4979c8 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -126,6 +126,17 @@
return
banduration = null
banjob = null
+ if(BANTYPE_ADMIN_PERMA)
+ if(!banckey || !banreason)
+ usr << "Not enough parameters (Requires ckey and reason)"
+ return
+ banduration = null
+ banjob = null
+ if(BANTYPE_ADMIN_TEMP)
+ if(!banckey || !banreason || !banduration)
+ usr << "Not enough parameters (Requires ckey, reason and duration)"
+ return
+ banjob = null
var/mob/playermob
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index f0532fbd254..134cc9ff3f5 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -323,8 +323,12 @@ var/list/forbidden_varedit_object_types = list(
for(var/p in forbidden_varedit_object_types)
if( istype(O,p) )
- usr << "\red It is forbidden to edit this object's variables."
+ usr << "It is forbidden to edit this object's variables."
return
+
+ if(istype(O, /client) && (param_var_name == "ckey" || param_var_name == "key"))
+ usr << "You cannot edit ckeys on client objects."
+ return
var/class
var/variable