Initial commit

This commit is contained in:
Melledy
2022-04-17 05:43:07 -07:00
commit 3b45ff7d46
1078 changed files with 367097 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
package emu.grasscutter.utils;
import java.security.SecureRandom;
import java.util.Base64;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.net.proto.GetPlayerTokenRspOuterClass.GetPlayerTokenRsp;
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp;
public class Crypto {
private static SecureRandom secureRandom = new SecureRandom();
public static final long ENCRYPT_SEED = Long.parseUnsignedLong("11468049314633205968");
public static byte[] ENCRYPT_SEED_BUFFER = new byte[0];
public static byte[] DISPATCH_KEY;
public static byte[] ENCRYPT_KEY;
public static void loadKeys() {
DISPATCH_KEY = FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchKey.bin");
ENCRYPT_KEY = FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "secretKey.bin");
ENCRYPT_SEED_BUFFER = FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "secretKeyBuffer.bin");
}
public static void xor(byte[] packet, byte[] key) {
try {
for (int i = 0; i < packet.length; i++) {
packet[i] ^= key[i % key.length];
}
} catch (Exception e) {
Grasscutter.getLogger().error("Crypto error.", e);
}
}
public static void extractSecretKeyBuffer(byte[] data) {
try {
GetPlayerTokenRsp p = GetPlayerTokenRsp.parseFrom(data);
FileUtils.write(Grasscutter.getConfig().KEY_FOLDER + "secretKeyBuffer.bin", p.getSecretKeyBuffer().toByteArray());
Grasscutter.getLogger().info("Secret Key: " + p.getSecretKey());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void extractDispatchSeed(String data) {
try {
QueryCurrRegionHttpRsp p = QueryCurrRegionHttpRsp.parseFrom(Base64.getDecoder().decode(data));
FileUtils.write(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin", p.getRegionInfo().getSecretKey().toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] createSessionKey(int length) {
byte[] bytes = new byte[length];
secureRandom.nextBytes(bytes);
return bytes;
}
}

View File

@@ -0,0 +1,48 @@
package emu.grasscutter.utils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FileUtils {
public static void write(String dest, byte[] bytes) {
Path path = Paths.get(dest);
try {
Files.write(path, bytes);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] read(String dest) {
return read(Paths.get(dest));
}
public static byte[] read(Path path) {
try {
return Files.readAllBytes(path);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new byte[0];
}
public static byte[] read(File file) {
return read(file.getPath());
}
public static String getFilenameWithoutPath(String fileName) {
if (fileName.indexOf(".") > 0) {
return fileName.substring(0, fileName.lastIndexOf("."));
} else {
return fileName;
}
}
}

View File

@@ -0,0 +1,156 @@
package emu.grasscutter.utils;
import java.io.Serializable;
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
public class Position implements Serializable {
private static final long serialVersionUID = -2001232313615923575L;
private float x;
private float y;
private float z;
public Position() {
}
public Position(float x, float y) {
set(x, y);
}
public Position(float x, float y, float z) {
set(x, y, z);
}
public Position(String p) {
String[] split = p.split(",");
if (split.length >= 2) {
this.x = Float.parseFloat(split[0]);
this.y = Float.parseFloat(split[1]);
}
if (split.length >= 3) {
this.z = Float.parseFloat(split[2]);
}
}
public Position(Vector vector) {
this.set(vector);
}
public Position(Position pos) {
this.set(pos);
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getZ() {
return z;
}
public void setZ(float z) {
this.z = z;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public Position set(float x, float y) {
this.x = x;
this.y = y;
return this;
}
// Deep copy
public Position set(Position pos) {
return this.set(pos.getX(), pos.getY(), pos.getZ());
}
public Position set(Vector pos) {
return this.set(pos.getX(), pos.getY(), pos.getZ());
}
public Position set(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
return this;
}
public Position add(Position add) {
this.x += add.getX();
this.y += add.getY();
this.z += add.getZ();
return this;
}
public Position addX(float d) {
this.x += d;
return this;
}
public Position addY(float d) {
this.y += d;
return this;
}
public Position addZ(float d) {
this.z += d;
return this;
}
public Position subtract(Position sub) {
this.x -= sub.getX();
this.y -= sub.getY();
this.z -= sub.getZ();
return this;
}
/** In radians
* */
public Position translate(float dist, float angle) {
this.x += dist * Math.sin(angle);
this.y += dist * Math.cos(angle);
return this;
}
public boolean equal2d(Position other) {
return getX() == other.getX() && getY() == other.getY();
}
public Position translateWithDegrees(float dist, float angle) {
angle = (float) Math.toRadians(angle);
this.x += dist * Math.sin(angle);
this.y += -dist * Math.cos(angle);
return this;
}
@Override
public Position clone() {
return new Position(x, y, z);
}
@Override
public String toString() {
return "(" + this.getX() + ", " + this.getY() + ", " + this.getZ() + ")";
}
public Vector toProto() {
return Vector.newBuilder()
.setX(this.getX())
.setY(this.getY())
.setZ(this.getZ())
.build();
}
}

View File

@@ -0,0 +1,10 @@
package emu.grasscutter.utils;
import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.proto.PropValueOuterClass.PropValue;
public class ProtoHelper {
public static PropValue newPropValue(PlayerProperty key, int value) {
return PropValue.newBuilder().setType(key.getId()).setIval(value).setVal(value).build();
}
}

View File

@@ -0,0 +1,79 @@
package emu.grasscutter.utils;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import emu.grasscutter.Grasscutter;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
public class Utils {
public static final Random random = new Random();
public static int randomRange(int min, int max) {
return random.nextInt(max - min + 1) + min;
}
public static float randomFloatRange(float min, float max) {
return random.nextFloat() * (max - min) + min;
}
public static int getCurrentSeconds() {
return (int) (System.currentTimeMillis() / 1000.0);
}
public static String lowerCaseFirstChar(String s) {
StringBuilder sb = new StringBuilder(s);
sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
return sb.toString();
}
public static String toString(InputStream inputStream) throws IOException {
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
for (int result = bis.read(); result != -1; result = bis.read()) {
buf.write((byte) result);
}
return buf.toString();
}
public static void logByteArray(byte[] array) {
ByteBuf b = Unpooled.wrappedBuffer(array);
Grasscutter.getLogger().info("\n" + ByteBufUtil.prettyHexDump(b));
b.release();
}
private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
public static String bytesToHex(ByteBuf buf) {
return bytesToHex(byteBufToArray(buf));
}
public static byte[] byteBufToArray(ByteBuf buf) {
byte[] bytes = new byte[buf.capacity()];
buf.getBytes(0, bytes);
return bytes;
}
public static int abilityHash(String str) {
int v7 = 0;
int v8 = 0;
while (v8 < str.length()) {
v7 = str.charAt(v8++) + 131 * v7;
}
return v7;
}
}

View File

@@ -0,0 +1,30 @@
package emu.grasscutter.utils;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom;
public class WeightedList<E> {
private final NavigableMap<Double, E> map = new TreeMap<Double, E>();
private double total = 0;
public WeightedList() {
}
public WeightedList<E> add(double weight, E result) {
if (weight <= 0) return this;
total += weight;
map.put(total, result);
return this;
}
public E next() {
double value = ThreadLocalRandom.current().nextDouble() * total;
return map.higherEntry(value).getValue();
}
public int size() {
return map.size();
}
}