This repository has been archived by the owner on Aug 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Update-ArcDPS.ps1
654 lines (612 loc) · 27.9 KB
/
Update-ArcDPS.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
<#
.SYNOPSIS
Update-ArcDPS
Update ArcDPS and optionally Start Guild Wars 2 after (so you can use
a shortcut to this script instead of the traditional launcher)
.DESCRIPTION
Reaches out to the hosting location for ArcDPS files, enumerates the
directory index, recursively downloads all updated directories, and then
places the base ArcDPS .dll into the Guild Wars 2 bin64 directory
(essentially, search-path hijacking D3D9) before optionally starting Guild
Wars 2 automatically.
.PARAMETER Remove
Removes ArcDPS, all Update-ArcDPS state and update.xml files.
.PARAMETER StartGW
Automatically starts Guild Wars 2 after updating. Without setting this flag,
ArcDPS is updated and installed and the powershell window will hang open,
allowing you to review the output.
.PARAMETER CreateShortcut
Automatically creates a shortcut on your Desktop that will run Update-ArcDPS
with the -StartGW flag enabled for future runs (bypasses Execution Policy)
.PARAMETER AutoUpdate
Check for the latest release of Update-ArcDPS via GitHub API and download
the latest version automatically, exiting with a notice about the update
afterwards.
.PARAMETER InstallDirectory
The path to the Update-ArcDPS XML state file, installation directory, and
more. THe state file is used to track the Guild Wars 2 path and script
version between runs. If it doesn't exist, it will be created.
The default path is in your AppData folder, and the state file is namedpdate_arcdps.xml.
.PARAMETER SearchPath
The path that Update-ArcDPS should use to search for your Guild Wars 2
directory.
.PARAMETER Path
The path to the .
.PARAMETER LiteralPath
Specifies a path to one or more locations. Unlike Path, the value of
LiteralPath is used exactly as it is typed. No characters are interpreted
as wildcards. If the path includes escape characters, enclose it in single
quotation marks. Single quotation marks tell Windows PowerShell not to
interpret any characters as escape sequences.
.NOTES
Name: Update-ArcDPS.ps1
Author: James Harmison
SCRIPT VERSION: 0.5.5
Requires: Powershell v5 or higher.
Version History:
0.5.5 - Fixed TacO update - thanks @Rukko!
0.5.4 - Fixed TacO downloads
0.5.3 - Corrected parsing for TacO website.
0.5.2 - Fixed up missing variable
0.5.1 - Corrected undefined variable
0.5.0 - Correcting download mechanism for deltaconnected site change
0.4.6 - Corrected bug that sometimes resulted in StateFile pathing problems
due to not re-rendering variables into StateFile path
0.4.5 - Corrected path problems with update shortcut
0.4.4 - Corrected a plethora of various bugs during implementation of new
directory location features'
0.4.3 - Provided the ability to choose a directory to install Update-ArcDPS
0.4.2 - Corrected variable type that caused TacO to error when launching
0.4.1 - Added more options around Update-TacO, increased verbosity during
various tasks, and provided for some sane TacO defaults
0.4.0 - Integrated Update-TacO.ps1
0.3.7 - Final fix for permissions - add the addons directory to the
permissions fix for ArcDPS to store its own configuration in.
0.3.6 - Fix for variable escaping under certain path situations for the
last patch.
0.3.5 - Check for write permissions on binpath and correct them if we don't
have access.
0.3.4 - Corrected scriptversion variable (I really need to automate updating
versions between tags)
0.3.3 - Fixed bad verb (Until vs While !)
0.3.2 - Corrected some help pages, corrected behavior in search, and added
auto-update functionality.
0.3.1 - Corrected breaking bugs
0.3 - Removed legacy content (buildtemplates, extras)
0.2.2 - Corrected searching, added option for exact match
0.2.1 - Adjusted bootstrap methodology
0.2 - Enabled bootstrapping - Added Bootstrap-ArcDPS.ps1
Removed requirement to modify execution policy and instead
bypass it on the shortcuts
Made the Gw2-64.exe search abuse traps and throw to make it faster
Significant amount of embarrassing commit history during tests
Updated documentation to reflect changes
0.1 - Initial public release
LICENSE:
MIT License
Copyright (c) 2019 James Harmison <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
.EXAMPLE
PS> Update-ArcDPS.ps1 -StartGW
<< Update-ArcDPS will identify your Guild Wars 2 installation location,
ask you which extras you want enabled, Download ArcDPS recursively,
and save update information in update.xml files in the /bin64 directory,
then save state in %appdata%\update_arcdps.xml and run Guild Wars 2 >>
PS> Update-ArcDPS.ps1 -StartGW
<< Starting Update-ArcDPS a second time will result in a state file being
found and loaded, then the ArcDPS website will be checked for updates
before launching Guild Wars 2 automatically >>
.EXAMPLE
PS> Update-ArcDPS.ps1 -Remove
<< Update-ArcDPS will load your state file if there is one, find Guild Wars
2's working directory if there isn't one, and remove all files dropped
by both ArcDPS and Update-ArcDPS before exiting >>
.LINK
https://www.github.com/solacelost/update-arcdps
#>
#Requires -Version 5
param (
[switch]$Remove,
[switch]$StartGW,
[switch]$CreateShortcut,
[switch]$AutoUpdate,
[string]$InstallDirectory=$(Join-Path "$env:APPDATA" "Update-ArcDPS"),
[string]$SearchPath="C:\Program F*"
)
$scriptversion = '0.5.5'
$needsupdate = $false
$StateFile = Join-Path "$InstallDirectory" update_arcdps.xml
Function Find-GuildWars2() {
Write-Host "Looking for Guild Wars 2 in $SearchPath"
# Reference https://www.vistax64.com/threads/how-to-stopping-a-search-after-the-file-is-found.156738/
# Find the first instance of Gw2-64.exe you can and stop looking
# Look in Program Files and (x86) first
$gw2path = &{
trap {
$error[0].exception.message
continue
}
Get-ChildItem "$SearchPath" -Filter "Gw2-64.exe" -Recurse `
-ErrorAction SilentlyContinue | ForEach-Object {
throw $_.DirectoryName
}
}
# Look in all drive letters globally if we didn't find it
if ($($gw2path | Measure-Object).Count -eq 0) {
Write-Host "Unable to find in expected path, expanding search."
$gw2path = &{
Get-CimInstance win32_logicaldisk -Filter "DriveType='3'" | `
ForEach-Object {
trap {
$error[0].exception.message
continue
}
$drive_letter = $_.DeviceID
Write-Host "Checking drive $drive_letter"
Get-ChildItem "$drive_letter\*" -Filter "Gw2-64.exe" -Recurse `
-ErrorAction SilentlyContinue | ForEach-Object {
throw $_.DirectoryName
}
}
}
}
Write-Host "Identified Guild Wars 2 in the following locations:"
Write-Host "$gw2path"
$numresults = $($gw2path | Measure-Object).Count
if ($numresults -eq 0) {
# Hard throw the error and abort if we couldn't find it
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
Throw "Unable to identify Guild Wars 2 location."
} elseif ($numresults -ne 1) {
# It would appear that we found GW2 on multiple locations
$correct = $false
while ( ! $correct) {
Write-Host "Select the installation you would like to add" `
"ArcDPS to from the following choices by their number:"
$gw2path | ForEach-Object {
Write-Host ($gw2path.indexof($_) + 1)") $_"
}
$selection = ($(Read-Host -Prompt "Selection") -as [int]) - 1
if ($selection -eq -1 -or $selection -ge $numresults) {
Write-Host "Please select an index from the list provided."
} else {
Write-Output $gw2path[$selection]
$correct = $true
}
}
} else {
Write-Output "$gw2path"
}
}
Function Get-YesOrNo([string]$Prompt, [switch]$DefaultYes) {
$correct = $false
While (!$correct) {
if ($DefaultYes) {
$yesorno = $(Read-Host -Prompt "$Prompt (Y/N Default: Y)").ToUpper()
} else {
$yesorno = $(Read-Host -Prompt "$Prompt (Y/N Default: N)").ToUpper()
}
Switch -Exact ($yesorno) {
"" {
$DefaultYes
$correct = $true
break
}
"N" {
$false
$correct = $true
break
}
"Y" {
$true
$correct = $true
break
}
Default {
Write-Host "'$yesorno' is not a valid option."
if ($DefaultYes) {
Write-Host "To answer in the negative, type the letter 'n' and press 'Enter.'"
Write-Host "To answer in the affirmative, either press 'Enter' or type the letter 'y' and press 'Enter.'"
} else {
Write-Host "To answer in the negative, either press 'Enter' or type the letter 'n' and press 'Enter.'"
Write-Host "To answer in the affirmative, type the letter 'y' and press 'Enter.'"
}
break
}
}
}
}
Function Create-Shortcuts {
Write-Host "Creating Desktop shortcut"
$ShortcutFile = "$DesktopDir\Guild Wars 2 - ArcDPS.lnk"
$WScriptShell = New-Object -ComObject WScript.Shell
$Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)
$Shortcut.TargetPath = "%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe"
$ScriptLocation = $(Join-Path $InstallDirectory Update-ArcDPS.ps1)
$Shortcut.Arguments = "-ExecutionPolicy Bypass -File `"$ScriptLocation`" -InstallDirectory `"$InstallDirectory`" -StartGW"
$Shortcut.WorkingDirectory = $state.binpath
$IconLocation = $(Resolve-Path $(Join-Path $state.binpath "..\Gw2-64.exe")).Path
$Shortcut.IconLocation = "$IconLocation"
$Shortcut.Save()
if ($state.updatetaco) {
$args_to_pass = @('-CreateShortcut', '-InstallDirectory', "$InstallDirectory")
if ($load_taco_defaults) {
$args_to_pass += '-SaneConfig'
}
& powershell.exe -ExecutionPolicy Bypass -File "$InstallDirectory/Update-TacO.ps1" $args_to_pass
}
}
Function Update-StateVersion {
# Legacy stuff - ArcDPS no longer has extras or buildtemplates
if ( $state.ContainsKey('enablers') ) {
$state.Remove('enablers')
}
if ( ! $state.ContainsKey('version') ) {
$state['version'] = '0.3'
}
if ( ! $state.ContainsKey('autoupdate') ) {
if ($AutoUpdate) {
$state['autoupdate'] = $true
} else {
Write-Host "Update-ArcDPS is now capable of keeping itself updated."
$correct = $false
$state['autoupdate'] = $(
Get-YesOrNo -prompt "Would you like to enable automatic update of Update-ArcDPS?"
)
}
}
if ($state.version -ne $scriptversion) {
if ($state.version.split('.')[1] -eq '3') {
Write-Host "Update-ArcDPS is now capable of updating and launching TacO with Tekkit's Workshop marker pack enabled."
$state['updatetaco'] = $(
Get-YesOrNo -prompt "Would you like to enable Update-ArcDPS to manage TacO?" -DefaultYes
)
$state['version'] = "0.4.0"
}
if ($state.version -eq "0.4.0") {
if ($state['updatetaco']) {
Write-Host "Update-ArcDPS can load some sane defaults into your TacO settings to reduce the screen clutter. You can always reenable individual settings yourself."
$load_taco_defaults = $(
Get-YesOrNo -prompt "Would you like to load sane default options for TacO?" -DefaultYes
)
Write-Host "Update-ArcDPS no longer assumes you want to launch TacO every time."
$state['launchtaco'] = $(
Get-YesOrNo -prompt "Would you like to enable TacO autostart with the same shortcut you update it with?" -DefaultYes
)
}
$state['version'] = '0.4.1'
}
if ($state.version -eq "0.4.1" -or $state.version -eq "0.4.2") {
$vestigal_file = $(Join-Path "$env:APPDATA" "Bootstrap-ArcDPS.ps1")
if (Test-Path "$vestigal_file") {
Remove-Item -Force -Path "$vestigal_file" -EA 0
}
Write-Host "Update-ArcDPS has now moved its default installation location to enable cleaner file storage."
$move_update_arcdps = $(
Get-YesOrNo -prompt "Would you like to move Update-ArcDPS into a unique folder to keep the files more contained?" -DefaultNo
)
if ($move_update_arcdps) {
Add-Type -AssemblyName System.Windows.Forms
# Default installation directory is a subfolder underneath APPDATA
$InstallDirectory = $(Join-Path "$env:APPDATA" "Update-ArcDPS")
New-Item "$InstallDirectory" -ItemType "directory" -EA 0 | Out-Null
# Prompt for an alternate installation directory
$BrowserText = "Pick the installation location for Update-ArcDPS and press OK, or just Cancel to select the default ($InstallDirectory)"
$FileBrowser = New-Object System.Windows.Forms.FolderBrowserDialog -Property @{
SelectedPath = "$InstallDirectory"
Description = "$BrowserText"
}
$ButtonPressed = $FileBrowser.ShowDialog()
# If you picked a different directory, remove our other created directory
if ($ButtonPressed -eq 'OK') {
if ($FileBrowser.SelectedPath -ne "$InstallDirectory") {
Remove-Item "$InstallDirectory" -recurse -force
$InstallDirectory = $FileBrowser.SelectedPath
}
}
$OldFiles = @(
"Update-ArcDPS.ps1",
"update_arcdps.xml",
"Update-TacO.ps1",
"Update-TacO",
"TacOConfig_sane.xml"
)
Write-Host "Moving old files and folders into $InstallDirectory"
ForEach ($OldFile in $OldFiles) {
$OldFilePath = $(Join-Path "$env:APPDATA" $OldFile)
if (Test-Path "$OldFilePath") {
Write-Host "$OldFilePath --> $(Join-Path $InstallDirectory $OldFile)"
Move-Item "$OldFilePath" "$InstallDirectory"
}
}
Create-Shortcuts
Write-Host ""
Write-Host "You should relaunch the script via the new shortcut (Which you're free to rename/move now) on the Desktop."
$state['version'] = '0.4.3'
$state['install_directory'] = "$InstallDirectory"
$StateFile = Join-Path "$InstallDirectory" update_arcdps.xml
$state | Export-Clixml -Path "$StateFile"
pause
exit
} else {
$InstallDirectory = "$env:APPDATA"
$state['install_location'] = "$InstallDirectory"
Create-Shortcuts
}
$state['version'] = '0.4.3'
}
}
# This is where update code should go for version-specific major changes
# Ex:
# if ($state['version'] -ne $scriptversion) {
# if ($state['version'] -eq "0.3.2") {
# <post 0.3.2 update code here>
# $state['version'] = "0.3.3"
# }
# if ($state['version'] -eq "0.3.3") {
# <post 0.3.3 update code here>
# $state['version'] = "0.4.0"
# }
# <etc until version catches up to $scriptversion>
# }
$state['version'] = $scriptversion
$StateFile = Join-Path "$InstallDirectory" update_arcdps.xml
$state | Export-Clixml -path $StateFile
}
$DesktopDir = [system.environment]::GetFolderPath("Desktop")
if ($Remove) {
# Import the statefile and remove it, or find GW2 to identify Arc files in
if (Test-Path $statefile) {
Write-Host "Identified previous choices saved in $statefile`n"
$state = Import-Clixml -Path $statefile
Write-Host "Removing $statefile"
Remove-Item -Force -Path $statefile
# Here is where I could handle version conflicts in state in the future
} else {
$state = @{}
$state['binpath'] = $(Find-GuildWars2) + '\bin64\'
$state['version'] = $scriptversion
}
# Remove this script
Remove-Item -Force -Path $MyInvocation.MyCommand.Definition -EA 0
# Remove Update-TacO.ps1
if (Test-Path "$PSScriptRoot/Update-TacO.ps1") {
& powershell.exe -ExecutionPolicy Bypass -File "$PSScriptRoot/Update-TacO.ps1" -InstallDirectory $InstallDirectory -Remove
}
if (Test-Path "$PSScriptRoot/TacOConfig_sane.xml") {
Remove-Item -Force -Path "$PSScriptRoot/TacOConfig_sane.xml" -EA 0
}
# Remove anything left behind if we're in a proper subdirectory
if ($(Split-Path $PSScriptRoot -Leaf) -eq "Update-ArcDPS") {
Remove-Item -Force -Recurse -Path $PSScriptRoot -EA 0
}
# Remove the shortcut
$ShortcutFile = "$DesktopDir\Guild Wars 2 - ArcDPS.lnk"
if (Test-Path $ShortcutFile) {
Write-Host "Removing $ShortcutFile"
Remove-Item -Force -Path $ShortcutFile
}
# These are the main files that we're looking to remove
$arcfiles = @( "README-links.txt",
"arcdps.ini",
"d3d9.dll",
"d3d9.dll.md5sum",
"update.xml"
)
# These are the (historical) extra directories
$arcdirs = @( "buildtemplates", "extras" )
# Remove all of the ArcDPS main files
$arcfiles | ForEach-Object {
$arcfile = $state.binpath + $_
if (Test-Path $arcfile) {
Write-Host ("Removing $arcfile")
Remove-Item -Force -Path $arcfile
}
}
# Enumerate everything in the subdirectories
$arcdirs | ForEach-Object {
Get-ChildItem -ErrorAction SilentlyContinue ($state.binpath + $_) | `
select -ExpandProperty Name | ForEach-Object {
# and remove them from the base bindir, if they've been enabled
$arcfile = $state.binpath + $_
if (Test-Path $arcfile) {
Write-Host ("Removing $arcfile")
Remove-Item -Force -Path $arcfile
}
}
# Also remove the subdirectory
$arcfile = $state.binpath + $_
if (Test-Path $arcfile) {
Write-Host ("Removing directory $arcfile")
Remove-Item -Force -Recurse -Path $arcfile
}
}
Write-Host "ArcDPS removed!"
pause
EXIT
}
# Maintain state in a dedicated xml file so we don't look for GW2 or prompt for
# questions after initial setup
$OldStateFile = $(Join-Path "$env:APPDATA" update_arcdps.xml)
if (-not $(Test-Path "$StateFile") -and $(Test-Path "$OldStateFile")) {
$oldstate = Import-Clixml -Path "$OldStateFile"
if (-not $($oldstate.ContainsKey('install_directory'))) {
Write-Host "Identified old-version previous choices saved in $OldStateFile`n"
$state = $oldstate
}
Update-StateVersion
} elseif (Test-Path "$StateFile") {
Write-Host "Identified previous choices saved in $StateFile`n"
$state = Import-Clixml -Path "$StateFile"
Update-StateVersion
} else { # If it's not already there, we'll go ahead and do initial setup
$state = @{}
$state['binpath'] = "$(Find-GuildWars2)\bin64\"
$state['version'] = $scriptversion
$state['install_directory'] = "$InstallDirectory"
if ($AutoUpdate) {
$state['autoupdate'] = $true
} else {
Write-Host "Update-ArcDPS is capable of keeping itself updated."
$state['autoupdate'] = $(
Get-YesOrNo -prompt "Would you like to enable AutoUpdate?"
)
Write-Host "Update-ArcDPS can also update GW2TacO with Tekkit's Workshop marker pack enabled."
$state['updatetaco'] = $(
Get-YesOrNo -prompt "Would you like to enable Update-ArcDPS to manage TacO and Tekkit's updates?" -DefaultYes
)
if ($state['updatetaco']) {
Write-Host "Update-ArcDPS can load some sane defaults into your TacO settings to reduce the screen clutter. You can always reenable individual settings yourself."
$load_taco_defaults = $(
Get-YesOrNo -prompt "Would you like to load these sane defaults?" -DefaultYes
)
Write-Host "Update-ArcDPS can also launch TacO for you every time you start the game."
$state['launchtaco'] = $(
Get-YesOrNo -prompt "Would you like to enable TacO autostart?" -DefaultYes
)
}
}
$StateFile = Join-Path "$InstallDirectory" update_arcdps.xml
$state | Export-Clixml -path $StateFile
}
if ("$OldStateFile" -ne $null -and $(Test-Path "$OldStateFile")) {
Remove-Item -Force "$OldStateFile" -EA 0 | Out-Null
}
if ($state.autoupdate -or $AutoUpdate) {
Write-Host "Checking for updates to Update-ArcDPS script"
$UpdateInfo = $(Invoke-WebRequest https://api.github.com/repos/solacelost/update-arcdps/releases/latest)
$LatestVersion = $(ConvertFrom-Json $UpdateInfo.content).tag_name
if ($LatestVersion -ne $scriptversion) {
Write-Host "Update-ArcDPS version $LatestVersion is available. Downloading." -NoNewLine
Invoke-WebRequest `
-URI https://github.com/solacelost/update-arcdps/archive/$LatestVersion.zip `
-OutFile $PSScriptRoot/Update-ArcDPS.zip
Write-Host "." -NoNewLine
Expand-Archive `
-path $PSScriptRoot/Update-ArcDPS.zip `
-DestinationPath $PSScriptRoot
Write-Host "."
Copy-Item `
$PSScriptRoot/update-arcdps-$LatestVersion/*.ps1 `
$PSScriptRoot/ `
-Exclude Bootstrap-ArcDPS.ps1
Copy-Item `
$PSScriptRoot/update-arcdps-$LatestVersion/TacOConfig_sane.xml `
$PSScriptRoot/
Remove-Item $PSScriptRoot/update-arcdps-$LatestVersion -recurse
Remove-Item $PSScriptRoot/Update-ArcDPS.zip
Write-Host "New version of Update-ArcDPS is installed. Please rerun this script via your normal shortcut."
pause
exit
}
}
Write-Host "Verifying file permissions on necessary directories"
$testpath = $($state.binpath + "/test.txt")
Write-Output "Test" | Out-File -EA 0 -FilePath $testpath
if ( $(Get-Content $testpath -EA SilentlyContinue | Measure-Object).count -eq 0) {
$Acl = Get-Acl $state.binpath
$UserPrincipal = $(Get-Acl $env:appdata).Owner
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($UserPrincipal, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$Acl.SetAccessRule($Ar)
$modify_path = $state.binpath
$modify_path_2 = $(Resolve-Path $(Join-Path $state.binpath ".."))
$modify_path_3 = $(Join-Path $modify_path_2 "addons")
$xml_path = $($env:temp + "/acl.xml")
$Acl | Export-Clixml -path "$xml_path"
Write-Host "We need to enable permissions for you to be able to install/update ArcDPS.`n"
Write-Host "Please accept the Windows UAC prompt when it appears to enable this functionality."
pause
# This extremely long line renders our variables out and updates filesystem
# permissions for the binpath and binpath/../addons directories (both are
# necessary for the ability to update and run ArcDPS)
Start-Process -FilePath powershell.exe -Verb RunAs -ArgumentList "`$Acl = `$(Import-Clixml '$xml_path') ; Set-Acl '$modify_path' `$Acl ; New-Item -Path '$modify_path_2' -Name 'addons' -ItemType 'directory' -EA 0 ; Set-Acl '$modify_path_3' `$Acl"
Write-Host "The directory permissions should have been modified by the pop-up window.`n"
Write-Host "We need to exit and relaunch the script to enable access."
pause
Remove-Item $xml_path
Remove-Item $testpath
exit
}
Remove-Item $testpath
$SetupScript = "$DesktopDir\Update-ArcDPS Setup.lnk"
if (Test-Path $SetupScript) {
Write-Host "Removing Bootstrapped setup shortcut"
Remove-Item -Force -Path $SetupScript
}
# Download ArcDPS
$utf8 = New-Object -TypeName System.Text.UTF8Encoding
$src = 'https://www.deltaconnected.com/arcdps/x64/'
$dst = $state.binpath
# To our GW2/bin64 directory
$file = 'd3d9.dll'
$sumfile = "$file.md5sum"
# Save the expected md5sum as a string
$arcdps_expected_sum = $utf8.GetString(
$(Invoke-WebRequest -UseBasicParsing -Uri "$src$sumfile").Content
).Split(' ')[0]
$md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
$ErrorActionPreference = "SilentlyContinue"
$installed_sum = $(Get-FileHash $(Join-Path $dst '/d3d9.dll')).Hash.ToLower()
$ErrorActionPreference = "Continue"
If ( $installed_sum -eq $arcdps_expected_sum ) {
Write-Host "Existing ArcDPS needs no update"
} Else {
Write-Host "Downloading update to ArcDPS"
$arcdps = Invoke-WebRequest -UseBasicParsing -Uri "$src$file"
Write-Host "Validating update checksum"
$arcdps_sum = -Join $($md5.ComputeHash($arcdps.content) | ForEach {'{0:x2}' -f $_ })
If ( $arcdps_expected_sum -eq $arcdps_sum ) {
Write-Host "Expected checksum matches. Saving update to ArcDPS"
[System.IO.File]::WriteAllBytes($(Join-Path $dst '/d3d9.dll'), $arcdps.content)
} Else {
Write-Error -Message "ArcDPS download did not match expected MD5 sum. Not saving file. Please try again later." `
-Category MetadataError -ErrorID MD5 -TargetObject $arcdps.content
}
}
# Create the shortcut if you asked for it
if ($CreateShortcut) {
Write-Host ""
Create-Shortcuts
}
# Start Guild Wars 2 if you asked for it
if ($StartGW) {
Write-Host ""
Write-Host "Starting Guild Wars 2"
& $(Resolve-Path $(Join-Path "$dst" "../Gw2-64.exe")).Path
Write-Host "Starting Update-TacO"
if ($state.updatetaco) {
if (! $(Test-Path "$PSScriptRoot/Update-TacO.ps1")) {
Invoke-WebRequest `
-URI https://raw.githubusercontent.com/solacelost/update-arcdps/$scriptversion/Update-TacO.ps1 `
-OutFile "$PSScriptRoot/Update-TacO.ps1"
Invoke-WebRequest `
-URI https://raw.githubusercontent.com/solacelost/update-arcdps/$scriptversion/TacOConfig_sane.xml `
-OutFile "$PSScriptRoot/TacOConfig_sane.xml"
}
$args_to_pass = @('-InstallDirectory', "$InstallDirectory")
if ($load_taco_defaults) {
$args_to_pass += '-SaneConfig'
}
if ($state['launchtaco']) {
$args_to_pass += '-StartTacO'
}
& powershell.exe -ExecutionPolicy Bypass -File "$PSScriptRoot/Update-TacO.ps1" $args_to_pass
}
} else {
pause
}