Jump to content

_FileWriteToLine & Arrays, is there a faster way to do this?


Recommended Posts

Hello,

Althou the script below works, is there a more elegant, faster way to do this?

#Include <File.au3>
#Include <Array.au3>
Dim $aRecords
Dim $avArray[1]
_FileReadToArray(@ScriptDir & "\Data\Equipment\select_equip.ini", $aRecords)
For $x = 1 To $aRecords[0]
    If StringInStr($aRecords[$x], "lodranges") Then
        _ArrayAdd($avArray, $x)
    EndIf
Next
_ArrayDelete($avArray, 0)
Do
    _FileWriteToLine(@ScriptDir & "\Data\Equipment\select_equip.ini", $avArray[0], "lodranges = 0, 1000000", 1)
    _ArrayDelete($avArray, 0)
Until @error

This is for the game "Freelancer" I still keep playing. In order to maximize details beyond what is possible with the game's configuration settings, I need to up the values of the "Lodranges = " lines to 1000000 (=1000k ingame). This makes stationary objects visible from a greater distance as well as eliminating the pop-up effect of the game switching between levels of detail when closing in on such an object (if I only had a clue how to do this for the textures as well...).

The script above is needed to automatically adjust these lodranges settings so I don't have to do this manually. This isn't the only file containing lodranges, there are more, some even a lot larger. Since I experiment alot with mods for this game, I need something that can handle all of the lodranges, no matter what line they appear in. If there is a "lodranges" line (e.g. "lodranges=0, 250, 500, 1000"), it should become "lodrange=0, 1000000".

Attached is the file "select_equip.ini" from the game so you can experiment with the script if you want.

Thank you in advance.

select_equip.zip

Link to comment
Share on other sites

Hello,

Althou the script below works, is there a more elegant, faster way to do this?

#Include <File.au3>
#Include <Array.au3>
Dim $aRecords
Dim $avArray[1]
_FileReadToArray(@ScriptDir & "\Data\Equipment\select_equip.ini", $aRecords)
For $x = 1 To $aRecords[0]
    If StringInStr($aRecords[$x], "lodranges") Then
        _ArrayAdd($avArray, $x)
    EndIf
Next
_ArrayDelete($avArray, 0)
Do
    _FileWriteToLine(@ScriptDir & "\Data\Equipment\select_equip.ini", $avArray[0], "lodranges = 0, 1000000", 1)
    _ArrayDelete($avArray, 0)
Until @error

This is for the game "Freelancer" I still keep playing. In order to maximize details beyond what is possible with the game's configuration settings, I need to up the values of the "Lodranges = " lines to 1000000 (=1000k ingame). This makes stationary objects visible from a greater distance as well as eliminating the pop-up effect of the game switching between levels of detail when closing in on such an object (if I only had a clue how to do this for the textures as well...).

The script above is needed to automatically adjust these lodranges settings so I don't have to do this manually. This isn't the only file containing lodranges, there are more, some even a lot larger. Since I experiment alot with mods for this game, I need something that can handle all of the lodranges, no matter what line they appear in. If there is a "lodranges" line (e.g. "lodranges=0, 250, 500, 1000"), it should become "lodrange=0, 1000000".

Attached is the file "select_equip.ini" from the game so you can experiment with the script if you want.

Thank you in advance.

check out StringRegExpReplace()

***edit***

also, a tip to speed up, when you read the file to an array, you can then turn the array into a string, and make your changes via StringRegExpReplace so you don't have to step through the array, and then just write back to the file.

Edited by cameronsdad
Link to comment
Share on other sites

Thank you for your quick replies.

Maybe I'm missing out on something... I'm not that good at Autoit yet, just barely got the above to work

Replacing the lodranges entries isn't just a task of replacing a string, it's about replacing a whole line of mostly unpredictable stuff. "Lodranges" is just always the beginning of such a line, what follows it differs alot in length and characters, for the various ingame objects.

I'm sorry, but I'm unable to see how a StringReplace("stringA", "stringB") could possibly change a whole line. From my point of view, StringReplace("lodranges*", "lodranges=0, 1000000") would be more like it.

Edited by Sven
Link to comment
Share on other sites

  • Moderators

Thank you for your quick replies.

Maybe I'm missing out on something... I'm not that good at Autoit yet, just barely got the above to work

Replacing the lodranges entries isn't just a task of replacing a string, it's about replacing a whole line of mostly unpredictable stuff. "Lodranges" is just always the beginning of such a line, what follows it differs alot in length and characters, for the various ingame objects.

I'm sorry, but I'm unable to see how a StringReplace("stringA", "stringB") could possibly change a whole line. From my point of view, StringReplace("lodranges*", "lodranges=0, 1000000") would be more like it.

I misread your code... I didn't see (or understand why) that you had it looping twice.

Edit:

