- Joined
- Nov 7, 2014
- Messages
- 571
Atc - Agent type counter
Atc counts the agents (handle types) stored in the handle table. I think these counts can give an insight into the robustness of a resource (spell, system, etc.) by answering the question of whether something leaks or not.
You can configure the script to only show specific agents like units, locations and groups.
By default the agent counts are shown in a leaderboard but you can disable that if you want to do something else with the data.
Atc counts the agents (handle types) stored in the handle table. I think these counts can give an insight into the robustness of a resource (spell, system, etc.) by answering the question of whether something leaks or not.
You can configure the script to only show specific agents like units, locations and groups.
By default the agent counts are shown in a leaderboard but you can disable that if you want to do something else with the data.
JASS:
library Atc /*
*/ uses /*
*/ Memory, /* // both libraries can be obtained from:
*/ Version /* // https://www.hiveworkshop.com/threads/accessing-memory-from-the-script-its-time-of-the-revolution.279262/
*/
globals
// set this to false if you want to show the count information some other way (with a multiboard)
// or just print it to the screen
private constant boolean Show_Counts_On_Leaderboard = true
private constant real Leaderboard_Update_Interval = 0.1 // in seconds
private constant boolean Show_Force_Count = true
private constant boolean Show_Player_Count = false
private constant boolean Show_Group_Count = true
private constant boolean Show_Unit_Count = true
private constant boolean Show_Item_Count = false
private constant boolean Show_Destructable_Count = false
private constant boolean Show_Location_Count = true
private constant boolean Show_Rect_Count = false
private constant boolean Show_Region_Count = false
private constant boolean Show_Trigger_Count = true
private constant boolean Show_Boolexpr_Count = false
private constant boolean Show_Triggercondition_Count = false
private constant boolean Show_Triggeraction_Count = false
private constant boolean Show_Unitpool_Count = false
private constant boolean Show_Itempool_Count = false
private constant boolean Show_Timer_Count = true
private constant boolean Show_Timerdialog_Count = false
private constant boolean Show_Sound_Count = false
private constant boolean Show_Camerasetup_Count = false
private constant boolean Show_Effect_Count = true
private constant boolean Show_Fogmodifier_Count = false
private constant boolean Show_Dialog_Count = false
private constant boolean Show_Button_Count = false
private constant boolean Show_Multiboard_Count = false
private constant boolean Show_Multiboarditem_Count = false
private constant boolean Show_Leaderboard_Count = false
private constant boolean Show_Trackable_Count = false
private constant boolean Show_Gamecache_Count = false
private constant boolean Show_Hashtable_Count = false
private constant boolean Show_Event_Count = false
private constant boolean Show_Leaked_Handle_Ids_Count = true
private constant boolean Show_Leaked_Handles_Count = true
private constant boolean Show_All_Count = false
endglobals
static if DEBUG_MODE then
private function to_hex takes integer i returns string
local string hex_digits = "0123456789ABCDEF"
local string result = ""
local integer n
local integer d
local integer t
local boolean is_neg
set is_neg = i < 0
if is_neg then
set i = i + 0x80000000
endif
set n = 0
loop
set n = n + 1
set t = i / 16
set d = i - t * 16
set i = t
set result = SubString(hex_digits, d, d + 1) + result
exitwhen n == 7
endloop
if is_neg then
set i = i + 0x8
endif
set result = SubString(hex_digits, i, i + 1) + result
return result
endfunction
private function to_base256 takes integer i returns string
local string digits = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
local string result = ""
local integer n
local integer d
local integer t
set n = 0
loop
set n = n + 1
set t = i / 256
set d = i - t * 256
set i = t
set d = d - 0x21
if d <= 94 then
set result = SubString(digits, d, d + 1) + result
else
set result = "?" + result
endif
exitwhen n == 4
endloop
return result
endfunction
endif // DEBUG_MODE
struct Atc
integer force_count = 0
integer player_count = 0
integer group_count = 0
integer unit_count = 0
integer item_count = 0
integer destructable_count = 0
integer location_count = 0
integer rect_count = 0
integer region_count = 0
integer trigger_count = 0
integer boolexpr_count = 0 // includes conditionfunc, filterfunc, 'bAnd', '+bOr' and 'bNot'
integer triggercondition_count = 0
integer triggeraction_count = 0
integer unitpool_count = 0
integer itempool_count = 0
integer timer_count = 0
integer timerdialog_count = 0
integer sound_count = 0
integer camerasetup_count = 0
integer effect_count = 0
integer fogmodifier_count = 0
integer dialog_count = 0
integer button_count = 0
integer multiboard_count = 0
integer multiboarditem_count = 0
integer leaderboard_count = 0
integer trackable_count = 0
integer gamecache_count = 0
integer hashtable_count = 0
// includes:
// 'vevt' -- TriggerRegisterVariableEvent
// 'tmvt' -- TriggerRegisterTimerEvent
// 'tmet' -- TriggerRegisterTimerExpireEvent
// 'gfvt' -- TriggerRegisterGameStateEvent
// 'gsvt' -- TriggerRegisterGameStateEvent
// 'devt' -- TriggerRegisterDialogEvent
// 'bevt' -- TriggerRegisterDialogButtonEvent
// 'gevt' -- TriggerRegisterGameEvent
// '+rev' -- TriggerRegisterEnterRegion, TriggerRegisterLeaveRegion
// '+tev' -- TriggerRegisterTrackableHitEvent, TriggerRegisterTrackableTrackEvent
// 'pevt' -- TriggerRegisterPlayerEvent, TriggerRegisterPlayerUnitEvent
// 'alvt' -- TriggerRegisterPlayerAllianceChange
// 'psvt' -- TriggerRegisterPlayerStateEvent
// 'pcvt' -- TriggerRegisterPlayerChatEvent
// 'wdvt' -- TriggerRegisterDeathEvent
// 'usvt' -- TriggerRegisterUnitStateEvent
// 'uevt' -- TriggerRegisterUnitEvent
// 'rgvt' -- TriggerRegisterUnitInRange
//
integer event_count = 0
// these handle types are not stored in the handle table, i.e
// they don't use handle-ids >= 0x00100000:
// ubersplat, image, texttag, lightning, weathereffect, terraindeformation
// the primitive types are: integer, real, boolean, string, code, handle
// the rest of the types declared in common.j are just enums (integers)
integer leaked_handle_ids_count = 0
integer leaked_handles_count = 0
integer all_count = 0
integer force_leak_count = 0
// integer player_leak_count = 0
integer group_leak_count = 0
integer unit_leak_count = 0
// integer item_leak_count = 0
// integer destructable_leak_count = 0
integer location_leak_count = 0
// integer rect_leak_count = 0
// integer region_leak_count = 0
// integer trigger_leak_count = 0
// integer boolexpr_leak_count = 0
// integer triggercondition_leak_count = 0
// integer triggeraction_leak_count = 0
// integer unitpool_leak_count = 0
// integer itempool_leak_count = 0
integer timer_leak_count = 0
// integer timerdialog_leak_count = 0
// integer sound_leak_count = 0
// integer camerasetup_leak_count = 0
integer effect_leak_count = 0
// integer fogmodifier_leak_count = 0
// integer dialog_leak_count = 0
// integer button_leak_count = 0
// integer multiboard_leak_count = 0
// integer multiboarditem_leak_count = 0
// integer leaderboard_leak_count = 0
// integer trackable_leak_count = 0
// integer gamecache_leak_count = 0
// integer hashtable_leak_count = 0
integer event_leak_count = 0
static if Show_Counts_On_Leaderboard then
private static Atc c
private static player local_player
private static timer ticker
private static leaderboard LBC
private static leaderboard LBL
private static integer shown_lb = 1 // 1 = LBC, 2 = LBL
private static method LB_update takes nothing returns nothing
local Atc c = Atc.c
local integer i
local integer ii
if shown_lb == 1 then
call PlayerSetLeaderboard(local_player, LBC)
set i = 1
set ii = LeaderboardGetItemCount(LBC)
loop
exitwhen i > ii
call LeaderboardRemoveItem(LBC, 0)
set i = i + 1
endloop
static if Show_Force_Count then
call LeaderboardAddItem(LBC, "force", c.force_count, local_player)
endif
static if Show_Player_Count then
call LeaderboardAddItem(LBC, "player", c.player_count, local_player)
endif
static if Show_Group_Count then
call LeaderboardAddItem(LBC, "group", c.group_count, local_player)
endif
static if Show_Unit_Count then
call LeaderboardAddItem(LBC, "unit", c.unit_count, local_player)
endif
static if Show_Item_Count then
call LeaderboardAddItem(LBC, "item", c.item_count, local_player)
endif
static if Show_Destructable_Count then
call LeaderboardAddItem(LBC, "destructable", c.destructable_count, local_player)
endif
static if Show_Location_Count then
call LeaderboardAddItem(LBC, "location", c.location_count, local_player)
endif
static if Show_Rect_Count then
call LeaderboardAddItem(LBC, "rect", c.rect_count, local_player)
endif
static if Show_Region_Count then
call LeaderboardAddItem(LBC, "region", c.region_count, local_player)
endif
static if Show_Trigger_Count then
call LeaderboardAddItem(LBC, "trigger", c.trigger_count, local_player)
endif
static if Show_Boolexpr_Count then
call LeaderboardAddItem(LBC, "boolexpr", c.boolexpr_count, local_player)
endif
static if Show_Triggercondition_Count then
call LeaderboardAddItem(LBC, "triggercondition", c.triggercondition_count, local_player)
endif
static if Show_Triggeraction_Count then
call LeaderboardAddItem(LBC, "triggeraction", c.triggeraction_count, local_player)
endif
static if Show_Unitpool_Count then
call LeaderboardAddItem(LBC, "unitpool", c.unitpool_count, local_player)
endif
static if Show_Itempool_Count then
call LeaderboardAddItem(LBC, "itempool", c.itempool_count, local_player)
endif
static if Show_Timer_Count then
call LeaderboardAddItem(LBC, "timer", c.timer_count, local_player)
endif
static if Show_Dialog_Count then
call LeaderboardAddItem(LBC, "timerdialog", c.timerdialog_count, local_player)
endif
static if Show_Sound_Count then
call LeaderboardAddItem(LBC, "sound", c.sound_count, local_player)
endif
static if Show_Camerasetup_Count then
call LeaderboardAddItem(LBC, "camerasetup", c.camerasetup_count, local_player)
endif
static if Show_Effect_Count then
call LeaderboardAddItem(LBC, "effect", c.effect_count, local_player)
endif
static if Show_Fogmodifier_Count then
call LeaderboardAddItem(LBC, "fogmodifier", c.fogmodifier_count, local_player)
endif
static if Show_Dialog_Count then
call LeaderboardAddItem(LBC, "dialog", c.dialog_count, local_player)
endif
static if Show_Button_Count then
call LeaderboardAddItem(LBC, "button", c.button_count, local_player)
endif
static if Show_Multiboard_Count then
call LeaderboardAddItem(LBC, "multiboard", c.multiboard_count, local_player)
endif
static if Show_Multiboarditem_Count then
call LeaderboardAddItem(LBC, "multiboarditem", c.multiboarditem_count, local_player)
endif
static if Show_Leaderboard_Count then
call LeaderboardAddItem(LBC, "leaderboard", c.leaderboard_count, local_player)
endif
static if Show_Trackable_Count then
call LeaderboardAddItem(LBC, "trackable", c.trackable_count, local_player)
endif
static if Show_Gamecache_Count then
call LeaderboardAddItem(LBC, "gamecache", c.gamecache_count, local_player)
endif
static if Show_Hashtable_Count then
call LeaderboardAddItem(LBC, "hashtable", c.hashtable_count, local_player)
endif
static if Show_Event_Count then
call LeaderboardAddItem(LBC, "event", c.event_count, local_player)
endif
static if Show_Leaked_Handle_Ids_Count then
call LeaderboardAddItem(LBC, "leaked handle ids", c.leaked_handle_ids_count, local_player)
endif
static if Show_Leaked_Handles_Count then
call LeaderboardAddItem(LBC, "leaked handles", c.leaked_handles_count, local_player)
endif
static if Show_All_Count then
call LeaderboardAddItem(LBC, "all", c.all_count, local_player)
endif
call LeaderboardSetSizeByItemCount(LBC, LeaderboardGetItemCount(LBC))
call LeaderboardSetLabelColor(LBC, /*R:*/ 0xFF, /*G:*/ 0xFF, /*B:*/ 0xFF, /*A:*/ 0xFF)
call LeaderboardSetValueColor(LBC, /*R:*/ 0xFF, /*G:*/ 0xFF, /*B:*/ 0xFF, /*A:*/ 0xFF)
call LeaderboardSortItemsByValue(LBC, /*ascending:*/ false)
call LeaderboardDisplay(LBC, true)
else // shown_lb == 2
call PlayerSetLeaderboard(local_player, LBL)
set i = 1
set ii = LeaderboardGetItemCount(LBL)
loop
exitwhen i > ii
call LeaderboardRemoveItem(LBL, 0)
set i = i + 1
endloop
if c.force_leak_count != 0 then
call LeaderboardAddItem(LBL, "force", c.force_leak_count, local_player)
endif
if c.group_leak_count != 0 then
call LeaderboardAddItem(LBL, "group", c.group_leak_count, local_player)
endif
if c.unit_leak_count != 0 then
call LeaderboardAddItem(LBL, "unit", c.unit_leak_count, local_player)
endif
if c.location_leak_count != 0 then
call LeaderboardAddItem(LBL, "location", c.location_leak_count, local_player)
endif
if c.timer_leak_count != 0 then
call LeaderboardAddItem(LBL, "timer", c.timer_leak_count, local_player)
endif
if c.effect_leak_count != 0 then
call LeaderboardAddItem(LBL, "effect", c.effect_leak_count, local_player)
endif
if c.event_leak_count != 0 then
call LeaderboardAddItem(LBL, "event", c.event_leak_count, local_player)
endif
call LeaderboardSetSizeByItemCount(LBL, LeaderboardGetItemCount(LBL))
call LeaderboardSetLabelColor(LBL, /*R:*/ 0xFF, /*G:*/ 0xFF, /*B:*/ 0xFF, /*A:*/ 0xFF)
call LeaderboardSetValueColor(LBL, /*R:*/ 0xFF, /*G:*/ 0xFF, /*B:*/ 0xFF, /*A:*/ 0xFF)
call LeaderboardSortItemsByValue(LBL, /*ascending:*/ false)
call LeaderboardDisplay(LBL, true)
endif // shown_lb
endmethod
endif // Show_Counts_On_Leaderboard
// iterate the handle table's entries and count the different types of agents
//
// we try to avoid the op-limit
private static Atc c_ef
private static integer ptr_ef
private static boolean done_ef
private static force exec
private static method count_ef takes nothing returns nothing
// we make at most this many iterations so that we can avoid the op-limit
local integer N = 1000
// this many consecutive empty entries in the handle table denote its end;
// we do it this way because we don't know how many entries are in the handle table =)
local integer M = 5
local integer m
local integer p
local integer q
local integer rc // reference count
local integer a // agent pointer
local integer ty // agent type
local Atc c
local boolean leak
set p = Atc.ptr_ef
set c = Atc.c_ef
loop
set rc = Memory[p/4]
set a = Memory[(p+0x04)/4]
if a == 0 then
if rc != 0 then
set c.all_count = c.all_count + 1
set c.leaked_handle_ids_count = c.leaked_handle_ids_count + 1
else
set m = M - 1
set q = p + 0x0C
loop
exitwhen m == 0
if Memory[q/4] != 0 then
exitwhen true
endif
set q = q + 0x0C
set m = m - 1
endloop
if m == 0 then
set Atc.done_ef = true
exitwhen true
endif
endif // rc != 0
else
set c.all_count = c.all_count + 1
// get the agent's type;
// note the unaligned memory read (Memory1);
set ty = Memory1[Memory[(Memory[a/4] + 0x1C)/4]/4]
set leak = rc == 1
if leak then
set c.leaked_handles_count = c.leaked_handles_count + 1
endif
if ty == '+loc' then
set c.location_count = c.location_count + 1
if leak then
set c.location_leak_count = c.location_leak_count + 1
endif
elseif ty == '+w3u' then
set c.unit_count = c.unit_count + 1
if leak then
set c.unit_leak_count = c.unit_leak_count + 1
endif
elseif ty == '+EIP' or ty == '+EIm' then
set c.effect_count = c.effect_count + 1
if leak then
set c.effect_leak_count = c.effect_leak_count + 1
endif
elseif ty == '+grp' then
set c.group_count = c.group_count + 1
if leak then
set c.group_leak_count = c.group_leak_count + 1
endif
elseif ty == '+trg' then
set c.trigger_count = c.trigger_count + 1
elseif ty == '+tmr' then
set c.timer_count = c.timer_count + 1
if leak then
set c.timer_leak_count = c.timer_leak_count + 1
endif
elseif ty == '+mbi' then
set c.multiboarditem_count = c.multiboarditem_count + 1
elseif ty == 'item' then
set c.item_count = c.item_count + 1
elseif ty == '+rct' then
set c.rect_count = c.rect_count + 1
elseif ty == '+dlb' then
set c.button_count = c.button_count + 1
elseif ty == '+frc' then
set c.force_count = c.force_count + 1
if leak then
set c.force_leak_count = c.force_leak_count + 1
endif
elseif ty == '+w3d' then
set c.destructable_count = c.destructable_count + 1
elseif ty == '+flt' or ty == 'bAnd' or ty == '+bOr' or ty == 'bNot' then
set c.boolexpr_count = c.boolexpr_count + 1
elseif ty == 'tcnd' then
set c.triggercondition_count = c.triggeraction_count + 1
elseif ty == '+tac' then
set c.triggeraction_count = c.triggeraction_count + 1
elseif ty == '+snd' then
set c.sound_count = c.sound_count + 1
elseif ty == '+cst' then
set c.camerasetup_count = c.camerasetup_count + 1
elseif ty == '+agr' then
set c.region_count = c.region_count + 1
elseif ty == '+dlg' then
set c.dialog_count = c.dialog_count + 1
elseif ty == '+mdb' then
set c.multiboard_count = c.multiboarditem_count + 1
elseif ty == 'ghth' then
set c.hashtable_count = c.hashtable_count + 1
elseif ty == 'gcch' then
set c.gamecache_count = c.gamecache_count + 1
elseif ty == '+fgm' then
set c.fogmodifier_count = c.fogmodifier_count + 1
elseif ty == '+ply' then
set c.player_count = c.player_count + 1
elseif ty == '+ldb' then
set c.leaderboard_count = c.leaderboard_count + 1
elseif ty == '+tid' then
set c.timerdialog_count = c.timerdialog_count + 1
elseif ty == '+trk' then
set c.trackable_count = c.trackable_count + 1
elseif ty == 'pool' then
set c.unitpool_count = c.unitpool_count + 1
elseif ty == 'ipol' then
set c.itempool_count = c.itempool_count + 1
elseif ty == 'pevt' /*
*/ or ty == 'uevt' /*
*/ or ty == 'usvt' /*
*/ or ty == 'psvt' /*
*/ or ty == 'tmet' /*
*/ or ty == 'tmvt' /*
*/ or ty == 'wdvt' /*
*/ or ty == '+rev' /*
*/ or ty == 'bevt' /*
*/ or ty == 'devt' /*
*/ or ty == 'gevt' /*
*/ or ty == 'gfvt' /*
*/ or ty == 'gsvt' /*
*/ or ty == 'rgvt' /*
*/ or ty == 'pcvt' /*
*/ or ty == 'alvt' /*
*/ or ty == '+tev'/*
*/ or ty == 'vevt' /*
*/ then
set c.event_count = c.event_count + 1
if leak then
set c.event_leak_count = c.event_leak_count + 1
endif
else
static if DEBUG_MODE then
if ty == 'pcmd' then
// skip
else
call BJDebugMsg("unknown handle type '" + to_base256(ty) + "' at: 0x" + to_hex(a))
call BJDebugMsg("handle type in hex: " + to_hex(ty))
set Atc.done_ef = true
static if Show_Leaderboard_Count then
call PauseTimer(ticker)
endif
call I2S(1 / 0)
endif
endif // DEBUG_MODE
endif // ty
endif // a == 0
// the size of a handle table entry seems to be 12 bytes
set p = p + 0x0C
set N = N - 1
exitwhen N == 0
endloop
set Atc.ptr_ef = p
endmethod
method count takes nothing returns nothing
local Atc c = this
set c.force_count = 0
set c.player_count = 0
set c.group_count = 0
set c.unit_count = 0
set c.item_count = 0
set c.destructable_count = 0
set c.location_count = 0
set c.rect_count = 0
set c.region_count = 0
set c.trigger_count = 0
set c.boolexpr_count = 0
set c.triggercondition_count = 0
set c.triggeraction_count = 0
set c.unitpool_count = 0
set c.itempool_count = 0
set c.timer_count = 0
set c.timerdialog_count = 0
set c.sound_count = 0
set c.camerasetup_count = 0
set c.effect_count = 0
set c.fogmodifier_count = 0
set c.dialog_count = 0
set c.button_count = 0
set c.multiboard_count = 0
set c.multiboarditem_count = 0
set c.leaderboard_count = 0
set c.trackable_count = 0
set c.gamecache_count = 0
set c.hashtable_count = 0
set c.event_count = 0
set c.leaked_handle_ids_count = 0
set c.leaked_handles_count = 0
set c.all_count = 0
set c.force_leak_count = 0
// set c.player_leak_count = 0
set c.group_leak_count = 0
set c.unit_leak_count = 0
// set c.item_leak_count = 0
// set c.destructable_leak_count = 0
set c.location_leak_count = 0
// set c.rect_leak_count = 0
// set c.region_leak_count = 0
// set c.trigger_leak_count = 0
// set c.boolexpr_leak_count = 0
// set c.triggercondition_leak_count = 0
// set c.triggeraction_leak_count = 0
// set c.unitpool_leak_count = 0
// set c.itempool_leak_count = 0
set c.timer_leak_count = 0
// set c.timerdialog_leak_count = 0
// set c.sound_leak_count = 0
// set c.camerasetup_leak_count = 0
set c.effect_leak_count = 0
// set c.fogmodifier_leak_count = 0
// set c.dialog_leak_count = 0
// set c.button_leak_count = 0
// set c.multiboard_leak_count = 0
// set c.multiboarditem_leak_count = 0
// set c.leaderboard_leak_count = 0
// set c.trackable_leak_count = 0
// set c.gamecache_leak_count = 0
// set c.hashtable_leak_count = 0
set c.event_leak_count = 0
set Atc.ptr_ef = Memory[Memory[GameState/4+7]/4+103] + 0x0C
set Atc.done_ef = false
set Atc.c_ef = c
loop
exitwhen Atc.done_ef
call ForForce(exec, function Atc.count_ef)
endloop
static if Show_Counts_On_Leaderboard then
call Atc.LB_update()
endif
endmethod
static if Show_Counts_On_Leaderboard then
private static method do_count takes nothing returns nothing
call Atc.c.count()
endmethod
private static method leaderboards_init takes nothing returns nothing
set LBC = CreateLeaderboard()
// call LeaderboardSetLabel(LBC, "Agent Type Counter")
call LeaderboardSetStyle(LBC, /*show_title:*/ false, /*show_item_labels:*/ true, /*show_item_values:*/ true, /*show_item_icons:*/ false)
set LBL = CreateLeaderboard()
call LeaderboardSetLabel(LBL, "Leaked Handles")
call LeaderboardSetStyle(LBL, /*show_title:*/ true, /*show_item_labels:*/ true, /*show_item_values:*/ true, /*show_item_icons:*/ false)
call PlayerSetLeaderboard(local_player, LBL)
set ticker = GetExpiredTimer()
call TimerStart(ticker, Leaderboard_Update_Interval, true, function Atc.do_count)
endmethod
private static string array T
private static integer T_count = 0
private static method tokenize takes nothing returns nothing
local string s = GetEventPlayerChatString()
local integer si
local integer i
local string ch
set T_count = 0
set i = 0
loop
loop
set ch = SubString(s, i, i + 1)
exitwhen ch != " "
set i = i + 1
endloop
exitwhen ch == ""
set si = i
loop
set i = i + 1
set ch = SubString(s, i, i + 1)
exitwhen ch == " " or ch == ""
endloop
set T_count = T_count + 1
set T[T_count] = SubString(s, si, i)
endloop
endmethod
private static method on_input takes nothing returns nothing
local integer i
call tokenize()
if T[1] == "!a" then
set i = S2I(T[2])
if i == 1 then
set shown_lb = 1
elseif i == 2 then
set shown_lb = 2
else
call BJDebugMsg("command 'a': expected second argument to be 1 or 2")
endif
endif
endmethod
endif // Show_Counts_On_Leaderboard
private static method onInit takes nothing returns nothing
local trigger t
set Atc.c = Atc.create()
set exec = CreateForce()
call ForceAddPlayer(exec, Player(15))
static if Show_Counts_On_Leaderboard then
set local_player = GetLocalPlayer()
set t = CreateTrigger()
call TriggerRegisterPlayerChatEvent(t, local_player, "", false)
call TriggerAddAction(t, function Atc.on_input)
call TimerStart(CreateTimer(), 0.0, false, function Atc.leaderboards_init)
endif
endmethod
endstruct
endlibrary
Attachments
Last edited: