Go Back   Steam Users' Forums > Steam Tool Discussions > Source Coding

Reply
 
Thread Tools Display Modes
Old 12-06-2009, 03:14 AM   #1
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
Lightbulb Filesystem question

Ok, so i got filesystem working. And i want to save player current health and stuff like that. But i need that files would be by saved by steamid. So heres the thing how can i get client steam id? If ill get that i believe ill manage to make them load too.
ks_ratchet is offline  
Reply With Quote
Old 12-06-2009, 04:49 AM   #2
z33ky
 
Join Date: May 2008
Reputation: 169
Posts: 5,361
Code:
CSteamID ID;
ToBaseMultiplayerPlayer( pPlayer )->GetSteamID( &ID );
z33ky is offline   Reply With Quote
Old 12-06-2009, 05:40 AM   #3
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
thanks this will be useful.
when ill find a way how to fix everyone using same hunger/thirst instead of their own
ks_ratchet is offline   Reply With Quote
Old 12-06-2009, 05:49 AM   #4
z33ky
 
Join Date: May 2008
Reputation: 169
Posts: 5,361
My first guess would be that you've made the member-variable static.
z33ky is offline   Reply With Quote
Old 12-06-2009, 05:58 AM   #5
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
I'd say its because its in server.
Though not sure what you mean by static.
ks_ratchet is offline   Reply With Quote
Old 12-11-2009, 10:05 AM   #6
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
Exclamation

Ok i think ill just revive the thread since its basicly same thing.

Ok heres what i got. I've added system that woud allow player to save steamid and some of his data.

Heres that code:
Code:
FileHandle_t fh;
//const char *filename = "data/save.log";
fh = filesystem->Open( data/save.log, "w+", "MOD");
const CSteamID *pClientID = engine->GetClientSteamID( edict() );
int ID;
ID = &IVEngineServer::GetPlayerUserId(edict());
if (fh)
{
	filesystem->FPrintf(fh, "%i		%i\n", engine->GetClientSteamID( pPlayer->edict() ), pPlayer->Hunger);
   // filesystem->Seek(fh, GetSteamID(pClientID), FILESYSTEM_SEEK_CURRENT);
	filesystem->Close(fh);
}
Everything in it seems fine, but either i need way to save file as steamid_stuff.log (so i could rewrite everytime instead of appending it) or make it seek for it in file and then replace variable next to it. But neither of way works.

Then i tried this
Code:
bool CHL2MP_Player::GetSteamID( CSteamID *pID )
{
	const CSteamID *pClientID = engine->GetClientSteamID( edict() );
	if ( pClientID )
	{
		return true;
	}

	return false;
}
with
Code:
DevMsg("%i", &CHL2MP_Player::GetSteamID);
When code is being displayed as integer it has good enough number, but when bool it's 0.

I've tried other various ways but neither of them helped

Then i thouth screw it i'll add sql database. Everything was ok. I've managed to implent it. Managed to fix object errors(like 14 of them), but diffrent thing happened in game. Everytime i tried to use any of the sql commands like creating database/adding stuff to database or even trying to see how many databases are created it just crashed. Tried to debug but nothing good appeared so deleted sql.

Any other ways to do this?
ks_ratchet is offline   Reply With Quote
Old 12-11-2009, 11:12 AM   #7
Biohazard_90
 
 
 
