//Either pass the mob you wish to ban in the 'banned_mob' attribute, or the banckey, banip and bancid variables. If both are passed, the mob takes priority! If a mob is not passed, banckey is the minimum that needs to be passed! banip and bancid are optional.
/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)
if(!check_rights(R_MOD,0) && !check_rights(R_BAN))
return
var/datum/admins/holder = null
if (usr)
holder = usr.client ? usr.client.holder : null
if (!holder)
return
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
return
var/serverip = "[world.internet_address]:[world.port]"
var/bantype_pass = 0
var/bantype_str
switch(bantype)
if(BANTYPE_PERMA)
bantype_str = "PERMABAN"
duration = -1
bantype_pass = 1
if(BANTYPE_TEMP)
bantype_str = "TEMPBAN"
bantype_pass = 1
if(BANTYPE_JOB_PERMA)
bantype_str = "JOB_PERMABAN"
duration = -1
bantype_pass = 1
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if( !bantype_pass ) return
if( !istext(reason) ) return
if( !isnum(duration) ) return
var/ckey
var/computerid
var/ip
if(ismob(banned_mob))
ckey = banned_mob.ckey
if(banned_mob.client)
computerid = banned_mob.client.computer_id
ip = banned_mob.client.address
else if(banckey)
ckey = ckey(banckey)
computerid = bancid
ip = banip
var/DBQuery/query = dbcon.NewQuery("SELECT id, computerid, ip FROM ss13_player WHERE ckey = '[ckey]'")
query.Execute()
var/validckey = 0
if(query.NextRow())
validckey = 1
// Stop relying on manual entry, use the database.
if (!computerid)
computerid = query.item[2]
if (!ip)
ip = query.item[3]
if(!validckey)
if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key)))
message_admins("[key_name_admin(usr)] attempted to ban [ckey], but [ckey] has not been seen yet. Please only ban actual players. ",1)
return
var/a_ckey
var/a_computerid
var/a_ip
if(holder && holder.owner && istype(holder.owner, /client))
a_ckey = holder.owner:ckey
a_computerid = holder.owner:computer_id
a_ip = holder.owner:address
else
a_ckey = "Adminbot"
a_computerid = ""
a_ip = world.address
var/who
for(var/client/C in clients)
if(!who)
who = "[C]"
else
who += ", [C]"
var/adminwho
for(var/client/C in admins)
if(!adminwho)
adminwho = "[C]"
else
adminwho += ", [C]"
reason = sql_sanitize_text(reason)
var/sql = "INSERT INTO ss13_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)
query_insert.Execute()
usr << "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)
/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
if(!check_rights(R_BAN)) return
var/bantype_str
if(bantype)
var/bantype_pass = 0
switch(bantype)
if(BANTYPE_PERMA)
bantype_str = "PERMABAN"
bantype_pass = 1
if(BANTYPE_TEMP)
bantype_str = "TEMPBAN"
bantype_pass = 1
if(BANTYPE_JOB_PERMA)
bantype_str = "JOB_PERMABAN"
bantype_pass = 1
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_ANY_FULLBAN)
bantype_str = "ANY"
bantype_pass = 1
if( !bantype_pass ) return
var/bantype_sql
if(bantype_str == "ANY")
bantype_sql = "(bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now() ) )"
else
bantype_sql = "bantype = '[bantype_str]'"
var/sql = "SELECT id FROM ss13_ban WHERE isnull(unbanned) AND [bantype_sql] AND ckey = '[ckey]'"
if(job)
sql += " AND job = '[job]'"
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
return
var/ban_id
var/ban_number = 0 //failsafe
var/DBQuery/query = dbcon.NewQuery(sql)
query.Execute()
while(query.NextRow())
ban_id = query.item[1]
ban_number++;
if(ban_number == 0)
usr << "Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin. "
return
if(ban_number > 1)
usr << "Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin. "
return
if(istext(ban_id))
ban_id = text2num(ban_id)
if(!isnum(ban_id))
usr << "Database update failed due to a ban ID mismatch. Contact the database admin. "
return
DB_ban_unban_by_id(ban_id)
/proc/DB_ban_edit(var/banid = null, var/param = null)
if(!check_rights(R_BAN)) return
if(!isnum(banid) || !istext(param))
usr << "Cancelled"
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, duration, reason FROM ss13_ban WHERE id = [banid]")
query.Execute()
var/eckey = usr.ckey //Editing admin ckey
var/pckey //(banned) Player ckey
var/duration //Old duration
var/reason //Old reason
if(query.NextRow())
pckey = query.item[1]
duration = query.item[2]
reason = query.item[3]
else
usr << "Invalid ban id. Contact the database admin"
return
reason = sql_sanitize_text(reason)
var/value
switch(param)
if("reason")
if(!value)
value = sanitize(input("Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null) as null|text)
value = sql_sanitize_text(value)
if(!value)
usr << "Cancelled"
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE ss13_ban SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\" ') WHERE id = [banid]")
update_query.Execute()
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s reason from [reason] to [value]",1)
if("duration")
if(!value)
value = input("Insert the new duration (in minutes) for [pckey]'s ban", "New Duration", "[duration]", null) as null|num
if(!isnum(value) || !value)
usr << "Cancelled"
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE ss13_ban SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value] '), expiration_time = DATE_ADD(bantime, INTERVAL [value] MINUTE) WHERE id = [banid]")
message_admins("[key_name_admin(usr)] has edited a ban for [pckey]'s duration from [duration] to [value]",1)
update_query.Execute()
if("unban")
if(alert("Unban [pckey]?", "Unban?", "Yes", "No") == "Yes")
DB_ban_unban_by_id(banid)
return
else
usr << "Cancelled"
return
else
usr << "Cancelled"
return
/proc/DB_ban_unban_by_id(var/id)
if(!check_rights(R_BAN)) return
var/sql = "SELECT ckey, bantype, job FROM ss13_ban WHERE id = [id]"
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
return
var/reason = input("Please specify an unban reason.", "Unban Reason", "Unbanned as per appeal.")
if (!reason)
usr << "Invalid reason given. Cancelled. "
return
var/ban_number = 0 //failsafe
var/pckey
var/ban_type
var/job // This is for integrating the static jobban API into this.
var/DBQuery/query = dbcon.NewQuery(sql)
query.Execute()
while(query.NextRow())
pckey = query.item[1]
ban_type = query.item[2]
job = query.item[3]
ban_number++;
if(ban_number == 0)
usr << "Database update failed due to a ban id not being present in the database. "
return
if(ban_number > 1)
usr << "Database update failed due to multiple bans having the same ID. Contact the database admin. "
return
var/datum/admins/holder = null
if (usr)
holder = usr.client ? usr.client.holder : null
if (!holder)
return
var/unban_ckey = holder ? holder.owner.ckey : "Adminbot"
var/unban_computerid = holder ? holder.owner.computer_id : ""
var/unban_ip = holder ? holder.owner.address : world.address
var/unban_reason = sanitizeSQL(reason)
var/sql_update = "UPDATE ss13_ban SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = '[unban_ip]', unbanned_reason = '[unban_reason]' WHERE id = [id]"
message_admins("[key_name_admin(usr)] has lifted [pckey]'s ban.",1)
var/DBQuery/query_update = dbcon.NewQuery(sql_update)
query_update.Execute()
notes_add_sql(ckey(pckey), "[ban_type] (#[id]) lifted. Reason for unban: [reason].", usr)
// If we're lifting a jobban, update the local array of bans.
if ((ban_type == "JOB_TEMPBAN" || ban_type == "JOB_PERMABAN") && job)
jobban_unban(pckey, job)
/client/proc/DB_ban_panel()
set category = "Admin"
set name = "Banning Panel"
set desc = "Edit admin permissions"
if(!holder)
return
holder.DB_ban_panel()
/datum/admins/proc/DB_ban_panel(var/playerckey = null, var/adminckey = null, var/playerip = null, var/playercid = null, var/dbbantype = null, var/match = null)
if(!usr.client)
return
if(!check_rights(R_BAN)) return
establish_db_connection(dbcon)
if(!dbcon.IsConnected())
usr << "Failed to establish database connection "
return
var/output = "
"
output += ""
output += "Banning panel "
output += " "
output += ""
output += ""
output += " "
output += " "
output += "
"
output += "
"
output += " "
output += " Match(min. 3 characters to search by key or ip, and 7 to search by cid) "
output += " "
output += "Please note that all jobban bans or unbans are in-effect the following round.
"
output += "This search shows only last 100 bans."
if(adminckey || playerckey || playerip || playercid || dbbantype)
adminckey = ckey(adminckey)
playerckey = ckey(playerckey)
playerip = sql_sanitize_text(playerip)
playercid = sql_sanitize_text(playercid)
if(adminckey || playerckey || playerip || playercid || dbbantype)
var/blcolor = "#ffeeee" //banned light
var/bdcolor = "#ffdddd" //banned dark
var/ulcolor = "#eeffee" //unbanned light
var/udcolor = "#ddffdd" //unbanned dark
var/alcolor = "#eeeeff" // auto-unbanned light
var/adcolor = "#ddddff" // auto-unbanned dark
var/adminsearch = ""
var/playersearch = ""
var/ipsearch = ""
var/cidsearch = ""
var/bantypesearch = ""
var/mirror_player = ""
var/mirror_ip = ""
var/mirror_cid = ""
if(!match)
if(adminckey)
adminsearch = "AND a_ckey = '[adminckey]' "
if(playerckey)
playersearch = "AND ckey = '[playerckey]' "
mirror_player = "AND mirrors.ckey = '[playerckey]' "
if(playerip)
ipsearch = "AND ip = '[playerip]' "
mirror_ip = "AND mirrors.ip = '[playerip]' "
if(playercid)
cidsearch = "AND computerid = '[playercid]' "
mirror_cid = "AND mirrors.computerid = '[playercid]'"
else
if(adminckey && lentext(adminckey) >= 3)
adminsearch = "AND a_ckey LIKE '[adminckey]%' "
if(playerckey && lentext(playerckey) >= 3)
playersearch = "AND ckey LIKE '[playerckey]%' "
if(playerip && lentext(playerip) >= 3)
ipsearch = "AND ip LIKE '[playerip]%' "
if(playercid && lentext(playercid) >= 7)
cidsearch = "AND computerid LIKE '[playercid]%' "
if(dbbantype)
bantypesearch = "AND bantype = "
switch(dbbantype)
if(BANTYPE_TEMP)
bantypesearch += "'TEMPBAN' "
if(BANTYPE_JOB_PERMA)
bantypesearch += "'JOB_PERMABAN' "
if(BANTYPE_JOB_TEMP)
bantypesearch += "'JOB_TEMPBAN' "
else
bantypesearch += "'PERMABAN' "
/**
* Do mirror checks first! Basically find active mirrors and add those to the output before we proceed onto finding bans.
*/
if (!match)
var/DBQuery/mirror_query = dbcon.NewQuery({"SELECT DISTINCT(mirrors.ban_id), bans.ckey FROM ss13_ban_mirrors mirrors
JOIN ss13_ban bans ON mirrors.ban_id = bans.id
WHERE (isnull(mirrors.deleted_at) AND (1 [mirror_player] [mirror_ip] [mirror_cid]))
AND (
ISNULL(bans.unbanned) AND (
(bans.bantype = 'PERMABAN')
OR
(bans.bantype = 'TEMPBAN' AND bans.expiration_time > NOW())
)
)"})
mirror_query.Execute()
var/mirror_count = 0
var/mirror_data = "
"
while (mirror_query.NextRow())
mirror_data += "Active mirror for #[mirror_query.item[1]] (
View Ban )
"
mirror_count++
if (mirror_count)
output += "
[mirror_count] Active Mirrors Found! "
output += mirror_data
output += "
"
output += "
"
output += ""
output += "TYPE "
output += "CKEY "
output += "TIME APPLIED "
output += "ADMIN "
output += "OPTIONS "
output += " "
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, unbanned_reason, edits, ip, computerid FROM ss13_ban WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100")
select_query.Execute()
var/now = time2text(world.realtime, "YYYY-MM-DD hh:mm:ss") // MUST BE the same format as SQL gives us the dates in, and MUST be least to most specific (i.e. year, month, day not day, month, year)
while(select_query.NextRow())
var/banid = select_query.item[1]
var/bantime = select_query.item[2]
var/bantype = select_query.item[3]
var/reason = select_query.item[4]
var/job = select_query.item[5]
var/duration = select_query.item[6]
var/expiration = select_query.item[7]
var/ckey = select_query.item[8]
var/ackey = select_query.item[9]
var/unbanned = select_query.item[10]
var/unbanckey = select_query.item[11]
var/unbantime = select_query.item[12]
var/unbanreason = select_query.item[13]
var/edits = select_query.item[14]
var/ip = select_query.item[15]
var/cid = select_query.item[16]
// true if this ban has expired
var/auto = (bantype in list("TEMPBAN", "JOB_TEMPBAN")) && now > expiration // oh how I love ISO 8601 (ish) date strings
var/lcolor = blcolor
var/dcolor = bdcolor
if(unbanned)
lcolor = ulcolor
dcolor = udcolor
else if(auto)
lcolor = alcolor
dcolor = adcolor
var/typedesc =""
switch(bantype)
if("PERMABAN")
typedesc = "PERMABAN "
if("TEMPBAN")
typedesc = "TEMPBAN ([duration] minutes) [(unbanned || auto) ? "" : "(Edit )"] Expires [expiration] "
if("JOB_PERMABAN")
typedesc = "JOBBAN ([job]) "
if("JOB_TEMPBAN")
typedesc = "TEMP JOBBAN ([job]) ([duration] minutes Expires [expiration] "
output += ""
output += "[typedesc] "
output += "[ckey] "
output += "[bantime] "
output += "[ackey] "
output += "[(unbanned || auto) ? "" : "Unban "] "
output += " "
output += ""
output += "IP: [ip] "
output += "CIP: [cid] "
output += " "
output += ""
output += "Reason: [(unbanned || auto) ? "" : "(Edit )"] \"[reason]\" "
output += " "
if(edits)
output += ""
output += "EDITS "
output += " "
output += ""
output += "[edits] "
output += " "
if(unbanned)
output += ""
output += "UNBANNED by admin [unbanckey] on [unbantime] "
if (!unbanreason)
unbanreason = "No unban reason given. (Ban probably lifted before update.)"
output += " "
output += "Reason for unban: [unbanreason]. "
output += " "
else if(auto)
output += ""
output += "EXPIRED at [expiration] "
output += " "
if (bantype in list("PERMABAN", "TEMPBAN"))
var/mirror_count = 0
var/DBQuery/get_mirrors = dbcon.NewQuery("SELECT id FROM ss13_ban_mirrors WHERE ban_id = :ban_id:")
get_mirrors.Execute(list("ban_id" = text2num(banid)))
while (get_mirrors.NextRow())
mirror_count++
if (mirror_count)
output += ""
output += "Ban Mirrored [mirror_count > 1 ? "[mirror_count] times" : "once"] ! "
output += " "
output += ""
output += "  "
output += " "
output += "
"
usr << browse(output,"window=lookupbans;size=900x700")