If you are using an Ini... why are you using _File* functions and not Ini* functions?

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

For me it was the only possibility to accomplish altering the lodranges lines. If the file is read into an array line by line, I can have the script look for and "remember" all the lines that start with "lodranges", then have another function jump directly to those lines and change them. Is this possible by using INI file operations, too?

Edited by Sven
Link to comment
Share on other sites

Thank you for your quick replies.

Maybe I'm missing out on something... I'm not that good at Autoit yet, just barely got the above to work

Replacing the lodranges entries isn't just a task of replacing a string, it's about replacing a whole line of mostly unpredictable stuff. "Lodranges" is just always the beginning of such a line, what follows it differs alot in length and characters, for the various ingame objects.

I'm sorry, but I'm unable to see how a StringReplace("stringA", "stringB") could possibly change a whole line. From my point of view, StringReplace("lodranges*", "lodranges=0, 1000000") would be more like it.

if you turn the array into a single string, you can still use StringRegExpReplace() to do what you want. example, if you use Chr(1) as your delimiter when you _ArrayToString() then your StringRegExpReplace() can replace patterns that start with 'lodranges' and end with Chr(1) with the replacement string that you want, with a Chr(1) on the end of it. It's faster than stepping through an array, and you can make the changes as dynamic as you want with your regex pattern. Smoke_N is pretty good with them, I believe, and could probably help on your pattern.

***edit***

oh yeah, and when you've done your replace, you can either strip out the delimiter and write it to a file, or you can _StringToArray() it back into the array, and write it back the same way you brought it in...

Edited by cameronsdad
Link to comment
Share on other sites

Dim $aRecords
#include <file.au3>
#Include<Array.au3>

_FileReadToArray(@ScriptDir & "\Data\Equipment\select_equip.ini", $aRecords)
Dim $sArrayString = _ArrayToString($aRecords,"|"& @CRLF)
$sArrayString = StringLower($sArrayString)
$test = StringRegExpReplace($sArrayString,"<(?i)lodranges>(.*?)</(?i)|>", "lodranges=0, 1000000",0)
_FileWriteLog(@ScriptDir & "\test.log", $test)

Can't seem to find the correct pattern to be replaced. Have to try again after some sleep. Thanks for the help, this seems to be just what I need. If I can get it to work :whistle:

Link to comment
Share on other sites

  • Moderators

Run this without adding any code (unless the file names are different) and see if this is the result you want:

$sString = FileRead(@ScriptDir & "\Data\Equipment\select_equip.ini")
$test = StringRegExpReplace($sString,"(?i)lodranges.*?\r", "lodranges=0, 1000000" & @CR,0)
FileClose(FileOpen(@ScriptDir & "\test.log", 2))
FileWrite(@ScriptDir & "\test.log", $test)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

It's working! Thank you both so much!

Althou I'll be using the StringRegExpReplace method, I have one more question about the array stuff in the starter posting: why is it that it seems to loop forever replacing the lodranges on a bigger (~27100 lines, ~650kbyte) file? In this file are around 730 lodranges entries that need to be replaced, and the script keeps doing that file over and over again. Is there a size limit for arrays?

Link to comment
Share on other sites

It's working! Thank you both so much!

Althou I'll be using the StringRegExpReplace method, I have one more question about the array stuff in the starter posting: why is it that it seems to loop forever replacing the lodranges on a bigger (~27100 lines, ~650kbyte) file? In this file are around 730 lodranges entries that need to be replaced, and the script keeps doing that file over and over again. Is there a size limit for arrays?

there is a size limit, but i doubt you're hitting it, 16 million elements i think

Link to comment
Share on other sites

Hi,

I think you are probably just noticing that _FileWriteToLine is slow, and reads the whole file each time in your 730 loops to find the position of the start of each line in the file?

You could get around that (see in my sig TailRW.au3), but the method you have now with rexExp is probably better.

Best, Randall

Link to comment
Share on other sites

Sorry for the late reply.

About my first method: When the script was just startet, the size of the file it was working on immediately dropped to 0kb, after some time increasing up to something around it's original size, then dropped to 0kb again repeating that over and over.

The StringRegExpReplace method is just beautiful, it never misses. Still amazes me how powerful stuff can be done with so little code. But I guess this just shows how much of a newbie I am :whistle:

Link to comment
Share on other sites

  • Moderators

Sorry for the late reply.

About my first method: When the script was just startet, the size of the file it was working on immediately dropped to 0kb, after some time increasing up to something around it's original size, then dropped to 0kb again repeating that over and over.

The StringRegExpReplace method is just beautiful, it never misses. Still amazes me how powerful stuff can be done with so little code. But I guess this just shows how much of a newbie I am :whistle:

Well when you think about it, it's not "So little" of code... there's a lot behind the "syntax" that you are using to make that "little" bit work.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...