@@ -23,7 +23,7 @@ public class MapLoader
23
23
24
24
/// <summary>
25
25
/// The relative path to the folder where custom maps are stored.
26
- /// This is the public version of CUSTOM_MAPS_DIRECTORY ending in a slash for convenience.
26
+ /// This is the public version of CUSTOM_MAPS_DIRECTORY with a "/" added for convenience.
27
27
/// </summary>
28
28
public const string CustomMapsDirectory = CUSTOM_MAPS_DIRECTORY + "/" ;
29
29
@@ -60,7 +60,7 @@ public class MapLoader
60
60
private FileSystemWatcher customMapFileWatcher ;
61
61
62
62
/// <summary>
63
- /// Check to see if a map matching the sha1 ID is already loaded.
63
+ /// Check to see if a map matching the SHA-1 ID is already loaded.
64
64
/// </summary>
65
65
/// <param name="sha1">The map ID to search the loaded maps for.</param>
66
66
/// <returns></returns>
@@ -70,10 +70,10 @@ public bool IsMapAlreadyLoaded(string sha1)
70
70
}
71
71
72
72
/// <summary>
73
- /// Search the loaded maps for the sha1 , return the map if a match is found.
73
+ /// Search the loaded maps for the SHA-1 , return the map if a match is found.
74
74
/// </summary>
75
75
/// <param name="sha1">The map ID to search the loaded maps for.</param>
76
- /// <returns>The map matching the sha1 if one was found.</returns>
76
+ /// <returns>The map matching the SHA-1 if one was found.</returns>
77
77
public GameModeMap GetLoadedMapBySha1 ( string sha1 )
78
78
{
79
79
return GameModeMaps . Find ( gmm => gmm . Map . SHA1 == sha1 ) ;
@@ -95,17 +95,9 @@ public void LoadMapsAsync()
95
95
/// </summary>
96
96
public void StartCustomMapFileWatcher ( )
97
97
{
98
- customMapFileWatcher = new FileSystemWatcher ( $ " { ProgramConstants . GamePath } { CustomMapsDirectory } " ) ;
98
+ customMapFileWatcher = new FileSystemWatcher ( SafePath . CombineDirectoryPath ( ProgramConstants . GamePath , CustomMapsDirectory ) ) ;
99
99
100
100
customMapFileWatcher . Filter = $ "*{ MAP_FILE_EXTENSION } ";
101
- customMapFileWatcher . NotifyFilter = NotifyFilters . Attributes
102
- | NotifyFilters . CreationTime
103
- | NotifyFilters . DirectoryName
104
- | NotifyFilters . FileName
105
- | NotifyFilters . LastAccess
106
- | NotifyFilters . LastWrite
107
- | NotifyFilters . Security
108
- | NotifyFilters . Size ;
109
101
110
102
customMapFileWatcher . Created += HandleCustomMapFolder_Created ;
111
103
customMapFileWatcher . Deleted += HandleCustomMapFolder_Deleted ;
@@ -127,8 +119,11 @@ public void HandleCustomMapFolder_Created(object sender, FileSystemEventArgs e)
127
119
{
128
120
// Get the map filename without the extension.
129
121
// The extension gets added in LoadCustomMap so we need to excise it to avoid "file.map.map".
130
- string name = e . Name . EndsWith ( MAP_FILE_EXTENSION ) ? e . Name . Remove ( e . Name . Length - MAP_FILE_EXTENSION . Length ) : e . Name ;
131
- string relativeMapPath = $ "{ CustomMapsDirectory } { name } ";
122
+ string name = Path . GetFileNameWithoutExtension ( e . Name ) ;
123
+
124
+ if ( name . StartsWith ( ) )
125
+
126
+ string relativeMapPath = SafePath . CombineFilePath ( CustomMapsDirectory , name ) ;
132
127
Map map = LoadCustomMap ( relativeMapPath , out string result ) ;
133
128
134
129
if ( map == null )
@@ -147,11 +142,13 @@ public void HandleCustomMapFolder_Created(object sender, FileSystemEventArgs e)
147
142
public void HandleCustomMapFolder_Deleted ( object sender , FileSystemEventArgs e )
148
143
{
149
144
Logger . Log ( $ "Map was deleted: map={ e . Name } ") ;
145
+ // Use the filename without the extension so we can remove maps that had their extension changed.
146
+ string name = Path . GetFileNameWithoutExtension ( e . Name ) ;
150
147
// The way we're detecting the loaded map is hacky, but we don't
151
- // have the sha1 to work with.
148
+ // have the SHA-1 to work with.
152
149
foreach ( GameMode gameMode in GameModes )
153
150
{
154
- gameMode . Maps . RemoveAll ( map => map . CompleteFilePath . EndsWith ( e . Name ) ) ;
151
+ gameMode . Maps . RemoveAll ( map => Path . GetFileNameWithoutExtension ( map . CompleteFilePath ) . EndsWith ( name ) ) ;
155
152
}
156
153
157
154
RemoveEmptyGameModesAndUpdateGameModeMaps ( ) ;
@@ -170,15 +167,29 @@ public void HandleCustomMapFolder_Deleted(object sender, FileSystemEventArgs e)
170
167
/// <param name="e"></param>
171
168
public void HandleCustomMapFolder_Renamed ( object sender , RenamedEventArgs e )
172
169
{
173
- string name = e . Name . EndsWith ( MAP_FILE_EXTENSION ) ? e . Name . Remove ( e . Name . Length - MAP_FILE_EXTENSION . Length ) : e . Name ;
174
- string relativeMapPath = $ "{ CustomMapsDirectory } { name } ";
170
+ string name = Path . GetFileNameWithoutExtension ( e . Name ) ;
171
+ string relativeMapPath = SafePath . CombineFilePath ( CustomMapsDirectory , name ) ;
172
+ bool oldPathIsMap = Path . GetExtension ( e . OldName ) == MAP_FILE_EXTENSION ;
173
+ bool newPathIsMap = Path . GetExtension ( e . Name ) == MAP_FILE_EXTENSION ;
175
174
176
175
// Check if the user is renaming a non ".map" file.
177
176
// This is just for logging to help debug.
178
- if ( ! e . OldName . EndsWith ( MAP_FILE_EXTENSION ) )
177
+ if ( ! oldPathIsMap && newPathIsMap )
179
178
{
180
179
Logger . Log ( $ "Renaming file changed the file extension. User is likely renaming a '.yrm' from Final Alert 2: old={ e . OldName } , new={ e . Name } ") ;
181
180
}
181
+ else if ( oldPathIsMap && ! newPathIsMap )
182
+ {
183
+ // A bit hacky, but this is a rare case.
184
+ Logger . Log ( $ "Renaming file changed the file extension to no longer be '.map' for some reason, removing from map list: old={ e . OldName } , new={ e . Name } ") ;
185
+ HandleCustomMapFolder_Deleted ( sender , e ) ;
186
+ }
187
+
188
+ if ( ! newPathIsMap )
189
+ {
190
+ Logger . Log ( $ "Renaming file. New extension is not '{ MAP_FILE_EXTENSION } ', moving on: file={ e . Name } ") ;
191
+ return ;
192
+ }
182
193
183
194
Map map = LoadCustomMap ( relativeMapPath , out string result ) ;
184
195
@@ -431,7 +442,7 @@ public Map LoadCustomMap(string mapPath, out string resultMessage)
431
442
}
432
443
433
444
// Make sure we don't accidentally load the same map twice.
434
- // This checks the sha1 , so duplicate maps in two .map files with different filenames can still be detected.
445
+ // This checks the SHA-1 , so duplicate maps in two .map files with different filenames can still be detected.
435
446
if ( IsMapAlreadyLoaded ( map . SHA1 ) )
436
447
{
437
448
Logger . Log ( "LoadCustomMap: Custom map " + customMapFile . FullName + " is already loaded!" ) ;
0 commit comments