Commit Graph

1009 Commits

Author SHA1 Message Date
alex
a70302f44d Change default auto settings hotkey to page up 2026-05-25 14:52:29 +02:00
alex
0b1af05841 Avoid unsafe force-kill for bot/controller shutdown 2026-05-25 14:46:11 +02:00
alex
d96cf544bf Fix rare-for-gold override when pickit cache is used 2026-05-25 14:41:36 +02:00
alex
fc3ac30431 Persist stats snapshot continuously for crash resilience 2026-05-25 14:36:11 +02:00
alex
a39acf510d Fix pytest setup and handle missing tesserocr in test env 2026-05-25 14:35:13 +02:00
alex
c9ffcf1e4f Add Discord status updates every N runs with config option 2026-05-25 14:30:33 +02:00
alex
0ccf8ae5ea Add structured run/item logging and per-area item stats 2026-05-25 14:28:52 +02:00
alex
d4e1758d97 Make pick_gold override BNIP gold threshold 2026-05-25 14:25:37 +02:00
alex
40d46bb592 Add simple pick_gold config toggle for ground gold 2026-05-25 14:22:35 +02:00
alex
c5519ff290 Add config toggle to pick and sell rares for gold 2026-05-25 14:18:57 +02:00
alex
dd45386579 Improve config docs and harden discord+difficulty parsing 2026-05-25 14:10:54 +02:00
alex
54f0e3ebcc Update docs and params defaults 2026-05-25 13:52:39 +02:00
alex
7eb961476e Fix Discord webhook init and add local config defaults/ignores 2026-05-25 13:51:50 +02:00
alex
d44acf8bf2 Add CI launch smoke test for built executables 2026-05-25 13:47:09 +02:00
alex
f597a0108c Fix cooldown pacing for Blizzard and FoH casts 2026-05-25 11:14:52 +02:00
alex
af06d8aff4 Fix show_belt key, post-attack wait, and pickit variable scope
- config/params.ini: show_belt k->n matches the actual D2R keybind so
  the bot can now correctly read and manage belt potion inventory.
  pickit_screenshots=1 enables per-run loot scan evidence.
- blizz_sorc.py: kill_pindle() now waits 1.5-2.0s (was ~0.33s) after
  the attack loop before teleporting to the loot area.  Blizzard has an
  ~1.8s fall duration, so the old wait left enemies alive when the sorc
  arrived.  Also adds _cast_static() at the start to reduce pack HP
  immediately.
- pickit.py: rename loop var i->ground_item (fixes potential NameError
  when items list is empty) and improve tele-fail warning message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:46:00 +02:00
alex
9ee102a0f1 Fix charged teleport not firing in traverse_nodes_fixed
The TELE_ACTIVE template only matches native teleport's icon. Charged
teleport (from a staff/item) shows a different icon with a blue charge
indicator, so is_right_skill_selected(["TELE_ACTIVE"]) returns False
and char.move() falls back to walking.

