DataCore (Open-Sourced DataStore Module)

This is just a code dump.5

local DataModule = {
	
	DataKey = "Santa",
	Cryption = {
		EncryptData = function(t)
			local p = nil
			pcall(function()
				p = game:GetService("HttpService"):JSONEncode(t)
			end)
			return p
		end,
		DecryptData = function(t)
			local p = nil
			if type(t) == "table" then
				p = t
			else
				pcall(function()
					p = game:GetService("HttpService"):JSONDecode(t) or nil
				end)
			end
			
			return p
		end,
	},
	Get = function(self, Key)
		return self.Cryption.DecryptData(game:GetService("DataStoreService"):GetDataStore(self.DataKey):GetAsync(Key))
	end,
	Post = function(self, Key, Data)
		return  game:GetService("DataStoreService"):GetDataStore(self.DataKey):SetAsync(Key, self.Cryption.EncryptData(Data))
	end,
	
}


return setmetatable(DataModule, {
	__call = function(index)
		return rawget(DataModule, index)
	end,
	__metatable = "Locked.",
	__index = function(index)
		return rawget(DataModule, index)
	end,
	__newindex = function()
		return "Locked."
	end,
})

Example Code:

local DataCore = require(script.DataModule)

local PlayerData = {}

local function onPlayerJoin(Player)

local DefaultData = {

Cash = 300,

}

local Data = DataCore:Get(Player.UserId) or DefaultData -- Could check again or retry // just example //

     PlayerData[Player.UserId] = Data

end

local function onPlayerLeave(Player)

      local Data = PlayerData[Player.UserId]

      return DataCore:Post(Player.UserId, Data)

end
1 Like

Few comments.

JSONEncoding is not encrypting so that’s a weird method name to use and I would not encourage it if you end up having any real encryption present in your experience. Naming aside, both methods could also be improved in terms of variable naming (one letter is often unreadable and nondescriptive, except in special circumstances like for loops)

-- "Encrypt"Data function
function(tbl)
    local _, result = pcall(function ()
        -- It'd be better to declare HttpService at the top
        -- to prevent using GetService for it every method.
        return HttpService:JSONEncode(tbl)
    end)

    return result
end

-- "Decrypt"Data function
function(tbl)
    if type(tbl) == "table" then
        return tbl
    else
        local success, result = pcall(function ()
            return HttpService:JSONDecode(tbl)
        end)

        if success then
            return result
        end
    end

    return nil
end

That all being said: there’s a lack of variables for things that could be variables to reduce yourself all the writing time and the whole DataCore in itself isn’t too useful. There’s a practice problem it implicates and the most its doing is wrapping DataStore calls in functions to pseudoabstract some calls.

JSON encoding data for a DataStore is a dated practice that now mostly only has relevance for developers applying compression strategies that rely on JSON format; other developers not compressing should not use JSON, your data already gets serialised when its being written to the data service. JSON text can bloat your value size a bit.

That’s just my advice/recommendations/comments, though! My main point would probably be that in creating a data module you’ll probably want it to do more than just wrapping calls in a lambda.

5 Likes