Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Understanding UserData #5

Open
RedFlames opened this issue Mar 17, 2024 · 0 comments
Open

Understanding UserData #5

RedFlames opened this issue Mar 17, 2024 · 0 comments

Comments

@RedFlames
Copy link
Owner

RedFlames commented Mar 17, 2024

ok alright so

UserData:

  • entirely abstract

methods related to "files"

methods related to raw "data" files

methods about user info?

  • string GetUID(string key);
  • string GetKey(string uid);
  • string Create(string uid, bool forceNewKey);
  • void RevokeKey(string key);
  • int GetRegisteredCount();
  • int GetAllCount();
  • string[] GetRegistered();
  • string[] GetAll();
  • T[] LoadRegistered<T>() where T : new();
  • T[] LoadAll<T>() where T : new();

FileSystemUserData:

Basics

  • all files are under Server.Settings.UserDataRoot, e.g. ./UserData/
    • string UserRoot => ... = ./UserData/User
    • string GlobalPath => ...= ./UserData/Global.yaml
  • Global.yaml only contains a Yaml-serialized FileSystemUserData.Global
    • which is a class with a Dictionary<string, string> UIDs
    • maps users' "key" => "UID"

Basic path/file related stuff

Examples for UID 12345:

  • string GetUserDir(string uid) => ./UserData/User/12345
  • static string GetDataFileName(Type type) => Celeste.Mod.CelesteNet.Server.BanInfo.yaml
  • string GetUserDataFilePath(string uid, Type type)
    • => ./UserData/User/12345/Celeste.Mod.CelesteNet.Server.BanInfo.yaml (?)
  • string GetUserDataFilePath(string uid, string name) => ./UserData/User/12345/name.yaml
  • string GetUserFilePath(string uid, string name) => ./UserData/User/12345/data/name

implementations of user info related stuff:

  • string GetUID(string key)
    • => tries to get UID for key from Global.yaml's UIDs dict, otherwise empty string
  • string GetKey(string uid)
    • => Load<PrivateUserInfo>(uid).Key;
  • string Create(string uid, bool forceNewKey)
    • load Global
    • check GetKey(uid) and if no forceNew, just return this key (loading global was pointless then)
    • generate new GUID as keyFull with no dashes, take first 16 chars as key
    • repeat while generated key already exists in Global.UIDs
    • Save(uid, new PrivateUserInfo { Key = key, KeyFull = keyFull });
    • save Global back to yaml
  • void RevokeKey(string key)
    • load Global
    • if key is in UIDs, remove it, save Global again, Delete<PrivateUserInfo>(uid);
  • int GetRegisteredCount()
    • => LoadRaw<Global>(GlobalPath).UIDs.Count;
  • int GetAllCount()
    • => Directory.GetDirectories(UserRoot).Length;
  • string[] GetRegistered()
    • => LoadRaw<Global>(GlobalPath).UIDs.Values.ToArray();
  • string[] GetAll()
    • => Directory.GetDirectories(UserRoot).Select(name => Path.GetFileName(name)).ToArray();
  • T[] LoadRegistered<T>()
    • => LoadRaw<Global>(GlobalPath).UIDs.Values.Select(uid => Load<T>(uid)).ToArray();
  • T[] LoadAll<T>()
    • => Directory.GetDirectories(UserRoot).Select(dir => LoadRaw<T>(Path.Combine(dir, GetDataFileName(typeof(T))))).ToArray();
  • void Insert(string uid, string key, string keyFull, bool registered)
    • only used by CopyTo in each UserData implementation /shrug

Raw (aren't overrides)

  • T LoadRaw<T>(string path)
    • => TryLoadRaw(path, out T value) ? value : value;
  • bool TryLoadRaw<T>(string path, out T value)
    • out new T() and return false if path no exist
    • otherwise open file and deserialize to T with YamlHelper
    • out that or new() if was null, return true
  • void SaveRaw<T>(string path, T data)
    • create path if it don't exist
    • serialize T into path+".tmp"
    • afterwards delete actual path and move tmp to path
  • void DeleteRaw(string path)
    • delete file at path if exists
  • void DeleteRawAll(string path)
    • delete directory at path if exists

UserDataFile (i.e. yamls...) methods:

  • bool TryLoad<T>(string uid, out T value)
  • void Save<T>(string uid, T value)
    • => SaveRaw(GetUserDataFilePath(uid, typeof(T)), value);
  • void Delete<T>(string uid)
  • void InsertData(string uid, string name, Type? type, Stream stream)
    • only used by CopyTo in each UserData implementation /shrug
    • uses private void InsertFileRaw

UserFile (i.e. raw under "data"...) methods:

  • bool HasFile(string uid, string name)
    • the implementation suggests this should be a "UserDataFile" thing but I'm 95% sure the implementation of this is simply wrong broken and should be using GetUserFilePath instead of GetUserDataFilePath
  • Stream? ReadFile(string uid, string name)
  • Stream WriteFile(string uid, string name)
  • void DeleteFile(string uid, string name)
  • void InsertFile(string uid, string name, Stream stream)
    • only used by CopyTo in each UserData implementation /shrug
    • uses private void InsertFileRaw

other:

  • private void CheckCleanup(string uid)
    • used to remove empty dirs after deleting files
  • void Wipe(string uid)
    • literally just DeleteRawAll(GetUserDir(uid));
  • void CopyTo(UserData other)
    • /shrug
  • private void InsertFileRaw(string path, Stream stream)
    • only used by InsertData and InsertFile which are used by CopyTo(UserData)

Observations:

  • Just about any UID can have a user directory for itself
  • Only registered users set up with a key by Create() will be in Global.UIDs and have a PrivateUserInfo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant