Files
RoomAwareVR/Assets/_Scripts/GhostSystem/SupabaseManager.cs
T
2025-10-02 00:07:11 +02:00

187 lines
7.4 KiB
C#

using System;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using Supabase.Gotrue;
using Supabase.Gotrue.Exceptions;
using Client = Supabase.Client;
using Cysharp.Threading.Tasks;
using TMPro;
// Dieses Script wickelt die gesamte Kommunikation mit der Datenbank ab. Das Skript enthält noch einige Verbindungstests (z.B. zu Google), die bei Bedarf zum Debuggen verwendet
// werden können.
namespace GhostSystem
{
public class SupabaseManager : MonoBehaviour
{
public static SupabaseManager instance { get; private set; }
public const string subabaseUrl = "https://cezghxztvyggwgunyhmq.supabase.co";
public const string supabaseAnonKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNlemdoeHp0dnlnZ3dndW55aG1xIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDcyMTk5MzcsImV4cCI6MjA2Mjc5NTkzN30.vr6-3X3Ux_DjcCiw_CqG-VKP8BiBXtmCzAXjYTiA_vY";
public Client supabase { get; private set; }
public string userId => supabase?.Auth?.CurrentUser?.Id;
private string email;
private string password;
private const string authFileName = "auth.txt";
public static event Action OnSuperbaseReady;
public TMP_Text textbox;
private void Start()
{
Initialize().Forget();
}
private async UniTask Initialize()
{
if (instance == null) // Zuerst wird sichergestellt, dass nur eine Instanz des Supabase-Managers existiert und beim Szenenwechsel mitgenommen wird.
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
return;
}
Debug.Log("Starting Supabase setup...");
await RunDiagnostics(); // Dann wird geprüft, ob die Supabase-Instanz erreichbar ist.
await InitSupabaseAsync(); // Eigentlicher Verbindungsaufbau.
OnSuperbaseReady?.Invoke(); // Wenn erfolgreich eine Verbindung zu Supabase aufgebaut wurde, wird das als Event gemeldet.
}
private async UniTask InitSupabaseAsync() // Wird aufgerufen, um die Verbindung zu Supabase zu initialisieren.
{
if (supabase != null)
return;
string path = Path.Combine(Application.persistentDataPath, authFileName);
if (File.Exists(path)) // Ist bereits eine Datei mit Email und Passwort auf dem VR-Headset hinterlegt, wird diese ausgelesen.
{
string[] lines = await UniTask.Run(() => File.ReadAllLines(path));
email = lines[0];
password = lines[1];
}
else
{ // Falls nicht, werden neue Anmeldedaten erstellt.
email = string.IsNullOrEmpty(SystemInfo.deviceUniqueIdentifier) // Fake-Email-Adresse wird aus der GUID des Gerätes generiert.
? $"{Guid.NewGuid()}@device.local" // Fallback, generiert theoretisch bei jeder Neuinstallation der App einen anderen User.
: $"{SystemInfo.deviceUniqueIdentifier}@device.local";
password = email; // selbe GUID, damit das Passwort sich nicht pro App-Version verändern kann.
await UniTask.Run(() => File.WriteAllLines(path, new[] { email, password }));
}
Debug.Log($"Using Email: {email}, Password: {password}");
supabase = new Client(subabaseUrl, supabaseAnonKey);
try
{
await supabase.InitializeAsync();
textbox.text += "\n\rSupabase initialized.";
Debug.Log("Supabase initialized.");
}
catch (Exception ex)
{
Debug.LogError($"Initialization failed: {ex}");
textbox.text += "\n\rInitialization failed";
}
await AuthenticateAsync(email, password);
Debug.Log($"Authenticated user ID: {userId}");
}
public async UniTask AuthenticateAsync(string email, string password) // Diese Methode übernimmt die Anmeldung als User bei der Supabase-Instanz.
{
try
{
await supabase.Auth.SignIn(email, password); // Nutzt die übergebene Mail-Adresse und das Passwort, um den Unser anzumelden.
textbox.text += "\n\rSign-in successful";
Debug.Log("Sign-in successful");
}
catch (Exception authEx) // Funktioniert die Anmeldung nicht, wird versucht, einen neuen User mit der übergebenen Mail-Adresse und dem
{ // Passwort zu registrieren.
Debug.LogWarning($"Sign-in failed, trying sign-up: {authEx.Message}");
try
{
await supabase.Auth.SignUp(email, password);
textbox.text += "\n\rSign-up successful";
Debug.Log("Sign-up successful");
}
catch (Exception ex)
{
textbox.text += "\n\rAuthentication failed";
Debug.LogError($"Authentication failed: {ex}");
}
}
}
private async UniTask RunDiagnostics()
{
await UniTask.WhenAll(CheckSupabaseHealthAsync(), CheckGoogleConnectionAsync());
}
private async UniTask CheckSupabaseHealthAsync() // Prüft, ob Supabase erreichbar ist.
{
using var www = UnityWebRequest.Get($"{subabaseUrl}/auth/v1/health");
www.SetRequestHeader("apikey", supabaseAnonKey);
await www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
//textbox.text += $"\n\rSupabase health: {www.downloadHandler.text}";
Debug.Log($"Supabase health: {www.downloadHandler.text}");
}
else
{
//textbox.text += $"\n\rSupabase health check failed: {www.error}";
Debug.LogError($"Supabase health check failed: {www.error}");
}
}
private async UniTask CheckGoogleConnectionAsync() // Testet, ob grundsätzlich eine Internetverbindung besteht.
{
using var www = UnityWebRequest.Get("https://www.google.com");
await www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
//textbox.text += "\n\rGoogle request succeeded.";
Debug.Log("Google request succeeded.");
}
else
{
textbox.text += $"\n\rGoogle connection failed: {www.error}";
Debug.LogError($"Google connection failed: {www.error}");
}
}
private async UniTask CheckApacheConnectionAsync()
{
using var www = UnityWebRequest.Get("http://192.168.0.85/test/index.html");
await www.SendWebRequest();
if (www.result == UnityWebRequest.Result.Success)
{
textbox.text += "\n\rApache request succeeded.";
Debug.Log("Apache request succeeded.");
}
else
{
textbox.text += $"\n\rApache connection failed: {www.error}";
Debug.LogError($"❌ Apache connection failed: {www.error}");
}
}
}
}