DataLoader.java 5.42 KB
Newer Older
1
2
3
4
5
6
package emu.grasscutter.data;

import emu.grasscutter.Grasscutter;
import emu.grasscutter.server.http.handlers.GachaHandler;
import emu.grasscutter.tools.Tools;
import emu.grasscutter.utils.FileUtils;
7
import emu.grasscutter.utils.JsonUtils;
8
9
import emu.grasscutter.utils.Utils;

10
11
import static emu.grasscutter.config.Configuration.DATA;

KingRainbow44's avatar
KingRainbow44 committed
12
13
import java.io.FileInputStream;
import java.io.FileNotFoundException;
14
import java.io.IOException;
KingRainbow44's avatar
KingRainbow44 committed
15
import java.io.InputStream;
16
import java.io.InputStreamReader;
17
18
import java.nio.file.Path;
import java.util.List;
19
import java.util.Map;
20
21
22
23
24

public class DataLoader {

    /**
     * Load a data file by its name. If the file isn't found within the /data directory then it will fallback to the default within the jar resources
KingRainbow44's avatar
KingRainbow44 committed
25
     *
26
27
28
     * @param resourcePath The path to the data file to be loaded.
     * @return InputStream of the data file.
     * @throws FileNotFoundException
KingRainbow44's avatar
KingRainbow44 committed
29
     * @see #load(String, boolean)
30
31
32
33
     */
    public static InputStream load(String resourcePath) throws FileNotFoundException {
        return load(resourcePath, true);
    }
github-actions's avatar
github-actions committed
34

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    /**
     * Creates an input stream reader for a data file. If the file isn't found within the /data directory then it will fallback to the default within the jar resources
     *
     * @param resourcePath The path to the data file to be loaded.
     * @return InputStreamReader of the data file.
     * @throws IOException
     * @throws FileNotFoundException
     * @see #load(String, boolean)
     */
    public static InputStreamReader loadReader(String resourcePath) throws IOException, FileNotFoundException {
        try {
            InputStream is = load(resourcePath, true);
            return new InputStreamReader(is);
        } catch (FileNotFoundException exception) {
            throw exception;
        }
    }
52
53
54

    /**
     * Load a data file by its name.
KingRainbow44's avatar
KingRainbow44 committed
55
     *
56
     * @param resourcePath The path to the data file to be loaded.
KingRainbow44's avatar
KingRainbow44 committed
57
     * @param useFallback  If the file does not exist in the /data directory, should it use the default file in the jar?
58
59
60
61
     * @return InputStream of the data file.
     * @throws FileNotFoundException
     */
    public static InputStream load(String resourcePath, boolean useFallback) throws FileNotFoundException {
KingRainbow44's avatar
KingRainbow44 committed
62
        if (Utils.fileExists(DATA(resourcePath))) {
63
64
65
            // Data is in the resource directory
            return new FileInputStream(DATA(resourcePath));
        } else {
KingRainbow44's avatar
KingRainbow44 committed
66
            if (useFallback) {
67
68
69
70
71
72
73
                return FileUtils.readResourceAsStream("/defaults/data/" + resourcePath);
            }
        }

        return null;
    }

74
75
    public static <T> T loadClass(String resourcePath, Class<T> classType) throws IOException {
        try (InputStreamReader reader = loadReader(resourcePath)) {
76
            return JsonUtils.loadToClass(reader, classType);
77
78
79
80
81
        }
    }

    public static <T> List<T> loadList(String resourcePath, Class<T> classType) throws IOException {
        try (InputStreamReader reader = loadReader(resourcePath)) {
82
            return JsonUtils.loadToList(reader, classType);
83
84
85
86
87
        }
    }

    public static <T1,T2> Map<T1,T2> loadMap(String resourcePath, Class<T1> keyType, Class<T2> valueType) throws IOException {
        try (InputStreamReader reader = loadReader(resourcePath)) {
88
            return JsonUtils.loadToMap(reader, keyType, valueType);
89
90
91
        }
    }

92
    public static void checkAllFiles() {
93
94
        try {
            List<Path> filenames = FileUtils.getPathsFromResource("/defaults/data/");
KingRainbow44's avatar
KingRainbow44 committed
95

96
            if (filenames == null) {
KingRainbow44's avatar
KingRainbow44 committed
97
98
                Grasscutter.getLogger().error("We were unable to locate your default data files.");
            } else for (Path file : filenames) {
99
                String relativePath = String.valueOf(file).split("defaults[\\\\\\/]data[\\\\\\/]")[1];
100

101
                checkAndCopyData(relativePath);
102
103
            }
        } catch (Exception e) {
104
            Grasscutter.getLogger().error("An error occurred while trying to check the data folder.", e);
105
106
        }

107
        generateGachaMappings();
108
109
    }

110
    private static void checkAndCopyData(String name) {
111
112
113
114
        String filePath = Utils.toFilePath(DATA(name));

        if (!Utils.fileExists(filePath)) {
            // Check if file is in subdirectory
115
            if (name.contains("/")) {
116
117
118
                String[] path = name.split("/");

                String folder = "";
KingRainbow44's avatar
KingRainbow44 committed
119
                for (int i = 0; i < (path.length - 1); i++) {
120
121
122
123
                    folder += path[i] + "/";

                    // Make sure the current folder exists
                    String folderToCreate = Utils.toFilePath(DATA(folder));
KingRainbow44's avatar
KingRainbow44 committed
124
                    if (!Utils.fileExists(folderToCreate)) {
125
126
127
128
129
130
131
132
133
134
135
                        Grasscutter.getLogger().info("Creating data folder '" + folder + "'");
                        Utils.createFolder(folderToCreate);
                    }
                }
            }

            Grasscutter.getLogger().info("Creating default '" + name + "' data");
            FileUtils.copyResource("/defaults/data/" + name, filePath);
        }
    }

136
    private static void generateGachaMappings() {
137
138
139
140
141
142
143
144
145
146
        if (!Utils.fileExists(GachaHandler.gachaMappings)) {
            try {
                Grasscutter.getLogger().info("Creating default '" + GachaHandler.gachaMappings + "' data");
                Tools.createGachaMapping(GachaHandler.gachaMappings);
            } catch (Exception exception) {
                Grasscutter.getLogger().warn("Failed to create gacha mappings. \n" + exception);
            }
        }
    }
}