Walking a path calibrated for teleport drops the sorc in the wrong
game-world position, so blizzard casts land south of Pindle ("below
targets") and the sorc is exposed to the full minion pack.

Fix: for can_teleport_with_charges chars, call select_tp() once then
pass force_tp=True to each char.move() hop. force_tp bypasses the
template check and re-arms the teleport hotkey before each right-click,
so charges are actually consumed per hop. If charges deplete mid-path
char.move() right-clicks with no effect and the remaining hops degrade
to standing still rather than walking into monsters.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 20:09:11 +02:00
alex
5e320f0eef Fix charges-sorc walking into Pindle's minion pack (death)
pindle.py: route can_teleport_with_charges chars through
traverse_nodes_fixed for the Pindle approach instead of traverse_nodes.
traverse_nodes (node-based) falls back to walking for charges chars
because pre_move does nothing for them — so the sorc was slow-walking
through the entire minion pack before the fight, arriving at near-zero HP.

pather.py: traverse_nodes_fixed now calls char.select_tp() before
pre_move when using charge-based teleport, so char.move() sees
teleport on the right-skill slot and uses charges for each step.
When charges deplete mid-path it falls back to walking gracefully.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:54:15 +02:00
alex
2634619b18 Fix window-detection race condition and None monitor range crash
- misc.py: catch psutil.NoSuchProcess in WindowSpec.match() — a process
  can exit between EnumWindows enumerating it and us calling .name(),
  which was crashing the window-detection thread and leaving
  monitor_x_range/monitor_y_range as None
- screen.py: guard convert_screen_to_monitor against None ranges so
  template matching doesn't throw TypeError before the D2R window is
  first located; logs a warning and returns unclamped coords instead
- main.py: switch BeautifulTable to STYLE_DEFAULT (ASCII only) to avoid
  UnicodeEncodeError on cp1252 terminals; add try/except fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:42:40 +02:00
alex
dc224bec5c Fix CTA spam, traverse_nodes_fixed crash, and add skill preflight/setter
- config: cta_available=0 (user has no CTA weapon; was causing 5 failed
  weapon-swap attempts per run)
- pather: traverse_nodes_fixed now allows can_teleport_with_charges chars
  through instead of raising ValueError; when charges deplete mid-path
  char.move() falls back to walking gracefully
- utils: add skill_preflight.py (visual hotkey verification, all blizz_sorc
  skills use side=right) and skill_hotkey_setter.py (automated picker binding
  with step-by-step logging)
- test: add test_skill_preflight.py (3 passing tests)
- assets: add sorc skill icon templates for preflight matching
- tools: add capture_sorc_skill_icons.py and set_sorc_skill_hotkeys.py
- key_detector: extend VK map with numpad/F-key/symbol codes; add
  validate_key_bindings() and parse_key_file(); fix char_name lookup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 19:26:00 +02:00
alex
a77e87e138 Improve Botty launch and runtime recovery 2026-05-24 18:14:23 +02:00
alex
080b7d1679 Set Botty to run Pindle with blizz sorc 2026-05-24 17:53:29 +02:00
alex
d4fec70950 feat: add character selector (blizz sorc / fohdin / hammerdin) to F6 UI
The run-selector window now also shows a character section with radio
buttons for the three supported builds. Selecting a char updates
Config().char["type"] in-memory alongside the run selection; both take
effect on the next game.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:52:45 +02:00
alex
d3dbf2bf9c fix: disable auto-login by default, require explicit auto_login=1
Auto-launch of D2R and bnet credential injection are now gated behind
an explicit `auto_login=0` flag in params.ini. Setting it to 1 restores
the previous behaviour. Credentials stored in bnet_name/bnet_pass are
never appended to launch options while auto_login=0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:45:23 +02:00
alex
887a97c93b feat: add F6 hotkey to select boss/farm runs at runtime
Adds a tkinter run-selector window accessible from the botty console via
the new select_runs_key hotkey (default F6). Users can check/uncheck any
of the 11 supported boss/farm runs; the selection updates Config in-memory
and takes effect on the next game without restarting botty.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:42:10 +02:00
alex
d6c8d8d5f7 fix: replace custom tesserocr wheel with conda-forge package
The custom tesserocr-2.5.2 wheel was compiled on a specific machine
against DLL versions that do not match a fresh conda-forge installation.
This caused persistent ImportError: DLL load failed regardless of PATH
or LoadLibraryExW approach.

conda-forge's tesserocr package is compiled against the exact same
conda-forge tesseract/leptonica binaries, so all DLL dependencies
are automatically satisfied within the conda environment — no manual
DLL path manipulation needed.

Changes:
- environment.yml: add tesserocr + tesseract as conda-forge packages,
  remove leptonica pin (no longer needed), remove custom wheel from pip
- install.bat: replace wheel force-reinstall with pip uninstall cleanup
- src/*.py: simplify DLL fix to os.add_dll_directory only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:49:00 +02:00
alex
e1c18faf26 fix: use conda run instead of direct python for DLL loading
Every approach to manually replicating conda's DLL environment from
Python code or batch PATH manipulation has failed. conda run activates
the environment exactly like "conda activate botty" — setting PATH,
running activate.d scripts, and properly resolving all transitive DLL
dependencies for tesseract51.dll.

run_botty.bat now derives conda.exe from the botty python.exe path
(two levels up: envs/botty -> envs -> miniforge3 -> Scripts/conda.exe)
and uses "conda run -n botty --no-capture-output python src/main.py".

install.bat smoke test now uses "%CONDA_EXE% run -n botty python -c ..."
which already has CONDA_EXE set from the install step.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:37:14 +02:00
alex
bdd6247342 fix: use LoadLibraryExW(0x1000) to preload tesseract51.dll
os.add_dll_directory alone is not enough — LOAD_LIBRARY_SEARCH_USER_DIRS
does not propagate to transitive deps of deps when loaded automatically
by the OS (e.g. tesseract51.dll's deps like mingw runtimes, leptonica).

LoadLibraryExW with LOAD_LIBRARY_SEARCH_DEFAULT_DIRS (0x1000) explicitly
propagates user DLL dir search to the entire transitive dep chain, so
leptonica, libgcc, libstdc++, zlib etc. are all found in Library\bin
and Library\mingw-w64\bin without conda activate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:30:12 +02:00
alex
77ad97022e fix: remove ctypes.WinDLL preload — use only os.add_dll_directory
ctypes.WinDLL uses LoadLibraryW which does NOT search user DLL dirs
registered via os.add_dll_directory/AddDllDirectory. It was throwing
FileNotFoundError and blocking the import before tesserocr was ever tried.

Python 3.8+ loads .pyd files with LOAD_LIBRARY_SEARCH_USER_DIRS which
DOES search user-registered dirs for the pyd and all its transitive DLL
dependencies. os.add_dll_directory(Library\bin) alone is sufficient.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:19:18 +02:00
alex
d9383cc164 feat: add update.bat for git pull workflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:12:31 +02:00
alex
a77dafaf08 fix: set conda DLL PATH at batch level before Python starts
os.environ['PATH'] set from inside Python does not affect the Windows
DLL loader used by ctypes.WinDLL — the loader reads the process PATH
at load time, not from Python's env dict. Set PATH in the .bat files
before python.exe is launched so tesseract51.dll's transitive deps
(leptonica, zlib, libpng, etc.) are findable by the loader.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:10:00 +02:00
alex
18c08a4c65 fix: prepend conda Library\bin to PATH before ctypes.WinDLL call
When ctypes.WinDLL loads tesseract51.dll by absolute path, Windows
resolves that DLL's own transitive deps using the standard search order:
app-dir → System32 → Windows → cwd → PATH. Library\bin is in none of
those (conda activate was not run), so leptonica, zlib, libpng, etc.
are invisible and the load fails even though the DLLs are all present.

Fix: prepend all conda DLL dirs to os.environ['PATH'] before the
ctypes.WinDLL call so the standard DLL search finds them. os.add_dll_directory
is still called for Python's LOAD_LIBRARY_SEARCH_USER_DIRS path.
Together the three steps guarantee the import works without conda activate:
  1. os.add_dll_directory  - for .pyd loading
  2. os.environ PATH       - for ctypes transitive dep resolution
  3. ctypes.WinDLL(abs)    - pre-cache tesseract so .pyd reuses it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 14:03:00 +02:00
alex
f8380af3bd fix: pre-load tesseract51.dll by absolute path to fix transitive DLL deps
os.add_dll_directory alone is not enough on Windows. When Python loads
the tesserocr .pyd via LOAD_LIBRARY_SEARCH_USER_DIRS, Windows finds
tesseract51.dll in the added directory but then resolves tesseract's own
transitive deps (leptonica, zlib, libpng etc.) using only the standard
system search path -- not the user DLL dirs. Those libs live in
Library\bin, not System32, so they're invisible and the load fails even
though every DLL is present.

Fix: call ctypes.WinDLL(absolute_path_to_tesseract51.dll) before the
tesserocr import. LoadLibraryW with a full path anchors tesseract51.dll
to Library\bin, so Windows searches that directory for its transitive
deps. The already-loaded DLL is then returned from cache when the .pyd
requests it, making the import succeed.

Applied to ocr.py (test entry point), main.py, and shopper.py.
Also updated install.bat smoke test and diagnostic to use the same fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 13:59:21 +02:00
alex
ee940b7e3d fix: pin leptonica=1.78.0 to match tesserocr wheel DLL dependency
The custom tesserocr wheel links against leptonica-1.78.0.dll at
compile time. Unpinned leptonica on conda-forge resolves to 1.82+
which installs leptonica-1.82.0.dll — a different filename — so
Windows DLL loader cannot find it regardless of os.add_dll_directory.

Also force-reinstall the wheel in install.bat to guarantee the
correct binary is used (not a stale cached version), and add a
diagnostic that prints which DLLs are actually present when the
smoke test fails so the root cause is visible instead of a vague
warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 13:51:54 +02:00
alex
91403e49d3 feat: make zip-download install flow work for first-time users
- README: add step-by-step Installation section (Miniforge → download
  ZIP → install.bat → config → run_botty.bat) so a non-technical user
  can follow it without reading development.md
- config/params.ini: reset personal fields (name, char_name,
  saved_games_folder) to generic defaults so the downloaded zip
  works out of the box for anyone
- install.bat: apply os.add_dll_directory before the tesserocr smoke
  test so it stops emitting a false warning on every install

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 09:39:12 +02:00
alex
8ee31d9691 fix: use sys.prefix for tesserocr DLL search in all entry points
dirname(dirname(sys.executable)) walks two levels up from the exe on
Windows, landing in the envs/ parent rather than the env root. Replace
with sys.prefix which is always the correct conda env root, and cover
Library/{bin,mingw-w64/bin,usr/bin} to handle all conda-forge layouts.
Also remove unused _dll_fix.py which had the same bug.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 09:34:59 +02:00
alex
40a207be9a feat: harden install.bat + add CI checks for launcher scripts
install.bat:
- Add conda self-test (conda --version) before env create
- Verify botty python.exe exists after env creation
- Smoke-test key imports (cv2, tesserocr, discord, etc.)

CI (.github/workflows/ci.yml):
- Add test_setup_bat_files.py to test matrix

test/test_setup_bat_files.py (7 tests):
- All expected .bat files exist
- No hardcoded usernames (alex, alexpolo, ultimate) in run scripts
- No absolute home paths in run scripts (must use %~dp0 / %USERNAME%)
- All run_*.bat source find_python.bat (no duplicated conda detection)
- find_python.bat checks >= 6 conda locations
- install.bat has conda self-test and python verification
2026-05-23 23:15:24 +02:00
alex
dec3269a0c fix: make launcher bat files work from any working directory
- Add find_python.bat shared helper to auto-detect conda env (6 locations)
- All bat scripts now resolve paths relative to script location (%~dp0)
- Fixes crash when launching from Start Menu / pinned shortcut (cwd=System32)
- Fixes hardcoded username path in run_asset_extractor.bat
2026-05-23 23:10:16 +02:00
alex
27573bf362 add blizzpw.txt to .gitignore 2026-05-23 00:06:10 +02:00
alex
5451357b86 fix tesserocr DLL load failure on CI Windows runners
Python 3.8+ no longer searches conda's Library\bin for DLLs automatically.
Add os.add_dll_directory(sys.prefix/Library/bin) before importing tesserocr
so leptonica and tesseract DLLs are found on any conda-based Windows env.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 00:04:40 +02:00
alex
94f3e6bca8 fix install.bat: cd to script dir so environment.yml is found
Without cd /d "%~dp0", conda resolves environment.yml relative to
wherever the user launched the bat from (e.g. C:\Windows\system32).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:54:33 +02:00
alex
6c261c3cbb fix fuzzy matching bug and CI coverage collection
find_best_match was using extractOne (which maximises its scorer) with
Levenshtein distance (lower = better), so it returned the worst match
instead of the best. Switch to extract+min to correctly minimise distance.
Fixes 6 failing tests in test_text_correction.py.

CI: run pytest under `coverage run` so coverage.xml has data to report;
drop deprecated use-only-tar-bz2 flag from setup-miniconda steps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:53:15 +02:00
alex
6ace0a7970 include install.bat, src, env files in release zip
Adds install.bat, run_botty.bat, run.bat, environment.yml, src/, and
dependencies/ to the build output so users can download zip → run
install.bat → run_botty.bat without needing a pre-built conda env.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:43:36 +02:00
alex
ed4aaf77f8 add install.bat: automates conda env setup from environment.yml
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 23:40:26 +02:00
alex
416b6714dd fix CI: add PYTHONPATH=./src to all steps 2026-05-22 23:31:27 +02:00
alex
ab29fa0a46 fix release bundle: main.exe naming, full zip with config+assets, add release trigger 2026-05-22 23:28:21 +02:00
alex
77d84680c6 fix CI: remove broken pytest-pythonpath, add test→build pipeline, fix test asset guards 2026-05-22 23:24:41 +02:00
alex
d0e6eb7d21 update params.ini, bot.py, win_input.py 2026-05-22 21:11:59 +02:00
alex
75f64351ee add stealth system, key detection, click recorder, FOHdin, new routes, and tooling updates 2026-05-21 23:34:20 +02:00
alex
8dc677d2e6 document stealth, key detection, click recorder, and FOHdin in README 2026-05-20 20:06:21 +02:00