Use message template to support other hooks (#265)

This commit is contained in:
nekolr
2021-12-12 08:22:36 +01:00
committed by GitHub
parent 4c52045f08
commit c2a017c517
9 changed files with 99 additions and 60 deletions
+1 -1
View File
@@ -75,7 +75,7 @@ run_shenk=0
| logger_lvl | Can be any of [info, debug] and determines how much output you see on the command line |
| randomize_runs | If 0, the order will always be pindle -> eldritch/shenk. If 1 the order will be random |
| difficulty | Set to `normal` `nightmare` or `hell` for game difficulty |
| custom_discord_hook | Add your own discord hook here to get messages about drops and in case botty got stuck and can not resume |
| custom_message_hook | Add your own message hook here to get messages about drops and in case botty got stuck and can not resume, discord webhook is default |
| discord_status_count | Number of games between discord status messges being sent. Leave empty for no status reports.
| info_screenshots | If 1, the bot takes a screenshot with timestamp on every stuck / chicken / timeout / inventory full event. This is 1 by Default, so remember to clean up the folder every once in a while |
| loot_screenshots | If 1, the bot takes a screenshot with timestamp everytime he presses show_items button and saves it to loot_screenshots folder. Remember to clear them once in a while... |
+4 -1
View File
@@ -11,7 +11,7 @@ graphic_debugger_key=f10
logg_lvl=debug
randomize_runs=0
difficulty=hell
custom_discord_hook=
custom_message_hook=
discord_status_count=20
info_screenshots=1
loot_screenshots=0
@@ -82,3 +82,6 @@ redemption=
[advanced_options]
;===== don't touch unless you know what you're doing =====
pathing_delay_factor=5
message_headers=
message_body_template={{"content": "{msg}"}}
message_highlight=1
+4 -1
View File
@@ -44,7 +44,7 @@ class Config:
"logg_lvl": self._select_val("general", "logg_lvl"),
"randomize_runs": bool(int(self._select_val("general", "randomize_runs"))),
"difficulty": self._select_val("general", "difficulty"),
"custom_discord_hook": self._select_val("general", "custom_discord_hook"),
"custom_message_hook": self._select_val("general", "custom_message_hook"),
"discord_status_count": False if not self._select_val("general", "discord_status_count") else int(self._select_val("general", "discord_status_count")),
"info_screenshots": bool(int(self._select_val("general", "info_screenshots"))),
"loot_screenshots": bool(int(self._select_val("general", "loot_screenshots"))),
@@ -109,6 +109,9 @@ class Config:
self.advanced_options = {
"pathing_delay_factor": min(max(int(self._select_val("advanced_options", "pathing_delay_factor")), 1), 10),
"message_headers": self._select_val("advanced_options", "message_headers"),
"message_body_template": self._select_val("advanced_options", "message_body_template"),
"message_highlight": bool(int(self._select_val("advanced_options", "message_highlight"))),
}
self.items = {}
+23 -20
View File
@@ -2,13 +2,17 @@ from logger import Logger
import time
import threading
from config import Config
from utils.misc import send_discord, hms
from messenger import Messenger
from utils.misc import hms
import inspect
from version import __version__
class GameStats:
def __init__(self):
self._config = Config()
self._messenger = Messenger()
self._picked_up_items = []
self._start_time = time.time()
self._timer = None
@@ -20,38 +24,37 @@ class GameStats:
self._runs_failed = 0
self._failed_game_time = 0
def _send_discord_thread(self, msg: str, color_it: bool = False):
if self._config.general["custom_discord_hook"]:
msg = f"{self._config.general['name']}: {msg}"
send_discord_thread = threading.Thread(
target=send_discord,
args=(msg, self._config.general["custom_discord_hook"], color_it)
def _send_message_thread(self, msg: str):
if self._config.general["custom_message_hook"]:
send_message_thread = threading.Thread(
target=self._messenger.send,
kwargs={"msg": msg}
)
send_discord_thread.daemon = True
send_discord_thread.start()
send_message_thread.daemon = True
send_message_thread.start()
def log_item_pickup(self, item_name: str, send_discord: bool, area: str = None):
def log_item_pickup(self, item_name: str, send_message: bool, area: str = None):
self._picked_up_items.append(item_name)
if send_discord:
msg = f"Found {item_name}"
if send_message:
msg = f"{self._config.general['name']}: Found {item_name}"
if area is not None:
msg += f" at {area}"
self._send_discord_thread(msg, True)
self._send_message_thread(msg)
def log_death(self):
self._death_counter += 1
self._send_discord_thread(f"You have died")
self._send_message_thread(f"{self._config.general['name']}: You have died")
def log_chicken(self):
self._chicken_counter += 1
self._send_discord_thread(f"You have chickened")
self._send_message_thread(f"{self._config.general['name']}: You have chickened")
def log_start_game(self):
if self._game_counter > 0:
self._save_stats_to_file()
if self._config.general["discord_status_count"] and self._game_counter % self._config.general["discord_status_count"] == 0:
# every 20th game send a discord update about current status
self._send_discord_status_update()
# every 20th game send a message update about current status
self._send_status_update()
self._game_counter += 1
self._timer = time.time()
Logger.info(f"Starting game #{self._game_counter}")
@@ -108,9 +111,9 @@ class GameStats:
''')
return msg
def _send_discord_status_update(self):
msg = f"Status Report\n{self._create_msg()}\nVersion:"
self._send_discord_thread(msg)
def _send_status_update(self):
msg = f"{self._config.general['name']}: Status Report\\n{self._create_msg()}\\nVersion: {__version__}"
self._send_message_thread(msg)
def _save_stats_to_file(self):
msg = self._create_msg()
+5 -3
View File
@@ -7,10 +7,11 @@ import logging
import cv2
import traceback
from messenger import Messenger
from version import __version__
from utils.graphic_debugger import run_graphic_debugger
from utils.auto_settings import adjust_settings
from utils.misc import kill_thread, send_discord
from utils.misc import kill_thread
from config import Config
from screen import Screen
@@ -42,6 +43,7 @@ def run_bot(
do_restart = False
keyboard.add_hotkey(config.general["exit_key"], lambda: Logger.info(f'Force Exit') or os._exit(1))
keyboard.add_hotkey(config.general['resume_key'], lambda: bot.toggle_pause())
messenger = Messenger()
while 1:
health_manager.update_location(bot.get_curr_location())
max_game_length_reached = game_stats.get_current_game_length() > config.general["max_game_length_s"]
@@ -72,8 +74,8 @@ def run_bot(
if config.general["info_screenshots"]:
cv2.imwrite("./info_screenshots/info_could_not_recover_" + time.strftime("%Y%m%d_%H%M%S") + ".png", bot._screen.grab())
Logger.error(f"{config.general['name']} could not recover from a max game length violation. Shutting down everything.")
if config.general["custom_discord_hook"]:
send_discord(f"{config.general['name']} got stuck and can not resume", config.general["custom_discord_hook"])
if config.general["custom_message_hook"]:
messenger.send(msg=f"{config.general['name']}: got stuck and can not resume")
os._exit(1)
def main():
+44
View File
@@ -0,0 +1,44 @@
from config import Config
import json
import requests
class Messenger:
def __init__(self):
self._config = Config()
def send(self, msg):
if self._config.advanced_options['message_highlight']:
if " magic_" in msg:
msg = f"```ini\\n[ {msg} \\n```"
elif " set_" in msg:
msg = f"```diff\\n+ {msg} \\n```"
elif " rune_" in msg:
msg = f"```css\\n[ {msg} ]\\n```"
elif " uniq_" in msg or "rare" in msg:
# TODO: It is more gold than yellow, find a better yellow highlight
msg = f"```fix\\n- {msg} \\n```"
elif " eth_" in msg:
msg = f"```python\\n# {msg} \\n```"
else:
msg = f"```\\n{msg} \\n```"
self._send(msg=msg)
def _send(self, msg):
url = self._config.general['custom_message_hook']
if not url:
return
headers = {}
if self._config.advanced_options['message_headers']:
headers = json.loads(self._config.advanced_options['message_headers'])
data = json.loads(self._config.advanced_options['message_body_template'].format(msg=msg), strict=False)
requests.post(url, headers=headers, json=data)
if __name__ == "__main__":
messenger = Messenger()
messenger.send(msg=f" uniq_test")
+10 -7
View File
@@ -12,9 +12,11 @@ from logger import Logger
from npc_manager import NpcManager, Npc
from template_finder import TemplateFinder
from utils.custom_mouse import mouse
from utils.misc import wait, load_template, send_discord
from utils.misc import wait, load_template
import cv2
from messenger import Messenger
def exit(run_obj):
run_time = str(datetime.timedelta(seconds=round(time.time() - run_obj.start_time)))
@@ -64,10 +66,11 @@ class AnyaShopper:
self.trap_claw_min_score = self._config.shop["trap_min_score"]
self.look_for_melee_claws = self._config.shop["shop_melee_claws"]
self.melee_claw_min_score = self._config.shop["melee_min_score"]
self._screen = Screen(config.general["monitor"])
self._template_finder = TemplateFinder(self._screen, ["assets\\templates", "assets\\npc", "assets\\shop"])
self._messenger = Messenger()
self._npc_manager = NpcManager(
screen=self._screen, template_finder=self._template_finder
)
@@ -126,7 +129,7 @@ class AnyaShopper:
)
if gg_gloves.valid:
mouse.click(button="right")
send_discord(f"Bought awesome IAS/+3 gloves!", self._config.general["custom_discord_hook"])
self._messenger.send(msg=f"{self._config.general['name']}: Bought awesome IAS/+3 gloves!")
Logger.info("IAS/+3 gloves bought!")
self.gloves_bought += 1
time.sleep(1)
@@ -143,7 +146,7 @@ class AnyaShopper:
)
if g_gloves.valid:
mouse.click(button="right")
send_discord(f"Bought some decent IAS/+2 gloves", self._config.general["custom_discord_hook"])
self._messenger.send(msg=f"{self._config.general['name']}: Bought some decent IAS/+2 gloves")
Logger.info("IAS/+2 gloves bought!")
self.gloves_bought += 1
time.sleep(1)
@@ -204,7 +207,7 @@ class AnyaShopper:
if trap_score > self.trap_claw_min_score and self.look_for_trap_claws is True:
# pick it up
mouse.click(button="right")
send_discord(f"Bought some terrific trap Claws (score: {trap_score})", self._config.general["custom_discord_hook"])
self._messenger.send(msg=f"{self._config.general['name']}: Bought some terrific trap Claws (score: {trap_score})")
Logger.info(f"Trap Claws (score: {trap_score}) bought!")
self.claws_bought += 1
time.sleep(1)
@@ -212,7 +215,7 @@ class AnyaShopper:
if melee_score > self.melee_claw_min_score and self.look_for_melee_claws is True:
# pick it up
mouse.click(button="right")
send_discord(f"Bought some mad melee Claws (score: {melee_score})", self._config.general["custom_discord_hook"])
self._messenger.send(msg=f"{self._config.general['name']}: Bought some mad melee Claws (score: {melee_score})")
Logger.info(f"Melee Claws (score: {melee_score}) bought!")
self.claws_bought += 1
time.sleep(1)
+8 -5
View File
@@ -7,7 +7,7 @@ import os
import numpy as np
from utils.custom_mouse import mouse
from utils.misc import wait, cut_roi, color_filter, send_discord
from utils.misc import wait, cut_roi, color_filter
from logger import Logger
from config import Config
@@ -15,6 +15,8 @@ from screen import Screen
from item import ItemFinder
from template_finder import TemplateFinder
from messenger import Messenger
class UiManager():
"""Everything that is clicking on some static 2D UI or is checking anything in regard to it should be placed here."""
@@ -22,6 +24,7 @@ class UiManager():
def __init__(self, screen: Screen, template_finder: TemplateFinder):
self._config = Config()
self._template_finder = template_finder
self._messenger = Messenger()
self._screen = screen
self._curr_stash = {"items": 0, "gold": 0} #0: personal, 1: shared1, 2: shared2, 3: shared3
@@ -325,8 +328,8 @@ class UiManager():
if inventory_full_gold.valid:
msg = "All stash tabs and character are full of gold, turn of gold pickup"
Logger.info(msg)
if self._config.general["custom_discord_hook"]:
send_discord(f"{self._config.general['name']}: {msg}", self._config.general["custom_discord_hook"])
if self._config.general["custom_message_hook"]:
self._messenger.send(msg=f"{self._config.general['name']}: {msg}")
self._config.items["misc_gold"] = 0
item_finder.update_items_to_pick(self._config)
else:
@@ -392,8 +395,8 @@ class UiManager():
self._curr_stash["items"] += 1
if self._curr_stash["items"] > 3:
Logger.error("All stash is full, quitting")
if self._config.general["custom_discord_hook"]:
send_discord(f"{self._config.general['name']} all stash is full, quitting", self._config.general["custom_discord_hook"])
if self._config.general["custom_message_hook"]:
self._messenger.send(msg=f"{self._config.general['name']}: all stash is full, quitting")
os._exit(1)
else:
# move to next stash
-22
View File
@@ -5,31 +5,9 @@ import numpy as np
from logger import Logger
import cv2
from typing import List, Tuple
import requests
import os
from version import __version__
def send_discord(msg, url: str, color_it: bool = False):
if not url:
return
msg = f"{msg} (v{__version__})"
if color_it:
if " magic_" in msg:
msg = f"```ini\n[ {msg} \n```"
elif " set_" in msg:
msg = f"```diff\n+ {msg} \n```"
elif " rune_" in msg:
msg = f"```css\n[ {msg} ]\n```"
elif " uniq_" in msg or "rare" in msg:
# TODO: It is more gold than yellow, find a better yellow highlight
msg = f"```fix\n- {msg} \n```"
elif " eth_" in msg:
msg = f"```python\n# {msg} \n```"
else:
msg = f"```\n {msg} \n```"
requests.post(url, json={"content": msg})
def wait(min_seconds, max_seconds = None):
if max_seconds is None:
max_seconds = min_seconds