• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[vJASS] code arrays...

Status
Not open for further replies.
Level 17
Joined
Jul 17, 2011
Messages
1,864
why didnt blizzard allow us to have code arrays ? ? ?

like

JASS:
code array j 
j[0] = function a1 
//errros!!!!!! kljlkasdjfj

the only way to make a system that would require code arrays is to have a

function which takes some id as a paramater and has to do a massive if then

else block check on that id to know the right if block to execute


so.. does anyone know a good way to implement a code array i cant think of anything.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
why didnt blizzard allow us to have code arrays ? ? ?
Because we used them to delete everyone's maps with a fake DotA Allstars version?

No I am not joking that really is the truth... Some criminals used the typecasting return exploit and code type to make a fake WC3 DotA map which when loaded infected their systems with serious malware.

This is why the typecasting exploit was patched and hashtables, GetHandleId and StringHash natives were added and code arrays were dis-allowed.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
Because we used them to delete everyone's maps with a fake DotA Allstars version?

No I am not joking that really is the truth... Some criminals used the typecasting return exploit and code type to make a fake WC3 DotA map which when loaded infected their systems with serious malware.

This is why the typecasting exploit was patched and hashtables, GetHandleId and StringHash natives were added and code arrays were dis-allowed.
I can't believe I'd say that but thank god there are evil people in this world.

Soo... anyone experienced with coding malware? *looks at preload native*
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
code arrays were not available right from the start, before any discovery of exploits in wc3.

If you really need code dynamically, besides the if/then/else, you can wrap all your functions like

JASS:
function someFunc ...
endfunction

function someFunc_setCodeVar takes nothing returns nothing
    set globalCodeVar = function sampleFunc
endfunction

function anotherFunc ...
endfunction

function anotherFunc_setCodeVar takes nothing returns nothing
    set globalCodeVar = function anotherFunc
endfunction

function getCodeByIndex takes integer i returns code
    call TriggerEvaluate(globalCodeVarTriggers[i])

    return globalCodeVar
endfunction

function init takes nothing returns nothing
    local trigger t

    set globalCodeVarTriggers[1] = CreateTrigger()
    call TriggerAddCondition(t, Condition(function someFunc_setCodeVar))

    set globalCodeVarTriggers[2] = CreateTrigger()
    call TriggerAddCondition(t, Condition(function anotherFunc_setCodeVar))
endfunction

The advantage is simply that you do not have the linear search/you do not have to model a binary search yourself.

As others stated though, there is little need having to have code directly. The containers are sufficient and the functions that make use of code can be mostly replaced.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
Can a struct extend an array?
If so you can create a struct that represents a code/function and use the array outside the struct to do stuff.

Next to that, I cannot think of a way to infect someones pc with malware through WC3.

When struct extends array, it merely means that it should not be instantiated, and it will not generate a create/destroy and allocate/deallocate methods. You can provide them yourself tho.

This is still not valid:

JASS:
struct A extends array
    code c
endstruct

because this will compile into

JASS:
globals
    code array A__c
endglobals

The way to replicate code array is either as WaterKnight proposed, or by using Boolexprs
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
As others stated though, there is little need having to have code directly. The containers are sufficient and the functions that make use of code can be mostly replaced.
True, but there is a significant speed difference involved here, unfortunately.

A typical example of when code arrays would be extremely useful is attaching a function to a struct, for example, for generating custom callbacks in missile systems without having to use textmacros.

Sure, you can do that via triggerconditions and TriggerEvaluate, but it's slow as hell.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Are not like all code invoking functions slow? It's not like there is any direct option.

I always favored functionality. For example my ForGroups look like this, it's not just to pass any function but to add a framework overhead. I did not want to pass native units to the target function but my Unit struct, pass additional event responses and having the thread as a trigger thread offers some advantages.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
And what exactly would be the advantage of a trigger over a single code variable to run if you just use TriggerEvaluate()?

