2525import java .nio .file .Path ;
2626import java .nio .file .Paths ;
2727import java .util .Optional ;
28+ import net .minecraft .registry .RegistryOps ;
29+ import net .minecraft .registry .RegistryWrapper ;
2830import net .minecraft .util .Identifier ;
31+ import net .fabricmc .api .EnvType ;
32+ import net .fabricmc .api .Environment ;
2933import net .fabricmc .api .ModInitializer ;
34+ import net .fabricmc .fabric .api .client .event .lifecycle .v1 .ClientLifecycleEvents ;
35+ import net .fabricmc .fabric .api .client .networking .v1 .ClientConfigurationConnectionEvents ;
36+ import net .fabricmc .fabric .api .client .networking .v1 .ClientConfigurationNetworking ;
37+ import net .fabricmc .fabric .api .client .networking .v1 .ClientLoginConnectionEvents ;
38+ import net .fabricmc .fabric .api .event .lifecycle .v1 .ServerLifecycleEvents ;
39+ import net .fabricmc .fabric .api .networking .v1 .PayloadTypeRegistry ;
3040import net .fabricmc .loader .api .FabricLoader ;
41+ import com .google .gson .JsonElement ;
3142import com .mojang .serialization .Codec ;
43+ import com .mojang .serialization .DynamicOps ;
3244import com .mojang .serialization .JsonOps ;
33- import com . mojang . serialization . MapCodec ;
45+ import de . mschae23 . config . api . ConfigIo ;
3446import de .mschae23 .config .api .ModConfig ;
3547import de .mschae23 .config .api .exception .ConfigException ;
36- import de .mschae23 .config .impl .ConfigUtil ;
48+ import de .mschae23 .grindenchantments .config .ClientConfig ;
49+ import de .mschae23 .grindenchantments .config .ServerConfig ;
3750import de .mschae23 .grindenchantments .config .legacy .v1 .GrindEnchantmentsConfigV1 ;
3851import de .mschae23 .grindenchantments .config .legacy .v2 .GrindEnchantmentsConfigV2 ;
3952import de .mschae23 .grindenchantments .config .legacy .v3 .GrindEnchantmentsConfigV3 ;
4356import de .mschae23 .grindenchantments .impl .DisenchantOperation ;
4457import de .mschae23 .grindenchantments .impl .MoveOperation ;
4558import de .mschae23 .grindenchantments .impl .ResetRepairCostOperation ;
59+ import de .mschae23 .grindenchantments .network .s2c .ServerConfigS2CPayload ;
4660import de .mschae23 .grindenchantments .registry .GrindEnchantmentsRegistries ;
4761import io .github .fourmisain .taxfreelevels .TaxFreeLevels ;
4862import org .apache .logging .log4j .Level ;
@@ -55,9 +69,32 @@ public class GrindEnchantmentsMod implements ModInitializer {
5569 public static final Logger LOGGER = LogManager .getLogger ("Grind Enchantments" );
5670
5771 private static GrindEnchantmentsConfigV3 LEGACY_CONFIG = GrindEnchantmentsConfigV3 .DEFAULT ;
72+ @ Nullable
73+ private static ServerConfig SERVER_CONFIG = null ;
74+ @ Nullable
75+ private static ClientConfig CLIENT_CONFIG = null ;
5876
5977 @ Override
6078 public void onInitialize () {
79+ // Singleplayer
80+ ServerLifecycleEvents .SERVER_STARTING .register (server -> readServerConfig (server .getRegistryManager ())
81+ .ifPresent (config -> SERVER_CONFIG = config ));
82+ ServerLifecycleEvents .SERVER_STOPPING .register (server -> SERVER_CONFIG = null );
83+
84+ // Multiplayer
85+ PayloadTypeRegistry .configurationS2C ().register (ServerConfigS2CPayload .ID , ServerConfigS2CPayload .CODEC );
86+
87+ ClientLifecycleEvents .CLIENT_STARTED .register (client -> {
88+ CLIENT_CONFIG = GrindEnchantmentsMod .readClientConfig ().orElse (ClientConfig .DEFAULT );
89+
90+ ClientConfigurationNetworking .registerGlobalReceiver (ServerConfigS2CPayload .ID , (payload , context ) -> {
91+ //noinspection resource
92+ context .client ().execute (() -> {
93+ // TODO
94+ });
95+ });
96+ });
97+
6198 LEGACY_CONFIG = readLegacyConfig ().orElse (GrindEnchantmentsConfigV3 .DEFAULT );
6299
63100 GrindEnchantmentsRegistries .init ();
@@ -85,29 +122,74 @@ public void onInitialize() {
85122 }
86123 }
87124
88- private static <T extends ModConfig <T >> ModConfig .Type <T , ?> getConfigType (int versionOffset , MapCodec <? extends ModConfig <T >>[] codecs , int version ) {
89- for (int i = codecs .length ; i > 0 ; i --) {
90- if (version == i ) {
91- return new ModConfig .Type <>(i + versionOffset , codecs [i - 1 ]);
125+ public static ServerConfig getServerConfig () {
126+ return SERVER_CONFIG == null ? ServerConfig .DEFAULT : SERVER_CONFIG ;
127+ }
128+
129+ public static ClientConfig getClientConfig () {
130+ return CLIENT_CONFIG == null ? ClientConfig .DEFAULT : CLIENT_CONFIG ;
131+ }
132+
133+ @ Deprecated
134+ public static GrindEnchantmentsConfigV3 getLegacyConfig () {
135+ return LEGACY_CONFIG ;
136+ }
137+
138+ private static <C extends ModConfig <C >> ModConfig .Type <C , ? extends ModConfig <C >> getConfigType (ModConfig .Type <C , ? extends ModConfig <C >>[] versions , int version ) {
139+ for (int i = versions .length - 1 ; i >= 0 ; i --) {
140+ ModConfig .Type <C , ? extends ModConfig <C >> v = versions [i ];
141+
142+ if (version == v .version ()) {
143+ return v ;
144+ }
145+ }
146+
147+ return versions [versions .length - 1 ];
148+ }
149+
150+ private static <C extends ModConfig <C >> Optional <C > readGenericConfig (Path configName , Codec <ModConfig <C >> codec ,
151+ DynamicOps <JsonElement > ops , String kind ) {
152+ Path filePath = FabricLoader .getInstance ().getConfigDir ().resolve (MODID ).resolve (configName );
153+ @ Nullable
154+ C config = null ;
155+
156+ if (Files .exists (filePath ) && Files .isRegularFile (filePath )) {
157+ try (InputStream input = Files .newInputStream (filePath )) {
158+ log (Level .INFO , "Reading " + kind + " config." );
159+
160+ ModConfig <C > readConfig = ConfigIo .decodeConfig (input , codec , ops );
161+ config = readConfig .latest ();
162+ } catch (IOException e ) {
163+ log (Level .ERROR , "IO exception while trying to read " + kind + " config: " + e .getLocalizedMessage ());
164+ } catch (ConfigException e ) {
165+ log (Level .ERROR , e .getLocalizedMessage ());
92166 }
93167 }
94168
95- return new ModConfig .Type <>(codecs .length + versionOffset , codecs [codecs .length - 1 ]);
169+ return Optional .ofNullable (config );
170+ }
171+
172+ public static Optional <ClientConfig > readClientConfig () {
173+ return readGenericConfig (Path .of ("client.json" ), ModConfig .<ClientConfig >createCodec (ClientConfig .TYPE .version (), version ->
174+ getConfigType (ClientConfig .VERSIONS , version )), JsonOps .INSTANCE , "client" );
175+ }
176+
177+ private static Optional <ServerConfig > readServerConfig (RegistryWrapper .WrapperLookup wrapperLookup ) {
178+ return readGenericConfig (Path .of ("server.json" ), ModConfig .<ServerConfig >createCodec (ServerConfig .TYPE .version (), version ->
179+ getConfigType (ServerConfig .VERSIONS , version )), RegistryOps .of (JsonOps .INSTANCE , wrapperLookup ), "server" );
96180 }
97181
98182 @ SuppressWarnings ("deprecation" )
99183 private static Optional <GrindEnchantmentsConfigV3 > readLegacyConfig () {
100184 final GrindEnchantmentsConfigV3 legacyLatestConfigDefault = GrindEnchantmentsConfigV3 .DEFAULT ;
101185 final int legacyLatestConfigVersion = legacyLatestConfigDefault .version ();
102186 @ SuppressWarnings ({"unchecked" , "deprecation" })
103- final MapCodec < ? extends ModConfig <GrindEnchantmentsConfigV3 >>[] legacyConfigCodecs = new MapCodec [] {
104- GrindEnchantmentsConfigV1 .TYPE_CODEC , GrindEnchantmentsConfigV2 .TYPE_CODEC , GrindEnchantmentsConfigV3 .TYPE_CODEC
187+ final ModConfig . Type < GrindEnchantmentsConfigV3 , ? extends ModConfig <GrindEnchantmentsConfigV3 >>[] legacyConfigCodecs = new ModConfig . Type [] {
188+ GrindEnchantmentsConfigV1 .TYPE , GrindEnchantmentsConfigV2 .TYPE , GrindEnchantmentsConfigV3 .TYPE
105189 };
106190
107191 final Codec <ModConfig <GrindEnchantmentsConfigV3 >> legacyConfigCodec = ModConfig .createCodec (legacyLatestConfigVersion , version ->
108- getConfigType (0 , legacyConfigCodecs , version ));
109-
110- // Unfortunately, this requires some manual work and usage of codec config API's internals
192+ getConfigType (legacyConfigCodecs , version ));
111193
112194 Path configPath = FabricLoader .getInstance ().getConfigDir ().resolve (Paths .get (MODID + ".json" ));
113195 @ Nullable
@@ -117,8 +199,7 @@ private static Optional<GrindEnchantmentsConfigV3> readLegacyConfig() {
117199 try (InputStream input = Files .newInputStream (configPath )) {
118200 log (Level .INFO , "Reading legacy config." );
119201
120- @ SuppressWarnings ("UnstableApiUsage" )
121- ModConfig <GrindEnchantmentsConfigV3 > readConfig = ConfigUtil .decodeConfig (input , legacyConfigCodec , JsonOps .INSTANCE );
202+ ModConfig <GrindEnchantmentsConfigV3 > readConfig = ConfigIo .decodeConfig (input , legacyConfigCodec , JsonOps .INSTANCE );
122203 config = readConfig .latest ();
123204 } catch (IOException e ) {
124205 log (Level .ERROR , "IO exception while trying to read config: " + e .getLocalizedMessage ());
@@ -130,10 +211,6 @@ private static Optional<GrindEnchantmentsConfigV3> readLegacyConfig() {
130211 return Optional .ofNullable (config );
131212 }
132213
133- public static GrindEnchantmentsConfigV3 getConfig () {
134- return LEGACY_CONFIG ;
135- }
136-
137214 public static void log (Level level , Object message ) {
138215 LOGGER .log (level , "[Grind Enchantments] {}" , message );
139216 }
0 commit comments