Advertisement
Guest User

Untitled

a guest
Nov 11th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.83 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. import socket
  3. import random
  4. from BeautifulSoup import BeautifulSoup
  5. from logging.handlers import RotatingFileHandler
  6. import time
  7. import logging
  8. import mechanize
  9. import os
  10. import re
  11. import sys
  12. from random import randint
  13. from datetime import datetime, timedelta
  14. from utils import *
  15. from urllib import urlencode
  16. from planet import Planet, Moon
  17. from attack import Attack
  18. from transport_manager import TransportManager
  19. from config import options
  20. from sim import Sim
  21. socket.setdefaulttimeout(float(options['general']['timeout']))
  22.  
  23.  
  24. class Bot(object):
  25.  
  26. BASE_URL = 'https://dk.ogame.gameforge.com/'
  27. LOGIN_URL = 'https://dk.ogame.gameforge.com/main/login'
  28. HEADERS = [('User-agent', 'Mozilla/5.0 (Windows NT 6.2; WOW64)\
  29. AppleWebKit/537.15 (KHTML, like Gecko) Chrome/24.0.1295.0 Safari/537.15')]
  30. RE_BUILD_REQUEST = re.compile(r"sendBuildRequest\(\'(.*)\', null, 1\)")
  31. RE_SERVER_TIME = re.compile(r"var serverTime=new Date\((.*)\);var localTime")
  32.  
  33. #ship -> ship id on the page
  34. SHIPS = {
  35. 'lm': '204',
  36. 'hm': '205',
  37. 'cr': '206',
  38. 'ow': '207',
  39. 'pn': '215',
  40. 'bb': '211',
  41. 'ns': '213',
  42. 'gs': '214',
  43. 'lt': '202',
  44. 'dt': '203',
  45. 'cs': '208',
  46. 'rc': '209',
  47. 'ss': '210'
  48. }
  49.  
  50. # mission ids
  51. MISSIONS = {
  52. 'attack': '1',
  53. 'transport': '3',
  54. 'station': '4',
  55. 'expedition': '15',
  56. 'collect' : '8'
  57. }
  58.  
  59. TARGETS = {
  60. 'planet' : '1',
  61. 'moon' : '3',
  62. 'debris' : '2'
  63. }
  64.  
  65. SPEEDS = {
  66. 100: '10',
  67. 90: '9',
  68. 80: '8',
  69. 70: '7',
  70. 60: '6',
  71. 50: '5',
  72. 40: '4',
  73. 30: '3',
  74. 20: '2',
  75. 10: '1'
  76. }
  77.  
  78. def __init__(self, username=None, password=None, uni='69'):
  79. self.uni = uni
  80. self.username = username
  81. self.password = password
  82. self.logged_in = False
  83.  
  84. self._prepare_logger()
  85. self._prepare_browser()
  86. farms = options['farming']['farms']
  87. self.farm_no = randint(0, len(farms)-1) if farms else 0
  88.  
  89. self.MAIN_URL = 'https://s%s-dk.ogame.gameforge.com/game/index.php' % self.uni
  90. self.PAGES = {
  91. 'main': self.MAIN_URL + '?page=overview',
  92. 'resources': self.MAIN_URL + '?page=resources',
  93. 'station': self.MAIN_URL + '?page=station',
  94. 'research': self.MAIN_URL + '?page=research',
  95. 'shipyard': self.MAIN_URL + '?page=shipyard',
  96. 'defense': self.MAIN_URL + '?page=defense',
  97. 'fleet': self.MAIN_URL + '?page=fleet1',
  98. 'galaxy': self.MAIN_URL + '?page=galaxy',
  99. 'galaxyCnt': self.MAIN_URL + '?page=galaxyContent',
  100. 'events': self.MAIN_URL + '?page=eventList',
  101. }
  102. self.planets = []
  103. self.moons = []
  104. self.active_attacks = []
  105.  
  106. self.fleet_slots = 0
  107. self.active_fleets = 0
  108.  
  109. self.server_time = self.local_time = datetime.now()
  110. self.time_diff = 0
  111. self.emergency_sms_sent = False
  112. self.transport_manager = TransportManager()
  113. self.sim = Sim()
  114.  
  115. def _get_url(self, page, planet=None):
  116. url = self.PAGES[page]
  117. if planet is not None:
  118. url += '&cp=%s' % planet.id
  119. return url
  120.  
  121. def _prepare_logger(self):
  122. self.logger = logging.getLogger("mechanize")
  123. fh = RotatingFileHandler('bot.log', maxBytes=100000, backupCount=5)
  124. sh = logging.StreamHandler()
  125. fmt = logging.Formatter(fmt='%(asctime)s %(levelname)s %(message)s',
  126. datefmt='%m-%d, %H:%M:%S')
  127. fh.setFormatter(fmt)
  128. sh.setFormatter(fmt)
  129. self.logger.setLevel(logging.INFO)
  130. self.logger.addHandler(fh)
  131. self.logger.addHandler(sh)
  132.  
  133. def _prepare_browser(self):
  134. self.br = mechanize.Browser()
  135. self.br.set_handle_equiv(True)
  136. self.br.set_handle_redirect(True)
  137. self.br.set_handle_referer(True)
  138. self.br.set_handle_robots(False)
  139. self.br.addheaders = self.HEADERS
  140.  
  141. def _parse_build_url(self, js):
  142. """
  143. convert: `sendBuildRequest('url', null, 1)`; into: `url`
  144. """
  145. return self.RE_BUILD_REQUEST.findall(js)[0]
  146.  
  147. def _parse_server_time(self, content):
  148. return self.RE_SERVER_TIME.findall(content)[0]
  149.  
  150. def get_mother(self):
  151. for p in self.planets:
  152. if p.mother:
  153. return p
  154. return p[0] if self.planets else None
  155.  
  156. def get_closest_planet(self, p):
  157. def min_dist(p, d):
  158. return d
  159. _, d, _ = p.split(":")
  160. return sorted([(planet, planet.get_distance(p)) for planet in self.planets],
  161. key=lambda x: x[1])[0][0]
  162.  
  163.  
  164. def find_planet(self, name=None, coords=None, id=None, is_moon=None):
  165. if is_moon:
  166. planets = self.moons
  167. else:
  168. planets = self.planets
  169. for p in planets:
  170. if name == p.name or coords == p.coords or id == p.id:
  171. return p
  172.  
  173. def get_safe_planet(self, planet):
  174. '''
  175. Get first planet which is not under attack and isn't `planet`
  176. '''
  177. unsafe_planets = [a.planet for a in self.active_attacks]
  178. for p in self.planets:
  179. if not p in unsafe_planets and p != planet:
  180. return p
  181. # no safe planets! go to mother
  182. return self.planets[0]
  183.  
  184. def login(self, username=None, password=None):
  185. username = username or self.username
  186. password = password or self.password
  187.  
  188. try:
  189. resp = self.br.open(self.MAIN_URL, timeout=10)
  190. soup = BeautifulSoup(resp)
  191. except:
  192. return False
  193.  
  194. alert = soup.find(id='attack_alert')
  195.  
  196. # no redirect on main page == user logged in
  197. if resp.geturl() != self.BASE_URL and alert:
  198. self.logged_in = True
  199. self.logger.info('Logged as: %s' % username)
  200. return True
  201.  
  202. self.logger.info('Logging in..')
  203. self.br.select_form(name='loginForm')
  204. self.br.form['uni'] = ['s%s-dk.ogame.gameforge.com' % self.uni]
  205. self.br.form['login'] = username
  206. self.br.form['pass'] = password
  207. self.br.submit()
  208.  
  209. if self.br.geturl().startswith(self.MAIN_URL):
  210. self.logged_in = True
  211. self.logger.info('Logged as: %s' % username)
  212. return True
  213. else:
  214. self.logged_in = False
  215. self.logger.error('Login failed!')
  216. return False
  217.  
  218. def calc_time(self, resp):
  219. try:
  220. y, mo, d, h, mi, sec = map(int, self._parse_server_time(resp).split(','))
  221. except:
  222. self.logger.error('Exception while calculating time')
  223. else:
  224. self.local_time = n = datetime.now()
  225. self.server_time = datetime(n.year, n.month, n.day, h, mi, sec)
  226. self.time_diff = self.server_time - self.local_time
  227.  
  228. self.logger.info('Server time: %s, local time: %s' % \
  229. (self.server_time, self.local_time))
  230.  
  231. def fetch_planets(self):
  232. self.logger.info('Fetching planets..')
  233. resp = self.br.open(self.PAGES['main']).read()
  234.  
  235. self.calc_time(resp)
  236.  
  237. soup = BeautifulSoup(resp)
  238. self.planets = []
  239. self.moons = []
  240.  
  241. try:
  242. for i, c in enumerate(soup.findAll('a', 'planetlink')):
  243. name = c.find('span', 'planet-name').text
  244. coords = c.find('span', 'planet-koords').text[1:-1]
  245. url = c.get('href')
  246. p_id = int(c.parent.get('id').split('-')[1])
  247. construct_mode = len(c.parent.findAll('a', 'constructionIcon')) != 0
  248. p = Planet(p_id, name, coords, url, construct_mode)
  249. if i == 0:
  250. p.mother = True
  251. self.planets.append(p)
  252.  
  253. #check if planet has moon
  254. moon = c.parent.find('a', 'moonlink')
  255. if moon and 'moonlink' in moon['class']:
  256. url = moon.get('href')
  257. m_id = url.split('cp=')[1]
  258. m = Moon(m_id, coords, url)
  259. self.moons.append(m)
  260. except:
  261. self.logger.exception('Exception while fetching planets')
  262. else:
  263. self.check_attacks(soup)
  264.  
  265. def handle_planets(self):
  266. self.fetch_planets()
  267.  
  268. for p in iter(self.planets):
  269. self.update_planet_info(p)
  270. self.update_planet_fleet(p)
  271. for m in iter(self.moons):
  272. self.update_planet_info(m)
  273. self.update_planet_fleet(m)
  274.  
  275. def update_planet_fleet(self, planet):
  276. resp = self.br.open(self._get_url('fleet', planet))
  277. soup = BeautifulSoup(resp)
  278. ships = {}
  279. for k, v in self.SHIPS.iteritems():
  280. available = 0
  281. try:
  282. s = soup.find(id='button' + v)
  283. available = int(s.find('span', 'textlabel').nextSibling.replace('.', ''))
  284. except:
  285. available = 0
  286. ships[k] = available
  287.  
  288. #self.logger.info('Updating %s fleet' % planet)
  289. #self.logger.info('%s' % fleet)
  290. planet.ships = ships
  291.  
  292. def update_planet_info(self, planet):
  293. in_construction_mode = False
  294. resp = self.br.open(self._get_url('resources', planet))
  295. soup = BeautifulSoup(resp)
  296.  
  297. try:
  298. metal = int(soup.find(id='resources_metal').text.replace('.',''))
  299. planet.resources['metal'] = metal
  300. crystal = int(soup.find(id='resources_crystal').text.replace('.',''))
  301. planet.resources['crystal'] = crystal
  302. deuterium = int(soup.find(id='resources_deuterium').text.replace('.',''))
  303. planet.resources['deuterium'] = deuterium
  304. energy = int(soup.find(id='resources_energy').text.replace('.',''))
  305. planet.resources['energy'] = energy
  306. except:
  307. self.logger.exception('Exception while updating resources info')
  308. else:
  309. self.logger.info('Updating resources info for %s:' % planet)
  310. s = 'metal - %(metal)s, crystal - %(crystal)s, deuterium - %(deuterium)s'
  311. self.logger.info(s % planet.resources)
  312. if planet.is_moon():
  313. return
  314. try:
  315. buildingList = soup.find(id='building')
  316. buildings = ('metalMine', 'crystalMine', 'deuteriumMine', 'solarPlant',
  317. 'fusionPlant', 'solarSatellite'
  318. )
  319. for building, b in zip(buildings, buildingList.findAll('li')):
  320. can_build = 'on' in b.get('class')
  321. fb = b.find('a', 'fastBuild')
  322. build_url = fb.get('onclick') if fb else ''
  323. if build_url:
  324. build_url = self._parse_build_url(build_url)
  325. try:
  326. level = int(b.find('span', 'textlabel').nextSibling)
  327. except AttributeError:
  328. try:
  329. level = int(b.find('span', 'level').text)
  330. except:
  331. pass
  332. suff_energy = planet.resources['energy'] - self.sim.upgrade_energy_cost(building, level+1) > 0
  333. res = dict(
  334. level=level,
  335. can_build=can_build,
  336. build_url=build_url,
  337. sufficient_energy=suff_energy
  338. )
  339.  
  340. planet.buildings[building] = res
  341.  
  342. if buildingList.find('div', 'construction'):
  343. in_construction_mode = True
  344. except:
  345. self.logger.exception('Exception while updating buildings info')
  346. return False
  347. else:
  348. self.logger.info('%s buildings were updated' % planet)
  349. if not in_construction_mode:
  350. text, url = planet.get_mine_to_upgrade()
  351. if url:
  352. self.logger.info('Building upgrade on %s: %s'% (planet, text))
  353. self.br.open(url)
  354. planet.in_construction_mode = True
  355. #let now transport manager to clear building queue
  356. self.transport_manager.update_building(planet)
  357. else:
  358. self.logger.info('Building queue is not empty')
  359. return True
  360.  
  361. def transport_resources(self):
  362. tasks = self.transport_manager.find_dest_planet(self.planets)
  363. if tasks is None:
  364. return False
  365. self.logger.info(self.transport_manager.get_summary())
  366. for task in iter(tasks):
  367. self.logger.info('Transport attempt from: %s, to: %s with resources %s' \
  368. % (task['from'], task['where'], task['resources']))
  369. result = self.send_fleet(
  370. task['from'],
  371. task['where'].coords,
  372. fleet=task['from'].get_fleet_for_resources(task['resources']),
  373. resources=task['resources'],
  374. mission='transport'
  375. )
  376. if result:
  377. self.transport_manager.update_sent_resources(task['resources'])
  378. self.logger.info('Resources sent: %s, resources needed: %s' \
  379. % (task['resources'], self.transport_manager.get_resources_needed()))
  380.  
  381. return True
  382.  
  383. def build_defense(self, planet):
  384. """
  385. Build defense for all resources on the planet
  386. 1. plasma
  387. 2. gauss
  388. 3. heavy cannon
  389. 4. light cannon
  390. 5. rocket launcher
  391. """
  392. url = self._get_url('defense', planet)
  393. resp = self.br.open(url)
  394. for t in ('406', '404', '403', '402', '401'):
  395. self.br.select_form(name='form')
  396. self.br.form.new_control('text','menge',{'value':'100'})
  397. self.br.form.fixup()
  398. self.br['menge'] = '100'
  399.  
  400. self.br.form.new_control('text','type',{'value':t})
  401. self.br.form.fixup()
  402. self.br['type'] = t
  403.  
  404. self.br.form.new_control('text','modus',{'value':'1'})
  405. self.br.form.fixup()
  406. self.br['modus'] = '1'
  407.  
  408. self.br.submit()
  409.  
  410. def get_player_status(self, destination, origin_planet=None):
  411. if not destination:
  412. return
  413.  
  414. status = {}
  415. origin_planet = origin_planet or self.get_closest_planet(destination)
  416. galaxy, system, position = destination.split(':')
  417.  
  418. url = self._get_url('galaxyCnt', origin_planet)
  419. data = urlencode({'galaxy': galaxy, 'system': system})
  420. resp = self.br.open(url, data=data)
  421. soup = BeautifulSoup(resp)
  422.  
  423. soup.find(id='galaxytable')
  424. planets = soup.findAll('tr', {'class': 'row'})
  425. target_planet = planets[int(position)-1]
  426. name_el = target_planet.find('td', 'playername')
  427. status['name'] = name_el.find('span').text
  428.  
  429. status['inactive'] = 'inactive' in name_el.get('class', '')
  430. return status
  431.  
  432. def find_inactive_nearby(self, planet, radius=15):
  433.  
  434. self.logger.info("Searching idlers near %s in radius %s"
  435. % (planet, radius))
  436.  
  437. nearby_systems = planet.get_nearby_systems(radius)
  438. idlers = []
  439.  
  440. for system in nearby_systems:
  441. galaxy, system = system.split(":")
  442. url = self._get_url('galaxyCnt', planet)
  443. data = urlencode({'galaxy': galaxy, 'system': system})
  444. resp = self.br.open(url, data=data)
  445. soup = BeautifulSoup(resp)
  446.  
  447. galaxy_el = soup.find(id='galaxytable')
  448. planets = galaxy_el.findAll('tr', {'class': 'row'})
  449. for pl in planets:
  450. name_el = pl.find('td', 'playername')
  451. debris_el = pl.find('td', 'debris')
  452. inactive = 'inactive' in name_el.get('class', '')
  453. debris_not_found = 'js_no_action' in debris_el.get('class', '')
  454. if not inactive or not debris_not_found:
  455. continue
  456. position = pl.find('td', 'position').text
  457. coords = "%s:%s:%s" % (galaxy, system, position)
  458. player_id = name_el.find('a').get('rel')
  459.  
  460. player_info = soup.find(id=player_id)
  461. rank_el = player_info.find('li', 'rank')
  462.  
  463. if not rank_el:
  464. continue
  465.  
  466. rank = int(rank_el.find('a').text)
  467. if rank > 4000 or rank < 900:
  468. continue
  469.  
  470. idlers.append(coords)
  471. time.sleep(2)
  472.  
  473. return idlers
  474.  
  475. def find_inactives(self):
  476.  
  477. inactives = []
  478. for p in self.planets:
  479. try:
  480. idlers = self.find_inactive_nearby(p)
  481. self.logger.info(" ".join(idlers))
  482. inactives.extend(idlers)
  483. except Exception as e:
  484. self.logger.exception(e)
  485. continue
  486. time.sleep(5)
  487.  
  488. self.logger.info(" ".join(inactives))
  489. self.inactives = list(set(inactives))
  490. self.logger.info(inactives)
  491.  
  492. def send_fleet(self, origin_planet, destination, fleet={}, resources={},
  493. mission='attack', target='planet', speed=None):
  494. if origin_planet.coords == destination:
  495. self.logger.error('Cannot send fleet to the same planet')
  496. return False
  497. self.logger.info('Sending fleet from %s to %s (%s)' \
  498. % (origin_planet, destination, mission))
  499. resp = self.br.open(self._get_url('fleet', origin_planet))
  500. try:
  501. try:
  502. self.br.select_form(name='shipsChosen')
  503. except mechanize.FormNotFoundError:
  504. self.logger.info('No available ships on the planet')
  505. return False
  506.  
  507. soup = BeautifulSoup(resp)
  508. for ship, num in fleet.iteritems():
  509. s = soup.find(id='button' + self.SHIPS[ship])
  510. num = int(num)
  511. try:
  512. available = int(s.find('span', 'textlabel').nextSibling.replace('.', ''))
  513. except:
  514. available = 0
  515. if available < num and mission in ('attack', 'expedition'):
  516. self.logger.info('No available ships to send')
  517. return False
  518. if num > 0:
  519. self.br.form['am' + self.SHIPS[ship]] = str(num)
  520.  
  521. self.br.submit()
  522.  
  523. try:
  524. self.br.select_form(name='details')
  525. except mechanize.FormNotFoundError:
  526. self.logger.info('No available ships on the planet')
  527. return False
  528.  
  529. galaxy, system, position = destination.split(':')
  530. self.br['galaxy'] = galaxy
  531. self.br['system'] = system
  532. self.br['position'] = position
  533. self.br.form.find_control("type").readonly = False
  534. self.br['type'] = self.TARGETS[target]
  535. self.br.form.find_control("speed").readonly = False
  536. if speed:
  537. self.br['speed'] = self.SPEEDS[speed]
  538. self.br.submit()
  539.  
  540. self.br.select_form(name='sendForm')
  541. self.br.form.find_control("mission").readonly = False
  542. self.br.form['mission'] = self.MISSIONS[mission]
  543. if 'metal' in resources:
  544. self.br.form['metal'] = str(resources['metal'])
  545. if 'crystal' in resources:
  546. self.br.form['crystal'] = str(resources['crystal'])
  547. if 'deuterium' in resources:
  548. self.br.form['deuterium'] = str(resources['deuterium'])
  549. self.br.submit()
  550. except Exception as e:
  551. self.logger.exception(e)
  552. return False
  553. else:
  554. if mission == 'attack':
  555. self.farm_no += 1
  556. return True
  557.  
  558. def send_message(self, url, player, subject, message):
  559. self.logger.info('Sending message to %s: %s' % (player, message))
  560. self.br.open(url)
  561. self.br.select_form(nr=0)
  562. self.br.form['betreff'] = subject
  563. self.br.form['text'] = message
  564. self.br.submit()
  565.  
  566. def send_sms(self, msg):
  567. from smsapigateway import SMSAPIGateway
  568. try:
  569. SMSAPIGateway().send(msg)
  570. except Exception as e:
  571. self.logger.exception(str(e))
  572.  
  573. def handle_attacks(self):
  574. attack_opts = options['attack']
  575. send_sms = bool(options['sms']['send_sms'])
  576.  
  577. for a in self.active_attacks:
  578. if a.is_dangerous():
  579. self.logger.info('Handling attack: %s' % a)
  580. if not a.planet.is_moon():
  581. self.build_defense(a.planet)
  582. if send_sms and not a.sms_sent:
  583. self.send_sms(a.get_sms_text())
  584. a.sms_sent = True
  585. if send_sms and not a.message_sent:
  586. self.send_message(a.message_url, a.player, attack_opts['message_topic'],
  587. a.get_random_message())
  588. a.message_sent = True
  589. self.fleet_save(a.planet)
  590.  
  591. def check_attacks(self, soup):
  592. alert = soup.find(id='attack_alert')
  593. if not alert:
  594. self.logger.exception('Check attack failed')
  595. return
  596. if 'noAttack' in alert.get('class', ''):
  597. self.logger.info('No attacks')
  598. self.active_attacks = []
  599. else:
  600. self.logger.info('ATTACK!')
  601. resp = self.br.open(self.PAGES['events'])
  602. soup = BeautifulSoup(resp)
  603. hostile = False
  604. try:
  605. for tr in soup.findAll('tr'):
  606. countDown = tr.find('td', 'countDown')
  607. if countDown and 'hostile' in countDown.get('class', ''):
  608. hostile = True
  609. # First: check if attack was noticed
  610. if tr.get('id'):
  611. attack_id = tr.get('id').split('-')[1]
  612. elif countDown.get('id'):
  613. attack_id = countDown.get('id').split('-')[2]
  614. if not attack_id or attack_id in [a.id for a in self.active_attacks]:
  615. continue
  616. try:
  617. # Attack first discovered: save attack info
  618. arrivalTime = tr.find('td', 'arrivalTime').text.split(' ')[0]
  619. coordsOrigin = tr.find('td', 'coordsOrigin')
  620. if coordsOrigin:
  621. if coordsOrigin.find('a'):
  622. coordsOrigin = coordsOrigin.find('a').text.strip()[1:-1]
  623. destCoords = tr.find('td', 'destCoords')
  624. if destCoords:
  625. destCoords = destCoords.find('a').text.strip()[1:-1]
  626. originFleet = tr.find('td', 'originFleet')
  627. detailsFleet = int(tr.find('td', 'detailsFleet').span.text.replace('.', ''))
  628. player_info = originFleet.find('a')
  629. message_url = player_info.get('href')
  630. player = player_info.get('data-player-name')
  631. is_moon = False # TODO!
  632. planet = self.find_planet(coords=destCoords, is_moon=is_moon)
  633. a = Attack(planet, attack_id, arrivalTime, coordsOrigin,
  634. destCoords, detailsFleet, player, message_url)
  635.  
  636. self.active_attacks.append(a)
  637. except Exception as e:
  638. self.logger.exception(e)
  639. self.send_sms('ATTACKEROR')
  640. if not hostile:
  641. self.active_attacks = []
  642. except Exception as e:
  643. self.logger.exception(e)
  644.  
  645. def fleet_save(self, p):
  646. if not p.has_ships():
  647. return
  648. fleet = p.ships
  649. #recyclers are staying!
  650. #fleet['rc'] = 0
  651. self.logger.info('Making fleet save from %s' % p)
  652. self.send_fleet(p,
  653. self.get_safe_planet(p).coords,
  654. fleet=fleet,
  655. mission='station',
  656. speed=10,
  657. resources={'metal': p.resources['metal']+500,
  658. 'crystal': p.resources['crystal']+500,
  659. 'deuterium': p.resources['deuterium']+500})
  660.  
  661. def collect_debris(self, p):
  662. if not p.has_ships():
  663. return
  664. self.logger.info('Collecting debris from %s using %s recyclers' % (p, p.ships['rc']))
  665. self.send_fleet(p,
  666. p.coords,
  667. fleet={'rc':p.ships['rc']},
  668. mission='collect',
  669. target='debris')
  670.  
  671. def send_expedition(self):
  672. expedition = options['expedition']
  673. planets = expedition['planets'].split(' ')
  674. random.shuffle(planets)
  675. for coords in planets[:3]:
  676. planet = self.find_planet(coords=coords)
  677. if planet:
  678. galaxy, system, position = planet.coords.split(':')
  679. expedition_coords = '%s:%s:16' % (galaxy, system)
  680. self.send_fleet(planet, expedition_coords,
  681. fleet={expedition['ships_kind']:expedition['ships_number']},
  682. mission='expedition')
  683.  
  684. def farm(self):
  685. farms = options['farming']['farms'].split(' ')
  686. ships_kind = options['farming']['ships_kind']
  687. ships_number = options['farming']['ships_number']
  688.  
  689. l = len(farms)
  690. if l == 0 or not farms[0]:
  691. return
  692. farm = farms[self.farm_no%l]
  693. if not self.get_player_status(farm)['inactive']:
  694. self.farm_no += 1
  695. self.logger.error('farm %s seems not to be inactive!', farm)
  696. return
  697. self.send_fleet(
  698. self.get_closest_planet(farm),
  699. farm,
  700. fleet={ships_kind:ships_number}
  701. )
  702.  
  703. def sleep(self):
  704. sleep_options = options['general']
  705. sleep_time = randint(0, int(sleep_options['seed']))+int(sleep_options['check_interval'])
  706. self.logger.info('Sleeping for %s secs' % sleep_time)
  707. if self.active_attacks:
  708. sleep_time = 60
  709. time.sleep(sleep_time)
  710.  
  711. def stop(self):
  712. self.logger.info('Stopping bot')
  713. os.unlink(self.pidfile)
  714.  
  715. def start(self):
  716. self.logger.info('Starting bot')
  717. self.pid = str(os.getpid())
  718. self.pidfile = 'bot.pid'
  719. file(self.pidfile, 'w').write(self.pid)
  720.  
  721. #main loop
  722. while True:
  723. if self.login():
  724. try:
  725. self.handle_planets()
  726. #self.find_inactives()
  727. if not self.active_attacks:
  728. if True or not self.transport_resources():
  729. self.send_expedition()
  730. self.farm()
  731. self.farm()
  732. else:
  733. self.handle_attacks()
  734.  
  735. except Exception as e:
  736. self.logger.exception(e)
  737. #self.stop()
  738. #return
  739. else:
  740. self.logger.error('Login failed!')
  741. #self.stop()
  742. #return
  743. self.sleep()
  744.  
  745. if __name__ == "__main__":
  746. credentials = options['credentials']
  747. bot = Bot(credentials['username'], credentials['password'], credentials['uni'])
  748. bot.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement