/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_danger("Failed to establish database connection."), confidential = TRUE) return if(!type) return 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) return var/new_ckey = ckey(new_key) var/datum/db_query/query_find_ckey = SSdbcore.NewQuery( "SELECT ckey FROM [format_table_name("player")] WHERE ckey = :ckey", list("ckey" = new_ckey) ) if(!query_find_ckey.warn_execute()) qdel(query_find_ckey) return if(!query_find_ckey.NextRow()) if(tgui_alert(usr, "[new_key]/([new_ckey]) has not been seen before, are you sure you want to create a [type] for them?", "Unknown ckey", list("Yes", "No", "Cancel")) != "Yes") qdel(query_find_ckey) return qdel(query_find_ckey) target_ckey = new_ckey target_key = new_key if(QDELETED(usr)) return if(!target_key) target_key = target_ckey if(!admin_ckey) admin_ckey = usr.ckey if(!admin_ckey) return if(!target_ckey) target_ckey = admin_ckey if(!text) text = input(usr,"Write your [type]","Create [type]") as null|message if(!text) return if(!server) var/ssqlname = CONFIG_GET(string/serversqlname) if (ssqlname) server = ssqlname if(isnull(secret)) switch(tgui_alert(usr,"Hide note from being viewed by players?", "Secret note?",list("Yes","No","Cancel"))) if("Yes") secret = 1 if("No") secret = 0 else return if(isnull(expiry)) if(tgui_alert(usr, "Set an expiry time? Expired messages are hidden like deleted ones.", "Expiry time?", list("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", ISOtime()) as null|text if(!expire_time) return var/datum/db_query/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)", list("expire_time" = expire_time) ) 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.", confidential = TRUE) 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 var/list/parameters = list( "type" = type, "target_ckey" = target_ckey, "admin_ckey" = admin_ckey, "text" = text, "server" = server, "internet_address" = world.internet_address || "0", "port" = "[world.port]", "round_id" = GLOB.round_id, "secret" = secret, "expiry" = expiry || null, "note_severity" = note_severity, ) if(timestamp) parameters["timestamp"] = timestamp var/datum/db_query/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, playtime) VALUES (:type, :target_ckey, :admin_ckey, :text, [timestamp? ":timestamp" : "Now()"], :server, INET_ATON(:internet_address), :port, :round_id, :secret, :expiry, :note_severity, (SELECT `minutes` FROM [format_table_name("role_time")] WHERE `ckey` = :target_ckey AND `job` = 'Living')) "}, parameters) var/pm = "[key_name(usr)] has created a [secret ? "secret " : ""][type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""]: [text]" var/header = "[key_name_admin(usr)] has created a [secret ? "secret " : ""][type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""]" if(!query_create_message.warn_execute()) qdel(query_create_message) return qdel(query_create_message) if(logged) log_admin_private(pm) message_admins("[header]:
[text]") admin_ticket_log(target_ckey, "[header]
[text]") if(browse) browse_messages("[type]") else browse_messages(target_ckey = target_ckey, agegate = TRUE) /proc/delete_message(message_id, logged = 1, browse) if(!SSdbcore.Connect()) to_chat(usr, span_danger("Failed to establish database connection."), confidential = TRUE) return message_id = text2num(message_id) if(!message_id) return var/type var/target_key var/text var/user_key_name = key_name(usr) var/user_name_admin = key_name_admin(usr) var/deleted_by_ckey = usr.ckey var/datum/db_query/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 = :id AND deleted = 0", list("id" = message_id) ) if(!query_find_del_message.warn_execute()) qdel(query_find_del_message) return if(query_find_del_message.NextRow()) type = query_find_del_message.item[1] target_key = query_find_del_message.item[2] text = query_find_del_message.item[3] qdel(query_find_del_message) var/datum/db_query/query_del_message = SSdbcore.NewQuery( "UPDATE [format_table_name("messages")] SET deleted = 1, deleted_ckey = :deleted_ckey WHERE id = :id", list("deleted_ckey" = deleted_by_ckey, "id" = message_id) ) if(!query_del_message.warn_execute()) qdel(query_del_message) return qdel(query_del_message) if(logged) var/m1 = "[user_key_name] has deleted a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for" : " made by"] [target_key]: [text]" var/m2 = "[user_name_admin] has deleted a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for" : " made by"] [target_key]:
[text]" log_admin_private(m1) message_admins(m2) if(browse) browse_messages("[type]") else browse_messages(target_ckey = ckey(target_key), agegate = TRUE) /proc/edit_message(message_id, browse) if(!SSdbcore.Connect()) to_chat(usr, span_danger("Failed to establish database connection."), confidential = TRUE) return message_id = text2num(message_id) if(!message_id) return var/editor_ckey = usr.ckey var/editor_key = usr.key var/kn = key_name(usr) var/kna = key_name_admin(usr) var/datum/db_query/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 = :id AND deleted = 0 "}, list("id" = message_id)) if(!query_find_edit_message.warn_execute()) qdel(query_find_edit_message) return if(query_find_edit_message.NextRow()) var/type = query_find_edit_message.item[1] var/target_key = query_find_edit_message.item[2] var/admin_key = query_find_edit_message.item[3] var/old_text = query_find_edit_message.item[4] var/new_text = input("Input new [type]", "New [type]", "[old_text]") as null|message if(!new_text) qdel(query_find_edit_message) return var/edit_text = "Edited by [editor_key] on [ISOtime()] from
[old_text]
to
[new_text]
" var/datum/db_query/query_edit_message = SSdbcore.NewQuery({" UPDATE [format_table_name("messages")] SET text = :text, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id = :id AND deleted = 0 "}, list("text" = new_text, "lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id)) if(!query_edit_message.warn_execute()) qdel(query_edit_message) return qdel(query_edit_message) log_admin_private("[kn] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [old_text] to [new_text]") message_admins("[kna] has edited a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from
[old_text]
to
[new_text]") if(browse) browse_messages("[type]") else 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_danger("Failed to establish database connection."), confidential = TRUE) return message_id = text2num(message_id) if(!message_id) return var/editor_ckey = usr.ckey var/editor_key = usr.key var/kn = key_name(usr) var/kna = key_name_admin(usr) var/datum/db_query/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 = :id AND deleted = 0 "}, list("id" = message_id)) 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 var/datum/db_query/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) "}, list("expire_time" = expire_time)) 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.", confidential = TRUE) 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 = "Expiration time edited by [editor_key] on [ISOtime()] from [(old_expiry ? old_expiry : "no expiration date")] to [new_expiry]
" var/datum/db_query/query_edit_message_expiry = SSdbcore.NewQuery({" UPDATE [format_table_name("messages")] SET expire_timestamp = :expire_time, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id = :id AND deleted = 0 "}, list("expire_time" = (expire_time == "-1" ? null : new_expiry), "lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id)) 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 ? old_expiry : "no expiration date")] 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 ? old_expiry : "no expiration date")] 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_danger("Failed to establish database connection."), confidential = TRUE) return message_id = text2num(message_id) if(!message_id) return var/kn = key_name(usr) var/kna = key_name_admin(usr) var/datum/db_query/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 = :id AND deleted = 0 "}, list("id" = message_id)) 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 = usr.key var/editor_ckey = 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 = new_severity var/edit_text = "Note severity edited by [editor_key] on [ISOtime()] from [old_severity] to [new_severity]
" var/datum/db_query/query_edit_note_severity = SSdbcore.NewQuery({" UPDATE [format_table_name("messages")] SET severity = :severity, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id = :id AND deleted = 0 "}, list("severity" = new_severity, "lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id)) 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_danger("Failed to establish database connection."), confidential = TRUE) return message_id = text2num(message_id) if(!message_id) return var/editor_ckey = usr.ckey var/editor_key = usr.key var/kn = key_name(usr) var/kna = key_name_admin(usr) var/datum/db_query/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 = :id AND deleted = 0 "}, list("id" = message_id)) if(!query_find_message_secret.warn_execute()) qdel(query_find_message_secret) return if(query_find_message_secret.NextRow()) var/type = query_find_message_secret.item[1] var/target_key = query_find_message_secret.item[2] var/admin_key = query_find_message_secret.item[3] var/secret = text2num(query_find_message_secret.item[4]) var/edit_text = "Made [secret ? "not secret" : "secret"] by [editor_key] on [ISOtime()]
" var/datum/db_query/query_message_secret = SSdbcore.NewQuery({" UPDATE [format_table_name("messages")] SET secret = NOT secret, lasteditor = :lasteditor, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id = :id "}, list("lasteditor" = editor_ckey, "edit_text" = edit_text, "id" = message_id)) if(!query_message_secret.warn_execute()) qdel(query_find_message_secret) qdel(query_message_secret) return qdel(query_message_secret) log_admin_private("[kn] has toggled [target_key]'s [type] made by [admin_key] to [secret ? "not secret" : "secret"]") message_admins("[kna] has toggled [target_key]'s [type] made by [admin_key] to [secret ? "not secret" : "secret"]") browse_messages(target_ckey = ckey(target_key), agegate = TRUE) qdel(query_find_message_secret) /proc/browse_messages(type, target_ckey, index, linkless = FALSE, filter, agegate = FALSE) if(!SSdbcore.Connect()) to_chat(usr, span_danger("Failed to establish database connection."), confidential = TRUE) return //Needs to be requested before url retrieval since you can view your notes before SSassets finishes initialization var/datum/asset/notes_assets = get_asset_datum(/datum/asset/simple/notes) var/list/output = list() var/ruler = "
" var/list/navbar = list("All#") for(var/letter in GLOB.alphabet) navbar += "[letter]" navbar += "MemosWatchlist" navbar += "
\ \ [HrefTokenFormField()]\ \
" if(!linkless) output = navbar if(type == "memo" || type == "watchlist entry") if(type == "memo") output += "