The only reason that comes to my mind is if you want to dynamically attach more than one conditionfunc ... for example when attaching proc effects to an onDamage trigger. And even then you just call for more trouble, as you can not change the order of conditions without removing/adding them again in the right order.

A code array would make this much more lightweight, as now you can just run the functions one by one and inside a single thread, instead of opening a new thread for every single condition. Plus swapping the order would be just as easy.

You know, I'm definitely not a speed freak when it comes to coding in WC3, but for certain applications like onDamage proccs, periodic buff callbacks, etc. this would be a godsend to improve performance.


Heck, I don't even use TriggerConditions for my onDamage events anymore to apply the effects of buffs/debuffs on damage dealt. Instead, I just hardcode everything via a giant if-then-else based case selection, simply because even 50 consecutive if's are faster than one single TriggerEvaluate().

It's basicly the same as ForGroup vs. FoG loops.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
? I said there is no direct function invokeFunc(<code>). There are functions like

JASS:
native ForForce (force whichForce, code callback) returns nothing
native EnumItemsInRect (rect r, boolexpr filter, code actionFunc) returns nothing
native TimerStart (timer whichTimer, real timeout, boolean periodic, code handlerFunc) returns nothing

and I doubt those are faster than TriggerEvaluate - or TimerStart has delay.

If I want to invoke multiple functions dynamically, I write a proper custom list to have full control.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,192
The actual problem with code is that I believe it is internally a type of function pointer. As such if you ever manage to corrupt one you can get the JASS virtual machine to jump to whatever code you want.

In the case of the malware writers I recall them using an integer array but the typecasting exploit to generate a code statement which would jump to the integer array origin address and so begin executing the assembly instructions written inside the integer array.

I am unsure how it still managed to execute (surely the "no execute" bit of the memory pages would throw a segmentation fault?) but it worked and people did use it for malicious purposes.
 
Level 17
Joined
Jul 17, 2011
Messages
1,864
And what exactly would be the advantage of a trigger over a single code variable to run if you just use TriggerEvaluate()?

The only reason that comes to my mind is if you want to dynamically attach more than one conditionfunc ... for example when attaching proc effects to an onDamage trigger. And even then you just call for more trouble, as you can not change the order of conditions without removing/adding them again in the right order.

A code array would make this much more lightweight, as now you can just run the functions one by one and inside a single thread, instead of opening a new thread for every single condition. Plus swapping the order would be just as easy.

You know, I'm definitely not a speed freak when it comes to coding in WC3, but for certain applications like onDamage proccs, periodic buff callbacks, etc. this would be a godsend to improve performance.


Heck, I don't even use TriggerConditions for my onDamage events anymore to apply the effects of buffs/debuffs on damage dealt. Instead, I just hardcode everything via a giant if-then-else based case selection, simply because even 50 consecutive if's are faster than one single TriggerEvaluate().

It's basicly the same as ForGroup vs. FoG loops.

thats insane xD i decided to use ExecuteFunc for buff events but i guess ill have to use conditions since its that much faster
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
thats insane xD i decided to use ExecuteFunc for buff events but i guess ill have to use conditions since its that much faster
ExecuteFunc is even slower than TriggerConditions, as it takes a string, not a function. Also, it breaks compatibility to Vexorian's Map Optimizer if you use String concatenation with it.

Been there, done that. I once thought it was a "smart" idea to name functions like the names of abilities cast to run my spell specific code with ExecuteFunc(GetAbilityName()). And then I ran the map optimizer and noticed that this requires to turn of string compression ... which made my map 300 kilobytes bigger in size.

--> back to triggerconditions and registry I went
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
you can invoke code by yourself, and the game will not do memory bound checking, or even check if such function exists(check DSG's post about malware being spread by warcraft 3), but trigger most likely has some in-built mechanics for this.

This is only speculation tho, the reason can be whatever
 
Status
Not open for further replies.
Top