Same old issue of others getting items when others open cases

I already made one thread about this and it worked when testing at the time but it is happening once again. Here is some of my code:
Module code for data:

local aloe = {};
--// SERVICES \\
local DataStoreService = game:GetService("DataStoreService")

--// DATA VARS \\
local sessionData = {};
local dataSet = DataStoreService:GetDataStore("AloeV.13")
local RapSet = DataStoreService:GetOrderedDataStore('AloeV.5_Rap')
local startData = {
	Values = {
		Bux = 250000,
		Tix = 0,
		XP = 0,
		Level = 0,
		Gems = 0,
		CasesOpen = 1,
		Progress = 0,
		Prestige = 1,
	},
	Arrays = {
		Inventory = {},
		Flags = {},
		Equipped = {};
	}
}
--// FUNCTIONS \\
local function recursiveCopy(dataTable)
	local tableCopy = {}
	for index, value in pairs(dataTable) do
		if type(value) == "table" then
			value = recursiveCopy(value)
		end
		tableCopy[index] = value
	end
	return tableCopy
end
aloe.post = function(player, body, title)
	game.ReplicatedStorage.Notification:FireClient(player, body, title)
end
aloe.Get = function(value1)
	return sessionData[value1];
end
local rewards = {};
aloe.AddReward = function(player, amount)
	rewards[player] += amount
end
aloe.GetReward = function(player)
	return rewards[player]
end

aloe.LockJackpotAndCrash = function()
	
end
aloe.FailSafeSave = function()
	local MainSavingPoint = coroutine.running()
	local MainPointsRunning = 0
	for k, v in ipairs(game.Players:GetPlayers()) do
		local MainSavingProcess = coroutine.wrap(function()
			aloe.Save(v) 
			MainPointsRunning -= 1 
			if MainPointsRunning == 0 then
				coroutine.resume(MainSavingPoint)
			end
		end)
		MainPointsRunning += 1
		MainSavingProcess(v)
	end
	if MainPointsRunning > 0 then
		coroutine.yield()
	end
end
aloe.RAPCalculate = function(value1)
	local inventory = sessionData[value1].Arrays.Inventory;
	if not inventory then return 0 end
	local rap = 0
	for i, v in pairs(inventory) do
		rap += v.Amount * v.Rap;
	end
	return rap;
end
aloe.StartServer = function(value1)
	if dataSet:GetAsync(value1.UserId) then
		sessionData[value1] = dataSet:GetAsync(value1.UserId)
	else
		sessionData[value1] = recursiveCopy(startData)
	end
	rewards[value1] = 0
end
aloe.Save = function(value1)
	task.spawn(function()
	dataSet:SetAsync(value1.UserId, sessionData[value1])
		RapSet:SetAsync(value1.Name .. ";" .. value1.UserId, aloe.RAPCalculate(value1))
	end)
