So I have been debugging for almost an hour now and nothing seems to be going good for me and here is the problem
There was an unexpected error, Error: 104: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters.
and here is the full code
-- Stats Service
-- Username
-- November 18, 2020
local StatsService = {Client = {}}
local PlayerDataSample = {
Stats = {
Coins = 0;
Level = 1;
EXP = 0;
MaxEXP = 50;
Class = "Mage"; -- {Mage, Warrior, Tank}
Quests = 0;
MaxQuests = 5; -- maximum is 5
Rank = "Rookie";
DoubleSword = false;
Banned = false;
SpellPoints = 1;
PhysicalPoints = 1;
Stamina = 1;
};
SetUp = {
Helmet = "none";
Armor = "none";
Pants = "none";
Boots = "none";
Sword = "none";
DualSword = "none"
};
Equipment = {
Armors = {
Chestplates = {
};
Helmets = {
};
Pants = {
};
};
};
Tools = {
Potions = {
};
Weapons = {
["Wooden Sword"] = {
Path = game.ServerStorage.Items.Weapons.Warrior["Wooden Sword"];
Damage = 1;
ClassFor = "Warrior";
Type = "Sword";
Rarity = "Common";
ChanceToGet = 100;
Physical = 1;
Spell = 1;
Upgrades = 0;
MaxUpgrades = 15;
Debounce = false;
CanDamage = false;
IsTradeable = false;
}
};
};
Spells = {
--[[
["SPELL_NAME"] = {
Class = "Mage";
BaseDamage = 0;
LevelRequired = 0;
SellAmount = 0;
Rarity = "Common";
ChanceToGet = 0;
SellAmount = 0;
IsTradeable = false;
}
]]
};
Quests = {
-- for examples only
--[[
["QuestName"] = {
IsCompleted = false;
XPWorth = 0;
CoinsWorth = 0;
QuestDescription = "Kill 1 Thing";
ThingsDone = 1;
IsFromNPC = "nil"
}
]]
}
}
local BannedPlayers = {} -- FerbZides name is for testing to see if it actually works
function StatsService:Start()
-- Services
local HttpService = game:GetService("HttpService")
local ServerStorage = game:GetService("ServerStorage")
-- Data Module
local DataModule = self.Modules.Data
-- Direct Path to Objects
-- Forking it
-- functions
local function KickPlayer(Player)
local Data = DataModule.ForPlayer(Player)
local success, PlayerData = Data:Get("PlayerData", PlayerDataSample):Await()
if (success) then
print("Data was Successfully Retrieved!")
else
warn("Failed to Retrieve Data!")
end
spawn(function()
if BannedPlayers[tostring(Player.Name)] then
Player:Kick("You are permanently Banned from this game, you are not welcome.")
elseif PlayerData.Stats.Banned == true then
Player:Kick("You are permanently Banned from this game, you are not welcome.")
else
print(Player.Name.." is authorized for this game!")
end
end)
end
local function PlayerAdded(Player)
print("Loading Data for "..Player.Name)
local Data = DataModule.ForPlayer(Player)
local PlayerDataFolder = Instance.new("Folder", Player)
PlayerDataFolder.Name = "PlayerData"
local Stats = Instance.new("Folder", PlayerDataFolder)
Stats.Name = "PlayerStats"
local Quests = Instance.new("Folder", PlayerDataFolder)
Quests.Name = "Quests"
local success, PlayerData = Data:Get("PlayerData", PlayerDataSample):Await()
if (success) then
print("Data was Successfully Retrieved!")
else
warn("Failed to Retrieve Data!")
end
KickPlayer(Player)
for Name, Val in pairs(PlayerData.Stats) do
if type(Val) == "number" then
local Value = Instance.new("NumberValue")
Value.Name = Name
Value.Value = Val
Value.Parent = Stats
elseif type(Val) == "string" then
local Value = Instance.new("StringValue")
Value.Name = Name
Value.Value = Val
Value.Parent = Stats
elseif type(Val) == "boolean" then
local Value = Instance.new("BoolValue")
Value.Name = Name
Value.Value = Val
Value.Parent = Stats
end
end
-- Load Tools table, gonna refork this a bit so yeah
for _, Tools in pairs(PlayerData.Tools) do
-- Player Backpacks
local PlayerStarterGear = Player.StarterGear
local PlayerBackpack = Player.Backpack
-- loop all the table
-- {Weapons, Potions} the only things that can be used as tools
-- loop all the items inside it
for ToolName, ToolValue in pairs(Tools) do
local Tool = ToolValue.Path:Clone()
Tool.Parent = PlayerStarterGear
local ValuesFolder = Instance.new("Folder")
ValuesFolder.Name = "Values"
ValuesFolder.Parent = Tool
for ToolValueName, ToolsValue in pairs(ToolValue) do
if type(ToolsValue) == "number" then
local Value = Instance.new("NumberValue")
Value.Name = ToolValueName
Value.Value = ToolsValue
Value.Parent = ValuesFolder
elseif type(ToolsValue) == "string" then
local Value = Instance.new("StringValue")
Value.Name = ToolValueName
Value.Value = ToolsValue
Value.Parent = ValuesFolder
elseif type(ToolsValue) == "boolean" then
local Value = Instance.new("BoolValue")
Value.Name = ToolValueName
Value.Value = ToolsValue
Value.Parent = ValuesFolder
end
end
end
end
-- get quests
for Name, Values in pairs(PlayerData.Quests) do
local QuestFolder = Instance.new("Folder", Quests)
QuestFolder.Name = Name
for Name, Val in pairs(Values) do
if type(Val) == "number" then
local Value = Instance.new("NumberValue")
Value.Name = Name
Value.Value = Val
Value.Parent = QuestFolder
elseif type(Val) == "string" then
local Value = Instance.new("StringValue")
Value.Name = Name
Value.Value = Val
Value.Parent = QuestFolder
elseif type(Val) == "boolean" then
local Value = Instance.new("BoolValue")
Value.Name = Name
Value.Value = Val
Value.Parent = QuestFolder
end
end
end
-- get data characters of the player
local TableToString = HttpService:JSONEncode(PlayerData)
print(Player.Name.."'s Data Characters were "..string.len(TableToString))
print("Succesfully Got Data from "..Player.Name)
end
local function PlayerRemoved(Player)
local Backpack = Player.Backpack
local Data = DataModule.ForPlayer(Player)
local success, PlayerData = Data:Get("PlayerData", PlayerDataSample):Await()
if (success) then
print("Data was Successfully Retrieved!")
else
warn("Failed to Retrieve Data!")
end
Data:Save("PlayerData"):Then(function()
print(Player.Name.."'s Data was Saved!")
end):Catch(function(err)
warn("There was an unexpected error, Error: ",err)
end):Finally(function()
print("Data handling on "..Player.Name.." was Successful!")
end)
end
game.Players.PlayerAdded:Connect(PlayerAdded)
game.Players.PlayerRemoving:Connect(PlayerRemoved)
end
function StatsService:Init()
end
return StatsService
but this thing I am just thinking of how to serialize path’s!
so my question is how do you serialize this?
game.ServerStorage.Items.Weapons.Warrior["Wooden Sword"];