discord.py imports aiohttp which calls ssl.create_default_context() at import
time. A malformed cert in the Windows cert store raises ASN1 NOT_ENOUGH_DATA.
The bot patches this at runtime via _patch_ssl(); the install check now applies
the same workaround (null-patch load_default_certs) so discord: OK on all machines.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- Echo with (no ABSOLUTE flag) had unescaped ) closing the if block early,
causing BOTH Win11 and Win10 branches to run and wrong requirements used.
Fix: escape the parens with ^( and ^).
- %errorlevel% inside ( ) blocks is expanded at parse time, not after the
command that sets it. Affects winget install result check, tesseract winget
check, pytesseract check, and dependency verify loop.
Fix: use !errorlevel! (delayed expansion) in those four spots.
- Remove final pause so the CMD window closes automatically on success.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
winget (available on Win10 1709+ and all Win11) handles registration,
PATH, and package integrity checks automatically — cleaner than the
NSIS /S fallback. Fall back to curl+NSIS if winget is absent or fails.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Miniforge3's JustMe default install location changed from
%USERPROFILE%\miniforge3 to %LOCALAPPDATA%\miniforge3 in recent versions
(per robotology-superbuild docs and winget package metadata). Both the
initial scan and the post-bootstrap rescan now check %LOCALAPPDATA% first.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Two bugs found by studying oobabooga/text-generation-webui (reference impl):
1. PowerShell Invoke-WebRequest without $ProgressPreference='SilentlyContinue'
renders an ASCII progress bar that drops download speed from ~50 MB/s to
~1 MB/s. Switch primary download to curl (built into Win10/11, fast, clean
progress bar). PowerShell is kept as a fallback with the flag set.
2. Running the NSIS installer directly ("installer.exe /S") can return before
the install finishes. The correct pattern is "start /wait "" installer.exe"
which blocks until the installer process truly exits. Also adds /NoShortcuts
and /NoRegistry flags (standard for embedded/self-contained installs).
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
NSIS /D= does not support paths with spaces. %USERPROFILE% often contains
spaces (e.g. C:\Users\John Smith). Omitting /D= lets Miniforge install to
its own default location (%USERPROFILE%\miniforge3) which it handles safely.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Users no longer need to pre-install conda. If the first scan finds no
conda.exe, install.bat downloads Miniforge3-Windows-x86_64.exe via
PowerShell (available on all Win10/Win11), installs it silently to
%USERPROFILE%\miniforge3 with no PATH changes, then re-scans and
continues. On failure it prints a manual fallback URL. Users with an
existing conda install are unaffected.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The old install.bat copied tesseract41.dll as tesseract.dll (wrong name — wheel
needs tesseract51.dll) and the bundled .pyd used MSVC C++ ABI that the MinGW conda
DLLs can't satisfy. Both tesserocr imports now work:
tesseract52.dll — MSVC tesseract 5.2.0 from conda-forge (compiled vs2019)
tesserocr.cp310-...pyd — conda-forge 2.5.2 build linked against tesseract52.dll
The MSVC leptonica-1.78.0.dll comes from the existing conda tesseract=4.x install.
ocr.py already registers Library/bin via os.add_dll_directory so both backends
(tesserocr fast path, pytesseract reliable fallback) load correctly at bot startup.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Architecture: two backends, first one that works wins at runtime (ocr.py).
1. tesserocr — C extension via conda tesseract 4.x DLLs + bundled wheel (fast)
2. pytesseract — subprocess via winget tesseract.exe (always works if exe exists)
Install changes:
- tesserocr setup: best-effort, never fatal. Wheel install failure or DLL mismatch
just falls through to pytesseract. Removes the hard-exit on missing wheel.
- pytesseract setup: winget install with a manual download link fallback for Win10
users where winget is unavailable. pytesseract is now in requirements.txt so it
is always importable.
- OCR verification: tests BOTH backends after setup, reports which is active.
Warns clearly if neither works rather than silently leaving OCR broken.
Sets ALL_OK=0 so the installer ends with a visible failure state.
- Dependency loop: removes tesserocr from the import check — OCR is now verified
end-to-end by the backend test above, not by a bare import.
- Removes the broken pytesseract source-patch block (syntax error, never ran).
- TESS_PATH hoisted to :env_found so it is available for the OCR check.
requirements.txt: add pytesseract (pure Python, no native deps).
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Reverts 63d0a33 and e712076. Both commits got the OCR architecture backwards:
- Made winget "optional" but DEPENDENCIES.md shows pytesseract is the working
backend on the actual machine (tesserocr is DLL-broken there)
- Added a tesserocr smoke test that would always fail on this machine
- Added pytesseract to verification loop but it's not in requirements.txt
Starting fresh with a correct understanding of the OCR stack.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
tesserocr (conda DLLs + bundled wheel) is the primary OCR backend and works
identically on both platforms. pytesseract is an optional fallback that needs
a working tesseract.exe, which winget can install on Win11 but not reliably
on Win10.
Changes:
- Winget step: reframed as optional/best-effort; failure is informational only,
not a warning that "OCR will not work" (tesserocr handles all OCR)
- Remove pytesseract from the verification loop — it is not in requirements.txt
and would always fail on Win10 without winget; adding it in the previous commit
was wrong
- Remove pytesseract-specific smoke test block
- Add tesserocr end-to-end smoke test after the verification loop: opens a
PyTessBaseAPI against the real tessdata model so DLL resolution + tessdata
access are both exercised; sets ALL_OK=0 on failure so the installer reports
the right thing
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Three fixes:
1. After winget tesseract install, check C:\Program Files\Tesseract-OCR\tesseract.exe
actually exists and print a download link if not — previously silent failure.
2. Remove the broken pytesseract source-patch block (Python syntax error on the
os.path.join call — it has never run). ocr.py already handles cmd discovery at
import time via PYTESSERACT_TESSERACT_CMD (Bug 14 fix), so patching is moot.
Replace with a pytesseract.get_tesseract_version() smoke test that exercises the
full exe chain and fails clearly if tesseract is missing.
3. Add pytesseract to the dependency verification loop alongside tesserocr.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- win_input.py: detect OS build via platform.win32_ver(), use
MOUSEEVENTF_ABSOLUTE only on Win10 (build < 22000)
- install.bat: detect and display Windows version on install
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
- 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 <[email protected]>
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
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 <[email protected]>