Author Topic: FountainFarm detection patch  (Read 2015 times)

Grief-Code

  • Guest
FountainFarm detection patch
« on: July 01, 2014, 03:00:17 pm »
Hey guys & hosters of dota, lod or dota ImbA,

this is maybe a good solution which I would like to share. I have spent lately a bit time to parse some action packets which are send by warcraft. It didnt took long until i noticed they can be used really nice. As example i started to create a founatnfarm detection. Since we are not ingame and its only a bot, it can't be 100% accurate. But I think i found a good solution.

At first we need to parse the action, this can be done at game_base.cpp, find the function EventPlayerAction:
Code: [Select]
bool CBaseGame :: EventPlayerAction( CGamePlayer *player, CIncomingAction *action ) {
if( ( !m_GameLoaded && !m_GameLoading ) || action->GetLength( ) > 1027 )
    {
        delete action;
        return false;
    }
Add after:
Code: [Select]
    if( !action->GetAction( )->empty( ) )
    {
        BYTEARRAY packet = *action->GetAction( );

        if((packet[0] == 18 || packet[0] == 17 ) && packet.size() > 21) {
                    unsigned char bufx[4]={packet[15],packet[16],packet[17],packet[18]};
                    unsigned char bufy[4]={packet[19],packet[20],packet[21],packet[22]};

                    unsigned char team = m_Slots[GetSIDFromPID( player->GetPID() )].GetTeam();
                    float x=*(float*)(bufx);
                    float y=*(float*)(bufy);

                    if(x < -6382 && y < -6290 && team == 1) {
                        player->SetLastAttackCommandToFountain( GetTime() );
                    }
                    if(x > 5893 && y > 5466 && team == 0) {
                        player->SetLastAttackCommandToFountain( GetTime() );
                    }
        }
    }
What are we doing here?
  • Action 18 is a right click, or an attack command, we are parsing the x & y coordinates, and matching them with a square on the fountainarea. If the player from the enemy fountain now clicks into that area, we setting him the current time as integer into the player object
  • Action 17 does nearly the same, this are simple ground spells, like aoe spells, keep in mind that an impale can kill someone in the fountain.

Next we need to add the variables to the player object, add on gameplayer.cpp twice:
Code: [Select]
m_LastAttackCommandToFountain( GetTime() ), m_FFLevel( 0 )Now add the definition and getter/setter on gameplayer.h:
Code: [Select]
uint32_t m_LastAttackCommandToFountain;
uint32_t m_FFLevel;
----
uint32_t GetLastAttackTimeToFountain( ) {
    return m_LastAttackCommandToFountain;
}
uint32_t GetFFLevel( ) {
    return m_FFLevel;
}
----
void SetLastAttackCommandToFountain( uint32_t time ) {
    m_LastAttackCommandToFountain = time;
}
void SetFFLevel( ) {
    m_FFLevel++;
}

With this we can finally add the part to the stats parsing and detect kills, add on statsdota.h a new variable, should be private:
Code: [Select]
uint32_t m_FFKills[12];Initialize it on statsdota.cpp:
Code: [Select]
m_FFKills[i] = 0;
Now find on the same file the case "Hero" and 'Killer && Victim' or 'Killer &&! Victim', add the following code:
Code: [Select]
if( GetTime() - Killer->GetLastAttackTimeToFountain() <=5 ) {
    m_Game->SendChat(Killer->GetPID(), "You have been detected as fountainfarmer");
    m_FFKills[ValueInt]++;
    Killer->SetFFLevel();

    if(Killer->GetFFLevel() == 3 ) {
          m_Game->m_PairedBanAdds.push_back( PairedBanAdd( string(), m_Game->m_GHost->m_DB->ThreadedBanAdd( Killer->GetJoinedRealm(), Killer->GetName(), Killer->GetExternalIPString( ), m_Game->m_GameName, "Anti-FF", "Fountainfarm" ) ) );
   }
}
Now find:
Code: [Select]
m_Players[ID]->SetKills( ValueInt );and replace with:
Code: [Select]
m_Players[ID]->SetKills( ValueInt - m_FFKills[ValueInt] );

Ok what happened here, we check if a player clicked into the founatinarea or used a spell into it, we save the time. Now we check if the last action is less than 5 seconds ago, if yes, he is noted as fountainfarmer, we now increase his fflevel. In that case we punish him after 3 increases of the ff level with a ban.
Additional we removing all kills which are noted as FF kills.

If you have problems finding the position, maybe this can help:
https://github.com/OHSystem/ohsystem/compare/6057018fae6aef7a373279dfcd242ac1d98ba281...master

The whole idea is only from scratch and is now on online on SGN bots, for testing. I dont know f 5 seconds are a valied solution and how many fails there happening. We will see this.

There also planed new options and ideas which are maybe upcoming soon, if you are interested keep track of ohsystem.
I hope this patch is useful for anyone :-P

Regards,
Grief-Code