Skip to content

Conversation

@Ven0m0
Copy link
Owner

@Ven0m0 Ven0m0 commented Dec 26, 2025

No description provided.

claude and others added 2 commits December 26, 2025 07:34
…to PowerShell

This comprehensive migration modernizes the codebase structure and eliminates
legacy dependencies.

## Directory Structure Changes
- Rename `AHK_v2/` to `ahk/` for cleaner naming
- Update all documentation references (README, CLAUDE, CONTRIBUTING, EXAMPLES)
- Update all internal script paths and links

## Citra Configuration Migration (v1 → v2)
- Create `Other/Citra_per_game_config/v2/` directory
- Eliminate tf.ahk dependency (1538-line v1 library)
- New v2 helper functions in `CitraConfigHelpers.ahk`:
  * RegExEscape() - Escape regex special characters
  * SetKey() - Set/replace INI key values
  * LoadConfig() - Load configuration files
  * SaveConfig() - Save with backup creation
  * ReplaceInFile() - Simplified text replacement

### Migrated Scripts:
- `CitraConfigBase.ahk` (v2) - Base initialization with error handling
- `CitraPerGame.ahk` (v2) - Per-game config applicator
- `Default.ahk` (v2) - Default configuration applier

### Benefits:
- No external library dependencies
- Native v2 functions (StrReplace, RegExReplace)
- Better error handling and validation
- Automatic backup file creation (.bak)
- OneDrive path validation

## CMD to PowerShell Conversions
- `update.cmd` → `Update-Downloaders.ps1`
  * Enhanced error handling
  * Colored console output
  * Better feedback messages
  * Cmdlet parameter validation

- `Copy_images.cmd` → `Copy-Images.ps1`
  * Parameter validation with types
  * Better error messages
  * Exit code handling
  * Help documentation with examples

## Workflow Updates
- Update `ahk-lint-format-compile.yml` to detect v2 scripts in:
  * `Lib/v2/` (existing)
  * `ahk/` (renamed from AHK_v2)
  * `Other/**/v2/` (new Citra v2 scripts)
- Improved version detection regex pattern

## Documentation Updates
- All references to AHK_v2 updated to 'ahk'
- Updated file paths in README.md
- Updated directory structure examples
- Updated CLAUDE.md migration notes
- Updated CONTRIBUTING.md structure
- Updated EXAMPLES.md code references

## Files Changed
- 7 new files created (v2 scripts and PowerShell)
- 26 files modified (docs, workflows, structure)
- 15 files renamed (AHK_v2 → ahk)

## Migration Status
✅ Directory rename complete (AHK_v2 → ahk)
✅ Citra config scripts migrated to v2
✅ CMD files converted to PowerShell
✅ Workflow updated for v2 detection
✅ Documentation updated

⏳ Remaining (for future PRs):
- Citra mod manager scripts migration
- Downloader GUI script migration
- Additional PowerShell script (Invoke-Robocopy.ps1)
- PowerShell linting workflow

## Testing
- Workflow syntax validated
- PowerShell scripts follow best practices
- v2 scripts use proper AutoHotkey v2.0 syntax
- All paths use forward-compatible patterns

Refs #21
Copilot AI review requested due to automatic review settings December 26, 2025 07:46
@continue
Copy link

continue bot commented Dec 26, 2025

All Green - Keep your PRs mergeable

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts


Unsubscribe from All Green comments

@Ven0m0 Ven0m0 merged commit c36c5c8 into main Dec 26, 2025
5 of 6 checks passed
@Ven0m0 Ven0m0 deleted the claude/migrate-ahk-v2-workflows-y3ieM branch December 26, 2025 07:47
@gemini-code-assist
Copy link

Summary of Changes

Hello @Ven0m0, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on a significant refactoring and modernization effort within the repository. It primarily involves renaming the main AutoHotkey v2 script directory to a more concise name, introducing new PowerShell-based utility scripts for common tasks, and migrating existing Citra emulator configuration logic to a more robust AutoHotkey v2 implementation. These changes aim to improve maintainability, update dependencies, and enhance the overall structure of the project.

