Compare commits
3 Commits
713ab652f8
...
1f0d593a8c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f0d593a8c | ||
![]() |
3f5ee57068 | ||
![]() |
1321b5d680 |
CREDITSgateway_versiongateway_version_velocity
buildtools
client_versiongateway
EaglercraftXBungee
EaglerXBungee-Latest.jar
src/main
java/net/lax1dude/eaglercraft/v1_8/plugin/gateway_bungeecord
resources
EaglercraftXVelocity
EaglerXVelocity-Latest.jar
src/main
java/net/lax1dude/eaglercraft/v1_8/plugin/gateway_velocity
resources
patches/minecraft
delete.txt
net/minecraft/block
Block.edit.javaBlockAir.edit.javaBlockAnvil.edit.javaBlockBanner.edit.javaBlockBarrier.edit.javaBlockBasePressurePlate.edit.javaBlockBeacon.edit.javaBlockBed.edit.javaBlockBookshelf.edit.javaBlockBreakable.edit.javaBlockBrewingStand.edit.javaBlockBush.edit.javaBlockButton.edit.javaBlockButtonStone.edit.javaBlockButtonWood.edit.javaBlockCactus.edit.javaBlockCake.edit.javaBlockCarpet.edit.javaBlockCarrot.edit.javaBlockCauldron.edit.javaBlockChest.edit.javaBlockClay.edit.javaBlockCocoa.edit.javaBlockColored.edit.javaBlockCommandBlock.edit.javaBlockCompressedPowered.edit.javaBlockContainer.edit.javaBlockCrops.edit.javaBlockDaylightDetector.edit.javaBlockDeadBush.edit.javaBlockDirectional.edit.javaBlockDirt.edit.javaBlockDispenser.edit.javaBlockDoor.edit.javaBlockDoublePlant.edit.javaBlockDoubleStoneSlab.edit.javaBlockDoubleStoneSlabNew.edit.javaBlockDoubleWoodSlab.edit.javaBlockDragonEgg.edit.javaBlockDropper.edit.javaBlockDynamicLiquid.edit.javaBlockEnchantmentTable.edit.javaBlockEndPortal.edit.javaBlockEndPortalFrame.edit.javaBlockEnderChest.edit.javaBlockEventData.edit.javaBlockFalling.edit.javaBlockFarmland.edit.javaBlockFence.edit.javaBlockFenceGate.edit.javaBlockFire.edit.javaBlockFlower.edit.javaBlockFlowerPot.edit.javaBlockFurnace.edit.javaBlockGlass.edit.javaBlockGlowstone.edit.javaBlockGrass.edit.javaBlockGravel.edit.javaBlockHalfStoneSlab.edit.javaBlockHalfStoneSlabNew.edit.javaBlockHalfWoodSlab.edit.javaBlockHardenedClay.edit.javaBlockHay.edit.javaBlockHopper.edit.javaBlockHugeMushroom.edit.javaBlockIce.edit.javaBlockJukebox.edit.java
61
CREDITS
61
CREDITS
|
@ -217,6 +217,28 @@
|
|||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: High Performance Primitive Collections
|
||||
Project Author: Carrot Search
|
||||
Project URL: http://labs.carrotsearch.com/hppc.html
|
||||
|
||||
Used For: Primitive collections library for the client
|
||||
|
||||
* Copyright 2010-2013, Carrot Search s.c., Boznicza 11/56, Poznan, Poland
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: Google Guava
|
||||
Project Author: Google
|
||||
Project URL: https://github.com/google/guava
|
||||
|
@ -514,6 +536,45 @@
|
|||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: OpenJDK
|
||||
Project Author: Oracle, IBM
|
||||
Project URL: https://openjdk.org/projects/jdk/17/
|
||||
|
||||
Used For: Debloated version of IBM's ICU4J for reordering Arabic and Hebrew text
|
||||
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
|
||||
* (C) Copyright IBM Corp. 1999-2003 - All Rights Reserved
|
||||
*
|
||||
* The original version of this source code and documentation is
|
||||
* copyrighted and owned by IBM. These materials are provided
|
||||
* under terms of a License Agreement between IBM and Sun.
|
||||
* This technology is protected by multiple US and International
|
||||
* patents. This notice and attribution to IBM may not be removed.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Project Name: Java-WebSocket
|
||||
Project Author: Nathan Rajlich (TooTallNate)
|
||||
Project URL: http://tootallnate.github.io/Java-WebSocket
|
||||
|
|
Binary file not shown.
|
@ -32,7 +32,7 @@ public class EaglerBuildTools {
|
|||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Eaglercraft 1.8 Build Tools");
|
||||
System.out.println("Copyright (c) 2022-2024 lax1dude");
|
||||
System.out.println("Copyright (c) 2022-2025 lax1dude");
|
||||
System.out.println();
|
||||
|
||||
if(!System.getProperty("eaglercraft.isJava11", "false").equalsIgnoreCase("true")) {
|
||||
|
|
|
@ -429,7 +429,7 @@ public class CompileLatestClientFrame {
|
|||
lblNewLabel_1.setFont(new Font("Dialog", Font.BOLD, 14));
|
||||
panel_2.add(lblNewLabel_1, BorderLayout.NORTH);
|
||||
|
||||
JLabel lblNewLabel_2 = new JLabel("Copyright (c) 2022-2024 lax1dude");
|
||||
JLabel lblNewLabel_2 = new JLabel("Copyright (c) 2022-2025 lax1dude");
|
||||
lblNewLabel_2.setVerticalAlignment(SwingConstants.TOP);
|
||||
lblNewLabel_2.setPreferredSize(new Dimension(27, 24));
|
||||
lblNewLabel_2.setFont(new Font("Dialog", Font.PLAIN, 14));
|
||||
|
|
|
@ -56,7 +56,7 @@ public class CompileLatestClientGUI {
|
|||
public static void main(String[] args) {
|
||||
System.out.println();
|
||||
System.out.println("Launching client compiler wizard...");
|
||||
System.out.println("Copyright (c) 2022-2024 lax1dude");
|
||||
System.out.println("Copyright (c) 2022-2025 lax1dude");
|
||||
System.out.println();
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
|
|
|
@ -58,13 +58,6 @@ public class TeaVMBinaries {
|
|||
public static final MavenJAREntry teavmRelocatedLibsASMUtil = new MavenJAREntry("org/teavm/teavm-relocated-libs-asm-util/0.9.2/teavm-relocated-libs-asm-util-0.9.2.jar");
|
||||
public static final MavenJAREntry teavmRelocatedLibsHPPC = new MavenJAREntry("org/teavm/teavm-relocated-libs-hppc/0.9.2/teavm-relocated-libs-hppc-0.9.2.jar");
|
||||
public static final MavenJAREntry teavmRelocatedLibsRhino = new MavenJAREntry("org/teavm/teavm-relocated-libs-rhino/0.9.2/teavm-relocated-libs-rhino-0.9.2.jar");
|
||||
public static final MavenJAREntry asm = new MavenJAREntry("org/ow2/asm/asm/9.5/asm-9.5.jar");
|
||||
public static final MavenJAREntry asmAnalysis = new MavenJAREntry("org/ow2/asm/asm-analysis/9.5/asm-analysis-9.5.jar");
|
||||
public static final MavenJAREntry asmCommons = new MavenJAREntry("org/ow2/asm/asm-commons/9.5/asm-commons-9.5.jar");
|
||||
public static final MavenJAREntry asmTree = new MavenJAREntry("org/ow2/asm/asm-tree/9.5/asm-tree-9.5.jar");
|
||||
public static final MavenJAREntry asmUtil = new MavenJAREntry("org/ow2/asm/asm-util/9.5/asm-util-9.5.jar");
|
||||
public static final MavenJAREntry hppc = new MavenJAREntry("com/carrotsearch/hppc/0.9.1/hppc-0.9.1.jar");
|
||||
public static final MavenJAREntry rhino = new MavenJAREntry("org/mozilla/rhino/1.7.14/rhino-1.7.14.jar");
|
||||
public static final MavenJAREntry teavmMetaprogrammingAPI = new MavenJAREntry("org/teavm/teavm-metaprogramming-api/0.9.2/teavm-metaprogramming-api-0.9.2.jar");
|
||||
public static final MavenJAREntry teavmMetaprogrammingImpl = new MavenJAREntry("org/teavm/teavm-metaprogramming-impl/0.9.2/teavm-metaprogramming-impl-0.9.2.jar");
|
||||
public static final MavenJAREntry teavmJodaTime = new MavenJAREntry("joda-time/joda-time/2.12.2/joda-time-2.12.2.jar");
|
||||
|
@ -73,10 +66,8 @@ public class TeaVMBinaries {
|
|||
private static final MavenJAREntry[] jarsList = new MavenJAREntry[] { teavmCore, teavmCli, teavmTooling,
|
||||
teavmPlatform, teavmClasslib, teavmInterop, teavmJSO, teavmJSOApis, teavmJSOImpl, teavmRelocatedLibsASM,
|
||||
teavmRelocatedLibsASMAnalysis, teavmRelocatedLibsASMCommons, teavmRelocatedLibsASMTree,
|
||||
teavmRelocatedLibsASMUtil, teavmRelocatedLibsHPPC, teavmRelocatedLibsRhino, asm, asmAnalysis, asmCommons,
|
||||
asmTree, asmUtil, hppc, rhino, teavmMetaprogrammingAPI, teavmMetaprogrammingImpl, teavmJodaTime,
|
||||
teavmJZLIB
|
||||
};
|
||||
teavmRelocatedLibsASMUtil, teavmRelocatedLibsHPPC, teavmRelocatedLibsRhino, teavmMetaprogrammingAPI,
|
||||
teavmMetaprogrammingImpl, teavmJodaTime, teavmJZLIB };
|
||||
|
||||
public static File teavmBridge = null;
|
||||
|
||||
|
@ -205,8 +196,7 @@ public class TeaVMBinaries {
|
|||
return new File[] { teavmCore.file, teavmCli.file, teavmTooling.file, teavmInterop.file,
|
||||
teavmRelocatedLibsASM.file, teavmRelocatedLibsASMAnalysis.file, teavmRelocatedLibsASMCommons.file,
|
||||
teavmRelocatedLibsASMTree.file, teavmRelocatedLibsASMUtil.file, teavmRelocatedLibsHPPC.file,
|
||||
teavmRelocatedLibsRhino.file, asm.file, asmAnalysis.file, asmCommons.file, asmTree.file, asmUtil.file,
|
||||
hppc.file, rhino.file, teavmMetaprogrammingAPI.file, teavmBridge };
|
||||
teavmRelocatedLibsRhino.file, teavmMetaprogrammingAPI.file, teavmBridge };
|
||||
}
|
||||
|
||||
public static String[] getTeaVMRuntimeClasspath() {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
Copyright (c) 2022-2024 lax1dude, ayunami2000. All Rights Reserved.
|
||||
Copyright (c) 2022-2025 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.
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2022-2024 lax1dude, ayunami2000.
|
||||
Copyright (c) 2022-2025 lax1dude, ayunami2000.
|
||||
All Rights Reserved.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
|
|
|
@ -1 +1 @@
|
|||
u46
|
||||
u47
|
Binary file not shown.
|
@ -64,8 +64,11 @@ import net.md_5.bungee.BungeeCord;
|
|||
*/
|
||||
public class EaglerXBungee extends Plugin {
|
||||
|
||||
public static final String NATIVE_BUNGEECORD_BUILD = "1.21-R0.1-SNAPSHOT:20a71b0:1887";
|
||||
public static final String NATIVE_WATERFALL_BUILD = "1.21-R0.1-SNAPSHOT:bf1be7e:581";
|
||||
public static final String NATIVE_BUNGEECORD_BUILD = "1.21-R0.1-SNAPSHOT:1265a99:1892";
|
||||
public static final String NATIVE_BUNGEECORD_BUILD_DL = "https://ci.md-5.net/job/BungeeCord/1892/artifact/bootstrap/target/BungeeCord.jar";
|
||||
|
||||
public static final String NATIVE_WATERFALL_BUILD = "1.21-R0.1-SNAPSHOT:9ab9e2b:582";
|
||||
public static final String NATIVE_WATERFALL_BUILD_DL = "https://api.papermc.io/v2/projects/waterfall/versions/1.21/builds/582/downloads/waterfall-1.21-582.jar";
|
||||
|
||||
static {
|
||||
CompatWarning.displayCompatWarning();
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.api.EaglerXBungeeAPIHelper;
|
||||
|
||||
|
@ -44,6 +46,7 @@ public class AuthLoadingCache<K, V> {
|
|||
boolean shouldEvict(K key, V value);
|
||||
}
|
||||
|
||||
private final ReadWriteLock cacheMapLock;
|
||||
private final Map<K, CacheEntry<V>> cacheMap;
|
||||
private final CacheLoader<K, V> provider;
|
||||
private final long cacheTTL;
|
||||
|
@ -51,6 +54,7 @@ public class AuthLoadingCache<K, V> {
|
|||
private long cacheTimer;
|
||||
|
||||
public AuthLoadingCache(CacheLoader<K, V> provider, long cacheTTL) {
|
||||
this.cacheMapLock = new ReentrantReadWriteLock();
|
||||
this.cacheMap = new HashMap<>();
|
||||
this.provider = provider;
|
||||
this.cacheTTL = cacheTTL;
|
||||
|
@ -58,13 +62,19 @@ public class AuthLoadingCache<K, V> {
|
|||
|
||||
public V get(K key) {
|
||||
CacheEntry<V> etr;
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.readLock().lock();
|
||||
try {
|
||||
etr = cacheMap.get(key);
|
||||
}finally {
|
||||
cacheMapLock.readLock().unlock();
|
||||
}
|
||||
if(etr == null) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
V loaded = provider.load(key);
|
||||
synchronized(cacheMap) {
|
||||
try {
|
||||
cacheMap.put(key, new CacheEntry<>(loaded));
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
return loaded;
|
||||
}else {
|
||||
|
@ -74,13 +84,17 @@ public class AuthLoadingCache<K, V> {
|
|||
}
|
||||
|
||||
public void evict(K key) {
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
cacheMap.remove(key);
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void evictAll(CacheVisitor<K, V> visitor) {
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
Iterator<Entry<K,CacheEntry<V>>> itr = cacheMap.entrySet().iterator();
|
||||
while(itr.hasNext()) {
|
||||
Entry<K,CacheEntry<V>> etr = itr.next();
|
||||
|
@ -88,6 +102,8 @@ public class AuthLoadingCache<K, V> {
|
|||
itr.remove();
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +111,8 @@ public class AuthLoadingCache<K, V> {
|
|||
long millis = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
if(millis - cacheTimer > (cacheTTL / 2L)) {
|
||||
cacheTimer = millis;
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
Iterator<CacheEntry<V>> mapItr = cacheMap.values().iterator();
|
||||
while(mapItr.hasNext()) {
|
||||
CacheEntry<V> etr = mapItr.next();
|
||||
|
@ -103,13 +120,18 @@ public class AuthLoadingCache<K, V> {
|
|||
mapItr.remove();
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
cacheMap.clear();
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.server.protocol;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
@ -238,10 +239,12 @@ public class GameProtocolMessageController {
|
|||
while(!sendQueueV4.isEmpty()) {
|
||||
sendCount = 0;
|
||||
totalLen = 0;
|
||||
Iterator<byte[]> itr = sendQueueV4.iterator();
|
||||
do {
|
||||
i = sendQueueV4.get(sendCount++).length;
|
||||
i = itr.next().length;
|
||||
totalLen += GamePacketOutputBuffer.getVarIntSize(i) + i;
|
||||
}while(totalLen < 32760 && sendCount < sendQueueV4.size());
|
||||
++sendCount;
|
||||
}while(totalLen < 32760 && itr.hasNext());
|
||||
if(totalLen >= 32760) {
|
||||
--sendCount;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ public class HttpWebServer {
|
|||
private final String page404;
|
||||
private static HttpMemoryCache default404Page;
|
||||
private static HttpMemoryCache default404UpgradePage;
|
||||
private static final Object cacheClearLock = new Object();
|
||||
|
||||
public HttpWebServer(File directory, Map<String,HttpContentType> contentTypes, List<String> index, String page404) {
|
||||
this.directory = directory;
|
||||
|
@ -52,15 +51,13 @@ public class HttpWebServer {
|
|||
|
||||
public void flushCache() {
|
||||
long millis = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
synchronized(cacheClearLock) {
|
||||
synchronized(filesCache) {
|
||||
Iterator<HttpMemoryCache> itr = filesCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
HttpMemoryCache i = itr.next();
|
||||
if(i.contentType.fileBrowserCacheTTL != Long.MAX_VALUE && millis - i.lastCacheHit > 900000l) {
|
||||
i.fileData.release();
|
||||
itr.remove();
|
||||
}
|
||||
synchronized(filesCache) {
|
||||
Iterator<HttpMemoryCache> itr = filesCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
HttpMemoryCache i = itr.next();
|
||||
if(i.contentType.fileBrowserCacheTTL != Long.MAX_VALUE && millis - i.lastCacheHit > 900000l) {
|
||||
i.fileData.release();
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,19 +91,16 @@ public class HttpWebServer {
|
|||
|
||||
String joinedPath = String.join("/", pathList);
|
||||
|
||||
synchronized(cacheClearLock) {
|
||||
synchronized(filesCache) {
|
||||
cached = filesCache.get(joinedPath);
|
||||
}
|
||||
//TODO: Rewrite this to cause less lock contention
|
||||
synchronized(filesCache) {
|
||||
cached = filesCache.get(joinedPath);
|
||||
|
||||
if(cached != null) {
|
||||
cached = validateCache(cached);
|
||||
if(cached != null) {
|
||||
return cached;
|
||||
}else {
|
||||
synchronized(filesCache) {
|
||||
filesCache.remove(joinedPath);
|
||||
}
|
||||
filesCache.remove(joinedPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,19 +117,13 @@ public class HttpWebServer {
|
|||
if(f.isDirectory()) {
|
||||
for(int i = 0, l = index.size(); i < l; ++i) {
|
||||
String p = joinedPath + "/" + index.get(i);
|
||||
synchronized(filesCache) {
|
||||
cached = filesCache.get(p);
|
||||
}
|
||||
cached = filesCache.get(p);
|
||||
if(cached != null) {
|
||||
cached = validateCache(cached);
|
||||
if(cached != null) {
|
||||
synchronized(filesCache) {
|
||||
filesCache.put(joinedPath, cached);
|
||||
}
|
||||
filesCache.put(joinedPath, cached);
|
||||
}else {
|
||||
synchronized(filesCache) {
|
||||
filesCache.remove(p);
|
||||
}
|
||||
filesCache.remove(p);
|
||||
if(page404 == null || path.equals(page404)) {
|
||||
return default404Page;
|
||||
}else {
|
||||
|
@ -151,9 +139,7 @@ public class HttpWebServer {
|
|||
if(ff.isFile()) {
|
||||
HttpMemoryCache memCache = retrieveFile(ff, p);
|
||||
if(memCache != null) {
|
||||
synchronized(filesCache) {
|
||||
filesCache.put(joinedPath, memCache);
|
||||
}
|
||||
filesCache.put(joinedPath, memCache);
|
||||
return memCache;
|
||||
}
|
||||
}
|
||||
|
@ -166,9 +152,7 @@ public class HttpWebServer {
|
|||
}else {
|
||||
HttpMemoryCache memCache = retrieveFile(f, joinedPath);
|
||||
if(memCache != null) {
|
||||
synchronized(filesCache) {
|
||||
filesCache.put(joinedPath, memCache);
|
||||
}
|
||||
filesCache.put(joinedPath, memCache);
|
||||
return memCache;
|
||||
}else {
|
||||
if(page404 == null || path.equals(page404)) {
|
||||
|
|
|
@ -37,7 +37,10 @@ public class CompatWarning {
|
|||
":> apart from the versions listed below:",
|
||||
":> ",
|
||||
":> - BungeeCord: " + EaglerXBungee.NATIVE_BUNGEECORD_BUILD,
|
||||
":> - " + EaglerXBungee.NATIVE_BUNGEECORD_BUILD_DL,
|
||||
":> ",
|
||||
":> - Waterfall: " + EaglerXBungee.NATIVE_WATERFALL_BUILD,
|
||||
":> - " + EaglerXBungee.NATIVE_WATERFALL_BUILD_DL,
|
||||
":> ",
|
||||
":> This is not a Bukkit/Spigot plugin!",
|
||||
":> ",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.skins;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.server.EaglerInitialHandler;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.GameMessagePacket;
|
||||
|
@ -13,7 +13,7 @@ import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketOtherCape
|
|||
import net.md_5.bungee.UserConnection;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2024-2025 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
|
||||
|
@ -31,21 +31,16 @@ public class CapeServiceOffline {
|
|||
|
||||
public static final int masterRateLimitPerPlayer = 250;
|
||||
|
||||
private final Map<UUID, GameMessagePacket> capesCache = new HashMap<>();
|
||||
private final ConcurrentMap<UUID, GameMessagePacket> capesCache = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerEaglercraftPlayer(UUID playerUUID, GameMessagePacket capePacket) {
|
||||
synchronized(capesCache) {
|
||||
capesCache.put(playerUUID, capePacket);
|
||||
}
|
||||
capesCache.put(playerUUID, capePacket);
|
||||
}
|
||||
|
||||
public void processGetOtherCape(UUID searchUUID, UserConnection sender) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler)sender.getPendingConnection();
|
||||
if(initialHandler.skinLookupRateLimiter.rateLimit(masterRateLimitPerPlayer)) {
|
||||
GameMessagePacket maybeCape;
|
||||
synchronized(capesCache) {
|
||||
maybeCape = capesCache.get(searchUUID);
|
||||
}
|
||||
GameMessagePacket maybeCape = capesCache.get(searchUUID);
|
||||
if(maybeCape != null) {
|
||||
initialHandler.sendEaglerMessage(maybeCape);
|
||||
}else {
|
||||
|
@ -56,10 +51,7 @@ public class CapeServiceOffline {
|
|||
}
|
||||
|
||||
public void processForceCape(UUID clientUUID, EaglerInitialHandler initialHandler) {
|
||||
GameMessagePacket maybeCape;
|
||||
synchronized(capesCache) {
|
||||
maybeCape = capesCache.get(clientUUID);
|
||||
}
|
||||
GameMessagePacket maybeCape = capesCache.get(clientUUID);
|
||||
if(maybeCape != null) {
|
||||
if (maybeCape instanceof SPacketOtherCapePresetEAG) {
|
||||
initialHandler.sendEaglerMessage(
|
||||
|
@ -72,15 +64,11 @@ public class CapeServiceOffline {
|
|||
}
|
||||
|
||||
public void unregisterPlayer(UUID playerUUID) {
|
||||
synchronized(capesCache) {
|
||||
capesCache.remove(playerUUID);
|
||||
}
|
||||
capesCache.remove(playerUUID);
|
||||
}
|
||||
|
||||
public GameMessagePacket getCape(UUID clientUUID) {
|
||||
synchronized(capesCache) {
|
||||
return capesCache.get(clientUUID);
|
||||
}
|
||||
return capesCache.get(clientUUID);
|
||||
}
|
||||
|
||||
public byte[] getCapeHandshakeData(UUID clientUUID) {
|
||||
|
@ -109,8 +97,6 @@ public class CapeServiceOffline {
|
|||
}
|
||||
|
||||
public void shutdown() {
|
||||
synchronized(capesCache) {
|
||||
capesCache.clear();
|
||||
}
|
||||
capesCache.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.skins;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -10,6 +11,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Consumer;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
|
@ -38,7 +43,7 @@ import net.md_5.bungee.connection.LoginResult;
|
|||
import net.md_5.bungee.protocol.Property;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2025 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
|
||||
|
@ -56,16 +61,20 @@ public class SkinService implements ISkinService {
|
|||
|
||||
public static final int masterRateLimitPerPlayer = 250;
|
||||
|
||||
private final Map<UUID, CachedPlayerSkin> onlinePlayersCache = new HashMap<>();
|
||||
private final ConcurrentMap<UUID, CachedPlayerSkin> onlinePlayersCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<UUID, UUID> onlinePlayersToTexturesMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<UUID, CachedForeignSkin> foreignSkinCache = new ConcurrentHashMap<>();
|
||||
|
||||
private final ReadWriteLock onlinePlayersFromTexturesMapLock = new ReentrantReadWriteLock();
|
||||
private final Multimap<UUID, UUID> onlinePlayersFromTexturesMap = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
private final Map<UUID, UUID> onlinePlayersToTexturesMap = new HashMap<>();
|
||||
private final Map<UUID, CachedForeignSkin> foreignSkinCache = new HashMap<>();
|
||||
|
||||
private final Map<UUID, PendingTextureDownload> pendingTextures = new HashMap<>();
|
||||
private final Map<UUID, PendingProfileUUIDLookup> pendingUUIDs = new HashMap<>();
|
||||
private final Map<String, PendingProfileNameLookup> pendingNameLookups = new HashMap<>();
|
||||
|
||||
private final ReadWriteLock antagonistsLock = new ReentrantReadWriteLock();
|
||||
private final TObjectIntMap<UUID> antagonists = new TObjectIntHashMap<>();
|
||||
|
||||
private long antagonistCooldown = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
|
||||
private final Consumer<Set<UUID>> antagonistLogger = new Consumer<Set<UUID>>() {
|
||||
|
@ -75,7 +84,8 @@ public class SkinService implements ISkinService {
|
|||
if(t.size() == 1) {
|
||||
int limit = EaglerXBungee.getEagler().getConfig().getAntagonistsRateLimit() << 1;
|
||||
UUID offender = t.iterator().next();
|
||||
synchronized(antagonists) {
|
||||
antagonistsLock.writeLock().lock();
|
||||
try {
|
||||
int v = antagonists.get(offender);
|
||||
if(v == antagonists.getNoEntryValue()) {
|
||||
antagonists.put(offender, 1);
|
||||
|
@ -84,6 +94,8 @@ public class SkinService implements ISkinService {
|
|||
antagonists.put(offender, v + 1);
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
antagonistsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +109,7 @@ public class SkinService implements ISkinService {
|
|||
protected final UUID uuid;
|
||||
protected final SkinPacketVersionCache data;
|
||||
protected final int modelKnown;
|
||||
protected long lastHit;
|
||||
protected volatile long lastHit;
|
||||
|
||||
protected CachedForeignSkin(UUID uuid, SkinPacketVersionCache data, int modelKnown) {
|
||||
this.uuid = uuid;
|
||||
|
@ -132,7 +144,7 @@ public class SkinService implements ISkinService {
|
|||
protected final Consumer<Set<UUID>> antagonistsCallback;
|
||||
|
||||
protected final long initializedTime;
|
||||
protected boolean finalized;
|
||||
protected volatile boolean finalized;
|
||||
|
||||
protected PendingTextureDownload(UUID textureUUID, String textureURL, UUID caller, Consumer<byte[]> callback,
|
||||
Consumer<Set<UUID>> antagonistsCallback) {
|
||||
|
@ -174,7 +186,7 @@ public class SkinService implements ISkinService {
|
|||
protected final Consumer<Set<UUID>> antagonistsCallback;
|
||||
|
||||
protected final long initializedTime;
|
||||
protected boolean finalized;
|
||||
protected volatile boolean finalized;
|
||||
|
||||
protected PendingProfileUUIDLookup(UUID profileUUID, UUID caller, Consumer<CacheFetchedProfile> callback,
|
||||
Consumer<Set<UUID>> antagonistsCallback) {
|
||||
|
@ -215,7 +227,7 @@ public class SkinService implements ISkinService {
|
|||
protected final Consumer<Set<UUID>> antagonistsCallback;
|
||||
|
||||
protected final long initializedTime;
|
||||
protected boolean finalized;
|
||||
protected volatile boolean finalized;
|
||||
|
||||
protected PendingProfileNameLookup(String profileName, UUID caller, Consumer<CacheFetchedProfile> callback,
|
||||
Consumer<Set<UUID>> antagonistsCallback) {
|
||||
|
@ -263,60 +275,46 @@ public class SkinService implements ISkinService {
|
|||
return;
|
||||
}
|
||||
|
||||
CachedPlayerSkin maybeCachedPacket;
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(searchUUID);
|
||||
}
|
||||
CachedPlayerSkin maybeCachedPacket = onlinePlayersCache.get(searchUUID);
|
||||
|
||||
if(maybeCachedPacket != null) {
|
||||
eaglerHandler.sendEaglerMessage(maybeCachedPacket.data.get(eaglerHandler.getEaglerProtocol()));
|
||||
}else {
|
||||
ProxiedPlayer player = BungeeCord.getInstance().getPlayer(searchUUID);
|
||||
UUID playerTexture;
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
playerTexture = onlinePlayersToTexturesMap.get(searchUUID);
|
||||
}
|
||||
UUID playerTexture = onlinePlayersToTexturesMap.get(searchUUID);
|
||||
if(playerTexture != null) {
|
||||
Collection<UUID> possiblePlayers;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
possiblePlayers = onlinePlayersFromTexturesMap.get(playerTexture);
|
||||
onlinePlayersFromTexturesMapLock.readLock().lock();
|
||||
try {
|
||||
possiblePlayers = new ArrayList<>(onlinePlayersFromTexturesMap.get(playerTexture));
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.readLock().unlock();
|
||||
}
|
||||
boolean playersExist = possiblePlayers.size() > 0;
|
||||
if(playersExist) {
|
||||
for(UUID uuid : possiblePlayers) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
}
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
if(maybeCachedPacket != null) {
|
||||
SkinPacketVersionCache rewritten = SkinPacketVersionCache.rewriteUUID(
|
||||
maybeCachedPacket.data, searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits());
|
||||
if(player != null) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
}
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
}
|
||||
eaglerHandler.sendEaglerMessage(rewritten.get(eaglerHandler.getEaglerProtocol()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
if(foreignSkin != null && foreignSkin.modelKnown != -1) {
|
||||
if(player != null) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(searchUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
}
|
||||
onlinePlayersCache.put(searchUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
}else {
|
||||
foreignSkin.lastHit = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
}
|
||||
|
@ -339,7 +337,7 @@ public class SkinService implements ISkinService {
|
|||
if(skinObj != null) {
|
||||
JsonElement url = json.get("url");
|
||||
if(url != null) {
|
||||
String urlStr = SkinService.sanitizeTextureURL(url.getAsString());
|
||||
String urlStr = sanitizeTextureURL(url.getAsString());
|
||||
if(urlStr == null) {
|
||||
break;
|
||||
}
|
||||
|
@ -353,19 +351,14 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
UUID skinUUID = SkinPackets.createEaglerURLSkinUUID(urlStr);
|
||||
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
if(foreignSkin != null) {
|
||||
registerTextureToPlayerAssociation(skinUUID, searchUUID);
|
||||
SkinPacketVersionCache rewrite = SkinPacketVersionCache
|
||||
.rewriteUUIDModel(foreignSkin.data,
|
||||
searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits(), model);
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
}
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
eaglerHandler.sendEaglerMessage(rewrite.get(eaglerHandler.getEaglerProtocol()));
|
||||
return;
|
||||
}
|
||||
|
@ -398,10 +391,7 @@ public class SkinService implements ISkinService {
|
|||
});
|
||||
}
|
||||
}else {
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
if(foreignSkin != null) {
|
||||
foreignSkin.lastHit = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
eaglerHandler.sendEaglerMessage(foreignSkin.data.get(eaglerHandler.getEaglerProtocol()));
|
||||
|
@ -430,25 +420,22 @@ public class SkinService implements ISkinService {
|
|||
if(!eaglerHandler.skinLookupRateLimiter.rateLimit(masterRateLimitPerPlayer)) {
|
||||
return;
|
||||
}
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
if(foreignSkin != null) {
|
||||
foreignSkin.lastHit = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
eaglerHandler.sendEaglerMessage(foreignSkin.data.get(eaglerHandler.getEaglerProtocol()));
|
||||
}else {
|
||||
Collection<UUID> possiblePlayers;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
possiblePlayers = onlinePlayersFromTexturesMap.get(searchUUID);
|
||||
onlinePlayersFromTexturesMapLock.readLock().lock();
|
||||
try {
|
||||
possiblePlayers = new ArrayList<>(onlinePlayersFromTexturesMap.get(searchUUID));
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.readLock().unlock();
|
||||
}
|
||||
boolean playersExist = possiblePlayers.size() > 0;
|
||||
if(playersExist) {
|
||||
for(UUID uuid : possiblePlayers) {
|
||||
CachedPlayerSkin maybeCachedPacket;
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
}
|
||||
CachedPlayerSkin maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
if(maybeCachedPacket != null) {
|
||||
eaglerHandler.sendEaglerMessage(maybeCachedPacket.data.get(eaglerHandler.getEaglerProtocol(),
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()));
|
||||
|
@ -461,10 +448,17 @@ public class SkinService implements ISkinService {
|
|||
searchUUID.getLeastSignificantBits(), 0));
|
||||
return;
|
||||
}
|
||||
if(eaglerHandler.skinTextureDownloadRateLimiter.rateLimit(config.getSkinRateLimitPlayer()) && !isLimitedAsAntagonist(sender.getUniqueId())) {
|
||||
doAsync(() -> {
|
||||
processResolveURLTextureForForeign(sender, searchUUID, searchUUID, skinURL, -1);
|
||||
});
|
||||
skinURL = sanitizeTextureURL(skinURL);
|
||||
if(skinURL != null) {
|
||||
final String skinURL_ = skinURL;
|
||||
if(eaglerHandler.skinTextureDownloadRateLimiter.rateLimit(config.getSkinRateLimitPlayer()) && !isLimitedAsAntagonist(sender.getUniqueId())) {
|
||||
doAsync(() -> {
|
||||
processResolveURLTextureForForeign(sender, searchUUID, searchUUID, skinURL_, -1);
|
||||
});
|
||||
}
|
||||
}else {
|
||||
eaglerHandler.sendEaglerMessage(new SPacketOtherSkinPresetEAG(searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -479,10 +473,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
if(skin != null) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler)initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
|
@ -510,9 +501,7 @@ public class SkinService implements ISkinService {
|
|||
onlineCacheUUID.getMostSignificantBits(),
|
||||
onlineCacheUUID.getLeastSignificantBits()), null, -1);
|
||||
}
|
||||
synchronized (onlinePlayersCache) {
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -538,10 +527,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
if(skin != null) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
|
@ -570,9 +556,7 @@ public class SkinService implements ISkinService {
|
|||
foreignCacheUUID.getLeastSignificantBits()),
|
||||
-1);
|
||||
}
|
||||
synchronized (foreignSkinCache) {
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -598,10 +582,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
|
@ -634,9 +615,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
}else {
|
||||
|
@ -666,10 +645,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(t.uuid);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(t.uuid);
|
||||
if(skin != null) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
|
@ -700,9 +676,7 @@ public class SkinService implements ISkinService {
|
|||
mapUUID.getMostSignificantBits(), mapUUID.getLeastSignificantBits(),
|
||||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0), null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
}else {
|
||||
|
@ -732,10 +706,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(playerUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
|
@ -768,9 +739,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
-1);
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler) initiator.getPendingConnection();
|
||||
initialHandler.sendEaglerMessage(skin.data.get(initialHandler.getEaglerProtocol()));
|
||||
}else {
|
||||
|
@ -791,27 +760,16 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
|
||||
public void registerEaglercraftPlayer(UUID clientUUID, SkinPacketVersionCache generatedPacket, int modelId) {
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.remove(clientUUID);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(clientUUID, new CachedPlayerSkin(generatedPacket, null, modelId));
|
||||
}
|
||||
foreignSkinCache.remove(clientUUID);
|
||||
onlinePlayersCache.put(clientUUID, new CachedPlayerSkin(generatedPacket, null, modelId));
|
||||
}
|
||||
|
||||
public void unregisterPlayer(UUID clientUUID) {
|
||||
CachedPlayerSkin data;
|
||||
synchronized(onlinePlayersCache) {
|
||||
data = onlinePlayersCache.remove(clientUUID);
|
||||
}
|
||||
CachedPlayerSkin data = onlinePlayersCache.remove(clientUUID);
|
||||
if(data != null) {
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(clientUUID, new CachedForeignSkin(clientUUID, data.data, data.modelId));
|
||||
}
|
||||
foreignSkinCache.put(clientUUID, new CachedForeignSkin(clientUUID, data.data, data.modelId));
|
||||
if(data.textureUUID != null) {
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(data.textureUUID, new CachedForeignSkin(data.textureUUID, data.data, data.modelId));
|
||||
}
|
||||
foreignSkinCache.put(data.textureUUID, new CachedForeignSkin(data.textureUUID, data.data, data.modelId));
|
||||
}
|
||||
deletePlayerTextureAssociation(clientUUID, data.textureUUID);
|
||||
}else {
|
||||
|
@ -821,94 +779,77 @@ public class SkinService implements ISkinService {
|
|||
|
||||
private void deletePlayerTextureAssociation(UUID clientUUID, UUID textureUUID) {
|
||||
if(textureUUID != null) {
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
}
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.remove(textureUUID, clientUUID);
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
}else {
|
||||
UUID removedUUID;
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
removedUUID = onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
}
|
||||
UUID removedUUID = onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
if(removedUUID != null) {
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.remove(removedUUID, clientUUID);
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTextureToPlayerAssociation(UUID textureUUID, UUID playerUUID) {
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.put(textureUUID, playerUUID);
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
onlinePlayersToTexturesMap.put(playerUUID, textureUUID);
|
||||
}
|
||||
CachedForeignSkin foreign;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreign = foreignSkinCache.remove(textureUUID);
|
||||
}
|
||||
onlinePlayersToTexturesMap.put(playerUUID, textureUUID);
|
||||
CachedForeignSkin foreign = foreignSkinCache.remove(textureUUID);
|
||||
if(foreign != null) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(foreign.data, textureUUID, foreign.modelKnown));
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(foreign.data, textureUUID, foreign.modelKnown));
|
||||
}
|
||||
}
|
||||
|
||||
public void processForceSkin(UUID playerUUID, EaglerInitialHandler eaglerHandler) {
|
||||
CachedPlayerSkin maybeCachedPacket;
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin maybeCachedPacket = onlinePlayersCache.get(playerUUID);
|
||||
|
||||
if(maybeCachedPacket != null) {
|
||||
eaglerHandler.sendEaglerMessage(maybeCachedPacket.data.getForceClientV4());
|
||||
}else {
|
||||
UUID playerTexture;
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
playerTexture = onlinePlayersToTexturesMap.get(playerUUID);
|
||||
}
|
||||
UUID playerTexture = onlinePlayersToTexturesMap.get(playerUUID);
|
||||
if(playerTexture != null) {
|
||||
Collection<UUID> possiblePlayers;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
possiblePlayers = onlinePlayersFromTexturesMap.get(playerTexture);
|
||||
onlinePlayersFromTexturesMapLock.readLock().lock();
|
||||
try {
|
||||
possiblePlayers = new ArrayList<>(onlinePlayersFromTexturesMap.get(playerTexture));
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.readLock().unlock();
|
||||
}
|
||||
boolean playersExist = possiblePlayers.size() > 0;
|
||||
if(playersExist) {
|
||||
for(UUID uuid : possiblePlayers) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
}
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
if(maybeCachedPacket != null) {
|
||||
SkinPacketVersionCache rewritten = SkinPacketVersionCache.rewriteUUID(
|
||||
maybeCachedPacket.data, playerUUID.getMostSignificantBits(),
|
||||
playerUUID.getLeastSignificantBits());
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
eaglerHandler.sendEaglerMessage(rewritten.getForceClientV4());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
if(foreignSkin != null && foreignSkin.modelKnown != -1) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
playerUUID.getMostSignificantBits(), playerUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
playerUUID.getMostSignificantBits(), playerUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
eaglerHandler.sendEaglerMessage(foreignSkin.data.getForceClientV4());
|
||||
return;
|
||||
}
|
||||
|
@ -927,7 +868,7 @@ public class SkinService implements ISkinService {
|
|||
if(skinObj != null) {
|
||||
JsonElement url = json.get("url");
|
||||
if(url != null) {
|
||||
String urlStr = SkinService.sanitizeTextureURL(url.getAsString());
|
||||
String urlStr = sanitizeTextureURL(url.getAsString());
|
||||
if(urlStr == null) {
|
||||
break;
|
||||
}
|
||||
|
@ -941,19 +882,14 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
UUID skinUUID = SkinPackets.createEaglerURLSkinUUID(urlStr);
|
||||
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
if(foreignSkin != null) {
|
||||
registerTextureToPlayerAssociation(skinUUID, playerUUID);
|
||||
SkinPacketVersionCache rewrite = SkinPacketVersionCache
|
||||
.rewriteUUIDModel(foreignSkin.data,
|
||||
playerUUID.getMostSignificantBits(),
|
||||
playerUUID.getLeastSignificantBits(), model);
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
eaglerHandler.sendEaglerMessage(rewrite.getForceClientV4());
|
||||
return;
|
||||
}
|
||||
|
@ -981,10 +917,7 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
});
|
||||
}else {
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(playerUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(playerUUID);
|
||||
if(foreignSkin != null) {
|
||||
foreignSkin.lastHit = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
eaglerHandler.sendEaglerMessage(foreignSkin.data.getForceClientV4());
|
||||
|
@ -1011,10 +944,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1041,9 +971,7 @@ public class SkinService implements ISkinService {
|
|||
onlineCacheUUID.getMostSignificantBits(),
|
||||
onlineCacheUUID.getLeastSignificantBits()), null, -1);
|
||||
}
|
||||
synchronized (onlinePlayersCache) {
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
||||
|
@ -1068,10 +996,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1099,9 +1024,7 @@ public class SkinService implements ISkinService {
|
|||
foreignCacheUUID.getLeastSignificantBits()),
|
||||
-1);
|
||||
}
|
||||
synchronized (foreignSkinCache) {
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
||||
|
@ -1126,10 +1049,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1161,9 +1081,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}else {
|
||||
processResolveURLTextureForOnlineToForce(initiator, playerUUID, t.textureUUID, t.texture,
|
||||
|
@ -1192,10 +1110,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(t.uuid);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(t.uuid);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1225,9 +1140,7 @@ public class SkinService implements ISkinService {
|
|||
mapUUID.getMostSignificantBits(), mapUUID.getLeastSignificantBits(),
|
||||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0), null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}else {
|
||||
processResolveURLTextureForOnlineToForce(initiator, mapUUID, t.textureUUID, t.texture,
|
||||
|
@ -1256,10 +1169,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(playerUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1291,9 +1201,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
-1);
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}else {
|
||||
processResolveURLTextureForForeignToForce(initiator, playerUUID, t.textureUUID, t.texture,
|
||||
|
@ -1315,12 +1223,16 @@ public class SkinService implements ISkinService {
|
|||
public void flush() {
|
||||
long millis = EaglerXBungeeAPIHelper.steadyTimeMillis();
|
||||
|
||||
synchronized(foreignSkinCache) {
|
||||
Iterator<CachedForeignSkin> itr = foreignSkinCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
if(millis - itr.next().lastHit > 900000l) { // 15 minutes
|
||||
itr.remove();
|
||||
}
|
||||
final List<UUID> foreignSkinCleanup = new ArrayList<>(4);
|
||||
foreignSkinCache.entrySet().forEach((etr) -> {
|
||||
if(millis - etr.getValue().lastHit > 900000l) { // 15 minutes
|
||||
foreignSkinCleanup.add(etr.getKey());
|
||||
}
|
||||
});
|
||||
|
||||
if(!foreignSkinCleanup.isEmpty()) {
|
||||
for(UUID uuid : foreignSkinCleanup) {
|
||||
foreignSkinCache.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1371,7 +1283,8 @@ public class SkinService implements ISkinService {
|
|||
elapsedCooldown /= cooldownPeriod;
|
||||
if(elapsedCooldown > 0) {
|
||||
antagonistCooldown += elapsedCooldown * cooldownPeriod;
|
||||
synchronized(antagonists) {
|
||||
antagonistsLock.writeLock().lock();
|
||||
try {
|
||||
Iterator<UUID> itr = antagonists.keySet().iterator();
|
||||
while(itr.hasNext()) {
|
||||
UUID key = itr.next();
|
||||
|
@ -1382,6 +1295,8 @@ public class SkinService implements ISkinService {
|
|||
antagonists.put(key, i);
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
antagonistsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1389,10 +1304,7 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
|
||||
public SkinPacketVersionCache getSkin(UUID playerUUID) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(playerUUID);
|
||||
return skin != null ? skin.data : null;
|
||||
}
|
||||
|
||||
|
@ -1407,25 +1319,26 @@ public class SkinService implements ISkinService {
|
|||
private boolean isLimitedAsAntagonist(UUID uuid) {
|
||||
int limit = EaglerXBungee.getEagler().getConfig().getAntagonistsRateLimit();
|
||||
limit += limit >> 1;
|
||||
synchronized(antagonists) {
|
||||
int i = antagonists.get(uuid);
|
||||
return i != antagonists.getNoEntryValue() && i > limit;
|
||||
int i;
|
||||
antagonistsLock.readLock().lock();
|
||||
try {
|
||||
i = antagonists.get(uuid);
|
||||
}finally {
|
||||
antagonistsLock.readLock().unlock();
|
||||
}
|
||||
return i != antagonists.getNoEntryValue() && i > limit;
|
||||
}
|
||||
|
||||
private void resetMaps() {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.clear();
|
||||
}
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersCache.clear();
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.clear();
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
onlinePlayersToTexturesMap.clear();
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.clear();
|
||||
}
|
||||
onlinePlayersToTexturesMap.clear();
|
||||
foreignSkinCache.clear();
|
||||
synchronized(pendingTextures) {
|
||||
pendingTextures.clear();
|
||||
}
|
||||
|
@ -1435,8 +1348,11 @@ public class SkinService implements ISkinService {
|
|||
synchronized(pendingNameLookups) {
|
||||
pendingNameLookups.clear();
|
||||
}
|
||||
synchronized(antagonists) {
|
||||
antagonistsLock.writeLock().lock();
|
||||
try {
|
||||
antagonists.clear();
|
||||
}finally {
|
||||
antagonistsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1453,7 +1369,7 @@ public class SkinService implements ISkinService {
|
|||
return null;
|
||||
}
|
||||
String host = uri.getHost();
|
||||
if(host == null) {
|
||||
if(host == null || !EaglerXBungee.getEagler().getConfig().isValidSkinHost(host)) {
|
||||
return null;
|
||||
}
|
||||
scheme = scheme.toLowerCase();
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.skins;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.server.EaglerInitialHandler;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketOtherSkinPresetEAG;
|
||||
|
@ -15,7 +10,7 @@ import net.lax1dude.eaglercraft.v1_8.socket.protocol.util.SkinPacketVersionCache
|
|||
import net.md_5.bungee.UserConnection;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2025 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
|
||||
|
@ -45,24 +40,17 @@ public class SkinServiceOffline implements ISkinService {
|
|||
|
||||
}
|
||||
|
||||
private final Map<UUID, CachedSkin> skinCache = new HashMap<>();
|
||||
|
||||
private final Multimap<UUID, UUID> onlinePlayersFromTexturesMap = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
private final ConcurrentMap<UUID, CachedSkin> skinCache = new ConcurrentHashMap<>();
|
||||
|
||||
public void init(String uri, String driverClass, String driverPath, int keepObjectsDays, int keepProfilesDays,
|
||||
int maxObjects, int maxProfiles) {
|
||||
synchronized(skinCache) {
|
||||
skinCache.clear();
|
||||
}
|
||||
skinCache.clear();
|
||||
}
|
||||
|
||||
public void processGetOtherSkin(UUID searchUUID, UserConnection sender) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler)sender.getPendingConnection();
|
||||
if(initialHandler.skinLookupRateLimiter.rateLimit(masterRateLimitPerPlayer)) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
cached = skinCache.get(searchUUID);
|
||||
}
|
||||
CachedSkin cached = skinCache.get(searchUUID);
|
||||
if(cached != null) {
|
||||
initialHandler.sendEaglerMessage(cached.packet.get(initialHandler.getEaglerProtocol()));
|
||||
}else {
|
||||
|
@ -74,24 +62,6 @@ public class SkinServiceOffline implements ISkinService {
|
|||
|
||||
public void processGetOtherSkin(UUID searchUUID, String skinURL, UserConnection sender) {
|
||||
EaglerInitialHandler initialHandler = (EaglerInitialHandler)sender.getPendingConnection();
|
||||
Collection<UUID> uuids;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
uuids = onlinePlayersFromTexturesMap.get(searchUUID);
|
||||
}
|
||||
if(uuids.size() > 0) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
Iterator<UUID> uuidItr = uuids.iterator();
|
||||
while(uuidItr.hasNext()) {
|
||||
cached = skinCache.get(uuidItr.next());
|
||||
if(cached != null) {
|
||||
initialHandler.sendEaglerMessage(cached.packet.get(initialHandler.getEaglerProtocol(),
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(skinURL.startsWith("eagler://")) { // customs skulls from exported singleplayer worlds
|
||||
initialHandler.sendEaglerMessage(new SPacketOtherSkinPresetEAG(searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits(), 0));
|
||||
|
@ -102,28 +72,21 @@ public class SkinServiceOffline implements ISkinService {
|
|||
}
|
||||
|
||||
public void registerEaglercraftPlayer(UUID clientUUID, SkinPacketVersionCache generatedPacket, int modelId) {
|
||||
synchronized(skinCache) {
|
||||
skinCache.put(clientUUID, new CachedSkin(clientUUID, generatedPacket));
|
||||
}
|
||||
skinCache.put(clientUUID, new CachedSkin(clientUUID, generatedPacket));
|
||||
}
|
||||
|
||||
public void unregisterPlayer(UUID clientUUID) {
|
||||
synchronized(skinCache) {
|
||||
skinCache.remove(clientUUID);
|
||||
}
|
||||
skinCache.remove(clientUUID);
|
||||
}
|
||||
|
||||
public void registerTextureToPlayerAssociation(String textureURL, UUID playerUUID) {
|
||||
}
|
||||
|
||||
public void registerTextureToPlayerAssociation(UUID textureUUID, UUID playerUUID) {
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersFromTexturesMap.put(textureUUID, playerUUID);
|
||||
}
|
||||
}
|
||||
|
||||
public void processForceSkin(UUID playerUUID, EaglerInitialHandler initialHandler) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
cached = skinCache.get(playerUUID);
|
||||
}
|
||||
CachedSkin cached = skinCache.get(playerUUID);
|
||||
if(cached != null) {
|
||||
initialHandler.sendEaglerMessage(cached.packet.getForceClientV4());
|
||||
}
|
||||
|
@ -134,16 +97,11 @@ public class SkinServiceOffline implements ISkinService {
|
|||
}
|
||||
|
||||
public void shutdown() {
|
||||
synchronized(skinCache) {
|
||||
skinCache.clear();
|
||||
}
|
||||
skinCache.clear();
|
||||
}
|
||||
|
||||
public SkinPacketVersionCache getSkin(UUID playerUUID) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
cached = skinCache.get(playerUUID);
|
||||
}
|
||||
CachedSkin cached = skinCache.get(playerUUID);
|
||||
return cached != null ? cached.packet : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: EaglercraftXBungee
|
||||
main: net.lax1dude.eaglercraft.v1_8.plugin.gateway_bungeecord.EaglerXBungee
|
||||
version: 1.3.4
|
||||
version: 1.3.5
|
||||
description: Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks
|
||||
author: lax1dude
|
Binary file not shown.
|
@ -17,13 +17,14 @@ package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity;
|
|||
*/
|
||||
public class EaglerXVelocityVersion {
|
||||
|
||||
public static final String NATIVE_VELOCITY_BUILD = "3.4.0-SNAPSHOT:a33f2d1a:b452";
|
||||
public static final String NATIVE_VELOCITY_BUILD = "3.4.0-SNAPSHOT:71feb11b:b461";
|
||||
public static final String NATIVE_VELOCITY_BUILD_DL = "https://api.papermc.io/v2/projects/velocity/versions/3.4.0-SNAPSHOT/builds/461/downloads/velocity-3.4.0-SNAPSHOT-461.jar";
|
||||
|
||||
public static final String ID = "EaglerXVelocity";
|
||||
public static final String PLUGIN_ID = "eaglerxvelocity";
|
||||
public static final String NAME = "EaglercraftXVelocity";
|
||||
public static final String DESCRIPTION = "Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks";
|
||||
public static final String VERSION = "1.1.5";
|
||||
public static final String VERSION = "1.1.6";
|
||||
public static final String[] AUTHORS = new String[] { "lax1dude", "ayunami2000" };
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.api.EaglerXVelocityAPIHelper;
|
||||
|
||||
|
@ -44,6 +46,7 @@ public class AuthLoadingCache<K, V> {
|
|||
boolean shouldEvict(K key, V value);
|
||||
}
|
||||
|
||||
private final ReadWriteLock cacheMapLock;
|
||||
private final Map<K, CacheEntry<V>> cacheMap;
|
||||
private final CacheLoader<K, V> provider;
|
||||
private final long cacheTTL;
|
||||
|
@ -51,6 +54,7 @@ public class AuthLoadingCache<K, V> {
|
|||
private long cacheTimer;
|
||||
|
||||
public AuthLoadingCache(CacheLoader<K, V> provider, long cacheTTL) {
|
||||
this.cacheMapLock = new ReentrantReadWriteLock();
|
||||
this.cacheMap = new HashMap<>();
|
||||
this.provider = provider;
|
||||
this.cacheTTL = cacheTTL;
|
||||
|
@ -58,13 +62,19 @@ public class AuthLoadingCache<K, V> {
|
|||
|
||||
public V get(K key) {
|
||||
CacheEntry<V> etr;
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.readLock().lock();
|
||||
try {
|
||||
etr = cacheMap.get(key);
|
||||
}finally {
|
||||
cacheMapLock.readLock().unlock();
|
||||
}
|
||||
if(etr == null) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
V loaded = provider.load(key);
|
||||
synchronized(cacheMap) {
|
||||
try {
|
||||
cacheMap.put(key, new CacheEntry<>(loaded));
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
return loaded;
|
||||
}else {
|
||||
|
@ -74,13 +84,17 @@ public class AuthLoadingCache<K, V> {
|
|||
}
|
||||
|
||||
public void evict(K key) {
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
cacheMap.remove(key);
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void evictAll(CacheVisitor<K, V> visitor) {
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
Iterator<Entry<K,CacheEntry<V>>> itr = cacheMap.entrySet().iterator();
|
||||
while(itr.hasNext()) {
|
||||
Entry<K,CacheEntry<V>> etr = itr.next();
|
||||
|
@ -88,6 +102,8 @@ public class AuthLoadingCache<K, V> {
|
|||
itr.remove();
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +111,8 @@ public class AuthLoadingCache<K, V> {
|
|||
long millis = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
if(millis - cacheTimer > (cacheTTL / 2L)) {
|
||||
cacheTimer = millis;
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
Iterator<CacheEntry<V>> mapItr = cacheMap.values().iterator();
|
||||
while(mapItr.hasNext()) {
|
||||
CacheEntry<V> etr = mapItr.next();
|
||||
|
@ -103,13 +120,18 @@ public class AuthLoadingCache<K, V> {
|
|||
mapItr.remove();
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
synchronized(cacheMap) {
|
||||
cacheMapLock.writeLock().lock();
|
||||
try {
|
||||
cacheMap.clear();
|
||||
}finally {
|
||||
cacheMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
|||
private static final Method loginEventFiredMethod;
|
||||
private static final Constructor<ConnectedPlayer> stupid3Constructor;
|
||||
private static final Constructor<ConnectedPlayer> stupid3Constructor_new;
|
||||
private static final Constructor<ConnectedPlayer> stupid3Constructor_new_new;
|
||||
private static final Method setPermissionFunctionMethod;
|
||||
private static final Field defaultPermissionsField;
|
||||
private static final Constructor<InitialConnectSessionHandler> stupid4Constructor;
|
||||
|
@ -137,16 +138,24 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
|||
loginEventFiredMethod.setAccessible(true);
|
||||
Constructor<ConnectedPlayer> c3 = null;
|
||||
Constructor<ConnectedPlayer> c3_new = null;
|
||||
Constructor<ConnectedPlayer> c3_new_new = null;
|
||||
try {
|
||||
c3_new = ConnectedPlayer.class.getDeclaredConstructor(VelocityServer.class, GameProfile.class, MinecraftConnection.class, InetSocketAddress.class, String.class, boolean.class, IdentifiedKey.class);
|
||||
c3_new.setAccessible(true);
|
||||
c3_new_new = ConnectedPlayer.class.getDeclaredConstructor(VelocityServer.class, GameProfile.class, MinecraftConnection.class, InetSocketAddress.class, String.class, boolean.class, HandshakeIntent.class, IdentifiedKey.class);
|
||||
c3_new_new.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
c3 = ConnectedPlayer.class.getDeclaredConstructor(VelocityServer.class, GameProfile.class, MinecraftConnection.class, InetSocketAddress.class, boolean.class, IdentifiedKey.class);
|
||||
c3.setAccessible(true);
|
||||
c3_new = null;
|
||||
try {
|
||||
c3_new_new = null;
|
||||
c3_new = ConnectedPlayer.class.getDeclaredConstructor(VelocityServer.class, GameProfile.class, MinecraftConnection.class, InetSocketAddress.class, String.class, boolean.class, IdentifiedKey.class);
|
||||
c3_new.setAccessible(true);
|
||||
} catch (NoSuchMethodException ee) {
|
||||
c3_new = null;
|
||||
c3 = ConnectedPlayer.class.getDeclaredConstructor(VelocityServer.class, GameProfile.class, MinecraftConnection.class, InetSocketAddress.class, boolean.class, IdentifiedKey.class);
|
||||
c3.setAccessible(true);
|
||||
}
|
||||
}
|
||||
stupid3Constructor = c3;
|
||||
stupid3Constructor_new = c3_new;
|
||||
stupid3Constructor_new_new = c3_new_new;
|
||||
setPermissionFunctionMethod = ConnectedPlayer.class.getDeclaredMethod("setPermissionFunction", PermissionFunction.class);
|
||||
setPermissionFunctionMethod.setAccessible(true);
|
||||
defaultPermissionsField = ConnectedPlayer.class.getDeclaredField("DEFAULT_PERMISSIONS");
|
||||
|
@ -1080,7 +1089,13 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
|||
}
|
||||
|
||||
ConnectedPlayer player;
|
||||
if(stupid3Constructor_new != null) {
|
||||
if(stupid3Constructor_new_new != null) {
|
||||
try {
|
||||
player = stupid3Constructor_new_new.newInstance(bungee, gp, con, lic.getVirtualHost().orElse(null), lic.getRawVirtualHost().orElse(null), false, HandshakeIntent.LOGIN, lic.getIdentifiedKey());
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}else if(stupid3Constructor_new != null) {
|
||||
try {
|
||||
player = stupid3Constructor_new.newInstance(bungee, gp, con, lic.getVirtualHost().orElse(null), lic.getRawVirtualHost().orElse(null), false, lic.getIdentifiedKey());
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
|
@ -1309,14 +1324,11 @@ public class HttpWebSocketHandler extends ChannelInboundHandlerAdapter {
|
|||
|
||||
pp.remove(HttpWebSocketHandler.this);
|
||||
|
||||
pp
|
||||
.addLast("EaglerMinecraftByteBufDecoder", new EaglerMinecraftDecoder())
|
||||
.addLast(LEGACY_PING_DECODER, new LegacyPingDecoder())
|
||||
pp.addLast("EaglerMinecraftByteBufDecoder", new EaglerMinecraftDecoder())
|
||||
.addLast(READ_TIMEOUT,
|
||||
new ReadTimeoutHandler(bungee.getConfiguration().getReadTimeout(),
|
||||
TimeUnit.MILLISECONDS))
|
||||
.addLast("EaglerMinecraftByteBufEncoder", new EaglerMinecraftEncoder())
|
||||
.addLast(LEGACY_PING_ENCODER, LegacyPingEncoder.INSTANCE)
|
||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolUtils.Direction.SERVERBOUND))
|
||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolUtils.Direction.CLIENTBOUND));
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.server.protocol;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
@ -241,10 +242,12 @@ public class GameProtocolMessageController {
|
|||
while(!sendQueueV4.isEmpty()) {
|
||||
sendCount = 0;
|
||||
totalLen = 0;
|
||||
Iterator<byte[]> itr = sendQueueV4.iterator();
|
||||
do {
|
||||
i = sendQueueV4.get(sendCount++).length;
|
||||
i = itr.next().length;
|
||||
totalLen += GamePacketOutputBuffer.getVarIntSize(i) + i;
|
||||
}while(totalLen < 32760 && sendCount < sendQueueV4.size());
|
||||
++sendCount;
|
||||
}while(totalLen < 32760 && itr.hasNext());
|
||||
if(totalLen >= 32760) {
|
||||
--sendCount;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ public class HttpWebServer {
|
|||
private final String page404;
|
||||
private static HttpMemoryCache default404Page;
|
||||
private static HttpMemoryCache default404UpgradePage;
|
||||
private static final Object cacheClearLock = new Object();
|
||||
|
||||
public HttpWebServer(File directory, Map<String,HttpContentType> contentTypes, List<String> index, String page404) {
|
||||
this.directory = directory;
|
||||
|
@ -53,15 +52,13 @@ public class HttpWebServer {
|
|||
|
||||
public void flushCache() {
|
||||
long millis = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
synchronized(cacheClearLock) {
|
||||
synchronized(filesCache) {
|
||||
Iterator<HttpMemoryCache> itr = filesCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
HttpMemoryCache i = itr.next();
|
||||
if(i.contentType.fileBrowserCacheTTL != Long.MAX_VALUE && millis - i.lastCacheHit > 900000l) {
|
||||
i.fileData.release();
|
||||
itr.remove();
|
||||
}
|
||||
synchronized(filesCache) {
|
||||
Iterator<HttpMemoryCache> itr = filesCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
HttpMemoryCache i = itr.next();
|
||||
if(i.contentType.fileBrowserCacheTTL != Long.MAX_VALUE && millis - i.lastCacheHit > 900000l) {
|
||||
i.fileData.release();
|
||||
itr.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -94,20 +91,17 @@ public class HttpWebServer {
|
|||
}
|
||||
|
||||
String joinedPath = String.join("/", pathList);
|
||||
|
||||
synchronized(cacheClearLock) {
|
||||
synchronized(filesCache) {
|
||||
cached = filesCache.get(joinedPath);
|
||||
}
|
||||
|
||||
//TODO: Rewrite this to cause less lock contention
|
||||
synchronized(filesCache) {
|
||||
cached = filesCache.get(joinedPath);
|
||||
|
||||
if(cached != null) {
|
||||
cached = validateCache(cached);
|
||||
if(cached != null) {
|
||||
return cached;
|
||||
}else {
|
||||
synchronized(filesCache) {
|
||||
filesCache.remove(joinedPath);
|
||||
}
|
||||
filesCache.remove(joinedPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,19 +118,13 @@ public class HttpWebServer {
|
|||
if(f.isDirectory()) {
|
||||
for(int i = 0, l = index.size(); i < l; ++i) {
|
||||
String p = joinedPath + "/" + index.get(i);
|
||||
synchronized(filesCache) {
|
||||
cached = filesCache.get(p);
|
||||
}
|
||||
cached = filesCache.get(p);
|
||||
if(cached != null) {
|
||||
cached = validateCache(cached);
|
||||
if(cached != null) {
|
||||
synchronized(filesCache) {
|
||||
filesCache.put(joinedPath, cached);
|
||||
}
|
||||
filesCache.put(joinedPath, cached);
|
||||
}else {
|
||||
synchronized(filesCache) {
|
||||
filesCache.remove(p);
|
||||
}
|
||||
filesCache.remove(p);
|
||||
if(page404 == null || path.equals(page404)) {
|
||||
return default404Page;
|
||||
}else {
|
||||
|
@ -152,9 +140,7 @@ public class HttpWebServer {
|
|||
if(ff.isFile()) {
|
||||
HttpMemoryCache memCache = retrieveFile(ff, p);
|
||||
if(memCache != null) {
|
||||
synchronized(filesCache) {
|
||||
filesCache.put(joinedPath, memCache);
|
||||
}
|
||||
filesCache.put(joinedPath, memCache);
|
||||
return memCache;
|
||||
}
|
||||
}
|
||||
|
@ -167,9 +153,7 @@ public class HttpWebServer {
|
|||
}else {
|
||||
HttpMemoryCache memCache = retrieveFile(f, joinedPath);
|
||||
if(memCache != null) {
|
||||
synchronized(filesCache) {
|
||||
filesCache.put(joinedPath, memCache);
|
||||
}
|
||||
filesCache.put(joinedPath, memCache);
|
||||
return memCache;
|
||||
}else {
|
||||
if(page404 == null || path.equals(page404)) {
|
||||
|
|
|
@ -34,6 +34,7 @@ public class CompatWarning {
|
|||
":> apart from the versions listed below:",
|
||||
":> ",
|
||||
":> - Velocity: " + EaglerXVelocityVersion.NATIVE_VELOCITY_BUILD,
|
||||
":> - " + EaglerXVelocityVersion.NATIVE_VELOCITY_BUILD_DL,
|
||||
":> ",
|
||||
":> This is not a Bukkit/Spigot plugin!",
|
||||
":> ",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.skins;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.server.EaglerPlayerData;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.GameMessagePacket;
|
||||
|
@ -12,7 +12,7 @@ import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketOtherCape
|
|||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketOtherCapePresetEAG;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2024-2025 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
|
||||
|
@ -30,20 +30,15 @@ public class CapeServiceOffline {
|
|||
|
||||
public static final int masterRateLimitPerPlayer = 250;
|
||||
|
||||
private final Map<UUID, GameMessagePacket> capesCache = new HashMap<>();
|
||||
private final ConcurrentMap<UUID, GameMessagePacket> capesCache = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerEaglercraftPlayer(UUID playerUUID, GameMessagePacket capePacket) {
|
||||
synchronized(capesCache) {
|
||||
capesCache.put(playerUUID, capePacket);
|
||||
}
|
||||
capesCache.put(playerUUID, capePacket);
|
||||
}
|
||||
|
||||
public void processGetOtherCape(UUID searchUUID, EaglerPlayerData sender) {
|
||||
if(sender.skinLookupRateLimiter.rateLimit(masterRateLimitPerPlayer)) {
|
||||
GameMessagePacket maybeCape;
|
||||
synchronized(capesCache) {
|
||||
maybeCape = capesCache.get(searchUUID);
|
||||
}
|
||||
GameMessagePacket maybeCape = capesCache.get(searchUUID);
|
||||
if(maybeCape != null) {
|
||||
sender.sendEaglerMessage(maybeCape);
|
||||
}else {
|
||||
|
@ -54,10 +49,7 @@ public class CapeServiceOffline {
|
|||
}
|
||||
|
||||
public void processForceCape(UUID clientUUID, EaglerPlayerData initialHandler) {
|
||||
GameMessagePacket maybeCape;
|
||||
synchronized(capesCache) {
|
||||
maybeCape = capesCache.get(clientUUID);
|
||||
}
|
||||
GameMessagePacket maybeCape = capesCache.get(clientUUID);
|
||||
if(maybeCape != null) {
|
||||
if (maybeCape instanceof SPacketOtherCapePresetEAG) {
|
||||
initialHandler.sendEaglerMessage(
|
||||
|
@ -70,15 +62,11 @@ public class CapeServiceOffline {
|
|||
}
|
||||
|
||||
public void unregisterPlayer(UUID playerUUID) {
|
||||
synchronized(capesCache) {
|
||||
capesCache.remove(playerUUID);
|
||||
}
|
||||
capesCache.remove(playerUUID);
|
||||
}
|
||||
|
||||
public GameMessagePacket getCape(UUID clientUUID) {
|
||||
synchronized(capesCache) {
|
||||
return capesCache.get(clientUUID);
|
||||
}
|
||||
return capesCache.get(clientUUID);
|
||||
}
|
||||
|
||||
public byte[] getCapeHandshakeData(UUID clientUUID) {
|
||||
|
@ -107,8 +95,6 @@ public class CapeServiceOffline {
|
|||
}
|
||||
|
||||
public void shutdown() {
|
||||
synchronized(capesCache) {
|
||||
capesCache.clear();
|
||||
}
|
||||
capesCache.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.skins;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -10,6 +11,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -36,7 +41,7 @@ import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketOtherSkin
|
|||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.util.SkinPacketVersionCache;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2025 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
|
||||
|
@ -54,16 +59,20 @@ public class SkinService implements ISkinService {
|
|||
|
||||
public static final int masterRateLimitPerPlayer = 250;
|
||||
|
||||
private final Map<UUID, CachedPlayerSkin> onlinePlayersCache = new HashMap<>();
|
||||
private final ConcurrentMap<UUID, CachedPlayerSkin> onlinePlayersCache = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<UUID, UUID> onlinePlayersToTexturesMap = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<UUID, CachedForeignSkin> foreignSkinCache = new ConcurrentHashMap<>();
|
||||
|
||||
private final ReadWriteLock onlinePlayersFromTexturesMapLock = new ReentrantReadWriteLock();
|
||||
private final Multimap<UUID, UUID> onlinePlayersFromTexturesMap = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
private final Map<UUID, UUID> onlinePlayersToTexturesMap = new HashMap<>();
|
||||
private final Map<UUID, CachedForeignSkin> foreignSkinCache = new HashMap<>();
|
||||
|
||||
private final Map<UUID, PendingTextureDownload> pendingTextures = new HashMap<>();
|
||||
private final Map<UUID, PendingProfileUUIDLookup> pendingUUIDs = new HashMap<>();
|
||||
private final Map<String, PendingProfileNameLookup> pendingNameLookups = new HashMap<>();
|
||||
|
||||
private final ReadWriteLock antagonistsLock = new ReentrantReadWriteLock();
|
||||
private final Object2IntMap<UUID> antagonists = new Object2IntOpenHashMap<>();
|
||||
|
||||
private long antagonistCooldown = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
|
||||
private final Consumer<Set<UUID>> antagonistLogger = new Consumer<Set<UUID>>() {
|
||||
|
@ -73,7 +82,8 @@ public class SkinService implements ISkinService {
|
|||
if(t.size() == 1) {
|
||||
int limit = EaglerXVelocity.getEagler().getConfig().getAntagonistsRateLimit() << 1;
|
||||
UUID offender = t.iterator().next();
|
||||
synchronized(antagonists) {
|
||||
antagonistsLock.writeLock().lock();
|
||||
try {
|
||||
int v = antagonists.getInt(offender);
|
||||
if(v == antagonists.defaultReturnValue()) {
|
||||
antagonists.put(offender, 1);
|
||||
|
@ -82,6 +92,8 @@ public class SkinService implements ISkinService {
|
|||
antagonists.put(offender, v + 1);
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
antagonistsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +107,7 @@ public class SkinService implements ISkinService {
|
|||
protected final UUID uuid;
|
||||
protected final SkinPacketVersionCache data;
|
||||
protected final int modelKnown;
|
||||
protected long lastHit;
|
||||
protected volatile long lastHit;
|
||||
|
||||
protected CachedForeignSkin(UUID uuid, SkinPacketVersionCache data, int modelKnown) {
|
||||
this.uuid = uuid;
|
||||
|
@ -130,7 +142,7 @@ public class SkinService implements ISkinService {
|
|||
protected final Consumer<Set<UUID>> antagonistsCallback;
|
||||
|
||||
protected final long initializedTime;
|
||||
protected boolean finalized;
|
||||
protected volatile boolean finalized;
|
||||
|
||||
protected PendingTextureDownload(UUID textureUUID, String textureURL, UUID caller, Consumer<byte[]> callback,
|
||||
Consumer<Set<UUID>> antagonistsCallback) {
|
||||
|
@ -172,7 +184,7 @@ public class SkinService implements ISkinService {
|
|||
protected final Consumer<Set<UUID>> antagonistsCallback;
|
||||
|
||||
protected final long initializedTime;
|
||||
protected boolean finalized;
|
||||
protected volatile boolean finalized;
|
||||
|
||||
protected PendingProfileUUIDLookup(UUID profileUUID, UUID caller, Consumer<CacheFetchedProfile> callback,
|
||||
Consumer<Set<UUID>> antagonistsCallback) {
|
||||
|
@ -213,7 +225,7 @@ public class SkinService implements ISkinService {
|
|||
protected final Consumer<Set<UUID>> antagonistsCallback;
|
||||
|
||||
protected final long initializedTime;
|
||||
protected boolean finalized;
|
||||
protected volatile boolean finalized;
|
||||
|
||||
protected PendingProfileNameLookup(String profileName, UUID caller, Consumer<CacheFetchedProfile> callback,
|
||||
Consumer<Set<UUID>> antagonistsCallback) {
|
||||
|
@ -260,60 +272,46 @@ public class SkinService implements ISkinService {
|
|||
return;
|
||||
}
|
||||
|
||||
CachedPlayerSkin maybeCachedPacket;
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(searchUUID);
|
||||
}
|
||||
CachedPlayerSkin maybeCachedPacket = onlinePlayersCache.get(searchUUID);
|
||||
|
||||
if(maybeCachedPacket != null) {
|
||||
sender.sendEaglerMessage(maybeCachedPacket.data.get(sender.getEaglerProtocol()));
|
||||
}else {
|
||||
Player player = EaglerXVelocity.proxy().getPlayer(searchUUID).orElse(null);
|
||||
UUID playerTexture;
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
playerTexture = onlinePlayersToTexturesMap.get(searchUUID);
|
||||
}
|
||||
UUID playerTexture = onlinePlayersToTexturesMap.get(searchUUID);
|
||||
if(playerTexture != null) {
|
||||
Collection<UUID> possiblePlayers;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
possiblePlayers = onlinePlayersFromTexturesMap.get(playerTexture);
|
||||
onlinePlayersFromTexturesMapLock.readLock().lock();
|
||||
try {
|
||||
possiblePlayers = new ArrayList<>(onlinePlayersFromTexturesMap.get(playerTexture));
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.readLock().unlock();
|
||||
}
|
||||
boolean playersExist = possiblePlayers.size() > 0;
|
||||
if(playersExist) {
|
||||
for(UUID uuid : possiblePlayers) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
}
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
if(maybeCachedPacket != null) {
|
||||
SkinPacketVersionCache rewritten = SkinPacketVersionCache.rewriteUUID(
|
||||
maybeCachedPacket.data, searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits());
|
||||
if(player != null) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
}
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
}
|
||||
sender.sendEaglerMessage(rewritten.get(sender.getEaglerProtocol()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
if(foreignSkin != null && foreignSkin.modelKnown != -1) {
|
||||
if(player != null) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(searchUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
}
|
||||
onlinePlayersCache.put(searchUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
}else {
|
||||
foreignSkin.lastHit = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
}
|
||||
|
@ -336,7 +334,7 @@ public class SkinService implements ISkinService {
|
|||
if(skinObj != null) {
|
||||
JsonElement url = json.get("url");
|
||||
if(url != null) {
|
||||
String urlStr = SkinService.sanitizeTextureURL(url.getAsString());
|
||||
String urlStr = sanitizeTextureURL(url.getAsString());
|
||||
if(urlStr == null) {
|
||||
break;
|
||||
}
|
||||
|
@ -350,19 +348,14 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
UUID skinUUID = SkinPackets.createEaglerURLSkinUUID(urlStr);
|
||||
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
if(foreignSkin != null) {
|
||||
registerTextureToPlayerAssociation(skinUUID, searchUUID);
|
||||
SkinPacketVersionCache rewrite = SkinPacketVersionCache
|
||||
.rewriteUUIDModel(foreignSkin.data,
|
||||
searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits(), model);
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
}
|
||||
onlinePlayersCache.put(searchUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
sender.sendEaglerMessage(rewrite.get(sender.getEaglerProtocol()));
|
||||
return;
|
||||
}
|
||||
|
@ -395,10 +388,7 @@ public class SkinService implements ISkinService {
|
|||
});
|
||||
}
|
||||
}else {
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
if(foreignSkin != null) {
|
||||
foreignSkin.lastHit = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
sender.sendEaglerMessage(foreignSkin.data.get(sender.getEaglerProtocol()));
|
||||
|
@ -426,25 +416,22 @@ public class SkinService implements ISkinService {
|
|||
if(!sender.skinLookupRateLimiter.rateLimit(masterRateLimitPerPlayer)) {
|
||||
return;
|
||||
}
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(searchUUID);
|
||||
if(foreignSkin != null) {
|
||||
foreignSkin.lastHit = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
sender.sendEaglerMessage(foreignSkin.data.get(sender.getEaglerProtocol()));
|
||||
}else {
|
||||
Collection<UUID> possiblePlayers;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
possiblePlayers = onlinePlayersFromTexturesMap.get(searchUUID);
|
||||
onlinePlayersFromTexturesMapLock.readLock().lock();
|
||||
try {
|
||||
possiblePlayers = new ArrayList<>(onlinePlayersFromTexturesMap.get(searchUUID));
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.readLock().unlock();
|
||||
}
|
||||
boolean playersExist = possiblePlayers.size() > 0;
|
||||
if(playersExist) {
|
||||
for(UUID uuid : possiblePlayers) {
|
||||
CachedPlayerSkin maybeCachedPacket;
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
}
|
||||
CachedPlayerSkin maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
if(maybeCachedPacket != null) {
|
||||
sender.sendEaglerMessage(maybeCachedPacket.data.get(sender.getEaglerProtocol(),
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()));
|
||||
|
@ -457,10 +444,17 @@ public class SkinService implements ISkinService {
|
|||
searchUUID.getLeastSignificantBits(), 0));
|
||||
return;
|
||||
}
|
||||
if(sender.skinTextureDownloadRateLimiter.rateLimit(config.getSkinRateLimitPlayer()) && !isLimitedAsAntagonist(sender.getUniqueId())) {
|
||||
doAsync(() -> {
|
||||
processResolveURLTextureForForeign(sender, searchUUID, searchUUID, skinURL, -1);
|
||||
});
|
||||
skinURL = sanitizeTextureURL(skinURL);
|
||||
if(skinURL != null) {
|
||||
final String skinURL_ = skinURL;
|
||||
if(sender.skinTextureDownloadRateLimiter.rateLimit(config.getSkinRateLimitPlayer()) && !isLimitedAsAntagonist(sender.getUniqueId())) {
|
||||
doAsync(() -> {
|
||||
processResolveURLTextureForForeign(sender, searchUUID, searchUUID, skinURL_, -1);
|
||||
});
|
||||
}
|
||||
}else {
|
||||
sender.sendEaglerMessage(new SPacketOtherSkinPresetEAG(searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,10 +469,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -505,9 +496,7 @@ public class SkinService implements ISkinService {
|
|||
onlineCacheUUID.getMostSignificantBits(),
|
||||
onlineCacheUUID.getLeastSignificantBits()), null, -1);
|
||||
}
|
||||
synchronized (onlinePlayersCache) {
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
||||
|
@ -532,10 +521,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -563,9 +549,7 @@ public class SkinService implements ISkinService {
|
|||
foreignCacheUUID.getLeastSignificantBits()),
|
||||
-1);
|
||||
}
|
||||
synchronized (foreignSkinCache) {
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
||||
|
@ -590,10 +574,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -625,9 +606,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}else {
|
||||
processResolveURLTextureForOnline(initiator, playerUUID, t.textureUUID, t.texture,
|
||||
|
@ -656,10 +635,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(t.uuid);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(t.uuid);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -689,9 +665,7 @@ public class SkinService implements ISkinService {
|
|||
mapUUID.getMostSignificantBits(), mapUUID.getLeastSignificantBits(),
|
||||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0), null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}else {
|
||||
processResolveURLTextureForOnline(initiator, mapUUID, t.textureUUID, t.texture,
|
||||
|
@ -720,10 +694,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(playerUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}
|
||||
|
@ -755,9 +726,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
-1);
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.get(initiator.getEaglerProtocol()));
|
||||
}else {
|
||||
processResolveURLTextureForForeign(initiator, playerUUID, t.textureUUID, t.texture,
|
||||
|
@ -777,27 +746,16 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
|
||||
public void registerEaglercraftPlayer(UUID clientUUID, SkinPacketVersionCache generatedPacket, int modelId) {
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.remove(clientUUID);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(clientUUID, new CachedPlayerSkin(generatedPacket, null, modelId));
|
||||
}
|
||||
foreignSkinCache.remove(clientUUID);
|
||||
onlinePlayersCache.put(clientUUID, new CachedPlayerSkin(generatedPacket, null, modelId));
|
||||
}
|
||||
|
||||
public void unregisterPlayer(UUID clientUUID) {
|
||||
CachedPlayerSkin data;
|
||||
synchronized(onlinePlayersCache) {
|
||||
data = onlinePlayersCache.remove(clientUUID);
|
||||
}
|
||||
CachedPlayerSkin data = onlinePlayersCache.remove(clientUUID);
|
||||
if(data != null) {
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(clientUUID, new CachedForeignSkin(clientUUID, data.data, data.modelId));
|
||||
}
|
||||
foreignSkinCache.put(clientUUID, new CachedForeignSkin(clientUUID, data.data, data.modelId));
|
||||
if(data.textureUUID != null) {
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(data.textureUUID, new CachedForeignSkin(data.textureUUID, data.data, data.modelId));
|
||||
}
|
||||
foreignSkinCache.put(data.textureUUID, new CachedForeignSkin(data.textureUUID, data.data, data.modelId));
|
||||
}
|
||||
deletePlayerTextureAssociation(clientUUID, data.textureUUID);
|
||||
}else {
|
||||
|
@ -807,94 +765,77 @@ public class SkinService implements ISkinService {
|
|||
|
||||
private void deletePlayerTextureAssociation(UUID clientUUID, UUID textureUUID) {
|
||||
if(textureUUID != null) {
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
}
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.remove(textureUUID, clientUUID);
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
}else {
|
||||
UUID removedUUID;
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
removedUUID = onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
}
|
||||
UUID removedUUID = onlinePlayersToTexturesMap.remove(clientUUID);
|
||||
if(removedUUID != null) {
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.remove(removedUUID, clientUUID);
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerTextureToPlayerAssociation(UUID textureUUID, UUID playerUUID) {
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.put(textureUUID, playerUUID);
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
onlinePlayersToTexturesMap.put(playerUUID, textureUUID);
|
||||
}
|
||||
CachedForeignSkin foreign;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreign = foreignSkinCache.remove(textureUUID);
|
||||
}
|
||||
onlinePlayersToTexturesMap.put(playerUUID, textureUUID);
|
||||
CachedForeignSkin foreign = foreignSkinCache.remove(textureUUID);
|
||||
if(foreign != null) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(foreign.data, textureUUID, foreign.modelKnown));
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(foreign.data, textureUUID, foreign.modelKnown));
|
||||
}
|
||||
}
|
||||
|
||||
public void processForceSkin(UUID playerUUID, EaglerPlayerData eaglerHandler) {
|
||||
CachedPlayerSkin maybeCachedPacket;
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin maybeCachedPacket = onlinePlayersCache.get(playerUUID);
|
||||
|
||||
if(maybeCachedPacket != null) {
|
||||
eaglerHandler.sendEaglerMessage(maybeCachedPacket.data.getForceClientV4());
|
||||
}else {
|
||||
UUID playerTexture;
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
playerTexture = onlinePlayersToTexturesMap.get(playerUUID);
|
||||
}
|
||||
UUID playerTexture = onlinePlayersToTexturesMap.get(playerUUID);
|
||||
if(playerTexture != null) {
|
||||
Collection<UUID> possiblePlayers;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
possiblePlayers = onlinePlayersFromTexturesMap.get(playerTexture);
|
||||
onlinePlayersFromTexturesMapLock.readLock().lock();
|
||||
try {
|
||||
possiblePlayers = new ArrayList<>(onlinePlayersFromTexturesMap.get(playerTexture));
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.readLock().unlock();
|
||||
}
|
||||
boolean playersExist = possiblePlayers.size() > 0;
|
||||
if(playersExist) {
|
||||
for(UUID uuid : possiblePlayers) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
}
|
||||
maybeCachedPacket = onlinePlayersCache.get(uuid);
|
||||
if(maybeCachedPacket != null) {
|
||||
SkinPacketVersionCache rewritten = SkinPacketVersionCache.rewriteUUID(
|
||||
maybeCachedPacket.data, playerUUID.getMostSignificantBits(),
|
||||
playerUUID.getLeastSignificantBits());
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewritten,
|
||||
maybeCachedPacket.textureUUID, maybeCachedPacket.modelId));
|
||||
eaglerHandler.sendEaglerMessage(rewritten.getForceClientV4());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(playerTexture);
|
||||
if(foreignSkin != null && foreignSkin.modelKnown != -1) {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
playerUUID.getMostSignificantBits(), playerUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID,
|
||||
new CachedPlayerSkin(SkinPacketVersionCache.rewriteUUID(foreignSkin.data,
|
||||
playerUUID.getMostSignificantBits(), playerUUID.getLeastSignificantBits()),
|
||||
playerTexture, foreignSkin.modelKnown));
|
||||
foreignSkinCache.remove(playerTexture);
|
||||
eaglerHandler.sendEaglerMessage(foreignSkin.data.getForceClientV4());
|
||||
return;
|
||||
}
|
||||
|
@ -913,7 +854,7 @@ public class SkinService implements ISkinService {
|
|||
if(skinObj != null) {
|
||||
JsonElement url = json.get("url");
|
||||
if(url != null) {
|
||||
String urlStr = SkinService.sanitizeTextureURL(url.getAsString());
|
||||
String urlStr = sanitizeTextureURL(url.getAsString());
|
||||
if(urlStr == null) {
|
||||
break;
|
||||
}
|
||||
|
@ -927,19 +868,14 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
UUID skinUUID = SkinPackets.createEaglerURLSkinUUID(urlStr);
|
||||
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.remove(skinUUID);
|
||||
if(foreignSkin != null) {
|
||||
registerTextureToPlayerAssociation(skinUUID, playerUUID);
|
||||
SkinPacketVersionCache rewrite = SkinPacketVersionCache
|
||||
.rewriteUUIDModel(foreignSkin.data,
|
||||
playerUUID.getMostSignificantBits(),
|
||||
playerUUID.getLeastSignificantBits(), model);
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, new CachedPlayerSkin(rewrite, skinUUID, model));
|
||||
eaglerHandler.sendEaglerMessage(rewrite.getForceClientV4());
|
||||
return;
|
||||
}
|
||||
|
@ -967,10 +903,7 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
});
|
||||
}else {
|
||||
CachedForeignSkin foreignSkin;
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkin = foreignSkinCache.get(playerUUID);
|
||||
}
|
||||
CachedForeignSkin foreignSkin = foreignSkinCache.get(playerUUID);
|
||||
if(foreignSkin != null) {
|
||||
foreignSkin.lastHit = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
eaglerHandler.sendEaglerMessage(foreignSkin.data.getForceClientV4());
|
||||
|
@ -997,10 +930,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(onlineCacheUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1027,9 +957,7 @@ public class SkinService implements ISkinService {
|
|||
onlineCacheUUID.getMostSignificantBits(),
|
||||
onlineCacheUUID.getLeastSignificantBits()), null, -1);
|
||||
}
|
||||
synchronized (onlinePlayersCache) {
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(onlineCacheUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
||||
|
@ -1054,10 +982,7 @@ public class SkinService implements ISkinService {
|
|||
|
||||
@Override
|
||||
public void accept(byte[] t) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(foreignCacheUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1085,9 +1010,7 @@ public class SkinService implements ISkinService {
|
|||
foreignCacheUUID.getLeastSignificantBits()),
|
||||
-1);
|
||||
}
|
||||
synchronized (foreignSkinCache) {
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(foreignCacheUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
||||
|
@ -1112,10 +1035,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1147,9 +1067,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(playerUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}else {
|
||||
processResolveURLTextureForOnlineToForce(initiator, playerUUID, t.textureUUID, t.texture,
|
||||
|
@ -1178,10 +1096,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(t.uuid);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(t.uuid);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1211,9 +1126,7 @@ public class SkinService implements ISkinService {
|
|||
mapUUID.getMostSignificantBits(), mapUUID.getLeastSignificantBits(),
|
||||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0), null, -1);
|
||||
}
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
}
|
||||
onlinePlayersCache.put(mapUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}else {
|
||||
processResolveURLTextureForOnlineToForce(initiator, mapUUID, t.textureUUID, t.texture,
|
||||
|
@ -1242,10 +1155,7 @@ public class SkinService implements ISkinService {
|
|||
@Override
|
||||
public void accept(CacheFetchedProfile t) {
|
||||
if(t == null || t.texture == null) {
|
||||
CachedForeignSkin skin;
|
||||
synchronized(foreignSkinCache) {
|
||||
skin = foreignSkinCache.get(playerUUID);
|
||||
}
|
||||
CachedForeignSkin skin = foreignSkinCache.get(playerUUID);
|
||||
if(skin != null) {
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}
|
||||
|
@ -1277,9 +1187,7 @@ public class SkinService implements ISkinService {
|
|||
SkinPackets.getModelId(t.model) == 1 ? 1 : 0),
|
||||
-1);
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
}
|
||||
foreignSkinCache.put(playerUUID, skin);
|
||||
initiator.sendEaglerMessage(skin.data.getForceClientV4());
|
||||
}else {
|
||||
processResolveURLTextureForForeignToForce(initiator, playerUUID, t.textureUUID, t.texture,
|
||||
|
@ -1301,12 +1209,16 @@ public class SkinService implements ISkinService {
|
|||
public void flush() {
|
||||
long millis = EaglerXVelocityAPIHelper.steadyTimeMillis();
|
||||
|
||||
synchronized(foreignSkinCache) {
|
||||
Iterator<CachedForeignSkin> itr = foreignSkinCache.values().iterator();
|
||||
while(itr.hasNext()) {
|
||||
if(millis - itr.next().lastHit > 900000l) { // 15 minutes
|
||||
itr.remove();
|
||||
}
|
||||
final List<UUID> foreignSkinCleanup = new ArrayList<>(4);
|
||||
foreignSkinCache.entrySet().forEach((etr) -> {
|
||||
if(millis - etr.getValue().lastHit > 900000l) { // 15 minutes
|
||||
foreignSkinCleanup.add(etr.getKey());
|
||||
}
|
||||
});
|
||||
|
||||
if(!foreignSkinCleanup.isEmpty()) {
|
||||
for(UUID uuid : foreignSkinCleanup) {
|
||||
foreignSkinCache.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1357,7 +1269,8 @@ public class SkinService implements ISkinService {
|
|||
elapsedCooldown /= cooldownPeriod;
|
||||
if(elapsedCooldown > 0) {
|
||||
antagonistCooldown += elapsedCooldown * cooldownPeriod;
|
||||
synchronized(antagonists) {
|
||||
antagonistsLock.writeLock().lock();
|
||||
try {
|
||||
Iterator<UUID> itr = antagonists.keySet().iterator();
|
||||
while(itr.hasNext()) {
|
||||
UUID key = itr.next();
|
||||
|
@ -1368,6 +1281,8 @@ public class SkinService implements ISkinService {
|
|||
antagonists.put(key, i);
|
||||
}
|
||||
}
|
||||
}finally {
|
||||
antagonistsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1375,10 +1290,7 @@ public class SkinService implements ISkinService {
|
|||
}
|
||||
|
||||
public SkinPacketVersionCache getSkin(UUID playerUUID) {
|
||||
CachedPlayerSkin skin;
|
||||
synchronized(onlinePlayersCache) {
|
||||
skin = onlinePlayersCache.get(playerUUID);
|
||||
}
|
||||
CachedPlayerSkin skin = onlinePlayersCache.get(playerUUID);
|
||||
return skin != null ? skin.data : null;
|
||||
}
|
||||
|
||||
|
@ -1393,25 +1305,26 @@ public class SkinService implements ISkinService {
|
|||
private boolean isLimitedAsAntagonist(UUID uuid) {
|
||||
int limit = EaglerXVelocity.getEagler().getConfig().getAntagonistsRateLimit();
|
||||
limit += limit >> 1;
|
||||
synchronized(antagonists) {
|
||||
int i = antagonists.getInt(uuid);
|
||||
return i != antagonists.defaultReturnValue() && i > limit;
|
||||
int i;
|
||||
antagonistsLock.readLock().lock();
|
||||
try {
|
||||
i = antagonists.getInt(uuid);
|
||||
}finally {
|
||||
antagonistsLock.readLock().unlock();
|
||||
}
|
||||
return i != antagonists.defaultReturnValue() && i > limit;
|
||||
}
|
||||
|
||||
private void resetMaps() {
|
||||
synchronized(onlinePlayersCache) {
|
||||
onlinePlayersCache.clear();
|
||||
}
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersCache.clear();
|
||||
onlinePlayersFromTexturesMapLock.writeLock().lock();
|
||||
try {
|
||||
onlinePlayersFromTexturesMap.clear();
|
||||
}finally {
|
||||
onlinePlayersFromTexturesMapLock.writeLock().unlock();
|
||||
}
|
||||
synchronized(onlinePlayersToTexturesMap) {
|
||||
onlinePlayersToTexturesMap.clear();
|
||||
}
|
||||
synchronized(foreignSkinCache) {
|
||||
foreignSkinCache.clear();
|
||||
}
|
||||
onlinePlayersToTexturesMap.clear();
|
||||
foreignSkinCache.clear();
|
||||
synchronized(pendingTextures) {
|
||||
pendingTextures.clear();
|
||||
}
|
||||
|
@ -1421,8 +1334,11 @@ public class SkinService implements ISkinService {
|
|||
synchronized(pendingNameLookups) {
|
||||
pendingNameLookups.clear();
|
||||
}
|
||||
synchronized(antagonists) {
|
||||
antagonistsLock.writeLock().lock();
|
||||
try {
|
||||
antagonists.clear();
|
||||
}finally {
|
||||
antagonistsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1439,7 +1355,7 @@ public class SkinService implements ISkinService {
|
|||
return null;
|
||||
}
|
||||
String host = uri.getHost();
|
||||
if(host == null) {
|
||||
if(host == null || !EaglerXVelocity.getEagler().getConfig().isValidSkinHost(host)) {
|
||||
return null;
|
||||
}
|
||||
scheme = scheme.toLowerCase();
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
package net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.skins;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.MultimapBuilder;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.server.EaglerPlayerData;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketOtherSkinPresetEAG;
|
||||
import net.lax1dude.eaglercraft.v1_8.socket.protocol.util.SkinPacketVersionCache;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2022-2023 lax1dude. All Rights Reserved.
|
||||
* Copyright (c) 2022-2025 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
|
||||
|
@ -44,22 +39,15 @@ public class SkinServiceOffline implements ISkinService {
|
|||
|
||||
}
|
||||
|
||||
private final Map<UUID, CachedSkin> skinCache = new HashMap<>();
|
||||
|
||||
private final Multimap<UUID, UUID> onlinePlayersFromTexturesMap = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||
private final ConcurrentMap<UUID, CachedSkin> skinCache = new ConcurrentHashMap<>();
|
||||
|
||||
public void init(String uri, String driverClass, String driverPath, int keepObjectsDays, int keepProfilesDays,
|
||||
int maxObjects, int maxProfiles) {
|
||||
synchronized(skinCache) {
|
||||
skinCache.clear();
|
||||
}
|
||||
skinCache.clear();
|
||||
}
|
||||
|
||||
public void processGetOtherSkin(UUID searchUUID, EaglerPlayerData sender) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
cached = skinCache.get(searchUUID);
|
||||
}
|
||||
CachedSkin cached = skinCache.get(searchUUID);
|
||||
if(cached != null) {
|
||||
sender.sendEaglerMessage(cached.packet.get(sender.getEaglerProtocol()));
|
||||
}else {
|
||||
|
@ -69,24 +57,6 @@ public class SkinServiceOffline implements ISkinService {
|
|||
}
|
||||
|
||||
public void processGetOtherSkin(UUID searchUUID, String skinURL, EaglerPlayerData sender) {
|
||||
Collection<UUID> uuids;
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
uuids = onlinePlayersFromTexturesMap.get(searchUUID);
|
||||
}
|
||||
if(uuids.size() > 0) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
Iterator<UUID> uuidItr = uuids.iterator();
|
||||
while(uuidItr.hasNext()) {
|
||||
cached = skinCache.get(uuidItr.next());
|
||||
if(cached != null) {
|
||||
sender.sendEaglerMessage(cached.packet.get(sender.getEaglerProtocol(),
|
||||
searchUUID.getMostSignificantBits(), searchUUID.getLeastSignificantBits()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(skinURL.startsWith("eagler://")) { // customs skulls from exported singleplayer worlds
|
||||
sender.sendEaglerMessage(new SPacketOtherSkinPresetEAG(searchUUID.getMostSignificantBits(),
|
||||
searchUUID.getLeastSignificantBits(), 0));
|
||||
|
@ -97,28 +67,21 @@ public class SkinServiceOffline implements ISkinService {
|
|||
}
|
||||
|
||||
public void registerEaglercraftPlayer(UUID clientUUID, SkinPacketVersionCache generatedPacket, int modelId) {
|
||||
synchronized(skinCache) {
|
||||
skinCache.put(clientUUID, new CachedSkin(clientUUID, generatedPacket));
|
||||
}
|
||||
skinCache.put(clientUUID, new CachedSkin(clientUUID, generatedPacket));
|
||||
}
|
||||
|
||||
public void unregisterPlayer(UUID clientUUID) {
|
||||
synchronized(skinCache) {
|
||||
skinCache.remove(clientUUID);
|
||||
}
|
||||
skinCache.remove(clientUUID);
|
||||
}
|
||||
|
||||
public void registerTextureToPlayerAssociation(String textureURL, UUID playerUUID) {
|
||||
}
|
||||
|
||||
public void registerTextureToPlayerAssociation(UUID textureUUID, UUID playerUUID) {
|
||||
synchronized(onlinePlayersFromTexturesMap) {
|
||||
onlinePlayersFromTexturesMap.put(textureUUID, playerUUID);
|
||||
}
|
||||
}
|
||||
|
||||
public void processForceSkin(UUID playerUUID, EaglerPlayerData initialHandler) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
cached = skinCache.get(playerUUID);
|
||||
}
|
||||
CachedSkin cached = skinCache.get(playerUUID);
|
||||
if(cached != null) {
|
||||
initialHandler.sendEaglerMessage(cached.packet.getForceClientV4());
|
||||
}
|
||||
|
@ -129,16 +92,11 @@ public class SkinServiceOffline implements ISkinService {
|
|||
}
|
||||
|
||||
public void shutdown() {
|
||||
synchronized(skinCache) {
|
||||
skinCache.clear();
|
||||
}
|
||||
skinCache.clear();
|
||||
}
|
||||
|
||||
public SkinPacketVersionCache getSkin(UUID playerUUID) {
|
||||
CachedSkin cached;
|
||||
synchronized(skinCache) {
|
||||
cached = skinCache.get(playerUUID);
|
||||
}
|
||||
CachedSkin cached = skinCache.get(playerUUID);
|
||||
return cached != null ? cached.packet : null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"id":"eaglerxvelocity","name":"EaglercraftXVelocity","version":"1.1.5","description":"Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks","authors":["lax1dude", "ayunami2000"],"dependencies":[],"main":"net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity"}
|
||||
{"id":"eaglerxvelocity","name":"EaglercraftXVelocity","version":"1.1.6","description":"Plugin to allow EaglercraftX 1.8 players to join your network, or allow EaglercraftX 1.8 players to use your network as a proxy to join other networks","authors":["lax1dude", "ayunami2000"],"dependencies":[],"main":"net.lax1dude.eaglercraft.v1_8.plugin.gateway_velocity.EaglerXVelocity"}
|
|
@ -1 +1 @@
|
|||
1.3.4
|
||||
1.3.5
|
|
@ -1 +1 @@
|
|||
1.1.5
|
||||
1.1.6
|
|
@ -1,4 +1,4 @@
|
|||
# 146 files to delete:
|
||||
# 148 files to delete:
|
||||
net/minecraft/client/renderer/VertexBufferUploader.java
|
||||
net/minecraft/realms/DisconnectedRealmsScreen.java
|
||||
net/minecraft/client/stream/Metadata.java
|
||||
|
@ -95,6 +95,7 @@ net/minecraft/realms/Tezzelator.java
|
|||
net/minecraft/command/server/CommandSaveOff.java
|
||||
net/minecraft/realms/RealmsLevelSummary.java
|
||||
net/minecraft/realms/RealmsServerAddress.java
|
||||
net/minecraft/util/LongHashMap.java
|
||||
net/minecraft/realms/RealmsAnvilLevelStorageSource.java
|
||||
net/minecraft/realms/RealmsSliderButton.java
|
||||
net/minecraft/world/storage/ThreadedFileIOBase.java
|
||||
|
@ -140,6 +141,7 @@ net/minecraft/command/server/CommandStop.java
|
|||
net/minecraft/realms/RealmsSharedConstants.java
|
||||
net/minecraft/server/management/UserList.java
|
||||
net/minecraft/realms/RealmsSimpleScrolledSelectionList.java
|
||||
net/minecraft/util/IntHashMap.java
|
||||
net/minecraft/client/resources/FolderResourcePack.java
|
||||
net/minecraft/client/stream/MetadataCombat.java
|
||||
net/minecraft/client/network/LanServerDetector.java
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,20 +1,29 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
||||
> DELETE 2 @ 2 : 3
|
||||
|
||||
> CHANGE 1 : 5 @ 1 : 4
|
||||
> CHANGE 2 : 7 @ 2 : 7
|
||||
|
||||
~ import net.lax1dude.eaglercraft.v1_8.EaglercraftRandom;
|
||||
~
|
||||
~ import com.google.common.collect.Maps;
|
||||
~ import com.carrotsearch.hppc.ObjectIntIdentityHashMap;
|
||||
~ import com.carrotsearch.hppc.ObjectIntMap;
|
||||
~
|
||||
|
||||
> CHANGE 118 : 119 @ 118 : 119
|
||||
> CHANGE 26 : 28 @ 26 : 28
|
||||
|
||||
~ private final ObjectIntMap<Block> encouragements = new ObjectIntIdentityHashMap<>();
|
||||
~ private final ObjectIntMap<Block> flammabilities = new ObjectIntIdentityHashMap<>();
|
||||
|
||||
> CHANGE 74 : 76 @ 74 : 76
|
||||
|
||||
~ this.encouragements.put(blockIn, encouragement);
|
||||
~ this.flammabilities.put(blockIn, flammability);
|
||||
|
||||
> CHANGE 14 : 15 @ 14 : 15
|
||||
|
||||
~ public int quantityDropped(EaglercraftRandom var1) {
|
||||
|
||||
|
@ -22,21 +31,45 @@
|
|||
|
||||
~ public void updateTick(World world, BlockPos blockpos, IBlockState iblockstate, EaglercraftRandom random) {
|
||||
|
||||
> CHANGE 106 : 107 @ 106 : 107
|
||||
> INSERT 59 : 61 @ 59
|
||||
|
||||
+ if (!world.isBlockLoaded(blockpos1))
|
||||
+ continue;
|
||||
|
||||
> CHANGE 38 : 39 @ 38 : 40
|
||||
|
||||
~ return this.flammabilities.getOrDefault(blockIn, 0);
|
||||
|
||||
> CHANGE 3 : 4 @ 3 : 5
|
||||
|
||||
~ return this.encouragements.getOrDefault(blockIn, 0);
|
||||
|
||||
> CHANGE 2 : 8 @ 2 : 4
|
||||
|
||||
~ private void catchOnFire(World worldIn, BlockPos pos, int chance, EaglercraftRandom random, int age) {
|
||||
~ IBlockState iblockstate = worldIn.getBlockStateIfLoaded(pos);
|
||||
~ if (iblockstate == null) {
|
||||
~ return;
|
||||
~ }
|
||||
~ int i = this.getFlammability(iblockstate.getBlock());
|
||||
|
||||
> CHANGE 23 : 26 @ 23 : 24
|
||||
> DELETE 1 @ 1 : 2
|
||||
|
||||
> CHANGE 20 : 23 @ 20 : 21
|
||||
|
||||
~ EnumFacing[] facings = EnumFacing._VALUES;
|
||||
~ for (int i = 0; i < facings.length; ++i) {
|
||||
~ EnumFacing enumfacing = facings[i];
|
||||
|
||||
> CHANGE 14 : 17 @ 14 : 16
|
||||
> CHANGE 14 : 21 @ 14 : 16
|
||||
|
||||
~ EnumFacing[] facings = EnumFacing._VALUES;
|
||||
~ BlockPos tmp = new BlockPos(0, 0, 0);
|
||||
~ for (int j = 0; j < facings.length; ++j) {
|
||||
~ i = Math.max(this.getEncouragement(worldIn.getBlockState(pos.offset(facings[j])).getBlock()), i);
|
||||
~ IBlockState type = worldIn.getBlockStateIfLoaded(pos.offsetEvenFaster(facings[j], tmp));
|
||||
~ if (type != null) {
|
||||
~ i = Math.max(this.getEncouragement(type.getBlock()), i);
|
||||
~ }
|
||||
|
||||
> CHANGE 37 : 38 @ 37 : 38
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
# Eagler Context Redacted Diff
|
||||
# Copyright (c) 2024 lax1dude. All rights reserved.
|
||||
# Copyright (c) 2025 lax1dude. All rights reserved.
|
||||
|
||||
# Version: 1.0
|
||||
# Author: lax1dude
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user