Page 1 of 1

Get the checksum of a file using GetChecksum() [SOLVED]

Posted: Mon May 06, 2019 5:07 pm
by PrinceOfFunky
There's a function declared in StatLogFile.uc called "GetChecksum()" with a out String parameter called "checksum", it is called in the same file inside "LogGameEnd()" function:

Code: Select all

GetChecksum( Checksum );
LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)$Checksum$"");
Looks like it doesn't work but doesn't even crash the game, since I can find these lines in the log files:

Code: Select all

14.50	game_end	mapchange
But when I try to do the same the game crashes:

Code: Select all

file = Spawn(class'StatLogFile');
file.StatLogFile = "../Logs/test.log";
file.StatLogFinal = "../Logs/test2.log";
file.OpenLog();
file.GetChecksum(checksum);
file.StopLog();
Log(checksum);
It crashes when GetChecksum is called. Do you know how to make it work without crashing the game?

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Mon May 06, 2019 5:18 pm
by sektor2111
I would like to be sure about what "FILE" is. I believe that if FILE is NULL or it's EMPTY with 0 bytes, perhaps I might expect a crash a la UE1 instead of pointing error problem. As I see here is about a group of executions - spawn-open-compute-close while this thing it's perhaps closer to None. Try to log something:

Code: Select all

...
foreach ...//whatever AllActors (....)
{
 i++;
 LogEventString("test-test-test "$i$" actors.");
}
file.GetChecksum(checksum);
file.StopLog();
Else... I would put logs for listing everything after each line in order to see what's going on and when...

I see also an "Indirect" problem, their Natives are called from inside other functions not directly - I don't get why but it might be a problem for some reason - or not ?

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Mon May 06, 2019 6:20 pm
by PrinceOfFunky
sektor2111 wrote:I would like to be sure about what "FILE" is. I believe that if FILE is NULL or it's EMPTY with 0 bytes, perhaps I might expect a crash a la UE1 instead of pointing error problem. As I see here is about a group of executions - spawn-open-compute-close while this thing it's perhaps closer to None. Try to log something:

Code: Select all

...
foreach ...//whatever AllActors (....)
{
 i++;
 LogEventString("test-test-test "$i$" actors.");
}
file.GetChecksum(checksum);
file.StopLog();
Else... I would put logs for listing everything after each line in order to see what's going on and when...

I see also an "Indirect" problem, their Natives are called from inside other functions not directly - I don't get why but it might be a problem for some reason - or not ?
"OpenLog()" creates a file, so it must be 0 bytes until "CloseLog()" is called. The file is created and without calling GetChecksum() everything works fine.
These are the crash logs:

Code: Select all

ScriptLog: Fabricate DEBUG.DEBUG
Critical: AStatLogFile::execGetChecksum
Critical: (DEBUG Entry.DEBUG0 @ Function DEBUG.DEBUG.Spawned : 0074)
Critical: UObject::ProcessEvent
Critical: (DEBUG Entry.DEBUG0, Function DEBUG.DEBUG.Spawned)
Critical: ULevel::SpawnActor
Critical: (DEBUG)
Critical: UObject::ProcessEvent
Critical: (TMale1 Entry.TMale1, Function Botpack.TournamentPlayer.Summon)
Critical: UObject::ScriptConsoleExec
Critical: (TMale1 Entry.TMale1)
Critical: UPlayer::Exec
Critical: UViewport::Exec
Critical: UWindowsViewport::Exec
Critical: UObject::ProcessEvent
Critical: (UTConsole Transient.UTConsole0, Function UTMenu.UTConsole.UWindow.KeyEvent)
Critical: UEngine::InputEvent
Critical: UWindowsViewport::CauseInputEvent
Critical: WM_KEYDOWN
Critical: UWindowsViewport::ViewportWndProc
Critical: WWindow::StaticProc
Critical: DispatchMessage
Critical: 00620254 256
Critical: MessagePump
Critical: MainLoop
Exit: Executing UObject::StaticShutdownAfterError
Exit: Executing UWindowsClient::ShutdownAfterError
Exit: UGalaxyAudioSubsystem::ShutdownAfterError
Log: DirectDraw End Mode
Exit: UD3D9RenderDevice::ShutdownAfterError
Exit: Exiting.
Uninitialized: Name subsystem shut down
Uninitialized: Log file closed, 05/06/19 17:59:00
Where DEBUG.DEBUG is my "package.class" .

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Mon May 06, 2019 7:38 pm
by TheDane
I just peaked at the stalogfile actor. What seems to cause the confuzion is the name of the variable used multiple times "checksum" and then the name of the GetCheckSum native function?

lets look at one function:

Code: Select all

function LogGameEnd( string Reason )
{
	local string Checksum;

	if( bWorld )
	{
		bWatermark = False;
		GetChecksum( Checksum );
		LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)$Checksum$"");
	}
	else Super.LogGameEnd(Reason);
}
look how the variable Checksum is declared localy as a string. That means the "Checksum" is nothing but a string that does not come from another class or function.
Then the function GetChecksum is called, and the variable ( Checksum ) is declared in that function as an outgoing string ( native final function GetChecksum( out string Checksum ); ). That means that what this call does, is to assign a value to the local string "Checksum".
Now look at the LogEventString call, here the local variable is added last: LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)$Checksum$"");
What this basicly means, is that Checksum is the text string of the log file itself, and is beeing rewritten with the newest update, by starting with "GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)" as the latest entry, then adding the older stuff to the file as $Checksum, and then close the log file.

I don't see it as a function capable of returning a checksum of a given file? I may be wrong, but try go through the statlogfile actor looking from the perspective I descriped here? What do you make of it?

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Mon May 06, 2019 8:49 pm
by PrinceOfFunky
TheDane wrote:I just peaked at the stalogfile actor. What seems to cause the confuzion is the name of the variable used multiple times "checksum" and then the name of the GetCheckSum native function?

lets look at one function:

Code: Select all

function LogGameEnd( string Reason )
{
	local string Checksum;

	if( bWorld )
	{
		bWatermark = False;
		GetChecksum( Checksum );
		LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)$Checksum$"");
	}
	else Super.LogGameEnd(Reason);
}
look how the variable Checksum is declared localy as a string. That means the "Checksum" is nothing but a string that does not come from another class or function.
Then the function GetChecksum is called, and the variable ( Checksum ) is declared in that function as an outgoing string ( native final function GetChecksum( out string Checksum ); ). That means that what this call does, is to assign a value to the local string "Checksum".
Now look at the LogEventString call, here the local variable is added last: LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)$Checksum$"");
What this basicly means, is that Checksum is the text string of the log file itself, and is beeing rewritten with the newest update, by starting with "GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)" as the latest entry, then adding the older stuff to the file as $Checksum, and then close the log file.

I don't see it as a function capable of returning a checksum of a given file? I may be wrong, but try go through the statlogfile actor looking from the perspective I descriped here? What do you make of it?

Yeah, that is why I call it like this:

Code: Select all

file.GetChecksum(checksum);
But it crashes the game. ("checksum" is a local variable in the function where I call file.GetChecksum(checksum);)

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Mon May 06, 2019 9:14 pm
by TheDane
yes, I wasn't clear eneough, your code:

Code: Select all

file = Spawn(class'StatLogFile');
file.StatLogFile = "../Logs/test.log";
file.StatLogFinal = "../Logs/test2.log";
file.OpenLog();
file.GetChecksum(checksum);
file.StopLog();
Log(checksum);
Now, this is just a guess.... I could be wrong, haven't tried to replicate this, so only looking at it from bird view.

What I see is you spawning the StatLogfile Actor into the world, you set the name for the file(s). then you call the function OpenLog(), but that doesn't create the file, I believe the function StartLog() does that? So, when you next call function GetCheckSum(), you ask it to get a checksum from a non existing file? that could cause a crash? Try forcing the StatLogFile to write the logfile to the disk before calling the GetCheckSum() function?

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Mon May 06, 2019 10:05 pm
by sektor2111
What I was trying to say, it's probably a BAD idea to create a checksum for a file having 0 bytes... just saying... That file has no content and I don't get how is checksum computed then...

Re: How to get the checksum of a file using GetChecksum() ?

Posted: Tue May 07, 2019 2:47 am
by PrinceOfFunky
I found the solution. Inside the spoiler there are the answers I gave before finding the solution.
Spoiler
TheDane wrote:yes, I wasn't clear eneough, your code:

Code: Select all

file = Spawn(class'StatLogFile');
file.StatLogFile = "../Logs/test.log";
file.StatLogFinal = "../Logs/test2.log";
file.OpenLog();
file.GetChecksum(checksum);
file.StopLog();
Log(checksum);
Now, this is just a guess.... I could be wrong, haven't tried to replicate this, so only looking at it from bird view.

What I see is you spawning the StatLogfile Actor into the world, you set the name for the file(s). then you call the function OpenLog(), but that doesn't create the file, I believe the function StartLog() does that? So, when you next call function GetCheckSum(), you ask it to get a checksum from a non existing file? that could cause a crash? Try forcing the StatLogFile to write the logfile to the disk before calling the GetCheckSum() function?
StartLog() is a non-native function, it calls OpenLog() (a native function) to create the file (same as "touch" on Linux) and write some log lines in it, appends the ".tmp" and "."log" to the files etc...
sektor2111 wrote:What I was trying to say, it's probably a BAD idea to create a checksum for a file having 0 bytes... just saying... That file has no content and I don't get how is checksum computed then...
Same happens with non-empty files, like DLLs etc...

This is the whole class:

Code: Select all

class DEBUG extends Actor;

event Spawned() {
	local StatLogFile file;
	local String checksum;
	
	file = Spawn(class'StatLogFile');
	file.StatLogFile = "UWeb.dll";
	file.StatLogFinal = "UWeb.dll";
	file.OpenLog();
	file.GetChecksum(checksum);
	file.StopLog();
	Log(checksum);
}
GetChecksum works with the LocalLog/WorldLog file spawned by GameInfo.
SOLUTION: Sadly the code isn't documented, but I noticed that in LogGameEnd(), before GetChecksum is called, there's a "if( bWorld )".
So, setting bWorld to True solved the issue. Now the game doesn't crash anymore and an actual hash is logged! Now I just need to find out what type of hash it is.