Fix player fields not being set

line seps r weird
This commit is contained in:
KingRainbow44
2023-04-10 22:46:19 -04:00
parent 5e56b5e3a8
commit 06cbae31fa
453 changed files with 63228 additions and 63071 deletions

View File

@@ -1,24 +1,24 @@
package emu.grasscutter.utils;
/* Various methods to convert from A -> B. */
public interface ConversionUtils {
/**
* Converts in-game minutes to days.
*
* @param minutes The elapsed in-game minutes.
* @return The elapsed in-game days.
*/
static long gameTimeToDays(long minutes) {
return minutes / 1440;
}
/**
* Converts in-game minutes to hours.
*
* @param minutes The elapsed in-game minutes.
* @return The elapsed in-game hours.
*/
static long gameTimeToHours(long minutes) {
return minutes / 60;
}
}
package emu.grasscutter.utils;
/* Various methods to convert from A -> B. */
public interface ConversionUtils {
/**
* Converts in-game minutes to days.
*
* @param minutes The elapsed in-game minutes.
* @return The elapsed in-game days.
*/
static long gameTimeToDays(long minutes) {
return minutes / 1440;
}
/**
* Converts in-game minutes to hours.
*
* @param minutes The elapsed in-game minutes.
* @return The elapsed in-game hours.
*/
static long gameTimeToHours(long minutes) {
return minutes / 60;
}
}

View File

