1 |
-- Data saving monstrocity |
2 |
-- Andrew Bereza |
3 |
local Saving = require(game.ServerScriptService.Saving) |
4 |
local Utl = require(game.ServerScriptService.Utl) |
5 |
local function SaveData(Player) |
6 |
pcall(function() |
7 |
Utl.CheckPasses(Player) |
8 |
end) |
9 |
local PlayerData = Utl.GetPlayerData(Player.userId) |
10 |
if Player:FindFirstChild("DataLoaded") and PlayerData ~= nil then |
11 |
PlayerData.Inventory = PlayerData.Inventory |
12 |
PlayerData.BaseData = PlayerData.BaseData |
13 |
PlayerData.Emblems = PlayerData.Emblems |
14 |
PlayerData.Storage = PlayerData.Storage |
15 |
PlayerData.XP = (Player:FindFirstChild("XP") and math.ceil(Player.XP.Value)) |
16 |
PlayerData.Level = (Player:FindFirstChild("Level") and Player.Level.Value) |
17 |
PlayerData.Pickaxe = (Player:FindFirstChild("Pickaxe") and Player.Pickaxe.Value) |
18 |
PlayerData.Mute = (Player:FindFirstChild("Mute") and Utl.BoolToInt(Player.Mute.Value)) |
19 |
PlayerData.Gold = (Player:FindFirstChild("Gold") and Player.Gold.Value) |
20 |
PlayerData.DiscordAward = (Player:FindFirstChild("DiscordAward") and Player.DiscordAward.Value) |
21 |
PlayerData.Crystals = (Player:FindFirstChild("Crystals") and Player.Crystals.Value) |
22 |
PlayerData.LastGift = (Player:FindFirstChild("LastGift") and Player.LastGift.Value) |
23 |
PlayerData.Emblem = (Player:FindFirstChild("Emblem") and Player.Emblem.Value) |
24 |
PlayerData.Tutorial = (Player:FindFirstChild("Tutorial") and Player.Tutorial.Value) |
25 |
PlayerData.GoldQuest = (Player:FindFirstChild("GoldQuest") and Player.GoldQuest.Value) |
26 |
PlayerData.EventStatus = (Player:FindFirstChild("EventStatus") and Player.EventStatus.Value) |
27 |
-- Use difference from when they joined and now to record total playtime |
28 |
if PlayerData.TimeStamp and PlayerData.TimeStamp > 0 then |
29 |
PlayerData.TotalPlaytime = PlayerData.TotalPlaytime + (PlayerData.TimeStamp - os.time()) |
30 |
end |
31 |
-- aaand reset TimeStamp |
32 |
PlayerData.TimeStamp = os.time() |
33 |
PlayerData.LifetimeOreTotal = PlayerData.LifetimeOreTotal |
34 |
local Success, Error = Saving.SaveData(Player, PlayerData) |
35 |
print("Saving Results") |
36 |
print(Success, Error) |
37 |
-- Attempt to save their billboard data, but don't let it interfere with important data |
38 |
spawn(function() |
39 |
pcall(function() |
40 |
local Leaderboard = game:GetService("DataStoreService"):GetOrderedDataStore("TopMiner"..tostring(Utl.CurrentDay())) |
41 |
Leaderboard:IncrementAsync(Player.userId, Player.OreMined.Value) |
42 |
PlayerData.LifetimeOreTotal = PlayerData.LifetimeOreTotal + Player.OreMined.Value |
43 |
Player.OreMined.Value = 0 |
44 |
end) |
45 |
end) |
46 |
return Success, Error |
47 |
end |
48 |
end |
49 |
local function LoadData(Player, RequestedTime) |
50 |
if game.ServerStorage.WorthlessGarbage:FindFirstChild(Player.Name) then |
51 |
game.ServerStorage.WorthlessGarbage:FindFirstChild(Player.Name):Destroy() |
52 |
end |
53 |
pcall(function() |
54 |
Utl.CheckPasses(Player) |
55 |
end) |
56 |
local Success, PlayerData, Error, TimeStamp = Saving.LoadData(Player) |
57 |
TimeStamp = TimeStamp or 0 |
58 |
if not Success then |
59 |
return Success, Error |
60 |
elseif RequestedTime and RequestedTime > 1 then |
61 |
if (RequestedTime - 1) >= (TimeStamp) then |
62 |
return false, "Waiting for newer data" |
63 |
end |
64 |
end |
65 |
PlayerData.DiscordAward = PlayerData.DiscordAward or 0 |
66 |
PlayerData.LifetimeOreTotal = PlayerData.LifetimeOreTotal or 0 |
67 |
PlayerData.TotalPlaytime = PlayerData.TotalPlaytime or 0 |
68 |
PlayerData["Inventory"] = PlayerData["Inventory"] or {} |
69 |
PlayerData["Storage"] = PlayerData["Storage"] or {} |
70 |
PlayerData["BaseData"] = PlayerData["BaseData"] or {} |
71 |
PlayerData["Emblems"] = PlayerData["Emblems"] or {} |
72 |
PlayerData["Pickaxes"] = PlayerData["Pickaxes"] or {} |
73 |
PlayerData.TimeStamp = os.time() |
74 |
for i,Pickaxe in pairs(game.ReplicatedStorage.Pickaxes:GetChildren()) do |
75 |
PlayerData.Pickaxes[Pickaxe.Name] = PlayerData.Pickaxes[Pickaxe.Name] or false |
76 |
end |
77 |
if PlayerData.Pickaxe ~= nil then |
78 |
PlayerData.Pickaxes[PlayerData.Pickaxe] = true |
79 |
end |
80 |
for i,Ore in pairs(game.ReplicatedStorage.Ores:GetChildren()) do |
81 |
PlayerData.Inventory[Ore.Name] = PlayerData.Inventory[Ore.Name] or 0 |
82 |
PlayerData.Storage[Ore.Name] = PlayerData.Storage[Ore.Name] or 0 |
83 |
end |
84 |
for i,Item in pairs(game.ServerStorage.BaseParts:GetChildren()) do |
85 |
PlayerData.BaseData[Item.Name] = PlayerData.BaseData[Item.Name] or 0 |
86 |
end |
87 |
for i,Emblem in pairs(game.ReplicatedStorage.Emblems:GetChildren()) do |
88 |
PlayerData.Emblems[Emblem.Name] = PlayerData.Emblems[Emblem.Name] or false |
89 |
end |
90 |
Utl.NewPlayerData(Player, PlayerData) |
91 |
--Temp value for storing ore counts every session |
92 |
local OreMined = Instance.new("IntValue") |
93 |
OreMined.Name = "OreMined" |
94 |
OreMined.Value = 0 |
95 |
OreMined.Parent = Player |
96 |
--Value for gold quest |
97 |
-- EVENT CLAUSE |
98 |
local GoldQuest = Instance.new("StringValue") |
99 |
GoldQuest.Name = "GoldQuest" |
100 |
if PlayerData.GoldQuest ~= "Done" and PlayerData.GoldQuest ~= "Started" and PlayerData.GoldQuest ~= "Awarded" then |
101 |
PlayerData.GoldQuest = "" |
102 |
end |
103 |
GoldQuest.Value = PlayerData.GoldQuest or "" |
104 |
GoldQuest.Parent = Player |
105 |
local Tag = Instance.new("BoolValue") |
106 |
Tag.Name = "Loading" |
107 |
Tag.Parent = Player |
108 |
local Emblem = Instance.new("StringValue") |
109 |
Emblem.Name = "Emblem" |
110 |
Emblem.Value = PlayerData["Emblem"] or "" |
111 |
Emblem.Parent = Player |
112 |
local XP = Instance.new("NumberValue") |
113 |
XP.Name = "XP" |
114 |
XP.Value = PlayerData["XP"] or 0 |
115 |
XP.Parent = Player |
116 |
local Level = Instance.new("IntValue") |
117 |
Level.Name = "Level" |
118 |
Level.Value = PlayerData["Level"] or 1 |
119 |
Level.Parent = Player |
120 |
local Gold = Instance.new("NumberValue") |
121 |
Gold.Name = "Gold" |
122 |
Gold.Value = PlayerData["Gold"] or 50 |
123 |
Gold.Parent = Player |
124 |
local DiscordAward = Instance.new("IntValue") |
125 |
DiscordAward.Name = "DiscordAward" |
126 |
DiscordAward.Value = PlayerData["DiscordAward"] or 0 |
127 |
DiscordAward.Parent = Player |
128 |
local Crystals = Instance.new("NumberValue") |
129 |
Crystals.Name = "Crystals" |
130 |
Crystals.Value = PlayerData["Crystals"] or 0 |
131 |
Crystals.Parent = Player |
132 |
local LastGift = Instance.new("IntValue") |
133 |
LastGift.Name = "LastGift" |
134 |
LastGift.Value = PlayerData["LastGift"] or 0 |
135 |
LastGift.Parent = Player |
136 |
local Pickaxe = Instance.new("StringValue") |
137 |
Pickaxe.Name = "Pickaxe" |
138 |
Pickaxe.Value = PlayerData["Pickaxe"] or "Stone" |
139 |
Pickaxe.Parent = Player |
140 |
local Mute = Instance.new("BoolValue") |
141 |
Mute.Name = "Mute" |
142 |
Mute.Value = Utl.IntToBool(PlayerData["Mute"]) or false |
143 |
Mute.Parent = Player |
144 |
local Tutorial = Instance.new("IntValue") |
145 |
Tutorial.Name = "Tutorial" |
146 |
if Level.Value > 4 then |
147 |
Tutorial.Value = -1 -- ya youre done |
148 |
elseif PlayerData["BaseData"]["Teleporter"] > 0 and PlayerData["Tutorial"] and PlayerData["Tutorial"] == 0 then |
149 |
Tutorial.Value = 1 |
150 |
else |
151 |
Tutorial.Value = PlayerData["Tutorial"] or 0 |
152 |
end |
153 |
Tutorial.Parent = Player |
154 |
-- not related to data |
155 |
local TPPad = Instance.new("ObjectValue") |
156 |
TPPad.Name = "TPPad" |
157 |
TPPad.Parent = Player |
158 |
XP.Changed:connect(function() |
159 |
local RealLevel = game.ReplicatedStorage.Levels:FindFirstChild(Level.Value) |
160 |
if RealLevel and RealLevel:FindFirstChild("AdvanceXP") then |
161 |
if XP.Value >= RealLevel.AdvanceXP.Value then |
162 |
Level.Value = Level.Value + 1 |
163 |
XP.Value = XP.Value - RealLevel.AdvanceXP.Value |
164 |
end |
165 |
end |
166 |
end) |
167 |
Level.Changed:connect(function() |
168 |
if Player.Character and Player.Character:FindFirstChild("PlayerBillboard") then |
169 |
local RealLevel = game.ReplicatedStorage.Levels:FindFirstChild(Level.Value) |
170 |
if RealLevel then |
171 |
Player.Character.PlayerBillboard.Username.TextColor3 = RealLevel.Color.Value |
172 |
end |
173 |
end |
174 |
end) |
175 |
local Tycoon = Utl.GetEmptyTycoon() |
176 |
Tycoon.Owner.Value = Player |
177 |
if Player:FindFirstChild("Loading") then |
178 |
Player.Loading:Destroy() |
179 |
end |
180 |
local SuccessTag = Instance.new("BoolValue") |
181 |
SuccessTag.Name = "DataLoaded" |
182 |
SuccessTag.Parent = Player |
183 |
game.ServerStorage.PlayerLoaded:Fire(Player) |
184 |
spawn(function() |
185 |
wait(1) |
186 |
local success = pcall(function() |
187 |
if Player.Character then |
188 |
Player.Character:Destroy() |
189 |
Player.Character = nil |
190 |
end |
191 |
Player:LoadCharacter() |
192 |
end) |
193 |
if not success then |
194 |
wait() |
195 |
Player.Character = nil |
196 |
Player:LoadCharacter() |
197 |
end |
198 |
wait(1) |
199 |
-- game.ReplicatedStorage.ShowSplash:FireClient(Player,1) |
200 |
game.ReplicatedStorage.Announce:FireClient(Player,"Welcome back!",3,Color3.new(0,0.7,0.7)) |
201 |
end) |
202 |
-- Autosave |
203 |
spawn(function() |
204 |
local WaitAmount = 180 |
205 |
while wait(WaitAmount) do |
206 |
if Player and Player.Parent == game.Players and not ShuttingDown then |
207 |
local Success = SaveData(Player) |
208 |
if Success then |
209 |
if WaitAmount == 3 then |
210 |
game.ReplicatedStorage.Announce:FireClient(Player,"Data autosaved successfully!",2,Color3.new(0.7,0.7,0.7)) |
211 |
end |
212 |
WaitAmount = 180 |
213 |
elseif Success == nil then |
214 |
game.ReplicatedStorage.Announce:FireClient(Player,"Could not locate save data. AutoSave disabled.",30,Color3.new(1,0.5,0.5)) |
215 |
break |
216 |
elseif Success == false then |
217 |
if WaitAmount == 180 then |
218 |
game.ReplicatedStorage.Announce:FireClient(Player,"AutoSave failed. Re-trying...",5,Color3.new(1,0.7,0.7)) |
219 |
WaitAmount = 3 |
220 |
else |
221 |
game.ReplicatedStorage.Announce:FireClient(Player,"AutoSave failed again. ROBLOX servers may be down.",7,Color3.new(1,0.7,0.7)) |
222 |
WaitAmount = 180 |
223 |
end |
224 |
end |
225 |
else |
226 |
break |
227 |
end |
228 |
end |
229 |
end) |
230 |
return true |
231 |
end |
232 |
function game.ReplicatedStorage.LoadData.OnServerInvoke(Player, RequestedTime) |
233 |
if Player:FindFirstChild("Loading") == nil and Player:FindFirstChild("DataLoaded") == nil then |
234 |
local Tag = Instance.new("BoolValue") |
235 |
Tag.Name = "Loading" |
236 |
Tag.Parent = Player |
237 |
local Success, Error = LoadData(Player, RequestedTime) |
238 |
return Success,Error |
239 |
end |
240 |
end |
241 |
--[[ |
242 |
game.Players.PlayerAdded:connect(LoadData) |
243 |
for i,Player in pairs(game.Players:GetPlayers()) do |
244 |
LoadData(Player) |
245 |
end |
246 |
]] |
247 |
function game.ReplicatedStorage.GetData.OnServerInvoke(Player) |
248 |
return Utl.GetPlayerData(Player.userId) |
249 |
end |
250 |
local function PlayerLeaving(Player) |
251 |
local Success = SaveData(Player) |
252 |
-- TODO: PlayerLeaving fo real |
253 |
--wipe data on server |
254 |
local Tycoon = Utl.GetTycoon(Player) |
255 |
if Tycoon then |
256 |
Tycoon.Owner.Value = nil |
257 |
end |
258 |
local Datafile = game.ServerStorage.PlayerData:FindFirstChild(tostring(Player.userId)) |
259 |
if Datafile then |
260 |
Datafile:Destroy() |
261 |
end |
262 |
return Success |
263 |
end |
264 |
game.Players.PlayerRemoving:connect(PlayerLeaving) |
265 |
game.OnClose = function() |
266 |
if game:GetService("RunService"):IsRunMode() then |
267 |
return false |
268 |
end |
269 |
ShuttingDown = true |
270 |
for i,Player in pairs(game.Players:GetPlayers()) do |
271 |
game.ReplicatedStorage.Announce:FireClient(Player,"SERVER RESTARTING FOR UPDATE. REJOIN AFTER SHUTDOWN",30,Color3.new(0.9,0.8,0.2)) |
272 |
game.ReplicatedStorage.Announce:FireClient(Player,"Your data is being saved.",30,Color3.new(0.5,0.9,0.2)) |
273 |
local Success = PlayerLeaving(Player) |
274 |
if Success then |
275 |
game.ReplicatedStorage.Announce:FireClient(Player,"Data saved successfully, feel free to go!",3,Color3.new(0.5,0.9,0.2)) |
276 |
else |
277 |
game.ReplicatedStorage.Announce:FireClient(Player,"Data failed to save!",10,Color3.new(1,0.5,0.2)) |
278 |
end |
279 |
end |
280 |
local e = 1 |
281 |
for i=1,5000 do |
282 |
e = e + 3 |
283 |
wait() |
284 |
end |
285 |
end |
Комментарии