chunk 1: core gameplay scripts scenes runtime assets

This commit is contained in:
2026-04-06 11:02:34 +03:00
parent fa0388bc79
commit 0d11a097d8
703 changed files with 2292651 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0dedb8f49baa023459fcd39e0d014a77
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.Collections.Generic;
[System.Serializable]
public class GameData
{
// Player Stats
public int currentLevel;
public int currentXP;
public int overall_matches;
public int overall_wins;
public int overall_losses;
public int win_streak;
public int loss_streak;
// Rank Data
public int rank_game;
public int rank_level;
public int prevrank_level;
public string rank;
public string prevRank;
// Mission Data
public List<int> completed_missions;
public List<int> completed_missions_toAnimate;
public int animation_status;
// Authentication and Settings
public bool isAuthenticated;
public GameSettings settings;
// Constructor with default values
public GameData()
{
currentLevel = 1;
currentXP = 100; // Starting XP for new players
overall_matches = 0;
overall_wins = 0;
overall_losses = 0;
win_streak = 0;
loss_streak = 0;
rank_game = 0;
rank_level = 1;
prevrank_level = 1;
rank = "Bronze";
prevRank = "Bronze";
completed_missions = new List<int>();
completed_missions_toAnimate = new List<int>();
animation_status = 0;
isAuthenticated = false;
settings = new GameSettings();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e3055bb04776e6a4a835b390bb3416bd

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d47e8022b76108146a58b1ca7dadd1d7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,5 @@
public interface IDataService
{
bool SaveData<T>(string RelativePath, T Data, bool Encrypted);
T LoadData<T>(string RelativePath, bool Encrypted);
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ee8bf3a8a594b1446a15e6b3876b927c

View File

@@ -0,0 +1,176 @@
using UnityEngine;
using System;
using System.Collections;
using System.Threading.Tasks;
public class SaveManager : MonoBehaviour
{
public static SaveManager Instance { get; private set; }
private IDataService dataService;
private const string SAVE_FILE = "/gameData.sav";
private GameData gameData;
private bool isSyncing = false;
[SerializeField] private float autoSaveInterval = 300f; // 5 minutes
private void Awake()
{
if (Instance == null)
{
Instance = this;
// Move to root before DontDestroyOnLoad (required for it to work)
transform.SetParent(null);
#if UNITY_EDITOR
if (Application.isPlaying)
{
DontDestroyOnLoad(gameObject);
}
#else
DontDestroyOnLoad(gameObject);
#endif
InitializeSaveSystem();
}
else
{
Destroy(gameObject);
}
}
private async void InitializeSaveSystem()
{
dataService = new JsonDataService();
// Temporarily rely on local data only while auth is disabled.
// await LoadGameDataFromServer();
LoadLocalData();
StartCoroutine(AutoSaveRoutine());
}
private IEnumerator AutoSaveRoutine()
{
while (true)
{
yield return new WaitForSeconds(autoSaveInterval);
SaveGame();
}
}
public async void SaveGame()
{
if (isSyncing) return;
isSyncing = true;
try
{
// Save locally first
SaveLocalData();
// Then try to save to server
// await ApiService.SaveUserGameData(gameData);
await Task.CompletedTask; // Placeholder await while remote save is disabled.
Debug.Log("Game saved locally");
}
catch (Exception e)
{
Debug.LogError($"Failed to save locally: {e.Message}");
// Debug.LogError($"Failed to save to server: {e.Message}");
}
finally
{
isSyncing = false;
}
}
private async Task LoadGameDataFromServer()
{
try
{
// gameData = await ApiService.FetchUserGameData();
// SaveLocalData(); // Cache server data locally
await Task.CompletedTask; // Placeholder await while remote load is disabled.
LoadLocalData();
}
catch (Exception)
{
LoadLocalData(); // Fallback to local data
}
}
private void SaveLocalData()
{
dataService.SaveData(SAVE_FILE, gameData, true);
}
private void LoadLocalData()
{
try
{
gameData = dataService.LoadData<GameData>(SAVE_FILE, true);
}
catch (Exception)
{
gameData = new GameData();
SaveLocalData();
}
}
public GameData GetGameData()
{
return gameData;
}
public void AddMatch()
{
gameData.overall_matches++;
SaveGame();
}
public void AddWin()
{
gameData.overall_wins++;
gameData.win_streak++;
gameData.loss_streak = 0;
SaveGame();
}
public void AddLoss()
{
gameData.overall_losses++;
gameData.loss_streak++;
gameData.win_streak = 0;
SaveGame();
}
public void AddCompletedMission(int missionID)
{
if (!gameData.completed_missions.Contains(missionID))
{
gameData.completed_missions.Add(missionID);
SaveGame();
}
}
public void UpdatePlayerStats(int xp, int level)
{
gameData.currentXP = xp;
gameData.currentLevel = level;
SaveGame();
}
public GameData LoadGame()
{
if (gameData == null)
{
LoadLocalData();
}
return gameData;
}
// Alternative if you need async loading
public async Task<GameData> LoadGameAsync()
{
if (gameData == null)
{
await LoadGameDataFromServer();
}
return gameData;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 607488e60497ce64699c50d9e0acc9d5

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7dc7390557cbd874c9884f4fbe267c6e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,92 @@
using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;
using Newtonsoft.Json;
public static class ApiService
{
private const string BASE_URL = "http://127.0.0.1:8001";
public static async Task<GameData> FetchUserGameData()
{
try
{
string url = $"{BASE_URL}/api/game/";
using (UnityWebRequest request = UnityWebRequest.Get(url))
{
string token = PlayerPrefs.GetString("AuthToken");
if (string.IsNullOrEmpty(token))
{
Debug.LogError("No auth token found");
throw new UnauthorizedAccessException("No auth token found");
}
request.SetRequestHeader("Authorization", $"Token {token}");
request.SetRequestHeader("Accept", "application/json");
var operation = request.SendWebRequest();
while (!operation.isDone)
await Task.Yield();
Debug.Log($"Response Code: {request.responseCode}");
Debug.Log($"Response: {request.downloadHandler.text}");
if (request.result == UnityWebRequest.Result.Success)
{
string jsonResponse = request.downloadHandler.text;
Debug.Log($"Received data: {jsonResponse}");
return JsonConvert.DeserializeObject<GameData>(jsonResponse);
}
else
{
Debug.LogError($"API Error: {request.responseCode} - {request.error}");
throw new Exception($"Server error: {request.error}");
}
}
}
catch (Exception e)
{
Debug.LogError($"Failed to fetch game data: {e.Message}");
throw;
}
}
public static async Task SaveUserGameData(GameData gameData)
{
string token = PlayerPrefs.GetString("AuthToken");
string jsonData = JsonConvert.SerializeObject(gameData);
using (UnityWebRequest request = new UnityWebRequest($"{BASE_URL}/api/game/save", "POST"))
{
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);
request.uploadHandler = new UploadHandlerRaw(bodyRaw);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Authorization", $"Token {token}");
request.SetRequestHeader("Content-Type", "application/json");
try
{
var operation = request.SendWebRequest();
while (!operation.isDone)
await Task.Yield();
if (request.result != UnityWebRequest.Result.Success)
{
if (request.responseCode == 401)
{
throw new UnauthorizedAccessException("Authentication failed");
}
throw new Exception($"Failed to save: {request.error}");
}
}
catch (Exception e)
{
Debug.LogError($"Failed to save game data: {e.Message}");
throw;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ba8e7ec37c2833f45bf7c48206d8e110

View File

@@ -0,0 +1,80 @@
using Newtonsoft.Json;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
public class JsonDataService : IDataService
{
public bool SaveData<T>(string relativePath, T data, bool encrypted)
{
string path = Application.persistentDataPath + relativePath;
try
{
string jsonData = JsonConvert.SerializeObject(data, Formatting.Indented);
if (encrypted)
{
jsonData = EncryptDecrypt(jsonData);
}
using (FileStream stream = new FileStream(path, FileMode.Create))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write(jsonData);
}
}
return true;
}
catch (Exception e)
{
Debug.LogError($"Failed to save data: {e.Message}");
return false;
}
}
public T LoadData<T>(string relativePath, bool encrypted)
{
string path = Application.persistentDataPath + relativePath;
if (!File.Exists(path))
{
throw new FileNotFoundException($"Cannot load file at {path}. File does not exist!");
}
try
{
string jsonData = "";
using (FileStream stream = new FileStream(path, FileMode.Open))
{
using (StreamReader reader = new StreamReader(stream))
{
jsonData = reader.ReadToEnd();
}
}
if (encrypted)
{
jsonData = EncryptDecrypt(jsonData);
}
return JsonConvert.DeserializeObject<T>(jsonData);
}
catch (Exception e)
{
Debug.LogError($"Failed to load data: {e.Message}");
throw;
}
}
private string EncryptDecrypt(string data)
{
// Simple XOR encryption (replace with more secure method for production)
string key = "YOUR_ENCRYPTION_KEY";
StringBuilder result = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
result.Append((char)(data[i] ^ key[i % key.Length]));
}
return result.ToString();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9317a7208a9f0ac40b2962d943b9bbc9