Update #0 - First Release

This commit is contained in:
LAX1DUDE
2022-12-25 01:12:28 -08:00
commit e7179fad45
2154 changed files with 256324 additions and 0 deletions

View File

@ -0,0 +1,55 @@
package net.lax1dude.eaglercraft.v1_8;
import net.minecraft.client.settings.KeyBinding;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class ArrayUtils {
public static KeyBinding[] clone(KeyBinding[] keyBinding) {
KeyBinding[] clone = new KeyBinding[keyBinding.length];
System.arraycopy(keyBinding, 0, clone, 0, keyBinding.length);
return clone;
}
public static KeyBinding[] addAll(KeyBinding[] arr1, KeyBinding[] arr2) {
KeyBinding[] clone = new KeyBinding[arr1.length + arr2.length];
System.arraycopy(arr1, 0, clone, 0, arr1.length);
System.arraycopy(arr2, 0, clone, arr1.length, arr2.length);
return clone;
}
public static String[] subarray(String[] stackTrace, int i, int j) {
String[] ret = new String[j - i];
System.arraycopy(stackTrace, i, ret, 0, j - i);
return ret;
}
public static String asciiString(byte[] bytes) {
char[] str = new char[bytes.length];
for(int i = 0; i < bytes.length; ++i) {
str[i] = (char)((int) bytes[i] & 0xFF);
}
return new String(str);
}
public static byte[] asciiString(String string) {
byte[] str = new byte[string.length()];
for(int i = 0; i < str.length; ++i) {
str[i] = (byte)string.charAt(i);
}
return str;
}
}

View File

@ -0,0 +1,857 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.lax1dude.eaglercraft.v1_8;
import java.math.BigInteger;
import java.nio.charset.Charset;
/**
* Provides Base64 encoding and decoding as defined by
* <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>.
*
* <p>
* This class implements section <cite>6.8. Base64
* Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose Internet
* Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by
* Freed and Borenstein.
* </p>
* <p>
* The class can be parameterized in the following manner with various
* constructors:
* </p>
* <ul>
* <li>URL-safe mode: Default off.</li>
* <li>Line length: Default 76. Line length that aren't multiples of 4 will
* still essentially end up being multiples of 4 in the encoded data.
* <li>Line separator: Default is CRLF ("\r\n")</li>
* </ul>
* <p>
* The URL-safe parameter is only applied to encode operations. Decoding
* seamlessly handles both modes.
* </p>
* <p>
* Since this class operates directly on byte streams, and not character
* streams, it is hard-coded to only encode/decode character encodings which are
* compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8,
* etc).
* </p>
* <p>
* This class is thread-safe.
* </p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
* @since 1.0
*/
public class Base64 extends BaseNCodec {
/**
* BASE32 characters are 6 bits in length. They are formed by taking a block of
* 3 octets to form a 24-bit string, which is converted into 4 BASE64
* characters.
*/
private static final int BITS_PER_ENCODED_BYTE = 6;
private static final int BYTES_PER_UNENCODED_BLOCK = 3;
private static final int BYTES_PER_ENCODED_BLOCK = 4;
/**
* This array is a lookup table that translates 6-bit positive integer index
* values into their "Base64 Alphabet" equivalents as specified in Table 1 of
* RFC 2045.
*
* Thanks to "commons" project in ws.apache.org for this code.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
*/
private static final byte[] STANDARD_ENCODE_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
'2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };
/**
* This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / changed
* to - and _ to make the encoded Base64 results more URL-SAFE. This table is
* only used when the Base64's mode is set to URL-SAFE.
*/
private static final byte[] URL_SAFE_ENCODE_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
'2', '3', '4', '5', '6', '7', '8', '9', '-', '_' };
/**
* This array is a lookup table that translates Unicode characters drawn from
* the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) into their 6-bit
* positive integer equivalents. Characters that are not in the Base64 alphabet
* but fall within the bounds of the array are translated to -1.
*
* Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This
* means decoder seamlessly handles both URL_SAFE and STANDARD base64. (The
* encoder, on the other hand, needs to know ahead of time what to emit).
*
* Thanks to "commons" project in ws.apache.org for this code.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
*/
private static final byte[] DECODE_TABLE = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00-0f
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-1f
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, // 20-2f + - /
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 30-3f 0-9
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 40-4f A-O
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63, // 50-5f P-Z _
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 60-6f a-o
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 // 70-7a p-z
};
/**
* Base64 uses 6-bit fields.
*/
/** Mask used to extract 6 bits, used when encoding */
private static final int MASK_6BITS = 0x3f;
/** Mask used to extract 4 bits, used when decoding final trailing character. */
private static final int MASK_4BITS = 0xf;
/** Mask used to extract 2 bits, used when decoding final trailing character. */
private static final int MASK_2BITS = 0x3;
// The static final fields above are used for the original static byte[] methods
// on Base64.
// The private member fields below are used with the new streaming approach,
// which requires
// some state be preserved between calls of encode() and decode().
/**
* Decodes Base64 data into octets.
* <p>
* <b>Note:</b> this method seamlessly handles data encoded in URL-safe or
* normal mode.
* </p>
*
* @param base64Data Byte array containing Base64 data
* @return Array containing decoded data.
*/
public static byte[] decodeBase64(final byte[] base64Data) {
return new Base64().decode(base64Data);
}
/**
* Decodes a Base64 String into octets.
* <p>
* <b>Note:</b> this method seamlessly handles data encoded in URL-safe or
* normal mode.
* </p>
*
* @param base64String String containing Base64 data
* @return Array containing decoded data.
* @since 1.4
*/
public static byte[] decodeBase64(final String base64String) {
return new Base64().decode(base64String);
}
// Implementation of integer encoding used for crypto
/**
* Decodes a byte64-encoded integer according to crypto standards such as W3C's
* XML-Signature.
*
* @param pArray a byte array containing base64 character data
* @return A BigInteger
* @since 1.4
*/
public static BigInteger decodeInteger(final byte[] pArray) {
return new BigInteger(1, decodeBase64(pArray));
}
/**
* Encodes binary data using the base64 algorithm but does not chunk the output.
*
* @param binaryData binary data to encode
* @return byte[] containing Base64 characters in their UTF-8 representation.
*/
public static byte[] encodeBase64(final byte[] binaryData) {
return encodeBase64(binaryData, false);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the
* output into 76 character blocks.
*
* @param binaryData Array containing binary data to encode.
* @param isChunked if {@code true} this encoder will chunk the base64 output
* into 76 character blocks
* @return Base64-encoded data.
* @throws IllegalArgumentException Thrown when the input array needs an output
* array bigger than {@link Integer#MAX_VALUE}
*/
public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked) {
return encodeBase64(binaryData, isChunked, false);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the
* output into 76 character blocks.
*
* @param binaryData Array containing binary data to encode.
* @param isChunked if {@code true} this encoder will chunk the base64 output
* into 76 character blocks
* @param urlSafe if {@code true} this encoder will emit - and _ instead of
* the usual + and / characters. <b>Note: no padding is added
* when encoding using the URL-safe alphabet.</b>
* @return Base64-encoded data.
* @throws IllegalArgumentException Thrown when the input array needs an output
* array bigger than {@link Integer#MAX_VALUE}
* @since 1.4
*/
public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe) {
return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE);
}
/**
* Encodes binary data using the base64 algorithm, optionally chunking the
* output into 76 character blocks.
*
* @param binaryData Array containing binary data to encode.
* @param isChunked if {@code true} this encoder will chunk the base64
* output into 76 character blocks
* @param urlSafe if {@code true} this encoder will emit - and _ instead
* of the usual + and / characters. <b>Note: no padding is
* added when encoding using the URL-safe alphabet.</b>
* @param maxResultSize The maximum result size to accept.
* @return Base64-encoded data.
* @throws IllegalArgumentException Thrown when the input array needs an output
* array bigger than maxResultSize
* @since 1.4
*/
public static byte[] encodeBase64(final byte[] binaryData, final boolean isChunked, final boolean urlSafe,
final int maxResultSize) {
if (binaryData == null || binaryData.length == 0) {
return binaryData;
}
// Create this so can use the super-class method
// Also ensures that the same roundings are performed by the ctor and the code
final Base64 b64 = isChunked ? new Base64(urlSafe) : new Base64(0, CHUNK_SEPARATOR, urlSafe);
final long len = b64.getEncodedLength(binaryData);
if (len > maxResultSize) {
throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + len
+ ") than the specified maximum size of " + maxResultSize);
}
return b64.encode(binaryData);
}
/**
* Encodes binary data using the base64 algorithm and chunks the encoded output
* into 76 character blocks
*
* @param binaryData binary data to encode
* @return Base64 characters chunked in 76 character blocks
*/
public static byte[] encodeBase64Chunked(final byte[] binaryData) {
return encodeBase64(binaryData, true);
}
/**
* Encodes binary data using the base64 algorithm but does not chunk the output.
*
* NOTE: We changed the behavior of this method from multi-line chunking
* (commons-codec-1.4) to single-line non-chunking (commons-codec-1.5).
*
* @param binaryData binary data to encode
* @return String containing Base64 characters.
* @since 1.4 (NOTE: 1.4 chunked the output, whereas 1.5 does not).
*/
public static String encodeBase64String(final byte[] binaryData) {
return new String(encodeBase64(binaryData, false), Charset.forName("UTF-8"));
}
/**
* Encodes binary data using a URL-safe variation of the base64 algorithm but
* does not chunk the output. The url-safe variation emits - and _ instead of +
* and / characters. <b>Note: no padding is added.</b>
*
* @param binaryData binary data to encode
* @return byte[] containing Base64 characters in their UTF-8 representation.
* @since 1.4
*/
public static byte[] encodeBase64URLSafe(final byte[] binaryData) {
return encodeBase64(binaryData, false, true);
}
/**
* Encodes binary data using a URL-safe variation of the base64 algorithm but
* does not chunk the output. The url-safe variation emits - and _ instead of +
* and / characters. <b>Note: no padding is added.</b>
*
* @param binaryData binary data to encode
* @return String containing Base64 characters
* @since 1.4
*/
public static String encodeBase64URLSafeString(final byte[] binaryData) {
return new String(encodeBase64(binaryData, false, true), Charset.forName("UTF-8"));
}
/**
* Encodes to a byte64-encoded integer according to crypto standards such as
* W3C's XML-Signature.
*
* @param bigInteger a BigInteger
* @return A byte array containing base64 character data
* @throws NullPointerException if null is passed in
* @since 1.4
*/
public static byte[] encodeInteger(final BigInteger bigInteger) {
return encodeBase64(toIntegerBytes(bigInteger), false);
}
/**
* Tests a given byte array to see if it contains only valid characters within
* the Base64 alphabet. Currently the method treats whitespace as valid.
*
* @param arrayOctet byte array to test
* @return {@code true} if all bytes are valid characters in the Base64 alphabet
* or if the byte array is empty; {@code false}, otherwise
* @deprecated 1.5 Use {@link #isBase64(byte[])}, will be removed in 2.0.
*/
@Deprecated
public static boolean isArrayByteBase64(final byte[] arrayOctet) {
return isBase64(arrayOctet);
}
/**
* Returns whether or not the {@code octet} is in the base 64 alphabet.
*
* @param octet The value to test
* @return {@code true} if the value is defined in the the base 64 alphabet,
* {@code false} otherwise.
* @since 1.4
*/
public static boolean isBase64(final byte octet) {
return octet == PAD_DEFAULT || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1);
}
/**
* Tests a given byte array to see if it contains only valid characters within
* the Base64 alphabet. Currently the method treats whitespace as valid.
*
* @param arrayOctet byte array to test
* @return {@code true} if all bytes are valid characters in the Base64 alphabet
* or if the byte array is empty; {@code false}, otherwise
* @since 1.5
*/
public static boolean isBase64(final byte[] arrayOctet) {
for (int i = 0; i < arrayOctet.length; i++) {
if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) {
return false;
}
}
return true;
}
/**
* Tests a given String to see if it contains only valid characters within the
* Base64 alphabet. Currently the method treats whitespace as valid.
*
* @param base64 String to test
* @return {@code true} if all characters in the String are valid characters in
* the Base64 alphabet or if the String is empty; {@code false},
* otherwise
* @since 1.5
*/
public static boolean isBase64(final String base64) {
return isBase64(base64.getBytes(Charset.forName("UTF-8")));
}
/**
* Returns a byte-array representation of a {@code BigInteger} without sign bit.
*
* @param bigInt {@code BigInteger} to be converted
* @return a byte array representation of the BigInteger parameter
*/
static byte[] toIntegerBytes(final BigInteger bigInt) {
int bitlen = bigInt.bitLength();
// round bitlen
bitlen = ((bitlen + 7) >> 3) << 3;
final byte[] bigBytes = bigInt.toByteArray();
if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) {
return bigBytes;
}
// set up params for copying everything but sign bit
int startSrc = 0;
int len = bigBytes.length;
// if bigInt is exactly byte-aligned, just skip signbit in copy
if ((bigInt.bitLength() % 8) == 0) {
startSrc = 1;
len--;
}
final int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec
final byte[] resizedBytes = new byte[bitlen / 8];
System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len);
return resizedBytes;
}
/**
* Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE
* above remains static because it is able to decode both STANDARD and URL_SAFE
* streams, but the encodeTable must be a member variable so we can switch
* between the two modes.
*/
private final byte[] encodeTable;
// Only one decode table currently; keep for consistency with Base32 code
private final byte[] decodeTable = DECODE_TABLE;
/**
* Line separator for encoding. Not used when decoding. Only used if lineLength
* &gt; 0.
*/
private final byte[] lineSeparator;
/**
* Convenience variable to help us determine when our buffer is going to run out
* of room and needs resizing. {@code decodeSize = 3 + lineSeparator.length;}
*/
private final int decodeSize;
/**
* Convenience variable to help us determine when our buffer is going to run out
* of room and needs resizing. {@code encodeSize = 4 + lineSeparator.length;}
*/
private final int encodeSize;
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in
* URL-unsafe mode.
* <p>
* When encoding the line length is 0 (no chunking), and the encoding table is
* STANDARD_ENCODE_TABLE.
* </p>
*
* <p>
* When decoding all variants are supported.
* </p>
*/
public Base64() {
this(0);
}
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in the
* given URL-safe mode.
* <p>
* When encoding the line length is 76, the line separator is CRLF, and the
* encoding table is STANDARD_ENCODE_TABLE.
* </p>
*
* <p>
* When decoding all variants are supported.
* </p>
*
* @param urlSafe if {@code true}, URL-safe encoding is used. In most cases this
* should be set to {@code false}.
* @since 1.4
*/
public Base64(final boolean urlSafe) {
this(MIME_CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe);
}
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in
* URL-unsafe mode.
* <p>
* When encoding the line length is given in the constructor, the line separator
* is CRLF, and the encoding table is STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being
* multiples of 4 in the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength Each line of encoded data will be at most of the given
* length (rounded down to nearest multiple of 4). If
* lineLength &lt;= 0, then the output will not be divided
* into lines (chunks). Ignored when decoding.
* @since 1.4
*/
public Base64(final int lineLength) {
this(lineLength, CHUNK_SEPARATOR);
}
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in
* URL-unsafe mode.
* <p>
* When encoding the line length and line separator are given in the
* constructor, and the encoding table is STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being
* multiples of 4 in the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength Each line of encoded data will be at most of the given
* length (rounded down to nearest multiple of 4). If
* lineLength &lt;= 0, then the output will not be divided
* into lines (chunks). Ignored when decoding.
* @param lineSeparator Each line of encoded data will end with this sequence of
* bytes.
* @throws IllegalArgumentException Thrown when the provided lineSeparator
* included some base64 characters.
* @since 1.4
*/
public Base64(final int lineLength, final byte[] lineSeparator) {
this(lineLength, lineSeparator, false);
}
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in
* URL-unsafe mode.
* <p>
* When encoding the line length and line separator are given in the
* constructor, and the encoding table is STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being
* multiples of 4 in the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength Each line of encoded data will be at most of the given
* length (rounded down to nearest multiple of 4). If
* lineLength &lt;= 0, then the output will not be divided
* into lines (chunks). Ignored when decoding.
* @param lineSeparator Each line of encoded data will end with this sequence of
* bytes.
* @param urlSafe Instead of emitting '+' and '/' we emit '-' and '_'
* respectively. urlSafe is only applied to encode
* operations. Decoding seamlessly handles both modes.
* <b>Note: no padding is added when using the URL-safe
* alphabet.</b>
* @throws IllegalArgumentException Thrown when the {@code lineSeparator}
* contains Base64 characters.
* @since 1.4
*/
public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe) {
this(lineLength, lineSeparator, urlSafe, CodecPolicy.LENIANT);
}
/**
* Creates a Base64 codec used for decoding (all modes) and encoding in
* URL-unsafe mode.
* <p>
* When encoding the line length and line separator are given in the
* constructor, and the encoding table is STANDARD_ENCODE_TABLE.
* </p>
* <p>
* Line lengths that aren't multiples of 4 will still essentially end up being
* multiples of 4 in the encoded data.
* </p>
* <p>
* When decoding all variants are supported.
* </p>
*
* @param lineLength Each line of encoded data will be at most of the given
* length (rounded down to nearest multiple of 4). If
* lineLength &lt;= 0, then the output will not be divided
* into lines (chunks). Ignored when decoding.
* @param lineSeparator Each line of encoded data will end with this sequence
* of bytes.
* @param urlSafe Instead of emitting '+' and '/' we emit '-' and '_'
* respectively. urlSafe is only applied to encode
* operations. Decoding seamlessly handles both modes.
* <b>Note: no padding is added when using the URL-safe
* alphabet.</b>
* @param decodingPolicy The decoding policy.
* @throws IllegalArgumentException Thrown when the {@code lineSeparator}
* contains Base64 characters.
* @since 1.15
*/
public Base64(final int lineLength, final byte[] lineSeparator, final boolean urlSafe,
final CodecPolicy decodingPolicy) {
super(BYTES_PER_UNENCODED_BLOCK, BYTES_PER_ENCODED_BLOCK, lineLength,
lineSeparator == null ? 0 : lineSeparator.length, PAD_DEFAULT, decodingPolicy);
// TODO could be simplified if there is no requirement to reject invalid line
// sep when length <=0
// @see test case Base64Test.testConstructors()
if (lineSeparator != null) {
if (containsAlphabetOrPad(lineSeparator)) {
final String sep = new String(lineSeparator, Charset.forName("UTF-8"));
throw new IllegalArgumentException("lineSeparator must not contain base64 characters: [" + sep + "]");
}
if (lineLength > 0) { // null line-sep forces no chunking rather than throwing IAE
this.encodeSize = BYTES_PER_ENCODED_BLOCK + lineSeparator.length;
this.lineSeparator = new byte[lineSeparator.length];
System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length);
} else {
this.encodeSize = BYTES_PER_ENCODED_BLOCK;
this.lineSeparator = null;
}
} else {
this.encodeSize = BYTES_PER_ENCODED_BLOCK;
this.lineSeparator = null;
}
this.decodeSize = this.encodeSize - 1;
this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE;
}
// Implementation of the Encoder Interface
/**
* <p>
* Decodes all of the provided data, starting at inPos, for inAvail bytes.
* Should be called at least twice: once with the data to decode, and once with
* inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" call
* is not necessary when decoding, but it doesn't hurt, either.
* </p>
* <p>
* Ignores all non-base64 characters. This is how chunked (e.g. 76 character)
* data is handled, since CR and LF are silently ignored, but has implications
* for other bytes, too. This method subscribes to the garbage-in, garbage-out
* philosophy: it will not check the provided data for validity.
* </p>
* <p>
* Thanks to "commons" project in ws.apache.org for the bitwise operations, and
* general approach.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
* </p>
*
* @param in byte[] array of ascii data to base64 decode.
* @param inPos Position to start reading data from.
* @param inAvail Amount of bytes available from input for decoding.
* @param context the context to be used
*/
@Override
void decode(final byte[] in, int inPos, final int inAvail, final Context context) {
if (context.eof) {
return;
}
if (inAvail < 0) {
context.eof = true;
}
for (int i = 0; i < inAvail; i++) {
final byte[] buffer = ensureBufferSize(decodeSize, context);
final byte b = in[inPos++];
if (b == pad) {
// We're done.
context.eof = true;
break;
}
if (b >= 0 && b < DECODE_TABLE.length) {
final int result = DECODE_TABLE[b];
if (result >= 0) {
context.modulus = (context.modulus + 1) % BYTES_PER_ENCODED_BLOCK;
context.ibitWorkArea = (context.ibitWorkArea << BITS_PER_ENCODED_BYTE) + result;
if (context.modulus == 0) {
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 16) & MASK_8BITS);
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
buffer[context.pos++] = (byte) (context.ibitWorkArea & MASK_8BITS);
}
}
}
}
// Two forms of EOF as far as base64 decoder is concerned: actual
// EOF (-1) and first time '=' character is encountered in stream.
// This approach makes the '=' padding characters completely optional.
if (context.eof && context.modulus != 0) {
final byte[] buffer = ensureBufferSize(decodeSize, context);
// We have some spare bits remaining
// Output all whole multiples of 8 bits and ignore the rest
switch (context.modulus) {
// case 0 : // impossible, as excluded above
case 1: // 6 bits - either ignore entirely, or raise an exception
validateTrailingCharacter();
break;
case 2: // 12 bits = 8 + 4
validateCharacter(MASK_4BITS, context);
context.ibitWorkArea = context.ibitWorkArea >> 4; // dump the extra 4 bits
buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
break;
case 3: // 18 bits = 8 + 8 + 2
validateCharacter(MASK_2BITS, context);
context.ibitWorkArea = context.ibitWorkArea >> 2; // dump 2 bits
buffer[context.pos++] = (byte) ((context.ibitWorkArea >> 8) & MASK_8BITS);
buffer[context.pos++] = (byte) ((context.ibitWorkArea) & MASK_8BITS);
break;
default:
throw new IllegalStateException("Impossible modulus " + context.modulus);
}
}
}
/**
* <p>
* Encodes all of the provided data, starting at inPos, for inAvail bytes. Must
* be called at least twice: once with the data to encode, and once with inAvail
* set to "-1" to alert encoder that EOF has been reached, to flush last
* remaining bytes (if not multiple of 3).
* </p>
* <p>
* <b>Note: no padding is added when encoding using the URL-safe alphabet.</b>
* </p>
* <p>
* Thanks to "commons" project in ws.apache.org for the bitwise operations, and
* general approach.
* http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
* </p>
*
* @param in byte[] array of binary data to base64 encode.
* @param inPos Position to start reading data from.
* @param inAvail Amount of bytes available from input for encoding.
* @param context the context to be used
*/
@Override
void encode(final byte[] in, int inPos, final int inAvail, final Context context) {
if (context.eof) {
return;
}
// inAvail < 0 is how we're informed of EOF in the underlying data we're
// encoding.
if (inAvail < 0) {
context.eof = true;
if (0 == context.modulus && lineLength == 0) {
return; // no leftovers to process and not using chunking
}
final byte[] buffer = ensureBufferSize(encodeSize, context);
final int savedPos = context.pos;
switch (context.modulus) { // 0-2
case 0: // nothing to do here
break;
case 1: // 8 bits = 6 + 2
// top 6 bits:
buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 2) & MASK_6BITS];
// remaining 2:
buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 4) & MASK_6BITS];
// URL-SAFE skips the padding to further reduce size.
if (encodeTable == STANDARD_ENCODE_TABLE) {
buffer[context.pos++] = pad;
buffer[context.pos++] = pad;
}
break;
case 2: // 16 bits = 6 + 6 + 4
buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 10) & MASK_6BITS];
buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 4) & MASK_6BITS];
buffer[context.pos++] = encodeTable[(context.ibitWorkArea << 2) & MASK_6BITS];
// URL-SAFE skips the padding to further reduce size.
if (encodeTable == STANDARD_ENCODE_TABLE) {
buffer[context.pos++] = pad;
}
break;
default:
throw new IllegalStateException("Impossible modulus " + context.modulus);
}
context.currentLinePos += context.pos - savedPos; // keep track of current line position
// if currentPos == 0 we are at the start of a line, so don't add CRLF
if (lineLength > 0 && context.currentLinePos > 0) {
System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
context.pos += lineSeparator.length;
}
} else {
for (int i = 0; i < inAvail; i++) {
final byte[] buffer = ensureBufferSize(encodeSize, context);
context.modulus = (context.modulus + 1) % BYTES_PER_UNENCODED_BLOCK;
int b = in[inPos++];
if (b < 0) {
b += 256;
}
context.ibitWorkArea = (context.ibitWorkArea << 8) + b; // BITS_PER_BYTE
if (0 == context.modulus) { // 3 bytes = 24 bits = 4 * 6 bits to extract
buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 18) & MASK_6BITS];
buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 12) & MASK_6BITS];
buffer[context.pos++] = encodeTable[(context.ibitWorkArea >> 6) & MASK_6BITS];
buffer[context.pos++] = encodeTable[context.ibitWorkArea & MASK_6BITS];
context.currentLinePos += BYTES_PER_ENCODED_BLOCK;
if (lineLength > 0 && lineLength <= context.currentLinePos) {
System.arraycopy(lineSeparator, 0, buffer, context.pos, lineSeparator.length);
context.pos += lineSeparator.length;
context.currentLinePos = 0;
}
}
}
}
}
/**
* Returns whether or not the {@code octet} is in the Base64 alphabet.
*
* @param octet The value to test
* @return {@code true} if the value is defined in the the Base64 alphabet
* {@code false} otherwise.
*/
@Override
protected boolean isInAlphabet(final byte octet) {
return octet >= 0 && octet < decodeTable.length && decodeTable[octet] != -1;
}
/**
* Returns our current encode mode. True if we're URL-SAFE, false otherwise.
*
* @return true if we're in URL-SAFE mode, false otherwise.
* @since 1.4
*/
public boolean isUrlSafe() {
return this.encodeTable == URL_SAFE_ENCODE_TABLE;
}
/**
* Validates whether decoding the final trailing character is possible in the
* context of the set of possible base 64 values.
*
* <p>
* The character is valid if the lower bits within the provided mask are zero.
* This is used to test the final trailing base-64 digit is zero in the bits
* that will be discarded.
*
* @param emptyBitsMask The mask of the lower bits that should be empty
* @param context the context to be used
*
* @throws IllegalArgumentException if the bits being checked contain any
* non-zero value
*/
private void validateCharacter(final int emptyBitsMask, final Context context) {
if (isStrictDecoding() && (context.ibitWorkArea & emptyBitsMask) != 0) {
throw new IllegalArgumentException(
"Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. "
+ "Expected the discarded bits from the character to be zero.");
}
}
/**
* Validates whether decoding allows an entire final trailing character that
* cannot be used for a complete byte.
*
* @throws IllegalArgumentException if strict decoding is enabled
*/
private void validateTrailingCharacter() {
if (isStrictDecoding()) {
throw new IllegalArgumentException(
"Strict decoding: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible encoding. "
+ "Decoding requires at least two trailing 6-bit characters to create bytes.");
}
}
}

View File

@ -0,0 +1,692 @@
package net.lax1dude.eaglercraft.v1_8;
import java.nio.charset.Charset;
import java.util.Arrays;
public abstract class BaseNCodec {
static enum CodecPolicy {
STRICT, LENIANT;
}
/**
* Holds thread context so classes can be thread-safe.
*
* This class is not itself thread-safe; each thread must allocate its own copy.
*
* @since 1.7
*/
static class Context {
/**
* Place holder for the bytes we're dealing with for our based logic. Bitwise
* operations store and extract the encoding or decoding from this variable.
*/
int ibitWorkArea;
/**
* Place holder for the bytes we're dealing with for our based logic. Bitwise
* operations store and extract the encoding or decoding from this variable.
*/
long lbitWorkArea;
/**
* Buffer for streaming.
*/
byte[] buffer;
/**
* Position where next character should be written in the buffer.
*/
int pos;
/**
* Position where next character should be read from the buffer.
*/
int readPos;
/**
* Boolean flag to indicate the EOF has been reached. Once EOF has been reached,
* this object becomes useless, and must be thrown away.
*/
boolean eof;
/**
* Variable tracks how many characters have been written to the current line.
* Only used when encoding. We use it to make sure each encoded line never goes
* beyond lineLength (if lineLength &gt; 0).
*/
int currentLinePos;
/**
* Writes to the buffer only occur after every 3/5 reads when encoding, and
* every 4/8 reads when decoding. This variable helps track that.
*/
int modulus;
Context() {
}
/**
* Returns a String useful for debugging (especially within a debugger.)
*
* @return a String useful for debugging.
*/
@SuppressWarnings("boxing") // OK to ignore boxing here
@Override
public String toString() {
return HString.format(
"%s[buffer=%s, currentLinePos=%s, eof=%s, ibitWorkArea=%s, lbitWorkArea=%s, "
+ "modulus=%s, pos=%s, readPos=%s]",
this.getClass().getSimpleName(), Arrays.toString(buffer), currentLinePos, eof, ibitWorkArea,
lbitWorkArea, modulus, pos, readPos);
}
}
/**
* EOF
*
* @since 1.7
*/
static final int EOF = -1;
/**
* MIME chunk size per RFC 2045 section 6.8.
*
* <p>
* The {@value} character limit does not count the trailing CRLF, but counts all
* other characters, including any equal signs.
* </p>
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a>
*/
public static final int MIME_CHUNK_SIZE = 76;
/**
* PEM chunk size per RFC 1421 section 4.3.2.4.
*
* <p>
* The {@value} character limit does not count the trailing CRLF, but counts all
* other characters, including any equal signs.
* </p>
*
* @see <a href="http://tools.ietf.org/html/rfc1421">RFC 1421 section
* 4.3.2.4</a>
*/
public static final int PEM_CHUNK_SIZE = 64;
private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2;
/**
* Defines the default buffer size - currently {@value} - must be large enough
* for at least one encoded block+separator
*/
private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* The maximum size buffer to allocate.
*
* <p>
* This is set to the same size used in the JDK {@code java.util.ArrayList}:
* </p>
* <blockquote> Some VMs reserve some header words in an array. Attempts to
* allocate larger arrays may result in OutOfMemoryError: Requested array size
* exceeds VM limit. </blockquote>
*/
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/** Mask used to extract 8 bits, used in decoding bytes */
protected static final int MASK_8BITS = 0xff;
/**
* Byte used to pad output.
*/
protected static final byte PAD_DEFAULT = '='; // Allow static access to default
/**
* Chunk separator per RFC 2045 section 2.1.
*
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
*/
static final byte[] CHUNK_SEPARATOR = { '\r', '\n' };
/**
* Compares two {@code int} values numerically treating the values as unsigned.
* Taken from JDK 1.8.
*
* <p>
* TODO: Replace with JDK 1.8 Integer::compareUnsigned(int, int).
* </p>
*
* @param x the first {@code int} to compare
* @param y the second {@code int} to compare
* @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if
* {@code x < y} as unsigned values; and a value greater than {@code 0}
* if {@code x > y} as unsigned values
*/
private static int compareUnsigned(final int xx, final int yy) {
int x = xx + Integer.MIN_VALUE;
int y = yy + Integer.MIN_VALUE;
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
/**
* Create a positive capacity at least as large the minimum required capacity.
* If the minimum capacity is negative then this throws an OutOfMemoryError as
* no array can be allocated.
*
* @param minCapacity the minimum capacity
* @return the capacity
* @throws OutOfMemoryError if the {@code minCapacity} is negative
*/
private static int createPositiveCapacity(final int minCapacity) {
if (minCapacity < 0) {
// overflow
throw new OutOfMemoryError("Unable to allocate array size: " + (minCapacity & 0xffffffffL));
}
// This is called when we require buffer expansion to a very big array.
// Use the conservative maximum buffer size if possible, otherwise the biggest
// required.
//
// Note: In this situation JDK 1.8 java.util.ArrayList returns
// Integer.MAX_VALUE.
// This excludes some VMs that can exceed MAX_BUFFER_SIZE but not allocate a
// full
// Integer.MAX_VALUE length array.
// The result is that we may have to allocate an array of this size more than
// once if
// the capacity must be expanded again.
return (minCapacity > MAX_BUFFER_SIZE) ? minCapacity : MAX_BUFFER_SIZE;
}
/**
* Gets a copy of the chunk separator per RFC 2045 section 2.1.
*
* @return the chunk separator
* @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a>
* @since 1.15
*/
public static byte[] getChunkSeparator() {
return CHUNK_SEPARATOR.clone();
}
/**
* Checks if a byte value is whitespace or not. Whitespace is taken to mean:
* space, tab, CR, LF
*
* @param byteToCheck the byte to check
* @return true if byte is whitespace, false otherwise
*/
protected static boolean isWhiteSpace(final byte byteToCheck) {
switch (byteToCheck) {
case ' ':
case '\n':
case '\r':
case '\t':
return true;
default:
return false;
}
}
/**
* Increases our buffer by the {@link #DEFAULT_BUFFER_RESIZE_FACTOR}.
*
* @param context the context to be used
* @param minCapacity the minimum required capacity
* @return the resized byte[] buffer
* @throws OutOfMemoryError if the {@code minCapacity} is negative
*/
private static byte[] resizeBuffer(final Context context, final int minCapacity) {
// Overflow-conscious code treats the min and new capacity as unsigned.
final int oldCapacity = context.buffer.length;
int newCapacity = oldCapacity * DEFAULT_BUFFER_RESIZE_FACTOR;
if (compareUnsigned(newCapacity, minCapacity) < 0) {
newCapacity = minCapacity;
}
if (compareUnsigned(newCapacity, MAX_BUFFER_SIZE) > 0) {
newCapacity = createPositiveCapacity(minCapacity);
}
final byte[] b = new byte[newCapacity];
System.arraycopy(context.buffer, 0, b, 0, context.buffer.length);
context.buffer = b;
return b;
}
/**
* @deprecated Use {@link #pad}. Will be removed in 2.0.
*/
@Deprecated
protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later
protected final byte pad; // instance variable just in case it needs to vary later
/**
* Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5
* for Base32
*/
private final int unencodedBlockSize;
/**
* Number of bytes in each full block of encoded data, e.g. 3 for Base64 and 8
* for Base32
*/
private final int encodedBlockSize;
/**
* Chunksize for encoding. Not used when decoding. A value of zero or less
* implies no chunking of the encoded data. Rounded down to nearest multiple of
* encodedBlockSize.
*/
protected final int lineLength;
/**
* Size of chunk separator. Not used unless {@link #lineLength} &gt; 0.
*/
private final int chunkSeparatorLength;
/**
* Defines the decoding behavior when the input bytes contain leftover trailing
* bits that cannot be created by a valid encoding. These can be bits that are
* unused from the final character or entire characters. The default mode is
* lenient decoding. Set this to {@code true} to enable strict decoding.
* <ul>
* <li>Lenient: Any trailing bits are composed into 8-bit bytes where possible.
* The remainder are discarded.
* <li>Strict: The decoding will raise an {@link IllegalArgumentException} if
* trailing bits are not part of a valid encoding. Any unused bits from the
* final character must be zero. Impossible counts of entire final characters
* are not allowed.
* </ul>
*
* <p>
* When strict decoding is enabled it is expected that the decoded bytes will be
* re-encoded to a byte array that matches the original, i.e. no changes occur
* on the final character. This requires that the input bytes use the same
* padding and alphabet as the encoder.
*/
private final CodecPolicy decodingPolicy;
/**
* Note {@code lineLength} is rounded down to the nearest multiple of the
* encoded block size. If {@code chunkSeparatorLength} is zero, then chunking is
* disabled.
*
* @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3)
* @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4)
* @param lineLength if &gt; 0, use chunking with a length
* {@code lineLength}
* @param chunkSeparatorLength the chunk separator length, if relevant
*/
protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, final int lineLength,
final int chunkSeparatorLength) {
this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, PAD_DEFAULT);
}
/**
* Note {@code lineLength} is rounded down to the nearest multiple of the
* encoded block size. If {@code chunkSeparatorLength} is zero, then chunking is
* disabled.
*
* @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3)
* @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4)
* @param lineLength if &gt; 0, use chunking with a length
* {@code lineLength}
* @param chunkSeparatorLength the chunk separator length, if relevant
* @param pad byte used as padding byte.
*/
protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, final int lineLength,
final int chunkSeparatorLength, final byte pad) {
this(unencodedBlockSize, encodedBlockSize, lineLength, chunkSeparatorLength, pad, CodecPolicy.LENIANT);
}
/**
* Note {@code lineLength} is rounded down to the nearest multiple of the
* encoded block size. If {@code chunkSeparatorLength} is zero, then chunking is
* disabled.
*
* @param unencodedBlockSize the size of an unencoded block (e.g. Base64 = 3)
* @param encodedBlockSize the size of an encoded block (e.g. Base64 = 4)
* @param lineLength if &gt; 0, use chunking with a length
* {@code lineLength}
* @param chunkSeparatorLength the chunk separator length, if relevant
* @param pad byte used as padding byte.
* @param decodingPolicy Decoding policy.
* @since 1.15
*/
protected BaseNCodec(final int unencodedBlockSize, final int encodedBlockSize, final int lineLength,
final int chunkSeparatorLength, final byte pad, final CodecPolicy decodingPolicy) {
this.unencodedBlockSize = unencodedBlockSize;
this.encodedBlockSize = encodedBlockSize;
final boolean useChunking = lineLength > 0 && chunkSeparatorLength > 0;
this.lineLength = useChunking ? (lineLength / encodedBlockSize) * encodedBlockSize : 0;
this.chunkSeparatorLength = chunkSeparatorLength;
this.pad = pad;
this.decodingPolicy = decodingPolicy;
}
/**
* Returns the amount of buffered data available for reading.
*
* @param context the context to be used
* @return The amount of buffered data available for reading.
*/
int available(final Context context) { // package protected for access from I/O streams
return context.buffer != null ? context.pos - context.readPos : 0;
}
/**
* Tests a given byte array to see if it contains any characters within the
* alphabet or PAD.
*
* Intended for use in checking line-ending arrays
*
* @param arrayOctet byte array to test
* @return {@code true} if any byte is a valid character in the alphabet or PAD;
* {@code false} otherwise
*/
protected boolean containsAlphabetOrPad(final byte[] arrayOctet) {
if (arrayOctet == null) {
return false;
}
for (final byte element : arrayOctet) {
if (pad == element || isInAlphabet(element)) {
return true;
}
}
return false;
}
/**
* Decodes a byte[] containing characters in the Base-N alphabet.
*
* @param pArray A byte array containing Base-N character data
* @return a byte array containing binary data
*/
public byte[] decode(final byte[] pArray) {
if (pArray == null || pArray.length == 0) {
return pArray;
}
final Context context = new Context();
decode(pArray, 0, pArray.length, context);
decode(pArray, 0, EOF, context); // Notify decoder of EOF.
final byte[] result = new byte[context.pos];
readResults(result, 0, result.length, context);
return result;
}
// package protected for access from I/O streams
abstract void decode(byte[] pArray, int i, int length, Context context);
/**
* Decodes an Object using the Base-N algorithm. This method is provided in
* order to satisfy the requirements of the Decoder interface, and will throw a
* DecoderException if the supplied object is not of type byte[] or String.
*
* @param obj Object to decode
* @return An object (of type byte[]) containing the binary data which
* corresponds to the byte[] or String supplied.
* @throws DecoderException if the parameter supplied is not of type byte[]
*/
public Object decode(final Object obj) {
if (obj instanceof byte[]) {
return decode((byte[]) obj);
} else if (obj instanceof String) {
return decode((String) obj);
} else {
return null;
}
}
/**
* Decodes a String containing characters in the Base-N alphabet.
*
* @param pArray A String containing Base-N character data
* @return a byte array containing binary data
*/
public byte[] decode(final String pArray) {
return decode(pArray.getBytes(Charset.forName("UTF-8")));
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing characters
* in the alphabet.
*
* @param pArray a byte array containing binary data
* @return A byte array containing only the base N alphabetic character data
*/
public byte[] encode(final byte[] pArray) {
if (pArray == null || pArray.length == 0) {
return pArray;
}
return encode(pArray, 0, pArray.length);
}
/**
* Encodes a byte[] containing binary data, into a byte[] containing characters
* in the alphabet.
*
* @param pArray a byte array containing binary data
* @param offset initial offset of the subarray.
* @param length length of the subarray.
* @return A byte array containing only the base N alphabetic character data
* @since 1.11
*/
public byte[] encode(final byte[] pArray, final int offset, final int length) {
if (pArray == null || pArray.length == 0) {
return pArray;
}
final Context context = new Context();
encode(pArray, offset, length, context);
encode(pArray, offset, EOF, context); // Notify encoder of EOF.
final byte[] buf = new byte[context.pos - context.readPos];
readResults(buf, 0, buf.length, context);
return buf;
}
// package protected for access from I/O streams
abstract void encode(byte[] pArray, int i, int length, Context context);
/**
* Encodes an Object using the Base-N algorithm. This method is provided in
* order to satisfy the requirements of the Encoder interface, and will throw an
* EncoderException if the supplied object is not of type byte[].
*
* @param obj Object to encode
* @return An object (of type byte[]) containing the Base-N encoded data which
* corresponds to the byte[] supplied.
* @throws EncoderException if the parameter supplied is not of type byte[]
*/
public Object encode(final Object obj) {
return encode((byte[]) obj);
}
/**
* Encodes a byte[] containing binary data, into a String containing characters
* in the appropriate alphabet. Uses UTF8 encoding.
*
* @param pArray a byte array containing binary data
* @return String containing only character data in the appropriate alphabet.
* @since 1.5 This is a duplicate of {@link #encodeToString(byte[])}; it was
* merged during refactoring.
*/
public String encodeAsString(final byte[] pArray) {
return new String(encode(pArray), Charset.forName("UTF-8"));
}
/**
* Encodes a byte[] containing binary data, into a String containing characters
* in the Base-N alphabet. Uses UTF8 encoding.
*
* @param pArray a byte array containing binary data
* @return A String containing only Base-N character data
*/
public String encodeToString(final byte[] pArray) {
return new String(encode(pArray), Charset.forName("UTF-8"));
}
/**
* Ensure that the buffer has room for {@code size} bytes
*
* @param size minimum spare space required
* @param context the context to be used
* @return the buffer
*/
protected byte[] ensureBufferSize(final int size, final Context context) {
if (context.buffer == null) {
context.buffer = new byte[Math.max(size, getDefaultBufferSize())];
context.pos = 0;
context.readPos = 0;
// Overflow-conscious:
// x + y > z == x + y - z > 0
} else if (context.pos + size - context.buffer.length > 0) {
return resizeBuffer(context, context.pos + size);
}
return context.buffer;
}
/**
* Returns the decoding behavior policy.
*
* <p>
* The default is lenient. If the decoding policy is strict, then decoding will
* raise an {@link IllegalArgumentException} if trailing bits are not part of a
* valid encoding. Decoding will compose trailing bits into 8-bit bytes and
* discard the remainder.
* </p>
*
* @return true if using strict decoding
* @since 1.15
*/
public CodecPolicy getCodecPolicy() {
return decodingPolicy;
}
/**
* Get the default buffer size. Can be overridden.
*
* @return the default buffer size.
*/
protected int getDefaultBufferSize() {
return DEFAULT_BUFFER_SIZE;
}
/**
* Calculates the amount of space needed to encode the supplied array.
*
* @param pArray byte[] array which will later be encoded
*
* @return amount of space needed to encoded the supplied array. Returns a long
* since a max-len array will require &gt; Integer.MAX_VALUE
*/
public long getEncodedLength(final byte[] pArray) {
// Calculate non-chunked size - rounded up to allow for padding
// cast to long is needed to avoid possibility of overflow
long len = ((pArray.length + unencodedBlockSize - 1) / unencodedBlockSize) * (long) encodedBlockSize;
if (lineLength > 0) { // We're using chunking
// Round up to nearest multiple
len += ((len + lineLength - 1) / lineLength) * chunkSeparatorLength;
}
return len;
}
/**
* Returns true if this object has buffered data for reading.
*
* @param context the context to be used
* @return true if there is data still available for reading.
*/
boolean hasData(final Context context) { // package protected for access from I/O streams
return context.buffer != null;
}
/**
* Returns whether or not the {@code octet} is in the current alphabet. Does not
* allow whitespace or pad.
*
* @param value The value to test
*
* @return {@code true} if the value is defined in the current alphabet,
* {@code false} otherwise.
*/
protected abstract boolean isInAlphabet(byte value);
/**
* Tests a given byte array to see if it contains only valid characters within
* the alphabet. The method optionally treats whitespace and pad as valid.
*
* @param arrayOctet byte array to test
* @param allowWSPad if {@code true}, then whitespace and PAD are also allowed
*
* @return {@code true} if all bytes are valid characters in the alphabet or if
* the byte array is empty; {@code false}, otherwise
*/
public boolean isInAlphabet(final byte[] arrayOctet, final boolean allowWSPad) {
for (final byte octet : arrayOctet) {
if (!isInAlphabet(octet) && (!allowWSPad || (octet != pad) && !isWhiteSpace(octet))) {
return false;
}
}
return true;
}
/**
* Tests a given String to see if it contains only valid characters within the
* alphabet. The method treats whitespace and PAD as valid.
*
* @param basen String to test
* @return {@code true} if all characters in the String are valid characters in
* the alphabet or if the String is empty; {@code false}, otherwise
* @see #isInAlphabet(byte[], boolean)
*/
public boolean isInAlphabet(final String basen) {
return isInAlphabet(basen.getBytes(Charset.forName("UTF-8")), true);
}
/**
* Returns true if decoding behavior is strict. Decoding will raise an
* {@link IllegalArgumentException} if trailing bits are not part of a valid
* encoding.
*
* <p>
* The default is false for lenient decoding. Decoding will compose trailing
* bits into 8-bit bytes and discard the remainder.
* </p>
*
* @return true if using strict decoding
* @since 1.15
*/
public boolean isStrictDecoding() {
return decodingPolicy == CodecPolicy.STRICT;
}
/**
* Extracts buffered data into the provided byte[] array, starting at position
* bPos, up to a maximum of bAvail bytes. Returns how many bytes were actually
* extracted.
* <p>
* Package protected for access from I/O streams.
*
* @param b byte[] array to extract the buffered data into.
* @param bPos position in byte[] array to start extraction at.
* @param bAvail amount of bytes we're allowed to extract. We may extract fewer
* (if fewer are available).
* @param context the context to be used
* @return The number of bytes successfully extracted into the provided byte[]
* array.
*/
int readResults(final byte[] b, final int bPos, final int bAvail, final Context context) {
if (context.buffer != null) {
final int len = Math.min(available(context), bAvail);
System.arraycopy(context.buffer, context.readPos, b, bPos, len);
context.readPos += len;
if (context.readPos >= context.pos) {
context.buffer = null; // so hasData() will return false, and this method can return -1
}
return len;
}
return context.eof ? EOF : 0;
}
}

View File

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class DecoderException extends RuntimeException {
public DecoderException() {
super();
}
public DecoderException(String message, Throwable cause) {
super(message, cause);
}
public DecoderException(String message) {
super(message);
}
public DecoderException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,59 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
public class Display {
private static long lastSwap = 0l;
public static int getWidth() {
return PlatformInput.getWindowWidth();
}
public static int getHeight() {
return PlatformInput.getWindowHeight();
}
public static boolean isActive() {
return PlatformInput.getWindowFocused();
}
public static void create() {
}
public static void setTitle(String string) {
}
public static boolean isCloseRequested() {
return PlatformInput.isCloseRequested();
}
public static void update() {
PlatformInput.update();
}
public static void sync(int limitFramerate) {
boolean limitFPS = limitFramerate > 0 && limitFramerate < 1000;
if(limitFPS) {
long millis = System.currentTimeMillis();
long frameMillis = (1000l / limitFramerate) - (millis - lastSwap);
if(frameMillis > 0l) {
EagUtils.sleep(frameMillis);
}
}
lastSwap = System.currentTimeMillis();
}
public static boolean contextLost() {
return PlatformInput.contextLost();
}
public static boolean wasResized() {
return PlatformInput.wasResized();
}
}

View File

@ -0,0 +1,274 @@
package net.lax1dude.eaglercraft.v1_8;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.FloatBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformAgent;
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformOS;
import net.lax1dude.eaglercraft.v1_8.internal.EnumPlatformType;
import net.lax1dude.eaglercraft.v1_8.internal.FileChooserResult;
import net.lax1dude.eaglercraft.v1_8.internal.IClientConfigAdapter;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformAssets;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EagRuntime {
private static final Logger logger = LogManager.getLogger("EagRuntime");
private static final Logger exceptionLogger = LogManager.getLogger("Exception");
private static boolean ssl = false;
public static String getVersion() {
return "EagRuntimeX 1.0";
}
public static void create() {
logger.info("Version: {}", getVersion());
PlatformRuntime.create();
ssl = PlatformRuntime.requireSSL();
EaglercraftGPU.warmUpCache();
}
public static void destroy() {
PlatformRuntime.destroy();
}
public static EnumPlatformType getPlatformType() {
return PlatformRuntime.getPlatformType();
}
public static EnumPlatformAgent getPlatformAgent() {
return PlatformRuntime.getPlatformAgent();
}
public static String getUserAgentString() {
return PlatformRuntime.getUserAgentString();
}
public static EnumPlatformOS getPlatformOS() {
return PlatformRuntime.getPlatformOS();
}
public static ByteBuffer allocateByteBuffer(int length) {
return PlatformRuntime.allocateByteBuffer(length);
}
public static IntBuffer allocateIntBuffer(int length) {
return PlatformRuntime.allocateIntBuffer(length);
}
public static FloatBuffer allocateFloatBuffer(int length) {
return PlatformRuntime.allocateFloatBuffer(length);
}
public static void freeByteBuffer(ByteBuffer floatBuffer) {
PlatformRuntime.freeByteBuffer(floatBuffer);
}
public static void freeIntBuffer(IntBuffer intBuffer) {
PlatformRuntime.freeIntBuffer(intBuffer);
}
public static void freeFloatBuffer(FloatBuffer byteBuffer) {
PlatformRuntime.freeFloatBuffer(byteBuffer);
}
public static byte[] getResourceBytes(String path) {
return PlatformAssets.getResourceBytes(path);
}
public static InputStream getResourceStream(String path) {
byte[] b = PlatformAssets.getResourceBytes(path);
if(b != null) {
return new EaglerInputStream(b);
}else {
return null;
}
}
public static String getResourceString(String path) {
byte[] bytes = PlatformAssets.getResourceBytes(path);
return bytes != null ? new String(bytes, StandardCharsets.UTF_8) : null;
}
public static List<String> getResourceLines(String path) {
byte[] bytes = PlatformAssets.getResourceBytes(path);
if(bytes != null) {
List<String> ret = new ArrayList();
try {
BufferedReader rd = new BufferedReader(new StringReader(path));
String s;
while((s = rd.readLine()) != null) {
ret.add(s);
}
}catch(IOException ex) {
// ??
}
return ret;
}else {
return null;
}
}
public static void debugPrintStackTraceToSTDERR(Throwable t) {
debugPrintStackTraceToSTDERR0("", t);
Throwable c = t.getCause();
while(c != null) {
debugPrintStackTraceToSTDERR0("Caused by: ", c);
c = c.getCause();
}
}
private static void debugPrintStackTraceToSTDERR0(String pfx, Throwable t) {
System.err.println(pfx + t.toString());
if(!PlatformRuntime.printJSExceptionIfBrowser(t)) {
getStackTrace(t, (s) -> {
System.err.println(" at " + s);
});
}
}
public static void getStackTrace(Throwable t, Consumer<String> ret) {
PlatformRuntime.getStackTrace(t, ret);
}
public static String[] getStackTraceElements(Throwable t) {
List<String> lst = new ArrayList();
PlatformRuntime.getStackTrace(t, (s) -> {
lst.add(s);
});
return lst.toArray(new String[lst.size()]);
}
public static String getStackTrace(Throwable t) {
StringBuilder sb = new StringBuilder();
getStackTrace0(t, sb);
Throwable c = t.getCause();
while(c != null) {
sb.append("\nCaused by: ");
getStackTrace0(c, sb);
c = c.getCause();
}
return sb.toString();
}
private static void getStackTrace0(Throwable t, StringBuilder sb) {
sb.append(t.toString());
getStackTrace(t, (s) -> {
sb.append('\n').append(" at ").append(s);
});
}
public static void debugPrintStackTrace(Throwable t) {
exceptionLogger.error(t);
}
public static void dumpStack() {
try {
throw new Exception("Stack Trace");
}catch(Exception ex) {
exceptionLogger.error(ex);
}
}
public static void exit() {
PlatformRuntime.exit();
}
public static long maxMemory() {
return PlatformRuntime.maxMemory();
}
public static long totalMemory() {
return PlatformRuntime.totalMemory();
}
public static long freeMemory() {
return PlatformRuntime.freeMemory();
}
public static boolean requireSSL() {
return ssl;
}
public static void showPopup(String msg) {
PlatformApplication.showPopup(msg);
}
public static String getClipboard() {
return PlatformApplication.getClipboard();
}
public static void setClipboard(String text) {
PlatformApplication.setClipboard(text);
}
public static void openLink(String url) {
PlatformApplication.openLink(url);
}
public static void displayFileChooser(String mime, String ext) {
PlatformApplication.displayFileChooser(mime, ext);
}
public static boolean fileChooserHasResult() {
return PlatformApplication.fileChooserHasResult();
}
public static FileChooserResult getFileChooserResult() {
return PlatformApplication.getFileChooserResult();
}
public static void setStorage(String name, byte[] data) {
PlatformApplication.setLocalStorage(name, data);
}
public static byte[] getStorage(String data) {
return PlatformApplication.getLocalStorage(data);
}
public static IClientConfigAdapter getConfiguration() {
return PlatformRuntime.getClientConfigAdapter();
}
public static String getRecText() {
return PlatformRuntime.getRecText();
}
public static void toggleRec() {
PlatformRuntime.toggleRec();
}
public static boolean recSupported() {
return PlatformRuntime.recSupported();
}
public static void openCreditsPopup(String text) {
PlatformApplication.openCreditsPopup(text);
}
}

View File

@ -0,0 +1,73 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EagUtils {
private static final String hex = "0123456789ABCDEF";
public static String hexString(int value, int digits) {
String ret = "";
for(int i = 0, l = digits << 2; i < l; i += 4) {
ret = hex.charAt((value >> i) & 0xF) + ret;
}
return ret;
}
public static int decodeHex(CharSequence num) {
int ret = 0;
for(int i = 0, l = num.length(); i < l; ++i) {
ret = ret << 4;
int v = hex.indexOf(num.charAt(i));
if(v >= 0) {
ret |= v;
}
}
return ret;
}
public static int decodeHexByte(CharSequence str, int off) {
return str.length() < off + 2 ? decodeHex(str.subSequence(off, 2)) : 0;
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
}catch(InterruptedException ex) {
}
}
public static String toASCIIEagler(String str) {
char[] ascii = new char[str.length()];
for(int i = 0; i < ascii.length; ++i) {
int c = (int)str.charAt(i);
if(c < 32 || c > 126) {
ascii[i] = '_';
}else {
ascii[i] = (char)c;
}
}
return new String(ascii);
}
public static void validateASCIIEagler(String str) {
for(int i = 0, l = str.length(); i < l; ++i) {
int c = (int)str.charAt(i);
if(c < 32 || c > 126) {
throw new IllegalArgumentException("invalid ascii");
}
}
}
}

View File

@ -0,0 +1,83 @@
package net.lax1dude.eaglercraft.v1_8;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglerInputStream extends ByteArrayInputStream {
public EaglerInputStream(byte[] buf) {
super(buf);
}
public EaglerInputStream(byte[] buf, int off, int len) {
super(buf, off, len);
}
public static byte[] inputStreamToBytesQuiet(InputStream is) {
try {
return inputStreamToBytes(is);
}catch(IOException ex) {
return null;
}
}
public static byte[] inputStreamToBytes(InputStream is) throws IOException {
if(is instanceof EaglerInputStream) {
return ((EaglerInputStream) is).getAsArray();
}else if(is instanceof ByteArrayInputStream) {
byte[] ret = new byte[is.available()];
is.read(ret);
return ret;
}else {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buf = new byte[1024];
int i;
while((i = is.read(buf)) != -1) {
os.write(buf, 0, i);
}
return os.toByteArray();
}
}
public byte[] getAsArray() {
if(pos == 0 && count == buf.length) {
return buf;
}else {
byte[] ret = new byte[count];
System.arraycopy(buf, pos, ret, 0, count);
return ret;
}
}
public boolean canUseArrayDirectly() {
return pos == 0 && count == buf.length;
}
public int getPosition() {
return pos;
}
public int getMark() {
return mark;
}
public int getCount() {
return count;
}
}

View File

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.v1_8;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglerZLIB {
public static OutputStream newDeflaterOutputStream(OutputStream os) throws IOException {
return PlatformRuntime.newDeflaterOutputStream(os);
}
public static OutputStream newGZIPOutputStream(OutputStream os) throws IOException {
return PlatformRuntime.newGZIPOutputStream(os);
}
public static InputStream newInflaterInputStream(InputStream is) throws IOException {
return PlatformRuntime.newInflaterInputStream(is);
}
public static InputStream newGZIPInputStream(InputStream is) throws IOException {
return PlatformRuntime.newGZIPInputStream(is);
}
}

View File

@ -0,0 +1,103 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglercraftRandom {
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
private static final double DOUBLE_UNIT = 0x1.0p-53;
private long seed = 69;
private static int yee = 0;
public EaglercraftRandom() {
this(System.currentTimeMillis() + (++yee));
}
public EaglercraftRandom(long seed) {
setSeed(seed);
}
public void setSeed(long yeed) {
seed = yeed;
}
protected int next(int bits) {
seed = (seed * multiplier + addend) & mask;
return (int) (seed >>> (48 - bits));
}
public void nextBytes(byte[] bytes) {
for (int i = 0, len = bytes.length; i < len;)
for (int rnd = nextInt(), n = Math.min(len - i, Integer.SIZE / Byte.SIZE); n-- > 0; rnd >>= Byte.SIZE)
bytes[i++] = (byte) rnd;
}
public int nextInt() {
return next(32);
}
public int nextInt(int bound) {
int r = next(31);
int m = bound - 1;
if ((bound & m) == 0) // i.e., bound is a power of 2
r = (int) ((bound * (long) r) >> 31);
else {
for (int u = r; u - (r = u % bound) + m < 0; u = next(31))
;
}
return r;
}
public long nextLong() {
return ((long) (next(32)) << 32) + next(32);
}
public boolean nextBoolean() {
return next(1) != 0;
}
public float nextFloat() {
return next(24) / ((float) (1 << 24));
}
public double nextDouble() {
return (((long) (next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
private double nextNextGaussian;
private boolean haveNextNextGaussian = false;
public double nextGaussian() {
// See Knuth, ACP, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian) {
haveNextNextGaussian = false;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1; // between -1 and 1
v2 = 2 * nextDouble() - 1; // between -1 and 1
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}

View File

@ -0,0 +1,354 @@
package net.lax1dude.eaglercraft.v1_8;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.internal.IAudioHandle;
import net.lax1dude.eaglercraft.v1_8.internal.IAudioResource;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformAudio;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.minecraft.client.audio.ISound;
import net.minecraft.client.audio.ISound.AttenuationType;
import net.minecraft.client.audio.ITickableSound;
import net.minecraft.client.audio.SoundCategory;
import net.minecraft.client.audio.SoundEventAccessorComposite;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.audio.SoundPoolEntry;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ITickable;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglercraftSoundManager {
protected static class ActiveSoundEvent {
protected final EaglercraftSoundManager manager;
protected final ISound soundInstance;
protected final SoundCategory soundCategory;
protected final SoundPoolEntry soundConfig;
protected IAudioHandle soundHandle;
protected float activeX;
protected float activeY;
protected float activeZ;
protected float activePitch;
protected float activeGain;
protected int repeatCounter = 0;
protected boolean paused = false;
protected ActiveSoundEvent(EaglercraftSoundManager manager, ISound soundInstance,
SoundCategory soundCategory, SoundPoolEntry soundConfig, IAudioHandle soundHandle) {
this.manager = manager;
this.soundInstance = soundInstance;
this.soundCategory = soundCategory;
this.soundConfig = soundConfig;
this.soundHandle = soundHandle;
this.activeX = soundInstance.getXPosF();
this.activeY = soundInstance.getYPosF();
this.activeZ = soundInstance.getZPosF();
this.activePitch = soundInstance.getPitch();
this.activeGain = soundInstance.getVolume();
}
protected void updateLocation() {
float x = soundInstance.getXPosF();
float y = soundInstance.getYPosF();
float z = soundInstance.getZPosF();
float pitch = soundInstance.getPitch();
float gain = soundInstance.getVolume();
if(x != activeX || y != activeY || z != activeZ) {
soundHandle.move(x, y, z);
activeX = x;
activeY = y;
activeZ = z;
}
if(pitch != activePitch) {
soundHandle.pitch(MathHelper.clamp_float(pitch * (float)soundConfig.getPitch(), 0.5f, 2.0f));
activePitch = pitch;
}
if(gain != activeGain) {
float attenuatedGain = gain * manager.categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
(soundCategory == SoundCategory.MASTER ? 1.0f : manager.categoryVolumes[soundCategory.getCategoryId()])
* (float)soundConfig.getVolume();
soundHandle.gain(MathHelper.clamp_float(attenuatedGain, 0.0f, 1.0f));
activeGain = gain;
}
}
}
protected static class WaitingSoundEvent {
protected final ISound playSound;
protected int playTicks;
protected boolean paused = false;
private WaitingSoundEvent(ISound playSound, int playTicks) {
this.playSound = playSound;
this.playTicks = playTicks;
}
}
private static final Logger logger = LogManager.getLogger("SoundManager");
private final GameSettings settings;
private final SoundHandler handler;
private final float[] categoryVolumes;
private final List<ActiveSoundEvent> activeSounds;
private final List<WaitingSoundEvent> queuedSounds;
public EaglercraftSoundManager(GameSettings settings, SoundHandler handler) {
this.settings = settings;
this.handler = handler;
categoryVolumes = new float[] {
settings.getSoundLevel(SoundCategory.MASTER), settings.getSoundLevel(SoundCategory.MUSIC),
settings.getSoundLevel(SoundCategory.RECORDS), settings.getSoundLevel(SoundCategory.WEATHER),
settings.getSoundLevel(SoundCategory.BLOCKS), settings.getSoundLevel(SoundCategory.MOBS),
settings.getSoundLevel(SoundCategory.ANIMALS), settings.getSoundLevel(SoundCategory.PLAYERS),
settings.getSoundLevel(SoundCategory.AMBIENT), settings.getSoundLevel(SoundCategory.VOICE)
};
activeSounds = new LinkedList();
queuedSounds = new LinkedList();
}
public void unloadSoundSystem() {
// handled by PlatformApplication
}
public void reloadSoundSystem() {
// irrelevant
}
public void setSoundCategoryVolume(SoundCategory category, float volume) {
categoryVolumes[category.getCategoryId()] = volume;
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if((category == SoundCategory.MASTER || evt.soundCategory == category)
&& !evt.soundHandle.shouldFree()) {
float newVolume = (evt.activeGain = evt.soundInstance.getVolume()) * categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
(evt.soundCategory == SoundCategory.MASTER ? 1.0f : categoryVolumes[evt.soundCategory.getCategoryId()])
* (float)evt.soundConfig.getVolume();
newVolume = MathHelper.clamp_float(newVolume, 0.0f, 1.0f);
if(newVolume > 0.0f) {
evt.soundHandle.gain(newVolume);
}else {
evt.soundHandle.end();
soundItr.remove();
}
}
}
}
public void stopAllSounds() {
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if(!evt.soundHandle.shouldFree()) {
evt.soundHandle.end();
}
}
activeSounds.clear();
}
public void pauseAllSounds() {
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if(!evt.soundHandle.shouldFree()) {
evt.soundHandle.pause(true);
evt.paused = true;
}
}
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
while(soundItr2.hasNext()) {
soundItr2.next().paused = true;
}
}
public void resumeAllSounds() {
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if(!evt.soundHandle.shouldFree()) {
evt.soundHandle.pause(false);
evt.paused = false;
}
}
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
while(soundItr2.hasNext()) {
soundItr2.next().paused = false;
}
}
public void updateAllSounds() {
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if(!evt.paused && (evt.soundInstance instanceof ITickable)) {
boolean destroy = false;
try {
((ITickable)evt.soundInstance).update();
if ((evt.soundInstance instanceof ITickableSound)
&& ((ITickableSound) evt.soundInstance).isDonePlaying()) {
destroy = true;
}
}catch(Throwable t) {
logger.error("Error ticking sound: {}", t.toString());
logger.error(t);
destroy = true;
}
if(destroy) {
if(!evt.soundHandle.shouldFree()) {
evt.soundHandle.end();
}
soundItr.remove();
}
}
if(evt.soundHandle.shouldFree()) {
if(evt.soundInstance.canRepeat()) {
if(!evt.paused && ++evt.repeatCounter > evt.soundInstance.getRepeatDelay()) {
evt.repeatCounter = 0;
evt.updateLocation();
evt.soundHandle.restart();
}
}else {
soundItr.remove();
}
}else {
evt.updateLocation();
}
}
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
while(soundItr2.hasNext()) {
WaitingSoundEvent evt = soundItr2.next();
if(!evt.paused && --evt.playTicks <= 0) {
soundItr2.remove();
playSound(evt.playSound);
}
}
PlatformAudio.clearAudioCache();
}
public boolean isSoundPlaying(ISound sound) {
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if(evt.soundInstance == sound) {
return !evt.soundHandle.shouldFree();
}
}
return false;
}
public void stopSound(ISound sound) {
Iterator<ActiveSoundEvent> soundItr = activeSounds.iterator();
while(soundItr.hasNext()) {
ActiveSoundEvent evt = soundItr.next();
if(evt.soundInstance == sound) {
if(!evt.soundHandle.shouldFree()) {
evt.soundHandle.end();
soundItr.remove();
return;
}
}
}
Iterator<WaitingSoundEvent> soundItr2 = queuedSounds.iterator();
while(soundItr2.hasNext()) {
if(soundItr2.next().playSound == sound) {
soundItr2.remove();
}
}
}
public void playSound(ISound sound) {
if(!PlatformAudio.available()) {
return;
}
if(sound != null && categoryVolumes[SoundCategory.MASTER.getCategoryId()] > 0.0f) {
SoundEventAccessorComposite accessor = handler.getSound(sound.getSoundLocation());
if(accessor == null) {
logger.warn("Unable to play unknown soundEvent(1): {}", sound.getSoundLocation().toString());
}else {
SoundPoolEntry etr = accessor.cloneEntry();
if (etr == SoundHandler.missing_sound) {
logger.warn("Unable to play empty soundEvent(2): {}", etr.getSoundPoolEntryLocation().toString());
}else {
ResourceLocation lc = etr.getSoundPoolEntryLocation();
IAudioResource trk = PlatformAudio.loadAudioData(
"/assets/" + lc.getResourceDomain() + "/" + lc.getResourcePath(), !etr.isStreamingSound());
if(trk == null) {
logger.warn("Unable to play unknown soundEvent(3): {}", sound.getSoundLocation().toString());
}else {
ActiveSoundEvent newSound = new ActiveSoundEvent(this, sound, accessor.getSoundCategory(), etr, null);
float pitch = MathHelper.clamp_float(newSound.activePitch * (float)etr.getPitch(), 0.5f, 2.0f);
float attenuatedGain = newSound.activeGain * categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
(accessor.getSoundCategory() == SoundCategory.MASTER ? 1.0f :
categoryVolumes[accessor.getSoundCategory().getCategoryId()]) * (float)etr.getVolume();
AttenuationType tp = sound.getAttenuationType();
if(tp == AttenuationType.LINEAR) {
newSound.soundHandle = PlatformAudio.beginPlayback(trk, newSound.activeX, newSound.activeY,
newSound.activeZ, attenuatedGain, pitch);
}else {
newSound.soundHandle = PlatformAudio.beginPlaybackStatic(trk, attenuatedGain, pitch);
}
if(newSound.soundHandle == null) {
logger.error("Unable to play soundEvent(4): {}", sound.getSoundLocation().toString());
}else {
activeSounds.add(newSound);
}
}
}
}
}
}
public void playDelayedSound(ISound sound, int delay) {
queuedSounds.add(new WaitingSoundEvent(sound, delay));
}
public void setListener(EntityPlayer player, float partialTicks) {
if(!PlatformAudio.available()) {
return;
}
if(player != null) {
try {
float f = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * partialTicks;
float f1 = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * partialTicks;
double d0 = player.prevPosX + (player.posX - player.prevPosX) * (double) partialTicks;
double d1 = player.prevPosY + (player.posY - player.prevPosY) * (double) partialTicks + (double) player.getEyeHeight();
double d2 = player.prevPosZ + (player.posZ - player.prevPosZ) * (double) partialTicks;
PlatformAudio.setListener((float)d0, (float)d1, (float)d2, f, f1);
}catch(Throwable t) {
// eaglercraft 1.5.2 had Infinity/NaN crashes for this function which
// couldn't be resolved via if statement checks in the above variables
}
}
}
}

View File

@ -0,0 +1,232 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.crypto.MD5Digest;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglercraftUUID implements Comparable<EaglercraftUUID> {
public final long msb;
public final long lsb;
public EaglercraftUUID(long msb, long lsb) {
this.msb = msb;
this.lsb = lsb;
}
public EaglercraftUUID(byte[] uuid) {
long msb = 0;
long lsb = 0;
for (int i = 0; i < 8; i++)
msb = (msb << 8) | (uuid[i] & 0xff);
for (int i = 8; i < 16; i++)
lsb = (lsb << 8) | (uuid[i] & 0xff);
this.msb = msb;
this.lsb = lsb;
}
public EaglercraftUUID(String uuid) {
String[] components = uuid.split("-");
if (components.length != 5)
throw new IllegalArgumentException("Invalid UUID string: " + uuid);
for (int i = 0; i < 5; i++)
components[i] = "0x" + components[i];
long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]).longValue();
long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]).longValue();
this.msb = mostSigBits;
this.lsb = leastSigBits;
}
private static byte long7(long x) {
return (byte) (x >> 56);
}
private static byte long6(long x) {
return (byte) (x >> 48);
}
private static byte long5(long x) {
return (byte) (x >> 40);
}
private static byte long4(long x) {
return (byte) (x >> 32);
}
private static byte long3(long x) {
return (byte) (x >> 24);
}
private static byte long2(long x) {
return (byte) (x >> 16);
}
private static byte long1(long x) {
return (byte) (x >> 8);
}
private static byte long0(long x) {
return (byte) (x);
}
public byte[] getBytes() {
byte[] ret = new byte[16];
ret[0] = long7(msb);
ret[1] = long6(msb);
ret[2] = long5(msb);
ret[3] = long4(msb);
ret[4] = long3(msb);
ret[5] = long2(msb);
ret[6] = long1(msb);
ret[7] = long0(msb);
ret[8] = long7(lsb);
ret[9] = long6(lsb);
ret[10] = long5(lsb);
ret[11] = long4(lsb);
ret[12] = long3(lsb);
ret[13] = long2(lsb);
ret[14] = long1(lsb);
ret[15] = long0(lsb);
return ret;
}
@Override
public String toString() {
return (digits(msb >> 32, 8) + "-" + digits(msb >> 16, 4) + "-" + digits(msb, 4) + "-" + digits(lsb >> 48, 4)
+ "-" + digits(lsb, 12));
}
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
@Override
public int hashCode() {
long hilo = msb ^ lsb;
return ((int) (hilo >> 32)) ^ (int) hilo;
}
@Override
public boolean equals(Object o) {
return (o instanceof EaglercraftUUID) && ((EaglercraftUUID) o).lsb == lsb && ((EaglercraftUUID) o).msb == msb;
}
public long getMostSignificantBits() {
return msb;
}
public long getLeastSignificantBits() {
return lsb;
}
private static final String HEX = "0123456789ABCDEF";
private static int nibbleValue(char c) {
int v = HEX.indexOf(Character.toUpperCase(c));
if (v == -1) {
return 0;
} else {
return v;
}
}
private static long parse4Nibbles(String name, int pos) {
int ch1 = nibbleValue(name.charAt(pos));
int ch2 = nibbleValue(name.charAt(pos + 1));
int ch3 = nibbleValue(name.charAt(pos + 2));
int ch4 = nibbleValue(name.charAt(pos + 3));
return (ch1 << 12) | (ch2 << 8) | (ch3 << 4) | ch4;
}
public static EaglercraftUUID fromString(String name) {
if (name.length() == 36) {
char ch1 = name.charAt(8);
char ch2 = name.charAt(13);
char ch3 = name.charAt(18);
char ch4 = name.charAt(23);
if (ch1 == '-' && ch2 == '-' && ch3 == '-' && ch4 == '-') {
long msb1 = parse4Nibbles(name, 0);
long msb2 = parse4Nibbles(name, 4);
long msb3 = parse4Nibbles(name, 9);
long msb4 = parse4Nibbles(name, 14);
long lsb1 = parse4Nibbles(name, 19);
long lsb2 = parse4Nibbles(name, 24);
long lsb3 = parse4Nibbles(name, 28);
long lsb4 = parse4Nibbles(name, 32);
if ((msb1 | msb2 | msb3 | msb4 | lsb1 | lsb2 | lsb3 | lsb4) >= 0) {
return new EaglercraftUUID(msb1 << 48 | msb2 << 32 | msb3 << 16 | msb4,
lsb1 << 48 | lsb2 << 32 | lsb3 << 16 | lsb4);
}
}
}
return fromString1(name);
}
private static EaglercraftUUID fromString1(String name) {
int len = name.length();
if (len > 36) {
throw new IllegalArgumentException("UUID string too large");
}
int dash1 = name.indexOf('-', 0);
int dash2 = name.indexOf('-', dash1 + 1);
int dash3 = name.indexOf('-', dash2 + 1);
int dash4 = name.indexOf('-', dash3 + 1);
int dash5 = name.indexOf('-', dash4 + 1);
if (dash4 < 0 || dash5 >= 0) {
throw new IllegalArgumentException("Invalid UUID string: " + name);
}
long mostSigBits = JDKBackports.parseLong(name, 0, dash1, 16) & 0xffffffffL;
mostSigBits <<= 16;
mostSigBits |= JDKBackports.parseLong(name, dash1 + 1, dash2, 16) & 0xffffL;
mostSigBits <<= 16;
mostSigBits |= JDKBackports.parseLong(name, dash2 + 1, dash3, 16) & 0xffffL;
long leastSigBits = JDKBackports.parseLong(name, dash3 + 1, dash4, 16) & 0xffffL;
leastSigBits <<= 48;
leastSigBits |= JDKBackports.parseLong(name, dash4 + 1, len, 16) & 0xffffffffffffL;
return new EaglercraftUUID(mostSigBits, leastSigBits);
}
public static EaglercraftUUID nameUUIDFromBytes(byte[] bytes) {
MD5Digest dg = new MD5Digest();
dg.update(bytes, 0, bytes.length);
byte[] md5Bytes = new byte[16];
dg.doFinal(md5Bytes, 0);
md5Bytes[6] &= 0x0f;
md5Bytes[6] |= 0x30;
md5Bytes[8] &= 0x3f;
md5Bytes[8] |= 0x80;
return new EaglercraftUUID(md5Bytes);
}
@Override
public int compareTo(EaglercraftUUID val) {
return (this.msb < val.msb ? -1
: (this.msb > val.msb ? 1 : (this.lsb < val.lsb ? -1 : (this.lsb > val.lsb ? 1 : 0))));
}
}

View File

@ -0,0 +1,46 @@
package net.lax1dude.eaglercraft.v1_8;
public class EaglercraftVersion {
//////////////////////////////////////////////////////////////////////
/// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u0";
public static final String projectForkVendor = "lax1dude";
public static final String projectForkURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
//////////////////////////////////////////////////////////////////////
// Do not change these, they must stay as credit to lax1dude's
// original repository for maintaining the project:
public static final String projectOriginName = "EaglercraftX";
public static final String projectOriginAuthor = "lax1dude";
public static final String projectOriginRevision = "1.8";
public static final String projectOriginVersion = "u0";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8";
// Miscellaneous variables:
public static final String mainMenuStringA = "Minecraft 1.8.8";
public static final String mainMenuStringB = projectOriginName + " " +
projectOriginRevision + "-" + projectOriginVersion;
public static final String mainMenuStringC = "Rewritten by " + projectOriginAuthor;
public static final String mainMenuStringD = "Resources Copyright Mojang AB";
public static final String mainMenuStringE = projectForkName + " " + projectForkVersion;
public static final String mainMenuStringF = "Made by " + projectForkVendor;
public static final boolean mainMenuEnableGithubButton = true;
}

View File

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EncoderException extends RuntimeException {
public EncoderException() {
super();
}
public EncoderException(String message, Throwable cause) {
super(message, cause);
}
public EncoderException(String message) {
super(message);
}
public EncoderException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,26 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class ExceptionUtils {
public static Throwable getRootCause(Throwable exception) {
Throwable t2;
while((t2 = exception.getCause()) != null) {
exception = t2;
}
return exception;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class HString {
public static String format(String format, Object... args) {
return new HFormatter().format(format, args).toString();
}
}

View File

@ -0,0 +1,72 @@
package net.lax1dude.eaglercraft.v1_8;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class IOUtils {
public static List<String> readLines(InputStream parInputStream, Charset charset) {
if(parInputStream instanceof EaglerInputStream) {
return Arrays.asList(
new String(((EaglerInputStream) parInputStream).getAsArray(), charset).split("(\\r\\n|\\n|\\r)"));
}else {
List<String> ret = new ArrayList();
try(InputStream is = parInputStream) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, charset));
String s;
while((s = rd.readLine()) != null) {
ret.add(s);
}
}catch(IOException ex) {
return null;
}
return ret;
}
}
public static void closeQuietly(Closeable reResourcePack) {
try {
reResourcePack.close();
}catch(Throwable t) {
}
}
public static String inputStreamToString(InputStream is, Charset c) throws IOException {
if(is instanceof EaglerInputStream) {
return new String(((EaglerInputStream)is).getAsArray(), c);
}else {
try {
StringBuilder b = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, c));
String s;
while((s = rd.readLine()) != null) {
b.append(s).append('\n');
}
return b.toString();
}finally {
is.close();
}
}
}
}

View File

@ -0,0 +1,88 @@
package net.lax1dude.eaglercraft.v1_8;
import java.util.function.Supplier;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class JDKBackports {
public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) {
throw new IndexOutOfBoundsException();
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
}
boolean negative = false;
int i = beginIndex;
long limit = -Long.MAX_VALUE;
if (i < endIndex) {
char firstChar = s.charAt(i);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Long.MIN_VALUE;
} else if (firstChar != '+') {
throw new NumberFormatException();
}
i++;
}
if (i >= endIndex) { // Cannot have lone "+", "-" or ""
throw new NumberFormatException();
}
long multmin = limit / radix;
long result = 0;
while (i < endIndex) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i), radix);
if (digit < 0 || result < multmin) {
throw new NumberFormatException();
}
result *= radix;
if (result < limit + digit) {
throw new NumberFormatException();
}
i++;
result -= digit;
}
return negative ? result : -result;
} else {
throw new NumberFormatException("");
}
}
public static <T> T javaUtilObject_requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier.get());
return obj;
}
public static <T> T javaUtilObject_requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
public static <T> T javaUtilObject_requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
}

View File

@ -0,0 +1,61 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.KeyboardConstants;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class Keyboard {
public static void enableRepeatEvents(boolean b) {
PlatformInput.keyboardEnableRepeatEvents(b);
}
public static boolean isCreated() {
return true;
}
public static boolean next() {
return PlatformInput.keyboardNext();
}
public static boolean getEventKeyState() {
return PlatformInput.keyboardGetEventKeyState();
}
public static char getEventCharacter() {
return PlatformInput.keyboardGetEventCharacter();
}
public static int getEventKey() {
return PlatformInput.keyboardGetEventKey();
}
public static void setFunctionKeyModifier(int key) {
PlatformInput.setFunctionKeyModifier(key);
}
public static boolean isKeyDown(int key) {
return PlatformInput.keyboardIsKeyDown(key);
}
public static String getKeyName(int key) {
return KeyboardConstants.getKeyName(key);
}
public static boolean isRepeatEvent() {
return PlatformInput.keyboardIsRepeatEvent();
}
}

View File

@ -0,0 +1,92 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class Mouse {
public static int getEventDWheel() {
return PlatformInput.mouseGetEventDWheel();
}
public static int getX() {
return PlatformInput.mouseGetX();
}
public static int getY() {
return PlatformInput.mouseGetY();
}
public static boolean getEventButtonState() {
return PlatformInput.mouseGetEventButtonState();
}
public static boolean isCreated() {
return true;
}
public static boolean next() {
return PlatformInput.mouseNext();
}
public static int getEventX() {
return PlatformInput.mouseGetEventX();
}
public static int getEventY() {
return PlatformInput.mouseGetEventY();
}
public static int getEventButton() {
return PlatformInput.mouseGetEventButton();
}
public static boolean isButtonDown(int i) {
return PlatformInput.mouseIsButtonDown(i);
}
public static int getDWheel() {
return PlatformInput.mouseGetDWheel();
}
public static void setGrabbed(boolean grab) {
PlatformInput.mouseSetGrabbed(grab);
}
public static int getDX() {
return PlatformInput.mouseGetDX();
}
public static int getDY() {
return PlatformInput.mouseGetDY();
}
public static void setCursorPosition(int x, int y) {
PlatformInput.mouseSetCursorPosition(x, y);
}
public static boolean isInsideWindow() {
return PlatformInput.mouseIsInsideWindow();
}
public static boolean isActuallyGrabbed() {
return PlatformInput.isPointerLocked();
}
public static boolean isMouseGrabbed() {
return PlatformInput.isMouseGrabbed();
}
}

View File

@ -0,0 +1,24 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class ThreadLocalRandom {
private static final EaglercraftRandom rand = new EaglercraftRandom();
public static EaglercraftRandom current() {
return rand;
}
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.cache;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface EaglerCacheProvider<K, V> {
V create(K key);
}

View File

@ -0,0 +1,38 @@
package net.lax1dude.eaglercraft.v1_8.cache;
import java.util.HashMap;
import java.util.Map;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglerLoadingCache<K, V> {
private final EaglerCacheProvider<K, V> provider;
private final Map<K, V> cacheMap;
public EaglerLoadingCache(EaglerCacheProvider<K, V> provider) {
this.provider = provider;
this.cacheMap = new HashMap();
}
public V get(K key) {
V etr = cacheMap.get(key);
if(etr == null) {
etr = provider.create(key);
cacheMap.put(key, etr);
}
return etr;
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
package net.lax1dude.eaglercraft.v1_8.crypto;
/**
* base implementation of MD4 family style digest as outlined in "Handbook of
* Applied Cryptography", pages 344 - 347.
*/
public abstract class GeneralDigest {
private byte[] xBuf;
private int xBufOff;
private long byteCount;
/**
* Standard constructor
*/
protected GeneralDigest() {
xBuf = new byte[4];
xBufOff = 0;
}
/**
* Copy constructor. We are using copy constructors in place of the
* Object.clone() interface as this interface is not supported by J2ME.
*/
protected GeneralDigest(GeneralDigest t) {
xBuf = new byte[t.xBuf.length];
System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
xBufOff = t.xBufOff;
byteCount = t.byteCount;
}
public void update(byte in) {
xBuf[xBufOff++] = in;
if (xBufOff == xBuf.length) {
processWord(xBuf, 0);
xBufOff = 0;
}
byteCount++;
}
public void update(byte[] in, int inOff, int len) {
//
// fill the current word
//
while ((xBufOff != 0) && (len > 0)) {
update(in[inOff]);
inOff++;
len--;
}
//
// process whole words.
//
while (len > xBuf.length) {
processWord(in, inOff);
inOff += xBuf.length;
len -= xBuf.length;
byteCount += xBuf.length;
}
//
// load in the remainder.
//
while (len > 0) {
update(in[inOff]);
inOff++;
len--;
}
}
public void finish() {
long bitLength = (byteCount << 3);
//
// add the pad bytes.
//
update((byte) 128);
while (xBufOff != 0) {
update((byte) 0);
}
processLength(bitLength);
processBlock();
}
public void reset() {
byteCount = 0;
xBufOff = 0;
for (int i = 0; i < xBuf.length; i++) {
xBuf[i] = 0;
}
}
protected abstract void processWord(byte[] in, int inOff);
protected abstract void processLength(long bitLength);
protected abstract void processBlock();
}

View File

@ -0,0 +1,265 @@
/*
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
package net.lax1dude.eaglercraft.v1_8.crypto;
/**
* implementation of MD5 as outlined in "Handbook of Applied Cryptography",
* pages 346 - 347.
*/
public class MD5Digest extends GeneralDigest {
private static final int DIGEST_LENGTH = 16;
private int H1, H2, H3, H4; // IV's
private int[] X = new int[16];
private int xOff;
/**
* Standard constructor
*/
public MD5Digest() {
reset();
}
public String getAlgorithmName() {
return "MD5";
}
public int getDigestSize() {
return DIGEST_LENGTH;
}
protected void processWord(byte[] in, int inOff) {
X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8) | ((in[inOff + 2] & 0xff) << 16)
| ((in[inOff + 3] & 0xff) << 24);
if (xOff == 16) {
processBlock();
}
}
protected void processLength(long bitLength) {
if (xOff > 14) {
processBlock();
}
X[14] = (int) (bitLength & 0xffffffff);
X[15] = (int) (bitLength >>> 32);
}
private void unpackWord(int word, byte[] out, int outOff) {
out[outOff] = (byte) word;
out[outOff + 1] = (byte) (word >>> 8);
out[outOff + 2] = (byte) (word >>> 16);
out[outOff + 3] = (byte) (word >>> 24);
}
public int doFinal(byte[] out, int outOff) {
finish();
unpackWord(H1, out, outOff);
unpackWord(H2, out, outOff + 4);
unpackWord(H3, out, outOff + 8);
unpackWord(H4, out, outOff + 12);
reset();
return DIGEST_LENGTH;
}
/**
* reset the chaining variables to the IV values.
*/
public void reset() {
super.reset();
H1 = 0x67452301;
H2 = 0xefcdab89;
H3 = 0x98badcfe;
H4 = 0x10325476;
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
//
// round 1 left rotates
//
private static final int S11 = 7;
private static final int S12 = 12;
private static final int S13 = 17;
private static final int S14 = 22;
//
// round 2 left rotates
//
private static final int S21 = 5;
private static final int S22 = 9;
private static final int S23 = 14;
private static final int S24 = 20;
//
// round 3 left rotates
//
private static final int S31 = 4;
private static final int S32 = 11;
private static final int S33 = 16;
private static final int S34 = 23;
//
// round 4 left rotates
//
private static final int S41 = 6;
private static final int S42 = 10;
private static final int S43 = 15;
private static final int S44 = 21;
/*
* rotate int x left n bits.
*/
private int rotateLeft(int x, int n) {
return (x << n) | (x >>> (32 - n));
}
/*
* F, G, H and I are the basic MD5 functions.
*/
private int F(int u, int v, int w) {
return (u & v) | (~u & w);
}
private int G(int u, int v, int w) {
return (u & w) | (v & ~w);
}
private int H(int u, int v, int w) {
return u ^ v ^ w;
}
private int K(int u, int v, int w) {
return v ^ (u | ~w);
}
protected void processBlock() {
int a = H1;
int b = H2;
int c = H3;
int d = H4;
//
// Round 1 - F cycle, 16 times.
//
a = rotateLeft(a + F(b, c, d) + X[0] + 0xd76aa478, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[1] + 0xe8c7b756, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[2] + 0x242070db, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[3] + 0xc1bdceee, S14) + c;
a = rotateLeft(a + F(b, c, d) + X[4] + 0xf57c0faf, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[5] + 0x4787c62a, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[6] + 0xa8304613, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[7] + 0xfd469501, S14) + c;
a = rotateLeft(a + F(b, c, d) + X[8] + 0x698098d8, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[9] + 0x8b44f7af, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[10] + 0xffff5bb1, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[11] + 0x895cd7be, S14) + c;
a = rotateLeft(a + F(b, c, d) + X[12] + 0x6b901122, S11) + b;
d = rotateLeft(d + F(a, b, c) + X[13] + 0xfd987193, S12) + a;
c = rotateLeft(c + F(d, a, b) + X[14] + 0xa679438e, S13) + d;
b = rotateLeft(b + F(c, d, a) + X[15] + 0x49b40821, S14) + c;
//
// Round 2 - G cycle, 16 times.
//
a = rotateLeft(a + G(b, c, d) + X[1] + 0xf61e2562, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[6] + 0xc040b340, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[11] + 0x265e5a51, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[0] + 0xe9b6c7aa, S24) + c;
a = rotateLeft(a + G(b, c, d) + X[5] + 0xd62f105d, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[10] + 0x02441453, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[15] + 0xd8a1e681, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[4] + 0xe7d3fbc8, S24) + c;
a = rotateLeft(a + G(b, c, d) + X[9] + 0x21e1cde6, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[14] + 0xc33707d6, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[3] + 0xf4d50d87, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[8] + 0x455a14ed, S24) + c;
a = rotateLeft(a + G(b, c, d) + X[13] + 0xa9e3e905, S21) + b;
d = rotateLeft(d + G(a, b, c) + X[2] + 0xfcefa3f8, S22) + a;
c = rotateLeft(c + G(d, a, b) + X[7] + 0x676f02d9, S23) + d;
b = rotateLeft(b + G(c, d, a) + X[12] + 0x8d2a4c8a, S24) + c;
//
// Round 3 - H cycle, 16 times.
//
a = rotateLeft(a + H(b, c, d) + X[5] + 0xfffa3942, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[8] + 0x8771f681, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[11] + 0x6d9d6122, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[14] + 0xfde5380c, S34) + c;
a = rotateLeft(a + H(b, c, d) + X[1] + 0xa4beea44, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[4] + 0x4bdecfa9, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[7] + 0xf6bb4b60, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[10] + 0xbebfbc70, S34) + c;
a = rotateLeft(a + H(b, c, d) + X[13] + 0x289b7ec6, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[0] + 0xeaa127fa, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[3] + 0xd4ef3085, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[6] + 0x04881d05, S34) + c;
a = rotateLeft(a + H(b, c, d) + X[9] + 0xd9d4d039, S31) + b;
d = rotateLeft(d + H(a, b, c) + X[12] + 0xe6db99e5, S32) + a;
c = rotateLeft(c + H(d, a, b) + X[15] + 0x1fa27cf8, S33) + d;
b = rotateLeft(b + H(c, d, a) + X[2] + 0xc4ac5665, S34) + c;
//
// Round 4 - K cycle, 16 times.
//
a = rotateLeft(a + K(b, c, d) + X[0] + 0xf4292244, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[7] + 0x432aff97, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[14] + 0xab9423a7, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[5] + 0xfc93a039, S44) + c;
a = rotateLeft(a + K(b, c, d) + X[12] + 0x655b59c3, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[3] + 0x8f0ccc92, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[10] + 0xffeff47d, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[1] + 0x85845dd1, S44) + c;
a = rotateLeft(a + K(b, c, d) + X[8] + 0x6fa87e4f, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[15] + 0xfe2ce6e0, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[6] + 0xa3014314, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[13] + 0x4e0811a1, S44) + c;
a = rotateLeft(a + K(b, c, d) + X[4] + 0xf7537e82, S41) + b;
d = rotateLeft(d + K(a, b, c) + X[11] + 0xbd3af235, S42) + a;
c = rotateLeft(c + K(d, a, b) + X[2] + 0x2ad7d2bb, S43) + d;
b = rotateLeft(b + K(c, d, a) + X[9] + 0xeb86d391, S44) + c;
H1 += a;
H2 += b;
H3 += c;
H4 += d;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
}

View File

@ -0,0 +1,234 @@
/*
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
package net.lax1dude.eaglercraft.v1_8.crypto;
/**
* implementation of SHA-1 as outlined in "Handbook of Applied Cryptography",
* pages 346 - 349.
*
* It is interesting to ponder why the, apart from the extra IV, the other
* difference here from MD5 is the "endienness" of the word processing!
*/
public class SHA1Digest extends GeneralDigest {
private static final int DIGEST_LENGTH = 20;
private int H1, H2, H3, H4, H5;
private int[] X = new int[80];
private int xOff;
/**
* Standard constructor
*/
public SHA1Digest() {
reset();
}
/**
* Copy constructor. This will copy the state of the provided message digest.
*/
public SHA1Digest(SHA1Digest t) {
super(t);
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
H4 = t.H4;
H5 = t.H5;
System.arraycopy(t.X, 0, X, 0, t.X.length);
xOff = t.xOff;
}
public String getAlgorithmName() {
return "SHA-1";
}
public int getDigestSize() {
return DIGEST_LENGTH;
}
protected void processWord(byte[] in, int inOff) {
X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16) | ((in[inOff + 2] & 0xff) << 8)
| ((in[inOff + 3] & 0xff));
if (xOff == 16) {
processBlock();
}
}
private void unpackWord(int word, byte[] out, int outOff) {
out[outOff] = (byte) (word >>> 24);
out[outOff + 1] = (byte) (word >>> 16);
out[outOff + 2] = (byte) (word >>> 8);
out[outOff + 3] = (byte) word;
}
protected void processLength(long bitLength) {
if (xOff > 14) {
processBlock();
}
X[14] = (int) (bitLength >>> 32);
X[15] = (int) (bitLength & 0xffffffff);
}
public int doFinal(byte[] out, int outOff) {
finish();
unpackWord(H1, out, outOff);
unpackWord(H2, out, outOff + 4);
unpackWord(H3, out, outOff + 8);
unpackWord(H4, out, outOff + 12);
unpackWord(H5, out, outOff + 16);
reset();
return DIGEST_LENGTH;
}
/**
* reset the chaining variables
*/
public void reset() {
super.reset();
H1 = 0x67452301;
H2 = 0xefcdab89;
H3 = 0x98badcfe;
H4 = 0x10325476;
H5 = 0xc3d2e1f0;
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
//
// Additive constants
//
private static final int Y1 = 0x5a827999;
private static final int Y2 = 0x6ed9eba1;
private static final int Y3 = 0x8f1bbcdc;
private static final int Y4 = 0xca62c1d6;
private int f(int u, int v, int w) {
return ((u & v) | ((~u) & w));
}
private int h(int u, int v, int w) {
return (u ^ v ^ w);
}
private int g(int u, int v, int w) {
return ((u & v) | (u & w) | (v & w));
}
private int rotateLeft(int x, int n) {
return (x << n) | (x >>> (32 - n));
}
protected void processBlock() {
//
// expand 16 word block into 80 word block.
//
for (int i = 16; i <= 79; i++) {
X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
}
//
// set up working variables.
//
int A = H1;
int B = H2;
int C = H3;
int D = H4;
int E = H5;
//
// round 1
//
for (int j = 0; j <= 19; j++) {
int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
//
// round 2
//
for (int j = 20; j <= 39; j++) {
int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
//
// round 3
//
for (int j = 40; j <= 59; j++) {
int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
//
// round 4
//
for (int j = 60; j <= 79; j++) {
int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
E = D;
D = C;
C = rotateLeft(B, 30);
B = A;
A = t;
}
H1 += A;
H2 += B;
H3 += C;
H4 += D;
H5 += E;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
}

View File

@ -0,0 +1,254 @@
/*
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
package net.lax1dude.eaglercraft.v1_8.crypto;
public class SHA256Digest extends GeneralDigest {
private static final int DIGEST_LENGTH = 32;
private int H1, H2, H3, H4, H5, H6, H7, H8;
private int[] X = new int[64];
private int xOff;
public SHA256Digest() {
reset();
}
public static int bigEndianToInt(byte[] bs, int off) {
int n = bs[off] << 24;
n |= (bs[++off] & 0xff) << 16;
n |= (bs[++off] & 0xff) << 8;
n |= (bs[++off] & 0xff);
return n;
}
public static void bigEndianToInt(byte[] bs, int off, int[] ns) {
for (int i = 0; i < ns.length; ++i) {
ns[i] = bigEndianToInt(bs, off);
off += 4;
}
}
public static byte[] intToBigEndian(int n) {
byte[] bs = new byte[4];
intToBigEndian(n, bs, 0);
return bs;
}
public static void intToBigEndian(int n, byte[] bs, int off) {
bs[off] = (byte) (n >>> 24);
bs[++off] = (byte) (n >>> 16);
bs[++off] = (byte) (n >>> 8);
bs[++off] = (byte) (n);
}
protected void processWord(byte[] in, int inOff) {
X[xOff] = bigEndianToInt(in, inOff);
if (++xOff == 16) {
processBlock();
}
}
protected void processLength(long bitLength) {
if (xOff > 14) {
processBlock();
}
X[14] = (int) (bitLength >>> 32);
X[15] = (int) (bitLength & 0xffffffff);
}
public int doFinal(byte[] out, int outOff) {
finish();
intToBigEndian(H1, out, outOff);
intToBigEndian(H2, out, outOff + 4);
intToBigEndian(H3, out, outOff + 8);
intToBigEndian(H4, out, outOff + 12);
intToBigEndian(H5, out, outOff + 16);
intToBigEndian(H6, out, outOff + 20);
intToBigEndian(H7, out, outOff + 24);
intToBigEndian(H8, out, outOff + 28);
reset();
return DIGEST_LENGTH;
}
/**
* reset the chaining variables
*/
public void reset() {
super.reset();
/*
* SHA-256 initial hash value The first 32 bits of the fractional parts of the
* square roots of the first eight prime numbers
*/
H1 = 0x6a09e667;
H2 = 0xbb67ae85;
H3 = 0x3c6ef372;
H4 = 0xa54ff53a;
H5 = 0x510e527f;
H6 = 0x9b05688c;
H7 = 0x1f83d9ab;
H8 = 0x5be0cd19;
xOff = 0;
for (int i = 0; i != X.length; i++) {
X[i] = 0;
}
}
protected void processBlock() {
//
// expand 16 word block into 64 word blocks.
//
for (int t = 16; t <= 63; t++) {
X[t] = Theta1(X[t - 2]) + X[t - 7] + Theta0(X[t - 15]) + X[t - 16];
}
//
// set up working variables.
//
int a = H1;
int b = H2;
int c = H3;
int d = H4;
int e = H5;
int f = H6;
int g = H7;
int h = H8;
int t = 0;
for (int i = 0; i < 8; i++) {
// t = 8 * i
h += Sum1(e) + Ch(e, f, g) + K[t] + X[t];
d += h;
h += Sum0(a) + Maj(a, b, c);
++t;
// t = 8 * i + 1
g += Sum1(d) + Ch(d, e, f) + K[t] + X[t];
c += g;
g += Sum0(h) + Maj(h, a, b);
++t;
// t = 8 * i + 2
f += Sum1(c) + Ch(c, d, e) + K[t] + X[t];
b += f;
f += Sum0(g) + Maj(g, h, a);
++t;
// t = 8 * i + 3
e += Sum1(b) + Ch(b, c, d) + K[t] + X[t];
a += e;
e += Sum0(f) + Maj(f, g, h);
++t;
// t = 8 * i + 4
d += Sum1(a) + Ch(a, b, c) + K[t] + X[t];
h += d;
d += Sum0(e) + Maj(e, f, g);
++t;
// t = 8 * i + 5
c += Sum1(h) + Ch(h, a, b) + K[t] + X[t];
g += c;
c += Sum0(d) + Maj(d, e, f);
++t;
// t = 8 * i + 6
b += Sum1(g) + Ch(g, h, a) + K[t] + X[t];
f += b;
b += Sum0(c) + Maj(c, d, e);
++t;
// t = 8 * i + 7
a += Sum1(f) + Ch(f, g, h) + K[t] + X[t];
e += a;
a += Sum0(b) + Maj(b, c, d);
++t;
}
H1 += a;
H2 += b;
H3 += c;
H4 += d;
H5 += e;
H6 += f;
H7 += g;
H8 += h;
//
// reset the offset and clean out the word buffer.
//
xOff = 0;
for (int i = 0; i < 16; i++) {
X[i] = 0;
}
}
/* SHA-256 functions */
private static int Ch(int x, int y, int z) {
return (x & y) ^ ((~x) & z);
// return z ^ (x & (y ^ z));
}
private static int Maj(int x, int y, int z) {
// return (x & y) ^ (x & z) ^ (y & z);
return (x & y) | (z & (x ^ y));
}
private static int Sum0(int x) {
return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
}
private static int Sum1(int x) {
return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
}
private static int Theta0(int x) {
return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
}
private static int Theta1(int x) {
return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10);
}
/*
* SHA-256 Constants (represent the first 32 bits of the fractional parts of the
* cube roots of the first sixty-four prime numbers)
*/
static final int K[] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138,
0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70,
0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa,
0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
}

View File

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8.futures;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class CancellationException extends IllegalStateException {
public CancellationException() {
}
public CancellationException(String s) {
super(s);
}
public CancellationException(String message, Throwable cause) {
super(message, cause);
}
public CancellationException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,33 @@
package net.lax1dude.eaglercraft.v1_8.futures;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class ExecutionException extends RuntimeException {
public ExecutionException() {
}
public ExecutionException(String message, Throwable cause) {
super(message, cause);
}
public ExecutionException(String message) {
super(message);
}
public ExecutionException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,47 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.Callable;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class Executors {
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
public static Callable<Object> callable(Runnable task) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<Object>(task, null);
}
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
}

View File

@ -0,0 +1,29 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.TimeUnit;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException;
}

View File

@ -0,0 +1,87 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class FutureTask<V> implements RunnableFuture<V> {
private boolean cancelled;
private boolean completed;
private V result;
private Callable<V> callable;
public FutureTask(Callable<V> callable) {
this.callable = callable;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if(!cancelled) {
cancelled = true;
if(!completed) {
done();
}
}
return true;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public boolean isDone() {
return cancelled || completed;
}
@Override
public V get() throws InterruptedException, ExecutionException {
if(!completed) {
if(!cancelled) {
try {
result = callable.call();
}catch(Throwable t) {
throw new ExecutionException(t);
}finally {
completed = true;
done();
}
}
}
return result;
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException {
return get();
}
@Override
public void run() {
try {
get();
} catch (ExecutionException t) {
throw t;
} catch (Throwable t) {
throw new ExecutionException(t);
}
}
protected void done() {
}
}

View File

@ -0,0 +1,129 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class Futures {
private abstract static class ImmediateFuture<V> implements ListenableFuture<V> {
private static final Logger log = LogManager.getLogger(ImmediateFuture.class.getName());
@Override
public void addListener(Runnable listener, Executor executor) {
checkNotNull(listener, "Runnable was null.");
checkNotNull(executor, "Executor was null.");
try {
executor.execute(listener);
} catch (RuntimeException e) {
log.error("RuntimeException while executing runnable " + listener + " with executor " + executor, e);
}
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public abstract V get() throws ExecutionException;
@Override
public V get(long timeout, TimeUnit unit) throws ExecutionException {
checkNotNull(unit);
return get();
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return true;
}
}
private static class ImmediateSuccessfulFuture<V> extends ImmediateFuture<V> {
@Nullable
private final V value;
ImmediateSuccessfulFuture(@Nullable V value) {
this.value = value;
}
@Override
public V get() {
return value;
}
}
private static class ImmediateFailedFuture<V> extends ImmediateFuture<V> {
private final Throwable thrown;
ImmediateFailedFuture(Throwable thrown) {
this.thrown = thrown;
}
@Override
public V get() throws ExecutionException {
throw new ExecutionException(thrown);
}
}
private static class ImmediateCancelledFuture<V> extends ImmediateFuture<V> {
private final CancellationException thrown;
ImmediateCancelledFuture() {
this.thrown = new CancellationException("Immediate cancelled future.");
}
@Override
public boolean isCancelled() {
return true;
}
@Override
public V get() {
throw new CancellationException("Task was cancelled.", thrown);
}
}
public static <V> ListenableFuture<V> immediateFuture(@Nullable V value) {
return new ImmediateSuccessfulFuture<V>(value);
}
public static <V> ListenableFuture<V> immediateFailedFuture(Throwable throwable) {
checkNotNull(throwable);
return new ImmediateFailedFuture<V>(throwable);
}
public static <V> ListenableFuture<V> immediateCancelledFuture() {
return new ImmediateCancelledFuture<V>();
}
}

View File

@ -0,0 +1,27 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.Executor;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface ListenableFuture<V> extends Future<V> {
static final Logger futureExceptionLogger = LogManager.getLogger("ListenableFuture");
void addListener(Runnable listener, Executor executor);
}

View File

@ -0,0 +1,57 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class ListenableFutureTask<V> extends FutureTask<V> implements ListenableFuture<V> {
private final List<Runnable> listeners = new ArrayList();
public ListenableFutureTask(Callable<V> callable) {
super(callable);
}
@Override
public void addListener(final Runnable listener, final Executor executor) {
listeners.add(new Runnable() {
@Override
public void run() {
executor.execute(listener); // so dumb
}
});
}
protected void done() {
for(Runnable r : listeners) {
try {
r.run();
}catch(Throwable t) {
ListenableFuture.futureExceptionLogger.error("Exception caught running future listener!");
ListenableFuture.futureExceptionLogger.error(t);
}
}
listeners.clear();
}
public static <V> ListenableFutureTask<V> create(Callable<V> callableToSchedule) {
return new ListenableFutureTask(callableToSchedule);
}
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.Future;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}

View File

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum EnumEaglerConnectionState {
CLOSED(true, false), CONNECTING(false, false), CONNECTED(false, true), FAILED(true, false);
private final boolean typeClosed;
private final boolean typeOpen;
private EnumEaglerConnectionState(boolean typeClosed, boolean typeOpen) {
this.typeClosed = typeClosed;
this.typeOpen = typeOpen;
}
public boolean isClosed() {
return typeClosed;
}
public boolean isOpen() {
return typeOpen;
}
}

View File

@ -0,0 +1,72 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum EnumPlatformANGLE {
DEFAULT(225281 /* GLFW_ANGLE_PLATFORM_TYPE_NONE */, "default", "Default"),
D3D11(225285 /* GLFW_ANGLE_PLATFORM_TYPE_D3D11 */, "d3d11", "Direct3D11"),
OPENGL(225282 /* GLFW_ANGLE_PLATFORM_TYPE_OPENGL */, "opengl", "OpenGL"),
OPENGLES(225283 /* GLFW_ANGLE_PLATFORM_TYPE_OPENGLES */, "opengles", "OpenGL ES"),
METAL(225288 /* GLFW_ANGLE_PLATFORM_TYPE_METAL */, "metal", "Metal"),
VULKAN(225287 /* GLFW_ANGLE_PLATFORM_TYPE_VULKAN */, "vulkan", "Vulkan");
public final int eglEnum;
public final String id;
public final String name;
private EnumPlatformANGLE(int eglEnum, String id, String name) {
this.eglEnum = eglEnum;
this.id = id;
this.name = name;
}
public String toString() {
return id;
}
public static EnumPlatformANGLE fromId(String id) {
if(id.equals("d3d11") || id.equals("d3d") || id.equals("dx11")) {
return D3D11;
}else if(id.equals("opengl")) {
return OPENGL;
}else if(id.equals("opengles")) {
return OPENGLES;
}else if(id.equals("metal")) {
return METAL;
}else if(id.equals("vulkan")) {
return VULKAN;
}else {
return DEFAULT;
}
}
public static EnumPlatformANGLE fromGLRendererString(String str) {
str = str.toLowerCase();
if(str.contains("direct3d11") || str.contains("d3d11")) {
return D3D11;
}else if(str.contains("opengl es")) {
return OPENGLES;
}else if(str.contains("opengl")) {
return OPENGL;
}else if(str.contains("metal")) {
return METAL;
}else if(str.contains("vulkan")) {
return VULKAN;
}else {
return DEFAULT;
}
}
}

View File

@ -0,0 +1,60 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum EnumPlatformAgent {
DESKTOP("LWJGL3"), CHROME("Chrome"), EDGE("Edge"), IE("IE"),
FIREFOX("Firefox"), SAFARI("Safari"), OPERA("Opera"), WEBKIT("WebKit"),
GECKO("Gecko"), UNKNOWN("Unknown");
private final String name;
private EnumPlatformAgent(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
public static EnumPlatformAgent getFromUA(String ua) {
ua = " " + ua.toLowerCase();
if(ua.contains(" edg/")) {
return EDGE;
}else if(ua.contains(" opr/")) {
return OPERA;
}else if(ua.contains(" chrome/")) {
return CHROME;
}else if(ua.contains(" firefox/")) {
return FIREFOX;
}else if(ua.contains(" safari/")) {
return SAFARI;
}else if(ua.contains(" trident/") || ua.contains(" msie")) {
return IE;
}else if(ua.contains(" webkit/")) {
return WEBKIT;
}else if(ua.contains(" gecko/")) {
return GECKO;
}else if(ua.contains(" desktop/")) {
return DESKTOP;
}else {
return UNKNOWN;
}
}
}

View File

@ -0,0 +1,72 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import net.minecraft.util.Util;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum EnumPlatformOS {
WINDOWS("Windows", Util.EnumOS.WINDOWS), MACOS("MacOS", Util.EnumOS.OSX), LINUX("Linux", Util.EnumOS.LINUX),
CHROMEBOOK_LINUX("ChromeOS", Util.EnumOS.LINUX), OTHER("Unknown", Util.EnumOS.UNKNOWN);
private final String name;
private final Util.EnumOS minecraftEnum;
private EnumPlatformOS(String name, Util.EnumOS minecraftEnum) {
this.name = name;
this.minecraftEnum = minecraftEnum;
}
public String getName() {
return name;
}
public Util.EnumOS getMinecraftEnum() {
return minecraftEnum;
}
public String toString() {
return name;
}
public static EnumPlatformOS getFromJVM(String osNameProperty) {
osNameProperty = osNameProperty.toLowerCase();
if(osNameProperty.contains("chrome")) {
return CHROMEBOOK_LINUX;
}else if(osNameProperty.contains("linux")) {
return LINUX;
}else if(osNameProperty.contains("windows") || osNameProperty.contains("win32")) {
return WINDOWS;
}else if(osNameProperty.contains("macos") || osNameProperty.contains("osx")) {
return MACOS;
}else {
return OTHER;
}
}
public static EnumPlatformOS getFromUA(String ua) {
ua = " " + ua.toLowerCase();
if(ua.contains(" cros")) {
return CHROMEBOOK_LINUX;
}else if(ua.contains(" linux")) {
return LINUX;
}else if(ua.contains(" windows") || ua.contains(" win32") || ua.contains(" win64")) {
return WINDOWS;
}else if(ua.contains(" macos") || ua.contains(" osx")) {
return MACOS;
}else {
return OTHER;
}
}
}

View File

@ -0,0 +1,33 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum EnumPlatformType {
DESKTOP("Desktop"), JAVASCRIPT("HTML5");
private final String name;
private EnumPlatformType(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum EnumServerRateLimit {
OK, BLOCKED, LOCKED_OUT
}

View File

@ -0,0 +1,26 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class FileChooserResult {
public final String fileName;
public final byte[] fileData;
public FileChooserResult(String fileName, byte[] fileData) {
this.fileName = fileName;
this.fileData = fileData;
}
}

View File

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class GLObjectMap<T> {
private Object[] values;
private int size;
private int insertIndex;
public int allocatedObjects;
public GLObjectMap(int initialSize) {
this.values = new Object[initialSize];
this.size = initialSize;
this.insertIndex = 0;
this.allocatedObjects = 0;
}
public int register(T obj) {
int start = insertIndex;
do {
++insertIndex;
if(insertIndex >= size) {
insertIndex = 0;
}
if(insertIndex == start) {
resize();
return register(obj);
}
}while(values[insertIndex] != null);
values[insertIndex] = obj;
++allocatedObjects;
return insertIndex + 1;
}
public T free(int obj) {
--obj;
if(obj >= size || obj < 0) return null;
Object ret = values[obj];
values[obj] = null;
--allocatedObjects;
return (T) ret;
}
public T get(int obj) {
--obj;
if(obj >= size || obj < 0) return null;
return (T) values[obj];
}
private void resize() {
int oldSize = size;
size += size / 2;
Object[] oldValues = values;
values = new Object[size];
System.arraycopy(oldValues, 0, values, 0, oldSize);
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IAudioHandle {
void pause(boolean setPaused);
void restart();
void move(float x, float y, float z);
void pitch(float f);
void gain(float f);
void end();
boolean shouldFree();
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IAudioResource {
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IBufferArrayGL extends IObjectGL {
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IBufferGL extends IObjectGL {
}

View File

@ -0,0 +1,38 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.List;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IClientConfigAdapter {
public static class DefaultServer {
public final String name;
public final String addr;
public DefaultServer(String name, String addr) {
this.name = name;
this.addr = addr;
}
}
String getDefaultLocale();
List<DefaultServer> getDefaultServerList();
String getServerToJoin();
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IFramebufferGL extends IObjectGL {
}

View File

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IObjectGL {
void free();
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IProgramGL extends IObjectGL {
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IQueryGL extends IObjectGL {
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IRenderbufferGL extends IObjectGL {
}

View File

@ -0,0 +1,26 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.io.InputStream;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IResourceHandle {
String getPath();
InputStream inputStream();
byte[] toByteArray();
}

View File

@ -0,0 +1,119 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import org.json.JSONObject;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IServerQuery {
public static final long defaultTimeout = 10000l;
public static enum QueryReadyState {
CONNECTING(true, false), OPEN(true, false), CLOSED(false, true), FAILED(false, true);
private final boolean open;
private final boolean closed;
private QueryReadyState(boolean open, boolean closed) {
this.open = open;
this.closed = closed;
}
public boolean isOpen() {
return open;
}
public boolean isClosed() {
return closed;
}
}
void send(String str);
default void send(JSONObject json) {
send(json.toString());
}
void send(byte[] bytes);
int responsesAvailable();
QueryResponse getResponse();
int binaryResponsesAvailable();
byte[] getBinaryResponse();
QueryReadyState readyState();
default boolean isOpen() {
return readyState().isOpen();
}
default boolean isClosed() {
return readyState().isClosed();
}
void close();
EnumServerRateLimit getRateLimit();
default boolean awaitResponseAvailable(long timeout) {
long start = System.currentTimeMillis();
while(isOpen() && responsesAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) {
try {
Thread.sleep(0l, 250000);
} catch (InterruptedException e) {
}
}
return responsesAvailable() > 0;
}
default boolean awaitResponseAvailable() {
return awaitResponseAvailable(defaultTimeout);
}
default boolean awaitResponseBinaryAvailable(long timeout) {
long start = System.currentTimeMillis();
while(isOpen() && binaryResponsesAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) {
try {
Thread.sleep(0l, 250000);
} catch (InterruptedException e) {
}
}
return binaryResponsesAvailable() > 0;
}
default boolean awaitResponseBinaryAvailable() {
return awaitResponseBinaryAvailable(defaultTimeout);
}
default QueryResponse awaitResponse(long timeout) {
return awaitResponseAvailable(timeout) ? getResponse() : null;
}
default QueryResponse awaitResponse() {
return awaitResponseAvailable() ? getResponse() : null;
}
default byte[] awaitResponseBinary(long timeout) {
return awaitResponseBinaryAvailable(timeout) ? getBinaryResponse() : null;
}
default byte[] awaitResponseBinary() {
return awaitResponseBinaryAvailable() ? getBinaryResponse() : null;
}
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IShaderGL extends IObjectGL {
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface ITextureGL extends IObjectGL {
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IUniformGL extends IObjectGL {
}

View File

@ -0,0 +1,398 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class KeyboardConstants {
private static final String[] keyboardNames = new String[256];
private static final int[] keyboardGLFWToEagler = new int[384];
private static final int[] keyboardEaglerToGLFW = new int[256];
private static final int[] keyboardBrowserToEagler = new int[384 * 4];
private static final int[] keyboardEaglerToBrowser = new int[256];
private static final char[] keyboardChars = new char[256];
public static final int KEY_NONE = 0x00;
public static final int KEY_ESCAPE = 0x01;
public static final int KEY_1 = 0x02;
public static final int KEY_2 = 0x03;
public static final int KEY_3 = 0x04;
public static final int KEY_4 = 0x05;
public static final int KEY_5 = 0x06;
public static final int KEY_6 = 0x07;
public static final int KEY_7 = 0x08;
public static final int KEY_8 = 0x09;
public static final int KEY_9 = 0x0A;
public static final int KEY_0 = 0x0B;
public static final int KEY_MINUS = 0x0C; /* - on main keyboard */
public static final int KEY_EQUALS = 0x0D;
public static final int KEY_BACK = 0x0E; /* backspace */
public static final int KEY_TAB = 0x0F;
public static final int KEY_Q = 0x10;
public static final int KEY_W = 0x11;
public static final int KEY_E = 0x12;
public static final int KEY_R = 0x13;
public static final int KEY_T = 0x14;
public static final int KEY_Y = 0x15;
public static final int KEY_U = 0x16;
public static final int KEY_I = 0x17;
public static final int KEY_O = 0x18;
public static final int KEY_P = 0x19;
public static final int KEY_LBRACKET = 0x1A;
public static final int KEY_RBRACKET = 0x1B;
public static final int KEY_RETURN = 0x1C; /* Enter on main keyboard */
public static final int KEY_LCONTROL = 0x1D;
public static final int KEY_A = 0x1E;
public static final int KEY_S = 0x1F;
public static final int KEY_D = 0x20;
public static final int KEY_F = 0x21;
public static final int KEY_G = 0x22;
public static final int KEY_H = 0x23;
public static final int KEY_J = 0x24;
public static final int KEY_K = 0x25;
public static final int KEY_L = 0x26;
public static final int KEY_SEMICOLON = 0x27;
public static final int KEY_APOSTROPHE = 0x28;
public static final int KEY_GRAVE = 0x29; /* accent grave */
public static final int KEY_LSHIFT = 0x2A;
public static final int KEY_BACKSLASH = 0x2B;
public static final int KEY_Z = 0x2C;
public static final int KEY_X = 0x2D;
public static final int KEY_C = 0x2E;
public static final int KEY_V = 0x2F;
public static final int KEY_B = 0x30;
public static final int KEY_N = 0x31;
public static final int KEY_M = 0x32;
public static final int KEY_COMMA = 0x33;
public static final int KEY_PERIOD = 0x34; /* . on main keyboard */
public static final int KEY_SLASH = 0x35; /* / on main keyboard */
public static final int KEY_RSHIFT = 0x36;
public static final int KEY_MULTIPLY = 0x37; /* * on numeric keypad */
public static final int KEY_LMENU = 0x38; /* left Alt */
public static final int KEY_SPACE = 0x39;
public static final int KEY_CAPITAL = 0x3A;
public static final int KEY_F1 = 0x3B;
public static final int KEY_F2 = 0x3C;
public static final int KEY_F3 = 0x3D;
public static final int KEY_F4 = 0x3E;
public static final int KEY_F5 = 0x3F;
public static final int KEY_F6 = 0x40;
public static final int KEY_F7 = 0x41;
public static final int KEY_F8 = 0x42;
public static final int KEY_F9 = 0x43;
public static final int KEY_F10 = 0x44;
public static final int KEY_NUMLOCK = 0x45;
public static final int KEY_SCROLL = 0x46; /* Scroll Lock */
public static final int KEY_NUMPAD7 = 0x47;
public static final int KEY_NUMPAD8 = 0x48;
public static final int KEY_NUMPAD9 = 0x49;
public static final int KEY_SUBTRACT = 0x4A; /* - on numeric keypad */
public static final int KEY_NUMPAD4 = 0x4B;
public static final int KEY_NUMPAD5 = 0x4C;
public static final int KEY_NUMPAD6 = 0x4D;
public static final int KEY_ADD = 0x4E; /* + on numeric keypad */
public static final int KEY_NUMPAD1 = 0x4F;
public static final int KEY_NUMPAD2 = 0x50;
public static final int KEY_NUMPAD3 = 0x51;
public static final int KEY_NUMPAD0 = 0x52;
public static final int KEY_DECIMAL = 0x53; /* . on numeric keypad */
public static final int KEY_F11 = 0x57;
public static final int KEY_F12 = 0x58;
public static final int KEY_F13 = 0x64; /* (NEC PC98) */
public static final int KEY_F14 = 0x65; /* (NEC PC98) */
public static final int KEY_F15 = 0x66; /* (NEC PC98) */
public static final int KEY_F16 = 0x67; /* Extended Function keys - (Mac) */
public static final int KEY_F17 = 0x68;
public static final int KEY_F18 = 0x69;
public static final int KEY_KANA = 0x70; /* (Japanese keyboard) */
public static final int KEY_F19 = 0x71; /* Extended Function keys - (Mac) */
public static final int KEY_CONVERT = 0x79; /* (Japanese keyboard) */
public static final int KEY_NOCONVERT = 0x7B; /* (Japanese keyboard) */
public static final int KEY_YEN = 0x7D; /* (Japanese keyboard) */
public static final int KEY_NUMPADEQUALS = 0x8D; /* = on numeric keypad (NEC PC98) */
public static final int KEY_CIRCUMFLEX = 0x90; /* (Japanese keyboard) */
public static final int KEY_AT = 0x91; /* (NEC PC98) */
public static final int KEY_COLON = 0x92; /* (NEC PC98) */
public static final int KEY_UNDERLINE = 0x93; /* (NEC PC98) */
public static final int KEY_KANJI = 0x94; /* (Japanese keyboard) */
public static final int KEY_STOP = 0x95; /* (NEC PC98) */
public static final int KEY_AX = 0x96; /* (Japan AX) */
public static final int KEY_UNLABELED = 0x97; /* (J3100) */
public static final int KEY_NUMPADENTER = 0x9C; /* Enter on numeric keypad */
public static final int KEY_RCONTROL = 0x9D;
public static final int KEY_SECTION = 0xA7; /* Section symbol (Mac) */
public static final int KEY_NUMPADCOMMA = 0xB3; /* , on numeric keypad (NEC PC98) */
public static final int KEY_DIVIDE = 0xB5; /* / on numeric keypad */
public static final int KEY_SYSRQ = 0xB7;
public static final int KEY_RMENU = 0xB8; /* right Alt */
public static final int KEY_FUNCTION = 0xC4; /* Function (Mac) */
public static final int KEY_PAUSE = 0xC5; /* Pause */
public static final int KEY_HOME = 0xC7; /* Home on arrow keypad */
public static final int KEY_UP = 0xC8; /* UpArrow on arrow keypad */
public static final int KEY_PRIOR = 0xC9; /* PgUp on arrow keypad */
public static final int KEY_LEFT = 0xCB; /* LeftArrow on arrow keypad */
public static final int KEY_RIGHT = 0xCD; /* RightArrow on arrow keypad */
public static final int KEY_END = 0xCF; /* End on arrow keypad */
public static final int KEY_DOWN = 0xD0; /* DownArrow on arrow keypad */
public static final int KEY_NEXT = 0xD1; /* PgDn on arrow keypad */
public static final int KEY_INSERT = 0xD2; /* Insert on arrow keypad */
public static final int KEY_DELETE = 0xD3; /* Delete on arrow keypad */
public static final int KEY_CLEAR = 0xDA; /* Clear key (Mac) */
public static final int KEY_LMETA = 0xDB; /* Left Windows/Option key */
public static final int KEY_RMETA = 0xDC; /* Right Windows/Option key */
public static final int KEY_APPS = 0xDD; /* AppMenu key */
public static final int KEY_POWER = 0xDE;
public static final int KEY_SLEEP = 0xDF;
private static final int GLFW_KEY_SPACE = 32, GLFW_KEY_APOSTROPHE = 39, GLFW_KEY_COMMA = 44, GLFW_KEY_MINUS = 45,
GLFW_KEY_PERIOD = 46, GLFW_KEY_SLASH = 47, GLFW_KEY_0 = 48, GLFW_KEY_1 = 49, GLFW_KEY_2 = 50,
GLFW_KEY_3 = 51, GLFW_KEY_4 = 52, GLFW_KEY_5 = 53, GLFW_KEY_6 = 54, GLFW_KEY_7 = 55, GLFW_KEY_8 = 56,
GLFW_KEY_9 = 57, GLFW_KEY_SEMICOLON = 59, GLFW_KEY_EQUAL = 61, GLFW_KEY_A = 65, GLFW_KEY_B = 66,
GLFW_KEY_C = 67, GLFW_KEY_D = 68, GLFW_KEY_E = 69, GLFW_KEY_F = 70, GLFW_KEY_G = 71, GLFW_KEY_H = 72,
GLFW_KEY_I = 73, GLFW_KEY_J = 74, GLFW_KEY_K = 75, GLFW_KEY_L = 76, GLFW_KEY_M = 77, GLFW_KEY_N = 78,
GLFW_KEY_O = 79, GLFW_KEY_P = 80, GLFW_KEY_Q = 81, GLFW_KEY_R = 82, GLFW_KEY_S = 83, GLFW_KEY_T = 84,
GLFW_KEY_U = 85, GLFW_KEY_V = 86, GLFW_KEY_W = 87, GLFW_KEY_X = 88, GLFW_KEY_Y = 89, GLFW_KEY_Z = 90,
GLFW_KEY_LEFT_BRACKET = 91, GLFW_KEY_BACKSLASH = 92, GLFW_KEY_RIGHT_BRACKET = 93,
GLFW_KEY_GRAVE_ACCENT = 96, GLFW_KEY_WORLD_1 = 161, GLFW_KEY_WORLD_2 = 162;
private static final int GLFW_KEY_ESCAPE = 256, GLFW_KEY_ENTER = 257, GLFW_KEY_TAB = 258, GLFW_KEY_BACKSPACE = 259,
GLFW_KEY_INSERT = 260, GLFW_KEY_DELETE = 261, GLFW_KEY_RIGHT = 262, GLFW_KEY_LEFT = 263,
GLFW_KEY_DOWN = 264, GLFW_KEY_UP = 265, GLFW_KEY_PAGE_UP = 266, GLFW_KEY_PAGE_DOWN = 267,
GLFW_KEY_HOME = 268, GLFW_KEY_END = 269, GLFW_KEY_CAPS_LOCK = 280, GLFW_KEY_SCROLL_LOCK = 281,
GLFW_KEY_NUM_LOCK = 282, GLFW_KEY_PRINT_SCREEN = 283, GLFW_KEY_PAUSE = 284, GLFW_KEY_F1 = 290,
GLFW_KEY_F2 = 291, GLFW_KEY_F3 = 292, GLFW_KEY_F4 = 293, GLFW_KEY_F5 = 294, GLFW_KEY_F6 = 295,
GLFW_KEY_F7 = 296, GLFW_KEY_F8 = 297, GLFW_KEY_F9 = 298, GLFW_KEY_F10 = 299, GLFW_KEY_F11 = 300,
GLFW_KEY_F12 = 301, GLFW_KEY_F13 = 302, GLFW_KEY_F14 = 303, GLFW_KEY_F15 = 304, GLFW_KEY_F16 = 305,
GLFW_KEY_F17 = 306, GLFW_KEY_F18 = 307, GLFW_KEY_F19 = 308, GLFW_KEY_F20 = 309, GLFW_KEY_F21 = 310,
GLFW_KEY_F22 = 311, GLFW_KEY_F23 = 312, GLFW_KEY_F24 = 313, GLFW_KEY_F25 = 314, GLFW_KEY_KP_0 = 320,
GLFW_KEY_KP_1 = 321, GLFW_KEY_KP_2 = 322, GLFW_KEY_KP_3 = 323, GLFW_KEY_KP_4 = 324, GLFW_KEY_KP_5 = 325,
GLFW_KEY_KP_6 = 326, GLFW_KEY_KP_7 = 327, GLFW_KEY_KP_8 = 328, GLFW_KEY_KP_9 = 329,
GLFW_KEY_KP_DECIMAL = 330, GLFW_KEY_KP_DIVIDE = 331, GLFW_KEY_KP_MULTIPLY = 332, GLFW_KEY_KP_SUBTRACT = 333,
GLFW_KEY_KP_ADD = 334, GLFW_KEY_KP_ENTER = 335, GLFW_KEY_KP_EQUAL = 336, GLFW_KEY_LEFT_SHIFT = 340,
GLFW_KEY_LEFT_CONTROL = 341, GLFW_KEY_LEFT_ALT = 342, GLFW_KEY_LEFT_SUPER = 343, GLFW_KEY_RIGHT_SHIFT = 344,
GLFW_KEY_RIGHT_CONTROL = 345, GLFW_KEY_RIGHT_ALT = 346, GLFW_KEY_RIGHT_SUPER = 347, GLFW_KEY_MENU = 348,
GLFW_KEY_LAST = GLFW_KEY_MENU;
private static final int DOM_KEY_LOCATION_STANDARD = 0, DOM_KEY_LOCATION_LEFT = 1, DOM_KEY_LOCATION_RIGHT = 2,
DOM_KEY_LOCATION_NUMPAD = 3;
private static void register(int eaglerId, int glfwId, int browserId, int browserLocation, String name, char character) {
if(keyboardEaglerToGLFW[eaglerId] != 0) throw new IllegalArgumentException("Duplicate keyboardEaglerToGLFW entry: " + eaglerId + " -> " + glfwId);
keyboardEaglerToGLFW[eaglerId] = glfwId;
if(keyboardGLFWToEagler[glfwId] != 0) throw new IllegalArgumentException("Duplicate keyboardGLFWToEagler entry: " + glfwId + " -> " + eaglerId);
keyboardGLFWToEagler[glfwId] = eaglerId;
if(browserLocation == 0) {
if(keyboardEaglerToBrowser[eaglerId] != 0) throw new IllegalArgumentException("Duplicate keyboardEaglerToBrowser entry: " + eaglerId + " -> " + browserId + "(0)");
keyboardEaglerToBrowser[eaglerId] = browserId;
if(keyboardBrowserToEagler[browserId] != 0) throw new IllegalArgumentException("Duplicate keyboardBrowserToEagler entry: " + browserId + "(0) -> " + eaglerId);
keyboardBrowserToEagler[browserId] = eaglerId;
}else {
browserLocation *= 384;
if(keyboardEaglerToBrowser[eaglerId] != 0) throw new IllegalArgumentException("Duplicate keyboardEaglerToBrowser entry: " + eaglerId + " -> " + browserId + "(" + browserLocation + ")");
keyboardEaglerToBrowser[eaglerId] = browserId + browserLocation;
if(keyboardBrowserToEagler[browserId + browserLocation] != 0) throw new IllegalArgumentException("Duplicate keyboardBrowserToEagler entry: " + browserId + "(" + browserLocation + ") -> " + eaglerId);
keyboardBrowserToEagler[browserId + browserLocation] = eaglerId;
}
if(keyboardNames[eaglerId] != null) throw new IllegalArgumentException("Duplicate keyboardNames entry: " + eaglerId + " -> " + name);
keyboardNames[eaglerId] = name;
if(keyboardChars[eaglerId] != '\0') throw new IllegalArgumentException("Duplicate keyboardChars entry: " + eaglerId + " -> " + character);
keyboardChars[eaglerId] = character;
}
private static void registerAlt(int eaglerId, int browserId, int browserLocation) {
if(browserLocation == 0) {
if(keyboardBrowserToEagler[browserId] != 0) throw new IllegalArgumentException("Duplicate (alt) keyboardBrowserToEagler entry: " + browserId + " -> " + eaglerId);
keyboardBrowserToEagler[browserId] = eaglerId;
}else {
browserLocation *= 384;
if(keyboardBrowserToEagler[browserId + browserLocation] != 0) throw new IllegalArgumentException("Duplicate (alt) keyboardBrowserToEagler entry: " + browserId + "(" + browserLocation + ") -> " + eaglerId);
keyboardBrowserToEagler[browserId + browserLocation] = eaglerId;
}
}
static {
register(KEY_SPACE, GLFW_KEY_SPACE, 32, DOM_KEY_LOCATION_STANDARD, "Space", ' ');
register(KEY_APOSTROPHE, GLFW_KEY_APOSTROPHE, 222, DOM_KEY_LOCATION_STANDARD, "Quote", '\'');
register(KEY_COMMA, GLFW_KEY_COMMA, 188, DOM_KEY_LOCATION_STANDARD, "Comma", ',');
register(KEY_MINUS, GLFW_KEY_MINUS, 189, DOM_KEY_LOCATION_STANDARD, "Minus", '-');
register(KEY_PERIOD, GLFW_KEY_PERIOD, 190, DOM_KEY_LOCATION_STANDARD, "Period", '.');
register(KEY_SLASH, GLFW_KEY_SLASH, 191, DOM_KEY_LOCATION_STANDARD, "Slash", '/');
register(KEY_0, GLFW_KEY_0, 48, DOM_KEY_LOCATION_STANDARD, "0", '0');
register(KEY_1, GLFW_KEY_1, 49, DOM_KEY_LOCATION_STANDARD, "1", '1');
register(KEY_2, GLFW_KEY_2, 50, DOM_KEY_LOCATION_STANDARD, "2", '2');
register(KEY_3, GLFW_KEY_3, 51, DOM_KEY_LOCATION_STANDARD, "3", '3');
register(KEY_4, GLFW_KEY_4, 52, DOM_KEY_LOCATION_STANDARD, "4", '4');
register(KEY_5, GLFW_KEY_5, 53, DOM_KEY_LOCATION_STANDARD, "5", '5');
register(KEY_6, GLFW_KEY_6, 54, DOM_KEY_LOCATION_STANDARD, "6", '6');
register(KEY_7, GLFW_KEY_7, 55, DOM_KEY_LOCATION_STANDARD, "7", '7');
register(KEY_8, GLFW_KEY_8, 56, DOM_KEY_LOCATION_STANDARD, "8", '8');
register(KEY_9, GLFW_KEY_9, 57, DOM_KEY_LOCATION_STANDARD, "9", '9');
register(KEY_SEMICOLON, GLFW_KEY_SEMICOLON, 186, DOM_KEY_LOCATION_STANDARD, "Semicolon", ';');
register(KEY_EQUALS, GLFW_KEY_EQUAL, 187, DOM_KEY_LOCATION_STANDARD, "Equals", '=');
register(KEY_A, GLFW_KEY_A, 65, DOM_KEY_LOCATION_STANDARD, "A", 'a');
register(KEY_B, GLFW_KEY_B, 66, DOM_KEY_LOCATION_STANDARD, "B", 'b');
register(KEY_C, GLFW_KEY_C, 67, DOM_KEY_LOCATION_STANDARD, "C", 'c');
register(KEY_D, GLFW_KEY_D, 68, DOM_KEY_LOCATION_STANDARD, "D", 'd');
register(KEY_E, GLFW_KEY_E, 69, DOM_KEY_LOCATION_STANDARD, "E", 'e');
register(KEY_F, GLFW_KEY_F, 70, DOM_KEY_LOCATION_STANDARD, "F", 'f');
register(KEY_G, GLFW_KEY_G, 71, DOM_KEY_LOCATION_STANDARD, "G", 'g');
register(KEY_H, GLFW_KEY_H, 72, DOM_KEY_LOCATION_STANDARD, "H", 'h');
register(KEY_I, GLFW_KEY_I, 73, DOM_KEY_LOCATION_STANDARD, "I", 'i');
register(KEY_J, GLFW_KEY_J, 74, DOM_KEY_LOCATION_STANDARD, "J", 'j');
register(KEY_K, GLFW_KEY_K, 75, DOM_KEY_LOCATION_STANDARD, "K", 'k');
register(KEY_L, GLFW_KEY_L, 76, DOM_KEY_LOCATION_STANDARD, "L", 'l');
register(KEY_M, GLFW_KEY_M, 77, DOM_KEY_LOCATION_STANDARD, "M", 'm');
register(KEY_N, GLFW_KEY_N, 78, DOM_KEY_LOCATION_STANDARD, "N", 'n');
register(KEY_O, GLFW_KEY_O, 79, DOM_KEY_LOCATION_STANDARD, "O", 'o');
register(KEY_P, GLFW_KEY_P, 80, DOM_KEY_LOCATION_STANDARD, "P", 'p');
register(KEY_Q, GLFW_KEY_Q, 81, DOM_KEY_LOCATION_STANDARD, "Q", 'q');
register(KEY_R, GLFW_KEY_R, 82, DOM_KEY_LOCATION_STANDARD, "R", 'r');
register(KEY_S, GLFW_KEY_S, 83, DOM_KEY_LOCATION_STANDARD, "S", 's');
register(KEY_T, GLFW_KEY_T, 84, DOM_KEY_LOCATION_STANDARD, "T", 't');
register(KEY_U, GLFW_KEY_U, 85, DOM_KEY_LOCATION_STANDARD, "U", 'u');
register(KEY_V, GLFW_KEY_V, 86, DOM_KEY_LOCATION_STANDARD, "V", 'v');
register(KEY_W, GLFW_KEY_W, 87, DOM_KEY_LOCATION_STANDARD, "W", 'w');
register(KEY_X, GLFW_KEY_X, 88, DOM_KEY_LOCATION_STANDARD, "X", 'x');
register(KEY_Y, GLFW_KEY_Y, 89, DOM_KEY_LOCATION_STANDARD, "Y", 'y');
register(KEY_Z, GLFW_KEY_Z, 90, DOM_KEY_LOCATION_STANDARD, "Z", 'z');
register(KEY_LBRACKET, GLFW_KEY_LEFT_BRACKET, 219, DOM_KEY_LOCATION_STANDARD, "L. Bracket", '[');
register(KEY_BACKSLASH, GLFW_KEY_BACKSLASH, 220, DOM_KEY_LOCATION_STANDARD, "Backslash", '\\');
register(KEY_RBRACKET, GLFW_KEY_RIGHT_BRACKET, 221, DOM_KEY_LOCATION_STANDARD, "R. Bracket", ']');
register(KEY_GRAVE, GLFW_KEY_GRAVE_ACCENT, 192, DOM_KEY_LOCATION_STANDARD, "Backtick", '`');
register(KEY_ESCAPE, GLFW_KEY_ESCAPE, 27, DOM_KEY_LOCATION_STANDARD, "Escape", '\0');
register(KEY_RETURN, GLFW_KEY_ENTER, 13, DOM_KEY_LOCATION_STANDARD, "Enter", '\n');
register(KEY_TAB, GLFW_KEY_TAB, 9, DOM_KEY_LOCATION_STANDARD, "Tab", '\t');
register(KEY_BACK, GLFW_KEY_BACKSPACE, 8, DOM_KEY_LOCATION_STANDARD, "Backspace", '\0');
register(KEY_INSERT, GLFW_KEY_INSERT, 45, DOM_KEY_LOCATION_STANDARD, "Insert", '\0');
register(KEY_DELETE, GLFW_KEY_DELETE, 46, DOM_KEY_LOCATION_STANDARD, "Delete", '\0');
register(KEY_RIGHT, GLFW_KEY_RIGHT, 39, DOM_KEY_LOCATION_STANDARD, "Right", '\0');
register(KEY_LEFT, GLFW_KEY_LEFT, 37, DOM_KEY_LOCATION_STANDARD, "Left", '\0');
register(KEY_DOWN, GLFW_KEY_DOWN, 40, DOM_KEY_LOCATION_STANDARD, "Down", '\0');
register(KEY_UP, GLFW_KEY_UP, 38, DOM_KEY_LOCATION_STANDARD, "Up", '\0');
register(KEY_PRIOR, GLFW_KEY_PAGE_UP, 33, DOM_KEY_LOCATION_STANDARD, "Page Up", '\0');
register(KEY_NEXT, GLFW_KEY_PAGE_DOWN, 34, DOM_KEY_LOCATION_STANDARD, "Page Down", '\0');
register(KEY_HOME, GLFW_KEY_HOME, 36, DOM_KEY_LOCATION_STANDARD, "Home", '\0');
register(KEY_END, GLFW_KEY_END, 35, DOM_KEY_LOCATION_STANDARD, "End", '\0');
register(KEY_CAPITAL, GLFW_KEY_CAPS_LOCK, 20, DOM_KEY_LOCATION_STANDARD, "Caps Lock", '\0');
register(KEY_SCROLL, GLFW_KEY_SCROLL_LOCK, 145, DOM_KEY_LOCATION_STANDARD, "Scroll Lock", '\0');
register(KEY_NUMLOCK, GLFW_KEY_NUM_LOCK, 144, DOM_KEY_LOCATION_STANDARD, "Num Lock", '\0');
register(KEY_PAUSE, GLFW_KEY_PAUSE, 19, DOM_KEY_LOCATION_STANDARD, "Pause", '\0');
register(KEY_F1, GLFW_KEY_F1, 112, DOM_KEY_LOCATION_STANDARD, "F1", '\0');
register(KEY_F2, GLFW_KEY_F2, 113, DOM_KEY_LOCATION_STANDARD, "F2", '\0');
register(KEY_F3, GLFW_KEY_F3, 114, DOM_KEY_LOCATION_STANDARD, "F3", '\0');
register(KEY_F4, GLFW_KEY_F4, 115, DOM_KEY_LOCATION_STANDARD, "F4", '\0');
register(KEY_F5, GLFW_KEY_F5, 116, DOM_KEY_LOCATION_STANDARD, "F5", '\0');
register(KEY_F6, GLFW_KEY_F6, 117, DOM_KEY_LOCATION_STANDARD, "F6", '\0');
register(KEY_F7, GLFW_KEY_F7, 118, DOM_KEY_LOCATION_STANDARD, "F7", '\0');
register(KEY_F8, GLFW_KEY_F8, 119, DOM_KEY_LOCATION_STANDARD, "F8", '\0');
register(KEY_F9, GLFW_KEY_F9, 120, DOM_KEY_LOCATION_STANDARD, "F9", '\0');
register(KEY_F10, GLFW_KEY_F10, 121, DOM_KEY_LOCATION_STANDARD, "F10", '\0');
register(KEY_F11, GLFW_KEY_F11, 122, DOM_KEY_LOCATION_STANDARD, "F11", '\0');
register(KEY_F12, GLFW_KEY_F12, 123, DOM_KEY_LOCATION_STANDARD, "F12", '\0');
register(KEY_NUMPAD0, GLFW_KEY_KP_0, 96, DOM_KEY_LOCATION_NUMPAD, "Keypad 0", '0');
register(KEY_NUMPAD1, GLFW_KEY_KP_1, 97, DOM_KEY_LOCATION_NUMPAD, "Keypad 1", '1');
register(KEY_NUMPAD2, GLFW_KEY_KP_2, 98, DOM_KEY_LOCATION_NUMPAD, "Keypad 2", '2');
register(KEY_NUMPAD3, GLFW_KEY_KP_3, 99, DOM_KEY_LOCATION_NUMPAD, "Keypad 3", '3');
register(KEY_NUMPAD4, GLFW_KEY_KP_4, 100, DOM_KEY_LOCATION_NUMPAD, "Keypad 4", '4');
register(KEY_NUMPAD5, GLFW_KEY_KP_5, 101, DOM_KEY_LOCATION_NUMPAD, "Keypad 5", '5');
register(KEY_NUMPAD6, GLFW_KEY_KP_6, 102, DOM_KEY_LOCATION_NUMPAD, "Keypad 6", '6');
register(KEY_NUMPAD7, GLFW_KEY_KP_7, 103, DOM_KEY_LOCATION_NUMPAD, "Keypad 7", '7');
register(KEY_NUMPAD8, GLFW_KEY_KP_8, 104, DOM_KEY_LOCATION_NUMPAD, "Keypad 8", '8');
register(KEY_NUMPAD9, GLFW_KEY_KP_9, 105, DOM_KEY_LOCATION_NUMPAD, "Keypad 9", '9');
register(KEY_DECIMAL, GLFW_KEY_KP_DECIMAL, 110, DOM_KEY_LOCATION_NUMPAD, "Decimal", '.');
register(KEY_DIVIDE, GLFW_KEY_KP_DIVIDE, 111, DOM_KEY_LOCATION_NUMPAD, "Divide", '/');
register(KEY_MULTIPLY, GLFW_KEY_KP_MULTIPLY, 106, DOM_KEY_LOCATION_NUMPAD, "Multiply", '*');
register(KEY_SUBTRACT, GLFW_KEY_KP_SUBTRACT, 109, DOM_KEY_LOCATION_NUMPAD, "Subtract", '-');
register(KEY_ADD, GLFW_KEY_KP_ADD, 107, DOM_KEY_LOCATION_NUMPAD, "Add", '+');
register(KEY_NUMPADENTER, GLFW_KEY_KP_ENTER, 13, DOM_KEY_LOCATION_NUMPAD, "Enter", '\n');
register(KEY_NUMPADEQUALS, GLFW_KEY_KP_EQUAL, 187, DOM_KEY_LOCATION_NUMPAD, "Equals", '=');
register(KEY_LSHIFT, GLFW_KEY_LEFT_SHIFT, 16, DOM_KEY_LOCATION_LEFT, "L. Shift", '\0');
register(KEY_LCONTROL, GLFW_KEY_LEFT_CONTROL, 17, DOM_KEY_LOCATION_LEFT, "L. Control", '\0');
register(KEY_LMENU, GLFW_KEY_LEFT_ALT, 18, DOM_KEY_LOCATION_LEFT, "L. Alt", '\0');
registerAlt(KEY_LSHIFT, 16, DOM_KEY_LOCATION_STANDARD);
registerAlt(KEY_LCONTROL, 17, DOM_KEY_LOCATION_STANDARD);
registerAlt(KEY_LMENU, 18, DOM_KEY_LOCATION_STANDARD);
register(KEY_RSHIFT, GLFW_KEY_RIGHT_SHIFT, 16, DOM_KEY_LOCATION_RIGHT, "R. Shift", '\0');
register(KEY_RCONTROL, GLFW_KEY_RIGHT_CONTROL, 17, DOM_KEY_LOCATION_RIGHT, "R. Control", '\0');
register(KEY_RMENU, GLFW_KEY_RIGHT_ALT, 18, DOM_KEY_LOCATION_RIGHT, "R. Alt", '\0');
}
public static String getKeyName(int key) {
if (key < 0 || key >= 256 || keyboardNames[key] == null) {
return "Unknown";
} else {
return keyboardNames[key];
}
}
public static int getEaglerKeyFromGLFW(int key) {
if (key < 0 || key >= 384) {
return 0;
} else {
return keyboardGLFWToEagler[key];
}
}
public static int getGLFWKeyFromEagler(int key) {
if (key < 0 || key >= 256) {
return 0;
} else {
return keyboardEaglerToGLFW[key];
}
}
public static int getEaglerKeyFromBrowser(int key) {
return getEaglerKeyFromBrowser(key, 0);
}
public static int getEaglerKeyFromBrowser(int key, int location) {
if (key < 0 || key >= 384) {
return 0;
} else {
if(location <= 0 || location >= 4) {
return keyboardBrowserToEagler[key];
}else {
int i = keyboardBrowserToEagler[key + location * 384];
if(i == 0) {
i = keyboardBrowserToEagler[key];
}
return i;
}
}
}
public static int getBrowserKeyFromEagler(int key) {
if (key < 0 || key >= 256) {
return 0;
} else {
return keyboardEaglerToBrowser[key] % 384;
}
}
public static int getBrowserLocationFromEagler(int key) {
if (key < 0 || key >= 384) {
return 0;
} else {
return keyboardEaglerToBrowser[key] / 384;
}
}
public static char getKeyCharFromEagler(int key) {
if (key < 0 || key >= 256) {
return '\0';
} else {
return keyboardChars[key];
}
}
}

View File

@ -0,0 +1,58 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import org.json.JSONObject;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class QueryResponse {
public final String responseType;
private final Object responseData;
public final String serverVersion;
public final String serverBrand;
public final String serverName;
public final long serverTime;
public final long clientTime;
public final boolean serverCracked;
public final long ping;
public QueryResponse(JSONObject obj, long ping) {
this.responseType = obj.getString("type").toLowerCase();
this.ping = ping;
this.responseData = obj.get("data");
this.serverVersion = obj.getString("vers");
this.serverBrand = obj.getString("brand");
this.serverName = obj.getString("name");
this.serverTime = obj.getLong("time");
this.clientTime = System.currentTimeMillis();
this.serverCracked = obj.optBoolean("cracked", false);
}
public boolean isResponseString() {
return responseData instanceof String;
}
public boolean isResponseJSON() {
return responseData instanceof JSONObject;
}
public String getResponseString() {
return (String)responseData;
}
public JSONObject getResponseJSON() {
return (JSONObject)responseData;
}
}

View File

@ -0,0 +1,52 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface Buffer {
int capacity();
int position();
Buffer position(int newPosition);
int limit();
Buffer limit(int newLimit);
Buffer mark();
Buffer reset();
Buffer clear();
Buffer flip();
Buffer rewind();
int remaining();
boolean hasRemaining();
boolean isReadOnly();
boolean hasArray();
Object array();
int arrayOffset();
boolean isDirect();
}

View File

@ -0,0 +1,106 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface ByteBuffer extends Buffer {
ByteBuffer slice();
ByteBuffer duplicate();
ByteBuffer asReadOnlyBuffer();
byte get();
ByteBuffer put(byte b);
byte get(int index);
ByteBuffer put(int index, byte b);
ByteBuffer get(byte[] dst, int offset, int length);
ByteBuffer get(byte[] dst);
ByteBuffer put(ByteBuffer src);
ByteBuffer put(byte[] src, int offset, int length);
ByteBuffer put(byte[] src);
int arrayOffset();
ByteBuffer compact();
char getChar();
ByteBuffer putChar(char value);
char getChar(int index);
ByteBuffer putChar(int index, char value);
public abstract short getShort();
ByteBuffer putShort(short value);
short getShort(int index);
ByteBuffer putShort(int index, short value);
ShortBuffer asShortBuffer();
int getInt();
ByteBuffer putInt(int value);
int getInt(int index);
ByteBuffer putInt(int index, int value);
IntBuffer asIntBuffer();
long getLong();
ByteBuffer putLong(long value);
long getLong(int index);
ByteBuffer putLong(int index, long value);
float getFloat();
ByteBuffer putFloat(float value);
float getFloat(int index);
ByteBuffer putFloat(int index, float value);
FloatBuffer asFloatBuffer();
ByteBuffer mark();
ByteBuffer reset();
ByteBuffer clear();
ByteBuffer flip();
ByteBuffer rewind();
ByteBuffer limit(int newLimit);
ByteBuffer position(int newPosition);
}

View File

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import java.io.IOException;
import java.io.InputStream;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglerBufferInputStream extends InputStream {
private final ByteBuffer buffer;
public EaglerBufferInputStream(ByteBuffer buffer) {
this.buffer = buffer;
}
@Override
public int read() throws IOException {
if(buffer.remaining() <= 0) {
return -1;
}
return (int)buffer.get() & 0xFF;
}
@Override
public int read(byte b[], int off, int len) throws IOException {
int p = buffer.position();
int l = buffer.limit();
int r = l - p;
if(r < len) {
len = r;
}
if(len > 0) {
buffer.get(b, off, len);
}
return len;
}
@Override
public long skip(long n) throws IOException {
int p = buffer.position();
int l = buffer.limit();
int r = l - p;
if(r < n) {
n = r;
}
if(n > 0) {
buffer.position(p + (int)n);
}
return n;
}
@Override
public int available() throws IOException {
return buffer.remaining();
}
}

View File

@ -0,0 +1,67 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface FloatBuffer extends Buffer {
FloatBuffer slice();
FloatBuffer duplicate();
FloatBuffer asReadOnlyBuffer();
float get();
FloatBuffer put(float b);
float get(int index);
FloatBuffer put(int index, float b);
float getElement(int index);
void putElement(int index, float value);
FloatBuffer get(float[] dst, int offset, int length);
FloatBuffer get(float[] dst);
FloatBuffer put(FloatBuffer src);
FloatBuffer put(float[] src, int offset, int length);
FloatBuffer put(float[] src);
int getArrayOffset();
FloatBuffer compact();
boolean isDirect();
FloatBuffer mark();
FloatBuffer reset();
FloatBuffer clear();
FloatBuffer flip();
FloatBuffer rewind();
FloatBuffer limit(int newLimit);
FloatBuffer position(int newPosition);
}

View File

@ -0,0 +1,67 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IntBuffer extends Buffer {
IntBuffer slice();
IntBuffer duplicate();
IntBuffer asReadOnlyBuffer();
int get();
IntBuffer put(int b);
int get(int index);
IntBuffer put(int index, int b);
int getElement(int index);
void putElement(int index, int value);
IntBuffer get(int[] dst, int offset, int length);
IntBuffer get(int[] dst);
IntBuffer put(IntBuffer src);
IntBuffer put(int[] src, int offset, int length);
IntBuffer put(int[] src);
int getArrayOffset();
IntBuffer compact();
boolean isDirect();
IntBuffer mark();
IntBuffer reset();
IntBuffer clear();
IntBuffer flip();
IntBuffer rewind();
IntBuffer limit(int newLimit);
IntBuffer position(int newPosition);
}

View File

@ -0,0 +1,66 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface ShortBuffer extends Buffer {
ShortBuffer slice();
ShortBuffer duplicate();
ShortBuffer asReadOnlyBuffer();
short get();
ShortBuffer put(short b);
short get(int index);
ShortBuffer put(int index, short b);
short getElement(int index);
void putElement(int index, short value);
ShortBuffer get(short[] dst, int offset, int length);
ShortBuffer get(short[] dst);
ShortBuffer put(ShortBuffer src);
ShortBuffer put(short[] src, int offset, int length);
ShortBuffer put(short[] src);
int getArrayOffset();
ShortBuffer compact();
boolean isDirect();
ShortBuffer mark();
ShortBuffer reset();
ShortBuffer clear();
ShortBuffer flip();
ShortBuffer rewind();
ShortBuffer limit(int newLimit);
ShortBuffer position(int newPosition);
}

View File

@ -0,0 +1,22 @@
package net.lax1dude.eaglercraft.v1_8.json;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface JSONDataParserImpl {
boolean accepts(Object type);
Object parse(Object data);
}

View File

@ -0,0 +1,18 @@
package net.lax1dude.eaglercraft.v1_8.json;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface JSONTypeCodec<O, J> extends JSONTypeSerializer<O, J>, JSONTypeDeserializer<J, O> {
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.v1_8.json;
import org.json.JSONException;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface JSONTypeDeserializer<J, O> {
default O deserializeFromJson(J json) throws JSONException {
try {
return deserialize(json);
}catch(JSONException obj) {
throw obj;
}catch(Throwable t) {
throw new JSONException("Exception deserializing JSON object", t);
}
}
O deserialize(J json) throws JSONException;
}

View File

@ -0,0 +1,157 @@
package net.lax1dude.eaglercraft.v1_8.json;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.json.JSONException;
import net.lax1dude.eaglercraft.v1_8.json.impl.JSONDataParserReader;
import net.lax1dude.eaglercraft.v1_8.json.impl.JSONDataParserStream;
import net.lax1dude.eaglercraft.v1_8.json.impl.JSONDataParserString;
import net.lax1dude.eaglercraft.v1_8.json.impl.SoundMapDeserializer;
import net.minecraft.client.audio.SoundHandler.SoundMap;
import net.minecraft.client.audio.SoundList;
import net.minecraft.client.audio.SoundListSerializer;
import net.minecraft.client.renderer.block.model.BlockFaceUV;
import net.minecraft.client.renderer.block.model.BlockPart;
import net.minecraft.client.renderer.block.model.BlockPartFace;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemTransformVec3f;
import net.minecraft.client.renderer.block.model.ModelBlock;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition;
import net.minecraft.client.resources.data.AnimationMetadataSection;
import net.minecraft.client.resources.data.AnimationMetadataSectionSerializer;
import net.minecraft.client.resources.data.FontMetadataSection;
import net.minecraft.client.resources.data.FontMetadataSectionSerializer;
import net.minecraft.client.resources.data.LanguageMetadataSection;
import net.minecraft.client.resources.data.LanguageMetadataSectionSerializer;
import net.minecraft.client.resources.data.PackMetadataSection;
import net.minecraft.client.resources.data.PackMetadataSectionSerializer;
import net.minecraft.client.resources.data.TextureMetadataSection;
import net.minecraft.client.resources.data.TextureMetadataSectionSerializer;
import net.minecraft.network.ServerStatusResponse;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.IChatComponent;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class JSONTypeProvider {
private static final Map<Class<?>,JSONTypeSerializer<?,?>> serializers = new HashMap();
private static final Map<Class<?>,JSONTypeDeserializer<?,?>> deserializers = new HashMap();
private static final List<JSONDataParserImpl> parsers = new ArrayList();
public static <J> J serialize(Object object) throws JSONException {
JSONTypeSerializer<Object,J> ser = (JSONTypeSerializer<Object,J>) serializers.get(object.getClass());
if(ser == null) {
for(Entry<Class<?>,JSONTypeSerializer<?,?>> etr : serializers.entrySet()) {
if(etr.getKey().isInstance(object)) {
ser = (JSONTypeSerializer<Object,J>)etr.getValue();
break;
}
}
}
if(ser != null) {
return ser.serializeToJson(object);
}else {
throw new JSONException("Could not find a serializer for " + object.getClass().getSimpleName());
}
}
public static <O> O deserialize(Object object, Class<O> clazz) throws JSONException {
return deserializeNoCast(parse(object), clazz);
}
public static <O> O deserializeNoCast(Object object, Class<O> clazz) throws JSONException {
JSONTypeDeserializer<Object,O> ser = (JSONTypeDeserializer<Object,O>) deserializers.get(clazz);
if(ser != null) {
return (O)ser.deserializeFromJson(object);
}else {
throw new JSONException("Could not find a deserializer for " + object.getClass().getSimpleName());
}
}
public static <O,J> JSONTypeSerializer<O,J> getSerializer(Class<O> object) {
return (JSONTypeSerializer<O,J>)serializers.get(object);
}
public static <J,O> JSONTypeDeserializer<J,O> getDeserializer(Class<O> object) {
return (JSONTypeDeserializer<J,O>)deserializers.get(object);
}
public static Object parse(Object object) {
for(int i = 0, l = parsers.size(); i < l; ++i) {
JSONDataParserImpl parser = parsers.get(i);
if(parser.accepts(object)) {
return parser.parse(object);
}
}
return object;
}
public static void registerType(Class<?> clazz, Object obj) {
boolean valid = false;
if(obj instanceof JSONTypeSerializer<?,?>) {
serializers.put(clazz, (JSONTypeSerializer<?,?>)obj);
valid = true;
}
if(obj instanceof JSONTypeDeserializer<?,?>) {
deserializers.put(clazz, (JSONTypeDeserializer<?,?>)obj);
valid = true;
}
if(!valid) {
throw new IllegalArgumentException("Object " + obj.getClass().getSimpleName() + " is not a JsonSerializer or JsonDeserializer object");
}
}
public static void registerParser(JSONDataParserImpl obj) {
parsers.add(obj);
}
static {
registerType(IChatComponent.class, new IChatComponent.Serializer());
registerType(ChatStyle.class, new ChatStyle.Serializer());
registerType(ServerStatusResponse.class, new ServerStatusResponse.Serializer());
registerType(ServerStatusResponse.MinecraftProtocolVersionIdentifier.class,
new ServerStatusResponse.MinecraftProtocolVersionIdentifier.Serializer());
registerType(ServerStatusResponse.PlayerCountData.class,
new ServerStatusResponse.PlayerCountData.Serializer());
registerType(ModelBlock.class, new ModelBlock.Deserializer());
registerType(BlockPart.class, new BlockPart.Deserializer());
registerType(BlockPartFace.class, new BlockPartFace.Deserializer());
registerType(BlockFaceUV.class, new BlockFaceUV.Deserializer());
registerType(ItemTransformVec3f.class, new ItemTransformVec3f.Deserializer());
registerType(ItemCameraTransforms.class, new ItemCameraTransforms.Deserializer());
registerType(ModelBlockDefinition.class, new ModelBlockDefinition.Deserializer());
registerType(ModelBlockDefinition.Variant.class, new ModelBlockDefinition.Variant.Deserializer());
registerType(SoundList.class, new SoundListSerializer());
registerType(SoundMap.class, new SoundMapDeserializer());
registerType(TextureMetadataSection.class, new TextureMetadataSectionSerializer());
registerType(FontMetadataSection.class, new FontMetadataSectionSerializer());
registerType(LanguageMetadataSection.class, new LanguageMetadataSectionSerializer());
registerType(PackMetadataSection.class, new PackMetadataSectionSerializer());
registerType(AnimationMetadataSection.class, new AnimationMetadataSectionSerializer());
registerParser(new JSONDataParserString());
registerParser(new JSONDataParserReader());
registerParser(new JSONDataParserStream());
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.v1_8.json;
import org.json.JSONException;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface JSONTypeSerializer<O, J> {
default J serializeToJson(O object) throws JSONException {
try {
return serialize(object);
}catch(JSONException obj) {
throw obj;
}catch(Throwable t) {
throw new JSONException("Exception serializing JSON object", t);
}
}
J serialize(O object) throws JSONException;
}

View File

@ -0,0 +1,50 @@
package net.lax1dude.eaglercraft.v1_8.json.impl;
import java.io.IOException;
import java.io.Reader;
import org.json.JSONException;
import net.lax1dude.eaglercraft.v1_8.json.JSONDataParserImpl;
import net.lax1dude.eaglercraft.v1_8.json.JSONTypeProvider;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class JSONDataParserReader implements JSONDataParserImpl {
public boolean accepts(Object type) {
return type instanceof Reader;
}
@Override
public Object parse(Object data) {
Reader r = (Reader)data;
StringBuilder builder = new StringBuilder();
char[] copyBuffer = new char[2048];
int i;
try {
try {
while((i = r.read(copyBuffer)) != -1) {
builder.append(copyBuffer, 0, i);
}
}finally {
r.close();
}
}catch(IOException ex) {
throw new JSONException("Could not deserialize from " + data.getClass().getSimpleName());
}
return JSONTypeProvider.parse(builder.toString());
}
}

View File

@ -0,0 +1,46 @@
package net.lax1dude.eaglercraft.v1_8.json.impl;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import org.json.JSONException;
import net.lax1dude.eaglercraft.v1_8.IOUtils;
import net.lax1dude.eaglercraft.v1_8.json.JSONDataParserImpl;
import net.lax1dude.eaglercraft.v1_8.json.JSONTypeProvider;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class JSONDataParserStream implements JSONDataParserImpl {
public boolean accepts(Object type) {
return type instanceof InputStream;
}
@Override
public Object parse(Object data) {
try {
InputStream s = (InputStream)data;
try {
return JSONTypeProvider.parse(IOUtils.inputStreamToString(s, StandardCharsets.UTF_8));
}finally {
s.close();
}
} catch (IOException e) {
throw new JSONException("Could not deserialize from " + data.getClass().getSimpleName());
}
}
}

View File

@ -0,0 +1,47 @@
package net.lax1dude.eaglercraft.v1_8.json.impl;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import net.lax1dude.eaglercraft.v1_8.json.JSONDataParserImpl;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class JSONDataParserString implements JSONDataParserImpl {
public boolean accepts(Object type) {
return type instanceof String;
}
@Override
public Object parse(Object data) {
String s = ((String)data).trim();
try {
if(s.indexOf('{') == 0 && s.lastIndexOf('}') == s.length() - 1) {
return new JSONObject(s);
}else if(s.indexOf('[') == 0 && s.lastIndexOf(']') == s.length() - 1) {
return new JSONArray(s);
}else if ((s.indexOf('\"') == 0 && s.lastIndexOf('\"') == s.length() - 1)
|| (s.indexOf('\'') == 0 && s.lastIndexOf('\'') == s.length() - 1)) {
return (new JSONObject("{\"E\":" + s + "}")).getString("E");
}else {
return (String)data;
}
}catch(JSONException ex) {
return (String)data;
}
}
}

View File

@ -0,0 +1,38 @@
package net.lax1dude.eaglercraft.v1_8.json.impl;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import net.lax1dude.eaglercraft.v1_8.json.JSONTypeDeserializer;
import net.lax1dude.eaglercraft.v1_8.json.JSONTypeProvider;
import net.minecraft.client.audio.SoundHandler.SoundMap;
import net.minecraft.client.audio.SoundList;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class SoundMapDeserializer implements JSONTypeDeserializer<JSONObject, SoundMap> {
@Override
public SoundMap deserialize(JSONObject json) throws JSONException {
Map<String, SoundList> soundsMap = new HashMap();
for(String str : json.keySet()) {
soundsMap.put(str, JSONTypeProvider.deserialize(json.getJSONObject(str), SoundList.class));
}
return new SoundMap(soundsMap);
}
}

View File

@ -0,0 +1,38 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
import java.io.PrintStream;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public enum Level {
TRACE(0, "TRACE", false), DEBUG(1, "DEBUG", false), INFO(2, "INFO", false),
WARN(3, "WARN", false), ERROR(4, "ERROR", true), FATAL(5, "FATAL", true),
OFF(Integer.MAX_VALUE, "DISABLED", false);
public final int levelInt;
public final String levelName;
public final PrintStream stdout;
private Level(int levelInt, String levelName, boolean stderr) {
this.levelInt = levelInt;
this.levelName = levelName;
this.stdout = stderr ? System.err : System.out;
}
PrintStream getPrintStream() {
return stdout;
}
}

View File

@ -0,0 +1,45 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
import java.util.HashMap;
import java.util.Map;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class LogManager {
private static final Map<String,Logger> loggerInstances = new HashMap();
public static final Object logLock = new Object();
public static Level logLevel = Level.DEBUG;
public static Logger getLogger() {
return getLogger("Minecraft");
}
public static Logger getLogger(String name) {
Logger ret;
synchronized(loggerInstances) {
ret = loggerInstances.get(name);
if(ret == null) {
ret = new Logger(name);
}
}
return ret;
}
public static void setLevel(Level lv) {
logLevel = lv;
}
}

View File

@ -0,0 +1,168 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class Logger {
public final String loggerName;
Logger(String name) {
this.loggerName = name;
}
public void trace(String msg) {
log(Level.TRACE, msg);
}
public void trace(String msg, Object... args) {
log(Level.TRACE, msg, args);
}
public void trace(Throwable msg) {
log(Level.WARN, msg);
}
public void debug(String msg) {
log(Level.DEBUG, msg);
}
public void debug(String msg, Object... args) {
log(Level.DEBUG, msg, args);
}
public void debug(Throwable msg) {
log(Level.DEBUG, msg);
}
public void info(String msg) {
log(Level.INFO, msg);
}
public void info(String msg, Object... args) {
log(Level.INFO, msg, args);
}
public void info(Throwable msg) {
log(Level.INFO, msg);
}
public void warn(String msg) {
log(Level.WARN, msg);
}
public void warn(String msg, Object... args) {
log(Level.WARN, msg, args);
}
public void warn(Throwable msg) {
log(Level.WARN, msg);
}
public void error(String msg) {
log(Level.ERROR, msg);
}
public void error(String msg, Object... args) {
log(Level.ERROR, msg, args);
}
public void error(Throwable msg) {
log(Level.ERROR, msg);
}
public void fatal(String msg) {
log(Level.FATAL, msg);
}
public void fatal(String msg, Object... args) {
log(Level.FATAL, msg, args);
}
public void fatal(Throwable msg) {
log(Level.FATAL, msg);
}
private static final SimpleDateFormat fmt = new SimpleDateFormat("hh:mm:ss+SSS");
private static final Date dateInstance = new Date();
public void log(Level level, String msg) {
if(level.levelInt >= LogManager.logLevel.levelInt) {
synchronized(LogManager.logLock) {
PrintStream ps = level.getPrintStream();
dateInstance.setTime(System.currentTimeMillis());
ps.println("[" + fmt.format(dateInstance) + "]" +
"[" + Thread.currentThread().getName() + "/" + level.levelName + "]" +
"[" + loggerName + "]: " + msg);
}
}
}
public void log(Level level, String msg, Object... args) {
if(level.levelInt >= LogManager.logLevel.levelInt) {
synchronized(LogManager.logLock) {
PrintStream ps = level.getPrintStream();
dateInstance.setTime(System.currentTimeMillis());
ps.println("[" + fmt.format(dateInstance) + "]" +
"[" + Thread.currentThread().getName() + "/" + level.levelName + "]" +
"[" + loggerName + "]: " + formatParams(msg, args));
}
}
}
public static String formatParams(String msg, Object... args) {
if(args.length > 0) {
StringBuilder builtString = new StringBuilder();
for(int i = 0; i < args.length; ++i) {
int idx = msg.indexOf("{}");
if(idx != -1) {
builtString.append(msg.substring(0, idx));
builtString.append(args[i]);
msg = msg.substring(idx + 2);
}else {
break;
}
}
builtString.append(msg);
return builtString.toString();
}else {
return msg;
}
}
public void log(Level level, Throwable msg) {
logExcp(level, "Exception Thrown", msg);
}
private void logExcp(final Level level, String h, Throwable msg) {
log(level, "{}: {}", h, msg.toString());
EagRuntime.getStackTrace(msg, (e) -> log(level, " at {}", e));
PlatformRuntime.printJSExceptionIfBrowser(msg);
Throwable cause = msg.getCause();
if(cause != null) {
logExcp(level, "Caused By", cause);
}
}
public boolean isDebugEnabled() {
return LogManager.logLevel.levelInt <= Level.DEBUG.levelInt;
}
}

View File

@ -0,0 +1,81 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import net.lax1dude.eaglercraft.v1_8.opengl.InstancedParticleRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class AcceleratedEffectRenderer implements IAcceleratedParticleEngine {
private float partialTicks;
private float f1;
private float f2;
private float f3;
private float f4;
private float f5;
public void begin(float partialTicks) {
this.partialTicks = partialTicks;
InstancedParticleRenderer.begin();
Entity et = Minecraft.getMinecraft().getRenderViewEntity();
if(et != null) {
f1 = MathHelper.cos(et.rotationYaw * 0.017453292F);
f2 = MathHelper.sin(et.rotationYaw * 0.017453292F);
f3 = -f2 * MathHelper.sin(et.rotationPitch * 0.017453292F);
f4 = f1 * MathHelper.sin(et.rotationPitch * 0.017453292F);
f5 = MathHelper.cos(et.rotationPitch * 0.017453292F);
}
}
public void draw(float texCoordWidth, float texCoordHeight) {
InstancedParticleRenderer.render(texCoordWidth, texCoordHeight, 0.0625f, f1, f5, f2, f3, f4);
}
@Override
public void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY, int lightMapData,
int texSize, float particleSize, float r, float g, float b, float a) {
float xx = (float) (entityIn.prevPosX + (entityIn.posX - entityIn.prevPosX) * (double) partialTicks - EntityFX.interpPosX);
float yy = (float) (entityIn.prevPosY + (entityIn.posY - entityIn.prevPosY) * (double) partialTicks - EntityFX.interpPosY);
float zz = (float) (entityIn.prevPosZ + (entityIn.posZ - entityIn.prevPosZ) * (double) partialTicks - EntityFX.interpPosZ);
drawParticle(xx, yy, zz, particleIndexX, particleIndexY, lightMapData, texSize, particleSize, r, g, b, a);
}
@Override
public void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY, int lightMapData,
int texSize, float particleSize, int rgba) {
float xx = (float) (entityIn.prevPosX + (entityIn.posX - entityIn.prevPosX) * (double) partialTicks - EntityFX.interpPosX);
float yy = (float) (entityIn.prevPosY + (entityIn.posY - entityIn.prevPosY) * (double) partialTicks - EntityFX.interpPosY);
float zz = (float) (entityIn.prevPosZ + (entityIn.posZ - entityIn.prevPosZ) * (double) partialTicks - EntityFX.interpPosZ);
drawParticle(xx, yy, zz, particleIndexX, particleIndexY, lightMapData, texSize, particleSize, rgba);
}
@Override
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a) {
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, r, g, b, a);
}
@Override
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba) {
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, rgba);
}
}

View File

@ -0,0 +1,231 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import java.util.LinkedList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
import net.lax1dude.eaglercraft.v1_8.opengl.WorldVertexBufferUploader;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RegionRenderCacheBuilder;
import net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator;
import net.minecraft.client.renderer.chunk.CompiledChunk;
import net.minecraft.client.renderer.chunk.ListedRenderChunk;
import net.minecraft.client.renderer.chunk.RenderChunk;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumWorldBlockLayer;
public class ChunkUpdateManager {
private static final Logger LOGGER = LogManager.getLogger();
private final WorldVertexBufferUploader worldVertexUploader;
private final RegionRenderCacheBuilder renderCache;
private int chunkUpdatesTotal = 0;
private int chunkUpdatesTotalLast = 0;
private int chunkUpdatesTotalImmediate = 0;
private int chunkUpdatesTotalImmediateLast = 0;
private int chunkUpdatesQueued = 0;
private int chunkUpdatesQueuedLast = 0;
private long chunkUpdatesTotalLastUpdate = 0l;
private final List<ChunkCompileTaskGenerator> queue = new LinkedList();
public ChunkUpdateManager() {
worldVertexUploader = new WorldVertexBufferUploader();
renderCache = new RegionRenderCacheBuilder();
}
public static class EmptyBlockLayerException extends IllegalStateException {
}
private void runGenerator(ChunkCompileTaskGenerator generator, Entity entity) {
generator.setRegionRenderCacheBuilder(renderCache);
float f = (float) entity.posX;
float f1 = (float) entity.posY + entity.getEyeHeight();
float f2 = (float) entity.posZ;
ChunkCompileTaskGenerator.Type chunkcompiletaskgenerator$type = generator.getType();
generator.setStatus(ChunkCompileTaskGenerator.Status.COMPILING);
if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.REBUILD_CHUNK) {
generator.getRenderChunk().rebuildChunk(f, f1, f2, generator);
} else if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.RESORT_TRANSPARENCY) {
RenderChunk r = generator.getRenderChunk();
try {
r.resortTransparency(f, f1, f2, generator);
if(generator.getCompiledChunk().isLayerEmpty(EnumWorldBlockLayer.TRANSLUCENT)) {
throw new EmptyBlockLayerException();
}
}catch(EmptyBlockLayerException ex) {
LOGGER.error("RenderChunk {} tried to update it's TRANSLUCENT layer with no proper initialization", r.getPosition());
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
return; // rip
}
}
generator.setStatus(ChunkCompileTaskGenerator.Status.UPLOADING);
final CompiledChunk compiledchunk = generator.getCompiledChunk();
if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.REBUILD_CHUNK) {
for (EnumWorldBlockLayer enumworldblocklayer : EnumWorldBlockLayer.values()) {
if (!compiledchunk.isLayerEmpty(enumworldblocklayer)) {
this.uploadChunk(enumworldblocklayer,
generator.getRegionRenderCacheBuilder().getWorldRendererByLayer(enumworldblocklayer),
generator.getRenderChunk(), compiledchunk);
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
}
}
generator.getRenderChunk().setCompiledChunk(compiledchunk);
} else if (chunkcompiletaskgenerator$type == ChunkCompileTaskGenerator.Type.RESORT_TRANSPARENCY) {
this.uploadChunk(EnumWorldBlockLayer.TRANSLUCENT, generator.getRegionRenderCacheBuilder()
.getWorldRendererByLayer(EnumWorldBlockLayer.TRANSLUCENT),
generator.getRenderChunk(), compiledchunk);
generator.getRenderChunk().setCompiledChunk(compiledchunk);
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
}
}
public boolean updateChunks(long timeout) {
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
if (entity == null) {
queue.clear();
chunkUpdatesQueued = 0;
return false;
}else {
boolean flag = false;
long millis = System.currentTimeMillis();
List<ChunkCompileTaskGenerator> droppedUpdates = new LinkedList();
while(!queue.isEmpty()) {
ChunkCompileTaskGenerator generator = queue.remove(0);
if(!generator.canExecuteYet()) {
if(millis - generator.goddamnFuckingTimeout < 60000l) {
droppedUpdates.add(generator);
}
continue;
}
runGenerator(generator, entity);
flag = true;
++chunkUpdatesTotal;
if(timeout < System.nanoTime()) {
break;
}
}
queue.addAll(droppedUpdates);
return flag;
}
}
public boolean updateChunkLater(RenderChunk chunkRenderer) {
final ChunkCompileTaskGenerator chunkcompiletaskgenerator = chunkRenderer.makeCompileTaskChunk();
boolean flag = queue.size() < 100;
if (!flag) {
chunkcompiletaskgenerator.finish();
}else {
chunkcompiletaskgenerator.addFinishRunnable(new Runnable() {
@Override
public void run() {
if(queue.remove(chunkcompiletaskgenerator)) {
++chunkUpdatesTotal;
}
}
});
queue.add(chunkcompiletaskgenerator);
++chunkUpdatesQueued;
}
return flag;
}
public boolean updateChunkNow(RenderChunk chunkRenderer) {
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
if (entity != null) {
runGenerator(chunkRenderer.makeCompileTaskChunk(), entity);
++chunkUpdatesTotalImmediate;
}
return true;
}
public void stopChunkUpdates() {
queue.clear();
chunkUpdatesQueued = 0;
}
public boolean updateTransparencyLater(RenderChunk chunkRenderer) {
if(isAlreadyQueued(chunkRenderer)) {
return true;
}
final ChunkCompileTaskGenerator chunkcompiletaskgenerator = chunkRenderer.makeCompileTaskTransparency();
if (chunkcompiletaskgenerator == null) {
return true;
}
chunkcompiletaskgenerator.goddamnFuckingTimeout = System.currentTimeMillis();
if(queue.size() < 100) {
chunkcompiletaskgenerator.addFinishRunnable(new Runnable() {
@Override
public void run() {
if(queue.remove(chunkcompiletaskgenerator)) {
++chunkUpdatesTotal;
}
}
});
queue.add(chunkcompiletaskgenerator);
++chunkUpdatesQueued;
return true;
}else {
return false;
}
}
public void uploadChunk(final EnumWorldBlockLayer player, final WorldRenderer chunkRenderer,
final RenderChunk compiledChunkIn, final CompiledChunk parCompiledChunk) {
this.uploadDisplayList(chunkRenderer,
((ListedRenderChunk) compiledChunkIn).getDisplayList(player, parCompiledChunk), compiledChunkIn);
chunkRenderer.setTranslation(0.0D, 0.0D, 0.0D);
}
private void uploadDisplayList(WorldRenderer chunkRenderer, int parInt1, RenderChunk parRenderChunk) {
EaglercraftGPU.glNewList(parInt1, GL_COMPILE);
GlStateManager.pushMatrix();
this.worldVertexUploader.func_181679_a(chunkRenderer);
GlStateManager.popMatrix();
EaglercraftGPU.glEndList();
}
public boolean isAlreadyQueued(RenderChunk update) {
for(int i = 0, l = queue.size(); i < l; ++i) {
if(queue.get(i).getRenderChunk() == update) {
return true;
}
}
return false;
}
public String getDebugInfo() {
long millis = System.currentTimeMillis();
if(millis - chunkUpdatesTotalLastUpdate > 500l) {
chunkUpdatesTotalLastUpdate = millis;
chunkUpdatesTotalLast = chunkUpdatesTotal;
chunkUpdatesTotalImmediateLast = chunkUpdatesTotalImmediate;
chunkUpdatesTotalImmediate = 0;
chunkUpdatesTotal = 0;
chunkUpdatesQueuedLast = chunkUpdatesQueued;
chunkUpdatesQueued -= chunkUpdatesTotalLast;
if(chunkUpdatesQueued < 0) {
chunkUpdatesQueued = 0;
}
}
return "Uq: " + (chunkUpdatesTotalLast + chunkUpdatesTotalImmediateLast) + "/"
+ (chunkUpdatesQueuedLast + chunkUpdatesTotalImmediateLast);
}
}

View File

@ -0,0 +1,231 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.InstancedFontRenderer;
import net.lax1dude.eaglercraft.v1_8.opengl.WorldRenderer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglerFontRenderer extends FontRenderer {
private final int[] temporaryCodepointArray = new int[6553];
public EaglerFontRenderer(GameSettings gameSettingsIn, ResourceLocation location, TextureManager textureManagerIn,
boolean unicode) {
super(gameSettingsIn, location, textureManagerIn, unicode);
}
public int drawString(String text, float x, float y, int color, boolean dropShadow) {
if (text == null || text.length() == 0) {
this.posX = x + (dropShadow ? 1 : 0);
this.posY = y;
} else {
if(this.unicodeFlag || !decodeASCIICodepointsAndValidate(text)) {
return super.drawString(text, x, y, color, dropShadow);
}
this.resetStyles();
if ((color & 0xFC000000) == 0) {
color |= 0xFF000000;
}
this.red = (float) (color >> 16 & 255) / 255.0F;
this.blue = (float) (color >> 8 & 255) / 255.0F;
this.green = (float) (color & 255) / 255.0F;
this.alpha = (float) (color >> 24 & 255) / 255.0F;
this.posX = x;
this.posY = y;
this.textColor = color;
this.renderStringAtPos0(text, dropShadow);
}
return (int) this.posX;
}
protected void renderStringAtPos(String parString1, boolean parFlag) {
if(parString1 == null) return;
if(this.unicodeFlag || !decodeASCIICodepointsAndValidate(parString1)) {
super.renderStringAtPos(parString1, parFlag);
}else {
renderStringAtPos0(parString1, false);
}
}
private void renderStringAtPos0(String parString1, boolean parFlag) {
renderEngine.bindTexture(locationFontTexture);
InstancedFontRenderer.begin();
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
boolean hasStrike = false;
for (int i = 0; i < parString1.length(); ++i) {
char c0 = parString1.charAt(i);
if (c0 == 167 && i + 1 < parString1.length()) {
int i1 = "0123456789abcdefklmnor".indexOf(Character.toLowerCase(parString1.charAt(i + 1)));
if (i1 < 16) {
this.randomStyle = false;
this.boldStyle = false;
this.strikethroughStyle = false;
this.underlineStyle = false;
this.italicStyle = false;
if (i1 < 0 || i1 > 15) {
i1 = 15;
}
int j1 = this.colorCode[i1];
this.textColor = j1 | (this.textColor & 0xFF000000);
} else if (i1 == 16) {
this.randomStyle = true;
} else if (i1 == 17) {
this.boldStyle = true;
} else if (i1 == 18) {
this.strikethroughStyle = true;
} else if (i1 == 19) {
this.underlineStyle = true;
} else if (i1 == 20) {
this.italicStyle = true;
} else if (i1 == 21) {
this.randomStyle = false;
this.boldStyle = false;
this.strikethroughStyle = false;
this.underlineStyle = false;
this.italicStyle = false;
this.textColor = ((int) (this.alpha * 255.0f) << 24) | ((int) (this.red * 255.0f) << 16)
| ((int) (this.green * 255.0f) << 8) | (int) (this.blue * 255.0f);
}
++i;
} else {
int j = temporaryCodepointArray[i];
if (this.randomStyle && j != -1) {
int k = this.getCharWidth(c0);
String chars = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
char c1;
while (true) {
j = this.fontRandom.nextInt(chars.length());
c1 = chars.charAt(j);
if (k == this.getCharWidth(c1)) {
break;
}
}
c0 = c1;
}
float f = this.appendCharToBuffer(j, this.textColor, this.boldStyle, this.italicStyle);
if (this.strikethroughStyle) {
hasStrike = true;
worldrenderer.pos((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D)
.endVertex();
worldrenderer
.pos((double) (this.posX + f), (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D)
.endVertex();
worldrenderer.pos((double) (this.posX + f),
(double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D).endVertex();
worldrenderer
.pos((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D)
.endVertex();
worldrenderer.putColor4(this.textColor);
}
if (this.underlineStyle) {
hasStrike = true;
int l = this.underlineStyle ? -1 : 0;
worldrenderer.pos((double) (this.posX + (float) l),
(double) (this.posY + (float) this.FONT_HEIGHT), 0.0D).endVertex();
worldrenderer.pos((double) (this.posX + f), (double) (this.posY + (float) this.FONT_HEIGHT), 0.0D)
.endVertex();
worldrenderer
.pos((double) (this.posX + f), (double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D)
.endVertex();
worldrenderer.pos((double) (this.posX + (float) l),
(double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D).endVertex();
worldrenderer.putColor4(this.textColor);
}
this.posX += (float) ((int) f);
}
}
float texScale = 0.0625f;
if(!hasStrike) {
worldrenderer.finishDrawing();
}
if(parFlag) {
if(hasStrike) {
GlStateManager.color(0.25f, 0.25f, 0.25f, 1.0f);
GlStateManager.translate(1.0f, 1.0f, 0.0f);
tessellator.draw();
GlStateManager.translate(-1.0f, -1.0f, 0.0f);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
InstancedFontRenderer.render(8, 8, texScale, texScale, true);
EaglercraftGPU.renderAgain();
}else {
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
InstancedFontRenderer.render(8, 8, texScale, texScale, true);
}
}else {
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
if(hasStrike) {
tessellator.draw();
}
InstancedFontRenderer.render(8, 8, texScale, texScale, false);
}
if(parFlag) {
this.posX += 1.0f;
}
}
private float appendCharToBuffer(int parInt1, int color, boolean boldStyle, boolean italicStyle) {
if (parInt1 == 32) {
return 4.0f;
}else {
int i = parInt1 % 16;
int j = parInt1 / 16;
float w = this.charWidth[parInt1];
if(boldStyle) {
InstancedFontRenderer.appendBoldQuad((int)this.posX, (int)this.posY, i, j, color, italicStyle);
++w;
}else {
InstancedFontRenderer.appendQuad((int)this.posX, (int)this.posY, i, j, color, italicStyle);
}
return w;
}
}
private boolean decodeASCIICodepointsAndValidate(String str) {
for(int i = 0, l = str.length(); i < l; ++i) {
int j = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000\u00a7"
.indexOf(str.charAt(i));
if(j != -1) {
temporaryCodepointArray[i] = j;
}else {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,355 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import com.google.common.collect.Lists;
import net.lax1dude.eaglercraft.v1_8.HString;
import net.lax1dude.eaglercraft.v1_8.opengl.ImageData;
import net.minecraft.client.renderer.texture.TextureClock;
import net.minecraft.client.renderer.texture.TextureCompass;
import net.minecraft.client.renderer.texture.TextureUtil;
import net.minecraft.client.resources.data.AnimationFrame;
import net.minecraft.client.resources.data.AnimationMetadataSection;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.util.ReportedException;
import net.minecraft.util.ResourceLocation;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglerTextureAtlasSprite {
private final String iconName;
protected List<int[][]> framesTextureData = Lists.newArrayList();
protected int[][] interpolatedFrameData;
private AnimationMetadataSection animationMetadata;
private int cacheInterpolateSteps;
protected boolean rotated;
protected int originX;
protected int originY;
protected int width;
protected int height;
private float minU;
private float maxU;
private float minV;
private float maxV;
protected int frameCounter;
protected int tickCounter;
private static String locationNameClock = "builtin/clock";
private static String locationNameCompass = "builtin/compass";
protected TextureAnimationCache animationCache = null;
public EaglerTextureAtlasSprite(String spriteName) {
this.iconName = spriteName;
}
public static EaglerTextureAtlasSprite makeAtlasSprite(ResourceLocation spriteResourceLocation) {
String s = spriteResourceLocation.toString();
return (EaglerTextureAtlasSprite) (locationNameClock.equals(s) ? new TextureClock(s)
: (locationNameCompass.equals(s) ? new TextureCompass(s) : new EaglerTextureAtlasSprite(s)));
}
public static void setLocationNameClock(String clockName) {
locationNameClock = clockName;
}
public static void setLocationNameCompass(String compassName) {
locationNameCompass = compassName;
}
public void initSprite(int inX, int inY, int originInX, int originInY, boolean rotatedIn) {
this.originX = originInX;
this.originY = originInY;
this.rotated = rotatedIn;
float f = (float) (0.009999999776482582D / (double) inX);
float f1 = (float) (0.009999999776482582D / (double) inY);
this.minU = (float) originInX / (float) ((double) inX) + f;
this.maxU = (float) (originInX + this.width) / (float) ((double) inX) - f;
this.minV = (float) originInY / (float) inY + f1;
this.maxV = (float) (originInY + this.height) / (float) inY - f1;
}
public void copyFrom(EaglerTextureAtlasSprite atlasSpirit) {
this.originX = atlasSpirit.originX;
this.originY = atlasSpirit.originY;
this.width = atlasSpirit.width;
this.height = atlasSpirit.height;
this.rotated = atlasSpirit.rotated;
this.minU = atlasSpirit.minU;
this.maxU = atlasSpirit.maxU;
this.minV = atlasSpirit.minV;
this.maxV = atlasSpirit.maxV;
}
public int getOriginX() {
return this.originX;
}
public int getOriginY() {
return this.originY;
}
public int getIconWidth() {
return this.width;
}
public int getIconHeight() {
return this.height;
}
public float getMinU() {
return this.minU;
}
public float getMaxU() {
return this.maxU;
}
public float getInterpolatedU(double u) {
float f = this.maxU - this.minU;
return this.minU + f * (float) u / 16.0F;
}
public float getMinV() {
return this.minV;
}
public float getMaxV() {
return this.maxV;
}
public float getInterpolatedV(double v) {
float f = this.maxV - this.minV;
return this.minV + f * ((float) v / 16.0F);
}
public String getIconName() {
return this.iconName;
}
public void updateAnimation() {
if(animationCache == null) {
throw new IllegalStateException("Animation cache for '" + this.iconName + "' was never baked!");
}
++this.tickCounter;
if (this.tickCounter >= this.animationMetadata.getFrameTimeSingle(this.frameCounter)) {
int i = this.animationMetadata.getFrameIndex(this.frameCounter);
int j = this.animationMetadata.getFrameCount() == 0 ? this.framesTextureData.size()
: this.animationMetadata.getFrameCount();
this.frameCounter = (this.frameCounter + 1) % j;
this.tickCounter = 0;
int k = this.animationMetadata.getFrameIndex(this.frameCounter);
if (i != k && k >= 0 && k < this.framesTextureData.size()) {
animationCache.copyFrameLevelsToTex2D(k, this.originX, this.originY, this.width, this.height);
}
} else if (this.animationMetadata.isInterpolate()) {
float f = 1.0f - (float) this.tickCounter / (float) this.animationMetadata.getFrameTimeSingle(this.frameCounter);
int i = this.animationMetadata.getFrameIndex(this.frameCounter);
int j = this.animationMetadata.getFrameCount() == 0 ? this.framesTextureData.size()
: this.animationMetadata.getFrameCount();
int k = this.animationMetadata.getFrameIndex((this.frameCounter + 1) % j);
if (i != k && k >= 0 && k < this.framesTextureData.size()) {
animationCache.copyInterpolatedFrameLevelsToTex2D(i, k, f, this.originX, this.originY, this.width, this.height);
}
}
}
public int[][] getFrameTextureData(int index) {
return (int[][]) this.framesTextureData.get(index);
}
public int getFrameCount() {
return this.framesTextureData.size();
}
public void setIconWidth(int newWidth) {
this.width = newWidth;
}
public void setIconHeight(int newHeight) {
this.height = newHeight;
}
public void loadSprite(ImageData[] images, AnimationMetadataSection meta) throws IOException {
this.resetSprite();
int i = images[0].width;
int j = images[0].height;
this.width = i;
this.height = j;
int[][] aint = new int[images.length][];
for (int k = 0; k < images.length; ++k) {
ImageData bufferedimage = images[k];
if (bufferedimage != null) {
if (k > 0 && (bufferedimage.width) != i >> k || bufferedimage.height != j >> k) {
throw new RuntimeException(
HString.format("Unable to load miplevel: %d, image is size: %dx%d, expected %dx%d",
new Object[] { Integer.valueOf(k), Integer.valueOf(bufferedimage.width),
Integer.valueOf(bufferedimage.height), Integer.valueOf(i >> k),
Integer.valueOf(j >> k) }));
}
aint[k] = new int[bufferedimage.width * bufferedimage.height];
bufferedimage.getRGB(0, 0, bufferedimage.width, bufferedimage.height, aint[k], 0, bufferedimage.width);
}
}
if (meta == null) {
if (j != i) {
throw new RuntimeException("broken aspect ratio and not an animation");
}
this.framesTextureData.add(aint);
} else {
int j1 = j / i;
int k1 = i;
int l = i;
this.height = this.width;
if (meta.getFrameCount() > 0) {
Iterator iterator = meta.getFrameIndexSet().iterator();
while (iterator.hasNext()) {
int i1 = ((Integer) iterator.next()).intValue();
if (i1 >= j1) {
throw new RuntimeException("invalid frameindex " + i1);
}
this.allocateFrameTextureData(i1);
this.framesTextureData.set(i1, getFrameTextureData(aint, k1, l, i1));
}
this.animationMetadata = meta;
} else {
ArrayList arraylist = Lists.newArrayList();
for (int l1 = 0; l1 < j1; ++l1) {
this.framesTextureData.add(getFrameTextureData(aint, k1, l, l1));
arraylist.add(new AnimationFrame(l1, -1));
}
this.animationMetadata = new AnimationMetadataSection(arraylist, this.width, this.height,
meta.getFrameTime(), meta.isInterpolate());
}
}
}
public void generateMipmaps(int level) {
ArrayList arraylist = Lists.newArrayList();
for (int i = 0; i < this.framesTextureData.size(); ++i) {
final int[][] aint = (int[][]) this.framesTextureData.get(i);
if (aint != null) {
try {
arraylist.add(TextureUtil.generateMipmapData(level, this.width, aint));
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Generating mipmaps for frame");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Frame being iterated");
crashreportcategory.addCrashSection("Frame index", Integer.valueOf(i));
crashreportcategory.addCrashSectionCallable("Frame sizes", new Callable<String>() {
public String call() throws Exception {
StringBuilder stringbuilder = new StringBuilder();
for (int[] aint1 : aint) {
if (stringbuilder.length() > 0) {
stringbuilder.append(", ");
}
stringbuilder.append(aint1 == null ? "null" : Integer.valueOf(aint1.length));
}
return stringbuilder.toString();
}
});
throw new ReportedException(crashreport);
}
}
}
this.setFramesTextureData(arraylist);
this.bakeAnimationCache();
}
public void bakeAnimationCache() {
if(animationMetadata != null) {
int mipLevels = framesTextureData.get(0).length;
if(animationCache == null) {
animationCache = new TextureAnimationCache(width, height, mipLevels);
}
animationCache.initialize(framesTextureData, animationMetadata.isInterpolate());
}
}
private void allocateFrameTextureData(int index) {
if (this.framesTextureData.size() <= index) {
for (int i = this.framesTextureData.size(); i <= index; ++i) {
this.framesTextureData.add((int[][]) null);
}
}
}
private static int[][] getFrameTextureData(int[][] data, int rows, int columns, int parInt3) {
int[][] aint = new int[data.length][];
for (int i = 0; i < data.length; ++i) {
int[] aint1 = data[i];
if (aint1 != null) {
aint[i] = new int[(rows >> i) * (columns >> i)];
System.arraycopy(aint1, parInt3 * aint[i].length, aint[i], 0, aint[i].length);
}
}
return aint;
}
public void clearFramesTextureData() {
this.framesTextureData.clear();
if(this.animationCache != null) {
this.animationCache.free();
this.animationCache = null;
}
}
public boolean hasAnimationMetadata() {
return this.animationMetadata != null;
}
public void setFramesTextureData(List<int[][]> newFramesTextureData) {
this.framesTextureData = newFramesTextureData;
}
private void resetSprite() {
this.animationMetadata = null;
this.setFramesTextureData(Lists.newArrayList());
this.frameCounter = 0;
this.tickCounter = 0;
if(this.animationCache != null) {
this.animationCache.free();
this.animationCache = null;
}
}
public String toString() {
return "TextureAtlasSprite{name=\'" + this.iconName + '\'' + ", frameCount=" + this.framesTextureData.size()
+ ", rotated=" + this.rotated + ", x=" + this.originX + ", y=" + this.originY + ", height="
+ this.height + ", width=" + this.width + ", u0=" + this.minU + ", u1=" + this.maxU + ", v0="
+ this.minV + ", v1=" + this.maxV + '}';
}
}

View File

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import net.minecraft.entity.Entity;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public interface IAcceleratedParticleEngine {
void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a);
void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba);
void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a);
void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba);
}

View File

@ -0,0 +1,237 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.IFramebufferGL;
import net.lax1dude.eaglercraft.v1_8.internal.IRenderbufferGL;
import net.lax1dude.eaglercraft.v1_8.internal.ITextureGL;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
import net.lax1dude.eaglercraft.v1_8.opengl.EaglercraftGPU;
import net.lax1dude.eaglercraft.v1_8.opengl.GlStateManager;
import net.lax1dude.eaglercraft.v1_8.opengl.SpriteLevelMixer;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
import net.minecraft.client.renderer.GLAllocation;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class TextureAnimationCache {
public static final int _GL_FRAMEBUFFER = 0x8D40; // enum not defined in RealOpenGLEnums
public static final int _GL_RENDERBUFFER = 0x8D41;
public static final int _GL_COLOR_ATTACHMENT0 = 0x8CE0;
public final int width;
public final int height;
public final int mipLevels;
private int frameCount = 1;
private int[] cacheTextures = null;
private IFramebufferGL[] cacheFramebuffers = null;
private IFramebufferGL interpolateFramebuffer = null;
private IRenderbufferGL interpolateRenderbuffer = null;
public TextureAnimationCache(int width, int height, int mipLevels) {
this.width = width;
this.height = height;
this.mipLevels = mipLevels;
}
public void initialize(List<int[][]> frames, boolean enableInterpolation) {
boolean init = cacheTextures == null;
if(init) {
cacheTextures = new int[mipLevels];
for(int i = 0; i < cacheTextures.length; ++i) {
cacheTextures[i] = GlStateManager.generateTexture();
GlStateManager.bindTexture(cacheTextures[i]);
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
EaglercraftGPU.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
if(enableInterpolation) {
interpolateFramebuffer = _wglCreateFramebuffer();
_wglBindFramebuffer(_GL_FRAMEBUFFER, interpolateFramebuffer);
interpolateRenderbuffer = _wglCreateRenderbuffer();
_wglBindRenderbuffer(_GL_RENDERBUFFER, interpolateRenderbuffer);
_wglRenderbufferStorage(_GL_RENDERBUFFER, GL_RGBA8, width, height);
_wglFramebufferRenderbuffer(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0,
_GL_RENDERBUFFER, interpolateRenderbuffer);
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
}
}
frameCount = frames.size();
IntBuffer pixels = GLAllocation.createDirectIntBuffer(width * height * frameCount);
try {
for(int i = 0; i < mipLevels; ++i) {
pixels.clear();
int lw = width >> i;
int lh = height >> i;
int tileLength = lw * lh;
for(int j = 0; j < frameCount; ++j) {
int[][] frame = frames.get(j);
if(frame.length <= i) {
throw new IllegalArgumentException("Frame #" + j + " only has " + frame.length + " mipmap levels! (" + mipLevels + " were expected)");
}
int[] frameLevel = frame[i];
if(frameLevel.length != tileLength) {
throw new IllegalArgumentException("Frame #" + j + " level " + i + " is " + frameLevel.length + " pixels large! (" + tileLength + " expected)");
}
pixels.put(frameLevel);
}
pixels.flip();
GlStateManager.bindTexture(cacheTextures[i]);
EaglercraftGPU.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, lw, lh * frameCount, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
}finally {
EagRuntime.freeIntBuffer(pixels);
}
if(init) {
cacheFramebuffers = new IFramebufferGL[mipLevels];
for(int i = 0; i < mipLevels; ++i) {
GlStateManager.bindTexture(cacheTextures[i]);
IFramebufferGL fbo = _wglCreateFramebuffer();
_wglBindFramebuffer(_GL_FRAMEBUFFER, fbo);
_wglFramebufferTexture2D(_GL_FRAMEBUFFER, _GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
EaglercraftGPU.getNativeTexture(cacheTextures[i]), 0);
cacheFramebuffers[i] = fbo;
}
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
}
}
public void free() {
if(cacheTextures != null) {
if(interpolateFramebuffer != null) {
_wglDeleteFramebuffer(interpolateFramebuffer);
interpolateFramebuffer = null;
}
if(interpolateRenderbuffer != null) {
_wglDeleteRenderbuffer(interpolateRenderbuffer);
interpolateRenderbuffer = null;
}
if(cacheFramebuffers != null) {
for(int i = 0; i < mipLevels; ++i) {
_wglDeleteFramebuffer(cacheFramebuffers[i]);
}
cacheFramebuffers = null;
}
for(int i = 0; i < cacheTextures.length; ++i) {
GlStateManager.deleteTexture(cacheTextures[i]);
}
cacheTextures = null;
}
}
public void copyFrameLevelsToTex2D(int animationFrame, int dx, int dy, int w, int h) {
copyFrameLevelsToTex2D(animationFrame, mipLevels, dx, dy, w, h);
}
public void copyFrameLevelsToTex2D(int animationFrame, int levels, int dx, int dy, int w, int h) {
for(int i = 0; i < levels; ++i) {
copyFrameToTex2D(animationFrame, i, dx >> i, dy >> i, w >> i, h >> i);
}
}
public void copyFrameToTex2D(int animationFrame, int level, int dx, int dy, int w, int h) {
if(cacheTextures == null) {
throw new IllegalStateException("Cannot copy from uninitialized TextureAnimationCache");
}
_wglBindFramebuffer(_GL_FRAMEBUFFER, cacheFramebuffers[level]);
_wglReadBuffer(_GL_COLOR_ATTACHMENT0);
_wglCopyTexSubImage2D(GL_TEXTURE_2D, level, dx, dy, 0, h * animationFrame, w, h);
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
}
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int dx,
int dy, int w, int h) {
copyInterpolatedFrameLevelsToTex2D(animationFrameFrom, animationFrameTo, factor, mipLevels, dx, dy, w, h);
}
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor,
int levels, int dx, int dy, int w, int h) {
for(int i = 0; i < levels; ++i) {
copyInterpolatedFrameToTex2D(animationFrameFrom, animationFrameTo, factor, i, dx >> i, dy >> i, w >> i, h >> i);
}
}
public void copyInterpolatedFrameToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int level,
int dx, int dy, int w, int h) {
if(cacheTextures == null) {
throw new IllegalStateException("Cannot copy from uninitialized TextureAnimationCache");
}
int storeTexture = GlStateManager.getTextureBound();
_wglBindFramebuffer(_GL_FRAMEBUFFER, interpolateFramebuffer);
GlStateManager.bindTexture(cacheTextures[level]);
int[] storeViewport = new int[4];
EaglercraftGPU.glGetInteger(GL_VIEWPORT, storeViewport);
GlStateManager.viewport(0, 0, w, h);
GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
GlStateManager.clear(GL_COLOR_BUFFER_BIT);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL_ONE, GL_ONE);
Matrix3f matrix = new Matrix3f();
matrix.m11 = 1.0f / frameCount;
matrix.m21 = matrix.m11 * animationFrameFrom;
SpriteLevelMixer.setMatrix3f(matrix);
SpriteLevelMixer.setBlendColor(factor, factor, factor, factor);
SpriteLevelMixer.setBiasColor(0.0f, 0.0f, 0.0f, 0.0f);
SpriteLevelMixer.drawSprite(0);
matrix.m21 = matrix.m11 * animationFrameTo;
SpriteLevelMixer.setMatrix3f(matrix);
float fac1 = 1.0f - factor;
SpriteLevelMixer.setBlendColor(fac1, fac1, fac1, fac1);
SpriteLevelMixer.drawSprite(0);
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.disableBlend();
GlStateManager.bindTexture(storeTexture);
GlStateManager.viewport(storeViewport[0], storeViewport[1], storeViewport[2], storeViewport[3]);
GlStateManager.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
_wglReadBuffer(_GL_COLOR_ATTACHMENT0);
_wglCopyTexSubImage2D(GL_TEXTURE_2D, level, dx, dy, 0, 0, w, h);
_wglBindFramebuffer(_GL_FRAMEBUFFER, null);
}
public int getFrameCount() {
return frameCount;
}
}

View File

@ -0,0 +1,96 @@
package net.lax1dude.eaglercraft.v1_8.mojang.authlib;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class GameProfile {
private final EaglercraftUUID id;
private final String name;
private final Multimap<String, Property> properties;
private TexturesProperty textures = null;
public GameProfile(EaglercraftUUID id, String name) {
this(id, name, MultimapBuilder.hashKeys().arrayListValues().build());
}
public GameProfile(EaglercraftUUID id, String name, Multimap<String, Property> properties) {
if (id == null && StringUtils.isBlank(name))
throw new IllegalArgumentException("Name and ID cannot both be blank");
this.id = id;
this.name = name;
this.properties = properties;
}
public EaglercraftUUID getId() {
return this.id;
}
public String getName() {
return this.name;
}
public boolean isComplete() {
return (this.id != null && StringUtils.isNotBlank(getName()));
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
GameProfile that = (GameProfile) o;
if ((this.id != null) ? !this.id.equals(that.id) : (that.id != null))
return false;
if ((this.name != null) ? !this.name.equals(that.name) : (that.name != null))
return false;
return true;
}
public int hashCode() {
int result = (this.id != null) ? this.id.hashCode() : 0;
result = 31 * result + ((this.name != null) ? this.name.hashCode() : 0);
return result;
}
public String toString() {
return (new ToStringBuilder(this)).append("id", this.id).append("name", this.name)
.append("legacy", false).toString();
}
public boolean isLegacy() {
return false;
}
public Multimap<String, Property> getProperties() {
return properties;
}
public TexturesProperty getTextures() {
if(textures == null) {
textures = TexturesProperty.parseProfile(this);
}
return textures;
}
}

View File

@ -0,0 +1,46 @@
package net.lax1dude.eaglercraft.v1_8.mojang.authlib;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class Property {
private final String name;
private final String value;
private final String signature;
public Property(final String value, final String name) {
this(value, name, null);
}
public Property(final String name, final String value, final String signature) {
this.name = name;
this.value = value;
this.signature = signature;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
public String getSignature() {
return this.signature;
}
public boolean hasSignature() {
return this.signature != null;
}
}

View File

@ -0,0 +1,87 @@
package net.lax1dude.eaglercraft.v1_8.mojang.authlib;
import java.util.Collection;
import org.json.JSONObject;
import net.lax1dude.eaglercraft.v1_8.ArrayUtils;
import net.lax1dude.eaglercraft.v1_8.Base64;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class TexturesProperty {
public final String skin;
public final String model;
public final String cape;
public final boolean eaglerPlayer;
public static final TexturesProperty defaultNull = new TexturesProperty(null, "default", null, false);
private TexturesProperty(String skin, String model, String cape, boolean eaglerPlayer) {
this.skin = skin;
this.model = model;
this.cape = cape;
this.eaglerPlayer = eaglerPlayer;
}
public static TexturesProperty parseProfile(GameProfile profile) {
Collection<Property> etr = profile.getProperties().get("textures");
if(!etr.isEmpty()) {
Property prop = etr.iterator().next();
String str;
try {
str = ArrayUtils.asciiString(Base64.decodeBase64(prop.getValue()));
}catch(Throwable t) {
return defaultNull;
}
boolean isEagler = false;
etr = profile.getProperties().get("isEaglerPlayer");
if(!etr.isEmpty()) {
prop = etr.iterator().next();
isEagler = prop.getValue().equalsIgnoreCase("true");
}
return parseTextures(str, isEagler);
}else {
return defaultNull;
}
}
public static TexturesProperty parseTextures(String string, boolean isEagler) {
String skin = null;
String model = "default";
String cape = null;
try {
JSONObject json = new JSONObject(string);
json = json.optJSONObject("textures");
if(json != null) {
JSONObject skinObj = json.optJSONObject("SKIN");
if(skinObj != null) {
skin = skinObj.optString("url");
JSONObject meta = skinObj.optJSONObject("metadata");
if(meta != null) {
model = meta.optString("model", model);
}
}
JSONObject capeObj = json.optJSONObject("SKIN");
if(capeObj != null) {
cape = capeObj.optString("url");
}
}
}catch(Throwable t) {
}
return new TexturesProperty(skin, model, cape, isEagler);
}
}

View File

@ -0,0 +1,26 @@
package net.lax1dude.eaglercraft.v1_8.mojang.authlib;
import net.lax1dude.eaglercraft.v1_8.EaglercraftUUID;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class UUIDTypeAdapter {
public static String fromUUID(EaglercraftUUID value) {
return value.toString().replace("-", "");
}
public static EaglercraftUUID fromString(String input) {
return EaglercraftUUID.fromString(input.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,252 @@
package net.lax1dude.eaglercraft.v1_8.netty;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class ByteBufEaglercraftImpl extends AbstractByteBuf {
private ByteBuffer internal;
public ByteBufEaglercraftImpl(ByteBuffer internal, int maxCapacity) {
super(maxCapacity);
if(internal.order() != ByteOrder.BIG_ENDIAN) {
this.internal = internal.order(ByteOrder.BIG_ENDIAN);
}else {
this.internal = internal;
}
}
@Override
protected byte _getByte(int index) {
return internal.get(index);
}
@Override
protected short _getShort(int index) {
return internal.getShort(index);
}
@Override
protected int _getUnsignedMedium(int index) {
return ((internal.get(index) & 0xFF) << 16) | ((internal.get(index + 1) & 0xFF) << 8) |
(internal.get(index + 2) & 0xFF);
}
@Override
protected int _getInt(int index) {
return internal.getInt(index);
}
@Override
protected long _getLong(int index) {
return internal.getLong(index);
}
@Override
protected void _setByte(int index, int value) {
internal.put(index, (byte)value);
}
@Override
protected void _setShort(int index, int value) {
internal.putShort(index, (short)value);
}
@Override
protected void _setMedium(int index, int value) {
internal.put(index, (byte)((value >> 16) & 0xFF));
internal.put(index + 1, (byte)((value >> 8) & 0xFF));
internal.put(index + 2, (byte)(value & 0xFF));
}
@Override
protected void _setInt(int index, int value) {
internal.putInt(index, value);
}
@Override
protected void _setLong(int index, long value) {
internal.putLong(index, value);
}
@Override
public int capacity() {
return internal.capacity();
}
@Override
public ByteBuf capacity(int newCapacity) {
if(newCapacity > internal.capacity()) {
ByteBuffer newCap = ByteBuffer.wrap(new byte[(int)(newCapacity * 1.5f)]);
NioBufferFunctions.put(newCap, 0, internal, 0, internal.capacity());
newCap.clear();
internal = newCap;
}
return this;
}
@Override
public ByteOrder order() {
return ByteOrder.BIG_ENDIAN;
}
@Override
public ByteBuf order(ByteOrder endianness) {
throw new UnsupportedOperationException("Not supported as it is not used by Eaglercraft");
}
@Override
public ByteBuf unwrap() {
return this;
}
@Override
public boolean isDirect() {
return false;
}
@Override
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
if(!(dst instanceof ByteBufEaglercraftImpl)) {
throw new IllegalArgumentException("The buffer passed is not an Eaglercraft byte buffer!");
}
NioBufferFunctions.put(((ByteBufEaglercraftImpl)dst).internal, dstIndex, internal, index, length);
return this;
}
@Override
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
NioBufferFunctions.get(internal, index, dst, dstIndex, length);
return this;
}
@Override
public ByteBuf getBytes(int index, ByteBuffer dst) {
NioBufferFunctions.put(dst, dst.position(), internal, index, dst.remaining());
dst.position(dst.limit());
return this;
}
@Override
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
byte[] buf = new byte[length];
NioBufferFunctions.get(internal, index, buf);
out.write(buf);
return this;
}
@Override
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
if(!(src instanceof ByteBufEaglercraftImpl)) {
throw new IllegalArgumentException("The buffer passed is not an Eaglercraft byte buffer!");
}
NioBufferFunctions.put(internal, index, ((ByteBufEaglercraftImpl)src).internal, srcIndex, length);
return this;
}
@Override
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
NioBufferFunctions.put(internal, index, src, srcIndex, length);
return this;
}
@Override
public ByteBuf setBytes(int index, ByteBuffer src) {
NioBufferFunctions.put(internal, index, src, src.position(), src.remaining());
src.position(src.limit());
return this;
}
@Override
public int setBytes(int index, InputStream in, int length) throws IOException {
byte[] buf = new byte[length];
int r = in.read(buf, 0, length);
if(r > 0) {
NioBufferFunctions.put(internal, index, buf, 0, r);
}
return r;
}
@Override
public ByteBuf copy(int index, int length) {
byte[] cpy = new byte[length];
NioBufferFunctions.get(internal, index, cpy);
return new ByteBufEaglercraftImpl(ByteBuffer.wrap(cpy), maxCapacity());
}
@Override
public int nioBufferCount() {
return 1;
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
//return internal.slice(index, length);
throw new UnsupportedOperationException("Not supported in JDK 8");
}
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
internal.position(index).limit(index + length);
return internal;
}
@Override
public ByteBuffer[] nioBuffers(int index, int length) {
//return new ByteBuffer[] { internal.slice(index, length) };
throw new UnsupportedOperationException("Not supported in JDK 8");
}
@Override
public boolean hasArray() {
return true;
}
@Override
public byte[] array() {
return internal.array();
}
@Override
public int arrayOffset() {
return 0;
}
@Override
public boolean hasMemoryAddress() {
return false;
}
@Override
public long memoryAddress() {
return 0;
}
@Override
public ByteBuf slice(int index, int length) {
//return new ByteBufEaglercraftImpl(internal.slice(index, length), maxCapacity());
throw new UnsupportedOperationException("Not supported in JDK 8");
}
@Override
public ByteBuf duplicate() {
return new ByteBufEaglercraftImpl(internal.duplicate(), maxCapacity());
}
}

View File

@ -0,0 +1,303 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package net.lax1dude.eaglercraft.v1_8.netty;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
/**
* An {@link InputStream} which reads data from a {@link ByteBuf}.
* <p>
* A read operation against this stream will occur at the {@code readerIndex} of
* its underlying buffer and the {@code readerIndex} will increase during the
* read operation. Please note that it only reads up to the number of readable
* bytes determined at the moment of construction. Therefore, updating
* {@link ByteBuf#writerIndex()} will not affect the return value of
* {@link #available()}.
* <p>
* This stream implements {@link DataInput} for your convenience. The endianness
* of the stream is not always big endian but depends on the endianness of the
* underlying buffer.
*
* @see ByteBufOutputStream
*/
public class ByteBufInputStream extends InputStream implements DataInput {
private final ByteBuf buffer;
private final int startIndex;
private final int endIndex;
/**
* To preserve backwards compatibility (which didn't transfer ownership) we
* support a conditional flag which indicates if {@link #buffer} should be
* released when this {@link InputStream} is closed. However in future releases
* ownership should always be transferred and callers of this class should call
* {@link ReferenceCounted#retain()} if necessary.
*/
private boolean releaseOnClose;
/**
* Creates a new stream which reads data from the specified {@code buffer}
* starting at the current {@code readerIndex} and ending at the current
* {@code writerIndex}.
*
* @param buffer The buffer which provides the content for this
* {@link InputStream}.
*/
public ByteBufInputStream(ByteBuf buffer) {
this(buffer, buffer.readableBytes());
}
/**
* Creates a new stream which reads data from the specified {@code buffer}
* starting at the current {@code readerIndex} and ending at
* {@code readerIndex + length}.
*
* @param buffer The buffer which provides the content for this
* {@link InputStream}.
* @param length The length of the buffer to use for this {@link InputStream}.
* @throws IndexOutOfBoundsException if {@code readerIndex + length} is greater
* than {@code writerIndex}
*/
public ByteBufInputStream(ByteBuf buffer, int length) {
this(buffer, length, false);
}
/**
* Creates a new stream which reads data from the specified {@code buffer}
* starting at the current {@code readerIndex} and ending at the current
* {@code writerIndex}.
*
* @param buffer The buffer which provides the content for this
* {@link InputStream}.
* @param releaseOnClose {@code true} means that when {@link #close()} is called
* then {@link ByteBuf#release()} will be called on
* {@code buffer}.
*/
public ByteBufInputStream(ByteBuf buffer, boolean releaseOnClose) {
this(buffer, buffer.readableBytes(), releaseOnClose);
}
/**
* Creates a new stream which reads data from the specified {@code buffer}
* starting at the current {@code readerIndex} and ending at
* {@code readerIndex + length}.
*
* @param buffer The buffer which provides the content for this
* {@link InputStream}.
* @param length The length of the buffer to use for this
* {@link InputStream}.
* @param releaseOnClose {@code true} means that when {@link #close()} is called
* then {@link ByteBuf#release()} will be called on
* {@code buffer}.
* @throws IndexOutOfBoundsException if {@code readerIndex + length} is greater
* than {@code writerIndex}
*/
public ByteBufInputStream(ByteBuf buffer, int length, boolean releaseOnClose) {
if (buffer == null) {
throw new NullPointerException("buffer");
}
if (length < 0) {
throw new IllegalArgumentException("length: " + length);
}
if (length > buffer.readableBytes()) {
throw new IndexOutOfBoundsException(
"Too many bytes to be read - Needs " + length + ", maximum is " + buffer.readableBytes());
}
this.releaseOnClose = releaseOnClose;
this.buffer = buffer;
startIndex = buffer.readerIndex();
endIndex = startIndex + length;
buffer.markReaderIndex();
}
/**
* Returns the number of read bytes by this stream so far.
*/
public int readBytes() {
return buffer.readerIndex() - startIndex;
}
@Override
public int available() throws IOException {
return endIndex - buffer.readerIndex();
}
@Override
public void mark(int readlimit) {
buffer.markReaderIndex();
}
@Override
public boolean markSupported() {
return true;
}
@Override
public int read() throws IOException {
if (!buffer.isReadable()) {
return -1;
}
return buffer.readByte() & 0xff;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int available = available();
if (available == 0) {
return -1;
}
len = Math.min(available, len);
buffer.readBytes(b, off, len);
return len;
}
@Override
public void reset() throws IOException {
buffer.resetReaderIndex();
}
@Override
public long skip(long n) throws IOException {
if (n > Integer.MAX_VALUE) {
return skipBytes(Integer.MAX_VALUE);
} else {
return skipBytes((int) n);
}
}
@Override
public boolean readBoolean() throws IOException {
checkAvailable(1);
return read() != 0;
}
@Override
public byte readByte() throws IOException {
if (!buffer.isReadable()) {
throw new EOFException();
}
return buffer.readByte();
}
@Override
public char readChar() throws IOException {
return (char) readShort();
}
@Override
public double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
@Override
public float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
@Override
public void readFully(byte[] b) throws IOException {
readFully(b, 0, b.length);
}
@Override
public void readFully(byte[] b, int off, int len) throws IOException {
checkAvailable(len);
buffer.readBytes(b, off, len);
}
@Override
public int readInt() throws IOException {
checkAvailable(4);
return buffer.readInt();
}
private final StringBuilder lineBuf = new StringBuilder();
@Override
public String readLine() throws IOException {
lineBuf.setLength(0);
loop: while (true) {
if (!buffer.isReadable()) {
return lineBuf.length() > 0 ? lineBuf.toString() : null;
}
int c = buffer.readUnsignedByte();
switch (c) {
case '\n':
break loop;
case '\r':
if (buffer.isReadable() && (char) buffer.getUnsignedByte(buffer.readerIndex()) == '\n') {
buffer.skipBytes(1);
}
break loop;
default:
lineBuf.append((char) c);
}
}
return lineBuf.toString();
}
@Override
public long readLong() throws IOException {
checkAvailable(8);
return buffer.readLong();
}
@Override
public short readShort() throws IOException {
checkAvailable(2);
return buffer.readShort();
}
@Override
public String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
@Override
public int readUnsignedByte() throws IOException {
return readByte() & 0xff;
}
@Override
public int readUnsignedShort() throws IOException {
return readShort() & 0xffff;
}
@Override
public int skipBytes(int n) throws IOException {
int nBytes = Math.min(available(), n);
buffer.skipBytes(nBytes);
return nBytes;
}
private void checkAvailable(int fieldSize) throws IOException {
if (fieldSize < 0) {
throw new IndexOutOfBoundsException("fieldSize cannot be a negative number");
}
if (fieldSize > available()) {
throw new EOFException("fieldSize is too long! Length is " + fieldSize + ", but maximum is " + available());
}
}
}

View File

@ -0,0 +1,144 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package net.lax1dude.eaglercraft.v1_8.netty;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
/**
* An {@link OutputStream} which writes data to a {@link ByteBuf}.
* <p>
* A write operation against this stream will occur at the {@code writerIndex}
* of its underlying buffer and the {@code writerIndex} will increase during the
* write operation.
* <p>
* This stream implements {@link DataOutput} for your convenience. The
* endianness of the stream is not always big endian but depends on the
* endianness of the underlying buffer.
*
* @see ByteBufInputStream
*/
public class ByteBufOutputStream extends OutputStream implements DataOutput {
private final ByteBuf buffer;
private final int startIndex;
private final DataOutputStream utf8out = new DataOutputStream(this);
/**
* Creates a new stream which writes data to the specified {@code buffer}.
*/
public ByteBufOutputStream(ByteBuf buffer) {
if (buffer == null) {
throw new NullPointerException("buffer");
}
this.buffer = buffer;
startIndex = buffer.writerIndex();
}
/**
* Returns the number of written bytes by this stream so far.
*/
public int writtenBytes() {
return buffer.writerIndex() - startIndex;
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (len == 0) {
return;
}
buffer.writeBytes(b, off, len);
}
@Override
public void write(byte[] b) throws IOException {
buffer.writeBytes(b);
}
@Override
public void write(int b) throws IOException {
buffer.writeByte(b);
}
@Override
public void writeBoolean(boolean v) throws IOException {
buffer.writeBoolean(v);
}
@Override
public void writeByte(int v) throws IOException {
buffer.writeByte(v);
}
@Override
public void writeBytes(String s) throws IOException {
buffer.writeBytes(s.getBytes(StandardCharsets.UTF_8));
}
@Override
public void writeChar(int v) throws IOException {
buffer.writeChar(v);
}
@Override
public void writeChars(String s) throws IOException {
int len = s.length();
for (int i = 0; i < len; i++) {
buffer.writeChar(s.charAt(i));
}
}
@Override
public void writeDouble(double v) throws IOException {
buffer.writeDouble(v);
}
@Override
public void writeFloat(float v) throws IOException {
buffer.writeFloat(v);
}
@Override
public void writeInt(int v) throws IOException {
buffer.writeInt(v);
}
@Override
public void writeLong(long v) throws IOException {
buffer.writeLong(v);
}
@Override
public void writeShort(int v) throws IOException {
buffer.writeShort((short) v);
}
@Override
public void writeUTF(String s) throws IOException {
utf8out.writeUTF(s);
}
/**
* Returns the buffer where this stream is writing data.
*/
public ByteBuf buffer() {
return buffer;
}
}

View File

@ -0,0 +1,598 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package net.lax1dude.eaglercraft.v1_8.netty;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.StandardCharsets;
import static net.lax1dude.eaglercraft.v1_8.netty.ObjectUtil.checkNotNull;
/**
* A collection of utility methods that is related with handling
* {@link ByteBuf}, such as the generation of hex dump and swapping an integer's
* byte order.
*/
public final class ByteBufUtil {
private static final byte WRITE_UTF_UNKNOWN = (byte) '?';
private static final int MAX_BYTES_PER_CHAR_UTF8 = 3;
/**
* Decode a 2-digit hex byte from within a string.
*/
public static byte decodeHexByte(CharSequence s, int pos) {
return (byte)EagUtils.decodeHexByte(s, pos);
}
/**
* Calculates the hash code of the specified buffer. This method is useful when
* implementing a new buffer type.
*/
public static int hashCode(ByteBuf buffer) {
final int aLen = buffer.readableBytes();
final int intCount = aLen >>> 2;
final int byteCount = aLen & 3;
int hashCode = 1;
int arrayIndex = buffer.readerIndex();
if (buffer.order() == ByteOrder.BIG_ENDIAN) {
for (int i = intCount; i > 0; i--) {
hashCode = 31 * hashCode + buffer.getInt(arrayIndex);
arrayIndex += 4;
}
} else {
for (int i = intCount; i > 0; i--) {
hashCode = 31 * hashCode + swapInt(buffer.getInt(arrayIndex));
arrayIndex += 4;
}
}
for (int i = byteCount; i > 0; i--) {
hashCode = 31 * hashCode + buffer.getByte(arrayIndex++);
}
if (hashCode == 0) {
hashCode = 1;
}
return hashCode;
}
/**
* Returns {@code true} if and only if the two specified buffers are identical
* to each other as described in {@code ChannelBuffer#equals(Object)}. This
* method is useful when implementing a new buffer type.
*/
public static boolean equals(ByteBuf bufferA, ByteBuf bufferB) {
final int aLen = bufferA.readableBytes();
if (aLen != bufferB.readableBytes()) {
return false;
}
final int longCount = aLen >>> 3;
final int byteCount = aLen & 7;
int aIndex = bufferA.readerIndex();
int bIndex = bufferB.readerIndex();
if (bufferA.order() == bufferB.order()) {
for (int i = longCount; i > 0; i--) {
if (bufferA.getLong(aIndex) != bufferB.getLong(bIndex)) {
return false;
}
aIndex += 8;
bIndex += 8;
}
} else {
for (int i = longCount; i > 0; i--) {
if (bufferA.getLong(aIndex) != swapLong(bufferB.getLong(bIndex))) {
return false;
}
aIndex += 8;
bIndex += 8;
}
}
for (int i = byteCount; i > 0; i--) {
if (bufferA.getByte(aIndex) != bufferB.getByte(bIndex)) {
return false;
}
aIndex++;
bIndex++;
}
return true;
}
/**
* Compares the two specified buffers as described in
* {@link ByteBuf#compareTo(ByteBuf)}. This method is useful when implementing a
* new buffer type.
*/
public static int compare(ByteBuf bufferA, ByteBuf bufferB) {
final int aLen = bufferA.readableBytes();
final int bLen = bufferB.readableBytes();
final int minLength = Math.min(aLen, bLen);
final int uintCount = minLength >>> 2;
final int byteCount = minLength & 3;
int aIndex = bufferA.readerIndex();
int bIndex = bufferB.readerIndex();
if (uintCount > 0) {
boolean bufferAIsBigEndian = bufferA.order() == ByteOrder.BIG_ENDIAN;
final long res;
int uintCountIncrement = uintCount << 2;
if (bufferA.order() == bufferB.order()) {
res = bufferAIsBigEndian ? compareUintBigEndian(bufferA, bufferB, aIndex, bIndex, uintCountIncrement)
: compareUintLittleEndian(bufferA, bufferB, aIndex, bIndex, uintCountIncrement);
} else {
res = bufferAIsBigEndian ? compareUintBigEndianA(bufferA, bufferB, aIndex, bIndex, uintCountIncrement)
: compareUintBigEndianB(bufferA, bufferB, aIndex, bIndex, uintCountIncrement);
}
if (res != 0) {
// Ensure we not overflow when cast
return (int) Math.min(Integer.MAX_VALUE, Math.max(Integer.MIN_VALUE, res));
}
aIndex += uintCountIncrement;
bIndex += uintCountIncrement;
}
for (int aEnd = aIndex + byteCount; aIndex < aEnd; ++aIndex, ++bIndex) {
int comp = bufferA.getUnsignedByte(aIndex) - bufferB.getUnsignedByte(bIndex);
if (comp != 0) {
return comp;
}
}
return aLen - bLen;
}
private static long compareUintBigEndian(ByteBuf bufferA, ByteBuf bufferB, int aIndex, int bIndex,
int uintCountIncrement) {
for (int aEnd = aIndex + uintCountIncrement; aIndex < aEnd; aIndex += 4, bIndex += 4) {
long comp = bufferA.getUnsignedInt(aIndex) - bufferB.getUnsignedInt(bIndex);
if (comp != 0) {
return comp;
}
}
return 0;
}
private static long compareUintLittleEndian(ByteBuf bufferA, ByteBuf bufferB, int aIndex, int bIndex,
int uintCountIncrement) {
for (int aEnd = aIndex + uintCountIncrement; aIndex < aEnd; aIndex += 4, bIndex += 4) {
long comp = (swapInt(bufferA.getInt(aIndex)) & 0xFFFFFFFFL)
- (swapInt(bufferB.getInt(bIndex)) & 0xFFFFFFFFL);
if (comp != 0) {
return comp;
}
}
return 0;
}
private static long compareUintBigEndianA(ByteBuf bufferA, ByteBuf bufferB, int aIndex, int bIndex,
int uintCountIncrement) {
for (int aEnd = aIndex + uintCountIncrement; aIndex < aEnd; aIndex += 4, bIndex += 4) {
long comp = bufferA.getUnsignedInt(aIndex) - (swapInt(bufferB.getInt(bIndex)) & 0xFFFFFFFFL);
if (comp != 0) {
return comp;
}
}
return 0;
}
private static long compareUintBigEndianB(ByteBuf bufferA, ByteBuf bufferB, int aIndex, int bIndex,
int uintCountIncrement) {
for (int aEnd = aIndex + uintCountIncrement; aIndex < aEnd; aIndex += 4, bIndex += 4) {
long comp = (swapInt(bufferA.getInt(aIndex)) & 0xFFFFFFFFL) - bufferB.getUnsignedInt(bIndex);
if (comp != 0) {
return comp;
}
}
return 0;
}
/**
* The default implementation of {@link ByteBuf#indexOf(int, int, byte)}. This
* method is useful when implementing a new buffer type.
*/
public static int indexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value) {
if (fromIndex <= toIndex) {
return firstIndexOf(buffer, fromIndex, toIndex, value);
} else {
return lastIndexOf(buffer, fromIndex, toIndex, value);
}
}
/**
* Toggles the endianness of the specified 16-bit short integer.
*/
public static short swapShort(short value) {
return Short.reverseBytes(value);
}
/**
* Toggles the endianness of the specified 24-bit medium integer.
*/
public static int swapMedium(int value) {
int swapped = value << 16 & 0xff0000 | value & 0xff00 | value >>> 16 & 0xff;
if ((swapped & 0x800000) != 0) {
swapped |= 0xff000000;
}
return swapped;
}
/**
* Toggles the endianness of the specified 32-bit integer.
*/
public static int swapInt(int value) {
return Integer.reverseBytes(value);
}
/**
* Toggles the endianness of the specified 64-bit long integer.
*/
public static long swapLong(long value) {
return Long.reverseBytes(value);
}
/**
* Read the given amount of bytes into a new {@link ByteBuf} that is allocated
* from the {@link ByteBufAllocator}.
*/
public static ByteBuf readBytes(ByteBuf buffer, int length) {
ByteBuf dst = Unpooled.buffer(length);
buffer.readBytes(dst);
return dst;
}
private static int firstIndexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value) {
fromIndex = Math.max(fromIndex, 0);
if (fromIndex >= toIndex || buffer.capacity() == 0) {
return -1;
}
for(int i = fromIndex; i < toIndex; ++i) {
if(buffer.getByte(i) == value) {
return i;
}
}
return -1;
}
private static int lastIndexOf(ByteBuf buffer, int fromIndex, int toIndex, byte value) {
fromIndex = Math.min(fromIndex, buffer.capacity());
if (fromIndex < 0 || buffer.capacity() == 0) {
return -1;
}
for(int i = fromIndex; i > toIndex; --i) {
if(buffer.getByte(i) == value) {
return i;
}
}
return -1;
}
/**
* Encode a {@link CharSequence} in
* <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> and write it to a
* {@link ByteBuf} allocated with {@code alloc}.
*
* @param alloc The allocator used to allocate a new {@link ByteBuf}.
* @param seq The characters to write into a buffer.
* @return The {@link ByteBuf} which contains the
* <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoded
* result.
*/
public static ByteBuf writeUtf8(CharSequence seq) {
// UTF-8 uses max. 3 bytes per char, so calculate the worst case.
ByteBuf buf = Unpooled.buffer(seq.length() * MAX_BYTES_PER_CHAR_UTF8);
writeUtf8(buf, seq);
return buf;
}
/**
* Encode a {@link CharSequence} in
* <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8</a> and write it to a
* {@link ByteBuf}.
*
* This method returns the actual number of bytes written.
*/
public static int writeUtf8(ByteBuf buf, CharSequence seq) {
final int len = seq.length();
buf.ensureWritable(len * MAX_BYTES_PER_CHAR_UTF8);
byte[] bytes = seq.toString().getBytes(StandardCharsets.UTF_8);
buf.writeBytes(bytes);
return bytes.length;
}
// Fast-Path implementation
private static int writeUtf8(AbstractByteBuf buffer, CharSequence seq, int len) {
int oldWriterIndex = buffer.writerIndex;
int writerIndex = oldWriterIndex;
// We can use the _set methods as these not need to do any index checks and
// reference checks.
// This is possible as we called ensureWritable(...) before.
for (int i = 0; i < len; i++) {
char c = seq.charAt(i);
if (c < 0x80) {
buffer._setByte(writerIndex++, (byte) c);
} else if (c < 0x800) {
buffer._setByte(writerIndex++, (byte) (0xc0 | (c >> 6)));
buffer._setByte(writerIndex++, (byte) (0x80 | (c & 0x3f)));
} else if (c >= '\uD800' && c <= '\uDFFF') { // isSurrogate(c)
if (!Character.isHighSurrogate(c)) {
buffer._setByte(writerIndex++, WRITE_UTF_UNKNOWN);
continue;
}
final char c2;
try {
// Surrogate Pair consumes 2 characters. Optimistically try to get the next
// character to avoid
// duplicate bounds checking with charAt. If an IndexOutOfBoundsException is
// thrown we will
// re-throw a more informative exception describing the problem.
c2 = seq.charAt(++i);
} catch (IndexOutOfBoundsException e) {
buffer._setByte(writerIndex++, WRITE_UTF_UNKNOWN);
break;
}
if (!Character.isLowSurrogate(c2)) {
buffer._setByte(writerIndex++, WRITE_UTF_UNKNOWN);
buffer._setByte(writerIndex++, Character.isHighSurrogate(c2) ? WRITE_UTF_UNKNOWN : c2);
continue;
}
int codePoint = Character.toCodePoint(c, c2);
// See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G2630.
buffer._setByte(writerIndex++, (byte) (0xf0 | (codePoint >> 18)));
buffer._setByte(writerIndex++, (byte) (0x80 | ((codePoint >> 12) & 0x3f)));
buffer._setByte(writerIndex++, (byte) (0x80 | ((codePoint >> 6) & 0x3f)));
buffer._setByte(writerIndex++, (byte) (0x80 | (codePoint & 0x3f)));
} else {
buffer._setByte(writerIndex++, (byte) (0xe0 | (c >> 12)));
buffer._setByte(writerIndex++, (byte) (0x80 | ((c >> 6) & 0x3f)));
buffer._setByte(writerIndex++, (byte) (0x80 | (c & 0x3f)));
}
}
// update the writerIndex without any extra checks for performance reasons
buffer.writerIndex = writerIndex;
return writerIndex - oldWriterIndex;
}
/**
* Encode the given {@link CharBuffer} using the given {@link Charset} into a
* new {@link ByteBuf} which is allocated via the {@link ByteBufAllocator}.
*/
public static ByteBuf encodeString(CharBuffer src, Charset charset) {
return encodeString0(false, src, charset);
}
static ByteBuf encodeString0(boolean enforceHeap, CharBuffer src, Charset charset) {
final CharsetEncoder encoder = charset.newEncoder();
int length = (int) ((double) src.remaining() * encoder.maxBytesPerChar());
final ByteBuf dst = Unpooled.buffer(length);
try {
final ByteBuffer dstBuf = dst.internalNioBuffer(dst.readerIndex(), length);
final int pos = dstBuf.position();
CoderResult cr = encoder.encode(src, dstBuf, true);
if (!cr.isUnderflow()) {
cr.throwException();
}
cr = encoder.flush(dstBuf);
if (!cr.isUnderflow()) {
cr.throwException();
}
dst.writerIndex(dst.writerIndex() + dstBuf.position() - pos);
return dst;
} catch (CharacterCodingException x) {
throw new IllegalStateException(x);
}
}
static String decodeString(ByteBuf src, int readerIndex, int len, Charset charset) {
if (len == 0) {
return "";
}
final CharsetDecoder decoder = charset.newDecoder();
final int maxLength = (int) ((double) len * decoder.maxCharsPerByte());
CharBuffer dst = CharBuffer.wrap(new char[maxLength]);
decodeString(decoder, src.nioBuffer(readerIndex, len), dst);
return dst.flip().toString();
}
private static void decodeString(CharsetDecoder decoder, ByteBuffer src, CharBuffer dst) {
try {
CoderResult cr = decoder.decode(src, dst, true);
if (!cr.isUnderflow()) {
cr.throwException();
}
cr = decoder.flush(dst);
if (!cr.isUnderflow()) {
cr.throwException();
}
} catch (CharacterCodingException x) {
throw new IllegalStateException(x);
}
}
/**
* Returns {@code true} if the given {@link ByteBuf} is valid text using the
* given {@link Charset}, otherwise return {@code false}.
*
* @param buf The given {@link ByteBuf}.
* @param charset The specified {@link Charset}.
*/
public static boolean isText(ByteBuf buf, Charset charset) {
return isText(buf, buf.readerIndex(), buf.readableBytes(), charset);
}
/**
* Returns {@code true} if the specified {@link ByteBuf} starting at
* {@code index} with {@code length} is valid text using the given
* {@link Charset}, otherwise return {@code false}.
*
* @param buf The given {@link ByteBuf}.
* @param index The start index of the specified buffer.
* @param length The length of the specified buffer.
* @param charset The specified {@link Charset}.
*
* @throws IndexOutOfBoundsException if {@code index} + {@code length} is
* greater than {@code buf.readableBytes}
*/
public static boolean isText(ByteBuf buf, int index, int length, Charset charset) {
checkNotNull(buf, "buf");
checkNotNull(charset, "charset");
final int maxIndex = buf.readerIndex() + buf.readableBytes();
if (index < 0 || length < 0 || index > maxIndex - length) {
throw new IndexOutOfBoundsException("index: " + index + " length: " + length);
}
return isUtf8(buf, index, length);
}
/**
* Returns {@code true} if the specified {@link ByteBuf} starting at
* {@code index} with {@code length} is valid UTF8 text, otherwise return
* {@code false}.
*
* @param buf The given {@link ByteBuf}.
* @param index The start index of the specified buffer.
* @param length The length of the specified buffer.
*
* @see <a href=http://www.ietf.org/rfc/rfc3629.txt>UTF-8 Definition</a>
*
* <pre>
* 1. Bytes format of UTF-8
*
* The table below summarizes the format of these different octet types.
* The letter x indicates bits available for encoding bits of the character number.
*
* Char. number range | UTF-8 octet sequence
* (hexadecimal) | (binary)
* --------------------+---------------------------------------------
* 0000 0000-0000 007F | 0xxxxxxx
* 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
* 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* </pre>
*
* <pre>
* 2. Syntax of UTF-8 Byte Sequences
*
* UTF8-octets = *( UTF8-char )
* UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
* UTF8-1 = %x00-7F
* UTF8-2 = %xC2-DF UTF8-tail
* UTF8-3 = %xE0 %xA0-BF UTF8-tail /
* %xE1-EC 2( UTF8-tail ) /
* %xED %x80-9F UTF8-tail /
* %xEE-EF 2( UTF8-tail )
* UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) /
* %xF1-F3 3( UTF8-tail ) /
* %xF4 %x80-8F 2( UTF8-tail )
* UTF8-tail = %x80-BF
* </pre>
*/
private static boolean isUtf8(ByteBuf buf, int index, int length) {
final int endIndex = index + length;
while (index < endIndex) {
byte b1 = buf.getByte(index++);
byte b2, b3, b4;
if ((b1 & 0x80) == 0) {
// 1 byte
continue;
}
if ((b1 & 0xE0) == 0xC0) {
// 2 bytes
//
// Bit/Byte pattern
// 110xxxxx 10xxxxxx
// C2..DF 80..BF
if (index >= endIndex) { // no enough bytes
return false;
}
b2 = buf.getByte(index++);
if ((b2 & 0xC0) != 0x80) { // 2nd byte not starts with 10
return false;
}
if ((b1 & 0xFF) < 0xC2) { // out of lower bound
return false;
}
} else if ((b1 & 0xF0) == 0xE0) {
// 3 bytes
//
// Bit/Byte pattern
// 1110xxxx 10xxxxxx 10xxxxxx
// E0 A0..BF 80..BF
// E1..EC 80..BF 80..BF
// ED 80..9F 80..BF
// E1..EF 80..BF 80..BF
if (index > endIndex - 2) { // no enough bytes
return false;
}
b2 = buf.getByte(index++);
b3 = buf.getByte(index++);
if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) { // 2nd or 3rd bytes not start with 10
return false;
}
if ((b1 & 0x0F) == 0x00 && (b2 & 0xFF) < 0xA0) { // out of lower bound
return false;
}
if ((b1 & 0x0F) == 0x0D && (b2 & 0xFF) > 0x9F) { // out of upper bound
return false;
}
} else if ((b1 & 0xF8) == 0xF0) {
// 4 bytes
//
// Bit/Byte pattern
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// F0 90..BF 80..BF 80..BF
// F1..F3 80..BF 80..BF 80..BF
// F4 80..8F 80..BF 80..BF
if (index > endIndex - 3) { // no enough bytes
return false;
}
b2 = buf.getByte(index++);
b3 = buf.getByte(index++);
b4 = buf.getByte(index++);
if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80 || (b4 & 0xC0) != 0x80) {
// 2nd, 3rd or 4th bytes not start with 10
return false;
}
if ((b1 & 0xFF) > 0xF4 // b1 invalid
|| (b1 & 0xFF) == 0xF0 && (b2 & 0xFF) < 0x90 // b2 out of lower bound
|| (b1 & 0xFF) == 0xF4 && (b2 & 0xFF) > 0x8F) { // b2 out of upper bound
return false;
}
} else {
return false;
}
}
return true;
}
private ByteBufUtil() {
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2015 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License, version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package net.lax1dude.eaglercraft.v1_8.netty;
/**
* Math utility methods.
*/
public final class MathUtil {
private MathUtil() {
}
/**
* Fast method of finding the next power of 2 greater than or equal to the
* supplied value.
*
* <p>
* If the value is {@code <= 0} then 1 will be returned. This method is not
* suitable for {@link Integer#MIN_VALUE} or numbers greater than 2^30.
*
* @param value from which to search for next power of 2
* @return The next power of 2 or the value itself if it is a power of 2
*/
public static int findNextPositivePowerOfTwo(final int value) {
assert value > Integer.MIN_VALUE && value < 0x40000000;
return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));
}
/**
* Fast method of finding the next power of 2 greater than or equal to the
* supplied value.
* <p>
* This method will do runtime bounds checking and call
* {@link #findNextPositivePowerOfTwo(int)} if within a valid range.
*
* @param value from which to search for next power of 2
* @return The next power of 2 or the value itself if it is a power of 2.
* <p>
* Special cases for return values are as follows:
* <ul>
* <li>{@code <= 0} -> 1</li>
* <li>{@code >= 2^30} -> 2^30</li>
* </ul>
*/
public static int safeFindNextPositivePowerOfTwo(final int value) {
return value <= 0 ? 1 : value >= 0x40000000 ? 0x40000000 : findNextPositivePowerOfTwo(value);
}
/**
* Determine if the requested {@code index} and {@code length} will fit within
* {@code capacity}.
*
* @param index The starting index.
* @param length The length which will be utilized (starting from
* {@code index}).
* @param capacity The capacity that {@code index + length} is allowed to be
* within.
* @return {@code false} if the requested {@code index} and {@code length} will
* fit within {@code capacity}. {@code true} if this would result in an
* index out of bounds exception.
*/
public static boolean isOutOfBounds(int index, int length, int capacity) {
return (index | length | capacity | (index + length) | (capacity - (index + length))) < 0;
}
/**
* Compares two {@code int} values.
*
* @param x the first {@code int} to compare
* @param y the second {@code int} to compare
* @return the value {@code 0} if {@code x == y}; {@code -1} if {@code x < y};
* and {@code 1} if {@code x > y}
*/
public static int compare(final int x, final int y) {
// do not subtract for comparison, it could overflow
return x < y ? -1 : (x > y ? 1 : 0);
}
/**
* Compare two {@code long} values.
*
* @param x the first {@code long} to compare.
* @param y the second {@code long} to compare.
* @return
* <ul>
* <li>0 if {@code x == y}</li>
* <li>{@code > 0} if {@code x > y}</li>
* <li>{@code < 0} if {@code x < y}</li>
* </ul>
*/
public static int compare(long x, long y) {
return (x < y) ? -1 : (x > y) ? 1 : 0;
}
}

View File

@ -0,0 +1,44 @@
package net.lax1dude.eaglercraft.v1_8.netty;
import java.nio.ByteBuffer;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.IntBuffer;
public class NioBufferFunctions {
public static final void get(ByteBuffer src, int index, byte[] dst, int dstOffset, int length) {
for(int i = 0; i < length; ++i) {
dst[i + dstOffset] = src.get(i + index);
}
}
public static final void put(ByteBuffer dst, int dstIndex, ByteBuffer src, int srcOffset, int length) {
for(int i = 0; i < length; ++i) {
dst.put(i + dstIndex, src.get(i + srcOffset));
}
}
public static final void put(ByteBuffer dst, int dstIndex, byte[] src, int srcOffset, int length) {
for(int i = 0; i < length; ++i) {
dst.put(i + dstIndex, src[i + srcOffset]);
}
}
public static final void get(ByteBuffer src, int index, byte[] dst) {
get(src, index, dst, 0, dst.length);
}
public static void put(ByteBuffer newBuffer, ByteBuffer flip) {
int len = flip.remaining();
for(int i = 0; i < len; ++i) {
newBuffer.put(flip.get());
}
}
public static void put(IntBuffer intBuffer, int index, int[] data) {
int p = intBuffer.position();
intBuffer.position(index);
intBuffer.put(data);
intBuffer.position(p);
}
}

View File

@ -0,0 +1,329 @@
/*
* Copyright 2014 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License, version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package net.lax1dude.eaglercraft.v1_8.netty;
import java.util.Collection;
import java.util.Map;
/**
* A grab-bag of useful utility methods.
*/
public final class ObjectUtil {
private static final float FLOAT_ZERO = 0.0F;
private static final double DOUBLE_ZERO = 0.0D;
private static final long LONG_ZERO = 0L;
private static final int INT_ZERO = 0;
private ObjectUtil() {
}
/**
* Checks that the given argument is not null. If it is, throws
* {@link NullPointerException}. Otherwise, returns the argument.
*/
public static <T> T checkNotNull(T arg, String text) {
if (arg == null) {
throw new NullPointerException(text);
}
return arg;
}
/**
* Check that the given varargs is not null and does not contain elements null
* elements.
*
* If it is, throws {@link NullPointerException}. Otherwise, returns the
* argument.
*/
public static <T> T[] deepCheckNotNull(String text, T... varargs) {
if (varargs == null) {
throw new NullPointerException(text);
}
for (T element : varargs) {
if (element == null) {
throw new NullPointerException(text);
}
}
return varargs;
}
/**
* Checks that the given argument is not null. If it is, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static <T> T checkNotNullWithIAE(final T arg, final String paramName) throws IllegalArgumentException {
if (arg == null) {
throw new IllegalArgumentException("Param '" + paramName + "' must not be null");
}
return arg;
}
/**
* Checks that the given argument is not null. If it is, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*
* @param <T> type of the given argument value.
* @param name of the parameter, belongs to the exception message.
* @param index of the array, belongs to the exception message.
* @param value to check.
* @return the given argument value.
* @throws IllegalArgumentException if value is null.
*/
public static <T> T checkNotNullArrayParam(T value, int index, String name) throws IllegalArgumentException {
if (value == null) {
throw new IllegalArgumentException(
"Array index " + index + " of parameter '" + name + "' must not be null");
}
return value;
}
/**
* Checks that the given argument is strictly positive. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static int checkPositive(int i, String name) {
if (i <= INT_ZERO) {
throw new IllegalArgumentException(name + " : " + i + " (expected: > 0)");
}
return i;
}
/**
* Checks that the given argument is strictly positive. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static long checkPositive(long l, String name) {
if (l <= LONG_ZERO) {
throw new IllegalArgumentException(name + " : " + l + " (expected: > 0)");
}
return l;
}
/**
* Checks that the given argument is strictly positive. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static double checkPositive(final double d, final String name) {
if (d <= DOUBLE_ZERO) {
throw new IllegalArgumentException(name + " : " + d + " (expected: > 0)");
}
return d;
}
/**
* Checks that the given argument is strictly positive. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static float checkPositive(final float f, final String name) {
if (f <= FLOAT_ZERO) {
throw new IllegalArgumentException(name + " : " + f + " (expected: > 0)");
}
return f;
}
/**
* Checks that the given argument is positive or zero. If it is not , throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static int checkPositiveOrZero(int i, String name) {
if (i < INT_ZERO) {
throw new IllegalArgumentException(name + " : " + i + " (expected: >= 0)");
}
return i;
}
/**
* Checks that the given argument is positive or zero. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static long checkPositiveOrZero(long l, String name) {
if (l < LONG_ZERO) {
throw new IllegalArgumentException(name + " : " + l + " (expected: >= 0)");
}
return l;
}
/**
* Checks that the given argument is positive or zero. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static double checkPositiveOrZero(final double d, final String name) {
if (d < DOUBLE_ZERO) {
throw new IllegalArgumentException(name + " : " + d + " (expected: >= 0)");
}
return d;
}
/**
* Checks that the given argument is positive or zero. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static float checkPositiveOrZero(final float f, final String name) {
if (f < FLOAT_ZERO) {
throw new IllegalArgumentException(name + " : " + f + " (expected: >= 0)");
}
return f;
}
/**
* Checks that the given argument is in range. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static int checkInRange(int i, int start, int end, String name) {
if (i < start || i > end) {
throw new IllegalArgumentException(name + ": " + i + " (expected: " + start + "-" + end + ")");
}
return i;
}
/**
* Checks that the given argument is in range. If it is not, throws
* {@link IllegalArgumentException}. Otherwise, returns the argument.
*/
public static long checkInRange(long l, long start, long end, String name) {
if (l < start || l > end) {
throw new IllegalArgumentException(name + ": " + l + " (expected: " + start + "-" + end + ")");
}
return l;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static <T> T[] checkNonEmpty(T[] array, String name) {
// No String concatenation for check
if (checkNotNull(array, name).length == 0) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return array;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static byte[] checkNonEmpty(byte[] array, String name) {
// No String concatenation for check
if (checkNotNull(array, name).length == 0) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return array;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static char[] checkNonEmpty(char[] array, String name) {
// No String concatenation for check
if (checkNotNull(array, name).length == 0) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return array;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static <T extends Collection<?>> T checkNonEmpty(T collection, String name) {
// No String concatenation for check
if (checkNotNull(collection, name).isEmpty()) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return collection;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static String checkNonEmpty(final String value, final String name) {
if (checkNotNull(value, name).isEmpty()) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return value;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static <K, V, T extends Map<K, V>> T checkNonEmpty(T value, String name) {
if (checkNotNull(value, name).isEmpty()) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return value;
}
/**
* Checks that the given argument is neither null nor empty. If it is, throws
* {@link NullPointerException} or {@link IllegalArgumentException}. Otherwise,
* returns the argument.
*/
public static CharSequence checkNonEmpty(final CharSequence value, final String name) {
if (checkNotNull(value, name).length() == 0) {
throw new IllegalArgumentException("Param '" + name + "' must not be empty");
}
return value;
}
/**
* Trims the given argument and checks whether it is neither null nor empty. If
* it is, throws {@link NullPointerException} or
* {@link IllegalArgumentException}. Otherwise, returns the trimmed argument.
*
* @param value to trim and check.
* @param name of the parameter.
* @return the trimmed (not the original) value.
* @throws NullPointerException if value is null.
* @throws IllegalArgumentException if the trimmed value is empty.
*/
public static String checkNonEmptyAfterTrim(final String value, final String name) {
String trimmed = checkNotNull(value, name).trim();
return checkNonEmpty(trimmed, name);
}
/**
* Resolves a possibly null Integer to a primitive int, using a default value.
*
* @param wrapper the wrapper
* @param defaultValue the default value
* @return the primitive value
*/
public static int intValue(Integer wrapper, int defaultValue) {
return wrapper != null ? wrapper : defaultValue;
}
/**
* Resolves a possibly null Long to a primitive long, using a default value.
*
* @param wrapper the wrapper
* @param defaultValue the default value
* @return the primitive value
*/
public static long longValue(Long wrapper, long defaultValue) {
return wrapper != null ? wrapper : defaultValue;
}
}

View File

@ -0,0 +1,778 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package net.lax1dude.eaglercraft.v1_8.netty;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Wrapper which swap the {@link ByteOrder} of a {@link ByteBuf}.
*/
public class SwappedByteBuf extends ByteBuf {
private final ByteBuf buf;
private final ByteOrder order;
public SwappedByteBuf(ByteBuf buf) {
if (buf == null) {
throw new NullPointerException("buf");
}
this.buf = buf;
if (buf.order() == ByteOrder.BIG_ENDIAN) {
order = ByteOrder.LITTLE_ENDIAN;
} else {
order = ByteOrder.BIG_ENDIAN;
}
}
@Override
public ByteOrder order() {
return order;
}
@Override
public ByteBuf order(ByteOrder endianness) {
if (endianness == null) {
throw new NullPointerException("endianness");
}
if (endianness == order) {
return this;
}
return buf;
}
@Override
public ByteBuf unwrap() {
return buf;
}
@Override
public int capacity() {
return buf.capacity();
}
@Override
public ByteBuf capacity(int newCapacity) {
buf.capacity(newCapacity);
return this;
}
@Override
public int maxCapacity() {
return buf.maxCapacity();
}
@Override
public boolean isDirect() {
return buf.isDirect();
}
@Override
public int readerIndex() {
return buf.readerIndex();
}
@Override
public ByteBuf readerIndex(int readerIndex) {
buf.readerIndex(readerIndex);
return this;
}
@Override
public int writerIndex() {
return buf.writerIndex();
}
@Override
public ByteBuf writerIndex(int writerIndex) {
buf.writerIndex(writerIndex);
return this;
}
@Override
public ByteBuf setIndex(int readerIndex, int writerIndex) {
buf.setIndex(readerIndex, writerIndex);
return this;
}
@Override
public int readableBytes() {
return buf.readableBytes();
}
@Override
public int writableBytes() {
return buf.writableBytes();
}
@Override
public int maxWritableBytes() {
return buf.maxWritableBytes();
}
@Override
public boolean isReadable() {
return buf.isReadable();
}
@Override
public boolean isReadable(int size) {
return buf.isReadable(size);
}
@Override
public boolean isWritable() {
return buf.isWritable();
}
@Override
public boolean isWritable(int size) {
return buf.isWritable(size);
}
@Override
public ByteBuf clear() {
buf.clear();
return this;
}
@Override
public ByteBuf markReaderIndex() {
buf.markReaderIndex();
return this;
}
@Override
public ByteBuf resetReaderIndex() {
buf.resetReaderIndex();
return this;
}
@Override
public ByteBuf markWriterIndex() {
buf.markWriterIndex();
return this;
}
@Override
public ByteBuf resetWriterIndex() {
buf.resetWriterIndex();
return this;
}
@Override
public ByteBuf discardReadBytes() {
buf.discardReadBytes();
return this;
}
@Override
public ByteBuf discardSomeReadBytes() {
buf.discardSomeReadBytes();
return this;
}
@Override
public ByteBuf ensureWritable(int writableBytes) {
buf.ensureWritable(writableBytes);
return this;
}
@Override
public int ensureWritable(int minWritableBytes, boolean force) {
return buf.ensureWritable(minWritableBytes, force);
}
@Override
public boolean getBoolean(int index) {
return buf.getBoolean(index);
}
@Override
public byte getByte(int index) {
return buf.getByte(index);
}
@Override
public short getUnsignedByte(int index) {
return buf.getUnsignedByte(index);
}
@Override
public short getShort(int index) {
return ByteBufUtil.swapShort(buf.getShort(index));
}
@Override
public int getUnsignedShort(int index) {
return getShort(index) & 0xFFFF;
}
@Override
public int getMedium(int index) {
return ByteBufUtil.swapMedium(buf.getMedium(index));
}
@Override
public int getUnsignedMedium(int index) {
return getMedium(index) & 0xFFFFFF;
}
@Override
public int getInt(int index) {
return ByteBufUtil.swapInt(buf.getInt(index));
}
@Override
public long getUnsignedInt(int index) {
return getInt(index) & 0xFFFFFFFFL;
}
@Override
public long getLong(int index) {
return ByteBufUtil.swapLong(buf.getLong(index));
}
@Override
public char getChar(int index) {
return (char) getShort(index);
}
@Override
public float getFloat(int index) {
return Float.intBitsToFloat(getInt(index));
}
@Override
public double getDouble(int index) {
return Double.longBitsToDouble(getLong(index));
}
@Override
public ByteBuf getBytes(int index, ByteBuf dst) {
buf.getBytes(index, dst);
return this;
}
@Override
public ByteBuf getBytes(int index, ByteBuf dst, int length) {
buf.getBytes(index, dst, length);
return this;
}
@Override
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
buf.getBytes(index, dst, dstIndex, length);
return this;
}
@Override
public ByteBuf getBytes(int index, byte[] dst) {
buf.getBytes(index, dst);
return this;
}
@Override
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
buf.getBytes(index, dst, dstIndex, length);
return this;
}
@Override
public ByteBuf getBytes(int index, ByteBuffer dst) {
buf.getBytes(index, dst);
return this;
}
@Override
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
buf.getBytes(index, out, length);
return this;
}
@Override
public ByteBuf setBoolean(int index, boolean value) {
buf.setBoolean(index, value);
return this;
}
@Override
public ByteBuf setByte(int index, int value) {
buf.setByte(index, value);
return this;
}
@Override
public ByteBuf setShort(int index, int value) {
buf.setShort(index, ByteBufUtil.swapShort((short) value));
return this;
}
@Override
public ByteBuf setMedium(int index, int value) {
buf.setMedium(index, ByteBufUtil.swapMedium(value));
return this;
}
@Override
public ByteBuf setInt(int index, int value) {
buf.setInt(index, ByteBufUtil.swapInt(value));
return this;
}
@Override
public ByteBuf setLong(int index, long value) {
buf.setLong(index, ByteBufUtil.swapLong(value));
return this;
}
@Override
public ByteBuf setChar(int index, int value) {
setShort(index, value);
return this;
}
@Override
public ByteBuf setFloat(int index, float value) {
setInt(index, Float.floatToRawIntBits(value));
return this;
}
@Override
public ByteBuf setDouble(int index, double value) {
setLong(index, Double.doubleToRawLongBits(value));
return this;
}
@Override
public ByteBuf setBytes(int index, ByteBuf src) {
buf.setBytes(index, src);
return this;
}
@Override
public ByteBuf setBytes(int index, ByteBuf src, int length) {
buf.setBytes(index, src, length);
return this;
}
@Override
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
buf.setBytes(index, src, srcIndex, length);
return this;
}
@Override
public ByteBuf setBytes(int index, byte[] src) {
buf.setBytes(index, src);
return this;
}
@Override
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
buf.setBytes(index, src, srcIndex, length);
return this;
}
@Override
public ByteBuf setBytes(int index, ByteBuffer src) {
buf.setBytes(index, src);
return this;
}
@Override
public int setBytes(int index, InputStream in, int length) throws IOException {
return buf.setBytes(index, in, length);
}
@Override
public ByteBuf setZero(int index, int length) {
buf.setZero(index, length);
return this;
}
@Override
public boolean readBoolean() {
return buf.readBoolean();
}
@Override
public byte readByte() {
return buf.readByte();
}
@Override
public short readUnsignedByte() {
return buf.readUnsignedByte();
}
@Override
public short readShort() {
return ByteBufUtil.swapShort(buf.readShort());
}
@Override
public int readUnsignedShort() {
return readShort() & 0xFFFF;
}
@Override
public int readMedium() {
return ByteBufUtil.swapMedium(buf.readMedium());
}
@Override
public int readUnsignedMedium() {
return readMedium() & 0xFFFFFF;
}
@Override
public int readInt() {
return ByteBufUtil.swapInt(buf.readInt());
}
@Override
public long readUnsignedInt() {
return readInt() & 0xFFFFFFFFL;
}
@Override
public long readLong() {
return ByteBufUtil.swapLong(buf.readLong());
}
@Override
public char readChar() {
return (char) readShort();
}
@Override
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
@Override
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
@Override
public ByteBuf readBytes(int length) {
return buf.readBytes(length).order(order());
}
@Override
public ByteBuf readSlice(int length) {
return buf.readSlice(length).order(order);
}
@Override
public ByteBuf readBytes(ByteBuf dst) {
buf.readBytes(dst);
return this;
}
@Override
public ByteBuf readBytes(ByteBuf dst, int length) {
buf.readBytes(dst, length);
return this;
}
@Override
public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) {
buf.readBytes(dst, dstIndex, length);
return this;
}
@Override
public ByteBuf readBytes(byte[] dst) {
buf.readBytes(dst);
return this;
}
@Override
public ByteBuf readBytes(byte[] dst, int dstIndex, int length) {
buf.readBytes(dst, dstIndex, length);
return this;
}
@Override
public ByteBuf readBytes(ByteBuffer dst) {
buf.readBytes(dst);
return this;
}
@Override
public ByteBuf readBytes(OutputStream out, int length) throws IOException {
buf.readBytes(out, length);
return this;
}
@Override
public ByteBuf skipBytes(int length) {
buf.skipBytes(length);
return this;
}
@Override
public ByteBuf writeBoolean(boolean value) {
buf.writeBoolean(value);
return this;
}
@Override
public ByteBuf writeByte(int value) {
buf.writeByte(value);
return this;
}
@Override
public ByteBuf writeShort(int value) {
buf.writeShort(ByteBufUtil.swapShort((short) value));
return this;
}
@Override
public ByteBuf writeMedium(int value) {
buf.writeMedium(ByteBufUtil.swapMedium(value));
return this;
}
@Override
public ByteBuf writeInt(int value) {
buf.writeInt(ByteBufUtil.swapInt(value));
return this;
}
@Override
public ByteBuf writeLong(long value) {
buf.writeLong(ByteBufUtil.swapLong(value));
return this;
}
@Override
public ByteBuf writeChar(int value) {
writeShort(value);
return this;
}
@Override
public ByteBuf writeFloat(float value) {
writeInt(Float.floatToRawIntBits(value));
return this;
}
@Override
public ByteBuf writeDouble(double value) {
writeLong(Double.doubleToRawLongBits(value));
return this;
}
@Override
public ByteBuf writeBytes(ByteBuf src) {
buf.writeBytes(src);
return this;
}
@Override
public ByteBuf writeBytes(ByteBuf src, int length) {
buf.writeBytes(src, length);
return this;
}
@Override
public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) {
buf.writeBytes(src, srcIndex, length);
return this;
}
@Override
public ByteBuf writeBytes(byte[] src) {
buf.writeBytes(src);
return this;
}
@Override
public ByteBuf writeBytes(byte[] src, int srcIndex, int length) {
buf.writeBytes(src, srcIndex, length);
return this;
}
@Override
public ByteBuf writeBytes(ByteBuffer src) {
buf.writeBytes(src);
return this;
}
@Override
public int writeBytes(InputStream in, int length) throws IOException {
return buf.writeBytes(in, length);
}
@Override
public ByteBuf writeZero(int length) {
buf.writeZero(length);
return this;
}
@Override
public int indexOf(int fromIndex, int toIndex, byte value) {
return buf.indexOf(fromIndex, toIndex, value);
}
@Override
public int bytesBefore(byte value) {
return buf.bytesBefore(value);
}
@Override
public int bytesBefore(int length, byte value) {
return buf.bytesBefore(length, value);
}
@Override
public int bytesBefore(int index, int length, byte value) {
return buf.bytesBefore(index, length, value);
}
@Override
public ByteBuf copy() {
return buf.copy().order(order);
}
@Override
public ByteBuf copy(int index, int length) {
return buf.copy(index, length).order(order);
}
@Override
public ByteBuf slice() {
return buf.slice().order(order);
}
@Override
public ByteBuf slice(int index, int length) {
return buf.slice(index, length).order(order);
}
@Override
public ByteBuf duplicate() {
return buf.duplicate().order(order);
}
@Override
public int nioBufferCount() {
return buf.nioBufferCount();
}
@Override
public ByteBuffer nioBuffer() {
return buf.nioBuffer().order(order);
}
@Override
public ByteBuffer nioBuffer(int index, int length) {
return buf.nioBuffer(index, length).order(order);
}
@Override
public ByteBuffer internalNioBuffer(int index, int length) {
return nioBuffer(index, length);
}
@Override
public ByteBuffer[] nioBuffers() {
ByteBuffer[] nioBuffers = buf.nioBuffers();
for (int i = 0; i < nioBuffers.length; i++) {
nioBuffers[i] = nioBuffers[i].order(order);
}
return nioBuffers;
}
@Override
public ByteBuffer[] nioBuffers(int index, int length) {
ByteBuffer[] nioBuffers = buf.nioBuffers(index, length);
for (int i = 0; i < nioBuffers.length; i++) {
nioBuffers[i] = nioBuffers[i].order(order);
}
return nioBuffers;
}
@Override
public boolean hasArray() {
return buf.hasArray();
}
@Override
public byte[] array() {
return buf.array();
}
@Override
public int arrayOffset() {
return buf.arrayOffset();
}
@Override
public boolean hasMemoryAddress() {
return buf.hasMemoryAddress();
}
@Override
public long memoryAddress() {
return buf.memoryAddress();
}
@Override
public String toString(Charset charset) {
return buf.toString(charset);
}
@Override
public String toString(int index, int length, Charset charset) {
return buf.toString(index, length, charset);
}
@Override
public int hashCode() {
return buf.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof ByteBuf) {
return ByteBufUtil.equals(this, (ByteBuf) obj);
}
return false;
}
@Override
public int compareTo(ByteBuf buffer) {
return ByteBufUtil.compare(this, buffer);
}
@Override
public String toString() {
return "Swapped(" + buf.toString() + ')';
}
}

Some files were not shown because too many files have changed in this diff Show More