· 4 years ago · Jan 31, 2021, 05:18 AM
1--|| Services ||--
2local RunService = game:GetService("RunService")
3
4local Rex = script.Parent.Parent
5
6local Server = RunService:IsServer()
7local Client = RunService:IsClient()
8
9local Module = {}
10local Databases = {}
11local DatabaseProxy = {}
12local CachedDatabase = {}
13
14local Print = require(Rex.Globals.Print)
15local Warn = require(Rex.Globals.Warn)
16local Copy = require(Rex.Globals.Copy)
17
18local ReplicatorEvent = Rex.RemoteEvents.ReplicatorEvent
19
20local DatabasesPackage = Rex.Databases
21
22--| Load Prebuilt Services
23for _, Database in ipairs(DatabasesPackage:GetChildren()) do
24 Databases[Database.Name] = require(Database)
25end
26
27setmetatable(DatabaseProxy, {
28 __newindex = function(self, index, value)
29 Databases[index] = value
30 return Databases[index]
31 end,
32 __index = function(self, index)
33 return Databases[index]
34 end
35})
36
37function Module:GetDatabase(Database)
38 --[[
39 Warning: This function will yield until loaded
40 ]]
41 local WantedDatabase = DatabaseProxy[Database] and DatabaseProxy[Database][1] or DatabaseProxy[Database]
42
43 if WantedDatabase then
44 return WantedDatabase
45 end
46
47 local Loaded = Server and Rex.Data.ServerLoaded or Rex.Data.ClientLoaded
48 while not Loaded.Value do
49 RunService.Stepped:Wait()
50 end
51
52 WantedDatabase = DatabaseProxy[Database] and DatabaseProxy[Database][1] or DatabaseProxy[Database]
53 return WantedDatabase
54end
55
56function Module:CreateDatabase(DatabaseId, Data, Replicate)
57 Data = Data or {}
58 Replicate = Replicate or false
59 local DatabaseExist = Databases[DatabaseId]
60
61 if DatabaseExist then
62 Warn(DatabaseId.." Already exists as a database! Was unable to create this database :(")
63 return
64 end
65
66 if Server then
67 CachedDatabase[DatabaseId] = {Copy(Data), Replicate}
68 Databases[DatabaseId] = {Data, Replicate}
69
70 -- Iterate through Client Functions
71 local CompactedData = {}
72 for Index, Data in next, Databases do
73 if Data[2] then
74 CompactedData[Index] = Data
75 end
76 end
77
78 -- Update clients that a new service was created
79 if Replicate then
80 ReplicatorEvent:FireAllClients("NewDatabase", DatabaseId, CompactedData)
81 end
82 Print(DatabaseId.." has been created on the server!")
83 elseif Client then
84 CachedDatabase[DatabaseId] = {Copy(Data), Replicate}
85 Databases[DatabaseId] = {Data, Replicate}
86 Print(DatabaseId.." has been created on the client!")
87 end
88 return Databases[DatabaseId][1]
89end
90
91--| Table Changed
92function Module:DisconnectDatabaseTablePropertyChanged(Directory)
93 local Folder = Server and Rex.ServerBindableEvents or Client and Rex.ClientBindableEvents
94 local Bindable = Folder:FindFirstChild(Directory)
95 if Bindable then
96 Bindable:Destroy()
97 end
98end
99
100function Module:GetDatabaseTablePropertyChanged(Directory, Function)
101 local Path = string.split(Directory, ".")
102 local StartDirectory = Databases[Path[1]]
103 if StartDirectory then
104 local StartDirectory = StartDirectory[1]
105 for i = 2, #Path do
106 StartDirectory = StartDirectory[Path[i]]
107 if not StartDirectory then
108 Warn("Could not locate "..Path[i].." in ", StartDirectory)
109 return nil
110 end
111 end
112
113 if typeof(StartDirectory) ~= "table" then
114 local Bindable = Instance.new("BindableEvent")
115 Bindable.Name = Directory
116 Bindable.Parent = Server and Rex.ServerBindableEvents or Client and Rex.ClientBindableEvents
117 Bindable.Event:Connect(Function)
118
119 local Data = {
120 Disconnect = function()
121 Rex:DisconnectDatabaseTablePropertyChanged(Directory)
122 end
123 }
124 return Data
125 else
126 Warn("Can not connect table property changed for tables!")
127 end
128 else
129 Warn("Could not connect Table Property Changed for "..Directory)
130 end
131end
132
133function Module:DetectChange(Table1, Table2)
134 local Folder = Server and Rex.ServerBindableEvents or Client and Rex.ClientBindableEvents
135
136 for _, Bindable in ipairs(Folder:GetChildren()) do
137 local Arguments = string.split(Bindable.Name, ".")
138 local StartingDirectory = Table1[Arguments[1]]
139 if StartingDirectory then
140 StartingDirectory = StartingDirectory[1]
141 for i = 2, #Arguments do
142 StartingDirectory = StartingDirectory[Arguments[i]]
143 if not StartingDirectory then
144 Warn(StartingDirectory, "No longers exists")
145 Bindable:Destroy() -- Disconnects
146 break
147 end
148 end
149 end
150
151 local StartingDirectory2 = Table2[Arguments[1]]
152 if StartingDirectory2 then
153 StartingDirectory2 = StartingDirectory2[1]
154 for i = 2, #Arguments do
155 StartingDirectory2 = StartingDirectory2[Arguments[i]]
156 if not StartingDirectory2 then
157 Warn(StartingDirectory2, "No longers exists")
158 Bindable:Destroy() -- Disconnects
159 break
160 end
161 end
162 end
163
164 if StartingDirectory and StartingDirectory2 then
165 if typeof(StartingDirectory) == "table" or typeof(StartingDirectory2) == "table" then
166 Bindable:Destroy() -- Disconnects
167 end
168
169 if StartingDirectory ~= StartingDirectory2 then
170 Bindable:Fire(StartingDirectory, StartingDirectory2)
171 end
172 end
173 end
174end
175
176function Module:GetAllDatabases()
177 return Databases
178end
179
180function Module:ReplicateDatabase()
181 local UpdatedDatabase = {}
182 for DatabaseId, Data in next, Databases do
183 if Data[2] then
184 UpdatedDatabase[DatabaseId] = Data
185 end
186 end
187 ReplicatorEvent:FireAllClients("UpdateDatabase", UpdatedDatabase)
188 Module:DetectChange(CachedDatabase, Databases)
189 CachedDatabase = Copy(Databases)
190end
191
192return Module