Hi Developers! ![]()
So, I have a weapon system that manages all weapon transactions and etc. Everything works fine but the player variable, for some reason when some functions are being fired they apply to every single player in the server!
The client side runs without any issues, not a single error shows up in console, everything works as intended in singleplayer session. All the functions like GetWeapon(), AddToEquipped and etc. mess up with the players and fire to all clients, even if there’s no :FireAllClients() in the entire game…
I’d appreciate any help provided
! If you need more info, please let know!
Here's the server script in ServerScriptService named 'Data'
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local DatastoreService = game:GetService("DataStoreService")
local MarketPlaceService = game:GetService("MarketplaceService")
local rs = game:GetService("ReplicatedStorage")
local Data = DatastoreService:GetDataStore("1")
local sessionData = {}
--weapons data
local WeaponData = DatastoreService:GetDataStore("WeaponData")
local WeaponSessionData = {}
function PlayerAdded(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local Kills = Instance.new("NumberValue")
Kills.Name = "Kills"
--Kills.Parent = player
Kills.Parent = leaderstats
local CC = Instance.new("IntValue")
CC.Name = "CC"
CC.Parent = player
local success, playerData = pcall(function()
return Data:GetAsync(player.UserId)
end)
if success then
if not playerData then
playerData = {
["Kills"] = 0,
["CC"] = 0,
}
end
sessionData[player.UserId] = playerData
else
warn("Couldn't load data: " .. player.Name)
player:Kick("Couldn't load your data, rejoin please!")
end
if CC.Value == nil then CC.Value = 0 end
Kills.Value = sessionData[player.UserId].Kills
Kills:GetPropertyChangedSignal("Value"):Connect(function()
sessionData[player.UserId].Kills = Kills.Value
end)
CC.Value = sessionData[player.UserId].CC
CC:GetPropertyChangedSignal("Value"):Connect(function()
sessionData[player.UserId].CC = CC.Value
end)
--=================================================================================================================================================
--============================================================WEAPON DATA AND PROCESSES============================================================
--=================================================================================================================================================
--unlocked weapons (the data table structure for weapons)
local weaponTable = {
OwnedWeapons = {
["G36"] = true,
["Five-Seven"] = true
},
EquippedWeapons = {
Primary = "G36",
Secondary = "Five-Seven",
Melee = nil
},
}
local InitialweaponTable = {
OwnedWeapons = {
["G36"] = true,
["Five-Seven"] = true
},
EquippedWeapons = {
Primary = "G36",
Secondary = "Five-Seven",
Melee = nil
},
}
local success, playerWpnsData = pcall(function()
return WeaponData:GetAsync(player.UserId)
end)
if success then
if not playerWpnsData then playerWpnsData = weaponTable end
WeaponSessionData[player.UserId] = playerWpnsData
else
warn("Couldn't load data: " .. player.Name)
player:Kick("Couldn't load your weapon data, rejoin please!")
end
-- Ensure weaponTable is initialized as a table
if not WeaponSessionData[player.UserId] then
WeaponSessionData[player.UserId] = weaponTable
else
weaponTable = WeaponSessionData[player.UserId]
end
if weaponTable ~= InitialweaponTable then
weaponTable = InitialweaponTable
print("yes", weaponTable, InitialweaponTable)
WeaponSessionData[player.UserId] = InitialweaponTable
end
CC.Value = 1000000
print("That's the data of", player, weaponTable)
------prices------
local weaponPrices = {
--historical
["G36"] = {
name = "G36",
price = 0,
class = "Primary",
},
["Five-Seven"] = {
name = "Five-Seven",
price = 0,
class = "Secondary",
},
["Glock 17"] = {
name = "Glock 17",
price = 9000,
class = "Secondary",
},
["SKS"] = {
name = "SKS",
price = 3300,
class = "Primary",
},
["Remington 870"] = {
name = "Remington 870",
price = 7200,
class = "Primary",
},
["M61 Vulcan"] = {
name = "M61 Vulcan",
price = 0,
class = "Primary"
},
["Handship"] = {
name = "Handship",
price = 0,
class = "Primary"
},
--unnatural
["Fire"] = {
name = "Fire",
price = 1800,
class = "Secondary",
},
["Magic Stick"] = {
name = "Magic Stick",
price = 3000,
class = "Primary",
},
}
------------------
local function GetWeapon(weapon)
warn(weaponTable)
warn(weapon)
warn(weaponTable.OwnedWeapons)
for i, v in pairs(weaponTable.OwnedWeapons) do
if i == weapon then
print("Already have that weapon", weapon)
return true
else
local unlockedStatus = true
weaponTable.OwnedWeapons[weapon] = unlockedStatus
WeaponSessionData[player.UserId] = weaponTable
print("check this, inserted ", weapon, " to ", player, ". Status:", unlockedStatus)
end
end
end
local function AddWeapon(player, WeaponName: string, WeaponFolder: string)
if WeaponName == nil then return end
local Weapon = nil
for i, folder in pairs(rs.WeaponStorage:GetChildren()) do
local find = folder[WeaponFolder]:FindFirstChild(WeaponName)
if find ~= nil then
Weapon = find
print("Found weapon", Weapon, WeaponName, "in", WeaponFolder)
else
print("Didn't find any weapon in", WeaponFolder,"!")
end
end
if Weapon then
local existingWeapon = player.Backpack:FindFirstChild(WeaponName)
if existingWeapon then
existingWeapon:Destroy()
else
--rs.WeaponNotification:FireClient(player, WeaponName)
end
local NewWeapon = Weapon:Clone()
NewWeapon.Parent = player.Backpack
print("added", Weapon, "to", player,"'s backpack!")
end
end
local function AddToEquipped(weaponName: string, weaponClass: string)
if weaponClass then
weaponTable["EquippedWeapons"][weaponClass] = weaponName
print("saved to equipped:", weaponName, weaponClass)
WeaponSessionData[player.UserId] = weaponTable
end
end
local function EquipWeapons(player, primary, secondary, melee)
AddWeapon(player, primary, "Primary")
task.wait(0.1)
AddWeapon(player, secondary, "Secondary")
task.wait(0.1)
AddWeapon(player, melee, "Melee")
end
local updateEvent = rs.WeaponSystemEvents:WaitForChild("UpdateWeapon")
local warning = rs.WeaponSystemEvents:WaitForChild("NotEnough")
local function OnBuyEvent(wpn)
warn(wpn, weaponPrices, weaponPrices[wpn]["price"])
local price = weaponPrices[wpn]["price"]
print("the price is", price, "weapon:", wpn, wpn.ClassName)
if price and price ~= nil then
if CC.Value >= price then
CC.Value -= price
GetWeapon(wpn)
updateEvent:FireClient(player, wpn)
else
local needed = price - CC.Value
warning:FireClient(player, needed)
end
end
end
--[[for _, weaponName in pairs(weaponTable) do
local weaponInfo = weaponPrices[weaponName]
if weaponInfo then
AddWeapon(weaponInfo.name, weaponInfo.class, weaponInfo.price)
end
end]]
--=====================Equipping and deploying==========================
local equipEvent = rs.WeaponSystemEvents:WaitForChild("Equip")
equipEvent.OnServerEvent:Connect(function(player, wpn)
warn("fired!", wpn)
for key, info in pairs(weaponPrices) do
if wpn == info.name then
AddToEquipped(wpn, info.class)
print("equipped", wpn, "and inserted to", weaponTable.EquippedWeapons)
else
warn("no such a weapon!")
end
end
end)
local deployEvent = rs.WeaponSystemEvents:WaitForChild("PlayPressed")
deployEvent.OnServerEvent:Connect(function(player)
local primary = weaponTable.EquippedWeapons.Primary
local secondary = weaponTable.EquippedWeapons.Secondary
local melee = weaponTable.EquippedWeapons.Melee
warn("WEAPONS:", primary, secondary, melee)
EquipWeapons(player, primary, secondary, melee)
print("deployed!", player, primary, secondary, melee)
end)
--===========buying new weapons=======================
local buyevent = rs.WeaponSystemEvents.Buy
buyevent.OnServerEvent:Connect(function(plr, weapon) print(weapon, plr) OnBuyEvent(weapon) end)
--=======Alert about a new weapon when round has ended=================
--=========Firing an event to show already equipped weapons============
rs.WeaponSystemEvents.GetEquipped:FireClient(player, weaponTable.EquippedWeapons)
print("fired equipped thing on join, you understand what I mean", weaponTable.EquippedWeapons)
--=========Give "Unlocked" status and price to client==================
local giveunlockedEvent = rs.WeaponSystemEvents:WaitForChild("GetUnlockStatus")
local givepriceEvent = rs.WeaponSystemEvents:WaitForChild("GetPrice")
--"unlocked"
giveunlockedEvent.OnServerInvoke = function(player, weaponName)
for key, wpnData in pairs(weaponTable.OwnedWeapons) do
warn(key)
if weaponName == key then
if wpnData then
print("success, sent", key, wpnData, "to", player)
return wpnData
end
end
end
end
--price
givepriceEvent.OnServerInvoke = function(player, weaponName)
for i, priceData in pairs(weaponPrices) do
if weaponName == priceData.name then
print("success, sent prices(", priceData.price, ") to", player)
return priceData.price
end
end
end
local VulcanGamepassID = 169225577
local HandshipGamepassID = 1004204303
if MarketPlaceService:UserOwnsGamePassAsync(player.UserId, VulcanGamepassID) then
GetWeapon("M61 Vulcan")
end
if MarketPlaceService:UserOwnsGamePassAsync(player.UserId, HandshipGamepassID) then
GetWeapon("Handship")
end
end
Players.PlayerAdded:Connect(PlayerAdded)
function PlayerLeaving(player)
if sessionData[player.UserId] then
local success, errorMsg = pcall(function()
Data:SetAsync(player.UserId, sessionData[player.UserId])
end)
if success then
else
-- If data saving fails, print a warning
warn("Can't save: " .. player.Name, "|", errorMsg)
end
end
if WeaponSessionData[player.UserId] then
local success, errorMsg = pcall(function()
WeaponData:SetAsync(player.UserId, WeaponSessionData[player.UserId])
end)
if success then
else
-- If data saving fails, print a warning
warn("Can't save weapons: " .. player.Name, "|", errorMsg, WeaponSessionData[player.UserId])
end
end
end
Players.PlayerRemoving:Connect(PlayerLeaving)
function ServerShutdown()
if RunService:IsStudio() then
return
end
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(function()
PlayerLeaving(player)
end)
end
end
game:BindToClose(ServerShutdown)