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