From 462f1e1f6ce8e5f64c319777fbf8555a1ec14546 Mon Sep 17 00:00:00 2001
From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com>
Date: Mon, 4 Jan 2021 19:05:58 +0000
Subject: [PATCH] A bit of GDPR compliance stuff (#15237)
* Moves TOS consent to /client instead of /mob
* Only store cookies if the client allows it
---
code/modules/client/client_defines.dm | 11 ++++++
code/modules/client/client_procs.dm | 40 ++++++++++++++++++++-
code/modules/mob/new_player/new_player.dm | 43 ++++++-----------------
goon/code/datums/browserOutput.dm | 4 ++-
4 files changed, 63 insertions(+), 35 deletions(-)
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index 9a85ba171b2..11c8307cfe1 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -105,3 +105,14 @@
/// Last world/time that a PM was sent to the player by an admin
var/received_discord_pm = -99999 // Yes this super low number is intentional
+
+ /// Has the client accepted the TOS about data collection and other stuff
+ var/tos_consent = FALSE
+
+/client/vv_edit_var(var_name, var_value)
+ switch(var_name)
+ // I know we will never be in a world where admins are editing client vars to let people bypass TOS
+ // But guess what, if I have the ability to overengineer something, I am going to do it
+ if("tos_consent")
+ return FALSE
+ return ..()
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index e7fe0710a05..261f1986ff0 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -293,6 +293,9 @@
if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps)
fps = prefs.clientfps
+ // Check if the client has or has not accepted TOS
+ check_tos_consent()
+
// This has to go here to avoid issues
// If you sleep past this point, you will get SSinput errors as well as goonchat errors
// DO NOT STUFF RANDOM SQL QUERIES BELOW THIS POINT WITHOUT USING `INVOKE_ASYNC()` OR SIMILAR
@@ -1044,7 +1047,6 @@
* Arguments:
* * notify - Do we notify admins of this new accounts date
*/
-
/client/proc/get_byond_account_date(notify = FALSE)
// First we see if the client has a saved date in the DB
var/datum/db_query/query_date = SSdbcore.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey=:ckey", list(
@@ -1101,6 +1103,42 @@
/client/proc/show_update_notice()
to_chat(src, "Your BYOND client (v: [byond_version].[byond_build]) is out of date. This can cause glitches. We highly suggest you download the latest client from byond.com before playing. You can also update via the BYOND launcher application.")
+/**
+ * Checks if the client has accepted TOS
+ *
+ * Runs some checks against vars and the DB to see if the client has accepted TOS.
+ * Returns TRUE or FALSE if they have or have not
+ */
+/client/proc/check_tos_consent()
+ // If there is no TOS, auto accept
+ if(!GLOB.join_tos)
+ tos_consent = TRUE
+ return TRUE
+
+ // If theres no DB, assume yes
+ if(!SSdbcore.IsConnected())
+ tos_consent = TRUE
+ return TRUE
+
+ var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("privacy")] WHERE ckey=:ckey AND consent=1", list(
+ "ckey" = ckey
+ ))
+ if(!query.warn_execute())
+ qdel(query)
+ // If our query failed, just assume yes
+ tos_consent = TRUE
+ return TRUE
+
+ // If we returned a row, they accepted
+ while(query.NextRow())
+ qdel(query)
+ tos_consent = TRUE
+ return TRUE
+
+ qdel(query)
+ // If we are here, they have not accepted, and need to read it
+ return FALSE
+
#undef LIMITER_SIZE
#undef CURRENT_SECOND
#undef SECOND_COUNT
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index e90b06614e1..09f794c8f98 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -3,7 +3,6 @@
var/spawning = 0 //Referenced when you want to delete the new_player later on in the code.
var/totalPlayers = 0 //Player counts for the Lobby tab
var/totalPlayersReady = 0
- var/tos_consent = FALSE
universal_speak = 1
invisibility = 101
@@ -23,35 +22,11 @@
/mob/new_player/verb/new_player_panel()
set src = usr
- if(handle_tos_consent())
+ if(client.tos_consent)
new_player_panel_proc()
+ else
+ privacy_consent()
-/mob/new_player/proc/handle_tos_consent()
- if(!GLOB.join_tos)
- tos_consent = TRUE
- return TRUE
-
- if(!SSdbcore.IsConnected())
- tos_consent = TRUE
- return TRUE
-
- var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("privacy")] WHERE ckey=:ckey AND consent=1", list(
- "ckey" = ckey
- ))
- if(!query.warn_execute())
- qdel(query)
- // If our query failed, just assume yes
- tos_consent = TRUE
- return TRUE
-
- while(query.NextRow())
- qdel(query)
- tos_consent = TRUE
- return TRUE
-
- qdel(query)
- privacy_consent()
- return FALSE
/mob/new_player/proc/privacy_consent()
src << browse(null, "window=playersetup")
@@ -147,10 +122,12 @@
query.warn_execute()
qdel(query)
src << browse(null, "window=privacy_consent")
- tos_consent = 1
+ client.tos_consent = TRUE
+ // Now they have accepted TOS, we can log data
+ client.chatOutput.sendClientData()
new_player_panel_proc()
if(href_list["consent_rejected"])
- tos_consent = 0
+ client.tos_consent = FALSE
to_chat(usr, "You must consent to the terms of service before you can join!")
var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list(
"ckey" = ckey
@@ -164,7 +141,7 @@
return TRUE
if(href_list["ready"])
- if(!tos_consent)
+ if(!client.tos_consent)
to_chat(usr, "You must consent to the terms of service before you can join!")
return FALSE
if(client.version_blocked)
@@ -182,7 +159,7 @@
new_player_panel_proc()
if(href_list["observe"])
- if(!tos_consent)
+ if(!client.tos_consent)
to_chat(usr, "You must consent to the terms of service before you can join!")
return FALSE
if(client.version_blocked)
@@ -227,7 +204,7 @@
return FALSE
if(href_list["late_join"])
- if(!tos_consent)
+ if(!client.tos_consent)
to_chat(usr, "You must consent to the terms of service before you can join!")
return FALSE
if(client.version_blocked)
diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm
index 314c101d797..b572b18256e 100644
--- a/goon/code/datums/browserOutput.dm
+++ b/goon/code/datums/browserOutput.dm
@@ -120,7 +120,9 @@ var/list/chatResources = list(
to_chat(owner, message)
messageQueue = null
- src.sendClientData()
+ // We can only store a cookie on the client if they actually accept TOS because GDPR is GDPR
+ if(owner.tos_consent)
+ sendClientData()
pingLoop()