Cleaned up some core files

This commit is contained in:
Oven Bread
2026-06-03 12:52:06 +00:00
committed by Ryan
parent 80c8b219ea
commit 13c4358d77
20 changed files with 644 additions and 1204 deletions
+1 -1
View File
@@ -145,7 +145,7 @@ public final class Cache {
buffer.putInt(0);
continue;
}
buffer.putInt(cacheFileManagers[index].getInformation().getInformationContainer().getCrc());
buffer.putInt(cacheFileManagers[index].getInformation().informationContainer.getCrc());
buffer.putInt(cacheFileManagers[index].getInformation().getRevision());
}
return buffer.array();
+1 -1
View File
@@ -66,7 +66,7 @@ public final class CacheFile {
return null;
}
if (xteaKeys != null && (xteaKeys[0] != 0 || xteaKeys[1] != 0 || xteaKeys[2] != 0 || xteaKeys[3] != 0)) {
packedData = XTEACryption.decrypt(xteaKeys, ByteBuffer.wrap(packedData), 5, packedData.length).array();
packedData = XTEACryption.Companion.decrypt(xteaKeys, ByteBuffer.wrap(packedData), 5, packedData.length).array();
}
return ContainersInformation.unpackCacheContainer(packedData);
}
-72
View File
@@ -1,72 +0,0 @@
package core.cache;
import java.nio.ByteBuffer;
/**
* Represents a file used in the server store.
* @author Emperor
*/
public final class StoreFile {
/**
* If the data can change during server runtime.
*/
private boolean dynamic;
/**
* The file data.
*/
private byte[] data;
/**
* Constructs a new {@code StoreFile} {@code Object}.
*/
public StoreFile() {
/*
* empty.
*/
}
/**
* Puts the data on the buffer.
* @param buffer The buffer.
*/
public void put(ByteBuffer buffer) {
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
this.data = data;
}
/**
* Creates a byte buffer containing the file data.
* @return The buffer.
*/
public ByteBuffer data() {
return ByteBuffer.wrap(data);
}
/**
* Sets the data.
* @param data The data.
*/
public void setData(byte[] data) {
this.data = data;
}
/**
* Gets the dynamic.
* @return The dynamic.
*/
public boolean isDynamic() {
return dynamic;
}
/**
* Sets the dynamic.
* @param dynamic The dynamic to set.
*/
public void setDynamic(boolean dynamic) {
this.dynamic = dynamic;
}
}
-271
View File
@@ -1,271 +0,0 @@
package core.cache.crypto;
/**
* <p> An implementation of an ISAAC cipher. See <a
* href="http://en.wikipedia.org/wiki/ISAAC_(cipher)">
* http://en.wikipedia.org/wiki/ISAAC_(cipher)</a> for more information. </p>
* <p> This implementation is based on the one written by Bob Jenkins, which is
* available at <a href="http://www.burtleburtle.net/bob/java/rand/Rand.java">
* http://www.burtleburtle.net/bob/java/rand/Rand.java</a>. </p>
* @author Graham Edgecombe
*/
public class ISAACCipher {
/**
* The golden ratio.
*/
public static final int RATIO = 0x9e3779b9;
/**
* The log of the size of the results and memory arrays.
*/
public static final int SIZE_LOG = 8;
/**
* The size of the results and memory arrays.
*/
public static final int SIZE = 1 << SIZE_LOG;
/**
* For pseudorandom lookup.
*/
public static final int MASK = (SIZE - 1) << 2;
/**
* The count through the results.
*/
private int count = 0;
/**
* The results.
*/
private int results[] = new int[SIZE];
/**
* The internal memory state.
*/
private int memory[] = new int[SIZE];
/**
* The accumulator.
*/
private int a;
/**
* The last result.
*/
private int b;
/**
* The counter.
*/
private int c;
/**
* Creates the ISAAC cipher.
* @param seed The seed.
*/
public ISAACCipher(int[] seed) {
for (int i = 0; i < seed.length; i++) {
results[i] = seed[i];
}
init(true);
}
/**
* Gets the next value.
* @return The next value.
*/
public int getNextValue() {
if (count-- == 0) {
isaac();
count = SIZE - 1;
}
return 0;//results[count];
}
/**
* Generates 256 results.
*/
public void isaac() {
int i, j, x, y;
b += ++c;
for (i = 0, j = SIZE / 2; i < SIZE / 2;) {
x = memory[i];
a ^= a << 13;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
x = memory[i];
a ^= a >>> 6;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
x = memory[i];
a ^= a << 2;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
x = memory[i];
a ^= a >>> 16;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
}
for (j = 0; j < SIZE / 2;) {
x = memory[i];
a ^= a << 13;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
x = memory[i];
a ^= a >>> 6;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
x = memory[i];
a ^= a << 2;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
x = memory[i];
a ^= a >>> 16;
a += memory[j++];
memory[i] = y = memory[(x & MASK) >> 2] + a + b;
results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x;
}
}
/**
* Initialises the ISAAC.
* @param flag Flag indicating if we should perform a second pass.
*/
public void init(boolean flag) {
int i;
int a, b, c, d, e, f, g, h;
a = b = c = d = e = f = g = h = RATIO;
for (i = 0; i < 4; ++i) {
a ^= b << 11;
d += a;
b += c;
b ^= c >>> 2;
e += b;
c += d;
c ^= d << 8;
f += c;
d += e;
d ^= e >>> 16;
g += d;
e += f;
e ^= f << 10;
h += e;
f += g;
f ^= g >>> 4;
a += f;
g += h;
g ^= h << 8;
b += g;
h += a;
h ^= a >>> 9;
c += h;
a += b;
}
for (i = 0; i < SIZE; i += 8) {
if (flag) {
a += results[i];
b += results[i + 1];
c += results[i + 2];
d += results[i + 3];
e += results[i + 4];
f += results[i + 5];
g += results[i + 6];
h += results[i + 7];
}
a ^= b << 11;
d += a;
b += c;
b ^= c >>> 2;
e += b;
c += d;
c ^= d << 8;
f += c;
d += e;
d ^= e >>> 16;
g += d;
e += f;
e ^= f << 10;
h += e;
f += g;
f ^= g >>> 4;
a += f;
g += h;
g ^= h << 8;
b += g;
h += a;
h ^= a >>> 9;
c += h;
a += b;
memory[i] = a;
memory[i + 1] = b;
memory[i + 2] = c;
memory[i + 3] = d;
memory[i + 4] = e;
memory[i + 5] = f;
memory[i + 6] = g;
memory[i + 7] = h;
}
if (flag) {
for (i = 0; i < SIZE; i += 8) {
a += memory[i];
b += memory[i + 1];
c += memory[i + 2];
d += memory[i + 3];
e += memory[i + 4];
f += memory[i + 5];
g += memory[i + 6];
h += memory[i + 7];
a ^= b << 11;
d += a;
b += c;
b ^= c >>> 2;
e += b;
c += d;
c ^= d << 8;
f += c;
d += e;
d ^= e >>> 16;
g += d;
e += f;
e ^= f << 10;
h += e;
f += g;
f ^= g >>> 4;
a += f;
g += h;
g ^= h << 8;
b += g;
h += a;
h ^= a >>> 9;
c += h;
a += b;
memory[i] = a;
memory[i + 1] = b;
memory[i + 2] = c;
memory[i + 3] = d;
memory[i + 4] = e;
memory[i + 5] = f;
memory[i + 6] = g;
memory[i + 7] = h;
}
}
isaac();
count = SIZE;
}
}
+213
View File
@@ -0,0 +1,213 @@
package core.cache.crypto
/**
* An implementation of an ISAAC cipher.
* See [http://en.wikipedia.org/wiki/ISAAC_(cipher)](http://en.wikipedia.org/wiki/ISAAC_(cipher)) for more information.
* Based on the one written by Bob Jenkins, which is available at
* [http://www.burtleburtle.net/bob/java/rand/Rand.java](http://www.burtleburtle.net/bob/java/rand/Rand.java).
*/
class ISAACCipher(seed: IntArray) {
companion object {
/** Golden ratio in 32 bit unsigned int. */
const val RATIO = -0x61c88647
/** The base 2 log of the size of the results and memory arrays. */
const val SIZE_LOG = 8
/** The size of the results and memory arrays. */
const val SIZE = 1 shl SIZE_LOG
/** For pseudorandom lookup. */
const val MASK = SIZE - 1 shl 2
}
/** The count through the results. */
private var count = 0
/** The results. */
private val results = IntArray(SIZE)
/** The internal memory state. */
private val memory = IntArray(SIZE)
/** The accumulator. */
private var a = 0
/** The last result. */
private var b = 0
/** The counter. */
private var c = 0
/**
* Creates the ISAAC cipher.
* @param seed The seed.
*/
init {
for (i in seed.indices) {
results[i] = seed[i]
}
init(true)
}
val nextValue: Int
/**
* Gets the next value.
* @return The next value.
*/
get() {
if (count-- == 0) {
isaac()
count = SIZE - 1
}
return 0 //results[count];
}
/**
* Generates 256 results.
*/
fun isaac() {
var i: Int
var j: Int
var x: Int
var y: Int
b += ++c
i = 0
j = SIZE / 2
while (i < SIZE / 2) {
x = memory[i]
a = a xor (a shl 13)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
x = memory[i]
a = a xor (a ushr 6)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
x = memory[i]
a = a xor (a shl 2)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
x = memory[i]
a = a xor (a ushr 16)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
}
j = 0
while (j < SIZE / 2) {
x = memory[i]
a = a xor (a shl 13)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
x = memory[i]
a = a xor (a ushr 6)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
x = memory[i]
a = a xor (a shl 2)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
x = memory[i]
a = a xor (a ushr 16)
a += memory[j++]
y = memory[x and MASK shr 2] + a + b
memory[i] = y
b = memory[y shr SIZE_LOG and MASK shr 2] + x
results[i++] = b
}
}
/**
* Initialises the ISAAC.
* @param flag Flag indicating if we should perform a second pass.
*/
fun init(flag: Boolean) {
var a = RATIO
var b = a; var c = b; var d = c; var e = d; var f = e; var g = f; var h = g
var i = 0
while (i < 4) {
a = a xor (b shl 11); d += a; b += c
b = b xor (c ushr 2); e += b; c += d
c = c xor (d shl 8); f += c; d += e
d = d xor (e ushr 16); g += d; e += f
e = e xor (f shl 10); h += e; f += g
f = f xor (g ushr 4); a += f; g += h
g = g xor (h shl 8); b += g; h += a
h = h xor (a ushr 9); c += h; a += b
++i
}
i = 0
while (i < SIZE) {
if (flag) {
a += results[i]
b += results[i + 1]
c += results[i + 2]
d += results[i + 3]
e += results[i + 4]
f += results[i + 5]
g += results[i + 6]
h += results[i + 7]
}
a = a xor (b shl 11); d += a; b += c
b = b xor (c ushr 2); e += b; c += d
c = c xor (d shl 8); f += c; d += e
d = d xor (e ushr 16); g += d; e += f
e = e xor (f shl 10); h += e; f += g
f = f xor (g ushr 4); a += f; g += h
g = g xor (h shl 8); b += g; h += a
h = h xor (a ushr 9); c += h; a += b
memory[i] = a
memory[i + 1] = b
memory[i + 2] = c
memory[i + 3] = d
memory[i + 4] = e
memory[i + 5] = f
memory[i + 6] = g
memory[i + 7] = h
i += 8
}
if (flag) {
i = 0
while (i < SIZE) {
a += memory[i]
b += memory[i + 1]
c += memory[i + 2]
d += memory[i + 3]
e += memory[i + 4]
f += memory[i + 5]
g += memory[i + 6]
h += memory[i + 7]
a = a xor (b shl 11); d += a; b += c
b = b xor (c ushr 2); e += b; c += d
c = c xor (d shl 8); f += c; d += e
d = d xor (e ushr 16); g += d; e += f
e = e xor (f shl 10); h += e; f += g
f = f xor (g ushr 4); a += f; g += h
g = g xor (h shl 8); b += g; h += a
h = h xor (a ushr 9); c += h; a += b
memory[i] = a
memory[i + 1] = b
memory[i + 2] = c
memory[i + 3] = d
memory[i + 4] = e
memory[i + 5] = f
memory[i + 6] = g
memory[i + 7] = h
i += 8
}
}
isaac()
count = SIZE
}
}
-45
View File
@@ -1,45 +0,0 @@
package core.cache.crypto;
/**
* Represents a ISAAC key pair, for both input and output.
* @author `Discardedx2
*/
public final class ISAACPair {
/**
* The input cipher.
*/
private ISAACCipher input;
/**
* The output cipher.
*/
private ISAACCipher output;
/**
* Constructs a new {@code ISAACPair} {@code Object}.
* @param input The input cipher.
* @param output The output cipher.
*/
public ISAACPair(ISAACCipher input, ISAACCipher output) {
this.input = input;
this.output = output;
}
/**
* Gets the input cipher.
* @return The input cipher.
*/
public ISAACCipher getInput() {
return input;
}
/**
* Gets the output cipher.
* @return The output cipher.
*/
public ISAACCipher getOutput() {
return output;
}
}
+9
View File
@@ -0,0 +1,9 @@
package core.cache.crypto
/**
* Represents a ISAAC key pair, for both input and output.
*/
class ISAACPair(
val input: ISAACCipher,
val output: ISAACCipher
)
-124
View File
@@ -1,124 +0,0 @@
package core.cache.crypto;
import java.nio.ByteBuffer;
/**
* Holds XTEA cryption methods.
* @author ?
* @author Emperor
*/
public final class XTEACryption {
/**
* The delta value
*/
private static final int DELTA = -1640531527;
/**
* The sum.
*/
private static final int SUM = -957401312;
/**
* The amount of "cryption cycles".
*/
private static final int NUM_ROUNDS = 32;
/**
* Constructs a new {@code XTEACryption}.
*/
private XTEACryption() {
/*
* empty.
*/
}
/**
* Decrypts the contents of the buffer.
* @param keys The cryption keys.
* @param buffer The buffer.
*/
public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer) {
return decrypt(keys, buffer, buffer.position(), buffer.limit());
}
/**
* Decrypts the buffer data.
* @param keys The keys.
* @param buffer The buffer to decrypt.
* @param offset The offset of the data to decrypt.
* @param length The length.
* @return The decrypted data.
*/
public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer, int offset, int length) {
int numBlocks = (length - offset) / 8;
int[] block = new int[2];
for (int i = 0; i < numBlocks; i++) {
int index = i * 8 + offset;
block[0] = buffer.getInt(index);
block[1] = buffer.getInt(index + 4);
decipher(keys, block);
buffer.putInt(index, block[0]);
buffer.putInt(index + 4, block[1]);
}
return buffer;
}
/**
* Deciphers the values.
* @param keys The cryption key.
* @param block The values to decipher.
*/
private static void decipher(int[] keys, int[] block) {
long sum = SUM;
for (int i = 0; i < NUM_ROUNDS; i++) {
block[1] -= (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5));
sum -= DELTA;
block[0] -= ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum);
}
}
/**
* Encrypts the contents of the byte buffer.
* @param keys The cryption keys.
* @param buffer The buffer to encrypt.
*/
public static void encrypt(int[] keys, ByteBuffer buffer) {
encrypt(keys, buffer, buffer.position(), buffer.limit());
}
/**
* Encrypts the buffer data.
* @param keys The keys.
* @param buffer The buffer to encrypt.
* @param offset The offset of the data to encrypt.
* @param length The length.
* @return The encrypted data.
*/
public static void encrypt(int[] keys, ByteBuffer buffer, int offset, int length) {
int numBlocks = (length - offset) / 8;
int[] block = new int[2];
for (int i = 0; i < numBlocks; i++) {
int index = i * 8 + offset;
block[0] = buffer.getInt(index);
block[1] = buffer.getInt(index + 4);
encipher(keys, block);
buffer.putInt(index, block[0]);
buffer.putInt(index + 4, block[1]);
}
}
/**
* Enciphers the values of the block.
* @param keys The cryption keys.
* @param block The block to encipher.
*/
private static void encipher(int[] keys, int[] block) {
long sum = 0;
for (int i = 0; i < NUM_ROUNDS; i++) {
block[0] += ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum);
sum += DELTA;
block[1] += (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5));
}
}
}
+97
View File
@@ -0,0 +1,97 @@
package core.cache.crypto
import java.nio.ByteBuffer
/** Holds XTEA(eXtended Tiny Encryption Algorithm) encryption/decryption methods. Usually used for RS Map decryption. */
class XTEACryption {
companion object {
// Purely Static Class
// XTEA consts https://scispace.com/pdf/xtea-cryptography-implementation-in-android-chatting-app-3pg6ownewx.pdf
/** Fibonacci hashing. Math.pow(2,32) * Math.sqrt(5)-1)/2 => 32 bits(int) multiply by reciprocal of golden ratio. */
private const val DELTA = -1640531527 // Formula cast to unsigned int.
/** DELTA << 5. Essentially multiply DELTA by NUM_ROUNDS or number of rounds. */
private const val SUM = -957401312 // 0xC6EF3720
/** The amount of "cryption cycles". */
private const val NUM_ROUNDS = 32
/** Constant to manipulate the key index in decipher/encrypt. This was a magic number randomly selected by RS. */
private const val KEY_SCRAMBLE = 0x1933
/**
* Decrypts the buffer data.
* @param keys The keys.
* @param buffer The buffer to decrypt.
* @param offset The offset of the data to decrypt.
* @param length The length.
* @return The decrypted data.
*/
fun decrypt(keys: IntArray, buffer: ByteBuffer, offset: Int, length: Int): ByteBuffer {
val numBlocks = (length - offset) / 8
val block = IntArray(2)
for (i in 0 until numBlocks) {
val index = i * 8 + offset
block[0] = buffer.getInt(index)
block[1] = buffer.getInt(index + 4)
decipher(keys, block)
buffer.putInt(index, block[0])
buffer.putInt(index + 4, block[1])
}
return buffer
}
/**
* Deciphers the values of the block using the Tiny Encryption Algorithm (TEA).
* This algorithm relies on a Feistel network, using bitwise operations and
* modular subtraction to remove confusion(block[0] line) and diffusion(block[1] line).
*
* @param keys 128-bit key (4x32-bit int).
* @param block 64-bit data block (2x32-bit int) to be decrypted.
*/
private fun decipher(keys: IntArray, block: IntArray) {
var sum =
SUM.toLong() // Running decreasing sum to ensure different round constants - should become 0 at the end.
for (i in 0 until NUM_ROUNDS) {
block[1] -= (keys[(sum and KEY_SCRAMBLE.toLong() ushr 11).toInt()] + sum xor (block[0] + (block[0] shl 4 xor (block[0] ushr 5))).toLong()).toInt()
sum -= DELTA.toLong()
block[0] -= (((block[1] shl 4 xor (block[1] ushr 5)) + block[1]).toLong() xor keys[(sum and 0x3L).toInt()] + sum).toInt()
}
}
/** === Encryption functions below are not used unless you are modifying the cache. === */
/**
* Encrypts the buffer data.
* @param keys The keys.
* @param buffer The buffer to encrypt.
* @param offset The offset of the data to encrypt.
* @param length The length.
* @return The encrypted data.
*/
fun encrypt(keys: IntArray, buffer: ByteBuffer, offset: Int, length: Int) {
val numBlocks = (length - offset) / 8
val block = IntArray(2)
for (i in 0 until numBlocks) {
val index = i * 8 + offset
block[0] = buffer.getInt(index)
block[1] = buffer.getInt(index + 4)
encipher(keys, block)
buffer.putInt(index, block[0])
buffer.putInt(index + 4, block[1])
}
}
/**
* Enciphers the values of the block using the Tiny Encryption Algorithm (TEA).
* This algorithm relies on a Feistel network, using bitwise operations and
* modular addition to provide confusion(block[0] line) and diffusion(block[1] line).
*
* @param keys 128-bit key (4x32-bit int).
* @param block 64-bit data block (2x32-bit int) to be encrypted.
*/
private fun encipher(keys: IntArray, block: IntArray) {
var sum: Long = 0 // Running sum to ensure different round constants - should match SUM at the end.
for (i in 0 until NUM_ROUNDS) {
block[0] += (((block[1] shl 4 xor (block[1] ushr 5)) + block[1]).toLong() xor keys[(sum and 0x3L).toInt()] + sum).toInt()
sum += DELTA.toLong()
block[1] += (keys[(sum and KEY_SCRAMBLE.toLong() ushr 11).toInt()] + sum xor (block[0] + (block[0] shl 4 xor (block[0] ushr 5))).toLong()).toInt()
}
}
}
}
-109
View File
@@ -1,109 +0,0 @@
package core.cache.misc;
/**
* A container.
* @author Dragonkk
*/
public class Container {
/**
* The version.
*/
private int version;
/**
* The CRC.
*/
private int crc;
/**
* The name hash.
*/
private int nameHash;
/**
* If updated.
*/
private boolean updated;
/**
* Construct a new container.
*/
public Container() {
nameHash = -1;
version = -1;
crc = -1;
}
/**
* Set the version.
* @param version
*/
public void setVersion(int version) {
this.version = version;
}
/**
* Update the version.
*/
public void updateVersion() {
version++;
updated = true;
}
/**
* Get the version.
* @return The version.
*/
public int getVersion() {
return version;
}
/**
* Get the next version.
* @return The next version.
*/
public int getNextVersion() {
return updated ? version : version + 1;
}
/**
* Set the CRC.
* @param crc The cRC.
*/
public void setCrc(int crc) {
this.crc = crc;
}
/**
* Get the CRC.
* @return The CRC.
*/
public int getCrc() {
return crc;
}
/**
* Set the name hash.
* @param nameHash The name hash.
*/
public void setNameHash(int nameHash) {
this.nameHash = nameHash;
}
/**
* Get the name hash.
* @return The name hash.
*/
public int getNameHash() {
return nameHash;
}
/**
* If is updated.
* @return If is updated.
*/
public boolean isUpdated() {
return updated;
}
}
+7
View File
@@ -0,0 +1,7 @@
package core.cache.misc
data class Container(
var version: Int = -1,
var crc: Int = -1,
var nameHash: Int = -1
)
@@ -1,228 +0,0 @@
package core.cache.misc;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.CRC32;
import core.cache.bzip2.BZip2Decompressor;
import core.cache.gzip.GZipDecompressor;
/**
* A class holding the containers information.
* @author Dragonkk
*/
public final class ContainersInformation {
/**
* The information container.
*/
private Container informationContainer;
/**
* The protocol.
*/
private int protocol;
/**
* The revision.
*/
private int revision;
/**
* The container indexes.
*/
private int[] containersIndexes;
/**
* The containers.
*/
private FilesContainer[] containers;
/**
* If files have to be named.
*/
private boolean filesNamed;
/**
* If it has to be whirpool.
*/
private boolean whirpool;
/**
* The data.
*/
private final byte[] data;
/**
* Construct a new containers information.
* @param informationContainerPackedData The information container data
* packed.
*/
public ContainersInformation(byte[] informationContainerPackedData) {
this.data = Arrays.copyOf(informationContainerPackedData, informationContainerPackedData.length);
informationContainer = new Container();
informationContainer.setVersion((informationContainerPackedData[informationContainerPackedData.length - 2] << 8 & 0xff00) + (informationContainerPackedData[-1 + informationContainerPackedData.length] & 0xff));
CRC32 crc32 = new CRC32();
crc32.update(informationContainerPackedData);
informationContainer.setCrc((int) crc32.getValue());
decodeContainersInformation(unpackCacheContainer(informationContainerPackedData));
}
/**
* Unpacks a container.
* @param packedData The packed container data.
* @return The unpacked data.
*/
public static final byte[] unpackCacheContainer(byte[] packedData) {
ByteBuffer buffer = ByteBuffer.wrap(packedData);
int compression = buffer.get() & 0xFF;
int containerSize = buffer.getInt();
if (containerSize < 0 || containerSize > 5000000) {
return null;
// throw new RuntimeException();
}
if (compression == 0) {
byte unpacked[] = new byte[containerSize];
buffer.get(unpacked, 0, containerSize);
return unpacked;
}
int decompressedSize = buffer.getInt();
if (decompressedSize < 0 || decompressedSize > 20000000) {
return null;
// throw new RuntimeException();
}
byte decompressedData[] = new byte[decompressedSize];
if (compression == 1) {
BZip2Decompressor.decompress(decompressedData, packedData, containerSize, 9);
} else {
GZipDecompressor.decompress(buffer, decompressedData);
}
return decompressedData;
}
/**
* Get the container indexes.
* @return The container indexes.
*/
public int[] getContainersIndexes() {
return containersIndexes;
}
/**
* Get the containers.
* @return The containers.
*/
public FilesContainer[] getContainers() {
return containers;
}
/**
* Get the information container.
* @return The information container.
*/
public Container getInformationContainer() {
return informationContainer;
}
/**
* Get the revision.
* @return The revision.
*/
public int getRevision() {
return revision;
}
/**
* Decode the containers information.
* @param data The data.
*/
public void decodeContainersInformation(byte[] data) {
ByteBuffer buffer = ByteBuffer.wrap(data);
protocol = buffer.get() & 0xFF;
if (protocol != 5 && protocol != 6) {
throw new RuntimeException();
}
revision = protocol < 6 ? 0 : buffer.getInt();
int nameHash = buffer.get() & 0xFF;
filesNamed = (0x1 & nameHash) != 0;
whirpool = (0x2 & nameHash) != 0;
containersIndexes = new int[buffer.getShort() & 0xFFFF];
int lastIndex = -1;
for (int index = 0; index < containersIndexes.length; index++) {
containersIndexes[index] = (buffer.getShort() & 0xFFFF) + (index == 0 ? 0 : containersIndexes[index - 1]);
if (containersIndexes[index] > lastIndex) {
lastIndex = containersIndexes[index];
}
}
containers = new FilesContainer[lastIndex + 1];
for (int index = 0; index < containersIndexes.length; index++) {
containers[containersIndexes[index]] = new FilesContainer();
}
if (filesNamed) {
for (int index = 0; index < containersIndexes.length; index++) {
containers[containersIndexes[index]].setNameHash(buffer.getInt());
}
}
byte[][] filesHashes = null;
if (whirpool) {
filesHashes = new byte[containers.length][];
for (int index = 0; index < containersIndexes.length; index++) {
filesHashes[containersIndexes[index]] = new byte[64];
buffer.get(filesHashes[containersIndexes[index]], 0, 64);
}
}
for (int index = 0; index < containersIndexes.length; index++) {
containers[containersIndexes[index]].setCrc(buffer.getInt());
}
for (int index = 0; index < containersIndexes.length; index++) {
containers[containersIndexes[index]].setVersion(buffer.getInt());
}
for (int index = 0; index < containersIndexes.length; index++) {
containers[containersIndexes[index]].setFilesIndexes(new int[buffer.getShort() & 0xFFFF]);
}
for (int index = 0; index < containersIndexes.length; index++) {
int lastFileIndex = -1;
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
containers[containersIndexes[index]].getFilesIndexes()[fileIndex] = (buffer.getShort() & 0xFFFF) + (fileIndex == 0 ? 0 : containers[containersIndexes[index]].getFilesIndexes()[fileIndex - 1]);
if (containers[containersIndexes[index]].getFilesIndexes()[fileIndex] > lastFileIndex) {
lastFileIndex = containers[containersIndexes[index]].getFilesIndexes()[fileIndex];
}
}
containers[containersIndexes[index]].setFiles(new Container[lastFileIndex + 1]);
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]] = new Container();
}
}
if (whirpool) {
for (int index = 0; index < containersIndexes.length; index++) {
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setVersion(filesHashes[containersIndexes[index]][containers[containersIndexes[index]].getFilesIndexes()[fileIndex]]);
}
}
}
if (filesNamed) {
for (int index = 0; index < containersIndexes.length; index++) {
for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) {
containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setNameHash(buffer.getInt());
}
}
}
}
/**
* If is whirpool.
* @return If is whirpool {@code true}.
*/
public boolean isWhirpool() {
return whirpool;
}
/**
* Gets the data.
* @return The data.
*/
public byte[] getData() {
return data;
}
}
+145
View File
@@ -0,0 +1,145 @@
package core.cache.misc
import core.cache.bzip2.BZip2Decompressor
import core.cache.gzip.GZipDecompressor
import java.nio.ByteBuffer
import java.util.*
import java.util.zip.CRC32
class ContainersInformation(informationContainerPackedData: ByteArray) {
@JvmField
val informationContainer: Container
private var protocol = 0
var revision = 0
var containersIndexes: IntArray = intArrayOf()
var containers: Array<FilesContainer?> = arrayOf()
private var filesNamed = false // If files has to be named
private var whirpool = false // Flag for whirpool
val data: ByteArray
init {
data = Arrays.copyOf(informationContainerPackedData, informationContainerPackedData.size)
informationContainer = Container()
informationContainer.version =
(informationContainerPackedData[informationContainerPackedData.size - 2].toInt() shl 8 and 0xff00) + (informationContainerPackedData[-1 + informationContainerPackedData.size].toInt() and 0xff)
val crc32 = CRC32()
crc32.update(informationContainerPackedData)
informationContainer.crc = crc32.value.toInt()
decodeContainersInformation(unpackCacheContainer(informationContainerPackedData))
}
fun decodeContainersInformation(data: ByteArray?) {
val buffer = ByteBuffer.wrap(data)
protocol = buffer.get().toInt() and 0xFF
if (protocol != 5 && protocol != 6) {
throw RuntimeException()
}
revision = if (protocol < 6) 0 else buffer.getInt()
val nameHash = buffer.get().toInt() and 0xFF
filesNamed = 0x1 and nameHash != 0
whirpool = 0x2 and nameHash != 0
containersIndexes = IntArray(buffer.getShort().toInt() and 0xFFFF)
var lastIndex = -1
for (index in containersIndexes.indices) {
val containerIndex =
(buffer.getShort().toInt() and 0xFFFF) + if (index == 0) 0 else containersIndexes[index - 1]
containersIndexes[index] = containerIndex
if (containerIndex > lastIndex) {
lastIndex = containerIndex
}
}
containers = arrayOfNulls(lastIndex + 1)
for (containerIdx in containersIndexes) {
containers[containerIdx] = FilesContainer()
}
if (filesNamed) {
for (containerIdx in containersIndexes) {
containers[containerIdx]!!.nameHash = buffer.getInt()
}
}
var filesHashes: Array<ByteArray?>? = null
if (whirpool) {
filesHashes = arrayOfNulls(containers.size)
for (containerIdx in containersIndexes) {
filesHashes[containerIdx] = ByteArray(64)
buffer[filesHashes[containerIdx], 0, 64]
}
}
for (containerIdx in containersIndexes) {
containers[containerIdx]!!.crc = buffer.getInt()
}
for (containerIdx in containersIndexes) {
containers[containerIdx]!!.version = buffer.getInt()
}
for (containerIdx in containersIndexes) {
containers[containerIdx]!!.filesIndexes = IntArray(buffer.getShort().toInt() and 0xFFFF)
}
for (containerIdx in containersIndexes) {
val container = containers[containerIdx]
val filesIndexes = container!!.filesIndexes
var lastFileIndex = -1
for (fileIndex in filesIndexes!!.indices) {
val fileIdx =
(buffer.getShort().toInt() and 0xFFFF) + if (fileIndex == 0) 0 else filesIndexes[fileIndex - 1]
filesIndexes[fileIndex] = fileIdx
if (fileIdx > lastFileIndex) {
lastFileIndex = fileIdx
}
}
val files = arrayOfNulls<Container>(lastFileIndex + 1)
container.files = files
for (fileIdx in filesIndexes) {
files[fileIdx] = Container()
}
}
if (whirpool) {
for (containerIdx in containersIndexes) {
val container = containers[containerIdx]
val containerHashes = filesHashes!![containerIdx]
val files = container!!.files
for (fileIdx in container.filesIndexes!!) {
files!![fileIdx]!!.version = containerHashes!![fileIdx].toInt()
}
}
}
if (filesNamed) {
for (containerIdx in containersIndexes) {
val container = containers[containerIdx]
val files = container!!.files
for (fileIdx in container.filesIndexes!!) {
files!![fileIdx]!!.nameHash = buffer.getInt()
}
}
}
}
companion object {
@JvmStatic
fun unpackCacheContainer(packedData: ByteArray?): ByteArray? {
val buffer = ByteBuffer.wrap(packedData)
val compression = buffer.get().toInt() and 0xFF
val containerSize = buffer.getInt()
if (containerSize < 0 || containerSize > 5000000) {
return null
// throw new RuntimeException();
}
if (compression == 0) {
val unpacked = ByteArray(containerSize)
buffer[unpacked, 0, containerSize]
return unpacked
}
val decompressedSize = buffer.getInt()
if (decompressedSize < 0 || decompressedSize > 20000000) {
return null
// throw new RuntimeException();
}
val decompressedData = ByteArray(decompressedSize)
if (compression == 1) {
BZip2Decompressor.decompress(decompressedData, packedData, containerSize, 9)
} else {
GZipDecompressor.decompress(buffer, decompressedData)
}
return decompressedData
}
}
}
-57
View File
@@ -1,57 +0,0 @@
package core.cache.misc;
/**
* A class holding the file containers.
* @author Dragonkk
*/
public final class FilesContainer extends Container {
/**
* The file indexes.
*/
private int[] filesIndexes;
/**
* The files.
*/
private Container[] files;
/**
* Construct a new files container.
*/
public FilesContainer() {
}
/**
* Set the files.
* @param containers The files.
*/
public void setFiles(Container[] containers) {
this.files = containers;
}
/**
* Get the files.
* @return The files.
*/
public Container[] getFiles() {
return files;
}
/**
* Set the file indexes.
* @param containersIndexes The file indexes.
*/
public void setFilesIndexes(int[] containersIndexes) {
this.filesIndexes = containersIndexes;
}
/**
* Get the file indexes.
* @return The file indexes.
*/
public int[] getFilesIndexes() {
return filesIndexes;
}
}
+9
View File
@@ -0,0 +1,9 @@
package core.cache.misc
data class FilesContainer(
var version: Int = -1,
var crc: Int = -1,
var nameHash: Int = -1,
var filesIndexes: IntArray? = null,
var files: Array<Container?>? = null
)
@@ -1,39 +0,0 @@
package core.cache.misc.buffer;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
/**
* Handles the reading of data from a byte buffer.
* @author Emperor
*/
public final class BufferInputStream extends InputStream {
/**
* The buffer to write on.
*/
private final ByteBuffer buffer;
/**
* The buffer input stream.
* @param buffer The buffer.
*/
public BufferInputStream(ByteBuffer buffer) throws IOException {
this.buffer = buffer;
}
@Override
public int read() throws IOException {
return buffer.get();
}
/**
* Gets the buffer.
* @return The buffer.
*/
public ByteBuffer getBuffer() {
return buffer;
}
}
@@ -1,57 +0,0 @@
package core.cache.misc.buffer;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* Handles the writing of data on a byte buffer.
* @author Emperor
*/
public final class BufferOutputStream extends OutputStream {
/**
* The buffer to write on.
*/
private final ByteBuffer buffer;
/**
* Constructs a new {@code BufferOutputStream} {@code Object}.
* @param buffer The buffer to write on.
* @throws IOException When an I/O exception occurs.
* @throws SecurityException If a security manager exists and its
* checkPermission method denies enabling subclassing.
*/
public BufferOutputStream(ByteBuffer buffer) throws IOException, SecurityException {
super();
this.buffer = buffer;
}
@Override
public void write(int b) throws IOException {
buffer.put((byte) b);
}
@Override
public void flush() {
/*
* empty.
*/
}
@Override
public void close() {
/*
* empty.
*/
}
/**
* Gets the buffer.
* @return The buffer.
*/
public ByteBuffer getBuffer() {
return buffer;
}
}
@@ -1,182 +0,0 @@
package core.cache.misc.buffer;
import java.io.ObjectInputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
/**
* Holds utility methods for reading/writing a byte buffer.
* @author Emperor
*/
public final class ByteBufferUtils {
/**
* Gets a string from the byte buffer.
* @param buffer The byte buffer.
* @return The string.
*/
public static String getString(ByteBuffer buffer) {
StringBuilder sb = new StringBuilder();
byte b;
while ((b = buffer.get()) != 0) {
sb.append((char) b);
}
return sb.toString();
}
/**
* Puts a string on the byte buffer.
* @param s The string to put.
* @param buffer The byte buffer.
*/
public static void putString(String s, ByteBuffer buffer) {
buffer.put(s.getBytes(StandardCharsets.UTF_8)).put((byte) 0);
}
/**
* Gets a string from the byte buffer.
* @param s The string.
* @param buffer The byte buffer.
* @return The string.
*/
public static ByteBuffer putGJ2String(String s, ByteBuffer buffer) {
byte[] packed = new byte[256];
int length = packGJString2(0, packed, s);
return buffer.put((byte) 0).put(packed, 0, length).put((byte) 0);
}
/**
* Decodes the XTEA encryption.
* @param keys The keys.
* @param start The start index.
* @param end The end index.
* @param buffer The byte buffer.
*/
public static void decodeXTEA(int[] keys, int start, int end, ByteBuffer buffer) {
int l = buffer.position();
buffer.position(start);
int length = (end - start) / 8;
for (int i = 0; i < length; i++) {
int firstInt = buffer.getInt();
int secondInt = buffer.getInt();
int sum = 0xc6ef3720;
int delta = 0x9e3779b9;
for (int j = 32; j-- > 0;) {
secondInt -= keys[(sum & 0x1c84) >>> 11] + sum ^ (firstInt >>> 5 ^ firstInt << 4) + firstInt;
sum -= delta;
firstInt -= (secondInt >>> 5 ^ secondInt << 4) + secondInt ^ keys[sum & 3] + sum;
}
buffer.position(buffer.position() - 8);
buffer.putInt(firstInt);
buffer.putInt(secondInt);
}
buffer.position(l);
}
/**
* Converts a String to an Integer?
* @param position The position.
* @param buffer The buffer used.
* @param string The String to convert.
* @return The Integer.
*/
public static int packGJString2(int position, byte[] buffer, String string) {
int length = string.length();
int offset = position;
for (int i = 0; length > i; i++) {
int character = string.charAt(i);
if (character > 127) {
if (character > 2047) {
buffer[offset++] = (byte) ((character | 919275) >> 12);
buffer[offset++] = (byte) (128 | ((character >> 6) & 63));
buffer[offset++] = (byte) (128 | (character & 63));
} else {
buffer[offset++] = (byte) ((character | 12309) >> 6);
buffer[offset++] = (byte) (128 | (character & 63));
}
} else
buffer[offset++] = (byte) character;
}
return offset - position;
}
/**
* Gets a tri-byte from the buffer.
* @param buffer The buffer.
* @return The value.
*/
public static int getMedium(ByteBuffer buffer) {
return ((buffer.get() & 0xFF) << 16) + ((buffer.get() & 0xFF) << 8) + (buffer.get() & 0xFF);
}
/**
* Gets a smart from the buffer.
* @param buffer The buffer.
* @return The value.
*/
public static int getSmart(ByteBuffer buffer) {
int peek = buffer.get() & 0xFF;
if (peek <= Byte.MAX_VALUE) {
return peek;
}
return ((peek << 8) | (buffer.get() & 0xFF)) - 32768;
}
/**
* Gets a smart from the buffer.
* @param buffer The buffer.
* @return The value.
*/
public static int getBigSmart(ByteBuffer buffer) {
int value = 0;
int current = getSmart(buffer);
while (current == 32767) {
current = getSmart(buffer);
value += 32767;
}
value += current;
return value;
}
/* *//**
* Writes an object on the buffer.
* @param buffer The buffer to write on.
* @param o The object.
*/
/*
* public static void putObject(ByteBuffer buffer, Object o) { ByteBuffer b;
* try (ObjectOutputStream out = new ObjectOutputStream(new
* BufferOutputStream(b = ByteBuffer.allocate(99999)))) {
* out.writeObject(o); b.flip(); } catch (Throwable e) {
* e.printStackTrace(); b = (ByteBuffer) ByteBuffer.allocate(0).flip(); }
* buffer.putInt(b.remaining()); if (b.remaining() > 0) { buffer.put(b); } }
*/
/**
* Gets an object from the byte buffer.
* @param buffer The buffer.
* @return The object.
*/
public static Object getObject(ByteBuffer buffer) {
int length = buffer.getInt();
if (length > 0) {
byte[] bytes = new byte[length];
buffer.get(bytes);
try (ObjectInputStream str = new ObjectInputStream(new BufferInputStream(ByteBuffer.wrap(bytes)))) {
return (Object) str.readObject();
} catch (Throwable e) {
e.printStackTrace();
}
}
return null;
}
/**
* Constructs a new {@code ByteBufferUtils} {@code Object}.
*/
private ByteBufferUtils() {
/*
* empty.
*/
}
}
@@ -0,0 +1,142 @@
package core.cache.misc.buffer
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
object ByteBufferUtils {
/**
* Gets a string from the byte buffer.
* @param buffer The byte buffer.
* @return The string.
*/
@JvmStatic
fun getString(buffer: ByteBuffer): String {
val sb = StringBuilder()
var b: Byte
while (buffer.get().also { b = it }.toInt() != 0) {
sb.append(Char(b.toUShort()))
}
return sb.toString()
}
/**
* Puts a string on the byte buffer.
* @param s The string to put.
* @param buffer The byte buffer.
*/
@JvmStatic
fun putString(s: String, buffer: ByteBuffer) {
buffer.put(s.toByteArray(StandardCharsets.UTF_8)).put(0.toByte())
}
/**
* Gets a string from the byte buffer.
* @param s The string.
* @param buffer The byte buffer.
* @return The string.
*/
fun putGJ2String(s: String, buffer: ByteBuffer): ByteBuffer {
val packed = ByteArray(256)
val length = packGJString2(0, packed, s)
return buffer.put(0.toByte()).put(packed, 0, length).put(0.toByte())
}
/**
* Decodes the XTEA encryption.
* @param keys The keys.
* @param start The start index.
* @param end The end index.
* @param buffer The byte buffer.
*/
fun decodeXTEA(keys: IntArray, start: Int, end: Int, buffer: ByteBuffer) {
val l = buffer.position()
buffer.position(start)
val length = (end - start) / 8
for (i in 0 until length) {
var firstInt = buffer.getInt()
var secondInt = buffer.getInt()
var sum = -0x3910c8e0
val delta = -0x61c88647
var j = 32
while (j-- > 0) {
secondInt -= keys[sum and 0x1c84 ushr 11] + sum xor (firstInt ushr 5 xor (firstInt shl 4)) + firstInt
sum -= delta
firstInt -= (secondInt ushr 5 xor (secondInt shl 4)) + secondInt xor keys[sum and 3] + sum
}
buffer.position(buffer.position() - 8)
buffer.putInt(firstInt)
buffer.putInt(secondInt)
}
buffer.position(l)
}
/**
* Converts a String to an Integer?
* @param position The position.
* @param buffer The buffer used.
* @param string The String to convert.
* @return The Integer.
*/
@JvmStatic
fun packGJString2(position: Int, buffer: ByteArray, string: String): Int {
val length = string.length
var offset = position
var i = 0
while (length > i) {
val character = string[i].code
if (character > 127) {
if (character > 2047) {
buffer[offset++] = (character or 919275 shr 12).toByte()
buffer[offset++] = (128 or (character shr 6 and 63)).toByte()
buffer[offset++] = (128 or (character and 63)).toByte()
} else {
buffer[offset++] = (character or 12309 shr 6).toByte()
buffer[offset++] = (128 or (character and 63)).toByte()
}
} else buffer[offset++] = character.toByte()
i++
}
return offset - position
}
/**
* Gets a tri-byte from the buffer.
* @param buffer The buffer.
* @return The value.
*/
@JvmStatic
fun getMedium(buffer: ByteBuffer): Int {
return (buffer.get().toInt() and 0xFF shl 16) + (buffer.get().toInt() and 0xFF shl 8) + (buffer.get()
.toInt() and 0xFF)
}
/**
* Gets a smart from the buffer.
* @param buffer The buffer.
* @return The value.
*/
@JvmStatic
fun getSmart(buffer: ByteBuffer): Int {
val peek = buffer.get().toInt() and 0xFF
return if (peek <= Byte.MAX_VALUE) {
peek
} else (peek shl 8 or (buffer.get().toInt() and 0xFF)) - 32768
}
/**
* Gets a smart from the buffer.
* @param buffer The buffer.
* @return The value.
*/
@JvmStatic
fun getBigSmart(buffer: ByteBuffer): Int {
var value = 0
var current = getSmart(buffer)
while (current == 32767) {
current = getSmart(buffer)
value += 32767
}
value += current
return value
}
}
@@ -190,15 +190,16 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
val dump = File("structs.txt")
val writer = BufferedWriter(FileWriter(dump))
val index = Cache.getIndexes()[2]
val containers = index.information.containers[26].filesIndexes
for(fID in containers)
{
val file = index.getFileData(26, fID)
if(file != null){
val def = Struct.parse(fID, file)
if(def.dataStore.isEmpty()) continue //no data in struct.
writer.write(def.toString())
writer.newLine()
val containers = index.information.containers[26]!!.filesIndexes
if (containers != null) {
for(fID in containers) {
val file = index.getFileData(26, fID)
if(file != null){
val def = Struct.parse(fID, file)
if(def.dataStore.isEmpty()) continue //no data in struct.
writer.write(def.toString())
writer.newLine()
}
}
}
writer.flush()
@@ -214,15 +215,16 @@ class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) {
for(cID in containers)
{
val fileIndexes = index.information.containers[cID].filesIndexes
for(fID in fileIndexes)
{
val file = index.getFileData(cID, fID)
if(file != null){
val def = DataMap.parse((cID shl 8) or fID, file)
if(def.keyType == '?') continue //Empty definition - only a 0 present in the cachefile data.
writer.write(def.toString())
writer.newLine()
val fileIndexes = index.information.containers[cID]!!.filesIndexes
if (fileIndexes != null) {
for(fID in fileIndexes) {
val file = index.getFileData(cID, fID)
if(file != null){
val def = DataMap.parse((cID shl 8) or fID, file)
if(def.keyType == '?') continue //Empty definition - only a 0 present in the cachefile data.
writer.write(def.toString())
writer.newLine()
}
}
}
}