module things, jfc

This commit is contained in:
Poojawa
2018-09-11 07:51:01 -05:00
parent 8b9ef1e400
commit 284e9d0325
695 changed files with 11343 additions and 5661 deletions
+23 -11
View File
@@ -80,8 +80,8 @@
var/client/banned_client = banned_mob?.client
var/banned_mob_guest_key = had_banned_mob && IsGuestKey(banned_mob.key)
banned_mob = null
var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
var/sql_ckey = sanitizeSQL(ckey)
var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
if(!query_add_ban_get_ckey.warn_execute())
qdel(query_add_ban_get_ckey)
return
@@ -123,9 +123,9 @@
adminwho += ", [C]"
reason = sanitizeSQL(reason)
var/sql_a_ckey = sanitizeSQL(a_ckey)
if(maxadminbancheck)
var/datum/DBQuery/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
var/datum/DBQuery/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[sql_a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_check_adminban_amt.warn_execute())
qdel(query_check_adminban_amt)
return
@@ -143,7 +143,12 @@
computerid = "0"
if(!ip)
ip = "0.0.0.0"
var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', INET_ATON('[ip]'), '[a_ckey]', '[a_computerid]', INET_ATON('[a_ip]'), '[who]', '[adminwho]')"
var/sql_job = sanitizeSQL(job)
var/sql_computerid = sanitizeSQL(computerid)
var/sql_ip = sanitizeSQL(ip)
var/sql_a_computerid = sanitizeSQL(a_computerid)
var/sql_a_ip = sanitizeSQL(a_ip)
var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[sql_job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[sql_ckey]', '[sql_computerid]', INET_ATON('[sql_ip]'), '[sql_a_ckey]', '[sql_a_computerid]', INET_ATON('[sql_a_ip]'), '[who]', '[adminwho]')"
var/datum/DBQuery/query_add_ban = SSdbcore.NewQuery(sql)
if(!query_add_ban.warn_execute())
qdel(query_add_ban)
@@ -207,10 +212,11 @@
bantype_sql = "(bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now() ) )"
else
bantype_sql = "bantype = '[bantype_str]'"
var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
var/sql_ckey = sanitizeSQL(ckey)
var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
if(job)
sql += " AND job = '[job]'"
var/sql_job = sanitizeSQL(job)
sql += " AND job = '[sql_job]'"
if(!SSdbcore.Connect())
return
@@ -252,7 +258,7 @@
to_chat(usr, "Cancelled")
return
var/datum/DBQuery/query_edit_ban_get_details = SSdbcore.NewQuery("SELECT (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), duration, reason FROM [format_table_name("ban")] WHERE id = [banid]")
var/datum/DBQuery/query_edit_ban_get_details = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), duration, reason FROM [format_table_name("ban")] WHERE id = [banid]")
if(!query_edit_ban_get_details.warn_execute())
qdel(query_edit_ban_get_details)
return
@@ -319,7 +325,7 @@
if(!check_rights(R_BAN))
return
var/sql = "SELECT (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey) FROM [format_table_name("ban")] WHERE id = [id]"
var/sql = "SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey) FROM [format_table_name("ban")] WHERE id = [id]"
if(!SSdbcore.Connect())
return
@@ -406,6 +412,12 @@
output += "<tr><td><b>IP:</b> <input type='text' name='dbbanaddip'></td>"
output += "<td><b>Computer id:</b> <input type='text' name='dbbanaddcid'></td></tr>"
output += "<tr><td><b>Duration:</b> <input type='text' name='dbbaddduration'></td>"
output += "<tr><td><b>Severity:</b><select name='dbbanaddseverity'>"
output += "<option value=''>--</option>"
output += "<option value='High'>High Severity</option>"
output += "<option value='Medium'>Medium Severity</option>"
output += "<option value='Minor'>Minor Severity</option>"
output += "<option value='None'>No Severity</option>"
output += "<td><b>Job:</b><select name='dbbanaddjob'>"
output += "<option value=''>--</option>"
for(var/j in get_all_jobs())
@@ -477,7 +489,7 @@
output += "<th width='15%'><b>OPTIONS</b></th>"
output += "</tr>"
var/limit = " LIMIT [bansperpage * page], [bansperpage]"
var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), unbanned, (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].unbanned_ckey), unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE [search] ORDER BY bantime DESC[limit]")
var/datum/DBQuery/query_search_bans = SSdbcore.NewQuery("SELECT id, bantime, bantype, reason, job, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), unbanned, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].unbanned_ckey), unbanned_ckey), unbanned_datetime, edits, round_id FROM [format_table_name("ban")] WHERE [search] ORDER BY bantime DESC[limit]")
if(!query_search_bans.warn_execute())
qdel(query_search_bans)
return
+2 -2
View File
@@ -75,8 +75,8 @@
if(computer_id)
cidquery = " OR computerid = '[computer_id]' "
var/datum/DBQuery/query_ban_check = SSdbcore.NewQuery("SELECT (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_ban_check.Execute())
var/datum/DBQuery/query_ban_check = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_ban_check.Execute(async = TRUE))
qdel(query_ban_check)
return
while(query_ban_check.NextRow())
+2 -2
View File
@@ -123,9 +123,9 @@ GLOBAL_PROTECT(Banlist)
if (temp)
WRITE_FILE(GLOB.Banlist["minutes"], bantimestamp)
if(!temp)
create_message("note", key, bannedby, "Permanently banned - [reason]", null, null, 0, 0)
create_message("note", key, bannedby, "Permanently banned - [reason]", null, null, 0, 0, null, 0, 0)
else
create_message("note", key, bannedby, "Banned for [minutes] minutes - [reason]", null, null, 0, 0)
create_message("note", key, bannedby, "Banned for [minutes] minutes - [reason]", null, null, 0, 0, null, 0, 0)
return 1
/proc/RemoveBan(foldername)
+9 -5
View File
@@ -29,7 +29,7 @@
body += "<body>Options panel for <b>[M]</b>"
if(M.client)
body += " played by <b>[M.client]</b> "
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[M.client.ckey] || GLOB.deadmins[M.client.ckey]) ? "rank" : "add"];ckey=[M.key]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
body += "\[<A href='?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[M.client.ckey] || GLOB.deadmins[M.client.ckey]) ? "rank" : "add"];key=[M.key]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
if(CONFIG_GET(flag/use_exp_tracking))
body += "\[<A href='?_src_=holder;[HrefToken()];getplaytimewindow=[REF(M)]'>" + M.client.get_exp_living() + "</a>\]"
@@ -50,6 +50,10 @@
body += "<a href='?_src_=holder;[HrefToken()];modantagrep=subtract;mob=[REF(M)]'>\[decrease\]</a> "
body += "<a href='?_src_=holder;[HrefToken()];modantagrep=set;mob=[REF(M)]'>\[set\]</a> "
body += "<a href='?_src_=holder;[HrefToken()];modantagrep=zero;mob=[REF(M)]'>\[zero\]</a>"
var/full_version = "Unknown"
if(M.client.byond_version)
full_version = "[M.client.byond_version].[M.client.byond_build ? M.client.byond_build : "xxx"]"
body += "<br>\[<b>Byond version:</b> [full_version]\]<br>"
body += "<br><br>\[ "
@@ -241,7 +245,7 @@
if(CHANNEL.is_admin_channel)
dat+="<B><FONT style='BACKGROUND-COLOR: LightGreen'><A href='?src=[REF(src)];ac_show_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A></FONT></B><BR>"
else
dat+="<B><A href='?src=[REF(src)];[HrefToken()];ac_show_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR></B>"
dat+="<B><A href='?src=[REF(src)];[HrefToken()];ac_show_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR></B>"
dat+="<BR><HR><A href='?src=[REF(src)];[HrefToken()];ac_refresh=1'>Refresh</A>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Back</A>"
if(2)
@@ -313,7 +317,7 @@
dat+="<I>No feed channels found active...</I><BR>"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_pick_censor_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR>"
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_pick_censor_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Cancel</A>"
if(11)
dat+="<B>Nanotrasen D-Notice Handler</B><HR>"
@@ -324,7 +328,7 @@
dat+="<I>No feed channels found active...</I><BR>"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_pick_d_notice=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ()]<BR>"
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_pick_d_notice=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Back</A>"
if(12)
@@ -546,7 +550,7 @@
/datum/admins/proc/toggleaooc()
set category = "Server"
set desc="Toggle dis bitch"
set desc="Toggle to bitch"
set name="Toggle Antag OOC"
toggle_aooc()
log_admin("[key_name(usr)] toggled Antagonist OOC.")
+44 -27
View File
@@ -42,9 +42,6 @@ GLOBAL_PROTECT(protected_ranks)
return QDEL_HINT_LETMELIVE
. = ..()
/datum/admin_rank/can_vv_get(var_name)
return FALSE
/datum/admin_rank/vv_edit_var(var_name, var_value)
return FALSE
@@ -74,7 +71,7 @@ GLOBAL_PROTECT(protected_ranks)
if("varedit")
flag = R_VAREDIT
if("everything","host","all")
flag = ALL
flag = R_EVERYTHING
if("sound","sounds")
flag = R_SOUNDS
if("spawn","create")
@@ -112,6 +109,22 @@ GLOBAL_PROTECT(protected_ranks)
if(flag)
return ((rank.rights & flag) == flag) //true only if right has everything in flag
/proc/sync_ranks_with_db()
set waitfor = FALSE
if(IsAdminAdvancedProcCall())
to_chat(usr, "<span class='admin prefix'>Admin rank DB Sync blocked: Advanced ProcCall detected.</span>")
return
var/list/sql_ranks = list()
for(var/datum/admin_rank/R in GLOB.protected_ranks)
var/sql_rank = sanitizeSQL(R.name)
var/sql_flags = sanitizeSQL(R.include_rights)
var/sql_exclude_flags = sanitizeSQL(R.exclude_rights)
var/sql_can_edit_flags = sanitizeSQL(R.can_edit_rights)
sql_ranks += list(list("rank" = "'[sql_rank]'", "flags" = "[sql_flags]", "exclude_flags" = "[sql_exclude_flags]", "can_edit_flags" = "[sql_can_edit_flags]"))
SSdbcore.MassInsert(format_table_name("admin_ranks"), sql_ranks, duplicate_key = TRUE)
//load our rank - > rights associations
/proc/load_admin_ranks(dbfail, no_update)
if(IsAdminAdvancedProcCall())
@@ -139,14 +152,7 @@ GLOBAL_PROTECT(protected_ranks)
if(!CONFIG_GET(flag/admin_legacy_system) || dbfail)
if(CONFIG_GET(flag/load_legacy_ranks_only))
if(!no_update)
var/list/sql_ranks = list()
for(var/datum/admin_rank/R in GLOB.admin_ranks)
var/sql_rank = sanitizeSQL(R.name)
var/sql_flags = sanitizeSQL(R.include_rights)
var/sql_exclude_flags = sanitizeSQL(R.exclude_rights)
var/sql_can_edit_flags = sanitizeSQL(R.can_edit_rights)
sql_ranks += list(list("rank" = "'[sql_rank]'", "flags" = "[sql_flags]", "exclude_flags" = "[sql_exclude_flags]", "can_edit_flags" = "[sql_can_edit_flags]"))
SSdbcore.MassInsert(format_table_name("admin_ranks"), sql_ranks, duplicate_key = TRUE, blocking = TRUE)
sync_ranks_with_db()
else
var/datum/DBQuery/query_load_admin_ranks = SSdbcore.NewQuery("SELECT rank, flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")]")
if(!query_load_admin_ranks.Execute())
@@ -172,20 +178,23 @@ GLOBAL_PROTECT(protected_ranks)
qdel(query_load_admin_ranks)
//load ranks from backup file
if(dbfail)
var/backup_file = file("data/admins_backup.json")
if(!fexists(backup_file))
var/backup_file = file2text("data/admins_backup.json")
if(backup_file == null)
log_world("Unable to locate admins backup file.")
return
var/list/json = json_decode(file2text(backup_file))
return FALSE
var/list/json = json_decode(backup_file)
for(var/J in json["ranks"])
var/skip
for(var/datum/admin_rank/R in GLOB.admin_ranks)
if(R.name == "[J]") //this rank was already loaded from txt override
continue
skip = TRUE
if(skip)
continue
var/datum/admin_rank/R = new("[J]", json["ranks"]["[J]"]["include rights"], json["ranks"]["[J]"]["exclude rights"], json["ranks"]["[J]"]["can edit rights"])
if(!R)
continue
GLOB.admin_ranks += R
return 1
return json
#ifdef TESTING
var/msg = "Permission Sets Built:\n"
for(var/datum/admin_rank/R in GLOB.admin_ranks)
@@ -210,7 +219,8 @@ GLOBAL_PROTECT(protected_ranks)
GLOB.admins.Cut()
GLOB.protected_admins.Cut()
GLOB.deadmins.Cut()
dbfail = load_admin_ranks(dbfail, no_update)
var/list/backup_file_json = load_admin_ranks(dbfail, no_update)
dbfail = backup_file_json != null
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
@@ -251,16 +261,23 @@ GLOBAL_PROTECT(protected_ranks)
qdel(query_load_admins)
//load admins from backup file
if(dbfail)
var/backup_file = file("data/admins_backup.json")
if(!fexists(backup_file))
log_world("Unable to locate admins backup file.")
return
var/list/json = json_decode(file2text(backup_file))
for(var/J in json["admins"])
if(!backup_file_json)
if(backup_file_json != null)
//already tried
return
var/backup_file = file2text("data/admins_backup.json")
if(backup_file == null)
log_world("Unable to locate admins backup file.")
return
backup_file_json = json_decode(backup_file)
for(var/J in backup_file_json["admins"])
var/skip
for(var/A in GLOB.admin_datums + GLOB.deadmins)
if(A == "[J]") //this admin was already loaded from txt override
continue
new /datum/admins(rank_names[ckeyEx(json["admins"]["[J]"])], ckey("[J]"))
skip = TRUE
if(skip)
continue
new /datum/admins(rank_names[ckeyEx(backup_file_json["admins"]["[J]"])], ckey("[J]"))
#ifdef TESTING
var/msg = "Admins Built:\n"
for(var/ckey in GLOB.admin_datums)
+2
View File
@@ -72,6 +72,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin())
/client/proc/stop_sounds,
/client/proc/hide_verbs, /*hides all our adminverbs*/
/client/proc/hide_most_verbs /*hides all our hideable adminverbs*/
/datum/admins/proc/open_borgopanel
)
GLOBAL_PROTECT(admin_verbs_ban)
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/DB_ban_panel, /client/proc/stickybanpanel))
@@ -161,6 +162,7 @@ GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug())
/client/proc/pump_random_event,
/client/proc/cmd_display_init_log,
/client/proc/cmd_display_overlay_log,
/client/proc/reload_configuration,
/datum/admins/proc/create_or_modify_area,
)
GLOBAL_PROTECT(admin_verbs_possess)
+1
View File
@@ -30,6 +30,7 @@
C.jobbancache = list()
var/datum/DBQuery/query_jobban_build_cache = SSdbcore.NewQuery("SELECT job, reason FROM [format_table_name("ban")] WHERE ckey = '[sanitizeSQL(C.ckey)]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
if(!query_jobban_build_cache.warn_execute())
qdel(query_jobban_build_cache)
return
while(query_jobban_build_cache.NextRow())
C.jobbancache[query_jobban_build_cache.item[1]] = query_jobban_build_cache.item[2]
+3 -3
View File
@@ -28,7 +28,7 @@
return
last_irc_check = rtod
var/server = CONFIG_GET(string/server)
return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]" //CIT CHANGE - obfuscates the current gamemode from players
return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]"
/datum/tgs_chat_command/ahelp
name = "ahelp"
@@ -84,7 +84,7 @@ GLOBAL_LIST(round_end_notifiees)
if(!SSticker.IsRoundInProgress() && SSticker.HasRoundStarted())
return "[sender.mention], the round has already ended!"
LAZYINITLIST(GLOB.round_end_notifiees)
GLOB.round_end_notifiees[sender] = TRUE
GLOB.round_end_notifiees[sender.mention] = TRUE
return "I will notify [sender.mention] when the round ends."
/datum/tgs_chat_command/sdql
@@ -116,4 +116,4 @@ GLOBAL_LIST(round_end_notifiees)
/datum/tgs_chat_command/reload_admins/proc/ReloadAsync()
set waitfor = FALSE
load_admins()
load_admins()
+4 -4
View File
@@ -154,12 +154,12 @@
else
dat += "ETA: <a href='?_src_=holder;[HrefToken()];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<B>Continuous Round Status</B><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];toggle_continuous=1'>[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]</a>"
if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag])
dat += ", <a href='?_src_=holder;[HrefToken()];toggle_midround_antag=1'>[CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]</a><BR>"
dat += "<a href='?_src_=holder;[HrefToken()];toggle_continuous=1'>[CONFIG_GET(keyed_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]</a>"
if(CONFIG_GET(keyed_list/continuous)[SSticker.mode.config_tag])
dat += ", <a href='?_src_=holder;[HrefToken()];toggle_midround_antag=1'>[CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]</a><BR>"
else
dat += "<BR>"
if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag])
if(CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag])
dat += "Time limit: <a href='?_src_=holder;[HrefToken()];alter_midround_time_limit=1'>[CONFIG_GET(number/midround_antag_time_check)] minutes into round</a><BR>"
dat += "Living crew limit: <a href='?_src_=holder;[HrefToken()];alter_midround_life_limit=1'>[CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive</a><BR>"
dat += "If limits past: <a href='?_src_=holder;[HrefToken()];toggle_noncontinuous_behavior=1'>[SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]</a><BR>"
+1
View File
@@ -43,6 +43,7 @@
var/checktime = text2num(query_validate_time.item[1])
if(!checktime)
to_chat(src, "Datetime entered is improperly formatted or not later than current server time.")
qdel(query_validate_time)
return
endtime = query_validate_time.item[1]
qdel(query_validate_time)
+2 -15
View File
@@ -102,19 +102,6 @@
qdel(src)
//Shuttle Build
/obj/effect/shuttle_build
name = "shuttle_build"
desc = "Some assembly required."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "syndballoon"
anchored = TRUE
/obj/effect/shuttle_build/New()
SSshuttle.emergency.initiate_docking(SSshuttle.getDock("emergency_home"))
qdel(src)
//Arena
/obj/effect/forcefield/arena_shuttle
@@ -127,7 +114,7 @@
for(var/obj/effect/landmark/shuttle_arena_safe/exit in GLOB.landmarks_list)
warp_points += exit
/obj/effect/forcefield/arena_shuttle/CollidedWith(atom/movable/AM)
/obj/effect/forcefield/arena_shuttle/Bumped(atom/movable/AM)
if(!isliving(AM))
return
@@ -158,7 +145,7 @@
timeleft = 0
var/list/warp_points = list()
/obj/effect/forcefield/arena_shuttle_entrance/CollidedWith(atom/movable/AM)
/obj/effect/forcefield/arena_shuttle_entrance/Bumped(atom/movable/AM)
if(!isliving(AM))
return
+1 -4
View File
@@ -137,7 +137,7 @@ GLOBAL_PROTECT(href_token)
/datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other)
if(!other)
return 1 //they have no rights
if(rank.rights == 65535)
if(rank.rights == R_EVERYTHING)
return 1 //we have all the rights
if(src == other)
return 1 //you always have more rights than yourself
@@ -146,9 +146,6 @@ GLOBAL_PROTECT(href_token)
return 1 //we have all the rights they have and more
return 0
/datum/admins/can_vv_get(var_name, var_value)
return FALSE //nice try trialmin
/datum/admins/vv_edit_var(var_name, var_value)
return FALSE //nice try trialmin
+2 -2
View File
@@ -44,7 +44,7 @@
pagecount++
output += "|"
var/limit = " LIMIT [logssperpage * page], [logssperpage]"
var/datum/DBQuery/query_search_admin_logs = SSdbcore.NewQuery("SELECT datetime, round_id, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), operation, IF(ckey IS NULL, target, byond_key), log FROM [format_table_name("admin_log")] LEFT JOIN [format_table_name("player")] ON target = ckey[search] ORDER BY datetime DESC[limit]")
var/datum/DBQuery/query_search_admin_logs = SSdbcore.NewQuery("SELECT datetime, round_id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), operation, IF(ckey IS NULL, target, byond_key), log FROM [format_table_name("admin_log")] LEFT JOIN [format_table_name("player")] ON target = ckey[search] ORDER BY datetime DESC[limit]")
if(!query_search_admin_logs.warn_execute())
qdel(query_search_admin_logs)
return
@@ -59,7 +59,7 @@
qdel(query_search_admin_logs)
if(action == 2)
output += "<h3>Admin ckeys with invalid ranks</h3>"
var/datum/DBQuery/query_check_admin_errors = SSdbcore.NewQuery("SELECT (SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("admin")].ckey), [format_table_name("admin")].rank FROM [format_table_name("admin")] LEFT JOIN [format_table_name("admin_ranks")] ON [format_table_name("admin_ranks")].rank = [format_table_name("admin")].rank WHERE [format_table_name("admin_ranks")].rank IS NULL")
var/datum/DBQuery/query_check_admin_errors = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("admin")].ckey), ckey), [format_table_name("admin")].rank FROM [format_table_name("admin")] LEFT JOIN [format_table_name("admin_ranks")] ON [format_table_name("admin_ranks")].rank = [format_table_name("admin")].rank WHERE [format_table_name("admin_ranks")].rank IS NULL")
if(!query_check_admin_errors.warn_execute())
qdel(query_check_admin_errors)
return
+101 -2
View File
@@ -8,8 +8,8 @@
<B>General Secrets</B><BR>
<BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=admin_log'>Admin Log</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=mentor_log'>Mentor Log</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=show_admins'>Show Admin List</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=mentor_log'>Mentor Log</A><BR>
<BR>
"}
@@ -66,6 +66,7 @@
<A href='?src=[REF(src)];[HrefToken()];secrets=blackout'>Break all lights</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=whiteout'>Fix all lights</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=floorlava'>The floor is lava! (DANGEROUS: extremely lame)</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=customportal'>Spawn a custom portal storm</A><BR>
<BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=flipmovement'>Flip client movement directions</A><BR>
<A href='?src=[REF(src)];[HrefToken()];secrets=randommovement'>Randomize client movement directions</A><BR>
@@ -110,6 +111,7 @@
if("mentor_log")
CitadelMentorLogSecret()
if("show_admins")
var/dat = "<B>Current admins:</B><HR>"
if(GLOB.admin_datums)
@@ -475,7 +477,7 @@
message_admins("[key_name_admin(usr)] activated AK-47s for Everyone!")
usr.client.ak47s()
sound_to_playing_players('sound/misc/ak47s.ogg')
if("guns")
if(!check_rights(R_FUN))
return
@@ -643,6 +645,77 @@
message_admins("[key_name_admin(usr)] has reset all movement keys.")
log_admin("[key_name(usr)] has reset all movement keys.")
if("customportal")
if(!check_rights(R_FUN))
return
var/list/settings = list(
"mainsettings" = list(
"typepath" = list("desc" = "Path to spawn", "type" = "datum", "path" = "/mob/living", "subtypesonly" = TRUE, "value" = /mob/living/simple_animal/hostile/poison/bees),
"humanoutfit" = list("desc" = "Outfit if human", "type" = "datum", "path" = "/datum/outfit", "subtypesonly" = TRUE, "value" = /datum/outfit),
"amount" = list("desc" = "Number per portal", "type" = "number", "value" = 1),
"portalnum" = list("desc" = "Number of total portals", "type" = "number", "value" = 10),
"offerghosts" = list("desc" = "Get ghosts to play mobs", "type" = "boolean", "value" = "No"),
"minplayers" = list("desc" = "Minimum number of ghosts", "type" = "number", "value" = 1),
"playersonly" = list("desc" = "Only spawn ghost-controlled mobs", "type" = "boolean", "value" = "No"),
"ghostpoll" = list("desc" = "Ghost poll question", "type" = "string", "value" = "Do you want to play as %TYPE% portal invader?"),
"delay" = list("desc" = "Time between portals, in deciseconds", "type" = "number", "value" = 50),
"color" = list("desc" = "Portal color", "type" = "color", "value" = "#00FF00"),
"playlightning" = list("desc" = "Play lightning sounds on announcement", "type" = "boolean", "value" = "Yes"),
"announce_players" = list("desc" = "Make an announcement", "type" = "boolean", "value" = "Yes"),
"announcement" = list("desc" = "Announcement", "type" = "string", "value" = "Massive bluespace anomaly detected en route to %STATION%. Brace for impact."),
)
)
message_admins("[key_name(usr)] is creating a custom portal storm...")
var/list/prefreturn = presentpreflikepicker(usr,"Customize Portal Storm", "Customize Portal Storm", Button1="Ok", width = 600, StealFocus = 1,Timeout = 0, settings=settings)
if (prefreturn["button"] == 1)
var/list/prefs = settings["mainsettings"]
if (prefs["amount"]["value"] < 1 || prefs["portalnum"]["value"] < 1)
to_chat(usr, "Number of portals and mobs to spawn must be at least 1")
return
var/mob/pathToSpawn = prefs["typepath"]["value"]
if (!ispath(pathToSpawn))
pathToSpawn = text2path(pathToSpawn)
if (!ispath(pathToSpawn))
to_chat(usr, "Invalid path [pathToSpawn]")
return
var/list/candidates = list()
if (prefs["offerghosts"]["value"] == "Yes")
candidates = pollGhostCandidates(replacetext(prefs["ghostpoll"]["value"], "%TYPE%", initial(pathToSpawn.name)), ROLE_TRAITOR)
if (prefs["playersonly"]["value"] == "Yes" && length(candidates) < prefs["minplayers"]["value"])
message_admins("Not enough players signed up to create a portal storm, the minimum was [prefs["minplayers"]["value"]] and the number of signups [length(candidates)]")
return
if (prefs["announce_players"]["value"] == "Yes")
portalAnnounce(prefs["announcement"]["value"], (prefs["playlightning"]["value"] == "Yes" ? TRUE : FALSE))
var/mutable_appearance/storm = mutable_appearance('icons/obj/tesla_engine/energy_ball.dmi', "energy_ball_fast", FLY_LAYER)
storm.color = prefs["color"]["value"]
message_admins("[key_name_admin(usr)] has created a customized portal storm that will spawn [prefs["portalnum"]["value"]] portals, each of them spawning [prefs["amount"]["value"]] of [pathToSpawn]")
log_admin("[key_name(usr)] has created a customized portal storm that will spawn [prefs["portalnum"]["value"]] portals, each of them spawning [prefs["amount"]["value"]] of [pathToSpawn]")
var/outfit = prefs["humanoutfit"]["value"]
if (!ispath(outfit))
outfit = text2path(outfit)
for (var/i in 1 to prefs["portalnum"]["value"])
if (length(candidates)) // if we're spawning players, gotta be a little tricky and also not spawn players on top of NPCs
var/ghostcandidates = list()
for (var/j in 1 to min(prefs["amount"]["value"], length(candidates)))
ghostcandidates += pick_n_take(candidates)
addtimer(CALLBACK(GLOBAL_PROC, .proc/doPortalSpawn, get_random_station_turf(), pathToSpawn, length(ghostcandidates), storm, ghostcandidates, outfit), i*prefs["delay"]["value"])
else if (prefs["playersonly"]["value"] != "Yes")
addtimer(CALLBACK(GLOBAL_PROC, .proc/doPortalSpawn, get_random_station_turf(), pathToSpawn, prefs["amount"]["value"], storm, null, outfit), i*prefs["delay"]["value"])
if(E)
E.processing = FALSE
if(E.announceWhen>0)
@@ -653,3 +726,29 @@
log_admin("[key_name(usr)] used secret [item]")
if (ok)
to_chat(world, text("<B>A secret has been activated by []!</B>", usr.key))
/proc/portalAnnounce(announcement, playlightning)
set waitfor = 0
if (playlightning)
sound_to_playing_players('sound/magic/lightning_chargeup.ogg')
sleep(80)
priority_announce(replacetext(announcement, "%STATION%", station_name()))
if (playlightning)
sleep(20)
sound_to_playing_players('sound/magic/lightningbolt.ogg')
/proc/doPortalSpawn(turf/loc, mobtype, numtospawn, portal_appearance, players, humanoutfit)
for (var/i in 1 to numtospawn)
var/mob/spawnedMob = new mobtype(loc)
if (length(players))
var/mob/chosen = players[1]
if (chosen.client)
chosen.client.prefs.copy_to(spawnedMob)
spawnedMob.key = chosen.key
players -= chosen
if (ishuman(spawnedMob) && ispath(humanoutfit, /datum/outfit))
var/mob/living/carbon/human/H = spawnedMob
H.equipOutfit(humanoutfit)
var/turf/T = get_step(loc, SOUTHWEST)
flick_overlay_static(portal_appearance, T, 15)
playsound(T, 'sound/magic/lightningbolt.ogg', rand(80, 100), 1)
+195 -48
View File
@@ -1,10 +1,10 @@
/proc/create_message(type, target_key, admin_ckey, text, timestamp, server, secret, logged = 1, browse)
/proc/create_message(type, target_key, admin_ckey, text, timestamp, server, secret, logged = 1, browse, expiry, note_severity)
if(!SSdbcore.Connect())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
if(!type)
return
var/target_ckey
var/target_ckey = ckey(target_key)
if(!target_key && (type == "note" || type == "message" || type == "watchlist entry"))
var/new_key = input(usr,"Who would you like to create a [type] for?","Enter a key or ckey",null) as null|text
if(!new_key)
@@ -23,13 +23,8 @@
target_key = new_key
if(QDELETED(usr))
return
if(!target_ckey)
if(target_key)
target_ckey = ckey(target_key)
else
return
if(target_ckey)
target_ckey = sanitizeSQL(ckey(target_ckey))
target_ckey = sanitizeSQL(target_ckey)
if(!target_key)
target_key = target_ckey
if(!admin_ckey)
@@ -59,7 +54,30 @@
secret = 0
else
return
var/datum/DBQuery/query_create_message = SSdbcore.NewQuery("INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, server_ip, server_port, round_id, secret) VALUES ('[type]', '[target_ckey]', '[admin_ckey]', '[text]', '[timestamp]', '[server]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]','[secret]')")
if(isnull(expiry))
if(alert(usr, "Set an expiry time? Expired messages are hidden like deleted ones.", "Expiry time?", "Yes", "No", "Cancel") == "Yes")
var/expire_time = input("Set expiry time for [type] as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than current time for obvious reasons.", "Set expiry time", SQLtime()) as null|text
if(!expire_time)
return
expire_time = sanitizeSQL(expire_time)
var/datum/DBQuery/query_validate_expire_time = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[expire_time]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[expire_time]','%Y-%c-%d %T'), 0)")
if(!query_validate_expire_time.warn_execute())
qdel(query_validate_expire_time)
return
if(query_validate_expire_time.NextRow())
var/checktime = text2num(query_validate_expire_time.item[1])
if(!checktime)
to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.")
qdel(query_validate_expire_time)
return
expiry = query_validate_expire_time.item[1]
qdel(query_validate_expire_time)
if(type == "note" && isnull(note_severity))
note_severity = input("Set the severity of the note.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
if(!note_severity)
return
note_severity = sanitizeSQL(note_severity)
var/datum/DBQuery/query_create_message = SSdbcore.NewQuery("INSERT INTO [format_table_name("messages")] (type, targetckey, adminckey, text, timestamp, server, server_ip, server_port, round_id, secret, expire_timestamp, severity) VALUES ('[type]', '[target_ckey]', '[admin_ckey]', '[text]', '[timestamp]', '[server]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]','[secret]', [expiry ? "'[expiry]'" : "NULL"], [note_severity ? "'[note_severity]'" : "NULL"])")
var/pm = "[key_name(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""]: [text]"
var/header = "[key_name_admin(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""]"
if(!query_create_message.warn_execute())
@@ -88,7 +106,7 @@
var/text
var/user_key_name = key_name(usr)
var/user_name_admin = key_name_admin(usr)
var/datum/DBQuery/query_find_del_message = SSdbcore.NewQuery("SELECT type, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
var/datum/DBQuery/query_find_del_message = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
if(!query_find_del_message.warn_execute())
qdel(query_find_del_message)
return
@@ -123,7 +141,7 @@
var/editor_key = sanitizeSQL(usr.key)
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
var/datum/DBQuery/query_find_edit_message = SSdbcore.NewQuery("SELECT type, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
var/datum/DBQuery/query_find_edit_message = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), targetckey), text FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
if(!query_find_edit_message.warn_execute())
qdel(query_find_edit_message)
return
@@ -151,6 +169,103 @@
browse_messages(target_ckey = ckey(target_key), agegate = TRUE)
qdel(query_find_edit_message)
/proc/edit_message_expiry(message_id, browse)
if(!SSdbcore.Connect())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
message_id = text2num(message_id)
if(!message_id)
return
var/editor_ckey = sanitizeSQL(usr.ckey)
var/editor_key = sanitizeSQL(usr.key)
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
var/datum/DBQuery/query_find_edit_expiry_message = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), expire_timestamp FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
if(!query_find_edit_expiry_message.warn_execute())
qdel(query_find_edit_expiry_message)
return
if(query_find_edit_expiry_message.NextRow())
var/type = query_find_edit_expiry_message.item[1]
var/target_key = query_find_edit_expiry_message.item[2]
var/admin_key = query_find_edit_expiry_message.item[3]
var/old_expiry = query_find_edit_expiry_message.item[4]
var/new_expiry
var/expire_time = input("Set expiry time for [type] as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than current time for obvious reasons. Enter -1 to remove expiry time.", "Set expiry time", old_expiry) as null|text
if(!expire_time)
qdel(query_find_edit_expiry_message)
return
if(expire_time == "-1")
new_expiry = "non-expiring"
else
expire_time = sanitizeSQL(expire_time)
var/datum/DBQuery/query_validate_expire_time_edit = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[expire_time]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[expire_time]','%Y-%c-%d %T'), 0)")
if(!query_validate_expire_time_edit.warn_execute())
qdel(query_validate_expire_time_edit)
qdel(query_find_edit_expiry_message)
return
if(query_validate_expire_time_edit.NextRow())
var/checktime = text2num(query_validate_expire_time_edit.item[1])
if(!checktime)
to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.")
qdel(query_validate_expire_time_edit)
qdel(query_find_edit_expiry_message)
return
new_expiry = query_validate_expire_time_edit.item[1]
qdel(query_validate_expire_time_edit)
var/edit_text = sanitizeSQL("Expiration time edited by [editor_key] on [SQLtime()] from [old_expiry] to [new_expiry]<hr>")
var/datum/DBQuery/query_edit_message_expiry = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET expire_timestamp = [expire_time == "-1" ? "NULL" : "'[new_expiry]'"], lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
if(!query_edit_message_expiry.warn_execute())
qdel(query_edit_message_expiry)
qdel(query_find_edit_expiry_message)
return
qdel(query_edit_message_expiry)
log_admin_private("[kn] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [old_expiry] to [new_expiry]")
message_admins("[kna] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [old_expiry] to [new_expiry]")
if(browse)
browse_messages("[type]")
else
browse_messages(target_ckey = ckey(target_key), agegate = TRUE)
qdel(query_find_edit_expiry_message)
/proc/edit_message_severity(message_id)
if(!SSdbcore.Connect())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
return
message_id = text2num(message_id)
if(!message_id)
return
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
var/datum/DBQuery/query_find_edit_note_severity = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), severity FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
if(!query_find_edit_note_severity.warn_execute())
qdel(query_find_edit_note_severity)
return
if(query_find_edit_note_severity.NextRow())
var/type = query_find_edit_note_severity.item[1]
var/target_key = query_find_edit_note_severity.item[2]
var/admin_key = query_find_edit_note_severity.item[3]
var/old_severity = query_find_edit_note_severity.item[4]
if(!old_severity)
old_severity = "NA"
var/editor_key = sanitizeSQL(usr.key)
var/editor_ckey = sanitizeSQL(usr.ckey)
var/new_severity = input("Set the severity of the note.", "Severity", null, null) as null|anything in list("high", "medium", "minor", "none") //lowercase for edit log consistency
if(!new_severity)
qdel(query_find_edit_note_severity)
return
new_severity = sanitizeSQL(new_severity)
var/edit_text = sanitizeSQL("Note severity edited by [editor_key] on [SQLtime()] from [old_severity] to [new_severity]<hr>")
var/datum/DBQuery/query_edit_note_severity = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET severity = '[new_severity]', lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
if(!query_edit_note_severity.warn_execute(async = TRUE))
qdel(query_edit_note_severity)
qdel(qdel(query_find_edit_note_severity))
return
qdel(query_edit_note_severity)
log_admin_private("[kn] has edited the severity of a [type] for [target_key] made by [admin_key] from [old_severity] to [new_severity]")
message_admins("[kna] has edited the severity time of a [type] for [target_key] made by [admin_key] from [old_severity] to [new_severity]")
browse_messages(target_ckey = ckey(target_key), agegate = TRUE)
qdel(query_find_edit_note_severity)
/proc/toggle_message_secrecy(message_id)
if(!SSdbcore.Connect())
to_chat(usr, "<span class='danger'>Failed to establish database connection.</span>")
@@ -162,7 +277,7 @@
var/editor_key = sanitizeSQL(usr.key)
var/kn = key_name(usr)
var/kna = key_name_admin(usr)
var/datum/DBQuery/query_find_message_secret = SSdbcore.NewQuery("SELECT type, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), secret FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
var/datum/DBQuery/query_find_message_secret = SSdbcore.NewQuery("SELECT type, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), targetckey), secret FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
if(!query_find_message_secret.warn_execute())
qdel(query_find_message_secret)
return
@@ -189,10 +304,10 @@
return
var/list/output = list()
var/ruler = "<hr style='background:#000000; border:0; height:3px'>"
var/list/navbar = list("<a href='?_src_=holder;[HrefToken()];nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;[HrefToken()];nonalpha=2'>\[#\]</a>")
var/list/navbar = list("<a href='?_src_=holder;[HrefToken()];nonalpha=1'>All</a><a href='?_src_=holder;[HrefToken()];nonalpha=2'>#</a>")
for(var/letter in GLOB.alphabet)
navbar += "|<a href='?_src_=holder;[HrefToken()];showmessages=[letter]'>\[[letter]\]</a>"
navbar += "|<a href='?_src_=holder;[HrefToken()];showmemo=1'>\[Memos\]</a>|<a href='?_src_=holder;[HrefToken()];showwatch=1'>\[Watchlist\]</a>"
navbar += "<a href='?_src_=holder;[HrefToken()];showmessages=[letter]'>[letter]</a>"
navbar += "<a href='?_src_=holder;[HrefToken()];showmemo=1'>Memos</a><a href='?_src_=holder;[HrefToken()];showwatch=1'>Watchlist</a>"
navbar += "<br><form method='GET' name='search' action='?'>\
<input type='hidden' name='_src_' value='holder'>\
[HrefTokenFormField()]\
@@ -203,16 +318,16 @@
if(type == "memo" || type == "watchlist entry")
if(type == "memo")
output += "<h2><center>Admin memos</h2>"
output += "<a href='?_src_=holder;[HrefToken()];addmemo=1'>\[Add memo\]</a></center>"
output += "<a href='?_src_=holder;[HrefToken()];addmemo=1'>Add memo</a></center>"
else if(type == "watchlist entry")
output += "<h2><center>Watchlist entries</h2>"
output += "<a href='?_src_=holder;[HrefToken()];addwatchempty=1'>\[Add watchlist entry\]</a>"
output += "<a href='?_src_=holder;[HrefToken()];addwatchempty=1'>Add watchlist entry</a>"
if(filter)
output += "|<a href='?_src_=holder;[HrefToken()];showwatch=1'>\[Unfilter clients\]</a></center>"
output += "<a href='?_src_=holder;[HrefToken()];showwatch=1'>Unfilter clients</a></center>"
else
output += "|<a href='?_src_=holder;[HrefToken()];showwatchfilter=1'>\[Filter offline clients\]</a></center>"
output += "<a href='?_src_=holder;[HrefToken()];showwatchfilter=1'>Filter offline clients</a></center>"
output += ruler
var/datum/DBQuery/query_get_type_messages = SSdbcore.NewQuery("SELECT id, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), text, timestamp, server, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor) FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0")
var/datum/DBQuery/query_get_type_messages = SSdbcore.NewQuery("SELECT id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), targetckey, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), text, timestamp, server, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor), expire_timestamp FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)")
if(!query_get_type_messages.warn_execute())
qdel(query_get_type_messages)
return
@@ -229,12 +344,17 @@
var/timestamp = query_get_type_messages.item[6]
var/server = query_get_type_messages.item[7]
var/editor_key = query_get_type_messages.item[8]
var/expire_timestamp = query_get_type_messages.item[9]
output += "<b>"
if(type == "watchlist entry")
output += "[t_key] | "
output += "[timestamp] | [server] | [admin_key]</b>"
output += " <a href='?_src_=holder;[HrefToken()];deletemessageempty=[id]'>\[Delete\]</a>"
output += " <a href='?_src_=holder;[HrefToken()];editmessageempty=[id]'>\[Edit\]</a>"
output += "[timestamp] | [server] | [admin_key]"
if(expire_timestamp)
output += " | Expires [expire_timestamp]"
output += "</b>"
output += " <a href='?_src_=holder;[HrefToken()];editmessageexpiryempty=[id]'>Change Expiry Time</a>"
output += " <a href='?_src_=holder;[HrefToken()];deletemessageempty=[id]'>Delete</a>"
output += " <a href='?_src_=holder;[HrefToken()];editmessageempty=[id]'>Edit</a>"
if(editor_key)
output += " <font size='2'>Last edit by [editor_key] <a href='?_src_=holder;[HrefToken()];messageedits=[id]'>(Click here to see edit log)</a></font>"
output += "<br>[text]<hr style='background:#000000; border:0; height:1px'>"
@@ -242,7 +362,7 @@
if(target_ckey)
target_ckey = sanitizeSQL(target_ckey)
var/target_key
var/datum/DBQuery/query_get_messages = SSdbcore.NewQuery("SELECT type, secret, id, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), text, timestamp, server, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), DATEDIFF(NOW(), timestamp) AS `age`, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey) FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = '[target_ckey]' AND deleted = 0 ORDER BY timestamp DESC")
var/datum/DBQuery/query_get_messages = SSdbcore.NewQuery("SELECT type, secret, id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), text, timestamp, server, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor), DATEDIFF(NOW(), timestamp), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), targetckey), expire_timestamp, severity FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = '[target_ckey]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY timestamp DESC")
if(!query_get_messages.warn_execute())
qdel(query_get_messages)
return
@@ -267,6 +387,8 @@
var/editor_key = query_get_messages.item[8]
var/age = text2num(query_get_messages.item[9])
target_key = query_get_messages.item[10]
var/expire_timestamp = query_get_messages.item[11]
var/severity = query_get_messages.item[12]
var/alphatext = ""
var/nsd = CONFIG_GET(number/note_stale_days)
var/nfd = CONFIG_GET(number/note_fresh_days)
@@ -280,21 +402,33 @@
alpha = 10
skipped = TRUE
alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];"
var/list/data = list("<p style='margin:0px;[alphatext]'> <b>[timestamp] | [server] | [admin_key]</b>")
var/list/data = list("<div style='margin:0px;[alphatext]'><p class='severity'>")
if(severity)
data += "<img src='[severity]_button.png' height='24' width='24'></img> "
data += "<b>[timestamp] | [server] | [admin_key][secret ? " | <i>- Secret</i>" : ""]"
if(expire_timestamp)
data += " | Expires [expire_timestamp]"
data += "</b></p><center>"
if(!linkless)
data += " <a href='?_src_=holder;[HrefToken()];deletemessage=[id]'>\[Delete\]</a>"
if(type == "note")
data += " <a href='?_src_=holder;[HrefToken()];secretmessage=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not secret\]"]</a>"
if(severity)
data += "<a href='?_src_=holder;[HrefToken()];editmessageseverity=[id]'>[severity=="none" ? "No" : "[capitalize(severity)]"] Severity</a>"
else
data += "<a href='?_src_=holder;[HrefToken()];editmessageseverity=[id]'>N/A Severity</a>"
data += " <a href='?_src_=holder;[HrefToken()];editmessageexpiry=[id]'>Change Expiry Time</a>"
data += " <a href='?_src_=holder;[HrefToken()];deletemessage=[id]'>Delete</a>"
if(type == "note")
data += " <a href='?_src_=holder;[HrefToken()];secretmessage=[id]'>[secret ? "<b>Secret</b>" : "Not secret"]</a>"
if(type == "message sent")
data += " <font size='2'>Message has been sent</font>"
if(editor_key)
data += "|"
else
data += " <a href='?_src_=holder;[HrefToken()];editmessage=[id]'>\[Edit\]</a>"
data += " <a href='?_src_=holder;[HrefToken()];editmessage=[id]'>Edit</a>"
if(editor_key)
data += " <font size='2'>Last edit by [editor_key] <a href='?_src_=holder;[HrefToken()];messageedits=[id]'>(Click here to see edit log)</a></font>"
data += "<br>[text]</p><hr style='background:#000000; border:0; height:1px; [alphatext]'>"
data += "</div></center>"
data += "<p style='[alphatext]'>[text]</p><hr style='background:#000000; border:0; height:1px; [alphatext]'>"
switch(type)
if("message")
messagedata += data
@@ -305,36 +439,43 @@
if("note")
notedata += data
qdel(query_get_messages)
if(!target_key)
var/datum/DBQuery/query_get_message_key = SSdbcore.NewQuery("SELECT byond_key FROM [format_table_name("player")] WHERE ckey = '[target_ckey]'")
if(!query_get_message_key.warn_execute())
qdel(query_get_message_key)
return
if(query_get_message_key.NextRow())
target_key = query_get_message_key.item[1]
qdel(query_get_message_key)
output += "<h2><center>[target_key]</center></h2><center>"
if(!linkless)
output += "<a href='?_src_=holder;[HrefToken()];addnote=[target_key]'>\[Add note\]</a>"
output += " <a href='?_src_=holder;[HrefToken()];addmessage=[target_key]'>\[Add message\]</a>"
output += " <a href='?_src_=holder;[HrefToken()];addwatch=[target_key]'>\[Add to watchlist\]</a>"
output += " <a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey]'>\[Refresh page\]</a></center>"
output += "<a href='?_src_=holder;[HrefToken()];addnote=[target_key]'>Add note</a>"
output += " <a href='?_src_=holder;[HrefToken()];addmessage=[target_key]'>Add message</a>"
output += " <a href='?_src_=holder;[HrefToken()];addwatch=[target_key]'>Add to watchlist</a>"
output += " <a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey]'>Refresh page</a></center>"
else
output += " <a href='?_src_=holder;[HrefToken()];showmessageckeylinkless=[target_ckey]'>\[Refresh page\]</a></center>"
output += " <a href='?_src_=holder;[HrefToken()];showmessageckeylinkless=[target_ckey]'>Refresh page</a></center>"
output += ruler
if(messagedata)
output += "<h4>Messages</h4>"
output += "<h2>Messages</h2>"
output += messagedata
if(watchdata)
output += "<h4>Watchlist</h4>"
output += "<h2>Watchlist</h2>"
output += watchdata
if(notedata)
output += "<h4>Notes</h4>"
output += "<h2>Notes</h2>"
output += notedata
if(!linkless)
if (agegate)
if (skipped) //the first skipped message is still shown so that we can put this link over it.
output += " <center><a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey];showall=1' style='position: relative; top: -3em;'>\[Show [skipped] hidden messages\]</center>"
output += "<center><a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey];showall=1' style='position: relative; top: -3em;'>Show [skipped] hidden messages</a></center>"
else
output += " <center><a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey];showall=1'>\[Show All\]</center>"
output += "<center><a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey];showall=1'>Show All</a></center>"
else
output += " <center><a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey]'>\[Hide Old\]</center>"
output += "<center><a href='?_src_=holder;[HrefToken()];showmessageckey=[target_ckey]'>Hide Old</a></center>"
if(index)
var/search
output += "<center><a href='?_src_=holder;[HrefToken()];addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;[HrefToken()];addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;[HrefToken()];addnoteempty=1'>\[Add note\]</a></center>"
output += "<center><a href='?_src_=holder;[HrefToken()];addmessageempty=1'>Add message</a><a href='?_src_=holder;[HrefToken()];addwatchempty=1'>Add watchlist entry</a><a href='?_src_=holder;[HrefToken()];addnoteempty=1'>Add note</a></center>"
output += ruler
if(!isnum(index))
index = sanitizeSQL(index)
@@ -345,7 +486,7 @@
search = "^\[^\[:alpha:\]\]"
else
search = "^[index]"
var/datum/DBQuery/query_list_messages = SSdbcore.NewQuery("SELECT DISTINCT targetckey, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey) FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey REGEXP '[search]' AND deleted = 0 ORDER BY targetckey")
var/datum/DBQuery/query_list_messages = SSdbcore.NewQuery("SELECT DISTINCT targetckey, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey) FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey REGEXP '[search]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY targetckey")
if(!query_list_messages.warn_execute())
qdel(query_list_messages)
return
@@ -354,12 +495,18 @@
return
var/index_ckey = query_list_messages.item[1]
var/index_key = query_list_messages.item[2]
if(!index_key)
index_key = index_ckey
output += "<a href='?_src_=holder;[HrefToken()];showmessageckey=[index_ckey]'>[index_key]</a><br>"
qdel(query_list_messages)
else if(!type && !target_ckey && !index)
output += "<center></a> <a href='?_src_=holder;[HrefToken()];addmessageempty=1'>\[Add message\]</a><a href='?_src_=holder;[HrefToken()];addwatchempty=1'>\[Add watchlist entry\]</a><a href='?_src_=holder;[HrefToken()];addnoteempty=1'>\[Add note\]</a></center>"
output += "<center><a href='?_src_=holder;[HrefToken()];addmessageempty=1'>Add message</a><a href='?_src_=holder;[HrefToken()];addwatchempty=1'>Add watchlist entry</a><a href='?_src_=holder;[HrefToken()];addnoteempty=1'>Add note</a></center>"
output += ruler
usr << browse({"<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /></head><body>[jointext(output, "")]</body></html>"}, "window=browse_messages;size=900x500")
var/datum/browser/browser = new(usr, "Note panel", "Manage player notes", 1000, 500)
var/datum/asset/notes_assets = get_asset_datum(/datum/asset/simple/notes)
notes_assets.send(src)
browser.set_content(jointext(output, ""))
browser.open()
/proc/get_message_output(type, target_ckey)
if(!SSdbcore.Connect())
@@ -370,7 +517,7 @@
var/output
if(target_ckey)
target_ckey = sanitizeSQL(target_ckey)
var/query = "SELECT id, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), text, timestamp, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor) FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0"
var/query = "SELECT id, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), adminckey), text, timestamp, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE ckey = lasteditor), lasteditor) FROM [format_table_name("messages")] WHERE type = '[type]' AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL)"
if(type == "message" || type == "watchlist entry")
query += " AND targetckey = '[target_ckey]'"
var/datum/DBQuery/query_get_message_output = SSdbcore.NewQuery(query)
@@ -432,7 +579,7 @@
timestamp = query_convert_time.item[1]
qdel(query_convert_time)
if(ckey && notetext && timestamp && admin_ckey && server)
create_message("note", ckey, admin_ckey, notetext, timestamp, server, 1, 0)
create_message("note", ckey, admin_ckey, notetext, timestamp, server, 1, 0, null, 0, 0)
notesfile.cd = "/"
notesfile.dir.Remove(ckey)
+82 -35
View File
@@ -215,37 +215,38 @@
var/banduration = text2num(href_list["dbbaddduration"])
var/banjob = href_list["dbbanaddjob"]
var/banreason = href_list["dbbanreason"]
var/banseverity = href_list["dbbanaddseverity"]
switch(bantype)
if(BANTYPE_PERMA)
if(!banckey || !banreason)
to_chat(usr, "Not enough parameters (Requires ckey and reason).")
if(!banckey || !banreason || !banseverity)
to_chat(usr, "Not enough parameters (Requires ckey, severity, and reason).")
return
banduration = null
banjob = null
if(BANTYPE_TEMP)
if(!banckey || !banreason || !banduration)
to_chat(usr, "Not enough parameters (Requires ckey, reason and duration).")
if(!banckey || !banreason || !banduration || !banseverity)
to_chat(usr, "Not enough parameters (Requires ckey, reason, severity and duration).")
return
banjob = null
if(BANTYPE_JOB_PERMA)
if(!banckey || !banreason || !banjob)
to_chat(usr, "Not enough parameters (Requires ckey, reason and job).")
if(!banckey || !banreason || !banjob || !banseverity)
to_chat(usr, "Not enough parameters (Requires ckey, severity, reason and job).")
return
banduration = null
if(BANTYPE_JOB_TEMP)
if(!banckey || !banreason || !banjob || !banduration)
to_chat(usr, "Not enough parameters (Requires ckey, reason and job).")
if(!banckey || !banreason || !banjob || !banduration || !banseverity)
to_chat(usr, "Not enough parameters (Requires ckey, severity, reason and job).")
return
if(BANTYPE_ADMIN_PERMA)
if(!banckey || !banreason)
to_chat(usr, "Not enough parameters (Requires ckey and reason).")
if(!banckey || !banreason || !banseverity)
to_chat(usr, "Not enough parameters (Requires ckey, severity and reason).")
return
banduration = null
banjob = null
if(BANTYPE_ADMIN_TEMP)
if(!banckey || !banreason || !banduration)
to_chat(usr, "Not enough parameters (Requires ckey, reason and duration).")
if(!banckey || !banreason || !banduration || !banseverity)
to_chat(usr, "Not enough parameters (Requires ckey, severity, reason and duration).")
return
banjob = null
@@ -270,7 +271,7 @@
if(!DB_ban_record(bantype, playermob, banduration, banreason, banjob, bankey, banip, bancid ))
to_chat(usr, "<span class='danger'>Failed to apply ban.</span>")
return
create_message("note", bankey, null, banreason, null, null, 0, 0)
create_message("note", bankey, null, banreason, null, null, 0, 0, null, 0, banseverity)
else if(href_list["editrightsbrowser"])
edit_admin_permissions(0)
@@ -340,7 +341,7 @@
else if(href_list["toggle_continuous"])
if(!check_rights(R_ADMIN))
return
var/list/continuous = CONFIG_GET(keyed_flag_list/continuous)
var/list/continuous = CONFIG_GET(keyed_list/continuous)
if(!continuous[SSticker.mode.config_tag])
continuous[SSticker.mode.config_tag] = TRUE
else
@@ -353,7 +354,7 @@
if(!check_rights(R_ADMIN))
return
var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag)
var/list/midround_antag = CONFIG_GET(keyed_list/midround_antag)
if(!midround_antag[SSticker.mode.config_tag])
midround_antag[SSticker.mode.config_tag] = TRUE
else
@@ -599,6 +600,9 @@
var/reason = input(usr,"Please State Reason.","Reason") as message|null
if(!reason)
return
var/severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
if(!severity)
return
if(!DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, "appearance"))
to_chat(usr, "<span class='danger'>Failed to apply ban.</span>")
return
@@ -606,7 +610,7 @@
jobban_buildcache(M.client)
ban_unban_log_save("[key_name(usr)] appearance banned [key_name(M)]. reason: [reason]")
log_admin_private("[key_name(usr)] appearance banned [key_name(M)]. \nReason: [reason]")
create_message("note", M.key, null, "Appearance banned - [reason]", null, null, 0, 0)
create_message("note", M.key, null, "Appearance banned - [reason]", null, null, 0, 0, null, 0, severity)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] appearance banned [key_name_admin(M)].</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been appearance banned by [usr.client.key].</BIG></span>")
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
@@ -804,30 +808,35 @@
//Drones
if(jobban_isbanned(M, "drone"))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=drone;jobban4=[REF(M)]'><font color=red>Drone</font></a></td>"
if(jobban_isbanned(M, ROLE_DRONE))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_DRONE];jobban4=[REF(M)]'><font color=red>Drone</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=drone;jobban4=[REF(M)]'>Drone</a></td>"
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_DRONE];jobban4=[REF(M)]'>Drone</a></td>"
//Positronic Brains
if(jobban_isbanned(M, "posibrain"))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=posibrain;jobban4=[REF(M)]'><font color=red>Posibrain</font></a></td>"
if(jobban_isbanned(M, ROLE_POSIBRAIN))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_POSIBRAIN];jobban4=[REF(M)]'><font color=red>Posibrain</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=posibrain;jobban4=[REF(M)]'>Posibrain</a></td>"
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_POSIBRAIN];jobban4=[REF(M)]'>Posibrain</a></td>"
//Sentience Potion Spawn
if(jobban_isbanned(M, ROLE_SENTIENCE))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_SENTIENCE];jobban4=[REF(M)]'><font color=red>Sentience Potion Spawn</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_SENTIENCE];jobban4=[REF(M)]'>Sentience Potion Spawn</a></td>"
//Deathsquad
if(jobban_isbanned(M, "deathsquad"))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=deathsquad;jobban4=[REF(M)]'><font color=red>Deathsquad</font></a></td>"
if(jobban_isbanned(M, ROLE_DEATHSQUAD))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_DEATHSQUAD];jobban4=[REF(M)]'><font color=red>Deathsquad</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=deathsquad;jobban4=[REF(M)]'>Deathsquad</a></td>"
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_DEATHSQUAD];jobban4=[REF(M)]'>Deathsquad</a></td>"
//Lavaland roles
if(jobban_isbanned(M, "lavaland"))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=lavaland;jobban4=[REF(M)]'><font color=red>Lavaland</font></a></td>"
if(jobban_isbanned(M, ROLE_LAVALAND))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_LAVALAND];jobban4=[REF(M)]'><font color=red>Lavaland</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=lavaland;jobban4=[REF(M)]'>Lavaland</a></td>"
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_LAVALAND];jobban4=[REF(M)]'>Lavaland</a></td>"
dat += "</tr></table>"
@@ -894,6 +903,16 @@
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=alien;jobban4=[REF(M)]'>Alien</a></td>"
//Other Roles (black)
dat += "<table cellpadding='1' cellspacing='0' width='100%'>"
dat += "<tr bgcolor='000000'><th colspan='5'><a href='?src=[REF(src)];[HrefToken()];jobban3=otherroles;jobban4=[REF(M)]' style='color: white;'>Other Roles</a></th></tr><tr align='center'>"
//Mind Transfer Potion
if(jobban_isbanned(M, ROLE_MIND_TRANSFER))
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_MIND_TRANSFER];jobban4=[REF(M)]'><font color=red>Mind Transfer Potion</font></a></td>"
else
dat += "<td width='20%'><a href='?src=[REF(src)];[HrefToken()];jobban3=[ROLE_MIND_TRANSFER];jobban4=[REF(M)]'>Mind Transfer Potion</a></td>"
dat += "</tr></table>"
usr << browse(dat, "window=jobban2;size=800x450")
return
@@ -953,11 +972,13 @@
continue
joblist += jobPos
if("ghostroles")
joblist += list(ROLE_PAI, "posibrain", "drone", "deathsquad", "lavaland")
joblist += list(ROLE_PAI, ROLE_POSIBRAIN, ROLE_DRONE , ROLE_DEATHSQUAD, ROLE_LAVALAND, ROLE_SENTIENCE)
if("teamantags")
joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN)
if("convertantags")
joblist += list(ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ALIEN)
if("otherroles")
joblist += list(ROLE_MIND_TRANSFER)
else
joblist += href_list["jobban3"]
@@ -969,6 +990,7 @@
//Banning comes first
if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
var/severity = null
switch(alert("Temporary Ban for [M.key]?",,"Yes","No", "Cancel"))
if("Yes")
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num|null
@@ -978,7 +1000,9 @@
var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
if(!reason)
return
severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
if(!severity)
return
var/msg
for(var/job in notbannedlist)
if(!DB_ban_record(BANTYPE_JOB_TEMP, M, mins, reason, job))
@@ -992,7 +1016,7 @@
msg = job
else
msg += ", [job]"
create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0)
create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg].</BIG></span>")
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
@@ -1001,6 +1025,9 @@
return 1
if("No")
var/reason = input(usr,"Please State Reason For Banning [M.key].","Reason") as message|null
severity = input("Set the severity of the note/ban.", "Severity", null, null) as null|anything in list("High", "Medium", "Minor", "None")
if(!severity)
return
if(reason)
var/msg
for(var/job in notbannedlist)
@@ -1015,7 +1042,7 @@
msg = job
else
msg += ", [job]"
create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0)
create_message("note", M.key, null, "Banned from [msg] - [reason]", null, null, 0, 0, null, 0, severity)
message_admins("<span class='adminnotice'>[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].</span>")
to_chat(M, "<span class='boldannounce'><BIG>You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.key] from: [msg].</BIG></span>")
to_chat(M, "<span class='boldannounce'>The reason is: [reason]</span>")
@@ -1140,6 +1167,24 @@
var/message_id = href_list["editmessageempty"]
edit_message(message_id, browse = 1)
else if(href_list["editmessageexpiry"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["editmessageexpiry"]
edit_message_expiry(message_id)
else if(href_list["editmessageexpiryempty"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["editmessageexpiryempty"]
edit_message_expiry(message_id, browse = 1)
else if(href_list["editmessageseverity"])
if(!check_rights(R_ADMIN))
return
var/message_id = href_list["editmessageseverity"]
edit_message_severity(message_id)
else if(href_list["secretmessage"])
if(!check_rights(R_ADMIN))
return
@@ -1204,7 +1249,9 @@
if(query_get_message_edits.NextRow())
var/edit_log = query_get_message_edits.item[1]
if(!QDELETED(usr))
usr << browse(edit_log,"window=noteedits")
var/datum/browser/browser = new(usr, "Note edits", "Note edits")
browser.set_content(jointext(edit_log, ""))
browser.open()
qdel(query_get_message_edits)
else if(href_list["newban"])
@@ -1365,10 +1412,10 @@
if(!ismob(M))
to_chat(usr, "this can only be used on instances of type /mob.")
var/speech = input("What will [key_name(M)] say?.", "Force speech", "")// Don't need to sanitize, since it does that in say(), we also trust our admins.
var/speech = input("What will [key_name(M)] say?", "Force speech", "")// Don't need to sanitize, since it does that in say(), we also trust our admins.
if(!speech)
return
M.say(speech)
M.say(speech, forced = "admin speech")
speech = sanitize(speech) // Nah, we don't trust them
log_admin("[key_name(usr)] forced [key_name(M)] to say: [speech]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] forced [key_name_admin(M)] to say: [speech]</span>")
+5 -4
View File
@@ -196,9 +196,10 @@
/proc/SDQL_testout(list/query_tree, indent = 0)
var/static/whitespace = "&nbsp;&nbsp;&nbsp; "
var/spaces = ""
for(var/s = 0, s < indent, s++)
spaces += " "
spaces += whitespace
for(var/item in query_tree)
if(istype(item, /list))
@@ -212,12 +213,12 @@
if(!isnum(item) && query_tree[item])
if(istype(query_tree[item], /list))
to_chat(usr, "[spaces] (")
to_chat(usr, "[spaces][whitespace](")
SDQL_testout(query_tree[item], indent + 2)
to_chat(usr, "[spaces] )")
to_chat(usr, "[spaces][whitespace])")
else
to_chat(usr, "[spaces] [query_tree[item]]")
to_chat(usr, "[spaces][whitespace][query_tree[item]]")
@@ -294,8 +294,8 @@
break
parse_error("Expected ',' or ']' after array assoc value, but found '[token(i)]'")
return i
i++
continue
i++
continue
temp_expression_list = list()
i = expression(i, temp_expression_list)
while(token(i) && token(i) != "]")
@@ -331,7 +331,7 @@
//string: ''' <some text> ''' | '"' <some text > '"'
/datum/SDQL_parser/proc/string(i, list/node)
if(copytext(token(i), 1, 2) in list("'", "\""))
node += copytext(token(i),2,-1)
node += token(i)
else
parse_error("Expected string but found '[token(i)]'")
return i + 1
+2 -3
View File
@@ -372,7 +372,6 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
var/msg = "<font color='red' size='4'><b>- AdminHelp marked as IC issue! -</b></font><br>"
msg += "<font color='red'><b>Losing is part of the game!</b></font><br>"
msg += "<font color='red'>It is also possible that your ahelp is unable to be answered properly, due to events occurring in the round.</font>"
if(initiator)
to_chat(initiator, msg)
@@ -607,7 +606,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
message["key"] = comms_key
message += type
var/list/servers = CONFIG_GET(keyed_string_list/cross_server)
var/list/servers = CONFIG_GET(keyed_list/cross_server)
for(var/I in servers)
world.Export("[servers[I]]?[list2params(message)]")
@@ -686,7 +685,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
var/is_antag = 0
if(found.mind && found.mind.special_role)
is_antag = 1
founds += "Name: [found.name]([found.real_name]) Ckey: [found.key] [is_antag ? "(Antag)" : null] "
founds += "Name: [found.name]([found.real_name]) Key: [found.key] Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;[HrefToken(TRUE)];adminmoreinfo=[REF(found)]'>?</A>|<A HREF='?_src_=holder;[HrefToken(TRUE)];adminplayerobservefollow=[REF(found)]'>F</A>)</font> "
continue
msg += "[original_word] "
+2 -3
View File
@@ -66,9 +66,8 @@
if(src.mob)
var/mob/A = src.mob
A.x = tx
A.y = ty
A.z = tz
var/turf/T = locate(tx,ty,tz)
A.forceMove(T)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Coordiate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]")
+3 -8
View File
@@ -9,16 +9,11 @@
if(!msg)
return
msg = emoji_parse(msg)
mob.log_talk(msg, LOG_ASAY)
log_talk(mob,"[key_name(src)] : [msg]",LOGASAY)
msg = keywords_lookup(msg)
if(check_rights(R_ADMIN,0))
msg = "<span class='admin'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
else
msg = "<span class='adminobserver'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
msg = "<span class='adminsay'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
to_chat(GLOB.admins, msg)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Asay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+9 -10
View File
@@ -21,18 +21,17 @@
var/mob/living/silicon/robot/borg
var/user
/datum/borgpanel/New(user, mob/living/silicon/robot/borg)
if(!istype(borg))
/datum/borgpanel/New(to_user, mob/living/silicon/robot/to_borg)
if(!istype(to_borg))
CRASH("Borg panel is only available for borgs")
qdel(src)
if (istype(user, /mob))
var/mob/M = user
if (!M.client)
CRASH("Borg panel attempted to open to a mob without a client")
src.user = M.client
else
src.user = user
src.borg = borg
user = CLIENT_FROM_VAR(to_user)
if (!user)
CRASH("Borg panel attempted to open to a mob without a client")
borg = to_borg
/datum/borgpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+3 -6
View File
@@ -1,6 +1,6 @@
/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 name = "Dsay"
set hidden = 1
if(!src.holder)
to_chat(src, "Only administrators may use this command.")
@@ -15,16 +15,13 @@
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
log_talk(mob,"[key_name(src)] : [msg]",LOGDSAY)
mob.log_talk(msg, LOG_DSAY)
if (!msg)
return
msg = emoji_parse(msg)
var/static/nicknames = world.file2list("[global.config.directory]/admin_nicknames.txt")
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[uppertext(holder.rank)]([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[msg]\"</span></span>"
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[uppertext(holder.rank)]([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[emoji_parse(msg)]\"</span></span>"
for (var/mob/M in GLOB.player_list)
if(isnewplayer(M))
+53
View File
@@ -959,6 +959,50 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
to_chat(usr, "<span class='name'>[template.name]</span>")
to_chat(usr, "<span class='italics'>[template.description]</span>")
/client/proc/place_ruin()
set category = "Debug"
set name = "Spawn Ruin"
set desc = "Attempt to randomly place a specific ruin."
if (!holder)
return
var/list/exists = list()
for(var/landmark in GLOB.ruin_landmarks)
var/obj/effect/landmark/ruin/L = landmark
exists[L.ruin_template] = landmark
var/list/names = list()
names += "---- Space Ruins ----"
for(var/name in SSmapping.space_ruins_templates)
names[name] = list(SSmapping.space_ruins_templates[name], ZTRAIT_SPACE_RUINS, /area/space)
names += "---- Lava Ruins ----"
for(var/name in SSmapping.lava_ruins_templates)
names[name] = list(SSmapping.lava_ruins_templates[name], ZTRAIT_LAVA_RUINS, /area/lavaland/surface/outdoors/unexplored)
var/ruinname = input("Select ruin", "Spawn Ruin") as null|anything in names
var/data = names[ruinname]
if (!data)
return
var/datum/map_template/ruin/template = data[1]
if (exists[template])
var/response = alert("There is already a [template] in existence.", "Spawn Ruin", "Jump", "Place Another", "Cancel")
if (response == "Jump")
usr.forceMove(get_turf(exists[template]))
return
else if (response == "Cancel")
return
var/len = GLOB.ruin_landmarks.len
seedRuins(SSmapping.levels_by_trait(data[2]), max(1, template.cost), data[3], list(ruinname = template))
if (GLOB.ruin_landmarks.len > len)
var/obj/effect/landmark/ruin/landmark = GLOB.ruin_landmarks[GLOB.ruin_landmarks.len]
log_admin("[key_name(src)] randomly spawned ruin [ruinname] at [COORD(landmark)].")
usr.forceMove(get_turf(landmark))
to_chat(src, "<span class='name'>[template.name]</span>")
to_chat(src, "<span class='italics'>[template.description]</span>")
else
to_chat(src, "<span class='warning'>Failed to place [template.name].</span>")
/client/proc/clear_dynamic_transit()
set category = "Debug"
set name = "Clear Dynamic Turf Reservations"
@@ -1047,3 +1091,12 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
return
sort = sortlist[sort]
profile_show(src, sort)
/client/proc/reload_configuration()
set category = "Debug"
set name = "Reload Configuration"
set desc = "Force config reload to world default"
if(!check_rights(R_DEBUG))
return
if(alert(usr, "Are you absolutely sure you want to reload the configuration from the default path on the disk, wiping any in-round modificatoins?", "Really reset?", "No", "Yes") == "Yes")
config.admin_reload()
+43 -28
View File
@@ -1,29 +1,45 @@
/proc/show_individual_logging_panel(mob/M, source = LOGSRC_CLIENT, type = INDIVIDUAL_ATTACK_LOG)
if(!M || !ismob(M))
return
var/ntype = text2num(type)
//Add client links
var/dat = ""
if(M.client)
dat += "<center><p>Client</p></center>"
dat += "<center><a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_ATTACK_LOG];log_src=[LOGSRC_CLIENT]'>Attack log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SAY_LOG];log_src=[LOGSRC_CLIENT]'>Say log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_EMOTE_LOG];log_src=[LOGSRC_CLIENT]'>Emote log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_OOC_LOG];log_src=[LOGSRC_CLIENT]'>OOC log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SHOW_ALL_LOG];log_src=[LOGSRC_CLIENT]'>Show all</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[type];log_src=[LOGSRC_CLIENT]'>Refresh</a></center>"
if(M.client)
dat += "<center><p>Client</p></center>"
dat += "<center>"
dat += individual_logging_panel_link(M, INDIVIDUAL_ATTACK_LOG, LOGSRC_CLIENT, "Attack Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_SAY_LOG, LOGSRC_CLIENT, "Say Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_EMOTE_LOG, LOGSRC_CLIENT, "Emote Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_COMMS_LOG, LOGSRC_CLIENT, "Comms Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_OOC_LOG, LOGSRC_CLIENT, "OOC Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_SHOW_ALL_LOG, LOGSRC_CLIENT, "Show All", source, ntype)
dat += "</center>"
else
dat += "<p> No client attached to mob </p>"
dat += "<hr style='background:#000000; border:0; height:1px'>"
dat += "<center><p>Mob</p></center>"
dat += "<center><p>Mob</p></center>"
//Add the links for the mob specific log
dat += "<center><a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_ATTACK_LOG];log_src=[LOGSRC_MOB]'>Attack log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SAY_LOG];log_src=[LOGSRC_MOB]'>Say log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_EMOTE_LOG];log_src=[LOGSRC_MOB]'>Emote log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_OOC_LOG];log_src=[LOGSRC_MOB]'>OOC log</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SHOW_ALL_LOG];log_src=[LOGSRC_MOB]'>Show all</a> | "
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[type];log_src=[LOGSRC_MOB]'>Refresh</a></center>"
dat += "<center>"
dat += individual_logging_panel_link(M, INDIVIDUAL_ATTACK_LOG, LOGSRC_MOB, "Attack Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_SAY_LOG, LOGSRC_MOB, "Say Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_EMOTE_LOG, LOGSRC_MOB, "Emote Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_COMMS_LOG, LOGSRC_MOB, "Comms Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_OOC_LOG, LOGSRC_MOB, "OOC Log", source, ntype)
dat += " | "
dat += individual_logging_panel_link(M, INDIVIDUAL_SHOW_ALL_LOG, LOGSRC_MOB, "Show All", source, ntype)
dat += "</center>"
dat += "<hr style='background:#000000; border:0; height:1px'>"
@@ -31,22 +47,21 @@
if(source == LOGSRC_CLIENT && M.client) //if client doesn't exist just fall back to the mob log
log_source = M.client.player_details.logging //should exist, if it doesn't that's a bug, don't check for it not existing
if(type == INDIVIDUAL_SHOW_ALL_LOG)
dat += "<center>Displaying all [source] logs of [key_name(M)]</center><br><hr>"
for(var/log_type in log_source)
dat += "<center><b>[log_type]</b></center><br>"
for(var/log_type in log_source)
var/nlog_type = text2num(log_type)
if(nlog_type & ntype)
var/list/reversed = log_source[log_type]
if(islist(reversed))
reversed = reverseRange(reversed.Copy())
for(var/entry in reversed)
dat += "<font size=2px>[entry]: [reversed[entry]]</font><br>"
dat += "<font size=2px><b>[entry]</b><br>[reversed[entry]]</font><br>"
dat += "<hr>"
else
dat += "<center>[source] [type] of [key_name(M)]</center><br>"
var/list/reversed = log_source[type]
if(reversed)
reversed = reverseRange(reversed.Copy())
for(var/entry in reversed)
dat += "<font size=2px>[entry]: [reversed[entry]]</font><hr>"
usr << browse(dat, "window=invidual_logging_[key_name(M)];size=600x480")
/proc/individual_logging_panel_link(mob/M, log_type, log_src, label, selected_src, selected_type)
var/slabel = label
if(selected_type == log_type && selected_src == log_src)
slabel = "<b>\[[label]\]</b>"
return "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[log_type];log_src=[log_src]'>[slabel]</a>"
@@ -4,7 +4,7 @@
var/datum/map_template/template
var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in SSmapping.map_templates
var/map = input(src, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in SSmapping.map_templates
if(!map)
return
template = SSmapping.map_templates[map]
@@ -18,35 +18,50 @@
var/image/item = image('icons/turf/overlays.dmi',S,"greenOverlay")
item.plane = ABOVE_LIGHTING_PLANE
preview += item
usr.client.images += preview
if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes")
images += preview
if(alert(src,"Confirm location.","Template Confirm","Yes","No") == "Yes")
if(template.load(T, centered = TRUE))
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]</span>")
message_admins("<span class='adminnotice'>[key_name_admin(src)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]</span>")
else
to_chat(usr, "Failed to place map")
usr.client.images -= preview
to_chat(src, "Failed to place map")
images -= preview
/client/proc/map_template_upload()
set category = "Debug"
set name = "Map Template - Upload"
var/map = input(usr, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
var/map = input(src, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
if(!map)
return
if(copytext("[map]",-4) != ".dmm")
to_chat(usr, "Bad map file: [map]")
to_chat(src, "<span class='warning'>Filename must end in '.dmm': [map]</span>")
return
var/datum/map_template/M
switch(alert(usr, "What kind of map is this?", "Map type", "Normal", "Shuttle", "Cancel"))
switch(alert(src, "What kind of map is this?", "Map type", "Normal", "Shuttle", "Cancel"))
if("Normal")
M = new /datum/map_template(map, "[map]")
M = new /datum/map_template(map, "[map]", TRUE)
if("Shuttle")
M = new /datum/map_template/shuttle(map, "[map]")
M = new /datum/map_template/shuttle(map, "[map]", TRUE)
else
return
if(M.preload_size(map))
to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])")
SSmapping.map_templates[M.name] = M
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map])</span>")
else
to_chat(usr, "Map template '[map]' failed to load properly")
if(!M.cached_map)
to_chat(src, "<span class='warning'>Map template '[map]' failed to parse properly.</span>")
return
var/datum/map_report/report = M.cached_map.check_for_errors()
var/report_link
if(report)
report.show_to(src)
report_link = " - <a href='?src=[REF(report)];[HrefToken(TRUE)];show=1'>validation report</a>"
to_chat(src, "<span class='warning'>Map template '[map]' <a href='?src=[REF(report)];[HrefToken()];show=1'>failed validation</a>.</span>")
if(report.loadable)
var/response = alert(src, "The map failed validation, would you like to load it anyways?", "Map Errors", "Cancel", "Upload Anyways")
if(response != "Upload Anyways")
return
else
alert(src, "The map failed validation and cannot be loaded.", "Map Errors", "Oh Darn")
return
SSmapping.map_templates[M.name] = M
message_admins("<span class='adminnotice'>[key_name_admin(src)] has uploaded a map template '[map]' ([M.width]x[M.height])[report_link].</span>")
to_chat(src, "<span class='notice'>Map template '[map]' ready to place ([M.width]x[M.height])</span>")
+2 -1
View File
@@ -47,7 +47,8 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/stop_line_profiling,
/client/proc/show_line_profiling,
/client/proc/create_mapping_job_icons,
/client/proc/debug_z_levels
/client/proc/debug_z_levels,
/client/proc/place_ruin
))
/obj/effect/debugging/mapfix_marker
@@ -629,9 +629,11 @@ GLOBAL_PROTECT(VVpixelmovement)
if (O.vv_edit_var(variable, var_new) == FALSE)
to_chat(src, "Your edit was rejected by the object.")
return
vv_update_display(O, "varedited", VV_MSG_EDITED)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_VAR_EDIT, args)
log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]")
log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]")
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]"
message_admins(msg)
admin_ticket_log(O, msg)
return TRUE
+1 -1
View File
@@ -351,7 +351,7 @@
"template" = list("desc" = "Template", "callback" = CALLBACK(src, .proc/makeERTTemplateModified), "type" = "datum", "path" = "/datum/ert", "subtypesonly" = TRUE, "value" = ertemplate.type),
"teamsize" = list("desc" = "Team Size", "type" = "number", "value" = ertemplate.teamsize),
"mission" = list("desc" = "Mission", "type" = "string", "value" = ertemplate.mission),
"polldesc" = list("desc" = "Ghost poll description", "string" = "text", "value" = ertemplate.polldesc),
"polldesc" = list("desc" = "Ghost poll description", "type" = "string", "value" = ertemplate.polldesc),
"enforce_human" = list("desc" = "Enforce human authority", "type" = "boolean", "value" = "[(CONFIG_GET(flag/enforce_human_authority) ? "Yes" : "No")]"),
"open_armory" = list("desc" = "Open armory doors", "type" = "boolean", "value" = "[(ertemplate.opendoors ? "Yes" : "No")]"),
)
+5 -4
View File
@@ -31,23 +31,24 @@
cross.icon_state = "tome"
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = "Nar-Sie"
deity = "Nar'Sie"
else if(isliving(usr))
var/mob/living/L = usr
if(L.has_trait(TRAIT_SPIRITUAL))
cross.icon_state = "holylight"
font_color = "blue"
prayer_type = "SPIRITUAL PRAYER"
var/msg_tmp = msg
msg = "<span class='adminnotice'>[icon2html(cross, GLOB.admins)]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> <span class='linkify'>[msg]</span></span>"
for(var/client/C in GLOB.admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
to_chat(C, msg)
if(C.prefs.toggles & SOUND_PRAYERS)
if(usr.job == "Chaplain")
SEND_SOUND(C, sound('sound/effects/pray.ogg'))
to_chat(usr, "Your prayers have been received by the gods.")
to_chat(usr, "<span class='info'>You pray to the gods: \"[msg_tmp]\"</span>")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Prayer") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
//log_admin("HELP: [key_name(src)]: [msg]")
+22 -86
View File
@@ -48,12 +48,12 @@
/client/proc/cmd_admin_headset_message(mob/M in GLOB.mob_list)
set category = "Special Verbs"
set name = "Headset Message"
admin_headset_message(M)
/client/proc/admin_headset_message(mob/M in GLOB.mob_list, sender = null)
var/mob/living/carbon/human/H = M
if(!check_rights(R_ADMIN))
return
@@ -75,7 +75,7 @@
message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.")
return
log_admin("[key_name(src)] replied to [key_name(H)]'s [sender] message with the message [input].")
log_directed_talk(src, H, input, LOG_ADMIN, "reply")
message_admins("[key_name_admin(src)] replied to [key_name_admin(H)]'s [sender] message with: \"[input]\"")
to_chat(H, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] <span class='bold'>[input].</span> Message ends.\"")
@@ -596,16 +596,28 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/admin_delete(datum/D)
var/atom/A = D
var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : ""
if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes")
log_admin("[key_name(usr)] deleted [D][coords]")
message_admins("[key_name_admin(usr)] deleted [D][coords]")
var/coords = ""
var/jmp_coords = ""
if(istype(A))
var/turf/T = get_turf(A)
if(T)
coords = "at [COORD(T)]"
jmp_coords = "at [ADMIN_COORDJMP(T)]"
else
jmp_coords = coords = "in nullspace"
if (alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes")
log_admin("[key_name(usr)] deleted [D] [coords]")
message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(isturf(D))
var/turf/T = D
T.ScrapeAway()
else
vv_update_display(D, "deleted", VV_MSG_DELETED)
qdel(D)
if(!QDELETED(D))
vv_update_display(D, "deleted", "")
/client/proc/cmd_admin_list_open_jobs()
set category = "Admin"
@@ -1117,7 +1129,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
return
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
new /obj/item/organ/zombie_infection(H)
new /obj/item/organ/zombie_infection/nodamage(H)
message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
@@ -1134,7 +1146,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
if(confirm != "Yes")
return
for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list)
for(var/obj/item/organ/zombie_infection/nodamage/I in GLOB.zombie_infection_list)
qdel(I)
message_admins("[key_name_admin(usr)] cured all zombies.")
@@ -1201,82 +1213,6 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Tip")
/proc/mass_purrbation()
for(var/M in GLOB.mob_list)
if(ishumanbasic(M))
purrbation_apply(M)
CHECK_TICK
/proc/mass_remove_purrbation()
for(var/M in GLOB.mob_list)
if(ishumanbasic(M))
purrbation_remove(M)
CHECK_TICK
/proc/purrbation_toggle(mob/living/carbon/human/H, silent = FALSE)
if(!ishumanbasic(H))
return
if(!iscatperson(H))
purrbation_apply(H, silent)
. = TRUE
else
purrbation_remove(H, silent)
. = FALSE
/proc/purrbation_apply(mob/living/carbon/human/H, silent = FALSE)
if(!ishuman(H))
return
if(iscatperson(H))
return
var/obj/item/organ/ears/cat/ears = new
var/obj/item/organ/tail/cat/tail = new
ears.Insert(H, drop_if_replaced=FALSE)
tail.Insert(H, drop_if_replaced=FALSE)
if(!silent)
to_chat(H, "Something is nya~t right.")
playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
/proc/purrbation_remove(mob/living/carbon/human/H, silent = FALSE)
if(!ishuman(H))
return
if(!iscatperson(H))
return
var/obj/item/organ/ears/cat/ears = H.getorgan(/obj/item/organ/ears/cat)
var/obj/item/organ/tail/cat/tail = H.getorgan(/obj/item/organ/tail/cat)
if(ears)
var/obj/item/organ/ears/NE
if(H.dna.species && H.dna.species.mutantears)
// Roundstart cat ears override H.dna.species.mutantears, reset it here.
H.dna.species.mutantears = initial(H.dna.species.mutantears)
if(H.dna.species.mutantears)
NE = new H.dna.species.mutantears()
if(!NE)
// Go with default ears
NE = new /obj/item/organ/ears()
NE.Insert(H, drop_if_replaced = FALSE)
if(tail)
var/obj/item/organ/tail/NT
if(H.dna.species && H.dna.species.mutanttail)
// Roundstart cat tail overrides H.dna.species.mutanttail, reset it here.
H.dna.species.mutanttail = initial(H.dna.species.mutanttail)
if(H.dna.species.mutanttail)
NT = new H.dna.species.mutanttail()
if(NT)
NT.Insert(H, drop_if_replaced = FALSE)
else
tail.Remove(H)
if(!silent)
to_chat(H, "You are no longer a cat.")
/client/proc/modify_goals()
set category = "Debug"
set name = "Modify goals"
@@ -1310,7 +1246,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
/client/proc/smite(mob/living/carbon/human/target as mob)
set name = "Smite"
set category = "Fun"
if(!check_rights(R_ADMIN))
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
return
var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA, ADMIN_PUNISHMENT_FIREBALL, ADMIN_PUNISHMENT_ROD, ADMIN_PUNISHMENT_SUPPLYPOD, ADMIN_PUNISHMENT_MAZING)