PokemonGoF / PokemonGo-Bot

The Pokemon Go Bot, baking with community.
MIT License
3.85k stars 1.54k forks source link

Perm Ban Test Results #4114

Closed talobear closed 7 years ago

talobear commented 7 years ago

Greetings,

Was a casualty of the first wave of perma-bans. Most of the bot activity was limited to activity in and around the neighborhood where I live and work.

After the ban I created a test account via PTC. I wanted to understand what would trigger a ban. I decided that until I reached level 20 I would keep no Pokemon nor visit a Gym. I would basically walk, spin and transfer whatever I encountered. The longest session would be no more than 1 hour long. I would keep the activity to two locations; home and work. No teleports, just the two locations I happened to be physically. The goal was to keep a low profile and emulate player behaviors.

The new account was setup on 8/12. Over the next four days the bot would run in roughly hour long blocks, 2-4 times a day. Typically in the AM, then lunch, then dinner. Two of the days I did a late night session around midnight. Never encountered any bans with this approach. The last session I ran was during lunch today. I was level 17 at this point. However, this session I forgot to kill it after an hours. It ended up running for about 2 hours. Since Im in a city with dense pokestops and pokemon a ton were encountered.

I went to run the next test. Launched it again and got the "failed to get game data" message. The bot reported "Probably permabanned, Game Over ! Play again at https://club.pokemon.com/us/pokemon-trainer-club/sign-up/"

Used a non-test account and was able to login without issue. This told me it was not a server issue.

There was clearly something that triggered this ban.

Can it be that I reached level 17 too quickly? Could be that the frequency of play was too often? 4-5 hours a day? I was not teleporting and had no inventory of high level pokemon. Could it be the rate at which they were turned in for candy?

Including my config for reference. Going to try another test account and adjust the rate of play. Any other suggestions I'm happy to test out.

