#NoTrayIcon #RequireAdmin #region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=launcher_128.ico #AutoIt3Wrapper_Compression=4 ;#AutoIt3Wrapper_Run_Obfuscator=y ;#Obfuscator_Parameters=/striponly #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #include #include #include #include #include #include #include #include #include #include #include _Singleton("7b9mzsl_lhrt", 0); This makes sure only one instance of the script is running at any given time. ;--- vvv --- Some global definitions. Global $title = "SWTOR & Ramdrive v0.6.1" Global $LauncherWindowDesc = "[TITLE:STAR WARS™: The Old Republic™; CLASS:SolidSkinnedWindow]" Global $ramdisk_drive, $robocopy_path, $swtor_path, $copy_swtor = 0, $copy_assets = 0, $copy_local = 0, $setup_ran = 0, $appdata_path = _SHGetSpecialFolderPath(28), $appdata_path_anon, $aIndvAssets ;--- ^^^ --- Some global definitions. ;--- vvv --- This is part of a safety mechanism. In case of a system crash while playing the game, the script can't restore the "swtor" directory to its original location. ; Instead, everything is restored after rebooting when Windows is running again. If $CmdLine[0] >= 1 Then If $CmdLine[1] = "restore" Then _get_script_config_from_file(); reads the script's configuration file and makes sure the settings contained in it are valid _exit(0) EndIf EndIf ; This is part of a safety mechanism. In case of a system crash while playing the game, the script can't restore the "swtor" directory to its original location. ;--- ^^^ --- Instead, everything is restored after rebooting when Windows is running again. _FileWriteLog(@ScriptDir & "\script.log", "-------------------- " & $title & " @ " & @OSVersion & " " & @OSArch & ", " & $appdata_path_anon & " --------------------") ;--- vvv --- Fetch update and info from the server. $aOnlineInfo = _getOnlineInfo() _FileWriteLog(@ScriptDir & "\script.log", "Time to get the messages from the server: " & $aOnlineInfo[0]) _check_update($aOnlineInfo[2]) _check_message($aOnlineInfo[1]) ;--- ^^^ --- Fetch update and info from the server. _check_settings(); Checks if the settings file is present; invokes setup if not. _get_script_config_from_file(); reads the script's configuration file and makes sure the settings contained in it are valid _FileWriteLog(@ScriptDir & "\script.log", "Script settings: " & $copy_swtor & ", " & $copy_assets & ", " & $copy_local) _verify_original_folders_presence(); make sure the original files and folders are in their original location _verify_ramdisk_presence(); ramdsk trial versions disable the corresponding ramdisk after a couple of weeks _get_script_config_from_file(); setup may have been invoked by the previous function where more than just the ramdisk drive letter may have been changed _check_filesystems(); Let's see if ramdisk and hard disk are using the NTFS file system _check_robocopy(); Robocopy is used to copy the files to the ramdisk, so we have to make sure it's there _check_robocopy_jobfile(); verifies the job file is present if the user has chosen to copy individual assets files to the ramdisk _check_ramdisk_size(); Checks if the ramdisk is big enough to store the files $time = _launcher(); Starting the launcher and checking its logs to see if patching / version checking has started, ended or if the user has quit the launcher _copy_to_ramdisk(); After patching is done and login is possible, we need to copy the necessary files to the ramdisk _check_files_on_ramdisk(); Making sure everything was copied to the ramdisk _make_links(); Preparing the junction(s) _enable_launcherwindow();At this point the script has finished all its copying, moving and linking. _wait_for_user_action($time); Everything is ready to go, so let's wait and see what the user does next. Func _enable_launcherwindow() _FileWriteLog(@ScriptDir & "\script.log", 'Enabling launcher window.') WinSetState($LauncherWindowDesc, "", @SW_ENABLE); this reenables the window. EndFunc ;==>_enable_launcherwindow Func _watch_local($game_quit = 0) If $copy_local = 1 Then RunWait(@ComSpec & " /c start /low /b " & $robocopy_path & ' ' & '"' & $ramdisk_drive & '\localswtor\."' & ' ' & '"' & $appdata_path & _ '\!back\swtor\." /e /xf DiskCacheStatic DiskCacheStream', @SystemDir, @SW_HIDE) If $game_quit = 0 Then Sleep(1000) EndIf If $copy_swtor = 1 Then RunWait(@ComSpec & " /c start /low /b " & $robocopy_path & ' ' & '"' & $ramdisk_drive & '\swtor\retailclient\swtor\logs\."' & ' ' & '"' & $swtor_path & _ '\!back\swtor\retailclient\swtor\logs\." /e', @SystemDir, @SW_HIDE) If $game_quit = 0 Then Sleep(1000) EndIf EndFunc ;==>_watch_local Func _start_launcher($launcher, $LauncherWindowDesc) Dim $szdrive, $szdir, $szfname, $szext $srun = $launcher $apath = _PathSplit($srun, $szdrive, $szdir, $szfname, $szext) Run($srun, $apath[1] & $apath[2]) Do Sleep(100) Until WinExists($LauncherWindowDesc) Sleep(2000) EndFunc ;==>_start_launcher Func _wait_logfile($logfile) Do Sleep(100) Until FileExists($logfile) EndFunc ;==>_wait_logfile Func _ReparsePoint($string) Local $FILE_ATTRIBUTE_REPARSE_POINT = 0x400 If Not FileExists($string) Then Return SetError(1, 0, '') EndIf $rc = DllCall('kernel32.dll', 'Int', 'GetFileAttributes', 'str', $string) If IsArray($rc) Then If BitAND($rc[0], $FILE_ATTRIBUTE_REPARSE_POINT) = $FILE_ATTRIBUTE_REPARSE_POINT Then Return True EndIf EndIf Return False EndFunc ;==>_ReparsePoint Func _prepare_runonce() If @Compiled = 1 Then FileCopy(@ScriptDir & "\" & @ScriptName, @TempDir, 1) FileCopy(@ScriptDir & "\" & "settings.ini", @TempDir, 1) $test = _StartupRegistry_Install(@ScriptName, @TempDir & "\" & @ScriptName & " restore", 1, 1) EndIf EndFunc ;==>_prepare_runonce Func _kill_runonce() If @Compiled = 1 Then _StartupRegistry_Uninstall(@ScriptName, @TempDir & "\" & @ScriptName & " restore", 1, 1) FileDelete(@TempDir & "\" & @ScriptName) FileDelete(@TempDir & "\" & "settings.ini") EndIf EndFunc ;==>_kill_runonce Func _exit($log = 1) If $copy_swtor = 1 Then _restore_swtor() EndIf If $copy_assets >= 1 Then _restore_assets() EndIf If $copy_local = 1 Then _restore_local_swtor() EndIf _kill_runonce() _FileWriteLog(@ScriptDir & "\script.log", "Bye.") Exit EndFunc ;==>_exit Func _setup() _FileWriteLog(@ScriptDir & "\script.log", "Showing script setup dialog.") Local $msg, $verify, $box1_status_old = 0, $box2_status_old = 0, $size_old = 0, $size_new = 0 Local $Form1 = GUICreate($title, 640, 635, -1, -1) Local $group1_y = 8 Local $Group1 = GUICtrlCreateGroup("Select ramdrive letter", 8, $group1_y, 625, 57) GUICtrlSetFont(-1, 8.5, 600) Local $g1label = GUICtrlCreateLabel('Ramdrive space required: ' & '0' & ' GB', 350, $group1_y + 26, 230, 20) Local $g1button_i = GUICtrlCreateButton("i", 615, $group1_y + 10, 14, 15) GUICtrlSetFont(-1, 7) Local $g1combo = GUICtrlCreateCombo("", 20, $group1_y + 22, 35) If ProcessExists("swtor.exe") Then GUICtrlSetState($g1combo, $GUI_DISABLE) EndIf Local $var = DriveGetDrive("all") GUICtrlSetTip($g1button_i, "click here for additional information") GUICtrlSetTip($g1combo, "click to select the ramdrive's drive letter") For $i = 1 To $var[0] GUICtrlSetData($g1combo, StringUpper($var[$i]), $var[1]) Next Local $group2_y = 90 Local $Group2 = GUICtrlCreateGroup("Select your Star Wars: The Old Republic installation folder", 8, $group2_y, 625, 100) GUICtrlSetFont(-1, 8.5, 600) Local $g2button_i = GUICtrlCreateButton("i", 615, $group2_y + 10, 14, 15) GUICtrlSetFont(-1, 7) Local $g2button_more = GUICtrlCreateButton("...", 20, $group2_y + 25, 30, 20) If ProcessExists("swtor.exe") Then GUICtrlSetState($g2button_more, $GUI_DISABLE) EndIf Local $g2input = GUICtrlCreateInput("", 20, $group2_y + 65, 600, 20) GUICtrlSetTip($g2button_i, "click here for additional information") GUICtrlSetTip($g2button_more, 'click to select "Star Wars: The Old Republic" installation folder') GUICtrlSetTip($g2input, "shows the path once it was selected") Local $group4_y = 215 Local $Group4 = GUICtrlCreateGroup('"swtor" subdirectory processing settings', 8, $group4_y, 625, 70) GUICtrlSetFont(-1, 8.5, 600) Local $g4check = GUICtrlCreateCheckbox('Copy whole "swtor" subdirectory to your ramdrive (contains area cache file)?', 20, $group4_y + 35, 600, 20) Local $g4button_i = GUICtrlCreateButton("i", 615, $group4_y + 10, 14, 15) GUICtrlSetFont(-1, 7) GUICtrlSetTip($g4button_i, "click here for additional information") GUICtrlSetTip($g4check, 'check this box to have the "swtor" subdirectory cached on the ramdrive') Local $group5_y = 310 Local $Group5 = GUICtrlCreateGroup('"local\swtor" subdirectory processing settings', 8, $group5_y, 625, 70) GUICtrlSetFont(-1, 8.5, 600) Local $g5button_i = GUICtrlCreateButton("i", 615, $group5_y + 10, 14, 15) GUICtrlSetFont(-1, 7) Local $g5check = GUICtrlCreateCheckbox('Copy whole "local\swtor" subdirectory to your ramdrive (contains static and stream cache files)?', 20, $group5_y + 35, 600, 20) GUICtrlSetTip($g5button_i, "click here for additional information") GUICtrlSetTip($g5check, 'check this box to have the "local\swtor" subdirectory cached on the ramdrive') Local $group3_y = 410 Local $Group3 = GUICtrlCreateGroup('"assets" subdirectory processing', 8, $group3_y, 625, 160) GUICtrlSetFont(-1, 8.5, 600) Local $g3button_i = GUICtrlCreateButton("i", 615, $group3_y + 10, 14, 15) GUICtrlSetFont(-1, 7) Local $g3check = GUICtrlCreateCheckbox('Copy whole "assets" subdirectory to your ramdrive?', 20, $group3_y + 35, 300, 20) ;Local $g3label = GuiCtrlCreateLabel('Current size of the "assets" folder: ' & round(DirGetSize("D:\Spiele Installationen MMO\Star Wars - The Old Republic\assets\") / (1024 ^ 3), 2) & " GB", 350, $group3_y + 38, 230, 20) _horizontalSeparator(20, $group3_y + 73, 600) Local $g3check_2 = GUICtrlCreateCheckbox('Copy individual "assets" files to your ramdrive?', 20, $group3_y + 95, 270, 20) ;Local $g3label_2 = GuiCtrlCreateLabel('Current size of your selected "assets" files: ' & "0" & " GB", 310, $group3_y + 98, 300, 20) Local $g3button_more = GUICtrlCreateButton("...", 18, $group3_y + 125, 30, 20) GUICtrlCreateLabel('Select individual "assets" files.', 50, $group3_y + 129, 500, 20) GUICtrlSetTip($g3button_i, "click here for additional information") GUICtrlSetTip($g3check, 'check this box to have the whole "assets" subdirectory cached on the ramdrive or select individual files via the button below') GUICtrlSetTip($g3button_more, 'click here to select individual files or check the box above to have the whole "assets" subdirectory cached on the ramdrive') If @OSVersion = "WIN_2003" Or @OSVersion = "WIN_XP" Or @OSVersion = "WIN_XPe" Or @OSVersion = "WIN_2000" Then If $copy_assets = 2 Then $copy_assets = 0 GUICtrlCreateLabel('This feature is unsupported by Windows XP and older Windows versions.', 275, $group3_y + 113, 350, 20) GUICtrlSetState($g3button_more, $GUI_DISABLE) GUICtrlSetState($g3check_2, $GUI_DISABLE) EndIf Local $bottom_y = 590 Local $bottomOk = GUICtrlCreateButton("Save and Exit", 100, $bottom_y, 137, 25) GUICtrlSetState($bottomOk, $GUI_DISABLE) Local $bottomCancel = GUICtrlCreateButton("Cancel", 400, $bottom_y, 137, 25) GUICtrlSetTip($bottomCancel, 'click here to abort without saving the settings and return to normal script operation') GUICtrlSetTip($bottomOk, 'click here to save the settings and return to normal script operation') If Not ($ramdisk_drive = "") And Not ($ramdisk_drive = -1) Then For $i = 1 To $var[0] If StringLower($var[$i]) = StringLower($ramdisk_drive) Then _GUICtrlComboBox_SetCurSel($g1combo, $i - 1) ExitLoop EndIf Next EndIf If Not ($swtor_path = "") And Not ($swtor_path = -1) Then GUICtrlSetData($g2input, $swtor_path) GUICtrlSetState($bottomOk, $GUI_ENABLE) EndIf If Not ($copy_swtor = -1) And Not ($copy_swtor = 0) Then $bla = GUICtrlSetState($g4check, $GUI_CHECKED) EndIf If $copy_assets = 1 Then GUICtrlSetState($g3check, $GUI_CHECKED) GUICtrlSetState($g3check_2, $GUI_UNCHECKED) EndIf If $copy_assets = 2 Then GUICtrlSetState($g3check, $GUI_UNCHECKED) GUICtrlSetState($g3check_2, $GUI_CHECKED) EndIf If Not ($copy_local = -1) And Not ($copy_local = 0) Then GUICtrlSetState($g5check, $GUI_CHECKED) EndIf GUISetState() Local $dis = 0 Local $size_assets = DirGetSize($swtor_path & "\assets\") While 1 $size_new = 0 If GUICtrlRead($g5check) = $GUI_CHECKED Then $size_new += 104857600; local EndIf If GUICtrlRead($g4check) = $GUI_CHECKED Then $size_new += 1395864371.2; swtor EndIf If GUICtrlRead($g3check) = $GUI_CHECKED And GUICtrlRead($g3check_2) = $GUI_UNCHECKED Then $size_new += $size_assets EndIf If GUICtrlRead($g3check_2) = $GUI_CHECKED And GUICtrlRead($g3check) = $GUI_UNCHECKED Then If IsArray($aIndvAssets) Then If Not ($aIndvAssets[0][0] = 0) Then For $i = 1 To $aIndvAssets[0][0] $size_new += FileGetSize($swtor_path & "\assets\" & $aIndvAssets[$i][1]) Next EndIf EndIf EndIf $size_new = Round($size_new / (1024 ^ 3), 2) If Not ($size_old = $size_new) Then $size_old = $size_new GUICtrlSetData($g1label, 'Ramdrive space required: ' & $size_new & ' GB') EndIf $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE GUIDelete($Form1) Return (-1) Case $msg = $g2button_more $swtor_path = FileSelectFolder("Choose your Star Wars: The Old Republic installation folder.", "") If Not ($swtor_path = -1) Then GUICtrlSetData($g2input, $swtor_path) $verify = _verify($swtor_path) If $verify = 0 Then MsgBox(48, "SWTOR & Ramdrive", $swtor_path & @CRLF & @CRLF & "does not appear to be the correct directory." & @CRLF & 'Please make sure you select the directory that contains the "swtor" subdirectory.' & @CRLF & @CRLF & 'Do not select the "swtor" subdirectory itself.') Else $size_assets = DirGetSize($swtor_path & "\assets\") GUICtrlSetState($bottomOk, $GUI_ENABLE) If Not (@OSVersion = "WIN_2003") And Not (@OSVersion = "WIN_XP") And Not (@OSVersion = "WIN_XPe") And Not (@OSVersion = "WIN_2000") Then GUICtrlSetState($g3button_more, $GUI_ENABLE) GUICtrlSetState($g3check_2, $GUI_ENABLE) EndIf EndIf EndIf Case $msg = $bottomOk If GUICtrlRead($g3check) = $GUI_CHECKED And GUICtrlRead($g3check_2) = $GUI_UNCHECKED Then $copy_assets = 1 EndIf If GUICtrlRead($g3check_2) = $GUI_CHECKED And GUICtrlRead($g3check) = $GUI_UNCHECKED Then If IsArray($aIndvAssets) Then If Not ($aIndvAssets[0][0] = 0) Then $copy_assets = 2 Else $copy_assets = 0 EndIf EndIf EndIf If GUICtrlRead($g3check) = $GUI_UNCHECKED And GUICtrlRead($g3check_2) = $GUI_UNCHECKED Then $copy_assets = 0 EndIf If GUICtrlRead($g4check) = 4 Then $copy_swtor = 0 Else $copy_swtor = 1 EndIf If GUICtrlRead($g5check) = 4 Then $copy_local = 0 Else $copy_local = 1 EndIf $ramdisk_drive = GUICtrlRead($g1combo) _save() GUIDelete($Form1) _check_ramdisk_size() ExitLoop Case $msg = $bottomCancel GUIDelete($Form1) If $copy_assets = 0 And $copy_local = 0 And $copy_swtor = 0 Then Exit Else Return (-1) EndIf Case $msg = $g3button_more GUISetState(@SW_DISABLE, $Form1) GUISetState(@SW_HIDE, $Form1) _assets_GUI() If IsArray($aIndvAssets) Then GUICtrlSetState($g3check_2, $GUI_CHECKED) GUICtrlSetState($g3check, $GUI_UNCHECKED) _make_rc_jobfile() EndIf GUISetState(@SW_SHOW, $Form1) GUISetState(@SW_ENABLE, $Form1) Case $msg = $g1button_i GUISetState(@SW_DISABLE, $Form1) MsgBox(64, $title, "You need to specify the drive letter assigned to your ramdrive." & @CRLF & @CRLF & "If you don't know that drive letter, check your ramdrive " & _ "configuration tool." & @CRLF & @CRLF & "A ramdrive is needed so the script can store parts of the game in your system's main memory, aka RAM. This will help " & _ "to improve loading times when visiting planets, entering phases, your ship, or when entering space battle.") GUISetState(@SW_ENABLE, $Form1) WinActivate($Form1) Case $msg = $g2button_i GUISetState(@SW_DISABLE, $Form1) MsgBox(64, $title, 'You need to pick the "Star Wars: The Old Republic" installation folder; the folder where you installed the game to.' & @CRLF & @CRLF & _ "This is needed so the script knows where all the files it can process are located.") GUISetState(@SW_ENABLE, $Form1) WinActivate($Form1) Case $msg = $g3button_i GUISetState(@SW_DISABLE, $Form1) MsgBox(64, $title, 'Major performance boost.' & @CRLF & @CRLF & _ 'The "assets" subdirectory contains all of the ' & "game's data files like textures, sounds, map data and things like that." & @CRLF & _ @CRLF & "If you have a big enough ramdrive, you can select to copy the whole " & '"assets"' & " folder to it. You can also select individual files " & _ "if your ramdrive is too small for the whole" & '"assets" folder or you know where your character is and that you won' & "'t visit other places." & @CRLF & @CRLF & _ "While you may spend 2 to 4 minutes (depending on the actual speed of your hard disk) waiting for the script to finish copying all the data to your ramdrive, " & _ "you'll get that time back after a couple of loading processes and start to make good after that.") GUISetState(@SW_ENABLE, $Form1) WinActivate($Form1) Case $msg = $g4button_i GUISetState(@SW_DISABLE, $Form1) MsgBox(64, $title, 'Medium performance boost.' & @CRLF & @CRLF & _ 'The "swtor" subdirectory contains an area cache file. This file is used by the game to cache the data of your current area, like textures, sounds and map data.' & _ @CRLF & @CRLF & "The purpose of that file is not yet fully understood. Since it is deleted when exiting the game, it cannot be used to get into the game " & _ "again quicker to continue your journey." & @CRLF & @CRLF & "Whenever the game is loading something, at the same time it takes that data and stores " & _ "it in the cache file. This results in the hard disk having to do two things simultaneously: Reading and writing data. Since hard disks still don't " & _ "handle reading and writing data at the same time very well, the performance of both reading and writing data is reduced, making each process take longer " & _ "to complete than when just reading or just writing data." & @CRLF & @CRLF & "By placing the " & '"assets"' & " folder and the cache file along with it onto " & _ "the ramdrive, the script allows the hard disk to focus solely on loading game data thus speeding up the process.") GUISetState(@SW_ENABLE, $Form1) WinActivate($Form1) Case $msg = $g5button_i GUISetState(@SW_DISABLE, $Form1) MsgBox(64, $title, 'Minor performance boost.' & @CRLF & @CRLF & _ 'The "local\swtor" folder contains cache files for smaller amounts of data.' & @CRLF & @CRLF & _ "Putting these onto the ramdrive as well can have a smaller positive effect on loading times.") GUISetState(@SW_ENABLE, $Form1) WinActivate($Form1) EndSelect If Not ($swtor_path = -1) Then If Not (GUICtrlRead($g2input) = $swtor_path) Then GUICtrlSetData($g2input, $swtor_path) EndIf EndIf If GUICtrlRead($g3check) = $GUI_CHECKED And $box1_status_old = 0 Then $box1_status_old = 1 $box2_status_old = 0 GUICtrlSetState($g3check_2, $GUI_UNCHECKED) EndIf If GUICtrlRead($g3check_2) = $GUI_CHECKED And $box2_status_old = 0 Then $box1_status_old = 0 $box2_status_old = 1 GUICtrlSetState($g3check, $GUI_UNCHECKED) If Not IsArray($aIndvAssets) Then GUISetState(@SW_DISABLE, $Form1) GUISetState(@SW_HIDE, $Form1) _assets_GUI() GUISetState(@SW_SHOW, $Form1) GUISetState(@SW_ENABLE, $Form1) EndIf EndIf WEnd EndFunc ;==>_setup Func _horizontalSeparator($x, $y, $w) GUICtrlCreateLabel("", $x, $y, $w, 1) GUICtrlSetBkColor(-1, 0xd5dfe5) GUICtrlCreateLabel("", $x, $y + 1, $w, 1) GUICtrlSetBkColor(-1, 0xffffff) EndFunc ;==>_horizontalSeparator Func _saveIndvAssets($aInput) Local $string For $i = 1 To $aInput[0] $string &= $aInput[$i] & @LF Next IniWriteSection(@ScriptDir & "\settings.ini", "individual assets", $string) EndFunc ;==>_saveIndvAssets Func _assets_gui() Local $aFiles[1][3] = [[0, 0, 0]] Local $count = 0, $start = 0, $gap = 20, $pos Local $Form2 = GUICreate('Select individual "assets" files to be copied to your ramdrive.', 325, 350, -1, -1, 0, 0) Local $cForm2 = GUICreate("Child GUI", 295, 200, 10, 60, $WS_CHILD, $WS_EX_CLIENTEDGE, $Form2) Local $file = FileFindFirstFile($swtor_path & "\assets\*.*") While 1 Local $filename = FileFindNextFile($file) If @error Then ExitLoop If Not (StringRight($filename, 4) = ".txt") Then $count += 1 ReDim $aFiles[UBound($aFiles) + 1][3] $aFiles[$count][0] = $filename EndIf WEnd $aFiles[0][0] = UBound($aFiles) - 1 For $i = 1 To $aFiles[0][0] $pos = $start + ($gap * ($i - 1)) $aFiles[$i][2] = GUICtrlCreateCheckbox($aFiles[$i][0], 3, $pos, 501, 20) Next GUIRegisterMsg($WM_SIZE, "WM_SIZE") GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL") GUISetState() _GUIScrollBars_Init($cForm2, 0, ($aFiles[0][0] + ($aFiles[0][0] / 7))) GUISwitch($Form2) Local $Form2Button1 = GUICtrlCreateButton("Save and Return", 10, 280, 137, 25) Local $Form2Button2 = GUICtrlCreateButton("Cancel", 170, 280, 137, 25) Local $Form2Button3 = GUICtrlCreateButton("Check all", 30, 22, 100, 20) Local $Form2Button4 = GUICtrlCreateButton("Uncheck all", 190, 22, 100, 20) If IsArray($aIndvAssets) Then For $i1 = 1 To $aIndvAssets[0][0] For $i2 = 1 To $aFiles[0][0] If $aIndvAssets[$i1][1] = $aFiles[$i2][0] Then GUICtrlSetState($aFiles[$i2][2], $GUI_CHECKED) ExitLoop EndIf Next Next EndIf GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $Form2Button3 For $i2 = 1 To $aFiles[0][0] GUICtrlSetState($aFiles[$i2][2], $GUI_CHECKED) Next Case $msg = $Form2Button4 For $i2 = 1 To $aFiles[0][0] GUICtrlSetState($aFiles[$i2][2], $GUI_UNCHECKED) Next Case $msg = $Form2Button1 Dim $aIndvAssets[1][2] = [[0, 0]] $count = 0 For $i = 1 To $aFiles[0][0] If Not (GUICtrlRead($aFiles[$i][2]) = 4) Then $count += 1 ReDim $aIndvAssets[$count + 1][2] $aIndvAssets[$count][0] = $count $aIndvAssets[$count][1] = $aFiles[$i][0] EndIf Next $aIndvAssets[0][0] = UBound($aIndvAssets) - 1 GUIDelete($cForm2) GUIDelete($Form2) Return Case $msg = $Form2Button2 GUIDelete($cForm2) GUIDelete($Form2) Return -1 EndSelect WEnd EndFunc ;==>_assets_gui Func _make_rc_jobfile() $file = FileOpen(@ScriptDir & "\swtorcopyjob.rcj", 2) FileWrite($file, "/SD:" & $swtor_path & "\assets\" & @CRLF) FileWrite($file, "/DD:" & $ramdisk_drive & "\assets\." & @CRLF) FileWrite($file, "/IF" & @CRLF) For $i = 1 To $aIndvAssets[0][0] FileWrite($file, @TAB & $aIndvAssets[$i][1] & @CRLF) Next FileWrite($file, "/COPY:DAT" & @CRLF) FileWrite($file, "/R:1000000" & @CRLF) FileWrite($file, "/W:30" & @CRLF) FileClose($file) EndFunc ;==>_make_rc_jobfile Func _read_rc_jobfile_files() Dim $aFiles[1] = [0] $file = FileOpen(@ScriptDir & "\swtorcopyjob.rcj", 0) $content = FileRead($file) FileClose($file) $content = StringReplace($content, @CRLF, "|") $regex = StringRegExp($content, "(?i)(?s)(?U)/if(.*)(?:/|\z)", 1) If IsArray($regex) Then $split = StringSplit($regex[0], "|") For $i = 1 To $split[0] If StringLen($split[$i]) >= 1 Then _ArrayAdd($aFiles, StringStripWS($split[$i], 8)) EndIf Next $aFiles[0] = UBound($aFiles) - 1 Return ($aFiles) EndIf Return (0) EndFunc ;==>_read_rc_jobfile_files Func _save() IniWrite(@ScriptDir & "\settings.ini", "ramdisk drive letter", "letter", $ramdisk_drive) IniWrite(@ScriptDir & "\settings.ini", "swtor installation path", "path", $swtor_path) IniWrite(@ScriptDir & "\settings.ini", "copy settings", "assets", $copy_assets) IniWrite(@ScriptDir & "\settings.ini", "copy settings", "swtor", $copy_swtor) IniWrite(@ScriptDir & "\settings.ini", "copy settings", "local swtor", $copy_local) If $copy_assets = 2 Then IniWriteSection(@ScriptDir & "\settings.ini", "individual assets", $aIndvAssets) _make_rc_jobfile() Else FileDelete(@ScriptDir & "\swtorcopyjob.rcj") EndIf EndFunc ;==>_save Func _verify($input) If Not FileExists($input & "\swtor") Then Return (0) Else Return (1) EndIf EndFunc ;==>_verify Func _getOnlineInfo() Local $info_done = 0 Local $changelog_done = 0 Dim $aCI[3] = [2, 0, 0] HttpSetUserAgent("Mozilla") Local $info = InetGet("http://lbsoftware.bplaced.net/info.html", @ScriptDir & "\temp_i.tmp", 1, 1) Local $changelog = InetGet("http://lbsoftware.bplaced.net/changelog.html", @ScriptDir & "\temp_c.tmp", 1, 1) $begin = TimerInit() While 1 Sleep(100) If InetGetInfo($info, 2) Then $info_done = 1 EndIf If InetGetInfo($changelog, 2) Then $changelog_done = 1 EndIf If $info_done = 1 Then InetClose($info) $file_i = FileOpen(@ScriptDir & "\temp_i.tmp", 0) $info = FileRead($file_i) FileClose($file_i) $aCI[1] = $info EndIf If $changelog_done = 1 Then InetClose($changelog) $file_c = FileOpen(@ScriptDir & "\temp_c.tmp", 0) $changelog = FileRead($file_c) FileClose($file_c) $aCI[2] = $changelog EndIf If $changelog_done = 1 And $info_done = 1 Then $aCI[0] = TimerDiff($begin) FileDelete(@ScriptDir & "\temp_i.tmp") FileDelete(@ScriptDir & "\temp_c.tmp") Return ($aCI) EndIf If TimerDiff($begin) >= 5000 Then If Not ($info_done = 1) Then InetClose($info) FileDelete(@ScriptDir & "\temp_i.tmp") EndIf If Not ($changelog_done = 1) Then InetClose($changelog) FileDelete(@ScriptDir & "\temp_c.tmp") EndIf $aCI[0] = "timeout" Return ($aCI) EndIf WEnd EndFunc ;==>_getOnlineInfo Func _check_update($changelog) Local $mandatory = 0 $remote_version = StringRegExp($changelog, "(?i)v(.*\d).*", 2); grab version information from the downloaded changelog $local_version = StringRegExp($title, "(?i:).*v(.*)", 1); grab version number from the title of the current script ;_arraydisplay($remote_version) ;_arraydisplay($local_version) If IsArray($remote_version) And IsArray($local_version) Then If Not ($local_version[0] = $remote_version[1]) Then; compare both version numbers; if they don't match ... If StringInStr($remote_version[0], "mandatory", 0) Then; check if it's a very important update $mandatory = 1; set "very important update" flag EndIf $oIE = _IECreateEmbedded(); creates a webbrower object so the script can show html content $updateinformer = GUICreate($title & " Update", 620, 510, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN); create a GUI If $mandatory = 1 Then GUICtrlCreateLabel("Mandatory update found. You have to update to the new version. See below for details.", 10, 18, 600, 20); create a label showing the ... Else GUICtrlCreateLabel("Update found. See below for details.", 10, 18, 600, 20); severity of the update EndIf GUICtrlSetFont(-1, 8.5, 600); modifying the look of the font GUICtrlCreateObj($oIE, 10, 50, 600, 360); puts the webbrowser object into the GUI _IENavigate($oIE, "about:blank"); navigates to a blank page _IEDocWriteHTML($oIE, $changelog); puts the previously downloaded changelog into the webbrowser object so the user can see it on the screen GUICtrlCreateLabel("Start download using your default web browser?", 10, 420, 290, 20); explaining what the buttons below do GUICtrlSetFont(-1, 8.5, 600); modifying the look of the font $button_y = GUICtrlCreateButton("Yes", 150, 460, 100, 30); creates the yes button If $mandatory = 1 Then; if the update is very important... $button_n = GUICtrlCreateButton("Exit", 370, 460, 100, 30); ... user can't be allowed to continue using the old script. It most likely wouldn't work anymore anyway Else $button_n = GUICtrlCreateButton("No", 370, 460, 100, 30); if the update isn't important, the user can continue using the old script EndIf GUISetState(); actually makes the GUI visible While 1; waiting for user action $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE; if the window's "X" button was clicked... Exit; exit the script Case $msg = $button_n; if the "no" / "exit" button was clicked... If $mandatory = 1 Then; ... and the update was mandatory GUIDelete($updateinformer); remove the GUI from screen Exit; exit the script Else; if the update wasn't mandatory... GUIDelete($updateinformer); remove the GUI from screen Return (0); continue running the script EndIf Case $msg = $button_y; if the "yes" button was clicked... GUIDelete($updateinformer); ... remove the GUI from screen ... ShellExecute("http://lbsoftware.bplaced.net/SWTOR_Ramdrive_v" & $remote_version[1] & ".zip"); ... and open the link to the new script using whatever is ; registered as the system default program for opening links Exit; exit the script (user should have his browser's download dialog on screen really soon if not already) EndSelect WEnd EndIf EndIf EndFunc ;==>_check_update Func _check_message($info) Local $aInfo If Not ($info = "") Then; if the info found wasn't empty; in human terms: if there's a message $infohash = _Crypt_HashData($info, $CALG_MD5); take a "fingerprint" of that message _FileReadToArray(@ScriptDir & "\info history.dat", $aInfo); try opening message "fingerprint" history If IsArray($aInfo) Then; if successful; in human terms: if we had a "fingerprint" history to open, meaning this isn't the first time a message was found on the server For $i = 1 To $aInfo[0]; search the fingerprint database to see if this exact same message was already displayed before If $aInfo[$i] = $infohash Then; if it was Return (0); end function; no need to bother the user with anything EndIf Next EndIf ; at this point we've ensured that a) there's a message on the server ; - and - ; b) that message was never displayed before $file = FileOpen(@ScriptDir & "\info history.dat", 1); open fingerprint history database so we can write to it FileWriteLine($file, "0x" & Hex($infohash)); write the fingerprint to the file FileClose($file); close the file $oIE = _IECreateEmbedded(); creates a webbrower object so the script can show html content $infoinformer = GUICreate($title & " Message", 620, 510, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN); create a GUI GUICtrlSetFont(-1, 8.5, 600); modifying the look of the font GUICtrlCreateObj($oIE, 10, 50, 600, 360); puts the webbrowser object into the GUI _IENavigate($oIE, "about:blank"); navigates to a blank page _IEDocWriteHTML($oIE, $info); puts the previously downloaded info into the webbrowser object so the user can see it on the screen $button_ok = GUICtrlCreateButton("Ok", 250, 445, 100, 30); creates the yes button GUISetState(); actually makes the GUI visible While 1; waiting for user action $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE; if the window's "X" button was clicked... GUIDelete($infoinformer); remove the GUI from screen Return (0); close the message window but continue running the script Case $msg = $button_ok; if the "ok" button was clicked... GUIDelete($infoinformer); remove the GUI from screen Return (0); close the message window but continue running the script EndSelect WEnd EndIf EndFunc ;==>_check_message ; #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 ; #INDEX# ======================================================================================================================= ; Title .........: _Startup ; AutoIt Version : v3.2.12.1 or higher ; Language ......: English ; Description ...: Create Startup entries in the startup folder or registry. The registry entries can be Run all the time (Run registry entry) or only once (RunOnce registry entry.) ; Note ..........: ; Author(s) .....: guinness ; Remarks .......: Special thanks to KaFu for EnumRegKeys2Array() which I used as inspiration for enumerating the Registry Keys. ; =============================================================================================================================== ; #INCLUDES# ========================================================================================================= ; None ; #GLOBAL VARIABLES# ================================================================================================= ; None ; #CURRENT# ===================================================================================================================== ; _StartupFolder_Install: Creates a Shortcut in the 'All Users/Current Users' startup folder. ; _StartupFolder_Uninstall: Deletes the Shortcut in the 'All Users/Current Users' startup folder. ; _StartupRegistry_Install: Creates an entry in the 'All Users/Current Users' registry. ; _StartupRegistry_Uninstall: Deletes the entry in the 'All Users/Current Users' registry. ; =============================================================================================================================== ; #INTERNAL_USE_ONLY#============================================================================================================ ; None ; =============================================================================================================================== ; #FUNCTION# ========================================================================================================= ; Name...........: _StartupFolder_Install() ; Description ...: Creates a Shortcut in the 'All Users/Current Users' startup folder. ; Syntax.........: _StartupFolder_Install([$sName = @ScriptName, [$sFilePath = @ScriptFullPath, [$iAllUsers = 0]]]) ; Parameters ....: $sName - [Optional] Name of the program. [Default = Script name.] ; $sFilePath - [Optional] Location of the program executable. [Default = Full script location.] ; $sCommandline - [Optional] Commandline arguments to be passed to the application. [Default = None.] ; $iAllUsers - [Optional] Add to Current Users (0) or All Users (1). [Default = 0 - Current user.] ; Requirement(s).: v3.2.12.1 or higher ; Return values .: Success - FileCreateShortcut() Return code. ; Failure - Returns 0 & sets @error = 1 ; Author ........: guinness ; Example........; Yes ;===================================================================================================================== Func _StartupFolder_Install($sName = @ScriptName, $sFilePath = @ScriptFullPath, $sCommandline = "", $iAllUsers = 0) Local $sStartup = "" $sName = StringReplace($sName, ".exe", "") If $sName = "" Or $sFilePath = "" Then Return SetError(1, 0, 0) EndIf _StartupFolder_Uninstall($sName, $sFilePath, $iAllUsers) ; Deletes The Shortcut In The 'All Users/Current Users' startup folder. If $iAllUsers Then $sStartup = @StartupCommonDir & "\" Else $sStartup = @StartupDir & "\" EndIf Return FileCreateShortcut($sFilePath, $sStartup & $sName & ".lnk", $sStartup, $sCommandline) EndFunc ;==>_StartupFolder_Install ; #FUNCTION# ========================================================================================================= ; Name...........: _StartupFolder_Uninstall() ; Description ...: Deletes the Shortcut in the 'All Users/Current Users' startup folder. ; Syntax.........: _StartupFolder_Uninstall([$sName = @ScriptName, [$sFilePath = @ScriptFullPath, [$iAllUsers = 0]]]) ; Parameters ....: $sName - [Optional] Name of the program. [Default = Script name.] ; $sFilePath - [Optional] Location of the program executable. [Default = Full script location.] ; $iAllUsers - [Optional] Was it Added to Current Users (0) or All Users (1). [Default = 0 - Current user] ; Requirement(s).: v3.2.12.1 or higher ; Return values .: Success - FileClose() Return code. ; Failure - Returns 0 & sets @error = 1 ; Author ........: guinness ; Example........; Yes ;===================================================================================================================== Func _StartupFolder_Uninstall($sName = @ScriptName, $sFilePath = @ScriptFullPath, $iAllUsers = 0) Local $aFileGetShortcut, $hSearch, $iStringLen = 0, $sFile, $sStartup = "" $sName = StringReplace($sName, ".exe", "") If $sName = "" Or $sFilePath = "" Then Return SetError(1, 0, 0) EndIf $iStringLen = StringLen($sName) If $iAllUsers Then $sStartup = @StartupCommonDir & "\" Else $sStartup = @StartupDir & "\" EndIf $hSearch = FileFindFirstFile($sStartup & "*.lnk") If $hSearch = -1 Then Return SetError(2, 0, 0) EndIf While 1 $sFile = FileFindNextFile($hSearch) If @error Then ExitLoop EndIf If StringLeft($sFile, $iStringLen) = $sName Then $aFileGetShortcut = FileGetShortcut($sStartup & $sFile) If @error Then ContinueLoop EndIf If $aFileGetShortcut[0] = $sFilePath Then FileDelete($sStartup & $sFile) EndIf EndIf WEnd Return FileClose($hSearch) EndFunc ;==>_StartupFolder_Uninstall ; #FUNCTION# ========================================================================================================= ; Name...........: _StartupRegistry_Install() ; Description ...: Creates an entry in the 'All Users/Current Users' registry. ; Syntax.........: _StartupRegistry_Install([$sName = @ScriptName, [$sFilePath = @ScriptFullPath, [$iAllUsers = 0, [$iRunOnce = 0]]]]) ; Parameters ....: $sName - [Optional] Name of the program. [Default = Script name] ; $sFilePath - [Optional] Location of the program executable. [Default = Full script location] ; $iAllUsers - [Optional] Add to Current Users (0) or All Users (1). [Default = 0 - Current user] ; $iRunOnce - [Optional] Always Run at System Startup (0) or Run only once (1)l [Default = 0 - Always run at system startup.] ; Requirement(s).: v3.2.12.1 or higher ; Return values .: Success - RegWrite() Return code. ; Failure - Returns 0 & sets @error = 1 ; Author ........: guinness ; Example........; Yes ;===================================================================================================================== Func _StartupRegistry_Install($sName = @ScriptName, $sFilePath = @ScriptFullPath, $iAllUsers = 0, $iRunOnce = 0) Local $i64Bit = "", $sRegistryKey, $sRunOnce = "" _StartupRegistry_Uninstall($sName, $sFilePath, $iAllUsers, $iRunOnce) ; Deletes The Entry In The 'All Users/Current Users' Registry. $sName = StringLower(StringReplace($sName, ".exe", "")) If $sName = "" Or $sFilePath = "" Then Return SetError(1, 0, 0) EndIf If $iRunOnce Then $sRunOnce = "Once" EndIf If @OSArch = "X64" Then $i64Bit = "64" EndIf If $iAllUsers Then $sRegistryKey = "HKEY_LOCAL_MACHINE" & $i64Bit & "\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" & $sRunOnce & "\" Else $sRegistryKey = "HKEY_CURRENT_USER" & $i64Bit & "\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" & $sRunOnce & "\" EndIf Return RegWrite($sRegistryKey, $sName, "REG_SZ", $sFilePath) EndFunc ;==>_StartupRegistry_Install ; #FUNCTION# ========================================================================================================= ; Name...........: _StartupRegistry_Uninstall() ; Description ...: Deletes the entry in the 'All Users/Current Users' registry. ; Syntax.........: _StartupRegistry_Uninstall([$sName = @ScriptName, [$sFilePath = @ScriptFullPath, [$iAllUsers = 0, [$iRunOnce = 0]]]]) ; Parameters ....: $sName - [Optional] Name of the program. [Default = Script name.] ; $sFilePath - [Optional] Location of the program executable. [Default = Full script location] ; $iAllUsers - [Optional] Was it Added to Current Users (0) or All Users (1). [Default = 0 - Current user.] ; $iRunOnce - [Optional] Was it Always Run at System Startup (0) or Run only once (1). [Default = 0 - Always run at system startup.] ; Requirement(s).: v3.2.12.1 or higher ; Return values .: Success - Returns 1 ; Failure - Returns 0 & sets @error = 1 ; Author ........: guinness ; Example........; Yes ;===================================================================================================================== Func _StartupRegistry_Uninstall($sName = @ScriptName, $sFilePath = @ScriptFullPath, $iAllUsers = 0, $iRunOnce = 0) Local $i64Bit = "", $iCount = 1, $sRegistryKey, $sRegistryName, $sRegistryValue, $sRunOnce $sName = StringLower(StringReplace($sName, ".exe", "")) If $sName = "" Or $sFilePath = "" Then Return SetError(1, 0, 0) EndIf If $iRunOnce Then $sRunOnce = "Once" EndIf If @OSArch = "X64" Then $i64Bit = "64" EndIf If $iAllUsers Then $sRegistryKey = "HKEY_LOCAL_MACHINE" & $i64Bit & "\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" & $sRunOnce & "\" Else $sRegistryKey = "HKEY_CURRENT_USER" & $i64Bit & "\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" & $sRunOnce & "\" EndIf While 1 $sRegistryName = RegEnumVal($sRegistryKey, $iCount) If @error Then ExitLoop EndIf $sRegistryValue = RegRead($sRegistryKey, $sRegistryName) If ($sRegistryName = $sName) And ($sRegistryValue = $sFilePath) Then RegDelete($sRegistryKey, $sName) EndIf $iCount += 1 WEnd Return 1 EndFunc ;==>_StartupRegistry_Uninstall ; #INDEX# ======================================================================================================================= ; Title .........: _RecFileListToArray ; AutoIt Version : v3.3.1.1 or higher ; Language ......: English ; Description ...: Lists files and\or folders in specified path with optional recursion to defined level and result sorting ; Note ..........: ; Author(s) .....: Melba23 ; Remarks .......: - Modified Array.au3 functions - credit: Jos van der Zande, LazyCoder, Tylo, Ultima, SolidSnake and gcriaco ; - SRE patterns - credit: various forum members and Spiff59 in particular ; - Despite the name, this UDF is iterative, not recursive ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _RecFileListToArray: Lists files and\or folders in a specified path with optional recursion to defined level and result sorting ; =============================================================================================================================== ; #INTERNAL_USE_ONLY#============================================================================================================ ; _RFLTA_ListToMask ......; Convert include/exclude lists to SRE format ; _RFLTA_AddToList .......; Add element to list which is resized if necessary ; _RFLTA_AddFileLists ....; Add internal lists after resizing and optional sorting ; _RFLTA_FileListSearch ..; Search file match list for files associated with a folder ; _RFLTA_ArraySort .......; Wrapper for QuickSort function ; _RFLTA_QuickSort .......: Recursive array sort ; _RFLTA_ArrayConcatenate : Join 2 arrays ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: _RecFileListToArray ; Description ...: Lists files and\or folders in a specified path with optional recursion to defined level and result sorting ; Syntax.........: _RecFileListToArray($sPath[, $sInclude_List = "*"[, $iReturn = 0[, $iRecur = 0[, $iSort = 0[, $iReturnPath = 1[, $sExclude_List = ""]]]]]]) ; Parameters ....: $sPath - Initial path used to generate filelist. If path ends in \ then folders will be returned with an ending \ ; $sInclude_List - Optional: filter for included results (default "*"). Multiple filters must be separated by ";" ; $iReturn - Optional: specifies whether to return files, folders or both ; |$iReturn = 0 (Default) Return both files and folders ; |$iReturn = 1 Return files only ; |$iReturn = 2 Return folders only ; $iRecur - Optional: specifies whether to search recursively in subfolders and to what level ; |$iRecur = 1 Search in all subfolders (unlimited recursion) ; |$iRecur = 0 (Default) Do not search in subfolders ; |$iRecur = Negative integer - Search in subfolders to specified depth ; $iSort - Optional: sort ordered in alphabetical and depth order ; |$iSort = 0 - Not sorted (Default) ; |$iSort = 1 - Sorted ; |$iSort = 2 - Sorted with faster algorithm (assumes files sorted within each folder - requires NTFS drive) ; $iReturnPath - Optional: specifies displayed path of results ; |$iReturnPath = 0 File/folder name only ; |$iReturnPath = 1 (Default) Relative to initial path ; |$iReturnPath = 2 Full path included ; $sExclude_List - Optional: filter for excluded results (default ""). Multiple filters must be separated by ";" ; Requirement(s).: v3.3.1.1 or higher ; Return values .: Success: One-dimensional array made up as follows: ; |$array[0] = Number of Files\Folders returned ; |$array[1] = 1st File\Folder ; |$array[2] = 2nd File\Folder ; |... ; |$array[n] = nth File\Folder ; Failure: Null string and @error = 1 with @extended set as follows: ; |1 = Path not found or invalid ; |2 = Invalid $sInclude_List ; |3 = Invalid $iReturn ; |4 = Invalid $iRecur ; |5 = Invalid $iSort ; |6 = Invalid $iReturnPath ; |7 = Invalid $sExclude_List ; |8 = No files/folders found ; Author ........: Melba23 ; Remarks .......: Compatible with existing _FileListToArray syntax ; Related .......: ; Link ..........; ; Example .......; Yes ; =============================================================================================================================== Func _RecFileListToArray($sInitialPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $iSort = 0, $iReturnPath = 1, $sExclude_List = "") Local $asReturnList[100] = [0], $asFileMatchList[100] = [0], $asRootFileMatchList[100] = [0], $asFolderMatchList[100] = [0], $asFolderSearchList[100] = [1] Local $sFolderSlash = "", $iMaxLevel, $sInclude_List_Mask, $sExclude_List_Mask, $hSearch, $fFolder, $sRetPath = "", $sCurrentPath, $sName Local $asFolderFileSectionList[100][2] = [[0, 0]], $sFolderToFind, $iFileSectionStartIndex, $iFileSectionEndIndex ; Check for valid path If Not FileExists($sInitialPath) Then Return SetError(1, 1, "") ; Check if folders should have trailing \ and ensure that initial path does have one If StringRight($sInitialPath, 1) = "\" Then $sFolderSlash = "\" Else $sInitialPath = $sInitialPath & "\" EndIf ; Add path to folder search list $asFolderSearchList[1] = $sInitialPath ; Check for valid recur value If $iRecur > 1 Or Not IsInt($iRecur) Then Return SetError(1, 4, "") ; If required, determine \ count for max Recursive level setting If $iRecur < 0 Then StringReplace($sInitialPath, "\", "", 2) $iMaxLevel = @extended - $iRecur EndIf ; Create Include List mask If $sInclude_List = "*" Then $sInclude_List_Mask = ".+" ; Set mask to exclude base folder with NULL name Else If Not _RFLTA_ListToMask($sInclude_List_Mask, $sInclude_List) Then Return SetError(1, 2, "") EndIf ; Create Exclude List mask If $sExclude_List = "" Then $sExclude_List_Mask = ":" ; Set unmatchable mask Else If Not _RFLTA_ListToMask($sExclude_List_Mask, $sExclude_List) Then Return SetError(1, 7, "") EndIf ; Verify other parameters If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(1, 3, "") If Not ($iSort = 0 Or $iSort = 1 Or $iSort = 2) Then Return SetError(1, 5, "") If Not ($iReturnPath = 0 Or $iReturnPath = 1 Or $iReturnPath = 2) Then Return SetError(1, 6, "") ; Search within listed folders While $asFolderSearchList[0] > 0 ; Set path to search $sCurrentPath = $asFolderSearchList[$asFolderSearchList[0]] ; Reduce folder search list count $asFolderSearchList[0] -= 1 ; Determine return path to add to file/folder name Switch $iReturnPath ; Case 0 ; Name only ; Leave as "" Case 1 ;Relative to initial path $sRetPath = StringReplace($sCurrentPath, $sInitialPath, "") Case 2 ; Full path $sRetPath = $sCurrentPath EndSwitch ; Get search handle $hSearch = FileFindFirstFile($sCurrentPath & "*") ; If folder empty move to next in list If $hSearch = -1 Then ContinueLoop EndIf ; If sorting files and folders with paths then store folder name and position of associated files in list If Not ($iReturn) And $iSort And $iReturnPath Then _RFLTA_AddToList($asFolderFileSectionList, $sRetPath, $asFileMatchList[0] + 1) EndIf ; Search folder While 1 $sName = FileFindNextFile($hSearch) ; Check for end of folder If @error Then ExitLoop EndIf ; Set subfolder flag - @extended set in 3.3.1.1 + $fFolder = @extended ; If folder then check whether to add to search list If $fFolder Then Switch $iRecur Case 1 ; Always add _RFLTA_AddToList($asFolderSearchList, $sCurrentPath & $sName & "\") Case 0 ; Never add ; Do nothing Case Else ; Add if max level not exceeded StringReplace($sCurrentPath, "\", "", 0, 2) If @extended < $iMaxLevel Then _RFLTA_AddToList($asFolderSearchList, $sCurrentPath & $sName & "\") EndIf EndSwitch EndIf ; Match name against Include/Exclude masks If StringRegExp($sName, $sInclude_List_Mask) And Not StringRegExp($sName, $sExclude_List_Mask) Then If $iSort Then ; Save in relevant folders for later sorting If $fFolder Then _RFLTA_AddToList($asFolderMatchList, $sRetPath & $sName & $sFolderSlash) Else ; Select required list for files If $sCurrentPath = $sInitialPath Then _RFLTA_AddToList($asRootFileMatchList, $sRetPath & $sName) Else _RFLTA_AddToList($asFileMatchList, $sRetPath & $sName) EndIf EndIf Else ; Save directly in return list ; Check file/folder type against required return value If $fFolder + $iReturn <> 2 Then ; Add final "\" to folders if required If $fFolder Then $sName &= $sFolderSlash _RFLTA_AddToList($asReturnList, $sRetPath & $sName) EndIf EndIf EndIf WEnd ; Close current search FileClose($hSearch) WEnd If $iSort Then ; Check if any file/folders have been added If $asRootFileMatchList[0] = 0 And $asFileMatchList[0] = 0 And $asFolderMatchList[0] = 0 Then Return SetError(1, 8, "") Switch $iReturn Case 2 ; Folders only ; Correctly size folder match list ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] ; Copy size folder match array $asReturnList = $asFolderMatchList ; Simple sort list _RFLTA_ArraySort($asReturnList) Case 1 ; Files only If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Simple sort combined file list _RFLTA_ArraySort($asReturnList) Else ; Combine sorted file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList, 1) EndIf Case 0 ; Both files and folders If $iReturnPath = 0 Then ; names only so simple sort suffices ; Combine file match lists _RFLTA_AddFileLists($asReturnList, $asRootFileMatchList, $asFileMatchList) ; Set correct count for folder add $asReturnList[0] += $asFolderMatchList[0] ; Resize and add file match array ReDim $asFolderMatchList[$asFolderMatchList[0] + 1] _RFLTA_ArrayConcatenate($asReturnList, $asFolderMatchList) ; Simple sort final list _RFLTA_ArraySort($asReturnList) Else ; Size return list Local $asReturnList[$asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0] + 1] $asReturnList[0] = $asFileMatchList[0] + $asRootFileMatchList[0] + $asFolderMatchList[0] ; Sort root file list _RFLTA_ArraySort($asRootFileMatchList, 1, $asRootFileMatchList[0]) ; Add the sorted root files at the top For $i = 1 To $asRootFileMatchList[0] $asReturnList[$i] = $asRootFileMatchList[$i] Next ; Set next insertion index Local $iNextInsertionIndex = $asRootFileMatchList[0] + 1 ; Sort folder list _RFLTA_ArraySort($asFolderMatchList, 1, $asFolderMatchList[0]) ; Work through folder list For $i = 1 To $asFolderMatchList[0] ; Format folder name for search If $sFolderSlash Then $sFolderToFind = $asFolderMatchList[$i] Else $sFolderToFind = $asFolderMatchList[$i] & "\" EndIf ; Find folder in FolderFileSectionList For $j = 1 To $asFolderFileSectionList[0][0] If $sFolderToFind = $asFolderFileSectionList[$j][0] Then ExitLoop Next ; Set file list indexes $iFileSectionStartIndex = $asFolderFileSectionList[$j][1] If $j = $asFolderFileSectionList[0][0] Then $iFileSectionEndIndex = $asFileMatchList[0] Else $iFileSectionEndIndex = $asFolderFileSectionList[$j + 1][1] - 1 EndIf ; Sort files if required If $iSort = 1 Then _RFLTA_ArraySort($asFileMatchList, $iFileSectionStartIndex, $iFileSectionEndIndex) EndIf ; Add folder to return list $asReturnList[$iNextInsertionIndex] = $asFolderMatchList[$i] $iNextInsertionIndex += 1 ; Add files to return list For $j = $iFileSectionStartIndex To $iFileSectionEndIndex $asReturnList[$iNextInsertionIndex] = $asFileMatchList[$j] $iNextInsertionIndex += 1 Next Next EndIf EndSwitch Else ; No sort ; Check if any file/folders have been added If $asReturnList[0] = 0 Then Return SetError(1, 8, "") ; Remove any unused return list elements from last ReDim ReDim $asReturnList[$asReturnList[0] + 1] EndIf Return $asReturnList EndFunc ;==>_RecFileListToArray ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_ListToMask ; Description ...: Convert include/exclude lists to SRE format ; Syntax ........: _RFLTA_ListToMask(ByRef $sMask, $sList) ; Parameters ....: $asMask - Include/Exclude mask to create ; $asList - Include/Exclude list to convert ; Return values .: Success: 1 ; Failure: 0 ; Author ........: SRE patterns developed from those posted by various forum members and Spiff59 in particular ; Remarks .......: This function is used internally by _RecFileListToArray ; =============================================================================================================================== Func _RFLTA_ListToMask(ByRef $sMask, $sList) ; Check for invalid characters within list If StringRegExp($sList, "\\|/|:|\<|\>|\|") Then Return 0 ; Strip WS and insert | for ; $sList = StringReplace(StringStripWS(StringRegExpReplace($sList, "\s*;\s*", ";"), 3), ";", "|") ; Convert to SRE pattern $sList = StringReplace(StringReplace(StringRegExpReplace($sList, "(\^|\$|\.)", "\\$1"), "?", "."), "*", ".*?") ; Add prefix and suffix $sMask = "(?i)^(" & $sList & ")\z" Return 1 EndFunc ;==>_RFLTA_ListToMask ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_AddToList ; Description ...: Add element to [?] or [?][2] list which is resized if necessary ; Syntax ........: _RFLTA_AddToList(ByRef $asList, $vValue_0, [$vValue_1]) ; Parameters ....: $aList - List to be added to ; $vValue_0 - Value to add (to [0] element in [?][2] array if $vValue_1 exists) ; $vValue_1 - Value to add to [1] element in [?][2] array (optional) ; Return values .: None - array modified ByRef ; Author ........: Melba23 ; Remarks .......: This function is used internally by _RecFileListToArray ; =============================================================================================================================== Func _RFLTA_AddToList(ByRef $aList, $vValue_0, $vValue_1 = -1) If $vValue_1 = -1 Then ; [?] array ; Increase list count $aList[0] += 1 ; Double list size if too small (fewer ReDim needed) If UBound($aList) <= $aList[0] Then ReDim $aList[UBound($aList) * 2] ; Add value $aList[$aList[0]] = $vValue_0 Else ; [?][2] array $aList[0][0] += 1 If UBound($aList) <= $aList[0][0] Then ReDim $aList[UBound($aList) * 2][2] $aList[$aList[0][0]][0] = $vValue_0 $aList[$aList[0][0]][1] = $vValue_1 EndIf EndFunc ;==>_RFLTA_AddToList ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_AddFileLists ; Description ...: Add internal lists after resizing and optional sorting ; Syntax ........: _RFLTA_AddFileLists(ByRef $asTarget, $asSource_1, $asSource_2[, $iSort = 0]) ; Parameters ....: $asReturnList - Base list ; $asRootFileMatchList - First list to add ; $asFileMatchList - Second list to add ; $iSort - (Optional) Whether to sort lists before adding ; |$iSort = 0 (Default) No sort ; |$iSort = 1 Sort in descending alphabetical order ; Return values .: None - array modified ByRef ; Author ........: Melba23 ; Remarks .......: This function is used internally by _RecFileListToArray ; =============================================================================================================================== Func _RFLTA_AddFileLists(ByRef $asTarget, $asSource_1, $asSource_2, $iSort = 0) ; Correctly size root file match array ReDim $asSource_1[$asSource_1[0] + 1] ; Simple sort root file match array if required If $iSort = 1 Then _RFLTA_ArraySort($asSource_1) ; Copy root file match array $asTarget = $asSource_1 ; Add file match count $asTarget[0] += $asSource_2[0] ; Correctly size file match array ReDim $asSource_2[$asSource_2[0] + 1] ; Simple sort file match array if required If $iSort = 1 Then _RFLTA_ArraySort($asSource_2) ; Add file match array _RFLTA_ArrayConcatenate($asTarget, $asSource_2) EndFunc ;==>_RFLTA_AddFileLists ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_FileListSearch ; Description ...: Search file array for beginning and end indices of folder associated files ; Syntax ........: _RFLTA_FileListSearch(Const ByRef $avArray, $vValue) ; Parameters ....: $avArray - Array to search ($asFileMatchList) ; $vValue - Value to search for (Folder name from $asFolderMatchList) ; $iIndex - Index to begin search (search down from here - and then from here to top if not found) ; $sSlash - \ if folder names end in \ - else empty string ; Return values .: Success: Array holding top and bottom indices of folder associated files ; Failure: Returns -1 ; Author ........: Melba23 ; Modified.......: ; Remarks .......: This function is used internally by _RecFileListToArray ; =============================================================================================================================== Func _RFLTA_FileListSearch(Const ByRef $avArray, $vValue, $iIndex, $sSlash) Local $aRet[2] ; Add final \ if required If Not $sSlash Then $vValue &= "\" ; Start by getting top match - search down from start index For $i = $iIndex To $avArray[0] ; SRE gives path less filename If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") = $vValue Then ExitLoop Next If $i > $avArray[0] Then ; No match found so look from start index upwards If $iIndex = $avArray[0] Then $iIndex -= 1 For $i = $iIndex + 1 To 1 Step -1 If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") = $vValue Then ExitLoop Next ; If still no match - return " nothing found" for empty folder If $i = 0 Then Return SetError(1, 0, "") ; Set index of bottom file $aRet[1] = $i ; Now look for top match For $i = $aRet[1] To 1 Step -1 If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") <> $vValue Then ExitLoop Next ; Set top match $aRet[0] = $i + 1 Else ; Set index of top associated file $aRet[0] = $i ; Now look for bottom match - find first file which does not match For $i = $aRet[0] To $avArray[0] If StringRegExpReplace($avArray[$i], "(^.*\\)(.*)", "\1") <> $vValue Then ExitLoop Next ; Set bottom match $aRet[1] = $i - 1 EndIf Return $aRet EndFunc ;==>_RFLTA_FileListSearch ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_ArraySort ; Description ...: Wrapper for QuickSort function ; Syntax ........: _RFLTA_ArraySort(ByRef $avArray) ; Parameters ....: $avArray - Array to sort ; $iStart - Index to start sort ; $iEnd - Index to end sort ; Return values .: None - array modified ByRef ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: Melba23 ; Remarks .......: This function is used internally by _RecFileListToArray ; =============================================================================================================================== Func _RFLTA_ArraySort(ByRef $avArray, $iStart = 1, $iEnd = -99) If $iEnd = -99 Then $iEnd = UBound($avArray) - 1 _RFLTA_QuickSort($avArray, $iStart, $iEnd) EndFunc ;==>_RFLTA_ArraySort ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_QuickSort ; Description ...: Recursive array sort ; Syntax ........: _RFLTA_QuickSort(ByRef $avArray, ByRef $iStart, ByRef $iEnd) ; Parameters ....: $avArray - Array to sort in descending alphabetical order ; $iStart - Start index ; $iEnd - End index ; Return values .: None - array modified ByRef ; Author ........: Jos van der Zande, LazyCoder, Tylo, Ultima ; Modified.......: Melba23 ; Remarks .......: This function is used internally by _RFLTA_ArraySort ; =============================================================================================================================== Func _RFLTA_QuickSort(ByRef $avArray, ByRef $iStart, ByRef $iEnd) Local $vTmp If ($iEnd - $iStart) < 15 Then Local $i, $j, $vCur For $i = $iStart + 1 To $iEnd $vTmp = $avArray[$i] If IsNumber($vTmp) Then For $j = $i - 1 To $iStart Step -1 $vCur = $avArray[$j] If ($vTmp >= $vCur And IsNumber($vCur)) Or (Not IsNumber($vCur) And StringCompare($vTmp, $vCur) >= 0) Then ExitLoop $avArray[$j + 1] = $vCur Next Else For $j = $i - 1 To $iStart Step -1 If (StringCompare($vTmp, $avArray[$j]) >= 0) Then ExitLoop $avArray[$j + 1] = $avArray[$j] Next EndIf $avArray[$j + 1] = $vTmp Next Return EndIf Local $L = $iStart, $R = $iEnd, $vPivot = $avArray[Int(($iStart + $iEnd) / 2)], $fNum = IsNumber($vPivot) Do If $fNum Then While ($avArray[$L] < $vPivot And IsNumber($avArray[$L])) Or (Not IsNumber($avArray[$L]) And StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While ($avArray[$R] > $vPivot And IsNumber($avArray[$R])) Or (Not IsNumber($avArray[$R]) And StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd Else While (StringCompare($avArray[$L], $vPivot) < 0) $L += 1 WEnd While (StringCompare($avArray[$R], $vPivot) > 0) $R -= 1 WEnd EndIf If $L <= $R Then $vTmp = $avArray[$L] $avArray[$L] = $avArray[$R] $avArray[$R] = $vTmp $L += 1 $R -= 1 EndIf Until $L > $R _RFLTA_QuickSort($avArray, $iStart, $R) _RFLTA_QuickSort($avArray, $L, $iEnd) EndFunc ;==>_RFLTA_QuickSort ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: _RFLTA_ArrayConcatenate ; Description ...: Joins 2 arrays ; Syntax ........: _RFLTA_ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource) ; Parameters ....: $avArrayTarget - Base array ; $avArraySource - Array to add from element 1 onwards ; Return values .: None - array modified ByRef ; Author ........: Ultima ; Modified.......: Melba23 ; Remarks .......: This function is used internally by _RecFileListToArray ; =============================================================================================================================== Func _RFLTA_ArrayConcatenate(ByRef $avArrayTarget, Const ByRef $avArraySource) Local $iUBoundTarget = UBound($avArrayTarget) - 1, $iUBoundSource = UBound($avArraySource) ReDim $avArrayTarget[$iUBoundTarget + $iUBoundSource] For $i = 1 To $iUBoundSource - 1 $avArrayTarget[$iUBoundTarget + $i] = $avArraySource[$i] Next EndFunc ;==>_RFLTA_ArrayConcatenate Func WM_SIZE($hWnd, $msg, $wParam, $lParam) #forceref $Msg, $wParam Local $index = -1, $yChar, $xChar, $xClientMax, $xClient, $yClient, $ivMax For $x = 0 To UBound($aSB_WindowInfo) - 1 If $aSB_WindowInfo[$x][0] = $hWnd Then $index = $x $xClientMax = $aSB_WindowInfo[$index][1] $xChar = $aSB_WindowInfo[$index][2] $yChar = $aSB_WindowInfo[$index][3] $ivMax = $aSB_WindowInfo[$index][7] ExitLoop EndIf Next If $index = -1 Then Return 0 Local $tSCROLLINFO = DllStructCreate($tagSCROLLINFO) ; Retrieve the dimensions of the client area. $xClient = BitAND($lParam, 0x0000FFFF) $yClient = BitShift($lParam, 16) $aSB_WindowInfo[$index][4] = $xClient $aSB_WindowInfo[$index][5] = $yClient ; Set the vertical scrolling range and page size DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE)) DllStructSetData($tSCROLLINFO, "nMin", 0) DllStructSetData($tSCROLLINFO, "nMax", $ivMax) DllStructSetData($tSCROLLINFO, "nPage", $yClient / $yChar) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) ; Set the horizontal scrolling range and page size DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE)) DllStructSetData($tSCROLLINFO, "nMin", 0) DllStructSetData($tSCROLLINFO, "nMax", 2 + $xClientMax / $xChar) DllStructSetData($tSCROLLINFO, "nPage", $xClient / $xChar) _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) Return $GUI_RUNDEFMSG EndFunc ;==>WM_SIZE Func WM_HSCROLL($hWnd, $msg, $wParam, $lParam) #forceref $Msg, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $index = -1, $xChar, $xPos Local $Min, $Max, $Page, $pos, $TrackPos For $x = 0 To UBound($aSB_WindowInfo) - 1 If $aSB_WindowInfo[$x][0] = $hWnd Then $index = $x $xChar = $aSB_WindowInfo[$index][2] ExitLoop EndIf Next If $index = -1 Then Return 0 ;~ ; Get all the horizontal scroll bar information Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") ; Save the position for comparison later on $xPos = DllStructGetData($tSCROLLINFO, "nPos") $pos = $xPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") #forceref $Min, $Max Switch $nScrollCode Case $SB_LINELEFT ; user clicked left arrow DllStructSetData($tSCROLLINFO, "nPos", $pos - 1) Case $SB_LINERIGHT ; user clicked right arrow DllStructSetData($tSCROLLINFO, "nPos", $pos + 1) Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box DllStructSetData($tSCROLLINFO, "nPos", $pos - $Page) Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box DllStructSetData($tSCROLLINFO, "nPos", $pos + $Page) Case $SB_THUMBTRACK ; user dragged the scroll box DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch ;~ // Set the position and then retrieve it. Due to adjustments ;~ // by Windows it may not be the same as the value set. DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) ;// If the position has changed, scroll the window and update it $pos = DllStructGetData($tSCROLLINFO, "nPos") If ($pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $pos), 0) Return $GUI_RUNDEFMSG EndFunc ;==>WM_HSCROLL Func WM_VSCROLL($hWnd, $msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $index = -1, $yChar, $yPos Local $Min, $Max, $Page, $pos, $TrackPos For $x = 0 To UBound($aSB_WindowInfo) - 1 If $aSB_WindowInfo[$x][0] = $hWnd Then $index = $x $yChar = $aSB_WindowInfo[$index][3] ExitLoop EndIf Next If $index = -1 Then Return 0 ; Get all the vertial scroll bar information Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") ; Save the position for comparison later on $yPos = DllStructGetData($tSCROLLINFO, "nPos") $pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP ; user clicked the HOME keyboard key DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM ; user clicked the END keyboard key DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP ; user clicked the top arrow DllStructSetData($tSCROLLINFO, "nPos", $pos - 1) Case $SB_LINEDOWN ; user clicked the bottom arrow DllStructSetData($tSCROLLINFO, "nPos", $pos + 1) Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box DllStructSetData($tSCROLLINFO, "nPos", $pos - $Page) Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box DllStructSetData($tSCROLLINFO, "nPos", $pos + $Page) Case $SB_THUMBTRACK ; user dragged the scroll box DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch ;~ // Set the position and then retrieve it. Due to adjustments ;~ // by Windows it may not be the same as the value set. DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) ;// If the position has changed, scroll the window and update it $pos = DllStructGetData($tSCROLLINFO, "nPos") If ($pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $pos)) $yPos = $pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_VSCROLL ; function by MHZ Func _SHGetSpecialFolderPath($csidl) Local $hwndOwner = 0, $lpszPath = "", $fCreate = False, $MAX_PATH = 260 $lpszPath = DllStructCreate("char[" & $MAX_PATH & "]") $BOOL = DllCall("shell32.dll", "int", "SHGetSpecialFolderPath", "int", $hwndOwner, "ptr", DllStructGetPtr($lpszPath), "int", $csidl, "int", $fCreate) If Not @error Then Return SetError($BOOL[0], 0, DllStructGetData($lpszPath, 1)) Else Return SetError(@error, 0, 3) EndIf EndFunc ;==>_SHGetSpecialFolderPath Func _prepare_tray_menu() Opt("TrayOnEventMode", 1) Opt("TrayMenuMode", 11) TrayCreateItem("Setup") TrayItemSetOnEvent(-1, "_Setup") TrayCreateItem("") TrayCreateItem("Exit") TrayItemSetOnEvent(-1, "_Exit") TraySetState() EndFunc ;==>_prepare_tray_menu Func _get_script_config_from_file() If Not FileExists(@ScriptDir & "\settings.ini") Then _setup() $begin = TimerInit() Do Sleep(100) If TimerDiff($begin) >= 5000 Then _FileWriteLog(@ScriptDir & "\script.log", 'settings.ini not found after running setup dialog. Aborting.') MsgBox(16, $title, '"settings.ini" file wasn' & "'t created in time. Aborting.") Exit EndIf Until FileExists(@ScriptDir & "\settings.ini") EndIf $ramdisk_drive = IniRead(@ScriptDir & "\settings.ini", "ramdisk drive letter", "letter", "error") $swtor_path = IniRead(@ScriptDir & "\settings.ini", "swtor installation path", "path", "error") $copy_assets = IniRead(@ScriptDir & "\settings.ini", "copy settings", "assets", "error") $copy_local = IniRead(@ScriptDir & "\settings.ini", "copy settings", "local swtor", "error") $copy_swtor = IniRead(@ScriptDir & "\settings.ini", "copy settings", "swtor", "error") $appdata_path_anon = StringReplace($appdata_path, @UserName, "-anonymized-") $aIndvAssets = IniReadSection(@ScriptDir & "\settings.ini", "individual assets") _verify_ramdisk_drive() _verify_swtor_path() _verify_assets() _verify_local() _verify_swtor() _verify_appdata_path() EndFunc ;==>_get_script_config_from_file Func _verify_ramdisk_drive() If $ramdisk_drive = "error" Or Not FileExists($ramdisk_drive) Then $ramdisk_drive = "-1" EndIf EndFunc ;==>_verify_ramdisk_drive Func _verify_swtor_path() If $swtor_path = "error" Or Not FileExists($swtor_path) Then $swtor_path = "-1" EndIf EndFunc ;==>_verify_swtor_path Func _verify_assets() If $copy_assets = "error" Then $copy_assets = "-1" EndIf EndFunc ;==>_verify_assets Func _verify_local() If $copy_local = "error" Then $copy_local = "-1" EndIf EndFunc ;==>_verify_local Func _verify_swtor() If $copy_swtor = "error" Then $copy_swtor = "-1" EndIf EndFunc ;==>_verify_swtor Func _verify_appdata_path() If $appdata_path = "error" Or Not FileExists($appdata_path & "\swtor") Then $appdata_path = "-1" EndIf EndFunc ;==>_verify_appdata_path Func _GetLauncherStatusFromLog($time) Local $aLauncherLog, $logpath, $patching_end = 0, $aLauncherStatus[4][3] = [["user login", 0, 0],["user exit", 0, 0],["patching end", 0, 0],["login failure", 0, 0]], $launcher_error = 0 Local $aLogs = _recfilelisttoarray($swtor_path & "\logs", "*", 1, 1, 1, 1) For $i = 1 To $aLogs[0] $split = StringSplit($aLogs[$i], "_.") $aLogs[$i] = $split[2] Next _ArraySort($aLogs, 1, 1) _FileReadToArray($swtor_path & "\logs\launcher_" & $aLogs[1] & ".log", $aLauncherLog) If Not IsArray($aLauncherLog) Then Return (-1) EndIf ;_arraydisplay($aLauncherLog) For $i = 1 To $aLauncherLog[0] ;msgbox(0, "line", $i) $regex = StringRegExp($aLauncherLog[$i], "(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})", 1) If IsArray($regex) Then ;msgbox(0, "test", "time1: " & $time & @crlf & "time2: " & Number($regex[0] & $regex[1] & $regex[2] & $regex[3] & $regex[4] & $regex[5])) If Number($regex[0] & $regex[1] & $regex[2] & $regex[3] & $regex[4] & $regex[5]) >= $time Then If StringInStr($aLauncherLog[$i], "user logs in", 0) Then ;_FileWriteLog(@ScriptDir & "\test.log", "user log in @ line " & $i) $aLauncherStatus[0][2] = 1 $aLauncherStatus[0][1] = $i EndIf If StringInStr($aLauncherLog[$i], "user presses exit", 0) Then ;_FileWriteLog(@ScriptDir & "\test.log", "user exit @ line " & $i) $aLauncherStatus[1][2] = 3 $aLauncherStatus[1][1] = $i EndIf If StringInStr($aLauncherLog[$i], "patching end", 0) Then $patching_end += 1 If $patching_end >= 2 Then ;_FileWriteLog(@ScriptDir & "\test.log", "patching end @ line " & $i) $aLauncherStatus[2][2] = 2 $aLauncherStatus[2][1] = $i EndIf EndIf If StringInStr($aLauncherLog[$i], " error ", 0) and not StringInStr($aLauncherLog[$i], "promos", 0) Then $launcher_error = 1 EndIf If StringInStr($aLauncherLog[$i], "login failure", 0) Then ;_FileWriteLog(@ScriptDir & "\test.log", "user exit @ line " & $i) $aLauncherStatus[3][2] = 5 $aLauncherStatus[3][1] = $i EndIf EndIf EndIf Next If $launcher_error = 1 Then Return (4) EndIf ;_arraydisplay($aLauncherStatus) _ArraySort($aLauncherStatus, 1, 0, 0, 1) Return ($aLauncherStatus[0][2]) Return (0) EndFunc ;==>_GetLauncherStatusFromLog Func _required_ramdisk_space(ByRef $rqrd_rmdsk_size, ByRef $avlbl_rmdsk_space) ;Local $rqrd_rmdsk_size If $copy_assets = 1 Then $rqrd_rmdsk_size += DirGetSize($swtor_path & "\assets") EndIf If $copy_assets = 2 Then For $i = 1 To $aIndvAssets[0][0] $rqrd_rmdsk_size += FileGetSize($swtor_path & "\assets\" & $aIndvAssets[$i][1]) Next EndIf If $copy_local = 1 Then $rqrd_rmdsk_size += 104857600 EndIf If $copy_swtor = 1 Then $rqrd_rmdsk_size += 1395864371.2 EndIf $rqrd_rmdsk_size = Round($rqrd_rmdsk_size / (1024 ^ 3), 2) $avlbl_rmdsk_space = Round(DriveSpaceTotal($ramdisk_drive & "\") / 1024, 2) EndFunc ;==>_required_ramdisk_space Func _check_ramdisk_size() _FileWriteLog(@ScriptDir & "\script.log", "Checking ramdisk size.") Local $rqrd_rmdsk_size, $avlbl_rmdsk_space While 1 _required_ramdisk_space($rqrd_rmdsk_size, $avlbl_rmdsk_space) If Not ($avlbl_rmdsk_space >= $rqrd_rmdsk_size) Then _FileWriteLog(@ScriptDir & "\script.log", 'Ramdisk too small. Required = ' & $rqrd_rmdsk_size & 'GB; available = ' & $avlbl_rmdsk_space & 'GB.') $return = MsgBox(20, $title, "Ramdisk too small. Please check your ramdisk settings and try again." & @CRLF & @CRLF & _ "Current ramdisk size: " & $avlbl_rmdsk_space & "GB." & @CRLF & _ "Required ramdisk space: " & $rqrd_rmdsk_size & "GB." & @CRLF & @CRLF & _ "You need at least " & $rqrd_rmdsk_size - $avlbl_rmdsk_space & "GB more space." & @CRLF & @CRLF & _ "If you want to copy individual assets files, you may have to deselect a couple of them for the rest to fit onto the ramdisk." & @CRLF & @CRLF & _ "Run Setup?") If $return = 6 Then _setup() Else Exit EndIf Else ExitLoop EndIf WEnd _FileWriteLog(@ScriptDir & "\script.log", "Check went well.") EndFunc ;==>_check_ramdisk_size Func _check_settings() If $ramdisk_drive = -1 Or $swtor_path = -1 Or $appdata_path = -1 Or $copy_swtor = -1 Or $copy_assets = -1 Or $copy_local = -1 Then _FileWriteLog(@ScriptDir & "\script.log", "Settings.ini not found or settings missing, starting setup dialog.") $setup_ran = 1 _setup() If $ramdisk_drive = -1 Or $swtor_path = -1 Or $appdata_path = -1 Or $copy_swtor = -1 Or $copy_assets = -1 Or $copy_local = -1 Then _FileWriteLog(@ScriptDir & "\script.log", "Setup dialog was started but exited without making any settings.") Exit EndIf EndIf EndFunc ;==>_check_settings Func _check_filesystems() $aSwtorDrive = StringSplit($swtor_path, "\") $swtorFileSystem = StringUpper(DriveGetFileSystem($aSwtorDrive[1] & "\")) _FileWriteLog(@ScriptDir & "\script.log", "Verifying the partition's file system type.") If Not ($swtorFileSystem = "NTFS") Then _FileWriteLog(@ScriptDir & "\script.log", "Partition's file system type was " & $swtorFileSystem & ", not NTFS.") MsgBox(16, $title, "The file system type of your hard disk or partition containing your Star Wars: The Old Republic installation needs to be NTFS," & _ "however currently it's " & $swtorFileSystem & "." & @CRLF & @CRLF & "Directory linking cannot be done on file system types other than NTFS." & _ @CRLF & @CRLF & "Exiting.") Exit EndIf _FileWriteLog(@ScriptDir & "\script.log", "Verification went well.") _FileWriteLog(@ScriptDir & "\script.log", "Verifying the ramdisk's file system type.") $ramdiskFileSystem = StringUpper(DriveGetFileSystem($ramdisk_drive & "\")) If Not ($ramdiskFileSystem = "NTFS") Then _FileWriteLog(@ScriptDir & "\script.log", "The ramdisk's file system type was " & $swtorFileSystem & ", not NTFS.") MsgBox(16, $title, "Your ramdisk's file system type needs to be NTFS, however currently it's " & _ $ramdiskFileSystem & "." & @CRLF & @CRLF & "Please format it and select NTFS as the file system type.") Exit EndIf _FileWriteLog(@ScriptDir & "\script.log", "Verification went well.") EndFunc ;==>_check_filesystems Func _check_robocopy() $robocopy_path = IniRead(@ScriptDir & "\settings.ini", "robocopy path", "path", "error") If $robocopy_path = "error" Or Not FileExists($robocopy_path) Then _FileWriteLog(@ScriptDir & "\script.log", "Searching for robocopy.exe.") ToolTip("Searching for robocopy.exe, please wait...", 0, 0) $aRobocopy = _recfilelisttoarray(@WindowsDir, "robocopy.exe", 1, 1, 1, 2) ToolTip("") If IsArray($aRobocopy) Then _FileWriteLog(@ScriptDir & "\script.log", "Robocopy.exe found.") $robocopy_path = $aRobocopy[1] IniWrite(@ScriptDir & "\settings.ini", "robocopy path", "path", $robocopy_path) Else _FileWriteLog(@ScriptDir & "\script.log", "Robocopy.exe not found.") ClipPut("http://www.microsoft.com/download/en/details.aspx?id=17657") MsgBox(16, $title, "Windows 7 or Windows Vista required." & @CRLF & @CRLF & "If you're running Windows XP, " & _ "please download and install the Windows Resource Kit, found at" & @CRLF & _ "http://www.microsoft.com/download/en/details.aspx?id=17657" & @CRLF & _ "(Link has been copied to your clipboard.)") Exit EndIf EndIf _FileWriteLog(@ScriptDir & "\script.log", "Checking robocopy.exe version.") $ver = FileGetVersion($robocopy_path) If Not ($ver = "6.1.7601") And Not ($ver = "5.1.10.1027") And Not ($ver = "5.1.2600.26") And Not ($ver = "5.1.1.1010") Then _FileWriteLog(@ScriptDir & "\script.log", "Robocopy.exe too old.") ClipPut("http://www.microsoft.com/download/en/details.aspx?id=17657") MsgBox(16, $title, "Your version of robocopy.exe is pretty old, " & _ "please download and install the Windows Resource Kit, found at" & @CRLF & _ "http://www.microsoft.com/download/en/details.aspx?id=17657" & @CRLF & _ "(Link has been copied to your clipboard.)") Exit EndIf _FileWriteLog(@ScriptDir & "\script.log", "Check went well.") EndFunc ;==>_check_robocopy Func _check_robocopy_jobfile() If $copy_assets = 2 Then _FileWriteLog(@ScriptDir & "\script.log", "Checking swtorcopyjob.rcj presence.") If Not FileExists(@ScriptDir & "\swtorcopyjob.rcj") Then If IsArray($aIndvAssets) Then _FileWriteLog(@ScriptDir & "\script.log", "swtorcopyjob.rcj not found. Rebuilding.") _make_rc_jobfile() EndIf Else _FileWriteLog(@ScriptDir & "\script.log", "swtorcopyjob.rcj found.") EndIf EndIf EndFunc ;==>_check_robocopy_jobfile Func _launcher() Local $time = @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC Local $previous_returncode _FileWriteLog(@ScriptDir & "\script.log", "Starting launcher and waiting for logfile.") _start_launcher($swtor_path & "\launcher.exe", $LauncherWindowDesc) _wait_logfile($swtor_path & "\logs\launcher_" & @YEAR & @MON & @MDAY & ".log") Do Sleep(100) Until WinExists($LauncherWindowDesc) _FileWriteLog(@ScriptDir & "\script.log", "Launcher and logfile found.") _prepare_tray_menu() _FileWriteLog(@ScriptDir & "\script.log", 'Waiting for update check to start.') $disabled = 0 While 1 Sleep(10) $launcher_status = _GetLauncherStatusFromLog($time) ; 1 = patch process started ; 2 = patching done ; 3 = launcher exit by user ; 4 = patching error ; 5 = login failure ; 0 = nothing of these ;) If $launcher_status = 1 And $disabled = 0 Then $disabled = 1 $previous_returncode = 1 _FileWriteLog(@ScriptDir & "\script.log", "Update check has started.") _FileWriteLog(@ScriptDir & "\script.log", "Disabling launcher window to prevent user from prematurely clicking the launch button.") WinSetState($LauncherWindowDesc, "", @SW_DISABLE); This might be annoying, but we have to prevent the user from clicking "launch" until the script has finished doing what it needs to. EndIf If $launcher_status = 2 Then $previous_returncode = 2 _FileWriteLog(@ScriptDir & "\script.log", "Update check has stopped.") Return (@YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC) ExitLoop EndIf If $launcher_status = 3 Then $previous_returncode = 3 _FileWriteLog(@ScriptDir & "\script.log", "User has closed the launcher.") Exit EndIf If $launcher_status = 4 And Not ($previous_returncode = 4) Then $previous_returncode = 4 _FileWriteLog(@ScriptDir & "\script.log", "Update check has failed.") _FileWriteLog(@ScriptDir & "\script.log", "Enabling launcher window.") $disabled = 0 WinSetState($LauncherWindowDesc, "", @SW_ENABLE); this reenables the window. EndIf If $launcher_status = 5 And $disabled = 1 Then $previous_returncode = 5 _FileWriteLog(@ScriptDir & "\script.log", "Login failure.") _FileWriteLog(@ScriptDir & "\script.log", "Enabling launcher window.") $disabled = 0 WinSetState($LauncherWindowDesc, "", @SW_ENABLE); this reenables the window. EndIf If Not WinExists($LauncherWindowDesc) Then $previous_returncode = 0 _FileWriteLog(@ScriptDir & "\script.log", "Launcher was closed another way.") Exit EndIf WEnd EndFunc ;==>_launcher Func _copy_to_ramdisk() If $copy_swtor = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Copying "swtor" to ramdisk.') RunWait(@ComSpec & " /c " & $robocopy_path & ' ' & '"' & $swtor_path & '\swtor\."' & ' ' & '"' & $ramdisk_drive & '\swtor\." /e /xf diskcachearena') EndIf If $copy_local = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Copying "appdata\local" to ramdisk.') RunWait(@ComSpec & " /c " & $robocopy_path & ' ' & '"' & $appdata_path & '\swtor\."' & ' ' & '"' & $ramdisk_drive & '\localswtor\." /e') EndIf If $copy_assets = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Copying whole "assets" to ramdisk.') RunWait(@ComSpec & " /c " & $robocopy_path & ' ' & '"' & $swtor_path & '\assets\."' & ' ' & '"' & $ramdisk_drive & '\assets\." /e') EndIf If $copy_assets = 2 Then _FileWriteLog(@ScriptDir & "\script.log", 'Copying selected "assets" to ramdisk.') RunWait(@ComSpec & " /c " & $robocopy_path & ' /job:swtorcopyjob.rcj"') EndIf _FileWriteLog(@ScriptDir & "\script.log", 'Copying files complete.') EndFunc ;==>_copy_to_ramdisk Func _check_files_on_ramdisk() _FileWriteLog(@ScriptDir & "\script.log", 'Making sure everything made it onto the ramdisk.') If $copy_swtor = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Checking "swtor" on ramdisk.') $aSwtor = _recfilelisttoarray($swtor_path & "\swtor", "*", 1, 1, 1, 1) For $i = 1 To $aSwtor[0] If Not StringInStr($aSwtor[$i], "diskcachearena", 0) Then $filesize_orig = FileGetSize($swtor_path & "\swtor\" & $aSwtor[$i]) $filesize_ramd = FileGetSize($ramdisk_drive & "\swtor\" & $aSwtor[$i]) If Not ($filesize_orig = $filesize_ramd) Then _enable_launcherwindow() MsgBox(0, $title, "File size mismatch on file" & @CRLF & $aSwtor[$i] & @CRLF & @CRLF & "File size on ramdisk was " & $filesize_ramd & " bytes." & _ @CRLF & @CRLF & "Cannot continue. Please make sure your ramdisk is big enough to store the files.") Exit EndIf EndIf Next EndIf If $copy_assets = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Checking "assets" on ramdisk.') $aAssets = _recfilelisttoarray($swtor_path & "\assets", "*", 1, 1, 1, 1) For $i = 1 To $aAssets[0] $filesize_orig = FileGetSize($swtor_path & "\assets\" & $aAssets[$i]) $filesize_ramd = FileGetSize($ramdisk_drive & "\assets\" & $aAssets[$i]) If Not ($filesize_orig = $filesize_ramd) Then _enable_launcherwindow() MsgBox(0, $title, "File size mismatch on file" & @CRLF & $aAssets[$i] & @CRLF & @CRLF & "File size on ramdisk was " & $filesize_ramd & " bytes." & _ @CRLF & @CRLF & "Cannot continue. Please make sure your ramdisk is big enough to store the files.") Exit EndIf Next EndIf If $copy_local = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Checking "local\swtor" on ramdisk.') $aLocal = _recfilelisttoarray($appdata_path & "\swtor", "*", 1, 1, 1, 1) For $i = 1 To $aLocal[0] If Not StringInStr($aLocal[$i], "diskcachestatic", 0) And Not StringInStr($aLocal[$i], "diskcachestream", 0) Then $filesize_orig = FileGetSize($appdata_path & "\swtor\" & $aLocal[$i]) $filesize_ramd = FileGetSize($ramdisk_drive & "\localswtor\" & $aLocal[$i]) If Not ($filesize_orig = $filesize_ramd) Then _enable_launcherwindow() MsgBox(0, $title, "File size mismatch on file" & @CRLF & $aLocal[$i] & @CRLF & @CRLF & "File size on ramdisk was " & $filesize_ramd & " bytes." & _ @CRLF & @CRLF & "Cannot continue. Please make sure your ramdisk is big enough to store the files.") Exit EndIf EndIf Next EndIf _FileWriteLog(@ScriptDir & "\script.log", 'Files on ramdisk seem complete.') EndFunc ;==>_check_files_on_ramdisk Func _make_links() _FileWriteLog(@ScriptDir & "\script.log", 'Preparing junction(s).') If $copy_swtor = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Preparing "swtor" junction.') _prepare_swtor() EndIf If $copy_local = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Preparing "appdata\swtor" junction.') _prepare_local_swtor() EndIf If $copy_assets = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Preparing "assets" junction.') _prepare_assets() EndIf If $copy_assets = 2 Then _FileWriteLog(@ScriptDir & "\script.log", 'Preparing "assets" junction.') _prepare_individual_assets() EndIf _FileWriteLog(@ScriptDir & "\script.log", 'Preparing junction(s) complete.') _prepare_runonce() EndFunc ;==>_make_links Func _wait_for_user_action($time) _FileWriteLog(@ScriptDir & "\script.log", '----- Waiting for user action: Start game or exit launcher. -----') While 1 Sleep(100) If ProcessExists("swtor.exe") Then; When the game was launched we need to wait... _FileWriteLog(@ScriptDir & "\script.log", 'Game was started.') $begin = TimerInit() Do Sleep(100) _watch_local() Until Not ProcessExists("swtor.exe"); ... until the game isn't running anymore ... _FileWriteLog(@ScriptDir & "\script.log", 'Game was quit.') _watch_local(1) _exit(); ... before we delete the linked "swtor" directory and move the original back to its place. EndIf If Not WinExists($LauncherWindowDesc) Then; If however the launcher was shut down, it may be because user closed the launcher or started the game If _GetLauncherStatusFromLog($time) = 3 Then ; user closed the launcher _FileWriteLog(@ScriptDir & "\script.log", "User has closed the launcher.") _exit() EndIf EndIf WEnd EndFunc ;==>_wait_for_user_action Func _verify_original_folders_presence() Local $folders, $message $as_pr = _verify_assets_presence() $ls_pr = _verify_local_swtor_presence() $sw_pr = _verify_swtor_presence() If $as_pr = -1 Or $as_pr = 1 Then $folders &= '"assets"|' If $ls_pr = -1 Or $ls_pr = 1 Then $folders &= '"local\swtor"|' If $sw_pr = -1 Or $sw_pr = 1 Then $folders &= '"swtor"' $aSplit = StringSplit($folders, "|") If IsArray($aSplit) Then For $i = 1 To $aSplit[0] If StringLen($aSplit[$i]) >= 1 Then $message &= $aSplit[$i] & ", " EndIf Next $message = StringReplace(StringTrimRight($message, 2), ",", " and", -1) EndIf If $as_pr = -1 Or $ls_pr = -1 Or $sw_pr = -1 Then MsgBox(16, $title, $message & ' folder(s) missing from its / their original and backup location(s).' & @CRLF & @CRLF & _ 'Pointless to continue. Either something went seriously wrong with the script or something else has deleted the folder(s) from it' & "'" & 's / their backup location(s).') Exit EndIf If $as_pr = 1 Or $ls_pr = 1 Or $sw_pr = 1 Then $return = MsgBox(52, $title, $message & ' file(s) and / or folder(s) restored to its / their original location(s).' & @CRLF & @CRLF & "Continue running the script?") If $return = 7 Then Exit EndIf EndIf EndFunc ;==>_verify_original_folders_presence Func _verify_swtor_presence() $return = _restore_swtor() If $return = 0 Then _FileWriteLog(@ScriptDir & "\script.log", '"swtor" folder exists and is not a junction. This is how it should be.') Return (0) EndIf Return ($return) EndFunc ;==>_verify_swtor_presence Func _verify_assets_presence() $return = _restore_assets() If $return = 0 Then _FileWriteLog(@ScriptDir & "\script.log", '"asset(s)" folder and files exist and are not symbolic links or a junction. This is how it should be.') Return (0) EndIf Return ($return) EndFunc ;==>_verify_assets_presence Func _verify_local_swtor_presence() $return = _restore_local_swtor() If $return = 0 Then _FileWriteLog(@ScriptDir & "\script.log", '"local\swtor" folder exists and is not a junction. This is how it should be.') Return (0) EndIf Return ($return) EndFunc ;==>_verify_local_swtor_presence Func _verify_ramdisk_presence() While 1 If Not FileExists($ramdisk_drive) Then $return = MsgBox(52, $title, "Ramdisk not found at the drive letter saved in settings.ini." & @CRLF & @CRLF & "Please make sure your ramdisk configuration hasn't changed or the ramdisk " & _ "software's trial period isn't up." & @CRLF & @CRLF & "You may also select a different ramdisk drive. Run Setup?") If $return = 6 Then _setup() Else Exit EndIf Else ExitLoop EndIf WEnd EndFunc ;==>_verify_ramdisk_presence Func _prepare_individual_assets() If FileExists($swtor_path & "\!back\assets") Then $aFiles = _recfilelisttoarray($swtor_path & "\!back\assets", "*", 1, 0, 1, 1) If IsArray($aFiles) Then _FileWriteLog(@ScriptDir & "\script.log", 'Error prepraring individual assets. "!back\assets" contains files. This shouldn' & "'" & 't be. Cannot continue.') ShellExecute($swtor_path & "\!back\assets") MsgBox(16, $title, 'Error prepraring individual asset files. "!back\assets" already contains files. This shouldn' & "'" & 't be. Cannot continue.' & @CRLF & @CRLF & _ 'Very likely these files are leftovers from a previous run of the script and weren' & "'" & 't restored when the game was closed. Either the script was ' & _ 'aborted or something interfered with the script' & "'" & 's operation.') Exit EndIf EndIf If Not FileExists($swtor_path & "\!back") Then _FileWriteLog(@ScriptDir & "\script.log", '"!back" folder was created.') DirCreate($swtor_path & "\!back") EndIf If Not FileExists($swtor_path & "\!back\assets") Then _FileWriteLog(@ScriptDir & "\script.log", '"!back\assets" folder was created.') DirCreate($swtor_path & "\!back\assets") EndIf For $i = 1 To $aIndvAssets[0][0] If FileExists($swtor_path & "\assets\" & $aIndvAssets[$i][1]) Then $return = FileMove($swtor_path & "\assets\" & $aIndvAssets[$i][1], $swtor_path & "\!back\assets", 0) _SymLink($swtor_path & "\assets\" & $aIndvAssets[$i][1], $ramdisk_drive & "\assets\" & $aIndvAssets[$i][1], 0) EndIf Next EndFunc ;==>_prepare_individual_assets Func _prepare_assets() If FileExists($swtor_path & "\!back\assets") Then $aFiles = _recfilelisttoarray($swtor_path & "\!back\assets", "*", 1, 0, 1, 1) If IsArray($aFiles) Then _FileWriteLog(@ScriptDir & "\script.log", 'Error prepraring assets folder. "!back\assets" contains files. This shouldn' & "'" & 't be. Cannot continue.') ShellExecute($swtor_path & "\!back\assets") MsgBox(16, $title, 'Error prepraring assets folder. "!back\assets" contains files. This shouldn' & "'" & 't be. Cannot continue.' & @CRLF & @CRLF & _ 'Very likely these files are leftovers from a previous run of the script and weren' & "'" & 't restored when the game was closed. Either the script was ' & _ 'aborted or something interfered with the script' & "'" & 's operation.') Exit EndIf EndIf If Not FileExists($swtor_path & "\!back") Then _FileWriteLog(@ScriptDir & "\script.log", 'Creating "!back" folder.') DirCreate($swtor_path & "\!back") EndIf If FileExists($swtor_path & "\!back\assets") Then DirRemove($swtor_path & "\!back\assets", 1) EndIf $return = DirMove($swtor_path & "\assets", $swtor_path & "\!back", 1) If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Moving "assets" to backup location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "assets" to backup location. Aborting') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to move "assets" to backup location. Aborting') Exit EndIf $return = FileCreateNTFSLink($ramdisk_drive & "\assets", $swtor_path & "\assets") If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Linking ramdisk' & "'" & 's "assets" to original location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to link "assets" to original location. Aborting.') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to link "assets" to original location. Aborting.') Exit EndIf EndFunc ;==>_prepare_assets Func _prepare_swtor() If FileExists($swtor_path & "\!back\swtor") Then $aFiles = _recfilelisttoarray($swtor_path & "\!back\swtor", "*", 1, 0, 1, 1) If IsArray($aFiles) Then _FileWriteLog(@ScriptDir & "\script.log", 'Error prepraring "swtor" folder. "' & $swtor_path & '\!back\swtor" contains files. This shouldn' & "'" & 't be. Cannot continue.') ShellExecute($swtor_path & "\!back\swtor") MsgBox(16, $title, 'Error prepraring "swtor" folder. "' & $swtor_path & '\!back\assets" contains files. This shouldn' & "'" & 't be. Cannot continue.' & @CRLF & @CRLF & _ 'Very likely these files are leftovers from a previous run of the script and weren' & "'" & 't restored when the game was closed. Either the script was ' & _ 'aborted or something interfered with the script' & "'" & 's operation.') Exit EndIf EndIf If Not FileExists($swtor_path & "\!back") Then _FileWriteLog(@ScriptDir & "\script.log", 'Creating "!back" folder.') DirCreate($swtor_path & "\!back") EndIf If FileExists($swtor_path & "\!back\swtor") Then DirRemove($swtor_path & "\!back\swtor", 1) EndIf $return = DirMove($swtor_path & "\swtor", $swtor_path & "\!back", 1) If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Moving "swtor" to backup location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "swtor" to backup location. Aborting') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to move "swtor" to backup location. Aborting') Exit EndIf $return = FileCreateNTFSLink($ramdisk_drive & "\swtor", $swtor_path & "\swtor") If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Linking ramdisk' & "'" & 's "swtor" to original location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to link "swtor" to original location. Aborting.') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to link "swtor" to original location. Aborting.') Exit EndIf EndFunc ;==>_prepare_swtor Func _prepare_local_swtor() If FileExists($appdata_path & "\!back\swtor") Then $aFiles = _recfilelisttoarray($appdata_path & "\!back\swtor", "*", 1, 0, 1, 1) If IsArray($aFiles) Then _FileWriteLog(@ScriptDir & "\script.log", 'Error prepraring "local\swtor" folder. "' & $appdata_path & '\!back\swtor" contains files. This shouldn' & "'" & 't be. Cannot continue.') ShellExecute($appdata_path & "\!back\assets") MsgBox(16, $title, 'Error prepraring "local\swtor" folder. "' & $appdata_path & '\!back\swtor" contains files. This shouldn' & "'" & 't be. Cannot continue.' & @CRLF & @CRLF & _ 'Very likely these files are leftovers from a previous run of the script and weren' & "'" & 't restored when the game was closed. Either the script was ' & _ 'aborted or something interfered with the script' & "'" & 's operation.') Exit EndIf EndIf If Not FileExists($appdata_path & "\!back") Then _FileWriteLog(@ScriptDir & "\script.log", 'Creating "local\!back" folder.') DirCreate($appdata_path & "\!back") EndIf If FileExists($appdata_path & "\!back\swtor") Then DirRemove($appdata_path & "\!back\swtor", 1) EndIf $return = DirMove($appdata_path & "\swtor", $appdata_path & "\!back", 1) If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Moving "local\swtor" to backup location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "local\swtor" to backup location. Aborting') ShellExecute($appdata_path) MsgBox(16, $title, 'Unable to move "local\swtor" to backup location. Aborting') Exit EndIf $return = FileCreateNTFSLink($ramdisk_drive & "\localswtor", $appdata_path & "\swtor") If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Linking ramdisk' & "'" & 's "local\swtor" to original location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to link "local\swtor" to original location. Aborting.') ShellExecute($appdata_path) MsgBox(16, $title, 'Unable to link "local\swtor" to original location. Aborting.') Exit EndIf EndFunc ;==>_prepare_local_swtor Func _restore_assets() Local $ret = 0 Do Sleep(100) Until FileExists($swtor_path) If _ReparsePoint($swtor_path & "\assets") = True Then If FileExists($swtor_path & "\!back\assets") Then If _ReparsePoint($swtor_path & "\!back\assets") = False Then $return = DirRemove($swtor_path & "\assets") If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Removing "assets" folder link.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to remove "assets" folder link. Aborting.') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to remove "assets" folder link. Aborting.') Return (-1) EndIf $return = DirMove($swtor_path & "\!back\assets", $swtor_path & "\assets", 0) If $return = 1 Then $ret = 1 _FileWriteLog(@ScriptDir & "\script.log", 'Moving "assets" folder from backup location to original location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "assets" folder from backup location to original location. Aborting') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to move "assets" folder from backup location to original location. Aborting') Return (-1) EndIf EndIf EndIf Else $aFiles = _recfilelisttoarray($swtor_path & "\assets", "*", 1, 0, 1, 1) If IsArray($aFiles) Then _FileWriteLog(@ScriptDir & "\script.log", 'Removing "assets" individual file(s) link(s).') For $i = 1 To $aFiles[0] If _ReparsePoint($swtor_path & "\assets\" & $aFiles[$i]) = True Then $return = FileDelete($swtor_path & "\assets\" & $aFiles[$i]) If Not ($return = 1) Then _FileWriteLog(@ScriptDir & "\script.log", 'Unable to delete linked "assets" file ' & $swtor_path & "\assets\" & $aFiles[$i] & '. Aborting') ShellExecute($swtor_path & "\assets") MsgBox(16, $title, 'Unable to delete linked "assets" file ' & $swtor_path & "\assets\" & $aFiles[$i] & '. Aborting') Return (-1) EndIf EndIf Next EndIf Sleep(1000) $aFiles = _recfilelisttoarray($swtor_path & "\!back\assets", "*", 1, 0, 1, 1) If IsArray($aFiles) Then _FileWriteLog(@ScriptDir & "\script.log", 'Moving "assets" individual file(s) from backup location to original location.') For $i = 1 To $aFiles[0] If Not FileExists($swtor_path & "\assets\" & $aFiles[$i]) Then; ... make sure they're not already in their original path $return = FileMove($swtor_path & "\!back\assets\" & $aFiles[$i], $swtor_path & "\assets", 0); and move them back If Not ($return = 1) Then _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "assets" file ' & $swtor_path & "\assets\" & $aFiles[$i] & ' from backup location to original location. Aborting') ShellExecute($swtor_path & "\assets") MsgBox(16, $title, 'Unable to move "assets" file ' & $swtor_path & "\assets\" & $aFiles[$i] & ' from backup location to original location. Aborting') Return (-1) EndIf EndIf Next $ret = 1 EndIf EndIf If FileExists($swtor_path & "\!back\assets") Then If FileFindFirstFile($swtor_path & "\!back\assets\*.*") = -1 Then DirRemove($swtor_path & "\!back\assets") EndIf EndIf Return ($ret) EndFunc ;==>_restore_assets Func _restore_swtor() Local $ret = 0 Do Sleep(100) Until FileExists($swtor_path) If _ReparsePoint($swtor_path & "\swtor") = True Then $return = DirRemove($swtor_path & "\swtor") If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Removing "swtor" link.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to remove "swtor" link. Aborting') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to remove "swtor" link. Aborting') Return (-1) EndIf $return = DirMove($swtor_path & "\!back\swtor", $swtor_path & "\swtor", 1) If $return = 1 Then $ret = 1 _FileWriteLog(@ScriptDir & "\script.log", 'Moving "swtor" from backup location to original location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "swtor" from backup location to original location. Aborting.') ShellExecute($swtor_path) MsgBox(16, $title, 'Unable to move "swtor" from backup location to original location. Aborting.') Return (-1) EndIf EndIf Return ($ret) EndFunc ;==>_restore_swtor Func _restore_local_swtor() Local $ret = 0 Do Sleep(100) Until FileExists($appdata_path) If _ReparsePoint($appdata_path & "\swtor") = True Then $return = DirRemove($appdata_path & "\swtor") If $return = 1 Then _FileWriteLog(@ScriptDir & "\script.log", 'Removing "local\swtor" link.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to remove "local\swtor" link. Aborting') ShellExecute($appdata_path) MsgBox(16, $title, 'Unable to remove "swtor" link. Aborting') Return (-1) EndIf $return = DirMove($appdata_path & "\!back\swtor", $appdata_path & "\swtor", 1) If $return = 1 Then $ret = 1 _FileWriteLog(@ScriptDir & "\script.log", 'Moving "local\swtor" from backup location to original location.') Else _FileWriteLog(@ScriptDir & "\script.log", 'Unable to move "local\swtor" from backup location to original location. Aborting.') ShellExecute($appdata_path) MsgBox(16, $title, 'Unable to move "local\swtor" from backup location to original location. Aborting.') Return (-1) EndIf EndIf Return ($ret) EndFunc ;==>_restore_local_swtor ;======================================================================================= ; Function Name: _SymLink ; Description: Creates an NTFS Symbolic Link at the specified location ; to another specified location. ; ; Parameter(s): $qLink = The file or directory you want to create. ; $qTarget = The location $qLink should Link to. ; $qIsDirectoryLink = 0 for a FILE symlink (default). ; 1 for a DIRECTORY symlink. ; ; Syntax: _SymLink( $qLink, $qTarget, [$qIsDirectoryLink = 0] ) ; ; Return Value(s): On Success: Returns the path to the created Symlink. ; ; On Failure: 0 and set @Error: ; ; 1 = DLLCall failed, @extended for more info ; 2 = $qLink already exists! ; ; Notes: To remove a Symbolic link, just delete it as you would any ; file or directory. ; ; Author(s): Andrew Bobulsky (RulerOf@{Google's-infamous-mail-service}.com) ; ; Other info: http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=762 ; MSDN: http://msdn.microsoft.com/en-us/library/aa363866(VS.85).aspx ;======================================================================================= Func _SymLink($qLink, $qTarget, $qIsDirectoryLink = 0) If FileExists($qLink) Then SetError(2) Return 0 EndIf DllCall("kernel32.dll", "BOOLEAN", "CreateSymbolicLink", "str", $qLink, "str", $qTarget, "DWORD", Hex($qIsDirectoryLink)) If @error Then SetError(1, @extended, 0) Return EndIf Return $qLink EndFunc ;==>_SymLink