Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
File "c:\bot\pirate\kuz\src\game_actors_and_handlers\wo rkers.py", line 110, in
handle
gameObject.target = dict2obj({'id': event_to_handle.targetId})
AttributeError: 'NoneType' object has no attribute 'target'
Периодически обваливается бот, подскажите куда глядеть? с таймером связано?
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Цитата:
File "c:\bot\pirate\kuz\src\game_actors_and_handlers\wo rkers.py", line 110, in
handle
gameObject.target = dict2obj({'id': event_to_handle.targetId})
AttributeError: 'NoneType' object has no attribute 'target'
Периодически обваливается бот, подскажите куда глядеть? с таймером связано?
Похоже я сталкнулся с похожей проблемой. Первый раз запустил бота на ночь рубить дрова. Утром обнаружил, что после вырубки дерева бот остановился. Я думаю, что обработка евента gainMaterial неправильная.
Что происходит:
- отравляется евент на рубку
- приходит евент gainMaterial с target
- после добычи ресурса опять приходит евент gainMaterial с target
...
- кончается ресурс, приходит евент gainMaterial без таргет:
{"type":"gainMaterial","action":"stop","objId":87, "startCounter":85,"doneCounter":85}
- бот не понимает, что ресурс кончился и нужно рубить другое дерево
Что могло произойти (и что у меня во время отладки до этого было):
- отравляется евент на рубку
- приходит евент gainMaterial с target
- после добычи ресурса опять приходит евент gainMaterial с target
...
- кончается ресурс, приходит евент gainMaterial с target
- бот понимает, что дерево кончилось и отправляется рубить другое дерево
приходит евент gainMaterial без таргет:
{"type":"gainMaterial","action":"stop","objId":87, "startCounter":85,"doneCounter":85}
- бот понимает, что ресурс кончился и нужно рубить другое дерево
Я думаю, что надо сделать так:
если приходит {"type":"gainMaterial","action":"stop","objId":87, "startCounter":85,"doneCounter":85},
то надо смотреть на параметры startCounter и doneCounter, если они равны, то ресурс закончился. Видимо не нужно обрабатывать jobEndTime, нужно тестировать.
Последний раз редактировалось ruslanische; 17.01.2015 в 16:42.
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Цитата:
Сообщение от Xmaxudigun
File "c:\bot\pirate\kuz\src\game_actors_and_handlers\wo rkers.py", line 110, in
handle
gameObject.target = dict2obj({'id': event_to_handle.targetId})
AttributeError: 'NoneType' object has no attribute 'target'
Периодически обваливается бот, подскажите куда глядеть? с таймером связано?
в данном случае когда пришел ответ от сервера то бот на локе не обнаружил работника , то есть скорее всего уже перешел на другой остров
из ошибки же видно AttributeError: 'NoneType' object has no attribute 'target', а gameObject мы обьявили: gameObject = self.__game_location.get_object_by_id(event_to_han dle.objId) нужно либо через try,except ,либо если gameObject is None return ну и проверку на атрибут 'target'
Добавлено через 2 минуты
Цитата:
Сообщение от ruslanische
Похоже я сталкнулся с похожей проблемой. Первый раз запустил бота на ночь рубить дрова. Утром обнаружил, что после вырубки дерева бот остановился. Я думаю, что обработка евента gainMaterial неправильная.
Что происходит:
- отравляется евент на рубку
- приходит евент gainMaterial с target
- после добычи ресурса опять приходит евент gainMaterial с target
...
- кончается ресурс, приходит евент gainMaterial без таргет:
{"type":"gainMaterial","action":"stop","objId":87, "startCounter":85,"doneCounter":85}
- бот не понимает, что ресурс кончился и нужно рубить другое дерево
Что могло произойти (и что у меня во время отладки до этого было):
- отравляется евент на рубку
- приходит евент gainMaterial с target
- после добычи ресурса опять приходит евент gainMaterial с target
...
- кончается ресурс, приходит евент gainMaterial с target
- бот понимает, что дерево кончилось и отправляется рубить другое дерево
приходит евент gainMaterial без таргет:
{"type":"gainMaterial","action":"stop","objId":87, "startCounter":85,"doneCounter":85}
- бот понимает, что ресурс кончился и нужно рубить другое дерево
Я думаю, что надо сделать так:
если приходит {"type":"gainMaterial","action":"stop","objId":87, "startCounter":85,"doneCounter":85},
то надо смотреть на параметры startCounter и doneCounter, если они равны, то ресурс закончился. Видимо не нужно обрабатывать jobEndTime, нужно тестировать.
смотреть надо action, если start то там будет таргет ,если стоп то таргета соответственно нет
Последний раз редактировалось greyzza; 17.01.2015 в 17:02.
Причина: Добавлено сообщение
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Цитата:
в общем у меня вот таким образом сделано, ни одной проблемы не возникает
Возможно проблема в том, что я после отправки евента жду результат в цикле. Т.е. после отправки "action": "gain" жду ответ "type":"gainMaterial". И вот ночью бот его почему-то не получил и завис в цикле, надо разбираться.
Добавлено через 8 минут
Как убедиться, что после отправки рубить лес на сервере зомби будет рубить лес? Я пока вижу, что никак. Да, сервер отправляет в ответ "type":"gainMaterial","action":"start", но тогда мы должны ждать этот ответ и не отправлять/обрабатывать другие евенты, т.к. иначе дерево придется заочно пометить занятым.
Последний раз редактировалось ruslanische; 17.01.2015 в 17:31.
Причина: Добавлено сообщение
, но выкладывать после уважаемого greyzza уже стыдно. Я не переписывал, а только закомментил и поправил баги, и, когда начало работать, забыл.
Цитата:
Сообщение от ruslanische
ошибка в алгоритме все же...
Хуже того, она закрыта try: except: pass . Как же меня это бесило, когда я это наконец-то заметил
Цитата:
Сообщение от ruslanische
жду результат
Ну, я хотел это откритиковать выше, что так почему-то нельзя делать, а теперь Вы видите, почему. Надо ждать - повешайте обработчик на ответ и забейте.
Цитата:
Сообщение от ruslanische
что-то не понял...
Начиная с 30.12.2014 или раньше, клиент отдаёт "time": время_с_начала_zombiferma_swf в запросе EVT, мы это пропустили. Кто не отдаёт, тот бот. Скоро обновление с окончанием продажи выкупа (он до 14.01 обещали)...
Последний раз редактировалось megabyte0; 17.01.2015 в 17:44.
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Цитата:
иначе дерево придется заочно пометить занятым
дак так в воркере и сделано, помечается ресурс занятым, согласен что неправильно, что если переход отключен то так и будет занят ресурс до перезагрузки бота но если переход включен то естественно что при заходе на остров он правильно видит ресурсы которые можно рубить и какие работники свободны. все острова вырублены этим воркером , ну вот не заморачивался я сидеть на одном острове и вырубать его в ноль когда активен супер урожай и прочее))
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Цитата:
Сообщение от greyzza
ну вот не заморачивался я сидеть на одном острове и вырубать его в ноль
Я заморачивался, помнится за золотую фемиду. Не в ноль, но гдет 1.5 суток убил. Всё было ок с моими обработчиками, может у меня сам вырубщик
Код:
# coding=utf-8
import logging
from game_state.game_types import GameWoodGrave, GameWoodGraveDouble,\
GamePickItem, GameWoodTree, GameGainItem, GamePickup,\
GameTraderGrave, GameTraderGraveWithBrains
from game_state.game_event import dict2obj
from game_actors_and_handlers.base import BaseActor
from game_actors_and_handlers.islandmap import Area
import time
logger = logging.getLogger(__name__)
class TargetSelecter(BaseActor):
def get_worker_types(self):
return []
def get_object_type(self):
return None
def get_sent_job(self):
return ""
def is_busy(self, worker):
return self._get_player_brains().is_using_brains(worker)
def perform_action(self):
# get all free workers
wood_graves = self._get_game_location().get_all_objects_by_types(
self.get_worker_types()
)
# get free workers
free_workers = []
for wood_grave in wood_graves:
if not self.is_busy(wood_grave):
free_workers.append(wood_grave)
# for each free worker
for free_worker in free_workers:
# check brains count
if self._get_player_brains().has_sufficient_brains_count(
free_worker):
self.start_job(free_worker)
def start_job(self, free_worker):
logger.info("Отправляем зомби на работу")
# select any wood tree
resources = self._get_game_location().get_all_objects_by_type(
self.get_object_type()
)
#self.reduce_resources(resources)
if resources:
# make sure gain is not started yet
resource = self.__find_first_gain_not_started(resources)
if not resource:
logger.info("Все ресурсы уже добываются")
else:
logger.info(self.get_sent_job())
gain_event = GameGainItem(resource.id, free_worker.id)
self._get_events_sender().send_game_events(
[gain_event])
resource.gainStarted = True
else:
logger.info("Не осталось ресурсов для добычи")
def __find_first_gain_not_started(self, resources):
resource_list=[resource for resource in resources if not resource.gainStarted]# and not ((self.location_id()=='main') and (resource.x>=64) and (resource.y<=29))]
if resource_list:
max_res=max((resource.materialCount,resource.id,resource) for resource in resource_list)[2]
##return max_res ##
else:
#все ресурсы добываются, или вообще нету
return None
if self.placeAvailable(Area(0,0,11,11))[0]:
return max_res
else:
min_list_ids=min(self.sumMaterial(Area(0,0,11,11)))[1]
min_list_gain_not_started=[]
found = False
for obj_id in min_list_ids:
obj=self._get_game_location().get_object_by_id(obj_id)
if (not obj.gainStarted):
if (obj.type in self.get_object_type()):
min_list_gain_not_started.append(obj)
else:
logger.info(u"Нужен добыватель %s"%obj.type)
found = True
#return None
if min_list_gain_not_started:
return max((resource.materialCount,resource.id,resource) for resource in min_list_gain_not_started)[2]
else:
return None if found else max_res
## for resource in resources:
## if not resource.gainStarted:
## return resource
class ResourcePicker(BaseActor):
def get_worker_types(self):
return []
def perform_action(self):
wood_graves = self._get_game_location().get_all_objects_by_types(
self.get_worker_types())
if not wood_graves: return
events=[]
material_ids={}
for wood_grave in wood_graves:
if hasattr(wood_grave,'jobEndTime'):
next_gain_time_after=( long(wood_grave.jobEndTime) -
self._get_timer()._get_current_client_time() )*0.001
self.visit_next_time(next_gain_time_after+5) ##
materials = list(wood_grave.materials)
for material_id in materials:
if material_ids.has_key(material_id):
material_ids[material_id]+=1
else:
material_ids[material_id]=1
material = self._get_item_reader().get(material_id)
#name = material.name
#logger.info(u'Подбираем ' + name)
events.append(self._pick_material(wood_grave, material.id))
# update game state
#if material.id<>None: self._get_game_state().add_from_storage('@'+material.id,1)
wood_grave.materials.remove(material_id)
#wood_grave.materials=[]
for material_id,v in material_ids.iteritems():
material = self._get_item_reader().get(material_id)
name = material.name
if material.id<>None: self._get_game_state().add_from_storage('@'+material.id,v)
have_in_storage = self._get_game_state().count_in_storage('@'+material.id)
logger.info(u'Подбираем %d %s /%d'%(v,name,have_in_storage))
if events:
self._get_events_sender().send_game_events(events)
self.set_visiting_time(600)
def _pick_material(self, wood_grave, material_id):
pick_item = GamePickItem(itemId=material_id, objId=wood_grave.id)
return pick_item
#self._get_events_sender().send_game_events([pick_item])
тоже поменян?
Цитата:
Сообщение от ruslanische
Как делать скрытый текст? [spoiler][/spoiler] не работает...
[ MORE = "текст спойлера" ] под спойлером [ /MORE ] без пробелов внутри тэгов.
Последний раз редактировалось megabyte0; 17.01.2015 в 17:51.
, то он должен был проверить, закончена ли работа:
Код:
if (self._get_timer().has_elapsed(worker[u'jobEndTime']))
Если условие не сработало, то дерево так и останется недобытым, хотя на сервере оно исчерпано.
Далее бот опять пытается добыть это дерево и ждет ответ от сервера, но тот мне не отвечал, т.к. дерева такого не было уже
Добавлено через 20 минут
Цитата:
Скоро обновление с окончанием продажи выкупа (он до 14.01 обещали)...
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Цитата:
Кажись я понял в чем у меня проблема:
если после вырубки дерева бот получил
Код:
{"type":"gainMaterial","action":"stop","objId":87, "startCounter":97,"doneCounter":97}
, то он должен был проверить, закончена ли работа:
Код:
if (self._get_timer().has_elapsed(worker[u'jobEndTime']))
Если условие не сработало, то дерево так и останется недобытым, хотя на сервере оно исчерпано.
Далее бот опять пытается добыть это дерево и ждет ответ от сервера, но тот мне не отвечал, т.к. дерева такого не было уже
да у тебя так и получилось, условие не сработало дальше: target_resource[u'gainStarted'] = False а на самом деле ресурс должен быть удалён)), так что таймер нафиг
Re: Zombot (Клиент для игры Зомби ферма) [Обсуждение]
Вот и выгода синхронной обработки событий, сразу видно рассинхрон - завис в цикле ожидания евента gainMaterial. Можно в этом цикле ждать несколько секунд и кидать исключение, после которого перезапускать бота.