This commit is contained in:
2026-04-25 23:37:10 +02:00
commit 19d6bd934a
476 changed files with 9198 additions and 0 deletions
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: edd53e70728b4e699b060546ad967812
timeCreated: 1761769944
@@ -0,0 +1,42 @@
using System;
using UnityEngine;
namespace RPGCore.GlobalModules.ProfileManagerGlobalModule
{
[Serializable]
public sealed class Profile<T> : Profile where T : class
{
public new T data
{
set => base.data = value;
get => base.data as T;
}
public Profile() : this(Environment.MachineName)
{
}
public Profile(string profileName)
{
name = profileName;
}
}
public abstract class Profile
{
private protected Profile()
{
}
public readonly string guid = Guid.NewGuid().ToString();
public readonly string version = Application.version;
public string name;
public object data;
public static bool operator ==(Profile obj1, Profile obj2) => obj1?.guid == obj2?.guid;
public static bool operator !=(Profile obj1, Profile obj2) => !(obj1 == obj2);
public override bool Equals(object obj) => obj is Profile other && guid == other.guid;
public override int GetHashCode() => guid.GetHashCode();
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e6fd81ed96154f9c807c110c191c8cdc
timeCreated: 1761770134
@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RPGCore.Core;
using UnityEngine;
namespace RPGCore.GlobalModules.ProfileManagerGlobalModule
{
[Serializable]
public class ProfileManagerModule : GlobalModule
{
// Paths
private static string directoryPath => Path.Combine(Application.persistentDataPath, "profiles");
private static string fileNameTemplate => "{0}_{1}.profile";
private static string fileNameMask => "*.profile";
private static string fileNameWithDefaultProfile => "default";
// Runtime
private Profile _activeProfile;
public event Action<Profile> OnProfileChange;
public Profile<T> LoadDefault<T>() where T : class
{
var defaultPath = Path.Combine(directoryPath, fileNameWithDefaultProfile);
// Default file not found
if (!File.Exists(defaultPath)) return null;
var guid = File.ReadAllText(defaultPath);
// Profile not found, by guid from default file
var file = Directory.GetFiles(directoryPath, string.Format(fileNameTemplate, "*", guid)).FirstOrDefault();
if (file == null) return null;
return JsonUtility.FromJson<Profile<T>>(File.ReadAllText(file));
}
/// <summary>
/// Gets currently active profile
/// </summary>
public Profile<T> Get<T>() where T : class
{
return _activeProfile as Profile<T>;
}
/// <summary>
/// Parse all profiles from files and returns them.
/// There is no caching, it will scan files everytime it is called.
/// </summary>
public List<Profile<T>> LoadAll<T>() where T : class
{
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
return Directory.GetFiles(directoryPath, fileNameMask)
.Select(File.ReadAllText)
.Select(JsonUtility.FromJson<Profile<T>>)
.ToList();
}
/// <summary>
/// Creates new profile with given name and saves it as file.
/// </summary>
public Profile<T> Create<T>(string name) where T : class
{
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
var newProfile = Activator.CreateInstance<Profile<T>>();
newProfile.name = name;
Save(newProfile);
return newProfile;
}
/// <summary>
/// Removes given profile from files and if its currently active unselects it.
/// </summary>
/// <param name="playerProfile"></param>
public void Delete<T>(Profile<T> playerProfile) where T : class
{
if (playerProfile == _activeProfile) Select<T>(null);
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
File.Delete(GetFullPathFor(playerProfile));
}
/// <summary>
/// Saves currently active profile as file.
/// </summary>
public void Save()
{
Save(_activeProfile);
}
/// <summary>
/// Saves given profile as file.
/// </summary>
private void Save(Profile profile)
{
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
File.WriteAllText(GetFullPathFor(profile), JsonUtility.ToJson(profile, true));
}
/// <summary>
/// Set active given profile. Will be selected automatically next time.
/// </summary>
public void Select<T>(Profile<T> playerProfile) where T : class
{
_activeProfile = playerProfile;
OnProfileChange?.Invoke(_activeProfile);
// No profile found - create it for user
_activeProfile ??= Create<T>("New Profile");
// Our selected profile will be default one when starting game again
File.WriteAllText(Path.Combine(directoryPath, fileNameWithDefaultProfile), _activeProfile.guid);
}
private string GetFullPathFor(Profile playerProfile)
{
var fileName = string.Format(fileNameTemplate, playerProfile.name, playerProfile.guid);
return Path.Combine(directoryPath, fileName);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 453d820269db447db331f632048a4215
timeCreated: 1761769954