System Agent Stats

Jesus4Lyf

Good Idea™
Reaction score
397
Agent Stats​
Version 1.2.0​

Requirements:
- Jass NewGen

Code:
JASS:
//
//        _   ___ ___ __  _ _____   ___ _____ _ _____ ___ 
//       /_\ / __| __|  \| |_   _| / __|_   _/_\_   _/ __|
//      / _ \ (_ | _|| \ \ | | |   \__ \ | |/ _ \| | \__ \
//     /_/ \_\___|___|_|\__| |_|   |___/ |_/_/ \_\_| |___/
//                                    By Jesus4Lyf. v1.2.0.
//
//      What is AgentStats?
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          AgentStats is a handle count debugging tool for monitoring the number of
//          handles in game, in debug mode.
//          
//      How to implement?
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          Create a new trigger object called AgentStats, go to 'Edit -> Convert
//          to Custom Text', and replace everything that's there with this script.
//          
//          Then, import the "trackagents.j" file to "war3mapImported\trackagents.j".
//
//      Commands Provided:
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          Type the following commands in game:
//          
//          -count                  Displays the number of agents in the game.
//          -count <handle>         Displays the number of <handle>s in the game.
//          -stats                  Displays agent stats.
//          -stats <handle>         Displays <handle> stats.
//          
//          Examples:
//             -stats timer
//             -count triggerevent
//             -stats
//             -count widget
//             -count
// 
library AgentStats initializer OnInit
    globals
        private constant integer SEARCH_DEGREE=20
        private constant string COMMAND_CHAR="-"
        private constant integer COMMAND_CHAR_LENGTH=StringLength(COMMAND_CHAR)
        private constant string TRACKER_PATH="war3mapImported\\trackagents.j"
    endglobals
    
    globals
        private string array TypeName
        private hashtable NameToType=InitHashtable()
        private constant integer TYPE_UNKNOWN           =0
        private constant integer TYPE_WIDGET            =1
        private constant integer TYPE_TRIGGER           =2
        private constant integer TYPE_DESTRUCTABLE      =3
        private constant integer TYPE_ITEM              =4
        private constant integer TYPE_UNIT              =5
        private constant integer TYPE_TIMER             =6
        private constant integer TYPE_HASHTABLE         =7
        private constant integer TYPE_TRIGGEREVENT      =8
        private constant integer TYPE_TRIGGERCONDITION  =9
        private constant integer TYPE_TRIGGERACTION     =10
        private constant integer TYPE_PLAYER            =11
        private constant integer TYPE_GROUP             =12
        private constant integer TYPE_EFFECT            =13
        private constant integer TYPE_LOCATION          =14
        private constant integer TYPE_RECT              =15
        private constant integer TYPE_BOOLEXPR          =16
        private constant integer TYPE_SOUND             =17
        private constant integer TYPE_FORCE             =18
        private constant integer TYPE_UNITPOOL          =19
        private constant integer TYPE_ITEMPOOL          =20
        private constant integer TYPE_QUEST             =21
        private constant integer TYPE_QUESTITEM         =22
        private constant integer TYPE_DEFEATCONDITION   =23
        private constant integer TYPE_TIMERDIALOG       =24
        private constant integer TYPE_LEADERBOARD       =25
        private constant integer TYPE_MULTIBOARDITEM    =26
        private constant integer TYPE_MULTIBOARD        =27
        private constant integer TYPE_TRACKABLE         =28
        private constant integer TYPE_DIALOG            =29
        private constant integer TYPE_BUTTON            =30
        private constant integer TYPE_TEXTTAG           =31
        private constant integer TYPE_LIGHTNING         =32
        private constant integer TYPE_IMAGE             =33
        private constant integer TYPE_UBERSPLAT         =34
        private constant integer TYPE_REGION            =35
        private constant integer TYPE_FOGSTATE          =36
        private constant integer TYPE_FOGMODIFIER       =37
        private constant integer TYPE_ABILITY           =38
        
        private constant integer MAX_TYPE               =38
    endglobals
    private function InitTypeNames takes nothing returns nothing
        local integer i=MAX_TYPE
        set TypeName[TYPE_UNKNOWN]          ="UNKNOWN"
        set TypeName[TYPE_WIDGET]           ="Widget"
        set TypeName[TYPE_TRIGGER]          ="Trigger"
        set TypeName[TYPE_DESTRUCTABLE]     ="Destructable"
        set TypeName[TYPE_ITEM]             ="Item"
        set TypeName[TYPE_UNIT]             ="Unit"
        set TypeName[TYPE_TIMER]            ="Timer"
        set TypeName[TYPE_HASHTABLE]        ="Hashtable"
        set TypeName[TYPE_TRIGGEREVENT]     ="TriggerEvent"
        set TypeName[TYPE_TRIGGERCONDITION] ="TriggerCondition"
        set TypeName[TYPE_TRIGGERACTION]    ="TriggerAction"
        set TypeName[TYPE_PLAYER]           ="Player"
        set TypeName[TYPE_GROUP]            ="Group"
        set TypeName[TYPE_EFFECT]           ="Effect"
        set TypeName[TYPE_LOCATION]         ="Location"
        set TypeName[TYPE_RECT]             ="Rect"
        set TypeName[TYPE_BOOLEXPR]         ="BoolExpr"
        set TypeName[TYPE_SOUND]            ="Sound"
        set TypeName[TYPE_FORCE]            ="Force"
        set TypeName[TYPE_UNITPOOL]         ="UnitPool"
        set TypeName[TYPE_ITEMPOOL]         ="ItemPool"
        set TypeName[TYPE_QUEST]            ="Quest"
        set TypeName[TYPE_QUESTITEM]        ="QuestItem"
        set TypeName[TYPE_DEFEATCONDITION]  ="DefeatCondition"
        set TypeName[TYPE_TIMERDIALOG]      ="TimerDialog"
        set TypeName[TYPE_LEADERBOARD]      ="Leaderboard"
        set TypeName[TYPE_MULTIBOARDITEM]   ="MultiboardItem"
        set TypeName[TYPE_MULTIBOARD]       ="Multiboard"
        set TypeName[TYPE_TRACKABLE]        ="Trackable"
        set TypeName[TYPE_DIALOG]           ="Dialog"
        set TypeName[TYPE_BUTTON]           ="Button"
        set TypeName[TYPE_TEXTTAG]          ="TextTag"
        set TypeName[TYPE_LIGHTNING]        ="Lightning"
        set TypeName[TYPE_IMAGE]            ="Image"
        set TypeName[TYPE_UBERSPLAT]        ="Ubersplat"
        set TypeName[TYPE_REGION]           ="Region"
        set TypeName[TYPE_FOGSTATE]         ="FogState"
        set TypeName[TYPE_FOGMODIFIER]      ="FogModifier"
        set TypeName[TYPE_ABILITY]          ="Ability"
        loop
            call SaveInteger(NameToType,0,StringHash(StringCase(TypeName<i>,false)),i)
            exitwhen i==0
            set i=i-1
        endloop
    endfunction
    
    globals
        private hashtable Read=InitHashtable()
        private hashtable Count=InitHashtable()
        private integer CountInstance=-1
        private integer Sum=0
    endglobals
    //! textmacro AgentStats__Count takes TYPECAPS
        call SaveInteger(Count,CountInstance,TYPE_$TYPECAPS$,LoadInteger(Count,CountInstance,TYPE_$TYPECAPS$)+1)
        set Sum=Sum+1
    //! endtextmacro
    private function CreateInstance takes nothing returns nothing
        local integer i=SEARCH_DEGREE
        local group g
        loop
            exitwhen i==0
            set i=i-1
            call DestroyGroup(CreateGroup())
        endloop
        set g=CreateGroup()
        set i=GetHandleId(g)
        call DestroyGroup(g)
        set g=null
        
        set CountInstance=CountInstance+1
        loop
            exitwhen i==0x100000
            set i=i-1
            call SaveFogStateHandle(Read,0,i,ConvertFogState(i))
            
            if LoadWidgetHandle(Read,0,i)!=null then
                call SaveInteger(Count,CountInstance,TYPE_WIDGET,LoadInteger(Count,CountInstance,TYPE_WIDGET)+1)
                if LoadUnitHandle(Read,0,i)!=null then
                    //! runtextmacro AgentStats__Count(&quot;UNIT&quot;)
                elseif LoadDestructableHandle(Read,0,i)!=null then
                    //! runtextmacro AgentStats__Count(&quot;DESTRUCTABLE&quot;)
                elseif LoadItemHandle(Read,0,i)!=null then
                    //! runtextmacro AgentStats__Count(&quot;ITEM&quot;)
                endif
            elseif LoadTriggerHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;TRIGGER&quot;)
            elseif LoadTimerHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;TIMER&quot;)
            elseif LoadHashtableHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;HASHTABLE&quot;)
            elseif LoadTriggerEventHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;TRIGGEREVENT&quot;)
            elseif LoadTriggerConditionHandle(Read,0,i)!=null then    
                //! runtextmacro AgentStats__Count(&quot;TRIGGERCONDITION&quot;)
            elseif LoadTriggerActionHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;TRIGGERACTION&quot;)
            elseif LoadPlayerHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;PLAYER&quot;)
            elseif LoadGroupHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;GROUP&quot;)
            elseif LoadEffectHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;EFFECT&quot;)
            elseif LoadLocationHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;LOCATION&quot;)
            elseif LoadRectHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;RECT&quot;)
            elseif LoadBooleanExprHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;BOOLEXPR&quot;)
            elseif LoadSoundHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;SOUND&quot;)
            elseif LoadForceHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;FORCE&quot;)
            elseif LoadUnitPoolHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;UNITPOOL&quot;)
            elseif LoadItemPoolHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;ITEMPOOL&quot;)
            elseif LoadQuestHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;QUEST&quot;)
            elseif LoadQuestItemHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;QUESTITEM&quot;)
            elseif LoadDefeatConditionHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;DEFEATCONDITION&quot;)
            elseif LoadTimerDialogHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;DIALOG&quot;)
            elseif LoadLeaderboardHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;LEADERBOARD&quot;)
            elseif LoadMultiboardItemHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;MULTIBOARDITEM&quot;)
            elseif LoadMultiboardHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;MULTIBOARD&quot;)
            elseif LoadTrackableHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;TRACKABLE&quot;)
            elseif LoadDialogHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;DIALOG&quot;)
            elseif LoadButtonHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;BUTTON&quot;)
            elseif LoadTextTagHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;TEXTTAG&quot;)
            elseif LoadLightningHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;LIGHTNING&quot;)
            elseif LoadImageHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;IMAGE&quot;)
            elseif LoadUbersplatHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;UBERSPLAT&quot;)
            elseif LoadRegionHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;REGION&quot;)
            elseif LoadFogStateHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;FOGSTATE&quot;)
            elseif LoadFogModifierHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;FOGMODIFIER&quot;)
            elseif LoadAbilityHandle(Read,0,i)!=null then
                //! runtextmacro AgentStats__Count(&quot;ABILITY&quot;)
            elseif HaveSavedHandle(Read,0,i) then
                //! runtextmacro AgentStats__Count(&quot;UNKNOWN&quot;)
            endif
        endloop
        call SaveInteger(Count,CountInstance,-1,Sum)
        set Sum=0
    endfunction
    
    // Abstraction
    private function GetLastInstance takes nothing returns integer
        return CountInstance
    endfunction
    private function GetTypeCount takes integer whichInstance, integer whichType returns integer
        return LoadInteger(Count,whichInstance,whichType)
    endfunction
    private function GetType takes string typeNameLowerCase returns integer
        return LoadInteger(NameToType,0,StringHash(typeNameLowerCase))
    endfunction
    private function GetTypeName takes integer whichType returns string
        return TypeName[whichType]
    endfunction
    private function GetTotalCount takes integer whichInstance returns integer
        return LoadInteger(Count,whichInstance,-1)
    endfunction
    
    globals
        private integer array Sorted
    endglobals
    private function InitSort takes nothing returns nothing
        local integer i=MAX_TYPE
        loop
            set Sorted<i>=i
            exitwhen i==0
            set i=i-1
        endloop
    endfunction
    private function Sort takes integer whichInstance returns nothing    
        local integer i=1
        local integer j
        local integer val
        loop
            set val=Sorted<i>
            set j=i-1
            loop
                exitwhen j&lt;0 or GetTypeCount(whichInstance,Sorted[j])&gt;GetTypeCount(whichInstance,val)
                set Sorted[j+1]=Sorted[j]
                set j=j-1
            endloop
            set Sorted[j+1]=val
            exitwhen i==MAX_TYPE
            set i=i+1
        endloop
    endfunction
    
    private function CommandCount takes string subject returns nothing
        local integer t=GetType(subject)
        if t!=0 or subject==&quot;unknown&quot; then
            call BJDebugMsg(&quot;Number of &quot;+GetTypeName(t)+&quot;s: &quot;+I2S(GetTypeCount(GetLastInstance(),t)))
        else
            call BJDebugMsg(&quot;Number of agents: &quot;+I2S(GetTotalCount(GetLastInstance())))
        endif
    endfunction
    
    private function CommandStats takes string subject returns nothing
        local integer t=GetType(subject)
        if t!=0 or subject==&quot;unknown&quot; then
            call BJDebugMsg(&quot; &quot;)
            call BJDebugMsg(&quot;  == &quot;+GetTypeName(t)+&quot; Stats ==&quot;)
            call BJDebugMsg(&quot;Currently: &quot;+I2S(GetTypeCount(GetLastInstance(),t))+&quot; exist.&quot;)
            call BJDebugMsg(&quot;Last Scan: &quot;+I2S(GetTypeCount(GetLastInstance()-1,t))+&quot; existed.&quot;)
            call BJDebugMsg(&quot;Post Init: &quot;+I2S(GetTypeCount(0,t))+&quot; existed.&quot;)
            call BJDebugMsg(&quot;Currently, &quot;+GetTypeName(t)+&quot;s make up &quot;+/*
                */R2S(GetTypeCount(GetLastInstance(),t)*100./GetTotalCount(GetLastInstance()))/*
                */+&quot;% of all agents.&quot;)
            call BJDebugMsg(&quot;Since last scan, &quot;+GetTypeName(t)+&quot;s have increased by &quot;+/*
                */I2S(GetTypeCount(GetLastInstance(),t)-GetTypeCount(GetLastInstance()-1,t))/*
                */+&quot;.&quot;)
        else
            call Sort(GetLastInstance())
            call BJDebugMsg(&quot; &quot;)
            call BJDebugMsg(&quot;  == Agent Stats ==&quot;)
            call BJDebugMsg(&quot;Currently: &quot;+I2S(GetTotalCount(GetLastInstance()))+&quot; exist.&quot;)
            call BJDebugMsg(&quot;Last Scan: &quot;+I2S(GetTotalCount(GetLastInstance()-1))+&quot; existed.&quot;)
            call BJDebugMsg(&quot;Post Init: &quot;+I2S(GetTotalCount(0))+&quot; existed.&quot;)
            call BJDebugMsg(&quot;Since last scan, Agents have increased by &quot;+/*
                */I2S(GetTotalCount(GetLastInstance())-GetTotalCount(GetLastInstance()-1))/*
                */+&quot;.&quot;)
            call Sort(GetLastInstance())
            call BJDebugMsg(&quot;Most common agents:&quot;)
            call BJDebugMsg(&quot;1. &quot;+GetTypeName(Sorted[0])+&quot;s - &quot;+I2S(GetTypeCount(GetLastInstance(),Sorted[0]))+&quot; in existance.&quot;)
            call BJDebugMsg(&quot;2. &quot;+GetTypeName(Sorted[1])+&quot;s - &quot;+I2S(GetTypeCount(GetLastInstance(),Sorted[1]))+&quot; in existance.&quot;)
            call BJDebugMsg(&quot;3. &quot;+GetTypeName(Sorted[2])+&quot;s - &quot;+I2S(GetTypeCount(GetLastInstance(),Sorted[2]))+&quot; in existance.&quot;)
        endif
    endfunction
    
    private function OnChat takes nothing returns boolean
        local string s=GetEventPlayerChatString()
        set s=StringCase(SubString(s,COMMAND_CHAR_LENGTH,StringLength(s)),false)
        if SubString(s,0,5)==&quot;count&quot; then
            call CreateInstance.evaluate()
            call CommandCount(SubString(s,6,StringLength(s)))
        elseif SubString(s,0,5)==&quot;stats&quot; then
            call CreateInstance.evaluate()
            call CommandStats(SubString(s,6,StringLength(s)))
        endif
        return false
    endfunction
    
    private function PostInit takes nothing returns nothing
        call CreateInstance() // Creates instance #0
        if GetTotalCount(GetLastInstance())==0 then
            call BJDebugMsg(&quot;AgentStats Error: Blizzard may have fixed the return bug, or else you are missing &quot;+TRACKER_PATH+&quot;.&quot;)
        endif
        call DestroyTimer(GetExpiredTimer())
    endfunction
    private function OnInit takes nothing returns nothing
        debug local integer i=11
        debug local trigger t=CreateTrigger()
        
        debug call StoreInteger(InitGameCache(&quot;Preloader.w3v&quot;),&quot;globals&quot;,&quot;hashtable&quot;,GetHandleId(Read))
        debug call InitTypeNames()
        debug call InitSort()
        debug call TimerStart(CreateTimer(),0,false,function PostInit)
        
        debug loop
            debug call TriggerRegisterPlayerChatEvent(t,Player(i),COMMAND_CHAR,false)
            debug exitwhen i==0
            debug set i=i-1
        debug endloop
        debug call TriggerAddCondition(t,Filter(function OnChat))
        debug set t=null
    endfunction
