Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

129ifier Automated Script

Discussion in 'The Lab' started by Retera, Apr 15, 2018.

?

Is it a good idea?

Poll closed Apr 27, 2018.
  1. Yes

    7 vote(s)
    87.5%
  2. No

    1 vote(s)
    12.5%
  1. Retera

    Retera

    Tool Reviewer

    Joined:
    Apr 19, 2008
    Messages:
    1,051
    Resources:
    27
    Models:
    18
    Tools:
    2
    Maps:
    6
    Reforged HD Models:
    1
    Resources:
    27
    I have this idea that you could write a program where you choose a map (even if it is optimized and protected) and then it ports the map to 1.29, fixing any compatibility issues automatically.

    What is any reason not to do this? I did not make it yet, but I believe it could be done. DrSuperGood created a Java lib for BLPs that is supposed to be super good so we should be able to tell which BLPs are "corrupted" as per the 1.29 definition. Also, for maps from before Patch 1.24, there is a forward port for any return bug system that can be done in an automated way which I used to produce a running version of the TToR mod (which I last had working on 1.21) that worked on 1.28.

    We know the scope of what must be done to port a map into the modern environment. Why don't we have this automatic updater tool? Any reason it couldn't be done (in case I try to write it later)?

    Then we could begin to unify the existing community and get people stuck on 1.26 or 1.28 to have their maps run on 1.29.

    Obviously memory hack would not be supported because you can't automatically move that stuff to 1.29 because it's a bad idea that shouldn't be supported and it's actually bad for me to mention it here as though it was ever a legitimate development decision made by any map developer to use such a thing. But last night I popped open old RPG maps made for Patch 1.21 and before, and played them in widescreen on 1.29, and all of these old maps worked flawlessly. The only places where little API obscurities have broken recent maps is when people tried to do illogical but functional operations -- such as BLPs with glitched mipmaps for smaller filesize and JASS stuff with the return bug, which was removed in 1.22/1.23 under the erroneous assumption that removing it would fix i2c. Hashtables were added to try to give maps the same general API behavior as the return bug, but pre-122 return bug maps all died. Removing the return bug didn't fix i2c, though, and so it was later in 1.27/1.28 where i2c memory hacking was legitimately removed by disallowing JASS bytecode to assign a value to the pointer of an array variable.

    These updates have created little bizarre schizms in the community of people who just want to play the game and get things done. Yet, no update was unknown, and no update legitimately stopped previous legitimate in-game behavior from being available. And so, logically, all content authors have created should be playable on the unified modern Warcraft III.

    Edit: This application should also include a UITile05 and UITile06 generator, operating to the best of it's ability
     
    Last edited: Apr 15, 2018
  2. Kakerate

    Kakerate

    Joined:
    Oct 18, 2013
    Messages:
    482
    Resources:
    0
    Resources:
    0
    actboy would probably dispute whether memory hacking was "legitimately removed" in 1.28 on account of him running a LUA engine through war3 on that patch ( ͡° ͜ʖ ͡°)
     
  3. Retera

    Retera

    Tool Reviewer

    Joined:
    Apr 19, 2008
    Messages:
    1,051
    Resources:
    27
    Models:
    18
    Tools:
    2
    Maps:
    6
    Reforged HD Models:
    1
    Resources:
    27
    For as long as Blizzard is releasing patches again, exploiting them to break the system in odd implementation dependent ways that will change and stop working in subsequent patches is not something I want to be involved with. Whatever it is I might wish to accomplish with this game engine, I will always have an easier time of it by bugging Blizzard themselves than by caring about the madness of something like an unintended lua engine running in the game client through exploitation.
    I should not even have mentioned such a thing exists.

    But, on topic, I noticed that I received rep from you saying you think 129ifier is a good idea. I appreciate the feedback.
     
  4. actboy168

    actboy168

    Joined:
    May 1, 2012
    Messages:
    95
    Resources:
    1
    Tools:
    1
    Resources:
    1
    I need to point out that I have a patch on the lua engine, but it does not use any memory hacks. It will not do anything to inject itself into war3. The usual scenario where people use the lua engine is that their war3 has already patched this patch.

    However, some people use the memory hack to inject patches into war3 on the map, but this has nothing to do with me. I personally do not recommend anyone to use the memory hack. 1.29 disabling the memory hack is too late, it should appear at 1.28, and even blz should provide an earlier war3 fix patch.
     
  5. actboy168

    actboy168

    Joined:
    May 1, 2012
    Messages:
    95
    Resources:
    1
    Tools:
    1
    Resources:
    1
    I am more concerned about how many incompatible changes with older versions. Does it have a list?
     
  6. apsyll

    apsyll

    Joined:
    Aug 28, 2015
    Messages:
    212
    Resources:
    1
    Maps:
    1
    Resources:
    1
    I think this program would be really usefull.
    One idea is coming up as I read this, could it be possible to give it always the newest update informations and this will update the maps towards the information you feed this program.
    I never really bothered with cracking open the files so I don't know what it takes to do this.
    From my idea how it works, it would be awsome you can dynamicly feed the patch 1.29 libraries to the program and it updates all maps to this patch and when blizzard push update 1.3 you just extrude the new libraries and feed the program with them.
     
  7. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    453
    Resources:
    2
    Tools:
    1
    Tutorials:
    1
    Resources:
    2
    Hey, is your injectable Lua engine public? I remember seeing a Lua engine somewhere else, but it was only supported on version 1.27 IIRC, and then the author disappeared. I would really appreciate if you could share it with the world!
     
  8. actboy168

    actboy168

    Joined:
    May 1, 2012
    Messages:
    95
    Resources:
    1
    Tools:
    1
    Resources:
    1
    The lua engine is included in YDWE, which currently has no separate version, although you can easily extract it from YDWE. Just like someone put it on the map and use memory hack to inject war3.

    This is YDWE's repo
    actboy168/YDWE

    This is a thread a long time ago
    A Lua Engine for Warcraft 3

    I don't know much about the habits of English players and English map authors. This may be the biggest reason why I didn't share my work.
     
  9. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    I think it'd be an amazing idea. Definitely very challenging though.

    One issue you might run into is protected maps. More than half of the compatibility update requests I've gotten were for protected maps, and it adds some complications to the coding process (a lot of mpq libraries assume there is a listfile. StormLib and a few others will work fine without one, but they cannot edit the MPQ unless you generate the listfile, so you'll have to write a namebreaker/name-searcher [which isn't too bad, just is a little annoying]).

    The other annoying thing is that it is hard to completely fix the return bug. Finding the problem-lines is pretty easy, pjass will report errors for the lines that have bad returns:
    lep/pjass
    But fixing it isn't always straightforward. There were at least 3 different major libraries that used the return bug (Vexorian's Caster System, Vexorian's Table, KaTTaNa's Local Handle Vars), and all three of them had a generic "AttachObject"/"SetHandleHandle" function:
    Code (vJASS):

    function AttachObject takes handle h, string label, handle x returns nothing
        local string k=I2S(CS_H2I(h))
        if(x==null)then
            call FlushStoredInteger(udg_cscache,k,label)
        else
            call StoreInteger(udg_cscache,k,label,CS_H2I(x))
        endif
    endfunction


    There is a way to fix that, but it is a little tricky. If you see someone use "AttachObject(...)" where "x" is a timer, you'll replace it with "AttachTimer(...)". That is easy to fix by hand, but a lot trickier to do in code since you'll have to build some AST, and in some cases, infer the type that a person is trying to use (e.g. someone uses a handle variable instead of a more specific type).

    I would probably break it up into smaller pieces at first:
    • First, add 1.29 fixes and warnings
    • Just report 1.24 issues at first. If you have time after that, write some rules to fix them. It is okay if you don't handle extreme cases like the one above imo. Just replacing H2I() alone will probably fix a lot of broken maps.
     
  10. Kyrbi0

    Kyrbi0

    Joined:
    Jul 29, 2008
    Messages:
    8,433
    Resources:
    2
    Models:
    1
    Maps:
    1
    Resources:
    2
    Great idea, and send like it would be of worth to the community.

    As a sidenote, I love this sentiment:
    It's the way I've always done things. Feels goodman.jpg : )
     
  11. Retera

    Retera

    Tool Reviewer

    Joined:
    Apr 19, 2008
    Messages:
    1,051
    Resources:
    27
    Models:
    18
    Tools:
    2
    Maps:
    6
    Reforged HD Models:
    1
    Resources:
    27
    @actboy168 fixing return bug is easier than you think. There's a bug where a local and global var with same name form a C Union that leandrotp described when he reported the new memory exploits to Blizzard Entertainment. They understood the fix was to stop arbitrary memory access via JASS array assignment, so this time Blizzard did not fix the return bug and instead fixed the JASS bytecode to disallow "set" keyword being used an array variable's internal memory pointer. So, they left in the return bug. You can take any return bug function and write it with 30 lines of code and an extra global for each variable type.

    Edit: as such, all maps should be playable in 1.29 or else *somebody is not doing their job*!!!

    Edit: and this fix can be done in an automated fashion
     
    Last edited: Apr 18, 2018
  12. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,793
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
    The return bug no longer works on patch 1.29.0.

    Ladik's MPQ editor contains a deep scanning function and it works very well.

    I have fixed this in multiple maps by doing something like this:

    Code (vJASS):
    function H2I takes handle h returns integer
        return GetHandleId(h)
    endfunction

    function FlushHandleLocals takes handle h returns nothing
        call FlushStoredMission(udg_gc_handlevars, I2S(H2I(h)) )
    endfunction

    function SetHandleInteger takes handle h, string name, integer i returns nothing
        call StoreInteger(udg_gc_handlevars, I2S(H2I(h)), name, i)
    endfunction

    function GetHandleInteger takes handle h, string name returns integer
        return GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)
    endfunction

    function SetHandleReal takes handle h, string name, real r returns nothing
        call StoreReal(udg_gc_handlevars, I2S(H2I(h)), name, r)
    endfunction

    function GetHandleReal takes handle h, string name returns real
        return GetStoredReal(udg_gc_handlevars, I2S(H2I(h)),name)
    endfunction

    function SetHandleHandle takes handle h, string name, handle value returns nothing
        call StoreInteger(udg_gc_handlevars, I2S(H2I(h)), name, H2I(value))
    endfunction

    function GetHandleUnit takes handle h, string name returns unit
        call SaveFogStateHandle(udg_HT_Typecast, 0, 0, ConvertFogState(GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)))
        return LoadUnitHandle(udg_HT_Typecast, 0, 0)
    endfunction

    function SetHandleBoolean takes handle h, string name, boolean b returns nothing
        call StoreBoolean(udg_gc_handlevars, I2S(H2I(h)), name, b)
    endfunction

    function GetHandleBoolean takes handle h, string name returns boolean
        return GetStoredBoolean(udg_gc_handlevars, I2S(H2I(h)),name)
    endfunction

    function SetHandleString takes handle h, string name, string s returns nothing
        call StoreString(udg_gc_handlevars, I2S(H2I(h)), name, s)
    endfunction

    function GetHandleString takes handle h, string name returns string
        return GetStoredString(udg_gc_handlevars, I2S(H2I(h)),name)
    endfunction

    function GetHandleForce takes handle h, string name returns force
        call SaveFogStateHandle(udg_HT_Typecast, 0, 0, ConvertFogState(GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)))
        return LoadForceHandle(udg_HT_Typecast, 0, 0)
    endfunction

    function GetHandleWeatherEffect takes handle h, string name returns weathereffect
        return null
    endfunction

    function GetHandleLocation takes handle h, string name returns location
        call SaveFogStateHandle(udg_HT_Typecast, 0, 0, ConvertFogState(GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)))
        return LoadLocationHandle(udg_HT_Typecast, 0, 0)
    endfunction

    function GetHandlePlayer takes handle h, string name returns player
        call SaveFogStateHandle(udg_HT_Typecast, 0, 0, ConvertFogState(GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)))
        return LoadPlayerHandle(udg_HT_Typecast, 0, 0)
    endfunction

    function GetHandleTimer takes handle h, string name returns timer
        call SaveFogStateHandle(udg_HT_Typecast, 0, 0, ConvertFogState(GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)))
        return LoadTimerHandle(udg_HT_Typecast, 0, 0)
    endfunction

    function GetHandleTriggerAction takes handle h, string name returns triggeraction
        call SaveFogStateHandle(udg_HT_Typecast, 0, 0, ConvertFogState(GetStoredInteger(udg_gc_handlevars, I2S(H2I(h)),name)))
        return LoadTriggerActionHandle(udg_HT_Typecast, 0, 0)
    endfunction
     
  13. Retera

    Retera

    Tool Reviewer

    Joined:
    Apr 19, 2008
    Messages:
    1,051
    Resources:
    27
    Models:
    18
    Tools:
    2
    Maps:
    6
    Reforged HD Models:
    1
    Resources:
    27
    I felt a great disturbance in the Force, as if millions of voices suddenly cried out in terror and were suddenly silenced. I fear something terrible has happened.
     
  14. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    you're right. and lmao that reminds me I made a shitty way to write
    GetHandleHandle
    as well, if you don't care for performance:
    Code (vJASS):
    globals
        unit gc_handle_unit = null
        timer gc_handle_timer = null
    endglobals

    function GetHandleHandle takes handle h, string name returns handle

        // check if unit
        set gc_handle_unit = GetHandleUnit(h, name)
        if gc_handle_unit != null then
             return gc_handle_unit
        endif

        // check if timer
        set gc_handle_timer = GetHandleTimer(h, name)
        if gc_handle_timer != null then
            return gc_handle_timer
        endif

        // etc. lol

        return null

    endfunction


    iirc, it was something like that. JASS dynamic type checking at its finest! So it shouldn't be too bad to automate at all.
     
  15. Aniki

    Aniki

    Joined:
    Nov 7, 2014
    Messages:
    564
    Resources:
    6
    Tools:
    1
    Maps:
    1
    Spells:
    1
    JASS:
    3
    Resources:
    6
    Noooo (in a darth-vadery kind of voice) oooouuuu...

    Now Blizzard's "hidden"
    Set|GetTriggerUserData
    cannot be used! Oh well...

    Code (vJASS):

    library libtriggeruserdata
    globals
        integer libtud_integer // not used, needed to fool jasshelper
        integer l__libtud_integer
        boolean libtud_boolean
        boolean l__libtud_boolean
    endglobals

    private function set_integer takes integer i returns nothing
        set l__libtud_integer = i
        return // prevent jasshelper from inlining this function
    endfunction

    private function set_boolean takes boolean b returns nothing
        set l__libtud_boolean = b
        return
    endfunction

    function libtud_enable_boolean_integer_typecasting takes nothing returns nothing
        local boolean libtud_integer
        local integer libtud_boolean
    endfunction

    //# +nosemanticerror
    private function cast_int_to_bool takes integer i returns boolean
        call set_integer(i)
        return l__libtud_integer
    endfunction

    //# +nosemanticerror
    private function cast_bool_to_int takes boolean b returns integer
        call set_boolean(b)
        return l__libtud_boolean
    endfunction

    function SetTriggerUserData takes trigger t, integer x returns nothing
        call TriggerWaitOnSleeps(t, cast_int_to_bool(x))
    endfunction

    function GetTriggerUserData takes trigger t returns integer
        return cast_bool_to_int(IsTriggerWaitOnSleeps(t))
    endfunction

    endlibrary
     
     
  16. GhostWolf

    GhostWolf

    Joined:
    Jul 29, 2007
    Messages:
    4,952
    Resources:
    2
    Tools:
    1
    Tutorials:
    1
    Resources:
    2
    What's the reason to use typecasting over a hashtable in this case?
     
  17. Retera

    Retera

    Tool Reviewer

    Joined:
    Apr 19, 2008
    Messages:
    1,051
    Resources:
    27
    Models:
    18
    Tools:
    2
    Maps:
    6
    Reforged HD Models:
    1
    Resources:
    27
    There were functions you could write with typecasting that you couldn't write with hashtables. Consider down casting. I can set a local handle type variable equal to a unit, but can't set a local unit variable to a handle. But, with the return bug, you could, and more importantly people did. So there are gazillions of ancient maps and mods that can never run on 1.29 without a full redesign (which will never happen).
     
  18. csh

    csh

    Joined:
    May 27, 2017
    Messages:
    19
    Resources:
    0
    Resources:
    0
    You dont know the truth, there is another way to writing memory with return bug that leandrotp didnt report to blizzard, and memory hack system was still working on patch 1.28, so blizzard fixed the return bug on 1.29 finally.
     
  19. Retera

    Retera

    Tool Reviewer

    Joined:
    Apr 19, 2008
    Messages:
    1,051
    Resources:
    27
    Models:
    18
    Tools:
    2
    Maps:
    6
    Reforged HD Models:
    1
    Resources:
    27
    That seemed to be what TriggerHappy was saying. That's why I quoted Obi Wan's little speech when he felt the Death Star destroy the planet Alderaan
     
  20. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,545
    Resources:
    9
    Models:
    1
    Icons:
    2
    Maps:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    9
    What is this, an off-Topic crossover episode?

    Pleasantries aside, this would greatly benefit those who would be drawn to mapmaking all over again, those who had abandoned their works long ago.