• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • ✅ The POLL for Hive's Texturing Contest #33 is OPEN! Vote for the TOP 3 SKINS! 🔗Click here to cast your vote!

TextFile

Status
Not open for further replies.
I know there is File IO by Nestharus to read/write localy with JASS.
However, someone (@Wietlol ) needed to create a plain .txt file without the extra Preload-bullshit texts.
He wants clear output, because he does not read it with jass.
The output will be read by an other 3rd party program or so.

So the solution is to create a preload function that creates a .bat file.
Then you run the .bat file (manualy) and it will create a clean .txt file for you.

Just in case someone else is interested, here is a sample code:

JASS:
library Batch// v1.0 --hiveworkshop.com/threads/textfile.290375/


// Creates a .bat file.


//! novjass
 //============ --------- API --------- =============

 struct Batch

    printStart takes nothing returns nothing
        // just call when you start
     
    print takes string s returns nothing
        // prints "s"

    printEnd takes nothing returns nothing
        // call it when you end
     
    string NL
        // use to write in a new line
        // it is 100% senseless to print it as standalone,
        // so only use as part of your input
     
//! endnovjass
struct Batch extends array

    public static string FOLDER = "Batch"
    public static string NAME   = "MyBat"

    public static constant string NL  = "\n"
                                                   
    public static method printStart takes nothing returns nothing
        call PreloadGenClear()
        call PreloadGenStart()
    endmethod
    public static method printEnd takes nothing returns nothing
        set FOLDER = FOLDER + "\\"
        call PreloadGenEnd(FOLDER + NAME + ".bat")
    endmethod
    public static method print takes string s returns nothing
        call Preload("\")\r\n" + s + "\r\n;")
    endmethod
endstruct
endlibrary

JASS:
library TextFile requires Batch // v1.0 --hiveworkshop.com/threads/textfile.290375/


// Creates a .bat file which will create a clean .txt file.


//! novjass
 //============ --------- API --------- =============

 struct TextFile

    printStart takes nothing returns nothing
        // just call when you start
     
    print takes string s returns nothing
        // prints "s" in same line

    println takes string s returns nothing
        // prints "s" and then jumps to next line

    emptyLine takes nothing returns nothing
        // prints an empty line

    printEnd takes nothing returns nothing
        // call it when you end
     
    string NL
        // use to write in a new line
     
//! endnovjass
struct TextFile extends array

    public static string NAME   = "MyText"

    public static constant string NL = "%NL%"

    private static string DIR_PATH = "\"" + NAME + ".txt\""
    public static method printStart takes nothing returns nothing
        call Batch.printStart()
        set DIR_PATH = "\"" + NAME + ".txt\""
        call Batch.print("echooff> " + DIR_PATH)
        call Batch.print(Batch.NL)
        call Batch.print("set NLM=^\r" + Batch.NL + Batch.NL + Batch.NL + "set NL=^^^%NLM%%NLM%^%NLM%%NLM%")
    endmethod

    public static method printEnd takes nothing returns nothing
        call Batch.printEnd()
    endmethod

    public static method emptyLine takes nothing returns nothing
        call Batch.print("echo.>> " + DIR_PATH)
    endmethod

    private static string temp = ""

    public static method print takes string s returns nothing
        set temp = temp + s
    endmethod

    public static method println takes string s returns nothing
        if (StringLength(s) == 1) then
            set s = "^" + s
        elseif s == null or s == NL then
            call Batch.print("echo.>> " + DIR_PATH)
            return
        endif
        set temp = temp + s
        call Batch.print("echo " + temp + ">> "  + DIR_PATH)
        set temp = ""
    endmethod
endstruct
endlibrary

Demo:

JASS:
struct Demo
    private static method init takes nothing returns nothing

        set TextFile.NAME        = "Worklist"
   
        call TextFile.printStart()
        call TextFile.println("1")
        call TextFile.println("2")
        call TextFile.print("3")
        call TextFile.println("3")
        call TextFile.print("5")
        call TextFile.emptyLine()
        call TextFile.print("5" + TextFile.NL)
        call TextFile.println("6")
       
        call TextFile.printEnd()
       
    endmethod
   
    private static method onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), 0.1, false, function thistype.init)
    endmethod
endstruct
 
Last edited:
Level 19
Joined
Jul 2, 2011
Messages
2,162
You know with a system like this you could prevent a warcraft map from running without this text file.

meaning a new way of protecting maps against theft.

if you were to include the text file in the map file. while also at the same time doing a sumcheck, you could prevent an unpacked map from running.

This is simply marvelous!
 
Level 19
Joined
Jul 2, 2011
Messages
2,162
as always, issue is people are dumb. runnig manually? u wot mate?
thats why you cannot rely on that, and such kind of "protect" will simply kill your map.
no you see it's perfect

it won't be two different filed, it will be one standard warcraft map

only once unpacked the sumcheck changes, which will prevent hacking

it's pure gold... but I'm not to sure if you can run a sumcheck in warcraft?

Can you? I assume if you can read a text file you can run a sum check as well.
 
Level 13
Joined
Nov 7, 2014
Messages
571
He wants clear output, because he does not read it with jass.
The output will be read by an other 3rd party program or so.

So the solution is to create a preload function that creates a .bat file.

Is it? It seems to me that extracting the stuff a user printed from a preload file is rather trivial:
JASS:
function PreloadFiles takes nothing returns nothing

    call Preload( "foo" )
    call Preload( "bar" )
    call Preload( "baz" )
    call PreloadEnd( 0.0 )

endfunction

I.e if a line starts with "\tcall Preload( \"" read until you see " )\r\n" (maybe it is only " )\n" on Mac OS?) and that should be it.
In fact because the generated .bat file has a lot of syntax errors, for big files it would take a lot of time for the .bat parser to report those like I've mentioned here.
Unless there's a way to silence them like redirecting stderr to the windows equivalent of /dev/null or something.


The state parameter of print seems strange to me:
JASS:
    call TextFile.print("Hello World 1!", TextFile.LINE_NEW)

    call TextFile.print("Hello World 2!", TextFile.LINE_START)
    call TextFile.print("Hello World 3!", TextFile.LINE_SAME)
    call TextFile.print("Hello World 4!", TextFile.LINE_END)

    call TextFile.print("Hello" + TextFile.BREAK_LINE + "World 5!", TextFile.LINE_NEW)

Why not two functions instead?:
JASS:
    call TextFile.println("Hello World 1!")

    call TextFile.print("Hello World 2!")
    call TextFile.print("Hello World 3!")
    call TextFile.println("Hello World 4!")

    call TextFile.println("Hello" + TextFile.BREAK_LINE + "World 5!")
 
Level 24
Joined
Aug 1, 2013
Messages
4,658
The output will be read by an other 3rd party program or so.
I explained you sooooo well... y u do dis to me?

Btw:
JASS:
        public static method printStart takes nothing returns nothing
            if .isOpened then
                call BJDebugMsg("File \""+ .FILE_NAME_BAT +"\" is opened.")
                return
            endif
            set .isOpened = true
            
            //bla bla
        endmethod
        
        public static method printEnd takes nothing returns nothing
            if not .isOpened then
                call BJDebugMsg("There is no opened file.")
                return
            endif
            
            //bla bla
            
            set .isOpened = false
        endmethod
        
        public static method print takes string text returns nothing
            if not .isOpened then
                call BJDebugMsg("There is no opened file.")
                return
            endif
            
            //bla bla
        endmethod

Safety check ;)

In fact because the generated .bat file has a lot of syntax errors, for big files it would take a lot of time
Not to mention that my .txt file is about 300k lines... Dont tell me it takes long.
 
Last edited:
if you can read a text file
You can't sadly simply read from a .txt file with jass I think. The file should have some jass interaction, so PreLoadFiles action that can be called with Preloader and then
some string exchange, like:
Code:
function PreloadFiles takes nothing returns nothing

    call SetPlayerName(Player(0), Sting_1 )
    call SetPlayerName(Player(1), Sting_2)

endfunction
Probably File IO should be just used for reading.
This method is just to write a batch/text file.
And, yeh, as you run it manualy to create wanted txt, it's not really automative. :<

In fact because the generated .bat file has a lot of syntax errors, for big files it would take a lot of time for the .bat parser to report those like I've mentioned here.
Unless there's a way to silence them like redirecting stderr to the windows equivalent of /dev/null or something.
Yeh, the whole extra crap makes it even a worse .bat file I guess. But result is what's important I guess.
I'm not too familar with how to increase performance with it, and maybe some know faster commands to use, but idk if it would change too much.. maybe.

Why not two functions instead?:
I think I didn't get it to work properly or elegantly like this. I ended up always with some shit, so I finaly just enforced to define a flag for each string-print.
But now I have to define the Start and the End of "a same line". If you can implement it better we might change it, had no luck yester.day

Safety check ;)
Man, this is just for special cases anyway, ^^ if one use it wrongly with reading the example you anyways should not use such things. ;D
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
I suggest using regular escape sequences...why do you need to make extra work, both for yourself, and for the users, instead of using a standard feature of every language in existence that supports strings?
\r
\n
\t
etc.

There is no escape sequence for "beginning of line", of course, because using that makes no sense whatsoever (you write forward, not backward).
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
You currently have code that transforms a string in such a way that it prints in a new line.

I never used these functions, nor have I touched Jass in years, so I have no clue how that works.

Regardless, since you have a function that does this, it follows that you can take any string with standard \n new lines in it, and transform it in such a way that you can send (possibly over a few iterations) everything with the proper new lines.

You are exposing weird constants, instead of supporting a standard feature of the language.
Even a split to print and println feels so much more natural than adding a constant as a second argument.
 
It's actually not that weird as it looks at the start, it's some abuse of "^" caret character, which is natural.
I know what you mean, but I can not truely achieve what you want. But this is anyways only \n emulator, and not needed really required.

... but I still tried to do it with you and aniki suggested with println (not related to the ugly line break), but I only could do it with a bit of an unwanted result..
that is probably why it just didn't work for me when I tried it first.
 

Attachments

  • ads.PNG
    ads.PNG
    1.1 KB · Views: 122
Last edited:
Level 6
Joined
Jul 30, 2013
Messages
282
i cant see how generating a .bat file that generates the actual file you read is significantly more elegant than..

you know just emitting a start and end token when writing and just throwing anything outside of these tokenxs away when reading the file?

i even did some really hacky things with communicating between a war3 map and a local process once and it kind of was less terrible than you might imagine (was a java app tho and uttetly horrible so i died of shame, so much for that project, also would have an issue with orphaned files piling up after their usefulness is over .. yeah you create a lot of crap that way..)
 
Level 6
Joined
Jul 30, 2013
Messages
282
depends..

sometimes it is easier to emit the code that emits the thing you really want..

sometimes it is easier to emit the thing you really want and just throw out the junk later.

in both cases it shouldn't be more than like 3 lines in most languages... 10 if you are forced to use something verbose..
 
Status
Not open for further replies.
Top