Merge branch 'release' of https://github.com/VOREStation/VOREStation into upstream-update

This commit is contained in:
izac112
2024-02-26 03:37:23 +01:00
1157 changed files with 778221 additions and 777841 deletions
+481 -481
View File
@@ -1,481 +1,481 @@
//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)
if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return
establish_db_connection()
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 FROM erro_player WHERE ckey = '[ckey]'")
query.Execute()
var/validckey = 0
if(query.NextRow())
validckey = 1
if(!validckey)
if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key))) //VOREStation Edit Start.
var/confirm = tgui_alert(usr, "This ckey hasn't been seen, are you sure?", "Confirm Badmin", list("Yes", "No"))
if(confirm == "No")
return //VOREStation Edit End
var/a_ckey
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
var/who
for(var/client/C in GLOB.clients)
if(!who)
who = "[C]"
else
who += ", [C]"
var/adminwho
for(var/client/C in GLOB.admins)
if(!adminwho)
adminwho = "[C]"
else
adminwho += ", [C]"
reason = sql_sanitize_text(reason)
var/sql = "INSERT INTO erro_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()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("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 = "")
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 erro_ban WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
if(job)
sql += " AND job = '[job]'"
establish_db_connection()
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)
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.")]</span>")
return
if(ban_number > 1)
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin.")]</span>")
return
if(istext(ban_id))
ban_id = text2num(ban_id)
if(!isnum(ban_id))
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to a ban ID mismatch. Contact the database admin.")]</span>")
return
DB_ban_unban_by_id(ban_id)
/datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
if(!check_rights(R_BAN)) return
if(!isnum(banid) || !istext(param))
to_chat(usr, "Cancelled")
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, duration, reason FROM erro_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
to_chat(usr, "<span class='filter_adminlog'>Invalid ban id. Contact the database admin</span>")
return
reason = sql_sanitize_text(reason)
var/value
switch(param)
if("reason")
if(!value)
value = sanitize(tgui_input_text(usr, "Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null))
value = sql_sanitize_text(value)
if(!value)
to_chat(usr, "Cancelled")
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE erro_ban SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from <cite><b>\\\"[reason]\\\"</b></cite> to <cite><b>\\\"[value]\\\"</b></cite><BR>') 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 = tgui_input_number(usr, "Insert the new duration (in minutes) for [pckey]'s ban", "New Duration", "[duration]", null)
if(!isnum(value) || !value)
to_chat(usr, "Cancelled")
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE erro_ban SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value]<br>'), 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(tgui_alert(usr, "Unban [pckey]?", "Unban?", list("Yes", "No")) == "Yes")
DB_ban_unban_by_id(banid)
return
to_chat(usr, "<span class='filter_adminlog'>Cancelled</span>")
return
/datum/admins/proc/DB_ban_unban_by_id(var/id)
if(!check_rights(R_BAN)) return
var/sql = "SELECT ckey FROM erro_ban WHERE id = [id]"
establish_db_connection()
if(!dbcon.IsConnected())
return
var/ban_number = 0 //failsafe
var/pckey
var/DBQuery/query = dbcon.NewQuery(sql)
query.Execute()
while(query.NextRow())
pckey = query.item[1]
ban_number++;
if(ban_number == 0)
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to a ban id not being present in the database.")]</span>")
return
if(ban_number > 1)
to_chat(usr, "<span class='filter_adminlog'>[span_red("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/unban_ckey = src.owner:ckey
var/unban_computerid = src.owner:computer_id
var/unban_ip = src.owner:address
var/sql_update = "UPDATE erro_ban SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = '[unban_ip]' 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()
/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()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='filter_adminlog'>[span_red("Failed to establish database connection")]</span>")
return
var/output = "<div align='center'><table width='90%'><tr>"
output += "<td width='35%' align='center'>"
output += "<h1>Banning panel</h1>"
output += "</td>"
output += "<td width='65%' align='center' bgcolor='#f9f9f9'>"
output += "<form method='GET' action='?src=\ref[src]'>[HrefTokenFormField()]"
output += "<b>Add custom ban:</b> (ONLY use this if you can't ban through any other method)"
output += "<input type='hidden' name='src' value='\ref[src]'>"
output += "<table width='100%'><tr>"
output += "<td width='50%' align='right'><b>Ban type:</b><select name='dbbanaddtype'>"
output += "<option value=''>--</option>"
output += "<option value='[BANTYPE_PERMA]'>PERMABAN</option>"
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "</select></td>"
output += "<td width='50%' align='right'><b>Ckey:</b> <input type='text' name='dbbanaddckey'></td></tr>"
output += "<tr><td width='50%' align='right'><b>IP:</b> <input type='text' name='dbbanaddip'></td>"
output += "<td width='50%' align='right'><b>CID:</b> <input type='text' name='dbbanaddcid'></td></tr>"
output += "<tr><td width='50%' align='right'><b>Duration:</b> <input type='text' name='dbbaddduration'></td>"
output += "<td width='50%' align='right'><b>Job:</b><select name='dbbanaddjob'>"
output += "<option value=''>--</option>"
for(var/j in get_all_jobs())
output += "<option value='[j]'>[j]</option>"
for(var/j in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
output += "<option value='[j]'>[j]</option>"
var/list/bantypes = list("traitor","changeling","operative","revolutionary","cultist","wizard") //For legacy bans.
for(var/antag_type in all_antag_types) // Grab other bans.
var/datum/antagonist/antag = all_antag_types[antag_type]
bantypes |= antag.bantype
for(var/j in bantypes)
output += "<option value='[j]'>[j]</option>"
output += "</select></td></tr></table>"
output += "<b>Reason:<br></b><textarea name='dbbanreason' cols='50'></textarea><br>"
output += "<input type='submit' value='Add ban'>"
output += "</form>"
output += "</td>"
output += "</tr>"
output += "</table>"
output += "<form method='GET' action='?src=\ref[src]'>[HrefTokenFormField()]"
output += "<table width='60%'><tr><td colspan='2' align='left'><b>Search:</b>"
output += "<input type='hidden' name='src' value='\ref[src]'></td></tr>"
output += "<tr><td width='50%' align='right'><b>Ckey:</b> <input type='text' name='dbsearchckey' value='[playerckey]'></td>"
output += "<td width='50%' align='right'><b>Admin ckey:</b> <input type='text' name='dbsearchadmin' value='[adminckey]'></td></tr>"
output += "<tr><td width='50%' align='right'><b>IP:</b> <input type='text' name='dbsearchip' value='[playerip]'></td>"
output += "<td width='50%' align='right'><b>CID:</b> <input type='text' name='dbsearchcid' value='[playercid]'></td></tr>"
output += "<tr><td width='50%' align='right' colspan='2'><b>Ban type:</b><select name='dbsearchbantype'>"
output += "<option value=''>--</option>"
output += "<option value='[BANTYPE_PERMA]'>PERMABAN</option>"
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "</select></td></tr></table>"
output += "<br><input type='submit' value='search'><br>"
output += "<input type='checkbox' value='[match]' name='dbmatch' [match? "checked=\"1\"" : null]> Match(min. 3 characters to search by key or ip, and 7 to search by cid)<br>"
output += "</form>"
output += "Please note that all jobban bans or unbans are in-effect the following round.<br>"
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
output += "<table width='90%' bgcolor='#e3e3e3' cellpadding='5' cellspacing='0' align='center'>"
output += "<tr>"
output += "<th width='25%'><b>TYPE</b></th>"
output += "<th width='20%'><b>CKEY</b></th>"
output += "<th width='20%'><b>TIME APPLIED</b></th>"
output += "<th width='20%'><b>ADMIN</b></th>"
output += "<th width='15%'><b>OPTIONS</b></th>"
output += "</tr>"
var/adminsearch = ""
var/playersearch = ""
var/ipsearch = ""
var/cidsearch = ""
var/bantypesearch = ""
if(!match)
if(adminckey)
adminsearch = "AND a_ckey = '[adminckey]' "
if(playerckey)
playersearch = "AND ckey = '[playerckey]' "
if(playerip)
ipsearch = "AND ip = '[playerip]' "
if(playercid)
cidsearch = "AND computerid = '[playercid]' "
else
if(adminckey && length(adminckey) >= 3)
adminsearch = "AND a_ckey LIKE '[adminckey]%' "
if(playerckey && length(playerckey) >= 3)
playersearch = "AND ckey LIKE '[playerckey]%' "
if(playerip && length(playerip) >= 3)
ipsearch = "AND ip LIKE '[playerip]%' "
if(playercid && length(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' "
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid FROM erro_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/edits = select_query.item[13]
var/ip = select_query.item[14]
var/cid = select_query.item[15]
// 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 = "<font color='red'><b>PERMABAN</b></font>"
if("TEMPBAN")
typedesc = "<b>TEMPBAN</b><br><font size='2'>([duration] minutes) [(unbanned || auto) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=duration;dbbanid=[banid]\">Edit</a>)"]<br>Expires [expiration]</font>"
if("JOB_PERMABAN")
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])</font>"
if("JOB_TEMPBAN")
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes<br>Expires [expiration]</font>"
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center'>[typedesc]</td>"
output += "<td align='center'><b>[ckey]</b></td>"
output += "<td align='center'>[bantime]</td>"
output += "<td align='center'><b>[ackey]</b></td>"
output += "<td align='center'>[(unbanned || auto) ? "" : "<b><a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=unban;dbbanid=[banid]\">Unban</a></b>"]</td>"
output += "</tr>"
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='2' bgcolor=''><b>IP:</b> [ip]</td>"
output += "<td align='center' colspan='3' bgcolor=''><b>CIP:</b> [cid]</td>"
output += "</tr>"
output += "<tr bgcolor='[lcolor]'>"
output += "<td align='center' colspan='5'><b>Reason: [(unbanned || auto) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=reason;dbbanid=[banid]\">Edit</a>)"]</b> <cite>\"[reason]\"</cite></td>"
output += "</tr>"
if(edits)
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='5'><b>EDITS</b></td>"
output += "</tr>"
output += "<tr bgcolor='[lcolor]'>"
output += "<td align='center' colspan='5'><font size='2'>[edits]</font></td>"
output += "</tr>"
if(unbanned)
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='5' bgcolor=''><b>UNBANNED by admin [unbanckey] on [unbantime]</b></td>"
output += "</tr>"
else if(auto)
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='5' bgcolor=''><b>EXPIRED at [expiration]</b></td>"
output += "</tr>"
output += "<tr>"
output += "<td colspan='5' bgcolor='white'>&nbsp</td>"
output += "</tr>"
output += "</table></div>"
usr << browse(output,"window=lookupbans;size=900x700")
//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)
if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return
establish_db_connection()
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 FROM erro_player WHERE ckey = '[ckey]'")
query.Execute()
var/validckey = 0
if(query.NextRow())
validckey = 1
if(!validckey)
if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key))) //VOREStation Edit Start.
var/confirm = tgui_alert(usr, "This ckey hasn't been seen, are you sure?", "Confirm Badmin", list("Yes", "No"))
if(confirm == "No")
return //VOREStation Edit End
var/a_ckey
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
var/who
for(var/client/C in GLOB.clients)
if(!who)
who = "[C]"
else
who += ", [C]"
var/adminwho
for(var/client/C in GLOB.admins)
if(!adminwho)
adminwho = "[C]"
else
adminwho += ", [C]"
reason = sql_sanitize_text(reason)
var/sql = "INSERT INTO erro_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()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("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 = "")
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 erro_ban WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
if(job)
sql += " AND job = '[job]'"
establish_db_connection()
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)
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to no bans fitting the search criteria. If this is not a legacy ban you should contact the database admin.")]</span>")
return
if(ban_number > 1)
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to multiple bans fitting the search criteria. Note down the ckey, job and current time and contact the database admin.")]</span>")
return
if(istext(ban_id))
ban_id = text2num(ban_id)
if(!isnum(ban_id))
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to a ban ID mismatch. Contact the database admin.")]</span>")
return
DB_ban_unban_by_id(ban_id)
/datum/admins/proc/DB_ban_edit(var/banid = null, var/param = null)
if(!check_rights(R_BAN)) return
if(!isnum(banid) || !istext(param))
to_chat(usr, "Cancelled")
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, duration, reason FROM erro_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
to_chat(usr, "<span class='filter_adminlog'>Invalid ban id. Contact the database admin</span>")
return
reason = sql_sanitize_text(reason)
var/value
switch(param)
if("reason")
if(!value)
value = sanitize(tgui_input_text(usr, "Insert the new reason for [pckey]'s ban", "New Reason", "[reason]", null))
value = sql_sanitize_text(value)
if(!value)
to_chat(usr, "Cancelled")
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE erro_ban SET reason = '[value]', edits = CONCAT(edits,'- [eckey] changed ban reason from <cite><b>\\\"[reason]\\\"</b></cite> to <cite><b>\\\"[value]\\\"</b></cite><BR>') 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 = tgui_input_number(usr, "Insert the new duration (in minutes) for [pckey]'s ban", "New Duration", "[duration]", null)
if(!isnum(value) || !value)
to_chat(usr, "Cancelled")
return
var/DBQuery/update_query = dbcon.NewQuery("UPDATE erro_ban SET duration = [value], edits = CONCAT(edits,'- [eckey] changed ban duration from [duration] to [value]<br>'), 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(tgui_alert(usr, "Unban [pckey]?", "Unban?", list("Yes", "No")) == "Yes")
DB_ban_unban_by_id(banid)
return
to_chat(usr, "<span class='filter_adminlog'>Cancelled</span>")
return
/datum/admins/proc/DB_ban_unban_by_id(var/id)
if(!check_rights(R_BAN)) return
var/sql = "SELECT ckey FROM erro_ban WHERE id = [id]"
establish_db_connection()
if(!dbcon.IsConnected())
return
var/ban_number = 0 //failsafe
var/pckey
var/DBQuery/query = dbcon.NewQuery(sql)
query.Execute()
while(query.NextRow())
pckey = query.item[1]
ban_number++;
if(ban_number == 0)
to_chat(usr, "<span class='filter_adminlog'>[span_red("Database update failed due to a ban id not being present in the database.")]</span>")
return
if(ban_number > 1)
to_chat(usr, "<span class='filter_adminlog'>[span_red("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/unban_ckey = src.owner:ckey
var/unban_computerid = src.owner:computer_id
var/unban_ip = src.owner:address
var/sql_update = "UPDATE erro_ban SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey = '[unban_ckey]', unbanned_computerid = '[unban_computerid]', unbanned_ip = '[unban_ip]' 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()
/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()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='filter_adminlog'>[span_red("Failed to establish database connection")]</span>")
return
var/output = "<div align='center'><table width='90%'><tr>"
output += "<td width='35%' align='center'>"
output += "<h1>Banning panel</h1>"
output += "</td>"
output += "<td width='65%' align='center' bgcolor='#f9f9f9'>"
output += "<form method='GET' action='?src=\ref[src]'>[HrefTokenFormField()]"
output += "<b>Add custom ban:</b> (ONLY use this if you can't ban through any other method)"
output += "<input type='hidden' name='src' value='\ref[src]'>"
output += "<table width='100%'><tr>"
output += "<td width='50%' align='right'><b>Ban type:</b><select name='dbbanaddtype'>"
output += "<option value=''>--</option>"
output += "<option value='[BANTYPE_PERMA]'>PERMABAN</option>"
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "</select></td>"
output += "<td width='50%' align='right'><b>Ckey:</b> <input type='text' name='dbbanaddckey'></td></tr>"
output += "<tr><td width='50%' align='right'><b>IP:</b> <input type='text' name='dbbanaddip'></td>"
output += "<td width='50%' align='right'><b>CID:</b> <input type='text' name='dbbanaddcid'></td></tr>"
output += "<tr><td width='50%' align='right'><b>Duration:</b> <input type='text' name='dbbaddduration'></td>"
output += "<td width='50%' align='right'><b>Job:</b><select name='dbbanaddjob'>"
output += "<option value=''>--</option>"
for(var/j in get_all_jobs())
output += "<option value='[j]'>[j]</option>"
for(var/j in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
output += "<option value='[j]'>[j]</option>"
var/list/bantypes = list("traitor","changeling","operative","revolutionary","cultist","wizard") //For legacy bans.
for(var/antag_type in all_antag_types) // Grab other bans.
var/datum/antagonist/antag = all_antag_types[antag_type]
bantypes |= antag.bantype
for(var/j in bantypes)
output += "<option value='[j]'>[j]</option>"
output += "</select></td></tr></table>"
output += "<b>Reason:<br></b><textarea name='dbbanreason' cols='50'></textarea><br>"
output += "<input type='submit' value='Add ban'>"
output += "</form>"
output += "</td>"
output += "</tr>"
output += "</table>"
output += "<form method='GET' action='?src=\ref[src]'>[HrefTokenFormField()]"
output += "<table width='60%'><tr><td colspan='2' align='left'><b>Search:</b>"
output += "<input type='hidden' name='src' value='\ref[src]'></td></tr>"
output += "<tr><td width='50%' align='right'><b>Ckey:</b> <input type='text' name='dbsearchckey' value='[playerckey]'></td>"
output += "<td width='50%' align='right'><b>Admin ckey:</b> <input type='text' name='dbsearchadmin' value='[adminckey]'></td></tr>"
output += "<tr><td width='50%' align='right'><b>IP:</b> <input type='text' name='dbsearchip' value='[playerip]'></td>"
output += "<td width='50%' align='right'><b>CID:</b> <input type='text' name='dbsearchcid' value='[playercid]'></td></tr>"
output += "<tr><td width='50%' align='right' colspan='2'><b>Ban type:</b><select name='dbsearchbantype'>"
output += "<option value=''>--</option>"
output += "<option value='[BANTYPE_PERMA]'>PERMABAN</option>"
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "</select></td></tr></table>"
output += "<br><input type='submit' value='search'><br>"
output += "<input type='checkbox' value='[match]' name='dbmatch' [match? "checked=\"1\"" : null]> Match(min. 3 characters to search by key or ip, and 7 to search by cid)<br>"
output += "</form>"
output += "Please note that all jobban bans or unbans are in-effect the following round.<br>"
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
output += "<table width='90%' bgcolor='#e3e3e3' cellpadding='5' cellspacing='0' align='center'>"
output += "<tr>"
output += "<th width='25%'><b>TYPE</b></th>"
output += "<th width='20%'><b>CKEY</b></th>"
output += "<th width='20%'><b>TIME APPLIED</b></th>"
output += "<th width='20%'><b>ADMIN</b></th>"
output += "<th width='15%'><b>OPTIONS</b></th>"
output += "</tr>"
var/adminsearch = ""
var/playersearch = ""
var/ipsearch = ""
var/cidsearch = ""
var/bantypesearch = ""
if(!match)
if(adminckey)
adminsearch = "AND a_ckey = '[adminckey]' "
if(playerckey)
playersearch = "AND ckey = '[playerckey]' "
if(playerip)
ipsearch = "AND ip = '[playerip]' "
if(playercid)
cidsearch = "AND computerid = '[playercid]' "
else
if(adminckey && length(adminckey) >= 3)
adminsearch = "AND a_ckey LIKE '[adminckey]%' "
if(playerckey && length(playerckey) >= 3)
playersearch = "AND ckey LIKE '[playerckey]%' "
if(playerip && length(playerip) >= 3)
ipsearch = "AND ip LIKE '[playerip]%' "
if(playercid && length(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' "
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid FROM erro_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/edits = select_query.item[13]
var/ip = select_query.item[14]
var/cid = select_query.item[15]
// 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 = "<font color='red'><b>PERMABAN</b></font>"
if("TEMPBAN")
typedesc = "<b>TEMPBAN</b><br><font size='2'>([duration] minutes) [(unbanned || auto) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=duration;dbbanid=[banid]\">Edit</a>)"]<br>Expires [expiration]</font>"
if("JOB_PERMABAN")
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])</font>"
if("JOB_TEMPBAN")
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes<br>Expires [expiration]</font>"
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center'>[typedesc]</td>"
output += "<td align='center'><b>[ckey]</b></td>"
output += "<td align='center'>[bantime]</td>"
output += "<td align='center'><b>[ackey]</b></td>"
output += "<td align='center'>[(unbanned || auto) ? "" : "<b><a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=unban;dbbanid=[banid]\">Unban</a></b>"]</td>"
output += "</tr>"
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='2' bgcolor=''><b>IP:</b> [ip]</td>"
output += "<td align='center' colspan='3' bgcolor=''><b>CIP:</b> [cid]</td>"
output += "</tr>"
output += "<tr bgcolor='[lcolor]'>"
output += "<td align='center' colspan='5'><b>Reason: [(unbanned || auto) ? "" : "(<a href=\"byond://?src=\ref[src];[HrefToken()];dbbanedit=reason;dbbanid=[banid]\">Edit</a>)"]</b> <cite>\"[reason]\"</cite></td>"
output += "</tr>"
if(edits)
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='5'><b>EDITS</b></td>"
output += "</tr>"
output += "<tr bgcolor='[lcolor]'>"
output += "<td align='center' colspan='5'><font size='2'>[edits]</font></td>"
output += "</tr>"
if(unbanned)
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='5' bgcolor=''><b>UNBANNED by admin [unbanckey] on [unbantime]</b></td>"
output += "</tr>"
else if(auto)
output += "<tr bgcolor='[dcolor]'>"
output += "<td align='center' colspan='5' bgcolor=''><b>EXPIRED at [expiration]</b></td>"
output += "</tr>"
output += "<tr>"
output += "<td colspan='5' bgcolor='white'>&nbsp</td>"
output += "</tr>"
output += "</table></div>"
usr << browse(output,"window=lookupbans;size=900x700")
+229 -229
View File
@@ -1,229 +1,229 @@
var/CMinutes = null
var/savefile/Banlist
/proc/CheckBan(var/ckey, var/id, var/address)
if(!Banlist) // if Banlist cannot be located for some reason
LoadBans() // try to load the bans
if(!Banlist) // uh oh, can't find bans!
return 0 // ABORT ABORT ABORT
. = list()
var/appeal
if(config && config.banappeals)
appeal = "\nFor more information on your ban, or to appeal, head to <a href='[config.banappeals]'>[config.banappeals]</a>"
Banlist.cd = "/base"
if( "[ckey][id]" in Banlist.dir )
Banlist.cd = "[ckey][id]"
if (Banlist["temp"])
if (!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: [GetExp(Banlist["minutes"])]\nBy: [Banlist["bannedby"]][appeal]"
else
Banlist.cd = "/base/[ckey][id]"
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: <B>PERMANENT</B>\nBy: [Banlist["bannedby"]][appeal]"
.["reason"] = "ckey/id"
return .
else
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
var/matches
if( ckey == Banlist["key"] )
matches += "ckey"
if( id == Banlist["id"] )
if(matches)
matches += "/"
matches += "id"
if( address == Banlist["ip"] )
if(matches)
matches += "/"
matches += "ip"
if(matches)
if(Banlist["temp"])
if (!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: [GetExp(Banlist["minutes"])]\nBy: [Banlist["bannedby"]][appeal]"
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: <B>PERMANENT</B>\nBy: [Banlist["bannedby"]][appeal]"
.["reason"] = matches
return .
return 0
/proc/UpdateTime() //No idea why i made this a proc.
CMinutes = (world.realtime / 10) / 60
return 1
/hook/startup/proc/loadBans()
return LoadBans()
/proc/LoadBans()
Banlist = new("data/banlist.bdb")
log_admin("Loading Banlist")
if (!length(Banlist.dir)) log_admin("Banlist is empty.")
if (!Banlist.dir.Find("base"))
log_admin("Banlist missing base dir.")
Banlist.dir.Add("base")
Banlist.cd = "/base"
else if (Banlist.dir.Find("base"))
Banlist.cd = "/base"
ClearTempbans()
return 1
/proc/ClearTempbans()
UpdateTime()
Banlist.cd = "/base"
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (!Banlist["key"] || !Banlist["id"])
RemoveBan(A)
log_admin("Invalid Ban.")
message_admins("Invalid Ban.")
continue
if (!Banlist["temp"]) continue
if (CMinutes >= Banlist["minutes"]) RemoveBan(A)
return 1
/proc/AddBan(ckey, computerid, reason, bannedby, temp, minutes, address)
var/bantimestamp
if (temp)
UpdateTime()
bantimestamp = CMinutes + minutes
Banlist.cd = "/base"
if ( Banlist.dir.Find("[ckey][computerid]") )
to_chat(usr, "<span class='filter_adminlog warning'>Ban already exists.</span>")
return 0
else
Banlist.dir.Add("[ckey][computerid]")
Banlist.cd = "/base/[ckey][computerid]"
Banlist["key"] << ckey
Banlist["id"] << computerid
Banlist["ip"] << address
Banlist["reason"] << reason
Banlist["bannedby"] << bannedby
Banlist["temp"] << temp
if (temp)
Banlist["minutes"] << bantimestamp
admin_action_message(bannedby, ckey, "banned", reason, temp ? minutes : -1) //VOREStation Add
return 1
/proc/RemoveBan(foldername)
var/key
var/id
Banlist.cd = "/base/[foldername]"
Banlist["key"] >> key
Banlist["id"] >> id
Banlist.cd = "/base"
if (!Banlist.dir.Remove(foldername)) return 0
if(!usr)
log_admin("Ban Expired: [key]")
message_admins("Ban Expired: [key]")
else
ban_unban_log_save("[key_name_admin(usr)] unbanned [key]")
log_admin("[key_name_admin(usr)] unbanned [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)
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (key == Banlist["key"] /*|| id == Banlist["id"]*/)
Banlist.cd = "/base"
Banlist.dir.Remove(A)
continue
admin_action_message(usr.key, key, "unbanned", "\[Unban\]", 0) //VOREStation Add
return 1
/proc/GetExp(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/unbanpanel()
var/count = 0
var/dat
//var/dat = "<HR><B>Unban Player:</B> <font color='blue'>(U) = Unban</font> , (E) = Edit Ban <font color='green'>(Total<HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 ></font>"
Banlist.cd = "/base"
for (var/A in Banlist.dir)
count++
Banlist.cd = "/base/[A]"
var/ref = "\ref[src]"
var/key = Banlist["key"]
var/id = Banlist["id"]
var/ip = Banlist["ip"]
var/reason = Banlist["reason"]
var/by = Banlist["bannedby"]
var/expiry
if(Banlist["temp"])
expiry = GetExp(Banlist["minutes"])
if(!expiry) expiry = "Removal Pending"
else expiry = "Permaban"
dat += text("<tr><td><A href='?src=[ref];[HrefToken()];unbanf=[key][id]'>(U)</A><A href='?src=[ref];[HrefToken()];unbane=[key][id]'>(E)</A> Key: <B>[key]</B></td><td>ComputerID: <B>[id]</B></td><td>IP: <B>[ip]</B></td><td> [expiry]</td><td>(By: [by])</td><td>(Reason: [reason])</td></tr>")
dat += "</table>"
dat = "<HR><B>Bans:</B> <FONT COLOR=blue>(U) = Unban , (E) = Edit Ban</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")
//////////////////////////////////// DEBUG ////////////////////////////////////
/proc/CreateBans()
UpdateTime()
var/i
var/last
for(i=0, i<1001, i++)
var/a = pick(1,0)
var/b = pick(1,0)
if(b)
Banlist.cd = "/base"
Banlist.dir.Add("trash[i]trashid[i]")
Banlist.cd = "/base/trash[i]trashid[i]"
to_chat(Banlist["key"], "trash[i]")
else
Banlist.cd = "/base"
Banlist.dir.Add("[last]trashid[i]")
Banlist.cd = "/base/[last]trashid[i]"
Banlist["key"] << last
to_chat(Banlist["id"], "trashid[i]")
to_chat(Banlist["reason"], "Trashban[i].")
Banlist["temp"] << a
Banlist["minutes"] << CMinutes + rand(1,2000)
to_chat(Banlist["bannedby"], "trashmin")
last = "trash[i]"
Banlist.cd = "/base"
/proc/ClearAllBans()
Banlist.cd = "/base"
for (var/A in Banlist.dir)
RemoveBan(A)
var/CMinutes = null
var/savefile/Banlist
/proc/CheckBan(var/ckey, var/id, var/address)
if(!Banlist) // if Banlist cannot be located for some reason
LoadBans() // try to load the bans
if(!Banlist) // uh oh, can't find bans!
return 0 // ABORT ABORT ABORT
. = list()
var/appeal
if(config && config.banappeals)
appeal = "\nFor more information on your ban, or to appeal, head to <a href='[config.banappeals]'>[config.banappeals]</a>"
Banlist.cd = "/base"
if( "[ckey][id]" in Banlist.dir )
Banlist.cd = "[ckey][id]"
if (Banlist["temp"])
if (!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: [GetExp(Banlist["minutes"])]\nBy: [Banlist["bannedby"]][appeal]"
else
Banlist.cd = "/base/[ckey][id]"
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: <B>PERMANENT</B>\nBy: [Banlist["bannedby"]][appeal]"
.["reason"] = "ckey/id"
return .
else
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
var/matches
if( ckey == Banlist["key"] )
matches += "ckey"
if( id == Banlist["id"] )
if(matches)
matches += "/"
matches += "id"
if( address == Banlist["ip"] )
if(matches)
matches += "/"
matches += "ip"
if(matches)
if(Banlist["temp"])
if (!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: [GetExp(Banlist["minutes"])]\nBy: [Banlist["bannedby"]][appeal]"
else
.["desc"] = "\nReason: [Banlist["reason"]]\nExpires: <B>PERMANENT</B>\nBy: [Banlist["bannedby"]][appeal]"
.["reason"] = matches
return .
return 0
/proc/UpdateTime() //No idea why i made this a proc.
CMinutes = (world.realtime / 10) / 60
return 1
/hook/startup/proc/loadBans()
return LoadBans()
/proc/LoadBans()
Banlist = new("data/banlist.bdb")
log_admin("Loading Banlist")
if (!length(Banlist.dir)) log_admin("Banlist is empty.")
if (!Banlist.dir.Find("base"))
log_admin("Banlist missing base dir.")
Banlist.dir.Add("base")
Banlist.cd = "/base"
else if (Banlist.dir.Find("base"))
Banlist.cd = "/base"
ClearTempbans()
return 1
/proc/ClearTempbans()
UpdateTime()
Banlist.cd = "/base"
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (!Banlist["key"] || !Banlist["id"])
RemoveBan(A)
log_admin("Invalid Ban.")
message_admins("Invalid Ban.")
continue
if (!Banlist["temp"]) continue
if (CMinutes >= Banlist["minutes"]) RemoveBan(A)
return 1
/proc/AddBan(ckey, computerid, reason, bannedby, temp, minutes, address)
var/bantimestamp
if (temp)
UpdateTime()
bantimestamp = CMinutes + minutes
Banlist.cd = "/base"
if ( Banlist.dir.Find("[ckey][computerid]") )
to_chat(usr, "<span class='filter_adminlog warning'>Ban already exists.</span>")
return 0
else
Banlist.dir.Add("[ckey][computerid]")
Banlist.cd = "/base/[ckey][computerid]"
Banlist["key"] << ckey
Banlist["id"] << computerid
Banlist["ip"] << address
Banlist["reason"] << reason
Banlist["bannedby"] << bannedby
Banlist["temp"] << temp
if (temp)
Banlist["minutes"] << bantimestamp
admin_action_message(bannedby, ckey, "banned", reason, temp ? minutes : -1) //VOREStation Add
return 1
/proc/RemoveBan(foldername)
var/key
var/id
Banlist.cd = "/base/[foldername]"
Banlist["key"] >> key
Banlist["id"] >> id
Banlist.cd = "/base"
if (!Banlist.dir.Remove(foldername)) return 0
if(!usr)
log_admin("Ban Expired: [key]")
message_admins("Ban Expired: [key]")
else
ban_unban_log_save("[key_name_admin(usr)] unbanned [key]")
log_admin("[key_name_admin(usr)] unbanned [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)
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (key == Banlist["key"] /*|| id == Banlist["id"]*/)
Banlist.cd = "/base"
Banlist.dir.Remove(A)
continue
admin_action_message(usr.key, key, "unbanned", "\[Unban\]", 0) //VOREStation Add
return 1
/proc/GetExp(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/unbanpanel()
var/count = 0
var/dat
//var/dat = "<HR><B>Unban Player:</B> <font color='blue'>(U) = Unban</font> , (E) = Edit Ban <font color='green'>(Total<HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 ></font>"
Banlist.cd = "/base"
for (var/A in Banlist.dir)
count++
Banlist.cd = "/base/[A]"
var/ref = "\ref[src]"
var/key = Banlist["key"]
var/id = Banlist["id"]
var/ip = Banlist["ip"]
var/reason = Banlist["reason"]
var/by = Banlist["bannedby"]
var/expiry
if(Banlist["temp"])
expiry = GetExp(Banlist["minutes"])
if(!expiry) expiry = "Removal Pending"
else expiry = "Permaban"
dat += text("<tr><td><A href='?src=[ref];[HrefToken()];unbanf=[key][id]'>(U)</A><A href='?src=[ref];[HrefToken()];unbane=[key][id]'>(E)</A> Key: <B>[key]</B></td><td>ComputerID: <B>[id]</B></td><td>IP: <B>[ip]</B></td><td> [expiry]</td><td>(By: [by])</td><td>(Reason: [reason])</td></tr>")
dat += "</table>"
dat = "<HR><B>Bans:</B> <FONT COLOR=blue>(U) = Unban , (E) = Edit Ban</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")
//////////////////////////////////// DEBUG ////////////////////////////////////
/proc/CreateBans()
UpdateTime()
var/i
var/last
for(i=0, i<1001, i++)
var/a = pick(1,0)
var/b = pick(1,0)
if(b)
Banlist.cd = "/base"
Banlist.dir.Add("trash[i]trashid[i]")
Banlist.cd = "/base/trash[i]trashid[i]"
to_chat(Banlist["key"], "trash[i]")
else
Banlist.cd = "/base"
Banlist.dir.Add("[last]trashid[i]")
Banlist.cd = "/base/[last]trashid[i]"
Banlist["key"] << last
to_chat(Banlist["id"], "trashid[i]")
to_chat(Banlist["reason"], "Trashban[i].")
Banlist["temp"] << a
Banlist["minutes"] << CMinutes + rand(1,2000)
to_chat(Banlist["bannedby"], "trashmin")
last = "trash[i]"
Banlist.cd = "/base"
/proc/ClearAllBans()
Banlist.cd = "/base"
for (var/A in Banlist.dir)
RemoveBan(A)
+89 -89
View File
@@ -1,89 +1,89 @@
//By Carnwennan
//fetches an external list and processes it into a list of ip addresses.
//It then stores the processed list into a savefile for later use
#define TORFILE "data/ToR_ban.bdb"
#define TOR_UPDATE_INTERVAL 216000 //~6 hours
/proc/ToRban_isbanned(var/ip_address)
var/savefile/F = new(TORFILE)
if(F)
if( ip_address in F.dir )
return 1
return 0
/proc/ToRban_autoupdate()
var/savefile/F = new(TORFILE)
if(F)
var/last_update
F["last_update"] >> last_update
if((last_update + TOR_UPDATE_INTERVAL) < world.realtime) //we haven't updated for a while
ToRban_update()
return
/proc/ToRban_update()
spawn(0)
log_misc("Downloading updated ToR data...")
var/http[] = world.Export("https://check.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
fdel(TORFILE)
var/savefile/F = new(TORFILE)
for( var/line in rawlist )
if(!line) continue
if( copytext(line,1,12) == "ExitAddress" )
var/cleaned = copytext(line,13,length(line)-19)
if(!cleaned) continue
F[cleaned] << 1
F["last_update"] << world.realtime
log_misc("ToR data updated!")
if(usr)
to_chat(usr, "<span class='filter_adminlog'>ToRban updated.</span>")
return
log_misc("ToR data update aborted: no data.")
return
/client/proc/ToRban(task in list("update","toggle","show","remove","remove all","find"))
set name = "ToRban"
set category = "Server"
if(!holder) return
switch(task)
if("update")
ToRban_update()
if("toggle")
if(config)
if(config.ToRban)
config.ToRban = 0
message_admins(span_red("ToR banning disabled."))
else
config.ToRban = 1
message_admins(span_green("ToR banning enabled."))
if("show")
var/savefile/F = new(TORFILE)
var/dat
if( length(F.dir) )
for( var/i=1, i<=length(F.dir), i++ )
dat += "<tr><td>#[i]</td><td> [F.dir[i]]</td></tr>"
dat = "<table width='100%'>[dat]</table>"
else
dat = "No addresses in list."
src << browse(dat,"window=ToRban_show")
if("remove")
var/savefile/F = new(TORFILE)
var/choice = tgui_input_list(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban", F.dir)
if(choice)
F.dir.Remove(choice)
to_chat(src, "<span class='filter_adminlog'><b>Address removed</b></span>")
if("remove all")
to_chat(src, "<span class='filter_adminlog'><b>[TORFILE] was [fdel(TORFILE)?"":"not "]removed.</b></span>")
if("find")
var/input = tgui_input_text(src,"Please input an IP address to search for:","Find ToR ban",null)
if(input)
if(ToRban_isbanned(input))
to_chat(src, "<span class='filter_adminlog'>[span_orange("<b>Address is a known ToR address</b>")]</span>")
else
to_chat(src, "<span class='filter_adminlog danger'>Address is not a known ToR address</span>")
return
#undef TORFILE
#undef TOR_UPDATE_INTERVAL
//By Carnwennan
//fetches an external list and processes it into a list of ip addresses.
//It then stores the processed list into a savefile for later use
#define TORFILE "data/ToR_ban.bdb"
#define TOR_UPDATE_INTERVAL 216000 //~6 hours
/proc/ToRban_isbanned(var/ip_address)
var/savefile/F = new(TORFILE)
if(F)
if( ip_address in F.dir )
return 1
return 0
/proc/ToRban_autoupdate()
var/savefile/F = new(TORFILE)
if(F)
var/last_update
F["last_update"] >> last_update
if((last_update + TOR_UPDATE_INTERVAL) < world.realtime) //we haven't updated for a while
ToRban_update()
return
/proc/ToRban_update()
spawn(0)
log_misc("Downloading updated ToR data...")
var/http[] = world.Export("https://check.torproject.org/exit-addresses")
var/list/rawlist = file2list(http["CONTENT"])
if(rawlist.len)
fdel(TORFILE)
var/savefile/F = new(TORFILE)
for( var/line in rawlist )
if(!line) continue
if( copytext(line,1,12) == "ExitAddress" )
var/cleaned = copytext(line,13,length(line)-19)
if(!cleaned) continue
F[cleaned] << 1
F["last_update"] << world.realtime
log_misc("ToR data updated!")
if(usr)
to_chat(usr, "<span class='filter_adminlog'>ToRban updated.</span>")
return
log_misc("ToR data update aborted: no data.")
return
/client/proc/ToRban(task in list("update","toggle","show","remove","remove all","find"))
set name = "ToRban"
set category = "Server"
if(!holder) return
switch(task)
if("update")
ToRban_update()
if("toggle")
if(config)
if(config.ToRban)
config.ToRban = 0
message_admins(span_red("ToR banning disabled."))
else
config.ToRban = 1
message_admins(span_green("ToR banning enabled."))
if("show")
var/savefile/F = new(TORFILE)
var/dat
if( length(F.dir) )
for( var/i=1, i<=length(F.dir), i++ )
dat += "<tr><td>#[i]</td><td> [F.dir[i]]</td></tr>"
dat = "<table width='100%'>[dat]</table>"
else
dat = "No addresses in list."
src << browse(dat,"window=ToRban_show")
if("remove")
var/savefile/F = new(TORFILE)
var/choice = tgui_input_list(src,"Please select an IP address to remove from the ToR banlist:","Remove ToR ban", F.dir)
if(choice)
F.dir.Remove(choice)
to_chat(src, "<span class='filter_adminlog'><b>Address removed</b></span>")
if("remove all")
to_chat(src, "<span class='filter_adminlog'><b>[TORFILE] was [fdel(TORFILE)?"":"not "]removed.</b></span>")
if("find")
var/input = tgui_input_text(src,"Please input an IP address to search for:","Find ToR ban",null)
if(input)
if(ToRban_isbanned(input))
to_chat(src, "<span class='filter_adminlog'>[span_orange("<b>Address is a known ToR address</b>")]</span>")
else
to_chat(src, "<span class='filter_adminlog danger'>Address is not a known ToR address</span>")
return
#undef TORFILE
#undef TOR_UPDATE_INTERVAL
+174 -174
View File
@@ -1,174 +1,174 @@
var/list/admin_ranks = list() //list of all ranks with associated rights
//load our rank - > rights associations
/proc/load_admin_ranks()
admin_ranks.Cut()
var/previous_rights = 0
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
//load text from file
var/list/Lines = file2list("config/admin_ranks.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
var/list/List = splittext(line,"+")
if(!List.len) continue
var/rank = ckeyEx(List[1])
switch(rank)
if(null,"") continue
if("Removed") continue //Reserved
var/rights = 0
for(var/i=2, i<=List.len, i++)
switch(ckey(List[i]))
if("@","prev") rights |= previous_rights
if("buildmode","build") rights |= R_BUILDMODE
if("admin") rights |= R_ADMIN
if("ban") rights |= R_BAN
if("fun") rights |= R_FUN
if("server") rights |= R_SERVER
if("debug") rights |= R_DEBUG
if("permissions","rights") rights |= R_PERMISSIONS
if("possess") rights |= R_POSSESS
if("stealth") rights |= R_STEALTH
if("rejuv","rejuvinate") rights |= R_REJUVINATE
if("varedit") rights |= R_VAREDIT
if("everything","host","all") rights |= (R_HOST | R_BUILDMODE | R_ADMIN | R_BAN | R_FUN | R_SERVER | R_DEBUG | R_PERMISSIONS | R_POSSESS | R_STEALTH | R_REJUVINATE | R_VAREDIT | R_SOUNDS | R_SPAWN | R_MOD| R_EVENT)
if("sound","sounds") rights |= R_SOUNDS
if("spawn","create") rights |= R_SPAWN
if("mod") rights |= R_MOD
if("event") rights |= R_EVENT
admin_ranks[rank] = rights
previous_rights = rights
#ifdef TESTING
var/msg = "Permission Sets Built:\n"
for(var/rank in admin_ranks)
msg += "\t[rank] - [admin_ranks[rank]]\n"
testing(msg)
#endif
/hook/startup/proc/loadAdmins()
load_admins()
return 1
/proc/load_admins()
//clear the datums references
admin_datums.Cut()
for(var/client/C in GLOB.admins)
C.remove_admin_verbs()
C.holder = null
GLOB.admins.Cut()
if(config.admin_legacy_system)
load_admin_ranks()
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
//load text from file
var/list/Lines = file2list("config/admins.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
//Split the line at every "-"
var/list/List = splittext(line, "-")
if(!List.len) continue
//ckey is before the first "-"
var/ckey = ckey(List[1])
if(!ckey) continue
//rank follows the first "-"
var/rank = ""
if(List.len >= 2)
rank = ckeyEx(List[2])
//load permissions associated with this rank
var/rights = admin_ranks[rank]
//create the admin datum and store it for later use
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
if(D.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
else
//The current admin system uses SQL
establish_db_connection()
if(!dbcon.IsConnected())
error("Failed to connect to database in load_admins(). Reverting to legacy system.")
log_misc("Failed to connect to database in load_admins(). Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
var/rank = query.item[2]
if(rank == "Removed") continue //This person was de-adminned. They are only in the admin list for archive purposes.
var/rights = query.item[4]
if(istext(rights)) rights = text2num(rights)
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
if(D.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
if(!admin_datums)
error("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
log_misc("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in admin_datums)
var/rank
var/datum/admins/D = admin_datums[ckey]
if(D) rank = D.rank
msg += "\t[ckey] - [rank]\n"
testing(msg)
#endif
#ifdef TESTING
/client/verb/changerank(newrank in admin_ranks)
if(holder)
holder.rank = newrank
holder.rights = admin_ranks[newrank]
else
holder = new /datum/admins(newrank,admin_ranks[newrank],ckey)
remove_admin_verbs()
holder.associate(src)
/client/verb/changerights(newrights as num)
if(holder)
holder.rights = newrights
else
holder = new /datum/admins("testing",newrights,ckey)
remove_admin_verbs()
holder.associate(src)
#endif
var/list/admin_ranks = list() //list of all ranks with associated rights
//load our rank - > rights associations
/proc/load_admin_ranks()
admin_ranks.Cut()
var/previous_rights = 0
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
//load text from file
var/list/Lines = file2list("config/admin_ranks.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
var/list/List = splittext(line,"+")
if(!List.len) continue
var/rank = ckeyEx(List[1])
switch(rank)
if(null,"") continue
if("Removed") continue //Reserved
var/rights = 0
for(var/i=2, i<=List.len, i++)
switch(ckey(List[i]))
if("@","prev") rights |= previous_rights
if("buildmode","build") rights |= R_BUILDMODE
if("admin") rights |= R_ADMIN
if("ban") rights |= R_BAN
if("fun") rights |= R_FUN
if("server") rights |= R_SERVER
if("debug") rights |= R_DEBUG
if("permissions","rights") rights |= R_PERMISSIONS
if("possess") rights |= R_POSSESS
if("stealth") rights |= R_STEALTH
if("rejuv","rejuvinate") rights |= R_REJUVINATE
if("varedit") rights |= R_VAREDIT
if("everything","host","all") rights |= (R_HOST | R_BUILDMODE | R_ADMIN | R_BAN | R_FUN | R_SERVER | R_DEBUG | R_PERMISSIONS | R_POSSESS | R_STEALTH | R_REJUVINATE | R_VAREDIT | R_SOUNDS | R_SPAWN | R_MOD| R_EVENT)
if("sound","sounds") rights |= R_SOUNDS
if("spawn","create") rights |= R_SPAWN
if("mod") rights |= R_MOD
if("event") rights |= R_EVENT
admin_ranks[rank] = rights
previous_rights = rights
#ifdef TESTING
var/msg = "Permission Sets Built:\n"
for(var/rank in admin_ranks)
msg += "\t[rank] - [admin_ranks[rank]]\n"
testing(msg)
#endif
/hook/startup/proc/loadAdmins()
load_admins()
return 1
/proc/load_admins()
//clear the datums references
admin_datums.Cut()
for(var/client/C in GLOB.admins)
C.remove_admin_verbs()
C.holder = null
GLOB.admins.Cut()
if(config.admin_legacy_system)
load_admin_ranks()
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
//load text from file
var/list/Lines = file2list("config/admins.txt")
//process each line seperately
for(var/line in Lines)
if(!length(line)) continue
if(copytext(line,1,2) == "#") continue
//Split the line at every "-"
var/list/List = splittext(line, "-")
if(!List.len) continue
//ckey is before the first "-"
var/ckey = ckey(List[1])
if(!ckey) continue
//rank follows the first "-"
var/rank = ""
if(List.len >= 2)
rank = ckeyEx(List[2])
//load permissions associated with this rank
var/rights = admin_ranks[rank]
//create the admin datum and store it for later use
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
if(D.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
else
//The current admin system uses SQL
establish_db_connection()
if(!dbcon.IsConnected())
error("Failed to connect to database in load_admins(). Reverting to legacy system.")
log_misc("Failed to connect to database in load_admins(). Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, rank, level, flags FROM erro_admin")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
var/rank = query.item[2]
if(rank == "Removed") continue //This person was de-adminned. They are only in the admin list for archive purposes.
var/rights = query.item[4]
if(istext(rights)) rights = text2num(rights)
var/datum/admins/D = new /datum/admins(rank, rights, ckey)
if(D.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
//find the client for a ckey if they are connected and associate them with the new admin datum
D.associate(GLOB.directory[ckey])
if(!admin_datums)
error("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
log_misc("The database query in load_admins() resulted in no admins being added to the list. Reverting to legacy system.")
config.admin_legacy_system = 1
load_admins()
return
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in admin_datums)
var/rank
var/datum/admins/D = admin_datums[ckey]
if(D) rank = D.rank
msg += "\t[ckey] - [rank]\n"
testing(msg)
#endif
#ifdef TESTING
/client/verb/changerank(newrank in admin_ranks)
if(holder)
holder.rank = newrank
holder.rights = admin_ranks[newrank]
else
holder = new /datum/admins(newrank,admin_ranks[newrank],ckey)
remove_admin_verbs()
holder.associate(src)
/client/verb/changerights(newrights as num)
if(holder)
holder.rights = newrights
else
holder = new /datum/admins("testing",newrights,ckey)
remove_admin_verbs()
holder.associate(src)
#endif
+182 -182
View File
@@ -1,182 +1,182 @@
// Reports are a way to notify admins of wrongdoings that happened
// while no admin was present. They work a bit similar to news, but
// they can only be read by admins and moderators.
// a single admin report
/datum//admin_report/var
ID // the ID of the report
body // the content of the report
author // key of the author
date // date on which this was created
done // whether this was handled
offender_key // store the key of the offender
offender_cid // store the cid of the offender
/datum//report_topic_handler
Topic(href,href_list)
..()
var/client/C = locate(href_list["client"])
if(href_list["action"] == "show_reports")
C.display_admin_reports()
else if(href_list["action"] == "remove")
C.mark_report_done(text2num(href_list["ID"]))
else if(href_list["action"] == "edit")
C.edit_report(text2num(href_list["ID"]))
var/datum/report_topic_handler/report_topic_handler
world/New()
..()
report_topic_handler = new
// add a new news datums
/proc/make_report(body, author, okey, cid)
var/savefile/Reports = new("data/reports.sav")
var/list/reports
var/lastID
Reports["reports"] >> reports
Reports["lastID"] >> lastID
if(!reports) reports = list()
if(!lastID) lastID = 0
var/datum/admin_report/created = new()
created.ID = ++lastID
created.body = body
created.author = author
created.date = world.realtime
created.done = 0
created.offender_key = okey
created.offender_cid = cid
reports.Insert(1, created)
Reports["reports"] << reports
Reports["lastID"] << lastID
// load the reports from disk
/proc/load_reports()
var/savefile/Reports = new("data/reports.sav")
var/list/reports
Reports["reports"] >> reports
if(!reports) reports = list()
return reports
// check if there are any unhandled reports
/client/proc/unhandled_reports()
if(!src.holder) return 0
var/list/reports = load_reports()
for(var/datum/admin_report/N in reports)
if(N.done)
continue
else return 1
return 0
// checks if the player has an unhandled report against him
/client/proc/is_reported()
var/list/reports = load_reports()
for(var/datum/admin_report/N in reports) if(!N.done)
if(N.offender_key == src.key)
return 1
return 0
// display only the reports that haven't been handled
/client/proc/display_admin_reports()
set category = "Admin"
set name = "Display Admin Reports"
if(!src.holder) return
var/list/reports = load_reports()
var/output = ""
if(unhandled_reports())
// load the list of unhandled reports
for(var/datum/admin_report/N in reports)
if(N.done)
continue
output += "<b>Reported player:</b> [N.offender_key](CID: [N.offender_cid])<br>"
output += "<b>Offense:</b>[N.body]<br>"
output += "<small>Occurred at [time2text(N.date,"MM/DD hh:mm:ss")]</small><br>"
output += "<small>authored by <i>[N.author]</i></small><br>"
output += " <a href='?src=\ref[report_topic_handler];client=\ref[src];[HrefToken()];action=remove;ID=[N.ID]'>Flag as Handled</a>"
if(src.key == N.author)
output += " <a href='?src=\ref[report_topic_handler];client=\ref[src];[HrefToken()];action=edit;ID=[N.ID]'>Edit</a>"
output += "<br>"
output += "<br>"
else
output += "Whoops, no reports!"
usr << browse(output, "window=news;size=600x400")
/client/proc/Report(mob/M as mob in world)
set category = "Admin"
if(!src.holder)
return
var/CID = "Unknown"
if(M.client)
CID = M.client.computer_id
var/body = tgui_input_text(src.mob, "Describe in detail what you're reporting [M] for", "Report")
if(!body) return
make_report(body, key, M.key, CID)
spawn(1)
display_admin_reports()
/client/proc/mark_report_done(ID as num)
if(!src.holder || src.holder.level < 0)
return
var/savefile/Reports = new("data/reports.sav")
var/list/reports
Reports["reports"] >> reports
var/datum/admin_report/found
for(var/datum/admin_report/N in reports)
if(N.ID == ID)
found = N
if(!found)
to_chat(src, "<b>* An error occurred, sorry.</b>")
found.done = 1
Reports["reports"] << reports
/client/proc/edit_report(ID as num)
if(!src.holder || src.holder.level < 0)
to_chat(src, "<b>You tried to modify the news, but you're not an admin!</b>")
return
var/savefile/Reports = new("data/reports.sav")
var/list/reports
Reports["reports"] >> reports
var/datum/admin_report/found
for(var/datum/admin_report/N in reports)
if(N.ID == ID)
found = N
if(!found)
to_chat(src, "<b>* An error occurred, sorry.</b>")
var/body = tgui_input_text(src.mob, "Enter a body for the news", "Body", multiline = TRUE, prevent_enter = TRUE)
if(!body) return
found.body = body
Reports["reports"] << reports
// Reports are a way to notify admins of wrongdoings that happened
// while no admin was present. They work a bit similar to news, but
// they can only be read by admins and moderators.
// a single admin report
/datum//admin_report/var
ID // the ID of the report
body // the content of the report
author // key of the author
date // date on which this was created
done // whether this was handled
offender_key // store the key of the offender
offender_cid // store the cid of the offender
/datum//report_topic_handler
Topic(href,href_list)
..()
var/client/C = locate(href_list["client"])
if(href_list["action"] == "show_reports")
C.display_admin_reports()
else if(href_list["action"] == "remove")
C.mark_report_done(text2num(href_list["ID"]))
else if(href_list["action"] == "edit")
C.edit_report(text2num(href_list["ID"]))
var/datum/report_topic_handler/report_topic_handler
world/New()
..()
report_topic_handler = new
// add a new news datums
/proc/make_report(body, author, okey, cid)
var/savefile/Reports = new("data/reports.sav")
var/list/reports
var/lastID
Reports["reports"] >> reports
Reports["lastID"] >> lastID
if(!reports) reports = list()
if(!lastID) lastID = 0
var/datum/admin_report/created = new()
created.ID = ++lastID
created.body = body
created.author = author
created.date = world.realtime
created.done = 0
created.offender_key = okey
created.offender_cid = cid
reports.Insert(1, created)
Reports["reports"] << reports
Reports["lastID"] << lastID
// load the reports from disk
/proc/load_reports()
var/savefile/Reports = new("data/reports.sav")
var/list/reports
Reports["reports"] >> reports
if(!reports) reports = list()
return reports
// check if there are any unhandled reports
/client/proc/unhandled_reports()
if(!src.holder) return 0
var/list/reports = load_reports()
for(var/datum/admin_report/N in reports)
if(N.done)
continue
else return 1
return 0
// checks if the player has an unhandled report against him
/client/proc/is_reported()
var/list/reports = load_reports()
for(var/datum/admin_report/N in reports) if(!N.done)
if(N.offender_key == src.key)
return 1
return 0
// display only the reports that haven't been handled
/client/proc/display_admin_reports()
set category = "Admin"
set name = "Display Admin Reports"
if(!src.holder) return
var/list/reports = load_reports()
var/output = ""
if(unhandled_reports())
// load the list of unhandled reports
for(var/datum/admin_report/N in reports)
if(N.done)
continue
output += "<b>Reported player:</b> [N.offender_key](CID: [N.offender_cid])<br>"
output += "<b>Offense:</b>[N.body]<br>"
output += "<small>Occurred at [time2text(N.date,"MM/DD hh:mm:ss")]</small><br>"
output += "<small>authored by <i>[N.author]</i></small><br>"
output += " <a href='?src=\ref[report_topic_handler];client=\ref[src];[HrefToken()];action=remove;ID=[N.ID]'>Flag as Handled</a>"
if(src.key == N.author)
output += " <a href='?src=\ref[report_topic_handler];client=\ref[src];[HrefToken()];action=edit;ID=[N.ID]'>Edit</a>"
output += "<br>"
output += "<br>"
else
output += "Whoops, no reports!"
usr << browse(output, "window=news;size=600x400")
/client/proc/Report(mob/M as mob in world)
set category = "Admin"
if(!src.holder)
return
var/CID = "Unknown"
if(M.client)
CID = M.client.computer_id
var/body = tgui_input_text(src.mob, "Describe in detail what you're reporting [M] for", "Report")
if(!body) return
make_report(body, key, M.key, CID)
spawn(1)
display_admin_reports()
/client/proc/mark_report_done(ID as num)
if(!src.holder || src.holder.level < 0)
return
var/savefile/Reports = new("data/reports.sav")
var/list/reports
Reports["reports"] >> reports
var/datum/admin_report/found
for(var/datum/admin_report/N in reports)
if(N.ID == ID)
found = N
if(!found)
to_chat(src, "<b>* An error occurred, sorry.</b>")
found.done = 1
Reports["reports"] << reports
/client/proc/edit_report(ID as num)
if(!src.holder || src.holder.level < 0)
to_chat(src, "<b>You tried to modify the news, but you're not an admin!</b>")
return
var/savefile/Reports = new("data/reports.sav")
var/list/reports
Reports["reports"] >> reports
var/datum/admin_report/found
for(var/datum/admin_report/N in reports)
if(N.ID == ID)
found = N
if(!found)
to_chat(src, "<b>* An error occurred, sorry.</b>")
var/body = tgui_input_text(src.mob, "Enter a body for the news", "Body", multiline = TRUE, prevent_enter = TRUE)
if(!body) return
found.body = body
Reports["reports"] << reports
+113 -113
View File
@@ -1,113 +1,113 @@
var/datum/admin_secrets/admin_secrets = new()
/datum/admin_secrets
var/list/datum/admin_secret_category/categories
var/list/datum/admin_secret_item/items
/datum/admin_secrets/New()
..()
categories = init_subtypes(/datum/admin_secret_category)
items = list()
var/list/category_assoc = list()
for(var/datum/admin_secret_category/category in categories)
category_assoc[category.type] = category
for(var/item_type in subtypesof(/datum/admin_secret_item))
var/datum/admin_secret_item/secret_item = item_type
if(!initial(secret_item.name))
continue
var/datum/admin_secret_item/item = new item_type()
var/datum/admin_secret_category/category = category_assoc[item.category]
dd_insertObjectList(category.items, item)
items += item
//
// Secret Item Category - Each subtype is a category for organizing secret commands.
//
/datum/admin_secret_category
var/name = ""
var/desc = ""
var/list/datum/admin_secret_item/items = list()
/datum/admin_secret_category/proc/can_view(var/mob/user)
for(var/datum/admin_secret_item/item in items)
if(item.can_view(user))
return 1
return 0
//
// Secret Item Datum - Each subtype is a command on the secrets panel.
// Override execute() with the implementation of the command.
//
/datum/admin_secret_item
var/name = ""
var/category = null
var/log = 1
var/feedback = 1
var/permissions = R_HOST
var/warn_before_use = 0
/datum/admin_secret_item/dd_SortValue()
return "[name]"
/datum/admin_secret_item/proc/name()
return name
/datum/admin_secret_item/proc/can_view(var/mob/user)
return check_rights(permissions, 0, user)
/datum/admin_secret_item/proc/can_execute(var/mob/user)
if(can_view(user))
if(!warn_before_use || tgui_alert(usr, "Execute the command '[name]'?", name, list("No","Yes")) == "Yes")
return 1
return 0
/datum/admin_secret_item/proc/execute(var/mob/user)
if(!can_execute(user))
return 0
if(log)
log_and_message_admins("used secret '[name]'", user)
if(feedback)
feedback_inc("admin_secrets_used",1)
feedback_add_details("admin_secrets_used","[name]")
return 1
/*************************
* Pre-defined categories *
*************************/
/datum/admin_secret_category/admin_secrets
name = "Admin Secrets"
/datum/admin_secret_category/random_events
name = "'Random' Events"
/datum/admin_secret_category/fun_secrets
name = "Fun Secrets"
/datum/admin_secret_category/final_solutions
name = "Final Solutions"
desc = "(Warning, these will end the round!)"
/*************************
* Pre-defined base items *
*************************/
/datum/admin_secret_item/admin_secret
category = /datum/admin_secret_category/admin_secrets
log = 0
permissions = R_ADMIN //VOREStation Edit
/datum/admin_secret_item/random_event
category = /datum/admin_secret_category/random_events
permissions = R_FUN //VOREStation Edit
warn_before_use = 1
/datum/admin_secret_item/fun_secret
category = /datum/admin_secret_category/fun_secrets
permissions = R_FUN //VOREStation Edit
warn_before_use = 1
/datum/admin_secret_item/final_solution
category = /datum/admin_secret_category/final_solutions
permissions = R_FUN|R_SERVER|R_ADMIN //VOREStation Edit
var/datum/admin_secrets/admin_secrets = new()
/datum/admin_secrets
var/list/datum/admin_secret_category/categories
var/list/datum/admin_secret_item/items
/datum/admin_secrets/New()
..()
categories = init_subtypes(/datum/admin_secret_category)
items = list()
var/list/category_assoc = list()
for(var/datum/admin_secret_category/category in categories)
category_assoc[category.type] = category
for(var/item_type in subtypesof(/datum/admin_secret_item))
var/datum/admin_secret_item/secret_item = item_type
if(!initial(secret_item.name))
continue
var/datum/admin_secret_item/item = new item_type()
var/datum/admin_secret_category/category = category_assoc[item.category]
dd_insertObjectList(category.items, item)
items += item
//
// Secret Item Category - Each subtype is a category for organizing secret commands.
//
/datum/admin_secret_category
var/name = ""
var/desc = ""
var/list/datum/admin_secret_item/items = list()
/datum/admin_secret_category/proc/can_view(var/mob/user)
for(var/datum/admin_secret_item/item in items)
if(item.can_view(user))
return 1
return 0
//
// Secret Item Datum - Each subtype is a command on the secrets panel.
// Override execute() with the implementation of the command.
//
/datum/admin_secret_item
var/name = ""
var/category = null
var/log = 1
var/feedback = 1
var/permissions = R_HOST
var/warn_before_use = 0
/datum/admin_secret_item/dd_SortValue()
return "[name]"
/datum/admin_secret_item/proc/name()
return name
/datum/admin_secret_item/proc/can_view(var/mob/user)
return check_rights(permissions, 0, user)
/datum/admin_secret_item/proc/can_execute(var/mob/user)
if(can_view(user))
if(!warn_before_use || tgui_alert(usr, "Execute the command '[name]'?", name, list("No","Yes")) == "Yes")
return 1
return 0
/datum/admin_secret_item/proc/execute(var/mob/user)
if(!can_execute(user))
return 0
if(log)
log_and_message_admins("used secret '[name]'", user)
if(feedback)
feedback_inc("admin_secrets_used",1)
feedback_add_details("admin_secrets_used","[name]")
return 1
/*************************
* Pre-defined categories *
*************************/
/datum/admin_secret_category/admin_secrets
name = "Admin Secrets"
/datum/admin_secret_category/random_events
name = "'Random' Events"
/datum/admin_secret_category/fun_secrets
name = "Fun Secrets"
/datum/admin_secret_category/final_solutions
name = "Final Solutions"
desc = "(Warning, these will end the round!)"
/*************************
* Pre-defined base items *
*************************/
/datum/admin_secret_item/admin_secret
category = /datum/admin_secret_category/admin_secrets
log = 0
permissions = R_ADMIN //VOREStation Edit
/datum/admin_secret_item/random_event
category = /datum/admin_secret_category/random_events
permissions = R_FUN //VOREStation Edit
warn_before_use = 1
/datum/admin_secret_item/fun_secret
category = /datum/admin_secret_category/fun_secrets
permissions = R_FUN //VOREStation Edit
warn_before_use = 1
/datum/admin_secret_item/final_solution
category = /datum/admin_secret_category/final_solutions
permissions = R_FUN|R_SERVER|R_ADMIN //VOREStation Edit
File diff suppressed because it is too large Load Diff
+118 -118
View File
@@ -1,118 +1,118 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
var/jobban_runonce // Updates legacy bans with new info
var/jobban_keylist[0] //to store the keys & ranks
/proc/jobban_fullban(mob/M, rank, reason)
if (!M || !M.key) return
jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_savebanfile()
/proc/jobban_client_fullban(ckey, rank)
if (!ckey || !rank) return
jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_savebanfile()
//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
if(M && rank)
/*
if(_jobban_isbanned(M, rank)) return "Reason Unspecified" //for old jobban
*/
if (guest_jobbans(rank))
if(config.guest_jobban && IsGuestKey(M.key))
return "Guest Job-ban"
if(config.usewhitelist && !check_whitelist(M))
return "Whitelisted Job"
return ckey_is_jobbanned(M.ckey, rank)
return 0
/proc/ckey_is_jobbanned(var/check_key, var/rank)
for(var/s in jobban_keylist)
if(findtext(s,"[check_key] - [rank]") == 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
/*
DEBUG
/mob/verb/list_all_jobbans()
set name = "list all jobbans"
for(var/s in jobban_keylist)
to_world(s)
/mob/verb/reload_jobbans()
set name = "reload jobbans"
jobban_loadbanfile()
*/
/hook/startup/proc/loadJobBans()
jobban_loadbanfile()
return 1
/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
if (!length(jobban_keylist))
jobban_keylist=list()
log_admin("jobban_keylist was empty")
else
if(!establish_db_connection())
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
//Job permabans
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
var/job = query.item[2]
jobban_keylist.Add("[ckey] - [job]")
//Job tempbans
var/DBQuery/query1 = dbcon.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
query1.Execute()
while(query1.NextRow())
var/ckey = query1.item[1]
var/job = query1.item[2]
jobban_keylist.Add("[ckey] - [job]")
/proc/jobban_savebanfile()
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] << jobban_keylist
/proc/jobban_unban(mob/M, rank)
jobban_remove("[M.ckey] - [rank]")
jobban_savebanfile()
/proc/ban_unban_log_save(var/formatted_log)
text2file(formatted_log,"data/ban_unban_log.txt")
/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
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
var/jobban_runonce // Updates legacy bans with new info
var/jobban_keylist[0] //to store the keys & ranks
/proc/jobban_fullban(mob/M, rank, reason)
if (!M || !M.key) return
jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_savebanfile()
/proc/jobban_client_fullban(ckey, rank)
if (!ckey || !rank) return
jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_savebanfile()
//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
if(M && rank)
/*
if(_jobban_isbanned(M, rank)) return "Reason Unspecified" //for old jobban
*/
if (guest_jobbans(rank))
if(config.guest_jobban && IsGuestKey(M.key))
return "Guest Job-ban"
if(config.usewhitelist && !check_whitelist(M))
return "Whitelisted Job"
return ckey_is_jobbanned(M.ckey, rank)
return 0
/proc/ckey_is_jobbanned(var/check_key, var/rank)
for(var/s in jobban_keylist)
if(findtext(s,"[check_key] - [rank]") == 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
/*
DEBUG
/mob/verb/list_all_jobbans()
set name = "list all jobbans"
for(var/s in jobban_keylist)
to_world(s)
/mob/verb/reload_jobbans()
set name = "reload jobbans"
jobban_loadbanfile()
*/
/hook/startup/proc/loadJobBans()
jobban_loadbanfile()
return 1
/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
if (!length(jobban_keylist))
jobban_keylist=list()
log_admin("jobban_keylist was empty")
else
if(!establish_db_connection())
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
//Job permabans
var/DBQuery/query = dbcon.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
var/job = query.item[2]
jobban_keylist.Add("[ckey] - [job]")
//Job tempbans
var/DBQuery/query1 = dbcon.NewQuery("SELECT ckey, job FROM erro_ban WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()")
query1.Execute()
while(query1.NextRow())
var/ckey = query1.item[1]
var/job = query1.item[2]
jobban_keylist.Add("[ckey] - [job]")
/proc/jobban_savebanfile()
var/savefile/S=new("data/job_full.ban")
S["keys[0]"] << jobban_keylist
/proc/jobban_unban(mob/M, rank)
jobban_remove("[M.ckey] - [rank]")
jobban_savebanfile()
/proc/ban_unban_log_save(var/formatted_log)
text2file(formatted_log,"data/ban_unban_log.txt")
/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
+210 -210
View File
@@ -1,210 +1,210 @@
/client/proc/callproc()
set category = "Debug"
set name = "Advanced ProcCall"
set waitfor = 0
if(!check_rights(R_DEBUG))
return
var/datum/target = null
var/targetselected = 0
var/returnval = null
switch(tgui_alert(usr, "Proc owned by something?","Call Proc",list("Yes","No")))
if("Yes")
targetselected = 1
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
if("No")
target = null
targetselected = 0
var/procname = tgui_input_text(usr, "Proc path, eg: /proc/fake_blood","Path:", null)
if(!procname)
return
//hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib")
var/testname = procname
if(targetselected)
//Find one of the 3 possible ways they could have written /proc/PROCNAME
if(findtext(procname, "/proc/"))
testname = replacetext(procname, "/proc/", "")
else if(findtext(procname, "/proc"))
testname = replacetext(procname, "/proc", "")
else if(findtext(procname, "proc/"))
testname = replacetext(procname, "proc/", "")
//Clear out any parenthesis if they're a dummy
testname = replacetext(testname, "()", "")
if(targetselected && !hascall(target,testname))
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc(): type [target.type] has no proc named [procname].") + "</span>")
return
else
var/procpath = text2path(procname)
if (!procpath)
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") + "</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(targetselected)
if(!target)
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc(): owner of proc no longer exists.") + "</span>")
return
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
//message_admins(msg) //Proccall announce removed.
admin_ticket_log(target, msg)
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
else
//this currently has no hascall protection. wasn't able to get it working.
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
//message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed.
returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
. = get_callproc_returnval(returnval, procname)
if(.)
to_chat(usr, .)
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOBAL_VAR(AdminProcCaller)
GLOBAL_PROTECT(AdminProcCaller)
GLOBAL_VAR_INIT(AdminProcCallCount, 0)
GLOBAL_PROTECT(AdminProcCallCount)
GLOBAL_VAR(LastAdminCalledTargetRef)
GLOBAL_PROTECT(LastAdminCalledTargetRef)
GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target && procname == "Del")
to_chat(usr, "<span class='filter_adminlog'>Calling Del() is not allowed</span>")
return
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
to_chat(usr, "<span class='filter_adminlog'>Proccall on [target.type]/proc/[procname] is disallowed!</span>")
return
var/current_caller = GLOB.AdminProcCaller
var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
if(!GLOB.AdminProcCallSpamPrevention[ckey])
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
UNTIL(!GLOB.AdminProcCaller)
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
GLOB.AdminProcCallSpamPrevention -= ckey
else
UNTIL(!GLOB.AdminProcCaller)
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "\ref[target]"
GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
++GLOB.AdminProcCallCount
. = world.WrapAdminProcCall(target, procname, arguments)
if(--GLOB.AdminProcCallCount == 0)
GLOB.AdminProcCaller = null
//adv proc call this, ya nerds
/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target == GLOBAL_PROC)
return call(procname)(arglist(arguments))
else if(target != world)
return call(target, procname)(arglist(arguments))
else
log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]")
/proc/IsAdminAdvancedProcCall()
#ifdef TESTING
return FALSE
#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = 0
if(!check_rights(R_DEBUG))
return
var/procname = tgui_input_text(usr, "Proc name, eg: fake_blood","Proc:", null)
if(!procname)
return
if(!hascall(A,procname))
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc_datum(): type [A.type] has no proc named [procname].") + "</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(!A || !IsValidSrc(A))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
return
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
//message_admins(msg)
admin_ticket_log(A, msg)
feedback_add_details("admin_verb","TPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
. = get_callproc_returnval(returnval,procname)
if(.)
to_chat(usr, .)
/client/proc/get_callproc_args()
var/argnum = tgui_input_number(usr, "Number of arguments","Number:",0)
if(isnull(argnum))
return null //Cancel
. = list()
//var/list/named_args = list() //Named arguments are removed, due to them making proccalling take too long.
while(argnum--)
/* //Named arguments are removed, due to them making proccalling take too long.
var/named_arg = input(usr,"Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null
if(isnull(named_arg))
return null //Cancel
*/
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
if (!value["class"])
return null //Cancel
/* //Named arguments are removed, due to them making proccalling take too long.
if(named_arg)
named_args[named_arg] = value["value"]
else
. += value["value"]
if(LAZYLEN(named_args))
. += named_args
*/
. += value["value"]
/client/proc/get_callproc_returnval(returnval,procname)
. = ""
if(islist(returnval))
var/list/returnedlist = returnval
. = "<span class='blue'>"
if(returnedlist.len)
var/assoc_check = returnedlist[1]
if(istext(assoc_check) && (returnedlist[assoc_check] != null))
. += "[procname] returned an associative list:"
for(var/key in returnedlist)
. += "\n[key] = [returnedlist[key]]"
else
. += "[procname] returned a list:"
for(var/elem in returnedlist)
. += "\n[elem]"
else
. = "[procname] returned an empty list"
. += "</span>"
else
. = span_blue("[procname] returned: [!isnull(returnval) ? returnval : "null"]")
/client/proc/callproc()
set category = "Debug"
set name = "Advanced ProcCall"
set waitfor = 0
if(!check_rights(R_DEBUG))
return
var/datum/target = null
var/targetselected = 0
var/returnval = null
switch(tgui_alert(usr, "Proc owned by something?","Call Proc",list("Yes","No")))
if("Yes")
targetselected = 1
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
if("No")
target = null
targetselected = 0
var/procname = tgui_input_text(usr, "Proc path, eg: /proc/fake_blood","Path:", null)
if(!procname)
return
//hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib")
var/testname = procname
if(targetselected)
//Find one of the 3 possible ways they could have written /proc/PROCNAME
if(findtext(procname, "/proc/"))
testname = replacetext(procname, "/proc/", "")
else if(findtext(procname, "/proc"))
testname = replacetext(procname, "/proc", "")
else if(findtext(procname, "proc/"))
testname = replacetext(procname, "proc/", "")
//Clear out any parenthesis if they're a dummy
testname = replacetext(testname, "()", "")
if(targetselected && !hascall(target,testname))
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc(): type [target.type] has no proc named [procname].") + "</span>")
return
else
var/procpath = text2path(procname)
if (!procpath)
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)") + "</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(targetselected)
if(!target)
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc(): owner of proc no longer exists.") + "</span>")
return
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
//message_admins(msg) //Proccall announce removed.
admin_ticket_log(target, msg)
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
else
//this currently has no hascall protection. wasn't able to get it working.
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
//message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed.
returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
. = get_callproc_returnval(returnval, procname)
if(.)
to_chat(usr, .)
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOBAL_VAR(AdminProcCaller)
GLOBAL_PROTECT(AdminProcCaller)
GLOBAL_VAR_INIT(AdminProcCallCount, 0)
GLOBAL_PROTECT(AdminProcCallCount)
GLOBAL_VAR(LastAdminCalledTargetRef)
GLOBAL_PROTECT(LastAdminCalledTargetRef)
GLOBAL_VAR(LastAdminCalledTarget)
GLOBAL_PROTECT(LastAdminCalledTarget)
GLOBAL_VAR(LastAdminCalledProc)
GLOBAL_PROTECT(LastAdminCalledProc)
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target && procname == "Del")
to_chat(usr, "<span class='filter_adminlog'>Calling Del() is not allowed</span>")
return
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
to_chat(usr, "<span class='filter_adminlog'>Proccall on [target.type]/proc/[procname] is disallowed!</span>")
return
var/current_caller = GLOB.AdminProcCaller
var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
if(!ckey)
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
if(current_caller && current_caller != ckey)
if(!GLOB.AdminProcCallSpamPrevention[ckey])
to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>")
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
UNTIL(!GLOB.AdminProcCaller)
to_chat(usr, "<span class='adminnotice'>Running your proc</span>")
GLOB.AdminProcCallSpamPrevention -= ckey
else
UNTIL(!GLOB.AdminProcCaller)
GLOB.LastAdminCalledProc = procname
if(target != GLOBAL_PROC)
GLOB.LastAdminCalledTargetRef = "\ref[target]"
GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
++GLOB.AdminProcCallCount
. = world.WrapAdminProcCall(target, procname, arguments)
if(--GLOB.AdminProcCallCount == 0)
GLOB.AdminProcCaller = null
//adv proc call this, ya nerds
/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
if(target == GLOBAL_PROC)
return call(procname)(arglist(arguments))
else if(target != world)
return call(target, procname)(arglist(arguments))
else
log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]")
/proc/IsAdminAdvancedProcCall()
#ifdef TESTING
return FALSE
#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = 0
if(!check_rights(R_DEBUG))
return
var/procname = tgui_input_text(usr, "Proc name, eg: fake_blood","Proc:", null)
if(!procname)
return
if(!hascall(A,procname))
to_chat(usr, "<span class='filter_adminlog'>" + span_red("Error: callproc_datum(): type [A.type] has no proc named [procname].") + "</span>")
return
var/list/lst = get_callproc_args()
if(!lst)
return
if(!A || !IsValidSrc(A))
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
return
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
log_admin(msg)
//message_admins(msg)
admin_ticket_log(A, msg)
feedback_add_details("admin_verb","TPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
. = get_callproc_returnval(returnval,procname)
if(.)
to_chat(usr, .)
/client/proc/get_callproc_args()
var/argnum = tgui_input_number(usr, "Number of arguments","Number:",0)
if(isnull(argnum))
return null //Cancel
. = list()
//var/list/named_args = list() //Named arguments are removed, due to them making proccalling take too long.
while(argnum--)
/* //Named arguments are removed, due to them making proccalling take too long.
var/named_arg = input(usr,"Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null
if(isnull(named_arg))
return null //Cancel
*/
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
if (!value["class"])
return null //Cancel
/* //Named arguments are removed, due to them making proccalling take too long.
if(named_arg)
named_args[named_arg] = value["value"]
else
. += value["value"]
if(LAZYLEN(named_args))
. += named_args
*/
. += value["value"]
/client/proc/get_callproc_returnval(returnval,procname)
. = ""
if(islist(returnval))
var/list/returnedlist = returnval
. = "<span class='blue'>"
if(returnedlist.len)
var/assoc_check = returnedlist[1]
if(istext(assoc_check) && (returnedlist[assoc_check] != null))
. += "[procname] returned an associative list:"
for(var/key in returnedlist)
. += "\n[key] = [returnedlist[key]]"
else
. += "[procname] returned a list:"
for(var/elem in returnedlist)
. += "\n[elem]"
else
. = "[procname] returned an empty list"
. += "</span>"
else
. = span_blue("[procname] returned: [!isnull(returnval) ? returnval : "null"]")
+9 -9
View File
@@ -1,9 +1,9 @@
/var/create_mob_html = null
/datum/admins/proc/create_mob(var/mob/user)
if (!create_mob_html)
var/mobjs = null
mobjs = jointext(typesof(/mob), ";")
create_mob_html = file2text('html/create_object.html')
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
user << browse(create_panel_helper(create_mob_html), "window=create_mob;size=680x600")
/var/create_mob_html = null
/datum/admins/proc/create_mob(var/mob/user)
if (!create_mob_html)
var/mobjs = null
mobjs = jointext(typesof(/mob), ";")
create_mob_html = file2text('html/create_object.html')
create_mob_html = replacetext(create_mob_html, "null /* object types */", "\"[mobjs]\"")
user << browse(create_panel_helper(create_mob_html), "window=create_mob;size=680x600")
+48 -48
View File
@@ -1,48 +1,48 @@
/datum/admins/proc/create_panel_helper(template)
var/final_html = replacetext(template, "/* ref src */", "\ref[src];[HrefToken()]")
final_html = replacetext(final_html,"/* hreftokenfield */","[HrefTokenFormField()]")
return final_html
/datum/admins/proc/create_object(var/mob/user)
var/static/create_object_html = null
if (!create_object_html)
var/objectjs = null
objectjs = jointext(typesof(/obj), ";")
create_object_html = file2text('html/create_object.html')
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(create_panel_helper(create_object_html), "window=create_object;size=680x600")
/datum/admins/proc/quick_create_object(var/mob/user)
var/quick_create_object_html = null
var/pathtext = null
var/list/choices = list("/obj",
"/obj/structure",
"/obj/item",
"/obj/item/device",
"/obj/item/weapon",
"/obj/item/weapon/gun",
"/obj/item/weapon/reagent_containers",
"/obj/item/weapon/reagent_containers/food",
"/obj/item/clothing",
"/obj/item/weapon/storage/box/fluff", //VOREStation Edit,
"/obj/machinery",
"/obj/mecha",
"/obj/item/mecha_parts",
"/obj/item/mecha_parts/mecha_equipment")
pathtext = tgui_input_list(usr, "Select the path of the object you wish to create.", "Path", choices, "/obj")
if(!pathtext)
return
var path = text2path(pathtext)
if (!quick_create_object_html)
var/objectjs = null
objectjs = jointext(typesof(path), ";")
quick_create_object_html = file2text('html/create_object.html')
quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(create_panel_helper(quick_create_object_html), "window=quick_create_object;size=680x600")
/datum/admins/proc/create_panel_helper(template)
var/final_html = replacetext(template, "/* ref src */", "\ref[src];[HrefToken()]")
final_html = replacetext(final_html,"/* hreftokenfield */","[HrefTokenFormField()]")
return final_html
/datum/admins/proc/create_object(var/mob/user)
var/static/create_object_html = null
if (!create_object_html)
var/objectjs = null
objectjs = jointext(typesof(/obj), ";")
create_object_html = file2text('html/create_object.html')
create_object_html = replacetext(create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(create_panel_helper(create_object_html), "window=create_object;size=680x600")
/datum/admins/proc/quick_create_object(var/mob/user)
var/quick_create_object_html = null
var/pathtext = null
var/list/choices = list("/obj",
"/obj/structure",
"/obj/item",
"/obj/item/device",
"/obj/item/weapon",
"/obj/item/weapon/gun",
"/obj/item/weapon/reagent_containers",
"/obj/item/weapon/reagent_containers/food",
"/obj/item/clothing",
"/obj/item/weapon/storage/box/fluff", //VOREStation Edit,
"/obj/machinery",
"/obj/mecha",
"/obj/item/mecha_parts",
"/obj/item/mecha_parts/mecha_equipment")
pathtext = tgui_input_list(usr, "Select the path of the object you wish to create.", "Path", choices, "/obj")
if(!pathtext)
return
var path = text2path(pathtext)
if (!quick_create_object_html)
var/objectjs = null
objectjs = jointext(typesof(path), ";")
quick_create_object_html = file2text('html/create_object.html')
quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"")
user << browse(create_panel_helper(quick_create_object_html), "window=quick_create_object;size=680x600")
+9 -9
View File
@@ -1,9 +1,9 @@
/var/create_turf_html = null
/datum/admins/proc/create_turf(var/mob/user)
if (!create_turf_html)
var/turfjs = null
turfjs = jointext(typesof(/turf), ";")
create_turf_html = file2text('html/create_object.html')
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
user << browse(create_panel_helper(create_turf_html), "window=create_turf;size=680x600")
/var/create_turf_html = null
/datum/admins/proc/create_turf(var/mob/user)
if (!create_turf_html)
var/turfjs = null
turfjs = jointext(typesof(/turf), ";")
create_turf_html = file2text('html/create_object.html')
create_turf_html = replacetext(create_turf_html, "null /* object types */", "\"[turfjs]\"")
user << browse(create_panel_helper(create_turf_html), "window=create_turf;size=680x600")
+157 -157
View File
@@ -1,157 +1,157 @@
GLOBAL_VAR_INIT(href_token, GenerateToken())
GLOBAL_PROTECT(href_token)
var/list/admin_datums = list()
/datum/admins
var/rank = "Temporary Admin"
var/client/owner = null
var/rights = 0
var/fakekey = null
var/datum/marked_datum
var/admincaster_screen = 0 //See newscaster.dm under machinery for a full description
var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders.
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
var/admincaster_signature //What you'll sign the newsfeeds as
var/href_token
/datum/admins/New(initial_rank = "Temporary Admin", initial_rights = 0, ckey)
if(!ckey)
error("Admin datum created without a ckey argument. Datum has been deleted")
qdel(src)
return
admincaster_signature = "[using_map.company_name] Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
href_token = GenerateToken()
rank = initial_rank
rights = initial_rights
admin_datums[ckey] = src
if(rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
/datum/admins/proc/associate(client/C)
if(istype(C))
owner = C
owner.holder = src
owner.add_admin_verbs() //TODO
GLOB.admins |= C
/datum/admins/proc/disassociate()
if(owner)
GLOB.admins -= owner
owner.remove_admin_verbs()
owner.deadmin_holder = owner.holder
owner.holder = null
/datum/admins/proc/reassociate()
if(owner)
GLOB.admins += owner
owner.holder = src
owner.deadmin_holder = null
owner.add_admin_verbs()
/datum/admins/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, rights) || var_name == NAMEOF(src, owner) || var_name == NAMEOF(src, rank))
return FALSE
return ..()
//TODO: Proccall guard, when all try/catch are removed and WrapAdminProccall is ported.
/*
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
if rights_required == 0, then it simply checks if they are an admin.
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
generally it would be used like so:
/proc/admin_proc()
if(!check_rights(R_ADMIN)) return
to_world("you have enough rights!")
NOTE: It checks usr by default. Supply the "user" argument if you wish to check for a specific mob.
*/
/proc/check_rights(rights_required, show_msg=1, var/client/C = usr)
if(ismob(C))
var/mob/M = C
C = M.client
if(!C)
return FALSE
if(!(istype(C, /client))) // If we still didn't find a client, something is wrong.
return FALSE
if(!C.holder)
if(show_msg)
to_chat(C, "<span class='filter_adminlog warning'>Error: You are not an admin.</span>")
return FALSE
if(rights_required)
if(rights_required & C.holder.rights)
return TRUE
else
if(show_msg)
to_chat(C, "<span class='filter_adminlog warning'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</span>")
return FALSE
else
return TRUE
//probably a bit iffy - will hopefully figure out a better solution
/proc/check_if_greater_rights_than(client/other)
if(usr && usr.client)
if(usr.client.holder)
if(!other || !other.holder)
return 1
if(usr.client.holder.rights != other.holder.rights)
if( (usr.client.holder.rights & other.holder.rights) == other.holder.rights )
return 1 //we have all the rights they have and more
to_chat(usr, "<span class='filter_adminlog warning'>Error: Cannot proceed. They have more or equal rights to us.</span>")
return 0
/client/proc/mark_datum(datum/D)
if(!holder)
return
if(holder.marked_datum)
vv_update_display(holder.marked_datum, "marked", "")
holder.marked_datum = D
vv_update_display(D, "marked", VV_MSG_MARKED)
/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view))
set category = "Debug"
set name = "Mark Object"
mark_datum(D)
/client/proc/deadmin()
if(holder)
holder.disassociate()
//qdel(holder)
return 1
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
/proc/check_rights_for(client/subject, rights_required)
if(subject && subject.holder)
if(rights_required && !(rights_required & subject.holder.rights))
return 0
return 1
return 0
/proc/GenerateToken()
. = ""
for(var/I in 1 to 32)
. += "[rand(10)]"
/proc/RawHrefToken(forceGlobal = FALSE)
var/tok = GLOB.href_token
if(!forceGlobal && usr)
var/client/C = usr.client
if(!C)
CRASH("No client for HrefToken()!")
var/datum/admins/holder = C.holder
if(holder)
tok = holder.href_token
return tok
/proc/HrefToken(forceGlobal = FALSE)
return "admin_token=[RawHrefToken(forceGlobal)]"
/proc/HrefTokenFormField(forceGlobal = FALSE)
return "<input type='hidden' name='admin_token' value='[RawHrefToken(forceGlobal)]'>"
GLOBAL_VAR_INIT(href_token, GenerateToken())
GLOBAL_PROTECT(href_token)
var/list/admin_datums = list()
/datum/admins
var/rank = "Temporary Admin"
var/client/owner = null
var/rights = 0
var/fakekey = null
var/datum/marked_datum
var/admincaster_screen = 0 //See newscaster.dm under machinery for a full description
var/datum/feed_message/admincaster_feed_message = new /datum/feed_message //These two will act as holders.
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
var/admincaster_signature //What you'll sign the newsfeeds as
var/href_token
/datum/admins/New(initial_rank = "Temporary Admin", initial_rights = 0, ckey)
if(!ckey)
error("Admin datum created without a ckey argument. Datum has been deleted")
qdel(src)
return
admincaster_signature = "[using_map.company_name] Officer #[rand(0,9)][rand(0,9)][rand(0,9)]"
href_token = GenerateToken()
rank = initial_rank
rights = initial_rights
admin_datums[ckey] = src
if(rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
/datum/admins/proc/associate(client/C)
if(istype(C))
owner = C
owner.holder = src
owner.add_admin_verbs() //TODO
GLOB.admins |= C
/datum/admins/proc/disassociate()
if(owner)
GLOB.admins -= owner
owner.remove_admin_verbs()
owner.deadmin_holder = owner.holder
owner.holder = null
/datum/admins/proc/reassociate()
if(owner)
GLOB.admins += owner
owner.holder = src
owner.deadmin_holder = null
owner.add_admin_verbs()
/datum/admins/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, rights) || var_name == NAMEOF(src, owner) || var_name == NAMEOF(src, rank))
return FALSE
return ..()
//TODO: Proccall guard, when all try/catch are removed and WrapAdminProccall is ported.
/*
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
if rights_required == 0, then it simply checks if they are an admin.
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
generally it would be used like so:
/proc/admin_proc()
if(!check_rights(R_ADMIN)) return
to_world("you have enough rights!")
NOTE: It checks usr by default. Supply the "user" argument if you wish to check for a specific mob.
*/
/proc/check_rights(rights_required, show_msg=1, var/client/C = usr)
if(ismob(C))
var/mob/M = C
C = M.client
if(!C)
return FALSE
if(!(istype(C, /client))) // If we still didn't find a client, something is wrong.
return FALSE
if(!C.holder)
if(show_msg)
to_chat(C, "<span class='filter_adminlog warning'>Error: You are not an admin.</span>")
return FALSE
if(rights_required)
if(rights_required & C.holder.rights)
return TRUE
else
if(show_msg)
to_chat(C, "<span class='filter_adminlog warning'>Error: You do not have sufficient rights to do that. You require one of the following flags:[rights2text(rights_required," ")].</span>")
return FALSE
else
return TRUE
//probably a bit iffy - will hopefully figure out a better solution
/proc/check_if_greater_rights_than(client/other)
if(usr && usr.client)
if(usr.client.holder)
if(!other || !other.holder)
return 1
if(usr.client.holder.rights != other.holder.rights)
if( (usr.client.holder.rights & other.holder.rights) == other.holder.rights )
return 1 //we have all the rights they have and more
to_chat(usr, "<span class='filter_adminlog warning'>Error: Cannot proceed. They have more or equal rights to us.</span>")
return 0
/client/proc/mark_datum(datum/D)
if(!holder)
return
if(holder.marked_datum)
vv_update_display(holder.marked_datum, "marked", "")
holder.marked_datum = D
vv_update_display(D, "marked", VV_MSG_MARKED)
/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view))
set category = "Debug"
set name = "Mark Object"
mark_datum(D)
/client/proc/deadmin()
if(holder)
holder.disassociate()
//qdel(holder)
return 1
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
/proc/check_rights_for(client/subject, rights_required)
if(subject && subject.holder)
if(rights_required && !(rights_required & subject.holder.rights))
return 0
return 1
return 0
/proc/GenerateToken()
. = ""
for(var/I in 1 to 32)
. += "[rand(10)]"
/proc/RawHrefToken(forceGlobal = FALSE)
var/tok = GLOB.href_token
if(!forceGlobal && usr)
var/client/C = usr.client
if(!C)
CRASH("No client for HrefToken()!")
var/datum/admins/holder = C.holder
if(holder)
tok = holder.href_token
return tok
/proc/HrefToken(forceGlobal = FALSE)
return "admin_token=[RawHrefToken(forceGlobal)]"
/proc/HrefTokenFormField(forceGlobal = FALSE)
return "<input type='hidden' name='admin_token' value='[RawHrefToken(forceGlobal)]'>"
+274 -274
View File
@@ -1,274 +1,274 @@
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, "Site Manager")
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, "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, "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]") )
to_chat(usr, span_red("Banjob already exists."))
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
admin_action_message(bannedby, ckey, "jobbanned-"+rank, reason, temp ? minutes : -1) //VOREStation Add
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]")
message_admins("Banjob Expired: [key]")
else
log_admin("[key_name_admin(usr)] unjobbanned [key] from [rank]")
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
admin_action_message(usr.key, key, "unjobbanned-"+rank, "\[Unban\]", 0) //VOREStation Add
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> <font color='blue'>(U) = Unban , (E) = Edit Ban</font> <font color='green'>(Total<HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 </font>>"
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
count++
Banlistjob.cd = "/base/[A]"
dat += text("<tr><td><A href='?src=\ref[src];[HrefToken()];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))
to_chat(M, "<font color='red'><BIG><B>You have been banned from [job] by [usr.client.ckey].\nReason: [reason].</B></BIG></font>")
to_chat(M, "<font color='red'>This is a permanent ban.</font>")
if(config.banappeals)
to_chat(M, "<font color='red'>To try to resolve this matter head to [config.banappeals]</font>")
else
to_chat(M, "<font color='red'>No ban appeals URL has been set.</font>")
log_admin("[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis is a permanent ban.")
message_admins("<font color='blue'>[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis is a permanent ban.</font>")
/datum/admins/proc/timejobban(ckey, computerid, reason, bannedby, temp, minutes, rank)
if(AddBanjob(ckey, computerid, reason, usr.ckey, 1, mins, job))
to_chat(M, "<font color='red'><BIG><B>You have been jobbanned from [job] by [usr.client.ckey].\nReason: [reason].</B></BIG></font>")
to_chat(M, "<font color='red'>This is a temporary ban, it will be removed in [mins] minutes.</font>")
if(config.banappeals)
to_chat(M, "<font color='red'>To try to resolve this matter head to [config.banappeals]</font>")
else
to_chat(M, "<font color='red'>No ban appeals URL has been set.</font>")
log_admin("[usr.client.ckey] has jobbanned from [job] [ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
message_admins("<font color='blue'>[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.</font>")*/
//////////////////////////////////// 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]"
to_chat(Banlistjob["key"], "trash[i]")
else
Banlistjob.cd = "/base"
Banlistjob.dir.Add("[last]trashid[i]")
Banlistjob.cd = "/base/[last]trashid[i]"
Banlistjob["key"] << last
to_chat(Banlistjob["id"], "trashid[i]")
to_chat(Banlistjob["reason"], "Trashban[i].")
Banlistjob["temp"] << a
Banlistjob["minutes"] << CMinutes + rand(1,2000)
to_chat(Banlistjob["bannedby"], "trashmin")
last = "trash[i]"
Banlistjob.cd = "/base"
/proc/ClearAllBansjob()
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
RemoveBanjob(A, "full")
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, "Site Manager")
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, "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, "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]") )
to_chat(usr, span_red("Banjob already exists."))
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
admin_action_message(bannedby, ckey, "jobbanned-"+rank, reason, temp ? minutes : -1) //VOREStation Add
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]")
message_admins("Banjob Expired: [key]")
else
log_admin("[key_name_admin(usr)] unjobbanned [key] from [rank]")
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
admin_action_message(usr.key, key, "unjobbanned-"+rank, "\[Unban\]", 0) //VOREStation Add
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> <font color='blue'>(U) = Unban , (E) = Edit Ban</font> <font color='green'>(Total<HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 </font>>"
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
count++
Banlistjob.cd = "/base/[A]"
dat += text("<tr><td><A href='?src=\ref[src];[HrefToken()];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))
to_chat(M, "<font color='red'><BIG><B>You have been banned from [job] by [usr.client.ckey].\nReason: [reason].</B></BIG></font>")
to_chat(M, "<font color='red'>This is a permanent ban.</font>")
if(config.banappeals)
to_chat(M, "<font color='red'>To try to resolve this matter head to [config.banappeals]</font>")
else
to_chat(M, "<font color='red'>No ban appeals URL has been set.</font>")
log_admin("[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis is a permanent ban.")
message_admins("<font color='blue'>[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis is a permanent ban.</font>")
/datum/admins/proc/timejobban(ckey, computerid, reason, bannedby, temp, minutes, rank)
if(AddBanjob(ckey, computerid, reason, usr.ckey, 1, mins, job))
to_chat(M, "<font color='red'><BIG><B>You have been jobbanned from [job] by [usr.client.ckey].\nReason: [reason].</B></BIG></font>")
to_chat(M, "<font color='red'>This is a temporary ban, it will be removed in [mins] minutes.</font>")
if(config.banappeals)
to_chat(M, "<font color='red'>To try to resolve this matter head to [config.banappeals]</font>")
else
to_chat(M, "<font color='red'>No ban appeals URL has been set.</font>")
log_admin("[usr.client.ckey] has jobbanned from [job] [ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
message_admins("<font color='blue'>[usr.client.ckey] has banned from [job] [ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.</font>")*/
//////////////////////////////////// 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]"
to_chat(Banlistjob["key"], "trash[i]")
else
Banlistjob.cd = "/base"
Banlistjob.dir.Add("[last]trashid[i]")
Banlistjob.cd = "/base/[last]trashid[i]"
Banlistjob["key"] << last
to_chat(Banlistjob["id"], "trashid[i]")
to_chat(Banlistjob["reason"], "Trashban[i].")
Banlistjob["temp"] << a
Banlistjob["minutes"] << CMinutes + rand(1,2000)
to_chat(Banlistjob["bannedby"], "trashmin")
last = "trash[i]"
Banlistjob.cd = "/base"
/proc/ClearAllBansjob()
Banlistjob.cd = "/base"
for (var/A in Banlistjob.dir)
RemoveBanjob(A, "full")
@@ -1,149 +1,149 @@
/client/proc/edit_admin_permissions()
set category = "Admin"
set name = "Permissions Panel"
set desc = "Edit admin permissions"
if(!check_rights(R_PERMISSIONS)) return
usr.client.holder.edit_admin_permissions()
/datum/admins/proc/edit_admin_permissions()
if(!check_rights(R_PERMISSIONS)) return
var/output = {"<!DOCTYPE html>
<html>
<head>
<title>Permissions Panel</title>
<script type='text/javascript' src='search.js'></script>
<link rel='stylesheet' type='text/css' href='panels.css'>
</head>
<body onload='selectTextField();updateSearch();'>
<div id='main'><table id='searchable' cellspacing='0'>
<tr class='title'>
<th style='width:125px;text-align:right;'>CKEY <a class='small' href='?src=\ref[src];[HrefToken()];editrights=add'>\[+\]</a></th>
<th style='width:125px;'>RANK</th><th style='width:100%;'>PERMISSIONS</th>
</tr>
"}
for(var/adm_ckey in admin_datums)
var/datum/admins/D = admin_datums[adm_ckey]
if(!D) continue
var/rank = D.rank ? D.rank : "*none*"
var/rights = rights2text(D.rights," ")
if(!rights) rights = "*none*"
output += "<tr>"
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=\ref[src];[HrefToken()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
output += "<td><a href='?src=\ref[src];[HrefToken()];editrights=rank;ckey=[adm_ckey]'>[rank]</a></td>"
output += "<td><a class='small' href='?src=\ref[src];[HrefToken()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></td>"
output += "</tr>"
output += {"
</table></div>
<div id='top'><b>Search:</b> <input type='text' id='filter' value='' style='width:70%;' onkeyup='updateSearch();'></div>
</body>
</html>"}
usr << browse(output,"window=editrights;size=600x500")
/datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank)
if(config.admin_legacy_system) return
if(!usr.client)
return
if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS))
to_chat(usr, "<span class='filter_adminlog'>[span_red("You do not have permission to do this!")]</span>")
return
establish_db_connection()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='filter_adminlog'>[span_red("Failed to establish database connection")]</span>")
return
if(!adm_ckey || !new_rank)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(!istext(adm_ckey) || !istext(new_rank))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM erro_admin WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/new_admin = 1
var/admin_id
while(select_query.NextRow())
new_admin = 0
admin_id = text2num(select_query.item[1])
if(new_admin)
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO `erro_admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("New admin added.")]</span>")
else
if(!isnull(admin_id) && isnum(admin_id))
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("Admin rank changed.")]</span>")
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
if(config.admin_legacy_system) return
if(!usr.client)
return
if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS))
to_chat(usr, "<span class='filter_adminlog'>[span_red(">You do not have permission to do this!")]</span>")
return
establish_db_connection()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='filter_adminlog'>[span_red("Failed to establish database connection!")]</span>")
return
if(!adm_ckey || !new_permission)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(istext(new_permission))
new_permission = text2num(new_permission)
if(!istext(adm_ckey) || !isnum(new_permission))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, flags FROM erro_admin WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/admin_id
var/admin_rights
while(select_query.NextRow())
admin_id = text2num(select_query.item[1])
admin_rights = text2num(select_query.item[2])
if(!admin_id)
return
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("Permission removed.")]</span>")
else //This admin doesn't have this permission, so we are adding it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("Permission added.")]</span>")
/client/proc/edit_admin_permissions()
set category = "Admin"
set name = "Permissions Panel"
set desc = "Edit admin permissions"
if(!check_rights(R_PERMISSIONS)) return
usr.client.holder.edit_admin_permissions()
/datum/admins/proc/edit_admin_permissions()
if(!check_rights(R_PERMISSIONS)) return
var/output = {"<!DOCTYPE html>
<html>
<head>
<title>Permissions Panel</title>
<script type='text/javascript' src='search.js'></script>
<link rel='stylesheet' type='text/css' href='panels.css'>
</head>
<body onload='selectTextField();updateSearch();'>
<div id='main'><table id='searchable' cellspacing='0'>
<tr class='title'>
<th style='width:125px;text-align:right;'>CKEY <a class='small' href='?src=\ref[src];[HrefToken()];editrights=add'>\[+\]</a></th>
<th style='width:125px;'>RANK</th><th style='width:100%;'>PERMISSIONS</th>
</tr>
"}
for(var/adm_ckey in admin_datums)
var/datum/admins/D = admin_datums[adm_ckey]
if(!D) continue
var/rank = D.rank ? D.rank : "*none*"
var/rights = rights2text(D.rights," ")
if(!rights) rights = "*none*"
output += "<tr>"
output += "<td style='text-align:right;'>[adm_ckey] <a class='small' href='?src=\ref[src];[HrefToken()];editrights=remove;ckey=[adm_ckey]'>\[-\]</a></td>"
output += "<td><a href='?src=\ref[src];[HrefToken()];editrights=rank;ckey=[adm_ckey]'>[rank]</a></td>"
output += "<td><a class='small' href='?src=\ref[src];[HrefToken()];editrights=permissions;ckey=[adm_ckey]'>[rights]</a></td>"
output += "</tr>"
output += {"
</table></div>
<div id='top'><b>Search:</b> <input type='text' id='filter' value='' style='width:70%;' onkeyup='updateSearch();'></div>
</body>
</html>"}
usr << browse(output,"window=editrights;size=600x500")
/datum/admins/proc/log_admin_rank_modification(var/adm_ckey, var/new_rank)
if(config.admin_legacy_system) return
if(!usr.client)
return
if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS))
to_chat(usr, "<span class='filter_adminlog'>[span_red("You do not have permission to do this!")]</span>")
return
establish_db_connection()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='filter_adminlog'>[span_red("Failed to establish database connection")]</span>")
return
if(!adm_ckey || !new_rank)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(!istext(adm_ckey) || !istext(new_rank))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id FROM erro_admin WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/new_admin = 1
var/admin_id
while(select_query.NextRow())
new_admin = 0
admin_id = text2num(select_query.item[1])
if(new_admin)
var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO `erro_admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (null, '[adm_ckey]', '[new_rank]', -1, 0)")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added new admin [adm_ckey] to rank [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("New admin added.")]</span>")
else
if(!isnull(admin_id) && isnum(admin_id))
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET rank = '[new_rank]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Edited the rank of [adm_ckey] to [new_rank]');")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("Admin rank changed.")]</span>")
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
if(config.admin_legacy_system) return
if(!usr.client)
return
if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS))
to_chat(usr, "<span class='filter_adminlog'>[span_red(">You do not have permission to do this!")]</span>")
return
establish_db_connection()
if(!dbcon.IsConnected())
to_chat(usr, "<span class='filter_adminlog'>[span_red("Failed to establish database connection!")]</span>")
return
if(!adm_ckey || !new_permission)
return
adm_ckey = ckey(adm_ckey)
if(!adm_ckey)
return
if(istext(new_permission))
new_permission = text2num(new_permission)
if(!istext(adm_ckey) || !isnum(new_permission))
return
var/DBQuery/select_query = dbcon.NewQuery("SELECT id, flags FROM erro_admin WHERE ckey = '[adm_ckey]'")
select_query.Execute()
var/admin_id
var/admin_rights
while(select_query.NextRow())
admin_id = text2num(select_query.item[1])
admin_rights = text2num(select_query.item[2])
if(!admin_id)
return
if(admin_rights & new_permission) //This admin already has this permission, so we are removing it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = [admin_rights & ~new_permission] WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]');")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("Permission removed.")]</span>")
else //This admin doesn't have this permission, so we are adding it.
var/DBQuery/insert_query = dbcon.NewQuery("UPDATE `erro_admin` SET flags = '[admin_rights | new_permission]' WHERE id = [admin_id]")
insert_query.Execute()
var/DBQuery/log_query = dbcon.NewQuery("INSERT INTO `test`.`erro_admin_log` (`id` ,`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (NULL , NOW( ) , '[usr.ckey]', '[usr.client.address]', 'Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]')")
log_query.Execute()
to_chat(usr, "<span class='filter_adminlog'>[span_blue("Permission added.")]</span>")
@@ -1,44 +1,44 @@
/datum/admin_secret_item/admin_secret/admin_logs
name = "Admin Logs"
/datum/admin_secret_item/admin_secret/admin_logs/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Admin Log<HR></B>"
for(var/l in admin_log)
dat += "<li>[l]</li>"
if(!admin_log.len)
dat += "No-one has done anything this round!"
var/datum/browser/popup = new(user, "adminlogs", "[src]", 550, 650, src)
popup.set_content(jointext(dat,null))
popup.open()
onclose(user, "adminlogs")
/datum/admin_secret_item/admin_secret/round_logs
name = "Round Dialogue Logs"
/datum/admin_secret_item/admin_secret/round_logs/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Dialogue Log<HR></B>"
dat += "<fieldset style='border: 2px solid white; display: inline'>"
for(var/l in GLOB.round_text_log)
dat += "<li>[l]</li>"
dat += "</fieldset>"
if(!GLOB.round_text_log)
dat += "No-one has said anything this round! (How odd?)"
var/datum/browser/popup = new(user, "dialoguelogs", "[src]", 550, 650, src)
popup.set_content(jointext(dat,null))
popup.open()
onclose(user, "dialoguelogs")
/datum/admin_secret_item/admin_secret/admin_logs
name = "Admin Logs"
/datum/admin_secret_item/admin_secret/admin_logs/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Admin Log<HR></B>"
for(var/l in admin_log)
dat += "<li>[l]</li>"
if(!admin_log.len)
dat += "No-one has done anything this round!"
var/datum/browser/popup = new(user, "adminlogs", "[src]", 550, 650, src)
popup.set_content(jointext(dat,null))
popup.open()
onclose(user, "adminlogs")
/datum/admin_secret_item/admin_secret/round_logs
name = "Round Dialogue Logs"
/datum/admin_secret_item/admin_secret/round_logs/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Dialogue Log<HR></B>"
dat += "<fieldset style='border: 2px solid white; display: inline'>"
for(var/l in GLOB.round_text_log)
dat += "<li>[l]</li>"
dat += "</fieldset>"
if(!GLOB.round_text_log)
dat += "No-one has said anything this round! (How odd?)"
var/datum/browser/popup = new(user, "dialoguelogs", "[src]", 550, 650, src)
popup.set_content(jointext(dat,null))
popup.open()
onclose(user, "dialoguelogs")
@@ -1,14 +1,14 @@
/datum/admin_secret_item/admin_secret/alter_narise
name = "Alter Nar-Sie"
/datum/admin_secret_item/admin_secret/alter_narise/execute(var/mob/user)
. = ..()
if(!.)
return
var/choice = tgui_alert(user, "How do you wish for Nar-Sie to interact with its surroundings?","NarChoice",list("CultStation13", "Nar-Singulo"))
if(choice == "CultStation13")
log_and_message_admins("has set narsie's behaviour to \"CultStation13\".", user)
narsie_behaviour = choice
if(choice == "Nar-Singulo")
log_and_message_admins("has set narsie's behaviour to \"Nar-Singulo\".", user)
narsie_behaviour = choice
/datum/admin_secret_item/admin_secret/alter_narise
name = "Alter Nar-Sie"
/datum/admin_secret_item/admin_secret/alter_narise/execute(var/mob/user)
. = ..()
if(!.)
return
var/choice = tgui_alert(user, "How do you wish for Nar-Sie to interact with its surroundings?","NarChoice",list("CultStation13", "Nar-Singulo"))
if(choice == "CultStation13")
log_and_message_admins("has set narsie's behaviour to \"CultStation13\".", user)
narsie_behaviour = choice
if(choice == "Nar-Singulo")
log_and_message_admins("has set narsie's behaviour to \"Nar-Singulo\".", user)
narsie_behaviour = choice
@@ -1,12 +1,12 @@
/datum/admin_secret_item/admin_secret/bombing_list
name = "Bombing List"
/datum/admin_secret_item/admin_secret/bombing_list/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Bombing List</B>"
for(var/l in bombers)
dat += text("[l]<BR>")
user << browse(dat, "window=bombers")
/datum/admin_secret_item/admin_secret/bombing_list
name = "Bombing List"
/datum/admin_secret_item/admin_secret/bombing_list/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Bombing List</B>"
for(var/l in bombers)
dat += text("[l]<BR>")
user << browse(dat, "window=bombers")
@@ -1,37 +1,37 @@
/datum/admin_secret_item/admin_secret/jump_shuttle
name = "Jump a Shuttle"
/datum/admin_secret_item/admin_secret/jump_shuttle/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/jump_shuttle/execute(var/mob/user)
. = ..()
if(!.)
return
var/shuttle_tag = tgui_input_list(user, "Which shuttle do you want to jump?", "Shuttle Choice", SSshuttles.shuttles)
if (!shuttle_tag) return
var/datum/shuttle/S = SSshuttles.shuttles[shuttle_tag]
var/list/area_choices = return_areas()
var/origin_area = tgui_input_list(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)", "Area Choice", area_choices)
if (!origin_area) return
var/destination_area = tgui_input_list(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)", "Area Choice", area_choices)
if (!destination_area) return
var/long_jump = tgui_alert(user, "Is there a transition area for this jump?","Transition?", list("Yes","No"))
if (long_jump == "Yes")
var/transition_area = tgui_input_list(user, "Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)", "Area Choice", area_choices)
if (!transition_area) return
var/move_duration = tgui_input_number(user, "How many seconds will this jump take?")
S.long_jump(area_choices[origin_area], area_choices[destination_area], area_choices[transition_area], move_duration)
message_admins("<span class='notice'>[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle</span>", 1)
log_admin("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle")
else
S.short_jump(area_choices[origin_area], area_choices[destination_area])
message_admins("<span class='notice'>[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle</span>", 1)
log_admin("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle")
/datum/admin_secret_item/admin_secret/jump_shuttle
name = "Jump a Shuttle"
/datum/admin_secret_item/admin_secret/jump_shuttle/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/jump_shuttle/execute(var/mob/user)
. = ..()
if(!.)
return
var/shuttle_tag = tgui_input_list(user, "Which shuttle do you want to jump?", "Shuttle Choice", SSshuttles.shuttles)
if (!shuttle_tag) return
var/datum/shuttle/S = SSshuttles.shuttles[shuttle_tag]
var/list/area_choices = return_areas()
var/origin_area = tgui_input_list(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)", "Area Choice", area_choices)
if (!origin_area) return
var/destination_area = tgui_input_list(user, "Which area is the shuttle at now? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)", "Area Choice", area_choices)
if (!destination_area) return
var/long_jump = tgui_alert(user, "Is there a transition area for this jump?","Transition?", list("Yes","No"))
if (long_jump == "Yes")
var/transition_area = tgui_input_list(user, "Which area is the transition area? (MAKE SURE THIS IS CORRECT OR THINGS WILL BREAK)", "Area Choice", area_choices)
if (!transition_area) return
var/move_duration = tgui_input_number(user, "How many seconds will this jump take?")
S.long_jump(area_choices[origin_area], area_choices[destination_area], area_choices[transition_area], move_duration)
message_admins("<span class='notice'>[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle</span>", 1)
log_admin("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] lasting [move_duration] seconds for the [shuttle_tag] shuttle")
else
S.short_jump(area_choices[origin_area], area_choices[destination_area])
message_admins("<span class='notice'>[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle</span>", 1)
log_admin("[key_name_admin(user)] has initiated a jump from [origin_area] to [destination_area] for the [shuttle_tag] shuttle")
@@ -1,26 +1,26 @@
/datum/admin_secret_item/admin_secret/launch_shuttle
name = "Launch a Shuttle"
/datum/admin_secret_item/admin_secret/launch_shuttle/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/launch_shuttle/execute(var/mob/user)
. = ..()
if(!.)
return
var/list/valid_shuttles = list()
for (var/shuttle_tag in SSshuttles.shuttles)
if (istype(SSshuttles.shuttles[shuttle_tag], /datum/shuttle/autodock))
valid_shuttles += shuttle_tag
var/shuttle_tag = tgui_input_list(user, "Which shuttle do you want to launch?", "Shuttle Choice", valid_shuttles)
if (!shuttle_tag)
return
var/datum/shuttle/autodock/S = SSshuttles.shuttles[shuttle_tag]
if (S.can_launch())
S.launch(user)
log_and_message_admins("launched the [shuttle_tag] shuttle", user)
else
tgui_alert_async(user, "The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.")
/datum/admin_secret_item/admin_secret/launch_shuttle
name = "Launch a Shuttle"
/datum/admin_secret_item/admin_secret/launch_shuttle/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/launch_shuttle/execute(var/mob/user)
. = ..()
if(!.)
return
var/list/valid_shuttles = list()
for (var/shuttle_tag in SSshuttles.shuttles)
if (istype(SSshuttles.shuttles[shuttle_tag], /datum/shuttle/autodock))
valid_shuttles += shuttle_tag
var/shuttle_tag = tgui_input_list(user, "Which shuttle do you want to launch?", "Shuttle Choice", valid_shuttles)
if (!shuttle_tag)
return
var/datum/shuttle/autodock/S = SSshuttles.shuttles[shuttle_tag]
if (S.can_launch())
S.launch(user)
log_and_message_admins("launched the [shuttle_tag] shuttle", user)
else
tgui_alert_async(user, "The [shuttle_tag] shuttle cannot be launched at this time. It's probably busy.")
@@ -1,26 +1,26 @@
/datum/admin_secret_item/admin_secret/launch_shuttle_forced
name = "Launch a Shuttle (Forced)"
/datum/admin_secret_item/admin_secret/launch_shuttle_forced/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/launch_shuttle_forced/execute(var/mob/user)
. = ..()
if(!.)
return
var/list/valid_shuttles = list()
for (var/shuttle_tag in SSshuttles.shuttles)
if (istype(SSshuttles.shuttles[shuttle_tag], /datum/shuttle/autodock))
valid_shuttles += shuttle_tag
var/shuttle_tag = tgui_input_list(user, "Which shuttle's launch do you want to force?", "Shuttle Choice", valid_shuttles)
if (!shuttle_tag)
return
var/datum/shuttle/autodock/S = SSshuttles.shuttles[shuttle_tag]
if (S.can_force())
S.force_launch(user)
log_and_message_admins("forced the [shuttle_tag] shuttle", user)
else
tgui_alert_async(user, "The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.")
/datum/admin_secret_item/admin_secret/launch_shuttle_forced
name = "Launch a Shuttle (Forced)"
/datum/admin_secret_item/admin_secret/launch_shuttle_forced/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/launch_shuttle_forced/execute(var/mob/user)
. = ..()
if(!.)
return
var/list/valid_shuttles = list()
for (var/shuttle_tag in SSshuttles.shuttles)
if (istype(SSshuttles.shuttles[shuttle_tag], /datum/shuttle/autodock))
valid_shuttles += shuttle_tag
var/shuttle_tag = tgui_input_list(user, "Which shuttle's launch do you want to force?", "Shuttle Choice", valid_shuttles)
if (!shuttle_tag)
return
var/datum/shuttle/autodock/S = SSshuttles.shuttles[shuttle_tag]
if (S.can_force())
S.force_launch(user)
log_and_message_admins("forced the [shuttle_tag] shuttle", user)
else
tgui_alert_async(user, "The [shuttle_tag] shuttle launch cannot be forced at this time. It's busy, or hasn't been launched yet.")
@@ -1,14 +1,14 @@
/datum/admin_secret_item/admin_secret/list_dna
name = "List DNA (Blood)"
/datum/admin_secret_item/admin_secret/list_dna/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing DNA from blood.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>DNA</th><th>Blood Type</th></tr>"
for(var/mob/living/carbon/human/H in mob_list)
if(H.dna && H.ckey)
dat += "<tr><td>[H]</td><td>[H.dna.unique_enzymes]</td><td>[H.b_type]</td></tr>"
dat += "</table>"
user << browse(dat, "window=DNA;size=440x410")
/datum/admin_secret_item/admin_secret/list_dna
name = "List DNA (Blood)"
/datum/admin_secret_item/admin_secret/list_dna/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing DNA from blood.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>DNA</th><th>Blood Type</th></tr>"
for(var/mob/living/carbon/human/H in mob_list)
if(H.dna && H.ckey)
dat += "<tr><td>[H]</td><td>[H.dna.unique_enzymes]</td><td>[H.b_type]</td></tr>"
dat += "</table>"
user << browse(dat, "window=DNA;size=440x410")
@@ -1,19 +1,19 @@
/datum/admin_secret_item/admin_secret/list_fingerprints
name = "List Fingerprints"
/datum/admin_secret_item/admin_secret/list_fingerprints/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing Fingerprints.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>Fingerprints</th></tr>"
for(var/mob/living/carbon/human/H in mob_list)
if(H.ckey)
if(H.dna && H.dna.uni_identity)
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
else if(H.dna && !H.dna.uni_identity)
dat += "<tr><td>[H]</td><td>H.dna.uni_identity = null</td></tr>"
else if(!H.dna)
dat += "<tr><td>[H]</td><td>H.dna = null</td></tr>"
dat += "</table>"
user << browse(dat, "window=fingerprints;size=440x410")
/datum/admin_secret_item/admin_secret/list_fingerprints
name = "List Fingerprints"
/datum/admin_secret_item/admin_secret/list_fingerprints/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing Fingerprints.</B><HR>"
dat += "<table cellspacing=5><tr><th>Name</th><th>Fingerprints</th></tr>"
for(var/mob/living/carbon/human/H in mob_list)
if(H.ckey)
if(H.dna && H.dna.uni_identity)
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
else if(H.dna && !H.dna.uni_identity)
dat += "<tr><td>[H]</td><td>H.dna.uni_identity = null</td></tr>"
else if(!H.dna)
dat += "<tr><td>[H]</td><td>H.dna = null</td></tr>"
dat += "</table>"
user << browse(dat, "window=fingerprints;size=440x410")
@@ -1,27 +1,27 @@
/datum/admin_secret_item/admin_secret/move_shuttle
name = "Move a Shuttle"
/datum/admin_secret_item/admin_secret/move_shuttle/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/move_shuttle/execute(var/mob/user)
. = ..()
if(!.)
return
var/confirm = tgui_alert(user, "This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", list("Ok", "Cancel"))
if (confirm == "Cancel")
return
var/shuttle_tag = tgui_input_list(user, "Which shuttle do you want to jump?", "Shuttle Choice", SSshuttles.shuttles)
if (!shuttle_tag) return
var/datum/shuttle/S = SSshuttles.shuttles[shuttle_tag]
var/destination_tag = tgui_input_list(user, "Which landmark do you want to jump to? (IF YOU GET THIS WRONG THINGS WILL BREAK)", "Landmark Choice", SSshuttles.registered_shuttle_landmarks)
if (!destination_tag) return
var/destination_location = SSshuttles.get_landmark(destination_tag)
if (!destination_location) return
S.attempt_move(destination_location)
log_and_message_admins("moved the [shuttle_tag] shuttle", user)
/datum/admin_secret_item/admin_secret/move_shuttle
name = "Move a Shuttle"
/datum/admin_secret_item/admin_secret/move_shuttle/can_execute(var/mob/user)
if(!SSshuttles) return 0
return ..()
/datum/admin_secret_item/admin_secret/move_shuttle/execute(var/mob/user)
. = ..()
if(!.)
return
var/confirm = tgui_alert(user, "This command directly moves a shuttle from one area to another. DO NOT USE THIS UNLESS YOU ARE DEBUGGING A SHUTTLE AND YOU KNOW WHAT YOU ARE DOING.", "Are you sure?", list("Ok", "Cancel"))
if (confirm == "Cancel")
return
var/shuttle_tag = tgui_input_list(user, "Which shuttle do you want to jump?", "Shuttle Choice", SSshuttles.shuttles)
if (!shuttle_tag) return
var/datum/shuttle/S = SSshuttles.shuttles[shuttle_tag]
var/destination_tag = tgui_input_list(user, "Which landmark do you want to jump to? (IF YOU GET THIS WRONG THINGS WILL BREAK)", "Landmark Choice", SSshuttles.registered_shuttle_landmarks)
if (!destination_tag) return
var/destination_location = SSshuttles.get_landmark(destination_tag)
if (!destination_location) return
S.attempt_move(destination_location)
log_and_message_admins("moved the [shuttle_tag] shuttle", user)
@@ -1,38 +1,38 @@
/datum/admin_secret_item/admin_secret/prison_warp
name = "Prison Warp"
/datum/admin_secret_item/admin_secret/prison_warp/can_execute(var/mob/user)
if(!ticker) return 0
return ..()
/datum/admin_secret_item/admin_secret/prison_warp/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/mob/living/carbon/human/H in mob_list)
var/turf/T = get_turf(H)
var/security = 0
if((T in using_map.admin_levels) || prisonwarped.Find(H))
//don't warp them if they aren't ready or are already there
continue
H.Paralyse(5)
if(H.wear_id)
var/obj/item/weapon/card/id/id = H.get_idcard()
for(var/A in id.access)
if(A == access_security)
security++
if(!security)
//strip their stuff before they teleport into a cell :downs:
for(var/obj/item/weapon/W in H)
if(istype(W, /obj/item/organ/external))
continue
//don't strip organs
H.drop_from_inventory(W)
//teleport person to cell
H.loc = pick(prisonwarp)
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/prison(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), slot_shoes)
else
//teleport security person
H.loc = pick(prisonsecuritywarp)
prisonwarped += H
/datum/admin_secret_item/admin_secret/prison_warp
name = "Prison Warp"
/datum/admin_secret_item/admin_secret/prison_warp/can_execute(var/mob/user)
if(!ticker) return 0
return ..()
/datum/admin_secret_item/admin_secret/prison_warp/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/mob/living/carbon/human/H in mob_list)
var/turf/T = get_turf(H)
var/security = 0
if((T in using_map.admin_levels) || prisonwarped.Find(H))
//don't warp them if they aren't ready or are already there
continue
H.Paralyse(5)
if(H.wear_id)
var/obj/item/weapon/card/id/id = H.get_idcard()
for(var/A in id.access)
if(A == access_security)
security++
if(!security)
//strip their stuff before they teleport into a cell :downs:
for(var/obj/item/weapon/W in H)
if(istype(W, /obj/item/organ/external))
continue
//don't strip organs
H.drop_from_inventory(W)
//teleport person to cell
H.loc = pick(prisonwarp)
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/prison(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(H), slot_shoes)
else
//teleport security person
H.loc = pick(prisonsecuritywarp)
prisonwarped += H
@@ -1,7 +1,7 @@
/datum/admin_secret_item/admin_secret/show_ai_laws
name = "Show AI laws"
/datum/admin_secret_item/admin_secret/show_ai_laws/execute(var/mob/user)
. = ..()
if(.)
user.client.holder.output_ai_laws()
/datum/admin_secret_item/admin_secret/show_ai_laws
name = "Show AI laws"
/datum/admin_secret_item/admin_secret/show_ai_laws/execute(var/mob/user)
. = ..()
if(.)
user.client.holder.output_ai_laws()
@@ -1,12 +1,12 @@
/datum/admin_secret_item/admin_secret/show_crew_manifest
name = "Show Crew Manifest"
/datum/admin_secret_item/admin_secret/show_crew_manifest/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat
dat += "<h4>Crew Manifest</h4>"
dat += data_core.get_manifest()
user << browse(dat, "window=manifest;size=370x420;can_close=1")
/datum/admin_secret_item/admin_secret/show_crew_manifest
name = "Show Crew Manifest"
/datum/admin_secret_item/admin_secret/show_crew_manifest/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat
dat += "<h4>Crew Manifest</h4>"
dat += data_core.get_manifest()
user << browse(dat, "window=manifest;size=370x420;can_close=1")
@@ -1,14 +1,14 @@
/datum/admin_secret_item/admin_secret/show_game_mode
name = "Show Game Mode"
/datum/admin_secret_item/admin_secret/show_game_mode/can_execute(var/mob/user)
if(!ticker)
return 0
return ..()
/datum/admin_secret_item/admin_secret/show_game_mode/execute(var/mob/user)
. = ..()
if(!.)
return
if (ticker.mode) tgui_alert_async(usr, "The game mode is [ticker.mode.name]")
else tgui_alert_async(usr, "For some reason there's a ticker, but not a game mode")
/datum/admin_secret_item/admin_secret/show_game_mode
name = "Show Game Mode"
/datum/admin_secret_item/admin_secret/show_game_mode/can_execute(var/mob/user)
if(!ticker)
return 0
return ..()
/datum/admin_secret_item/admin_secret/show_game_mode/execute(var/mob/user)
. = ..()
if(!.)
return
if (ticker.mode) tgui_alert_async(usr, "The game mode is [ticker.mode.name]")
else tgui_alert_async(usr, "For some reason there's a ticker, but not a game mode")
@@ -1,15 +1,15 @@
/datum/admin_secret_item/admin_secret/show_law_changes
name = "Show law changes"
/datum/admin_secret_item/admin_secret/show_law_changes/name()
return "Show Last [length(lawchanges)] Law change\s"
/datum/admin_secret_item/admin_secret/show_law_changes/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing last [length(lawchanges)] law changes.</B><HR>"
for(var/sig in lawchanges)
dat += "[sig]<BR>"
user << browse(dat, "window=lawchanges;size=800x500")
/datum/admin_secret_item/admin_secret/show_law_changes
name = "Show law changes"
/datum/admin_secret_item/admin_secret/show_law_changes/name()
return "Show Last [length(lawchanges)] Law change\s"
/datum/admin_secret_item/admin_secret/show_law_changes/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing last [length(lawchanges)] law changes.</B><HR>"
for(var/sig in lawchanges)
dat += "[sig]<BR>"
user << browse(dat, "window=lawchanges;size=800x500")
@@ -1,15 +1,15 @@
/datum/admin_secret_item/admin_secret/show_signalers
name = "Show Last Signalers"
/datum/admin_secret_item/admin_secret/show_signalers/name()
return "Show Last [length(lastsignalers)] Signaler\s"
/datum/admin_secret_item/admin_secret/show_signalers/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing last [length(lastsignalers)] signalers.</B><HR>"
for(var/sig in lastsignalers)
dat += "[sig]<BR>"
user << browse(dat, "window=lastsignalers;size=800x500")
/datum/admin_secret_item/admin_secret/show_signalers
name = "Show Last Signalers"
/datum/admin_secret_item/admin_secret/show_signalers/name()
return "Show Last [length(lastsignalers)] Signaler\s"
/datum/admin_secret_item/admin_secret/show_signalers/execute(var/mob/user)
. = ..()
if(!.)
return
var/dat = "<B>Showing last [length(lastsignalers)] signalers.</B><HR>"
for(var/sig in lastsignalers)
dat += "[sig]<BR>"
user << browse(dat, "window=lastsignalers;size=800x500")
@@ -1,7 +1,7 @@
/datum/admin_secret_item/admin_secret/traitors_and_objectives
name = "Show current traitors and objectives"
/datum/admin_secret_item/admin_secret/traitors_and_objectives/execute(var/mob/user)
. = ..()
if(.)
user.client.holder.check_antagonists()
/datum/admin_secret_item/admin_secret/traitors_and_objectives
name = "Show current traitors and objectives"
/datum/admin_secret_item/admin_secret/traitors_and_objectives/execute(var/mob/user)
. = ..()
if(.)
user.client.holder.check_antagonists()
@@ -1,11 +1,11 @@
/datum/admin_secret_item/final_solution/summon_narsie
name = "Summon Nar-Sie"
/datum/admin_secret_item/final_solution/summon_narsie/execute(var/mob/user)
. = ..()
if(!.)
return
var/choice = tgui_alert(user, "You sure you want to end the round and summon Nar-Sie at your location? Misuse of this could result in removal of flags or hilarity.","WARNING!",list("PRAISE SATAN", "Cancel"))
if(choice == "PRAISE SATAN")
new /obj/singularity/narsie/large(get_turf(user))
log_and_message_admins("has summoned Nar-Sie and brought about a new realm of suffering.", user)
/datum/admin_secret_item/final_solution/summon_narsie
name = "Summon Nar-Sie"
/datum/admin_secret_item/final_solution/summon_narsie/execute(var/mob/user)
. = ..()
if(!.)
return
var/choice = tgui_alert(user, "You sure you want to end the round and summon Nar-Sie at your location? Misuse of this could result in removal of flags or hilarity.","WARNING!",list("PRAISE SATAN", "Cancel"))
if(choice == "PRAISE SATAN")
new /obj/singularity/narsie/large(get_turf(user))
log_and_message_admins("has summoned Nar-Sie and brought about a new realm of suffering.", user)
@@ -1,13 +1,13 @@
/datum/admin_secret_item/final_solution/supermatter_cascade
name = "Supermatter Cascade"
/datum/admin_secret_item/final_solution/supermatter_cascade/execute(var/mob/user)
. = ..()
if(!.)
return
var/choice = tgui_alert(user, "You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or hilarity.","WARNING!", list("NO TIME TO EXPLAIN", "Cancel"))
if(choice == "NO TIME TO EXPLAIN")
explosion(get_turf(user), 8, 16, 24, 32, 1)
new /turf/unsimulated/wall/supermatter(get_turf(user))
SetUniversalState(/datum/universal_state/supermatter_cascade)
message_admins("[key_name_admin(user)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(user)]")
/datum/admin_secret_item/final_solution/supermatter_cascade
name = "Supermatter Cascade"
/datum/admin_secret_item/final_solution/supermatter_cascade/execute(var/mob/user)
. = ..()
if(!.)
return
var/choice = tgui_alert(user, "You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or hilarity.","WARNING!", list("NO TIME TO EXPLAIN", "Cancel"))
if(choice == "NO TIME TO EXPLAIN")
explosion(get_turf(user), 8, 16, 24, 32, 1)
new /turf/unsimulated/wall/supermatter(get_turf(user))
SetUniversalState(/datum/universal_state/supermatter_cascade)
message_admins("[key_name_admin(user)] has managed to destroy the universe with a supermatter cascade. Good job, [key_name_admin(user)]")
@@ -1,7 +1,7 @@
/datum/admin_secret_item/fun_secret/break_all_lights
name = "Break All Lights"
/datum/admin_secret_item/fun_secret/break_all_lights/execute(var/mob/user)
. = ..()
if(.)
lightsout(0,0)
/datum/admin_secret_item/fun_secret/break_all_lights
name = "Break All Lights"
/datum/admin_secret_item/fun_secret/break_all_lights/execute(var/mob/user)
. = ..()
if(.)
lightsout(0,0)
@@ -1,7 +1,7 @@
/datum/admin_secret_item/fun_secret/break_some_lights
name = "Break Some Lights"
/datum/admin_secret_item/fun_secret/break_some_lights/execute(var/mob/user)
. = ..()
if(.)
lightsout(1,2)
/datum/admin_secret_item/fun_secret/break_some_lights
name = "Break Some Lights"
/datum/admin_secret_item/fun_secret/break_some_lights/execute(var/mob/user)
. = ..()
if(.)
lightsout(1,2)
@@ -1,10 +1,10 @@
/datum/admin_secret_item/fun_secret/fix_all_lights
name = "Fix All Lights"
/datum/admin_secret_item/fun_secret/fix_all_lights/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/obj/machinery/light/L in machines)
L.fix()
/datum/admin_secret_item/fun_secret/fix_all_lights
name = "Fix All Lights"
/datum/admin_secret_item/fun_secret/fix_all_lights/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/obj/machinery/light/L in machines)
L.fix()
@@ -1,48 +1,48 @@
/datum/admin_secret_item/fun_secret/ghost_mode
name = "Ghost Mode"
var/list/affected_mobs
/datum/admin_secret_item/fun_secret/ghost_mode/New()
..()
affected_mobs = list()
/datum/admin_secret_item/fun_secret/ghost_mode/execute(var/mob/user)
. = ..()
if(!.)
return
var/list/affected_areas = list()
for(var/mob/M in living_mob_list)
if(M.stat == CONSCIOUS && !(M in affected_mobs))
affected_mobs |= M
switch(rand(1,4))
if(1)
M.show_message(text("<span class='notice'>You shudder as if cold...</span>"), 1)
if(2)
M.show_message(text("<span class='notice'>You feel something gliding across your back...</span>"), 1)
if(3)
M.show_message(text("<span class='notice'>Your eyes twitch, you feel like something you can't see is here...</span>"), 1)
if(4)
M.show_message(text("<span class='notice'>You notice something moving out of the corner of your eye, but nothing is there...</span>"), 1)
for(var/obj/W in orange(5,M))
if(prob(25) && !W.anchored)
step_rand(W)
var/area/A = get_area(M)
if(A.requires_power && !A.always_unpowered && A.power_light && (A.z in using_map.player_levels))
affected_areas |= get_area(M)
affected_mobs |= user
for(var/area/AffectedArea in affected_areas)
AffectedArea.power_light = 0
AffectedArea.power_change()
spawn(rand(25,50))
AffectedArea.power_light = 1
AffectedArea.power_change()
sleep(100)
for(var/mob/M in affected_mobs)
M.show_message(text("<span class='notice'>The chilling wind suddenly stops...</span>"), 1)
affected_mobs.Cut()
affected_areas.Cut()
/datum/admin_secret_item/fun_secret/ghost_mode
name = "Ghost Mode"
var/list/affected_mobs
/datum/admin_secret_item/fun_secret/ghost_mode/New()
..()
affected_mobs = list()
/datum/admin_secret_item/fun_secret/ghost_mode/execute(var/mob/user)
. = ..()
if(!.)
return
var/list/affected_areas = list()
for(var/mob/M in living_mob_list)
if(M.stat == CONSCIOUS && !(M in affected_mobs))
affected_mobs |= M
switch(rand(1,4))
if(1)
M.show_message(text("<span class='notice'>You shudder as if cold...</span>"), 1)
if(2)
M.show_message(text("<span class='notice'>You feel something gliding across your back...</span>"), 1)
if(3)
M.show_message(text("<span class='notice'>Your eyes twitch, you feel like something you can't see is here...</span>"), 1)
if(4)
M.show_message(text("<span class='notice'>You notice something moving out of the corner of your eye, but nothing is there...</span>"), 1)
for(var/obj/W in orange(5,M))
if(prob(25) && !W.anchored)
step_rand(W)
var/area/A = get_area(M)
if(A.requires_power && !A.always_unpowered && A.power_light && (A.z in using_map.player_levels))
affected_areas |= get_area(M)
affected_mobs |= user
for(var/area/AffectedArea in affected_areas)
AffectedArea.power_light = 0
AffectedArea.power_change()
spawn(rand(25,50))
AffectedArea.power_light = 1
AffectedArea.power_change()
sleep(100)
for(var/mob/M in affected_mobs)
M.show_message(text("<span class='notice'>The chilling wind suddenly stops...</span>"), 1)
affected_mobs.Cut()
affected_areas.Cut()
@@ -1,7 +1,7 @@
/datum/admin_secret_item/fun_secret/only_one
name = "There Can Be Only One"
/datum/admin_secret_item/fun_secret/only_one/execute(var/mob/user)
. = ..()
if(.)
only_one()
/datum/admin_secret_item/fun_secret/only_one
name = "There Can Be Only One"
/datum/admin_secret_item/fun_secret/only_one/execute(var/mob/user)
. = ..()
if(.)
only_one()
@@ -1,14 +1,14 @@
/datum/admin_secret_item/fun_secret/paintbal_mode
name = "Paintball Mode"
/datum/admin_secret_item/fun_secret/paintbal_mode/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/species in GLOB.all_species)
var/datum/species/S = GLOB.all_species[species]
S.blood_color = "rainbow"
for(var/obj/effect/decal/cleanable/blood/B in world)
B.basecolor = "rainbow"
B.update_icon()
/datum/admin_secret_item/fun_secret/paintbal_mode
name = "Paintball Mode"
/datum/admin_secret_item/fun_secret/paintbal_mode/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/species in GLOB.all_species)
var/datum/species/S = GLOB.all_species[species]
S.blood_color = "rainbow"
for(var/obj/effect/decal/cleanable/blood/B in world)
B.basecolor = "rainbow"
B.update_icon()
@@ -1,7 +1,7 @@
/datum/admin_secret_item/fun_secret/power_all_smes
name = "Power All SMES"
/datum/admin_secret_item/fun_secret/power_all_smes/execute(var/mob/user)
. = ..()
if(.)
power_restore_quick()
/datum/admin_secret_item/fun_secret/power_all_smes
name = "Power All SMES"
/datum/admin_secret_item/fun_secret/power_all_smes/execute(var/mob/user)
. = ..()
if(.)
power_restore_quick()
@@ -1,10 +1,10 @@
/datum/admin_secret_item/fun_secret/remove_all_clothing
name = "Remove ALL Clothing"
/datum/admin_secret_item/fun_secret/remove_all_clothing/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/obj/item/clothing/O in world)
qdel(O)
/datum/admin_secret_item/fun_secret/remove_all_clothing
name = "Remove ALL Clothing"
/datum/admin_secret_item/fun_secret/remove_all_clothing/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/obj/item/clothing/O in world)
qdel(O)
@@ -1,10 +1,10 @@
/datum/admin_secret_item/fun_secret/remove_internal_clothing
name = "Remove 'Internal' Clothing"
/datum/admin_secret_item/fun_secret/remove_internal_clothing/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/obj/item/clothing/under/O in world)
qdel(O)
/datum/admin_secret_item/fun_secret/remove_internal_clothing
name = "Remove 'Internal' Clothing"
/datum/admin_secret_item/fun_secret/remove_internal_clothing/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/obj/item/clothing/under/O in world)
qdel(O)
@@ -1,11 +1,11 @@
/datum/admin_secret_item/fun_secret/send_strike_team
name = "Send Strike Team"
/datum/admin_secret_item/fun_secret/send_strike_team/can_execute(var/mob/user)
if(!ticker) return 0
return ..()
/datum/admin_secret_item/fun_secret/send_strike_team/execute(var/mob/user)
. = ..()
if(.)
return user.client.strike_team()
/datum/admin_secret_item/fun_secret/send_strike_team
name = "Send Strike Team"
/datum/admin_secret_item/fun_secret/send_strike_team/can_execute(var/mob/user)
if(!ticker) return 0
return ..()
/datum/admin_secret_item/fun_secret/send_strike_team/execute(var/mob/user)
. = ..()
if(.)
return user.client.strike_team()
@@ -1,21 +1,21 @@
/datum/admin_secret_item/fun_secret/toggle_bomb_cap
name = "Toggle Bomb Cap"
permissions = R_SERVER
/datum/admin_secret_item/fun_secret/toggle_bomb_cap/execute(var/mob/user)
. = ..()
if(!.)
return
switch(max_explosion_range)
if(14) max_explosion_range = 16
if(16) max_explosion_range = 20
if(20) max_explosion_range = 28
if(28) max_explosion_range = 56
if(56) max_explosion_range = 128
if(128) max_explosion_range = 14
var/range_dev = max_explosion_range *0.25
var/range_high = max_explosion_range *0.5
var/range_low = max_explosion_range
message_admins("<span class='danger'>[key_name_admin(user)] changed the bomb cap to [range_dev], [range_high], [range_low]</span>", 1)
log_admin("[key_name_admin(user)] changed the bomb cap to [max_explosion_range]")
/datum/admin_secret_item/fun_secret/toggle_bomb_cap
name = "Toggle Bomb Cap"
permissions = R_SERVER
/datum/admin_secret_item/fun_secret/toggle_bomb_cap/execute(var/mob/user)
. = ..()
if(!.)
return
switch(max_explosion_range)
if(14) max_explosion_range = 16
if(16) max_explosion_range = 20
if(20) max_explosion_range = 28
if(28) max_explosion_range = 56
if(56) max_explosion_range = 128
if(128) max_explosion_range = 14
var/range_dev = max_explosion_range *0.25
var/range_high = max_explosion_range *0.5
var/range_low = max_explosion_range
message_admins("<span class='danger'>[key_name_admin(user)] changed the bomb cap to [range_dev], [range_high], [range_low]</span>", 1)
log_admin("[key_name_admin(user)] changed the bomb cap to [max_explosion_range]")
@@ -1,13 +1,13 @@
/datum/admin_secret_item/fun_secret/triple_ai_mode
name = "Triple AI Mode"
/datum/admin_secret_item/fun_secret/triple_ai_mode/can_execute(var/mob/user)
if(ticker && ticker.current_state > GAME_STATE_PREGAME)
return 0
return ..()
/datum/admin_secret_item/admin_secret/triple_ai_mode/execute(var/mob/user)
. = ..()
if(.)
user.client.triple_ai()
/datum/admin_secret_item/fun_secret/triple_ai_mode
name = "Triple AI Mode"
/datum/admin_secret_item/fun_secret/triple_ai_mode/can_execute(var/mob/user)
if(ticker && ticker.current_state > GAME_STATE_PREGAME)
return 0
return ..()
/datum/admin_secret_item/admin_secret/triple_ai_mode/execute(var/mob/user)
. = ..()
if(.)
user.client.triple_ai()
@@ -1,11 +1,11 @@
/datum/admin_secret_item/fun_secret/turn_humans_into_corgies
name = "Turn All Humans Into Corgies"
/datum/admin_secret_item/fun_secret/turn_humans_into_corgies/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/mob/living/carbon/human/H in mob_list)
spawn(0)
H.corgize()
/datum/admin_secret_item/fun_secret/turn_humans_into_corgies
name = "Turn All Humans Into Corgies"
/datum/admin_secret_item/fun_secret/turn_humans_into_corgies/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/mob/living/carbon/human/H in mob_list)
spawn(0)
H.corgize()
@@ -1,11 +1,11 @@
/datum/admin_secret_item/fun_secret/turn_humans_into_monkeys
name = "Turn All Humans Into Monkeys"
/datum/admin_secret_item/fun_secret/turn_humans_into_monkeys/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/mob/living/carbon/human/H in mob_list)
spawn(0)
H.monkeyize()
/datum/admin_secret_item/fun_secret/turn_humans_into_monkeys
name = "Turn All Humans Into Monkeys"
/datum/admin_secret_item/fun_secret/turn_humans_into_monkeys/execute(var/mob/user)
. = ..()
if(!.)
return
for(var/mob/living/carbon/human/H in mob_list)
spawn(0)
H.monkeyize()
@@ -1,31 +1,31 @@
/**********
* Gravity *
**********/
/datum/admin_secret_item/random_event/gravity
name = "Toggle Station Artificial Gravity"
/datum/admin_secret_item/random_event/gravity/can_execute(var/mob/user)
if(!(ticker && ticker.mode))
return 0
return ..()
/datum/admin_secret_item/random_event/gravity/execute(var/mob/user)
. = ..()
if(!.)
return
gravity_is_on = !gravity_is_on
for(var/area/A in world)
A.gravitychange(gravity_is_on)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Grav")
if(gravity_is_on)
log_admin("[key_name(user)] toggled gravity on.", 1)
message_admins("<span class='notice'>[key_name_admin(user)] toggled gravity on.</span>", 1)
command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.")
else
log_admin("[key_name(user)] toggled gravity off.", 1)
message_admins("<span class='notice'>[key_name_admin(usr)] toggled gravity off.</span>", 1)
command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.")
/**********
* Gravity *
**********/
/datum/admin_secret_item/random_event/gravity
name = "Toggle Station Artificial Gravity"
/datum/admin_secret_item/random_event/gravity/can_execute(var/mob/user)
if(!(ticker && ticker.mode))
return 0
return ..()
/datum/admin_secret_item/random_event/gravity/execute(var/mob/user)
. = ..()
if(!.)
return
gravity_is_on = !gravity_is_on
for(var/area/A in world)
A.gravitychange(gravity_is_on)
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Grav")
if(gravity_is_on)
log_admin("[key_name(user)] toggled gravity on.", 1)
message_admins("<span class='notice'>[key_name_admin(user)] toggled gravity on.</span>", 1)
command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.")
else
log_admin("[key_name(user)] toggled gravity off.", 1)
message_admins("<span class='notice'>[key_name_admin(usr)] toggled gravity off.</span>", 1)
command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.")
@@ -1,7 +1,7 @@
/datum/admin_secret_item/random_event/trigger_cordical_borer_infestation
name = "Trigger a Cortical Borer infestation"
/datum/admin_secret_item/random_event/trigger_cordical_borer_infestation/execute(var/mob/user)
. = ..()
if(.)
return borers.attempt_random_spawn()
/datum/admin_secret_item/random_event/trigger_cordical_borer_infestation
name = "Trigger a Cortical Borer infestation"
/datum/admin_secret_item/random_event/trigger_cordical_borer_infestation/execute(var/mob/user)
. = ..()
if(.)
return borers.attempt_random_spawn()
+36 -36
View File
@@ -1,36 +1,36 @@
/proc/getbrokeninhands()
var/icon/IL = new('icons/mob/items/lefthand.dmi')
var/list/Lstates = IL.IconStates()
var/icon/IR = new('icons/mob/items/righthand.dmi')
var/list/Rstates = IR.IconStates()
var/text
for(var/A in typesof(/obj/item))
var/obj/item/O = new A( locate(1,1,1) )
if(!O) continue
var/icon/J = new(O.icon)
var/list/istates = J.IconStates()
if(!Lstates.Find(O.icon_state) && !Lstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing left hand icon called \"[O.icon_state]\".\n"
if(!Rstates.Find(O.icon_state) && !Rstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing right hand icon called \"[O.icon_state]\".\n"
if(O.icon_state)
if(!istates.Find(O.icon_state))
text += "[O.type] is missing normal icon called \"[O.icon_state]\" in \"[O.icon]\".\n"
//if(O.item_state)
// if(!istates.Find(O.item_state))
// text += "[O.type] MISSING NORMAL ICON CALLED\n\"[O.item_state]\" IN \"[O.icon]\"\n"
//text+="\n"
qdel(O)
if(text)
var/F = file("broken_icons.txt")
fdel(F)
F << text
to_world("<span class='filter_system'>Completeled successfully and written to [F]</span>")
/proc/getbrokeninhands()
var/icon/IL = new('icons/mob/items/lefthand.dmi')
var/list/Lstates = IL.IconStates()
var/icon/IR = new('icons/mob/items/righthand.dmi')
var/list/Rstates = IR.IconStates()
var/text
for(var/A in typesof(/obj/item))
var/obj/item/O = new A( locate(1,1,1) )
if(!O) continue
var/icon/J = new(O.icon)
var/list/istates = J.IconStates()
if(!Lstates.Find(O.icon_state) && !Lstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing left hand icon called \"[O.icon_state]\".\n"
if(!Rstates.Find(O.icon_state) && !Rstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] is missing right hand icon called \"[O.icon_state]\".\n"
if(O.icon_state)
if(!istates.Find(O.icon_state))
text += "[O.type] is missing normal icon called \"[O.icon_state]\" in \"[O.icon]\".\n"
//if(O.item_state)
// if(!istates.Find(O.item_state))
// text += "[O.type] MISSING NORMAL ICON CALLED\n\"[O.item_state]\" IN \"[O.icon]\"\n"
//text+="\n"
qdel(O)
if(text)
var/F = file("broken_icons.txt")
fdel(F)
F << text
to_world("<span class='filter_system'>Completeled successfully and written to [F]</span>")
+63 -63
View File
@@ -1,63 +1,63 @@
/client/proc/cmd_admin_say(msg as text)
set category = "Special Verbs"
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
set hidden = 1
if(!check_rights(R_ADMIN)) //VOREStation Edit
return
msg = sanitize(msg)
if(!msg)
return
log_adminsay(msg,src)
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN, 0, C))
to_chat(C, "<span class='admin_channel'>" + create_text_tag("admin", "ADMIN:", C) + " <span class='name'>[key_name(usr, 1)]</span>([admin_jump_link(mob, src)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_mod_say(msg as text)
set category = "Special Verbs"
set name = "Msay"
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD|R_SERVER)) //VOREStation Edit
return
msg = sanitize(msg)
log_modsay(msg,src)
if (!msg)
return
var/sender_name = key_name(usr, 1)
if(check_rights(R_ADMIN, 0))
sender_name = "<span class='admin'>[sender_name]</span>"
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN|R_MOD|R_SERVER, 0, C)) //VOREStation Edit //YW Edit, fix issue with C missing from check_rights, so all admins could see mchat
to_chat(C, "<span class='mod_channel'>" + create_text_tag("mod", "MOD:", C) + " <span class='name'>[sender_name]</span>([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_event_say(msg as text)
set category = "Special Verbs"
set name = "Esay"
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD|R_EVENT|R_SERVER)) //VOREStation Edit
return
msg = sanitize(msg)
log_eventsay(msg,src)
if (!msg)
return
var/sender_name = key_name(usr, 1)
if(check_rights(R_ADMIN, 0))
sender_name = "<span class='admin'>[sender_name]</span>"
for(var/client/C in GLOB.admins)
to_chat(C, "<span class='event_channel'>" + create_text_tag("event", "EVENT:", C) + " <span class='name'>[sender_name]</span>([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_say(msg as text)
set category = "Special Verbs"
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
set hidden = 1
if(!check_rights(R_ADMIN)) //VOREStation Edit
return
msg = sanitize(msg)
if(!msg)
return
log_adminsay(msg,src)
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN, 0, C))
to_chat(C, "<span class='admin_channel'>" + create_text_tag("admin", "ADMIN:", C) + " <span class='name'>[key_name(usr, 1)]</span>([admin_jump_link(mob, src)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_mod_say(msg as text)
set category = "Special Verbs"
set name = "Msay"
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD|R_SERVER)) //VOREStation Edit
return
msg = sanitize(msg)
log_modsay(msg,src)
if (!msg)
return
var/sender_name = key_name(usr, 1)
if(check_rights(R_ADMIN, 0))
sender_name = "<span class='admin'>[sender_name]</span>"
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN|R_MOD|R_SERVER, 0, C)) //VOREStation Edit //YW Edit, fix issue with C missing from check_rights, so all admins could see mchat
to_chat(C, "<span class='mod_channel'>" + create_text_tag("mod", "MOD:", C) + " <span class='name'>[sender_name]</span>([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_event_say(msg as text)
set category = "Special Verbs"
set name = "Esay"
set hidden = 1
if(!check_rights(R_ADMIN|R_MOD|R_EVENT|R_SERVER)) //VOREStation Edit
return
msg = sanitize(msg)
log_eventsay(msg,src)
if (!msg)
return
var/sender_name = key_name(usr, 1)
if(check_rights(R_ADMIN, 0))
sender_name = "<span class='admin'>[sender_name]</span>"
for(var/client/C in GLOB.admins)
to_chat(C, "<span class='event_channel'>" + create_text_tag("event", "EVENT:", C) + " <span class='name'>[sender_name]</span>([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>")
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+59 -59
View File
@@ -1,60 +1,60 @@
/client/proc/atmosscan()
set category = "Mapping"
set name = "Check Piping"
set background = 1
if(!src.holder)
return
feedback_add_details("admin_verb","CP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(tgui_alert(usr, "WARNING: This command should not be run on a live server. Do you want to continue?", "Check Piping", list("No", "Yes")) == "No")
return
to_chat(usr, "Checking for disconnected pipes...")
//all plumbing - yes, some things might get stated twice, doesn't matter.
for (var/obj/machinery/atmospherics/plumbing in machines)
if (plumbing.nodealert)
to_chat(usr, "<span class='filter_adminlog warning'>Unconnected [plumbing.name] located at [plumbing.x],[plumbing.y],[plumbing.z] ([get_area(plumbing.loc)])</span>")
//Manifolds
for (var/obj/machinery/atmospherics/pipe/manifold/pipe in machines)
if (!pipe.node1 || !pipe.node2 || !pipe.node3)
to_chat(usr, "<span class='filter_adminlog warning'>Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])</span>")
//Pipes
for (var/obj/machinery/atmospherics/pipe/simple/pipe in machines)
if (!pipe.node1 || !pipe.node2)
to_chat(usr, "<span class='filter_adminlog warning'>Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])</span>")
to_chat(usr, "Checking for overlapping pipes...")
next_turf:
for(var/turf/T in world)
for(var/dir in cardinal)
var/list/connect_types = list(1 = 0, 2 = 0, 3 = 0)
for(var/obj/machinery/atmospherics/pipe in T)
if(dir & pipe.initialize_directions)
for(var/connect_type in pipe.connect_types)
connect_types[connect_type] += 1
if(connect_types[1] > 1 || connect_types[2] > 1 || connect_types[3] > 1)
to_chat(usr, "<span class='filter_adminlog warning'>Overlapping pipe ([pipe.name]) located at [T.x],[T.y],[T.z] ([get_area(T)])</span>")
continue next_turf
to_chat(usr, "Done")
/client/proc/powerdebug()
set category = "Mapping"
set name = "Check Power"
if(!src.holder)
return
feedback_add_details("admin_verb","CPOW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for (var/datum/powernet/PN in powernets)
if (!PN.nodes || !PN.nodes.len)
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "<span class='filter_adminlog'>Powernet with no nodes! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]</span>")
if (!PN.cables || (PN.cables.len < 10))
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
/client/proc/atmosscan()
set category = "Mapping"
set name = "Check Piping"
set background = 1
if(!src.holder)
return
feedback_add_details("admin_verb","CP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(tgui_alert(usr, "WARNING: This command should not be run on a live server. Do you want to continue?", "Check Piping", list("No", "Yes")) == "No")
return
to_chat(usr, "Checking for disconnected pipes...")
//all plumbing - yes, some things might get stated twice, doesn't matter.
for (var/obj/machinery/atmospherics/plumbing in machines)
if (plumbing.nodealert)
to_chat(usr, "<span class='filter_adminlog warning'>Unconnected [plumbing.name] located at [plumbing.x],[plumbing.y],[plumbing.z] ([get_area(plumbing.loc)])</span>")
//Manifolds
for (var/obj/machinery/atmospherics/pipe/manifold/pipe in machines)
if (!pipe.node1 || !pipe.node2 || !pipe.node3)
to_chat(usr, "<span class='filter_adminlog warning'>Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])</span>")
//Pipes
for (var/obj/machinery/atmospherics/pipe/simple/pipe in machines)
if (!pipe.node1 || !pipe.node2)
to_chat(usr, "<span class='filter_adminlog warning'>Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])</span>")
to_chat(usr, "Checking for overlapping pipes...")
next_turf:
for(var/turf/T in world)
for(var/dir in cardinal)
var/list/connect_types = list(1 = 0, 2 = 0, 3 = 0)
for(var/obj/machinery/atmospherics/pipe in T)
if(dir & pipe.initialize_directions)
for(var/connect_type in pipe.connect_types)
connect_types[connect_type] += 1
if(connect_types[1] > 1 || connect_types[2] > 1 || connect_types[3] > 1)
to_chat(usr, "<span class='filter_adminlog warning'>Overlapping pipe ([pipe.name]) located at [T.x],[T.y],[T.z] ([get_area(T)])</span>")
continue next_turf
to_chat(usr, "Done")
/client/proc/powerdebug()
set category = "Mapping"
set name = "Check Power"
if(!src.holder)
return
feedback_add_details("admin_verb","CPOW") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for (var/datum/powernet/PN in powernets)
if (!PN.nodes || !PN.nodes.len)
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "<span class='filter_adminlog'>Powernet with no nodes! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]</span>")
if (!PN.cables || (PN.cables.len < 10))
if(PN.cables && (PN.cables.len > 1))
var/obj/structure/cable/C = PN.cables[1]
to_chat(usr, "<span class='filter_adminlog'>Powernet with fewer than 10 cables! (number [PN.number]) - example cable at [C.x], [C.y], [C.z] in area [get_area(C.loc)]</span>")
File diff suppressed because it is too large Load Diff
+31 -31
View File
@@ -1,31 +1,31 @@
/client/proc/dsay(msg as text)
set category = "Special Verbs"
set name = "Dsay" //Gave this shit a shorter name so you only have to time out "dsay" rather than "dead say" to use it --NeoFite
set hidden = 1
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
if(!src.mob)
return
if(prefs.muted & MUTE_DEADCHAT)
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
return
if(!is_preference_enabled(/datum/client_preference/show_dsay))
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
return
if (src.handle_spam_prevention(msg,MUTE_DEADCHAT))
return
var/stafftype = uppertext(holder.rank)
msg = sanitize(msg)
log_admin("DSAY: [key_name(src)] : [msg]")
if (!msg)
return
say_dead_direct("<span class='name'>[stafftype]([src.holder.fakekey ? src.holder.fakekey : src.key])</span> says, <span class='message'>\"[msg]\"</span>")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/dsay(msg as text)
set category = "Special Verbs"
set name = "Dsay" //Gave this shit a shorter name so you only have to time out "dsay" rather than "dead say" to use it --NeoFite
set hidden = 1
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
if(!src.mob)
return
if(prefs.muted & MUTE_DEADCHAT)
to_chat(src, "<span class='warning'>You cannot send DSAY messages (muted).</span>")
return
if(!is_preference_enabled(/datum/client_preference/show_dsay))
to_chat(src, "<span class='warning'>You have deadchat muted.</span>")
return
if (src.handle_spam_prevention(msg,MUTE_DEADCHAT))
return
var/stafftype = uppertext(holder.rank)
msg = sanitize(msg)
log_admin("DSAY: [key_name(src)] : [msg]")
if (!msg)
return
say_dead_direct("<span class='name'>[stafftype]([src.holder.fakekey ? src.holder.fakekey : src.key])</span> says, <span class='message'>\"[msg]\"</span>")
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+187 -187
View File
@@ -1,187 +1,187 @@
/client/proc/air_report()
set category = "Debug"
set name = "Show Air Report"
if(!master_controller || !air_master)
tgui_alert_async(usr,"Master_controller or air_master not found.","Air Report")
return
var/active_groups = air_master.active_zones
var/inactive_groups = air_master.zones.len - active_groups
var/hotspots = 0
for(var/obj/fire/hotspot in world)
hotspots++
var/active_on_main_station = 0
var/inactive_on_main_station = 0
for(var/zone/zone in air_master.zones)
var/turf/simulated/turf = locate() in zone.contents
if(turf?.z in using_map.station_levels)
if(zone.needs_update)
active_on_main_station++
else
inactive_on_main_station++
var/output = {"<B>AIR SYSTEMS REPORT</B><HR>
<B>General Processing Data</B><BR>
Cycle: [air_master.current_cycle]<br>
Groups: [air_master.zones.len]<BR>
---- <I>Active:</I> [active_groups]<BR>
---- <I>Inactive:</I> [inactive_groups]<BR><br>
---- <I>Active on station:</i> [active_on_main_station]<br>
---- <i>Inactive on station:</i> [inactive_on_main_station]<br>
<BR>
<B>Special Processing Data</B><BR>
Hotspot Processing: [hotspots]<BR>
<br>
<B>Geometry Processing Data</B><BR>
Tile Update: [air_master.tiles_to_update.len]<BR>
"}
usr << browse(output,"window=airreport")
/client/proc/fix_next_move()
set category = "Debug"
set name = "Unfreeze Everyone"
var/largest_move_time = 0
var/largest_click_time = 0
var/mob/largest_move_mob = null
var/mob/largest_click_mob = null
for(var/mob/M in mob_list)
if(!M.client)
continue
if(M.next_move >= largest_move_time)
largest_move_mob = M
if(M.next_move > world.time)
largest_move_time = M.next_move - world.time
else
largest_move_time = 1
if(M.next_click >= largest_click_time)
largest_click_mob = M
if(M.next_click > world.time)
largest_click_time = M.next_click - world.time
else
largest_click_time = 0
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] next_click = [M.next_click] world.time = [world.time]")
M.next_move = 1
M.next_click = 0
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
message_admins("world.time = [world.time]", 1)
feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/radio_report()
set category = "Debug"
set name = "Radio report"
var/output = "<b>Radio Report</b><hr>"
for (var/fq in radio_controller.frequencies)
output += "<b>Freq: [fq]</b><br>"
var/datum/radio_frequency/fqs = radio_controller.frequencies[fq]
if (!fqs)
output += "&nbsp;&nbsp;<b>ERROR</b><br>"
continue
for (var/radio_filter in fqs.devices)
var/list/f = fqs.devices[radio_filter]
if (!f)
output += "&nbsp;&nbsp;[radio_filter]: ERROR<br>"
continue
output += "&nbsp;&nbsp;[radio_filter]: [f.len]<br>"
for (var/device in f)
if (isobj(device))
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])<br>"
else
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device]<br>"
usr << browse(output,"window=radioreport")
feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reload_admins()
set name = "Reload Admins"
set category = "Debug"
if(!check_rights(R_SERVER)) return
message_admins("[usr] manually reloaded admins")
load_admins()
feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reload_eventMs()
set name = "Reload Event Managers"
set category = "Debug"
if(!check_rights(R_SERVER)) return
message_admins("[usr] manually reloaded Event Managers")
world.load_mods()
//todo:
/client/proc/jump_to_dead_group()
set name = "Jump to dead group"
set category = "Debug"
/*
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
if(!air_master)
to_chat(usr, "Cannot find air_system")
return
var/datum/air_group/dead_groups = list()
for(var/datum/air_group/group in air_master.air_groups)
if (!group.group_processing)
dead_groups += group
var/datum/air_group/dest_group = pick(dead_groups)
usr.loc = pick(dest_group.members)
feedback_add_details("admin_verb","JDAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
*/
/client/proc/kill_airgroup()
set name = "Kill Local Airgroup"
set desc = "Use this to allow manual manupliation of atmospherics."
set category = "Debug"
/*
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
if(!air_master)
to_chat(usr, "Cannot find air_system")
return
var/turf/T = get_turf(usr)
if(istype(T, /turf/simulated))
var/datum/air_group/AG = T:parent
AG.next_check = 30
AG.group_processing = 0
else
to_chat(usr, "Local airgroup is unsimulated!")
feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
*/
/client/proc/print_jobban_old()
set name = "Print Jobban Log"
set desc = "This spams all the active jobban entries for the current round to standard output."
set category = "Debug"
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in jobban_keylist)
to_chat(usr, "[t]")
/client/proc/print_jobban_old_filter()
set name = "Search Jobban Log"
set desc = "This searches all the active jobban entries for the current round and outputs the results to standard output."
set category = "Debug"
var/job_filter = tgui_input_text(usr, "Contains what?","Job Filter")
if(!job_filter)
return
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in jobban_keylist)
if(findtext(t, job_filter))
to_chat(usr, "[t]")
/client/proc/air_report()
set category = "Debug"
set name = "Show Air Report"
if(!master_controller || !air_master)
tgui_alert_async(usr,"Master_controller or air_master not found.","Air Report")
return
var/active_groups = air_master.active_zones
var/inactive_groups = air_master.zones.len - active_groups
var/hotspots = 0
for(var/obj/fire/hotspot in world)
hotspots++
var/active_on_main_station = 0
var/inactive_on_main_station = 0
for(var/zone/zone in air_master.zones)
var/turf/simulated/turf = locate() in zone.contents
if(turf?.z in using_map.station_levels)
if(zone.needs_update)
active_on_main_station++
else
inactive_on_main_station++
var/output = {"<B>AIR SYSTEMS REPORT</B><HR>
<B>General Processing Data</B><BR>
Cycle: [air_master.current_cycle]<br>
Groups: [air_master.zones.len]<BR>
---- <I>Active:</I> [active_groups]<BR>
---- <I>Inactive:</I> [inactive_groups]<BR><br>
---- <I>Active on station:</i> [active_on_main_station]<br>
---- <i>Inactive on station:</i> [inactive_on_main_station]<br>
<BR>
<B>Special Processing Data</B><BR>
Hotspot Processing: [hotspots]<BR>
<br>
<B>Geometry Processing Data</B><BR>
Tile Update: [air_master.tiles_to_update.len]<BR>
"}
usr << browse(output,"window=airreport")
/client/proc/fix_next_move()
set category = "Debug"
set name = "Unfreeze Everyone"
var/largest_move_time = 0
var/largest_click_time = 0
var/mob/largest_move_mob = null
var/mob/largest_click_mob = null
for(var/mob/M in mob_list)
if(!M.client)
continue
if(M.next_move >= largest_move_time)
largest_move_mob = M
if(M.next_move > world.time)
largest_move_time = M.next_move - world.time
else
largest_move_time = 1
if(M.next_click >= largest_click_time)
largest_click_mob = M
if(M.next_click > world.time)
largest_click_time = M.next_click - world.time
else
largest_click_time = 0
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] next_click = [M.next_click] world.time = [world.time]")
M.next_move = 1
M.next_click = 0
message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
message_admins("world.time = [world.time]", 1)
feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/proc/radio_report()
set category = "Debug"
set name = "Radio report"
var/output = "<b>Radio Report</b><hr>"
for (var/fq in radio_controller.frequencies)
output += "<b>Freq: [fq]</b><br>"
var/datum/radio_frequency/fqs = radio_controller.frequencies[fq]
if (!fqs)
output += "&nbsp;&nbsp;<b>ERROR</b><br>"
continue
for (var/radio_filter in fqs.devices)
var/list/f = fqs.devices[radio_filter]
if (!f)
output += "&nbsp;&nbsp;[radio_filter]: ERROR<br>"
continue
output += "&nbsp;&nbsp;[radio_filter]: [f.len]<br>"
for (var/device in f)
if (isobj(device))
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])<br>"
else
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device]<br>"
usr << browse(output,"window=radioreport")
feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reload_admins()
set name = "Reload Admins"
set category = "Debug"
if(!check_rights(R_SERVER)) return
message_admins("[usr] manually reloaded admins")
load_admins()
feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reload_eventMs()
set name = "Reload Event Managers"
set category = "Debug"
if(!check_rights(R_SERVER)) return
message_admins("[usr] manually reloaded Event Managers")
world.load_mods()
//todo:
/client/proc/jump_to_dead_group()
set name = "Jump to dead group"
set category = "Debug"
/*
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
if(!air_master)
to_chat(usr, "Cannot find air_system")
return
var/datum/air_group/dead_groups = list()
for(var/datum/air_group/group in air_master.air_groups)
if (!group.group_processing)
dead_groups += group
var/datum/air_group/dest_group = pick(dead_groups)
usr.loc = pick(dest_group.members)
feedback_add_details("admin_verb","JDAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
*/
/client/proc/kill_airgroup()
set name = "Kill Local Airgroup"
set desc = "Use this to allow manual manupliation of atmospherics."
set category = "Debug"
/*
if(!holder)
to_chat(src, "Only administrators may use this command.")
return
if(!air_master)
to_chat(usr, "Cannot find air_system")
return
var/turf/T = get_turf(usr)
if(istype(T, /turf/simulated))
var/datum/air_group/AG = T:parent
AG.next_check = 30
AG.group_processing = 0
else
to_chat(usr, "Local airgroup is unsimulated!")
feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
*/
/client/proc/print_jobban_old()
set name = "Print Jobban Log"
set desc = "This spams all the active jobban entries for the current round to standard output."
set category = "Debug"
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in jobban_keylist)
to_chat(usr, "[t]")
/client/proc/print_jobban_old_filter()
set name = "Search Jobban Log"
set desc = "This searches all the active jobban entries for the current round and outputs the results to standard output."
set category = "Debug"
var/job_filter = tgui_input_text(usr, "Contains what?","Job Filter")
if(!job_filter)
return
to_chat(usr, "<b>Jobbans active in this round.</b>")
for(var/t in jobban_keylist)
if(findtext(t, job_filter))
to_chat(usr, "[t]")
+23 -23
View File
@@ -1,23 +1,23 @@
//Merged Doohl's and the existing ticklag as they both had good elements about them ~
//Replaces the old Ticklag verb, fps is easier to understand
/client/proc/set_server_fps()
set category = "Debug"
set name = "Set Server FPS"
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
if(!check_rights(R_DEBUG))
return
var/new_fps = round(tgui_input_number(usr, "Sets game frames-per-second. Can potentially break the game (default: [config.fps])", "FPS", world.fps), round(config.fps * 1.5))
if(new_fps <= 0)
to_chat(src, "<span class='danger'>Error: set_server_fps(): Invalid world.fps value. No changes made.</span>")
return
if(new_fps > config.fps * 1.5)
if(tgui_alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]", "Warning!", list("Confirm", "ABORT-ABORT-ABORT")) != "Confirm")
return
var/msg = "[key_name(src)] has modified world.fps to [new_fps]"
log_admin(msg, 0)
message_admins(msg, 0)
world.change_fps(new_fps)
feedback_add_details("admin_verb", "SETFPS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//Merged Doohl's and the existing ticklag as they both had good elements about them ~
//Replaces the old Ticklag verb, fps is easier to understand
/client/proc/set_server_fps()
set category = "Debug"
set name = "Set Server FPS"
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
if(!check_rights(R_DEBUG))
return
var/new_fps = round(tgui_input_number(usr, "Sets game frames-per-second. Can potentially break the game (default: [config.fps])", "FPS", world.fps), round(config.fps * 1.5))
if(new_fps <= 0)
to_chat(src, "<span class='danger'>Error: set_server_fps(): Invalid world.fps value. No changes made.</span>")
return
if(new_fps > config.fps * 1.5)
if(tgui_alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]", "Warning!", list("Confirm", "ABORT-ABORT-ABORT")) != "Confirm")
return
var/msg = "[key_name(src)] has modified world.fps to [new_fps]"
log_admin(msg, 0)
message_admins(msg, 0)
world.change_fps(new_fps)
feedback_add_details("admin_verb", "SETFPS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+311 -311
View File
@@ -1,311 +1,311 @@
//world/proc/shelleo
#define SHELLEO_ERRORLEVEL 1
#define SHELLEO_STDOUT 2
#define SHELLEO_STDERR 3
var/list/sounds_cache = list()
/client/proc/play_sound(S as sound)
set category = "Fun"
set name = "Play Global Sound"
if(!check_rights(R_SOUNDS))
return
var/freq = 1
var/vol = tgui_input_number(usr, "What volume would you like the sound to play at?",, 100, 100, 1)
if(!vol)
return
vol = clamp(vol, 1, 100)
var/sound/admin_sound = new()
admin_sound.file = S
admin_sound.priority = 250
admin_sound.channel = 777
admin_sound.frequency = freq
admin_sound.wait = 1
admin_sound.repeat = FALSE
admin_sound.status = SOUND_STREAM
admin_sound.volume = vol
sounds_cache += S
var/res = tgui_alert(usr, "Show the title of this song ([S]) to the players?\nOptions 'Yes' and 'No' will play the sound.",, list("Yes", "No", "Cancel"))
switch(res)
if("Yes")
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>", confidential = TRUE)
if("Cancel")
return
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in player_list)
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis))
admin_sound.volume = vol * M.client.admin_music_volume
SEND_SOUND(M, admin_sound)
admin_sound.volume = vol
feedback_add_details("admin_verb", "Play Global Sound")
/client/proc/play_local_sound(S as sound)
set category = "Fun"
set name = "Play Local Sound"
if(!check_rights(R_SOUNDS))
return
log_admin("[key_name(src)] played a local sound [S]")
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
playsound(src.mob, S, 50, 0, 0)
feedback_add_details("admin_verb", "Play Local Sound")
/client/proc/play_direct_mob_sound(S as sound, mob/M)
set category = "Fun"
set name = "Play Direct Mob Sound"
if(!check_rights(R_SOUNDS))
return
if(!M)
M = tgui_input_list(usr, "Choose a mob to play the sound to. Only they will hear it.", "Play Mob Sound", sortNames(player_list))
if(!M || QDELETED(M))
return
log_admin("[key_name(src)] played a direct mob sound [S] to [M].")
message_admins("[key_name_admin(src)] played a direct mob sound [S] to [ADMIN_LOOKUPFLW(M)].")
SEND_SOUND(M, S)
feedback_add_details("admin_verb", "Play Direct Mob Sound")
/client/proc/play_z_sound(S as sound)
set category = "Fun"
set name = "Play Z Sound"
if(!check_rights(R_SOUNDS)) return
var/target_z = mob.z
var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = 777)
uploaded_sound.priority = 250
sounds_cache += S
if(tgui_alert(usr, "Do you ready?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request", list("Play","Cancel")) == "Cancel")
return
log_admin("[key_name(src)] played sound [S] on Z[target_z]")
message_admins("[key_name_admin(src)] played sound [S] on Z[target_z]", 1)
for(var/mob/M in player_list)
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis) && M.z == target_z)
M << uploaded_sound
feedback_add_details("admin_verb", "Play Z Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_server_sound()
set category = "Fun"
set name = "Play Server Sound"
if(!check_rights(R_SOUNDS))
return
var/list/sounds = file2list("sound/serversound_list.txt");
sounds += "--CANCEL--"
sounds += sounds_cache
var/melody = tgui_input_list(usr, "Select a sound from the server to play", "Server sound list", sounds, "--CANCEL--")
if(melody == "--CANCEL--")
return
play_sound(melody)
feedback_add_details("admin_verb", "Play Server Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
///Takes an input from either proc/play_web_sound or the request manager and runs it through youtube-dl and prompts the user before playing it to the server.
/proc/web_sound(mob/user, input, credit)
if(!check_rights(R_SOUNDS))
return
var/ytdl = config.invoke_youtubedl
if(!ytdl)
to_chat(user, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>", confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
return
var/web_sound_url = ""
var/stop_web_sounds = FALSE
var/list/music_extra_data = list()
var/duration = 0
if(istext(input))
var/shell_scrubbed_input = shell_url_scrub(input)
var/list/output = world.shelleo("[ytdl] --geo-bypass --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height <= 360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --dump-single-json --no-playlist -- \"[shell_scrubbed_input]\"")
var/errorlevel = output[SHELLEO_ERRORLEVEL]
var/stdout = output[SHELLEO_STDOUT]
var/stderr = output[SHELLEO_STDERR]
if(errorlevel)
to_chat(user, "<span class='boldwarning'>Youtube-dl URL retrieval FAILED:</span>", confidential = TRUE)
to_chat(user, "<span class='warning'>[stderr]</span>", confidential = TRUE)
return
var/list/data
try
data = json_decode(stdout)
catch(var/exception/e)
to_chat(user, "<span class='boldwarning'>Youtube-dl JSON parsing FAILED:</span>", confidential = TRUE)
to_chat(user, "<span class='warning'>[e]: [stdout]</span>", confidential = TRUE)
return
if (data["url"])
web_sound_url = data["url"]
var/title = "[data["title"]]"
var/webpage_url = title
if (data["webpage_url"])
webpage_url = "<a href=\"[data["webpage_url"]]\">[title]</a>"
music_extra_data["duration"] = DisplayTimeText(data["duration"] * 1 SECONDS)
music_extra_data["link"] = data["webpage_url"]
music_extra_data["artist"] = data["artist"]
music_extra_data["upload_date"] = data["upload_date"]
music_extra_data["album"] = data["album"]
duration = data["duration"] * 1 SECONDS
if (duration > 10 MINUTES)
if((tgui_alert(user, "This song is over 10 minutes long. Are you sure you want to play it?", "Length Warning!", list("No", "Yes", "Cancel")) != "Yes"))
return
var/res = tgui_alert(user, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No", "Cancel"))
switch(res)
if("Yes")
music_extra_data["title"] = data["title"]
if("No")
music_extra_data["link"] = "Song Link Hidden"
music_extra_data["title"] = "Song Title Hidden"
music_extra_data["artist"] = "Song Artist Hidden"
music_extra_data["upload_date"] = "Song Upload Date Hidden"
music_extra_data["album"] = "Song Album Hidden"
if("Cancel", null)
return
var/anon = tgui_alert(user, "Display who played the song?", "Credit Yourself?", list("Yes", "No", "Cancel"))
switch(anon)
if("Yes")
if(res == "Yes")
to_chat(world, "<span class='boldannounce'>[user.key] played: [webpage_url]</span>", confidential = TRUE)
else
to_chat(world, "<span class='boldannounce'>[user.key] played a sound</span>", confidential = TRUE)
if("No")
if(res == "Yes")
to_chat(world, "<span class='boldannounce'>An admin played: [webpage_url]</span>", confidential = TRUE)
if("Cancel", null)
return
if(credit)
to_chat(world, "<span class='boldannounce'>[credit]</span>", confidential = TRUE)
//SSblackbox.record_feedback("nested tally", "played_url", 1, list("[user.ckey]", "[input]"))
log_admin("[key_name(user)] played web sound: [input]")
message_admins("[key_name(user)] played web sound: [input]")
else
//pressed ok with blank
log_admin("[key_name(user)] stopped web sounds.")
message_admins("[key_name(user)] stopped web sounds.")
web_sound_url = null
stop_web_sounds = TRUE
if(web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol))
tgui_alert(user, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol. This is a security risk and the sound will not be played.", "Security Risk", list("OK"))
to_chat(user, "<span class='boldwarning'>BLOCKED: Content URL not using HTTP(S) Protocol!</span>", confidential = TRUE)
return
if(web_sound_url || stop_web_sounds)
for(var/m in player_list)
var/mob/M = m
var/client/C = M.client
if(C.is_preference_enabled(/datum/client_preference/play_admin_midis))
if(!stop_web_sounds)
C.tgui_panel?.play_music(web_sound_url, music_extra_data)
else
C.tgui_panel?.stop_music()
S_TIMER_COOLDOWN_START(SStimer, COOLDOWN_INTERNET_SOUND, duration)
feedback_add_details("admin_verb", "Play Internet Sound")
/client/proc/play_web_sound()
set category = "Fun"
set name = "Play Internet Sound"
if(!check_rights(R_SOUNDS))
return
var/ytdl = config.invoke_youtubedl
if(!ytdl)
to_chat(src, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>", confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
return
if(S_TIMER_COOLDOWN_TIMELEFT(SStimer, COOLDOWN_INTERNET_SOUND))
if(tgui_alert(usr, "Someone else is already playing an Internet sound! It has [DisplayTimeText(S_TIMER_COOLDOWN_TIMELEFT(SStimer, COOLDOWN_INTERNET_SOUND), 1)] remaining. \
Would you like to override?", "Musicalis Interruptus", list("No","Yes")) != "Yes")
return
var/web_sound_input = tgui_input_text(usr, "Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound", null)
if(length(web_sound_input))
web_sound_input = trim(web_sound_input)
if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol))
to_chat(src, "<span class='boldwarning'>Non-http(s) URIs are not allowed.</span>", confidential = TRUE)
to_chat(src, "<span class='warning'>For youtube-dl shortcuts like ytsearch: please use the appropriate full URL from the website.</span>", confidential = TRUE)
return
web_sound(usr, web_sound_input)
else
web_sound(usr, null)
/client/proc/stop_sounds()
set category = "Debug"
set name = "Stop All Playing Sounds"
if(!src.holder)
return
log_admin("[key_name(src)] stopped all currently playing sounds.")
message_admins("[key_name_admin(src)] stopped all currently playing sounds.")
for(var/mob/M in player_list)
SEND_SOUND(M, sound(null))
var/client/C = M.client
C?.tgui_panel?.stop_music()
S_TIMER_COOLDOWN_RESET(SStimer, COOLDOWN_INTERNET_SOUND)
feedback_add_details("admin_verb", "Stop All Playing Sounds")
//world/proc/shelleo
#undef SHELLEO_ERRORLEVEL
#undef SHELLEO_STDOUT
#undef SHELLEO_STDERR
/*
/client/proc/cuban_pete()
set category = "Fun"
set name = "Cuban Pete Time"
message_admins("[key_name_admin(usr)] has declared Cuban Pete Time!", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'cubanpetetime.ogg'
for(var/mob/living/carbon/human/CP in human_mob_list)
if(CP.real_name=="Cuban Pete" && CP.key!="Rosham")
to_chat(CP, "Your body can't contain the rhumba beat")
CP.gib()
/client/proc/bananaphone()
set category = "Fun"
set name = "Banana Phone"
message_admins("[key_name_admin(usr)] has activated Banana Phone!", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'bananaphone.ogg'
/client/proc/space_asshole()
set category = "Fun"
set name = "Space Asshole"
message_admins("[key_name_admin(usr)] has played the Space Asshole Hymn.", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'sound/music/space_asshole.ogg'
/client/proc/honk_theme()
set category = "Fun"
set name = "Honk"
message_admins("[key_name_admin(usr)] has creeped everyone out with Blackest Honks.", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'honk_theme.ogg'*/
//world/proc/shelleo
#define SHELLEO_ERRORLEVEL 1
#define SHELLEO_STDOUT 2
#define SHELLEO_STDERR 3
var/list/sounds_cache = list()
/client/proc/play_sound(S as sound)
set category = "Fun"
set name = "Play Global Sound"
if(!check_rights(R_SOUNDS))
return
var/freq = 1
var/vol = tgui_input_number(usr, "What volume would you like the sound to play at?",, 100, 100, 1)
if(!vol)
return
vol = clamp(vol, 1, 100)
var/sound/admin_sound = new()
admin_sound.file = S
admin_sound.priority = 250
admin_sound.channel = 777
admin_sound.frequency = freq
admin_sound.wait = 1
admin_sound.repeat = FALSE
admin_sound.status = SOUND_STREAM
admin_sound.volume = vol
sounds_cache += S
var/res = tgui_alert(usr, "Show the title of this song ([S]) to the players?\nOptions 'Yes' and 'No' will play the sound.",, list("Yes", "No", "Cancel"))
switch(res)
if("Yes")
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>", confidential = TRUE)
if("Cancel")
return
log_admin("[key_name(src)] played sound [S]")
message_admins("[key_name_admin(src)] played sound [S]", 1)
for(var/mob/M in player_list)
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis))
admin_sound.volume = vol * M.client.admin_music_volume
SEND_SOUND(M, admin_sound)
admin_sound.volume = vol
feedback_add_details("admin_verb", "Play Global Sound")
/client/proc/play_local_sound(S as sound)
set category = "Fun"
set name = "Play Local Sound"
if(!check_rights(R_SOUNDS))
return
log_admin("[key_name(src)] played a local sound [S]")
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
playsound(src.mob, S, 50, 0, 0)
feedback_add_details("admin_verb", "Play Local Sound")
/client/proc/play_direct_mob_sound(S as sound, mob/M)
set category = "Fun"
set name = "Play Direct Mob Sound"
if(!check_rights(R_SOUNDS))
return
if(!M)
M = tgui_input_list(usr, "Choose a mob to play the sound to. Only they will hear it.", "Play Mob Sound", sortNames(player_list))
if(!M || QDELETED(M))
return
log_admin("[key_name(src)] played a direct mob sound [S] to [M].")
message_admins("[key_name_admin(src)] played a direct mob sound [S] to [ADMIN_LOOKUPFLW(M)].")
SEND_SOUND(M, S)
feedback_add_details("admin_verb", "Play Direct Mob Sound")
/client/proc/play_z_sound(S as sound)
set category = "Fun"
set name = "Play Z Sound"
if(!check_rights(R_SOUNDS)) return
var/target_z = mob.z
var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = 777)
uploaded_sound.priority = 250
sounds_cache += S
if(tgui_alert(usr, "Do you ready?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request", list("Play","Cancel")) == "Cancel")
return
log_admin("[key_name(src)] played sound [S] on Z[target_z]")
message_admins("[key_name_admin(src)] played sound [S] on Z[target_z]", 1)
for(var/mob/M in player_list)
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis) && M.z == target_z)
M << uploaded_sound
feedback_add_details("admin_verb", "Play Z Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/play_server_sound()
set category = "Fun"
set name = "Play Server Sound"
if(!check_rights(R_SOUNDS))
return
var/list/sounds = file2list("sound/serversound_list.txt");
sounds += "--CANCEL--"
sounds += sounds_cache
var/melody = tgui_input_list(usr, "Select a sound from the server to play", "Server sound list", sounds, "--CANCEL--")
if(melody == "--CANCEL--")
return
play_sound(melody)
feedback_add_details("admin_verb", "Play Server Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
///Takes an input from either proc/play_web_sound or the request manager and runs it through youtube-dl and prompts the user before playing it to the server.
/proc/web_sound(mob/user, input, credit)
if(!check_rights(R_SOUNDS))
return
var/ytdl = config.invoke_youtubedl
if(!ytdl)
to_chat(user, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>", confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
return
var/web_sound_url = ""
var/stop_web_sounds = FALSE
var/list/music_extra_data = list()
var/duration = 0
if(istext(input))
var/shell_scrubbed_input = shell_url_scrub(input)
var/list/output = world.shelleo("[ytdl] --geo-bypass --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height <= 360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --dump-single-json --no-playlist -- \"[shell_scrubbed_input]\"")
var/errorlevel = output[SHELLEO_ERRORLEVEL]
var/stdout = output[SHELLEO_STDOUT]
var/stderr = output[SHELLEO_STDERR]
if(errorlevel)
to_chat(user, "<span class='boldwarning'>Youtube-dl URL retrieval FAILED:</span>", confidential = TRUE)
to_chat(user, "<span class='warning'>[stderr]</span>", confidential = TRUE)
return
var/list/data
try
data = json_decode(stdout)
catch(var/exception/e)
to_chat(user, "<span class='boldwarning'>Youtube-dl JSON parsing FAILED:</span>", confidential = TRUE)
to_chat(user, "<span class='warning'>[e]: [stdout]</span>", confidential = TRUE)
return
if (data["url"])
web_sound_url = data["url"]
var/title = "[data["title"]]"
var/webpage_url = title
if (data["webpage_url"])
webpage_url = "<a href=\"[data["webpage_url"]]\">[title]</a>"
music_extra_data["duration"] = DisplayTimeText(data["duration"] * 1 SECONDS)
music_extra_data["link"] = data["webpage_url"]
music_extra_data["artist"] = data["artist"]
music_extra_data["upload_date"] = data["upload_date"]
music_extra_data["album"] = data["album"]
duration = data["duration"] * 1 SECONDS
if (duration > 10 MINUTES)
if((tgui_alert(user, "This song is over 10 minutes long. Are you sure you want to play it?", "Length Warning!", list("No", "Yes", "Cancel")) != "Yes"))
return
var/res = tgui_alert(user, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No", "Cancel"))
switch(res)
if("Yes")
music_extra_data["title"] = data["title"]
if("No")
music_extra_data["link"] = "Song Link Hidden"
music_extra_data["title"] = "Song Title Hidden"
music_extra_data["artist"] = "Song Artist Hidden"
music_extra_data["upload_date"] = "Song Upload Date Hidden"
music_extra_data["album"] = "Song Album Hidden"
if("Cancel", null)
return
var/anon = tgui_alert(user, "Display who played the song?", "Credit Yourself?", list("Yes", "No", "Cancel"))
switch(anon)
if("Yes")
if(res == "Yes")
to_chat(world, "<span class='boldannounce'>[user.key] played: [webpage_url]</span>", confidential = TRUE)
else
to_chat(world, "<span class='boldannounce'>[user.key] played a sound</span>", confidential = TRUE)
if("No")
if(res == "Yes")
to_chat(world, "<span class='boldannounce'>An admin played: [webpage_url]</span>", confidential = TRUE)
if("Cancel", null)
return
if(credit)
to_chat(world, "<span class='boldannounce'>[credit]</span>", confidential = TRUE)
//SSblackbox.record_feedback("nested tally", "played_url", 1, list("[user.ckey]", "[input]"))
log_admin("[key_name(user)] played web sound: [input]")
message_admins("[key_name(user)] played web sound: [input]")
else
//pressed ok with blank
log_admin("[key_name(user)] stopped web sounds.")
message_admins("[key_name(user)] stopped web sounds.")
web_sound_url = null
stop_web_sounds = TRUE
if(web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol))
tgui_alert(user, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol. This is a security risk and the sound will not be played.", "Security Risk", list("OK"))
to_chat(user, "<span class='boldwarning'>BLOCKED: Content URL not using HTTP(S) Protocol!</span>", confidential = TRUE)
return
if(web_sound_url || stop_web_sounds)
for(var/m in player_list)
var/mob/M = m
var/client/C = M.client
if(C.is_preference_enabled(/datum/client_preference/play_admin_midis))
if(!stop_web_sounds)
C.tgui_panel?.play_music(web_sound_url, music_extra_data)
else
C.tgui_panel?.stop_music()
S_TIMER_COOLDOWN_START(SStimer, COOLDOWN_INTERNET_SOUND, duration)
feedback_add_details("admin_verb", "Play Internet Sound")
/client/proc/play_web_sound()
set category = "Fun"
set name = "Play Internet Sound"
if(!check_rights(R_SOUNDS))
return
var/ytdl = config.invoke_youtubedl
if(!ytdl)
to_chat(src, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>", confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
return
if(S_TIMER_COOLDOWN_TIMELEFT(SStimer, COOLDOWN_INTERNET_SOUND))
if(tgui_alert(usr, "Someone else is already playing an Internet sound! It has [DisplayTimeText(S_TIMER_COOLDOWN_TIMELEFT(SStimer, COOLDOWN_INTERNET_SOUND), 1)] remaining. \
Would you like to override?", "Musicalis Interruptus", list("No","Yes")) != "Yes")
return
var/web_sound_input = tgui_input_text(usr, "Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound", null)
if(length(web_sound_input))
web_sound_input = trim(web_sound_input)
if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol))
to_chat(src, "<span class='boldwarning'>Non-http(s) URIs are not allowed.</span>", confidential = TRUE)
to_chat(src, "<span class='warning'>For youtube-dl shortcuts like ytsearch: please use the appropriate full URL from the website.</span>", confidential = TRUE)
return
web_sound(usr, web_sound_input)
else
web_sound(usr, null)
/client/proc/stop_sounds()
set category = "Debug"
set name = "Stop All Playing Sounds"
if(!src.holder)
return
log_admin("[key_name(src)] stopped all currently playing sounds.")
message_admins("[key_name_admin(src)] stopped all currently playing sounds.")
for(var/mob/M in player_list)
SEND_SOUND(M, sound(null))
var/client/C = M.client
C?.tgui_panel?.stop_music()
S_TIMER_COOLDOWN_RESET(SStimer, COOLDOWN_INTERNET_SOUND)
feedback_add_details("admin_verb", "Stop All Playing Sounds")
//world/proc/shelleo
#undef SHELLEO_ERRORLEVEL
#undef SHELLEO_STDOUT
#undef SHELLEO_STDERR
/*
/client/proc/cuban_pete()
set category = "Fun"
set name = "Cuban Pete Time"
message_admins("[key_name_admin(usr)] has declared Cuban Pete Time!", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'cubanpetetime.ogg'
for(var/mob/living/carbon/human/CP in human_mob_list)
if(CP.real_name=="Cuban Pete" && CP.key!="Rosham")
to_chat(CP, "Your body can't contain the rhumba beat")
CP.gib()
/client/proc/bananaphone()
set category = "Fun"
set name = "Banana Phone"
message_admins("[key_name_admin(usr)] has activated Banana Phone!", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'bananaphone.ogg'
/client/proc/space_asshole()
set category = "Fun"
set name = "Space Asshole"
message_admins("[key_name_admin(usr)] has played the Space Asshole Hymn.", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'sound/music/space_asshole.ogg'
/client/proc/honk_theme()
set category = "Fun"
set name = "Honk"
message_admins("[key_name_admin(usr)] has creeped everyone out with Blackest Honks.", 1)
for(var/mob/M in player_list)
if(M.client)
if(M.client.midis)
M << 'honk_theme.ogg'*/
+44 -44
View File
@@ -1,44 +1,44 @@
/mob/verb/pray()
set category = "IC"
set name = "Pray"
if(say_disabled) //This is here to try to identify lag problems
to_chat(usr, span_red("Speech is currently admin-disabled."))
return
var/raw_msg = sanitize(tgui_input_text(usr, "Prayers are sent to staff but do not open tickets or go to Discord. If you have a technical difficulty or an event/spice idea/hook - please ahelp instead. Thank you!", "Pray", null, MAX_MESSAGE_LEN))
if(!raw_msg) return
if(usr.client)
if(raw_msg)
client.handle_spam_prevention(MUTE_PRAY)
if(usr.client.prefs.muted & MUTE_PRAY)
to_chat(usr, span_red("You cannot pray (muted)."))
return
var/icon/cross = icon('icons/obj/storage.dmi',"bible")
var/msg = "<span class='filter_pray'>" + span_blue("\icon[cross][bicon(cross)] <b>" + span_purple("PRAY: ") + "[key_name(src, 1)] [ADMIN_QUE(src)] [ADMIN_PP(src)] [ADMIN_VV(src)] [ADMIN_SM(src)] ([admin_jump_link(src, src)]) [ADMIN_CA(src)] [ADMIN_SC(src)] [ADMIN_SMITE(src)]:</b> [raw_msg]") + "</span>"
for(var/client/C in GLOB.admins)
if(R_ADMIN|R_EVENT & C.holder.rights)
if(C.is_preference_enabled(/datum/client_preference/admin/show_chat_prayers))
to_chat(C, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE)
C << 'sound/effects/ding.ogg'
to_chat(usr, "Your prayers have been received by the gods.", confidential = TRUE)
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_pray(raw_msg, src)
/proc/CentCom_announce(var/msg, var/mob/Sender, var/iamessage)
msg = span_blue("<b>" + span_orange("[uppertext(using_map.boss_short)]M[iamessage ? " IA" : ""]:") + "[key_name(Sender, 1)] [ADMIN_PP(Sender)] [ADMIN_VV(Sender)] [ADMIN_SM(Sender)] ([admin_jump_link(Sender)]) [ADMIN_CA(Sender)] [ADMIN_BSA(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]:</b> [msg]")
for(var/client/C in GLOB.admins) //VOREStation Edit - GLOB admins
if(R_ADMIN|R_EVENT & C.holder.rights)
to_chat(C,msg)
C << 'sound/machines/signal.ogg'
/proc/Syndicate_announce(var/msg, var/mob/Sender)
msg = span_blue("<b>" + span_crimson("ILLEGAL:") + "[key_name(Sender, 1)] [ADMIN_PP(Sender)] [ADMIN_VV(Sender)] [ADMIN_SM(Sender)] ([admin_jump_link(Sender)]) [ADMIN_CA(Sender)] [ADMIN_BSA(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]:</b> [msg]")
for(var/client/C in GLOB.admins) //VOREStation Edit - GLOB admins
if(R_ADMIN|R_EVENT & C.holder.rights)
to_chat(C,msg)
C << 'sound/machines/signal.ogg'
/mob/verb/pray()
set category = "IC"
set name = "Pray"
if(say_disabled) //This is here to try to identify lag problems
to_chat(usr, span_red("Speech is currently admin-disabled."))
return
var/raw_msg = sanitize(tgui_input_text(usr, "Prayers are sent to staff but do not open tickets or go to Discord. If you have a technical difficulty or an event/spice idea/hook - please ahelp instead. Thank you!", "Pray", null, MAX_MESSAGE_LEN))
if(!raw_msg) return
if(usr.client)
if(raw_msg)
client.handle_spam_prevention(MUTE_PRAY)
if(usr.client.prefs.muted & MUTE_PRAY)
to_chat(usr, span_red("You cannot pray (muted)."))
return
var/icon/cross = icon('icons/obj/storage.dmi',"bible")
var/msg = "<span class='filter_pray'>" + span_blue("\icon[cross][bicon(cross)] <b>" + span_purple("PRAY: ") + "[key_name(src, 1)] [ADMIN_QUE(src)] [ADMIN_PP(src)] [ADMIN_VV(src)] [ADMIN_SM(src)] ([admin_jump_link(src, src)]) [ADMIN_CA(src)] [ADMIN_SC(src)] [ADMIN_SMITE(src)]:</b> [raw_msg]") + "</span>"
for(var/client/C in GLOB.admins)
if(R_ADMIN|R_EVENT & C.holder.rights)
if(C.is_preference_enabled(/datum/client_preference/admin/show_chat_prayers))
to_chat(C, msg, type = MESSAGE_TYPE_PRAYER, confidential = TRUE)
C << 'sound/effects/ding.ogg'
to_chat(usr, "Your prayers have been received by the gods.", confidential = TRUE)
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_pray(raw_msg, src)
/proc/CentCom_announce(var/msg, var/mob/Sender, var/iamessage)
msg = span_blue("<b>" + span_orange("[uppertext(using_map.boss_short)]M[iamessage ? " IA" : ""]:") + "[key_name(Sender, 1)] [ADMIN_PP(Sender)] [ADMIN_VV(Sender)] [ADMIN_SM(Sender)] ([admin_jump_link(Sender)]) [ADMIN_CA(Sender)] [ADMIN_BSA(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]:</b> [msg]")
for(var/client/C in GLOB.admins) //VOREStation Edit - GLOB admins
if(R_ADMIN|R_EVENT & C.holder.rights)
to_chat(C,msg)
C << 'sound/machines/signal.ogg'
/proc/Syndicate_announce(var/msg, var/mob/Sender)
msg = span_blue("<b>" + span_crimson("ILLEGAL:") + "[key_name(Sender, 1)] [ADMIN_PP(Sender)] [ADMIN_VV(Sender)] [ADMIN_SM(Sender)] ([admin_jump_link(Sender)]) [ADMIN_CA(Sender)] [ADMIN_BSA(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]:</b> [msg]")
for(var/client/C in GLOB.admins) //VOREStation Edit - GLOB admins
if(R_ADMIN|R_EVENT & C.holder.rights)
to_chat(C,msg)
C << 'sound/machines/signal.ogg'
File diff suppressed because it is too large Load Diff
+56 -56
View File
@@ -1,56 +1,56 @@
//STRIKE TEAMS
var/const/commandos_possible = 6 //if more Commandos are needed in the future
/client/proc/strike_team()
set category = "Fun"
set name = "Spawn Strike Team"
set desc = "Spawns a strike team if you want to run an admin event."
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
if(!ticker)
to_chat(usr, span_red("The game hasn't started yet!"))
return
if(world.time < 6000)
to_chat(usr, span_red("There are [(6000-world.time)/10] seconds remaining before it may be called."))
return
var/datum/antagonist/deathsquad/team
var/choice = tgui_input_list(usr, "Select type of strike team:", "Strike Team", list("Heavy Asset Protection", "Mercenaries"))
if(!choice)
return
switch(choice)
if("Heavy Asset Protection")
team = deathsquad
if("Mercenaries")
team = commandos
else
return
if(team.deployed)
to_chat(usr, span_red("Someone is already sending a team."))
return
if(tgui_alert(usr, "Do you want to send in a strike team? Once enabled, this is irreversible.","Strike Team",list("Yes","No"))!="Yes")
return
tgui_alert(usr, "This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") // Should remain tgui_alert() (blocking)
choice = null
while(!choice)
choice = sanitize(tgui_input_text(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", ""))
if(!choice)
if(tgui_alert(usr, "Error, no mission set. Do you want to exit the setup process?","Strike Team",list("Yes","No"))=="Yes")
return
consider_ert_load() //VOREStation Add
if(team.deployed)
to_chat(usr, "Looks like someone beat you to it.")
return
team.attempt_random_spawn()
//STRIKE TEAMS
var/const/commandos_possible = 6 //if more Commandos are needed in the future
/client/proc/strike_team()
set category = "Fun"
set name = "Spawn Strike Team"
set desc = "Spawns a strike team if you want to run an admin event."
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
return
if(!ticker)
to_chat(usr, span_red("The game hasn't started yet!"))
return
if(world.time < 6000)
to_chat(usr, span_red("There are [(6000-world.time)/10] seconds remaining before it may be called."))
return
var/datum/antagonist/deathsquad/team
var/choice = tgui_input_list(usr, "Select type of strike team:", "Strike Team", list("Heavy Asset Protection", "Mercenaries"))
if(!choice)
return
switch(choice)
if("Heavy Asset Protection")
team = deathsquad
if("Mercenaries")
team = commandos
else
return
if(team.deployed)
to_chat(usr, span_red("Someone is already sending a team."))
return
if(tgui_alert(usr, "Do you want to send in a strike team? Once enabled, this is irreversible.","Strike Team",list("Yes","No"))!="Yes")
return
tgui_alert(usr, "This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned commandos have internals cameras which are viewable through a monitor inside the Spec. Ops. Office. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.") // Should remain tgui_alert() (blocking)
choice = null
while(!choice)
choice = sanitize(tgui_input_text(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", ""))
if(!choice)
if(tgui_alert(usr, "Error, no mission set. Do you want to exit the setup process?","Strike Team",list("Yes","No"))=="Yes")
return
consider_ert_load() //VOREStation Add
if(team.deployed)
to_chat(usr, "Looks like someone beat you to it.")
return
team.attempt_random_spawn()
+22 -22
View File
@@ -1,22 +1,22 @@
/client/proc/triple_ai()
set category = "Fun"
set name = "Create AI Triumvirate"
if(ticker.current_state > GAME_STATE_PREGAME)
to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.")
return
if(job_master && ticker)
var/datum/job/job = job_master.GetJob("AI")
if(!job)
to_chat(usr, "Unable to locate the AI job")
return
if(ticker.triai)
ticker.triai = 0
to_chat(usr, "Only one AI will be spawned at round start.")
message_admins(span_blue("[key_name_admin(usr)] has toggled off triple AIs at round start."), 1)
else
ticker.triai = 1
to_chat(usr, "There will be an AI Triumvirate at round start.")
message_admins(span_blue("[key_name_admin(usr)] has toggled on triple AIs at round start."), 1)
return
/client/proc/triple_ai()
set category = "Fun"
set name = "Create AI Triumvirate"
if(ticker.current_state > GAME_STATE_PREGAME)
to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.")
return
if(job_master && ticker)
var/datum/job/job = job_master.GetJob("AI")
if(!job)
to_chat(usr, "Unable to locate the AI job")
return
if(ticker.triai)
ticker.triai = 0
to_chat(usr, "Only one AI will be spawned at round start.")
message_admins(span_blue("[key_name_admin(usr)] has toggled off triple AIs at round start."), 1)
else
ticker.triai = 1
to_chat(usr, "There will be an AI Triumvirate at round start.")
message_admins(span_blue("[key_name_admin(usr)] has toggled on triple AIs at round start."), 1)
return
@@ -97,7 +97,7 @@
if (VV_NUM)
.["value"] = tgui_input_number(usr, "Enter new number:", "Num", current_value, INFINITY, -INFINITY)
.["value"] = tgui_input_number(usr, "Enter new number:", "Num", current_value, INFINITY, -INFINITY, round_value = FALSE)
if (.["value"] == null)
.["class"] = null
return
@@ -1,285 +1,285 @@
/client/proc/debug_variables(datum/D in world)
set category = "Debug"
set name = "View Variables"
//set src in world
var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round.
if(!usr.client || !usr.client.holder) //The usr vs src abuse in this proc is intentional and must not be changed
to_chat(usr, "<span class='danger'>You need to be an administrator to access this.</span>")
return
if(!D)
return
var/islist = islist(D)
if (!islist && !istype(D))
return
//VOREStation Edit Start - the rest of this proc in a spawn
spawn(0)
var/title = ""
var/refid = "\ref[D]"
var/icon/sprite
var/hash
var/type = /list
if (!islist)
type = D.type
if(istype(D, /atom))
var/atom/AT = D
if(AT.icon && AT.icon_state)
sprite = new /icon(AT.icon, AT.icon_state)
hash = md5(AT.icon)
hash = md5(hash + AT.icon_state)
src << browse_rsc(sprite, "vv[hash].png")
title = "[D] (\ref[D]) = [type]"
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
var/sprite_text
if(sprite)
sprite_text = "<img src='vv[hash].png'></td><td>"
var/list/header = islist(D)? list("<b>/list</b>") : D.vv_get_header()
var/marked
if(holder && holder.marked_datum && holder.marked_datum == D)
marked = VV_MSG_MARKED
var/varedited_line = ""
if(!islist && (D.datum_flags & DF_VAR_EDITED))
varedited_line = VV_MSG_EDITED
var/deleted_line
if(!islist && D.gc_destroyed)
deleted_line = VV_MSG_DELETED
var/list/dropdownoptions = list()
var/autoconvert_dropdown = FALSE
if (islist)
dropdownoptions = list(
"---",
"Add Item" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ADD]=TRUE;target=[refid]",
"Remove Nulls" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ERASE_NULLS]=TRUE;target=[refid]",
"Remove Dupes" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ERASE_DUPES]=TRUE;target=[refid]",
"Set len" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_SET_LENGTH]=TRUE;target=[refid]",
"Shuffle" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_SHUFFLE]=TRUE;target=[refid]",
// "Show VV To Player" = "?_src_=vars;[HrefToken()];[VV_HK_EXPOSE]=TRUE;target=[refid]" // TODO - Not yet implemented for lists
)
autoconvert_dropdown = TRUE
else
dropdownoptions = D.vv_get_dropdown()
var/list/dropdownoptions_html = list()
if(autoconvert_dropdown)
for (var/name in dropdownoptions)
var/link = dropdownoptions[name]
if (link)
dropdownoptions_html += "<option value='[link]'>[name]</option>"
else
dropdownoptions_html += "<option value>[name]</option>"
else
dropdownoptions_html = dropdownoptions + D.get_view_variables_options()
var/list/names = list()
if (!islist)
names = D.get_variables()
//sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects. //VOREStation edit - commented out, replaced with spawn(0) above
var/list/variable_html = list()
if (islist)
var/list/L = D
for (var/i in 1 to L.len)
var/key = L[i]
var/value
if (IS_NORMAL_LIST(L) && IS_VALID_ASSOC_KEY(key))
value = L[key]
variable_html += debug_variable(i, value, 0, D)
else
names = sortList(names)
for (var/V in names)
if(D.can_vv_get(V))
variable_html += D.vv_get_var(V)
var/html = {"
<html>
<head>
<title>[title]</title>
<style>
body {
font-family: Verdana, sans-serif;
font-size: 9pt;
}
.value {
font-family: "Courier New", monospace;
font-size: 8pt;
}
</style>
</head>
<body onload='selectTextField()' onkeydown='return handle_keydown()' onkeyup='handle_keyup()'>
<script type="text/javascript">
// onload
function selectTextField() {
var filter_text = document.getElementById('filter');
filter_text.focus();
filter_text.select();
var lastsearch = getCookie("[refid][cookieoffset]search");
if (lastsearch) {
filter_text.value = lastsearch;
updateSearch();
}
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca\[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}
// main search functionality
var last_filter = "";
function updateSearch() {
var filter = document.getElementById('filter').value.toLowerCase();
var vars_ol = document.getElementById("vars");
if (filter === last_filter) {
// An event triggered an update but nothing has changed.
return;
} else if (filter.indexOf(last_filter) === 0) {
// The new filter starts with the old filter, fast path by removing only.
var children = vars_ol.childNodes;
for (var i = children.length - 1; i >= 0; --i) {
try {
var li = children\[i];
if (li.innerText.toLowerCase().indexOf(filter) == -1) {
vars_ol.removeChild(li);
}
} catch(err) {}
}
} else {
// Remove everything and put back what matches.
while (vars_ol.hasChildNodes()) {
vars_ol.removeChild(vars_ol.lastChild);
}
for (var i = 0; i < complete_list.length; ++i) {
try {
var li = complete_list\[i];
if (!filter || li.innerText.toLowerCase().indexOf(filter) != -1) {
vars_ol.appendChild(li);
}
} catch(err) {}
}
}
last_filter = filter;
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
}
// onkeydown
function handle_keydown() {
if(event.keyCode == 116) { //F5 (to refresh properly)
document.getElementById("refresh_link").click();
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
return false;
}
return true;
}
// onkeyup
function handle_keyup() {
updateSearch();
}
// onchange
function handle_dropdown(list) {
var value = list.options\[list.selectedIndex].value;
if (value !== "") {
location.href = value;
}
list.selectedIndex = 0;
document.getElementById('filter').focus();
}
// byjax
function replace_span(what) {
var idx = what.indexOf(':');
document.getElementById(what.substr(0, idx)).innerHTML = what.substr(idx + 1);
}
</script>
<div align='center'>
<table width='100%'>
<tr>
<td width='50%'>
<table align='center' width='100%'>
<tr>
<td>
[sprite_text]
<div align='center'>
[header.Join()]
</div>
</td>
</tr>
</table>
<div align='center'>
<b><font size='1'>[formatted_type]</font></b>
<span id='marked'>[marked]</span>
<span id='varedited'>[varedited_line]</span>
<span id='deleted'>[deleted_line]</span>
</div>
</td>
<td width='50%'>
<div align='center'>
<a id='refresh_link' href='?_src_=vars;
datumrefresh=[refid]'>Refresh</a>
<form>
<select name="file" size="1"
onchange="handle_dropdown(this)"
onmouseclick="this.focus()">
<option value selected>Select option</option>
[dropdownoptions_html.Join()]
</select>
</form>
</div>
</td>
</tr>
</table>
</div>
<hr>
<font size='1'>
<b>E</b> - Edit, tries to determine the variable type by itself.<br>
<b>C</b> - Change, asks you for the var type first.<br>
<b>M</b> - Mass modify: changes this variable for all objects of this type.<br>
</font>
<hr>
<table width='100%'>
<tr>
<td width='20%'>
<div align='center'>
<b>Search:</b>
</div>
</td>
<td width='80%'>
<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>
</td>
</tr>
</table>
<hr>
<ol id='vars'>
[variable_html.Join()]
</ol>
<script type='text/javascript'>
var complete_list = \[\];
var lis = document.getElementById("vars").children;
for(var i = lis.length; i--;) complete_list\[i\] = lis\[i\];
</script>
</body>
</html>
"}
src << browse(html, "window=variables[refid];size=475x650") //VOREStation edit end
/client/proc/vv_update_display(datum/D, span, content)
src << output("[span]:[content]", "variables\ref[D].browser:replace_span")
/client/proc/debug_variables(datum/D in world)
set category = "Debug"
set name = "View Variables"
//set src in world
var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round.
if(!usr.client || !usr.client.holder) //The usr vs src abuse in this proc is intentional and must not be changed
to_chat(usr, "<span class='danger'>You need to be an administrator to access this.</span>")
return
if(!D)
return
var/islist = islist(D)
if (!islist && !istype(D))
return
//VOREStation Edit Start - the rest of this proc in a spawn
spawn(0)
var/title = ""
var/refid = "\ref[D]"
var/icon/sprite
var/hash
var/type = /list
if (!islist)
type = D.type
if(istype(D, /atom))
var/atom/AT = D
if(AT.icon && AT.icon_state)
sprite = new /icon(AT.icon, AT.icon_state)
hash = md5(AT.icon)
hash = md5(hash + AT.icon_state)
src << browse_rsc(sprite, "vv[hash].png")
title = "[D] (\ref[D]) = [type]"
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
var/sprite_text
if(sprite)
sprite_text = "<img src='vv[hash].png'></td><td>"
var/list/header = islist(D)? list("<b>/list</b>") : D.vv_get_header()
var/marked
if(holder && holder.marked_datum && holder.marked_datum == D)
marked = VV_MSG_MARKED
var/varedited_line = ""
if(!islist && (D.datum_flags & DF_VAR_EDITED))
varedited_line = VV_MSG_EDITED
var/deleted_line
if(!islist && D.gc_destroyed)
deleted_line = VV_MSG_DELETED
var/list/dropdownoptions = list()
var/autoconvert_dropdown = FALSE
if (islist)
dropdownoptions = list(
"---",
"Add Item" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ADD]=TRUE;target=[refid]",
"Remove Nulls" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ERASE_NULLS]=TRUE;target=[refid]",
"Remove Dupes" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ERASE_DUPES]=TRUE;target=[refid]",
"Set len" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_SET_LENGTH]=TRUE;target=[refid]",
"Shuffle" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_SHUFFLE]=TRUE;target=[refid]",
// "Show VV To Player" = "?_src_=vars;[HrefToken()];[VV_HK_EXPOSE]=TRUE;target=[refid]" // TODO - Not yet implemented for lists
)
autoconvert_dropdown = TRUE
else
dropdownoptions = D.vv_get_dropdown()
var/list/dropdownoptions_html = list()
if(autoconvert_dropdown)
for (var/name in dropdownoptions)
var/link = dropdownoptions[name]
if (link)
dropdownoptions_html += "<option value='[link]'>[name]</option>"
else
dropdownoptions_html += "<option value>[name]</option>"
else
dropdownoptions_html = dropdownoptions + D.get_view_variables_options()
var/list/names = list()
if (!islist)
names = D.get_variables()
//sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects. //VOREStation edit - commented out, replaced with spawn(0) above
var/list/variable_html = list()
if (islist)
var/list/L = D
for (var/i in 1 to L.len)
var/key = L[i]
var/value
if (IS_NORMAL_LIST(L) && IS_VALID_ASSOC_KEY(key))
value = L[key]
variable_html += debug_variable(i, value, 0, D)
else
names = sortList(names)
for (var/V in names)
if(D.can_vv_get(V))
variable_html += D.vv_get_var(V)
var/html = {"
<html>
<head>
<title>[title]</title>
<style>
body {
font-family: Verdana, sans-serif;
font-size: 9pt;
}
.value {
font-family: "Courier New", monospace;
font-size: 8pt;
}
</style>
</head>
<body onload='selectTextField()' onkeydown='return handle_keydown()' onkeyup='handle_keyup()'>
<script type="text/javascript">
// onload
function selectTextField() {
var filter_text = document.getElementById('filter');
filter_text.focus();
filter_text.select();
var lastsearch = getCookie("[refid][cookieoffset]search");
if (lastsearch) {
filter_text.value = lastsearch;
updateSearch();
}
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca\[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}
// main search functionality
var last_filter = "";
function updateSearch() {
var filter = document.getElementById('filter').value.toLowerCase();
var vars_ol = document.getElementById("vars");
if (filter === last_filter) {
// An event triggered an update but nothing has changed.
return;
} else if (filter.indexOf(last_filter) === 0) {
// The new filter starts with the old filter, fast path by removing only.
var children = vars_ol.childNodes;
for (var i = children.length - 1; i >= 0; --i) {
try {
var li = children\[i];
if (li.innerText.toLowerCase().indexOf(filter) == -1) {
vars_ol.removeChild(li);
}
} catch(err) {}
}
} else {
// Remove everything and put back what matches.
while (vars_ol.hasChildNodes()) {
vars_ol.removeChild(vars_ol.lastChild);
}
for (var i = 0; i < complete_list.length; ++i) {
try {
var li = complete_list\[i];
if (!filter || li.innerText.toLowerCase().indexOf(filter) != -1) {
vars_ol.appendChild(li);
}
} catch(err) {}
}
}
last_filter = filter;
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
}
// onkeydown
function handle_keydown() {
if(event.keyCode == 116) { //F5 (to refresh properly)
document.getElementById("refresh_link").click();
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
return false;
}
return true;
}
// onkeyup
function handle_keyup() {
updateSearch();
}
// onchange
function handle_dropdown(list) {
var value = list.options\[list.selectedIndex].value;
if (value !== "") {
location.href = value;
}
list.selectedIndex = 0;
document.getElementById('filter').focus();
}
// byjax
function replace_span(what) {
var idx = what.indexOf(':');
document.getElementById(what.substr(0, idx)).innerHTML = what.substr(idx + 1);
}
</script>
<div align='center'>
<table width='100%'>
<tr>
<td width='50%'>
<table align='center' width='100%'>
<tr>
<td>
[sprite_text]
<div align='center'>
[header.Join()]
</div>
</td>
</tr>
</table>
<div align='center'>
<b><font size='1'>[formatted_type]</font></b>
<span id='marked'>[marked]</span>
<span id='varedited'>[varedited_line]</span>
<span id='deleted'>[deleted_line]</span>
</div>
</td>
<td width='50%'>
<div align='center'>
<a id='refresh_link' href='?_src_=vars;
datumrefresh=[refid]'>Refresh</a>
<form>
<select name="file" size="1"
onchange="handle_dropdown(this)"
onmouseclick="this.focus()">
<option value selected>Select option</option>
[dropdownoptions_html.Join()]
</select>
</form>
</div>
</td>
</tr>
</table>
</div>
<hr>
<font size='1'>
<b>E</b> - Edit, tries to determine the variable type by itself.<br>
<b>C</b> - Change, asks you for the var type first.<br>
<b>M</b> - Mass modify: changes this variable for all objects of this type.<br>
</font>
<hr>
<table width='100%'>
<tr>
<td width='20%'>
<div align='center'>
<b>Search:</b>
</div>
</td>
<td width='80%'>
<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>
</td>
</tr>
</table>
<hr>
<ol id='vars'>
[variable_html.Join()]
</ol>
<script type='text/javascript'>
var complete_list = \[\];
var lis = document.getElementById("vars").children;
for(var i = lis.length; i--;) complete_list\[i\] = lis\[i\];
</script>
</body>
</html>
"}
src << browse(html, "window=variables[refid];size=475x650") //VOREStation edit end
/client/proc/vv_update_display(datum/D, span, content)
src << output("[span]:[content]", "variables\ref[D].browser:replace_span")