Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
library AntiMhShield uses TimerUtils
/*******************************************************************
*
* AntiMhShield
* __________________
* v1.0.1.1
* by Thelordmarshall
*
* Well, another anti maphack system...
* It is 100% functional? Not at the moment because WE have to improve
* some functions and perfecting typical events of the "maphackers".
*
* Pros:
* _____
*
* - Detect mh when clic a foged/masked unit.
* - Detect mh when clic invisible units (without item detection, for
* example a gem).
*
* Cons:
* _____
*
* - The system is not perfect.
* - I have many ideas to perfecting the system but I have not been able
* to add all.
*
* Credits:
* ________
*
* - Vexorian: TimerUtils.
*
* Notes:
* ______
*
* - If you have mh test the system for me :).
* - I waiting for your suggestions.
*
* Copyright © 2015.
*************************************************************************/
globals
private integer array invId
private integer array revealId
private real array revealAoE
endglobals
//CONFIGURATION
//========================================================================
globals
private constant integer MAX_ALERTS=3
private constant integer MAX_FLAGS=20
private constant real CHECK_PERIOD=0.3
private constant real RADIUS=300.00
private constant real FLAGS_DELAY=3.50
private constant real VOTING_DELAY=60.00
private constant integer END_GAME_DELAY=10
private constant boolean DETECT_ONLY_HEROES=true
private constant boolean DETECT_ONLY_USERS_PLAYERS=false
endglobals
private function ConfigInviAbilities takes nothing returns nothing
//Abilities
set invId[1]='Aivs'
set invId[2]='Abur'
set invId[3]='Abu2'
set invId[4]='Abu3'
set invId[5]='Ashm'
set invId[6]='Sshm'
set invId[7]='Ahid'
set invId[8]='Asb3'
set invId[9]='Asb2'
set invId[10]='Asb1'
set invId[11]='Apiv'
//Buff
set invId[12]='BOwk'
set invId[13]='Binv'
set invId[14]='Bivs'
endfunction
private function ConfigRevealAbilities takes nothing returns nothing
set revealId[1]='Adts'
set revealAoE[1]=900.00
set revealId[2]='Adt1'
set revealAoE[2]=1100.00
set revealId[3]='Atru'
set revealAoE[3]=900.00
set revealId[4]='Adtg'
set revealAoE[4]=900.00
set revealId[5]='ANtr'
set revealAoE[5]=900.00
endfunction
//========================================================================
//ENDCONFIGURATION
private struct AntiMh
static constant timer T=CreateTimer() //(!)
static integer array flag[11]
static integer array alert[11]
static integer array endDur[11]
static boolean array onAlert[11]
static player p=null
static unit u=null
static unit f=null
static method isTargetType takes unit o returns boolean
static if DETECT_ONLY_HEROES then
return IsUnitType(o,UNIT_TYPE_HERO)
else
return true
endif
return false
endmethod
static method isPlayerControl takes player k returns boolean
static if DETECT_ONLY_USERS_PLAYERS then
return GetPlayerController(k)==MAP_CONTROL_USER
else
return true
endif
return false
endmethod
static method groupFilter1 takes nothing returns boolean
local integer i=1
local integer c=0
set f=GetFilterUnit()
loop
exitwhen revealId[i]==null
if GetUnitAbilityLevel(f,revealId[i])>0 then
set c=c+1
endif
set i=i+1
endloop
return IsUnitOwnedByPlayer(f,p) and c>0
endmethod
static method playerHasDetectItem takes unit mhTarget, player mhPlayer returns boolean
set p=mhPlayer
call GroupEnumUnitsInRange(bj_lastCreatedGroup,GetUnitX(mhTarget),GetUnitY(mhTarget),9999.,Filter(function thistype.groupFilter1))
if FirstOfGroup(bj_lastCreatedGroup)!=null then
return true
endif
return false
endmethod
static method effectiveDetect1 takes nothing returns boolean
return IsUnitFogged(u,p) or IsUnitMasked(u,p)
endmethod
static method effectiveDetect2 takes nothing returns boolean
return .effectiveDetect1() and IsUnitInvisible(u,p) and not .playerHasDetectItem(u,p)
endmethod
//Not perfect yet :(
static method effectiveDetect3 takes nothing returns boolean
return IsUnitInvisible(u,p) and not .playerHasDetectItem(u,p)
endmethod
static method endDelay takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer i=GetTimerData(t)
local player l=GetLocalPlayer()
local player h=Player(i)
local string s="|c00FF0000[AntiMapHack]|r: "+GetPlayerName(h)+" is using map hack, left in "+"|c0080FF00"+I2S(endDur[i]-1)+"|r"
set endDur[i]=endDur[i]-1
call DisplayTimedTextToPlayer(l,0.,0.,60.,s)
if endDur[i]<=0. then
if l==h then
call EndGame(true)
endif
call ReleaseTimer(t)
endif
set t=null
endmethod
static method endGame takes nothing returns nothing
local integer i=GetPlayerId(p)
set endDur[i]=END_GAME_DELAY
call TimerStart(NewTimerEx(i),1.,true,function thistype.endDelay)
endmethod
static method removeMhAlert takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer i=GetTimerData(t)
set onAlert[i]=false
call ReleaseTimer(t)
set t=null
endmethod
static method alertMh takes string msg, real d returns nothing
call DisplayTimedTextToPlayer(GetLocalPlayer(),0.,0.,60.,msg)
if d>0. then
call TimerStart(NewTimerEx(GetPlayerId(p)),d,false,function thistype.removeMhAlert)
endif
endmethod
static method decreaseFlags takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer i=GetTimerData(t)
set flag[i]=flag[i]-1
call ReleaseTimer(t)
set t=null
endmethod
static method groupFilter2 takes nothing returns boolean
set f=GetFilterUnit()
return IsUnitEnemy(f,p) and .isTargetType(f) and .isPlayerControl(GetOwningPlayer(f))
endmethod
//Not work yet. I finish for the next version :)
static method automaticDetect takes nothing returns nothing
local real x=GetCameraEyePositionX()
local real y=GetCameraEyePositionY()+(GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)/2)
local integer i=0
local string s
loop
exitwhen i==bj_MAX_PLAYERS
set p=Player(i)
if GetPlayerSlotState(p)==PLAYER_SLOT_STATE_PLAYING then
call GroupEnumUnitsInRange(bj_lastCreatedGroup,x,y,RADIUS,Filter(function thistype.groupFilter2))
if FirstOfGroup(bj_lastCreatedGroup)!=null then
set flag[i]=flag[i]+1
call TimerStart(NewTimerEx(GetPlayerId(p)),FLAGS_DELAY,false,function thistype.decreaseFlags)
if flag[i]>=MAX_FLAGS then
set alert[i]=alert[i]+1
set flag[i]=0
if alert[i]>=MAX_ALERTS and not onAlert[i] then
set s=GetPlayerName(p)
call .alertMh("|c00FF0000[MH Alert]|r: Player "+s+" has reached the flags limits warnings, it is possible this using MH.",VOTING_DELAY)
call .alertMh("|c00FF0000[MH Alert]|r: The voting to kick the player "+s+" has started.",0.)
set onAlert[i]=true
endif
endif
endif
endif
set i=i+1
endloop
endmethod
static method manualDetect takes nothing returns boolean
set u=GetTriggerUnit()
set p=GetTriggerPlayer()
if GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER then
set u=GetOrderTargetUnit()
endif
if not IsUnitOwnedByPlayer(u,p) then
if .effectiveDetect1() then
call .endGame() //100%
elseif .effectiveDetect2() then
call .endGame() //100%
elseif .effectiveDetect3() then
call .endGame() //100% (!)
endif
endif
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t=CreateTrigger()
local integer i=0
local player k
call ConfigRevealAbilities()
call ConfigInviAbilities()
loop
exitwhen i==bj_MAX_PLAYERS
set k=Player(i)
call TriggerRegisterPlayerUnitEvent(t,k,EVENT_PLAYER_UNIT_SELECTED,null)
call TriggerRegisterPlayerUnitEvent(t,k,EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER,null)
set flag[i]=0
set i=i+1
endloop
call TriggerAddCondition(t,function thistype.manualDetect)
//call TimerStart(T,CHECK_PERIOD,true,function thistype.automaticDetect)
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TimerUtilsEx requires optional Table
/*************************************************
*
* TimerUtilsEx
* v2.1.0.2
* By Vexorian, Bribe & Magtheridon96
*
* Original version by Vexorian.
*
* Flavors:
* Hashtable:
* - RAM: Minimal
* - TimerData: Slow
*
* Array:
* - RAM: Maximal
* - TimerData: Fast
*
* All the functions have O(1) complexity.
* The Array version is the fastest, but the hashtable
* version is the safest. The Array version is still
* quite safe though, and I would recommend using it.
* The system is much slower in debug mode.
*
* Optional Requirement:
* - Table by Bribe
* - hiveworkshop.com/forums/showthread.php?t=188084
*
* API:
* ----
* - function NewTimer takes nothing returns timer
* - Returns a new timer from the stack.
* - function NewTimerEx takes integer i returns timer
* - Returns a new timer from the stack and attaches a value to it.
* - function ReleaseTimer takes timer t returns integer
* - Throws a timer back into the stack. Also returns timer data.
* - function SetTimerData takes timer t, integer value returns nothing
* - Attaches a value to a timer.
* - function GetTimerData takes timer t returns integer
* - Returns the attached value.
*
*************************************************/
// Configuration
globals
// Use hashtable, or fast array?
private constant boolean USE_HASH = true
// Max Number of Timers Held in Stack
private constant integer QUANTITY = 512
endglobals
globals
private timer array tT
private integer tN = 0
endglobals
private module Init
private static method onInit takes nothing returns nothing
static if not USE_HASH then
local integer i = QUANTITY
loop
set i = i - 1
set tT[i] = CreateTimer()
exitwhen i == 0
endloop
set tN = QUANTITY
elseif LIBRARY_Table then
set tb = Table.create()
endif
endmethod
endmodule
// JassHelper doesn't support static ifs for globals.
private struct Data extends array
static if not USE_HASH then
static integer array data
endif
static if LIBRARY_Table then
static Table tb = 0
else
static hashtable ht = InitHashtable()
endif
implement Init
endstruct
// Double free protection
private function ValidTimer takes integer i returns boolean
static if LIBRARY_Table then
return Data.tb.boolean[-i]
else
return LoadBoolean(Data.ht, i, 1)
endif
endfunction
private function Get takes integer id returns integer
debug if not ValidTimer(id) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: Tried to get data from invalid timer.")
debug endif
static if USE_HASH then
static if LIBRARY_Table then
return Data.tb[id]
else
return LoadInteger(Data.ht, id, 0)
endif
else
return Data.data[id - 0x100000]
endif
endfunction
private function Set takes integer id, integer data returns nothing
debug if not ValidTimer(id) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: Tried to attach data to invalid timer.")
debug endif
static if USE_HASH then
static if LIBRARY_Table then
set Data.tb[id] = data
else
call SaveInteger(Data.ht, id, 0, data)
endif
else
set Data.data[id - 0x100000] = data
endif
endfunction
function SetTimerData takes timer t, integer data returns nothing
call Set(GetHandleId(t), data)
endfunction
function GetTimerData takes timer t returns integer
return Get(GetHandleId(t))
endfunction
function NewTimerEx takes integer data returns timer
local integer id
if tN == 0 then
static if USE_HASH then
set tT[0] = CreateTimer()
else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: No Timers In The Stack! You must increase 'QUANTITY'")
return null
endif
else
set tN = tN - 1
endif
set id = GetHandleId(tT[tN])
static if LIBRARY_Table then
set Data.tb.boolean[-id] = true
else
call SaveBoolean(Data.ht, id, 1, true)
endif
call Set(id, data)
return tT[tN]
endfunction
function NewTimer takes nothing returns timer
return NewTimerEx(0)
endfunction
function ReleaseTimer takes timer t returns integer
local integer id = GetHandleId(t)
local integer data = 0
// Pause the timer just in case.
call PauseTimer(t)
// Make sure the timer is valid.
if ValidTimer(id) then
// Get the timer's data.
set data = Get(id)
// Unmark handle id as a valid timer.
static if LIBRARY_Table then
call Data.tb.boolean.remove(-id)
else
call RemoveSavedBoolean(Data.ht, id, 1)
endif
//If it's not run in USE_HASH mode, this next block is useless.
static if USE_HASH then
//At least clear hash memory while it's in the recycle stack.
static if LIBRARY_Table then
call Data.tb.remove(id)
else
call RemoveSavedInteger(Data.ht, id, 0)
endif
// If the recycle limit is reached
if tN == QUANTITY then
// then we destroy the timer.
call DestroyTimer(t)
return data
endif
endif
//Recycle the timer.
set tT[tN] = t
set tN = tN + 1
//Tried to pass a bad timer.
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[TimerUtils]Error: Tried to release non-active timer!")
endif
//Return Timer Data.
return data
endfunction
endlibrary
library TimerUtils requires TimerUtilsEx
endlibrary