add files

This commit is contained in:
eaglercraft 2024-02-14 20:52:11 -08:00
commit 784a776dbb
7211 changed files with 811080 additions and 0 deletions

View file

@ -0,0 +1,69 @@
package net.lax1dude.eaglercraft.v1_8;
import java.util.List;
import net.minecraft.client.settings.KeyBinding;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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;
}
public static <T> void eaglerShuffle(List<T> list, EaglercraftRandom rnd) {
T k;
for (int i = list.size() - 1, j; i > 0; --i) {
j = rnd.nextInt(i + 1);
k = list.get(j);
list.set(j, list.get(i));
list.set(i, k);
}
}
}

View file

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

View file

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

View file

@ -0,0 +1,36 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class DecoderException extends RuntimeException {
public DecoderException() {
super();
}
public DecoderException(String message, Throwable cause) {
super(message, cause);
}
public DecoderException(String message) {
super(message);
}
public DecoderException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,82 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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();
}
public static boolean isFullscreen() {
return PlatformInput.isFullscreen();
}
public static void toggleFullscreen() {
PlatformInput.toggleFullscreen();
}
}

View file

@ -0,0 +1,312 @@
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.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
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;
import net.lax1dude.eaglercraft.v1_8.update.UpdateService;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EagRuntime {
private static final Logger logger = LogManager.getLogger("EagRuntime");
private static final Logger exceptionLogger = LogManager.getLogger("Exception");
private static boolean ssl = false;
private static boolean offlineDownloadURL = false;
public static String getVersion() {
return "EagRuntimeX 1.0";
}
public static void create() {
logger.info("Version: {}", getVersion());
PlatformRuntime.create();
ssl = PlatformRuntime.requireSSL();
offlineDownloadURL = PlatformRuntime.isOfflineDownloadURL();
UpdateService.initialize();
EaglerXBungeeVersion.initialize();
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 boolean isOfflineDownloadURL() {
return offlineDownloadURL;
}
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 clearFileChooserResult() {
PlatformApplication.clearFileChooserResult();
}
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);
}
public static void downloadFileWithName(String fileName, byte[] fileContents) {
PlatformApplication.downloadFileWithName(fileName, fileContents);
}
public static String currentThreadName() {
return PlatformRuntime.currentThreadName();
}
public static void showDebugConsole() {
PlatformApplication.showDebugConsole();
}
public static Calendar getLocaleCalendar() {
return Calendar.getInstance(); //TODO: fix teavm calendar's time zone offset
}
public static <T extends DateFormat> T fixDateFormat(T input) {
input.setCalendar(getLocaleCalendar());
return input;
}
}

View file

@ -0,0 +1,88 @@
package net.lax1dude.eaglercraft.v1_8;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EagUtils {
private static final String hex = "0123456789ABCDEF";
public static final Pattern splitPattern = Pattern.compile("(\\r\\n|\\n|\\r)");
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 String[] linesArray(String input) {
return splitPattern.split(input);
}
public static List<String> linesList(String input) {
return Arrays.asList(splitPattern.split(input));
}
public static int decodeHex(CharSequence num) {
int ret = 0;
for(int i = 0, l = num.length(); i < l; ++i) {
ret = ret << 4;
int v = hex.indexOf(num.charAt(i));
if(v >= 0) {
ret |= v;
}
}
return ret;
}
public static int decodeHexByte(CharSequence str, int off) {
return str.length() < off + 2 ? decodeHex(str.subSequence(off, 2)) : 0;
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
}catch(InterruptedException ex) {
}
}
public static String toASCIIEagler(String str) {
char[] ascii = new char[str.length()];
for(int i = 0; i < ascii.length; ++i) {
int c = (int)str.charAt(i);
if(c < 32 || c > 126) {
ascii[i] = '_';
}else {
ascii[i] = (char)c;
}
}
return new String(ascii);
}
public static void validateASCIIEagler(String str) {
for(int i = 0, l = str.length(); i < l; ++i) {
int c = (int)str.charAt(i);
if(c < 32 || c > 126) {
throw new IllegalArgumentException("invalid ascii");
}
}
}
}

View file

@ -0,0 +1,88 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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) {
if(is == null) {
return null;
}
try {
return inputStreamToBytes(is);
}catch(IOException ex) {
return null;
}
}
public static byte[] inputStreamToBytes(InputStream is) throws IOException {
if(is instanceof EaglerInputStream) {
return ((EaglerInputStream) is).getAsArray();
}else if(is instanceof ByteArrayInputStream) {
byte[] ret = new byte[is.available()];
is.read(ret);
return ret;
}else {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buf = new byte[1024];
int i;
while((i = is.read(buf)) != -1) {
os.write(buf, 0, i);
}
return os.toByteArray();
}
}
public byte[] getAsArray() {
if(pos == 0 && count == buf.length) {
return buf;
}else {
byte[] ret = new byte[count];
System.arraycopy(buf, pos, ret, 0, count);
return ret;
}
}
public boolean canUseArrayDirectly() {
return pos == 0 && count == buf.length;
}
public int getPosition() {
return pos;
}
public int getMark() {
return mark;
}
public int getCount() {
return count;
}
}

View file

@ -0,0 +1,97 @@
package net.lax1dude.eaglercraft.v1_8;
import org.json.JSONObject;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerXBungeeVersion {
public static final String pluginFileEPK = "plugin_download.zip";
private static String pluginName = null;
private static String pluginVersion = null;
private static long pluginVersionLong = 0l;
private static String pluginButton = null;
private static String pluginFilename = null;
public static void initialize() {
String pluginVersionJson = EagRuntime.getResourceString("plugin_version.json");
if(pluginVersionJson == null) {
throw new RuntimeException("File \"plugin_version.json\" is missing in the epk!");
}
JSONObject json = new JSONObject(pluginVersionJson);
pluginName = json.getString("pluginName");
pluginVersion = json.getString("pluginVersion");
pluginVersionLong = getVersionAsLong(pluginVersion);
pluginButton = json.getString("pluginButton");
pluginFilename = json.getString("pluginFilename");
}
public static String getPluginName() {
return pluginName;
}
public static String getPluginVersion() {
return pluginVersion;
}
public static long getPluginVersionLong() {
return pluginVersionLong;
}
public static String getPluginButton() {
return pluginButton;
}
public static String getPluginFilename() {
return pluginFilename;
}
public static long getVersionAsLong(String vers) {
try {
String[] verz = vers.split("\\.");
long ret = 0;
long div = 1000000000000l;
for(int i = 0; i < verz.length; ++i) {
ret += div * Long.parseLong(verz[i]);
div /= 10000l;
}
return ret;
}catch(Throwable t) {
return -1l;
}
}
public static byte[] getPluginDownload() {
byte[] ret = EagRuntime.getResourceBytes(pluginFileEPK);
if(ret == null) {
throw new RuntimeException("File \"" + pluginFileEPK + "\" is missing in the epk!");
}
return ret;
}
public static void startPluginDownload() {
EagRuntime.downloadFileWithName(pluginFilename, getPluginDownload());
}
public static boolean isUpdateToPluginAvailable(String brand, String vers) {
if(pluginVersionLong == -1l || !pluginName.equals(brand)) {
return false;
}
long verz = getVersionAsLong(vers);
return verz != -1l && verz < pluginVersionLong;
}
}

View file

@ -0,0 +1,42 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerZLIB {
public static OutputStream newDeflaterOutputStream(OutputStream os) throws IOException {
return PlatformRuntime.newDeflaterOutputStream(os);
}
public static OutputStream newGZIPOutputStream(OutputStream os) throws IOException {
return PlatformRuntime.newGZIPOutputStream(os);
}
public static InputStream newInflaterInputStream(InputStream is) throws IOException {
return PlatformRuntime.newInflaterInputStream(is);
}
public static InputStream newGZIPInputStream(InputStream is) throws IOException {
return PlatformRuntime.newGZIPInputStream(is);
}
}

View file

