1+ using LabApi . Features . Wrappers ;
2+ using Newtonsoft . Json ;
3+ using Newtonsoft . Json . Linq ;
4+ using SER . ArgumentSystem . Arguments ;
5+ using SER . Helpers . Extensions ;
6+ using SER . Helpers . ResultSystem ;
7+ using SER . ValueSystem ;
8+ using Db = System . Collections . Generic . Dictionary < string , SER . FileSystem . Structures . Database . DatabaseValue > ;
9+
10+ namespace SER . FileSystem . Structures ;
11+
12+ public class Database
13+ {
14+ public readonly struct DatabaseValue ( Type originalType , object value )
15+ {
16+ public string Type { get ; } = originalType . GetAccurateName ( ) ;
17+ public object Value { get ; } = value ;
18+ }
19+
20+ private static readonly JsonSerializerSettings Settings = new ( )
21+ {
22+ TypeNameHandling = TypeNameHandling . Arrays
23+ } ;
24+
25+ private readonly string _path ;
26+ private readonly string _name ;
27+ private readonly Db _db ;
28+
29+ protected Database ( string path , Db db )
30+ {
31+ _path = path ;
32+ _db = db ;
33+ _name = Path . GetFileNameWithoutExtension ( path ) ;
34+ AllDatabases . Add ( this ) ;
35+ }
36+
37+ private static readonly List < Database > AllDatabases = [ ] ;
38+
39+ public static void Create ( string name )
40+ {
41+ Directory . CreateDirectory ( FileSystem . DbDirPath ) ;
42+ var path = Path . Combine ( FileSystem . DbDirPath , $ "{ name } .json") ;
43+ if ( File . Exists ( path ) ) return ;
44+
45+ using var file = File . CreateText ( path ) ;
46+ file . Write ( "{}" ) ;
47+ file . Close ( ) ;
48+ }
49+
50+ public static TryGet < Database > TryGet ( string name )
51+ {
52+ if ( AllDatabases . FirstOrDefault ( d => d . _name == name ) is { } foundDb )
53+ {
54+ return foundDb ;
55+ }
56+
57+ var path = Path . Combine ( FileSystem . DbDirPath , $ "{ name } .json") ;
58+ if ( ! File . Exists ( path ) )
59+ {
60+ return $ "There is no database called '{ name } '";
61+ }
62+
63+ string content = File . ReadAllText ( path ) ;
64+ if ( JsonConvert . DeserializeObject < Db > ( content , Settings ) is not { } db )
65+ {
66+ return $ "Database '{ name } ' is corrupted!";
67+ }
68+
69+ return new Database ( path , db ) ;
70+ }
71+
72+ public Result Set ( string key , Value value , bool save = true )
73+ {
74+ object saveVal ;
75+ switch ( value )
76+ {
77+ case LiteralValue literalValue :
78+ saveVal = literalValue . Value ;
79+ break ;
80+ case PlayerValue playerValue :
81+ saveVal = playerValue . Players . Select ( p => p . UserId ) . ToArray ( ) ;
82+ break ;
83+ default :
84+ return $ "Value '{ value } ' cannot be stored in databases";
85+ }
86+
87+ _db [ key ] = new ( value . GetType ( ) , saveVal ) ;
88+ if ( save ) Save ( ) ;
89+ return true ;
90+ }
91+
92+ public TryGet < Value > Get ( string key )
93+ {
94+ if ( ! _db . TryGetValue ( key , out var val ) )
95+ {
96+ return $ "There is no key called '{ key } ' in the '{ _name } ' database.";
97+ }
98+
99+ if ( val . Value is null )
100+ {
101+ return $ "Value of key '{ key } ' is not set.";
102+ }
103+
104+ if ( val . Type == typeof ( PlayerValue ) . GetAccurateName ( ) )
105+ {
106+ if ( val . Value is not string [ ] playerIds )
107+ {
108+ return $ "Value for key '{ key } ' is corrupted";
109+ }
110+
111+ return Value . Parse ( Player . List . Where ( p => playerIds . Contains ( p . UserId ) ) ) ;
112+ }
113+
114+ if ( Value . Parse ( val . Value ) is { } value && value . GetType ( ) . GetAccurateName ( ) == val . Type )
115+ {
116+ return value ;
117+ }
118+
119+ return $ "Value for key '{ key } ' is corrupted";
120+ }
121+
122+ public void Save ( )
123+ {
124+ string json = JsonConvert . SerializeObject ( _db , Formatting . Indented , Settings ) ;
125+ File . WriteAllText ( _path , json ) ;
126+ }
127+ }
0 commit comments