Tools.java 8.35 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
package emu.grasscutter.tools;

3
import java.io.BufferedReader;
4
import java.io.File;
5
import java.io.FileInputStream;
6
import java.io.FileOutputStream;
Melledy's avatar
Melledy committed
7
8
import java.io.FileReader;
import java.io.FileWriter;
9
import java.io.FilenameFilter;
10
import java.io.InputStreamReader;
11
import java.io.OutputStreamWriter;
Melledy's avatar
Melledy committed
12
import java.io.PrintWriter;
13
import java.nio.charset.StandardCharsets;
Melledy's avatar
Melledy committed
14
15
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
KingRainbow44's avatar
KingRainbow44 committed
16
import java.util.ArrayList;
Melledy's avatar
Melledy committed
17
18
19
20
21
22
23
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.google.gson.reflect.TypeToken;

24
import emu.grasscutter.GameConstants;
Melledy's avatar
Melledy committed
25
import emu.grasscutter.Grasscutter;
26
import emu.grasscutter.data.GameData;
Melledy's avatar
Melledy committed
27
28
29
30
import emu.grasscutter.data.ResourceLoader;
import emu.grasscutter.data.def.AvatarData;
import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.data.def.MonsterData;
31
import emu.grasscutter.data.def.SceneData;
32
import emu.grasscutter.utils.Utils;
Melledy's avatar
Melledy committed
33

KingRainbow44's avatar
KingRainbow44 committed
34
public final class Tools {
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	public static void createGmHandbook() throws Exception {
		ToolsWithLanguageOption.createGmHandbook(getLanguageOption());
	}

	public static void createGachaMapping(String location) throws Exception {
		ToolsWithLanguageOption.createGachaMapping(location, getLanguageOption());
	}

	public static List<String> getAvailableLanguage() throws Exception {
		File textMapFolder = new File(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap");
		List<String> availableLangList = new ArrayList<String>();
		for (String textMapFileName : textMapFolder.list(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				if (name.startsWith("TextMap") && name.endsWith(".json")){
					return true;
				}
				return false;
			}
		})) {
			availableLangList.add(textMapFileName.replace("TextMap","").replace(".json","").toLowerCase());
		}
		return availableLangList;
	}

	public static String getLanguageOption() throws Exception {
		List<String> availableLangList = getAvailableLanguage();
Melledy's avatar
Melledy committed
62
	
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
		// Use system out for better format
		if (availableLangList.size() == 1) {
			return availableLangList.get(0).toUpperCase();
		}
		System.out.println("The following languages mappings are available, please select one: [default: EN]");
		String groupedLangList = "> ";
		int groupedLangCount = 0;
		String input = "";
		for (String availableLanguage: availableLangList){
			groupedLangCount++;
			groupedLangList = groupedLangList + "" + availableLanguage + "\t";
			if (groupedLangCount == 6) {
				System.out.println(groupedLangList);
				groupedLangCount = 0;
				groupedLangList = "> ";
			}
		}
		if (groupedLangCount > 0) {
			System.out.println(groupedLangList);
		}
Magix's avatar
Magix committed
83
		System.out.print("\nYour choice:[EN] ");
84
85
86
87
88
89
90
91
92
93
94
95

		input = new BufferedReader(new InputStreamReader(System.in)).readLine();
		if (availableLangList.contains(input.toLowerCase())) {
			return input.toUpperCase();
		}
		Grasscutter.getLogger().info("Invalid option. Will use EN(English) as fallback");

		return "EN";
	}
}

final class ToolsWithLanguageOption {
Melledy's avatar
Melledy committed
96
	@SuppressWarnings("deprecation")
97
	public static void createGmHandbook(String language) throws Exception {
Melledy's avatar
Melledy committed
98
99
100
		ResourceLoader.loadResources();
		
		Map<Long, String> map;
101
		try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap/TextMap"+language+".json")), StandardCharsets.UTF_8)) {
Melledy's avatar
Melledy committed
102
103
104
105
106
			map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType());
		}
		
		List<Integer> list;
		String fileName = "./GM Handbook.txt";
107
		try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
Melledy's avatar
Melledy committed
108
109
110
			DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");  
			LocalDateTime now = LocalDateTime.now();
			   
111
			writer.println("// Grasscutter " + GameConstants.VERSION + " GM Handbook");
Melledy's avatar
Melledy committed
112
113
			writer.println("// Created " + dtf.format(now) + System.lineSeparator() + System.lineSeparator());
			
114
			list = new ArrayList<>(GameData.getAvatarDataMap().keySet());