endlibrary
</i></i></i>

This is an overpowered handle counter. It scans the game and detects all handles of all types, and sorts them and counts them. It is only useful for debugging, leak monitoring and curiosity. It is set up to only work in debug mode.

Updates:
- Version 1.2.0: Fixed compatability for Warcraft III patch 1.24c. Removed Preloader use.
- Version 1.1.0: Just provides simple text commands now (rework).
- Version 1.0.0 (ALPHA): Release.
 

Attachments

  • AgentStats.w3x
    25.1 KB · Views: 391

Romek

Super Moderator
Reaction score
963
This is interesting. :p
A leaderboard or something would be nice though, showing the count of each major type.

The import is inconvenient, but I'm guessing that's to avoid syntax errors on that return bug?
 

Renendaru

(Evol)ution is nothing without love.
Reaction score
309
I did not expect THAT approach, so good job for confounding me yet again Jesus.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>The import is inconvenient, but I'm guessing that's to avoid syntax errors on that return bug?
Yeah, that. Also means if a map is produced with it and Blizz fixes things, then only the preloader file will fail syntax and the map won't break. :)

I need to do major updates to this, but it is already useful. I was originally even thinking of graphing the handles. I don't like a leaderboard/multiboard simply because this system is too costly to performance to reach a released map, and since many maps use leaderboards or multiboards, well, it would be lame to override them for a debug thing...
 

