Feature - Rewriting jobbans! (#2114)

Current jobban system:

Jobbans stored as plain text and require a for loop to go through and search for specific ones.
Fiddly as shit, because, again, stored as plain text and not quickly break-up-able.
butts
No temporary jobbans on the old file system.
No centralized API to handle jobbanning. Jobbans have to be ran through separate procs in case of the MySQL system being used.
New jobban system:

Associated lists to store bans. This allows key based accessing and validation of a ban. Much faster than for-looping twice to compare text.
Associated lists saved to the ban file. Pretty good stuff that this works.
Temporary jobbans for file system. Bans which are expired are removed right as they're checked.
Binding of the MySQL procs with the old jobban API. More centralized design. (Less, "Oh god, I forgot to save this to the DB!")
Instant effect on unbans. As opposed to waiting 1 round for it to take effect.
Removal of dormant code.
This commit is contained in:
skull132
2017-05-24 20:46:07 +03:00
committed by GitHub
parent 266f8c1d7d
commit 8cca057344
7 changed files with 804 additions and 786 deletions
+39 -18
View File
@@ -1,8 +1,16 @@
//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.
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)
/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
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())
@@ -63,10 +71,14 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
var/a_computerid
var/a_ip
if(src.owner && istype(src.owner, /client))
a_ckey = src.owner:ckey
a_computerid = src.owner:computer_id
a_ip = src.owner:address
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)
@@ -90,9 +102,7 @@ datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration =
usr << "<span class='notice'>Ban saved to database.</span>"
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)
datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
if(!check_rights(R_BAN)) return
@@ -156,7 +166,7 @@ datum/admins/proc/DB_ban_unban(var/ckey, var/bantype, var/job = "")
DB_ban_unban_by_id(ban_id)
datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
/proc/DB_ban_edit(var/banid = null, var/param = null)
if(!check_rights(R_BAN)) return
@@ -216,17 +226,17 @@ datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
usr << "Cancelled"
return
datum/admins/proc/DB_ban_unban_by_id(var/id)
/proc/DB_ban_unban_by_id(var/id)
if(!check_rights(R_BAN)) return
var/sql = "SELECT ckey, bantype FROM ss13_ban WHERE id = [id]"
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 appear.")
var/reason = input("Please specify an unban reason.", "Unban Reason", "Unbanned as per appeal.")
if (!reason)
usr << "<span class='warning'>Invalid reason given. Cancelled.</span>"
return
@@ -235,11 +245,13 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
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)
@@ -250,12 +262,17 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
usr << "<span class='warning'>Database update failed due to multiple bans having the same ID. Contact the database admin.</span>"
return
if(!src.owner || !istype(src.owner, /client))
return
var/datum/admins/holder = null
var/unban_ckey = src.owner:ckey
var/unban_computerid = src.owner:computer_id
var/unban_ip = src.owner:address
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]"
@@ -266,6 +283,10 @@ datum/admins/proc/DB_ban_unban_by_id(var/id)
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"
+1 -1
View File
@@ -140,7 +140,7 @@ var/savefile/Banlist
log_admin("[key_name_admin(usr)] unbanned [key]",admin_key=key_name(usr),ckey=key)
message_admins("[key_name_admin(usr)] unbanned: [key]")
feedback_inc("ban_unban",1)
usr.client.holder.DB_ban_unban( ckey(key), BANTYPE_ANY_FULLBAN)
DB_ban_unban( ckey(key), BANTYPE_ANY_FULLBAN)
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (key == Banlist["key"] /*|| id == Banlist["id"]*/)
+13 -8
View File
@@ -63,7 +63,7 @@ proc/admin_notice(var/message, var/rights)
<A href='?_src_=holder;warn=[M.ckey]'>Warn</A> |
<a href='?src=\ref[src];warnsearchckey=[M.ckey]'>Warnings</a> |
<A href='?src=\ref[src];newban=\ref[M]'>Ban</A> |
<A href='?src=\ref[src];jobban2=\ref[M]'>Jobban</A> |
<A href='?src=\ref[src];jobban_panel=\ref[M]'>Jobban</A> |
<A href='?src=\ref[src];notes=show;mob=\ref[M]'>Notes</A>
"}
@@ -575,14 +575,19 @@ proc/admin_notice(var/message, var/rights)
/datum/admins/proc/Jobbans()
if(!check_rights(R_BAN)) return
if(!check_rights(R_BAN))
return
// RIP whoever uses this panel. It's going to be amazingly painful!
var/dat = "<B>Job Bans!</B><HR>"
dat += "<a href='?src=\ref[src];jobban_search=1'>Search via ckey</a><br>"
dat += "<table>"
for (var/ckey in jobban_keylist)
for (var/job in jobban_keylist[ckey])
var/list/ban = jobban_keylist[ckey][job]
if (!jobban_isexpired(ban, null, job, ckey))
dat += "<tr><td>[ckey] - [ban[2]] - (<a href='?src=\ref[src];jobban_tgt=[ckey];jobban_job=[job];'>unban</a>)</td></tr>"
var/dat = "<B>Job Bans!</B><HR><table>"
for(var/t in jobban_keylist)
var/r = t
if( findtext(r,"##") )
r = copytext( r, 1, findtext(r,"##") )//removes the description
dat += text("<tr><td>[t] (<A href='?src=\ref[src];removejobban=[r]'>unban</A>)</td></tr>")
dat += "</table>"
usr << browse(dat, "window=ban;size=400x400")
+736 -84
View File
@@ -1,26 +1,122 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
#define CKEY_OR_MOB(tgt, ref) \
if (istext(ref)) { \
tgt = ckey(ref); \
var/mob/CKM = locate(ref); \
if (CKM && istype(CKM)) { \
if (CKM.ckey) { \
tgt = CKM.ckey; \
} else { \
tgt = null; \
} \
} \
} else if (ismob(ref)) { \
var/mob/CKM = ref; \
tgt = CKM.ckey; \
}
var/jobban_runonce // Updates legacy bans with new info
var/jobban_keylist[0] //to store the keys & ranks
var/list/jobban_keylist = list() // Global jobban list.
/proc/jobban_fullban(mob/M, rank, reason)
if (!M || !M.key) return
jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_savebanfile()
/*
* Expected format:
* list("canonckey1" = list("jobname" = list("reason", time),
* "jobname2" = list("reason", time)),
* "canonckey2" = list("jobname" = list("reason", time)))
*
* And yes, this is all actually savefile compatible, as they can load and
* save associated lists quite neatly. Assoc lists remove the stupid amounts
* of for-looping and string searching, and allow you to simply grab a ban with:
*
* jobban_keylist[ckey][job]
*
* If record doesn't exist, he's not banned there. As easy as that.
*
* "time" should be BYOND realtime. For MySQL bans, it's not relevant, so we
* can get away with just using this. For permanent bans, leave 0.
*
* - Skull132, 17APR2017
*/
/proc/jobban_client_fullban(ckey, rank)
if (!ckey || !rank) return
jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_savebanfile()
/**
* Global hook for loading jobbans.
*
* @return num 1
*/
/hook/startup/proc/loadJobBans()
if (config.ban_legacy_system)
jobban_loadbanfile()
else
jobban_loaddatabase()
//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
if(M && rank)
testing("Database: [json_encode(jobban_keylist)]")
return 1
/**
* Logs a new jobban for a user.
* Will save the bans to a save file if we're using the legacy system. Otherwise,
* should be called via DB_ban_record.
*
* @param str|mob player The mob object or ckey of the player we're looking for.
* @param str rank The string name of the rank we want to ban the user from.
* @param str reason The reason for the ban.
* @param num minutes The length of the ban in minutes. -1 for permanent.
* @param datum/admins holder The holder of the admin doing the unbanning.
* required to access the DB ban procs.
*/
/proc/jobban_fullban(player, rank, reason, minutes)
var/key = null
CKEY_OR_MOB(key, player)
if (!key)
return
// Create a new record if the client isn't logged already.
if (!jobban_keylist[key])
jobban_keylist[key] = list()
// Sanity catch. This shouldn't happen, but better safe than sorry.
if (jobban_keylist[key][rank] && !jobban_isexpired(jobban_keylist[key][rank], player, rank))
log_and_message_admins("Attempted to apply a jobban to [key] while they already have an active ban. Job: [rank].")
return
// Set the expirey time in case of temp bans.
var/unban_time = minutes
if (minutes > -1)
unban_time = world.realtime + (minutes MINUTES)
// Create the entry.
jobban_keylist[key][rank] = list(reason, unban_time)
// Log the ban to the appropriate place.
if (config.ban_legacy_system)
jobban_savebanfile()
else
DB_ban_record(minutes < 0 ? BANTYPE_JOB_PERMA : BANTYPE_JOB_TEMP, null, minutes, reason, rank, banckey = key)
/**
* Checks if the player attached to the given mob M is banned from
* the given rank. Returns 0 if client is not banned, a reason (str)
* if is banned.
*
* If an antagonist role is sent, then the global "Antagonist" ban rank
* is also checked for.
*
* @param str|mob player The mob object or ckey of the player we're looking for.
* @param str rank The rank name that we're looking for a ban on.
*
* @return mixed str containing the ban reason if user is banned.
* null if user is not banned from given role.
*/
/proc/jobban_isbanned(player, rank)
var/ckey = null
CKEY_OR_MOB(ckey, player)
if (ckey)
if (guest_jobbans(rank))
if(config.guest_jobban && IsGuestKey(M.key))
if (config.guest_jobban && IsGuestKey(ckey))
return "Guest Job-ban"
if(config.usewhitelist && !check_whitelist(M))
return "Whitelisted Job"
if (config.usewhitelist && ismob(player) && !check_whitelist(player))
return "No Whitelist"
var/static/list/antag_bantypes
@@ -29,7 +125,7 @@ var/jobban_keylist[0] //to store the keys & ranks
for (var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if (antag && antag.bantype)
antag_bantypes |= "[antag.bantype]"
antag_bantypes |= antag.bantype
// We manage antagonist bans at this end point.
// Alternative is to manage it at each call to jobban_isbanned, however,
@@ -38,89 +134,645 @@ var/jobban_keylist[0] //to store the keys & ranks
if (rank in antag_bantypes)
antag_ban = TRUE
for (var/s in jobban_keylist)
if(findtext(s,"[M.ckey] - [rank]") == 1 || (antag_ban && findtext(s, "[M.ckey] - Antagonist") == 1))
var/startpos = findtext(s, "## ")+3
if(startpos && startpos<length(s))
var/text = copytext(s, startpos, 0)
if(text)
return text
return "Reason Unspecified"
return 0
// Get the user's ckey.
var/list/entry = jobban_keylist[ckey]
/*
DEBUG
/mob/verb/list_all_jobbans()
set name = "list all jobbans"
// If this is false, then we have no entry. As such, they have no active
// bans!
if (entry)
// Look for the rank specific ban.
var/list/ban = entry[rank]
for(var/s in jobban_keylist)
world << s
// We have it, return it!
if (ban && !jobban_isexpired(ban, player, rank))
return ban[1]
/mob/verb/reload_jobbans()
set name = "reload jobbans"
// Catch for global antagonist bans as a failsafe.
if (antag_ban)
ban = entry["Antagonist"]
if (ban && !jobban_isexpired(ban, player, rank))
return ban[1]
jobban_loadbanfile()
*/
/hook/startup/proc/loadJobBans()
jobban_loadbanfile()
return 1
return null
/**
* @name jobban_loadbanfile()
* @desc Loads all currently saved jobbans from the data/job_full.ban file.
*
* @return null
*/
/proc/jobban_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] >> jobban_keylist
log_admin("Loading jobban_rank")
S["runonce"] >> jobban_runonce
var/savefile/S = new("data/job_full.ban")
S["bans"] >> jobban_keylist
log_admin("Loading jobban_rank")
if (!length(jobban_keylist))
jobban_keylist=list()
log_admin("jobban_keylist was empty")
else
if(!establish_db_connection(dbcon))
error("Database connection failed. Reverting to the legacy ban system.")
log_misc("Database connection failed. Reverting to the legacy ban system.")
config.ban_legacy_system = 1
jobban_loadbanfile()
return
if (!jobban_keylist)
jobban_keylist = list()
log_admin("jobban_keylist was empty")
//Job permabans
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, job FROM ss13_ban WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
query.Execute()
/**
* Loads all currently active bans from the database. Sets expiration
* times to 0, as the query refreshes records every time it's pulled.
* Unlike the hard file bans.
*/
/proc/jobban_loaddatabase()
// No database. Weee.
if (!establish_db_connection(dbcon))
error("Database connection failed. Reverting to the legacy ban system.")
log_misc("Database connection failed. Reverting to the legacy ban system.")
config.ban_legacy_system = 1
jobban_loadbanfile()
return
while(query.NextRow())
var/ckey = query.item[1]
var/job = query.item[2]
// All jobbans in one query. Because we don't actually care.
var/DBQuery/query = dbcon.NewQuery("SELECT id, ckey, job, reason FROM ss13_ban WHERE isnull(unbanned) AND ((bantype = 'JOB_PERMABAN') OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now()))")
query.Execute()
jobban_keylist.Add("[ckey] - [job]")
while (query.NextRow())
var/ckey = ckey(query.item[2])
var/job = query.item[3]
var/reason = query.item[4]
//Job tempbans
var/DBQuery/query1 = dbcon.NewQuery("SELECT ckey, job FROM ss13_ban WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
query1.Execute()
if (!jobban_keylist[ckey])
jobban_keylist[ckey] = list()
while(query1.NextRow())
var/ckey = query1.item[1]
var/job = query1.item[2]
jobban_keylist.Add("[ckey] - [job]")
if (!jobban_keylist[ckey][job])
// Insert it with 0 time because the expiration of a temp jobban for
// MySQL is dependent on the database and query itself. So we can just
// politely not care.
jobban_keylist[ckey][job] = list(reason, -1)
else
// Woups. What happened here...?
log_and_message_admins("JOBBANS: Duplicate jobban entry in MySQL for [ckey]. Ban ID: #[query.item[1]]")
/**
* Saves the current bans into the data/job_full.ban file.
*/
/proc/jobban_savebanfile()
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] << jobban_keylist
var/savefile/S = new("data/job_full.ban")
S["bans"] << jobban_keylist
/proc/jobban_unban(mob/M, rank)
jobban_remove("[M.ckey] - [rank]")
jobban_savebanfile()
/**
* Removes a jobban entry from the code and calls the config appropriate
* record removal method. In case of legacy bans, jobban file is updated.
*
* For the DB system, the DB_ban_unban_by_id method calls this to remove the local
* instance of the ban.
*
* @param str|mob player The mob object or ckey of the player we're looking for.
* @param str rank The job from which we want to unban the given player.
*/
/proc/jobban_unban(player, rank)
var/ckey = null
CKEY_OR_MOB(ckey, player)
if (!ckey)
log_debug("JOBBAN: jobban_unban called without a mob and a backup ckey.")
return
// Check for a player record.
var/list/entry = jobban_keylist[ckey]
if (entry)
// Find the specific ban.
var/list/ban = entry[rank]
if (ban)
// Remove said ban. Lists pass by ref, so this is fine.
entry[rank] = null
entry -= rank
// If the entry is now empty, remove the entire ckey from the list.
if (!entry.len)
jobban_keylist[ckey] = null
jobban_keylist -= ckey
// Update appropriate ban files.
if (config.ban_legacy_system)
jobban_savebanfile()
/**
* Checks whether or not a jobban is expired. If a ban is expired,
* it'll call jobban_unban to lift the ban. This allows for temporary
* jobbans with the old file system.
*
* Does not work on the MySQL system. The bans for that refresh every
* round, as per the queries.
*
* @param list tuple The list containing reason and expiery time to check.
* @param str|mob player The mob object or ckey of the player we're looking for.
* @param str rank The job we're checking. To be passed into jobban_unban in case
* of an expired ban.
*
* @return num TRUE if ban is expired.
* FALSE if ban is not expired.
*/
/proc/jobban_isexpired(var/list/tuple, var/player, var/rank)
if (config.ban_legacy_system && tuple[2] && (tuple[2] > 0) && (tuple[2] < world.realtime))
// It's expired. Remove it.
jobban_unban(player, rank)
return TRUE
return FALSE
/**
* Updates the ban_unban_log.txt file by appending formatted_log to its
* contents.
*
* @param str formatted_log The new content to be appended to the log file.
*/
/proc/ban_unban_log_save(var/formatted_log)
text2file(formatted_log,"data/ban_unban_log.txt")
text2file(formatted_log, "data/ban_unban_log.txt")
/**
* Opens the jobban panel, showing the bans of the passed mob or ckey.
*
* @param str|mob tgt_ref The target we want to view jobbans of. Can be a reference
* to a mob object (gotten with \ref[M]) or an actual mob object.
*/
/datum/admins/proc/jobban_panel(var/tgt_ref = null)
if (!tgt_ref)
return
/proc/jobban_remove(X)
for (var/i = 1; i <= length(jobban_keylist); i++)
if( findtext(jobban_keylist[i], "[X]") )
jobban_keylist.Remove(jobban_keylist[i])
jobban_savebanfile()
return 1
return 0
// Check against usr's perms.
if (!check_rights(R_ADMIN|R_MOD|R_BAN))
return
var/ckey = null
CKEY_OR_MOB(ckey, tgt_ref)
if (!ckey)
to_chat(src.owner, "This mob has no ckey.")
return
var/dat = ""
var/header = "<head><title>Job-Ban Panel: [ckey]</title></head>"
var/body
var/jobs = ""
/***********************************WARNING!************************************
The jobban stuff looks mangled and disgusting
But it looks beautiful in-game
-Nodrak
************************************WARNING!***********************************/
var/counter = 0
//Regular jobs
//Command (Blue)
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr align='center' bgcolor='ccccff'><th colspan='[length(command_positions)]'><a href='?src=\ref[src];jobban_job=commanddept;jobban_tgt=[ckey]'>Command Positions</a></th></tr><tr align='center'>"
for (var/jobPos in command_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 6) //So things dont get squiiiiished!
jobs += "</tr><tr>"
counter = 0
jobs += "</tr></table>"
//Security (Red)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffddf0'><th colspan='[length(security_positions)]'><a href='?src=\ref[src];jobban_job=securitydept;jobban_tgt=[ckey]'>Security Positions</a></th></tr><tr align='center'>"
for (var/jobPos in security_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Engineering (Yellow)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(engineering_positions)]'><a href='?src=\ref[src];jobban_job=engineeringdept;jobban_tgt=[ckey]'>Engineering Positions</a></th></tr><tr align='center'>"
for (var/jobPos in engineering_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Medical (White)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffeef0'><th colspan='[length(medical_positions)]'><a href='?src=\ref[src];jobban_job=medicaldept;jobban_tgt=[ckey]'>Medical Positions</a></th></tr><tr align='center'>"
for (var/jobPos in medical_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Science (Purple)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='e79fff'><th colspan='[length(science_positions)]'><a href='?src=\ref[src];jobban_job=sciencedept;jobban_tgt=[ckey]'>Science Positions</a></th></tr><tr align='center'>"
for (var/jobPos in science_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Cargo (Brown ish)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='f49d50'><th colspan='[length(cargo_positions)]'><a href='?src=\ref[src];jobban_job=cargodept;jobban_tgt=[ckey]'>Cargo Positions</a></th></tr><tr align='center'>"
for (var/jobPos in cargo_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5)
jobs += "</tr><tr align='center'>"
counter = 0
//Civilian (Grey)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='dddddd'><th colspan='[length(civilian_positions)]'><a href='?src=\ref[src];jobban_job=civiliandept;jobban_tgt=[ckey]'>Civilian Positions</a></th></tr><tr align='center'>"
for (var/jobPos in civilian_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
if (jobban_isbanned(ckey, "Internal Affairs Agent"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=Internal Affairs Agent;jobban_tgt=[ckey]'><font color=red>Internal Affairs Agent</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=Internal Affairs Agent;jobban_tgt=[ckey]'>Internal Affairs Agent</a></td>"
jobs += "</tr></table>"
//Non-Human (Green)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)+1]'><a href='?src=\ref[src];jobban_job=nonhumandept;jobban_tgt=[ckey]'>Non-human Positions</a></th></tr><tr align='center'>"
for (var/jobPos in nonhuman_positions)
if (!jobPos)
continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if (!job)
continue
if (jobban_isbanned(ckey, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[job.title];jobban_tgt=[ckey]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
//pAI isn't technically a job, but it goes in here.
if (jobban_isbanned(ckey, "pAI"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=pAI;jobban_tgt=[ckey]'><font color=red>pAI</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=pAI;jobban_tgt=[ckey]'>pAI</a></td>"
if (jobban_isbanned(ckey, "AntagHUD"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=AntagHUD;jobban_tgt=[ckey]'><font color=red>AntagHUD</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=AntagHUD;jobban_tgt=[ckey]'>AntagHUD</a></td>"
jobs += "</tr></table>"
//Antagonist (Orange)
var/isbanned_dept = jobban_isbanned(ckey, "Antagonist")
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffeeaa'><th colspan='10'><a href='?src=\ref[src];jobban_job=Antagonist;jobban_tgt=[ckey]'>Antagonist Positions</a></th></tr><tr align='center'>"
// Antagonists.
counter = 0
for (var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if (!antag || !antag.bantype)
continue
if (isbanned_dept || jobban_isbanned(ckey, antag.bantype))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[antag.bantype];jobban_tgt=[ckey]'><font color=red>[replacetext("[antag.role_text]", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=[antag.bantype];jobban_tgt=[ckey]'>[replacetext("[antag.role_text]", " ", "&nbsp")]</a></td>"
counter++
if (counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Other races (BLUE, because I have no idea what other color to make this)
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ccccff'><th colspan='1'>Other Races</th></tr><tr align='center'>"
if (jobban_isbanned(ckey, "Dionaea"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=Dionaea;jobban_tgt=[ckey]'><font color=red>Dionaea</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban_job=Dionaea;jobban_tgt=[ckey]'>Dionaea</a></td>"
jobs += "</tr></table>"
body = "<body>[jobs]</body>"
dat = "<tt>[header][body]</tt>"
usr << browse(dat, "window=jobban_panel;size=800x490")
return
/**
* Handles the insertion of a new job ban. Currently called from /datum/admins/Topic().
*
* Relays a new ban to jobban_fullban and also manages database insertions where needed.
*
* @param str tgt_ref The \ref[] of the target mob we want to dinbannu.
* @param str job The name of the job we want to ban the target from.
*
* @return num 1 if something was done.
* 0 otherwise.
*/
/datum/admins/proc/jobban_handle(var/tgt_ref, var/job)
if (!check_rights(R_MOD, 0) && !check_rights(R_ADMIN, 0))
to_chat(usr, "<span class='warning'>You do not have the appropriate permissions to add job bans!</span>")
return 0
if (check_rights(R_MOD, 0) && !check_rights(R_ADMIN, 0) && !config.mods_can_job_tempban) // If mod and tempban disabled
to_chat(usr, "<span class='warning'>Mod jobbanning is disabled!</span>")
return 0
var/ckey = null
CKEY_OR_MOB(ckey, tgt_ref)
if (!ckey)
to_chat(usr, "<span class='warning'>No valid target sent. Cancelling.</span>")
return 0
if (admin_datums[ckey])
if (ckey != usr.ckey) //we can jobban ourselves
var/datum/admins/other_holder = admin_datums[ckey]
if(other_holder && (other_holder.rights & R_BAN)) //they can ban too. So we can't ban them
alert("You cannot perform this action. You must be of a higher administrative rank!")
return 0
//get jobs for department if specified, otherwise just returnt he one job in a list.
var/list/joblist = list()
switch (job)
if ("commanddept")
for (var/jobPos in command_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("securitydept")
for (var/jobPos in security_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("engineeringdept")
for (var/jobPos in engineering_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("medicaldept")
for (var/jobPos in medical_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("sciencedept")
for (var/jobPos in science_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("civiliandept")
for (var/jobPos in civilian_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("nonhumandept")
joblist += "pAI"
for (var/jobPos in nonhuman_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
if ("cargodept")
for (var/jobPos in cargo_positions)
if (!jobPos)
continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if (!temp)
continue
joblist += temp.title
else
joblist += job
//Create a list of unbanned jobs within joblist
var/list/notbannedlist = list()
for (var/R in joblist)
if (!jobban_isbanned(ckey, R))
notbannedlist += R
//Banning comes first
if (notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
switch (alert("Temporary Ban?",,"Yes","No", "Cancel"))
if ("Yes")
if (!check_rights(R_MOD,0) && !check_rights(R_BAN, 0))
to_chat(usr, "<span class='warning'>You Cannot issue temporary job-bans!</span>")
return 0
var/mins = input(usr, "How long (in minutes)?", "Ban time", 1440) as num|null
if (!mins)
return 0
if (check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > config.mod_job_tempban_max)
to_chat(usr, "<span class='warning'>Moderators can only job tempban up to [config.mod_job_tempban_max] minutes!</span>")
return 0
var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null)
if (!reason)
return 0
var/msg
for (var/R in notbannedlist)
ban_unban_log_save("[key_name(usr)] temp-jobbanned [ckey] from [R] for [mins] minutes. reason: [reason]")
log_admin("[key_name(usr)] temp-jobbanned [ckey] from [R] for [mins] minutes",admin_key=key_name(usr))
feedback_inc("ban_job_tmp", 1)
feedback_add_details("ban_job_tmp","- [R]")
jobban_fullban(ckey, R, reason, mins)
if (!msg)
msg = R
else
msg += ", [R]"
if (config.ban_legacy_system)
notes_add(ckey, "Banned from [msg] - [reason]", usr)
else
notes_add_sql(ckey, "Banned from [msg] - [reason]", usr)
message_admins("<span class='notice'>[key_name_admin(usr)] banned [ckey] from [msg] for [mins] minutes.</span>", 1)
if (ismob(tgt_ref))
var/mob/M = tgt_ref
to_chat(M, "<span class='danger'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>")
to_chat(M, "<span class='danger'>The reason is: [reason]</span>")
to_chat(M, "<span class='warning'>This jobban will be lifted in [mins] minutes.</span>")
jobban_panel(ckey)
return 1
if ("No")
if (!check_rights(R_BAN))
return
var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null)
if (reason)
var/msg
for (var/R in notbannedlist)
ban_unban_log_save("[key_name(usr)] perma-jobbanned [ckey] from [R]. reason: [reason]")
log_admin("[key_name(usr)] perma-banned [ckey] from [R]",admin_key=key_name(usr))
feedback_inc("ban_job", 1)
feedback_add_details("ban_job", "- [R]")
jobban_fullban(ckey, R, reason, -1)
if (!msg)
msg = R
else
msg += ", [R]"
if (config.ban_legacy_system)
notes_add(ckey, "Banned from [msg] - [reason]", usr)
else
notes_add_sql(ckey, "Banned from [msg] - [reason]", usr)
message_admins("<span class='notice'>[key_name_admin(usr)] banned [ckey] from [msg]</span>", 1)
if (ismob(tgt_ref))
var/mob/M = tgt_ref
to_chat(M, "<span class='danger'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>")
to_chat(M, "<span class='danger'>The reason is: [reason]</span>")
to_chat(M, "<span class='warning'>Jobban can be lifted only upon request.</span>")
jobban_panel(ckey)
return 1
if("Cancel")
return
//Unbanning joblist
//all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned)
if (joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban.
if (!config.ban_legacy_system)
// This is important. jobban_unban() can't actually lift DB bans. So the DB unban
// panel must be used instead.
to_chat(usr, "Unfortunately, database based unbanning cannot be done through this panel")
DB_ban_panel(ckey)
return 0
var/msg
for (var/R in joblist)
var/reason = jobban_isbanned(ckey, R)
if (!reason)
continue //skip if it isn't jobbanned anyway
switch (alert("Job: '[R]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No"))
if ("Yes")
ban_unban_log_save("[key_name(usr)] unjobbanned [ckey] from [R]")
log_admin("[key_name(usr)] unbanned [ckey] from [R]",admin_key=key_name(usr),ckey=ckey)
jobban_unban(ckey, R) // Refer to the jobban API.
feedback_inc("ban_job_unban",1)
feedback_add_details("ban_job_unban","- [R]")
if (!msg)
msg = R
else
msg += ", [R]"
else
continue
if (msg)
message_admins("<span class='notice'>[key_name_admin(usr)] unbanned [ckey] from [msg]</span>", 1)
if (ismob(tgt_ref))
var/mob/M = tgt_ref
to_chat(M, "<span class='danger'><BIG>You have been un-jobbanned by [usr.client.ckey] from [msg].</BIG></span>")
jobban_panel(ckey)
return 1
return 0 //we didn't do anything!
#undef CKEY_OR_MOB
-274
View File
@@ -1,274 +0,0 @@
var/savefile/Banlistjob
/proc/_jobban_isbanned(var/client/clientvar, var/rank)
if(!clientvar) return 1
ClearTempbansjob()
var/id = clientvar.computer_id
var/key = clientvar.ckey
if (guest_jobbans(rank))
if(config.guest_jobban && IsGuestKey(key))
return 1
Banlistjob.cd = "/base"
if (Banlistjob.dir.Find("[key][id][rank]"))
return 1
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
Banlistjob.cd = "/base/[A]"
if ((id == Banlistjob["id"] || key == Banlistjob["key"]) && rank == Banlistjob["rank"])
return 1
return 0
/proc/LoadBansjob()
Banlistjob = new("data/job_fullnew.bdb")
log_admin("Loading Banlistjob")
if (!length(Banlistjob.dir)) log_admin("Banlistjob is empty.")
if (!Banlistjob.dir.Find("base"))
log_admin("Banlistjob missing base dir.")
Banlistjob.dir.Add("base")
Banlistjob.cd = "/base"
else if (Banlistjob.dir.Find("base"))
Banlistjob.cd = "/base"
ClearTempbansjob()
return 1
/proc/ClearTempbansjob()
UpdateTime()
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
Banlistjob.cd = "/base/[A]"
//if (!Banlistjob["key"] || !Banlistjob["id"])
// RemoveBanjob(A, "full")
// log_admin("Invalid Ban.")
// message_admins("Invalid Ban.")
// continue
if (!Banlistjob["temp"]) continue
if (CMinutes >= Banlistjob["minutes"]) RemoveBanjob(A)
return 1
/proc/AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, rank)
UpdateTime()
var/bantimestamp
if (temp)
UpdateTime()
bantimestamp = CMinutes + minutes
if(rank == "Heads")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Head of Personnel")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Captain")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Head of Security")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Engineer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
return 1
if(rank == "Security")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Head of Security")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Warden")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Detective")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Security Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Cyborg")
return 1
if(rank == "Engineering")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Station Engineer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Atmospheric Technician")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Engineer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Cyborg")
return 1
if(rank == "Research")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Scientist")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Geneticist")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director")
return 1
if(rank == "Medical")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Geneticist")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Medical Doctor")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chemist")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Cyborg")
return 1
if(rank == "CE_Station_Engineer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Station Engineer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Engineer")
return 1
if(rank == "CE_Atmospheric_Tech")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Atmospheric Technician")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Engineer")
return 1
if(rank == "CE_Shaft_Miner")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Shaft Miner")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Engineer")
return 1
if(rank == "Chemist_RD_CMO")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chemist")
return 1
if(rank == "Geneticist_RD_CMO")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Geneticist")
return 1
if(rank == "MD_CMO")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Medical Doctor")
return 1
if(rank == "Scientist_RD")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Scientist")
return 1
if(rank == "AI_Cyborg")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Cyborg")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "AI")
return 1
if(rank == "Detective_HoS")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Detective")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Head of Security")
return 1
if(rank == "Virologist_RD_CMO")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Chief Medical Officer")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Research Director")
AddBanjob(ckey, computerid, reason, bannedby, temp, minutes, "Virologist")
return 1
Banlistjob.cd = "/base"
if ( Banlistjob.dir.Find("[ckey][computerid][rank]") )
usr << text("<span class='warning'>Banjob already exists.</span>")
return 0
else
Banlistjob.dir.Add("[ckey][computerid][rank]")
Banlistjob.cd = "/base/[ckey][computerid][rank]"
Banlistjob["key"] << ckey
Banlistjob["id"] << computerid
Banlistjob["rank"] << rank
Banlistjob["reason"] << reason
Banlistjob["bannedby"] << bannedby
Banlistjob["temp"] << temp
if (temp)
Banlistjob["minutes"] << bantimestamp
return 1
/proc/RemoveBanjob(foldername)
var/key
var/id
var/rank
Banlistjob.cd = "/base/[foldername]"
Banlistjob["key"] >> key
Banlistjob["id"] >> id
Banlistjob["rank"] >> rank
Banlistjob.cd = "/base"
if (!Banlistjob.dir.Remove(foldername)) return 0
if(!usr)
log_admin("Banjob Expired: [key]",ckey=key)
message_admins("Banjob Expired: [key]")
else
log_admin("[key_name_admin(usr)] unjobbanned [key] from [rank]",admin_key=key_name(usr),ckey=key)
message_admins("[key_name_admin(usr)] unjobbanned:[key] from [rank]")
ban_unban_log_save("[key_name_admin(usr)] unjobbanned [key] from [rank]")
feedback_inc("ban_job_unban",1)
feedback_add_details("ban_job_unban","- [rank]")
for (var/A in Banlistjob.dir)
Banlistjob.cd = "/base/[A]"
if ((key == Banlistjob["key"] || id == Banlistjob["id"]) && (rank == Banlistjob["rank"]))
Banlistjob.cd = "/base"
Banlistjob.dir.Remove(A)
continue
return 1
/proc/GetBanExpjob(minutes as num)
UpdateTime()
var/exp = minutes - CMinutes
if (exp <= 0)
return 0
else
var/timeleftstring
if (exp >= 1440) //1440 = 1 day in minutes
timeleftstring = "[round(exp / 1440, 0.1)] Days"
else if (exp >= 60) //60 = 1 hour in minutes
timeleftstring = "[round(exp / 60, 0.1)] Hours"
else
timeleftstring = "[exp] Minutes"
return timeleftstring
/datum/admins/proc/unjobbanpanel()
var/count = 0
var/dat
//var/dat = "<HR><B>Unban Player:</B> \blue(U) = Unban , (E) = Edit Ban\green (Total<HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 >"
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
count++
Banlistjob.cd = "/base/[A]"
dat += text("<tr><td><A href='?src=\ref[src];unjobbanf=[Banlistjob["key"]][Banlistjob["id"]][Banlistjob["rank"]]'>(U)</A> Key: <B>[Banlistjob["key"]] </B>Rank: <B>[Banlistjob["rank"]]</B></td><td> ([Banlistjob["temp"] ? "[GetBanExpjob(Banlistjob["minutes"]) ? GetBanExpjob(Banlistjob["minutes"]) : "Removal pending" ]" : "Permaban"])</td><td>(By: [Banlistjob["bannedby"]])</td><td>(Reason: [Banlistjob["reason"]])</td></tr>")
dat += "</table>"
dat = "<HR><B>Bans:</B> <FONT COLOR=blue>(U) = Unban , </FONT> - <FONT COLOR=green>([count] Bans)</FONT><HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 >[dat]"
usr << browse(dat, "window=unbanp;size=875x400")
/*/datum/admins/proc/permjobban(ckey, computerid, reason, bannedby, temp, minutes, rank)
if(AddBanjob(ckey, computerid, reason, usr.ckey, 0, 0, job))
M << "\red<BIG><B>You have been banned from [job] by [usr.client.ckey].\nReason: [reason].</B></BIG>"
M << "\red This is a permanent ban."
if(config.banappeals)
M << "\red To try to resolve this matter head to [config.banappeals]"
else
M << "\red No ban appeals URL has been set."
log_admin("[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis is a permanent ban.")
message_admins("\blue[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis is a permanent ban.")
/datum/admins/proc/timejobban(ckey, computerid, reason, bannedby, temp, minutes, rank)
if(AddBanjob(ckey, computerid, reason, usr.ckey, 1, mins, job))
M << "\red<BIG><B>You have been jobbanned from [job] by [usr.client.ckey].\nReason: [reason].</B></BIG>"
M << "\red This is a temporary ban, it will be removed in [mins] minutes."
if(config.banappeals)
M << "\red To try to resolve this matter head to [config.banappeals]"
else
M << "\red No ban appeals URL has been set."
log_admin("[usr.client.ckey] has jobbanned from [job] [ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
message_admins("\blue[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")*/
//////////////////////////////////// DEBUG ////////////////////////////////////
/proc/CreateBansjob()
UpdateTime()
var/i
var/last
for(i=0, i<1001, i++)
var/a = pick(1,0)
var/b = pick(1,0)
if(b)
Banlistjob.cd = "/base"
Banlistjob.dir.Add("trash[i]trashid[i]")
Banlistjob.cd = "/base/trash[i]trashid[i]"
Banlistjob["key"] << "trash[i]"
else
Banlistjob.cd = "/base"
Banlistjob.dir.Add("[last]trashid[i]")
Banlistjob.cd = "/base/[last]trashid[i]"
Banlistjob["key"] << last
Banlistjob["id"] << "trashid[i]"
Banlistjob["reason"] << "Trashban[i]."
Banlistjob["temp"] << a
Banlistjob["minutes"] << CMinutes + rand(1,2000)
Banlistjob["bannedby"] << "trashmin"
last = "trash[i]"
Banlistjob.cd = "/base"
/proc/ClearAllBansjob()
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
RemoveBanjob(A, "full")
+14 -400
View File
@@ -396,397 +396,26 @@
/////////////////////////////////////new ban stuff
else if(href_list["jobban2"])
// if(!check_rights(R_BAN)) return
var/mob/M = locate(href_list["jobban2"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
return
if(!M.ckey) //sanity
usr << "This mob has no ckey"
return
var/dat = ""
var/header = "<head><title>Job-Ban Panel: [M.name]</title></head>"
var/body
var/jobs = ""
/***********************************WARNING!************************************
The jobban stuff looks mangled and disgusting
But it looks beautiful in-game
-Nodrak
************************************WARNING!***********************************/
var/counter = 0
//Regular jobs
//Command (Blue)
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr align='center' bgcolor='ccccff'><th colspan='[length(command_positions)]'><a href='?src=\ref[src];jobban3=commanddept;jobban4=\ref[M]'>Command Positions</a></th></tr><tr align='center'>"
for(var/jobPos in command_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 6) //So things dont get squiiiiished!
jobs += "</tr><tr>"
counter = 0
jobs += "</tr></table>"
//Security (Red)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffddf0'><th colspan='[length(security_positions)]'><a href='?src=\ref[src];jobban3=securitydept;jobban4=\ref[M]'>Security Positions</a></th></tr><tr align='center'>"
for(var/jobPos in security_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Engineering (Yellow)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(engineering_positions)]'><a href='?src=\ref[src];jobban3=engineeringdept;jobban4=\ref[M]'>Engineering Positions</a></th></tr><tr align='center'>"
for(var/jobPos in engineering_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Medical (White)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffeef0'><th colspan='[length(medical_positions)]'><a href='?src=\ref[src];jobban3=medicaldept;jobban4=\ref[M]'>Medical Positions</a></th></tr><tr align='center'>"
for(var/jobPos in medical_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Science (Purple)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='e79fff'><th colspan='[length(science_positions)]'><a href='?src=\ref[src];jobban3=sciencedept;jobban4=\ref[M]'>Science Positions</a></th></tr><tr align='center'>"
for(var/jobPos in science_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
jobs += "</tr></table>"
//Civilian (Grey)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='dddddd'><th colspan='[length(civilian_positions)]'><a href='?src=\ref[src];jobban3=civiliandept;jobban4=\ref[M]'>Civilian Positions</a></th></tr><tr align='center'>"
for(var/jobPos in civilian_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
if(jobban_isbanned(M, "Internal Affairs Agent"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Internal Affairs Agent;jobban4=\ref[M]'><font color=red>Internal Affairs Agent</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Internal Affairs Agent;jobban4=\ref[M]'>Internal Affairs Agent</a></td>"
jobs += "</tr></table>"
//Non-Human (Green)
counter = 0
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)+1]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
for(var/jobPos in nonhuman_positions)
if(!jobPos) continue
var/datum/job/job = SSjobs.GetJob(jobPos)
if(!job) continue
if(jobban_isbanned(M, job.title))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'><font color=red>[replacetext(job.title, " ", "&nbsp")]</font></a></td>"
counter++
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[job.title];jobban4=\ref[M]'>[replacetext(job.title, " ", "&nbsp")]</a></td>"
counter++
if(counter >= 5) //So things dont get squiiiiished!
jobs += "</tr><tr align='center'>"
counter = 0
//pAI isn't technically a job, but it goes in here.
if(jobban_isbanned(M, "pAI"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=pAI;jobban4=\ref[M]'><font color=red>pAI</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=pAI;jobban4=\ref[M]'>pAI</a></td>"
if(jobban_isbanned(M, "AntagHUD"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=AntagHUD;jobban4=\ref[M]'><font color=red>AntagHUD</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=AntagHUD;jobban4=\ref[M]'>AntagHUD</a></td>"
jobs += "</tr></table>"
//Antagonist (Orange)
var/isbanned_dept = jobban_isbanned(M, "Antagonist")
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ffeeaa'><th colspan='10'><a href='?src=\ref[src];jobban3=Antagonist;jobban4=\ref[M]'>Antagonist Positions</a></th></tr><tr align='center'>"
// Antagonists.
for(var/antag_type in all_antag_types)
var/datum/antagonist/antag = all_antag_types[antag_type]
if(!antag || !antag.bantype)
continue
if(jobban_isbanned(M, "[antag.bantype]") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[antag.bantype];jobban4=\ref[M]'><font color=red>[replacetext("[antag.role_text]", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=[antag.bantype];jobban4=\ref[M]'>[replacetext("[antag.role_text]", " ", "&nbsp")]</a></td>"
jobs += "</tr></table>"
//Other races (BLUE, because I have no idea what other color to make this)
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
jobs += "<tr bgcolor='ccccff'><th colspan='1'>Other Races</th></tr><tr align='center'>"
if(jobban_isbanned(M, "Dionaea"))
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Dionaea;jobban4=\ref[M]'><font color=red>Dionaea</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=Dionaea;jobban4=\ref[M]'>Dionaea</a></td>"
jobs += "</tr></table>"
body = "<body>[jobs]</body>"
dat = "<tt>[header][body]</tt>"
usr << browse(dat, "window=jobban2;size=800x490")
else if(href_list["jobban_panel"])
jobban_panel(href_list["jobban_panel"])
return
//JOBBAN'S INNARDS
else if(href_list["jobban3"])
if(!check_rights(R_MOD,0) && !check_rights(R_ADMIN,0))
usr << "<span class='warning'>You do not have the appropriate permissions to add job bans!</span>"
// JOBBAN'S INNARDS
// Are now moved to banjob.dm. For use with the newer system.
else if(href_list["jobban_job"])
return jobban_handle(href_list["jobban_tgt"], href_list["jobban_job"])
else if(href_list["jobban_search"])
if (!check_rights(R_MOD|R_ADMIN))
return
if(check_rights(R_MOD,0) && !check_rights(R_ADMIN,0) && !config.mods_can_job_tempban) // If mod and tempban disabled
usr << "<span class='warning'>Mod jobbanning is disabled!</span>"
var/ckey = ckey(input("Please specify the ckey you want to search for:", "ckey")) as text
if (!ckey)
usr << "<span class='notice'>Cancelled.</span>"
return
var/mob/M = locate(href_list["jobban4"])
if(!ismob(M))
usr << "This can only be used on instances of type /mob"
return
if(M != usr) //we can jobban ourselves
if(M.client && M.client.holder && (M.client.holder.rights & R_BAN)) //they can ban too. So we can't ban them
alert("You cannot perform this action. You must be of a higher administrative rank!")
return
//get jobs for department if specified, otherwise just returnt he one job in a list.
var/list/joblist = list()
switch(href_list["jobban3"])
if("commanddept")
for(var/jobPos in command_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
if("securitydept")
for(var/jobPos in security_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
if("engineeringdept")
for(var/jobPos in engineering_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
if("medicaldept")
for(var/jobPos in medical_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
if("sciencedept")
for(var/jobPos in science_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
if("civiliandept")
for(var/jobPos in civilian_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
if("nonhumandept")
joblist += "pAI"
for(var/jobPos in nonhuman_positions)
if(!jobPos) continue
var/datum/job/temp = SSjobs.GetJob(jobPos)
if(!temp) continue
joblist += temp.title
else
joblist += href_list["jobban3"]
//Create a list of unbanned jobs within joblist
var/list/notbannedlist = list()
for(var/job in joblist)
if(!jobban_isbanned(M, job))
notbannedlist += job
//Banning comes first
if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
switch(alert("Temporary Ban?",,"Yes","No", "Cancel"))
if("Yes")
if(!check_rights(R_MOD,0) && !check_rights(R_BAN, 0))
usr << "<span class='warning'>You Cannot issue temporary job-bans!</span>"
return
if(config.ban_legacy_system)
usr << "<span class='warning'>Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban.</span>"
return
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
if(!mins)
return
if(check_rights(R_MOD, 0) && !check_rights(R_BAN, 0) && mins > config.mod_job_tempban_max)
usr << "<span class='warning'>Moderators can only job tempban up to [config.mod_job_tempban_max] minutes!</span>"
return
var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null)
if(!reason)
return
var/msg
for(var/job in notbannedlist)
ban_unban_log_save("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes. reason: [reason]")
log_admin("[key_name(usr)] temp-jobbanned [key_name(M)] from [job] for [mins] minutes",admin_key=key_name(usr))
feedback_inc("ban_job_tmp",1)
DB_ban_record(BANTYPE_JOB_TEMP, M, mins, reason, job)
feedback_add_details("ban_job_tmp","- [job]")
jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]") //Legacy banning does not support temporary jobbans.
if(!msg)
msg = job
else
msg += ", [job]"
if (config.ban_legacy_system)
notes_add(M.ckey, "Banned from [msg] - [reason]", usr)
else
notes_add_sql(M.ckey, "Banned from [msg] - [reason]", usr, M.lastKnownIP, M.computer_id)
message_admins("<span class='notice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.</span>", 1)
M << "<span class='danger'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='danger'>The reason is: [reason]</span>"
M << "<span class='warning'>This jobban will be lifted in [mins] minutes.</span>"
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
if("No")
if(!check_rights(R_BAN)) return
var/reason = sanitize(input(usr,"Reason?","Please State Reason","") as text|null)
if(reason)
var/msg
for(var/job in notbannedlist)
ban_unban_log_save("[key_name(usr)] perma-jobbanned [key_name(M)] from [job]. reason: [reason]")
log_admin("[key_name(usr)] perma-banned [key_name(M)] from [job]",admin_key=key_name(usr))
feedback_inc("ban_job",1)
DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, job)
feedback_add_details("ban_job","- [job]")
jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]")
if(!msg) msg = job
else msg += ", [job]"
if (config.ban_legacy_system)
notes_add(M.ckey, "Banned from [msg] - [reason]", usr)
else
notes_add_sql(M.ckey, "Banned from [msg] - [reason]", usr, M.lastKnownIP, M.computer_id)
message_admins("<span class='notice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg]</span>", 1)
M << "<span class='danger'><BIG>You have been jobbanned by [usr.client.ckey] from: [msg].</BIG></span>"
M << "<span class='danger'>The reason is: [reason]</span>"
M << "<span class='warning'>Jobban can be lifted only upon request.</span>"
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
if("Cancel")
return
//Unbanning joblist
//all jobs in joblist are banned already OR we didn't give a reason (implying they shouldn't be banned)
if(joblist.len) //at least 1 banned job exists in joblist so we have stuff to unban.
if(!config.ban_legacy_system)
usr << "Unfortunately, database based unbanning cannot be done through this panel"
DB_ban_panel(M.ckey)
return
var/msg
for(var/job in joblist)
var/reason = jobban_isbanned(M, job)
if(!reason) continue //skip if it isn't jobbanned anyway
switch(alert("Job: '[job]' Reason: '[reason]' Un-jobban?","Please Confirm","Yes","No"))
if("Yes")
ban_unban_log_save("[key_name(usr)] unjobbanned [key_name(M)] from [job]")
log_admin("[key_name(usr)] unbanned [key_name(M)] from [job]",admin_key=key_name(usr),ckey=key_name(M))
DB_ban_unban(M.ckey, BANTYPE_JOB_PERMA, job)
feedback_inc("ban_job_unban",1)
feedback_add_details("ban_job_unban","- [job]")
jobban_unban(M, job)
if(!msg) msg = job
else msg += ", [job]"
else
continue
if(msg)
message_admins("<span class='notice'>[key_name_admin(usr)] unbanned [key_name_admin(M)] from [msg]</span>", 1)
M << "<span class='danger'><BIG>You have been un-jobbanned by [usr.client.ckey] from [msg].</BIG></span>"
href_list["jobban2"] = 1 // lets it fall through and refresh
return 1
return 0 //we didn't do anything!
jobban_panel(ckey)
return
else if(href_list["boot2"])
var/mob/M = locate(href_list["boot2"])
@@ -803,21 +432,6 @@
//M.client = null
qdel(M.client)
else if(href_list["removejobban"])
if(!check_rights(R_BAN)) return
var/t = href_list["removejobban"]
if(t)
if((alert("Do you want to unjobban [t]?","Unjobban confirmation", "Yes", "No") == "Yes") && t) //No more misclicks! Unless you do it twice.
log_admin("[key_name(usr)] removed [t]",admin_key=key_name(usr))
message_admins("<span class='notice'>[key_name_admin(usr)] removed [t]</span>", 1)
jobban_remove(t)
href_list["ban"] = 1 // lets it fall through and refresh
var/t_split = text2list(t, " - ")
var/key = t_split[1]
var/job = t_split[2]
DB_ban_unban(ckey(key), BANTYPE_JOB_PERMA, job)
else if(href_list["newban"])
if(!check_rights(R_MOD,0) && !check_rights(R_BAN, 0))
usr << "<span class='warning'>You do not have the appropriate permissions to add bans!</span>"