Files
my-botty/scripts/convert_chipped.py
Alex 5c687773b1 Click-and-go install: self-bootstrapping install.bat + tesserocr DLL fix (#2)
Merges fix/stash-full-guard-and-testbed into main. See PR #2 for full description.
2026-06-20 09:27:12 +02:00

145 lines
4.5 KiB
Python

import sys
import os
import time
import itertools
import numpy as np
root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
src = os.path.join(root, "src")
sys.path.insert(0, src)
sys.path.insert(0, root)
os.chdir(root)
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
import ssl
def _patch_ssl():
_orig = ssl.SSLContext.load_default_certs
def _safe(self, purpose=ssl.Purpose.CLIENT_AUTH):
try:
_orig(self, purpose)
except ssl.SSLError:
try:
import certifi
self.load_verify_locations(certifi.where())
except Exception:
pass
ssl.SSLContext.load_default_certs = _safe
_patch_ssl()
from logger import Logger
from config import Config
import screen
from screen import grab, convert_screen_to_monitor, set_window_position
from input_layer import mouse, keyboard
from inventory import common
from d2r_image import processing as d2r_image
from utils.misc import WindowSpec, find_d2r_window, wait
from ui_manager import is_visible, ScreenObjects
CHIPPED_GEMS = [
"Chipped Diamond", "Chipped Topaz", "Chipped Sapphire",
"Chipped Emerald", "Chipped Ruby", "Chipped Amethyst",
"Chipped Skull", "Chipped Star", "Chipped Flame",
"Chipped Sky", "Chipped Thunder", "Chipped Moon",
"Chipped Sun", "Chipped Shadow", "Chipped Death",
"Chipped Life", "Chipped Energy", "Chipped Mana"
]
def get_all_inventory_items(img):
cfg = Config()
items = []
for col, row in itertools.product(range(cfg.char["num_loot_columns"]), range(4)):
center_pos, slot_img = common.get_slot_pos_and_img(img, col, row)
if not common.slot_has_item(slot_img):
continue
x_m, y_m = convert_screen_to_monitor(center_pos)
mouse.move(x_m, y_m, randomize=3, delay_factor=[0.1, 0.15])
wait(0.2, 0.3)
hover_img = grab(True)
try:
item_props, item_box = d2r_image.get_hovered_item(hover_img)
if item_box and item_box.ocr_result:
name = item_box.ocr_result.text.strip().splitlines()[0]
items.append({"pos": center_pos, "col": col, "row": row, "name": name})
print(f" [{col},{row}] {name}")
else:
print(f" [{col},{row}] (has item, no tooltip)")
except Exception as e:
print(f" [{col},{row}] ERROR: {e}")
return items
def convert_chipped(item):
x_m, y_m = convert_screen_to_monitor(item["pos"])
mouse.move(x_m, y_m, randomize=3, delay_factor=[0.2, 0.3])
wait(0.2, 0.3)
mouse.click(button="right")
wait(0.5, 0.8)
print(f" Converted: {item['name']}")
def main():
Logger.info("=== Chipped Gem Converter ===")
# Find D2R window
print("Finding D2R window...")
spec = WindowSpec(title_regex=None, process_name_regex="D2R\\.exe")
pos = find_d2r_window(spec, offset=(0, 0))
if pos is None:
print("ERROR: Could not find D2R window")
return
set_window_position(*pos)
print(f"Client area at ({pos[0]},{pos[1]})")
# Close any open UI panels
print("Closing open UI...")
for _ in range(5):
keyboard.send("esc")
wait(0.3)
wait(0.5)
# Open inventory
print("Opening inventory...")
cfg = Config()
keyboard.send(cfg.char["inventory_screen"])
wait(1.0)
# Verify inventory is open by checking slot brightness
img = grab(True)
# Check if any slot has content (brightness > 16)
has_content = False
for col in range(cfg.char["num_loot_columns"]):
for row in range(4):
_, slot_img = common.get_slot_pos_and_img(img, col, row)
if common.slot_has_item(slot_img):
has_content = True
break
if has_content:
break
if not has_content:
print("ERROR: Inventory appears empty or not open")
keyboard.send("esc")
return
print("Inventory open, scanning...")
all_items = get_all_inventory_items(img)
# Filter for chipped gems
chipped = [i for i in all_items if any(c in i["name"] for c in CHIPPED_GEMS)]
if not chipped:
print("\nNo chipped gems found in inventory.")
else:
print(f"\nFound {len(chipped)} chipped gem(s). Converting...")
for item in chipped:
convert_chipped(item)
# Close inventory
print("\nClosing inventory...")
keyboard.send("esc")
wait(0.3, 0.5)
print("Done.")
if __name__ == "__main__":
main()