33import com .google .gson .FieldNamingPolicy ;
44import com .google .gson .Gson ;
55import com .google .gson .GsonBuilder ;
6+ import com .google .gson .JsonParseException ;
67import com .google .gson .annotations .SerializedName ;
78import com .mojang .blaze3d .opengl .GlBackend ;
89import it .unimi .dsi .fastutil .objects .Object2BooleanArrayMap ;
1819import org .lwjgl .glfw .GLFW ;
1920
2021import java .io .File ;
21- import java .io .FileReader ;
22- import java .io .FileWriter ;
2322import java .io .IOException ;
2423import java .lang .reflect .Modifier ;
24+ import java .nio .charset .StandardCharsets ;
25+ import java .nio .file .Files ;
26+ import java .nio .file .Path ;
2527import java .util .Arrays ;
2628import java .util .EnumSet ;
2729import java .util .Map ;
@@ -39,30 +41,37 @@ public class SodiumExtraGameOptions implements StorageEventHandler {
3941 public RenderSettings renderSettings = new RenderSettings ();
4042 @ SerializedName (SodiumExtraConfigKeys .EXTRA_SETTINGS )
4143 public ExtraSettings extraSettings = new ExtraSettings ();
42- private File file ;
44+ private Path path ;
4345
4446 public static SodiumExtraGameOptions load (File file ) {
47+ return load (file .toPath ());
48+ }
49+
50+ public static SodiumExtraGameOptions load (Path path ) {
4551 SodiumExtraGameOptions config ;
52+ boolean shouldWriteChanges = true ;
4653
47- if (file .exists ()) {
48- try (FileReader reader = new FileReader ( file )) {
54+ if (Files .exists (path )) {
55+ try (var reader = Files . newBufferedReader ( path , StandardCharsets . UTF_8 )) {
4956 config = gson .fromJson (reader , SodiumExtraGameOptions .class );
50- } catch (Exception e ) {
51- SodiumExtraClientMod .logger ().error ("Could not parse config, falling back to defaults!" , e );
57+ if (config == null ) {
58+ throw new JsonParseException ("Root element must be a JSON object" );
59+ }
60+ } catch (IOException | JsonParseException | IllegalStateException e ) {
61+ SodiumExtraClientMod .logger ().warn ("Could not read config, falling back to defaults" , e );
5262 config = new SodiumExtraGameOptions ();
63+ shouldWriteChanges = moveCorruptConfig (path );
5364 }
5465 } else {
5566 config = new SodiumExtraGameOptions ();
5667 }
5768
58- if (config == null ) {
59- SodiumExtraClientMod .logger ().error ("Could not parse config, falling back to defaults!" );
60- config = new SodiumExtraGameOptions ();
61- }
62-
6369 config .sanitize ();
64- config .file = file ;
65- config .writeChanges ();
70+ config .path = path ;
71+
72+ if (shouldWriteChanges ) {
73+ config .writeChanges ();
74+ }
6675
6776 return config ;
6877 }
@@ -93,20 +102,27 @@ private void sanitize() {
93102 }
94103
95104 public void writeChanges () {
96- File dir = this .file .getParentFile ();
105+ if (this .path == null ) {
106+ SodiumExtraClientMod .logger ().warn ("Could not save configuration file because no path was set" );
107+ return ;
108+ }
97109
98- if (!dir .exists ()) {
99- if (!dir .mkdirs ()) {
100- throw new RuntimeException ("Could not create parent directories" );
101- }
102- } else if (!dir .isDirectory ()) {
103- throw new RuntimeException ("The parent file is not a directory" );
110+ try {
111+ this .sanitize ();
112+ ConfigFileIO .writeStringAtomically (this .path , gson .toJson (this ) + System .lineSeparator ());
113+ } catch (IOException e ) {
114+ SodiumExtraClientMod .logger ().warn ("Could not save configuration file" , e );
104115 }
116+ }
105117
106- try (FileWriter writer = new FileWriter (this .file )) {
107- gson .toJson (this , writer );
118+ private static boolean moveCorruptConfig (Path path ) {
119+ try {
120+ Path corruptPath = ConfigFileIO .moveCorruptFile (path );
121+ SodiumExtraClientMod .logger ().warn ("Moved corrupt configuration file to {}" , corruptPath );
122+ return true ;
108123 } catch (IOException e ) {
109- throw new RuntimeException ("Could not save configuration file" , e );
124+ SodiumExtraClientMod .logger ().warn ("Could not move corrupt configuration file" , e );
125+ return false ;
110126 }
111127 }
112128
0 commit comments