• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Convert integer to handle?

Status
Not open for further replies.
Level 13
Joined
Jan 2, 2016
Messages
973
Is it possible to convert integer to handle?
Like.. if I do something like this:
JASS:
call SetUnitUserData(GetSpellTargetUnit(), GetHandleId(GetTriggerUnit()))

// in another trigger:
local unit u = /*some function to get the handle*/(GetUnitUserData(GetTriggerUnit()))
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,184
That should work in theory.

The thing that could screw it up is that the handle number is too big for the integer.

edit: seems to work for me.
JASS:
unit u = CreateUnit(id, unitid, x, y, face);
			SetUnitUserData(u, GetHandleId(u));
			BJDebugMsg(I2S(GetHandleId(u)));
			BJDebugMsg(I2S(GetUnitUserData(u)));

This writes the same number twice for me.

edit2: It should be said that you can't use it in an array though. Because an array can only be 8k max, and a handle number is much higher.
In vjass you can extend it to 400k, but that's not enough.
set whatever[GetUnitUserData()] = something //will not work to make things MUI
 
Level 13
Joined
Jan 2, 2016
Messages
973
That wasn't my question tho :p
I was asking about something more like (will edit your code a bit to show you what I meant):
JASS:
local unit u = CreateUnit(id, unitid, x, y, face)
call SetUnitUserData(GetTriggerUnit(), GetHandleId(u))
call KillUnit( /*some func*/(GetUnitUserData(GetTriggerUnit())))
I'm curious is there any function I can put in the "some func" field :p
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The approach is pretty useless, but not impossible:
JASS:
globals
    hashtable udg_TypeCastHashtable = InitHashtable()
endglobals

