Skip to content
Snippets Groups Projects
Commit 8b5f7dd0 authored by KingRainbow44's avatar KingRainbow44
Browse files

Refactor existing code

parent 7925d1cd
Branches
Tags
No related merge requests found
Showing
with 311 additions and 264 deletions
Manifest-Version: 1.0
Main-Class: emu.grasscutter.Grasscutter
package emu.grasscutter; package emu.grasscutter;
public class Config { public final class Config {
public String DispatchServerIp = "127.0.0.1"; public String DispatchServerIp = "127.0.0.1";
public int DispatchServerPort = 443; public int DispatchServerPort = 443;
public String DispatchServerKeystorePath = "./keystore.p12"; public String DispatchServerKeystorePath = "./keystore.p12";
...@@ -31,14 +31,14 @@ public class Config { ...@@ -31,14 +31,14 @@ public class Config {
return ServerOptions; return ServerOptions;
} }
public class GameRates { public static class GameRates {
public float ADVENTURE_EXP_RATE = 1.0f; public float ADVENTURE_EXP_RATE = 1.0f;
public float MORA_RATE = 1.0f; public float MORA_RATE = 1.0f;
public float DOMAIN_DROP_RATE = 1.0f; public float DOMAIN_DROP_RATE = 1.0f;
} }
public class ServerOptions { public static class ServerOptions {
public int MaxEntityLimit = 1000; // Max entity limit per world. TODO Unenforced for now public int MaxEntityLimit = 1000; // Max entity limit per world. // TODO: Enforce later.
public int[] WelcomeEmotes = {2007, 1002, 4010}; public int[] WelcomeEmotes = {2007, 1002, 4010};
public String WelcomeMotd = "Welcome to Grasscutter emu"; public String WelcomeMotd = "Welcome to Grasscutter emu";
} }
......
...@@ -2,11 +2,10 @@ package emu.grasscutter; ...@@ -2,11 +2,10 @@ package emu.grasscutter;
import java.util.Arrays; import java.util.Arrays;
import emu.grasscutter.game.props.OpenState;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
public class GenshinConstants { public final class GenshinConstants {
public static String VERSION = "2.6.0"; public static String VERSION = "2.6.0";
public static final int MAX_TEAMS = 4; public static final int MAX_TEAMS = 4;
...@@ -25,9 +24,9 @@ public class GenshinConstants { ...@@ -25,9 +24,9 @@ public class GenshinConstants {
public static final int MAX_FRIENDS = 45; public static final int MAX_FRIENDS = 45;
public static final int MAX_FRIEND_REQUESTS = 50; public static final int MAX_FRIEND_REQUESTS = 50;
public static final int SERVER_CONSOLE_UID = 99; // uid of the fake player used for commands public static final int SERVER_CONSOLE_UID = 99; // The UID of the server console's "player".
// Default entity ability hashes // Default entity ability hashes.
public static final String[] DEFAULT_ABILITY_STRINGS = { public static final String[] DEFAULT_ABILITY_STRINGS = {
"Avatar_DefaultAbility_VisionReplaceDieInvincible", "Avatar_DefaultAbility_AvartarInShaderChange", "Avatar_SprintBS_Invincible", "Avatar_DefaultAbility_VisionReplaceDieInvincible", "Avatar_DefaultAbility_AvartarInShaderChange", "Avatar_SprintBS_Invincible",
"Avatar_Freeze_Duration_Reducer", "Avatar_Attack_ReviveEnergy", "Avatar_Component_Initializer", "Avatar_FallAnthem_Achievement_Listener" "Avatar_Freeze_Duration_Reducer", "Avatar_Attack_ReviveEnergy", "Avatar_Component_Initializer", "Avatar_FallAnthem_Achievement_Listener"
......
...@@ -6,8 +6,8 @@ import java.io.FileReader; ...@@ -6,8 +6,8 @@ import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Arrays;
import emu.grasscutter.utils.Utils;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.google.gson.Gson; import com.google.gson.Gson;
...@@ -22,19 +22,25 @@ import emu.grasscutter.server.game.GameServer; ...@@ -22,19 +22,25 @@ import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.tools.Tools; import emu.grasscutter.tools.Tools;
import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.Crypto;
public class Grasscutter { public final class Grasscutter {
private static Logger log = (Logger) LoggerFactory.getLogger(Grasscutter.class); private static final Logger log = (Logger) LoggerFactory.getLogger(Grasscutter.class);
private static Config config; private static Config config;
private static Gson gson = new GsonBuilder().setPrettyPrinting().create(); private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private static File configFile = new File("./config.json"); private static final File configFile = new File("./config.json");
public static RunMode MODE = RunMode.BOTH; public static RunMode MODE = RunMode.BOTH;
private static DispatchServer dispatchServer; private static DispatchServer dispatchServer;
private static GameServer gameServer; private static GameServer gameServer;
public static void main(String[] args) throws Exception { static {
// Load configuration.
Grasscutter.loadConfig(); Grasscutter.loadConfig();
// Check server structure.
Utils.startupCheck();
}
public static void main(String[] args) throws Exception {
Crypto.loadKeys(); Crypto.loadKeys();
for (String arg : args) { for (String arg : args) {
...@@ -48,56 +54,34 @@ public class Grasscutter { ...@@ -48,56 +54,34 @@ public class Grasscutter {
case "-handbook": case "-handbook":
Tools.createGmHandbook(); Tools.createGmHandbook();
return; return;
} }
} }
// Startup // Initialize server.
Grasscutter.getLogger().info("Grasscutter Emu"); Grasscutter.getLogger().info("Starting Grasscutter...");
// Load resource files // Load all resources.
ResourceLoader.loadAll(); ResourceLoader.loadAll();
// Database // Database
DatabaseManager.initialize(); DatabaseManager.initialize();
// Run servers // Start servers.
dispatchServer = new DispatchServer(); dispatchServer = new DispatchServer();
dispatchServer.start(); dispatchServer.start();
gameServer = new GameServer(new InetSocketAddress(getConfig().GameServerIp, getConfig().GameServerPort)); gameServer = new GameServer(new InetSocketAddress(getConfig().GameServerIp, getConfig().GameServerPort));
gameServer.start(); gameServer.start();
// Open console.
startConsole(); startConsole();
} }
public static Config getConfig() {
return config;
}
public static Logger getLogger() {
return log;
}
public static Gson getGsonFactory() {
return gson;
}
public static DispatchServer getDispatchServer() {
return dispatchServer;
}
public static GameServer getGameServer() {
return gameServer;
}
public static void loadConfig() { public static void loadConfig() {
try (FileReader file = new FileReader(configFile)) { try (FileReader file = new FileReader(configFile)) {
config = gson.fromJson(file, Config.class); config = gson.fromJson(file, Config.class);
} catch (Exception e) { } catch (Exception e) {
Grasscutter.config = new Config(); Grasscutter.config = new Config(); saveConfig();
} }
saveConfig();
} }
public static void saveConfig() { public static void saveConfig() {
...@@ -115,7 +99,7 @@ public class Grasscutter { ...@@ -115,7 +99,7 @@ public class Grasscutter {
ServerCommands.handle(input); ServerCommands.handle(input);
} }
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().error("Console error:", e); Grasscutter.getLogger().error("An error occurred.", e);
} }
} }
...@@ -124,4 +108,24 @@ public class Grasscutter { ...@@ -124,4 +108,24 @@ public class Grasscutter {
AUTH, AUTH,
GAME GAME
} }
public static Config getConfig() {
return config;
}
public static Logger getLogger() {
return log;
}
public static Gson getGsonFactory() {
return gson;
}
public static DispatchServer getDispatchServer() {
return dispatchServer;
}
public static GameServer getGameServer() {
return gameServer;
}
} }
...@@ -5,9 +5,9 @@ import java.lang.annotation.RetentionPolicy; ...@@ -5,9 +5,9 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Command { public @interface Command {
public String[] aliases() default ""; String[] aliases() default "";
public int gmLevel() default 1; int gmLevel() default 1;
public String helpText() default ""; String helpText() default "";
} }
package emu.grasscutter.database; package emu.grasscutter.database;
import java.sql.Connection;
import java.sql.SQLException;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI; import com.mongodb.MongoClientURI;
import com.mongodb.MongoCommandException; import com.mongodb.MongoCommandException;
...@@ -18,12 +15,11 @@ import emu.grasscutter.game.avatar.GenshinAvatar; ...@@ -18,12 +15,11 @@ import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.friends.Friendship; import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.inventory.GenshinItem; import emu.grasscutter.game.inventory.GenshinItem;
public class DatabaseManager { public final class DatabaseManager {
private static MongoClient mongoClient; private static MongoClient mongoClient;
private static Morphia morphia;
private static Datastore datastore; private static Datastore datastore;
private static Class<?>[] mappedClasses = new Class<?>[] { private static final Class<?>[] mappedClasses = new Class<?>[] {
DatabaseCounter.class, Account.class, GenshinPlayer.class, GenshinAvatar.class, GenshinItem.class, Friendship.class DatabaseCounter.class, Account.class, GenshinPlayer.class, GenshinAvatar.class, GenshinItem.class, Friendship.class
}; };
...@@ -39,14 +35,10 @@ public class DatabaseManager { ...@@ -39,14 +35,10 @@ public class DatabaseManager {
return getDatastore().getDatabase(); return getDatastore().getDatabase();
} }
public static Connection getConnection() throws SQLException {
return null;
}
public static void initialize() { public static void initialize() {
// Initialize // Initialize
mongoClient = new MongoClient(new MongoClientURI(Grasscutter.getConfig().DatabaseUrl)); mongoClient = new MongoClient(new MongoClientURI(Grasscutter.getConfig().DatabaseUrl));
morphia = new Morphia(); Morphia morphia = new Morphia();
// TODO Update when migrating to Morphia 2.0 // TODO Update when migrating to Morphia 2.0
morphia.getMapper().getOptions().setStoreEmpties(true); morphia.getMapper().getOptions().setStoreEmpties(true);
......
...@@ -7,7 +7,7 @@ import java.util.Collections; ...@@ -7,7 +7,7 @@ import java.util.Collections;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpHandler;
public class DispatchHttpJsonHandler implements HttpHandler { public final class DispatchHttpJsonHandler implements HttpHandler {
private final String response; private final String response;
public DispatchHttpJsonHandler(String response) { public DispatchHttpJsonHandler(String response) {
...@@ -24,5 +24,4 @@ public class DispatchHttpJsonHandler implements HttpHandler { ...@@ -24,5 +24,4 @@ public class DispatchHttpJsonHandler implements HttpHandler {
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
} }
} }
...@@ -43,8 +43,7 @@ import emu.grasscutter.utils.Utils; ...@@ -43,8 +43,7 @@ import emu.grasscutter.utils.Utils;
import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpServer;
public class DispatchServer { public final class DispatchServer {
private HttpsServer server;
private final InetSocketAddress address; private final InetSocketAddress address;
private final Gson gson; private final Gson gson;
private QueryCurrRegionHttpRsp currRegion; private QueryCurrRegionHttpRsp currRegion;
...@@ -135,12 +134,12 @@ public class DispatchServer { ...@@ -135,12 +134,12 @@ public class DispatchServer {
this.regionCurrentBase64 = Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray()); this.regionCurrentBase64 = Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray());
this.currRegion = parsedRegionQuery; this.currRegion = parsedRegionQuery;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Grasscutter.getLogger().error("Error while initializing region info!", e);
} }
} }
public void start() throws Exception { public void start() throws Exception {
server = HttpsServer.create(getAddress(), 0); HttpsServer server = HttpsServer.create(getAddress(), 0);
SSLContext sslContext = SSLContext.getInstance("TLS"); SSLContext sslContext = SSLContext.getInstance("TLS");
try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().DispatchServerKeystorePath)) { try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().DispatchServerKeystorePath)) {
...@@ -158,9 +157,7 @@ public class DispatchServer { ...@@ -158,9 +157,7 @@ public class DispatchServer {
return; return;
} }
server.createContext("/", new HttpHandler() { server.createContext("/", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
//Create a response form the request query parameters //Create a response form the request query parameters
String response = "Hello"; String response = "Hello";
//Set the response header status and length //Set the response header status and length
...@@ -170,13 +167,10 @@ public class DispatchServer { ...@@ -170,13 +167,10 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
// Dispatch // Dispatch
server.createContext("/query_region_list", new HttpHandler() { server.createContext("/query_region_list", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
// Log // Log
Grasscutter.getLogger().info("Client request: query_region_list"); Grasscutter.getLogger().info("Client request: query_region_list");
// Create a response form the request query parameters // Create a response form the request query parameters
...@@ -188,11 +182,8 @@ public class DispatchServer { ...@@ -188,11 +182,8 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
server.createContext("/query_cur_region", new HttpHandler() { server.createContext("/query_cur_region", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
// Log // Log
Grasscutter.getLogger().info("Client request: query_cur_region"); Grasscutter.getLogger().info("Client request: query_cur_region");
// Create a response form the request query parameters // Create a response form the request query parameters
...@@ -208,12 +199,9 @@ public class DispatchServer { ...@@ -208,12 +199,9 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
// Login via account // Login via account
server.createContext("/hk4e_global/mdk/shield/api/login", new HttpHandler() { server.createContext("/hk4e_global/mdk/shield/api/login", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
// Get post data // Get post data
LoginAccountRequestJson requestData = null; LoginAccountRequestJson requestData = null;
try { try {
...@@ -251,12 +239,9 @@ public class DispatchServer { ...@@ -251,12 +239,9 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
// Login via token // Login via token
server.createContext("/hk4e_global/mdk/shield/api/verify", new HttpHandler() { server.createContext("/hk4e_global/mdk/shield/api/verify", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
// Get post data // Get post data
LoginTokenRequestJson requestData = null; LoginTokenRequestJson requestData = null;
try { try {
...@@ -294,12 +279,9 @@ public class DispatchServer { ...@@ -294,12 +279,9 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
// Exchange for combo token // Exchange for combo token
server.createContext("/hk4e_global/combo/granter/login/v2/login", new HttpHandler() { server.createContext("/hk4e_global/combo/granter/login/v2/login", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
// Get post data // Get post data
ComboTokenReqJson requestData = null; ComboTokenReqJson requestData = null;
try { try {
...@@ -338,7 +320,6 @@ public class DispatchServer { ...@@ -338,7 +320,6 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
// Agreement and Protocol // Agreement and Protocol
server.createContext( // hk4e-sdk-os.hoyoverse.com server.createContext( // hk4e-sdk-os.hoyoverse.com
...@@ -420,9 +401,7 @@ public class DispatchServer { ...@@ -420,9 +401,7 @@ public class DispatchServer {
"/crash/dataUpload", "/crash/dataUpload",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}")
); );
uploadLogServer.createContext("/gacha", new HttpHandler() { uploadLogServer.createContext("/gacha", t -> {
@Override
public void handle(HttpExchange t) throws IOException {
//Create a response form the request query parameters //Create a response form the request query parameters
String response = "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>"; String response = "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>";
//Set the response header status and length //Set the response header status and length
...@@ -432,7 +411,6 @@ public class DispatchServer { ...@@ -432,7 +411,6 @@ public class DispatchServer {
OutputStream os = t.getResponseBody(); OutputStream os = t.getResponseBody();
os.write(response.getBytes()); os.write(response.getBytes());
os.close(); os.close();
}
}); });
uploadLogServer.start(); uploadLogServer.start();
Grasscutter.getLogger().info("Log server (log-upload-os) started on port " + 80); Grasscutter.getLogger().info("Log server (log-upload-os) started on port " + 80);
......
...@@ -8,10 +8,8 @@ import emu.grasscutter.game.props.OpenState; ...@@ -8,10 +8,8 @@ import emu.grasscutter.game.props.OpenState;
import emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp; import emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp;
import emu.grasscutter.net.proto.GetShopRspOuterClass.GetShopRsp; import emu.grasscutter.net.proto.GetShopRspOuterClass.GetShopRsp;
import emu.grasscutter.net.proto.OpenStateUpdateNotifyOuterClass.OpenStateUpdateNotify; import emu.grasscutter.net.proto.OpenStateUpdateNotifyOuterClass.OpenStateUpdateNotify;
import emu.grasscutter.utils.FileUtils;
public class Dumpers {
public final class Dumpers {
public static void extractBanner(byte[] data) throws Exception { public static void extractBanner(byte[] data) throws Exception {
GetGachaInfoRsp proto = GetGachaInfoRsp.parseFrom(data); GetGachaInfoRsp proto = GetGachaInfoRsp.parseFrom(data);
System.out.println(proto); System.out.println(proto);
......
...@@ -5,6 +5,7 @@ import java.io.FileWriter; ...@@ -5,6 +5,7 @@ import java.io.FileWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
...@@ -20,7 +21,7 @@ import emu.grasscutter.data.def.AvatarData; ...@@ -20,7 +21,7 @@ import emu.grasscutter.data.def.AvatarData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.data.def.MonsterData; import emu.grasscutter.data.def.MonsterData;
public class Tools { public final class Tools {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void createGmHandbook() throws Exception { public static void createGmHandbook() throws Exception {
...@@ -40,7 +41,7 @@ public class Tools { ...@@ -40,7 +41,7 @@ public class Tools {
writer.println("// Genshin Impact " + GenshinConstants.VERSION + " GM Handbook"); writer.println("// Genshin Impact " + GenshinConstants.VERSION + " GM Handbook");
writer.println("// Created " + dtf.format(now) + System.lineSeparator() + System.lineSeparator()); writer.println("// Created " + dtf.format(now) + System.lineSeparator() + System.lineSeparator());
list = GenshinData.getAvatarDataMap().keySet().stream().collect(Collectors.toList()); list = new ArrayList<>(GenshinData.getAvatarDataMap().keySet());
Collections.sort(list); Collections.sort(list);
writer.println("// Avatars"); writer.println("// Avatars");
...@@ -51,7 +52,7 @@ public class Tools { ...@@ -51,7 +52,7 @@ public class Tools {
writer.println(); writer.println();
list = GenshinData.getItemDataMap().keySet().stream().collect(Collectors.toList()); list = new ArrayList<>(GenshinData.getItemDataMap().keySet());
Collections.sort(list); Collections.sort(list);
writer.println("// Items"); writer.println("// Items");
...@@ -63,7 +64,7 @@ public class Tools { ...@@ -63,7 +64,7 @@ public class Tools {
writer.println(); writer.println();
writer.println("// Monsters"); writer.println("// Monsters");
list = GenshinData.getMonsterDataMap().keySet().stream().collect(Collectors.toList()); list = new ArrayList<>(GenshinData.getMonsterDataMap().keySet());
Collections.sort(list); Collections.sort(list);
for (Integer id : list) { for (Integer id : list) {
......
...@@ -7,8 +7,8 @@ import emu.grasscutter.Grasscutter; ...@@ -7,8 +7,8 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.net.proto.GetPlayerTokenRspOuterClass.GetPlayerTokenRsp; import emu.grasscutter.net.proto.GetPlayerTokenRspOuterClass.GetPlayerTokenRsp;
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp; import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp;
public class Crypto { public final class Crypto {
private static SecureRandom secureRandom = new SecureRandom(); private static final SecureRandom secureRandom = new SecureRandom();
public static final long ENCRYPT_SEED = Long.parseUnsignedLong("11468049314633205968"); public static final long ENCRYPT_SEED = Long.parseUnsignedLong("11468049314633205968");
public static byte[] ENCRYPT_SEED_BUFFER = new byte[0]; public static byte[] ENCRYPT_SEED_BUFFER = new byte[0];
...@@ -37,8 +37,7 @@ public class Crypto { ...@@ -37,8 +37,7 @@ public class Crypto {
FileUtils.write(Grasscutter.getConfig().KEY_FOLDER + "secretKeyBuffer.bin", p.getSecretKeyBuffer().toByteArray()); FileUtils.write(Grasscutter.getConfig().KEY_FOLDER + "secretKeyBuffer.bin", p.getSecretKeyBuffer().toByteArray());
Grasscutter.getLogger().info("Secret Key: " + p.getSecretKey()); Grasscutter.getLogger().info("Secret Key: " + p.getSecretKey());
} catch (Exception e) { } catch (Exception e) {
// TODO Auto-generated catch block Grasscutter.getLogger().error("Crypto error.", e);
e.printStackTrace();
} }
} }
...@@ -47,7 +46,7 @@ public class Crypto { ...@@ -47,7 +46,7 @@ public class Crypto {
QueryCurrRegionHttpRsp p = QueryCurrRegionHttpRsp.parseFrom(Base64.getDecoder().decode(data)); QueryCurrRegionHttpRsp p = QueryCurrRegionHttpRsp.parseFrom(Base64.getDecoder().decode(data));
FileUtils.write(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin", p.getRegionInfo().getSecretKey().toByteArray()); FileUtils.write(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin", p.getRegionInfo().getSecretKey().toByteArray());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Grasscutter.getLogger().error("Crypto error.", e);
} }
} }
......
package emu.grasscutter.utils; package emu.grasscutter.utils;
import emu.grasscutter.Grasscutter;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
public class FileUtils { public final class FileUtils {
public static void write(String dest, byte[] bytes) { public static void write(String dest, byte[] bytes) {
Path path = Paths.get(dest); Path path = Paths.get(dest);
try { try {
Files.write(path, bytes); Files.write(path, bytes);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block Grasscutter.getLogger().warn("Failed to write file: " + dest);
e.printStackTrace();
} }
} }
...@@ -27,8 +27,7 @@ public class FileUtils { ...@@ -27,8 +27,7 @@ public class FileUtils {
try { try {
return Files.readAllBytes(path); return Files.readAllBytes(path);
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block Grasscutter.getLogger().warn("Failed to read file: " + path);
e.printStackTrace();
} }
return new byte[0]; return new byte[0];
......
...@@ -3,7 +3,7 @@ package emu.grasscutter.utils; ...@@ -3,7 +3,7 @@ package emu.grasscutter.utils;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.PropValueOuterClass.PropValue; import emu.grasscutter.net.proto.PropValueOuterClass.PropValue;
public class ProtoHelper { public final class ProtoHelper {
public static PropValue newPropValue(PlayerProperty key, int value) { public static PropValue newPropValue(PlayerProperty key, int value) {
return PropValue.newBuilder().setType(key.getId()).setIval(value).setVal(value).build(); return PropValue.newBuilder().setType(key.getId()).setIval(value).setVal(value).build();
} }
......
package emu.grasscutter.utils; package emu.grasscutter.utils;
import java.io.BufferedInputStream; import java.io.*;
import java.io.ByteArrayOutputStream; import java.nio.file.Files;
import java.io.IOException; import java.nio.file.StandardCopyOption;
import java.io.InputStream;
import java.util.Random; import java.util.Random;
import emu.grasscutter.Config;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import org.slf4j.Logger;
public class Utils { @SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"})
public final class Utils {
public static final Random random = new Random(); public static final Random random = new Random();
public static int randomRange(int min, int max) { public static int randomRange(int min, int max) {
...@@ -76,4 +78,77 @@ public class Utils { ...@@ -76,4 +78,77 @@ public class Utils {
} }
return v7; return v7;
} }
/**
* Checks if a file exists on the file system.
* @param path The path to the file.
* @return True if the file exists, false otherwise.
*/
public static boolean fileExists(String path) {
return new File(path).exists();
}
/**
* Creates a folder on the file system.
* @param path The path to the folder.
* @return True if the folder was created, false otherwise.
*/
public static boolean createFolder(String path) {
return new File(path).mkdirs();
}
/**
* Copies a file from the archive's resources to the file system.
* @param resource The path to the resource.
* @param destination The path to copy the resource to.
* @return True if the file was copied, false otherwise.
*/
public static boolean copyFromResources(String resource, String destination) {
try (InputStream stream = Grasscutter.class.getResourceAsStream(resource)) {
if(stream == null) {
Grasscutter.getLogger().warn("Could not find resource: " + resource);
return false;
}
Files.copy(stream, new File(destination).toPath(), StandardCopyOption.REPLACE_EXISTING);
return true;
} catch (Exception e) {
Grasscutter.getLogger().warn("Unable to copy resource " + resource + " to " + destination, e);
return false;
}
}
/**
* Checks for required files and folders before startup.
*/
public static void startupCheck() {
Config config = Grasscutter.getConfig();
Logger logger = Grasscutter.getLogger();
boolean exit = false;
String resourcesFolder = config.RESOURCE_FOLDER;
String dataFolder = config.DATA_FOLDER;
// Check for resources folder.
if(!fileExists(resourcesFolder)) {
logger.info("Creating resources folder...");
logger.info("Place a copy of 'GenshinData' in the resources folder.");
createFolder(resourcesFolder); exit = true;
}
// Check for GenshinData.
if(!fileExists(resourcesFolder + "BinOutput") ||
!fileExists(resourcesFolder + "ExcelBinOutput")) {
logger.info("Place a copy of 'GenshinData' in the resources folder.");
exit = true;
}
// Check for game data.
if(!fileExists(dataFolder))
createFolder(dataFolder);
if(!fileExists(dataFolder + "AbilityEmbryos.json"))
copyFromResources("data/AbilityEmbryos.json", dataFolder);
if(exit) System.exit(1);
}
} }
File moved
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment