Tools.java 8.39 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
		// Use system out for better format
		if (availableLangList.size() == 1) {
			return availableLangList.get(0).toUpperCase();
		}
mingjun97's avatar
mingjun97 committed
67
68
69
		String stagedMessage = "";
		stagedMessage += "The following languages mappings are available, please select one: [default: EN]\n";
		String groupedLangList = ">\t";
70
71
72
73
74
75
		int groupedLangCount = 0;
		String input = "";
		for (String availableLanguage: availableLangList){
			groupedLangCount++;
			groupedLangList = groupedLangList + "" + availableLanguage + "\t";
			if (groupedLangCount == 6) {
mingjun97's avatar
mingjun97 committed
76
				stagedMessage += groupedLangList + "\n";
77
				groupedLangCount = 0;
mingjun97's avatar
mingjun97 committed
78
				groupedLangList = ">\t";
79
80
81
			}
		}
		if (groupedLangCount > 0) {
mingjun97's avatar
mingjun97 committed
82
			stagedMessage += groupedLangList + "\n";
83
		}
mingjun97's avatar
mingjun97 committed
84
85
86
		stagedMessage += "\nYour choice:[EN] ";
		
		input = Grasscutter.getConsole().readLine(stagedMessage);
87
88
89
90
91
92
93
94
95
96
		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
97
	@SuppressWarnings("deprecation")
98
	public static void createGmHandbook(String language) throws Exception {
Melledy's avatar
Melledy committed
99
100
101
		ResourceLoader.loadResources();
		
		Map<Long, String> map;
102
		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
103
104
105
106
107
			map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType());
		}
		
		List<Integer> list;
		String fileName = "./GM Handbook.txt";
108
		try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
Melledy's avatar
Melledy committed
109
110
111
			DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");  
			LocalDateTime now = LocalDateTime.now();
			   
112
			writer.println("// Grasscutter " + GameConstants.VERSION + " GM Handbook");
Melledy's avatar
Melledy committed
113
114
			writer.println("// Created " + dtf.format(now) + System.lineSeparator() + System.lineSeparator());
			
115
			list = new ArrayList<>(GameData.getAvatarDataMap().keySet());
Melledy's avatar
Melledy committed
116
117
118
119
			Collections.sort(list); 
			 
			writer.println("// Avatars");
			for (Integer id : list) {
120
				AvatarData data = GameData.getAvatarDataMap().get(id);
Melledy's avatar
Melledy committed
121
122
123
124
125
				writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
			}
			
			writer.println();
			
126
			list = new ArrayList<>(GameData.getItemDataMap().keySet());
Melledy's avatar
Melledy committed
127
128
129
130
			Collections.sort(list); 
			
			writer.println("// Items");
			for (Integer id : list) {
131
				ItemData data = GameData.getItemDataMap().get(id);
Melledy's avatar
Melledy committed
132
133
134
135
136
				writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
			}
			
			writer.println();
			
137
			writer.println("// Scenes");
138
			list = new ArrayList<>(GameData.getSceneDataMap().keySet());
139
140
141
			Collections.sort(list); 
			
			for (Integer id : list) {
142
				SceneData data = GameData.getSceneDataMap().get(id);
143
144
145
146
147
				writer.println(data.getId() + " : " + data.getScriptData());
			}
			
			writer.println();
			
Melledy's avatar
Melledy committed
148
			writer.println("// Monsters");
149
			list = new ArrayList<>(GameData.getMonsterDataMap().keySet());
Melledy's avatar
Melledy committed
150
151
152
			Collections.sort(list); 
			
			for (Integer id : list) {
153
				MonsterData data = GameData.getMonsterDataMap().get(id);
Melledy's avatar
Melledy committed
154
155
156
157
158
159
				writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
			}
		}
		
		Grasscutter.getLogger().info("GM Handbook generated!");
	}
160
161

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

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

		try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
			
			list = new ArrayList<>(GameData.getAvatarDataMap().keySet());
			Collections.sort(list); 
			 
179
180
181
			// 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.
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
208
			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";
				}
209
				// Got the magic number 4233146695 from manually search in the json file
210
211
				writer.println(
					"\"" + (avatarID % 1000 + 1000) + "\" : [\"" 
212
					+ map.get(data.getNameTextMapHash()) + "(" +  map.get(4233146695L)+ ")\", \"" 
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
					+ 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
				}
242
243
244
				
				// Got the magic number 4231343903 from manually search in the json file

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