22
33import com .cleanroommc .groovyscript .GroovyScript ;
44import com .cleanroommc .groovyscript .sandbox .SandboxData ;
5- import com .google .gson .JsonElement ;
6- import com .google .gson .JsonObject ;
7- import com .google .gson .JsonParser ;
5+ import com .google .gson .*;
86import com .google .gson .stream .JsonReader ;
97import it .unimi .dsi .fastutil .objects .Object2ObjectOpenHashMap ;
108import it .unimi .dsi .fastutil .objects .ObjectOpenHashSet ;
9+ import net .minecraftforge .fml .relauncher .FMLLaunchHandler ;
1110import net .minecraftforge .fml .relauncher .Side ;
11+ import org .jetbrains .annotations .ApiStatus ;
1212
13- import java .io .File ;
14- import java .io .FileInputStream ;
15- import java .io .InputStreamReader ;
16- import java .io .Reader ;
13+ import java .io .*;
1714import java .nio .charset .StandardCharsets ;
15+ import java .nio .file .Files ;
16+ import java .util .Collections ;
17+ import java .util .List ;
1818import java .util .Map ;
1919import java .util .function .Function ;
2020
@@ -27,37 +27,102 @@ public class SideOnlyConfig {
2727 };
2828 private static final Map <String , MethodSet > clientRemovals = new Object2ObjectOpenHashMap <>();
2929 private static final Map <String , MethodSet > serverRemovals = new Object2ObjectOpenHashMap <>();
30+ private static JsonObject generatedCfg ;
31+ private static JsonObject generatedClient ;
32+ private static JsonObject generatedServer ;
3033
3134 public static void clientOnly (String className , String member ) {
32- serverRemovals . computeIfAbsent ( className , DEFAULT_METHOD_SET ). add (member );
35+ addAutoDetectedFailingMembers ( generatedClient , className , Collections . singletonList (member ) );
3336 }
3437
3538 public static void serverOnly (String className , String member ) {
36- clientRemovals . computeIfAbsent ( className , DEFAULT_METHOD_SET ). add (member );
39+ addAutoDetectedFailingMembers ( generatedServer , className , Collections . singletonList (member ) );
3740 }
3841
3942 static void init () {
43+ generatedCfg = readFile (SandboxData .getSideOnlyGeneratedFile ());
44+ if (generatedCfg == null ) {
45+ createGeneratedConfig ();
46+ } else {
47+ generatedClient = generatedCfg .getAsJsonObject ("client" );
48+ generatedServer = generatedCfg .getAsJsonObject ("server" );
49+ }
50+ readFile (new File (SandboxData .getScriptFile (), "sideOnly.json" ));
51+ }
52+
53+ private static void createGeneratedConfig () {
54+ generatedCfg = new JsonObject ();
55+ generatedClient = new JsonObject ();
56+ generatedServer = new JsonObject ();
57+ generatedCfg .addProperty ("ATTENTION" , "This file is auto generated. Manual editing is not advised." );
58+ generatedCfg .add ("common" , new JsonObject ());
59+ generatedCfg .add ("client" , generatedClient );
60+ generatedCfg .add ("server" , generatedServer );
61+
4062 clientOnly ("net.minecraftforge.common.config.Configuration" , "setCategoryConfigEntryClass()" );
63+ writeGeneratedConfig ();
64+ }
4165
42- initConfig ();
66+ @ ApiStatus .Internal
67+ public static void addAutoDetectedFailingMembers (Class <?> c , List <String > members ) {
68+ // if the current side is server, it means its likely meant for client
69+ addAutoDetectedFailingMembers (FMLLaunchHandler .side ().isServer () ? generatedClient : generatedServer , c .getName (), members );
70+ }
71+
72+ private static void addAutoDetectedFailingMembers (JsonObject sideJson , String className , List <String > members ) {
73+ JsonArray classJson = sideJson .getAsJsonArray (className );
74+ if (classJson == null ) {
75+ classJson = new JsonArray ();
76+ sideJson .add (className , classJson );
77+ }
78+ main :
79+ for (String member : members ) {
80+ for (JsonElement e : classJson ) {
81+ if (e .isJsonPrimitive () && e .getAsString ().equals (member )) {
82+ continue main ;
83+ }
84+ }
85+ classJson .add (member );
86+ }
87+ }
88+
89+ public static void writeGeneratedConfig () {
90+ File file = SandboxData .getSideOnlyGeneratedFile ();
91+ try {
92+ if (file .exists ()) {
93+ file .delete ();
94+ } else {
95+ file .getParentFile ().mkdirs ();
96+ }
97+
98+ if (!file .getParentFile ().isDirectory ()) {
99+ if (!file .getParentFile ().mkdirs ()) {
100+ GroovyScriptCore .LOG .error ("Failed to create file dirs on path {}" , file );
101+ }
102+ }
103+ Writer writer = new OutputStreamWriter (Files .newOutputStream (file .toPath ()), StandardCharsets .UTF_8 );
104+ writer .write (new GsonBuilder ().setPrettyPrinting ().create ().toJson (generatedCfg ));
105+ writer .close ();
106+ } catch (Exception e ) {
107+ GroovyScriptCore .LOG .error ("Failed to save file on path {}" , file , e );
108+ }
43109 }
44110
45- private static void initConfig () {
46- File sideOnlyConfig = new File (SandboxData .getScriptFile (), "sideOnly.json" );
111+ private static JsonObject readFile (File sideOnlyConfig ) {
47112 JsonObject json ;
48113 try {
49- if (!sideOnlyConfig .isFile ()) return ;
114+ if (!sideOnlyConfig .isFile ()) return null ;
50115 Reader reader = new InputStreamReader (new FileInputStream (sideOnlyConfig ), StandardCharsets .UTF_8 );
51116 JsonElement jsonElement = new JsonParser ().parse (new JsonReader (reader ));
52117 reader .close ();
53118 if (jsonElement instanceof JsonObject jsonObject ) {
54119 json = jsonObject ;
55120 } else {
56- return ;
121+ return null ;
57122 }
58123 } catch (Exception e ) {
59124 GroovyScript .LOGGER .error ("Failed to read file on path {}" , sideOnlyConfig , e );
60- return ;
125+ return null ;
61126 }
62127 if (json .has ("client" )) {
63128 readConfig (serverRemovals , json .getAsJsonObject ("client" ));
@@ -81,6 +146,7 @@ private static void initConfig() {
81146 break ;
82147 }
83148 }
149+ return json ;
84150 }
85151
86152 private static void readConfig (Map <String , MethodSet > removals , JsonObject json ) {
0 commit comments