Join Date: Jun 2008
Reputation: 351
Posts: 1,811
I think you should either use the KeyValue class (with SaveToFile()/ LoadFromFile()) and maybe use the steamid as a part of each subkey (that way you've got everything organized) or you could use CUtlBuffer and filesystem->ReadFile()/ filesystem->WriteFile().

The former method would be extremely easy to modify outside of the game, and for the latter one you could add some simple protection, in case you actually want to anyway.

Quote:
Originally Posted by ks_ratchet View Post
Code:
bool CHL2MP_Player::GetSteamID( CSteamID *pID )
{
	const CSteamID *pClientID = engine->GetClientSteamID( edict() );
	if ( pClientID )
	{
		return true;
	}

	return false;
}
with
Code:
DevMsg("%i", &CHL2MP_Player::GetSteamID);
When code is being displayed as integer it has good enough number, but when bool it's 0.
That's because you're using a function pointer here and not return a value.
Also, inside that function, you're not modifiyng pID, so it's kinda useless I guess?.
Biohazard_90 is offline   Reply With Quote
Old 12-11-2009, 11:04 PM   #8
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
Oh yeh keyvalues. Something simila to sourcemod addon which im already familiar with. And since i've used it already it shouldnt be hard here too. I'll post later if ill still have problems.
ks_ratchet is offline   Reply With Quote
Old 12-12-2009, 01:16 AM   #9
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
Ok got it to load just the way i want it to problem is saving it. Not realy sure how to do it. It just breaks my file.

Code:
	KeyValues *pkv = new KeyValues( "SAVES" );
	Assert( pkv );
	pkv->SaveToFile( g_pFullFileSystem, "data/saves.txt", "MOD" );
	if(pkv->FindKey( "Hunger", false ))
	{
		pkv->SetInt(UTIL_VarArgs("%i %i", engine->GetClientSteamID( pPlayer->edict() )), Hunger);
	}
	else
		DevWarning(1, "Cannot find 'Hunger'\n");
	pkv->deleteThis();
ks_ratchet is offline   Reply With Quote
Old 12-12-2009, 01:43 AM   #10
Biohazard_90
 
 
 
Join Date: Jun 2008
Reputation: 351
Posts: 1,811
Quote:
Originally Posted by ks_ratchet View Post
Ok got it to load just the way i want it to problem is saving it. Not realy sure how to do it. It just breaks my file.

Code:
	KeyValues *pkv = new KeyValues( "SAVES" );
	Assert( pkv );
	pkv->SaveToFile( g_pFullFileSystem, "data/saves.txt", "MOD" );
	if(pkv->FindKey( "Hunger", false ))
	{
		pkv->SetInt(UTIL_VarArgs("%i %i", engine->GetClientSteamID( pPlayer->edict() )), Hunger);
	}
	else
		DevWarning(1, "Cannot find 'Hunger'\n");
	pkv->deleteThis();
This is what you're doing right now:
  • You create a new keyvalue object
  • You save the empty object to a file
  • You try to read something from the empty object

Instead of FindKey, add a subkey and call SaveToFile at the very end before deleting it; I think it would be much more efficient btw if you'd use the steamid or a part of it as the subkey name and then put all info into there (hunger, health, whatever you need).

Also, you might need to pass the absolute path, though I might be wrong, in case that's correct though build the path with engine->GetGameDirectory() or engine->GetGameDir() (former for client, latter for server).
Biohazard_90 is offline   Reply With Quote
Old 12-12-2009, 02:42 AM   #11
z33ky
 
Join Date: May 2008
Reputation: 169
Posts: 5,361
Quote:
Originally Posted by Biohazard_90 View Post
Instead of FindKey, add a subkey
You can do both in one step:
Code:
pSubKey->SetInt( "Hunger", Hunger );
pSubKey would be the subkey for the steamid.

But it might be more efficient to create a new file for each steamid. It would take longer when a new client joins in, but at least you don't have to buffer the whole file when it gets big.
And you can let the server-maintainer delete old files when he likes to.

Last edited by z33ky: 12-12-2009 at 02:53 AM.
z33ky is offline   Reply With Quote
Old 12-12-2009, 02:46 AM   #12
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
Thanks z33ky but i've already finished it. I'll look into optimizing later though.
Thank you biohazard for helping me your tips solved everything.

Code:
	KeyValues *pkv = new KeyValues( "SAVES" );
	KeyValues *sub = new KeyValues( "Hunger" );
	if(!pkv->FindKey( "Hunger", false))
		pkv->AddSubKey( sub );

	sub->SetInt(UTIL_VarArgs("%i", engine->GetClientSteamID( pPlayer->edict() )), Hunger);
	
	pkv->SaveToFile( g_pFullFileSystem, "data/saves.txt", "MOD" );
	pkv->deleteThis();
Does everything perfectly
ks_ratchet is offline   Reply With Quote
Old 12-12-2009, 03:42 AM   #13
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
I've got another problem.

Since i need player to save/load all the time i need way to force load before save. Or else instead of loading it saves first which leads to hunger being 0 all the time. I've added bool to prevent that. But problem is the server. Every time i restart game eveything is fine, but if i lets say changelevel the server thinks that i'm already loaded and saves me without loading me which leads hunger being saved as 0. I've added
Code:
pPlayer->FirstSpawn = false;
to hl2mp_client.cpp in Finished Client Put in server section. But it seems that it doesnt point to correct variable and server still thinks i was already on. I still trying to solve it but maybe you guys got an idea? Weird part is that integers always are 0(NULL) when starting, but bools stays true and if i remember correct bool should start as false.

EDIT
Problem is something else. As i removed parts where bool becomes true and after map loaded second time it still wasn't responding to it. Maybe its because its listen server and i cant use bools? But that would be weird ill try to make it as integer.

EDIT2
Nope problem is not that. I changed it to load all the time but theres still something weird. Something wrong with saving/loading...

Last edited by ks_ratchet: 12-12-2009 at 04:06 AM.
ks_ratchet is offline   Reply With Quote
Old 12-12-2009, 04:20 AM   #14
Biohazard_90
 
 
 
Join Date: Jun 2008
Reputation: 351
Posts: 1,811
From where do you call Save/Load? I'd say set FirstSpawn to true in the constructor and then call the load function in spawn() and set that bool back to false. That should probably work fine...

And saving could simply be done through the destructor, if the steamid is not accessible then you could store it in an int on load. (Or through something like OnDisconnect() or ClientDisconnect(), but I don't know if something like this even exists, but maybe in the client.cpp).

For the saving part you could completely remove 'FindKey' because it would naturally always return false, the keyvalues are empty, otherwise it looks correct.
Beside the part that z33ky is probably right with the idea of having a seperate file for every player. But for now you could show us the load function if you still can't get it to work.

Does calling deletethis() on a keyvalue object also remove all of its subkeys? I'm unsure about that right now.
Biohazard_90 is offline   Reply With Quote
Old 12-12-2009, 04:51 AM   #15
ks_ratchet
 
Banned
Join Date: Mar 2008
Reputation: 2
Posts: 367
This is my load.
Code:
	KeyValues *pkv = new KeyValues( "SAVES" );
	Assert( pkv );
	if( !pkv->LoadFromFile( g_pFullFileSystem, "data/saves.txt", "MOD" ) )
	{
		DevWarning( 1, "Unable to load '%s'\n", "data/saves.txt" );
	}
	else
	{
	DevWarning( 1, "Reading SAVES\n");
	pkv->FindKey( "Hunger", false );
	if( pkv )
	{
		KeyValues *sub = pkv->FindKey("Hunger", false);
		DevWarning( 1, "READING 'Hunger'\n");
		pPlayer->Hunger = sub->GetInt(UTIL_VarArgs("%i", engine->GetClientSteamID( pPlayer->edict() )));
		//DevWarning( 1, "Your STEAM ID is: %i\n",engine->GetClientSteamID( pPlayer->edict() ));
	}
	//sub->deleteThis();
	pkv->deleteThis();
	}
I'm doing everything in hl2mp_player.cpp as for me it's the best place.
And yes i've tried deletethis() for everything not for load yet though as i had an idea that it might be the problem. In any case i know now that mistake is somewhere in load function.
ks_ratchet is offline   Reply With Quote
Reply

Go Back   Steam Users' Forums > Steam Tool Discussions > Source Coding


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT -7. The time now is 03:25 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site Content Copyright Valve Corporation 1998-2014, All Rights Reserved.