{
    "auth_service": "",
    "username": "",
    "password": "",
    "location": "",
    "gmapkey": "",
      "tasks": [
        {
          "type": "HandleSoftBan"
        },
        {
          "type": "SleepSchedule",
          "config": {
            "enabled": true,
            "time": "22:54",
            "duration":"7:46",
            "time_random_offset": "00:24",
            "duration_random_offset": "00:43"
          }
        },
        {
          "type": "CollectLevelUpReward"
        },
        {
          "type": "IncubateEggs",
          "config": {
            "longer_eggs_first": true
          }
        },
        {
          "type": "UpdateLiveStats",
          "config": {
            "enabled": true,
            "min_interval": 10,
            "stats": ["uptime", "stardust_earned", "xp_earned", "xp_per_hour", "stops_visited"],
            "terminal_log": true,
            "terminal_title": true
          }
        },
        {
          "type": "TransferPokemon"
        },
        {
          "type": "NicknamePokemon",
          "config": {
            "enabled": true,
            "nickname_template": "{iv_pct}_{iv_ads}"
          }
        },
        {
          "type": "EvolvePokemon",
          "config": {
              "evolve_all": "none",
              "first_evolve_by": "cp",
              "evolve_above_cp": 500,
              "evolve_above_iv": 0.8,
              "logic": "or",
              "evolve_speed": 20,
              "use_lucky_egg": false
          }
        },
        {
          "type": "RecycleItems",
          "config": {
            "min_empty_space": 15,
            "item_filter": {
              "Pokeball":       { "keep" : 25 },
          "Greatball":      { "keep" : 125 },
              "Potion":         { "keep" : 10 },
              "Super Potion":   { "keep" : 20 },
              "Hyper Potion":   { "keep" : 30 },
              "Revive":         { "keep" : 15 },
              "Razz Berry":     { "keep" : 45 }
            }
          }
        },
        {
          "type": "CatchVisiblePokemon"
        },
        {
          "type": "CatchLuredPokemon"
        },
        {
          "type": "SpinFort"
        },
        {
          "type": "MoveToFort",
          "config": {
              "lure_attraction": true,
              "lure_max_distance": 2000
          }
        },
        {
          "type": "FollowSpiral",
          "config": {
            "diameter": 4,
            "step_size": 70
          }
        }
      ],
      "map_object_cache_time": 5,
      "forts": {
        "avoid_circles": true,
        "max_circle_size": 50,
        "cache_recent_forts": true
      },
      "websocket_server": false,
      "walk": 4.16,
      "action_wait_min": 1,
      "action_wait_max": 4,
      "debug": false,
      "test": false,
      "health_record": true,
      "location_cache": false,
      "distance_unit": "km",
      "reconnecting_timeout": 15,
      "catch_randomize_reticle_factor": 0.5,
      "catch_randomize_spin_factor": 0.5,
      "min_ultraball_to_keep": 10,
      "logging_color": true,
      "catch": {
        "any": {"catch_above_cp": 0, "catch_above_iv": 0, "logic": "or"},
        "// Example of always catching Rattata:": {},
        "// Rattata": { "always_catch" : true }
      },
      "catch_throw_parameters": {
        "excellent_rate": 0.1,
        "great_rate": 0.5,
        "nice_rate": 0.3,
        "normal_rate": 0.1,
        "spin_success_rate" : 0.5
      },
      "release": {
        "any": {"release_below_cp": 1000, "release_below_iv": 0.9, "logic": "and"},
        "// Example of always releasing Rattata:": {},
        "// any": {"always_release": true},
        "// Example of keeping 3 stronger (based on CP) Pidgey:": {},
        "// Pidgey": {"keep_best_cp": 3},
        "// Example of keeping 2 stronger (based on IV) Zubat:": {},
        "// Zubat": {"keep_best_iv": 2},
        "// Also, it is working with any": {},
        "// any": {"keep_best_iv": 3},
        "// Example of keeping the 2 strongest (based on CP) and 3 best (based on IV) Zubat:": {},
        "// Zubat": {"keep_best_cp": 2, "keep_best_iv": 3}
      },
      "vips" : {
           "Any pokemon put here directly force to use Berry & Best Ball to capture, to secure the capture rate!": {},
          "any": {"catch_above_cp": 1200, "catch_above_iv": 0.9, "logic": "or" },
          "Lapras": {},
          "Moltres": {},
          "Zapdos": {},
          "Articuno": {},

          "// S-Tier pokemons (if pokemon can be evolved into tier, list the representative)": {},
          "Mewtwo": {},
          "Dragonite": {},
          "Snorlax": {},
          "// Mew evolves to Mewtwo": {},
          "Mew": {},
          "Arcanine": {},
          "Vaporeon": {},
          "Gyarados": {},
          "Exeggutor": {},
          "Muk": {},
          "Weezing": {},
          "Flareon": {}

      }
  }
ProblemFactory commented 7 years ago

I think the real game sends some additional data to server than the fake client, which makes the detection of bots pretty easy. The behavior of bot is not really matter.

talobear commented 7 years ago

If that is true then it looks like the bot is not viable, correct?

smfbrooks commented 7 years ago

I have anecdotal evidence that nullifies this. Where were you playing and how many kilometers were walked total?

notVitaliy commented 7 years ago

If the app is sending extra data back to the server then the packets could be sniffed easily and then replicated. Which would make it a pretty bad way to detect if the api calls are coming from the app vs a bot.

There is probably some sort of behavior detection algorithm on their servers, which is why they created the ban-appeal page, in case their algo picked up false positives.

Chances are it's looking for timing of api calls. The UX of the app only allows for the user to perform so many actions within a certain time period. So the server got a spinFort api call within a short time after an evolvePokemon call, then it'd know something is up.

It's probably not exactly that sequence of events, just used that to make my point.

It could have to do with how often the app scans for nearby or how often it reports the user's coordinates. Any number of things can be recorded and then analyzed.

GrosCep commented 7 years ago

