Feature Request: File I/O

A forum for feature requests/discussions and user submitted patches that improve MQ2

Moderator: MacroQuest Developers

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Feature Request: File I/O

Post by BlueSkies » Thu Jun 26, 2003 7:42 pm

Not sure how this'll go over, as I've seen debates in the past about this subject, but that was a long time ago.

What I'd like to see in a future CVS build of MQ is the ability to manipulate files.

The benifits are obvious. Macros that read initialization data and settings from plain text files, or obtain game data that can be put to use and manipulated (like the Bazaar stuff, for example). I'm writing a path recording macro (that at the moment relies on an external VB app I wrote to parse /MQLOG output), and that would be so much easier (and more self-contained) to use if I had access to file input/output, and I think a lot of people would find this very useful for things I can't even begin to think about.

I know there are potential problems. I remember hearing talk about 'MacroQuest Trojans' that could destroy files, etc. To be honest, I don't think this is a real problem, as any such macros posted in the macro depot would be quickly identified (not to mention the fact that you shouldn't run any macro you're not familiar with).
To further reduce risk of these types of macros, we could limit file i/o to one directory, perhaps nested in the Macros directory.

Commands could be as follows:

/openfile <nameoffile> <filehandle> <openmode>
-- This would open the specified file for input/output on the specified handle, in the specified open mode (String or Binary)

$readfile(<filehandle>,<numbytes>,[<startposition>])
-- read the specified number of bytes from the specified file, starting at the specified byte position, or if the start position is omitted, starting from the current cursor position.

$readfileline(<filehandle>,[<linenumber>])
-- reads the specified line from the specified file, or if the line number is omitted, it returns the next line.

/writefile <expression> <filehandle> [<startposition>]
-- writes the specified expression to the specified file at the specified position, or if the position is omitted, it writes to the current cursor position, overwriting whatever was previously there.

/writefileline <expression> <filehandle> <linenumber>
-- writes the specified expression to the specified file at the specified line number, or if the line number is omitted, it writes to the current line number, overwriting whatever was previously there.

/closefile <filehandle>
-- Closes the file previously opened by /openfile. Filehandle could be replaced with 'All,' and would close all open files.



And we could have functions like:

$nextfile
-- Returns the next available file handle

$getpos(<filehandle>)
-- Returns the current cursor position of the specified file. For Binary files, it'd return the literal byte position, and for String files, it'd return the line number.

/setpos <filehandle> <position>
-- Sets the current cursor position of the specified file. For Binary files, it'd set the literal byte position, and for String files, it'd set the line number. Position can also be BOF (for Beginning Of File) or EOF (for End Of File).

$sizeof(<filehandle>)
-- Returns the size (in bytes for Binary files, or lines for String files) of the specified file.


An example of the use could be something like the following:

Code: Select all

Sub Main
    /openfile "somestuff.dat" 1 String
    
    /for l1 1 to $sizeof(1)
        /echo $readfileline(1,$l1)
    /next l1
    
    /closefile 1
/return
This code would open a file, assign it to File Number 1, and it'd be opened as 'String' type, so it'd be read in lines. It iterates from the first line to the last, echoing every line, and finally closes the file and exits.


That's about all I can think of right now. I'd be more than willing to help work on this, but, as I'm just starting to learn C++ at the moment (I'm a veteran VB programmer), I'd need some guidance. PM me or Email me at BlueSkies.SC@comcast.net if anyone's interested in helping me with a nudge in the right direction, or reply here if you have questions.
Live your dreams! Blue Skies everyone

Mckorr
Developer
Developer
Posts: 2326
Joined: Fri Oct 18, 2002 1:16 pm
Location: Texas

Post by Mckorr » Fri Jun 27, 2003 12:46 pm

Ack! If all you are using is text files, and reading/writing strings from/to them, why use handles at all. How about something simpler like "writeline".

/openfile $f0 "record.txt"
:loop
/readline $f0 String
/if String=MyString goto exitloop
/nextline $f0
/goto loop
:exitloop

/writeline $f0 MyString
/closefile $f0

Basic functions: open, close, read, write, nextline, newline, stuff like that. Hmph, believe part of the function is already there, isn't there an addline command that tacks a new line onto a macro?

Anyway, skip the complicated C style syntax, manipulate strings instead of pointers.
MQ2: Think of it as Evolution in action.

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 12:49 pm

*shrugs* It was just a suggestion on a potential command set. :) I'm certainly willing to simplify it :P I literally threw those commands together as I wrote the post.

How difficult do you think this would be to work into MQ? Would it be worth the effort?
Live your dreams! Blue Skies everyone

Mckorr
Developer
Developer
Posts: 2326
Joined: Fri Oct 18, 2002 1:16 pm
Location: Texas

Post by Mckorr » Fri Jun 27, 2003 12:55 pm

Dunno, don't have the source code here. I'd have to take a look for that addline command, see what it does and how it interfaces with the macro file.

As those who helped me with the screen location parser can attest, string manipulation is not my strong suit. I had a tremendous amount of help in getting all that working, and even then I had a tutorial open in one window, a manual open on the desk, and DKAA yelling at me about not knowing what I was doing :)

If I get a chance I'll grab the CVS here at work and see what I can find out.
MQ2: Think of it as Evolution in action.

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 1:20 pm

String manipulation is FUN! (*ahem*BULLSHIT*ahem*)

I just finished writing a program in VB that reads the output log file from a macro I wrote that records y,x point data and converts that into a macro that walks the path you just recorded... *phew* Fun stuff.

[/sarcasm]

I dunno. As much as I hate dealing with strings, I'm actually pretty good at it. When I get done with the pathwalking scripts (I'm about 98% done -- all I gotta do now is get it to walk the path the other way, from end to start) I'll post them, plus the VB parsing source. To be honest, I think string manipulation will be the easy part of implementing this functionality.

As for File I/O, I wasn't aware that was C-style syntax. I have no experience with C's file I/O functions. :P

I like your idea about creating a new variable for file handles -- the $f# stuff you have in your example code.

And about only manipulating strings -- if you look in my post, I have references to reading/writing binary data. Figured it'd be useful in some way to be able to read/write binary data. *shrugs*
Live your dreams! Blue Skies everyone

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Fri Jun 27, 2003 2:50 pm

Mckorr wrote: and DKAA yelling at me about not knowing what I was doing :)
I never yelled.

I don't see the real cost/benefit value in this proposal. Things get written to the logfile if you turn in it on. Simple perl (or vb) scripts can pull the needed data out of the log file.

We already read from files (the /macro command).

Am I missing something?

Mckorr
Developer
Developer
Posts: 2326
Joined: Fri Oct 18, 2002 1:16 pm
Location: Texas

Post by Mckorr » Fri Jun 27, 2003 2:56 pm

I wouldn't include binary data, too much potential for abuse, and much more open to malicious scripts. Since macros are all text scripts anyway they'd only need to be able to read/write text files.

For example your recording macro would get locations, write them to your text file. Your walking macro would then read back those text values in reverse sequence to walk you back to your starting point. Since MQ parses the macro arguments as text (you'll see a lot of szArg1, szArg2, etc. in the source code) and converts them internally as needed, using straight binary data would just confuse existing functions.

In addition, reading/writing binary data could end up turning MQ into a hacking tool far worse than it already is as people write scripts to capture binary information, then alter it and feed it back to the program. Since MQ is about automating tedious tasks, not about true "hacking", it would go against the grain of the project goals.
MQ2: Think of it as Evolution in action.

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 3:07 pm

I've posted a poll in MQ General to see what other users think. If it gets enough positive response, I'll tackle it myself and submit it for CVS.

McKorr, you're probably right about limiting it to String data only. Though I don't think including Binary capability would create any potential for malicious scripts, and I already posted a fix for that -- limiting what directories MQ File I/O functions have access to (like Macros/Data or something).

Doesn't matter. Binary's out -- I like straight String data anyway. Easier to work with :P
Live your dreams! Blue Skies everyone

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 3:09 pm

Oh, and, DKAA -- I've already done the log file parsing with a VB program... It works, yes, but it's NOT a clean solution.

I'm actually about to post a set of scripts (and the accompanying VB code) that does exactly this.
Live your dreams! Blue Skies everyone

kaz
a ghoul
a ghoul
Posts: 103
Joined: Tue Jan 14, 2003 4:09 am

Post by kaz » Fri Jun 27, 2003 4:14 pm

use perl scripts to parse your log files, will be much cleaner than using mq to open files and you can use regex, seems like the most powerful and simplest solution to me, or am I missing something your trying to get out of this?

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 4:25 pm

First, I don't know perl, and I don't want to learn it.

Second, with file i/o BUILT IN to macroquest, I don't have to do all this crap manually. I can write a script that does it for me, without my interaction. MUCH more powerful than using Perl or VB or whatever.

MacroQuest is all about automation, is it not? (I'm not talking about unattended macroing here.)

What if I want to make a Bazaar macro that changes prices on the fly, starts and stops trader mode when the prices change, etc.? I can't do that automatically if I have to use some external program (in whatever language). With Built-In file processing functionality, I could. That is just ONE example. With the number of people active in the MQ community, I'm sure with this kind of functionality we'd have hundreds of uses I can't begin to think of.

So, yeah, you're missing something. The input of the entire MQ community. I'm missing it too.

Besides, we don't want those Xylo people saying "Oh yeah? We've got File I/O! Hah!" :P (That's a joke, guys.)
Live your dreams! Blue Skies everyone

kaz
a ghoul
a ghoul
Posts: 103
Joined: Tue Jan 14, 2003 4:09 am

Post by kaz » Fri Jun 27, 2003 5:52 pm

ok the bazaar example is valid sorta, except you wouldnt use file i/o for something like that, you'd want database i/o, and tell me how a bazaar macro that automatically changes prices doesnt sound like an unattended macro? lol

what are some other examples of how a macro would benefit from file i/o? specifics.

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 6:01 pm

Kaz, use your imagination. I'm not going to do it for you. :)

The bazaar file isn't a database, it's a plain text file. BZR_<charname>_<servernum>.ini in your EQ game directory. Check it out -- looks like any standard Windows INI file.

My pathwalking macros, which are currently in the Macro Depot, would benefit by removing the necessity to have an outside process parse the log file before you can use the path.
Right now, you have to (1)record the path, (2)leave the EQW process, (3)parse the log file, (4)enter back into the EQW process, (5)run the walk script. With File Manipulation functions, steps 2, 3, and 4 disappear completely.

I think it's pretty damned obvious what the benefits are.
Live your dreams! Blue Skies everyone

kaz
a ghoul
a ghoul
Posts: 103
Joined: Tue Jan 14, 2003 4:09 am

Post by kaz » Fri Jun 27, 2003 6:04 pm

ok I thought you meant writing a bazaar bot, which if I was going to do it would operate off a database, sorry misunderstood.

User avatar
BlueSkies
a ghoul
a ghoul
Posts: 132
Joined: Tue Oct 01, 2002 6:22 pm

Post by BlueSkies » Fri Jun 27, 2003 6:09 pm

Oh, no, hehe :) I see what you thought I meant. :)

And by changing prices on the fly, I meant via command from tells, or whatnot, so you could control your bazaar bot from another computer. I have a couple computers here set up without keyboards, mice, or monitors that I used to bot with, and something like that for the Bazaar would have been awesome.

Now that you mention it... Database access would be pretty damned cool... :P (though probably quite a bit overboard, hehe)
Live your dreams! Blue Skies everyone