Highlights

  • Directory Renaming: The primary directory for AutoHotkey v2 scripts has been renamed from AHK_v2/ to ahk/ for consistency and brevity. This change is reflected across documentation and internal references.
  • New PowerShell Utilities: Two new PowerShell scripts have been introduced: Update-Downloaders.ps1 for updating media download tools (yt-dlp and spotdl) and Copy-Images.ps1 for multi-threaded image copying using Robocopy.
  • Citra Per-Game Config Migration: The Citra per-game configuration scripts have been migrated to AutoHotkey v2, including new helper functions (CitraConfigHelpers.ahk) and base initialization (CitraConfigBase.ahk), replacing older dependencies like tf.ahk.
  • Documentation Updates: Several documentation files (CLAUDE.md, CONTRIBUTING.md, EXAMPLES.md, README.md, and various README.md files within the ahk/ subdirectories) have been updated to reflect the directory renaming and new script paths.
  • Removed GitHub README: The .github/README.md file has been removed, streamlining the repository's top-level documentation structure.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/ahk-lint-format-compile.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a significant and positive step forward for the repository. The migration of scripts from AutoHotkey v1 to v2, the conversion of batch files to more robust PowerShell scripts, and the structural improvement of renaming the AHK_v2 directory to ahk all enhance the project's quality and maintainability. The new v2 scripts for Citra configuration are a great addition. My review focuses on a critical performance issue and several correctness bugs within these new Citra scripts, primarily concerning inefficient file I/O and brittle string replacements. I have also provided suggestions to improve the robustness of the new PowerShell scripts. Overall, this is excellent work, and the suggested changes will make it even better.