Hey, I did more or less the same, with some of the sessions being a bit longer, some a lot shorter, and more sessions too. No teleporting, always running the bot in the same area. The account was created just after the first ban wave a few days ago. I had reached level 24, and got banned between 8:30pm and 10:30pm (GMT + 1) today. I also experienced a soft ban on the first day, because of the 1k pokemons / 24h rule, and get unbanned 12 hours after. The last three were not very active, I have captured more or less 300 pokemons since saturday. And now I get the "Server seems to be busy or offline", only for this account.

leftie1 commented 7 years ago

This makes it easy for Niantic to detect

talobear commented 7 years ago

Ok, so that would mean at the moment the bot should not be used on anything except a test account like GrosCep and I setup. Or said another way, use the bot and you will be banned.

mjmadsen commented 7 years ago

@keugnu What is the proof? I'm quite curious because my account graveyard is adding up pretty quickly.

smfbrooks commented 7 years ago

image I have run this bot for 3 days. It sleeps for about 17 hours a day, so it has been farming for close to maybe 21 hours. Getting close to the 1000 pokemon in 24 hours as you can see. This bot has not had any softban issues whatsoever.

GrosCep commented 7 years ago

@keugnu Wait a bit... My bet is your account will be down by the end of the week. Hopefully I'm wrong... I wonder why my account has been banned while I was not really using it, max 1hr and a half every day during the last three days, always same location etc etc. I guess they gather some data we are not aware of, and two possibilities then, they wait a bit collecting them and ban after a while to avoid too many false positives, or they just do some banning waves twice or three times a week.

avexus commented 7 years ago

Good warning guys.

ubu13 commented 7 years ago

yeah just make new account if you got banned, leveling fast and get banned again. Everytime i open issue page there are some people afraid about banned, if u are afraid dont use bot, chickens!

avexus commented 7 years ago

It's not afraid. If you know the possibility of getting banned is high and avoid using it, it's called cautious.

jboffel commented 7 years ago

API always sends altitude as 8 API doesn't send a bunch of device info

Could you point out more precisely the source code you are referring to? Based on this bot source code it seems it always send 0 not 8. So are you referring to the pogoapi library used by the bot? If so could you show the exact lines and files concerned by that?

Thanks

pickerflicker commented 7 years ago

The bot capture rate was unrealistic and captured pokemon at an impossible rate ignoring animation times. I just saw a commit added to make capturing more realistic! I hope this prevents detection:

"catch_simulation": {
        "flee_count": 3,
        "flee_duration": 2,
        "catch_wait_min": 2,
        "catch_wait_max": 6,
        "berry_wait_min": 2,
        "berry_wait_max": 3,
        "changeball_wait_min": 2,
        "changeball_wait_max": 3
      }

I'd like to see an option setting to occasionally miss with a pokeball though

jboffel commented 7 years ago

I added something similar to pokeball miss already on my local source code. It's not clean but it does the job currently.

In human_behaviour.py:

def miss_pokeball_percentage(factor):
    value = uniform(0, 99)
    logger.info('Pokeball miss throw percentage: {}, chance percentage: {}'.format(factor, value))
    if value >= factor:
        return 1
    else:
        return 0

Used in pokemon_catch_worker.py as it:

response_dict = self.api.catch_pokemon(
                                encounter_id=encounter_id,
                                pokeball=pokeball,
                                normalized_reticle_size=reticle_size_parameter,
                                spawn_point_id=self.spawn_point_guid,
                                hit_pokemon=miss_pokeball_percentage(50),
                                spin_modifier=spin_modifier_parameter,
                                normalized_hit_position=1
                            )

I try to miss basically 50% of my pokeball throw... However it's totally possible I misunderstood how works some of the API parameters. So use at your own risk...

Also rather than adding a specific configuration per action on any thing involving API call, I added a random timer directly on all API call. However I agree that it does not care much about the animation time. Based on the values above, set the minimal random value for the timer to 6 would be sufficient but it will make the bot quite slow.

