Initial Repository Push
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user