diff --git a/SQL/migrate/V029__player_notifications.sql b/SQL/migrate/V029__player_notifications.sql
new file mode 100644
index 00000000000..5ad9f44b42d
--- /dev/null
+++ b/SQL/migrate/V029__player_notifications.sql
@@ -0,0 +1,16 @@
+--
+-- Notifications for Players
+--
+CREATE TABLE `ss13_player_notifications` (
+ `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+ `ckey` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
+ `type` ENUM('player_greeting','player_greeting_chat','admin','ccia') NOT NULL COLLATE 'utf8_bin',
+ `message` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
+ `created_by` VARCHAR(50) NOT NULL COLLATE 'utf8_bin',
+ `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `acked_by` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_bin',
+ `acked_at` DATETIME NULL DEFAULT NULL,
+ PRIMARY KEY (`id`)
+)
+COLLATE='utf8_bin'
+ENGINE=InnoDB;
\ No newline at end of file
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 4c5e8f5ebc2..6c5c9cd83f1 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -6,7 +6,8 @@ var/list/admin_verbs_default = list(
/client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/
/client/proc/hide_verbs, /*hides all our adminverbs*/
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
- /client/proc/cmd_mentor_check_new_players
+ /client/proc/cmd_mentor_check_new_players,
+ /client/proc/notification_add /*allows everyone to set up player notifications*/
)
var/list/admin_verbs_admin = list(
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game.*/
diff --git a/code/modules/admin/verbs/warning.dm b/code/modules/admin/verbs/warning.dm
index 1cf55a457b9..08d31cb0cc0 100644
--- a/code/modules/admin/verbs/warning.dm
+++ b/code/modules/admin/verbs/warning.dm
@@ -102,7 +102,7 @@
*/
/client/verb/warnings_check()
- set name = "My warnings"
+ set name = "Warnings and Notifications"
set category = "OOC"
set desc = "Display warnings issued to you."
@@ -115,7 +115,48 @@
alert("Connection to the SQL database lost. Aborting. Please alert an Administrator or a member of staff.")
return
- var/dat = "
Warnings received
"
+ 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 += "| ADMIN | "
+ dat += "TEXT | "
+ dat += "ACKNOWLEDGE | "
+ dat += "
"
+
+ dat += ""
+ dat += "| [notification_query.item[3]] | "
+ dat += "[notification_query.item[2]] | "
+ dat += "(Acknowledge Notification) | "
+ dat += "
"
+
+ if(notification_header)
+ dat += "
"
+
+ //
+ // Warnings
+ //
+
+ dat += "Warnings Received
"
dat += ""
dat += ""
@@ -182,6 +223,23 @@
warnings_check()
+/client/proc/notifications_acknowledge(var/id)
+ if(!id)
+ error("Error: Argument ID for notificaton acknowledgement not supplied.")
+ return
+
+ if (!establish_db_connection(dbcon))
+ error("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
@@ -334,6 +392,50 @@
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))
+ error("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
*/
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index 1314701f634..94a564d3ca8 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -101,6 +101,10 @@
if(href_list["warnacknowledge"])
var/queryid = text2num(href_list["warnacknowledge"])
warnings_acknowledge(queryid)
+
+ if(href_list["notifacknowledge"])
+ var/queryid = text2num(href_list["notifacknowledge"])
+ notifications_acknowledge(queryid)
if(href_list["warnview"])
warnings_check()
diff --git a/code/modules/client/preferences_notification.dm b/code/modules/client/preferences_notification.dm
index 171aab8fb84..f8b30b51718 100644
--- a/code/modules/client/preferences_notification.dm
+++ b/code/modules/client/preferences_notification.dm
@@ -153,9 +153,62 @@
var/cciaa_actions = count_ccia_actions(user)
if (cciaa_actions)
new_notification("info", cciaa_actions)
+
+ add_active_notifications(user)
+
+/datum/preferences/proc/add_active_notifications(var/client/user)
+ if(!user)
+ return null
+
+ if (!establish_db_connection(dbcon))
+ error("Error initiatlizing database connection while getting notifications.")
+ return null
+
+ var/DBQuery/query = dbcon.NewQuery({"SELECT
+ message, type, id
+ FROM ss13_player_notifications
+ WHERE acked_at IS NULL AND ckey = :ckey:
+ "})
+ query.Execute(list("ckey" = user.ckey))
+
+ var/chat_notification=0
+ var/panel_notification=0
+ var/notification_count=0
+
+ while(query.NextRow())
+ var/autoack=0
+ //Lets loop through the results
+ switch(query.item[2])
+ if("player_greeting")
+ panel_notification=1
+ notification_count++
+ if("player_greeting_chat")
+ chat_notification=1
+ panel_notification=1
+ notification_count++
+ if("admin")
+ discord_bot.send_to_admins("Server Notification for [user.ckey]: [query.item[1]]")
+ post_webhook_event(WEBHOOK_ADMIN, list("title"="Server Notification for: [user.ckey]", "message"="Server Notification Triggered for [user.ckey]: [query.item[1]]"))
+ //Immediately ack the notification
+ autoack=1
+ if("ccia")
+ discord_bot.send_to_cciaa("Server Notification for [user.ckey]: [query.item[1]]")
+ post_webhook_event(WEBHOOK_CCIAA_EMERGENCY_MESSAGE, list("title"="Server Notification for: [user.ckey]", "message"="Server Notification Triggered for [user.ckey]: [query.item[1]]"))
+ //Immeidately ack the notification
+ autoack=1
+ if(autoack)
+ var/DBQuery/ackquery = dbcon.NewQuery({"UPDATE ss13_player_notifications
+ SET acked_by = 'autoack-server', acked_at = NOW()
+ WHERE id = :id:
+ "})
+ ackquery.Execute(list("id" = query.item[3]))
+ if(panel_notification)
+ new_notification("warning","You have [notification_count] unread notifications! Click here to review and acknowledge them!")
+ if(chat_notification)
+ to_chat(user,"You have unacknowledged notifications.
Click here to review and acknowledge them!")
/*
- * Helper proc for getting a count of active CCIA actions against the player's character.
+ * Helper proc for getting a count of active CCIA actions against the player's characters.
*/
/datum/preferences/proc/count_ccia_actions(var/client/user)
if (!user)
diff --git a/html/changelogs/Arrow768-playernotifications.yml b/html/changelogs/Arrow768-playernotifications.yml
new file mode 100644
index 00000000000..a4054065269
--- /dev/null
+++ b/html/changelogs/Arrow768-playernotifications.yml
@@ -0,0 +1,37 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+#################################
+
+# Your name.
+author: Arrow768
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Adds a Notification System to send notifications to players."
\ No newline at end of file