Configuration.java 10.2 KB
Newer Older
KingRainbow44's avatar
KingRainbow44 committed
1
2
package emu.grasscutter;

3
import com.google.gson.JsonObject;
KingRainbow44's avatar
KingRainbow44 committed
4
5
6
import emu.grasscutter.Grasscutter.*;
import emu.grasscutter.game.mail.Mail.*;

7
import java.io.FileReader;
8
9
import java.lang.reflect.Field;
import java.util.Arrays;
KingRainbow44's avatar
KingRainbow44 committed
10
11
import java.util.Locale;

12
13
import static emu.grasscutter.Grasscutter.config;

KingRainbow44's avatar
KingRainbow44 committed
14
15
/**
 * A data container for the server's configuration.
16
17
18
 * 
 * Use `import static emu.grasscutter.Configuration.*;`
 * to import all configuration constants.
KingRainbow44's avatar
KingRainbow44 committed
19
20
 */
public final class Configuration {
21
22
23
24
25
26
27
28
    private static int version() {
        return 1;
    }
    
    /**
     * Attempts to update the server's existing configuration to the latest configuration.
     */
    public static void updateConfig() {
29
30
31
32
33
34
35
36
37
38
        try { // Check if the server is using a legacy config.
            JsonObject configObject = Grasscutter.getGsonFactory()
                    .fromJson(new FileReader(Grasscutter.configFile), JsonObject.class);
            if(!configObject.has("version")) {
                Grasscutter.getLogger().info("Updating legacy configuration...");
                Grasscutter.saveConfig(null);
            }
        } catch (Exception ignored) { }
        
        var existing = config.version;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
        var latest = version();
        
        if(existing == latest) 
            return;
        
        // Create a new configuration instance.
        Configuration updated = new Configuration();
        // Update all configuration fields.
        Field[] fields = Configuration.class.getDeclaredFields();
        Arrays.stream(fields).forEach(field -> {
            try {
                field.set(updated, field.get(config));
            } catch (Exception exception) {
                Grasscutter.getLogger().error("Failed to update a configuration field.", exception);
            }
        });
        
        try { // Save configuration & reload.
            Grasscutter.saveConfig(updated);
            Grasscutter.reloadConfig();
        } catch (Exception exception) {
            Grasscutter.getLogger().warn("Failed to inject the updated configuration.", exception);
        }
    }
    
    /*
     * Constants
     */
    
    // 'c' is short for 'config' and makes code look 'cleaner'.
    public static final Configuration c = config;
    
    public static final Locale LANGUAGE = config.language.language;
    public static final Locale FALLBACK_LANGUAGE = config.language.fallback;
    public static final String DATA_FOLDER = config.folderStructure.data;
    public static final String RESOURCES_FOLDER = config.folderStructure.resources;
    public static final String KEYS_FOLDER = config.folderStructure.keys;
    public static final String PLUGINS_FOLDER = config.folderStructure.plugins;
    public static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
    public static final String PACKETS_FOLDER = config.folderStructure.packets;
    
    public static final Server SERVER = config.server;
    public static final Database DATABASE = config.databaseInfo;
    public static final Account ACCOUNT = config.account;
    
    public static final Dispatch DISPATCH_INFO = config.server.dispatch;
    public static final Game GAME_INFO = config.server.game;
    
    public static final Encryption DISPATCH_ENCRYPTION = config.server.dispatch.encryption;
    public static final Policies DISPATCH_POLICIES = config.server.dispatch.policies;
    
    public static final GameOptions GAME_OPTIONS = config.server.game.gameOptions;
    public static final GameOptions.InventoryLimits INVENTORY_LIMITS = config.server.game.gameOptions.inventoryLimits;
    
    /*
     * Utilities
     */
    
    public static String DATA(String path) {
        return DATA_FOLDER + "/" + path;
    }
    
    public static String RESOURCE(String path) {
        return RESOURCES_FOLDER + "/" + path;
    }
    
    public static String SCRIPT(String path) {
        return SCRIPTS_FOLDER + "/" + path;
    }

    /**
     * Fallback method.
     * @param left Attempt to use.
     * @param right Use if left is undefined.
     * @return Left or right.
     */
    public static <T> T lr(T left, T right) {
        return left == null ? right : left;
    }

    /**
     * {@link Configuration#lr(Object, Object)} for {@link String}s.
     * @param left Attempt to use.
     * @param right Use if left is empty.
     * @return Left or right.
     */
    public static String lr(String left, String right) {
        return left.isEmpty() ? right : left;
    }

    /**
     * {@link Configuration#lr(Object, Object)} for {@link Integer}s.
     * @param left Attempt to use.
     * @param right Use if left is 0.
     * @return Left or right.
     */
    public static int lr(int left, int right) {
        return left == 0 ? right : left;
    }
    
    /*
     * Configuration data.
     */
    
KingRainbow44's avatar
KingRainbow44 committed
143
144
145
    public Structure folderStructure;
    public Database databaseInfo;
    public Language language;
146
    public Account account;
KingRainbow44's avatar
KingRainbow44 committed
147
148
    public Server server;
    
149
150
151
    // DO NOT. TOUCH. THE VERSION NUMBER.
    public int version = version();
    
KingRainbow44's avatar
KingRainbow44 committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
    /* Option containers. */
    
