/* * DB based warning proc */ /client/proc/warn(warned_ckey) if (!check_rights(R_ADMIN|R_MOD)) return if (!warned_ckey || !istext(warned_ckey)) return if (!establish_db_connection(dbcon)) to_chat(usr, "Error: warn(): Database Connection failed, reverting to legacy systems.") usr.client.warn_legacy(warned_ckey) return var/warning_reason = input("Add Warning Reason. This is visible to the player.") as null|text if (!warning_reason) return var/warning_notes = input("Add additional information. This is visible only to staff.") as null|text var/warning_severity switch (alert("Set warning severity", null, "Standard", "Severe")) if ("standard") warning_severity = "0" if ("Severe") warning_severity = "1" var/warned_computerid = null var/warned_ip = null var/client/C = directory[warned_ckey] if (C) warned_computerid = C.computer_id warned_ip = C.address else var/DBQuery/lookup_query = dbcon.NewQuery("SELECT ip, computerid FROM ss13_player WHERE ckey = :ckey:") lookup_query.Execute(list("ckey" = warned_ckey)) if (lookup_query.NextRow()) warned_ip = lookup_query.item[1] warned_computerid = lookup_query.item[2] var/DBQuery/insert_query = dbcon.NewQuery("INSERT INTO ss13_warnings (id, time, game_id, severity, reason, notes, ckey, computerid, ip, a_ckey, a_ip, a_computerid) VALUES (null, Now(), :game_id:, :warning_severity:, :warning_reason:, :warning_notes:, :warned_ckey:, :warned_computerid:, :warned_ip:, :a_ckey:, :a_ip:, :a_computerid:)") insert_query.Execute(list("game_id" = game_id,"warning_severity" = warning_severity, "warning_reason" = warning_reason, "warning_notes" = warning_notes, "warned_ckey" = warned_ckey, "warned_computerid" = warned_computerid, "warned_ip" = warned_ip, "a_ckey" = ckey, "a_ip" = address, "a_computerid" = computer_id)) notes_add_sql(warned_ckey, "Warning added by [ckey], for: [warning_reason]. || Notes regarding the warning: [warning_notes].", src, warned_ip, warned_computerid) feedback_add_details("admin_verb", "WARN-DB") if (C) to_chat(C, "You have been warned by an administrator.
Click here to review and acknowledge them!
") message_admins("[key_name_admin(src)] has warned [warned_ckey] for: [warning_reason].") /* * Legacy warning proc */ #define MAX_WARNS 3 #define AUTOBANTIME 10 /client/proc/warn_legacy(warned_ckey) if (!warned_ckey) to_chat(usr, "Error: warn_legacy(): No ckey passed!") return var/datum/preferences/D var/client/C = directory[warned_ckey] if(C) D = C.prefs else D = preferences_datums[warned_ckey] if(!D) to_chat(src, "Error: warn_legacy(): No such ckey found.") return if(++D.warns >= MAX_WARNS) //uh ohhhh...you'reee iiiiin trouuuubble O:) ban_unban_log_save("[ckey] warned [warned_ckey], resulting in a [AUTOBANTIME] minute autoban.") if(C) message_admins("[key_name_admin(src)] has warned [key_name_admin(C)] resulting in a [AUTOBANTIME] minute ban.") to_chat_immediate(C, "You have been autobanned due to a warning by [ckey].
This is a temporary ban, it will be removed in [AUTOBANTIME] minutes.
") qdel(C) else message_admins("[key_name_admin(src)] has warned [warned_ckey] resulting in a [AUTOBANTIME] minute ban.") AddBan(warned_ckey, D.last_id, "Autobanning due to too many formal warnings", ckey, 1, AUTOBANTIME) feedback_inc("ban_warn",1) else if(C) to_chat(C, "You have been warned by an administrator.
Further warnings will result in an autoban.
") message_admins("[key_name_admin(src)] has warned [key_name_admin(C)]. They have [MAX_WARNS-D.warns] strikes remaining.") else message_admins("[key_name_admin(src)] has warned [warned_ckey] (DC). They have [MAX_WARNS-D.warns] strikes remaining.") feedback_add_details("admin_verb","WARN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! #undef MAX_WARNS #undef AUTOBANTIME /* * A proc for a player to check their own warnings */ /client/verb/warnings_check() set name = "Warnings and Notifications" set category = "OOC" set desc = "Display warnings issued to you." var/lcolor = "#ffeeee" //light colour, severity = 0 var/dcolor = "#ffaaaa" //dark colour, severity = 1 var/ecolor = "#e3e3e3" //gray colour, expired = 1 if (!establish_db_connection(dbcon)) alert("Connection to the SQL database lost. Aborting. Please alert an Administrator or a member of staff.") return var/dat = "" // // Notifications // var/DBQuery/notification_query = dbcon.NewQuery({"SELECT id, message, created_by FROM ss13_player_notifications WHERE acked_at IS NULL AND ckey = :ckey: AND type IN ('player_greeting','player_greeting_chat') "}) notification_query.Execute(list("ckey" = ckey)) var/notification_header=0 while(notification_query.NextRow()) if(!notification_header) notification_header=1 dat += "

Pending Notifications


" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" if(notification_header) dat += "
ADMINTEXTACKNOWLEDGE
[notification_query.item[3]][notification_query.item[2]](Acknowledge Notification)
" // // Warnings // dat += "

Warnings Received


" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" var/DBQuery/search_query = dbcon.NewQuery("SELECT id, time, severity, reason, a_ckey, acknowledged, expired FROM ss13_warnings WHERE visible = 1 AND (ckey = :ckey: OR computerid = :computer_id: OR ip = :address:) ORDER BY time DESC;") search_query.Execute(list("ckey" = ckey, "computer_id" = computer_id, "address" = address)) while (search_query.NextRow()) var/id = text2num(search_query.item[1]) var/time = search_query.item[2] var/severity = text2num(search_query.item[3]) var/reason = search_query.item[4] var/a_ckey = search_query.item[5] var/ackn = text2num(search_query.item[6]) var/expired = text2num(search_query.item[7]) var/bgcolor = lcolor if (severity) bgcolor = dcolor if (expired) bgcolor = ecolor dat += "" dat += "" dat += "" dat += "" dat += "" if (!ackn) dat += "" else if (expired) dat += "" else dat += "" dat += "" dat += "" dat += "" dat += "
ADMINTIME ISSUEDREASON
[a_ckey][time][reason]
(Acknowledge Warning)
Warning expired and no longer active!
Warning acknowledged!
 
" usr << browse(dat, "window=mywarnings;size=900x500") /* * A proc for acknowledging a warning */ /client/proc/warnings_acknowledge(warning_id) if (!warning_id) return if (!establish_db_connection(dbcon)) alert("Connection to SQL database failed while attempting to update your warning's status!") return var/DBQuery/query = dbcon.NewQuery("UPDATE ss13_warnings SET acknowledged = 1 WHERE id = :warning_id:;") query.Execute(list("warning_id" = warning_id)) warnings_check() fetch_unacked_warning_count() /client/proc/notifications_acknowledge(var/id) if(!id) log_world("ERROR: Error: Argument ID for notificaton acknowledgement not supplied.") return if (!establish_db_connection(dbcon)) log_world("ERROR: Unable to establish db connection during notification acknowledgement.") return var/DBQuery/query = dbcon.NewQuery({"UPDATE ss13_player_notifications SET acked_by = :ckey:, acked_at = NOW() WHERE id = :id: AND ckey = :ckey: "}) query.Execute(list("ckey" = src.ckey, "id" = id)) warnings_check() /* * A proc to gather notifications regarding your warnings. * Called by /datum/preferences/proc/gather_notifications() in preferences.dm */ /client/proc/warnings_gather() var/count = 0 var/count_expire = 0 if (!establish_db_connection(dbcon)) return var/list/client_details = list("ckey" = ckey, "computer_id" = computer_id, "address" = address) var/DBQuery/expire_query = dbcon.NewQuery("SELECT id FROM ss13_warnings WHERE (acknowledged = 1 AND expired = 0 AND DATE_SUB(CURDATE(),INTERVAL 3 MONTH) > time) AND (ckey = :ckey: OR computerid = :computer_id: OR ip = :address:)") expire_query.Execute(client_details) while (expire_query.NextRow()) var/warning_id = text2num(expire_query.item[1]) var/DBQuery/update_query = dbcon.NewQuery("UPDATE ss13_warnings SET expired = 1 WHERE id = :warning_id:") update_query.Execute(list("warning_id" = warning_id)) count_expire++ var/DBQuery/query = dbcon.NewQuery("SELECT id FROM ss13_warnings WHERE (visible = 1 AND acknowledged = 0 AND expired = 0) AND (ckey = :ckey: OR computerid = :computer_id: OR ip = :address:)") query.Execute(client_details) while (query.NextRow()) count++ var/list/data = list("unread" = "", "expired" = "") if (count) data["unread"] = "You have [count] unread warning\s! Click here to review and acknowledge them!" if (count_expire) data["expired"] = "[count_expire] of your warnings have expired." return data /* * A proc used to gather if someone has Unacknowledged Warnings */ /client/proc/fetch_unacked_warning_count() if (!dbcon) return if (!establish_db_connection(dbcon)) return var/count = 0 var/DBQuery/warning_count_query = dbcon.NewQuery("SELECT COUNT(*) FROM ss13_warnings WHERE (visible = 1 AND acknowledged = 0 AND expired = 0) AND (ckey = :ckey: OR computerid = :computer_id: OR ip = :address:)") warning_count_query.Execute(list("ckey" = ckey, "computer_id" = computer_id, "address" = address)) if(warning_count_query.NextRow()) count += text2num(warning_count_query.item[1]) var/DBQuery/notification_count_query = dbcon.NewQuery("SELECT COUNT(*) FROM ss13_player_notifications WHERE ckey = :ckey: AND acked_at is NULL and type IN ('player_greeting','player_greeting_chat')") notification_count_query.Execute(list("ckey" = ckey)) if(notification_count_query.NextRow()) count += text2num(notification_count_query.item[1]) unacked_warning_count = count return unacked_warning_count /* * A proc for an admin/moderator to look up a member's warnings. */ /client/proc/warning_panel() set category = "Admin" set name = "Warnings Panel" set desc = "Look-up warnings assigned to players." if(!holder) return holder.warning_panel() /datum/admins/proc/warning_panel(var/adminckey = null, var/playerckey = null) if (!check_rights(R_ADMIN|R_MOD)) return var/lcolor = "#ffeeee" //light colour, severity = 0 var/dcolor = "#ffdddd" //dark colour, severity = 1 var/ecolor = "#e3e3e3" //gray colour, expired = 1 if (!establish_db_connection(dbcon)) alert("Connection to the SQL database lost. Aborting. Please alert the database admin!") return var/dat = "

Warning Look-up Panel


" //Totally not stealing code from the DB_ban_panel dat += "
Search: " dat += "" dat += "Ckey: " dat += "Admin ckey: " dat += "" dat += "
" if (adminckey || playerckey) dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" var/list/query_details = list("a_ckey", "ckey") var/paramone = "" var/paramtwo = "" if(adminckey) paramone = "AND a_ckey = :a_ckey: " query_details["a_ckey"] = adminckey if(playerckey) paramtwo = "AND ckey = :ckey: " query_details["ckey"] = playerckey var/DBQuery/search_query = dbcon.NewQuery("SELECT id, time, severity, reason, notes, ckey, a_ckey, acknowledged, expired, edited, lasteditor, lasteditdate FROM ss13_warnings WHERE visible = 1 [paramone] [paramtwo] ORDER BY time DESC;") search_query.Execute(query_details) while (search_query.NextRow()) var/id = text2num(search_query.item[1]) var/time = search_query.item[2] var/severity = text2num(search_query.item[3]) var/reason = search_query.item[4] var/notes = search_query.item[5] var/ckey = search_query.item[6] var/a_ckey = search_query.item[7] var/ackn = text2num(search_query.item[8]) var/expired = text2num(search_query.item[9]) var/edited = text2num(search_query.item[10]) var/bgcolor = lcolor if(severity) bgcolor = dcolor if(expired) bgcolor = ecolor dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" if(!ackn) dat += "" if(expired) dat += "" if(edited) var/lastEditor = search_query.item[11] var/lastEditDate = search_query.item[12] dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat +="
ISSUED TOISSUED BYTIME ISSUEDREASON
[ckey][a_ckey][time][reason]
Staff Notes: \"[notes]\"
Warning has not been acknolwedged by recipient.
The warning has expired.
Warning last edited: [lastEditDate], by: [lastEditor].
Options: " if(check_rights(R_ADMIN) || a_ckey == sanitizeSQL(ckey)) dat += "Edit Reason " dat += "Edit Note " dat += "Delete Warning" else dat += "You can only edit or delete notes that you have issued." dat += "
 
" usr << browse(dat, "window=lookupwarns;size=900x500") feedback_add_details("admin_verb","WARN-LKUP") //Admin Proc to add a new User Notification /client/proc/notification_add() set category = "Admin" set name = "Add Notification" if(!check_rights(R_ADMIN|R_MOD|R_DEV|R_CCIAA)) return if (!establish_db_connection(dbcon)) log_world("ERROR: Unable to establish db connection while adding a notification.") return var/ckey = ckey(input(usr, "What ckey?", "Enter a ckey")) if(!ckey) to_chat(usr,"You need to specify a ckey.") return //Validate ckey var/DBQuery/validatequery = dbcon.NewQuery("SELECT id FROM ss13_player WHERE ckey = :ckey:") validatequery.Execute(list("ckey" = ckey)) if (validatequery.RowCount() == 0) to_chat(usr, "Could not find a player with that ckey.") return else if (validatequery.RowCount() != 1) to_chat(usr, "Found more than one player with this ckey. This should not happen, please inform the server maintainers.") return var/list/types=list("player_greeting","player_greeting_chat","admin","ccia") var/type = input(usr, "Which Type?", "Choose a type", "") as null|anything in (types) if(!type) to_chat(usr,"You need to specify a type.") return var/message = sanitize(input(usr,"Notification Message", "Specify a notification message")) if(!message) to_chat(usr,"You need to specify a notification message.") return var/DBQuery/addquery = dbcon.NewQuery("INSERT INTO ss13_player_notifications (`ckey`, `type`, `message`, `created_by`) VALUES (:ckey:, :type:, :message:, :a_ckey:)") addquery.Execute(list("ckey" = ckey, "type" = type, "message" = message, "a_ckey" = usr.ckey)) to_chat(usr,"Notification added.") /* * A proc for editing and deleting warnings issued */ /proc/warningsEdit(var/warning_id, var/warning_edit) if(!warning_id || !warning_edit) return if(!establish_db_connection(dbcon)) alert("Connection to the SQL database lost. Aborting. Please alert the database admin!") return var/count = 0 //failsafe var/ckey var/reason var/notes var/list/query_details = list("warning_id" = warning_id, "a_ckey" = usr.ckey) var/DBQuery/initial_query = dbcon.NewQuery("SELECT ckey, reason, notes FROM ss13_warnings WHERE id = :warning_id:") initial_query.Execute(query_details) while (initial_query.NextRow()) ckey = initial_query.item[1] reason = initial_query.item[2] notes = initial_query.item[3] count++ if (count == 0) to_chat(usr, "Database update failed due to a warning id not being present in the database.") log_world("ERROR: Database update failed due to a warning id not being present in the database.") return if (count > 1) to_chat(usr, "Database update failed due to multiple warnings having the same ID. Contact the database admin.") log_world("ERROR: Database update failed due to multiple warnings having the same ID. Contact the database admin.") return switch (warning_edit) if ("delete") if(alert("Delete this warning?", "Delete?", "Yes", "No") == "Yes") var/DBQuery/deleteQuery = dbcon.NewQuery("UPDATE ss13_warnings SET visible = 0 WHERE id = :warning_id:") deleteQuery.Execute(query_details) message_admins("[key_name_admin(usr)] deleted one of [ckey]'s warnings.") log_admin("[key_name(usr)] deleted one of [ckey]'s warnings.", admin_key=key_name(usr), ckey=ckey) else to_chat(usr, "Cancelled") return if ("editReason") query_details["new_reason"] = input("Edit this warning's reason.", "New Reason", reason, null) as null|text if(!query_details["new_reason"] || query_details["new_reason"] == reason) to_chat(usr, "Cancelled") return var/DBQuery/reason_query = dbcon.NewQuery("UPDATE ss13_warnings SET reason = :new_reason:, edited = 1, lasteditor = :a_ckey:, lasteditdate = NOW() WHERE id = :warning_id:") reason_query.Execute(query_details) message_admins("[key_name_admin(usr)] edited one of [ckey]'s warning reasons.") log_admin("[key_name(usr)] edited one of [ckey]'s warning reasons.", admin_key=key_name(usr), ckey=ckey) if("editNotes") query_details["new_notes"] = input("Edit this warning's notes.", "New Notes", notes, null) as null|text if(!query_details["new_notes"] || query_details["new_notes"] == notes) to_chat(usr, "Cancelled") return var/DBQuery/notes_query = dbcon.NewQuery("UPDATE ss13_warnings SET notes = :new_notes:, edited = 1, lasteditor = :a_ckey:, lasteditdate = NOW() WHERE id = :warning_id:") notes_query.Execute(query_details) message_admins("[key_name_admin(usr)] edited one of [ckey]'s warning notes.") log_admin("[key_name(usr)] edited one of [ckey]'s warning notes.", admin_key=key_name(usr), ckey=ckey)