Thread: Anit Recoil 2.4

Results 1 to 4 of 4
  1. #1
    wyvern1990's Avatar
    Join Date
    Jun 2012
    Gender
    male
    Posts
    137
    Reputation
    10
    Thanks
    2,817

    Anti Recoil 2.4

    If you don't know how to use ahk, this is not for you!

    I'll only release the code as .exe will get you kicked.
    Cut and paste into an .ahk script.

    Added an window to modify hotkeys.
    if you dont have an Numpad to begin with, make an HotKeys.ini (Rename extension of .txt to .ini)
    and copy paste:

    [Hotkeys]
    Hotkey14=Numpad0

    in to the file.
    Rename Numpad0 to a key on you keyboard you do have.

    As always you need iniLib1.0.ahk to use the save and load functions.


    save Primary and Secundary ( MWeel Down = Sec\ MWeelUP is Pri)
    Script will only activate if you assign an program to it with Ctrl+f3
    Added First Shot Multiplier( FSM) = Numpad2
    https://symthic.com/bf4-weapon-charts use this to find the right FSM for weapon.

    How to use!
    1. open Game (Window Borderless)
    2.Open Anti-Recoil
    3.Press Control+F3 to activate with the game
    4. make settings(hotkeys)
    5. Press Numpad0 to save them.

    HotKeys.
    Add Window to Allow using Anti-Recoil = Ctrl+F3

    X shots before Y +1 = Ins
    X shots before Y -1= Home

    Toggle Tap Firing = Numpad6
    Use L or L+R Mouse Button Toggle = Numpad3

    PixelUp = pgup
    PixelDown = pgdn
    PixelLeft = del
    PixelRight = end

    Toggle ON = NumpadMult
    +RPM = NumpadAdd
    -RPM = NumpadSub
    USE = LButton
    Load and Save options = Numpad0


    Anti Recoil 2.4
    Code:
    ;By Wyvern1990
    
    
    ;-------------------------------------------------------------------------------
    ;	GENERAL SETTINGS
    ;-------------------------------------------------------------------------------
    
    
    
    #NoEnv
    #SingleInstance force
    #MaxThreadsPerHotkey 5
    ;#InstallKeybdHook
    ;#InstallMouseHook
    #include IniLib1.0.ahk
    SetBatchLines, -1
    SetTitleMatchMode, 3
    SetTitleMatchMode, Fast
    
    
    
    
    
    ;-------------------------------------------------------------------------------
    ;	Vars
    ;-------------------------------------------------------------------------------
    PresetKeys = Ins|Home|del|end|pgup|pgdn|NumpadMult|NumpadAdd|NumpadSub|Numpad3|Numpad1|Numpad2|Numpad6|Numpad0|^F3|LButton|WheelUp|WheelDown|
    PorS = 1
    Both = 1
    FSM = 1.00
    ReadWin = 0
    Tap = 0
    SH = 1
    pixelx = 0
    pixely = 0
    rpm = 800
    NoRecoil = 0
    enough = 0
    WheelCount = 0
    Burst = 1
    Fired = 0
    NWheelCount := WheelCount
    
    
    ReadHotKeys:
    Loop, Parse,  PresetKeys,| ; Loads PresetKeys 
    				{
    					
                        PreKeys%a_Index% = %a_LoopField% ; save as
    					
    				}
    Loop,18
    {
    	iniRead, HotkeyedPRE, HotKeys.ini, Hotkeys,Hotkey%A_Index%
    		if HotkeyedPRE = ERROR ; if not set PResets (Reset)
    		{
    	       Hotkey%a_Index% := PreKeys%a_Index% ;empty key is PresetKey
    		}
    		else ; Read Value from Ini.
    		{
    			iniRead, Hotkey%A_Index%, HotKeys.ini, Hotkeys,Hotkey%A_Index%
    		}
    		if HotkeyedPRE =    ; if Empty PResets (Reset)
    		{
    	       Hotkey%a_Index% := PreKeys%a_Index% ;empty key is PresetKey
    		}
    	}
    
    
    ;-------------------------------------------------------------------------------
    ;	Hotkeys
    ;-------------------------------------------------------------------------------
    Hotkey, ~*$%Hotkey1%, DoSHDown
    Hotkey, ~*$%Hotkey2%, DoSHUp
    Hotkey, ~*$%Hotkey3%, DoPixelLeft
    Hotkey, ~*$%Hotkey4%, DoPixelRight
    Hotkey, ~*$%Hotkey5%, DoPixelUp
    Hotkey, ~*$%Hotkey6%, DoPixelDown
    HotKey, ~*$%Hotkey7%, DoToggleNoRecoil
    HotKey, ~*$%Hotkey8%, DoDelayUp
    HotKey, ~*$%Hotkey9%, DoDelayDown
    Hotkey, ~*$%Hotkey10%, BothB
    Hotkey, ~*$%Hotkey11%, BurstMode
    Hotkey, ~*$%Hotkey12%, FirstShotMulti
    Hotkey, ~*$%Hotkey13%, SemiAuto
    Hotkey, ~*$%Hotkey14%, GetFromIni
    Hotkey, ~*$%Hotkey15%, AddGame
    Hotkey, ~*$%Hotkey16%, BothButtons
    Hotkey, ~*$%Hotkey17%, WheelCount_Up, On B0 T20
    Hotkey, ~*$%Hotkey18%, WheelCount_Down, On B0 T20
    SetTimer,CheckActiveWin, 1
    
    ;-------------------------------------------------------------------------------
    ;	Functions
    ;-------------------------------------------------------------------------------
    CheckExitFile:
    IfnotExist, exit.gif
    {
    URLDownloadToFile, https://albatross1.com/HIGHRES/exit.gif, exit.gif ;Downloads close icon in GUI
    Loop
    {
    	sleep, 1
    	ifExist, exit.gif
    		Continue
    }
    }
    
    
    TipRPS(PopupText)
    {
    	Gui,2: Destroy
    	Gui,2: +AlwaysOnTop +ToolWindow -SysMenu -Caption
    	Gui,2: Color, 000000
    	Gui,2: Font, s10 Wbold, Lucida Colsole
    	Gui,2: Add, Text, x5 y5 c00ff00, %PopupText%
    	Gui,2: Show, NoActivate X0 Y36,Tip1
    	WinSet, TransColor,000000 200,Tip1
    }
    
    TipOn(PopupText)
    {
    	Gui,2: Destroy
    	Gui,2: +AlwaysOnTop +ToolWindow -SysMenu -Caption
    	Gui,2: Color, 000000
    	Gui,2: Font, s10 Wbold, Lucida Colsole
    	Gui,2: Add, Text, x5 y5 c00ff00, %PopupText%
    	Gui,2: Show, NoActivate X0 Y18, Tip2
    	WinSet, TransColor,000000 200,Tip2
    }
    
    TipOff(PopupText)
    {
    	Gui,2: Destroy
    	Gui,2: +AlwaysOnTop +ToolWindow -SysMenu -Caption
    	Gui,2: Color, 000000
    	Gui,2: Font, s10 WBold, Lucida Colsole
    	Gui,2: Add, Text, x5 y5 cff0000, %PopupText%
    	Gui,2: Show, NoActivate X0 Y54,Tip3
    	WinSet, TransColor,000000 200,Tip3
    }
    
    
    TipClear:
    {
    	SetTimer,TipClear, 2000
    	Gui,2: destroy
    }
    return
    
    
    Return
    
    
    ;-------------------------------------------------------------------------------
    ;	Hotkey labels
    ;-------------------------------------------------------------------------------
    
    AddGame:
    Suspend, Permit
    	SetTimer, CheckActiveWin, Off
    	WinGetActiveTitle, CurrentWindow
    	WinGet, ActiveADD, ProcessName, %CurrentWindow%
    	IniWrite, %ActiveADD%, AllowedGames.ini,Games,%CurrentWindow% ;Writes ProcessName to ini as "ActiveWindow=ProcessName"
    MsgBox, Added %ActiveADD%
    SetTimer, CheckActiveWin, On
    return
    
    CheckActiveWin:
    suspend, permit
    WinGetActiveTitle, title
    WinGet,ProcesName, ProcessName, %title%
    loop,1
    {
    	;tooltip, | %Pors% | %PorsW% ,0,0
    	IniRead,Allowed,AllowedGames.ini,Games,%title%, ; checks if current window is in AllowdGames.ini, returns ERROR if (Key=WinTitle Value=ProcesName)  is not found.
    	if Allowed = Error ;Suspend All Hotkeys
    	{
    		Count := 2
    		AllSuspend := 1
    		Suspend, On
    	}
    	else
    	{
    		Count := 1
    		AllSuspend := 2
    		Suspend, Off
    	}	
    }
    return
    
    WheelCount_Down:
    NWheelCount := WheelCount
    if WheelCount = 1
    {
    	WheelCount = 0
    	WeaponLoad = %SecundairyWeapon%
    	if WheelCount <> NWheelcount
    	{
    	TipOn(WeaponLoad)
        }
    	 gosub, LoadFromIni
    	;ToolTip, %WheelCount% | %NWheelCount%,0,0
    }
    	Return
    
    WheelCount_Up:
    NWheelCount := WheelCount
    if WheelCount = 0
    {
    	WheelCount = 1
    	WeaponLoad = %PrimairyWeapon%
    	if WheelCount <> NWheelCount
    	{
    	TipOn(WeaponLoad)
    	}
    	Gosub, LoadFromIni
    	;ToolTip, %WheelCount% | %NWheelCount%,0,0
    }
    	Return
    
    PorST:
    if PorS = 1
    {
    	PorS -= 1
    	if PorS = 0
    	{
    		PorSW = Secundairy	
        }
    }
    else 
    {
    	PorS = 1
    	if PorS = 1
    	{
    		PorSW = Primairy
    	}
    }
    GuiControl ,, Button4, Save As %PorSW%
    Return
    	
    BothB:
    if Both = 1
    {
    	Both -=1
    	TipOn(" LMouseButton")
    }
    else
    {
    	Both = 1
    TipOff("L+R MouseButton")
    }
    return
    	
    
    BurstMode:
    if Burst <= 4
    {
    	Burst += 2
    TipOn("Burst = " Burst)
    }
    else
    {
    	Burst = 1
    TipOff("Burst = Off")
    }
    return
    
    FirstShotMulti:
    if FSM <= 3.0
    {
    	FSM += 0.05
    	TipOn("Fisrt Shot Multi  = "Round(FSM,2) " X  = " Mul(pixely,FSM))
    }
    else ;FSM = 2.00
    {
    	FSM := 1.0
    	TipOn("First Shot Multi  = " FSM)
    }
    return
    
    
    SemiAuto:
    If Tap = 0
    {
    	Tap +=1
    	TipOn("Tap  = ON")
    }
    else
    {
    	Tap -= 1
    	TipOn("Tap  = OFF")
    }
    return
    
    
    DoToggleNoRecoil:
    if NoRecoil < 1
    {
    	NoRecoil += 1
    	if NoRecoil = 1
    	{
    		;SoundBeep, 800, 200
    		TipOn("ON")
    	}
    }
    else
    {
    	NoRecoil := 0
    	;SoundBeep, 200, 100
    	;SoundBeep, 200, 100
    	TipOff("OFF")
    }
    return
    
    DoSHDown:
    If SH > 1
    	SH -= 1
    SHK = 0
    TipOn("SH  = " SH)
    return
    
    DoSHUp:
    If SH <20
    	SH += 1
    SHK = 0
    TipOn("SH  = " SH)
    return
    
    DoPixelRight:
    if pixelx < 10
    	pixelx += 1
    TipOn("Pixel X Is " pixelX)
    return
    
    DoPixelLeft:
    if pixelx > -10
    	pixelx -= 1
    TipOn("Pixel X Is " pixelX)
    return
    
    DoPixelUp:
    if pixely < 50
    	pixely += 1
    TipOn("Pixel Y Is " pixelY)
    return
    
    DoPixelDown:
    if pixely > 0
    	pixely -= 1
    TipOn("Pixel Y Is " pixelY)
    return
    
    DoDelayUp:
    if rpm > 400
    	rpm -= 10
    TipRPS("RPM: " rpm "  " "RPS:" f(rpm))
    return
    
    DoDelayDown:
    if rpm < 4000
    	rpm += 10
    TipRPS("RPM: " rpm "  " "RPS:" f(rpm))
    return
    
    DoPeriodUp:
    if period > 100
    	period -= 100
    TipOn("PERIOD IS " period)
    return
    
    DoPeriodDown:
    if period < 6000
    	period += 100
    TipOn("PERIOD IS " period)
    return
    
    
    ;----------------------------------------------SAVE, LOAD, DELETE, FUNC-------------------------------------------------------------------
    ;-----------------------------------------------------------------------------------------------------------------------------------------
    ;Pulls up Listview of Saved Weapon for easy picking.
    GetFromIni:
    SetTimer, Update, 100
    SetTimer, TipClear, Off
    FileRead, iniWeapons, %title%.ini ; reads .ini for the game you are playing
    FileRead, iniPriSec, %title%PriSec.ini
    Sort, iniPriSec,D[]
    Sort, iniWeapons,D[]
    SetTimer,CheckActiveWin, Off
    NoRecoil = 0
    PorS = 0
    There = 0
    
    ;----------------------------------------------------------------------------------------------------------------------------------
    ;--------------------------------------------------------GUI SETTINGS--------------------------------------------------------------
    if ReadWin = 0
    {
    	ReadWin = 1
    	WinGetTitle, title, %title%
    }
    Gui,Destroy
    Gui, -Caption +Toolwindow
    Gui, Color, 000000
    Gui, Add, Checkbox, x532 y9 w280 h20 vCheckBox1 cFF0000 checked%Both% gBothB, Press L + R Mousekey to Activate
    Gui, Add, Text, x12 y9 w150 h20 vText1 cFF0000, Save To INI
    Gui, Add, Edit, x172 y9 w150 h20 vWeaponSend
    Gui, Add, Button, x172 y39 w150 h20 R1 gSaveToIni , Save To Ini
    Gui, Add, Checkbox, x12 y39 w150 h20 vCheckBox2 cFF0000 checked%PorS% gPorST ,Checked is Secundary
    gosub, PorST
    Gui, Add, Button, x12 y69 w150 h20 vPorSW  gLoadFromIni, Save As %PorSW%
    Gui, Add, Button, x172 y69 w150 h20 gDelete , Delete
    Gui, Add, Text, x12 y99 w300 h20 vText2 cFF0000, Settings from %title%.ini
    Gui, Add, Text, x532 y39 w280 h20 vText3 cFF0000, Double Click in listview to Load
    Gui, Add, Button, x532 y69 w150 h20 gHotkeys, Hotkeys
    Gui, Add, ListView, x12 y129 w570 h420 Background000000 cFF0000 vLV1 gMyWeaponView , Name|SH|X|Y|RPM|TAP|FSM|Burst|
    Gosub,FillWeaponList
    Gui, Add, Text, x842 y69 w430 h20 c00FF00 vText4, Settings From %title%PriSec.ini
    Gui, Add, DropDownList, x842 y9 w120 h30 R5 c00FF00 Background000000 vSetSend , Assault||Engineer|Support|Recon|
    Gui, Add, Button, x842 y39 w150 h20 gSaveToClass, Save Class to Ini
    Gui, Add, ListView, x842 y129 w490 h420 c00FF00 Background000000 vLV2 gMyClassView , Class|Primary|Secundary
    Gosub,FillClassList
    Gui, Add , Picture, AltSubmit x1280 y9 w32 h32 gExitApp, exit.gif
    gui, font,S12 cRed WBold, MS sans serif
    GuiControl +BackgroundTrans, Text1
    GuiControl Font, Text1
    GuiControl +BackgroundTrans, Text2
    GuiControl Font, Text2
    gui, font,S12 c0000FF WBold, MS sans serif
    GuiControl +BackgroundTrans, Text3
    GuiControl Font, Text3
    gui, font,S12 c00FF00 WBold, MS sans serif
    GuiControl +BackgroundTrans, Text4
    GuiControl Font, Text4
    gui, font,S6 cRed WBold, MS sans serif
    GuiControl Font, CheckBox1
    GuiControl Font, CheckBox2
    Gui, Show, w1360 h706, Settings
    return
    
    FillWeaponList:
    Gui, ListView, LV1
    Weapons := ini_getAllSectionNames(iniWeapons)
    Loop, Parse, Weapons, `,
    {
    	LV_Add("", A_LoopField, ini_getValue(iniWeapons, A_LoopField, "SH"),ini_getValue(iniWeapons, A_LoopField, "X"),ini_getValue(iniWeapons,A_LoopField, "Y"), ini_getValue(iniWeapons, A_LoopField, "rpm"), ini_GetValue(iniWeapons, A_LoopField, "TAP"),ini_GetValue(iniWeapons, A_LoopField, "FSM"),ini_getValue(iniWeapons, A_LoopField, "Burst"))
    }
    LV_ModifyCol(20)  ; Auto-size each column to fit its contents.
    LV_ModifyCol()  ; For sorting purposes.
    return
    
    FillClassList:
    Gui, Listview, LV2
    PriSec := ini_getAllSectionNames(iniPriSec)
    loop, Parse, PriSec, `,
    {
    	LV_Add("", A_LoopField, ini_getValue(iniPriSec, A_LoopField, "PrimairyWeapon"),ini_getValue(iniPriSec, A_LoopField, "SecundairyWeapon"))
    }
    LV_ModifyCol()  ; Auto-size each column to fit its contents.
    ; Display the window and return. The script will be notified whenever the user double clicks a row.
    return
    
    ;----------------------------------------------------------------------------------------------------------------------------------
    ;--------------------------------------------------------GUI HOETKEYS--------------------------------------------------------------
    
    HotKeys:
    Gui, 3:Destroy
    Gui, 3:-Caption +Toolwindow
    Gui, 3:Color, 000000
    Gui, 3: Font, cFFFFFF
    ;-----------------------------------TEXT-------------------------------------------
    Gui, 3: Add, Text, x12 y9 w250 h30 vT1 , + # Y-Movements shots before X-movement 
    Gui, 3: Add, Text, x12 y49 w250 h30 vT2, - # Y-Movements shots before X-movement 
    Gui, 3: Add, Text, x12 y89 w250 h30 vT3, Pixel-Left	
    Gui, 3: Add, Text, x12 y129 w250 h30 vT4, Pixel-Right
    Gui, 3: Add, Text, x12 y169 w250 h30 vT5, Pixel-Up
    Gui, 3: Add, Text, x12 y209 w250 h30 vT6, Pixel-Down
    Gui, 3: Add, Text, x12 y249 w250 h30 vT7, Toggle Anti Recoil
    Gui, 3: Add, Text, x12 y289 w250 h30 vT8, RPM/Delay Up
    Gui, 3: Add, Text, x12 y329 w250 h30  vT9, RPM/Delay Down
    
    Gui, 3: Add, Text, x412 y9 w250 h30 vT10, L or L+R Mouse Buttons
    Gui, 3: Add, Text, x412 y49 w250 h30 vT11, Burst
    Gui, 3: Add, Text, x412 y89 w250 h30 vT12, First Shot Multiplier
    Gui, 3: Add, Text, x412 y129 w250 h30 vT13, Semi Auto(Tap fire)
    Gui, 3: Add, Text, x412 y169 w250 h30 vT14, Anti Recoil Settings
    Gui, 3: Add, Text, x412 y209 w250 h30 vT15, AddGame
    Gui, 3: Add, Text, x412 y249 w250 h30 vT16, USE (remaps Left Mouse Button )
    Gui, 3: Add, Text, x412 y289 w250 h30 vT17, Select  Primary Weapon
    Gui, 3: Add, Text, x412 y329 w250 h30 vT18, Select Secondary Weapon
    
    Gui, 3: Add, Button, x12 y369 w170 h30 gSaveHotkeys, Save Hotkeys
    Gui, 3: Add, Button, x222 y369 w170 h30 gResetHotkeys, Reset Hotkeys
    ;---------------------------------------------DDL-------------------------------------------------
    Gui, 3: Add, Hotkey, x272  y9 w120 h30 vDDL1,  %Hotkey1%
    Gui, 3: Add, Hotkey, x272 y49 w120 h30 vDDL2, %Hotkey2%
    Gui, 3: Add, Hotkey, x272 y89 w120 h30  vDDL3,  %Hotkey3% 
    Gui, 3: Add, Hotkey, x272 y129 w120 h30 vDDL4, %Hotkey4%
    Gui, 3: Add, Hotkey, x272 y169 w120 h30 vDDL5,  %Hotkey5%
    Gui, 3: Add, Hotkey, x272 y209 w120 h30 vDDL6, %Hotkey6%
    Gui, 3: Add, Hotkey, x272 y249 w120 h30 vDDL7, %Hotkey7%
    Gui, 3: Add, Hotkey, x272 y289 w120 h30 vDDL8, %Hotkey8%
    Gui, 3: Add, Hotkey, x272 y329 w120 h30 vDDL9, %Hotkey9%
    Gui, 3: Add, Hotkey, x672 y9 w120 h30 vDDL10, %Hotkey10% 
    Gui, 3: Add, Hotkey, x672 y49 w120 h30 vDDL11, %Hotkey11%
    Gui, 3: Add, Hotkey, x672 y89 w120 h30 vDDL12, %Hotkey12%
    Gui, 3: Add, Hotkey, x672 y129 w120 h30 vDDL13, %Hotkey13%
    Gui, 3: Add, Hotkey, x672 y169 w120 h30 vDDL14, %Hotkey14%
    Gui, 3: Add, Hotkey, x672 y209 w120 h30 vDDL15, %Hotkey15%
    Gui, 3: Add, DropDownList, x672 y249 w120 h30 R2 vDDL16, LButton|MButton
    Gui, 3: Add, DropDownList, x672 y289 w120 h30 R10 vDDL17, WheelUp|WheelDown|1|2|3|4|5|6|7|8|9|0
    Gui, 3: Add, DropDownList, x672 y329 w120 h30 R10 vDDL18, WheelUp|WheelDown|1|2|3|4|5|6|7|8|9|0
    ; Generated using SmartGUI Creator for SciTE
    Gui, 3: Add , Picture, AltSubmit x800 y9 w32 h32 gExitHotKeys, exit.gif
    gosub, DDLPopulate
    Gui, 3: Show, w830 h423, HotKeys
    return
    
    DDLPopulate:
    loop,18
    {
    	her = DDL%A_Index%
    	Hotkeying := Hotkey%a_Index%
    GuiControl, 3:ChooseString, %her%, %Hotkeying%
    }
    Return
    
    ResetHotkeys:
    FileDelete, HotKeys.ini
    gosub,ReadHotKeys
    Gosub,HotKeys
    return
    
    
    ExitHotKeys:
    Gui 3:Destroy
    return
    
    
    SaveHotkeys:
    FileDelete, HotKeys.ini
    Gui, Submit, Nohide ; submit changes
    Loop,18
    {	
    	FileRead, iniCheckList, HotKeys.ini ; reads every new line written to it
    	CheckList  := ini_GetAllValues(iniCheckList,HotKeys) ; make list of hotkeys currently written, expands by 1 on every iteratiion
    	DDL := DDL%A_Index% ; input from DDL
    	IniWrite, %DDL%, HotKeys.ini, Hotkeys, Hotkey%A_Index%
    	T = T%A_Index%
    	loop, parse, Checklist, `n,
    	{
    		if not InStr(CheckList,DDL) ; IF NOT DUP
    		{
    			gui, font,S6 c00FF00 WBold, MS sans serif
    			GuiControl Font, %T%
    		}			
    		if instr(CheckList,DDL)  ; IF DUP
    		{
    			gui, font,S6 cRed WBold, MS sans serif
                GuiControl Font, %T%
                Return
    		} 
    	}
    }
    Gosub, ReadHotKeys
    ;gosub, HotKeys
    Return
    
    
    Update: 
    GuiControlGet,focused,FocusV
    if A_GuiEvent = 
    	loop
    {
    if focused = LV1
    	RowNumber = 0
    	Loop,1
      ; This causes the first loop iteration to start the search at the top of the list.
        {
    		Gui,ListView, LV1
    	RowNumber := LV_GetNext(0,"focused")	; Resume the search at the row after that found by the previous iteration.
    	if not RowNumber  ; The above returned zero, so there are no more selected rows.
    		break
    	LV_GetText(Delete, RowNumber)
    	GuiControl,, WeaponSend, %Delete%
        }
    if focused = LV2
    	RowNumber = 0
    	loop,1
      ; This causes the first loop iteration to start the search at the top of the list.
        {
    		Gui, ListView, LV2
    	RowNumber := LV_GetNext(0,"focused")	; Resume the search at the row after that found by the previous iteration.
    	if not RowNumber  ; The above returned zero, so there are no more selected rows.
    		break
    	LV_GetText(set, RowNumber)
    	GuiControl,, SetSend, %set%
        }
    	Sleep,20
    }
    return
    
    
    Delete:
    ~*Del::
    GuiControlGet, focused2,FocusV
    {
        if focused = LV1
        RowNumber = 0
        Loop
    	{
            Gui,ListView, LV1
    		RowNumber := LV_GetNext(0,"focused2")
            if not RowNumber
    			break
            LV_GetText(Delete, RowNumber)
            IniDelete,%title%.ini,%Delete%
            gosub,GetFromIni
        }
        if focused = LV2
        RowNumber = 0
        loop
    	{
    		Gui, ListView, LV2
            RowNumber := LV_GetNext(0,"focused2")
            if not RowNumber
    			break
            LV_GetText(set, RowNumber)
    		IniDelete,%title%PriSec.ini,%set%
            gosub,GetFromIni
    	}
    }
    return
    
    MyClassView:
    Gui,ListView, LV2
    if A_GuiEvent = DoubleClick
    {
    	LV_GetText(Class, A_EventInfo)
    	LV_GetText(PrimairyWeapon, A_EventInfo, 2)  ; Get the text from the row's first field.
    	LV_GetText(SecundairyWeapon, A_EventInfo, 3)
    }
    Gosub, GuiClose
    TipRPS(" Loaded!!  Sec = "SecundairyWeapon "     Pri = " PrimairyWeapon)
    return
    
    MyWeaponView:
    Gui,ListView, LV1
    if A_GuiEvent = DoubleClick
    {
    		WeaponLoad = %Delete%
        if PorS = 1
        {
            PrimairyWeapon = %WeaponLoad%
        }
    else
        {
    	    SecundairyWeapon = %WeaponLoad%	
        }
    }	
    	LV_GetText(Delete, A_EventInfo)
    	LV_GetText(SH, A_EventInfo, 2)  ; Get the text from the row's first field.
    	LV_GetText(pixelx, A_EventInfo, 3)
    	LV_GetText(pixely, A_EventInfo, 4)
    	LV_GetText(rpm, A_EventInfo, 5)
    	LV_GetText(Tap, A_EventInfo, 6)
    	LV_GetText(FSM, A_eventInfo, 7)
    	LV_GetText(Burst, A_eventInfo, 8)
    	Gosub, GuiClose
    	TipRPS(" Loaded!!    Weapon : " Delete " " "Y : "pixely "  " "X : "pixelx "  "  "RPM : " rpm "  "" SH" "  " SH " "" TAP" TAP)
    return
    
    
    LoadFromIni:
    If ReadWin = 1
    {
        GoSub, Update
    	WeaponLoad = %Delete%
        if PorS = 1
        {
            PrimairyWeapon = %WeaponLoad%
        }
    else
        {
    	    SecundairyWeapon = %WeaponLoad%	
        }
    }
    IniRead, SH, %a_workingDir%\%title%.ini, %WeaponLoad%, SH, 1
    IniRead, pixely, %a_workingDir%\%title%.ini, %WeaponLoad%, Y,0
    IniRead, pixelx, %a_workingDir%\%title%.ini, %WeaponLoad%, X,0
    IniRead, rpm, %a_workingDir%\%title%.ini, %WeaponLoad%, rpm, 800
    IniRead, TAP, %a_workingDir%\%title%.ini, %WeaponLoad%, TAP, 0
    IniRead, FSM, %a_workingDir%\%title%.ini, %WeaponLoad%, FSM, 1.00
    IniRead,Burst, %A_WorkingDir%\%title%.ini,%Weaponload%, Burst,1
    return 
    
    
    
    SaveToClass:
    Gui,Submit, Nohide
    if There >= 0
    {
    	There += 1
    }
    IniRead,Exist,%title%PriSec.ini,%SetSend%%There% ;checks if class+number exist
    if Exist is not space ;if not blanc
    	Gosub, SaveToClass ; reruns previous till name is empty and save acordingly
    else
    {
    	SetSend = %SetSend%%There%
        IniWrite,%PrimairyWeapon%,%A_WorkingDir%\%title%PriSec.ini,%SetSend%,PrimairyWeapon
        IniWrite,%SecundairyWeapon%,%A_WorkingDir%\%title%PriSec.ini,%SetSend%,SecundairyWeapon
    	gosub,GuiCLose
    	TipRPS(" Saved!! " SetSend)
    	return
    }
    return
    
    
    
    SaveToIni:
    Gui,Submit, Nohide
    {
    	IniDelete, %A_WorkingDir%\%title%.ini, %WeaponSend%
    	IniWrite,%SH%,%A_WorkingDir%\%title%.ini,%WeaponSend%,SH
    	IniWrite,%pixely%,%A_WorkingDir%\%title%.ini,%WeaponSend%,Y
    	IniWrite,%pixelx%,%A_WorkingDir%\%title%.ini,%WeaponSend%,X
    	IniWrite,%rpm%,%A_WorkingDir%\%title%.ini,%WeaponSend%,rpm
    	IniWrite,%TAP%,%A_WorkingDir%\%title%.ini,%WeaponSend%, Tap
    	IniWrite,%FSM%,%A_WorkingDir%\%title%.ini,%WeaponSend%, FSM
    	IniWrite,%Burst%,%A_Workingdir%\%title%.ini,%WeaponSend%, Burst
    	Gosub, GuiClose
    	TipRPS(" Saved!!    Weapon :" WeaponSend " " "Y :" pixely "  " "X : " pixelx "  "  "RPM :" rpm "  ""SH" "  " SH " " "TAP" TAP)
        }
    return
    	
    ExitApp:
    GuiClose:
    SetTimer,CheckActiveWin, On
    SetTimer,Update, Off
    Settimer, TipClear, 2000
    Gui, 2:Destroy
    Gui, 3:Destroy
    Gui, Destroy
    ReadWin = 0
    NoRecoil = 1
    return
    ;------------------------------------------------------------------------------------------------------------
    ;------------------------------------------------------------------------------------------------------------
    
    BothButtons:
    if NoRecoil = 1
    {
    	if Both = 1
    		{
    			GetKeyState, state, RButton, P ; RButton must me held down to use the LButton(Mouse)
    			if state = U
    				return
    		}
    		loop
    			{
    				GetKeyState, state2, LButton, P
    		        if state2 = U
    					break
    		        if Tap = 1
    					{
    						MouseClick, Left,,,,,D
    			            MouseClick, Left,,,,,U
    					}
    				if Burst >=2
    					{
    					if A_index = %Burst% 
    						{
    						MouseClick, Left,,,,,U
    							break
    						}
    					}
    					 if getKeystate("LButton", "P") = 0
    					    {
    						Break
    					    }
    					if Burst >= 2
    						{
    						MouseClick, Left,,,,,D
    						}
    					if Tap = 1
    						{
    						SetMouseDelay, f(rpm)
    						}
    					else
    						{
    						sleep, f(rpm)
    						}
    					if FSM >= 1.00
    					    {
    						if A_Index <= 1
    							{
    						    Round(FSMY := pixely * FSM)
    						    DllCall("mouse_event", "uint",1 , "Uint", 0,"Uint", Mul(pixely,FSM))
    					        }
    					    else
    					        {
    							DllCall("mouse_event", "uint",1 , "Uint", 0,"Uint", pixely)
    					        }
    				        }
    						SHK += 1
    				     If SH = %SHK% ; If equals then x
    					    {    
    						SHK := 0 ; Resets Counter
    						DllCall("mouse_event", "uint",1 , "Uint", pixelx,"Uint", 0)
    					    }
    				    }
    			    }
    return
    
    ;-------------------------------interval per shot in Miliseconds----------------------------------------
    
    
    Mul(A,B)
    {
    	Return Round(A*B,2)
    }
    return
    
    
    f(n)
    {
    	Return Round(60000/n)
    	
    }
    return

    iniLib1.0.ahk
    Copy paste to IniLib1.0.ahk and put it in the same folder.
    Code:
    /*
    Title: Basic ini string functions
        Operate on variables instead of files. An easy to use ini parser.
        
    About: License
        New BSD License
    Copyright (c) 2010, Tuncay
    All rights reserved.
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
        * Redistributions of source code must retain the above copyright
          notice, this list of conditions and the following disclaimer.
        * Redistributions in binary form must reproduce the above copyright
          notice, this list of conditions and the following disclaimer in the
          documentation and/or other materials provided with the distribution.
        * Neither the name of the Tuncay nor the
          names of its contributors may be used to endorse or promote products
          derived from this software without specific prior written permission.
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL Tuncay BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    About: Introduction
        Ini files are used mostly as configuration files. In general, they have the
        ".ini"-extension. It is a simple standardized organization of text data. 
        Many other simple programs use them for storing text.    
        
        AutoHotkey provides three commands IniDelete, IniRead and IniWrite. These
        commands are stable, but they have some disadvantages. First disadvantage
        is, that they access the file directly. The file on the disk is opened, 
        load into memory and then read or manipulated and then saved with every 
        single command.    
        With the custom functions I wrote here, the user accessess on variables 
        instead of files. This is super fast, in comparison to disk access. Ini 
        files can be created by Ahk just like any other variable. But Ahk itself 
        does not have any function to operate on ini strings (variables). If you 
        read often from ini file, then this might for you. 
        
        No other framework or library is required, no special object files are 
        created; just work on ordinary ini file contents or variables. The load
        and save functions are added for comfort reason and are not really needed.
        
        * *First do this:*
        
        > FileRead, ini, config.ini
        
        * *or load default file with:*
        
        > ini_load(ini)
        
        * *or create the content yourself:*
        
        (Start Code)
        ini =
        (
        [Tip]
        TimeStamp = 20090716194758
        [Recent File List]
        File1=F:\testfile.ahk
        File2=Z:\tempfile.tmp
        )
        (End Code)
        
        In this example "Tip" and "Recent File List" are name of the sections. The
        file consist in this example of 2 sections. Every section contains variables,
        so called "keys". Every key is a part of a section. In this example, the 
        section "Tip" have one key "TimeStamp". And every key has a content, 
        called value. The "TimeStamp" key have the value "20090716194758".
        
        After that, you can access and modify the content of the ini variable with 
        the following functions. But the modifications are only temporary and must 
        me saved to disk. This should be done by overwriting the source (not 
        appending).
        
        *Notes*: A keys content (the value) goes until end of line. Any space 
        surroounding the value is at default lost. For best compatibility, the
        names of section and key should consist of alpha (a-z), num (0-9) and the
        underscore only. In general, the names are case insensitiv.
    Links:
        * Lib Home: [https://autohotkey.net/~Tuncay/lib/index.html]
        * Download: [https://autohotkey.net/~Tuncay/lib/ini.zip]
        * Discussion: [https://www.autohotkey.com/forum/viewtopic.php?t=46226]
        * License: [https://autohotkey.net/~Tuncay/licenses/newBSD_tuncay.txt]
    Date:
        2010-09-26
    Revision:
        1.0
    Developers:
        * Tuncay (Author)
        * Mystiq (Tester and Co-Author of an important regex)
        * Fry (Tester)
    Category:
        String Manipulation, FileSystem
    Type:
        Library
    Standalone (such as no need for extern file or library):
        Yes
    StdLibConform (such as use of prefix and no globals use):
        Yes
    Related:
        *Format Specifications (not strictly implemented)*
        * Wikipedia - INI file [https://en.wikipedia.org/wiki/INI_file]
        * Cloanto Implementation of INI File Format [https://www.cloanto.com/specs/ini.html]
        
        *AutoHotkey Commands*
        * IniRead: [https://www.autohotkey.com/docs/commands/IniRead.htm]
        * IniWrite: [https://www.autohotkey.com/docs/commands/IniWrite.htm]
        * IniDelete: [https://www.autohotkey.com/docs/commands/IniDelete.htm]
        
        *Other Community Solutions*
        * INI Library by Titan: [https://www.autohotkey.com/forum/viewtopic.php?t=26141]
        * [Class] IniFile by bmcclure: [https://www.autohotkey.com/forum/viewtopic.php?t=41506]
        * [module] Ini by majkinetor: [https://www.autohotkey.com/forum/viewtopic.php?t=22495]
        * Auto read,load and save by Superfraggle: [https://www.autohotkey.com/forum/viewtopic.php?t=21346]
        * globalsFromIni by Tuncay: [https://www.autohotkey.com/forum/viewtopic.php?t=27928]
        * Read .INI file in one go by Smurth: [https://www.autohotkey.com/forum/viewtopic.php?t=36601]
    About: Examples
        
    Usage:
        
        (Code)
        value := ini_getValue(ini, "Section", "Key")                    ; <- Get value of a key.
        value := ini_getValue(ini, "", "Key")                           ; <- Get value of first found key.
        key := ini_getKey(ini, "Section", "Key")                        ; <- Get key/value pair.
        section := ini_getSection(ini, "Section")                       ; <- Get full section with all keys.
        
        ini_replaceValue(ini, "Section", "Key", A_Now)                  ; -> Update value of a key.
        ini_replaceKey(ini, "Section", "Key")                           ; -> Delete a key.
        ini_replaceSection(ini, "Section", "[Section1]Key1=0`nKey2=1")  ; -> Replace a section with all its keys.
        
        ini_insertValue(ini, "Section", "Key" ",ListItem")              ; -> Add a value to existing value.
        ini_insertKey(ini, "Section", "Key=" . A_Now)                   ; -> Add a key/value pair.
        ini_insertSection(ini, "Section", "Key1=ini`nKey2=Tuncay")      ; -> Add a section.
        
        keys := ini_getAllKeyNames(ini, "Section")                      ;
        <- Get a list of all key names.
        sections := ini_getAllSectionNames(ini)                         ; <- Get a list of all section names.
        (End Code)
    About: Functions
    Parameters:
        Content         - Content of an ini file (also this can be one section
                            only).
        Section         - Unique name of the section. Some functions support the
                            default empty string "". This leads to look up at 
                            first found section. 
        Key             - Name of the variable under the section.
        Replacement     - New content to use.
        PreserveSpace   - Should be set to 1 if spaces around the value of a key
                            should be saved, otherwise they are lost. The
                            surrounding single or double quotes are also lost.
        The 'get' functions returns the desired contents without touching the 
        variable.
        
        The 'replace' and 'insert' functions changes the desired content directly
        and returns 1 for success and 0 otherwise.
        
        There are some more type of functions and parameters. But these are not listed
        here.
    Remarks:
        On success, ErrorLevel is set to '0'. Otherwise ErrorLevel is set to '1' if
        key under desired section is not found.
        
        The functions are not designed to be used in all situations. On rare 
        conditions, the result could be corrupt or not usable. In example, there 
        is no handling of commas inside the key or section names.
        Any "\E" would end the literal sequence and switch back to regex. The
        "\E" sequence is not escaped, because its very uncommon to use backslashes
        inside key and section names. To workaround this, replace at every key or
        section name the "\E" part with "\E\\E\Q":
        
        > Name := "Folder\Edit\Test1"
        > IfInString, Name, \
        > {
        >     StringReplace, Name, Name, \E, \E\\E\Q, All
        > }
        > MsgBox % ini_getValue(ini, "paths", Name)
        This allows us to work with regex, but then at the end it should be closed 
        with "\Q" again.
        > ; Used regex at keyname: "Time.*"
        > value := ini_getValue(ini, "Tip", "\ETime.*\Q")
    */
    
    
    /*
    _______________________________________________________________________________
    _______________________________________________________________________________
    Section: Parse
    About: About
    Brief:
        Main functions for getting, setting and updating section or key.
    _______________________________________________________________________________
    _______________________________________________________________________________
    */
    
    
    ; .............................................................................
    ; Group: Get
    ;   Functions for reading data.
    ; .............................................................................
    
    
    /*
    Func: ini_getValue
        Read and return a value from a key
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. If it is specified to "", 
                            then section is ignored and first found key is get.
        Key             - Name of the variable under the section.
        PreserveSpace   - *Optional* Should be set to 1 if spaces around the value 
                            of a key should be saved, otherwise they are lost. The
                            surrounding single or double quotes are also lost.
                            Default is deleting surrounding spaces and quotes.
    Returns:
        On success the content of desired key is returned, otherwise an empty string.
    Examples:
        > value := ini_getValue(ini, "Tip", "TimeStamp")
        > MsgBox %value%
        *Output:*
        > 20090716194758
    */
    ini_getValue(ByRef _Content, _Section, _Key, _PreserveSpace = False)
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
        {
             _Section = \[\s*?\Q%_Section%\E\s*?]
        }
        ; Note: The regex of this function was rewritten by Mystiq.
        RegEx = `aiU)(?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*.+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=(.*)(?=\R|$)
    /*
        RegEx := "`aiU)"
          . "(?:\R|^)\s*" . _Section . "\s*"         ;-- section
          . "(?:"
          . "\R\s*"                           ;-- empty lines
          . "|\R\s*[\w\s]+\s*=\s*.*?\s*(?=\R)"      ;-- OR other key=value pairs
          . "|\R\s*[;#].*?(?=\R)"                  ;-- OR commented lines
          . ")*"
          . "\R\s*\Q" . _Key . "\E\s*=(.*)(?=\R|$)"   ;-- match
    */
       
        If RegExMatch(_Content, RegEx, Value)
        {
            If Not _PreserveSpace
            {
                Value1 = %Value1% ; Trim spaces.
                FirstChar := SubStr(Value1, 1, 1)
                If (FirstChar = """" AND SubStr(Value1, 0, 1)= """"
                    OR FirstChar = "'" AND SubStr(Value1, 0, 1)= "'")
                {
                    StringTrimLeft, Value1, Value1, 1
                    StringTrimRight, Value1, Value1, 1
                }
            }
            ErrorLevel = 0
        }
        Else
        {
            ErrorLevel = 1
            Value1 =
        }
        Return Value1
    }
    
    
    /*
    Func: ini_getKey
        Read and return a complete key with key name and content.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. If it is specified to "", 
                            then section is ignored and first found key is get.
        Key             - Name of the variable under the section.
    Returns:
        On success the key and value pair in one string is returned, otherwise an empty string.
    Examples:
        > key := ini_getKey(ini, "Tip", "TimeStamp")
        > MsgBox %key%
        *Output:*
        > TimeStamp = 20090716194758
    */
    ini_getKey(ByRef _Content, _Section, _Key)
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
             _Section = \[\s*?\Q%_Section%\E\s*?]
       
        ; Note: The regex of this function was rewritten by Mystiq.
        RegEx = `aiU)(?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*.+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R(\s*\Q%_Key%\E\s*=.*)(?=\R|$)
        If RegExMatch(_Content, RegEx, Value)
            ErrorLevel = 0
        Else
        {
            ErrorLevel = 1
            Value1 =
        }
        Return Value1
    }
    
    
    /*
    Func: ini_getSection
        Read and return a complete section with section name.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. (An enmpty string "" is not
                            working.)
    Returns:
        On success the entire section in one string is returned, otherwise an empty string.
        
    Examples:
        > section := ini_getSection(ini, "Tip")
        > MsgBox %section% 
        *Output:*
        > [Tip]
        > TimeStamp = 20090716194758
    */
    ini_getSection(ByRef _Content, _Section)
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
             _Section = \[\s*?\Q%_Section%\E\s*?]
        RegEx = `aisUS)^.*(%_Section%\s*\R?.*)(?:\R*\s*(?:\[.*?|\R))?$
        If RegExMatch(_Content, RegEx, Value)
            ErrorLevel = 0
        Else
        {
            ErrorLevel = 1
            Value1 =
        }
        Return Value1
    }
    
    /*
    Func: ini_getAllValues
        Read and get a new line separated list of all values in one go.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - *Optional* Unique name of the section.
        Count           - *Variable Optional* The number of found values/keys.
    Returns:
        On success a newline "`n" separated list with all name of keys is returned, 
        otherwise an empty string. If section is specified, only those from that
        section is returned, otherwise from all sections.
    Remarks:
        Other than the other getAll-functions list separator, this function uses
        the new line "`n" character instead the comma "," for separating values.
        Also other than the other getValue functions, this does not provide any
        preserveSpaces option, as it allways preserves surrounding spaces and
        quotes.
    Examples:
        > values := ini_getAllValues(ini, "Recent File List")
        > MsgBox %values%
        *Output:*
        > F:\testfile.ahk
        > Z:\tempfile.tmp
    */
    ini_getAllValues(ByRef _Content, _Section = "", ByRef _count = "")
    {
        RegEx = `aisUmS)^(?=.*)(?:\s*\[\s*?.*\s*?]\s*|\s*?.+\s*?=(.*))(?=.*)$
        If (_Section != "")
            Values := RegExReplace(ini_getSection(_Content, _Section), RegEx, "$1`n", Match)
        Else
            Values := RegExReplace(_Content, RegEx, "$1`n", Match)
        If Match
        {
            Values := RegExReplace(Values, "`aS)\R+", "`n")
            ; Workaround, sometimes it catches sections. Whitespaces only should be eliminated also.
            Values := RegExReplace(Values, "`aS)\[.*?]\R+|\R+$|\R+ +$", "") 
            StringReplace, Values, Values, `n, `n, UseErrorLevel
            _count := ErrorLevel ? ErrorLevel : 0
            StringTrimLeft, Values, Values, 1
            ErrorLevel = 0
        }
        Else
        {
            ErrorLevel = 1
            _count = 0
            Values =
        }
        Return Values
    }
    
    
    /*
    Func: ini_getAllKeyNames
        Read and get a comma separated list of all key names in one go.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - *Optional* Unique name of the section.
        Count           - *Variable Optional* The number of found keys.
    Returns:
        On success a comma separated list with all name of keys is returned, 
        otherwise an empty string. If section is specified, only those from that
        section is returned, otherwise from all sections.
        
    Examples:
        > keys := ini_getAllKeyNames(ini, "Recent File List")
        > MsgBox %keys%
        *Output:*
        > File1,File2
    */
    ini_getAllKeyNames(ByRef _Content, _Section = "", ByRef _count = "")
    {
        RegEx = `aisUmS)^.*(?:\s*\[\s*?.*\s*?]\s*|\s*?(.+)\s*?=.*).*$
        If (_Section != "")
            KeyNames := RegExReplace(ini_getSection(_Content, _Section), RegEx, "$1", Match)
        Else
            KeyNames := RegExReplace(_Content, RegEx, "$1", Match)
        If Match
        {
            KeyNames := RegExReplace(KeyNames, "S)\R+", ",")
            ; Workaround, sometimes it catches sections. Whitespaces only should be eliminated also.
            KeyNames := RegExReplace(KeyNames, "S)\[.*?],+|,+$|,+ +", "") 
            StringReplace, KeyNames, KeyNames, `,, `,, UseErrorLevel
            _count := ErrorLevel ? ErrorLevel : 0
            StringTrimLeft, KeyNames, KeyNames, 1
            ErrorLevel = 0
        }
        Else
        {
            ErrorLevel = 1
            _count = 0
            KeyNames =
        }
        Return KeyNames
    }
    
    
    /*
    Func: ini_getAllSectionNames
        Read and get a comma separated list of all section names in one go.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Count           - *Variable Optional* The number of found sections.
    Returns:
        On success a comma separated list with all name of sections is returned, 
        otherwise an empty string.
        
    Examples:
        > sections := ini_getAllSectionNames(ini)
        > MsgBox %sections%
        *Output:*
        > Tip,Recent File List
    */
    ini_getAllSectionNames(ByRef _Content, ByRef _count = "")
    {
        RegEx = `aisUmS)^.*(?:\s*\[\s*?(.*)\s*?]\s*|.+=.*).*$
        SectionNames := RegExReplace(_Content, RegEx, "$1", MatchNum)
        If MatchNum
        {
            SectionNames := RegExReplace(SectionNames, "S)\R+", ",", _count)
            ; Workaround, whitespaces only should be eliminated.
            SectionNames := RegExReplace(SectionNames, "S),+ +", "") 
            StringReplace, SectionNames, SectionNames, `,, `,, UseErrorLevel
            _count := ErrorLevel ? ErrorLevel : 0
            _count := _count ? _count : 0
            StringTrimRight, SectionNames, SectionNames, 1
            ErrorLevel = 0
        }
        Else
        {
            ErrorLevel = 1
            _count = 0
            SectionNames =
            
            
        }
        Return SectionNames
    }
    
    
    ; .............................................................................
    ; Group: Replace
    ;   Functions for replacing existing data.
    ; .............................................................................
    
    
    /*
    Func: ini_replaceValue
        Updates the value of a key.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. If it is specified to "", 
                            then section is ignored and first found key is get.
        Key             - Name of the variable under the section. 
        Replacement     - *Optional* New content to use. If not specified, the 
                            content will be replaced with no content. That means
                            it is deleted/set to empty string.
        PreserveSpace   - *Optional* Should be set to 1 if spaces around the value 
                            of a key should be saved, otherwise they are lost. The
                            surrounding single or double quotes are also lost.
                            Default is deleting surrounding spaces.
    Returns:
        Returns 1 if key is updated to new value, and 0 otherwise (opposite of 
        ErrorLevel). 
        
    Examples:
        > ini_replaceValue(ini, "Tip", "TimeStamp", 2009)
        > value := ini_getValue(ini, "Tip", "TimeStamp")
        > MsgBox %value%
        *Output:*
        > 2009
    */
    ini_replaceValue(ByRef _Content, _Section, _Key, _Replacement = "", _PreserveSpace = False)
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
             _Section = \[\s*?\Q%_Section%\E\s*?]
        If Not _PreserveSpace
        {
            _Replacement = %_Replacement% ; Trim spaces.
            FirstChar := SubStr(_Replacement, 1, 1)
            If (FirstChar = """" AND SubStr(_Replacement, 0, 1)= """"
                OR FirstChar = "'" AND SubStr(_Replacement, 0, 1)= "'")
            {
                StringTrimLeft, _Replacement, _Replacement, 1
                StringTrimRight, _Replacement, _Replacement, 1
            }
        }
        ; Note: The regex of this function was written by Mystiq.
        RegEx = `aiU)((?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*.+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=).*((?=\R|$))
        _Content := RegExReplace(_Content, RegEx, "$1" . _Replacement . "$2", isReplaced, 1)
        If isReplaced
            ErrorLevel = 0
        Else
            ErrorLevel = 1
        Return isReplaced
    }
    
    
    /*
    Func: ini_replaceKey
        Changes complete key with its name and value.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. If it is specified to "", 
                            then section is ignored and first found key is get.
        Key             - Name of the variable under the section.
        Replacement     - *Optional* New content to use. If not specified, the 
                            content will be replaced with no content. That means
                            it is deleted/set to empty string.
                          The replacement should contain an equality sign.
                          (Expected form: "keyName=value")
    Returns:
        Returns 1 if key is updated to new value, and 0 otherwise (opposite of 
        ErrorLevel). 
        
    Examples:
        > ini_replaceKey(ini, "Tip", "TimeStamp", "TimeStamp=1980")
        > value := ini_getValue(ini, "Tip", "TimeStamp")
        > MsgBox %value%
        *Output:*
        > 1980
    */
    ini_replaceKey(ByRef _Content, _Section, _Key, _Replacement = "")
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
             _Section = \[\s*?\Q%_Section%\E\s*?]
        If _Replacement !=
        {
            _Replacement = %_Replacement%
            _Replacement = `n%_Replacement%
        }
        ; Note: The regex of this function was written by Mystiq.
        RegEx = `aiU)((?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*.+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*)\R\s*\Q%_Key%\E\s*=.*((?=\R|$))
        _Content := RegExReplace(_Content, RegEx, "$1" . _Replacement . "$2", isReplaced, 1)
        If isReplaced
            ErrorLevel = 0
        Else
            ErrorLevel = 1
        Return isReplaced
    }
    
    /*
    Func: ini_replaceSection
        Changes complete section with all its keys and contents.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. If it is specified to "", 
                            then section is ignored and first found key is get.
        Replacement     - *Optional* New content to use. If not specified, the 
                            content will be replaced with no content. That means
                            it is deleted/set to empty string.
                          The replacement should contain everything what a section
                          contains, like the "[" and "]" before and after section
                          name and all keys with its equality sign and value.
                          (Expected form: "[sectionName]`nkeyName=value")
    Returns:
        Returns 1 if key is updated to new value, and 0 otherwise (opposite of 
        ErrorLevel). 
        
    Examples:
        > ini_replaceSection(ini, "Tip", "TimeStamp", "[Section1]`nKey1=Hello`nKey2=You!")
        > value := ini_getValue(ini, "Section1", "Key1")
        > MsgBox %value%
        *Output:*
        > Hello
    */
    ini_replaceSection(ByRef _Content, _Section, _Replacement = "")
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
             _Section = \[\s*?\Q%_Section%\E\s*?]
        RegEx = `aisU)^(\s*?.*)%_Section%\s*\R?.*(\R*\s*(?:\[.*|\R))?$ 
        _Content := RegExReplace(_Content, RegEx, "$1" . _Replacement . "$2", isReplaced, 1)
        If isReplaced
            ErrorLevel = 0
        Else
            ErrorLevel = 1
        Return isReplaced
    }
    
    
    ; .............................................................................
    ; Group: Insert
    ;   Functions for adding new data.
    ; .............................................................................
    
    
    /*
    Func: ini_insertValue
        Adds value to the end of existing value of specified key.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. If it is specified to "", 
                            then section is ignored and first found key is get.
        Key             - Name of the variable under the section.
        Value           - Value to be inserted at end of currently existing value.
        PreserveSpace   - *Optional* Should be set to 1 if spaces around the value 
                            of a key should be saved, otherwise they are lost. The
                            surrounding single or double quotes are also lost.
                            Default is deleting surrounding spaces.
    Returns:
        Returns 1 if value is inserted, and 0 otherwise (opposite of ErrorLevel).
        
    Examples:
        > ini_insertValue(ini, "Recent File List", "File1", ", " . A_ScriptName)
        > value := ini_getValue(ini, "Recent File List", "File1")
        > MsgBox %value%
        *Output:*
        > F:\testfile.ahk, ini.ahk
    */
    ini_insertValue(ByRef _Content, _Section, _Key, _Value, _PreserveSpace = False)
    {
        If (_Section = "")
            _Section = (?:\[.*])?
        Else
             _Section = \[\s*?\Q%_Section%\E\s*?]
        If Not _PreserveSpace
        {
            _Value = %_Value% ; Trim spaces.
            FirstChar := SubStr(_Value, 1, 1)
            If (FirstChar = """" AND SubStr(_Value, 0, 1)= """"
                OR FirstChar = "'" AND SubStr(_Value, 0, 1)= "'")
            {
                StringTrimLeft, _Value, _Value, 1
                StringTrimRight, _Value, _Value, 1
            }
        }
        ; Note: The regex of this function was written by Mystiq.
        RegEx = S`aiU)((?:\R|^)\s*%_Section%\s*(?:\R\s*|\R\s*.+\s*=\s*.*?\s*(?=\R)|\R\s*[;#].*?(?=\R))*\R\s*\Q%_Key%\E\s*=.*?)((?=\R|$))
        _Content := RegExReplace(_Content, RegEx, "$1" . _Value . "$2", isInserted, 1)
        If isInserted
            ErrorLevel = 0
        Else
            ErrorLevel = 1
        Return isInserted
    }
    
    
    /*
    Func: ini_insertKey
        Adds a key pair with its name and value, if key does not already exists.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section. (An enmpty string "" is not
                            working.)
        Key             - Key and value pair splitted by an equality sign.
    Returns:
        Returns 1 if key is inserted, and 0 otherwise (opposite of ErrorLevel).
    Remarks:
        Currently, it works as a workaround with different function calls instead 
        of one regex call. This makes it slower against the other functions.
        
    Examples:
        > ini_insertKey(ini, "Tip", "TimeNow=" . 20090925195317)
        > value := ini_getValue(ini, "Tip", "TimeNow")
        > MsgBox %value%
        *Output:*
        > 20090925195317
    */
    ini_insertKey(ByRef _Content, _Section, _Key)
    {
        StringLeft, K, _Key, % InStr(_Key, "=") - 1
        sectionCopy := ini_getSection(_Content, _Section)
        keyList := ini_getAllKeyNames(sectionCopy)
        isInserted = 0
        If K Not In %keyList%
        {
            sectionCopy .= "`n" . _Key
            isInserted = 1
        }
        If isInserted
        {
            ini_replaceSection(_Content, _Section, sectionCopy)
            ErrorLevel = 0 
        }
        Else
        {
            ErrorLevel = 1
        } 
        Return isInserted
    }
    
    /*
    Func: ini_insertSection
        Adds a section and its keys, if section does not exist already.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section to be added and checked if
                            it is already existing.
        Keys            - *Optional* Set of key value pairs. Every key and value 
                            pair should be at its own line divided by a new line 
                            character.
    Returns:
        Returns 1 if section and the keys are inserted, and 0 otherwise (opposite 
        of ErrorLevel).
        
    Examples:
        > ini_insertSection(ini, "Tip", "Files", "Name1=Programs`nPath1=C:\Program Files")
        > value := ini_getValue(ini, "Files", "Name1")
        > MsgBox %value%
        *Output:*
        > Programs
    */
    ini_insertSection(ByRef _Content, _Section, _Keys = "")
    {
        RegEx = `aisU)^.*\R*\[\s*?\Q%_Section%\E\s*?]\s*\R+.*$
        If Not RegExMatch(_Content, RegEx)
        {
            _Content = %_Content%`n[%_Section%]`n%_Keys%
            isInserted = 1
            ErrorLevel = 0
        }
        Else
        {
            isInserted = 0
            ErrorLevel = 1
        }
        Return isInserted
    }
    
    
    /*
    _______________________________________________________________________________
    _______________________________________________________________________________
    Section: Additional
    About: About
    Brief:
        Other functions besides the core ones.
    _______________________________________________________________________________
    _______________________________________________________________________________
    */
    
    ; .............................................................................
    ; Group: File
    ;   Related routines about file handling with some comfort.
    ; .............................................................................
    
    /*
    Func: ini_load
        Reads an ini file into a variable and resolves any part of the path.
    Parameters:
        Content         - *Variable* On success, the file is loaded into this 
                            variable.
        Path            - *Optional* Source filename or -path to look for. It
                            can contain wildcards. If this is an existing directory 
                            (or contains backslash at the end), then default 
                            filename is appended. Default filename is ScriptName 
                            with ".ini" extension (in example "script.ini").
                            Relative Pathes are solved to current WorkingDir. 
                            Every part of the path (like filename and -extension) 
                            are optional. Default extension is logically ".ini". 
                            Binary files are not loaded. Empty string is resolved 
                            to "ScriptPathNoExt + .ini".
        convertNewLine  - *Optional* If this is true, all "`r`n" (CRLF) new line
                            sequence of files content will be replaced with "`n" 
                            (LF) only. Normally this is not necessary.
    Returns:
        The resolved full path which was searched for. If file exists, the full 
        path with correct case from the disk is get.
    Remarks:
        This function is not necessary to work with the ini-library. In fact, in 
        the heart, it does nothing else than FileRead. The filled variable is an
        ordinary string. You can work with custom functions other from this library
        on these variables, as if you would do allways.
        
        If file is not found or content is binary, or at any other reason ErrorLevel
        is set to 1 and Content is set to "" (empty).
    Examples:
        > ; Load content of default file into variable "ini".
        > path := ini_load(ini)
        > MsgBox %path%
        *Output:*
        > E:\Tuncay\AutoHotkey\scriptname.ini
    */
    ini_load(ByRef _Content, _Path = "", _convertNewLine = false)
    {
        ini_buildPath(_Path)
        error := true ; If file is found next, then its set to false.
        Loop, %_Path%, 0, 0
        {
            _Path := A_LoopFileLongPath
            error := false
            Break
        }    
        If (error = false)
        {
            FileRead, _Content, %_Path%
            If (ErrorLevel)
            {
                error := true
            }
            Else
            {
                FileGetSize, fileSize, %_Path%
                If (fileSize != StrLen(_Content))
                {
                    error := true
                }
            }
        }
        If (error)
        {
            _Content := ""
        }
        Else If (_convertNewLine)
        {
            StringReplace, _Content, _Content, `r`n, `n, All
        }
        ErrorLevel := error
        Return _Path
    }
    
    
    /*
    Func: ini_save
        Writes an ini file from variable to disk.
    Parameters:
        Content         - *Variable* Ini content to save at given path on disk.
        Path            - *Optional* Source filename or -path to look for. It
                            can contain wildcards. If this is an existing directory 
                            (or contains backslash at the end), then default 
                            filename is appended. Default filename is ScriptName 
                            with ".ini" extension (in example "script.ini").
                            Relative Pathes are solved to current WorkingDir. 
                            Every part of the path (like filename and -extension) 
                            are optional. Default extension is logically ".ini". 
                            Binary files are not loaded. Empty string is resolved 
                            to "ScriptPathNoExt + .ini".
        convertNewLine  - *Optional* If this is true, all "`n" (LF) new line
                            sequence of files content will be replaced with "`r`n"
                            (CRLF). Normally, Windows default new line sequence is
                            "`r`n". (Source is not changed with this option.)
        overwrite       - *Optional* If this mode is enabled (true at default), 
                            the source file will be updated. Otherwise, the
                            file is saved to disk only if source does not exist
                            already.
    Returns:
        The resolved full path which was searched for.
    Remarks:
        If overwrite mode is enabled and file could not be deleted, then ErrorLevel 
        is set to 1. Otherwise, if overwriting an existing file is not allowed 
        (overwrite = false) and file is existing, then ErrorLevel will be set to 1 
        also.
    Examples:
        > ; Write and update content of ini variable to default file.
        > path := ini_save(ini)
        > MsgBox %path%
        *Output:*
        > E:\Tuncay\AutoHotkey\scriptname.ini
    */
    ini_save(ByRef _Content, _Path = "", _convertNewLine = true, _overwrite = true)
    {
        ini_buildPath(_Path)
        error := false
        If (_overwrite)
        {
            Loop, %_Path%, 0, 0
            {
                _Path := A_LoopFileLongPath
                Break
            }    
            If FileExist(_Path)
            {
                FileDelete, %_Path%
                If (ErrorLevel)
                {
                    error := true
                }
            }
        }
        Else If FileExist(_Path)
        {
            error := true
        }
        If (error = false)
        {
            If (_convertNewLine)
            {
                StringReplace, _Content, _Content, `r`n, `n, All
                StringReplace, _Content, _Content, `n, `r`n, All
                FileAppend, %_Content%, %_Path%
            }
            Else
            {
                FileAppend, %_Content%, *%_Path%
            }
            If (ErrorLevel)
            {
                error := true
            }
        }
        ErrorLevel := error
        Return _Path
    }
    
    ; An internally used function, made not for public.
    ini_buildPath(ByRef _path)
    {
        ; Set to default wildcard if filename or exension are not set.
        If (_Path = "")
        {
            _Path := RegExReplace(A_ScriptFullPath, "S)\..*?$") . ".ini"
        }
        Else If (SubStr(_Path, 0, 1) = "\")
        {
            _Path .= RegExReplace(A_ScriptName, "S)\..*?$") . ".ini"
        }
        Else
        {
            If (InStr(FileExist(_Path), "D"))
            {
                ; If the current path is a directory, then add default file pattern to the directory.
                _Path .= "\" . RegExReplace(A_ScriptName, "S)\..*?$") . ".ini"
            }
            Else
            {
                ; Check all parts of path and use defaults, if any part is not specified.
                SplitPath, _Path,, fileDir, fileExtension, fileNameNoExt
                If (fileDir = "")
                {
                    fileDir := A_WorkingDir
                }
                If (fileExtension = "")
                {
                    fileExtension := "ini"
                }
                If (fileNameNoExt = "")
                {
                    fileNameNoExt := RegExReplace(A_ScriptName, "S)\..*?$")
                }
                _Path := fileDir . "\" . fileNameNoExt . "." . fileExtension
            }
        }
        Return 0
    }
    
    ; .............................................................................
    ; Group: Edit
    ;   These manipulates the whole ini structure (or an extracted section only).
    ; .............................................................................
    
    /*
    Func: ini_repair
        Repair and build an ini from scratch. Leave out comments and trim unneeded 
        whitespaces.
    Parameters:
        Content         - Content of an ini file (also this can be one 
                            section only).
        PreserveSpace   - *Optional* Should be set to 1 if spaces around the value 
                            of a key should be saved, otherwise they are lost. 
                            Default is deleting surrounding spaces.
        CommentSymbols  - *Optional* List of characters which are should be treated 
                            as comment symbols. Every single character in list is 
                            a symbol. Default are ";" and "#", in example defined 
                            as ";#". 
        LineDelim       - *Optional* A sequence of characters which should be the
                            delimiter as the line end symbol. Default is "`n", a
                            new line.
    Returns:
        The new formatted ini string with trimmed whitespaces and without comments.
    Remarks:
        Other than the most other functions here, the ini Content variable is not
        a byref and will not manipulated directly. The return value is the new ini.
        The LineDelim option can be leaved as is. Internally all commands of 
        AutoHotkey like MsgBox or FileAppend are working correctly with this.
        
        What it does is, building a new ini content string from an existing one.
        The reason to use this function is, if anyone have problems with the 
        source ini because of whitespaces or comments and formatting. The new
        resulting ini is consistently reduced to standard ini format (at least,
        it should).
        Dublicate key entries in same section are merged into one key. The last
        instance overwrites just the one before.
    Examples:
        (code)
        ini =
        (
        
            [ malformed section  ]
    city   =  Berlin'
    whatever='this ; is nasty'
         [bad]
    cat    =     'miao'
        )
        ini := ini_repair(ini, true)
        MsgBox %ini%
        (end)
        *Output:*
        (code)
    [malformed section]
    city=  Berlin'
    whatever='this 
    [bad]
    cat=     'miao'
        (end)
    */
    ini_repair(_Content, _PreserveSpace = False, _CommentSymbols = ";#", _LineDelim = "`n")
    {
        If (_CommentSymbols != "")
        {
            regex = `aiUSm)(?:\R\s*|(s*|\t*))[%_CommentSymbols%].*?(?=\R)
            _Content := RegExReplace(_Content, regex, "$1")
        }
        Loop, Parse, _Content, `n, `r
        {
            If (RegExMatch(A_LoopField, "`aiSm)\[\s*(.+?)\s*]", Match))
            {
                newIni .= _LineDelim . "[" . Match1 . "]"
                section := Match1
                KeyList := ""
            }
            Else If (RegExMatch(A_LoopField, "`aiSm)\s*(\b(?:.+?|\s?)\b)\s*=(.*)", Match))
            {
                If (_PreserveSpace = false)
                {
                    Match2 = %Match2%
                }
                If Match1 Not in %KeyList% ; Disallowes dublicate.
                {
                    KeyList .= "," . Match1
                }
                Else
                {
                    ; As a workaround it should be just deleted, because if set 
                    ; here the surrounding whitespaces are lost.
                    ini_replaceKey(newIni, section, Match1, "")
                }
                newIni .= _LineDelim . Match1 . "=" . Match2
            }
        }
        StringReplace, newIni, newIni, %_LineDelim%
        If (newIni != "")
        {
            ErrorLevel := 0
        }
        Else
        {
            ErrorLevel := 1
        }
        Return newIni
    }
    
    
    /*
    Func: ini_mergeKeys
        Merge two ini sources into first one. Adds new sections and keys and 
        processess existing keys.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only). This is the destination where new 
                            sections and keys are added into.
        source          - *Variable* This is also an ini content from which to 
                            retrieve the new data. These will be added into Content 
                            variable.
        updateMode      - *Optional* Defines how existing keys should be processed.
                            Default is ('1') overwriting last instance with newest 
                            one. 
            updateMode: '1' - ("Default") Replace existng key with newest/last one
                        from source.
            
            updateMode: '2' - Append everything to existing key in Content.
            
            updateMode: '3' - Replace only if source is higher than destination key
                        in Content.
            
            updateMode: '4' - Exclude keys in Content, which exists in both sources.
            
            updateMode: '0' - ("Or any other value") Does not manipulate existing keys
                        in Content, leaving them in their orginal state. Just add 
                        new unknown keys to Content.
                            
    Returns:
        Returns the steps taken to manipulate the destination Content. Every added or 
        manipulated key and section are rising by 1 the return value. 0 if nothing is
        changed.
    Remarks:    
        ErrorLevel is set to '1' if something is changed in Content, '0' otherwise.
        
        The Content variable is updated with the content from source. This means, new
        sections and keys are added allways. In a conflict where same key was found 
        in source again, in case it is existing in Content already, then the variable
        updateMode defines how they should be processed. Default is, to use last found
        key.
    Examples:
        (code)
        ini1=
        (LTrim
            [vasara]
            tuni=1232
            edg=94545
            k=1
        )
        ini2=
        (LTrim
            [vasara]
            tuni=9999
            c=
            edg=5
            [taitos]
            isa=17
        )
        ini_mergeKeys(ini1, ini2)
        MsgBox %ini1%
        (end)
        *Output:*
        (code)
            [vasara]
            tuni=9999
            edg=5
            k1
            c=
            [taitos]
            isa=17
        (end)
    */
    ini_mergeKeys(ByRef _Content, ByRef _source, _updateMode = 1)
    {
        steps := 0
        laststep := 0
        destSectionNames := ini_getAllSectionNames(_Content), sourceSectionNames := ini_getAllSectionNames(_source)
        Loop, Parse, sourceSectionNames, `,
        {
            sectionName := A_LoopField
            sourceSection := ini_getSection(_source, sectionName)
            If sectionName Not In %destSectionNames%
            {
                _Content .= "`n" . sourceSection
                steps++
                Continue
            }
            Else
            {
                destSection := ini_getSection(_Content, sectionName), destKeyNames := ini_getAllKeyNames(destSection), sourceKeyNames := ini_getAllKeyNames(sourceSection)
                Loop, Parse, sourceKeyNames, `,
                {
                    keyName := A_LoopField
                    If keyName Not In %destKeyNames%
                    {
                        destSection .= "`n" . ini_getKey(sourceSection, sectionName, keyName)
                        steps++
                        Continue
                    }
                    Else If (_updateMode = 1)
                    {
                        ini_replaceValue(destSection, sectionName, keyName, ini_getValue(sourceSection, sectionName, keyName))
                        steps++
                    }
                    Else If (_updateMode = 2)
                    {
                        ini_replaceValue(destSection, sectionName, keyName, ini_getValue(destSection, sectionName, keyName) . ini_getValue(sourceSection, sectionName, keyName))
                        steps++
                    }
                    Else If (_updateMode = 3)
                    {
                        If ((sourceValue := ini_getValue(sourceSection, sectionName, keyName)) > ini_getValue(destSection, sectionName, keyName))
                        {
                            ini_replaceValue(destSection, sectionName, keyName, sourceValue)
                            steps++
                        }
                    }
                    Else If (_updateMode = 4)
                    {
                        ini_replaceKey(destSection, sectionName, keyName, "")
                        steps++
                    }
                }
                If (laststep != steps)
                {
                    laststep := steps
                    ini_replaceSection(_Content, sectionName, destSection)
                }
            }
        }
        If (steps > 0)
        {
            ErrorLevel := 0
        }
        Else
        {
            ErrorLevel := 1
        }
        Return steps
    }
    
    
    ; .............................................................................
    ; Group: Convert
    ;   Export and import functions to convert ini structure.
    ; .............................................................................
    
    
    /*
    Func: ini_exportToGlobals
        Creates global variables from the ini structure.
    Parameters:
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        CreateIndexVars - *Optional* If this is set to 'true', some additional 
                            variables are created. These are variables for indexed
                            access of sections and keys. The scheme how the variables
                            named are described below under Remarks.
        Prefix          - *Optional* This is the leading part of all created variable
                            names. (Default: "ini")
        Seperator       - *Optional* This is part of all created variable names. It
                            is added between every section and key part and the 
                            leading part to separate them. (Default: "_")
        SectionSpaces   - *Optional* Every space inside section name will be replaced
                            by this character or string. This is needed for creating
                            AutoHotkey variables, which cannot hold spaces at name.
                            Default is to delete any space with empty value: "".
        PreserveSpace   - *Optional* Should be set to 1 if spaces around the value 
                            of a key should be saved, otherwise they are lost.
                            Surrounding quotes (" or ') are also lost, if not set
                            to 1. Default is deleting surrounding spaces and quotes.
    Returns:
        Gets count of all created keys (attention, keys in sense of ini keys, not variables). 
    Remarks:
        Creates global variables from ini source. The scheme for building the variables is
        following: 
        
        > Prefix  +  Seperator  +  SectionName  + Seperator  +  KeyName
        >   ini   +      _      +      Tip      +     _      + TimeStamp
        > --------------------------------------------------------------
        > ini_Tip_TimeStamp := "20090716194758"
        
        Standard prefix to every variable is "ini" and all parts are delimited by the 
        separator "_". The SectionSpaces parameter deletes at default every space from 
        name of section, because spaces inside ahk variable names are not allowed.
    CreateIndexVars:    
        These variables are created additionally to the other variables, if option 
        CreateIndexVars is set to true (or 1 or any other value evaluating to true).
        
        Scheme for sections
        > Prefix  +  Seperator  +  Index
        >   ini   +      _      +    1
        > ------------------------------
        > ini_1 := "Tip"
        
        Scheme for keys
        > Prefix  +  Seperator  +  SectionName  + Index
        >   ini   +      _      +      Tip      +   1
        > ---------------------------------------------
        > ini_Tip1 := "20090716194758"
        
        The index "0" contains number of all elements.
    Examples:
        > ini_exportToGlobals(ini, 0)
        > ListVars
        > Msgbox % ini_RecentFileList_File2
        *Output:*
        > Z:\tempfile.tmp
        
        The example would create all these variables with following 
        values:
        > ini_RecentFileList_File1 := "F:\testfile.ahk"
        > ini_RecentFileList_File2 := "Z:\tempfile.tmp"
        > ini_Tip_TimeStamp := "20090716194758"
        
        These variables would be created in addition to the above ones, if 
        CreateIndexVars option was set to true:
        > ini_0 := "2"
        > ini_1 := "Tip"
        > ini_2 := "RecentFileList"
        > ini_RecentFileList0 := "2"
        > ini_RecentFileList1 := "File1"
        > ini_RecentFileList2 := "File2"
        > ini_Tip0 := "1"
        > ini_Tip1 := "TimeStamp"
    */
    ini_exportToGlobals(ByRef _Content, _CreateIndexVars = false, _Prefix = "ini", _Seperator = "_", _SectionSpaces = "", _PreserveSpace = False)
    {
        Global
        Local secCount := 0, keyCount := 0, i := 0, Section, Section1, currSection, Pair, Pair1, Pair2, FirstChar
        If (_Prefix != "")
        {
            _Prefix .= _Seperator
        }
        Loop, Parse, _Content, `n, `r
        {
            If (Not RegExMatch(A_LoopField, "`aiSm)\[\s*(.+?)\s*]", Section))
            {
                If (RegExMatch(A_LoopField, "`aiSm)\s*(\b(?:.+?|\s?)\b)\s*=(.*)", Pair))
                {
                    If (!_PreserveSpace)
                    {
                        StringReplace, Pair1, Pair1, %A_Space%, , All
                        Pair2 = %Pair2% ; Trim spaces.
                        FirstChar := SubStr(Pair2, 1, 1)
                        If (FirstChar = """" AND SubStr(Pair2, 0, 1)= """"
                            OR FirstChar = "'" AND SubStr(Pair2, 0, 1)= "'")
                        {
                            StringTrimLeft, Pair2, Pair2, 1
                            StringTrimRight, Pair2, Pair2, 1
                        }
                    }
                    StringReplace, currSection, currSection, %A_Space%, %_SectionSpaces%, All
                    %_Prefix%%currSection%%_Seperator%%Pair1% := Pair2 ; ini_section_key := value
                    keyCount++
                    If (_CreateIndexVars)
                    {
                        %_Prefix%%currSection%0++
                        i := %_Prefix%%currSection%0
                        %_Prefix%%currSection%%i% := Pair1
                    }
                }
            }
            Else
            {
                currSection := Section1
                If (_CreateIndexVars)
                {
                    StringReplace, currSection, currSection, %A_Space%, %_SectionSpaces%, All
                    secCount++
                    %_Prefix%%secCount% := currSection
                }
            }
        }
        If (_CreateIndexVars)
        {
            %_Prefix%0 := secCount
        }
        If (secCount = 0 AND keyCount = 0)
        {
            ErrorLevel = 1
        }
        Else
        {
            ErrorLevel = 0
        }
        Return keyCount
    }
    
    
    /*
    _______________________________________________________________________________
    _______________________________________________________________________________
    Section: Aliases
    About: About
    Brief:
        Function wrappers to work with existing commands or functions via "Basic 
        ini string functions". They try to mimic the interface for look and feel of
        original. This can help to migrate others to this library with lesser
        possible work.
    _______________________________________________________________________________
    _______________________________________________________________________________
    */
    
    ; .............................................................................
    ; Group: AutoHotkey
    ;   Built-in Commands of AutoHotkey.
    ; .............................................................................
    
    /*
    Func: Ini_Read
        Reads a value. Alias of IniRead.
    Parameters:
        OutputVar       - *Variable* The name of the variable in which to store the retrieved 
                            value. If the value cannot be retrieved, the variable 
                            is set to the value indicated by the Default parameter 
                            (described below). 
        Content         - *Variable* Content of an ini file (also this can be one 
                            section only).
        Section         - Unique name of the section.
        Key             - Name of the variable under the section.
        Default         - *Optional* The value to store in OutputVar if the 
                            requested key is not found. If omitted, it defaults to 
                            the word ERROR.
    Returns:
        Does not return anything.
        
    Remarks:
        ErrorLevel is not set by this function (backed up and restored).
        In Ahk you had to specify the filename of the ini file. Here you need to 
        give the content, instead of.
        Compared to "Basic ini string functions" the parameter section is not 
        allowed to be set to an empty string anymore.
    Related:
        * IniRead: [https://www.autohotkey.com/docs/commands/IniRead.htm]
        
    Examples:
        > FileRead, ini, C:\Temp\myfile.ini
        > Ini_Read(OutputVar, ini, "section2", "key")
        > MsgBox %OutputVar%
    */
    Ini_Read(ByRef _OutputVar, ByRef _Content, _Section, _Key, _Default = "ERROR")
    {
        If (_Section != "")
        {
            BackupErrorLevel := ErrorLevel
            _OutputVar := ini_getValue(_Content, _Section, _Key)
            If ErrorLevel
            {
                _OutputVar := _Default
            }
            ErrorLevel := BackupErrorLevel
        }
        Else
        {
            _OutputVar := _Default
        }
        Return 
    }
    
    
    /*
    Func: Ini_Write
        Writes a value. Alias of IniWrite.
    Parameters:
        Value           - The string or number that will be written to the right 
                            of Key's equal sign (=).
        Content         - *Variable* Content of an ini file .
        Section         - Unique name of the section.
        Key             - Name of the variable under the section.
    Returns:
        Does not return anything.
        
    Remarks:
        ErrorLevel is set to 1 if there was a problem or 0 otherwise.
        In Ahk you had to specify the filename of the ini file. Here you need to 
        give the content, instead of.
        Compared to "Basic ini string functions" the parameter section is not 
        allowed to be set to an empty string anymore.
    Related:
        * IniWrite: [https://www.autohotkey.com/docs/commands/IniWrite.htm]
        
    Examples:
        > FileRead, ini, C:\Temp\myfile.ini
        > Ini_Write("this is a new value", ini, "section2", "key")
        > FileDelete, C:\Temp\myfile.ini
        > FileAppend, %ini%, C:\Temp\myfile.ini
    */
    Ini_Write(_Value, ByRef _Content, _Section, _Key)
    {
        If (_Section = "")
        {
            ErrorLevel = 1
        }
        Else
        {
            ini_replaceValue(_Content, _Section, _Key, _Value)
        }
        Return 
    }
    
    
    /*
    Func: Ini_Delete
        Deletes a value or section. Alias of IniDelete.
    Parameters:
        Content         - *Variable* Content of an ini file.
        Section         - Unique name of the section.
        Key             - *Optional* Name of the variable under the section.
    Returns:
        Does not return anything.
        
    Remarks:
        ErrorLevel is set to 1 if there was a problem or 0 otherwise.
        In Ahk you had to specify the filename of the ini file. Here you need to 
        give the content, instead of.
        Compared to "Basic ini string functions" the parameter section is not 
        allowed to be set to an empty string anymore.
    Related:
        * IniDelete: [https://www.autohotkey.com/docs/commands/IniDelete.htm]
        
    Examples:
        > FileRead, ini, C:\Temp\myfile.ini
        > Ini_Delete(ini, "section2", "key")
        > FileDelete, C:\Temp\myfile.ini
        > FileAppend, %ini%, C:\Temp\myfile.ini
    */
    Ini_Delete(ByRef _Content, _Section, _Key = "")
    {
        If (_Section = "")
        {
            ErrorLevel = 1
        }
        Else
        {
            If (_Key != "")
            {
                ini_replaceKey(_Content, _Section, _Key, "")
            }
            Else
            {
                ini_replaceSection(_Content, _Section, "")
            }
        }
        Return 
    }
    1st window


    Hotkey Window


    Succesfull Saved


    Duplicated Hotkeys
    Last edited by wyvern1990; 06-30-2015 at 12:32 PM.

  2. #2
    zandar's Avatar
    Join Date
    Feb 2009
    Gender
    male
    Location
    At-Ghost
    Posts
    14
    Reputation
    10
    Thanks
    1
    My Mood
    Happy
    is this safe to use ? or not .

  3. #3
    BanWish's Avatar
    Join Date
    Jun 2015
    Gender
    male
    Posts
    21
    Reputation
    10
    Thanks
    0
    I'm using it and nothing yet. I would assume safe to use since it controls the mouse, it doesn't write to memory. having a little trouble trying to figure out burst fire though. once I get it, AN-94 will be lazor

  4. #4
    wyvern1990's Avatar
    Join Date
    Jun 2012
    Gender
    male
    Posts
    137
    Reputation
    10
    Thanks
    2,817
    Quote Originally Posted by BanWish View Post
    I'm using it and nothing yet. I would assume safe to use since it controls the mouse, it doesn't write to memory. having a little trouble trying to figure out burst fire though. once I get it, AN-94 will be lazor
    Burst fire will only shoot 3 or 5 shots, it all depends on the Sleep( Ms) between each shot. If your RPM does not match that of the weapon in game you can have an weird effect like shooting 4 or 2 times (depending on Sleep in Ms), as AN-94 only has 2 shots burst it will probably not add up. But you have the source so modify to your liking .

Similar Threads

  1. Anit Recoil Damper (XP+Vista)
    By TheKamikazes in forum Battlefield Heroes Hacks
    Replies: 8
    Last Post: 09-29-2009, 07:10 AM
  2. No Recoil Hack
    By quin123 in forum CounterStrike (CS) 1.6 Hacks / Counter Strike: Source (CSS) Hacks
    Replies: 9
    Last Post: 03-21-2007, 03:14 PM
  3. America's Army No Recoil/Reload LUA code.
    By MagikBullet in forum General Game Hacking
    Replies: 7
    Last Post: 02-25-2007, 10:11 AM
  4. No recoil hack????
    By max.here in forum WarRock - International Hacks
    Replies: 2
    Last Post: 02-21-2007, 05:52 AM
  5. No recoil/no spread addys?
    By IBEZ in forum WarRock - International Hacks
    Replies: 8
    Last Post: 01-14-2007, 08:39 PM