commit c4d7284ad46d4f9df6f21cff72a54dbf9ce47eed Author: Mar Alegre Date: Sun Oct 18 22:51:40 2020 -0400 First commit diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/lib/General.ahk b/lib/General.ahk new file mode 100644 index 0000000..680eb11 --- /dev/null +++ b/lib/General.ahk @@ -0,0 +1,60 @@ +; Set default location and name convention for compiled scripts to use +;@Ahk2Exe-ExeName %A_MyDocuments%\AutoHotkey\bin\AHK-%A_ScriptName% + +; Install hooks to make sure script can get physical state of keys instead of logical state. +#InstallKeybdHook +#InstallMouseHook + +; Settings +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +#UseHook ; All hotkeys are implemented through keyboard hook to avoid script activating itself. +#MenuMaskKey vkFF + +; +; Function definitions +; + +Hold(Primary, Secondary) { + Send {%Primary% down} + if ( Secondary.Length() != 0 ) { + ThisLoop := Func("HoldLoop").bind(Primary,Secondary) + SetTimer, %ThisLoop%, 50 + } +} + +HoldLoop(Primary, Secondary) { + if GetKeyState(Primary,"P") { + SetTimer, , Delete + } + for index,key in Secondary { + if GetKeyState(key,"P") { + Send {%Primary% up} + SetTimer, , Delete + } + } +} + +Repeat(Primary, Secondary) { + Send {%Primary% up} + Sleep 100 + RepeatVar := 0 + Loop { + if GetKeyState(Primary,"P") { + return + } + for index,key in Secondary { + if GetKeyState(key,"P") { + return + } + } + if (RepeatVar == 2) { + SendEvent, {%Primary%} + RepeatVar := 1 + } else { + RepeatVar++ + } + Sleep 50 + } +} \ No newline at end of file diff --git a/src/Minecraft.ahk b/src/Minecraft.ahk new file mode 100644 index 0000000..f769e28 --- /dev/null +++ b/src/Minecraft.ahk @@ -0,0 +1,72 @@ +; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey +; https://www.autohotkey.com + +; +; Front Matter +; + +; Include general library +#Include ../lib/General.ahk + +; Only do hotkeys if relevant window is active +#IfWinActive, Minecraft + +; +; Hotkeys +; + +; Tab will be the hotkey +~Tab::return + +; Hold/Autoclick mouse buttons +; Holds if single click, autoclicks if double click +Tab & LButton UP:: +KeyWait, LButton, D, T0.2 +if (ErrorLevel = 0) { + Repeat("LButton",["RButton","MButton"]) +} else { + Hold("LButton",["RButton","MButton"]) +} +return +Tab & RButton UP:: +KeyWait, RButton, D, T0.2 +if (ErrorLevel = 0) { + Repeat("RButton",["LButton","MButton"]) +} else { + Hold("RButton",["LButton","MButton"]) +} +return + +; Autorun +Tab & w UP::Hold("w",["s"]) +Tab & s UP::Hold("s",["w"]) +Tab & a UP::Hold("a",["d","w","s"]) +Tab & d UP::Hold("d",["a","w","s"]) + +; Hold crouch +Tab & Shift UP:: +if GetKeyState("Alt","P") { + Hold("Shift",["Ctrl"]) +} else { + Hold("Shift",["Ctrl","Space"]) +} +return + +; Autojump/auto-ascend +Tab & Space UP::Hold("Space",["Shift"]) + +; Mouse button 4: auto-takeoff +; Macro assumes you have your fireworks in the first hotbar slot +XButton1:: +Loop, 5 { + Send {Space down} + Sleep 10 +} +Send {Space up}1 +Sleep 225 +Loop, 5 { + Send {Space down} + Sleep 10 +} +Send {Space up}{RButton} +return \ No newline at end of file diff --git a/src/Outer_Wilds.ahk b/src/Outer_Wilds.ahk new file mode 100644 index 0000000..6c51483 --- /dev/null +++ b/src/Outer_Wilds.ahk @@ -0,0 +1,101 @@ +; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey +; https://www.autohotkey.com + +; +; Front Matter +; + +; Include general library +#Include ../lib/General.ahk + +; Include ViGEm library +#Include ../thirdparty/AHK-ViGEm-Bus/AHK-ViGEm-Bus.ahk +; Create a new Xbox 360 controller +MyXbox := new ViGEmXb360() + +; Settings +SetTitleMatchMode,2 +DetectHiddenWindows,On + +; Set percent to deflect by for fine controls +Defl := 30 + +; Create Gui to show deflection percent +MyGuiTime = 1 +Gui, +AlwaysOnTop -Caption +ToolWindow +Gui, Margin, 0, 0 +Gui, Font, s20 CWhite +Gui, Color, Black +Gui, Add, Text, vMyGuiText +Center, Fine Controls: 100`% +Gui, Show, NoActivate, OuterWildsAhkGui +WinSet, TransColor, Black, OuterWildsAhkGui + +UpdateGui: +If (MyGuiTime != 0) { + Gui, Show, NoActivate + GuiControl, Text, MyGuiText, Fine Controls: %Defl%`% + MyGuiTime-- + If (MyGuiTime == 0) { + Gui, Hide + SetTimer, UpdateGui, Off + } +} +return + +; Only do hotkeys if relevant window is active +#IfWinActive, Outer Wilds + +; +; Hotkeys +; + +; Hold keys +*!w UP::Hold("w",["s"]) +*!s UP::Hold("s",["w"]) +*!a UP::Hold("a",["d","w","s"]) +*!d UP::Hold("d",["a","w","s"]) +*!Space UP::Hold("Space",["Shift"]) +*!Shift UP::Hold("Shift",["Space"]) + +; Alt+Scroll changes deflect percent +*!WheelUp:: +Defl := Min(Defl + 5,100) +MyGuiTime = 10 +SetTimer, UpdateGui, 100 +Goto UpdateGui +return +*!WheelDown:: +Defl := Max(Defl - 5,0) +MyGuiTime = 10 +SetTimer, UpdateGui, 100 +Goto UpdateGui +return + +; Reset all axes when capslock is pressed +~CapsLock:: +MyXbox.Axes.LY.SetState(50) +MyXbox.Axes.LX.SetState(50) +MyXbox.Axes.RT.SetState(0) +MyXbox.Axes.LT.SetState(0) +return + +; Fine control is active when caps lock is on +#If GetKeyState("CapsLock","T") + +W::MyXbox.Axes.LY.SetState(50+Defl*.5) +W UP::MyXbox.Axes.LY.SetState(50) + +S::MyXbox.Axes.LY.SetState(50-Defl*.5) +S UP::MyXbox.Axes.LY.SetState(50) + +D::MyXbox.Axes.LX.SetState(50+Defl*.5) +D UP::MyXbox.Axes.LX.SetState(50) + +A::MyXbox.Axes.LX.SetState(50-Defl*.5) +A UP::MyXbox.Axes.LX.SetState(50) + +Space::MyXbox.Axes.RT.SetState(Defl*.16) +Space UP::MyXbox.Axes.RT.SetState(0) + +Shift::MyXbox.Axes.LT.SetState(Defl*.16) +Shift UP::MyXbox.Axes.LT.SetState(0) \ No newline at end of file diff --git a/thirdparty/AHK-ViGEm-Bus/AHK-ViGEm-Bus.ahk b/thirdparty/AHK-ViGEm-Bus/AHK-ViGEm-Bus.ahk new file mode 100644 index 0000000..56d83c6 --- /dev/null +++ b/thirdparty/AHK-ViGEm-Bus/AHK-ViGEm-Bus.ahk @@ -0,0 +1,207 @@ +#include %A_LineFile%\..\CLR.ahk + +; Static class, holds ViGEm Client instance +class ViGEmWrapper { + static asm := 0 + static client := 0 + + Init(){ + if (this.client == 0){ + this.asm := CLR_LoadLibrary(A_LineFile "\..\ViGEmWrapper.dll") + } + } + + CreateInstance(cls){ + return this.asm.CreateInstance(cls) + } + +} + +; Base class for ViGEm "Targets" (Controller types - eg xb360 / ds4) to inherit from +class ViGEmTarget { + target := 0 + helperClass := "" + controllerClass := "" + + __New(){ + ;~ this.asm := CLR_LoadLibrary(A_LineFile "\..\ViGEmWrapper.dll") + ViGEmWrapper.Init() + this.Instance := ViGEmWrapper.CreateInstance(this.helperClass) + + if (this.Instance.OkCheck() != "OK"){ + msgbox ViGEmWrapper.dll failed to load! + ExitApp + } + } + + SendReport(){ + this.Instance.SendReport() + } +} + +; DS4 (DualShock 4 for Playstation 4) +class ViGEmDS4 extends ViGEmTarget { + helperClass := "ViGEmWrapper.Ds4" + __New(){ + static buttons := {Square: 16, Cross: 32, Circle: 64, Triangle: 128, L1: 256, R1: 512, L2: 1024, R2: 2048 + , Share: 4096, Options: 8192, LS: 16384, RS: 32768 } + static specialButtons := {Ps: 1, TouchPad: 2} + static axes := {LX: 2, LY: 3, RX: 4, RY: 5, LT: 0, RT: 1} + + this.Buttons := {} + for name, id in buttons { + this.Buttons[name] := new this._ButtonHelper(this, id) + } + for name, id in specialButtons { + this.Buttons[name] := new this._SpecialButtonHelper(this, id) + } + + this.Axes := {} + for name, id in axes { + this.Axes[name] := new this._AxisHelper(this, id) + } + + this.Dpad := new this._DpadHelper(this) + base.__New() + } + + class _ButtonHelper { + __New(parent, id){ + this._Parent := parent + this._Id := id + } + + SetState(state){ + this._Parent.Instance.SetButtonState(this._Id, state) + this._Parent.Instance.SendReport() + return this._Parent + } + } + + class _SpecialButtonHelper { + __New(parent, id){ + this._Parent := parent + this._Id := id + } + + SetState(state){ + this._Parent.Instance.SetSpecialButtonState(this._Id, state) + this._Parent.Instance.SendReport() + return this._Parent + } + } + + class _AxisHelper { + __New(parent, id){ + this._Parent := parent + this._Id := id + } + + SetState(state){ + this._Parent.Instance.SetAxisState(this._Id, this.ConvertAxis(state)) + this._Parent.Instance.SendReport() + return this._Parent + } + + ConvertAxis(state){ + return round(state * 2.55) + } + } + + class _DpadHelper { + __New(parent){ + this._Parent := parent + this._Id := id + } + + SetState(state){ + static dPadDirections := {Up: 0, UpRight: 1, Right: 2, DownRight: 3, Down: 4, DownLeft: 5, Left: 6, UpLeft: 7, None: 8} + this._Parent.Instance.SetDpadState(dPadDirections[state]) + this._Parent.Instance.SendReport() + return this._Parent + } + } +} + +; Xb360 +class ViGEmXb360 extends ViGEmTarget { + helperClass := "ViGEmWrapper.Xb360" + __New(){ + static buttons := {A: 4096, B: 8192, X: 16384, Y: 32768, LB: 256, RB: 512, LS: 64, RS: 128, Back: 32, Start: 16, Xbox: 1024} + static axes := {LX: 2, LY: 3, RX: 4, RY: 5, LT: 0, RT: 1} + + this.Buttons := {} + for name, id in buttons { + this.Buttons[name] := new this._ButtonHelper(this, id) + } + + this.Axes := {} + for name, id in axes { + this.Axes[name] := new this._AxisHelper(this, id) + } + + this.Dpad := new this._DpadHelper(this) + + base.__New() + } + + class _ButtonHelper { + __New(parent, id){ + this._Parent := parent + this._Id := id + } + + SetState(state){ + this._Parent.Instance.SetButtonState(this._Id, state) + this._Parent.Instance.SendReport() + return this._Parent + } + } + + class _AxisHelper { + __New(parent, id){ + this._Parent := parent + this._id := id + } + + SetState(state){ + this._Parent.Instance.SetAxisState(this._Id, this.ConvertAxis(state)) + this._Parent.Instance.SendReport() + } + + ConvertAxis(state){ + value := round((state * 655.36) - 32768) + if (value == 32768) + return 32767 + return value + } + } + + class _DpadHelper { + _DpadStates := {1:0, 8:0, 2:0, 4:0} ; Up, Right, Down, Left + __New(parent){ + this._Parent := parent + } + + SetState(state){ + static dpadDirections := { None: {1:0, 8:0, 2:0, 4:0} + , Up: {1:1, 8:0, 2:0, 4:0} + , UpRight: {1:1, 8:1, 2:0, 4:0} + , Right: {1:0, 8:1, 2:0, 4:0} + , DownRight: {1:0, 8:1, 2:1, 4:0} + , Down: {1:0, 8:0, 2:1, 4:0} + , DownLeft: {1:0, 8:0, 2:1, 4:1} + , Left: {1:0, 8:0, 2:0, 4:1} + , UpLeft: {1:1, 8:0, 2:0, 4:1}} + newStates := dpadDirections[state] + for id, newState in newStates { + oldState := this._DpadStates[id] + if (oldState != newState){ + this._DpadStates[id] := newState + this._Parent.Instance.SetButtonState(id, newState) + } + this._Parent.SendReport() + } + } + } +} \ No newline at end of file diff --git a/thirdparty/AHK-ViGEm-Bus/CLR.ahk b/thirdparty/AHK-ViGEm-Bus/CLR.ahk new file mode 100644 index 0000000..c8993f1 --- /dev/null +++ b/thirdparty/AHK-ViGEm-Bus/CLR.ahk @@ -0,0 +1,151 @@ +; ========================================================== +; .NET Framework Interop +; https://autohotkey.com/boards/viewtopic.php?t=4633 +; ========================================================== +; +; Author: Lexikos +; Version: 1.2 +; Requires: AutoHotkey_L v1.0.96+ +; + +CLR_LoadLibrary(AssemblyName, AppDomain=0) +{ + if !AppDomain + AppDomain := CLR_GetDefaultDomain() + e := ComObjError(0) + Loop 1 { + if assembly := AppDomain.Load_2(AssemblyName) + break + static null := ComObject(13,0) + args := ComObjArray(0xC, 1), args[0] := AssemblyName + typeofAssembly := AppDomain.GetType().Assembly.GetType() + if assembly := typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, null, null, args) + break + if assembly := typeofAssembly.InvokeMember_3("LoadFrom", 0x158, null, null, args) + break + } + ComObjError(e) + return assembly +} + +CLR_CreateObject(Assembly, TypeName, Args*) +{ + if !(argCount := Args.MaxIndex()) + return Assembly.CreateInstance_2(TypeName, true) + + vargs := ComObjArray(0xC, argCount) + Loop % argCount + vargs[A_Index-1] := Args[A_Index] + + static Array_Empty := ComObjArray(0xC,0), null := ComObject(13,0) + + return Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty) +} + +CLR_CompileC#(Code, References="", AppDomain=0, FileName="", CompilerOptions="") +{ + return CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions) +} + +CLR_CompileVB(Code, References="", AppDomain=0, FileName="", CompilerOptions="") +{ + return CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions) +} + +CLR_StartDomain(ByRef AppDomain, BaseDirectory="") +{ + static null := ComObject(13,0) + args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComObject(0xB,false) + AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, null, null, args) + return A_LastError >= 0 +} + +CLR_StopDomain(ByRef AppDomain) +{ ; ICorRuntimeHost::UnloadDomain + DllCall("SetLastError", "uint", hr := DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+20*A_PtrSize), "ptr", RtHst, "ptr", ComObjValue(AppDomain))), AppDomain := "" + return hr >= 0 +} + +; NOTE: IT IS NOT NECESSARY TO CALL THIS FUNCTION unless you need to load a specific version. +CLR_Start(Version="") ; returns ICorRuntimeHost* +{ + static RtHst := 0 + ; The simple method gives no control over versioning, and seems to load .NET v2 even when v4 is present: + ; return RtHst ? RtHst : (RtHst:=COM_CreateObject("CLRMetaData.CorRuntimeHost","{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}"), DllCall(NumGet(NumGet(RtHst+0)+40),"uint",RtHst)) + if RtHst + return RtHst + EnvGet SystemRoot, SystemRoot + if Version = + Loop % SystemRoot "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*", 2 + if (FileExist(A_LoopFileFullPath "\mscorlib.dll") && A_LoopFileName > Version) + Version := A_LoopFileName + if DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0 + , "ptr", CLR_GUID(CLSID_CorRuntimeHost, "{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}") + , "ptr", CLR_GUID(IID_ICorRuntimeHost, "{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}") + , "ptr*", RtHst) >= 0 + DllCall(NumGet(NumGet(RtHst+0)+10*A_PtrSize), "ptr", RtHst) ; Start + return RtHst +} + +; +; INTERNAL FUNCTIONS +; + +CLR_GetDefaultDomain() +{ + static defaultDomain := 0 + if !defaultDomain + { ; ICorRuntimeHost::GetDefaultDomain + if DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+13*A_PtrSize), "ptr", RtHst, "ptr*", p:=0) >= 0 + defaultDomain := ComObject(p), ObjRelease(p) + } + return defaultDomain +} + +CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain=0, FileName="", CompilerOptions="") +{ + if !AppDomain + AppDomain := CLR_GetDefaultDomain() + + if !(asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain)) + || !(codeProvider := asmProvider.CreateInstance(ProviderType)) + || !(codeCompiler := codeProvider.CreateCompiler()) + return 0 + + if !(asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain)) + return 0 + + ; Convert | delimited list of references into an array. + StringSplit, Refs, References, |, %A_Space%%A_Tab% + aRefs := ComObjArray(8, Refs0) + Loop % Refs0 + aRefs[A_Index-1] := Refs%A_Index% + + ; Set parameters for compiler. + prms := CLR_CreateObject(asmSystem, "System.CodeDom.Compiler.CompilerParameters", aRefs) + , prms.OutputAssembly := FileName + , prms.GenerateInMemory := FileName="" + , prms.GenerateExecutable := SubStr(FileName,-3)=".exe" + , prms.CompilerOptions := CompilerOptions + , prms.IncludeDebugInformation := true + + ; Compile! + compilerRes := codeCompiler.CompileAssemblyFromSource(prms, Code) + + if error_count := (errors := compilerRes.Errors).Count + { + error_text := "" + Loop % error_count + error_text .= ((e := errors.Item[A_Index-1]).IsWarning ? "Warning " : "Error ") . e.ErrorNumber " on line " e.Line ": " e.ErrorText "`n`n" + MsgBox, 16, Compilation Failed, %error_text% + return 0 + } + ; Success. Return Assembly object or path. + return compilerRes[FileName="" ? "CompiledAssembly" : "PathToAssembly"] +} + +CLR_GUID(ByRef GUID, sGUID) +{ + VarSetCapacity(GUID, 16, 0) + return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &GUID) >= 0 ? &GUID : "" +} \ No newline at end of file diff --git a/thirdparty/AHK-ViGEm-Bus/Nefarius.ViGEmClient.dll b/thirdparty/AHK-ViGEm-Bus/Nefarius.ViGEmClient.dll new file mode 100644 index 0000000..fd2669f Binary files /dev/null and b/thirdparty/AHK-ViGEm-Bus/Nefarius.ViGEmClient.dll differ diff --git a/thirdparty/AHK-ViGEm-Bus/ViGEmWrapper.dll b/thirdparty/AHK-ViGEm-Bus/ViGEmWrapper.dll new file mode 100644 index 0000000..e965665 Binary files /dev/null and b/thirdparty/AHK-ViGEm-Bus/ViGEmWrapper.dll differ