Jail DataStore Help

Is there a way to implement a saving system where, if the player exits the game while they are in jail, the timer for their prison time is saved, and when they return, they are automatically sent back to jail with the timer starting from where it left off?

local url = ""
local http = game:GetService("HttpService")
local playersService = game:GetService("Players")
local pvalue = script.Preso.Value

local allowedTeams = {
	["Police"] = true,
	["Staff"] = true
}

game.Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		local args = string.split(message, " ")
		if #args >= 4 and args[1] == "/arrest" then
			local team = player.Team
			local playerName = args[2]
			local reason = args[3]
			local time = tonumber(args[4])

			if allowedTeams[team.Name] then
				local targetPlayer = game.Players:FindFirstChild(playerName)
				if targetPlayer then
					local markPrison = workspace:FindFirstChild("MarkPreso")
					local markRelease = workspace:FindFirstChild("MarkSolto")
					local originalPosition = targetPlayer.Character and targetPlayer.Character:FindFirstChild("HumanoidRootPart") and targetPlayer.Character.HumanoidRootPart.CFrame
					local playerName = targetPlayer.Name
					local playerId = targetPlayer.UserId
					local playerThumbnail = "https://www.roblox.com/headshot-thumbnail/image?userId=" .. playerId .. "&width=420&height=420&format=png"
					local mapName = game.Name

					if markPrison and targetPlayer.Character then
						local humanoid = targetPlayer.Character:FindFirstChildOfClass("Humanoid")
						if humanoid then
							if not pvalue then
								local currentTime = os.time()
								local endTime = currentTime + time

								humanoid.WalkSpeed = 0
								humanoid.PlatformStand = false
								pvalue = true
								local data = {
									["embeds"] = {
										{
											["author"] = {
												["name"] = playerName,
												["icon_url"] = playerThumbnail
											},
											["title"] = "<a:Siren:1218377793369280552> - ARREST",
											["color"] = 16758784,
											["description"] = "**Time:** ".. time .. " seconds" .. "\n **Reason:** ".. reason .. "\n **Performed by:** " .. player.Name,
											["fields"] = {
												{
													["name"] = "Player ID:",
													["value"] = tostring(playerId),
													["inline"] = true
												},
												{
													["name"] = "Account Age:",
													["value"] = player.AccountAge,
													["inline"] = true
												},
												{
													["name"] = "Map:",
													["value"] = mapName,
													["inline"] = true
												}
											},
											["footer"] = {
												["text"] = "StarCity • © All rights reserved",
												["icon_url"] = "https://cdn.discordapp.com/attachments/1201030585964052643/1212452272488058900/starcitylogo.png?ex=65f1e32c&is=65df6e2c&hm=37fccdbdf9b00bbbf52aacd397e2518e4483f86c75d71f0eea9f8f8f46a97cf9&"
											}
										}
									}
								}
								local finalData = http:JSONEncode(data)
								http:PostAsync(url, finalData)
								targetPlayer.Character:SetPrimaryPartCFrame(markPrison.CFrame)
								game:GetService("ReplicatedStorage").Notify:FireClient(player, "Successfully arrested!")

								local guiPrison = targetPlayer.PlayerGui:FindFirstChild("GuiPreso")
								if guiPrison then
									guiPrison.Enabled = true
									guiPrison.Frame.Reason.Texto.Text = reason
									guiPrison.Frame.Who.Texto.Text = player.Name
									guiPrison.Parent.DisableScript.Enabled = true
									guiPrison.Parent.DisableScript.EnableScript.Enabled = false
									wait(0.1)
									while time > 0 do
										guiPrison.Frame.Time.Texto.Text = time .. " seconds"
										wait(1)
										time = time - 1
									end
								end

								local function checkPlayerStatus()
									local currentTime = os.time()
									if currentTime >= endTime then
										humanoid.WalkSpeed = 16
										humanoid.PlatformStand = false
										pvalue = false
										if guiPrison then
											guiPrison.Enabled = false
											guiPrison.Frame.Time.Texto.Text = "0 seconds"
											guiPrison.Parent.DisableScript.Enabled = false
											guiPrison.Parent.DisableScript.EnableScript.Enabled = true
										end

										if markRelease and originalPosition and not pvalue and not targetPlayer.Character:FindFirstChild("HasBeenTeleported") then
											targetPlayer.Character:SetPrimaryPartCFrame(markRelease.CFrame)
											targetPlayer.Character.HumanoidRootPart.CFrame = originalPosition
											targetPlayer.Character:FindFirstChild("HasBeenTeleported").Value = false
										end

										local guiNotifyPolice = player:FindFirstChild("NotifyPolice")
										if guiNotifyPolice then
											guiNotifyPolice.Enabled = true
											wait(5)
											guiNotifyPolice.Enabled = false
										end
									end
								end

								while true do
									wait(1)
									checkPlayerStatus()
								end
							else
								game:GetService("ReplicatedStorage").Notify:FireClient(player, "Player is already arrested.")
							end
						end
					else
						game:GetService("ReplicatedStorage").Notify:FireClient(player, "Prison teleporter not found.")
					end
				else
					game:GetService("ReplicatedStorage").Notify:FireClient(player, "Player not found.")
				end
			else
				game:GetService("ReplicatedStorage").Notify:FireClient(player, "You are not police or admin!")
			end
		end
	end)