fosspill commented 7 years ago

Hey all, I've been running my own tests as well! So far I don't have much evidence for anything but maybe it might help:

First bot: Kept most configs standard and ran for about ~10 hours a day for a week. Got banned on the first ban wave. The bot had spent a lot of time trying to catch pokemon without balls right before the ban hit...

Second bot: Tried to make the configs as human like as possible but still ran it for maybe ~10 hours a day. Took 1 day to reach permban. Here I'd manually switch between different paths and turn off and on pokemon catching to vary what it was doing.

Third bot: As humanlike and slow as I could make it with the current options. Only running in a path around my home. I run it for maybe ~2 hours total each day. Going strong 5th day in.

To me it seems like it might have something to do with play time + distance walked. At least this makes me believe that they are NOT detecting something specifically sent from this bot.

EmDee commented 7 years ago

Having the NicknamePokemon task enabled probably doesn't help preventing bans either?

AcorpBG commented 7 years ago

I tested 1 account only after the first wave. Path mode no teleports, running 10hrs a day never ever got soft banned. 2nd wave hit it.

iruy commented 7 years ago

I made a similar test, with a PTC account, I let it run about an entire day, and got to lv 20 very quickly. No softbans, no permabans hit that account. My only banned account, was the one which got softbanned more often, due to quick location changes...

Moreover, I know fair players which plays 10 hour a day, so I don't think Niantic will ban accounts according to long running games. I think it could be more probably due to impossible location changes and (maybe?) IP mismatch between location and connection (I mean, I shouldn't have an Italian IP if my bot is running in NY)

fosspill commented 7 years ago

Ah, that's actually a fair point @iruy. My two first banned accounts were both running from a server I have in a neighbouring country. Now it's running from a server on my own city and I have yet to face a ban on that one.

vosk commented 7 years ago

