2022-04-17 20:43:07 +08:00
|
|
|
package emu.grasscutter.tools;
|
|
|
|
|
2022-05-06 12:56:34 +08:00
|
|
|
import java.io.BufferedReader;
|
2022-05-02 14:17:18 +08:00
|
|
|
import java.io.File;
|
2022-04-22 23:11:29 +08:00
|
|
|
import java.io.FileInputStream;
|
2022-04-23 02:28:34 +08:00
|
|
|
import java.io.FileOutputStream;
|
2022-04-17 20:43:07 +08:00
|
|
|
import java.io.FileReader;
|
|
|
|
import java.io.FileWriter;
|
2022-05-06 12:56:34 +08:00
|
|
|
import java.io.FilenameFilter;
|
2022-04-22 23:11:29 +08:00
|
|
|
import java.io.InputStreamReader;
|
2022-04-23 02:28:34 +08:00
|
|
|
import java.io.OutputStreamWriter;
|
2022-04-17 20:43:07 +08:00
|
|
|
import java.io.PrintWriter;
|
2022-04-22 23:11:29 +08:00
|
|
|
import java.nio.charset.StandardCharsets;
|
2022-04-17 20:43:07 +08:00
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.format.DateTimeFormatter;
|
2022-05-08 05:20:12 +08:00
|
|
|
import java.util.*;
|
2022-04-17 20:43:07 +08:00
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
import com.google.gson.reflect.TypeToken;
|
|
|
|
|
2022-04-27 12:21:57 +08:00
|
|
|
import emu.grasscutter.GameConstants;
|
2022-04-17 20:43:07 +08:00
|
|
|
import emu.grasscutter.Grasscutter;
|
2022-05-08 05:20:12 +08:00
|
|
|
import emu.grasscutter.command.Command;
|
2022-05-08 10:33:53 +08:00
|
|
|
import emu.grasscutter.command.CommandHandler;
|
2022-05-08 05:20:12 +08:00
|
|
|
import emu.grasscutter.command.CommandMap;
|
2022-04-27 12:21:57 +08:00
|
|
|
import emu.grasscutter.data.GameData;
|
2022-04-17 20:43:07 +08:00
|
|
|
import emu.grasscutter.data.ResourceLoader;
|
|
|
|
import emu.grasscutter.data.def.AvatarData;
|
|
|
|
import emu.grasscutter.data.def.ItemData;
|
|
|
|
import emu.grasscutter.data.def.MonsterData;
|
2022-04-19 01:14:45 +08:00
|
|
|
import emu.grasscutter.data.def.SceneData;
|
2022-04-20 02:11:48 +08:00
|
|
|
import emu.grasscutter.utils.Utils;
|
2022-04-17 20:43:07 +08:00
|
|
|
|
2022-05-08 14:44:14 +08:00
|
|
|
import static emu.grasscutter.utils.Language.translate;
|
|
|
|
|
2022-04-18 13:11:27 +08:00
|
|
|
public final class Tools {
|
2022-05-06 12:56:34 +08:00
|
|
|
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();
|
2022-04-17 20:43:07 +08:00
|
|
|
|
2022-05-06 12:56:34 +08:00
|
|
|
// Use system out for better format
|
|
|
|
if (availableLangList.size() == 1) {
|
|
|
|
return availableLangList.get(0).toUpperCase();
|
|
|
|
}
|
2022-05-07 13:47:36 +08:00
|
|
|
String stagedMessage = "";
|
|
|
|
stagedMessage += "The following languages mappings are available, please select one: [default: EN]\n";
|
|
|
|
String groupedLangList = ">\t";
|
2022-05-06 12:56:34 +08:00
|
|
|
int groupedLangCount = 0;
|
|
|
|
String input = "";
|
|
|
|
for (String availableLanguage: availableLangList){
|
|
|
|
groupedLangCount++;
|
|
|
|
groupedLangList = groupedLangList + "" + availableLanguage + "\t";
|
|
|
|
if (groupedLangCount == 6) {
|
2022-05-07 13:47:36 +08:00
|
|
|
stagedMessage += groupedLangList + "\n";
|
2022-05-06 12:56:34 +08:00
|
|
|
groupedLangCount = 0;
|
2022-05-07 13:47:36 +08:00
|
|
|
groupedLangList = ">\t";
|
2022-05-06 12:56:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (groupedLangCount > 0) {
|
2022-05-07 13:47:36 +08:00
|
|
|
stagedMessage += groupedLangList + "\n";
|
2022-05-06 12:56:34 +08:00
|
|
|
}
|
2022-05-07 13:47:36 +08:00
|
|
|
stagedMessage += "\nYour choice:[EN] ";
|
|
|
|
|
|
|
|
input = Grasscutter.getConsole().readLine(stagedMessage);
|
2022-05-06 12:56:34 +08:00
|
|
|
if (availableLangList.contains(input.toLowerCase())) {
|
|
|
|
return input.toUpperCase();
|
|
|
|
}
|
|
|
|
Grasscutter.getLogger().info("Invalid option. Will use EN(English) as fallback");
|
|
|
|
|
|
|
|
return "EN";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final class ToolsWithLanguageOption {
|
2022-04-17 20:43:07 +08:00
|
|
|
@SuppressWarnings("deprecation")
|
2022-05-06 12:56:34 +08:00
|
|
|
public static void createGmHandbook(String language) throws Exception {
|
2022-04-17 20:43:07 +08:00
|
|
|
ResourceLoader.loadResources();
|
|
|
|
|
|
|
|
Map<Long, String> map;
|
2022-05-06 12:56:34 +08:00
|
|
|
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap/TextMap"+language+".json")), StandardCharsets.UTF_8)) {
|
2022-04-17 20:43:07 +08:00
|
|
|
map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
List<Integer> list;
|
|
|
|
String fileName = "./GM Handbook.txt";
|
2022-04-23 02:28:34 +08:00
|
|
|
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
|
2022-04-17 20:43:07 +08:00
|
|
|
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
|
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
2022-04-27 12:21:57 +08:00
|
|
|
writer.println("// Grasscutter " + GameConstants.VERSION + " GM Handbook");
|
2022-04-17 20:43:07 +08:00
|
|
|
writer.println("// Created " + dtf.format(now) + System.lineSeparator() + System.lineSeparator());
|
2022-05-08 05:20:12 +08:00
|
|
|
|
|
|
|
CommandMap cmdMap = new CommandMap(true);
|
2022-05-08 14:44:14 +08:00
|
|
|
List<Command> cmdList = new ArrayList<>(cmdMap.getAnnotationsAsList());
|
2022-05-08 05:20:12 +08:00
|
|
|
|
|
|
|
writer.println("// Commands");
|
2022-05-08 14:44:14 +08:00
|
|
|
for (Command cmd : cmdList) {
|
|
|
|
String cmdName = cmd.label();
|
2022-05-08 05:20:12 +08:00
|
|
|
while (cmdName.length() <= 15) {
|
|
|
|
cmdName = " " + cmdName;
|
|
|
|
}
|
2022-05-08 14:44:14 +08:00
|
|
|
writer.println(cmdName + " : " + translate(cmd.description()));
|
|
|
|
}
|
2022-05-08 05:20:12 +08:00
|
|
|
writer.println();
|
|
|
|
|
2022-04-27 12:21:57 +08:00
|
|
|
list = new ArrayList<>(GameData.getAvatarDataMap().keySet());
|
2022-04-17 20:43:07 +08:00
|
|
|
Collections.sort(list);
|
|
|
|
|
|
|
|
writer.println("// Avatars");
|
|
|
|
for (Integer id : list) {
|
2022-04-27 12:21:57 +08:00
|
|
|
AvatarData data = GameData.getAvatarDataMap().get(id);
|
2022-04-17 20:43:07 +08:00
|
|
|
writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
|
|
|
|
}
|
|
|
|
|
|
|
|
writer.println();
|
|
|
|
|
2022-04-27 12:21:57 +08:00
|
|
|
list = new ArrayList<>(GameData.getItemDataMap().keySet());
|
2022-04-17 20:43:07 +08:00
|
|
|
Collections.sort(list);
|
|
|
|
|
|
|
|
writer.println("// Items");
|
|
|
|
for (Integer id : list) {
|
2022-04-27 12:21:57 +08:00
|
|
|
ItemData data = GameData.getItemDataMap().get(id);
|
2022-04-17 20:43:07 +08:00
|
|
|
writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
|
|
|
|
}
|
|
|
|
|
|
|
|
writer.println();
|
|
|
|
|
2022-04-19 01:14:45 +08:00
|
|
|
writer.println("// Scenes");
|
2022-04-27 12:21:57 +08:00
|
|
|
list = new ArrayList<>(GameData.getSceneDataMap().keySet());
|
2022-04-19 01:14:45 +08:00
|
|
|
Collections.sort(list);
|
|
|
|
|
|
|
|
for (Integer id : list) {
|
2022-04-27 12:21:57 +08:00
|
|
|
SceneData data = GameData.getSceneDataMap().get(id);
|
2022-04-19 01:14:45 +08:00
|
|
|
writer.println(data.getId() + " : " + data.getScriptData());
|
|
|
|
}
|
|
|
|
|
|
|
|
writer.println();
|
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
writer.println("// Monsters");
|
2022-04-27 12:21:57 +08:00
|
|
|
list = new ArrayList<>(GameData.getMonsterDataMap().keySet());
|
2022-04-17 20:43:07 +08:00
|
|
|
Collections.sort(list);
|
|
|
|
|
|
|
|
for (Integer id : list) {
|
2022-04-27 12:21:57 +08:00
|
|
|
MonsterData data = GameData.getMonsterDataMap().get(id);
|
2022-04-17 20:43:07 +08:00
|
|
|
writer.println(data.getId() + " : " + map.get(data.getNameTextMapHash()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Grasscutter.getLogger().info("GM Handbook generated!");
|
|
|
|
}
|
2022-05-02 14:17:18 +08:00
|
|
|
|
|
|
|
@SuppressWarnings("deprecation")
|
2022-05-06 12:56:34 +08:00
|
|
|
public static void createGachaMapping(String location, String language) throws Exception {
|
2022-05-02 14:17:18 +08:00
|
|
|
ResourceLoader.loadResources();
|
|
|
|
|
|
|
|
Map<Long, String> map;
|
2022-05-06 12:56:34 +08:00
|
|
|
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(Grasscutter.getConfig().RESOURCE_FOLDER + "TextMap/TextMap"+language+".json")), StandardCharsets.UTF_8)) {
|
2022-05-02 14:17:18 +08:00
|
|
|
map = Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<Long, String>>() {}.getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
List<Integer> list;
|
|
|
|
|
2022-05-05 15:59:48 +08:00
|
|
|
String fileName = location;
|
2022-05-02 14:17:18 +08:00
|
|
|
|
|
|
|
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8), false)) {
|
|
|
|
|
|
|
|
list = new ArrayList<>(GameData.getAvatarDataMap().keySet());
|
|
|
|
Collections.sort(list);
|
|
|
|
|
2022-05-06 12:56:34 +08:00
|
|
|
// 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.
|
2022-05-02 14:17:18 +08:00
|
|
|
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";
|
|
|
|
}
|
2022-05-06 12:56:34 +08:00
|
|
|
// Got the magic number 4233146695 from manually search in the json file
|
2022-05-02 14:17:18 +08:00
|
|
|
writer.println(
|
|
|
|
"\"" + (avatarID % 1000 + 1000) + "\" : [\""
|
2022-05-06 12:56:34 +08:00
|
|
|
+ map.get(data.getNameTextMapHash()) + "(" + map.get(4233146695L)+ ")\", \""
|
2022-05-02 14:17:18 +08:00
|
|
|
+ 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
|
|
|
|
}
|
2022-05-06 12:56:34 +08:00
|
|
|
|
|
|
|
// Got the magic number 4231343903 from manually search in the json file
|
|
|
|
|
2022-05-02 14:17:18 +08:00
|
|
|
writer.println(",\"" + data.getId() +
|
|
|
|
"\" : [\"" + map.get(data.getNameTextMapHash()).replaceAll("\"", "")
|
2022-05-06 12:56:34 +08:00
|
|
|
+ "("+ map.get(4231343903L)+")\",\""+ color + "\"]");
|
2022-05-02 14:17:18 +08:00
|
|
|
}
|
2022-05-06 16:47:25 +08:00
|
|
|
writer.println(",\"200\": \""+map.get(332935371L)+"\", \"301\": \""+ map.get(2272170627L) + "\", \"302\": \""+map.get(2864268523L)+"\"");
|
2022-05-02 14:17:18 +08:00
|
|
|
writer.println("}\n}");
|
|
|
|
}
|
2022-05-06 12:57:45 +08:00
|
|
|
|
2022-05-07 13:47:36 +08:00
|
|
|
Grasscutter.getLogger().info("Mappings generated to " + location + " !");
|
2022-05-02 14:17:18 +08:00
|
|
|
}
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|