Initial Repository Push

This commit is contained in:
2022-04-30 09:41:17 -04:00
parent d4eef9097a
commit bbfdde57a3
835 changed files with 168392 additions and 0 deletions
+224
View File
@@ -0,0 +1,224 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.util;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
public class ByteAnalyzer {
public static void analyze4Bytes(byte[] data, String Label,
boolean switchEndian) throws IOException {
ByteArrayInputStream bias = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bias);
dis.mark(4);
System.out.println("Analysis 4 bytes: (" + Label + ')');
System.out.println("\t Hex: " + ByteUtils.byteArrayToStringHex(data));
System.out.println(ByteAnalyzer.buildAll4(dis, switchEndian));
System.out.println(ByteAnalyzer.buildUTF8(dis));
System.out.println(ByteAnalyzer.buildUTF16(dis));
System.out.println(ByteAnalyzer.buildRawNumericalBytes(dis));
System.out.println();
}
public static void analyze8Bytes(byte[] data, String Label,
boolean switchEndian) throws IOException {
ByteArrayInputStream bias = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bias);
dis.mark(8);
System.out.println("Analysis for 8 bytes: (" + Label + ')');
System.out.println("\tHex: " + ByteUtils.byteArrayToStringHex(data));
System.out.println(ByteAnalyzer.buildAll8(dis, switchEndian));
dis.reset();
System.out.println(ByteAnalyzer.buildUTF8(dis));
System.out.println(ByteAnalyzer.buildUTF16(dis));
System.out.println(ByteAnalyzer.buildRawNumericalBytes(dis));
System.out.println("\n");
}
public static String buildAll8(DataInputStream indis, boolean se)
throws IOException {
byte[] ba = new byte[8];
indis.read(ba);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(ba));
dis.mark(8);
String out = "";
out += buildFromTemplate("8", dis, se);
out += buildFromTemplate("4.4", dis, se);
out += buildFromTemplate("4.2.2", dis, se);
out += buildFromTemplate("4.2.1.1", dis, se);
out += buildFromTemplate("4.1.2.1", dis, se);
out += buildFromTemplate("4.1.1.2", dis, se);
out += buildFromTemplate("4.1.1.1.1", dis, se);
out += buildFromTemplate("2.2.4", dis, se);
out += buildFromTemplate("2.1.1.4", dis, se);
out += buildFromTemplate("1.2.1.4", dis, se);
out += buildFromTemplate("1.1.2.4", dis, se);
out += buildFromTemplate("1.1.1.1.4", dis, se);
out += buildFromTemplate("2.4.2", dis, se);
out += buildFromTemplate("2.4.1.1", dis, se);
out += buildFromTemplate("1.1.4.2", dis, se);
out += buildFromTemplate("1.1.4.1.1", dis, se);
out += buildFromTemplate("2.1.2.2.1", dis, se);
out += buildFromTemplate("2.1.2.1.2", dis, se);
out += buildFromTemplate("1.2.2.2.1", dis, se);
out += buildFromTemplate("1.2.2.1.2", dis, se);
out += buildFromTemplate("1.1.1.2.2.1", dis, se);
out += buildFromTemplate("2.1.2.1.1.1", dis, se);
out += buildFromTemplate("1.1.1.2.1.1.1", dis, se);
out += buildFromTemplate("1.1.1.1.1.1.1.1", dis, se);
out += buildFromTemplate("2.1.1.1.1.1.1", dis, se);
out += buildFromTemplate("1.2.1.1.1.1.1", dis, se);
out += buildFromTemplate("1.1.2.1.1.1.1", dis, se);
out += buildFromTemplate("1.1.1.1.2.1.1", dis, se);
out += buildFromTemplate("1.1.1.1.1.2.1", dis, se);
out += buildFromTemplate("1.1.1.1.1.1.2", dis, se);
return out;
}
public static String buildAll4(DataInputStream indis, boolean se)
throws IOException {
byte[] ba = new byte[4];
indis.read(ba);
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(ba));
dis.mark(4);
String out = "";
out += buildFromTemplate("4", dis, se);
out += buildFromTemplate("2.2", dis, se);
out += buildFromTemplate("2.1.1", dis, se);
out += buildFromTemplate("1.2.1", dis, se);
out += buildFromTemplate("1.1.2", dis, se);
out += buildFromTemplate("1.1.1.1", dis, se);
return out;
}
public static String buildFromTemplate(String template,
DataInputStream dis, boolean se) throws IOException {
String out = '\t' + template + ": ";
for (int i = template.length(); i < 16; ++i) {
out += " ";
}
template = template.replace(".", "");
String[] items = template.split("");
dis.mark(dis.available());
for (String s : items) {
if (s.equals("1")) {
out += " (B:" + dis.readByte();
dis.reset();
out += "/uB:" + dis.readUnsignedByte() + ')';
} else if (s.equals("2")) {
byte[] read = new byte[2];
dis.read(read);
byte[] use = new byte[2];
if (se) {
use = ByteUtils.switchByteArrayEndianness(read);
} else {
use = read;
}
out += " (S:"
+ new DataInputStream(new ByteArrayInputStream(use))
.readShort();
out += "/uS:"
+ new DataInputStream(new ByteArrayInputStream(use))
.readUnsignedShort() + ')';
} else if (s.equals("4")) {
byte[] read = new byte[4];
dis.read(read);
byte[] use = new byte[4];
if (se) {
use = ByteUtils.switchByteArrayEndianness(read);
} else {
use = read;
}
out += " (I:";
out += new DataInputStream(new ByteArrayInputStream(use))
.readInt();
out += " / F:";
out += new DataInputStream(new ByteArrayInputStream(use))
.readFloat()
+ ")";
} else if (s.equals("8")) {
byte[] read = new byte[8];
dis.read(read);
byte[] use = new byte[8];
if (se) {
use = ByteUtils.switchByteArrayEndianness(read);
} else {
use = read;
}
out += " (L:";
out += new DataInputStream(new ByteArrayInputStream(use))
.readLong();
out += " / D:";
out += new DataInputStream(new ByteArrayInputStream(use))
.readDouble()
+ ")";
}
}
dis.reset();
return out + '\n';
}
public static String buildUTF8(DataInputStream dis) throws IOException {
dis.mark(dis.available());
String out = "\tUTF-8: ";
while (dis.available() > 1) {
out += " '" + (char) dis.read() + '\'';
}
dis.reset();
return out;
}
public static String buildUTF16(DataInputStream dis) throws IOException {
dis.mark(dis.available());
String out = "\tUTF-16:";
while (dis.available() > 1) {
out += " '" + dis.readChar() + '\'';
}
dis.reset();
return out;
}
public static String buildRawNumericalBytes(DataInputStream dis)
throws IOException {
dis.mark(dis.available());
String out = "\tRaw Bytes (int vals): ";
while (dis.available() > 1) {
out += " '" + dis.read() + '\'';
}
dis.reset();
return out;
}
}
+221
View File
@@ -0,0 +1,221 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.util;
import java.io.UnsupportedEncodingException;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
public class ByteBufferUtils {
public static String getString(ByteBuffer bb)
throws BufferUnderflowException {
return getString(bb, false, false);
}
public static String getString(ByteBuffer bb, boolean switchEndian, boolean small)
throws BufferUnderflowException {
String out = "";
synchronized (bb) {
//This version works with non-latin characters
int stringLen;
if (small)
stringLen = (int)bb.get();
else
stringLen = bb.getInt();
if (switchEndian)
stringLen = ((Integer.reverseBytes(stringLen)) * 2);
else
stringLen *= 2;
byte[] b = new byte[stringLen];
for (int i=0;i<stringLen;i+=2) {
if (switchEndian) {
b[i+1] = bb.get();
b[i] = bb.get();
} else {
b[i] = bb.get();
b[i+1] = bb.get();
}
}
try {
out = new String(b, "UTF-16BE");
} catch (UnsupportedEncodingException e) {}
}
return out;
}
public static void putString(ByteBuffer bb, String data, boolean small)
throws BufferOverflowException {
putString(bb, data, false, small);
}
public static void putString(ByteBuffer bb, String data,
boolean switchEndian, boolean small) throws BufferOverflowException {
if (data == null) {
data = "";
}
char[] chars = data.toCharArray();
int length = chars.length;
if (small && length > 255)
length = 255; //limit for smallString
synchronized (bb) {
// Write length
if (small)
bb.put((byte)length);
else {
if (switchEndian) {
bb.putInt(Integer.reverseBytes(length));
} else {
bb.putInt(length);
}
}
// Write chars
for (int i=0;i<length;i++) {
char c = chars[i];
if (switchEndian) {
bb.putChar(Character.reverseBytes(c));
} else {
bb.putChar(c);
}
}
}
}
public static String getHexString(ByteBuffer bb)
throws BufferUnderflowException {
return getHexString(bb, false);
}
public static String getHexString(ByteBuffer bb, boolean switchEndian)
throws BufferUnderflowException {
String out = "";
synchronized (bb) {
// Read len
int stringLen = bb.getInt();
if (switchEndian) {
stringLen = Integer.reverseBytes(stringLen);
}
// Read len worth of chars
for (int i = 0; i < stringLen; ++i) {
out += Integer.toString((bb.get() & 0xff) + 0x100, 16)
.substring(1);
}
}
return out;
}
public static void putHexString(ByteBuffer bb, String data)
throws BufferOverflowException {
putHexString(bb, data, false);
}
public static void putHexString(ByteBuffer bb, String data,
boolean switchEndian) throws BufferOverflowException {
if (data == null) {
data = "";
}
byte[] bts = new byte[data.length() / 2];
for (int i = 0; i < bts.length; i++) {
bts[i] = (byte) Integer.parseInt(data.substring(2 * i, 2 * i + 1),
16);
}
synchronized (bb) {
if (switchEndian) {
bb.putInt(Integer.reverseBytes(data.length() / 2));
} else {
bb.putInt(data.length() / 2);
}
bb.put(bts);
}
}
public static String getUnicodeString(ByteBuffer bb)
throws BufferUnderflowException {
return getUnicodeString(bb, false);
}
public static String getUnicodeString(ByteBuffer bb, boolean switchEndian)
throws BufferUnderflowException {
byte[] out;
short thisChar;
synchronized (bb) {
// Read len
int stringLen = bb.getInt();
if (switchEndian) {
stringLen = Integer.reverseBytes(stringLen);
}
out = new byte[stringLen];
// Read len worth of chars
for (int i = 0; i < stringLen; ++i) {
thisChar = bb.getShort();
if (switchEndian)
Short.reverseBytes(thisChar);
out[i] = (byte) (thisChar & 0xff); // ignore first byte
}
}
return new String(out);
}
public static void putUnicodeString(ByteBuffer bb, String data)
throws BufferOverflowException {
putUnicodeString(bb, data, false);
}
public static void putUnicodeString(ByteBuffer bb, String data,
boolean switchEndian) throws BufferOverflowException {
byte[] out;
short thisChar;
if (data == null)
return;
out = new byte[data.length()];
out = data.getBytes();
for (byte b : out) {
thisChar = b;
if (switchEndian)
thisChar = Short.reverseBytes(thisChar);
bb.putShort(thisChar);
}
}
public static boolean checkByteBufferNearFull(ByteBuffer bb) {
return bb.position() >= (bb.capacity() * 0.9);
}
//FIXME: Replace these!!!
// public static ByteBuffer resizeByteBuffer(ByteBuffer bb, int multiplyer) {
//
// ByteBuffer out = ByteBuffer.allocate(bb.capacity() * multiplyer);
//
// // Copy the data to a temp buf
// bb.flip();
// out.put(bb);
//
// return out;
// }
//
// public static ByteBuffer shrinkByteBuffer(ByteBuffer bb) {
//
// bb.flip();
// ByteBuffer out = ByteBuffer.allocate(bb.remaining());
// out.put(bb);
// return out;
// }
}
+171
View File
@@ -0,0 +1,171 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public abstract class ByteUtils {
private ByteUtils() {
}
public static byte[] switchByteArrayEndianness(byte[] in) {
int size = in.length;
byte[] out = new byte[size];
for (int i = 0; i < size; ++i) {
out[size - i - 1] = in[i];
}
return out;
}
/*
* Converts a single byte to a hex StringBuffer
*/
public static void byteToStringHex(byte b, StringBuffer buf) {
char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
/*
* Converts a single byte to a hex String
*/
public static String byteToStringHex(byte b) {
StringBuffer sb = new StringBuffer();
byteToStringHex(b, sb);
return sb.toString();
}
/*
* Converts a byte array to hex String
*/
public static String byteArrayToStringHex(byte[] block) {
StringBuffer buf = new StringBuffer();
int len = block.length;
for (int i = 0; i < len; i++) {
ByteUtils.byteToStringHex(block[i], buf);
if (i < len - 1) {
buf.append(':');
}
}
return buf.toString();
}
/*
* Converts a single byte to a hex StringBuffer
*/
public static void byteToSafeStringHex(byte b, StringBuffer buf) {
char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
int high = ((b & 0xf0) >> 4);
int low = (b & 0x0f);
buf.append(hexChars[high]);
buf.append(hexChars[low]);
}
/*
* Converts a single byte to a hex String
*/
public static String byteToSafeStringHex(byte b) {
StringBuffer sb = new StringBuffer();
byteToSafeStringHex(b, sb);
return sb.toString();
}
/*
* Converts a byte array to hex String
*/
public static String byteArrayToSafeStringHex(byte[] block) {
StringBuffer buf = new StringBuffer();
int len = block.length;
for (int i = 0; i < len; i++) {
ByteUtils.byteToSafeStringHex(block[i], buf);
}
return buf.toString();
}
/*
* Converts a hex string to Byte Array
*/
public static byte[] stringHexToByteArray(String hex) {
int length = hex.length();
char[] hexchar = hex.toCharArray();
byte[] ret = new byte[length / 2];
int i1 = 0;
for (int i = 0; i < length - 1; i += 2) {
ret[i1] = (byte) (Character.digit(hexchar[i], 16) * 16 + Character
.digit(hexchar[i + 1], 16));
i1++;
}
return ret;
}
/*
* Converts a hex string formatted by our byteToStringHex to a byte array
* returns null if passed a null string
*/
public static byte[] formattedStringHexToByteArray(String hex) {
if(hex == null){
return null;
}
String tmpString = hex.replaceAll(":","");
int length = tmpString.length();
char[] hexchar = tmpString.toCharArray();
byte[] ret = new byte[length / 2];
int i1 = 0;
for (int i = 0; i < length - 1; i += 2) {
ret[i1] = (byte) (Character.digit(hexchar[i], 16) * 16 + Character
.digit(hexchar[i + 1], 16));
i1++;
}
return ret;
}
public static byte[] compress(final byte[] in) throws IOException{
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final GZIPOutputStream gzOs = new GZIPOutputStream(out);
gzOs.write(in);
gzOs.close();
return out.toByteArray();
}
public static byte[] decompress(final byte[] in) throws IOException{
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final GZIPInputStream gzIs = new GZIPInputStream(new ByteArrayInputStream(in));
final byte[] buffer = new byte[512];
int lastRead = 0;
lastRead = gzIs.read(buffer);
while (lastRead > 0) {
out.write(buffer,0,lastRead);
lastRead = gzIs.read(buffer);
}
gzIs.close();
return out.toByteArray();
}
}
+382
View File
@@ -0,0 +1,382 @@
package engine.util;
import java.util.*;
/*
* Author: https://github.com/peet/hashids.java
*/
public class Hasher {
private static final String DEFAULT_ALPHABET = "xcS4F6h89aUbideAI7tkynuopqrXCgTE5GBKHLMjfRsz";
private static final int[] PRIMES = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
private static final int[] SEPS_INDICES = {0, 4, 8, 12};
private String salt_ = "";
private String alphabet_ = "";
private int minHashLength_;
private ArrayList<Character> seps_ = new ArrayList<>();
private ArrayList<Character> guards_ = new ArrayList<>();
public Hasher() {
this("");
}
public Hasher(String salt) {
this(salt, 0);
}
public Hasher(String salt, int minHashLength) {
this(salt, minHashLength, DEFAULT_ALPHABET);
}
public Hasher(String salt, int minHashLength, String alphabet) {
if (alphabet == null || alphabet.trim().isEmpty()) {
throw new IllegalArgumentException("alphabet must not be empty");
}
if (salt != null) {
salt_ = salt;
}
if (minHashLength > 0) {
minHashLength_ = minHashLength;
}
alphabet_ = join(new LinkedHashSet<>(Arrays.asList(alphabet.split(""))), "");
if (alphabet_.length() < 4) {
throw new IllegalArgumentException("Alphabet must contain at least 4 unique characters.");
}
for (int prime : PRIMES) {
if (prime < alphabet_.length()) {
char c = alphabet_.charAt(prime - 1);
seps_.add(c);
alphabet_ = alphabet_.replace(c, ' ');
}
}
for (int index : SEPS_INDICES) {
if (index < seps_.size()) {
guards_.add(seps_.get(index));
seps_.remove(index);
}
}
alphabet_ = consistentShuffle(alphabet_.replaceAll(" ", ""), salt_);
}
public String encrypt(long... numbers) {
return encode(numbers, alphabet_, salt_, minHashLength_);
}
public long[] decrypt(String hash) {
return decode(hash);
}
private String encode(long[] numbers, String alphabet, String salt, int minHashLength) {
String ret = "";
String seps = consistentShuffle(join(seps_, ""), join(numbers, ""));
char lotteryChar = 0;
for (int i = 0; i < numbers.length; i++) {
if (i == 0) {
String lotterySalt = join(numbers, "-");
for (long number : numbers) {
lotterySalt += "-" + (number + 1) * 2;
}
String lottery = consistentShuffle(alphabet, lotterySalt);
lotteryChar = lottery.charAt(0);
ret += lotteryChar;
alphabet = lotteryChar + alphabet.replaceAll(String.valueOf(lotteryChar), "");
}
alphabet = consistentShuffle(alphabet, ((int) lotteryChar & 12345) + salt);
ret += hash(numbers[i], alphabet);
if (i + 1 < numbers.length) {
ret += seps.charAt((int) ((numbers[i] + i) % seps.length()));
}
}
if (ret.length() < minHashLength) {
int firstIndex = 0;
for (int i = 0; i < numbers.length; i++) {
firstIndex += (i + 1) * numbers[i];
}
int guardIndex = firstIndex % guards_.size();
char guard = guards_.get(guardIndex);
ret = guard + ret;
if (ret.length() < minHashLength) {
guardIndex = (guardIndex + ret.length()) % guards_.size();
guard = guards_.get(guardIndex);
ret += guard;
}
}
while (ret.length() < minHashLength) {
long[] padArray = new long[]{alphabet.charAt(1), alphabet.charAt(0)};
String padLeft = encode(padArray, alphabet, salt, 0);
String padRight = encode(padArray, alphabet, join(padArray, ""), 0);
ret = padLeft + ret + padRight;
int excess = ret.length() - minHashLength;
if (excess > 0) {
ret = ret.substring(excess / 2, excess / 2 + minHashLength);
}
alphabet = consistentShuffle(alphabet, salt + ret);
}
return ret;
}
private static String hash(long number, String alphabet) {
String hash = "";
while (number > 0) {
hash = alphabet.charAt((int) (number % alphabet.length())) + hash;
number /= alphabet.length();
}
return hash;
}
private static long unhash(String hash, String alphabet) {
int number = 0;
for (int i = 0; i < hash.length(); i++) {
int pos = alphabet.indexOf(hash.charAt(i));
number += pos * (int) Math.pow(alphabet.length(), hash.length() - i - 1);
}
return number;
}
private long[] decode(String hash) {
List<Long> ret = new ArrayList<>();
String originalHash = hash;
if (hash != null && !hash.isEmpty()) {
String alphabet = "";
char lotteryChar = 0;
for (char guard : guards_) {
hash = hash.replaceAll(String.valueOf(guard), " ");
}
String[] hashSplit = hash.split(" ");
hash = hashSplit[hashSplit.length == 3 || hashSplit.length == 2 ? 1 : 0];
for (char sep : seps_) {
hash = hash.replaceAll(String.valueOf(sep), " ");
}
String[] hashArray = hash.split(" ");
for (int i = 0; i < hashArray.length; i++) {
String subHash = hashArray[i];
if (subHash != null && !subHash.isEmpty()) {
if (i == 0) {
lotteryChar = hash.charAt(0);
subHash = subHash.substring(1);
alphabet = lotteryChar + alphabet_.replaceAll(String.valueOf(lotteryChar), "");
}
}
if (alphabet.length() > 0) {
alphabet = consistentShuffle(alphabet, ((int) lotteryChar & 12345) + salt_);
ret.add(unhash(subHash, alphabet));
}
}
}
long[] numbers = longListToPrimitiveArray(ret);
if (!encrypt(numbers).equals(originalHash)) {
return new long[0];
}
return numbers;
}
private static String consistentShuffle(String alphabet, String salt) {
String ret = "";
if (!alphabet.isEmpty()) {
List<String> alphabetArray = charArrayToStringList(alphabet.toCharArray());
if (salt == null || salt.isEmpty()) {
salt = new String(new char[]{'\0'});
}
int[] sortingArray = new int[salt.length()];
for (int i = 0; i < salt.length(); i++) {
sortingArray[i] = salt.charAt(i);
}
for (int i = 0; i < sortingArray.length; i++) {
boolean add = true;
for (int k = i; k != sortingArray.length + i - 1; k++) {
int nextIndex = (k + 1) % sortingArray.length;
if (add) {
sortingArray[i] += sortingArray[nextIndex] + (k * i);
} else {
sortingArray[i] -= sortingArray[nextIndex];
}
add = !add;
}
sortingArray[i] = Math.abs(sortingArray[i]);
}
int i = 0;
while (alphabetArray.size() > 0) {
int pos = sortingArray[i];
if (pos >= alphabetArray.size()) {
pos %= alphabetArray.size();
}
ret += alphabetArray.get(pos);
alphabetArray.remove(pos);
i = ++i % sortingArray.length;
}
}
return ret;
}
public String getSalt() {
return salt_;
}
public String getAlphabet() {
return alphabet_;
}
public int getMinHashLength() {
return minHashLength_;
}
public static String getVersion() {
return "0.1.4";
}
private static long[] longListToPrimitiveArray(List<Long> longs) {
long[] longArr = new long[longs.size()];
int i = 0;
for (long l : longs) {
longArr[i++] = l;
}
return longArr;
}
private static List<String> charArrayToStringList(char[] chars) {
ArrayList<String> list = new ArrayList<>(chars.length);
for (char c : chars) {
list.add(String.valueOf(c));
}
return list;
}
private static String join(long[] a, String delimiter) {
ArrayList<String> strList = new ArrayList<>(a.length);
for (long l : a) {
strList.add(String.valueOf(l));
}
return join(strList, delimiter);
}
private static String join(Collection<?> s, String delimiter) {
Iterator<?> iter = s.iterator();
if (iter.hasNext()) {
StringBuilder builder = new StringBuilder(s.size());
builder.append(iter.next());
while (iter.hasNext()) {
builder.append(delimiter);
builder.append(iter.next());
}
return builder.toString();
}
return "";
}
public static int SBStringHash(String toHash) {
byte[] hashArray = toHash.getBytes();
int hash = 0;
int shift = 0;
if (toHash.equals("SafeModeA"))
return -1661750486;
if (toHash.equals("SafeModeB"))
return -1661751254;
if (toHash.equals("INVIS-D"))
return -1661751254;
if (toHash.equals("SafeMode"))
return -1661750486;
if ((hashArray.length != 8 && hashArray.length != 7) || hashArray[3] != 45) {
hash = 0;
shift = 0;
for (int i = 0; i < hashArray.length; i++) {
if (i == 0)
shift = 0;
else
shift = shift + 5;
int toShift = hashArray[i] - 0x20;
hash ^= toShift << shift;
if (shift > 24) {
int newShift = 0x20 - shift;
hash ^= toShift >> newShift;
if (shift >= 27) {
shift = shift - 0x20;
}
}
}
return hash;
} else {
int ecx = 0;
if (hashArray.length == 8) {
ecx = hashArray[7];
}
int eax = hashArray[4];
int esi = ecx * 0x8;
eax = eax ^ esi;
ecx = ecx ^ 0x5A0;
esi = hashArray[5];
eax = eax << 4;
eax = eax ^ esi;
esi = hashArray[6];
eax = eax << 4;
eax = eax ^ esi;
esi = hashArray[2];
eax = eax << 5;
eax = eax ^ esi;
esi = hashArray[1];
int edx = hashArray[0];
eax = eax << 5;
eax = eax ^ esi;
ecx = ecx / 2;
ecx = ecx / 2;
eax = eax << 5;
ecx = ecx ^ edx;
eax = eax ^ ecx;
return eax;
}
}
}
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright MagicBane 2013
*/
package engine.util;
import engine.Enum.RealmType;
import engine.server.MBServerStatics;
import engine.server.world.WorldServer;
import org.pmw.tinylog.Logger;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public enum MapLoader {
MAPLOADER;
public static int[][] loadMap() {
BufferedImage image;
int[][] realmMap;
long timeToLoad = System.currentTimeMillis();
long bytesRead = 0;
long realmsWritten = 0;
Integer realmUUID = null;
// Load image from disk
try {
image = ImageIO.read(new File(MBServerStatics.DEFAULT_DATA_DIR + "realmmap.png"));
// Array size determined by image size
MBServerStatics.SPATIAL_HASH_BUCKETSX = image.getWidth();
MBServerStatics.SPATIAL_HASH_BUCKETSY = image.getHeight();
realmMap = new int[MBServerStatics.SPATIAL_HASH_BUCKETSX][MBServerStatics.SPATIAL_HASH_BUCKETSY];
} catch (IOException e) {
Logger.error( "Error loading realm map: " + e.toString());
return null;
}
// Flip image on the y axis
image = flipImage(image);
// Initialize color lookup table
for (RealmType realm : RealmType.values()) {
realm.addToColorMap();
}
// Load spatial imageMap with color data from file
for (int i = 0; i < MBServerStatics.SPATIAL_HASH_BUCKETSY; i++) {
for (int j = 0; j < MBServerStatics.SPATIAL_HASH_BUCKETSX; j++) {
try {
int rgb = image.getRGB(j, i);
realmUUID = RealmType.getRealmIDByRGB(rgb);
if (realmUUID == null) {
Logger.error("Corrupted png: unknown color " + rgb);
WorldServer.shutdown();
}
realmMap[j][i] = realmUUID.intValue();
bytesRead++;
if (realmUUID.intValue() != 0)
realmsWritten++;
}catch (Exception e){
// Logger.error("REALMEDIT ERROR", e.getMessage());
continue;
}
}
}
timeToLoad = System.currentTimeMillis() - timeToLoad;
Logger.info( bytesRead + " pixels processed in " + timeToLoad / 1000 + " seconds");
Logger.info("Realm pixels written : " + realmsWritten);
image = null;
return realmMap;
}
public static BufferedImage flipImage(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getColorModel()
.getTransparency());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, 0, h, w, 0, null);
g.dispose();
return dimg;
}
}
+94
View File
@@ -0,0 +1,94 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.util;
import engine.server.MBServerStatics;
import java.util.regex.Pattern;
public class MiscUtils {
// no need to recompile these each call, put them in object scope and
// compile just once.
private static final Pattern lastNameRegex = Pattern
.compile("^[A-Za-z][-'A-Za-z\\x20]*$");
private static final Pattern firstNameRegex = Pattern
.compile("^[A-Za-z]+$");
public static boolean checkIfFirstNameInvalid(String firstName) {
if ((firstName == null) || (firstName.length() == 0)
|| (firstName.length() > MBServerStatics.MAX_NAME_LENGTH)
|| (firstName.length() < MBServerStatics.MIN_NAME_LENGTH)) {
return true;
}
return (!firstNameRegex.matcher(firstName).matches());
}
public static boolean checkIfLastNameInvalid(String lastName) {
if ((lastName != null) && (lastName.length() != 0)) {
// make sure it's less than max length
return lastName.length() > MBServerStatics.MAX_NAME_LENGTH;
// first character: A-Z, a-z
// remaining chars (optional): hyphen, apostrophe, A-Z, a-z, space
// return (!lastNameRegex.matcher(lastName).matches());
}
// empty last names are fine, return false
return false;
}
public static String getCallingMethodName() {
StackTraceElement e[] = Thread.currentThread().getStackTrace();
int numElements = e.length;
if (numElements < 1) {
return "NoStack";
}
if (numElements == 1) {
return e[0].getMethodName();
} else if (numElements == 2) {
return e[1].getMethodName();
} else if (numElements == 3) {
return e[2].getMethodName();
} else {
return e[3].getMethodName();
}
}
public static String getCallStackAsString() {
String out = "";
StackTraceElement e[] = Thread.currentThread().getStackTrace();
int numElements = e.length;
for (int i = (numElements - 1); i > 1; --i) {
String[] classStack = e[i].getClassName().split("\\.");
String methName = e[i].getMethodName();
String className = classStack[classStack.length - 1];
if (methName.equals("<init>")) {
methName = className;
}
out += className + '.' + methName + "()";
if (i > 2) {
out += " -> ";
}
}
return out;
}
}
+150
View File
@@ -0,0 +1,150 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.util;
import java.net.InetAddress;
import java.util.StringTokenizer;
public class StringUtils {
public static String addWS(String s, int totalLen) {
if (s.length() >= totalLen) {
return s;
}
int diff = totalLen - s.length();
String out = s;
for (int i = 0; i < diff; ++i) {
out += " ";
}
return out;
}
public static String bannerize(String s, int totalLen) {
if (s.length() >= totalLen) {
return s;
}
int diff = totalLen - s.length();
int halfDiff = diff / 2;
String side = "";
for (int i = 0; i < halfDiff; ++i) {
side += "*";
}
return side + ' ' + s + ' ' + side;
}
public static String InetAddressToClientString(InetAddress address) {
return address.toString().replaceAll("/", "");
}
public static String toHexString(int i) {
return Integer.toHexString(i).toUpperCase();
}
public static String toHexString(long l) {
return Long.toHexString(l).toUpperCase();
}
// Well done IDA Pro.
public static int hashString(String toHash) {
byte[] hashArray = toHash.getBytes();
int hash = 0;
int shift = 0;
if (hashArray.length == 8 ||hashArray.length == 7){
int ecx = 0;
if (hashArray.length == 8){
ecx = hashArray[7];
}
int eax = hashArray[4];
int esi = ecx * 0x8;
eax ^= esi;
ecx ^= 0x5A0;
esi = hashArray[5];
eax <<= 4;
eax ^= esi;
esi = hashArray[6];
eax <<= 4;
eax ^= esi;
esi = hashArray[2];
eax <<= 5;
eax ^= esi;
esi = hashArray[1];
int edx = hashArray[0];
eax <<= 5;
eax ^= esi;
ecx /= 2;
ecx /= 2;
eax <<= 5;
ecx ^= edx;
eax ^= ecx;
return eax;
}else{
for (int i = 0; i<hashArray.length;i++){
if (i == 0)
shift = 0;
else
shift += 5;
int toShift = hashArray[i] - 0x20;
int shifted = (toShift<<shift);
hash ^= shifted;
if (shift > 24){
int newShift = 0x20 - shift;
int newShifted = toShift >> newShift;
hash ^= newShifted;
if (shift > 27){
shift -= 0x20;
}
}
}
return hash;
}
}
public static String wordWrap(String text,int LineWidth)
{
StringTokenizer st=new StringTokenizer(text);
int SpaceLeft=LineWidth;
int SpaceWidth=80;
String outString = "";
while(st.hasMoreTokens())
{
String word=st.nextToken();
if((word.length()+SpaceWidth)>SpaceLeft)
{
outString+= '\n' +word+ ' ';
SpaceLeft=LineWidth-word.length();
}
else
{
outString+=word+ ' ';
SpaceLeft-=(word.length()+SpaceWidth);
}
}
return outString;
}
public static String truncate(String input, int length) {
if (input != null && input.length() > length)
input = input.substring(0, length);
return input;
}
}
+43
View File
@@ -0,0 +1,43 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.util;
import org.pmw.tinylog.Logger;
public abstract class ThreadUtils {
private ThreadUtils() {
}
/**
* Force the current thread to sleep for <i>sec</i> seconds and <i>ms</i>
* milliseconds.
*
*
*/
public static void sleep(int sec, long ms) {
try {
Thread.sleep((1000L * sec) + ms);
} catch (InterruptedException e) {
Logger.error( e.toString());
}
}
/**
* Force the current thread to sleep for <i>ms</i> milliseconds.
*
*
*/
public static void sleep(long ms) {
ThreadUtils.sleep(0, ms);
}
}