@@ -1,265 +1,265 @@
package emu.grasscutter.utils;
import emu.grasscutter.Grasscutter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.val;
public final class FileUtils {
private static final Path DATA_DEFAULT_PATH;
private static final Path DATA_USER_PATH = Path.of(Grasscutter.config.folderStructure.data);
private static final Path PACKETS_PATH = Path.of(Grasscutter.config.folderStructure.packets);
private static final Path PLUGINS_PATH = Path.of(Grasscutter.config.folderStructure.plugins);
private static final Path RESOURCES_PATH;
private static final Path SCRIPTS_PATH;
private static final String[] TSJ_JSON_TSV = {"tsj", "json", "tsv"};
static {
FileSystem fs = null;
Path path = null;
// Setup access to jar resources
try {
var uri = Grasscutter.class.getResource("/defaults/data").toURI();
switch (uri.getScheme()) {
case "jar": // When running normally, as a jar
case "zip": // Honestly I have no idea what setup would result in this, but this should work
// regardless
fs =
FileSystems.newFileSystem(
uri,
Map.of()); // Have to mount zip filesystem. This leaks, but we want to keep it
// forever anyway.
// Fall-through
case "file": // When running in an IDE
path = Path.of(uri); // Can access directly
break;
default:
Grasscutter.getLogger()
.error("Invalid URI scheme for class resources: " + uri.getScheme());
break;
}
} catch (URISyntaxException | IOException e) {
// Failed to load this jar. How?
Grasscutter.getLogger().error("Failed to load jar?!");
} finally {
DATA_DEFAULT_PATH = path;
Grasscutter.getLogger().debug("Setting path for default data: " + path.toAbsolutePath());
}
// Setup Resources path
final String resources = Grasscutter.config.folderStructure.resources;
fs = null;
path = Path.of(resources);
if (resources.endsWith(
".zip")) { // Would be nice to support .tar.gz too at some point, but it doesn't come for
// free in Java
try {
fs = FileSystems.newFileSystem(path);
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load resources zip \"" + resources + "\"");
}
}
if (fs != null) {
var root = fs.getPath("");
try (Stream<Path> pathStream =
Files.find(
root,
3,
(p, a) -> {
var filename = p.getFileName();
if (filename == null) return false;
return filename.toString().equals("ExcelBinOutput");
})) {
var excelBinOutput = pathStream.findFirst();
if (excelBinOutput.isPresent()) {
path = excelBinOutput.get().getParent();
if (path == null) path = root;
Grasscutter.getLogger()
.debug("Resources will be loaded from \"" + resources + "/" + path + "\"");
} else {
Grasscutter.getLogger()
.error("Failed to find ExcelBinOutput in resources zip \"" + resources + "\"");
}
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to scan resources zip \"" + resources + "\"");
}
}
RESOURCES_PATH = path;
// Setup Scripts path
final String scripts = Grasscutter.config.folderStructure.scripts;
SCRIPTS_PATH =
(scripts.startsWith("resources:"))
? RESOURCES_PATH.resolve(scripts.substring("resources:".length()))
: Path.of(scripts);
}
/* Apply after initialization. */
private static final Path[] DATA_PATHS = {DATA_USER_PATH, DATA_DEFAULT_PATH};
public static Path getDataPathTsjJsonTsv(String filename) {
return getDataPathTsjJsonTsv(filename, true);
}
public static Path getDataPathTsjJsonTsv(String filename, boolean fallback) {
val name = getFilenameWithoutExtension(filename);
for (val data_path : DATA_PATHS) {
for (val ext : TSJ_JSON_TSV) {
val path = data_path.resolve(name + "." + ext);
if (Files.exists(path)) return path;
}
}
return fallback
? DATA_USER_PATH.resolve(name + ".tsj")
: null; // Maybe they want to write to a new file
}
public static Path getDataPath(String path) {
Path userPath = DATA_USER_PATH.resolve(path);
if (Files.exists(userPath)) return userPath;
Path defaultPath = DATA_DEFAULT_PATH.resolve(path);
if (Files.exists(defaultPath)) return defaultPath;
return userPath; // Maybe they want to write to a new file
}
public static Path getDataUserPath(String path) {
return DATA_USER_PATH.resolve(path);
}
public static Path getPacketPath(String path) {
return PACKETS_PATH.resolve(path);
}
public static Path getPluginPath(String path) {
return PLUGINS_PATH.resolve(path);
}
public static Path getResourcePath(String path) {
return RESOURCES_PATH.resolve(path);
}
public static Path getExcelPath(String filename) {
return getTsjJsonTsv(RESOURCES_PATH.resolve("ExcelBinOutput"), filename);
}
// Gets path of a resource.
// If multiple formats of it exist, priority is TSJ > JSON > TSV
// If none exist, return the TSJ path, in case it wants to create a file
public static Path getTsjJsonTsv(Path root, String filename) {
val name = getFilenameWithoutExtension(filename);
for (val ext : TSJ_JSON_TSV) {
val path = root.resolve(name + "." + ext);
if (Files.exists(path)) return path;
}
return root.resolve(name + ".tsj");
}
public static Path getScriptPath(String path) {
return SCRIPTS_PATH.resolve(path);
}
public static void write(String dest, byte[] bytes) {
Path path = Path.of(dest);
try {
Files.write(path, bytes);
} catch (IOException e) {
Grasscutter.getLogger().warn("Failed to write file: " + dest);
}
}
public static byte[] read(String dest) {
return read(Path.of(dest));
}
public static byte[] read(Path path) {
try {
return Files.readAllBytes(path);
} catch (IOException e) {
Grasscutter.getLogger().warn("Failed to read file: " + path);
}
return new byte[0];
}
public static InputStream readResourceAsStream(String resourcePath) {
return Grasscutter.class.getResourceAsStream(resourcePath);
}
public static byte[] readResource(String resourcePath) {
try (InputStream is = Grasscutter.class.getResourceAsStream(resourcePath)) {
return is.readAllBytes();
} catch (Exception exception) {
Grasscutter.getLogger().warn("Failed to read resource: " + resourcePath);
exception.printStackTrace();
}
return new byte[0];
}
public static byte[] read(File file) {
return read(file.getPath());
}
public static void copyResource(String resourcePath, String destination) {
try {
byte[] resource = FileUtils.readResource(resourcePath);
FileUtils.write(destination, resource);
} catch (Exception exception) {
Grasscutter.getLogger().warn("Failed to copy resource: " + resourcePath + "\n" + exception);
}
}
@Deprecated // Misnamed legacy function
public static String getFilenameWithoutPath(String filename) {
return getFilenameWithoutExtension(filename);
}
public static String getFilenameWithoutExtension(String filename) {
int i = filename.lastIndexOf(".");
return (i < 0) ? filename : filename.substring(0, i);
}
public static String getFileExtension(Path path) {
val filename = path.toString();
int i = filename.lastIndexOf(".");
return (i < 0) ? "" : filename.substring(i + 1);
}
public static List<Path> getPathsFromResource(String folder) throws URISyntaxException {
try {
// file walks JAR
return Files.walk(Path.of(Grasscutter.class.getResource(folder).toURI()))
.filter(Files::isRegularFile)
.collect(Collectors.toList());
} catch (IOException e) {
// Eclipse puts resources in its bin folder
try {
return Files.walk(Path.of(System.getProperty("user.dir"), folder))
.filter(Files::isRegularFile)
.collect(Collectors.toList());
} catch (IOException ignored) {
return null;
}
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static String readToString(InputStream file) throws IOException {
byte[] content = file.readAllBytes();
return new String(content, StandardCharsets.UTF_8);
}
}
package emu.grasscutter.utils;
import emu.grasscutter.Grasscutter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.val;
public final class FileUtils {
private static final Path DATA_DEFAULT_PATH;
private static final Path DATA_USER_PATH = Path.of(Grasscutter.config.folderStructure.data);
private static final Path PACKETS_PATH = Path.of(Grasscutter.config.folderStructure.packets);
private static final Path PLUGINS_PATH = Path.of(Grasscutter.config.folderStructure.plugins);
private static final Path RESOURCES_PATH;
private static final Path SCRIPTS_PATH;
private static final String[] TSJ_JSON_TSV = {"tsj", "json", "tsv"};
static {
FileSystem fs = null;
Path path = null;
// Setup access to jar resources
try {
var uri = Grasscutter.class.getResource("/defaults/data").toURI();
switch (uri.getScheme()) {
case "jar": // When running normally, as a jar
case "zip": // Honestly I have no idea what setup would result in this, but this should work
// regardless
fs =
FileSystems.newFileSystem(
uri,
Map.of()); // Have to mount zip filesystem. This leaks, but we want to keep it
// forever anyway.
// Fall-through
case "file": // When running in an IDE
path = Path.of(uri); // Can access directly
break;
default:
Grasscutter.getLogger()
.error("Invalid URI scheme for class resources: " + uri.getScheme());
break;
}
} catch (URISyntaxException | IOException e) {
// Failed to load this jar. How?
Grasscutter.getLogger().error("Failed to load jar?!");
} finally {
DATA_DEFAULT_PATH = path;
Grasscutter.getLogger().debug("Setting path for default data: " + path.toAbsolutePath());
}
// Setup Resources path
final String resources = Grasscutter.config.folderStructure.resources;
fs = null;
path = Path.of(resources);
if (resources.endsWith(
".zip")) { // Would be nice to support .tar.gz too at some point, but it doesn't come for
// free in Java
try {
fs = FileSystems.newFileSystem(path);
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load resources zip \"" + resources + "\"");
}
}
if (fs != null) {
var root = fs.getPath("");
try (Stream<Path> pathStream =
Files.find(
root,
3,
(p, a) -> {
var filename = p.getFileName();
if (filename == null) return false;
return filename.toString().equals("ExcelBinOutput");
})) {
var excelBinOutput = pathStream.findFirst();
if (excelBinOutput.isPresent()) {
path = excelBinOutput.get().getParent();
if (path == null) path = root;
Grasscutter.getLogger()
.debug("Resources will be loaded from \"" + resources + "/" + path + "\"");
} else {
Grasscutter.getLogger()
.error("Failed to find ExcelBinOutput in resources zip \"" + resources + "\"");
}
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to scan resources zip \"" + resources + "\"");
}
}
RESOURCES_PATH = path;
// Setup Scripts path
final String scripts = Grasscutter.config.folderStructure.scripts;
SCRIPTS_PATH =
(scripts.startsWith("resources:"))
? RESOURCES_PATH.resolve(scripts.substring("resources:".length()))
: Path.of(scripts);
}
/* Apply after initialization. */
private static final Path[] DATA_PATHS = {DATA_USER_PATH, DATA_DEFAULT_PATH};
public static Path getDataPathTsjJsonTsv(String filename) {
return getDataPathTsjJsonTsv(filename, true);
}
public static Path getDataPathTsjJsonTsv(String filename, boolean fallback) {
val name = getFilenameWithoutExtension(filename);
for (val data_path : DATA_PATHS) {
for (val ext : TSJ_JSON_TSV) {
val path = data_path.resolve(name + "." + ext);
if (Files.exists(path)) return path;
}
}
return fallback
? DATA_USER_PATH.resolve(name + ".tsj")
: null; // Maybe they want to write to a new file
}
public static Path getDataPath(String path) {
Path userPath = DATA_USER_PATH.resolve(path);
if (Files.exists(userPath)) return userPath;
Path defaultPath = DATA_DEFAULT_PATH.resolve(path);
if (Files.exists(defaultPath)) return defaultPath;
return userPath; // Maybe they want to write to a new file
}
public static Path getDataUserPath(String path) {
return DATA_USER_PATH.resolve(path);
}
public static Path getPacketPath(String path) {
return PACKETS_PATH.resolve(path);
}
public static Path getPluginPath(String path) {
return PLUGINS_PATH.resolve(path);
}
public static Path getResourcePath(String path) {
return RESOURCES_PATH.resolve(path);
}
public static Path getExcelPath(String filename) {
return getTsjJsonTsv(RESOURCES_PATH.resolve("ExcelBinOutput"), filename);
}
// Gets path of a resource.
// If multiple formats of it exist, priority is TSJ > JSON > TSV
// If none exist, return the TSJ path, in case it wants to create a file
public static Path getTsjJsonTsv(Path root, String filename) {
val name = getFilenameWithoutExtension(filename);
for (val ext : TSJ_JSON_TSV) {
val path = root.resolve(name + "." + ext);
if (Files.exists(path)) return path;
}
return root.resolve(name + ".tsj");
}
public static Path getScriptPath(String path) {
return SCRIPTS_PATH.resolve(path);
}
public static void write(String dest, byte[] bytes) {
Path path = Path.of(dest);
try {
Files.write(path, bytes);
} catch (IOException e) {
Grasscutter.getLogger().warn("Failed to write file: " + dest);
}
}
public static byte[] read(String dest) {
return read(Path.of(dest));
}
public static byte[] read(Path path) {
try {
return Files.readAllBytes(path);
} catch (IOException e) {
Grasscutter.getLogger().warn("Failed to read file: " + path);
}
return new byte[0];
}
public static InputStream readResourceAsStream(String resourcePath) {
return Grasscutter.class.getResourceAsStream(resourcePath);
}
public static byte[] readResource(String resourcePath) {
try (InputStream is = Grasscutter.class.getResourceAsStream(resourcePath)) {
return is.readAllBytes();
} catch (Exception exception) {
Grasscutter.getLogger().warn("Failed to read resource: " + resourcePath);
exception.printStackTrace();
}
return new byte[0];
}
public static byte[] read(File file) {
return read(file.getPath());
}
public static void copyResource(String resourcePath, String destination) {
try {
byte[] resource = FileUtils.readResource(resourcePath);
FileUtils.write(destination, resource);
} catch (Exception exception) {
Grasscutter.getLogger().warn("Failed to copy resource: " + resourcePath + "\n" + exception);
}
}
@Deprecated // Misnamed legacy function
public static String getFilenameWithoutPath(String filename) {
return getFilenameWithoutExtension(filename);
}
public static String getFilenameWithoutExtension(String filename) {
int i = filename.lastIndexOf(".");
return (i < 0) ? filename : filename.substring(0, i);
}
public static String getFileExtension(Path path) {
val filename = path.toString();
int i = filename.lastIndexOf(".");
return (i < 0) ? "" : filename.substring(i + 1);
}
public static List<Path> getPathsFromResource(String folder) throws URISyntaxException {
try {
// file walks JAR
return Files.walk(Path.of(Grasscutter.class.getResource(folder).toURI()))
.filter(Files::isRegularFile)
.collect(Collectors.toList());
} catch (IOException e) {
// Eclipse puts resources in its bin folder
try {
return Files.walk(Path.of(System.getProperty("user.dir"), folder))
.filter(Files::isRegularFile)
.collect(Collectors.toList());
} catch (IOException ignored) {
return null;
}
}
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public static String readToString(InputStream file) throws IOException {
byte[] content = file.readAllBytes();
return new String(content, StandardCharsets.UTF_8);
}
}

View File

@@ -1,113 +1,113 @@
package emu.grasscutter.utils;
import dev.morphia.annotations.Entity;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Entity
public class GridPosition implements Serializable {
private static final long serialVersionUID = -2001232300615923575L;
@Getter @Setter private int x;
@Getter @Setter private int z;
@Getter @Setter private int width;
public GridPosition() {}
public GridPosition(int x, int y, int width) {
set(x, y, width);
}
public GridPosition(GridPosition pos) {
this.set(pos);
}
public GridPosition(Position pos, int width) {
this.set((int) (pos.getX() / width), (int) (pos.getZ() / width), width);
}
public GridPosition(List<Integer> xzwidth) {
this.width = xzwidth.get(2);
this.z = xzwidth.get(1);
this.x = xzwidth.get(0);
}
public GridPosition(String str) throws IOException {
String[] listOfParams = str.replace(" ", "").replace("(", "").replace(")", "").split(",");
if (listOfParams.length != 3)
throw new IOException("invalid size on GridPosition definition - ");
try {
this.x = Integer.parseInt(listOfParams[0]);
this.z = Integer.parseInt(listOfParams[1]);
this.width = Integer.parseInt(listOfParams[2]);
} catch (NumberFormatException ignored) {
throw new IOException("invalid number on GridPosition definition - ");
}
}
public GridPosition set(int x, int z) {
this.x = x;
this.z = z;
return this;
}
public GridPosition set(int x, int z, int width) {
this.x = x;
this.z = z;
this.width = width;
return this;
}
// Deep copy
public GridPosition set(GridPosition pos) {
return this.set(pos.getX(), pos.getZ(), pos.getWidth());
}
public GridPosition addClone(int x, int z) {
GridPosition pos = clone();
pos.x += x;
pos.z += z;
return pos;
}
@Override
public GridPosition clone() {
return new GridPosition(x, z, width);
}
@Override
public String toString() {
return "(" + this.getX() + ", " + this.getZ() + ", " + this.getWidth() + ")";
}
public int[] toIntArray() {
return new int[] {x, z, width};
}
public int[] toXZIntArray() {
return new int[] {x, z};
}
@Override
public int hashCode() {
int result = (int) (x ^ (x >>> 32));
result = 31 * result + (int) (z ^ (z >>> 32));
result = 31 * result + (int) (width ^ (width >>> 32));
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (getClass() != o.getClass()) return false;
GridPosition pos = (GridPosition) o;
// field comparison
return pos.x == x && pos.z == z && pos.width == width;
}
}
package emu.grasscutter.utils;
import dev.morphia.annotations.Entity;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
@Entity
public class GridPosition implements Serializable {
private static final long serialVersionUID = -2001232300615923575L;
@Getter @Setter private int x;
@Getter @Setter private int z;
@Getter @Setter private int width;
public GridPosition() {}
public GridPosition(int x, int y, int width) {
set(x, y, width);
}
public GridPosition(GridPosition pos) {
this.set(pos);
}
public GridPosition(Position pos, int width) {
this.set((int) (pos.getX() / width), (int) (pos.getZ() / width), width);
}
public GridPosition(List<Integer> xzwidth) {
this.width = xzwidth.get(2);
this.z = xzwidth.get(1);
this.x = xzwidth.get(0);
}
public GridPosition(String str) throws IOException {
String[] listOfParams = str.replace(" ", "").replace("(", "").replace(")", "").split(",");
if (listOfParams.length != 3)
throw new IOException("invalid size on GridPosition definition - ");
try {
this.x = Integer.parseInt(listOfParams[0]);
this.z = Integer.parseInt(listOfParams[1]);
this.width = Integer.parseInt(listOfParams[2]);
} catch (NumberFormatException ignored) {
throw new IOException("invalid number on GridPosition definition - ");
}
}
public GridPosition set(int x, int z) {
this.x = x;
this.z = z;
return this;
}
public GridPosition set(int x, int z, int width) {
this.x = x;
this.z = z;
this.width = width;
return this;
}
// Deep copy
public GridPosition set(GridPosition pos) {
return this.set(pos.getX(), pos.getZ(), pos.getWidth());
}
public GridPosition addClone(int x, int z) {
GridPosition pos = clone();
pos.x += x;
pos.z += z;
return pos;
}
@Override
public GridPosition clone() {
return new GridPosition(x, z, width);
}
@Override
public String toString() {
return "(" + this.getX() + ", " + this.getZ() + ", " + this.getWidth() + ")";
}
public int[] toIntArray() {
return new int[] {x, z, width};
}
public int[] toXZIntArray() {
return new int[] {x, z};
}
@Override
public int hashCode() {
int result = (int) (x ^ (x >>> 32));
result = 31 * result + (int) (z ^ (z >>> 32));
result = 31 * result + (int) (width ^ (width >>> 32));
return result;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
if (getClass() != o.getClass()) return false;
GridPosition pos = (GridPosition) o;
// field comparison
return pos.x == x && pos.z == z && pos.width == width;
}
}

View File

@@ -1,68 +1,68 @@
package emu.grasscutter.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class KahnsSort {
public static class Node {
int source, dest; // Dest is a value, and source too
public Node(int source, int dest) {
this.source = source;
this.dest = dest;
}
}
public static class Graph {
Map<Integer, List<Integer>> mainList;
Map<Integer, Integer> degreeList;
List<Integer> nodeList;
public Graph(List<Node> nodes, List<Integer> nodeList) {
mainList = new HashMap<>();
this.nodeList = nodeList;
for (int i = 0; i < nodeList.size(); i++) mainList.put(nodeList.get(i), new ArrayList<>());
degreeList = new HashMap<>();
for (int i = 0; i < nodeList.size(); i++) degreeList.put(nodeList.get(i), 0);
for (Node node : nodes) {
mainList.get(node.source).add(node.dest);
degreeList.replace(node.dest, degreeList.get(node.dest) + 1);
}
}
}
public static List<Integer> doSort(Graph graph) {
List<Integer> orderedList = new ArrayList<>();
Map<Integer, Integer> degreeList = graph.degreeList;
Stack<Integer> zeroStack = new Stack<>();
degreeList.forEach(
(key, value) -> {
if (value == 0) zeroStack.add(key);
});
while (!zeroStack.isEmpty()) {
int element = zeroStack.pop();
// If the list is empty then this node
if (!graph.mainList.get(element).isEmpty()) orderedList.add(element);
for (int topElement : graph.mainList.get(element)) {
degreeList.replace(topElement, degreeList.get(topElement) - 1);
if (degreeList.get(topElement) == 0) zeroStack.add(topElement);
}
}
if (degreeList.values().stream().filter(value -> value != 0).count() != 0)
return null; // Loop found
return orderedList;
}
}
package emu.grasscutter.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class KahnsSort {
public static class Node {
int source, dest; // Dest is a value, and source too
public Node(int source, int dest) {
this.source = source;
this.dest = dest;
}
}
public static class Graph {
Map<Integer, List<Integer>> mainList;
Map<Integer, Integer> degreeList;
List<Integer> nodeList;
public Graph(List<Node> nodes, List<Integer> nodeList) {
mainList = new HashMap<>();
this.nodeList = nodeList;
for (int i = 0; i < nodeList.size(); i++) mainList.put(nodeList.get(i), new ArrayList<>());
degreeList = new HashMap<>();
for (int i = 0; i < nodeList.size(); i++) degreeList.put(nodeList.get(i), 0);
for (Node node : nodes) {
mainList.get(node.source).add(node.dest);
degreeList.replace(node.dest, degreeList.get(node.dest) + 1);
}
}
}
public static List<Integer> doSort(Graph graph) {
List<Integer> orderedList = new ArrayList<>();
Map<Integer, Integer> degreeList = graph.degreeList;
Stack<Integer> zeroStack = new Stack<>();
degreeList.forEach(
(key, value) -> {
if (value == 0) zeroStack.add(key);
});
while (!zeroStack.isEmpty()) {
int element = zeroStack.pop();
// If the list is empty then this node
if (!graph.mainList.get(element).isEmpty()) orderedList.add(element);
for (int topElement : graph.mainList.get(element)) {
degreeList.replace(topElement, degreeList.get(topElement) - 1);
if (degreeList.get(topElement) == 0) zeroStack.add(topElement);
}
}
if (degreeList.values().stream().filter(value -> value != 0).count() != 0)
return null; // Loop found
return orderedList;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,129 +1,129 @@
package emu.grasscutter.utils;
import static emu.grasscutter.config.Configuration.*;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import emu.grasscutter.BuildConfig;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode;
import emu.grasscutter.net.packet.PacketOpcodesUtils;
import java.util.Map;
import java.util.function.Function;
import org.slf4j.LoggerFactory;
/** A parser for start-up arguments. */
public final class StartupArguments {
/* A map of parameter -> argument handler. */
private static final Map<String, Function<String, Boolean>> argumentHandlers =
Map.of(
"-dumppacketids",
parameter -> {
PacketOpcodesUtils.dumpPacketIds();
return true;
},
"-version", StartupArguments::printVersion,
"-debug", StartupArguments::enableDebug,
"-lang",
parameter -> {
Grasscutter.setPreferredLanguage(parameter);
return false;
},
"-game",
parameter -> {
Grasscutter.setRunModeOverride(ServerRunMode.GAME_ONLY);
return false;
},
"-dispatch",
parameter -> {
Grasscutter.setRunModeOverride(ServerRunMode.DISPATCH_ONLY);
return false;
},
"-test",
parameter -> {
// Disable the console.
SERVER.game.enableConsole = false;
// Disable HTTP encryption.
SERVER.http.encryption.useEncryption = false;
return false;
},
// Aliases.
"-v", StartupArguments::printVersion,
"-debugall",
parameter -> {
StartupArguments.enableDebug("all");
return false;
});
private StartupArguments() {
// This class is not meant to be instantiated.
}
/**
* Parses the provided start-up arguments.
*
* @param args The application start-up arguments.
* @return If the application should exit.
*/
public static boolean parse(String[] args) {
boolean exitEarly = false;
// Parse the arguments.
for (var input : args) {
var containsParameter = input.contains("=");
var argument = containsParameter ? input.split("=")[0] : input;
var handler = argumentHandlers.get(argument.toLowerCase());
if (handler != null) {
exitEarly |= handler.apply(containsParameter ? input.split("=")[1] : null);
}
}
return exitEarly;
}
/**
* Prints the server version.
*
* @param parameter Additional parameters.
* @return True to exit early.
*/
private static boolean printVersion(String parameter) {
System.out.println("Grasscutter version: " + BuildConfig.VERSION + "-" + BuildConfig.GIT_HASH);
return true;
}
/**
* Enables debug logging.
*
* @param parameter Additional parameters.
* @return False to continue execution.
*/
private static boolean enableDebug(String parameter) {
if (parameter != null && parameter.equals("all")) {
// Override default debug configs
GAME_INFO.isShowLoopPackets = DEBUG_MODE_INFO.isShowLoopPackets;
GAME_INFO.isShowPacketPayload = DEBUG_MODE_INFO.isShowPacketPayload;
GAME_INFO.logPackets = DEBUG_MODE_INFO.logPackets;
DISPATCH_INFO.logRequests = DEBUG_MODE_INFO.logRequests;
}
// Set the main logger to debug.
Grasscutter.getLogger().setLevel(DEBUG_MODE_INFO.serverLoggerLevel);
Grasscutter.getLogger().debug("The logger is now running in debug mode.");
// Log level to other third-party services
Level loggerLevel = DEBUG_MODE_INFO.servicesLoggersLevel;
// Change loggers to debug.
((Logger) LoggerFactory.getLogger("io.javalin")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.quartz")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.reflections")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.eclipse.jetty")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.mongodb.driver")).setLevel(loggerLevel);
return false;
}
}
package emu.grasscutter.utils;
import static emu.grasscutter.config.Configuration.*;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import emu.grasscutter.BuildConfig;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode;
import emu.grasscutter.net.packet.PacketOpcodesUtils;
import java.util.Map;
import java.util.function.Function;
import org.slf4j.LoggerFactory;
/** A parser for start-up arguments. */
public final class StartupArguments {
/* A map of parameter -> argument handler. */
private static final Map<String, Function<String, Boolean>> argumentHandlers =
Map.of(
"-dumppacketids",
parameter -> {
PacketOpcodesUtils.dumpPacketIds();
return true;
},
"-version", StartupArguments::printVersion,
"-debug", StartupArguments::enableDebug,
"-lang",
parameter -> {
Grasscutter.setPreferredLanguage(parameter);
return false;
},
"-game",
parameter -> {
Grasscutter.setRunModeOverride(ServerRunMode.GAME_ONLY);
return false;
},
"-dispatch",
parameter -> {
Grasscutter.setRunModeOverride(ServerRunMode.DISPATCH_ONLY);
return false;
},
"-test",
parameter -> {
// Disable the console.
SERVER.game.enableConsole = false;
// Disable HTTP encryption.
SERVER.http.encryption.useEncryption = false;
return false;
},
// Aliases.
"-v", StartupArguments::printVersion,
"-debugall",
parameter -> {
StartupArguments.enableDebug("all");
return false;
});
private StartupArguments() {
// This class is not meant to be instantiated.
}
/**
* Parses the provided start-up arguments.
*
* @param args The application start-up arguments.
* @return If the application should exit.
*/
public static boolean parse(String[] args) {
boolean exitEarly = false;
// Parse the arguments.
for (var input : args) {
var containsParameter = input.contains("=");
var argument = containsParameter ? input.split("=")[0] : input;
var handler = argumentHandlers.get(argument.toLowerCase());
if (handler != null) {
exitEarly |= handler.apply(containsParameter ? input.split("=")[1] : null);
}
}
return exitEarly;
}
/**
* Prints the server version.
*
* @param parameter Additional parameters.
* @return True to exit early.
*/
private static boolean printVersion(String parameter) {
System.out.println("Grasscutter version: " + BuildConfig.VERSION + "-" + BuildConfig.GIT_HASH);
return true;
}
/**
* Enables debug logging.
*
* @param parameter Additional parameters.
* @return False to continue execution.
*/
private static boolean enableDebug(String parameter) {
if (parameter != null && parameter.equals("all")) {
// Override default debug configs
GAME_INFO.isShowLoopPackets = DEBUG_MODE_INFO.isShowLoopPackets;
GAME_INFO.isShowPacketPayload = DEBUG_MODE_INFO.isShowPacketPayload;
GAME_INFO.logPackets = DEBUG_MODE_INFO.logPackets;
DISPATCH_INFO.logRequests = DEBUG_MODE_INFO.logRequests;
}
// Set the main logger to debug.
Grasscutter.getLogger().setLevel(DEBUG_MODE_INFO.serverLoggerLevel);
Grasscutter.getLogger().debug("The logger is now running in debug mode.");
// Log level to other third-party services
Level loggerLevel = DEBUG_MODE_INFO.servicesLoggersLevel;
// Change loggers to debug.
((Logger) LoggerFactory.getLogger("io.javalin")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.quartz")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.reflections")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.eclipse.jetty")).setLevel(loggerLevel);
((Logger) LoggerFactory.getLogger("org.mongodb.driver")).setLevel(loggerLevel);
return false;
}
}