Melledy's avatar
Melledy committed
115
116
117
118
			Collections.sort(list); 
			 
			writer.println("// Avatars");
			for (Integer id : list) {
119
				AvatarData data = GameData.getAvatarDataMap().get(id);
Melledy's avatar
Melledy committed
120
121
122
123
124
				writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
			}
			
			writer.println();
			
125
			list = new ArrayList<>(GameData.getItemDataMap().keySet());
Melledy's avatar
Melledy committed
126
127
128
129
			Collections.sort(list); 
			
			writer.println("// Items");
			for (Integer id : list) {
130
				ItemData data = GameData.getItemDataMap().get(id);
Melledy's avatar
Melledy committed
131
132
133
134
135
				writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
			}
			
			writer.println();
			
136
			writer.println("// Scenes");
137
			list = new ArrayList<>(GameData.getSceneDataMap().keySet());
138
139
140
			Collections.sort(list); 
			
			for (Integer id : list) {
141
				SceneData data = GameData.getSceneDataMap().get(id);
142
143
144
145
146
				writer.println(data.getId() + " : " + data.getScriptData());
			}
			
			writer.println();
			
Melledy's avatar
Melledy committed
147
			writer.println("// Monsters");
148
			list = new ArrayList<>(GameData.getMonsterDataMap().keySet());
Melledy's avatar
Melledy committed
149
150
151
			Collections.sort(list); 
			
			for (Integer id : list) {
152
				MonsterData data = GameData.getMonsterDataMap().get(id);
Melledy's avatar
Melledy committed
153
154
155
156
157
158
				writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
			}
		}
		
		Grasscutter.getLogger().info("GM Handbook generated!");
	}
159
160

	@SuppressWarnings("deprecation")
161
	public static void createGachaMapping(String location, String language) throws Exception {
162
163
164
		ResourceLoader.loadResources();
		
		Map<Long, String> map;
165
		try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap/TextMap"+language+".json")), StandardCharsets.UTF_8)) {
166
167
168
169
170
			map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType());
		}
		
		List<Integer> list;

171
		String fileName = location;
172
173
174
175
176
177

		try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
			
			list = new ArrayList<>(GameData.getAvatarDataMap().keySet());
			Collections.sort(list); 
			 
178
179
180
			// if the user made choices for language, I assume it's okay to assign his/her selected language to "en-us"
			// since it's the fallback language and there will be no difference in the gacha record page. 
			// The enduser can still modify the `gacha_mappings.js` directly to enable multilingual for the gacha record system.
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
			writer.println("mappings = {\"en-us\": {"); 

			// Avatars
			boolean first = true;
			for (Integer id : list) {
				AvatarData data = GameData.getAvatarDataMap().get(id);
				int avatarID = data.getId();
				if (avatarID >= 11000000) { // skip test avatar
					continue;
				}
				if (first) { // skip adding comma for the first element
					first = false;
				} else {
					writer.print(",");
				}
				String color;
				switch (data.getQualityType()){
					case "QUALITY_PURPLE":
						color = "purple";
						break;
					case "QUALITY_ORANGE":
						color = "yellow";
						break;
					case "QUALITY_BLUE":
					default:
						color = "blue";
				}
208
				// Got the magic number 4233146695 from manually search in the json file
209
210
				writer.println(
					"\"" + (avatarID % 1000 + 1000) + "\" : [\"" 
211
					+ map.get(data.getNameTextMapHash()) + "(" +  map.get(4233146695L)+ ")\", \"" 
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
					+ color + "\"]");
			}
			
			writer.println();
			
			list = new ArrayList<>(GameData.getItemDataMap().keySet());
			Collections.sort(list); 
			
			// Weapons
			for (Integer id : list) {
				ItemData data = GameData.getItemDataMap().get(id);
				if (data.getId() <= 11101 || data.getId() >= 20000) {
					continue; //skip non weapon items
				}
				String color;

				switch (data.getRankLevel()){
					case 3: 
						color = "blue";
						break;
					case 4:
						color = "purple";
						break;
					case 5:
						color = "yellow";
						break;
					default:
						continue; // skip unnecessary entries
				}
241
242
243
				
				// Got the magic number 4231343903 from manually search in the json file

244
245
				writer.println(",\"" + data.getId() +
						 "\" : [\"" + map.get(data.getNameTextMapHash()).replaceAll("\"", "")
246
						 + "("+ map.get(4231343903L)+")\",\""+ color + "\"]");
247
			}
248
			writer.println(",\"200\": \""+map.get(332935371L)+"\", \"301\": \""+ map.get(2272170627L) + "\", \"302\": \""+map.get(2864268523L)+"\"");
249
250
			writer.println("}\n}");
		}
251
		
252
253
		Grasscutter.getLogger().info("Mappings generated!");
	}
Melledy's avatar
Melledy committed
254
}