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()