Page 1 of 2
You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 1:19 pm
by PrinceOfFunky
"You cannot write on files using Unreal" - they said.
"You can only write on INI files and read from INI and INT files using Unreal" - they said.
Fake! Like in any other programming language you can write on file and perform all the needed operations on it, like creating the file itself, opening, flushing and closing it.
This works like a charm:
Code: Select all
local StatLogFile file;
file = Spawn(class'StatLogFile');
//tmp file name.
file.StatLogFile = "test.tmp";
//final file name.
file.StatLogFinal = "test.log";
file.OpenLog();
file.FileLog("HERE GOES WHAT YOU WANT TO WRITE ON THE FILE");
file.FileFlush();
file.CloseLog();
Video proof:
BhBSJanAYVM
BeginPlay set the timer to 30 and the Timer logs players info, so
if you don't want your file to include the players info every 30 seconds, you should disable Timer() or overwrite BeginPlay().
StatLogFile variable can be whatever directory, the parent class of StatLogFile contains some useful functions I didn't read, so basing on what I wrote
here, you could create a script file from scratch and then execute it using Unreal for the whole process.
I'm not sure if you want to see the mutator I showed in the vid, if you need it just tell me and I'll post it on here.
I think if people will start using new directories, we should make a standard before we get a lot of folders spread around.
(And I was even making Unreal communicating through TCP just to write few info using Java -__-")
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 2:39 pm
by nogardilaref
I truly wonder how I have missed this actor myself for all these years... very interesting indeed, this will certainly allow the sort of thing I aim to do in the future a lot more easily.
Although this is as powerful as it is dangerous, for obvious reasons.
As for appending, perhaps if you do not call "file.CloseLog();" and keep global reference in your class rather than a local one, it might keep appending stuff to it instead, until the actual actor itself is destroyed on map change or on exit.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 3:03 pm
by sektor2111
nogardilaref wrote:As for appending, perhaps if you do not call "file.CloseLog();" and keep global reference in your class rather than a local one, it might keep appending stuff to it instead, until the actual actor itself is destroyed on map change or on exit.
I did not recall any chatlog file removed from my system all this time - IT USES THE same way for writing files outta sandbox. Yeah, Funky, it's done already...
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 3:15 pm
by PrinceOfFunky
sektor2111 wrote:nogardilaref wrote:As for appending, perhaps if you do not call "file.CloseLog();" and keep global reference in your class rather than a local one, it might keep appending stuff to it instead, until the actual actor itself is destroyed on map change or on exit.
I did not recall any chatlog file removed from my system all this time - IT USES THE same way for writing files outta sandbox. Yeah, Funky, it's done already...
Yeah IkIk that the appending works, but I meant appending after closing/reopening the file.
I think the best thing would be to read files other than writing them, I mean we can read from INI and INTs but they must be in a standard format, reading from whatever structure would be a lot better.
EDIT: Also:
nogardilaref wrote:I truly wonder how I have missed this actor myself for all these years...
Maybe cause the name of the class/file is StatLogFile and not something like FileWriter and basing on what we are used to read in unrealscript classes, like that when you read things that are not usually from the unrealscript world we tend to think that those things must be hardcoded natively.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 4:22 pm
by nogardilaref
PrinceOfFunky wrote:
nogardilaref wrote:I truly wonder how I have missed this actor myself for all these years...
Maybe cause the name of the class/file is StatLogFile and not something like FileWriter and basing on what we are used to read in unrealscript classes, like that when you read things that are not usually from the unrealscript world we tend to think that those things must be hardcoded natively.
Nah, I am used to weird names and all, and in this case is called "StatLogFile" which is actually pretty obvious, so I think it was mostly over the fact that I barely look into Info classes and I didn't expect something like this to be under "Info" at all, and be an actual actor to top it off (I assumed it would be an non-actor, so there's where I looked in the past).
Which means I will probably have to recheck every class again one of these days, once I pick stuff like this again.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 5:06 pm
by Higor
You can only write 16 bit characters using statlog.
And in a certain UT build you cannot even generate characters outside of the 8 bit range.
Worthless.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 5:33 pm
by nogardilaref
Well... that would at least make it a lot less dangerous, but .int files are localization files, which UT should be able to load from 16-bit characters as well, right?
Given that we can use this class to perhaps create .int files themselves, and Localize to read them, if both work well enough (with the special case of Localize remaining cached in the engine itself), there is still some very useful stuff which can be done, and which fits exactly what I need in my particular case for what I intend to do in the future.
@PrinceOfFunky: did you test to write a "new" .int file with the proper format using this, and then read it with Localize to check if it works at all?
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 7:46 pm
by Higor
Self-localizing in UT has platform-specific code that requires different UnrealScript code for both windows and linux.
Also, UTF localization files require an additional character at the beginning of the text file to indicate UT should read it as UTF.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 9:13 pm
by nogardilaref
Yeah, I just went ahead and tested it myself... bummer.
Well, at least with this you're not bound to a single log file, and this can still be used for plenty of stuff other than logging, although to read back it's indeed quite pointless the way things are saved.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 9:59 pm
by Higor
Forget about windows and linux, let's talk about ANSI or UNICODE
Essentially:
- ANSI: log as usual.
- UNICODE: add the special character start of file, then log as usual.
Try the following
Code: Select all
function StartHeader( string FirstLine)
{
if ( asc(chr(1000)) == 1000 ) //ANSI UT will fail this check
AddString( chr(65279)$ FirstLine);
else
AddString( FirstLine);
}
EDIT: That will only work on INT files btw.
INI will fail.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 10:28 pm
by nogardilaref
Worked like a charm
, here's the code:
Code: Select all
function PostBeginPlay()
{
local StatLogFile file;
//open
file = Spawn(class'StatLogFile');
file.StatLogFile = "TEST.tmp";
file.StatLogFinal = "TEST.int";
file.OpenLog();
//header
if (Asc(Chr(1000)) == 1000) { //ANSI UT will fail this check
file.FileLog(Chr(65279));
}
//data
file.FileLog("[MySection]");
file.FileLog("a={\"key\":\"value\"}");
file.FileLog("b=This proves Higor is THE MAN!");
//finish
file.FileFlush();
file.CloseLog();
//load
Log("TEST.MySection.a = " $ Localize("MySection", "a", "TEST"), 'YOLO_TEST');
Log("TEST.MySection.b = " $ Localize("MySection", "b", "TEST"), 'YOLO_TEST');
}
and here's the log:
Code: Select all
YOLO_TEST: TEST.MySection.a = {"key":"value"}
YOLO_TEST: TEST.MySection.b = This proves Higor is THE MAN!
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 11:06 pm
by Higor
You can also create entire ANSI files using windows statlog, at least to be able to write binary files (pair amount of bytes only).
But you'll need to do a lot of buffering and character conversion, without proper unrealscript optimization the UNICODE build of the statlog may be extremely slow.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 11:16 pm
by PrinceOfFunky
Is it cause of the missing header that this localization doesn't work?:
Code: Select all
local StatLogFile file;
file = Spawn(class'StatLogFile');
//tmp file name.
file.StatLogFile = "test_2.tmp";
//final file name.
file.StatLogFinal = "test_2.int";
file.OpenLog();
file.FileLog("[tests]");
file.FileFlush();
file.FileLog("test1=hello");
file.FileFlush();
file.CloseLog();
Level.Game.BroadcastMessage(Localize("tests", "test1", "test_2"));
EDIT:
Higor wrote:You can also create entire ANSI files using windows statlog, at least to be able to write binary files (pair amount of bytes only).
But you'll need to do a lot of buffering and character conversion, without proper unrealscript optimization the UNICODE build of the statlog may be extremely slow.
Or you run an external script which converts the file from ANSI to UNICODE.
Re: You can create and write a file using Unreal
Posted: Sat Dec 09, 2017 11:22 pm
by Higor
Re: You can create and write a file using Unreal
Posted: Sun Dec 10, 2017 12:26 am
by nogardilaref
@PrinceOfFunky: Yeah, what I commented as header is essentially what Higor posted right before and is simply the UTF-16 BOM (Byte Order Mark), which hints a text reader in which encoding the file is, be it ANSI, UTF-8, UTF-16 or something else, as well as endianess.
In the case of UTF-16, is what Higor just posted, hence that "magic" number at the start, so when the engine loads the .int file, it gets correctly interpreted as UTF-16 rather than ANSI.
As for the first check with Chr(1000), 1000 is just a random UTF-16 character just to check if UT is able to recognize UTF-16 or not.
To be honest, until Higor posted it, I thought that Chr was limited to 255 (ANSI) for some reason, perhaps because there's a difference depending on the version from what he said which I was completely unaware about. I'm glad he sorted it out.
Higor wrote:You can also create entire ANSI files using windows statlog, at least to be able to write binary files (pair amount of bytes only).
But you'll need to do a lot of buffering and character conversion, without proper unrealscript optimization the UNICODE build of the statlog may be extremely slow.
I guess it would be something like this then? (untested code)
Code: Select all
function string convert(string data)
{
local string final_data;
local int data_len, i;
//convert
data_len = len(data);
for (i = 1; i < data_len; i += 2) {
final_data = final_data $ chr((asc(data[i - 1]) << 8) | asc(data[i]));
}
//convert remaining byte
if (data_len % 2 === 1) {
final_data = final_data $ chr(asc(data[data_len - 1]) << 8);
}
//return
return final_data;
}
But then, I am worried about the NULL bytes, because they break strings in this engine, given that strings are NULL terminated after all.
Hence when I created hashing functions for instance (namely MD5 and SHA family), I had to specifically create byte arrays so I could handle the NULL bytes, unless I am missing something here...