This rating system I made uses messaging service to send the votes from one server to another, so that all the servers have the same rating data.
I was wondering if there was a better way to approach doing this?
--> Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local MessagingService = game:GetService("MessagingService")
--> Table
local Ratings = {}
--> Data Store
local DataStore = DataStoreService:GetDataStore("Car_Ratingssssss", "Ratingsssssss")
--> Load Ratings
local Succ, Data = pcall(function()
return DataStore:GetAsync("Rating_Cars")
end)
if Data ~= nil then
Ratings = Data
end
--> Modules
local Math = require(ReplicatedStorage:WaitForChild("MathAddons"))
--> Remotes
local Remotes = ReplicatedStorage:WaitForChild("Remotes")
local GetRating = Remotes:WaitForChild("GetRating")
local Rate = Remotes:WaitForChild("Rate")
local Notify = Remotes:WaitForChild("Notify")
--> Topic
local Topic = "CarRate"
--> Message Recieved
MessagingService:SubscribeAsync(Topic, function(msg)
local Str = tostring(msg.Data)
local Splitted = string.split(Str, "/")
local car = Splitted[1]
local avg = Splitted[2]
table.remove(Splitted, 1)
table.remove(Splitted, 2)
local RatingsTbl = {}
for _, v in pairs(Splitted) do
local UserId, Rate = unpack(string.split(v, "|"))
RatingsTbl[tostring(UserId)] = Rate
end
if Ratings[car] ~= nil then
for UID, Val in pairs(RatingsTbl) do
Ratings[car].Ratings[tostring(UID)] = Val
end
local NumTbl = {}
for _, v in pairs(Ratings[car].Ratings) do
table.insert(NumTbl, v)
end
Ratings[car].Average = math.clamp(Math.avg(NumTbl), 1, 5)
Ratings[car].Average = math.floor(Ratings[car].Average * 10) / 10
else
Ratings[car] = {
Ratings = RatingsTbl,
Average = 0
}
Ratings[car].Average = math.clamp(Math.avg(Ratings[car].Ratings), 1, 5)
Ratings[car].Average = math.floor(Ratings[car].Average * 10) / 10
end
end)
GetRating.OnServerInvoke = function(player, CarName)
if Ratings[CarName] == nil then return 0 end
return Ratings[CarName].Average
end
Rate.OnServerEvent:Connect(function(player: Player, Car, Rating)
if Rating <= 0 then return end
if Rating > 5 then return end
local UserId = player.UserId
if not workspace:WaitForChild("Cars"):FindFirstChild(Car) then
Notify:FireClient(player, "Cannot vote for a non-existant car!", Color3.fromRGB(255, 97, 97), 3)
end
if Ratings[Car] ~= nil then
if Ratings[Car].Ratings[tostring(UserId)] ~= nil then
Ratings[Car].Ratings[tostring(UserId)] = Rating
else
Ratings[Car].Ratings[tostring(UserId)] = Rating
end
local NumTbl = {}
for _, v in pairs(Ratings[Car].Ratings) do
table.insert(NumTbl, v)
end
Ratings[Car].Average = math.clamp(Math.avg(NumTbl), 1, 5)
Ratings[Car].Average = math.floor(Ratings[Car].Average * 10) / 10
elseif Ratings[Car] == nil then
Ratings[Car] = {
Ratings = {
[tostring(UserId)] = Rating
},
Average = Rating
}
end
Notify:FireClient(player, tostring("You Voted " .. tostring(Rating) .. " Star(s) On The " .. Car .. "!"), Color3.fromRGB(85, 170, 127), 3)
end)
Players.PlayerRemoving:Connect(function()
DataStore:SetAsync("Rating_Cars", Ratings)
end)
game:BindToClose(function()
DataStore:SetAsync("Rating_Cars", Ratings)
end)
while task.wait(30) do
for Car, Values in pairs(Ratings) do
local RatingsTbl = Values.Ratings
local Avg = Values.Average
local str = tostring(Car .. "/" .. tostring(Avg))
for UserId, Val in pairs(RatingsTbl) do
str = tostring(str .. "/" .. tostring(UserId) .. "|" .. tostring(Val))
end
MessagingService:PublishAsync(Topic, str)
end
end