end)


game.Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		local args = string.split(message, " ")
		if #args == 2 and args[1] == "/release" then
			local playerName = args[2]
			local targetPlayer = game.Players:FindFirstChild(playerName)
			if targetPlayer then
				local markRelease = workspace:FindFirstChild("MarkRelease")
				if markRelease then
					local team = player.Team
					if allowedTeams[team.Name] then
						if targetPlayer.Character then
							local humanoid = targetPlayer.Character:FindFirstChild("HumanoidRootPart")
							if humanoid and pvalue then
								humanoid.CFrame = markRelease.CFrame
								pvalue = false
								humanoid.WalkSpeed = 16
								humanoid.PlatformStand = false
								game:GetService("ReplicatedStorage").Notify:FireClient(player, "Successfully released!")
							else
								game:GetService("ReplicatedStorage").Notify:FireClient(player, "Player is not arrested.")
							end
						end
					else
						game:GetService("ReplicatedStorage").Notify:FireClient(player, "You are not police or admin!")
					end
				else
					game:GetService("ReplicatedStorage").Notify:FireClient(player, "Prison teleporter not found.")
				end
			else
				game:GetService("ReplicatedStorage").Notify:FireClient(player, "Player not found.")
			end
		end
	end)
end)

Try this:

local DataStoreService = game:GetService("DataStoreService")
local JailTimeStore = DataStoreService:GetDataStore("JailTimeStore")

-- Function to save jail time
local function saveJailTime(player, timeRemaining)
    local success, errorMessage = pcall(function()
        JailTimeStore:SetAsync(player.UserId, timeRemaining)
    end)
    if success then
        print("Jail time saved for " .. player.Name)
    else
        warn("Error saving jail time for " .. player.Name .. ": " .. errorMessage)
    end
end

-- Function to load jail time
local function loadJailTime(player)
    local success, timeRemaining = pcall(function()
        return JailTimeStore:GetAsync(player.UserId)
    end)
    if success and timeRemaining then
        return timeRemaining
    else
        warn("Error loading jail time for " .. player.Name)
        return nil -- No time found, or an error occurred
    end
end

-- Rest of your existing code...

-- When a player leaves the game, save their remaining jail time
game.Players.PlayerRemoving:Connect(function(player)
    if playerIsInJail(player) then -- You'll need to implement this check
        local timeRemaining = calculateTimeRemaining(player) -- You'll need to implement this calculation
        saveJailTime(player, timeRemaining)
    end
end)

-- When a player joins the game, check if they have remaining jail time
game.Players.PlayerAdded:Connect(function(player)
    local remainingTime = loadJailTime(player)
    if remainingTime and remainingTime > 0 then
        -- Send player back to jail with the remaining time
        sendPlayerToJail(player, remainingTime) -- You'll need to implement this function
    end
end)

-- Rest of your existing code...

-- Example implementation for playerIsInJail function
local function playerIsInJail(player)
    -- Check if the player is currently marked as in jail
    -- This could be a value in their Player object, for example
    return player:GetAttribute("IsInJail") == true
end

-- Example implementation for calculateTimeRemaining function
local function calculateTimeRemaining(player)
    -- Calculate the time remaining based on the player's jail end time attribute
    local endTime = player:GetAttribute("JailEndTime")
    if endTime then
        local currentTime = os.time()
        return endTime - currentTime
    end
    return 0
end

-- Example implementation for sendPlayerToJail function
local function sendPlayerToJail(player, remainingTime)
    -- Send the player to the jail location and set their jail time attributes
    local markPrison = workspace:FindFirstChild("MarkPreso")
    if markPrison and player.Character then
        player.Character:SetPrimaryPartCFrame(markPrison.CFrame)
        player:SetAttribute("IsInJail", true)
        player:SetAttribute("JailEndTime", os.time() + remainingTime)
        -- Additional code to handle the jail GUI and other jail-related logic
    end
end

-- Make sure to set up attributes when arresting a player
-- For example, when you arrest a player:
local function arrestPlayer(player, targetPlayer, time)
    -- Your existing arrest logic...
    targetPlayer:SetAttribute("IsInJail", true)
    targetPlayer:SetAttribute("JailEndTime", os.time() + time)
    -- Rest of your arrest logic...
end

-- Don't forget to reset attributes when releasing a player from jail
local function releasePlayerFromJail(player)
    player:SetAttribute("IsInJail", false)
    player:SetAttribute("JailEndTime", nil)
    -- Additional code to handle the release process
end

-- Rest of your existing code...

yes, first, save the remaining jail time too, along with everything else into the datastore as a custom name, like “JailData” ,then when player rejoins, check if the player has its UserID in that JailData, if he has, load everything up, and then update the jail time, if the current time is greater than or equal to the end time, you would also remove the player’s data from the DataStore.

you could try using something like

local jailDataStore = game:GetService("DataStoreService"):GetDataStore("JailData")
        jailDataStore:SetAsync(tostring(playerId), {CurrentTime = currentTime, EndTime = endTime})