    public static class Database {
        public String connectionUri = "mongodb://localhost:27017";
        public String collection = "grasscutter";
    }
    
    public static class Structure {
        public String resources = "./resources/";
        public String data = "./data/";
        public String packets = "./packets/";
        public String keys = "./keys/";
        public String scripts = "./resources/scripts/";
        public String plugins = "./plugins/";
        
        // UNUSED (potentially added later?)
        // public String dumps = "./dumps/";
    }
    
    public static class Server {
        public ServerDebugMode debugLevel = ServerDebugMode.NONE;
        public ServerRunMode runMode = ServerRunMode.HYBRID;
        
        public Dispatch dispatch = new Dispatch();
        public Game game = new Game();
    }
    
    public static class Language {
        public Locale language = Locale.getDefault();
        public Locale fallback = Locale.US;
    }
183
184
185
186
187
    
    public static class Account {
        public boolean autoCreate = false;
        public String[] defaultPermissions = {};
    }
KingRainbow44's avatar
KingRainbow44 committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

    /* Server options. */

    public static class Dispatch {
        public String bindAddress = "0.0.0.0";
        /* This is the address used in URLs. */
        public String accessAddress = "127.0.0.1";

        public int bindPort = 443;
        /* This is the port used in URLs. */
        public int accessPort = 443;
        
        public Encryption encryption = new Encryption();
        public Policies policies = new Policies();
        public Region[] regions = {};
203
204
        
        public String defaultName = "Grasscutter";
KingRainbow44's avatar
KingRainbow44 committed
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    }
    
    public static class Game {
        public String bindAddress = "0.0.0.0";
        /* This is the address used in the default region. */
        public String accessAddress = "127.0.0.1";

        public int bindPort = 443;
        /* This is the port used in the default region. */
        public int accessPort = 443;
        
        public GameOptions gameOptions = new GameOptions();
        public JoinOptions joinOptions = new JoinOptions();
        public ConsoleAccount serverAccount = new ConsoleAccount();
    }
    
    /* Data containers. */
    
    public static class Encryption {
        public boolean useEncryption = true;
        /* Should 'https' be appended to URLs? */
        public boolean useInRouting = true;
        public String keystore = "./keystore.p12";
        public String keystorePassword = "123456";
    }
    
    public static class Policies {
        public CORS cors = new CORS();
        
        public static class CORS {
            public boolean enabled = false;
            public String[] allowedOrigins = new String[]{"*"};
        }
    }
    
    public static class GameOptions {
        public InventoryLimits inventoryLimits = new InventoryLimits();
        public AvatarLimits avatarLimits = new AvatarLimits();
        public int worldEntityLimit = 1000; // Unenforced. TODO: Implement.
        
245
        public boolean watchGachaConfig = false;
KingRainbow44's avatar
KingRainbow44 committed
246
        public boolean enableShopItems = true;
247
        public boolean staminaUsage = true;
KingRainbow44's avatar
KingRainbow44 committed
248
249
        public Rates rates = new Rates();
        
250
251
        public Database databaseInfo = new Database();
        
KingRainbow44's avatar
KingRainbow44 committed
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
        public static class InventoryLimits {
            public int weapons = 2000;
            public int relics = 2000;
            public int materials = 2000;
            public int furniture = 2000;
            public int all = 30000;
        }
        
        public static class AvatarLimits {
            public int singlePlayerTeam = 4;
            public int multiplayerTeam = 4;
        }
        
        public static class Rates {
            public float adventureExp = 1.0f;
            public float mora = 1.0f;
            public float leyLines = 1.0f;
        }
    }

    public static class JoinOptions {
        public int[] welcomeEmotes = {2007, 1002, 4010};
        public String welcomeMessage = "Welcome to a Grasscutter server.";
275
        public Mail welcomeMail = new Mail();
KingRainbow44's avatar
KingRainbow44 committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
        
        public static class Mail {
            public String title = "Welcome to Grasscutter!";
            public String content = """
                    Hi there!\r
                    First of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! \r
                    \r
                    Check out our:\r
                    <type="browser" text="Discord" href="https://discord.gg/T5vZU6UyeG"/>
                    """;
            public String sender = "Lawnmower";
            public MailItem[] items = {
                    new MailItem(13509, 1, 1),
                    new MailItem(201, 99999, 1)
            };
        }
    }
    
    public static class ConsoleAccount {
        public int avatarId = 10000007;
        public int nameCardId = 210001;
        public int adventureRank = 1;
        public int worldLevel = 0;
        
        public String nickName = "Server";
        public String signature = "Welcome to Grasscutter!";
    }

    /* Objects. */
    
    public static class Region {
        public String Name = "os_usa";
        public String Title = "Grasscutter";
        public String Ip = "127.0.0.1";
        public int Port = 22102;
    }
}