Romek

Super Moderator
Reaction score
963
Just have a boolean 'ENABLED' or something. o_O
Performance doesn't really matter with systems like this, which are used solely for debugging. For the final release, it'll simply be removed. If another board should be tested, then this can be disabled.
 

Jesus4Lyf

Good Idea™
Reaction score
397
>Performance doesn't really matter with systems like this, which are used solely for debugging.
Yeah. I'll probably debug out the whole library some time. :p

I hope to also make it self contained. Expose only text commands and stuff, so you can dump it in your maps and care more about useful things.

It's pretty nice at the moment, even though it is proof of concept kind of thing... you can see how many timers/triggers etc exist at any time during a map. Obviously cool for leak hunting.

Interestingly enough, the count function leaks an unknown agent. I'm pretty sure it's gamecache, though. <_<
 

quraji

zap
Reaction score
144
Debug libraries are fun! I have a suggestion from a tiny one I made, just add [ljass]debug[/ljass] to the whole library. Obviously makes it work only in debug mode (as intended) and won't hurt if anyone leaves it in their map.

Edit: Nevermind, you said that. Well cool thing anyways :p
 

Furby

Current occupation: News poster
Reaction score
144
Pro as usual. ^_^

For lazy-asses:
124vtqo.jpg
 

Azlier