@ -0,0 +1,107 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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(PlatformRuntime.randomSeed());
}
public EaglercraftRandom(long seed) {
setSeed(seed);
}
public void setSeed(long yeed) {
seed = yeed;
}
protected int next(int bits) {
seed = (seed * multiplier + addend) & mask;
return (int) (seed >>> (48 - bits));
}
public void nextBytes(byte[] bytes) {
for (int i = 0, len = bytes.length; i < len;)
for (int rnd = nextInt(), n = Math.min(len - i, Integer.SIZE / Byte.SIZE); n-- > 0; rnd >>= Byte.SIZE)
bytes[i++] = (byte) rnd;
}
public int nextInt() {
return next(32);
}
public int nextInt(int bound) {
int r = next(31);
int m = bound - 1;
if ((bound & m) == 0) // i.e., bound is a power of 2
r = (int) ((bound * (long) r) >> 31);
else {
for (int u = r; u - (r = u % bound) + m < 0; u = next(31))
;
}
return r;
}
public long nextLong() {
return ((long) (next(32)) << 32) + next(32);
}
public boolean nextBoolean() {
return next(1) != 0;
}
public float nextFloat() {
return next(24) / ((float) (1 << 24));
}
public double nextDouble() {
return (((long) (next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
private double nextNextGaussian;
private boolean haveNextNextGaussian = false;
public double nextGaussian() {
// See Knuth, ACP, Section 3.4.1 Algorithm C.
if (haveNextNextGaussian) {
haveNextNextGaussian = false;
return nextNextGaussian;
} else {
double v1, v2, s;
do {
v1 = 2 * nextDouble() - 1; // between -1 and 1
v2 = 2 * nextDouble() - 1; // between -1 and 1
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}

View file

@ -0,0 +1,372 @@
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.EnumPlatformType;
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.Minecraft;
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-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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() {
PlatformAudio.flushAudioCache();
}
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();
}
}
}
private final PlatformAudio.IAudioCacheLoader browserResourcePackLoader = filename -> {
try {
return EaglerInputStream.inputStreamToBytesQuiet(Minecraft.getMinecraft().getResourceManager()
.getResource(new ResourceLocation(filename)).getInputStream());
}catch(Throwable t) {
return null;
}
};
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;
if(EagRuntime.getPlatformType() != EnumPlatformType.DESKTOP) {
trk = PlatformAudio.loadAudioDataNew(lc.toString(), !etr.isStreamingSound(), browserResourcePackLoader);
}else {
trk = PlatformAudio.loadAudioData(
"/assets/" + lc.getResourceDomain() + "/" + lc.getResourcePath(), !etr.isStreamingSound());
}
if(trk == null) {
logger.warn("Unable to play unknown soundEvent(3): {}", sound.getSoundLocation().toString());
}else {
ActiveSoundEvent newSound = new ActiveSoundEvent(this, sound, accessor.getSoundCategory(), etr, null);
float pitch = MathHelper.clamp_float(newSound.activePitch * (float)etr.getPitch(), 0.5f, 2.0f);
float attenuatedGain = newSound.activeGain * categoryVolumes[SoundCategory.MASTER.getCategoryId()] *
(accessor.getSoundCategory() == SoundCategory.MASTER ? 1.0f :
categoryVolumes[accessor.getSoundCategory().getCategoryId()]) * (float)etr.getVolume();
AttenuationType tp = sound.getAttenuationType();
if(tp == AttenuationType.LINEAR) {
newSound.soundHandle = PlatformAudio.beginPlayback(trk, newSound.activeX, newSound.activeY,
newSound.activeZ, attenuatedGain, pitch);
}else {
newSound.soundHandle = PlatformAudio.beginPlaybackStatic(trk, attenuatedGain, pitch);
}
if(newSound.soundHandle == null) {
logger.error("Unable to play soundEvent(4): {}", sound.getSoundLocation().toString());
}else {
activeSounds.add(newSound);
}
}
}
}
}
}
public void playDelayedSound(ISound sound, int delay) {
queuedSounds.add(new WaitingSoundEvent(sound, delay));
}
public void setListener(EntityPlayer player, float partialTicks) {
if(!PlatformAudio.available()) {
return;
}
if(player != null) {
try {
float f = player.prevRotationPitch + (player.rotationPitch - player.prevRotationPitch) * partialTicks;
float f1 = player.prevRotationYaw + (player.rotationYaw - player.prevRotationYaw) * partialTicks;
double d0 = player.prevPosX + (player.posX - player.prevPosX) * (double) partialTicks;
double d1 = player.prevPosY + (player.posY - player.prevPosY) * (double) partialTicks + (double) player.getEyeHeight();
double d2 = player.prevPosZ + (player.posZ - player.prevPosZ) * (double) partialTicks;
PlatformAudio.setListener((float)d0, (float)d1, (float)d2, f, f1);
}catch(Throwable t) {
// eaglercraft 1.5.2 had Infinity/NaN crashes for this function which
// couldn't be resolved via if statement checks in the above variables
}
}
}
}

View file

@ -0,0 +1,244 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.crypto.MD5Digest;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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);
}
public static EaglercraftUUID randomUUID() {
byte[] randomBytes = new byte[16];
(new EaglercraftRandom()).nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new EaglercraftUUID(randomBytes);
}
@Override
public int compareTo(EaglercraftUUID val) {
return (this.msb < val.msb ? -1
: (this.msb > val.msb ? 1 : (this.lsb < val.lsb ? -1 : (this.lsb > val.lsb ? 1 : 0))));
}
}

View file

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8;
import java.math.BigInteger;
public class EaglercraftVersion {
//////////////////////////////////////////////////////////////////////
/// Customize these to fit your fork:
public static final String projectForkName = "EaglercraftX";
public static final String projectForkVersion = "u22";
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 = "u22";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace
// Updating configuration
public static final boolean enableUpdateService = true;
public static final String updateBundlePackageName = "net.lax1dude.eaglercraft.v1_8.client";
public static final int updateBundlePackageVersionInt = 22;
public static final String updateLatestLocalStorageKey = "latestUpdate_" + updateBundlePackageName;
// public key modulus for official 1.8 updates
public static final BigInteger updateSignatureModulus = new BigInteger("14419476194820052109078379102436982757438300194194974078260570958862225232043861026588258585967060437391326494976080031137298500457111529693806931143421725626747051503616606418909609840275122831550688481329699012469742002429706330734797679859799085213517354399295425740214330234086361416936984593337389989505613123225737002654977194421571825036717017788527234114501215218715499682638139386636103589791643964827904791195488978835113700772208317974307363542114867750505953323167521731238542123593257269990619007858952216110012513121779359926747737258698347806747854986471035713105133999027704095451858121831297923962641");
// Miscellaneous variables:
public static final String mainMenuStringA = "Minecraft 1.8.8";
public static final String mainMenuStringB = projectOriginName + " " +
projectOriginRevision + "-" + projectOriginVersion + " ultimate";
public static final String mainMenuStringC = "";
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 String mainMenuStringG = "Collector's Edition";
public static final String mainMenuStringH = "PBR Shaders";
public static final long demoWorldSeed = (long) "North Carolina".hashCode();
public static final boolean mainMenuEnableGithubButton = false;
public static final boolean forceDemoMode = false;
}

View file

@ -0,0 +1,36 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EncoderException extends RuntimeException {
public EncoderException() {
super();
}
public EncoderException(String message, Throwable cause) {
super(message, cause);
}
public EncoderException(String message) {
super(message);
}
public EncoderException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,28 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ExceptionUtils {
public static Throwable getRootCause(Throwable exception) {
Throwable t2;
while((t2 = exception.getCause()) != null) {
exception = t2;
}
return exception;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,24 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class HString {
public static String format(String format, Object... args) {
return new HFormatter().format(format, args).toString();
}
}

View file

@ -0,0 +1,74 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class IOUtils {
public static List<String> readLines(InputStream parInputStream, Charset charset) {
if(parInputStream instanceof EaglerInputStream) {
return Arrays.asList(
new String(((EaglerInputStream) parInputStream).getAsArray(), charset).split("(\\r\\n|\\n|\\r)"));
}else {
List<String> ret = new ArrayList();
try(InputStream is = parInputStream) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, charset));
String s;
while((s = rd.readLine()) != null) {
ret.add(s);
}
}catch(IOException ex) {
return null;
}
return ret;
}
}
public static void closeQuietly(Closeable reResourcePack) {
try {
reResourcePack.close();
}catch(Throwable t) {
}
}
public static String inputStreamToString(InputStream is, Charset c) throws IOException {
if(is instanceof EaglerInputStream) {
return new String(((EaglerInputStream)is).getAsArray(), c);
}else {
try {
StringBuilder b = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, c));
String s;
while((s = rd.readLine()) != null) {
b.append(s).append('\n');
}
return b.toString();
}finally {
is.close();
}
}
}
}

View file

@ -0,0 +1,90 @@
package net.lax1dude.eaglercraft.v1_8;
import java.util.function.Supplier;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class JDKBackports {
public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) {
throw new IndexOutOfBoundsException();
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
}
boolean negative = false;
int i = beginIndex;
long limit = -Long.MAX_VALUE;
if (i < endIndex) {
char firstChar = s.charAt(i);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Long.MIN_VALUE;
} else if (firstChar != '+') {
throw new NumberFormatException();
}
i++;
}
if (i >= endIndex) { // Cannot have lone "+", "-" or ""
throw new NumberFormatException();
}
long multmin = limit / radix;
long result = 0;
while (i < endIndex) {
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i), radix);
if (digit < 0 || result < multmin) {
throw new NumberFormatException();
}
result *= radix;
if (result < limit + digit) {
throw new NumberFormatException();
}
i++;
result -= digit;
}
return negative ? result : -result;
} else {
throw new NumberFormatException("");
}
}
public static <T> T javaUtilObject_requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier.get());
return obj;
}
public static <T> T javaUtilObject_requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
public static <T> T javaUtilObject_requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
}

View file

@ -0,0 +1,63 @@
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-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class Keyboard {
public static void enableRepeatEvents(boolean b) {
PlatformInput.keyboardEnableRepeatEvents(b);
}
public static boolean isCreated() {
return true;
}
public static boolean next() {
return PlatformInput.keyboardNext();
}
public static boolean getEventKeyState() {
return PlatformInput.keyboardGetEventKeyState();
}
public static char getEventCharacter() {
return PlatformInput.keyboardGetEventCharacter();
}
public static int getEventKey() {
return PlatformInput.keyboardGetEventKey();
}
public static void setFunctionKeyModifier(int key) {
PlatformInput.setFunctionKeyModifier(key);
}
public static boolean isKeyDown(int key) {
return PlatformInput.keyboardIsKeyDown(key);
}
public static String getKeyName(int key) {
return KeyboardConstants.getKeyName(key);
}
public static boolean isRepeatEvent() {
return PlatformInput.keyboardIsRepeatEvent();
}
}

View file

@ -0,0 +1,120 @@
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.internal.EnumCursorType;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
/**
* Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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();
}
private static int customCursorCounter = 0;
private static EnumCursorType currentCursorType = EnumCursorType.DEFAULT;
public static void showCursor(EnumCursorType cursor) {
if(EagRuntime.getConfiguration().useSpecialCursors()) {
customCursorCounter = 2;
if(currentCursorType != cursor) {
PlatformInput.showCursor(cursor);
currentCursorType = cursor;
}
}
}
public static void tickCursorShape() {
if(EagRuntime.getConfiguration().useSpecialCursors()) {
if(customCursorCounter > 0) {
if(--customCursorCounter == 0) {
if(currentCursorType != EnumCursorType.DEFAULT) {
PlatformInput.showCursor(EnumCursorType.DEFAULT);
currentCursorType = EnumCursorType.DEFAULT;
}
}
}
}
}
}

View file

@ -0,0 +1,26 @@
package net.lax1dude.eaglercraft.v1_8;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ThreadLocalRandom {
private static final EaglercraftRandom rand = new EaglercraftRandom();
public static EaglercraftRandom current() {
return rand;
}
}

View file

@ -0,0 +1,22 @@
package net.lax1dude.eaglercraft.v1_8.cache;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface EaglerCacheProvider<K, V> {
V create(K key);
}

View file

@ -0,0 +1,40 @@
package net.lax1dude.eaglercraft.v1_8.cache;
import java.util.HashMap;
import java.util.Map;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerLoadingCache<K, V> {
private final EaglerCacheProvider<K, V> provider;
private final Map<K, V> cacheMap;
public EaglerLoadingCache(EaglerCacheProvider<K, V> provider) {
this.provider = provider;
this.cacheMap = new HashMap();
}
public V get(K key) {
V etr = cacheMap.get(key);
if(etr == null) {
etr = provider.create(key);
cacheMap.put(key, etr);
}
return etr;
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,36 @@
package net.lax1dude.eaglercraft.v1_8.futures;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class CancellationException extends IllegalStateException {
public CancellationException() {
}
public CancellationException(String s) {
super(s);
}
public CancellationException(String message, Throwable cause) {
super(message, cause);
}
public CancellationException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.futures;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ExecutionException extends RuntimeException {
public ExecutionException() {
}
public ExecutionException(String message, Throwable cause) {
super(message, cause);
}
public ExecutionException(String message) {
super(message);
}
public ExecutionException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,49 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.Callable;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class Executors {
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
public static Callable<Object> callable(Runnable task) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<Object>(task, null);
}
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
}

View file

@ -0,0 +1,31 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.TimeUnit;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException;
}

View file

@ -0,0 +1,89 @@
package net.lax1dude.eaglercraft.v1_8.futures;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FutureTask<V> implements RunnableFuture<V> {
private boolean cancelled;
private boolean completed;
private V result;
private Callable<V> callable;
public FutureTask(Callable<V> callable) {
this.callable = callable;
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
if(!cancelled) {
cancelled = true;
if(!completed) {
done();
}
}
return true;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public boolean isDone() {
return cancelled || completed;
}
@Override
public V get() throws InterruptedException, ExecutionException {
if(!completed) {
if(!cancelled) {
try {
result = callable.call();
}catch(Throwable t) {
throw new ExecutionException(t);
}finally {
completed = true;
done();
}
}
}
return result;
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException {
return get();
}
@Override
public void run() {
try {
get();
} catch (ExecutionException t) {
throw t;
} catch (Throwable t) {
throw new ExecutionException(t);
}
}
protected void done() {
}
}

View file

@ -0,0 +1,131 @@
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-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class Futures {
private abstract static class ImmediateFuture<V> implements ListenableFuture<V> {
private static final Logger log = LogManager.getLogger(ImmediateFuture.class.getName());
@Override
public void addListener(Runnable listener, Executor executor) {
checkNotNull(listener, "Runnable was null.");
checkNotNull(executor, "Executor was null.");
try {
executor.execute(listener);
} catch (RuntimeException e) {
log.error("RuntimeException while executing runnable " + listener + " with executor " + executor, e);
}
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public abstract V get() throws ExecutionException;
@Override
public V get(long timeout, TimeUnit unit) throws ExecutionException {
checkNotNull(unit);
return get();
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return true;
}
}
private static class ImmediateSuccessfulFuture<V> extends ImmediateFuture<V> {
@Nullable
private final V value;
ImmediateSuccessfulFuture(@Nullable V value) {
this.value = value;
}
@Override
public V get() {
return value;
}
}
private static class ImmediateFailedFuture<V> extends ImmediateFuture<V> {
private final Throwable thrown;
ImmediateFailedFuture(Throwable thrown) {
this.thrown = thrown;
}
@Override
public V get() throws ExecutionException {
throw new ExecutionException(thrown);
}
}
private static class ImmediateCancelledFuture<V> extends ImmediateFuture<V> {
private final CancellationException thrown;
ImmediateCancelledFuture() {
this.thrown = new CancellationException("Immediate cancelled future.");
}
@Override
public boolean isCancelled() {
return true;
}
@Override
public V get() {
throw new CancellationException("Task was cancelled.", thrown);
}
}
public static <V> ListenableFuture<V> immediateFuture(@Nullable V value) {
return new ImmediateSuccessfulFuture<V>(value);
}
public static <V> ListenableFuture<V> immediateFailedFuture(Throwable throwable) {
checkNotNull(throwable);
return new ImmediateFailedFuture<V>(throwable);
}
public static <V> ListenableFuture<V> immediateCancelledFuture() {
return new ImmediateCancelledFuture<V>();
}
}

View file

@ -0,0 +1,29 @@
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-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface ListenableFuture<V> extends Future<V> {
static final Logger futureExceptionLogger = LogManager.getLogger("ListenableFuture");
void addListener(Runnable listener, Executor executor);
}

View file

@ -0,0 +1,59 @@
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-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class ListenableFutureTask<V> extends FutureTask<V> implements ListenableFuture<V> {
private final List<Runnable> listeners = new ArrayList();
public ListenableFutureTask(Callable<V> callable) {
super(callable);
}
@Override
public void addListener(final Runnable listener, final Executor executor) {
listeners.add(new Runnable() {
@Override
public void run() {
executor.execute(listener); // so dumb
}
});
}
protected void done() {
for(Runnable r : listeners) {
try {
r.run();
}catch(Throwable t) {
ListenableFuture.futureExceptionLogger.error("Exception caught running future listener!");
ListenableFuture.futureExceptionLogger.error(t);
}
}
listeners.clear();
}
public static <V> ListenableFutureTask<V> create(Callable<V> callableToSchedule) {
return new ListenableFutureTask(callableToSchedule);
}
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.futures;
/**
* Copyright (c) 2022-2023 lax1dude, ayunami2000. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumCursorType {
DEFAULT, HAND, TEXT;
}

View file

@ -0,0 +1,37 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumEaglerConnectionState {
CLOSED(true, false), CONNECTING(false, false), CONNECTED(false, true), FAILED(true, false);
private final boolean typeClosed;
private final boolean typeOpen;
private EnumEaglerConnectionState(boolean typeClosed, boolean typeOpen) {
this.typeClosed = typeClosed;
this.typeOpen = typeOpen;
}
public boolean isClosed() {
return typeClosed;
}
public boolean isOpen() {
return typeOpen;
}
}

View file

@ -0,0 +1,74 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumPlatformANGLE {
DEFAULT(225281 /* GLFW_ANGLE_PLATFORM_TYPE_NONE */, "default", "Default"),
D3D11(225285 /* GLFW_ANGLE_PLATFORM_TYPE_D3D11 */, "d3d11", "Direct3D11"),
OPENGL(225282 /* GLFW_ANGLE_PLATFORM_TYPE_OPENGL */, "opengl", "OpenGL"),
OPENGLES(225283 /* GLFW_ANGLE_PLATFORM_TYPE_OPENGLES */, "opengles", "OpenGL ES"),
METAL(225288 /* GLFW_ANGLE_PLATFORM_TYPE_METAL */, "metal", "Metal"),
VULKAN(225287 /* GLFW_ANGLE_PLATFORM_TYPE_VULKAN */, "vulkan", "Vulkan");
public final int eglEnum;
public final String id;
public final String name;
private EnumPlatformANGLE(int eglEnum, String id, String name) {
this.eglEnum = eglEnum;
this.id = id;
this.name = name;
}
public String toString() {
return id;
}
public static EnumPlatformANGLE fromId(String id) {
if(id.equals("d3d11") || id.equals("d3d") || id.equals("dx11")) {
return D3D11;
}else if(id.equals("opengl")) {
return OPENGL;
}else if(id.equals("opengles")) {
return OPENGLES;
}else if(id.equals("metal")) {
return METAL;
}else if(id.equals("vulkan")) {
return VULKAN;
}else {
return DEFAULT;
}
}
public static EnumPlatformANGLE fromGLRendererString(String str) {
str = str.toLowerCase();
if(str.contains("direct3d11") || str.contains("d3d11")) {
return D3D11;
}else if(str.contains("opengl es")) {
return OPENGLES;
}else if(str.contains("opengl")) {
return OPENGL;
}else if(str.contains("metal")) {
return METAL;
}else if(str.contains("vulkan")) {
return VULKAN;
}else {
return DEFAULT;
}
}
}

View file

@ -0,0 +1,62 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumPlatformAgent {
DESKTOP("LWJGL3"), CHROME("Chrome"), EDGE("Edge"), IE("IE"),
FIREFOX("Firefox"), SAFARI("Safari"), OPERA("Opera"), WEBKIT("WebKit"),
GECKO("Gecko"), UNKNOWN("Unknown");
private final String name;
private EnumPlatformAgent(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
public static EnumPlatformAgent getFromUA(String ua) {
ua = " " + ua.toLowerCase();
if(ua.contains(" edg/")) {
return EDGE;
}else if(ua.contains(" opr/")) {
return OPERA;
}else if(ua.contains(" chrome/")) {
return CHROME;
}else if(ua.contains(" firefox/")) {
return FIREFOX;
}else if(ua.contains(" safari/")) {
return SAFARI;
}else if(ua.contains(" trident/") || ua.contains(" msie")) {
return IE;
}else if(ua.contains(" webkit/")) {
return WEBKIT;
}else if(ua.contains(" gecko/")) {
return GECKO;
}else if(ua.contains(" desktop/")) {
return DESKTOP;
}else {
return UNKNOWN;
}
}
}

View file

@ -0,0 +1,74 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import net.minecraft.util.Util;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumPlatformOS {
WINDOWS("Windows", Util.EnumOS.WINDOWS), MACOS("MacOS", Util.EnumOS.OSX), LINUX("Linux", Util.EnumOS.LINUX),
CHROMEBOOK_LINUX("ChromeOS", Util.EnumOS.LINUX), OTHER("Unknown", Util.EnumOS.UNKNOWN);
private final String name;
private final Util.EnumOS minecraftEnum;
private EnumPlatformOS(String name, Util.EnumOS minecraftEnum) {
this.name = name;
this.minecraftEnum = minecraftEnum;
}
public String getName() {
return name;
}
public Util.EnumOS getMinecraftEnum() {
return minecraftEnum;
}
public String toString() {
return name;
}
public static EnumPlatformOS getFromJVM(String osNameProperty) {
osNameProperty = osNameProperty.toLowerCase();
if(osNameProperty.contains("chrome")) {
return CHROMEBOOK_LINUX;
}else if(osNameProperty.contains("linux")) {
return LINUX;
}else if(osNameProperty.contains("windows") || osNameProperty.contains("win32")) {
return WINDOWS;
}else if(osNameProperty.contains("macos") || osNameProperty.contains("osx")) {
return MACOS;
}else {
return OTHER;
}
}
public static EnumPlatformOS getFromUA(String ua) {
ua = " " + ua.toLowerCase();
if(ua.contains(" cros")) {
return CHROMEBOOK_LINUX;
}else if(ua.contains(" linux")) {
return LINUX;
}else if(ua.contains(" windows") || ua.contains(" win32") || ua.contains(" win64")) {
return WINDOWS;
}else if(ua.contains(" macos") || ua.contains(" osx")) {
return MACOS;
}else {
return OTHER;
}
}
}

View file

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumPlatformType {
DESKTOP("Desktop"), JAVASCRIPT("HTML5");
private final String name;
private EnumPlatformType(String name) {
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public enum EnumServerRateLimit {
OK, BLOCKED, LOCKED_OUT
}

View file

@ -0,0 +1,28 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class FileChooserResult {
public final String fileName;
public final byte[] fileData;
public FileChooserResult(String fileName, byte[] fileData) {
this.fileName = fileName;
this.fileData = fileData;
}
}

View file

@ -0,0 +1,70 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class GLObjectMap<T> {
private Object[] values;
private int size;
private int insertIndex;
public int allocatedObjects;
public GLObjectMap(int initialSize) {
this.values = new Object[initialSize];
this.size = initialSize;
this.insertIndex = 0;
this.allocatedObjects = 0;
}
public int register(T obj) {
int start = insertIndex;
do {
++insertIndex;
if(insertIndex >= size) {
insertIndex = 0;
}
if(insertIndex == start) {
resize();
return register(obj);
}
}while(values[insertIndex] != null);
values[insertIndex] = obj;
++allocatedObjects;
return insertIndex + 1;
}
public T free(int obj) {
--obj;
if(obj >= size || obj < 0) return null;
Object ret = values[obj];
values[obj] = null;
--allocatedObjects;
return (T) ret;
}
public T get(int obj) {
--obj;
if(obj >= size || obj < 0) return null;
return (T) values[obj];
}
private void resize() {
int oldSize = size;
size += size / 2;
Object[] oldValues = values;
values = new Object[size];
System.arraycopy(oldValues, 0, values, 0, oldSize);
}
}

View file

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IAudioHandle {
void pause(boolean setPaused);
void restart();
void move(float x, float y, float z);
void pitch(float f);
void gain(float f);
void end();
boolean shouldFree();
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IAudioResource {
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IBufferArrayGL extends IObjectGL {
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IBufferGL extends IObjectGL {
}

View file

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.sp.relay.RelayEntry;
import org.json.JSONObject;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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();
String getWorldsDB();
JSONObject dumpConfig();
List<RelayEntry> getRelays();
boolean checkShaderGLErrors();
boolean isDemo();
boolean allowUpdateSvc();
boolean allowUpdateDL();
boolean isEnableDownloadOfflineButton();
String getDownloadOfflineButtonLink();
boolean useSpecialCursors();
boolean isLogInvalidCerts();
boolean isCheckRelaysForUpdates();
boolean isEnableSignatureBadge();
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IFramebufferGL extends IObjectGL {
}

View file

@ -0,0 +1,22 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IObjectGL {
void free();
}

View file

@ -0,0 +1,28 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class IPCPacketData {
public final String channel;
public final byte[] contents;
public IPCPacketData(String channel, byte[] contents) {
this.channel = channel;
this.contents = contents;
}
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IProgramGL extends IObjectGL {
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IQueryGL extends IObjectGL {
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IRenderbufferGL extends IObjectGL {
}

View file

@ -0,0 +1,28 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import java.io.InputStream;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IResourceHandle {
String getPath();
InputStream inputStream();
byte[] toByteArray();
}

View file

@ -0,0 +1,121 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import org.json.JSONObject;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IServerQuery {
public static final long defaultTimeout = 10000l;
public static enum QueryReadyState {
CONNECTING(true, false), OPEN(true, false), CLOSED(false, true), FAILED(false, true);
private final boolean open;
private final boolean closed;
private QueryReadyState(boolean open, boolean closed) {
this.open = open;
this.closed = closed;
}
public boolean isOpen() {
return open;
}
public boolean isClosed() {
return closed;
}
}
void send(String str);
default void send(JSONObject json) {
send(json.toString());
}
void send(byte[] bytes);
int responsesAvailable();
QueryResponse getResponse();
int binaryResponsesAvailable();
byte[] getBinaryResponse();
QueryReadyState readyState();
default boolean isOpen() {
return readyState().isOpen();
}
default boolean isClosed() {
return readyState().isClosed();
}
void close();
EnumServerRateLimit getRateLimit();
default boolean awaitResponseAvailable(long timeout) {
long start = System.currentTimeMillis();
while(isOpen() && responsesAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) {
try {
Thread.sleep(0l, 250000);
} catch (InterruptedException e) {
}
}
return responsesAvailable() > 0;
}
default boolean awaitResponseAvailable() {
return awaitResponseAvailable(defaultTimeout);
}
default boolean awaitResponseBinaryAvailable(long timeout) {
long start = System.currentTimeMillis();
while(isOpen() && binaryResponsesAvailable() <= 0 && (timeout <= 0l || System.currentTimeMillis() - start < timeout)) {
try {
Thread.sleep(0l, 250000);
} catch (InterruptedException e) {
}
}
return binaryResponsesAvailable() > 0;
}
default boolean awaitResponseBinaryAvailable() {
return awaitResponseBinaryAvailable(defaultTimeout);
}
default QueryResponse awaitResponse(long timeout) {
return awaitResponseAvailable(timeout) ? getResponse() : null;
}
default QueryResponse awaitResponse() {
return awaitResponseAvailable() ? getResponse() : null;
}
default byte[] awaitResponseBinary(long timeout) {
return awaitResponseBinaryAvailable(timeout) ? getBinaryResponse() : null;
}
default byte[] awaitResponseBinary() {
return awaitResponseBinaryAvailable() ? getBinaryResponse() : null;
}
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IShaderGL extends IObjectGL {
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface ITextureGL extends IObjectGL {
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IUniformGL extends IObjectGL {
}

View file

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

View file

@ -0,0 +1,60 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import org.json.JSONObject;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class QueryResponse {
public final String responseType;
private final Object responseData;
public final String serverVersion;
public final String serverBrand;
public final String serverName;
public final long serverTime;
public final long clientTime;
public final boolean serverCracked;
public final long ping;
public QueryResponse(JSONObject obj, long ping) {
this.responseType = obj.getString("type").toLowerCase();
this.ping = ping;
this.responseData = obj.get("data");
this.serverVersion = obj.getString("vers");
this.serverBrand = obj.getString("brand");
this.serverName = obj.getString("name");
this.serverTime = obj.getLong("time");
this.clientTime = System.currentTimeMillis();
this.serverCracked = obj.optBoolean("cracked", false);
}
public boolean isResponseString() {
return responseData instanceof String;
}
public boolean isResponseJSON() {
return responseData instanceof JSONObject;
}
public String getResponseString() {
return (String)responseData;
}
public JSONObject getResponseJSON() {
return (JSONObject)responseData;
}
}

View file

@ -0,0 +1,28 @@
package net.lax1dude.eaglercraft.v1_8.internal;
import net.lax1dude.eaglercraft.v1_8.internal.vfs2.VFSIterator2.BreakLoop;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface VFSFilenameIterator {
public default void end() {
throw new BreakLoop();
}
public void next(String entry);
}

View file

@ -0,0 +1,54 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface Buffer {
int capacity();
int position();
Buffer position(int newPosition);
int limit();
Buffer limit(int newLimit);
Buffer mark();
Buffer reset();
Buffer clear();
Buffer flip();
Buffer rewind();
int remaining();
boolean hasRemaining();
boolean isReadOnly();
boolean hasArray();
Object array();
int arrayOffset();
boolean isDirect();
}

View file

@ -0,0 +1,109 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface ByteBuffer extends Buffer {
ByteBuffer slice();
ByteBuffer duplicate();
ByteBuffer asReadOnlyBuffer();
byte get();
ByteBuffer put(byte b);
byte get(int index);
ByteBuffer put(int index, byte b);
ByteBuffer get(byte[] dst, int offset, int length);
ByteBuffer get(byte[] dst);
ByteBuffer put(ByteBuffer src);
ByteBuffer put(byte[] src, int offset, int length);
ByteBuffer put(byte[] src);
int arrayOffset();
ByteBuffer compact();
char getChar();
ByteBuffer putChar(char value);
char getChar(int index);
ByteBuffer putChar(int index, char value);
public abstract short getShort();
ByteBuffer putShort(short value);
short getShort(int index);
ByteBuffer putShort(int index, short value);
ShortBuffer asShortBuffer();
int getInt();
ByteBuffer putInt(int value);
int getInt(int index);
ByteBuffer putInt(int index, int value);
IntBuffer asIntBuffer();
long getLong();
ByteBuffer putLong(long value);
long getLong(int index);
ByteBuffer putLong(int index, long value);
float getFloat();
ByteBuffer putFloat(float value);
float getFloat(int index);
ByteBuffer putFloat(int index, float value);
FloatBuffer asFloatBuffer();
ByteBuffer mark();
ByteBuffer reset();
ByteBuffer clear();
ByteBuffer flip();
ByteBuffer rewind();
ByteBuffer limit(int newLimit);
ByteBuffer position(int newPosition);
}

View file

@ -0,0 +1,71 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
import java.io.IOException;
import java.io.InputStream;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerBufferInputStream extends InputStream {
private final ByteBuffer buffer;
public EaglerBufferInputStream(ByteBuffer buffer) {
this.buffer = buffer;
}
@Override
public int read() throws IOException {
if(buffer.remaining() <= 0) {
return -1;
}
return (int)buffer.get() & 0xFF;
}
@Override
public int read(byte b[], int off, int len) throws IOException {
int p = buffer.position();
int l = buffer.limit();
int r = l - p;
if(r < len) {
len = r;
}
if(len > 0) {
buffer.get(b, off, len);
}
return len;
}
@Override
public long skip(long n) throws IOException {
int p = buffer.position();
int l = buffer.limit();
int r = l - p;
if(r < n) {
n = r;
}
if(n > 0) {
buffer.position(p + (int)n);
}
return n;
}
@Override
public int available() throws IOException {
return buffer.remaining();
}
}

View file

@ -0,0 +1,69 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface FloatBuffer extends Buffer {
FloatBuffer slice();
FloatBuffer duplicate();
FloatBuffer asReadOnlyBuffer();
float get();
FloatBuffer put(float b);
float get(int index);
FloatBuffer put(int index, float b);
float getElement(int index);
void putElement(int index, float value);
FloatBuffer get(float[] dst, int offset, int length);
FloatBuffer get(float[] dst);
FloatBuffer put(FloatBuffer src);
FloatBuffer put(float[] src, int offset, int length);
FloatBuffer put(float[] src);
int getArrayOffset();
FloatBuffer compact();
boolean isDirect();
FloatBuffer mark();
FloatBuffer reset();
FloatBuffer clear();
FloatBuffer flip();
FloatBuffer rewind();
FloatBuffer limit(int newLimit);
FloatBuffer position(int newPosition);
}

View file

@ -0,0 +1,69 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IntBuffer extends Buffer {
IntBuffer slice();
IntBuffer duplicate();
IntBuffer asReadOnlyBuffer();
int get();
IntBuffer put(int b);
int get(int index);
IntBuffer put(int index, int b);
int getElement(int index);
void putElement(int index, int value);
IntBuffer get(int[] dst, int offset, int length);
IntBuffer get(int[] dst);
IntBuffer put(IntBuffer src);
IntBuffer put(int[] src, int offset, int length);
IntBuffer put(int[] src);
int getArrayOffset();
IntBuffer compact();
boolean isDirect();
IntBuffer mark();
IntBuffer reset();
IntBuffer clear();
IntBuffer flip();
IntBuffer rewind();
IntBuffer limit(int newLimit);
IntBuffer position(int newPosition);
}

View file

@ -0,0 +1,68 @@
package net.lax1dude.eaglercraft.v1_8.internal.buffer;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface ShortBuffer extends Buffer {
ShortBuffer slice();
ShortBuffer duplicate();
ShortBuffer asReadOnlyBuffer();
short get();
ShortBuffer put(short b);
short get(int index);
ShortBuffer put(int index, short b);
short getElement(int index);
void putElement(int index, short value);
ShortBuffer get(short[] dst, int offset, int length);
ShortBuffer get(short[] dst);
ShortBuffer put(ShortBuffer src);
ShortBuffer put(short[] src, int offset, int length);
ShortBuffer put(short[] src);
int getArrayOffset();
ShortBuffer compact();
boolean isDirect();
ShortBuffer mark();
ShortBuffer reset();
ShortBuffer clear();
ShortBuffer flip();
ShortBuffer rewind();
ShortBuffer limit(int newLimit);
ShortBuffer position(int newPosition);
}

View file

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerFileSystemException extends RuntimeException {
public EaglerFileSystemException() {
}
public EaglerFileSystemException(String message, Throwable cause) {
super(message, cause);
}
public EaglerFileSystemException(String message) {
super(message);
}
public EaglerFileSystemException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,33 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class VFSFilenameIteratorImpl implements VFSFilenameIterator {
protected VFSIterator2 itr;
VFSFilenameIteratorImpl(VFSIterator2 itr) {
this.itr = itr;
}
@Override
public void next(String entry) {
itr.next(new VFile2(entry));
}
}

View file

@ -0,0 +1,32 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface VFSIterator2 {
public static class BreakLoop extends RuntimeException {
public BreakLoop() {
super("iterator loop break request");
}
}
public default void end() {
throw new BreakLoop();
}
public void next(VFile2 entry);
}

View file

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class VFSListFilenamesIteratorImpl implements VFSFilenameIterator {
protected List<String> list;
VFSListFilenamesIteratorImpl(List<String> list) {
this.list = list;
}
@Override
public void next(String entry) {
list.add(entry);
}
}

View file

@ -0,0 +1,35 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.internal.VFSFilenameIterator;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class VFSListFilesIteratorImpl implements VFSFilenameIterator {
protected List<VFile2> list;
VFSListFilesIteratorImpl(List<VFile2> list) {
this.list = list;
}
@Override
public void next(String entry) {
list.add(new VFile2(entry));
}
}

View file

@ -0,0 +1,254 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import net.lax1dude.eaglercraft.v1_8.EagUtils;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class VFile2 {
public static final String pathSeperator = "/";
public static final String[] altPathSeperator = new String[] { "\\" };
public static String normalizePath(String p) {
for(int i = 0; i < altPathSeperator.length; ++i) {
p = p.replace(altPathSeperator[i], pathSeperator);
}
if(p.startsWith(pathSeperator)) {
p = p.substring(1);
}
if(p.endsWith(pathSeperator)) {
p = p.substring(0, p.length() - pathSeperator.length());
}
return p;
}
public static String[] splitPath(String p) {
String[] pth = normalizePath(p).split(pathSeperator);
for(int i = 0; i < pth.length; ++i) {
pth[i] = pth[i].trim();
}
return pth;
}
protected String path;
public static String createPath(Object... p) {
ArrayList<String> r = new ArrayList();
for(int i = 0; i < p.length; ++i) {
if(p[i] == null) {
continue;
}
String gg = p[i].toString();
if(gg == null) {
continue;
}
String[] parts = splitPath(gg);
for(int j = 0; j < parts.length; ++j) {
if(parts[j] == null || parts[j].equals(".")) {
continue;
}else if(parts[j].equals("..") && r.size() > 0) {
int k = r.size() - 1;
if(!r.get(k).equals("..")) {
r.remove(k);
}else {
r.add("..");
}
}else {
r.add(parts[j]);
}
}
}
if(r.size() > 0) {
StringBuilder s = new StringBuilder();
for(int i = 0; i < r.size(); ++i) {
if(i > 0) {
s.append(pathSeperator);
}
s.append(r.get(i));
}
return s.toString();
}else {
return null;
}
}
public VFile2(Object... p) {
this.path = createPath(p);
}
public InputStream getInputStream() {
assertNotRelative();
return new VFileInputStream(PlatformFilesystem.eaglerRead(path));
}
public OutputStream getOutputStream() {
assertNotRelative();
return new VFileOutputStream(this);
}
public String toString() {
return path;
}
public boolean isRelative() {
return path == null || path.contains("..");
}
public void assertNotRelative() {
if(isRelative()) throw new EaglerFileSystemException("Relative paths are not allowed: " + path);
}
public boolean canRead() {
return !isRelative() && PlatformFilesystem.eaglerExists(path);
}
public String getPath() {
return path.equals("unnamed") ? null : path;
}
public String getName() {
int i = path.lastIndexOf(pathSeperator);
return i == -1 ? path : path.substring(i + 1);
}
public static String getNameFromPath(String path) {
path = normalizePath(path);
int i = path.lastIndexOf(pathSeperator);
return i == -1 ? path : path.substring(i + 1);
}
public boolean canWrite() {
return !isRelative();
}
public String getParent() {
if(path == null) {
return null;
}
int i = path.lastIndexOf(pathSeperator);
return i == -1 ? ".." : path.substring(0, i);
}
public int hashCode() {
return path == null ? 0 : path.hashCode();
}
public boolean equals(Object o) {
return path != null && o != null && (o instanceof VFile2) && path.equals(((VFile2)o).path);
}
public boolean exists() {
return !isRelative() && PlatformFilesystem.eaglerExists(path);
}
public boolean delete() {
return !isRelative() && PlatformFilesystem.eaglerDelete(path);
}
public boolean renameTo(String p) {
if(!isRelative() && PlatformFilesystem.eaglerMove(path, p)) {
return true;
}
return false;
}
public boolean renameTo(VFile2 p) {
return renameTo(p.path);
}
public int length() {
return isRelative() ? -1 : PlatformFilesystem.eaglerSize(path);
}
public byte[] getAllBytes() {
assertNotRelative();
if(!exists()) {
return null;
}
ByteBuffer readBuffer = PlatformFilesystem.eaglerRead(path);
try {
byte[] copyBuffer = new byte[readBuffer.remaining()];
readBuffer.get(copyBuffer);
return copyBuffer;
}finally {
PlatformRuntime.freeByteBuffer(readBuffer);
}
}
public String getAllChars() {
assertNotRelative();
if(!exists()) {
return null;
}
return new String(getAllBytes(), StandardCharsets.UTF_8);
}
public String[] getAllLines() {
assertNotRelative();
if(!exists()) {
return null;
}
return EagUtils.linesArray(new String(getAllBytes(), StandardCharsets.UTF_8));
}
public void setAllChars(String bytes) {
setAllBytes(bytes.getBytes(StandardCharsets.UTF_8));
}
public void setAllBytes(byte[] bytes) {
assertNotRelative();
ByteBuffer copyBuffer = PlatformRuntime.allocateByteBuffer(bytes.length);
try {
copyBuffer.put(bytes);
copyBuffer.flip();
PlatformFilesystem.eaglerWrite(path, copyBuffer);
}finally {
PlatformRuntime.freeByteBuffer(copyBuffer);
}
}
public void iterateFiles(VFSIterator2 itr, boolean recursive) {
assertNotRelative();
PlatformFilesystem.eaglerIterate(path, new VFSFilenameIteratorImpl(itr), recursive);
}
public List<String> listFilenames(boolean recursive) {
List<String> ret = new ArrayList();
PlatformFilesystem.eaglerIterate(path, new VFSListFilenamesIteratorImpl(ret), recursive);
return ret;
}
public List<VFile2> listFiles(boolean recursive) {
List<VFile2> ret = new ArrayList();
PlatformFilesystem.eaglerIterate(path, new VFSListFilesIteratorImpl(ret), recursive);
return ret;
}
public static int copyFile(VFile2 src, VFile2 dst) {
src.assertNotRelative();
dst.assertNotRelative();
return PlatformFilesystem.eaglerCopy(src.path, dst.path);
}
}

View file

@ -0,0 +1,89 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.io.IOException;
import java.io.InputStream;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class VFileInputStream extends InputStream {
private ByteBuffer fileBuffer;
VFileInputStream(ByteBuffer buffer) {
this.fileBuffer = buffer;
}
@Override
public int read() throws IOException {
if(fileBuffer == null) {
throw new IOException("Stream is closed");
}
if(fileBuffer.remaining() <= 0) {
return -1;
}
return (int)fileBuffer.get() & 0xFF;
}
@Override
public int read(byte b[], int off, int len) throws IOException {
if(fileBuffer == null) {
throw new IOException("Stream is closed");
}
int p = fileBuffer.position();
int l = fileBuffer.limit();
int r = l - p;
if(r < len) {
len = r;
}
if(len > 0) {
fileBuffer.get(b, off, len);
}
return len;
}
@Override
public long skip(long n) throws IOException {
if(fileBuffer == null) {
throw new IOException("Stream is closed");
}
int p = fileBuffer.position();
int l = fileBuffer.limit();
int r = l - p;
if(r < n) {
n = r;
}
if(n > 0) {
fileBuffer.position(p + (int)n);
}
return n;
}
@Override
public int available() throws IOException {
return fileBuffer == null ? -1 : fileBuffer.remaining();
}
@Override
public void close() {
if(fileBuffer != null) {
PlatformRuntime.freeByteBuffer(fileBuffer);
fileBuffer = null;
}
}
}

View file

@ -0,0 +1,54 @@
package net.lax1dude.eaglercraft.v1_8.internal.vfs2;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformFilesystem;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
import net.lax1dude.eaglercraft.v1_8.internal.buffer.ByteBuffer;
/**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
class VFileOutputStream extends ByteArrayOutputStream {
private final VFile2 vfsFile;
private boolean closed = false;
VFileOutputStream(VFile2 vfsFile) {
super(256);
this.vfsFile = vfsFile;
}
@Override
public void close() throws IOException {
if(!closed) {
closed = true;
ByteBuffer copyBuffer = PlatformRuntime.allocateByteBuffer(count);
try {
copyBuffer.put(buf, 0, count);
copyBuffer.flip();
try {
PlatformFilesystem.eaglerWrite(vfsFile.path, copyBuffer);
}catch(Throwable t) {
throw new IOException("Could not write stream contents to file!", t);
}
}finally {
PlatformRuntime.freeByteBuffer(copyBuffer);
}
}
}
}

View file

@ -0,0 +1,24 @@
package net.lax1dude.eaglercraft.v1_8.json;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface JSONDataParserImpl {
boolean accepts(Object type);
Object parse(Object data);
}

View file

@ -0,0 +1,20 @@
package net.lax1dude.eaglercraft.v1_8.json;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface JSONTypeCodec<O, J> extends JSONTypeSerializer<O, J>, JSONTypeDeserializer<J, O> {
}

View file

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8.json;
import org.json.JSONException;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface JSONTypeDeserializer<J, O> {
default O deserializeFromJson(J json) throws JSONException {
try {
return deserialize(json);
}catch(JSONException obj) {
throw obj;
}catch(Throwable t) {
throw new JSONException("Exception deserializing JSON object", t);
}
}
O deserialize(J json) throws JSONException;
}

View file

@ -0,0 +1,161 @@
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;
import net.minecraft.world.gen.ChunkProviderSettings;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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());
registerType(ChunkProviderSettings.Factory.class, new ChunkProviderSettings.Serializer());
registerParser(new JSONDataParserString());
registerParser(new JSONDataParserReader());
registerParser(new JSONDataParserStream());
}
}

View file

@ -0,0 +1,34 @@
package net.lax1dude.eaglercraft.v1_8.json;
import org.json.JSONException;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface JSONTypeSerializer<O, J> {
default J serializeToJson(O object) throws JSONException {
try {
return serialize(object);
}catch(JSONException obj) {
throw obj;
}catch(Throwable t) {
throw new JSONException("Exception serializing JSON object", t);
}
}
J serialize(O object) throws JSONException;
}

View file

@ -0,0 +1,52 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class JSONDataParserReader implements JSONDataParserImpl {
public boolean accepts(Object type) {
return type instanceof Reader;
}
@Override
public Object parse(Object data) {
Reader r = (Reader)data;
StringBuilder builder = new StringBuilder();
char[] copyBuffer = new char[2048];
int i;
try {
try {
while((i = r.read(copyBuffer)) != -1) {
builder.append(copyBuffer, 0, i);
}
}finally {
r.close();
}
}catch(IOException ex) {
throw new JSONException("Could not deserialize from " + data.getClass().getSimpleName());
}
return JSONTypeProvider.parse(builder.toString());
}
}

View file

@ -0,0 +1,48 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class JSONDataParserStream implements JSONDataParserImpl {
public boolean accepts(Object type) {
return type instanceof InputStream;
}
@Override
public Object parse(Object data) {
try {
InputStream s = (InputStream)data;
try {
return JSONTypeProvider.parse(IOUtils.inputStreamToString(s, StandardCharsets.UTF_8));
}finally {
s.close();
}
} catch (IOException e) {
throw new JSONException("Could not deserialize from " + data.getClass().getSimpleName());
}
}
}

View file

@ -0,0 +1,49 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class JSONDataParserString implements JSONDataParserImpl {
public boolean accepts(Object type) {
return type instanceof String;
}
@Override
public Object parse(Object data) {
String s = ((String)data).trim();
try {
if(s.indexOf('{') == 0 && s.lastIndexOf('}') == s.length() - 1) {
return new JSONObject(s);
}else if(s.indexOf('[') == 0 && s.lastIndexOf(']') == s.length() - 1) {
return new JSONArray(s);
}else if ((s.indexOf('\"') == 0 && s.lastIndexOf('\"') == s.length() - 1)
|| (s.indexOf('\'') == 0 && s.lastIndexOf('\'') == s.length() - 1)) {
return (new JSONObject("{\"E\":" + s + "}")).getString("E");
}else {
return (String)data;
}
}catch(JSONException ex) {
return (String)data;
}
}
}

View file

@ -0,0 +1,40 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class SoundMapDeserializer implements JSONTypeDeserializer<JSONObject, SoundMap> {
@Override
public SoundMap deserialize(JSONObject json) throws JSONException {
Map<String, SoundList> soundsMap = new HashMap();
for(String str : json.keySet()) {
soundsMap.put(str, JSONTypeProvider.deserialize(json.getJSONObject(str), SoundList.class));
}
return new SoundMap(soundsMap);
}
}

View file

@ -0,0 +1,22 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface ILogRedirector {
void log(String txt, boolean err);
}

View file

@ -0,0 +1,42 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
import java.io.PrintStream;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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;
public final boolean isErr;
private Level(int levelInt, String levelName, boolean stderr) {
this.levelInt = levelInt;
this.levelName = levelName;
this.stdout = stderr ? System.err : System.out;
this.isErr = stderr;
}
PrintStream getPrintStream() {
return stdout;
}
}

View file

@ -0,0 +1,48 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
import java.util.HashMap;
import java.util.Map;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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 ILogRedirector logRedirector = null;
public static Logger getLogger() {
return getLogger("Minecraft");
}
public static Logger getLogger(String name) {
Logger ret;
synchronized(loggerInstances) {
ret = loggerInstances.get(name);
if(ret == null) {
ret = new Logger(name);
}
}
return ret;
}
public static void setLevel(Level lv) {
logLevel = lv;
}
}

View file

@ -0,0 +1,175 @@
package net.lax1dude.eaglercraft.v1_8.log4j;
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-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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 = EagRuntime.fixDateFormat(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) {
dateInstance.setTime(System.currentTimeMillis());
String line = "[" + fmt.format(dateInstance) + "]" +
"[" + EagRuntime.currentThreadName() + "/" + level.levelName + "]" +
"[" + loggerName + "]: " + msg;
level.getPrintStream().println(line);
if(LogManager.logRedirector != null) {
LogManager.logRedirector.log(line, level.isErr);
}
}
}
}
public void log(Level level, String msg, Object... args) {
if(level.levelInt >= LogManager.logLevel.levelInt) {
synchronized(LogManager.logLock) {
dateInstance.setTime(System.currentTimeMillis());
String line = "[" + fmt.format(dateInstance) + "]" +
"[" + EagRuntime.currentThreadName() + "/" + level.levelName + "]" +
"[" + loggerName + "]: " + formatParams(msg, args);
level.getPrintStream().println(line);
if(LogManager.logRedirector != null) {
LogManager.logRedirector.log(line, level.isErr);
}
}
}
}
public static String formatParams(String msg, Object... args) {
if(args.length > 0) {
StringBuilder builtString = new StringBuilder();
for(int i = 0; i < args.length; ++i) {
int idx = msg.indexOf("{}");
if(idx != -1) {
builtString.append(msg.substring(0, idx));
builtString.append(args[i]);
msg = msg.substring(idx + 2);
}else {
break;
}
}
builtString.append(msg);
return builtString.toString();
}else {
return msg;
}
}
public void log(Level level, Throwable msg) {
logExcp(level, "Exception Thrown", msg);
}
private void logExcp(final Level level, String h, Throwable msg) {
log(level, "{}: {}", h, msg.toString());
EagRuntime.getStackTrace(msg, (e) -> log(level, " at {}", e));
PlatformRuntime.printJSExceptionIfBrowser(msg);
Throwable cause = msg.getCause();
if(cause != null) {
logExcp(level, "Caused By", cause);
}
}
public boolean isDebugEnabled() {
return LogManager.logLevel.levelInt <= Level.DEBUG.levelInt;
}
}

View file

@ -0,0 +1,85 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class AcceleratedEffectRenderer implements IAcceleratedParticleEngine {
private float partialTicks;
private float f1;
private float f2;
private float f3;
private float f4;
private float f5;
@Override
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);
}
}
@Override
public void draw(float texCoordWidth, float texCoordHeight) {
InstancedParticleRenderer.render(texCoordWidth, texCoordHeight, 0.0625f, f1, f5, f2, f3, f4);
}
@Override
public void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY, int lightMapData,
int texSize, float particleSize, float r, float g, float b, float a) {
float xx = (float) (entityIn.prevPosX + (entityIn.posX - entityIn.prevPosX) * (double) partialTicks - EntityFX.interpPosX);
float yy = (float) (entityIn.prevPosY + (entityIn.posY - entityIn.prevPosY) * (double) partialTicks - EntityFX.interpPosY);
float zz = (float) (entityIn.prevPosZ + (entityIn.posZ - entityIn.prevPosZ) * (double) partialTicks - EntityFX.interpPosZ);
drawParticle(xx, yy, zz, particleIndexX, particleIndexY, lightMapData, texSize, particleSize, r, g, b, a);
}
@Override
public void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY, int lightMapData,
int texSize, float particleSize, int rgba) {
float xx = (float) (entityIn.prevPosX + (entityIn.posX - entityIn.prevPosX) * (double) partialTicks - EntityFX.interpPosX);
float yy = (float) (entityIn.prevPosY + (entityIn.posY - entityIn.prevPosY) * (double) partialTicks - EntityFX.interpPosY);
float zz = (float) (entityIn.prevPosZ + (entityIn.posZ - entityIn.prevPosZ) * (double) partialTicks - EntityFX.interpPosZ);
drawParticle(xx, yy, zz, particleIndexX, particleIndexY, lightMapData, texSize, particleSize, rgba);
}
@Override
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a) {
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, r, g, b, a);
}
@Override
public void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba) {
InstancedParticleRenderer.appendParticle(posX, posY, posZ, particleIndexX, particleIndexY, lightMapData & 0xFF,
(lightMapData >> 16) & 0xFF, (int)(particleSize * 16.0f), texSize, rgba);
}
}

View file

@ -0,0 +1,239 @@
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);
CompiledChunk ch = generator.getCompiledChunk();
if(ch.isLayerEmpty(EnumWorldBlockLayer.TRANSLUCENT) && ch.isLayerEmpty(EnumWorldBlockLayer.REALISTIC_WATER)) {
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) {
if(!compiledchunk.isLayerEmpty(EnumWorldBlockLayer.TRANSLUCENT)) {
this.uploadChunk(EnumWorldBlockLayer.TRANSLUCENT, generator.getRegionRenderCacheBuilder()
.getWorldRendererByLayer(EnumWorldBlockLayer.TRANSLUCENT),
generator.getRenderChunk(), compiledchunk);
}
if(!compiledchunk.isLayerEmpty(EnumWorldBlockLayer.REALISTIC_WATER)) {
this.uploadChunk(EnumWorldBlockLayer.REALISTIC_WATER, generator.getRegionRenderCacheBuilder()
.getWorldRendererByLayer(EnumWorldBlockLayer.REALISTIC_WATER),
generator.getRenderChunk(), compiledchunk);
}
generator.getRenderChunk().setCompiledChunk(compiledchunk);
generator.setStatus(ChunkCompileTaskGenerator.Status.DONE);
}
}
public boolean updateChunks(long timeout) {
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
if (entity == null) {
queue.clear();
chunkUpdatesQueued = 0;
return false;
}else {
boolean flag = false;
long millis = System.currentTimeMillis();
List<ChunkCompileTaskGenerator> droppedUpdates = new LinkedList();
while(!queue.isEmpty()) {
ChunkCompileTaskGenerator generator = queue.remove(0);
if(!generator.canExecuteYet()) {
if(millis - generator.goddamnFuckingTimeout < 60000l) {
droppedUpdates.add(generator);
}
continue;
}
runGenerator(generator, entity);
flag = true;
++chunkUpdatesTotal;
if(timeout < System.nanoTime()) {
break;
}
}
queue.addAll(droppedUpdates);
return flag;
}
}
public boolean updateChunkLater(RenderChunk chunkRenderer) {
final ChunkCompileTaskGenerator chunkcompiletaskgenerator = chunkRenderer.makeCompileTaskChunk();
boolean flag = queue.size() < 100;
if (!flag) {
chunkcompiletaskgenerator.finish();
}else {
chunkcompiletaskgenerator.addFinishRunnable(new Runnable() {
@Override
public void run() {
if(queue.remove(chunkcompiletaskgenerator)) {
++chunkUpdatesTotal;
}
}
});
queue.add(chunkcompiletaskgenerator);
++chunkUpdatesQueued;
}
return flag;
}
public boolean updateChunkNow(RenderChunk chunkRenderer) {
Entity entity = Minecraft.getMinecraft().getRenderViewEntity();
if (entity != null) {
runGenerator(chunkRenderer.makeCompileTaskChunk(), entity);
++chunkUpdatesTotalImmediate;
}
return true;
}
public void stopChunkUpdates() {
queue.clear();
chunkUpdatesQueued = 0;
}
public boolean updateTransparencyLater(RenderChunk chunkRenderer) {
if(isAlreadyQueued(chunkRenderer)) {
return true;
}
final ChunkCompileTaskGenerator chunkcompiletaskgenerator = chunkRenderer.makeCompileTaskTransparency();
if (chunkcompiletaskgenerator == null) {
return true;
}
chunkcompiletaskgenerator.goddamnFuckingTimeout = System.currentTimeMillis();
if(queue.size() < 100) {
chunkcompiletaskgenerator.addFinishRunnable(new Runnable() {
@Override
public void run() {
if(queue.remove(chunkcompiletaskgenerator)) {
++chunkUpdatesTotal;
}
}
});
queue.add(chunkcompiletaskgenerator);
++chunkUpdatesQueued;
return true;
}else {
return false;
}
}
public void uploadChunk(final EnumWorldBlockLayer player, final WorldRenderer chunkRenderer,
final RenderChunk compiledChunkIn, final CompiledChunk parCompiledChunk) {
this.uploadDisplayList(chunkRenderer,
((ListedRenderChunk) compiledChunkIn).getDisplayList(player, parCompiledChunk), compiledChunkIn);
chunkRenderer.setTranslation(0.0D, 0.0D, 0.0D);
}
private void uploadDisplayList(WorldRenderer chunkRenderer, int parInt1, RenderChunk parRenderChunk) {
EaglercraftGPU.glNewList(parInt1, GL_COMPILE);
GlStateManager.pushMatrix();
this.worldVertexUploader.func_181679_a(chunkRenderer);
GlStateManager.popMatrix();
EaglercraftGPU.glEndList();
}
public boolean isAlreadyQueued(RenderChunk update) {
for(int i = 0, l = queue.size(); i < l; ++i) {
if(queue.get(i).getRenderChunk() == update) {
return true;
}
}
return false;
}
public String getDebugInfo() {
long millis = System.currentTimeMillis();
if(millis - chunkUpdatesTotalLastUpdate > 500l) {
chunkUpdatesTotalLastUpdate = millis;
chunkUpdatesTotalLast = chunkUpdatesTotal;
chunkUpdatesTotalImmediateLast = chunkUpdatesTotalImmediate;
chunkUpdatesTotalImmediate = 0;
chunkUpdatesTotal = 0;
chunkUpdatesQueuedLast = chunkUpdatesQueued;
chunkUpdatesQueued -= chunkUpdatesTotalLast;
if(chunkUpdatesQueued < 0) {
chunkUpdatesQueued = 0;
}
}
return "Uq: " + (chunkUpdatesTotalLast + chunkUpdatesTotalImmediateLast) + "/"
+ (chunkUpdatesQueuedLast + chunkUpdatesTotalImmediateLast);
}
}

View file

@ -0,0 +1,233 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerFontRenderer extends FontRenderer {
private final int[] temporaryCodepointArray = new int[6553];
public EaglerFontRenderer(GameSettings gameSettingsIn, ResourceLocation location, TextureManager textureManagerIn,
boolean unicode) {
super(gameSettingsIn, location, textureManagerIn, unicode);
}
public int drawString(String text, float x, float y, int color, boolean dropShadow) {
if (text == null || text.length() == 0) {
this.posX = x + (dropShadow ? 1 : 0);
this.posY = y;
} else {
if(this.unicodeFlag || !decodeASCIICodepointsAndValidate(text)) {
return super.drawString(text, x, y, color, dropShadow);
}
this.resetStyles();
if ((color & 0xFC000000) == 0) {
color |= 0xFF000000;
}
this.red = (float) (color >> 16 & 255) / 255.0F;
this.blue = (float) (color >> 8 & 255) / 255.0F;
this.green = (float) (color & 255) / 255.0F;
this.alpha = (float) (color >> 24 & 255) / 255.0F;
this.posX = x;
this.posY = y;
this.textColor = color;
this.renderStringAtPos0(text, dropShadow);
}
return (int) this.posX;
}
protected void renderStringAtPos(String parString1, boolean parFlag) {
if(parString1 == null) return;
if(this.unicodeFlag || !decodeASCIICodepointsAndValidate(parString1)) {
super.renderStringAtPos(parString1, parFlag);
}else {
renderStringAtPos0(parString1, false);
}
}
private void renderStringAtPos0(String parString1, boolean parFlag) {
renderEngine.bindTexture(locationFontTexture);
InstancedFontRenderer.begin();
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR);
boolean hasStrike = false;
for (int i = 0; i < parString1.length(); ++i) {
char c0 = parString1.charAt(i);
if (c0 == 167 && i + 1 < parString1.length()) {
int i1 = "0123456789abcdefklmnor".indexOf(Character.toLowerCase(parString1.charAt(i + 1)));
if (i1 < 16) {
this.randomStyle = false;
this.boldStyle = false;
this.strikethroughStyle = false;
this.underlineStyle = false;
this.italicStyle = false;
if (i1 < 0 || i1 > 15) {
i1 = 15;
}
int j1 = this.colorCode[i1];
this.textColor = j1 | (this.textColor & 0xFF000000);
} else if (i1 == 16) {
this.randomStyle = true;
} else if (i1 == 17) {
this.boldStyle = true;
} else if (i1 == 18) {
this.strikethroughStyle = true;
} else if (i1 == 19) {
this.underlineStyle = true;
} else if (i1 == 20) {
this.italicStyle = true;
} else if (i1 == 21) {
this.randomStyle = false;
this.boldStyle = false;
this.strikethroughStyle = false;
this.underlineStyle = false;
this.italicStyle = false;
this.textColor = ((int) (this.alpha * 255.0f) << 24) | ((int) (this.red * 255.0f) << 16)
| ((int) (this.green * 255.0f) << 8) | (int) (this.blue * 255.0f);
}
++i;
} else {
int j = temporaryCodepointArray[i];
if (this.randomStyle && j != -1) {
int k = this.getCharWidth(c0);
String chars = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
char c1;
while (true) {
j = this.fontRandom.nextInt(chars.length());
c1 = chars.charAt(j);
if (k == this.getCharWidth(c1)) {
break;
}
}
c0 = c1;
}
float f = this.appendCharToBuffer(j, this.textColor, this.boldStyle, this.italicStyle);
if (this.strikethroughStyle) {
hasStrike = true;
worldrenderer.pos((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D)
.endVertex();
worldrenderer
.pos((double) (this.posX + f), (double) (this.posY + (float) (this.FONT_HEIGHT / 2)), 0.0D)
.endVertex();
worldrenderer.pos((double) (this.posX + f),
(double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D).endVertex();
worldrenderer
.pos((double) this.posX, (double) (this.posY + (float) (this.FONT_HEIGHT / 2) - 1.0F), 0.0D)
.endVertex();
worldrenderer.putColor4(this.textColor);
}
if (this.underlineStyle) {
hasStrike = true;
int l = this.underlineStyle ? -1 : 0;
worldrenderer.pos((double) (this.posX + (float) l),
(double) (this.posY + (float) this.FONT_HEIGHT), 0.0D).endVertex();
worldrenderer.pos((double) (this.posX + f), (double) (this.posY + (float) this.FONT_HEIGHT), 0.0D)
.endVertex();
worldrenderer
.pos((double) (this.posX + f), (double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D)
.endVertex();
worldrenderer.pos((double) (this.posX + (float) l),
(double) (this.posY + (float) this.FONT_HEIGHT - 1.0F), 0.0D).endVertex();
worldrenderer.putColor4(this.textColor);
}
this.posX += (float) ((int) f);
}
}
float texScale = 0.0625f;
if(!hasStrike) {
worldrenderer.finishDrawing();
}
if(parFlag) {
if(hasStrike) {
GlStateManager.color(0.25f, 0.25f, 0.25f, 1.0f);
GlStateManager.translate(1.0f, 1.0f, 0.0f);
tessellator.draw();
GlStateManager.translate(-1.0f, -1.0f, 0.0f);
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
InstancedFontRenderer.render(8, 8, texScale, texScale, true);
EaglercraftGPU.renderAgain();
}else {
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
InstancedFontRenderer.render(8, 8, texScale, texScale, true);
}
}else {
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
if(hasStrike) {
tessellator.draw();
}
InstancedFontRenderer.render(8, 8, texScale, texScale, false);
}
if(parFlag) {
this.posX += 1.0f;
}
}
private float appendCharToBuffer(int parInt1, int color, boolean boldStyle, boolean italicStyle) {
if (parInt1 == 32) {
return 4.0f;
}else {
int i = parInt1 % 16;
int j = parInt1 / 16;
float w = this.charWidth[parInt1];
if(boldStyle) {
InstancedFontRenderer.appendBoldQuad((int)this.posX, (int)this.posY, i, j, color, italicStyle);
++w;
}else {
InstancedFontRenderer.appendQuad((int)this.posX, (int)this.posY, i, j, color, italicStyle);
}
return w;
}
}
private boolean decodeASCIICodepointsAndValidate(String str) {
for(int i = 0, l = str.length(); i < l; ++i) {
int j = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000\u00a7"
.indexOf(str.charAt(i));
if(j != -1) {
temporaryCodepointArray[i] = j;
}else {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,380 @@
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.internal.IFramebufferGL;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class EaglerTextureAtlasSprite {
private static final Logger logger = LogManager.getLogger("EaglerTextureAtlasSprite");
protected final String iconName;
protected List<int[][]> framesTextureData = Lists.newArrayList();
protected int[][] interpolatedFrameData;
protected AnimationMetadataSection animationMetadata;
protected boolean rotated;
protected int originX;
protected int originY;
protected int width;
protected int height;
protected float minU;
protected float maxU;
protected float minV;
protected float maxV;
protected int frameCounter;
protected int tickCounter;
protected static String locationNameClock = "builtin/clock";
protected 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(IFramebufferGL[] copyColorFramebuffer) {
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, copyColorFramebuffer);
}
} 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, copyColorFramebuffer);
}
}
}
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);
}
}
protected void allocateFrameTextureData(int index) {
if (this.framesTextureData.size() <= index) {
for (int i = this.framesTextureData.size(); i <= index; ++i) {
this.framesTextureData.add((int[][]) null);
}
}
}
protected 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;
}
protected 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 + '}';
}
public void loadSpritePBR(ImageData[][] imageDatas, AnimationMetadataSection animationmetadatasection,
boolean dontAnimateNormals, boolean dontAnimateMaterial) {
Throwable t = new UnsupportedOperationException("PBR is not enabled");
try {
throw t;
}catch(Throwable tt) {
logger.error(t);
}
}
public void updateAnimationPBR(IFramebufferGL[] copyColorFramebuffer, IFramebufferGL[] copyMaterialFramebuffer, int materialTexOffset) {
Throwable t = new UnsupportedOperationException("PBR is not enabled");
try {
throw t;
}catch(Throwable tt) {
logger.error(t);
}
}
}

View file

@ -0,0 +1,38 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import net.minecraft.entity.Entity;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public interface IAcceleratedParticleEngine {
void begin(float partialTicks);
void draw(float texCoordWidth, float texCoordHeight);
void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a);
void drawParticle(Entity entityIn, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba);
void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, float r, float g, float b, float a);
void drawParticle(float posX, float posY, float posZ, int particleIndexX, int particleIndexY,
int lightMapData, int texSize, float particleSize, int rgba);
}

View file

@ -0,0 +1,185 @@
package net.lax1dude.eaglercraft.v1_8.minecraft;
import static net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL.*;
import static net.lax1dude.eaglercraft.v1_8.opengl.RealOpenGLEnums.*;
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.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.opengl.TextureCopyUtil;
import net.lax1dude.eaglercraft.v1_8.vector.Matrix3f;
import net.minecraft.client.renderer.GLAllocation;
/**
* Copyright (c) 2022 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class TextureAnimationCache {
public final int width;
public final int height;
public final int mipLevels;
private int frameCount = 1;
private int[] cacheTextures = null;
public static final int _GL_FRAMEBUFFER = 0x8D40;
public TextureAnimationCache(int width, int height, int mipLevels) {
this.width = width;
this.height = height;
this.mipLevels = mipLevels;
}
public void initialize(List<int[][]> frames) {
if(cacheTextures == null) {
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);
}
}
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);
}
}
public void free() {
if(cacheTextures != 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, IFramebufferGL[] dstFramebuffers) {
copyFrameLevelsToTex2D(animationFrame, mipLevels, dx, dy, w, h, dstFramebuffers);
}
/**
* WARNING: call <code>_wglBindFramebuffer(_GL_FRAMEBUFFER, null);</code> when complete
*/
public void copyFrameLevelsToTex2D(int animationFrame, int levels, int dx, int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
for(int i = 0; i < levels; ++i) {
_wglBindFramebuffer(_GL_FRAMEBUFFER, dstFramebuffers[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");
}
GlStateManager.bindTexture(cacheTextures[level]);
TextureCopyUtil.srcSize(width >> level, (height >> level) * frameCount);
TextureCopyUtil.blitTextureUsingViewports(0, h * animationFrame, dx, dy, w, h);
}
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor, int dx,
int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
copyInterpolatedFrameLevelsToTex2D(animationFrameFrom, animationFrameTo, factor, mipLevels, dx, dy, w, h, dstFramebuffers);
}
/**
* WARNING: call <code>_wglBindFramebuffer(_GL_FRAMEBUFFER, null);</code> when complete
*/
public void copyInterpolatedFrameLevelsToTex2D(int animationFrameFrom, int animationFrameTo, float factor,
int levels, int dx, int dy, int w, int h, IFramebufferGL[] dstFramebuffers) {
for(int i = 0; i < levels; ++i) {
_wglBindFramebuffer(_GL_FRAMEBUFFER, dstFramebuffers[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");
}
GlStateManager.viewport(dx, dy, w, h);
GlStateManager.bindTexture(cacheTextures[level]);
GlStateManager.disableBlend();
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);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL_ONE, GL_ONE);
SpriteLevelMixer.drawSprite(0);
GlStateManager.disableBlend();
GlStateManager.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
public int getFrameCount() {
return frameCount;
}
}

View file

@ -0,0 +1,98 @@
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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
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;
}
}

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