Personally, I haven`t had a single softban or ban on my fork. The reason, I think, is simple: human behavior. Let me enumerate possible ways for ban detection: get_map_objects timestamps (always zero) altitude (always zero) heartbeat rate (1 sec in the past, really?) get_hatched_eggs rate signature message acc+gyro (not present) pokemon encounter distance (can be up to >110, while the client allows 70m) between StepWalker calls, position remains fixed.

There is a bug in dev that causes the bot to request an already used incubator on every freaking tick() after incubating some egg.

leftie1 commented 7 years ago

@jboffel I'm not a Python dev but it looks like the altitude hard-coding is in src\pgoapi\pgoapi\rpc_apy.pi request.altitude = 8

Also, Signature.proto lists a bunch of items in the data structures but then within _build_main_request() in rpc_api.py, only a few like location_hash1 and location_hash2 are set. You could set more values following https://github.com/keyphact/pgoapi/issues/82#issuecomment-239129004. I don't know what values should be used/whether this is a good idea though.

From Signature.proto, iPhone seems to send alot less information than Android. It'd be good if we knew what a real iPhone Pokemon go client request looks like so we can try to mimic that.

GhosterBot commented 7 years ago

@vosk, did you fixed all thoses points on your fork ?

vosk commented 7 years ago

Of COURSE NOT ! :D I have played with: altitude using gmaps elevation heartbeat rate : 15 sec pokemon encounter distance : limited to something like 40m

vosk commented 7 years ago

@jboffel

That 8 value for alt is rewritten on api.set_position calls with 0.0 (not an all calls)

@all

One important thing I forgot!: every pokeball throw is a hit !

GhosterBot commented 7 years ago

@vosk okay ;-) If I understood you right:

1) altitude using gmaps elevation : You rewrite all call like : self.api.set_position(lat, lng, 0) replacing 0 by the actual altitude of the position given in config file?

2) pokemon encounter distance : limited to something like 40m Where did you change that value ?

thanks ;)

jboffel commented 7 years ago

@vosk @leftie1 Ok so I think the modification I made to support gmaps elevation API (as you did too seems @vosk ) are functional if the bot overwrite the API default value.

On another issue I attached a snippet of code to deal with the altitude but I cleaned it a bit to something like that:

(instead of replacing all the self.apit.set_position I played on the get_position that seems to be used to transfer the position changed by the set_position to the pgoapi)

class PokemonGoBot(object):
    @property
    def position(self):
        alt = get_alt_from_lat_lng((self.api._position_lat, self.api._position_lng),self.config.gmapkey)
        return self.api._position_lat, self.api._position_lng, alt

And in human_behavior.py

def get_alt_from_lat_lng(tuple, api_key):
    logger = logging.getLogger('AltitudeFaker')
    logger.setLevel(logging.INFO)
    # logger.info('Start to capture altitude for current location!')
    alt = 0
    if alt_cache.has_key(tuple):
        alt = alt_cache[tuple]
    else:
        # logger.info('Not in cache yet')
        try:
            gmaps = googlemaps.Client(key=api_key)
            logger.info('Got client')
            alt = gmaps.elevation(tuple)
            logger.info('Got response')
            alt = alt[0]['elevation']
            logger.info('Show response: {}'.format(alt))
            alt_cache[tuple] = alt
        except IOError as e:
            logger.info('Cannot get alt: %s' % e)
            alt = 0
    return alt

The idea behind that is that no matter what coordinate have been set, the get_position will always return the matching altitude then.

@vosk Can you confirm this snippet of code does the job? It ssems to work, but I'm not a python developper and I am not well equipped to debug that precisely.

talobear commented 7 years ago

@iruy, my location changes were not extreme. Just walking around the office during work and then home later. No teleports as I wanted to emulate what I typically would do with the app without the bot.

vosk commented 7 years ago

actually no, the property is just to link the bot to pgo api: @property def position(self): return self.api._position_lat, self.api._position_lng, self.api._position_alt

This simply makes bot.position equal to bot.api._position_lat, [lng], [alt] you need to replace all set_position calls and change the third argument to a valid altitude. However, doing a gmaps elevation call on every tick() will consume your 2500 api call/day limit very fast.

jboffel commented 7 years ago

@vosk I see, however it's difficult to avoid to call at each position change. Calling the API once with multiple value is only possible if you know in advance the path (if you work with random move it seems difficult)...

vosk commented 7 years ago

@jboffel are you referring to calls of set_position? Because think I lost you there.

cypha88 commented 7 years ago

@vosk How do you adjust and make walk rates random? Change altitude?

jboffel commented 7 years ago

@vosk

However, doing a gmaps elevation call on every tick() will consume your 2500 api call/day limit very fast.

I was talking about that comment, I call the API only for unkown coordinate altitude per bot run as I'm caching previous result (only in memory) but yeah it is still a lot of call per day and will use all API call in less than a day.

MeretrixLxxv commented 7 years ago

I am NO expert but assuming you are generally using one area for botting, maybe coordinate/elevation data could be saved in a database (SQL or such) and archived over time. The more that is gathered, the more accurate it could become. That would allow for elevations to be calculated as an average from the DB instead of hammering the Maps API. Of course a reasonable grid size would need to be established as to not map every possible coordinate and it associated elevation. Maybe 10m increments as an example (this is what see in geo datasets I use in my work life). Again, just a thought.

jboffel commented 7 years ago

@MeretrixLxxv If you know the path in advance there are no issue to store the alt permanantly. But if you really do random and want to be accurate it's going to be an issue to store everything even for a limited area

AcorpBG commented 7 years ago

If you use path and GPsie gpx track you already have the altitude in the track.gpx itself

mjmadsen commented 7 years ago

Could use this https://geocoder.readthedocs.io/providers/Google.html#elevation

jboffel commented 7 years ago

@AcorpBG

If you use path and GPsie gpx track you already have the altitude in the track.gpx itself

Of course. But not all people want to use a pre define path

Also even if you use a pre define path, if you use the walk mode then it will generate random point between your define path point to make it looks natural. Then it would mean that you still call the API for all those in the middle random points or that you use an approximative value calculated from the the two already known altitude between point 1 and 2...

pickerflicker commented 7 years ago

prior to iphone 6, there was no altimeter? Can we set our "device name" as say iphone 5 to get around setting alt?

MeretrixLxxv commented 7 years ago

@jboffel I agree with you completely regarding the storage. That is why I stated if it were a recurring area, it may make more sense. Along with a fixed grid pattern, calculate the elevation based on nearest grid point. Again, we don't need precision, just close enough so we do not rely on a hard coded or non-existent value. A quick Google search found me this site (http://www.geoplaner.com/) where could create a "path" or "grid" before hand and then download to a GPX file. In that file, the elevation data is kept. If a decent amount of points were in that file, it may be possible to create an average elevation profile for an area and have that randomized slightly for use in the API calls. I am sure this makes no sense to most of you but hopefully someone gets my idea. :)

keenb commented 7 years ago

Guys, I also want to share my own findings. I run multiple bots and it seems that those I run through my IP are now banned (as I used to run 5 bots from a single IP) no matter how minimal I ran them for. However, the ones going through a VPN is fine - some are constrained to a path and some are to forts all over and it seems to still work. Just my two cents...

GrosCep commented 7 years ago

Just to add something more, I'm noticing that the new soft bans are set up immediately (like once you have reached 1K pokemons in less than 24h, you are soft banned immediately). Where as it seems to take more time for the perm ban. For example, I started a new account 20hours ago, did manual snipping around the world for 2 hours (with old softban each time, fixed par the bot) and then run it a bit around my home. I just started it again, it works perfectly... at level 13.

OR

there is a level threshold for the permaban, for example level 20.

Has someone heard about permaban for a low leveled account ? Like less than 15 or 20 ?

avexus commented 7 years ago

i'm still new to this and it's the first time i hear about 2500 api call/day limit. Can we set up a local database of often-visited spots with altitudes info already pulled? Like record them on a local file like path.json? also we can have info about this from other users too.

avexus commented 7 years ago

@vosk what does "heartbeat rate : 15 sec" do? thank you

GrosCep commented 7 years ago

@oleerik @iruy @vosk

It seems that you have working accounts with some kind of human behavior bots. Just to know, do you use nicknaming ? If yes, which kind of template ?

I'm just asking because, as, I guess, almost everyone using the nicknames (with this bot, or with others, they have the same feature as far as I know, or even manually) puts the hidden IV values in the nickname, it's a very easy way to find people that don't respect the rules, botting or not botting, it just shows that someone has used a third-party app. And avoid the false positives for Niantic.

fosspill commented 7 years ago

@GrosCep I had nicknaming active on my two banned accounts but not my current, still alive one.

However you got me thinking... Both of my banned accounts got banned after they reached 20. Does it have something to do with how quickly we reach 20, combined with some other triggers, possibly?

My current one reached 20 just a few hours ago, we'll see if it survives or not!

EDIT: I used name_iv% as my template. However, there are legit ways of finding IV so I don't think having IVs in the names would trigger a ban.

GrosCep commented 7 years ago

I'm not really sure it's about how fast you can reach level 20... Or any level around 20 which could be a threshold... Some people can go quickly to level 20 using lucky eggs and catching every pudgy they find, without cheating. So I think they start to look at something specific once you have reached this threshold level, not before. That could explain why my last night account, after visiting Bombai, New York, Melbourne, is still running now... currently at level 15.

fosspill commented 7 years ago

We shall see. I'll keep running mine as human-like as I can and see if it helps at all or if I'll face a new permban

supergithubo commented 7 years ago

I get banned today and also my friend who used 4 bots. All of our accounts were created same day. We survived the first ban wave but not this time. Banned account levels (27, 26, 25, 22). One of his account is still in level 18 also created same day but still running fine.