Old World Ghost
Reaction score
461
So much better than a handle counter.

This potentially beats any leak checker.
 

Romek

Super Moderator
Reaction score
963
I'd still rather this have a leaderboard.
If you think it'd be too distracting, it could easily be enabled/disabled with a constant or something.

This is too inconvenient to use as it currently is, IMO.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
It's a pretty good idea.
I've a question.
Currently i don't see the usefulness of the constant SEARCH_DEGREE.
I know you need to create an handle in the function CreateInstance to get the handle id max, but 1 is not enough ?
 

Jesus4Lyf

Good Idea™
Reaction score
397
>I know you need to create an handle in the function CreateInstance to get the handle id max, but 1 is not enough ?
There can be gaps where handles have been freed already. The DestroyGroup(CreateGroup() stuff occupies a handle id for the duration of the function call, basically (until 0 second wait or something). So if there are gaps, it will fill up to x gaps before accepting the next handle as the max handle (hence the constant).

>I'd still rather this have a leaderboard.
And run the scan periodically? It can be done. What a pain. :(

Would make your map thoroughly unplayable in debug mode, I expect. I might not do it, but I might (optional if I do, of course)...

>So much better than a handle counter.
>This potentially beats any leak checker.
That was my opinion. :)
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Believe me or not i thought about that before you answered.
Hmm, in fact 20 should be not enough, but unless you hook/define all functions which create/destroy handles, and that should be really lame lol, i guess there is no safe way to do it.
Personally i would use 100 or so.

Also, i'm wondering how ghost handles are detected ? (handle which was destroyed but the variable associated to it was not setted to an other value, so the handle id wasn't recycled)
I mean they are detected as their native type (unit,triggerevent...) or as unknown ?
 

Jesus4Lyf

Good Idea™
Reaction score
397
>I mean they are detected as their native type (unit,triggerevent...) or as unknown ?
Unknown. (Pretty sure.)

>Jesus, any chance to get the origin of the handle leak?
The line of code that created it? Lol, sorry. No chance.
It is possible to destroy the handles, but it is silly. I was thinking of adding a text command to destroy every handle of type x on the map, but it really is useless... :)
 

Hatebreeder

So many apples
Reaction score
380
I've got this in my map for debugging =)

made approx 200 leaks less (from things that i thought shouldn't have leaked).
 

Romek

Super Moderator
Reaction score
963
This is approvable as it currently is, though A leaderboard would certainly make this much, much more usable.

Efficiency, speed, space, etc are not a problem when debugging.

Edit: 8,000 posts. :eek:
 

Hatebreeder

So many apples
Reaction score
380
This is approvable as it currently is, though A leaderboard would certainly make this much, much more usable.

Efficiency, speed, space, etc are not a problem when debugging.

I think it's fine like this.
Since I use multiboards and leaderboards. It would fuck up with my current leaderboard, no?
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top