Advertisement
Guest User

Untitled

a guest
Sep 21st, 2016
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.32 KB | None | 0 0
  1. import asyncio
  2. import configparser
  3. import math
  4. import os
  5. import re
  6. import subprocess
  7. import time
  8.  
  9.  
  10. import discord
  11. from termcolor import cprint
  12.  
  13. CONFIG_SECTION = 'DiscoSnipe'
  14. CONFIG = None
  15. DISCORD_CLIENT = None
  16.  
  17.  
  18. def init():
  19. print('[INIT] DiscoSnipe v0.2-alpha started')
  20. print('[INIT] Loading config...')
  21. global CONFIG
  22. CONFIG = configparser.ConfigParser()
  23. if not CONFIG.read('discosnipe.cfg'):
  24. print('[INIT] discosnipe.cfg was not found. Initializing first time setup.')
  25. CONFIG = generate_config(CONFIG)
  26. return
  27.  
  28.  
  29. class CatchLog(object):
  30. c_list = []
  31.  
  32. def update(self):
  33. for catch in self.c_list:
  34. if time.time() - catch.time_caught > 120:
  35. self.c_list.remove(catch)
  36.  
  37. def add(self, catch=None):
  38. self.update()
  39. self.c_list.append(catch)
  40.  
  41. def exists(self, target=None):
  42. for catch in self.c_list:
  43. for poke in catch.pokemons:
  44. dist = distance_between(target, poke)
  45. if (dist < 50) & (target.name == poke.name):
  46. return True
  47. return False
  48.  
  49.  
  50. poke_to_relay = None
  51. catch_log = CatchLog()
  52.  
  53.  
  54. def main():
  55. init()
  56.  
  57. discord_username = CONFIG.get(CONFIG_SECTION, 'username')
  58. discord_password = CONFIG.get(CONFIG_SECTION, 'password')
  59. discord_channels = CONFIG.get(CONFIG_SECTION, 'channels').split(',')
  60.  
  61. print('[INIT] Configuration loaded! Logging in to Discord...')
  62. global DISCORD_CLIENT
  63. DISCORD_CLIENT = discord.Client()
  64.  
  65. @DISCORD_CLIENT.event
  66. async def on_ready():
  67. print('[INIT] Logged in as ' + DISCORD_CLIENT.user.name)
  68. print('[INIT] Watching the following channels: ' + ', '.join(discord_channels))
  69.  
  70. @DISCORD_CLIENT.event
  71. async def on_message(message):
  72. if message.channel.name in discord_channels:
  73. parse_message(message)
  74.  
  75. async def relay_to_channel():
  76. global DISCORD_CLIENT
  77. await DISCORD_CLIENT.wait_until_ready()
  78. while not DISCORD_CLIENT.is_closed:
  79. for catch in catch_log.c_list:
  80. poke = catch.pokemons[0]
  81. if poke.iv is not None:
  82. if not catch.relayed:
  83. if float(poke.iv) == 100:
  84. if poke.channel.name != 'donor_100iv':
  85. msg = '**%sIV - %s at %s,%s [Moveset: %s]**' % (
  86. '100', poke.name.title(), poke.lat, poke.lon, poke.moveset)
  87. channel = discord.Object(id='209174231269769216') # donor_100iv 209174231269769216
  88. await DISCORD_CLIENT.send_message(channel, msg)
  89. # elif float(poke.iv) >= 90:
  90. # if poke.channel.name != '90plus_ivonly':
  91. # msg = '%s,%s - %s %sIV [Moveset: %s]' % (
  92. # poke.lat, poke.lon, poke.name.title(), str(round(float(poke.iv), 2)),
  93. # poke.moveset)
  94. # channel = discord.Object(id='209171120702619648') # 90plus_ivonly 209171120702619648
  95. # await DISCORD_CLIENT.send_message(channel, msg)
  96. catch.relayed = True
  97.  
  98. await asyncio.sleep(1)
  99.  
  100. DISCORD_CLIENT.loop.create_task(relay_to_channel())
  101. DISCORD_CLIENT.run(discord_username, discord_password)
  102.  
  103.  
  104. POKEMON = ["abra", "aerodactyl", "alakazam", "arbok", "arcanine", "articuno", "beedrill", "bellsprout", "blastoise",
  105. "bulbasaur", "butterfree", "caterpie", "chansey", "charizard", "charmander", "charmeleon", "clefable",
  106. "clefairy", "cloyster", "cubone", "dewgong", "diglett", "ditto", "dodrio", "doduo", "dragonair", "dragonite",
  107. "dratini", "drowzee", "dugtrio", "eevee", "ekans", "electabuzz", "electrode", "exeggcute", "exeggutor",
  108. "farfetch'd", "fearow", "flareon", "gastly", "gengar", "geodude", "gloom", "golbat", "goldeen", "golduck",
  109. "golem", "graveler", "grimer", "growlithe", "gyarados", "haunter", "hitmonchan", "hitmonlee", "horsea",
  110. "hypno", "ivysaur", "jigglypuff", "jolteon", "jynx", "kabuto", "kabutops", "kadabra", "kakuna", "kangaskhan",
  111. "kingler", "koffing", "krabby", "lapras", "lickitung", "machamp", "machoke", "machop", "magikarp", "magmar",
  112. "magnemite", "magneton", "mankey", "marowak", "meowth", "metapod", "mew", "mewtwo", "moltres", "mrmime",
  113. "muk",
  114. "nidoking", "nidoqueen", "nidoranf", "nidoranm", "nidorina", "nidorino", "ninetales", "oddish", "omanyte",
  115. "omastar", "onix", "paras", "parasect", "persian", "pidgeot", "pidgeotto", "pidgey", "pikachu", "pinsir",
  116. "poliwag", "poliwhirl", "poliwrath", "ponyta", "porygon", "primeape", "psyduck", "raichu", "rapidash",
  117. "raticate", "rattata", "rhydon", "rhyhorn", "sandshrew", "sandslash", "scyther", "seadra", "seaking", "seel",
  118. "shellder", "slowbro", "slowpoke", "snorlax", "spearow", "squirtle", "starmie", "staryu", "tangela",
  119. "tauros",
  120. "tentacool", "tentacruel", "vaporeon", "venomoth", "venonat", "venusaur", "victreebel", "vileplume",
  121. "voltorb",
  122. "vulpix", "wartortle", "weedle", "weepinbell", "weezing", "wigglytuff", "zapdos", "zubat"]
  123.  
  124.  
  125. class Pokemon(object):
  126. class Moveset(object):
  127. def __init__(self, move1, move2):
  128. self.move2 = move2
  129. self.move1 = move1
  130.  
  131. def __str__(self):
  132. return self.move1 + '/' + self.move2
  133.  
  134. def __init__(self, name=None, lat=None, lon=None, channel=None, cp=None, iv=None, moveset=None):
  135. self.moveset = moveset
  136. self.iv = iv
  137. self.cp = cp
  138. self.channel = channel
  139. self.name = name
  140. self.lat = lat
  141. self.lon = lon
  142.  
  143.  
  144. class CatchResult(object):
  145. CATCH_SUCCESS = 0
  146. CATCH_FAIL = 1
  147. CATCH_FAIL_RAN_AWAY = 2
  148. CATCH_FAIL_NOT_FOUND = 3
  149. CATCH_FAIL_NO_POKEBALLS = 4
  150.  
  151. def __init__(self, result=None, pokemons=None):
  152. self.result = result
  153. self.time_caught = time.time()
  154. self.pokemons = pokemons
  155. self.relayed = False
  156.  
  157.  
  158. def get_coords(message):
  159. if len(re.findall(r'(,)', message.content)) == 3:
  160. s = message.content.split(',')
  161. m = '%s.%s,%s.%s' % (s[0], s[1], s[2], s[3])
  162. else:
  163. m = message.content
  164.  
  165. match = re.search("(-?\d{1,3}.\d*,\s?-?\d{1,3}.\d*)", m)
  166. if match:
  167. return match.group(0).replace(' ', '')
  168. return None
  169.  
  170.  
  171. def get_poke_name(message):
  172. match = re.findall("([a-zA-Z]+)", message.content)
  173. if match:
  174. for word in match:
  175. word = word.lower()
  176. if word in POKEMON:
  177. return word
  178. return None
  179.  
  180.  
  181. def distance_between(poke1, poke2):
  182. lat1 = float(poke1.lat)
  183. lon1 = float(poke1.lon)
  184. lat2 = float(poke2.lat)
  185. lon2 = float(poke2.lon)
  186. r = 6371 * 1000 # meters
  187. dlat = math.radians(lat2 - lat1)
  188. dlon = math.radians(lon1 - lon2)
  189. lat1 = math.radians(lat1)
  190. lat2 = math.radians(lat2)
  191.  
  192. a = math.sin(dlat / 2.0) * math.sin(dlat / 2.0) + math.sin(dlon / 2.0) * math.sin(dlon / 2.0) * math.cos(
  193. lat1) * math.cos(lat2)
  194. c = 2.0 * math.atan2(math.sqrt(a), math.sqrt(1.0 - a))
  195. d = r * c
  196. return d
  197.  
  198.  
  199. def get_snipe_result(stdout):
  200. pattern = re.compile(r'(\[.+(\bWe caught\b).+(.+\n){5})', re.MULTILINE)
  201. matches = re.findall(pattern, stdout)
  202. if len(matches) > 0:
  203. # catch success
  204. pokemons = []
  205. for match in matches:
  206. pattern = re.compile(r'[\S]+(?=\.?$)', re.MULTILINE)
  207. info = re.findall(pattern, match[0])
  208. poke = Pokemon(name=info[0][:-1],
  209. cp=info[1],
  210. iv=info[2],
  211. moveset=Pokemon.Moveset(info[3], info[4]))
  212. pokemons.append(poke)
  213. return CatchResult(CatchResult.CATCH_SUCCESS, pokemons)
  214. elif 'There is no' in stdout:
  215. return CatchResult(CatchResult.CATCH_FAIL_NOT_FOUND)
  216. elif 'Got into the fight without any Pokeballs.' in stdout:
  217. return CatchResult(CatchResult.CATCH_FAIL_NO_POKEBALLS)
  218. else:
  219. # catch failure
  220. return CatchResult(CatchResult.CATCH_FAIL)
  221.  
  222.  
  223. def snipe_pokemon(target):
  224. path = CONFIG.get(CONFIG_SECTION, 'pokesniper')
  225. directory = path[:path.rindex('\\') + 1]
  226. cprint('[SNIPE] Sniping %s at %s,%s from #%s' % (target.name.title(), target.lat, target.lon, target.channel.name),
  227. 'yellow')
  228. child = subprocess.run(path + ' %s %s %s' % (target.name, target.lat, target.lon), stdout=subprocess.PIPE,
  229. cwd=directory,
  230. universal_newlines=True)
  231. with open('log.txt', 'a') as logfile:
  232. logfile.write(child.stdout)
  233. catch_result = get_snipe_result(child.stdout)
  234. if catch_result.result == CatchResult.CATCH_SUCCESS:
  235. for poke in catch_result.pokemons:
  236. cprint(
  237. '[SNIPE] Caught %s (CP:%s IV:%s Moves:%s)' % (
  238. poke.name.title(), poke.cp, str(round(float(poke.iv), 2)), poke.moveset),
  239. 'green')
  240. target.moveset = poke.moveset
  241. target.iv = poke.iv
  242. catch_result.pokemons = [target]
  243. else:
  244. catch_result.pokemons = [target]
  245. if catch_result.result == CatchResult.CATCH_FAIL:
  246. cprint(
  247. '[SNIPE] Failed to catch the %s at %s,%s from #%s. See log.txt for details' % (
  248. target.name.title(), target.lat, target.lon, target.channel.name),
  249. 'red')
  250. elif catch_result.result == CatchResult.CATCH_FAIL_NOT_FOUND:
  251. cprint(
  252. "[SNIPE] Couldn't find the %s at %s,%s from #%s" % (
  253. target.name.title(), target.lat, target.lon, target.channel.name),
  254. 'red')
  255. elif catch_result.result == CatchResult.CATCH_FAIL_NO_POKEBALLS:
  256. cprint(
  257. '[SNIPE] Failed to catch the %s at %s,%s from #%s. Out of Pokeballs' % (
  258. target.name.title(), target.lat, target.lon, target.channel.name),
  259. 'red')
  260. catch_log.add(catch_result)
  261.  
  262.  
  263. def parse_message(msg):
  264. message = msg
  265. if 'Snipe Bot' in message.author.name:
  266. message.content = msg.content.split('\n')[len(msg.content.split('\n')) - 1]
  267. name = get_poke_name(message)
  268. coords = get_coords(message)
  269. # print('Name: ' + name)
  270. # print('Coords: ' + coords)
  271. if (name is not None) & (coords is not None):
  272. coords = coords.split(',')
  273. poke = Pokemon(name, coords[0], coords[1])
  274. poke.channel = message.channel
  275. if catch_log.exists(poke):
  276. cprint('Duplicate %s from #%s' % (poke.name.title(), poke.channel), 'grey')
  277. else:
  278. snipe_pokemon(poke)
  279.  
  280.  
  281. def generate_config(config):
  282. pokesniper_path = None
  283. print('[SETUP] NOTE: Your credentials will be stored in plaintext in discosnipe.cfg!')
  284. config.add_section(CONFIG_SECTION)
  285. config.set(CONFIG_SECTION, 'username', input('Discord Username: '))
  286. # config.set(CONFIG_SECTION, 'password', input('Discord Password: '))
  287. config.set(CONFIG_SECTION, 'password', '-snip-')
  288. config.set(CONFIG_SECTION, 'channels', input('Channels'))
  289. if os.path.isfile('PokeSniper2.exe'):
  290. pokesniper_path = os.getcwd() + '\PokeSniper2.exe'
  291. print('[SETUP] PokeSniper executable found at ' + pokesniper_path)
  292. print('[SETUP] Leave PokeSniper Path blank to use this path.')
  293. path_input = input('PokeSniper Path: ')
  294. while not (is_path_valid(path_input) | (path_input == '')):
  295. print('[SETUP] Invalid path')
  296. path_input = input('PokeSniper Path: ')
  297. if path_input:
  298. pokesniper_path = path_input
  299. config.set(CONFIG_SECTION, 'pokesniper', pokesniper_path)
  300. print('[SETUP] Saving configuration...')
  301. with open('discosnipe.cfg', 'w') as configfile:
  302. config.write(configfile)
  303. print('[SETUP] Configuration saved. Setup complete.')
  304. return config
  305.  
  306.  
  307. def is_path_valid(path):
  308. valid = os.path.isfile(path)
  309. return valid
  310.  
  311.  
  312. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement