mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #0 - First Release
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
}
|
857
sources/main/java/net/lax1dude/eaglercraft/v1_8/Base64.java
Normal file
857
sources/main/java/net/lax1dude/eaglercraft/v1_8/Base64.java
Normal 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
|
||||
* > 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 <= 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 <= 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 <= 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 <= 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.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
692
sources/main/java/net/lax1dude/eaglercraft/v1_8/BaseNCodec.java
Normal file
692
sources/main/java/net/lax1dude/eaglercraft/v1_8/BaseNCodec.java
Normal 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 > 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} > 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 > 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 > 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 > 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 > 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
59
sources/main/java/net/lax1dude/eaglercraft/v1_8/Display.java
Normal file
59
sources/main/java/net/lax1dude/eaglercraft/v1_8/Display.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
274
sources/main/java/net/lax1dude/eaglercraft/v1_8/EagRuntime.java
Normal file
274
sources/main/java/net/lax1dude/eaglercraft/v1_8/EagRuntime.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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))));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
2751
sources/main/java/net/lax1dude/eaglercraft/v1_8/HFormatter.java
Normal file
2751
sources/main/java/net/lax1dude/eaglercraft/v1_8/HFormatter.java
Normal file
File diff suppressed because it is too large
Load Diff
22
sources/main/java/net/lax1dude/eaglercraft/v1_8/HString.java
Normal file
22
sources/main/java/net/lax1dude/eaglercraft/v1_8/HString.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
72
sources/main/java/net/lax1dude/eaglercraft/v1_8/IOUtils.java
Normal file
72
sources/main/java/net/lax1dude/eaglercraft/v1_8/IOUtils.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
92
sources/main/java/net/lax1dude/eaglercraft/v1_8/Mouse.java
Normal file
92
sources/main/java/net/lax1dude/eaglercraft/v1_8/Mouse.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
20
sources/main/java/net/lax1dude/eaglercraft/v1_8/cache/EaglerCacheProvider.java
vendored
Normal file
20
sources/main/java/net/lax1dude/eaglercraft/v1_8/cache/EaglerCacheProvider.java
vendored
Normal 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);
|
||||
|
||||
}
|
38
sources/main/java/net/lax1dude/eaglercraft/v1_8/cache/EaglerLoadingCache.java
vendored
Normal file
38
sources/main/java/net/lax1dude/eaglercraft/v1_8/cache/EaglerLoadingCache.java
vendored
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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 };
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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() {
|
||||
}
|
||||
|
||||
}
|
@ -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>();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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 {
|
||||
|
||||
}
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 + '}';
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
1767
sources/main/java/net/lax1dude/eaglercraft/v1_8/netty/ByteBuf.java
Normal file
1767
sources/main/java/net/lax1dude/eaglercraft/v1_8/netty/ByteBuf.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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() {
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
Reference in New Issue
Block a user