end
aloe.GrabRap = function()
	local globalData = {};
	local page = RapSet:GetSortedAsync(false, 100);
	page = page:GetCurrentPage();

	for key, value in next, page do
		globalData[#globalData + 1] = {value.key, value.value};
	end

	return globalData;
end

aloe.Flag = function(player, FlagReason, FlagTitle)

end

aloe.GiveItem = function(player, item2, Amount)
	local item
	local inventory = sessionData[player].Arrays.Inventory;
	for i = 1, #inventory do
		local v = inventory[i]
		if v.ItemId == item2 then
			v.Amount += Amount
			return
		end
	end
	local items = require(script.Parent.Items)
	for i, v in pairs(items) do
		if v.ItemId == item2 then
			item = v
		end
	end
	item.Amount = Amount;
	inventory[#inventory + 1] = item;
end
aloe.CaseItem = function(player, item2, Amount)
	local item
	local inventory = sessionData[player].Arrays.Inventory;
	for i = 1, #inventory do
		local v = inventory[i]
		if v.ItemId == item2.ItemId then
			v.Amount += Amount
			return
		end
	end
	item2.Amount = Amount;
	inventory[#inventory + 1] = item2;
end
aloe.RemoveItem = function(player, itemId, amount)
	local inventory = sessionData[player].Arrays.Inventory;
	if not itemId then return end
	local buxToReturn = 0 -- This is only if selling and not jackpotting
	for i, v in pairs(inventory) do
		if v.ItemId == itemId then
			if v.Locked == true then
				buxToReturn = 0;
				break
			end
			if v.Amount - amount == 0 then
				buxToReturn = amount * v.Rap
				table.remove(inventory, i);
				break
			end
			if tonumber(v.Amount) > amount then
				v.Amount -= amount;
				buxToReturn = amount * v.Rap
				break
			end
		end
	end
	local x = sessionData[player].Values.Prestige
	if x == 1 then x = 1 else x = x * 5.75 end
	return buxToReturn * x
end
aloe.Prestige = function(player)
	local inventory = sessionData[player].Arrays.Inventory; -- BYPASSES LOCK
	local prestigeItemCount = 0
	for i, v in pairs(inventory) do
		if inventory[i].ItemId == 140469106 then
			prestigeItemCount += inventory[i].Amount
			break
		end
	end
	sessionData[player].Arrays.Inventory = {};
	aloe.GiveItem(player, 140469106, prestigeItemCount)
end
aloe.SellAll = function(player)
	local offset = 0;
	local inventory = sessionData[player].Arrays.Inventory;
	for index = 1, #inventory do
		local item = inventory[index - offset];

		if not item.Locked then
			if item and item.Amount > 1 then

				local averagePrice = aloe.RemoveItem(player, item.ItemId, item.Amount);

				if averagePrice then
					sessionData[player].Values.Bux = sessionData[player].Values.Bux + averagePrice;
				end
			else
				local averagePrice = aloe.RemoveItem(player, item.ItemId, item.Amount);
				if averagePrice then
					sessionData[player].Values.Bux  = sessionData[player].Values.Bux + averagePrice;
				end
			end
			offset = offset + 1;
		end
	end
end

aloe.FindSpecificInventoryItem = function(player, itemInLook)
	local inventory = sessionData[player].Arrays.Inventory;
	local found = false;
	for i = 1, #inventory do
		if inventory[i].ItemId == itemInLook then
			found = true
			break
		end
	end
	return found
end

aloe.JackpotItem = function(player, itemId, amount)
	local inventory = sessionData[player].Arrays.Inventory;
	local doesHaveItem = false
	if amount < 1 then 
		return false
	end
	for i, v in pairs(inventory) do
		if v.ItemId == itemId then
			if v.Locked == true then
				doesHaveItem = false;
				break
			end
			if v.Amount - amount == 0 then
				doesHaveItem = true;
				table.remove(inventory, i);
				break
			end
			if tonumber(v.Amount) > amount then
				v.Amount -= amount;
				doesHaveItem = true;
				break
			end
		end
	end
	return doesHaveItem;
end
return aloe;

Server Code for Open Case Remote:

game.ReplicatedStorage.Spin.OnServerEvent:Connect(function(player, case, amount, key)
	local playerData = Data.Get(player);
	amount = tonumber(amount) or 1	
	if case then
		local caseItems = require(script.CaseData)[case].Items;
		local casePrice = require(script.CaseData)[case].Price;
		local winner = caseItems[math.random(1,#caseItems)];
		local bux = playerData.Values.Bux
		local casesOpen = playerData.Values.CasesOpen;
		if bux >= casePrice and casesOpen >= amount then
			playerData.Values.Bux-=casePrice*amount;
			local secretChance = math.random(1, 1000000000)
			if secretChance == 1 then 
				winner = 10760425;
				game.ReplicatedStorage.Chat:FireAllClients(player.Name .. ' has unboxed a secret item! The Staff of Sparks! (0.000000001' .. '%)','SourceSansBold')
			end
			giveItem(player, winner, amount)
			openCase(player, winner, amount)
			playerData.Values.Progress += 1
		else
			Data.post(player, 'You are missing bux or cases required.','Case')
		end
	end
end)

Open case: [This just makes the case win gui appear with the right item for the client.]

function openCase(player, itemid, amount)
	for i = 1, #require(script.Items) do
		local item = require(script.Items)[i];
		if item.ItemId == itemid then
			game.ReplicatedStorage.Spin:FireClient(player, item, amount)
			break
		end
	end
end