-
Notifications
You must be signed in to change notification settings - Fork 1
/
VaganteModLoader.ps1
172 lines (145 loc) · 7.52 KB
/
VaganteModLoader.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
Import-Module -Name .\Anybox\Anybox.psm1
$ModLoaderTempFolderPath = ".\ModLoaderTempFolder"
$ModsFolder = ".\Mods"
$ExtractorPath = ".\vagante-extract.exe"
$VraPath = ".\data.vra"
$BackupVraPath = ".\dataBackup.vra"
$UpdateDetectionDataPath = ".\updateDetectionData.doNotDelete.txt"
$UpdateDetectionModdedHashPrepend = "ModdedVraHash: "
#This creates a popup box, and asks the user to choose which mod will prevail when two mods try to change the same file.
function Resolve-ModConflict {
param([string]$DuplicateFile, [string]$FirstMod, [string]$SecondMod)
$Anybox = New-Object Anybox.Anybox
$Anybox.Icon = 'Question'
$Anybox.Title = "Mod conflict detected"
$Anybox.Message = "Two mods are trying to change the same file (" + $FileRelativePath + ").`r`n Choose which one you want to stay:"
$Anybox.FontSize = 14
$Anybox.ContentAlignment = 'Center'
$Anybox.Buttons = @(
New-AnyboxButton -Name "UseFirstMod" -Text ("Use " + $FirstMod + "'s version")
New-AnyboxButton -Name "UseSecondMod" -Text ("Use " + $SecondMod + "'s version")
New-AnyboxButton -Name "Cancel" -Text 'Cancel mod loading' -IsDefault
)
$Anybox.DefaultButton = 'Yes'
$Anybox.CancelButton = 'No'
$Anybox.ButtonRows = 2
$Anybox.Topmost = $true
$Response = $Anybox | Show-Anybox
if ($Response['UseFirstMod'] -eq $true) {
return $FirstMod
}
elseif ($Response['UseSecondMod'] -eq $true) {
return $SecondMod
}
elseif ($Response['Cancel'] -eq $true) {
return "Cancel"
}
}
function Write-UpdateDetectionFile {
param([string]$ModdedVraHash)
$Output = "#Please don't change anything in this file - that could mess up update detection and leave you with unwanted mods and/or an unupdated data.vra# `r`n"
$Output = $Output + $UpdateDetectionModdedHashPrepend + $ModdedVraHash + "`r`n"
$Output | Out-File -FilePath $UpdateDetectionDataPath
}
#Checks if the data.vra is different from both the backup and the latest modded data.vra
#If that's true, it means one of two things:
#The data.vra was updated by the user, but not using the modloader (unlikely)
#The data.vra was updated by steam (more likely)
function CheckForUpdates {
$BackupVraHash = (Get-FileHash $BackupVraPath -Algorithm MD5).Hash
$VraHash = (Get-FileHash $VraPath -Algorithm MD5).Hash
$ModdedVraHash = ""
foreach($Line in Get-Content $UpdateDetectionDataPath)
{
if($Line.Contains($UpdateDetectionModdedHashPrepend)){
$ModdedVraHash = $Line.Substring($UpdateDetectionModdedHashPrepend.Length)
}
}
return ($VraHash -ne $ModdedVraHash -and $VraHash -ne $BackupVraHash)
}
#Main function
function LoadMods {
if(Test-Path $ModLoaderTempFolderPath){ #If temporary folder exists, delete it
Remove-Item $ModLoaderTempFolderPath -Recurse
}
if(!(Test-Path $ModsFolder)){ #If Mods folder doesn't exist yet, create it and exit
New-item $ModsFolder -itemtype directory
exit
}
$Mods = Get-ChildItem -Directory $ModsFolder
$FilesMarkedForModding = @{}
#Loop through all folders inside Mods/
foreach($RootFolder in $Mods){
"Mod found: " + $RootFolder.Name
$ModdedFiles = Get-ChildItem -File -Recurse $RootFolder.FullName;
foreach($File in $ModdedFiles){
if($File.Name -ne "ignoreme.ignore" -and $File.Name -ne "readme.txt"){
"Found modded file in " + $ModdedFolder.Name + ": " + $File.Name
#This was the only way I found to get a relative path from a path that is not the current path
$FileRelativePath = $File.FullName.Replace($RootFolder.FullName + "\", "")
$conflictResolution = ""
#If the file is already in the list of modded files, resolve the conflict
if($FilesMarkedForModding.ContainsKey($FileRelativePath)){
"Two mods are trying to change the same file: " + $FileRelativePath
$conflictResolution = Resolve-ModConflict -DuplicateFile $FileRelativePath -FirstMod $FilesMarkedForModding.Item($FileRelativePath) -SecondMod $RootFolder.Name
if($conflictResolution -eq "Cancel"){
exit
} else {
$FilesMarkedForModding.Item($FileRelativePath) = $conflictResolution
}
}
else { #Else, add the file to the list, along with the name of the mod that will change it
$FilesMarkedForModding.Add($FileRelativePath, $RootFolder.Name)
}
}
}
}
"`r`nHere are what files were changed (Name column) by which mods (Value column)"
$FilesMarkedForModding
if($FilesMarkedForModding.Count -eq 0){
"No mods found!"
[System.Windows.MessageBox]::Show("No mod folders were found inside Mods. Are you sure you installed the mods correctly? `r`nFor example, if your mod only changes rooms.json, the directory tree needs to look kinda like this:`r`nMods\`r`n--->RandomModName`r`n------>rooms.json",'No mods found','OK','Info') | Out-Null
exit
}
"Unpacking data.vra..."
$BackupExists = Test-Path $BackupVraPath
$GameWasUpdated = $false
if(!$BackupExists){
Copy-Item $VraPath $BackupVraPath
$GameWasUpdated = $true
}
#If the backup exists and there's a update detection file, check for updates
if($BackupExists -and (Test-Path $UpdateDetectionDataPath)){
$GameWasUpdated = CheckForUpdates
}
#If the game was updated, we need to update the backup
if($GameWasUpdated){
"The game apparently was updated. Updating data.vra backup."
Copy-Item $VraPath $BackupVraPath
}
#This just didn't work for some reason, so I put out-null instead
#If anyone knows how to properly redirect the output of Vagante-Extract to a file, that'd help with eventual troubleshooting
& $extractorPath extract $BackupVraPath $ModLoaderTempFolderPath | Out-Null #| Out-File -FilePath $VaganteExtractLogPath
"data.vra unpacked. Placing modded files..."
foreach($File in $FilesMarkedForModding.GetEnumerator()){
$Destination = Join-Path $ModLoaderTempFolderPath $File.Name
$Source = Join-Path $ModsFolder $File.Value
$Source = Join-Path $Source $File.Name
#if the file exists in Mods/RandomMod but doesn't exist inside the original data.vra, something is wrong
if(!(Test-Path $Destination)) {
"Invalid mod file detected."
[System.Windows.MessageBox]::Show("The mod " + $File.Value + "tried to replace a file that doesn't exist on the game: " + $File.Name + ".`r`nThis file will be ignored and won't be inserted into data.vra.`r`nPlease inform the mod maker about this.",'Invalid File Replacement','OK','Info') | Out-Null
}
else {
Copy-Item -Path $Source -Destination $Destination
}
}
"Repacking data.vra with the modded files..."
& $ExtractorPath archive $ModLoaderTempFolderPath $VraPath | Out-Null #| Add-Content -Path $VaganteExtractLogPath #This just didn't work for some reason, so I put out-null instead
#Now we update the update detection file with the latest modded content
$ModdedVraHash = (Get-FileHash $VraPath -Algorithm MD5).Hash
Write-UpdateDetectionFile -ModdedVraHash $ModdedVraHash
Remove-Item $ModLoaderTempFolderPath -Recurse
"Done!"
}
LoadMods