Admin memos

" output += "Add memo" else if(type == "watchlist entry") output += "

Watchlist entries

" output += "Add watchlist entry" if(filter) output += "Unfilter clients" else output += "Filter offline clients" output += ruler var/datum/db_query/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, playtime, round_id FROM [format_table_name("messages")] WHERE type = :type AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) "}, list("type" = type)) if(!query_get_type_messages.warn_execute()) qdel(query_get_type_messages) return while(query_get_type_messages.NextRow()) if(QDELETED(usr)) return var/id = query_get_type_messages.item[1] var/t_key = query_get_type_messages.item[2] var/t_ckey = query_get_type_messages.item[3] if(type == "watchlist entry" && filter && !(t_ckey in GLOB.directory)) continue var/admin_key = query_get_type_messages.item[4] var/text = query_get_type_messages.item[5] 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] var/playtime = query_get_type_messages.item[10] var/round_id = query_get_type_messages.item[11] output += "" if(type == "watchlist entry") output += "[t_key] | " output += "[timestamp] | [server] | Round [round_id] | [admin_key]" if(type == "watchlist entry") output += " | [get_exp_format(text2num(playtime))] Living Playtime" if(expire_timestamp) output += " | Expires [expire_timestamp]" output += "" output += " Change Expiry Time" output += " Delete" output += " Edit" if(editor_key) output += " Last edit by [editor_key] (Click here to see edit log)" output += "
[text]
" qdel(query_get_type_messages) if(target_ckey) var/target_key var/datum/db_query/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, playtime, round_id FROM [format_table_name("messages")] WHERE type <> 'memo' AND targetckey = :targetckey AND deleted = 0 AND (expire_timestamp > NOW() OR expire_timestamp IS NULL) ORDER BY timestamp DESC "}, list("targetckey" = target_ckey)) if(!query_get_messages.warn_execute()) qdel(query_get_messages) return var/list/messagedata = list() var/list/watchdata = list() var/list/notedata = list() var/skipped = 0 while(query_get_messages.NextRow()) if(QDELETED(usr)) return type = query_get_messages.item[1] if(type == "memo") continue var/secret = text2num(query_get_messages.item[2]) if(linkless && secret) continue var/id = query_get_messages.item[3] var/admin_key = query_get_messages.item[4] var/text = query_get_messages.item[5] var/timestamp = query_get_messages.item[6] var/server = query_get_messages.item[7] 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/playtime = query_get_messages.item[13] var/round_id = query_get_messages.item[14] var/alphatext = "" var/nsd = CONFIG_GET(number/note_stale_days) var/nfd = CONFIG_GET(number/note_fresh_days) if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd) var/alpha = clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) if (alpha < 100) if (alpha <= 15) if (skipped) skipped++ continue alpha = 10 skipped = TRUE alphatext = "filter: alpha(opacity=[alpha]); opacity: [alpha/100];" var/list/data = list("

") if(severity) data += " " data += "[timestamp] | [server] | Round [round_id] | [admin_key][secret ? " | - Secret" : ""] | [get_exp_format(text2num(playtime))] Living Playtime" if(expire_timestamp) data += " | Expires [expire_timestamp]" data += "

" if(!linkless) if(type == "note") if(severity) data += "[severity == "none" ? "No" : "[capitalize(severity)]"] Severity" else data += "N/A Severity" data += " Change Expiry Time" data += " Delete" if(type == "note") data += " [secret ? "Secret" : "Not secret"]" if(type == "message sent") data += " Message has been sent" if(editor_key) data += "|" else data += " Edit" if(editor_key) data += " Last edit by [editor_key] (Click here to see edit log)" data += "
" data += "

[text]


" switch(type) if("message") messagedata += data if("message sent") messagedata += data if("watchlist entry") watchdata += data if("note") notedata += data qdel(query_get_messages) if(!target_key) var/datum/db_query/query_get_message_key = SSdbcore.NewQuery({" SELECT byond_key FROM [format_table_name("player")] WHERE ckey = :ckey "}, list("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 += "

[target_key]

" if(!linkless) output += "Add note" output += " Add message" output += " Add to watchlist" output += " Refresh page
" else output += " Refresh page" output += ruler if(messagedata) output += "

Messages

" output += messagedata if(watchdata) output += "

Watchlist

" output += watchdata if(notedata) output += "

Notes

" 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 += "
Show [skipped] hidden messages
" else output += "
Show All
" else output += "
Hide Old
" if(index) var/search output += "
Add messageAdd watchlist entryAdd note
" output += ruler switch(index) if(1) search = "^." if(2) search = "^\[^\[:alpha:\]\]" else search = "^[index]" var/datum/db_query/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 "}, list("search" = search)) if(!query_list_messages.warn_execute()) qdel(query_list_messages) return while(query_list_messages.NextRow()) if(QDELETED(usr)) 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 += "[index_key]
" qdel(query_list_messages) else if(!type && !target_ckey && !index) output += "
Add messageAdd watchlist entryAdd note
" output += ruler var/datum/browser/browser = new(usr, "Note panel", "Manage player notes", 1000, 500) notes_assets.send(usr.client) browser.set_content(jointext(output, "")) browser.open() /// Represents a message stored in the db /datum/admin_message /// The uid of this message var/id /// The admin who left this message var/admin_key /// The text of this message var/text /// The time this message was first created var/timestamp /// The admin who last edited this message var/editor_key /proc/get_message_output(type, target_ckey, show_secret = TRUE, after_timestamp) if(!SSdbcore.Connect()) to_chat(usr, span_danger("Failed to establish database connection."), confidential = TRUE) return if(!type) return var/list/parameters = list( "targetckey" = target_ckey, "type" = type, ) if(after_timestamp) parameters["after_timestamp"] = after_timestamp var/datum/db_query/query_get_message_output = SSdbcore.NewQuery({" 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) AND (type = 'memo' OR targetckey = :targetckey) [after_timestamp? "AND timestamp > :after_timestamp": ""] [!show_secret? "AND secret = 0": ""] "}, parameters) if(!query_get_message_output.warn_execute()) qdel(query_get_message_output) return var/list/datum/admin_message/messages = list() while(query_get_message_output.NextRow()) var/datum/admin_message/message = new() message.id = query_get_message_output.item[1] message.admin_key = query_get_message_output.item[2] message.text = query_get_message_output.item[3] message.timestamp = query_get_message_output.item[4] message.editor_key = query_get_message_output.item[5] messages += message qdel(query_get_message_output) if(!length(messages)) return return messages /proc/display_admin_messages(client/display_to) var/list/text = list() for(var/datum/admin_message/message in get_message_output("message", display_to.ckey)) text += "Admin message left by [span_prefix("[message.admin_key]")] on [message.timestamp]" text += "
[message.text] (Click here to verify you have read this message)
" if(length(text)) to_chat(display_to, text.Join()) /proc/display_unread_notes(client/display_to, show_after) var/list/text = list() for(var/datum/admin_message/message in get_message_output("note", display_to.ckey, FALSE, show_after)) text += "Note left by [span_prefix("[message.admin_key]")] on [message.timestamp]" text += "
[message.text]
" if(length(text)) to_chat(display_to, text.Join()) /proc/display_admin_memos(client/display_to) var/list/text = list() for(var/datum/admin_message/message in get_message_output("memo", display_to.ckey)) text += "[span_memo("Memo by [message.admin_key]")] on [message.timestamp]" if(message.editor_key) text += "
[span_memoedit("Last edit by [message.editor_key] (Click here to see edit log)")]" text += "
[message.text]

" if(length(text)) to_chat(display_to, text.Join()) /proc/scream_about_watchlists(client/read_from) for(var/datum/admin_message/message in get_message_output("watchlist entry", read_from.ckey)) message_admins("Notice: [key_name_admin(read_from.ckey)] has been on the watchlist since [message.timestamp] and has just connected - Reason: [message.text]") send2tgs_adminless_only("Watchlist", "[key_name(read_from.ckey)] is on the watchlist and has just connected - Reason: [message.text]") #define NOTESFILE "data/player_notes.sav" //if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas /proc/convert_notes_sql(ckey) if(!fexists(NOTESFILE)) return var/savefile/notesfile = new(NOTESFILE) if(!notesfile) log_game("Error: Cannot access [NOTESFILE]") return notesfile.cd = "/[ckey]" while(!notesfile.eof) var/notetext notesfile >> notetext var/server var/ssqlname = CONFIG_GET(string/serversqlname) if (ssqlname) server = ssqlname var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i") note.Find(notetext) var/timestamp = note.group[1] notetext = note.group[2] var/admin_ckey = note.group[3] var/datum/db_query/query_convert_time = SSdbcore.NewQuery("SELECT ADDTIME(STR_TO_DATE(:timestamp,'%d-%b-%Y'), '0')", list("timestamp" = timestamp)) if(!query_convert_time.Execute()) qdel(query_convert_time) return if(query_convert_time.NextRow()) 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, null, 0, 0) notesfile.cd = "/" notesfile.dir.Remove(ckey) #undef NOTESFILE