mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-17 10:03:50 +01:00
Updates some admin stuff (#15297)
* Fixes camera view * Unique CID tracking notes * Ban tracking * Note round IDs * Karma viewing * Minor tweak * Manual ban job bans * More tweaks * Farie tweaks * Connection result field * Orange watchlist names * Autopopulate tickbox
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
|
||||
if(!key || !address || !computer_id)
|
||||
log_adminwarn("Failed Login (invalid data): [key] [address]-[computer_id]")
|
||||
// The nested ternaries are needed here
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, (ckey(key) || ""), (address || ""), (computer_id || ""), CONNECTION_TYPE_DROPPED_INVALID)
|
||||
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, please try again. Error message: Your computer provided invalid or blank information to the server on connection (BYOND Username, IP, and Computer ID). Provided information for reference: Username: '[key]' IP: '[address]' Computer ID: '[computer_id]'. If you continue to get this error, please restart byond or contact byond support.")
|
||||
|
||||
if(type == "world")
|
||||
@@ -10,6 +12,7 @@
|
||||
|
||||
if(text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
|
||||
log_adminwarn("Failed Login (invalid cid): [key] [address]-[computer_id]")
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_INVALID)
|
||||
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.")
|
||||
|
||||
var/admin = 0
|
||||
@@ -28,6 +31,7 @@
|
||||
if(!GLOB.guests_allowed && IsGuestKey(key))
|
||||
log_adminwarn("Failed Login: [key] [computer_id] [address] - Guests not allowed")
|
||||
// message_admins("<span class='notice'>Failed Login: [key] - Guests not allowed</span>")
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_BANNED)
|
||||
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a BYOND account.")
|
||||
|
||||
//check if the IP address is a known proxy/vpn, and the user is not whitelisted
|
||||
@@ -36,6 +40,7 @@
|
||||
var/mistakemessage = ""
|
||||
if(config.banappeals)
|
||||
mistakemessage = "\nIf you have to use one, request whitelisting at: [config.banappeals]"
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_IPINTEL)
|
||||
return list("reason"="using proxy or vpn", "desc"="\nReason: Proxies/VPNs are not allowed here. [mistakemessage]")
|
||||
|
||||
|
||||
@@ -72,7 +77,7 @@
|
||||
sql_query_params["cid"] = computer_id
|
||||
|
||||
var/datum/db_query/query = SSdbcore.NewQuery({"
|
||||
SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM [format_table_name("ban")]
|
||||
SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype, ban_round_id FROM [format_table_name("ban")]
|
||||
WHERE (ckey=:ckeytext [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN'
|
||||
OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)"}, sql_query_params)
|
||||
|
||||
@@ -91,6 +96,7 @@
|
||||
var/duration = query.item[7]
|
||||
var/bantime = query.item[8]
|
||||
var/bantype = query.item[9]
|
||||
var/ban_round_id = query.item[10]
|
||||
if(bantype == "ADMIN_PERMABAN" || bantype == "ADMIN_TEMPBAN")
|
||||
//admin bans MUST match on ckey to prevent cid-spoofing attacks
|
||||
// as well as dynamic ip abuse
|
||||
@@ -114,11 +120,12 @@
|
||||
appealmessage = " You may appeal it at <a href='[config.banappeals]'>[config.banappeals]</a>."
|
||||
expires = " This ban does not expire automatically and must be appealed.[appealmessage]"
|
||||
|
||||
var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime].[expires]"
|
||||
var/desc = "\nReason: You, or another user of this computer or connection ([pckey]) is banned from playing here. The ban reason is:\n[reason]\nThis ban was applied by [ackey] on [bantime][ban_round_id ? " (Round [ban_round_id])" : ""].[expires]"
|
||||
|
||||
. = list("reason"="[bantype]", "desc"="[desc]")
|
||||
|
||||
log_adminwarn("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_BANNED)
|
||||
qdel(query)
|
||||
return .
|
||||
qdel(query)
|
||||
@@ -135,5 +142,5 @@
|
||||
return null
|
||||
else
|
||||
log_adminwarn("Failed Login: [key] [computer_id] [address] - Banned [.["message"]]")
|
||||
|
||||
INVOKE_ASYNC(GLOBAL_PROC, .proc/log_connection, ckey(key), address, computer_id, CONNECTION_TYPE_DROPPED_BANNED)
|
||||
return .
|
||||
|
||||
@@ -126,6 +126,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
|
||||
body += "<A href='?_src_=holder;jobban2=[M.UID()];dbbanaddckey=[M.ckey]'>Jobban</A> | "
|
||||
body += "<A href='?_src_=holder;appearanceban=[M.UID()];dbbanaddckey=[M.ckey]'>Appearance Ban</A> | "
|
||||
body += "<A href='?_src_=holder;shownoteckey=[M.ckey]'>Notes</A> | "
|
||||
body += "<A href='?_src_=holder;viewkarma=[M.ckey]'>View Karma</A> | "
|
||||
if(config.forum_playerinfo_url)
|
||||
body += "<A href='?_src_=holder;webtools=[M.ckey]'>WebInfo</A> | "
|
||||
if(M.client)
|
||||
|
||||
@@ -42,6 +42,19 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ##
|
||||
else
|
||||
return 0
|
||||
|
||||
/proc/jobban_isbanned_ckey(ckey, rank)
|
||||
if(!ckey || !rank)
|
||||
return null
|
||||
|
||||
if(config.guest_jobban && guest_jobbans(rank))
|
||||
if(IsGuestKey(ckey))
|
||||
return "Guest Job-ban"
|
||||
|
||||
if(GLOB.jobban_assoclist[ckey])
|
||||
return GLOB.jobban_assoclist[ckey][rank]
|
||||
|
||||
return null
|
||||
|
||||
/proc/jobban_loadbanfile()
|
||||
if(config.ban_legacy_system)
|
||||
var/savefile/S=new("data/job_full.ban")
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// This file houses all the code for cookie datum serialization and deserialization
|
||||
//
|
||||
// If you are going to modify ANYTHING in here, please test it THOROUGHLY
|
||||
// The serialization and deserialization here is so complicated that you WILL break something here
|
||||
// PLEASE test things properly if you modify this file. -aa07
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Everything in this file is intentionally NOT autodocumented. PLEASE keep it that way.
|
||||
// All these defines are integral to the workings and mesh together with the database.
|
||||
// DO NOT EDIT THESE UNDER ANY CIRCUMSTANCES EVER
|
||||
#define COOKIERECORD_FIRST_INFRACTION "First cookie match: "
|
||||
#define COOKIERECORD_LAST_INFRACTION "Last cookie match: "
|
||||
#define COOKIERECORD_TOTAL_INFRACTIONS "Total cookie matches: "
|
||||
#define COOKIERECORD_MATCHED_CKEYS "Matched ckeys: "
|
||||
#define COOKIERECORD_MATCHED_IPS "Matched IPs: "
|
||||
#define COOKIERECORD_MATCHED_CIDS "Matched CIDS: "
|
||||
#define COOKIERECORD_PSUEDO_CKEY "ALICE-COOKIE_RECORD"
|
||||
|
||||
/datum/cookie_record
|
||||
var/cookie_holder_ckey
|
||||
var/first_infraction_date
|
||||
var/last_infraction_date
|
||||
var/infraction_count
|
||||
var/list/matched_ckeys = list()
|
||||
var/list/matched_ips = list()
|
||||
var/list/matched_cids = list()
|
||||
|
||||
// Some of these params can be null, others CAN NOT
|
||||
/datum/cookie_record/New(holder_ckey, matched_ckey, matched_ip, matched_cid)
|
||||
// Right off the bat
|
||||
cookie_holder_ckey = holder_ckey
|
||||
|
||||
var/has_note = FALSE
|
||||
var/raw_text = ""
|
||||
// Now lets see if we have a note logging the infraction in the past
|
||||
var/datum/db_query/check_existing_note = SSdbcore.NewQuery("SELECT notetext FROM [format_table_name("notes")] WHERE ckey=:ckey AND adminckey=:ackey", list(
|
||||
"ckey" = cookie_holder_ckey,
|
||||
"ackey" = COOKIERECORD_PSUEDO_CKEY
|
||||
))
|
||||
if(!check_existing_note.warn_execute())
|
||||
qdel(check_existing_note)
|
||||
return
|
||||
if(check_existing_note.NextRow())
|
||||
has_note = TRUE
|
||||
raw_text = check_existing_note.item[1]
|
||||
qdel(check_existing_note)
|
||||
|
||||
if(has_note)
|
||||
deserialize_and_load(raw_text)
|
||||
infraction_count++
|
||||
else
|
||||
// Sane defaults
|
||||
first_infraction_date = SQLtime()
|
||||
infraction_count = 1
|
||||
|
||||
last_infraction_date = SQLtime()
|
||||
matched_ckeys |= matched_ckey
|
||||
matched_ips |= matched_ip
|
||||
matched_cids |= matched_cid
|
||||
|
||||
serialize_and_save(has_note)
|
||||
|
||||
/*
|
||||
Expected output below. These are parsed from raw_text by splitting by <br>
|
||||
[1] COOKIERECORD_FIRST_INFRACTION
|
||||
[2] COOKIERECORD_LAST_INFRACTION
|
||||
[3] COOKIERECORD_TOTAL_INFRACTIONS
|
||||
[4] COOKIERECORD_MATCHED_CKEYS
|
||||
[5] COOKIERECORD_MATCHED_IPS
|
||||
[6] COOKIERECORD_MATCHED_CIDS
|
||||
*/
|
||||
|
||||
/datum/cookie_record/proc/deserialize_and_load(raw_text)
|
||||
var/list/lines = splittext(raw_text, "<br>")
|
||||
// Text
|
||||
first_infraction_date = splittext(lines[1], COOKIERECORD_FIRST_INFRACTION)[2]
|
||||
last_infraction_date = splittext(lines[2], COOKIERECORD_LAST_INFRACTION)[2]
|
||||
// Number
|
||||
infraction_count = text2num(splittext(lines[3], COOKIERECORD_TOTAL_INFRACTIONS)[2]) // Make sure its a number
|
||||
// Lists
|
||||
matched_ckeys = splittext(splittext(lines[4], COOKIERECORD_MATCHED_CKEYS)[2], ",")
|
||||
matched_ips = splittext(splittext(lines[5], COOKIERECORD_MATCHED_IPS)[2], ",")
|
||||
matched_cids = splittext(splittext(lines[6], COOKIERECORD_MATCHED_CIDS)[2], ",")
|
||||
|
||||
/datum/cookie_record/proc/serialize_and_save(has_note)
|
||||
var/serialized_text
|
||||
var/list/serialized_list = list()
|
||||
serialized_list.len = 6 // Make it 6 off the bat
|
||||
|
||||
serialized_list[1] = "[COOKIERECORD_FIRST_INFRACTION][first_infraction_date]"
|
||||
serialized_list[2] = "[COOKIERECORD_LAST_INFRACTION][last_infraction_date]"
|
||||
serialized_list[3] = "[COOKIERECORD_TOTAL_INFRACTIONS][infraction_count]"
|
||||
serialized_list[4] = "[COOKIERECORD_MATCHED_CKEYS][matched_ckeys.Join(",")]"
|
||||
serialized_list[5] = "[COOKIERECORD_MATCHED_IPS][matched_ips.Join(",")]"
|
||||
serialized_list[6] = "[COOKIERECORD_MATCHED_CIDS][matched_cids.Join(",")]"
|
||||
|
||||
serialized_text = serialized_list.Join("<br>")
|
||||
|
||||
if(has_note) // They have a note. Update.
|
||||
var/datum/db_query/update_existing_note = SSdbcore.NewQuery("UPDATE [format_table_name("notes")] SET notetext=:nt, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list(
|
||||
"nt" = serialized_text,
|
||||
"rid" = GLOB.round_id,
|
||||
"ckey" = cookie_holder_ckey,
|
||||
"ackey" = COOKIERECORD_PSUEDO_CKEY
|
||||
))
|
||||
if(!update_existing_note.warn_execute())
|
||||
qdel(update_existing_note)
|
||||
return
|
||||
qdel(update_existing_note)
|
||||
else // They dont have a note. Insert.
|
||||
add_note(cookie_holder_ckey, serialized_text, adminckey = COOKIERECORD_PSUEDO_CKEY, logged = FALSE, checkrights = FALSE, automated = TRUE)
|
||||
@@ -146,8 +146,8 @@
|
||||
qdel(adm_query)
|
||||
|
||||
var/datum/db_query/query_insert = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`)
|
||||
VALUES (null, Now(), :serverip, :bantype_str, :reason, :job, :duration, :rounds, Now() + INTERVAL :duration MINUTE, :ckey, :computerid, :ip, :a_ckey, :a_computerid, :a_ip, :who, :adminwho, '', null, null, null, null, null)
|
||||
INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`,`ban_round_id`,`unbanned_round_id`)
|
||||
VALUES (null, Now(), :serverip, :bantype_str, :reason, :job, :duration, :rounds, Now() + INTERVAL :duration MINUTE, :ckey, :computerid, :ip, :a_ckey, :a_computerid, :a_ip, :who, :adminwho, '', null, null, null, null, null, :roundid, null)
|
||||
"}, list(
|
||||
// Get ready for parameters
|
||||
"serverip" = serverip,
|
||||
@@ -163,7 +163,8 @@
|
||||
"a_computerid" = a_computerid,
|
||||
"a_ip" = a_ip,
|
||||
"who" = who,
|
||||
"adminwho" = adminwho
|
||||
"adminwho" = adminwho,
|
||||
"roundid" = GLOB.round_id
|
||||
))
|
||||
if(!query_insert.warn_execute())
|
||||
qdel(query_insert)
|
||||
@@ -399,10 +400,11 @@
|
||||
var/unban_computerid = src.owner:computer_id
|
||||
var/unban_ip = src.owner:address
|
||||
|
||||
var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey=:unban_ckey, unbanned_computerid=:unban_computerid, unbanned_ip=:unban_ip WHERE id=:id", list(
|
||||
var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey=:unban_ckey, unbanned_computerid=:unban_computerid, unbanned_ip=:unban_ip, unbanned_round_id=:roundid WHERE id=:id", list(
|
||||
"unban_ckey" = unban_ckey,
|
||||
"unban_computerid" = unban_computerid,
|
||||
"unban_ip" = unban_ip,
|
||||
"roundid" = GLOB.round_id,
|
||||
"id" = id
|
||||
))
|
||||
if(!query_update.warn_execute())
|
||||
@@ -477,6 +479,7 @@
|
||||
output += "<option value='[j]'>[j]</option>"
|
||||
output += "</select></td></tr></table>"
|
||||
output += "<b>Reason:<br></b><textarea name='dbbanreason' cols='50'></textarea><br>"
|
||||
output += "<input type='checkbox' value='1' name='autopopulate' checked='1'> Auto populate CID & IP for online players<br>"
|
||||
output += "<input type='submit' value='Add ban'>"
|
||||
output += "</form>"
|
||||
|
||||
@@ -582,7 +585,7 @@
|
||||
|
||||
|
||||
var/datum/db_query/select_query = SSdbcore.NewQuery({"
|
||||
SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid
|
||||
SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid, ban_round_id, unbanned_round_id
|
||||
FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100"}, sql_params)
|
||||
|
||||
if(!select_query.warn_execute())
|
||||
@@ -605,6 +608,8 @@
|
||||
var/edits = select_query.item[13]
|
||||
var/ip = select_query.item[14]
|
||||
var/cid = select_query.item[15]
|
||||
var/ban_round_id = select_query.item[16]
|
||||
var/unban_round_id = select_query.item[17]
|
||||
|
||||
var/lcolor = blcolor
|
||||
var/dcolor = bdcolor
|
||||
@@ -632,7 +637,7 @@
|
||||
output += "<tr bgcolor='[dcolor]'>"
|
||||
output += "<td align='center'>[typedesc]</td>"
|
||||
output += "<td align='center'><b>[ckey]</b></td>"
|
||||
output += "<td align='center'>[bantime]</td>"
|
||||
output += "<td align='center'>[bantime][ban_round_id ? " (Round [ban_round_id])" : ""]</td>"
|
||||
output += "<td align='center'><b>[ackey]</b></td>"
|
||||
output += "<td align='center'>[(unbanned) ? "" : "<b><a href=\"byond://?src=[UID()];dbbanedit=unban;dbbanid=[banid]\">Unban</a></b>"]</td>"
|
||||
output += "</tr>"
|
||||
@@ -652,7 +657,7 @@
|
||||
output += "</tr>"
|
||||
if(unbanned)
|
||||
output += "<tr bgcolor='[dcolor]'>"
|
||||
output += "<td align='center' colspan='5' bgcolor=''><b>UNBANNED by admin [unbanckey] on [unbantime]</b></td>"
|
||||
output += "<td align='center' colspan='5' bgcolor=''><b>UNBANNED by admin [unbanckey] on [unbantime][unban_round_id ? " (Round [unban_round_id])" : ""]</b></td>"
|
||||
output += "</tr>"
|
||||
output += "<tr>"
|
||||
output += "<td colspan='5' bgcolor='white'> </td>"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Do not attemtp to remove the blank string from the server arg. It will break DB saving.
|
||||
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server = "", checkrights = 1)
|
||||
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server = "", checkrights = 1, show_after = TRUE, automated = FALSE)
|
||||
if(checkrights && !check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
if(!SSdbcore.IsConnected())
|
||||
@@ -57,15 +57,20 @@
|
||||
if(config && config.server_name)
|
||||
server = config.server_name
|
||||
|
||||
// Force cast this to 1/0 incase someone tries to feed bad data
|
||||
automated = !!automated
|
||||
|
||||
var/datum/db_query/query_noteadd = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime)
|
||||
VALUES (:targetckey, NOW(), :notetext, :adminkey, :server, :crewnum)
|
||||
INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime, round_id, automated)
|
||||
VALUES (:targetckey, NOW(), :notetext, :adminkey, :server, :crewnum, :roundid, :automated)
|
||||
"}, list(
|
||||
"targetckey" = target_ckey,
|
||||
"notetext" = notetext,
|
||||
"adminkey" = adminckey,
|
||||
"server" = server,
|
||||
"crewnum" = crew_number
|
||||
"crewnum" = crew_number,
|
||||
"roundid" = GLOB.round_id,
|
||||
"automated" = automated
|
||||
))
|
||||
if(!query_noteadd.warn_execute())
|
||||
qdel(query_noteadd)
|
||||
@@ -74,7 +79,8 @@
|
||||
if(logged)
|
||||
log_admin("[usr ? key_name(usr) : adminckey] has added a note to [target_ckey]: [notetext]")
|
||||
message_admins("[usr ? key_name_admin(usr) : adminckey] has added a note to [target_ckey]:<br>[notetext]")
|
||||
show_note(target_ckey)
|
||||
if(show_after)
|
||||
show_note(target_ckey)
|
||||
|
||||
/proc/remove_note(note_id)
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
@@ -124,7 +130,7 @@
|
||||
return
|
||||
note_id = text2num(note_id)
|
||||
var/target_ckey
|
||||
var/datum/db_query/query_find_note_edit = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id=:note_id", list(
|
||||
var/datum/db_query/query_find_note_edit = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey, automated FROM [format_table_name("notes")] WHERE id=:note_id", list(
|
||||
"note_id" = note_id
|
||||
))
|
||||
if(!query_find_note_edit.warn_execute())
|
||||
@@ -134,6 +140,10 @@
|
||||
target_ckey = query_find_note_edit.item[1]
|
||||
var/old_note = query_find_note_edit.item[2]
|
||||
var/adminckey = query_find_note_edit.item[3]
|
||||
var/automated = query_find_note_edit.item[4]
|
||||
if(automated)
|
||||
to_chat(usr, "<span class='notice'>That note is generated automatically. You can't edit it.</span>")
|
||||
return
|
||||
var/new_note = input("Input new note", "New Note", "[old_note]") as message|null
|
||||
if(!new_note)
|
||||
return
|
||||
@@ -171,7 +181,7 @@
|
||||
if(target_ckey)
|
||||
var/target_sql_ckey = ckey(target_ckey)
|
||||
var/datum/db_query/query_get_notes = SSdbcore.NewQuery({"
|
||||
SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime
|
||||
SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime, round_id, automated
|
||||
FROM [format_table_name("notes")] WHERE ckey=:targetkey ORDER BY timestamp"}, list(
|
||||
"targetkey" = target_sql_ckey
|
||||
))
|
||||
@@ -190,14 +200,16 @@
|
||||
var/last_editor = query_get_notes.item[5]
|
||||
var/server = query_get_notes.item[6]
|
||||
var/mins = text2num(query_get_notes.item[7])
|
||||
output += "<b>[timestamp] | [server] | [adminckey]"
|
||||
var/round_id = text2num(query_get_notes.item[8])
|
||||
var/automated = text2num(query_get_notes.item[9]) // 0/1 bool stored in table
|
||||
output += "<b>[timestamp][round_id ? " (Round [round_id])" : ""] | [server] | [adminckey]"
|
||||
if(mins)
|
||||
var/playstring = get_exp_format(mins)
|
||||
output += " | [playstring] as Crew"
|
||||
output += "</b>"
|
||||
|
||||
if(!linkless)
|
||||
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
|
||||
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> [automated ? "\[Automated Note\]" : "<a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"]"
|
||||
if(last_editor)
|
||||
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;noteedits=[id]'>(Click here to see edit log)</a></font>"
|
||||
output += "<br>[notetext]<hr style='background:#000000; border:0; height:1px'>"
|
||||
|
||||
+127
-6
@@ -108,6 +108,10 @@
|
||||
var/banjob = href_list["dbbanaddjob"]
|
||||
var/banreason = href_list["dbbanreason"]
|
||||
|
||||
var/job_ban = FALSE
|
||||
var/multi_job = FALSE
|
||||
var/list/jobs_to_ban = list()
|
||||
|
||||
banckey = ckey(banckey)
|
||||
|
||||
switch(bantype)
|
||||
@@ -127,10 +131,12 @@
|
||||
to_chat(usr, "<span class='warning'>Not enough parameters (Requires ckey, reason and job)</span>")
|
||||
return
|
||||
banduration = null
|
||||
job_ban = TRUE
|
||||
if(BANTYPE_JOB_TEMP)
|
||||
if(!banckey || !banreason || !banjob || !banduration)
|
||||
to_chat(usr, "<span class='warning'>Not enough parameters (Requires ckey, reason and job)</span>")
|
||||
return
|
||||
job_ban = TRUE
|
||||
if(BANTYPE_APPEARANCE)
|
||||
if(!banckey || !banreason)
|
||||
to_chat(usr, "<span class='warning'>Not enough parameters (Requires ckey and reason)</span>")
|
||||
@@ -151,11 +157,11 @@
|
||||
|
||||
var/mob/playermob
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.ckey == banckey)
|
||||
playermob = M
|
||||
break
|
||||
|
||||
if("autopopulate" in href_list)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.ckey == banckey)
|
||||
playermob = M
|
||||
break
|
||||
|
||||
banreason = "(MANUAL BAN) "+banreason
|
||||
|
||||
@@ -167,7 +173,68 @@
|
||||
else
|
||||
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom IP and computer id fields replaced with the IP and computer id from the located mob")
|
||||
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
|
||||
if(job_ban)
|
||||
if(banjob in list("commanddept","securitydept","engineeringdept","medicaldept","sciencedept","supportdept","nonhumandept"))
|
||||
multi_job = TRUE
|
||||
switch(banjob)
|
||||
if("commanddept")
|
||||
for(var/jobPos in GLOB.command_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
if("securitydept")
|
||||
for(var/jobPos in GLOB.security_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
if("engineeringdept")
|
||||
for(var/jobPos in GLOB.engineering_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
if("medicaldept")
|
||||
for(var/jobPos in GLOB.medical_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
if("sciencedept")
|
||||
for(var/jobPos in GLOB.science_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
if("supportdept")
|
||||
for(var/jobPos in GLOB.support_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
if("nonhumandept")
|
||||
jobs_to_ban += "pAI"
|
||||
for(var/jobPos in GLOB.nonhuman_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = SSjobs.GetJob(jobPos)
|
||||
if(!temp) continue
|
||||
jobs_to_ban += temp.title
|
||||
|
||||
// If the job ban is for multiple jobs in one group (IE: Command), iterate through jobs and ban each individually
|
||||
if(multi_job)
|
||||
//Create a list of unbanned jobs within joblist
|
||||
var/list/notbannedlist = list()
|
||||
for(var/job in jobs_to_ban)
|
||||
if(!jobban_isbanned_ckey(banckey, job))
|
||||
notbannedlist += job
|
||||
|
||||
for(var/job in notbannedlist)
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, job, null, banckey, banip, bancid)
|
||||
|
||||
// Otherwise, do it normally
|
||||
else
|
||||
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid)
|
||||
|
||||
|
||||
else if(href_list["editrights"])
|
||||
@@ -3423,7 +3490,61 @@
|
||||
log_sql("[usr.key] | [response]")
|
||||
else if(answer == "no")
|
||||
log_sql("[usr.key] | Reported no server hang. Please investigate")
|
||||
else if(href_list["suppresscidwarning"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
add_note(href_list["suppresscidwarning"], CIDWARNING_SUPPRESSED_NOTETEXT, show_after = FALSE)
|
||||
else if(href_list["viewkarma"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/target_ckey = href_list["viewkarma"]
|
||||
|
||||
var/total_karma = 0
|
||||
var/spent_karma = 0
|
||||
var/unlocked_jobs = ""
|
||||
var/unlocked_species = ""
|
||||
// Get their totals
|
||||
var/datum/db_query/query_get_totals = SSdbcore.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey=:ckey", list(
|
||||
"ckey" = target_ckey
|
||||
))
|
||||
if(!query_get_totals.warn_execute())
|
||||
qdel(query_get_totals)
|
||||
return
|
||||
// Even if there aint a row, we can still assume the defaults of 0 above
|
||||
if(query_get_totals.NextRow())
|
||||
total_karma = query_get_totals.item[1]
|
||||
spent_karma = query_get_totals.item[2]
|
||||
|
||||
qdel(query_get_totals)
|
||||
|
||||
// Now get their unlocks
|
||||
var/datum/db_query/query_get_unlocks = SSdbcore.NewQuery("SELECT job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list(
|
||||
"ckey" = target_ckey
|
||||
))
|
||||
if(!query_get_unlocks.warn_execute())
|
||||
qdel(query_get_unlocks)
|
||||
return
|
||||
if(query_get_unlocks.NextRow())
|
||||
unlocked_jobs = query_get_unlocks.item[1]
|
||||
unlocked_species = query_get_unlocks.item[2]
|
||||
|
||||
qdel(query_get_unlocks)
|
||||
|
||||
// Pack it into a dat
|
||||
var/dat = {"
|
||||
<ul>
|
||||
<li>Total Karma: [total_karma]</li>
|
||||
<li>Spent Karma: [spent_karma]</li>
|
||||
<li>Available Karma: [total_karma - spent_karma]</li>
|
||||
<li>Unlocked Jobs: [unlocked_jobs]</li>
|
||||
<li>Unlocked Species: [unlocked_species]</li>
|
||||
</ul>
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(usr, "view_karma", "Karma stats for [target_ckey]", 600, 300)
|
||||
popup.set_content(dat)
|
||||
popup.open(FALSE)
|
||||
|
||||
/client/proc/create_eventmob_for(var/mob/living/carbon/human/H, var/killthem = 0)
|
||||
if(!check_rights(R_EVENT))
|
||||
|
||||
@@ -22,15 +22,6 @@
|
||||
GLOBAL_VAR_INIT(camera_range_display_status, 0)
|
||||
GLOBAL_VAR_INIT(intercom_range_display_status, 0)
|
||||
|
||||
/obj/effect/debugging/camera_range
|
||||
icon = 'icons/480x480.dmi'
|
||||
icon_state = "25percent"
|
||||
|
||||
/obj/effect/debugging/camera_range/New()
|
||||
. = ..()
|
||||
src.pixel_x = -224
|
||||
src.pixel_y = -224
|
||||
|
||||
/obj/effect/debugging/mapfix_marker
|
||||
name = "map fix marker"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
@@ -56,12 +47,16 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0)
|
||||
else
|
||||
GLOB.camera_range_display_status = 1
|
||||
|
||||
for(var/obj/effect/debugging/camera_range/C in world)
|
||||
qdel(C)
|
||||
for(var/obj/effect/debugging/marker/M in world)
|
||||
qdel(M)
|
||||
|
||||
if(GLOB.camera_range_display_status)
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
new/obj/effect/debugging/camera_range(C.loc)
|
||||
for(var/turf/T in orange(7, C))
|
||||
var/obj/effect/debugging/marker/F = new/obj/effect/debugging/marker(T)
|
||||
if(!(F in view(7, C.loc)))
|
||||
qdel(F)
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Camera Range Display") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/sec_camera_report()
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
return
|
||||
log_admin("[key_name(usr)] has added [target_ckey] to the watchlist - Reason: [reason]")
|
||||
message_admins("[key_name_admin(usr)] has added [target_ckey] to the watchlist - Reason: [reason]", 1)
|
||||
if(GLOB.directory[target_ckey])
|
||||
var/client/C = GLOB.directory[target_ckey]
|
||||
C.watchlisted = TRUE // Mark them ingame now
|
||||
if(browse)
|
||||
watchlist_show(target_ckey)
|
||||
|
||||
@@ -56,6 +59,9 @@
|
||||
qdel(query_watchdel)
|
||||
log_admin("[key_name(usr)] has removed [target_ckey] from the watchlist")
|
||||
message_admins("[key_name_admin(usr)] has removed [target_ckey] from the watchlist", 1)
|
||||
if(GLOB.directory[target_ckey])
|
||||
var/client/C = GLOB.directory[target_ckey]
|
||||
C.watchlisted = FALSE // Mark them ingame now
|
||||
if(browse)
|
||||
watchlist_show()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user