//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 += "" output += "" output += "
" output += "

Banning panel

" output += "
" output += "
Add custom ban: (ONLY use this if you can't ban through any other method)" output += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "
Ban type:Ckey:
IP: CID:
Duration: Job:
" output += "Reason:

" output += "" output += "
" output += "
" output += "
" output += "" output += "" output += "" output += "" output += "
Search:" output += "
Ckey: Admin ckey:
IP: CID:
Ban type:
" 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 += "" output += "" output += "" output += "" output += "" 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 += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "" output += "" if(edits) output += "" output += "" output += "" output += "" output += "" output += "" if(unbanned) output += "" output += "" if (!unbanreason) unbanreason = "No unban reason given. (Ban probably lifted before update.)" output += "" output += "" output += "" else if(auto) output += "" output += "" 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 += "" output += "" output += "" output += "" output += "" output += "
TYPECKEYTIME APPLIEDADMINOPTIONS
[typedesc][ckey][bantime][ackey][(unbanned || auto) ? "" : "Unban"]
IP: [ip]CIP: [cid]
Reason: [(unbanned || auto) ? "" : "(Edit)"] \"[reason]\"
EDITS
[edits]
UNBANNED by admin [unbanckey] on [unbantime]
Reason for unban: [unbanreason].
EXPIRED at [expiration]
Ban Mirrored [mirror_count > 1 ? "[mirror_count] times" : "once"]!
 
" usr << browse(output,"window=lookupbans;size=900x700")