· 6 years ago · Mar 17, 2019, 07:42 PM
1local globalplayerstats = game:GetService("DataStoreService"):GetDataStore("playerstat")
2local globalscoremapstats = game:GetService("DataStoreService"):GetDataStore("mapstats")
3local globalratings = game:GetService("DataStoreService"):GetOrderedDataStore("ratings")
4local songs = game:GetService("ReplicatedStorage").Songs
5local savetesting = true
6local overridestats = false
7--//players that can unlock epic secret songs (please add ur id now lol)
8local AdminPlayers = 36304080, 33607300, 45616186, 167327389,35585415,77833049,58107975
9
10--//players who are banned from the game
11local toxicPlayers = {
12 544802279, --Lord_Believe
13 328239043, --Main Acc of Lord_Believe
14}
15--//players who are shadowbanned
16local bannedPlayers = {
17 544802279, --Lord_Believe
18 328239043, --Main Acc of Lord_Believe
19}
20function calculateRating(rate, acc, diff)
21 local ratemult = 1
22 if rate then
23 if rate >= 1 then
24 ratemult = 1 + (rate-1) * 0.6
25 else
26 ratemult = 1 + (rate-1) * 2
27 end
28 end
29 print(rate, ratemult, acc, diff)
30 return ratemult * ((acc/97)^4) * diff
31end
32
33function checkifcheated(player, mapid, acc)
34 local map
35 if string.len(tostring(mapid)) == 2 then
36 mapid = "0"..mapid
37 end
38 if string.len(tostring(mapid)) == 1 then
39 mapid = "00"..mapid
40 end
41 for i, song in ipairs(songs:GetChildren()) do
42 local songid = string.sub(song.Name, 2, 4)
43 print(songid)
44 if tostring(mapid) == tostring(songid) then
45 map = song
46 break
47 end
48 end
49 local diff = map.SongDiff.Value
50 print(tonumber(string.sub(acc,1,5)))
51 print(diff)
52 local cheated = true
53 if tonumber(player.leaderstats["Skill Rating"].Value) > (tonumber(diff - 10)) then
54 cheated = false
55 end
56 if tonumber(string.sub(acc,1,5)*100) <= 10000 then
57 cheated = false
58 end
59 return cheated
60end
61
62--//1 is for the scores, 2 is for the ratings.
63local scriptstats = {}
64game.Players.PlayerAdded:connect(function(p)
65 local key = "plr_"..p.UserId
66 local playerstats
67 local i = 0
68 local savestats = true
69 local succ, err
70 local stats = Instance.new("IntValue")
71 stats.Name = "leaderstats"
72 stats.Parent = p
73
74 local skill = Instance.new("NumberValue")
75 skill.Name = "Skill Rating"
76 skill.Parent = stats
77
78 local rank = Instance.new("StringValue")
79 rank.Name = "Rank"
80 rank.Value = "#??"
81
82 local scores = Instance.new("StringValue")
83 scores.Name = "Scores"
84 scores.Parent = p
85 --find player stats
86 if savetesting == true then
87 repeat wait(1)
88 i = i + 1
89 succ, err = pcall(function()
90 playerstats = globalplayerstats:GetAsync(key)
91 end)
92 until succ or i > 5
93 --if unable to load, don't save stats
94 if not succ then
95 warn("Player stats "..p.Name.." failed to load, error "..err)
96 savestats = false
97 end
98 if succ then
99 table.insert(scriptstats, p.UserId, playerstats)
100 playerstats = scriptstats[p.UserId]
101 end
102 --create stats for each song played
103 for i, obj in pairs(songs:GetChildren()) do
104 local song = Instance.new("NumberValue", scores)
105 song.Name = "Map_"..i
106 local acc = Instance.new("NumberValue", song)
107 acc.Name = "Accuracy"
108 local score = Instance.new("NumberValue", song)
109 score.Name = "Score"
110 local scoredata = Instance.new("StringValue", song)
111 scoredata.Name = "ScoreData"
112 local rating = Instance.new("NumberValue", song)
113 rating.Name = "Rating"
114 local ratingdata = Instance.new("StringValue", song)
115 ratingdata.Name = "RatingData"
116 local spread = Instance.new("StringValue", song)
117 spread.Name = "Spread"
118 end
119 --if no stats were found, but loading did work, create empty stats for the player
120 if playerstats == nil and savestats == true or overridestats == true then
121 playerstats = {{}, {}, {97, 115, 100, 102, 1, true, true, true, true, true, true, 0, 0, 0, 70}}
122 for id, v in ipairs(songs:GetChildren()) do
123 local i = "Map_"..id
124 local songtable = {["Accuracy"] = 0, ["Score"] = 0, ["Rate"] = 0, ["Spread"] = "0x/0/0/0/0/0/0"}
125 scores[i].ScoreData.Value = "Acc: 0% | Rate: 1x"
126 scores[i].RatingData.Value = "Best Score: 0 | Rate: 1x"
127 scores[i].Score.Value = 0
128 scores[i].Accuracy.Value = 0
129 scores[i].Rating.Value = 0
130 scores[i].Spread.Value = "0x/0/0/0/0/0/0"
131 table.insert(playerstats[1], id, songtable)
132 table.insert(playerstats[2], id, songtable)
133 table.insert(scriptstats, p.UserId, playerstats)
134 playerstats = scriptstats[p.UserId]
135 end
136 repeat wait(1)
137 i = i + 1
138 succ, err = pcall(function()
139 globalplayerstats:SetAsync("plr_"..p.UserId, playerstats)
140 end)
141 until succ or i > 5
142 if err then
143 warn(err)
144 end
145 --if stats were found
146 else
147 if playerstats[1] and playerstats[2] then
148 for save = 1, 2 do
149 local mapstats = playerstats[save]
150 --if there are more songs than stats for songs(new songs being added)
151 if #mapstats < #songs:GetChildren() then
152 for id, obj in pairs(songs:GetChildren()) do
153 local key = string.sub(obj.Name, 2, 4)
154 if mapstats[key] == nil then
155 local songtable = {["Accuracy"] = 0, ["Score"] = 0, ["Rate"] = 0, ["Spread"] = "0x/0/0/0/0/0/0"}
156 table.insert(mapstats, key, songtable)
157 end
158 end
159 end
160 end
161 --for each stat for each map
162 for i, map in ipairs(songs:GetChildren()) do
163 local scoretable = playerstats[1][i]
164 local ratingtable = playerstats[2][i]
165 local mapscore = scores["Map_"..i]
166 --calculate rate multiplier
167 --if accuracy table exists, also to calculate rating
168 if ratingtable["Accuracy"] then
169 mapscore.Accuracy.Value = ratingtable["Accuracy"].."%"
170 mapscore.Rating.Value = calculateRating(ratingtable["Rate"], ratingtable["Accuracy"], map.SongDiff.Value)
171 else
172 warn("score table for accuracy for song "..i.." not found in player "..p.Name.."'s table")
173 mapscore.Accuracy.Value = 0
174 end
175 --if score table exists
176 if scoretable["Score"] then
177 mapscore.Score.Value = math.floor(scoretable["Score"]/100)
178 else
179 warn("score table for score for song "..i.." not found in player "..p.Name.."'s table")
180 mapscore.Score.Value = 0
181 end
182 mapscore.ScoreData.Value = "Acc: "..(scoretable["Accuracy"] or "0") .." | Rate: ".. (scoretable["Rate"] or "1.0")
183 mapscore.RatingData.Value = "Acc: ".. (ratingtable["Accuracy"] or "0") .. " | Rate: ".. (ratingtable["Rate"] or "1.0")
184 end
185 end
186 end
187 _G.CalculatePlayerRating(p)
188 end
189
190 --local ing = Instance.new("BoolValue")
191 --ing.Name = "InGame"
192 --ing.Value = false
193
194 spawn(function()
195 if savetesting == false then
196 for i, obj in ipairs(game:GetService("ReplicatedStorage").Songs:getChildren()) do
197 local s = Instance.new("StringValue", scores)
198 s.Name = "Map_"..i
199
200 local s2 = Instance.new("NumberValue", s)
201 s2.Name = "Score"
202
203 local s3 = Instance.new("IntValue", s)
204 s3.Name = "Accuracy"
205
206 local s4 = Instance.new("NumberValue", s)
207 s4.Name = "Rating"
208 s4.Value = 60
209
210 local s5 = Instance.new("StringValue", s)
211 s5.Name = "RatingData"
212 s5.Value = 60
213
214 local s6 = Instance.new("StringValue", s)
215 s6.Name = "ScoreData"
216 s6.Value = 60
217
218 local s7 = Instance.new("IntValue", s)
219 s7.Name = "Version"
220 s7.Value = 1
221 end
222 end
223 end)
224
225 skill.Parent = stats
226 rank.Parent = stats
227 --ing.Parent = stats
228end)
229
230game:GetService("ReplicatedStorage").SubmitScore.OnServerEvent:Connect(function(player, map, rate, score, acc, spread)
231 local playerstats = scriptstats[player.UserId]
232 if playerstats and savetesting then
233 local cheated = checkifcheated(player, map, acc)
234 print(score, playerstats[1][map]["Score"] < score, cheated)
235 if playerstats[1][map]["Score"] < score and savetesting == true and cheated == false then
236 playerstats[1][map]["Score"] = tonumber(score)
237 playerstats[1][map]["Rate"] = tonumber(string.sub(rate,1,string.len(rate)-1))
238 playerstats[1][map]["Accuracy"] = tonumber(string.sub(acc,1,5))
239 playerstats[1][map]["Spread"] = spread
240 player.Scores["Map_"..map].Rating.Value = calculateRating()
241 player.Scores["Map_"..map].Score.Value = math.floor(playerstats[1][map]["Score"]/100)
242 player.Scores["Map_"..map].Accuracy.Value = playerstats[1][map]["Accuracy"]
243 local banned = false
244 for i = 1, #bannedPlayers do
245 if bannedPlayers[i] == player.UserId then
246 banned = true
247 end
248 end
249 _G.UpdateLeaderboard(1, map, {["Rate"] = playerstats[1][map]["Rate"], ["Score"] = playerstats[1][map]["Score"], ["Accuracy"] = playerstats[1][map]["Accuracy"], ["Player"] = player.UserId}, banned)
250 end
251 end
252end)
253
254game:GetService("ReplicatedStorage").SubmitPP.OnServerEvent:Connect(function(player, map, rate, savedrating, acc, spread)
255 local playerstats = scriptstats[player.UserId]
256 if playerstats and savetesting then
257 local cheated = checkifcheated(player, map, acc)
258 print(cheated)
259 if playerstats[2][map]["Score"] < savedrating and savetesting == true and cheated == false then
260 local rating = string.sub(savedrating, 1, string.len(savedrating)-6)
261 print(rating)
262 playerstats[2][map]["Rate"] = tonumber(string.sub(rate,1,string.len(rate)-1))
263 playerstats[2][map]["Score"] = tonumber(savedrating)
264 playerstats[2][map]["Accuracy"] = tonumber(string.sub(acc,1,5))
265 playerstats[2][map]["Spread"] = tonumber(spread)
266 player.Scores["Map_"..map].Rating.Value = playerstats[2][map]["Rate"]
267 player.Scores["Map_"..map].Score.Value = math.floor(playerstats[2][map]["Score"]/100)
268 player.Scores["Map_"..map].Accuracy.Value = playerstats[2][map]["Accuracy"]
269 local banned = false
270 for i = 1, #bannedPlayers do
271 if bannedPlayers[i] == player.UserId then
272 banned = true
273 end
274 end
275 _G.UpdateLeaderboard(2, map, {["Rating"] = math.floor(tonumber(rating/10))/100, ["Score"] = savedrating, ["Rate"] = playerstats[2][map]["Rate"], ["Accuracy"] = playerstats[2][map]["Accuracy"], ["Player"] = player.UserId}, banned)
276 end
277 end
278end)
279
280game:GetService("ReplicatedStorage").SaveRating.OnServerEvent:Connect(function(player, rating, mapstats, rank, options)
281 local playerstats = scriptstats[player.UserId]
282 if playerstats and savetesting then
283 local succ, err
284 local key = "plr_"..player.UserId
285 local savestats = {playerstats[1], playerstats[2], options}
286 local i = 0
287 repeat wait(1) i, succ, err = i + 1, pcall(function()globalplayerstats:SetAsync(key, playerstats)end) until succ or i > 5
288 if not succ then
289 warn(err)
290 end
291 end
292end)
293
294
295game.Players.PlayerRemoving:Connect(function(player)
296 local playerstats = scriptstats[player.UserId]
297 if playerstats and savetesting then
298 local succ, err
299 local key = "plr_"..player.UserId
300 local i = 0
301 repeat wait(1) i, succ, err = i + 1, pcall(function()globalplayerstats:SetAsync(key, playerstats)end) until succ or i > 5
302 if not succ then
303 warn(err)
304 end
305 end
306end)
307
308
309repeat wait() until #game.Players:GetChildren() ~= 0
310if game.Players:GetChildren()[1].UserId == AdminPlayers then
311 local copy = game.ReplicatedStorage.AdminSongs:GetChildren()
312 for i=1, #copy do
313 copy[i]:Clone().Parent = game.ReplicatedStorage.Songs
314 end
315end