-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMainFunctions.vb
More file actions
358 lines (297 loc) · 14.1 KB
/
MainFunctions.vb
File metadata and controls
358 lines (297 loc) · 14.1 KB
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
Imports System.IO
Imports System.Text
Imports System.Threading
Imports System.Text.RegularExpressions
Public Module MainFunction
Async Function ScanModFolder(TopModFolderPath As String, SkipDisabledPacks As Boolean) As Task(Of Dictionary(Of String, CustomSong))
'This function scans all song pack folders and then collects relavant data into a dictionary collection
Dim SongDict As New Dictionary(Of String, CustomSong)
Dim ModFolders() As String
ModFolders = Directory.GetDirectories(TopModFolderPath)
Dim SongRegex As New Regex("^pv_(\d{3,4})\.")
For i As Integer = 0 To ModFolders.Length - 1
Dim ModName As String, ModNameExplicit As Boolean, ModEnabled As Boolean
Dim ConfigPath As String = ModFolders(i) & "\config.toml"
Try 'Get mod name from config.toml
ModName = ""
Dim ConfigArr() As String = File.ReadAllLines(ConfigPath)
For Each str As String In ConfigArr
Dim param As String = Trim(Split(str, "=")(0))
If param = "enabled" Then
ModEnabled = Split(str, "=")(1).Trim({" "c, """"c})
If ModEnabled = False AndAlso SkipDisabledPacks = True Then
Exit For
End If
ElseIf param = "name" Then
ModName = Split(str, "=")(1).Trim({" "c, """"c})
Exit For
End If
Next
If SkipDisabledPacks = True AndAlso ModEnabled = False Then
Continue For
End If
If ModName = "" Then
ModName = Path.GetFileName(ModFolders(i))
ModNameExplicit = False
Else
ModNameExplicit = True
End If
Catch ex As FileNotFoundException
Continue For 'If this file is missing, then folder is not a proper mod folder
Catch ex As Exception
MsgBox("Error reading config file:" & vbCrLf & ConfigPath)
Exit Function
End Try
Dim modDBpath As String = ModFolders(i) & "\rom\mod_pv_db.txt"
If File.Exists(modDBpath) Then '
Dim DBarr() As String = File.ReadAllLines(modDBpath)
For j As Long = 0 To DBarr.LongLength - 1
Dim LineStr As String = DBarr(j)
Dim RegMatch As Match = SongRegex.Match(LineStr)
If RegMatch.Success = True Then
Dim ID As String = RegMatch.Groups(1).Value 'returns numeric portion of string
If CustomSong.OfficialSongCheck(ID) = False Then
If SongDict.ContainsKey(ID) = False Then
SongDict.Add(ID, New CustomSong(ID))
SongDict(ID).ModName = ModName
If ModNameExplicit = False Then
SongDict(ID).LogError("Note: Mod name not specified in .toml file.")
End If
SongDict(ID).FolderPath = ModFolders(i)
SongDict(ID).dbPath = modDBpath
ParseSongParameter(ID, SongDict, DBarr(j), _CustomSongParameters)
Else
If SongDict(ID).dbPath <> modDBpath Then
SongDict(ID).dbPath = modDBpath
End If
ParseSongParameter(ID, SongDict, DBarr(j), _CustomSongParameters)
End If
End If
End If
Next j
End If
Next i
Dim vanillaDB As String = _ini.EXEfolder & "\vanilla_pv_db.txt"
If File.Exists(vanillaDB) Then '
Dim DBarr() As String = File.ReadAllLines(vanillaDB)
For j As Long = 0 To DBarr.LongLength - 1
Dim LineStr As String = DBarr(j)
Dim RegMatch As Match = SongRegex.Match(LineStr)
Dim ID As String = RegMatch.Groups(1).Value 'returns numeric portion of string
If SongDict.ContainsKey(ID) = False Then
SongDict.Add(ID, New CustomSong(ID))
SongDict(ID).ModName = "Vanilla"
'SongDict(ID).FolderPath = ModFolders(i)
SongDict(ID).dbPath = vanillaDB
ParseSongParameter(ID, SongDict, DBarr(j), _CustomSongParameters)
ParseSongParameter(ID, SongDict, DBarr(j), _CustomSongParameters)
Else
If SongDict(ID).dbPath <> vanillaDB Then
SongDict(ID).dbPath = vanillaDB
End If
ParseSongParameter(ID, SongDict, DBarr(j), _CustomSongParameters)
End If
Next j
End If
Dim SongOffsets As String = _ini.EXEfolder & "\suggested_song_offsets.csv"
If File.Exists(SongOffsets) Then '
Dim StrArr() As String = File.ReadAllLines(SongOffsets)
For j As Long = 0 To StrArr.LongLength - 1
Dim LineStr As String = StrArr(j)
Dim lineArr() = LineStr.Split(","c)
Dim ID As String = lineArr(1)
Dim offset As String = lineArr(2)
If SongDict.ContainsKey(ID) = True Then
SongDict(ID).SuggestedSongOffset = offset
End If
Next j
End If
Return SongDict
End Function
Function ParseSongParameter(ID As String, SongDict As Dictionary(Of String, CustomSong), DBstr As String, CustomParameters As HashSet(Of String)) As String
Dim ParamAndVal As String = DBstr.Substring(DBstr.IndexOf(".") + 1) 'removes pv_1234.
Dim SongParam As String = Split(ParamAndVal, "=")(0)
Dim ParamVal As String
Try
ParamVal = Split(ParamAndVal, "=")(1)
Catch ex As Exception
ParamVal = ""
End Try
Dim SongObj As CustomSong = SongDict(ID)
Select Case SongParam
Case "song_name_en"
SongObj.SongName = ParamVal
SongObj.StoreCustomValue(SongParam, ParamVal)
Case "difficulty.extreme.1.level"
SongObj.AddDifficulty(ParamVal, CustomSong.Difficulties.ExEx)
Case "difficulty.extreme.0.level"
SongObj.AddDifficulty(ParamVal, CustomSong.Difficulties.Extreme)
Case "difficulty.hard.0.level"
SongObj.AddDifficulty(ParamVal, CustomSong.Difficulties.Hard)
Case "difficulty.normal.0.level"
SongObj.AddDifficulty(ParamVal, CustomSong.Difficulties.Normal)
Case "difficulty.easy.0.level"
SongObj.AddDifficulty(ParamVal, CustomSong.Difficulties.Easy)
Case Else
If CustomParameters.Contains(SongParam) Then
SongObj.StoreCustomValue(SongParam, ParamVal)
End If
End Select
Return SongParam
End Function
Function ReadOverlayTemplate(templateStr As String) As HashSet(Of String)
Dim paramSet As New HashSet(Of String)
Dim regStr As String = "\{([^}]+)\}"
Dim paramMatches As MatchCollection = Regex.Matches(templateStr, regStr)
For Each match As Match In paramMatches
paramSet.Add(match.Groups(1).Value)
Next
Return paramSet
End Function
Function ParseOverlayText(templateStr As String, songID As String) As String
Dim DisplayStr As String = templateStr
For Each paramStr As String In _CustomSongParameters
DisplayStr = DisplayStr.Replace("{" & paramStr & "}", _FullSongDict(songID).GetCustomValue(paramStr))
Next
Return DisplayStr
End Function
Public Sub StartMainRoutine()
_MonitorGame = True 'global var
_RefreshOvlConfig = False
Dim defaultConfig As New GameOverLay.OverlayConfig
Dim ErrStr As String
If _MainForm.GetOverlayConfig(defaultConfig, False) = False Then
_MainForm.dbBox("Cannot start overlay. Input parameters invalid")
Exit Sub
End If
If _MainForm.VerifySettings(ErrStr) = False Then
_MainForm.dbBox(ErrStr)
Exit Sub
End If
Dim MainWorkThread As New Task(Sub() MainRoutine(300, defaultConfig))
MainWorkThread.Start()
End Sub
Public Async Sub MainRoutine(pingTime As Integer, defaultConfig As GameOverLay.OverlayConfig)
Dim songID As Integer, IDstr As String, LastID As Integer
While _MonitorGame = True 'global var
If _pipeClient.IsConnected = False Then
_MainForm.ResetConnection()
_MainForm.SetStatus("lostConnection")
If _MainForm.CB_ExitOnConnectionLost.Checked = True Then
_MainForm.dbBox("Program will close in 10. Uncheck box to leave it open.")
Await WaitAsync(10000)
If _MainForm.CB_ExitOnConnectionLost.Checked = True Then
Application.Exit()
End If
End If
Exit Sub
Else
Await WaitAsync(pingTime)
songID = GetSongID()
If songID <> -1 AndAlso LastID <> songID Then
LastID = songID
If songID < 1000 Then
IDstr = songID.ToString.PadLeft(3, "0"c)
Else
IDstr = songID
End If
Try
If _RefreshOvlConfig = True Then
If _MainForm.GetOverlayConfig(defaultConfig, False) = False Then
_MainForm.dbBox("ERROR: Cannot update overlay confing.Input parameters invalid")
End If
_RefreshOvlConfig = False
End If
defaultConfig.DisplayStr = ParseOverlayText(defaultConfig.TemplateStr, IDstr)
OverLayTextWindow(defaultConfig)
Catch ex As KeyNotFoundException
_MainForm.dbBox($"Error getting getting info for ID {IDstr}")
Catch ex As Exception
_MainForm.dbBox($"Unknown error occured when trying to present overlay.")
End Try
ElseIf songID = -1 Then
LastID = 0 'this bit of logic makes it so that the song overlay appears if the song is replayed from the menu
End If
End If
End While
End Sub
Public Sub OverlayNow(Optional AltBoxConfig As Boolean = False)
Dim defaultConfig As GameOverLay.OverlayConfig
If AltBoxConfig = False Then
If _MainForm.GetOverlayConfig(defaultConfig, False) = False Then
_MainForm.dbBox("Cannot start overlay. Input parameters invalid")
Exit Sub
End If
Else
_MainForm.GetOverlayConfig(defaultConfig, False, True)
End If
Dim songID As Integer, IDstr As String, LastID As Integer
If _pipeClient.IsConnected = False Then
_MainForm.dbBox("Not connected. Running test overaly instead...")
_MainForm.OverlayTest(AltBoxConfig)
Exit Sub
Else
songID = GetSongID()
If songID = -1 Then
_MainForm.dbBox("No song selected. Running overlay test instead.")
_MainForm.OverlayTest(AltBoxConfig)
Exit Sub
ElseIf songID < 1000 Then
IDstr = songID.ToString.PadLeft(3, "0"c)
Else
IDstr = songID
End If
Try
defaultConfig.DisplayStr = ParseOverlayText(defaultConfig.TemplateStr, IDstr)
OverLayTextWindow(defaultConfig)
Catch ex As KeyNotFoundException
_MainForm.dbBox($"Error getting getting info for ID {IDstr}")
Catch ex As Exception
_MainForm.dbBox($"Unknown error occured when trying to present overlay.")
End Try
End If
End Sub
Public Async Sub OverLayTextWindow(config As GameOverLay.OverlayConfig)
Dim backgroundThread As New Thread(Sub()
Dim overlay As New GameOverLay(config)
If overlay.Initiate() = True Then overlay.Run()
End Sub)
backgroundThread.IsBackground = True
backgroundThread.Start()
Await WaitAsync(config.DisplayTime + 250)
backgroundThread.Abort()
End Sub
Public Function StartPipeConnection() As Boolean
Try
_pipeClient.Connect(1000)
Return True
Catch ex As Exception
_MainForm.dbBox("FAILED TO CONNECT.")
Return False
End Try
End Function
Public Function GetSongID() As Integer
Try
Dim message As Byte() = Encoding.ASCII.GetBytes("song-id")
_pipeClient.Write(message, 0, message.Length)
_pipeClient.Flush() ' Flush to ensure the message is sent
' Read 4 bytes as a response from the server
Dim response(3) As Byte
_pipeClient.Read(response, 0, response.Length)
'Dim responseString As String = Encoding.ASCII.GetString(response)
Dim result As Integer = BitConverter.ToInt32(response, 0)
Return result
Catch ex As Exception
If _pipeClient.IsConnected = False Then
_MainForm.dbBox("Communication failed. Pipe connection lost.")
Else
_MainForm.dbBox("Unknown pipe communication error." & vbCrLf & ex.Message)
End If
Return 0
End Try
End Function
Async Function WaitAsync(milliseconds As Integer) As Task
Await Task.Delay(milliseconds)
End Function
End Module