Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaShared/SharedSource/GameAnalytics/GameAnalyticsConsent.cs
2022-02-26 02:43:01 +09:00

241 lines
8.0 KiB
C#

using Barotrauma.Steam;
using RestSharp;
using System;
using System.Net;
namespace Barotrauma
{
static partial class GameAnalyticsManager
{
public enum Consent
{
/// <summary>
/// No attempt to contact the consent server has been made
/// </summary>
Unknown,
/// <summary>
/// An error occurred while attempting to retrieve consent status
/// </summary>
Error,
/// <summary>
/// The consent status was not saved on the remote database
/// </summary>
Ask,
/// <summary>
/// The user explicitly denied consent
/// </summary>
No,
/// <summary>
/// The user explicitly granted consent
/// </summary>
Yes
}
public static Consent UserConsented { get; private set; } = Consent.Unknown;
public static bool SendUserStatistics => UserConsented == Consent.Yes && loadedImplementation != null;
private static bool consentTextAvailable
=> TextManager.ContainsTag("statisticsconsentheader")
&& TextManager.ContainsTag("statisticsconsenttext");
private readonly static string consentServerUrl = "https://barotraumagame.com/baromaster/";
private readonly static string consentServerFile = "consentserver.php";
private static string GetAuthTicket()
{
Steamworks.AuthTicket authTicket = SteamManager.GetAuthSessionTicket();
//convert byte array to hex
return BitConverter.ToString(authTicket.Data).Replace("-", "");
}
/// <summary>
/// Sets the consent status. This method cannot be called to
/// set the status to Consent.Yes; only a positive response from
/// the database or the user accepting via the privacy policy
/// prompt should enable it.
/// </summary>
public static void SetConsent(Consent consent)
{
if (consent == Consent.Yes)
{
throw new Exception(
"Cannot call SetConsent with value Consent.Yes, must only be set to this value via consent prompt");
}
SetConsentInternal(consent);
}
/// <summary>
/// Implementation of the bulk of SetConsent.
/// DO NOT CALL THIS UNLESS NEEDED.
/// </summary>
private static void SetConsentInternal(Consent consent)
{
if (UserConsented == consent) { return; }
if (consent == Consent.Ask)
{
CreateConsentPrompt();
}
if (consent != Consent.No && consent != Consent.Yes)
{
UserConsented = consent;
ShutDown();
return;
}
if (consent == Consent.No)
{
UserConsented = consent;
ShutDown();
}
string authTicketStr;
try
{
authTicketStr = GetAuthTicket();
}
catch (Exception e)
{
DebugConsole.ThrowError("Error in GameAnalyticsManager.SetConsent. Could not get a Steam authentication ticket.", e);
return;
}
RestClient client = null;
try
{
client = new RestClient(consentServerUrl);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error while connecting to consent server", e);
}
if (client == null) { return; }
var request = new RestRequest(consentServerFile, Method.GET);
request.AddParameter("authticket", authTicketStr);
request.AddParameter("action", "setconsent");
request.AddParameter("consent", consent == Consent.Yes ? 1 : 0);
var response = client.Execute(request, Method.GET);
if (CheckResponse(response))
{
UserConsented = consent;
if (consent == Consent.Yes)
{
Init();
}
}
}
static partial void CreateConsentPrompt();
public static void InitIfConsented()
{
#if DEBUG
return;
#endif
if (!consentTextAvailable)
{
SetConsent(Consent.Unknown);
return;
}
static void error(string reason, Exception exception)
{
DebugConsole.ThrowError($"Error in GameAnalyticsManager.GetConsent: {reason}", exception);
SetConsent(Consent.Error);
}
if (!SteamManager.IsInitialized)
{
DebugConsole.AddWarning("Error in GameAnalyticsManager.GetConsent: Could not get a Steam authentication ticket (not connected to Steam).");
SetConsent(Consent.Error);
return;
}
string authTicketStr;
try
{
authTicketStr = GetAuthTicket();
}
catch (Exception e)
{
error("Could not get a Steam authentication ticket.", e);
return;
}
RestClient client;
try
{
client = new RestClient(consentServerUrl);
}
catch (Exception e)
{
error("Error while connecting to consent server.", e);
return;
}
var request = new RestRequest(consentServerFile, Method.GET);
request.AddParameter("authticket", authTicketStr);
request.AddParameter("action", "getconsent");
TaskPool.Add($"{nameof(GameAnalyticsManager)}.{nameof(InitIfConsented)}", client.ExecuteAsync(request), (t) =>
{
if (t.Exception != null)
{
error("Error executing the request to the consent server.", t.Exception.InnerException);
return;
}
if (!t.TryGetResult(out IRestResponse response)) { return; }
if (!CheckResponse(response))
{
SetConsent(Consent.Error);
}
else if (string.IsNullOrEmpty(response.Content))
{
SetConsent(Consent.Ask);
}
else
{
SetConsentInternal(response.Content[0] == '1'
? Consent.Yes
: Consent.No);
}
});
}
private static bool CheckResponse(IRestResponse response)
{
if (response.ErrorException != null)
{
DebugConsole.ThrowError(TextManager.GetWithVariable("MasterServerErrorException", "[error]", response.ErrorException.ToString()));
return false;
}
else if (response.StatusCode != HttpStatusCode.OK)
{
switch (response.StatusCode)
{
case HttpStatusCode.NotFound:
DebugConsole.ThrowError(TextManager.GetWithVariable("MasterServerError404", "[masterserverurl]", consentServerUrl));
break;
case HttpStatusCode.ServiceUnavailable:
DebugConsole.ThrowError(TextManager.Get("MasterServerErrorUnavailable"));
break;
default:
DebugConsole.ThrowError(TextManager.GetWithVariables("MasterServerErrorDefault",
("[statuscode]", response.StatusCode.ToString()),
("[statusdescription]", response.StatusDescription)));
break;
}
}
return response.StatusCode == HttpStatusCode.OK;
}
}
}