Comment on lines +118 to +124
if (game = "default") {
SetRes(10)
SetFilter("xBRZ freescale", false)
SetShader("Bump_Mapping_AA_optimize", true)
SetPreload(true)
SetClock(125)
SetLayout(2)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

There is a significant performance issue here. Each Set... function call reads the entire configuration file from disk and then writes it back. For the "default" game configuration, this results in 6 separate file reads and 6 writes, which is very inefficient and can cause unnecessary disk wear.

To fix this, you should refactor the script to:

  1. Load the configuration file once at the beginning.
  2. Modify the helper functions (SetRes, SetFilter, etc.) to accept the configuration string as a parameter and return the modified string, instead of performing file I/O themselves.
  3. Apply all changes to the configuration string in memory.
  4. Save the final configuration string to the file once at the end.

This will dramatically improve performance by reducing disk I/O.

Here is a conceptual example:

; --- In CitraPerGame.ahk ---
; Load config once
cfg := LoadConfig(CitraConfigFile)

; Apply configs
if (game = "default") {
    cfg := SetRes(cfg, 10)
    cfg := SetFilter(cfg, "xBRZ freescale", false)
    cfg := SetShader(cfg, "Bump_Mapping_AA_optimize", true)
    cfg := SetPreload(cfg, true)
    cfg := SetClock(cfg, 125)
    cfg := SetLayout(cfg, 2)
} else if ... {
    ...
}

; Save config once
SaveConfig(cfg, CitraConfigFile)


; --- Example of modified helper function ---
SetRes(cfg, f) {
    ; No LoadConfig or SaveConfig here
    return RegExReplace(cfg, "m)^resolution_factor=([2-9]|10|1)$", "resolution_factor=" f)
}

cfg := LoadConfig(CitraConfigFile)

cfg := StrReplace(cfg, "preload_textures\default=" (on ? "true" : "false"), "preload_textures\default=" (on ? "false" : "true"))
cfg := StrReplace(cfg, "preload_textures=" (on ? "false" : "false"), "preload_textures=" (on ? "true" : "false"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There appears to be a copy-paste error in this line. The second argument to StrReplace is (on ? "false" : "false"), which always evaluates to "false". This means the line will only ever try to replace preload_textures=false and will do nothing if on is false.

While fixing the immediate bug, I strongly recommend replacing this brittle StrReplace with a more robust RegExReplace to ensure the value is set correctly regardless of its previous state.

    cfg := RegExReplace(cfg, "m)^preload_textures=.*$", "preload_textures=" (on ? "true" : "false"))

Comment on lines +59 to +60
cfg := StrReplace(cfg, "cpu_clock_percentage=125", "cpu_clock_percentage=" pct)
cfg := StrReplace(cfg, "cpu_clock_percentage=25", "cpu_clock_percentage=" pct)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The SetClock function is not robust because it uses StrReplace to find specific values (125 and 25). If the current cpu_clock_percentage is any other value (e.g., 100), this function will fail to update it.

You should use RegExReplace to match the key and replace its value, regardless of what the current value is. This makes the function much more reliable. This same issue applies to SetFilter, SetShader, and SetLayout.

    cfg := RegExReplace(cfg, "m)^cpu_clock_percentage=\d+$", "cpu_clock_percentage=" pct)

Comment on lines +16 to +17
cfg := StrReplace(cfg, "texture_filter_name=none", "texture_filter_name=xBRZ freescale")
cfg := StrReplace(cfg, "texture_filter_name\default=true", "texture_filter_name\default=false")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using StrReplace here is not robust. If texture_filter_name is set to something other than none, this replacement will fail. Similarly, if texture_filter_name\default is already false, the second replacement will fail.

It's much safer to use RegExReplace to match the key and replace the entire value, ensuring the setting is always applied correctly. This advice applies to the other StrReplace calls in this file as well.

cfg := RegExReplace(cfg, "m)^texture_filter_name=.*$", "texture_filter_name=xBRZ freescale")
cfg := RegExReplace(cfg, "m)^texture_filter_name\\default=.*$", "texture_filter_name\default=false")

Comment on lines +19 to +24
[Parameter(Mandatory=$false, Position=0)]
[string]$Source = "input Path",

[Parameter(Mandatory=$false, Position=1)]
[string]$Destination = "output path",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Source and Destination parameters have placeholder default values ("input Path", "output path"). This can lead to errors if the script is run without arguments, as it will attempt to copy from a folder that likely doesn't exist. It's better to make these parameters mandatory to ensure the user always provides valid paths.

    [Parameter(Mandatory=$true, Position=0)]
    [string]$Source,

    [Parameter(Mandatory=$true, Position=1)]
    [string]$Destination,

Comment on lines +91 to +99
try {
if FileExist(configFile)
FileDelete(configFile)
FileAppend(cfg, configFile)
return true
} catch as err {
MsgBox("Error saving config: " . err.Message, "Config Save Error", 16)
return false
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current implementation deletes the file and then appends to it. A more idiomatic and potentially safer approach in AutoHotkey v2 is to use FileOpen() with write mode ("w"), which truncates the file and prepares it for writing in a single, atomic step. This also helps ensure proper encoding is used.

    try {
        FileOpen(configFile, "w", "UTF-8").Write(cfg)
        return true
    } catch as err {
        MsgBox("Error saving config: " . err.Message, "Config Save Error", 16)
        return false
    }

Write-Host "Copying images from '$Source' to '$Destination'..." -ForegroundColor Cyan

# Execute robocopy
$result = robocopy "$Source" "$Destination" $extensions /s /MT:$Threads /NJH /NFL /NC /NS

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The $result variable is assigned the output of robocopy, but it's never used. The script correctly relies on $LASTEXITCODE for status checking. This unused variable can be removed to improve code clarity.

robocopy "$Source" "$Destination" $extensions /s /MT:$Threads /NJH /NFL /NC /NS

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the migration from "AHK_v2" to "ahk" directory naming as part of a broader AutoHotkey v2 workflow consolidation. The changes migrate multiple scripts to v2 syntax, add comprehensive documentation for game automation macros, and update all cross-references throughout the repository.

Key changes:

  • Renamed "AHK_v2" directory to "ahk" with corresponding path updates across 10+ files
  • Migrated 15+ AutoHotkey scripts to v2 (Powerplan, Keys, Fullscreen, ControllerQuit, GUI launchers, game macros)
  • Added 2 new PowerShell utilities (Copy-Images.ps1, Update-Downloaders.ps1)
  • Migrated Citra per-game configuration tools to v2 with 4 new helper modules
  • Added extensive README documentation for Minecraft and Black Ops 6 AFK macros (800+ lines)
  • Updated GitHub Actions workflow to detect v2 scripts in new "ahk/" path

Reviewed changes

Copilot reviewed 14 out of 26 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
ahk/README.md Updated directory path references from "AHK_v2" to "ahk"
ahk/Powerplan.ahk New v2 auto power plan switcher based on process detection
ahk/Keys.ahk New v2 comprehensive hotkey suite with window management
ahk/Fullscreen.ahk New v2 consolidated borderless fullscreen toggle script
ahk/ControllerQuit.ahk New v2 controller-based window closing utility
ahk/GUI/WM.ahk New v2 auto-save/restore window position manager
ahk/GUI/GUI_Shared.ahk New v2 data-driven GUI framework for script launchers
ahk/GUI/GUI.ahk New v2 unified launcher combining multiple button sets
ahk/GUI/README.md Updated parent directory reference from "AHK_v2" to "ahk"
ahk/Minecraft/README.md New 464-line comprehensive documentation for Minecraft AFK macros
ahk/Minecraft/MC_Bedrock.ahk New v2 Bedrock Edition launcher with audio device setup
ahk/Minecraft/MC_AFK.ahk New v2 AFK fishing and mob grinding automation
ahk/Black_ops_6/README.md New 353-line comprehensive documentation for BO6 AFK macros
ahk/Black_ops_6/bo6-afk.ahk New v2 modular AFK macro with multiple game modes
Other/Robocopy/Copy-Images.ps1 New PowerShell script for multi-threaded image copying
Other/Downloader/Update-Downloaders.ps1 New PowerShell script for updating yt-dlp and spotdl
Other/Citra_per_game_config/v2/CitraConfigBase.ahk New v2 shared initialization for Citra config scripts
Other/Citra_per_game_config/v2/CitraConfigHelpers.ahk New v2 helper functions eliminating tf.ahk dependency
Other/Citra_per_game_config/v2/CitraPerGame.ahk New v2 unified per-game config applicator
Other/Citra_per_game_config/v2/Default.ahk New v2 default Citra configuration applicator
README.md Updated directory structure and script table references from "AHK_v2" to "ahk"
EXAMPLES.md Updated script path reference from "AHK_v2" to "ahk"
CONTRIBUTING.md Updated directory structure reference from "AHK_v2" to "ahk"
CLAUDE.md Updated consolidation notes and build system documentation for new path
.github/workflows/ahk-lint-format-compile.yml Enhanced v2 path detection to include "ahk/" and "Other/**/v2/"
.github/README.md Deleted 180-line featured tools documentation file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +50 to +51
cfg := StrReplace(cfg, "preload_textures\default=" (on ? "true" : "false"), "preload_textures\default=" (on ? "false" : "true"))
cfg := StrReplace(cfg, "preload_textures=" (on ? "false" : "false"), "preload_textures=" (on ? "true" : "false"))
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for setting the preload_textures value is incorrect. When on is true, the code sets preload_textures=true but searches for the pattern where preload_textures=false, which means it won't replace anything if the current value is already true. The replacement pattern should use a regex or check both possible states. The same issue exists for the false case.

Suggested change
cfg := StrReplace(cfg, "preload_textures\default=" (on ? "true" : "false"), "preload_textures\default=" (on ? "false" : "true"))
cfg := StrReplace(cfg, "preload_textures=" (on ? "false" : "false"), "preload_textures=" (on ? "true" : "false"))
; Normalize both default and actual preload_textures booleans to match `on`
cfg := RegExReplace(cfg, "m)^preload_textures\\default=(true|false)$", "preload_textures\default=" (on ? "true" : "false"))
cfg := RegExReplace(cfg, "m)^preload_textures=(true|false)$", "preload_textures=" (on ? "true" : "false"))

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
[Parameter(Mandatory=$false, Position=0)]
[string]$Source = "input Path",

[Parameter(Mandatory=$false, Position=1)]
[string]$Destination = "output path",
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default parameter values "input Path" and "output path" are misleading placeholders. Since Mandatory is set to $false, these defaults will be used if no arguments are provided, which would result in attempting to copy from/to invalid paths. Either make these parameters truly mandatory (Mandatory=$true) or provide sensible default values. Having non-functional placeholder strings as defaults violates the principle of safe defaults.

Suggested change
[Parameter(Mandatory=$false, Position=0)]
[string]$Source = "input Path",
[Parameter(Mandatory=$false, Position=1)]
[string]$Destination = "output path",
[Parameter(Mandatory=$true, Position=0)]
[string]$Source,
[Parameter(Mandatory=$true, Position=1)]
[string]$Destination,

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +23
[Parameter(Mandatory=$false, Position=0)]
[string]$Source = "input Path",

[Parameter(Mandatory=$false, Position=1)]
[string]$Destination = "output path",
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default parameter values "input Path" and "output path" are lowercase placeholder text that don't follow the casing convention used in the rest of the parameter. If these are meant to be placeholders, they should be properly capitalized ("Input Path", "Output Path") or better yet, use actual valid default paths or make the parameters truly mandatory without defaults.

Suggested change
[Parameter(Mandatory=$false, Position=0)]
[string]$Source = "input Path",
[Parameter(Mandatory=$false, Position=1)]
[string]$Destination = "output path",
[Parameter(Mandatory=$true, Position=0)]
[string]$Source,
[Parameter(Mandatory=$true, Position=1)]
[string]$Destination,

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +21
ListLines False
SetKeyDelay -1, -1
SetMouseDelay -1
SetDefaultMouseSpeed 0
SetWinDelay -1
SetControlDelay -1
SendMode "Input"
SetTitleMatchMode 3
SetWorkingDir A_ScriptDir
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using #KeyHistory directive with value 0 in a v2 script. In AutoHotkey v2, the correct directive is #KeyHistory MaxEvents where MaxEvents should be a number. To disable key history, use #KeyHistory 0 (which is correct), but the directive should appear before any executable code. However, line 3 has ListLines False which should also be a directive (#NoTrayIcon, not a command). These should be directives at the top.

Suggested change
ListLines False
SetKeyDelay -1, -1
SetMouseDelay -1
SetDefaultMouseSpeed 0
SetWinDelay -1
SetControlDelay -1
SendMode "Input"
SetTitleMatchMode 3
SetWorkingDir A_ScriptDir
ListLines(0)
SetKeyDelay(-1, -1)
SetMouseDelay(-1)
SetDefaultMouseSpeed(0)
SetWinDelay(-1)
SetControlDelay(-1)
SendMode("Input")
SetTitleMatchMode(3)
SetWorkingDir(A_ScriptDir)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants