Jump to content

How do you save client data on servers?


Recommended Posts

I have some component tables and variables that I'd like to store within client-specific save files. The server doesn't need to know about the data; it's just for the client. Is this possible? How would I go about inserting and retrieving the data? 

Link to comment
Share on other sites

@BluesyBuesy

Ah, you want to save persistent data.

TheSim:SetPersistentString(String:FilePath, String:Data, Boolean:ShouldCompressData, Function:CallbackOnSuccess)

And to retrieve the data..

TheSim:GetPersistentString(String:FilePath, Function:CallbackOnFailOrSuccess)

 

Example use:

TheSim:SetPersistentString(
    "mymodname_data",
    "My mod's information stored here as a string type.  Read up on serialization for objects like tables to store those here.",
    true, -- Save space on HD!
    function()
        GLOBAL.print("Data saved successfully!")
    end
)


TheSim:GetPersistentString(
    "mymodname_data",
    function(success, data)
        if(success)
        then
            GLOBAL.print("Data loaded!  Read up on deserialization for objects like tables to read those here.  Data:", data)
        else
            GLOBAL.print("Data failed to load.  Wrong file name, or data hasn't been saved yet!")
        end
    end
)

By default the functions save in the Klei/DST/client_save/ folder.

You should be able to escape out of it should you choose, as well as being able to go into the user's server session folder if you want to save data on a per-server basis.

 

To obtain the user's session string for a per-server basis you can use:

local FilePath = "session/"..(TheNet:GetSessionIdentifier() or "INVALID_SESSION").."/"..(TheNet:GetUserID() or "INVALID_USERID").."_/".."mymodname_data"

 

Link to comment
Share on other sites

11 minutes ago, CarlZalph said:

@BluesyBuesy

Ah, you want to save persistent data.

TheSim:SetPersistentString(String:FilePath, String:Data, Boolean:ShouldCompressData, Function:CallbackOnSuccess)

And to retrieve the data..

TheSim:GetPersistentString(String:FilePath, Function:CallbackOnFailOrSuccess)

 

Example use:


TheSim:SetPersistentString(
    "mymodname_data",
    "My mod's information stored here as a string type.  Read up on serialization for objects like tables to store those here.",
    true, -- Save space on HD!
    function()
        GLOBAL.print("Data saved successfully!")
    end
)


TheSim:GetPersistentString(
    "mymodname_data",
    function(success, data)
        if(success)
        then
            GLOBAL.print("Data loaded!  Read up on deserialization for objects like tables to read those here.  Data:", data)
        else
            GLOBAL.print("Data failed to load.  Wrong file name, or data hasn't been saved yet!")
        end
    end
)

By default the functions save in the Klei/DST/client_save/ folder.

You should be able to escape out of it should you choose, as well as being able to go into the user's server session folder if you want to save data on a per-server basis.

 

To obtain the user's session string for a per-server basis you can use:


local FilePath = "session/"..(TheNet:GetSessionIdentifier() or "INVALID_SESSION").."/"..(TheNet:GetUserID() or "INVALID_USERID").."_/".."mymodname_data"

 

Interesting... I'll sink my teeth into this and report back if I have any more questions. Thank you very much!

Link to comment
Share on other sites

This may be a bit easier than I was thinking it'd be. It turns out that my data is being saved even as a client, I just didn't realize because the load function isn't working for some reason. 

This is what it looks like in the session save file:

data={MyComponentName={_MyTable={"stuff1", "stuff2",},

Here is what my save and load function were originally:

 

function self:OnSave()   
	local data =
	{
		_MyTable = self.MyTable,
	}
	return data
end

function self:OnLoad(data) 
	if --everything exists and isn't nil-- then
		self.MyTable = data._MyTable
	else 
		self:doStuff
	end
end

 

The above worked for hosts, but just to test as a client, I changed it to this:

 

function self:OnLoad(data) 
	if --everything exists and isn't nil-- then
		self.MyTable = data.MyComponentName._MyTable
	else 
		self:doStuff
	end
end

 

It still will not load the data as a client. Any ideas?

edit: actually, I don't think it's passing through OnSave or OnLoad at all because my test prints aren't showing up in the client log. I think what's happening is that SerializeUserSession(ThePlayer) is just saving my component's data by happenstance because I attached the component to ThePlayer... 

If that's the case, I just need to figure out how to get that data back. *scratches head*

edit 2:

okay so actually the OnSave function is being called, but the OnLoad isn't. I'm confused why that'd be the case.

Edited by BluesyBuesy
Link to comment
Share on other sites

"How do you save client data on servers?"

"The server doesn't need to know about the data; it's just for the client."

You want to store data for each client, on each client's computer, or store data for each client, on the server?

Link to comment
Share on other sites

4 hours ago, DarkXero said:

"How do you save client data on servers?"

"The server doesn't need to know about the data; it's just for the client."

You want to store data for each client, on each client's computer, or store data for each client, on the server?

Whichever way works, it just has to be specific to each server. As long as the client can log back into the server and get the data back, then that'll work. 

Link to comment
Share on other sites

3 hours ago, BluesyBuesy said:

Whichever way works, it just has to be specific to each server. As long as the client can log back into the server and get the data back, then that'll work. 

If you have a component and use the onsave/onload functions, it will save that data for each client. Like how health stores the CURRENT health the player has when they log out, and when they log in, if its the same server, the data is loaded and you start with that amount of health. I think you're either not explaining yourself well, or you're over thinking it.

Link to comment
Share on other sites

49 minutes ago, Aquaterion said:

If you have a component and use the onsave/onload functions, it will save that data for each client. Like how health stores the CURRENT health the player has when they log out, and when they log in, if its the same server, the data is loaded and you start with that amount of health. I think you're either not explaining yourself well, or you're over thinking it.

That'd be brilliant if that'd work, but my OnLoad function isn't even being called when I'm a client. This is what I have:

function self:OnSave()   
	print('yyyyyyyy')
	local data =
	{
		_stuff = self.stuff,
	}
	return data
end

function self:OnLoad(data) 
	print('xxxxxxxxx')
	self.stuff = data._stuff
end

When I log out or when the world saves, I see 'yyyyyy' in the log and the data is being saved in the session file. 

When I log in, I do not see 'xxxxx' in the log, and the data is not being loaded.

What am I doing wrong? 

Link to comment
Share on other sites

18 minutes ago, BluesyBuesy said:

That'd be brilliant if that'd work, but my OnLoad function isn't even being called when I'm a client. This is what I have:


function self:OnSave()   
	print('yyyyyyyy')
	local data =
	{
		_stuff = self.stuff,
	}
	return data
end

function self:OnLoad(data) 
	print('xxxxxxxxx')
	self.stuff = data._stuff
end

When I log out or when the world saves, I see 'yyyyyy' in the log and the data is being saved in the session file. 

When I log in, I do not see 'xxxxx' in the log, and the data is not being loaded.

What am I doing wrong? 

did you check both server log and client log? because since its stored on the server, i think it would be loaded on the server, not the client

Link to comment
Share on other sites

17 minutes ago, Aquaterion said:

did you check both server log and client log? because since its stored on the server, i think it would be loaded on the server, not the client

I don't know whether or not it's being stored on the server. I don't have access to the server files. I'm just logging in and out of some random server. The data is being saved in my client session save files. I checked the server log just in case, but there's neither 'yyyy' or 'xxxx' there. 

Just to be clear, this works fine when I'm the host. I'm just running into issues specifically when I'm a client. 

Link to comment
Share on other sites

18 minutes ago, Aquaterion said:

When you say you enter a random server, that server has your mod right?

No. The data I'm trying to load is only for the client. Nobody else will see or care about the data. It doesn't mess with server data like, say, current health. 

Is it the case that I need a server to validate something even though it's client data, and the data is stored in the client's own files?

edit: if so, is there any workaround?

Edited by BluesyBuesy
Link to comment
Share on other sites

I made use of Carl's methods to save a persistent string.

All you need to do is populate the myinfo table of the bluesyinfo component.

The game will encode the table into a string, then save it.

Then when your character is loaded (spawned into the game, triggering the player post inits), the component will get initialized and will search for that persistent string.

Then it will decode it and attach it as the myinfo table.

SaveTest.zip

  • Health 1
Link to comment
Share on other sites

7 hours ago, DarkXero said:

I made use of Carl's methods to save a persistent string.

All you need to do is populate the myinfo table of the bluesyinfo component.

The game will encode the table into a string, then save it.

Then when your character is loaded (spawned into the game, triggering the player post inits), the component will get initialized and will search for that persistent string.

Then it will decode it and attach it as the myinfo table.

SaveTest.zip

It works! I can save and load multiple tables as a client on random servers. Now I just need to reconfigure my mod to accommodate the change and it'll pretty much be finished. 

Thanks for laying it out for me @DarkXero

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...