library TypeCasting
    
    //BooleanExpr
    function Integer2BooleanExpr takes integer i returns boolexpr
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadBooleanExprHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2BooleanExpr takes handle h returns boolexpr
        return Integer2BooleanExpr(GetHandleId(h))
    endfunction
    function BooleanExpr2Handle takes boolexpr b returns handle
        return b
    endfunction
    
    //Button
    function Integer2Button takes integer i returns button
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadButtonHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Button takes handle h returns button
        return Integer2Button(GetHandleId(h))
    endfunction
    function Button2Handle takes button b returns handle
        return b
    endfunction
    
    //DefeatCondition
    function Integer2DefeatCondition takes integer i returns defeatcondition
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadDefeatConditionHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2DefeatCondition takes handle h returns defeatcondition
        return Integer2DefeatCondition(GetHandleId(h))
    endfunction
    function DefeatCondition2Handle takes defeatcondition d returns handle
        return d
    endfunction
    
    //Destructable
    function Integer2Destructable takes integer i returns destructable
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadDestructableHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Destructable takes handle h returns destructable
        return Integer2Destructable(GetHandleId(h))
    endfunction
    function Destructable2Handle takes destructable d returns handle
        return d
    endfunction
    
    //Dialog
    function Integer2Dialog takes integer i returns dialog
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadDialogHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Dialog takes handle h returns dialog
        return Integer2Dialog(GetHandleId(h))
    endfunction
    function Dialog2Handle takes dialog d returns handle
        return d
    endfunction
    
    //Effect
    function Integer2Effect takes integer i returns effect
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadEffectHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Effect takes handle h returns effect
        return Integer2Effect(GetHandleId(h))
    endfunction
    function Effect2Handle takes effect e returns handle
        return e
    endfunction
    
    //FogModifier
    function Integer2FogModifier takes integer i returns fogmodifier
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadFogModifierHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2FogModifier takes handle h returns fogmodifier
        return Integer2FogModifier(GetHandleId(h))
    endfunction
    function FogModifier2Handle takes fogmodifier f returns handle
        return f
    endfunction
    
    //FogState
    function Integer2FogState takes integer i returns fogstate
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadFogStateHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2FogState takes handle h returns fogstate
        return Integer2FogState(GetHandleId(h))
    endfunction
    function FogState2Handle takes fogstate f returns handle
        return f
    endfunction
    
    //Force
    function Integer2Force takes integer i returns force
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadForceHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Force takes handle h returns force
        return Integer2Force(GetHandleId(h))
    endfunction
    function Force2Handle takes force f returns handle
        return f
    endfunction
    
    //Group
    function Integer2Group takes integer i returns group
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadGroupHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Group takes handle h returns group
        return Integer2Group(GetHandleId(h))
    endfunction
    function Group2Handle takes group g returns handle
        return g
    endfunction
    
    //Hashtable
    function Integer2Hashtable takes integer i returns hashtable
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadHashtableHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Hashtable takes handle h returns hashtable
        return Integer2Hashtable(GetHandleId(h))
    endfunction
    function Hashtable2Handle takes hashtable h returns handle
        return h
    endfunction
    
    //Image
    function Integer2Image takes integer i returns image
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadImageHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Image takes handle h returns image
        return Integer2Image(GetHandleId(h))
    endfunction
    function Image2Handle takes image i returns handle
        return i
    endfunction
    
    //Item
    function Integer2Item takes integer i returns item
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadItemHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Item takes handle h returns item
        return Integer2Item(GetHandleId(h))
    endfunction
    function Item2Handle takes item i returns handle
        return i
    endfunction
    
    //ItemPool
    function Integer2ItemPool takes integer i returns itempool
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadItemPoolHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2ItemPool takes handle h returns itempool
        return Integer2ItemPool(GetHandleId(h))
    endfunction
    function ItemPool2Handle takes itempool i returns handle
        return i
    endfunction
    
    //Leaderboard
    function Integer2Leaderboard takes integer i returns leaderboard
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadLeaderboardHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Leaderboard takes handle h returns leaderboard
        return Integer2Leaderboard(GetHandleId(h))
    endfunction
    function Leaderboard2Handle takes leaderboard l returns handle
        return l
    endfunction
    
    //Lightning
    function Integer2Lightning takes integer i returns lightning
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadLightningHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Lightning takes handle h returns lightning
        return Integer2Lightning(GetHandleId(h))
    endfunction
    function Lightning2Handle takes lightning l returns handle
        return l
    endfunction
    
    //Location
    function Integer2Location takes integer i returns location
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadLocationHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Location takes handle h returns location
        return Integer2Location(GetHandleId(h))
    endfunction
    function Location2Handle takes location l returns handle
        return l
    endfunction
    
    //Multiboard
    function Integer2Multiboard takes integer i returns multiboard
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadMultiboardHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Multiboard takes handle h returns multiboard
        return Integer2Multiboard(GetHandleId(h))
    endfunction
    function Multiboard2Handle takes multiboard m returns handle
        return m
    endfunction
    
    //MultiboardItem
    function Integer2MultiboardItem takes integer i returns multiboarditem
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadMultiboardItemHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2MultiboardItem takes handle h returns multiboarditem
        return Integer2MultiboardItem(GetHandleId(h))
    endfunction
    function MultiboardItem2Handle takes multiboarditem m returns handle
        return m
    endfunction
    
    //Player
    function Integer2Player takes integer i returns player
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadPlayerHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Player takes handle h returns player
        return Integer2Player(GetHandleId(h))
    endfunction
    function Player2Handle takes player p returns handle
        return p
    endfunction
    
    //Quest
    function Integer2Quest takes integer i returns quest
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadQuestHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Quest takes handle h returns quest
        return Integer2Quest(GetHandleId(h))
    endfunction
    function Quest2Handle takes quest q returns handle
        return q
    endfunction
    
    //QuestItem
    function Integer2QuestItem takes integer i returns questitem
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadQuestItemHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2QuestItem takes handle h returns questitem
        return Integer2QuestItem(GetHandleId(h))
    endfunction
    function QuestItem2Handle takes questitem q returns handle
        return q
    endfunction
    
    //Rect
    function Integer2Rect takes integer i returns rect
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadRectHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Rect takes handle h returns rect
        return Integer2Rect(GetHandleId(h))
    endfunction
    function Rect2Handle takes rect r returns handle
        return r
    endfunction
    
    //Region
    function Integer2Region takes integer i returns region
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadRegionHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Region takes handle h returns region
        return Integer2Region(GetHandleId(h))
    endfunction
    function Region2Handle takes region r returns handle
        return r
    endfunction
    
    //Sound
    function Integer2Sound takes integer i returns sound
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadSoundHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Sound takes handle h returns sound
        return Integer2Sound(GetHandleId(h))
    endfunction
    function Sound2Handle takes sound s returns handle
        return s
    endfunction
    
    //TextTag
    function Integer2TextTag takes integer i returns texttag
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTextTagHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2TextTag takes handle h returns texttag
        return Integer2TextTag(GetHandleId(h))
    endfunction
    function TextTag2Handle takes texttag t returns handle
        return t
    endfunction
    
    //Timer
    function Integer2Timer takes integer i returns timer
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTimerHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Timer takes handle h returns timer
        return Integer2Timer(GetHandleId(h))
    endfunction
    function Timer2Handle takes timer t returns handle
        return t
    endfunction
    
    //TimerDialog
    function Integer2TimerDialog takes integer i returns timerdialog
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTimerDialogHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2TimerDialog takes handle h returns timerdialog
        return Integer2TimerDialog(GetHandleId(h))
    endfunction
    function TimerDialog2Handle takes timerdialog t returns handle
        return t
    endfunction
    
    //Trackable
    function Integer2Trackable takes integer i returns trackable
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTrackableHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Trackable takes handle h returns trackable
        return Integer2Trackable(GetHandleId(h))
    endfunction
    function Trackable2Handle takes trackable t returns handle
        return t
    endfunction
    
    //Trigger
    function Integer2Trigger takes integer i returns trigger
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTriggerHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2WTrigger takes handle h returns trigger
        return Integer2Trigger(GetHandleId(h))
    endfunction
    function Trigger2Handle takes trigger t returns handle
        return t
    endfunction
    
    //TriggerAction
    function Integer2TriggerAction takes integer i returns triggeraction
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTriggerActionHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2TriggerAction takes handle h returns triggeraction
        return Integer2TriggerAction(GetHandleId(h))
    endfunction
    function TriggerAction2Handle takes triggeraction t returns handle
        return t
    endfunction
    
    //TriggerCondition
    function Integer2TriggerCondition takes integer i returns triggercondition
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTriggerConditionHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2TriggerCondition takes handle h returns triggercondition
        return Integer2TriggerCondition(GetHandleId(h))
    endfunction
    function TriggerCondition2Handle takes triggercondition t returns handle
        return t
    endfunction
    
    //TriggerEvent
    function Integer2TriggerEvent takes integer i returns event
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadTriggerEventHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2TriggerEvent takes handle h returns event
        return Integer2TriggerEvent(GetHandleId(h))
    endfunction
    function TriggerEvent2Handle takes event e returns handle
        return e
    endfunction
    
    //Ubersplat
    function Integer2Ubersplat takes integer i returns ubersplat
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadUbersplatHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Ubersplat takes handle h returns ubersplat
        return Integer2Ubersplat(GetHandleId(h))
    endfunction
    function Ubersplat2Handle takes ubersplat u returns handle
        return u
    endfunction
    
    //Unit
    function Integer2Unit takes integer i returns unit
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadUnitHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Unit takes handle h returns unit
        return Integer2Unit(GetHandleId(h))
    endfunction
    function Unit2Handle takes unit u returns handle
        return u
    endfunction
    
    //UnitPool
    function Integer2UnitPool takes integer i returns unitpool
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadUnitPoolHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2UnitPool takes handle h returns unitpool
        return Integer2UnitPool(GetHandleId(h))
    endfunction
    function UnitPool2Handle takes unitpool u returns handle
        return u
    endfunction
    
    //Widget
    function Integer2Widget takes integer i returns widget
        call SaveFogStateHandle(udg_TypeCastHashtable, 0, 0, ConvertFogState(i))
        return LoadWidgetHandle(udg_TypeCastHashtable, 0, 0)
    endfunction
    function Handle2Widget takes handle h returns widget
        return Integer2Widget(GetHandleId(h))
    endfunction
    function Widget2Handle takes widget w returns handle
        return w
    endfunction
    
