11using log4net ;
22using NETworkManager . Models ;
33using NETworkManager . Models . Network ;
4+ using NETworkManager . Utilities ;
45using System ;
56using System . IO ;
67using System . Linq ;
8+ using System . Text . Json ;
9+ using System . Text . Json . Serialization ;
710using System . Xml . Serialization ;
811
912namespace NETworkManager . Settings ;
@@ -22,6 +25,11 @@ public static class SettingsManager
2225 /// </summary>
2326 private static string SettingsFolderName => "Settings" ;
2427
28+ /// <summary>
29+ /// Settings backups directory name.
30+ /// </summary>
31+ private static string BackupFolderName => "Backups" ;
32+
2533 /// <summary>
2634 /// Settings file name.
2735 /// </summary>
@@ -30,7 +38,13 @@ public static class SettingsManager
3038 /// <summary>
3139 /// Settings file extension.
3240 /// </summary>
33- private static string SettingsFileExtension => ".xml" ;
41+ private static string SettingsFileExtension => ".json" ;
42+
43+ /// <summary>
44+ /// Legacy XML settings file extension.
45+ /// </summary>
46+ [ Obsolete ( "Legacy XML settings are no longer used, but the extension is kept for migration purposes." ) ]
47+ private static string LegacySettingsFileExtension => ".xml" ;
3448
3549 /// <summary>
3650 /// Settings that are currently loaded.
@@ -42,6 +56,17 @@ public static class SettingsManager
4256 /// </summary>
4357 public static bool HotKeysChanged { get ; set ; }
4458
59+ /// <summary>
60+ /// JSON serializer options for consistent serialization/deserialization.
61+ /// </summary>
62+ private static readonly JsonSerializerOptions JsonOptions = new ( )
63+ {
64+ WriteIndented = true ,
65+ PropertyNameCaseInsensitive = true ,
66+ DefaultIgnoreCondition = JsonIgnoreCondition . Never ,
67+ Converters = { new JsonStringEnumConverter ( ) }
68+ } ;
69+
4570 #endregion
4671
4772 #region Settings location, default paths and file names
@@ -58,6 +83,15 @@ public static string GetSettingsFolderLocation()
5883 AssemblyManager . Current . Name , SettingsFolderName ) ;
5984 }
6085
86+ /// <summary>
87+ /// Method to get the path of the settings backup folder.
88+ /// </summary>
89+ /// <returns>Path to the settings backup folder.</returns>
90+ public static string GetSettingsBackupFolderLocation ( )
91+ {
92+ return Path . Combine ( GetSettingsFolderLocation ( ) , BackupFolderName ) ;
93+ }
94+
6195 /// <summary>
6296 /// Method to get the settings file name.
6397 /// </summary>
@@ -67,6 +101,16 @@ public static string GetSettingsFileName()
67101 return $ "{ SettingsFileName } { SettingsFileExtension } ";
68102 }
69103
104+ /// <summary>
105+ /// Method to get the legacy settings file name.
106+ /// </summary>
107+ /// <returns>Legacy settings file name.</returns>
108+ [ Obsolete ( "Legacy XML settings are no longer used, but the method is kept for migration purposes." ) ]
109+ public static string GetLegacySettingsFileName ( )
110+ {
111+ return $ "{ SettingsFileName } { LegacySettingsFileExtension } ";
112+ }
113+
70114 /// <summary>
71115 /// Method to get the settings file path.
72116 /// </summary>
@@ -76,6 +120,16 @@ public static string GetSettingsFilePath()
76120 return Path . Combine ( GetSettingsFolderLocation ( ) , GetSettingsFileName ( ) ) ;
77121 }
78122
123+ /// <summary>
124+ /// Method to get the legacy XML settings file path.
125+ /// </summary>
126+ /// <returns>Legacy XML settings file path.</returns>
127+ [ Obsolete ( "Legacy XML settings are no longer used, but the method is kept for migration purposes." ) ]
128+ private static string GetLegacySettingsFilePath ( )
129+ {
130+ return Path . Combine ( GetSettingsFolderLocation ( ) , GetLegacySettingsFileName ( ) ) ;
131+ }
132+
79133 #endregion
80134
81135 #region Initialize, load and save
@@ -99,7 +153,9 @@ public static void Initialize()
99153 public static void Load ( )
100154 {
101155 var filePath = GetSettingsFilePath ( ) ;
156+ var legacyFilePath = GetLegacySettingsFilePath ( ) ;
102157
158+ // Check if JSON file exists
103159 if ( File . Exists ( filePath ) )
104160 {
105161 Current = DeserializeFromFile ( filePath ) ;
@@ -109,22 +165,66 @@ public static void Load()
109165 return ;
110166 }
111167
168+ // Check if legacy XML file exists and migrate it
169+ if ( File . Exists ( legacyFilePath ) )
170+ {
171+ Log . Info ( "Legacy XML settings file found. Migrating to JSON format..." ) ;
172+
173+ Current = DeserializeFromXmlFile ( legacyFilePath ) ;
174+
175+ Current . SettingsChanged = false ;
176+
177+ // Save in new JSON format
178+ Save ( ) ;
179+
180+ // Create a backup of the legacy XML file and delete the original
181+ Directory . CreateDirectory ( GetSettingsBackupFolderLocation ( ) ) ;
182+
183+ var backupFilePath = Path . Combine ( GetSettingsBackupFolderLocation ( ) ,
184+ $ "{ TimestampHelper . GetTimestamp ( ) } _{ GetLegacySettingsFileName ( ) } ") ;
185+
186+ File . Copy ( legacyFilePath , backupFilePath , true ) ;
187+
188+ File . Delete ( legacyFilePath ) ;
189+
190+ Log . Info ( $ "Legacy XML settings file backed up to: { backupFilePath } ") ;
191+
192+ Log . Info ( "Settings migration from XML to JSON completed successfully." ) ;
193+
194+ return ;
195+ }
196+
112197 // Initialize the default settings if there is no settings file.
113198 Initialize ( ) ;
114199 }
115200
116201 /// <summary>
117- /// Method to deserialize the settings from a file.
202+ /// Method to deserialize the settings from a JSON file.
118203 /// </summary>
119204 /// <param name="filePath">Path to the settings file.</param>
120205 /// <returns>Settings as <see cref="SettingsInfo" />.</returns>
121206 private static SettingsInfo DeserializeFromFile ( string filePath )
207+ {
208+ var jsonString = File . ReadAllText ( filePath ) ;
209+
210+ var settingsInfo = JsonSerializer . Deserialize < SettingsInfo > ( jsonString , JsonOptions ) ;
211+
212+ return settingsInfo ;
213+ }
214+
215+ /// <summary>
216+ /// Method to deserialize the settings from a legacy XML file.
217+ /// </summary>
218+ /// <param name="filePath">Path to the XML settings file.</param>
219+ /// <returns>Settings as <see cref="SettingsInfo" />.</returns>
220+ [ Obsolete ( "Legacy XML settings are no longer used, but the method is kept for migration purposes." ) ]
221+ private static SettingsInfo DeserializeFromXmlFile ( string filePath )
122222 {
123223 var xmlSerializer = new XmlSerializer ( typeof ( SettingsInfo ) ) ;
124224
125225 using var fileStream = new FileStream ( filePath , FileMode . Open ) ;
126226
127- var settingsInfo = ( SettingsInfo ) xmlSerializer . Deserialize ( fileStream ) ;
227+ var settingsInfo = xmlSerializer . Deserialize ( fileStream ) as SettingsInfo ;
128228
129229 return settingsInfo ;
130230 }
@@ -145,17 +245,28 @@ public static void Save()
145245 }
146246
147247 /// <summary>
148- /// Method to serialize the settings to a file.
248+ /// Method to serialize the settings to a JSON file.
149249 /// </summary>
150250 /// <param name="filePath">Path to the settings file.</param>
151251 private static void SerializeToFile ( string filePath )
152252 {
153- var xmlSerializer = new XmlSerializer ( typeof ( SettingsInfo ) ) ;
253+ var jsonString = JsonSerializer . Serialize ( Current , JsonOptions ) ;
254+
255+ File . WriteAllText ( filePath , jsonString ) ;
256+ }
154257
155- using var fileStream = new FileStream ( filePath , FileMode . Create ) ;
258+ #endregion
259+
260+ #region Backup
261+ /*
262+ private static void Backup()
263+ {
264+ Log.Info("Creating settings backup...");
156265
157- xmlSerializer . Serialize ( fileStream , Current ) ;
266+ // Create the backup directory if it does not exist
267+ Directory.CreateDirectory(GetSettingsBackupFolderLocation());
158268 }
269+ */
159270
160271 #endregion
161272
0 commit comments