endlibrary

Also, your example should be more like a usefull example.
It is useless to do SomeFunction(Integer2Unit(GetHandleId(GetTriggerUnit())))
You should do SomeFunction(GetTriggerUnit()) instead.
So you should provide a better example.
 
Level 13
Joined
Jan 2, 2016
Messages
973
Well, yeah. This approach doesn't open any new possibilities - it just offers alternatives xP
GetHandleId is much lighter than Integer2Handle function, so it wouldn't be really efficient to do things this way.

I kind a asked for the sake of knowledge :p

Any ideas WHY is it working like this btw? Is it just a bug, or there is some logic behind it?
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The point is that ConvertFogState() does return an actual object of the game independent of what the id was.
And SaveFogStateHandle() is able to store that object in a hashtable which can only store one handle in each hash at a time, so Load...Handle will load that object from the hashtable and return the actual object of which the id belongs.

But this would only be usefull to store a generic type and load in the specific type by type casting... however, that is not necessary as you will have to be able to know what type you actually want in the first place in which case you can just make an array of the corresponding handle versions that you want to store/load.

So, nice trick, but hardly any usefullness.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,223
Is it possible to convert integer to handle?
Yes, no and it used to be.

In the past I2H was common place. It used the type casting exploit to convert an integer value into a handle. Combined with H2I and game caches it was a dominate storage method of the intellectual developer until they realised about string leaks and such.

Current it is theoretically not possible as they officially patched out the exploit for security reasons.

Reality is it is still possible. Either via new forms of type casting exploit, or with some other exploit. Although I doubt if what is shown above works (early development of hash tables caused crashes if types were not correct), it might as they did seem to fix many of the crashes so it might be possible to type cast using hashtables. Additionally other more obscure forms of the type casting exploit still do exist as shown in the arbitrary code thread which will convert from integer to handle.

The truth is you never should need do it. It is just plain bad programming. Unlike handle variables, it does not reference count track the handle you are storing as it thinks it is an integer. This means the handle can be recycled and given to another object, possibly of a different type, yet is still represented by your integer. If you type cast and then use any manner of bug could occur from fatal error to strange stuff in game. If someone comes to maintain your code they might not be aware of this and so spend hours trying to fix bugs.

Ultimately you never want to lose track of what type something is. The reason it was used in the past was because type safe storage did not exist.
 
Status
Not open for further replies.
Top