mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-27 18:38:14 -05:00
Update #47 - Singleplayer lag fixes
This commit is contained in:
@ -3,9 +3,11 @@ package net.lax1dude.eaglercraft.v1_8.sp.ipc;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.carrotsearch.hppc.IntObjectHashMap;
|
||||
import com.carrotsearch.hppc.IntObjectMap;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
|
||||
*
|
||||
@ -23,7 +25,7 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
public class IPCPacketManager {
|
||||
|
||||
public static final HashMap<Integer, Supplier<IPCPacketBase>> mappings = new HashMap<>();
|
||||
public static final IntObjectMap<Supplier<IPCPacketBase>> mappings = new IntObjectHashMap<>();
|
||||
|
||||
public final IPCInputStream IPC_INPUT_STREAM = new IPCInputStream();
|
||||
public final IPCOutputStream IPC_OUTPUT_STREAM = new IPCOutputStream();
|
||||
|
@ -2,9 +2,7 @@ package net.lax1dude.eaglercraft.v1_8.sp.lan;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EagRuntime;
|
||||
import net.lax1dude.eaglercraft.v1_8.EagUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerInputStream;
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerZLIB;
|
||||
import net.lax1dude.eaglercraft.v1_8.IOUtils;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.EnumEaglerConnectionState;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.PlatformWebRTC;
|
||||
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
|
||||
@ -21,7 +19,6 @@ import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.util.IChatComponent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -308,13 +305,26 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
||||
}
|
||||
for(int k = 0, l = packets.size(); k < l; ++k) {
|
||||
byte[] data = packets.get(k);
|
||||
|
||||
if(firstPacket) {
|
||||
// 1.5 kick packet
|
||||
if(data.length == 31 && data[0] == (byte)0xFF && data[1] == (byte)0x00 && data[2] == (byte)0x0E) {
|
||||
logger.error("Detected a 1.5 LAN server!");
|
||||
this.closeChannel(new ChatComponentTranslation("singleplayer.outdatedLANServerKick"));
|
||||
firstPacket = false;
|
||||
return;
|
||||
}
|
||||
firstPacket = false;
|
||||
}
|
||||
|
||||
byte[] fullData;
|
||||
boolean compressed = false;
|
||||
int off = 0;
|
||||
|
||||
if (data[0] == 0 || data[0] == 2) {
|
||||
if(fragmentedPacket.isEmpty()) {
|
||||
fullData = new byte[data.length - 1];
|
||||
System.arraycopy(data, 1, fullData, 0, fullData.length);
|
||||
fullData = data;
|
||||
off = 1;
|
||||
}else {
|
||||
fragmentedPacket.add(data);
|
||||
int len = 0;
|
||||
@ -341,34 +351,23 @@ public class LANClientNetworkManager extends EaglercraftNetworkManager {
|
||||
}
|
||||
|
||||
if(compressed) {
|
||||
if(fullData.length < 4) {
|
||||
if(fullData.length < 4 + off) {
|
||||
throw new IOException("Recieved invalid " + fullData.length + " byte compressed packet");
|
||||
}
|
||||
EaglerInputStream bi = new EaglerInputStream(fullData);
|
||||
int i = (bi.read() << 24) | (bi.read() << 16) | (bi.read() << 8) | bi.read();
|
||||
fullData = new byte[i];
|
||||
int r;
|
||||
try(InputStream inflaterInputStream = EaglerZLIB.newInflaterInputStream(bi)) {
|
||||
r = IOUtils.readFully(inflaterInputStream, fullData);
|
||||
}
|
||||
int i = (((int) fullData[off] & 0xFF) << 24) | (((int) fullData[off + 1] & 0xFF) << 16)
|
||||
| (((int) fullData[off + 2] & 0xFF) << 8) | ((int) fullData[off + 3] & 0xFF);
|
||||
byte[] fullData2 = new byte[i];
|
||||
int r = EaglerZLIB.inflateFull(fullData, off + 4, fullData.length - off - 4, fullData2, 0, i);
|
||||
fullData = fullData2;
|
||||
off = 0;
|
||||
if (i != r) {
|
||||
logger.warn("Decompressed packet expected size {} differs from actual size {}!", i, r);
|
||||
}
|
||||
}
|
||||
|
||||
if(firstPacket) {
|
||||
// 1.5 kick packet
|
||||
if(fullData.length == 31 && fullData[0] == (byte)0xFF && fullData[1] == (byte)0x00 && fullData[2] == (byte)0x0E) {
|
||||
logger.error("Detected a 1.5 LAN server!");
|
||||
this.closeChannel(new ChatComponentTranslation("singleplayer.outdatedLANServerKick"));
|
||||
firstPacket = false;
|
||||
return;
|
||||
}
|
||||
firstPacket = false;
|
||||
}
|
||||
|
||||
ByteBuf nettyBuffer = Unpooled.buffer(fullData, fullData.length);
|
||||
nettyBuffer.writerIndex(fullData.length);
|
||||
nettyBuffer.readerIndex(off);
|
||||
PacketBuffer input = new PacketBuffer(nettyBuffer);
|
||||
int pktId = input.readVarIntFromBuffer();
|
||||
|
||||
|
@ -0,0 +1,107 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.sp.server;
|
||||
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.gen.layer.GenLayer;
|
||||
import net.minecraft.world.gen.layer.IntCache;
|
||||
|
||||
/**
|
||||
* Copyright (c) 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
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
public class GenLayerEaglerRivers extends GenLayer {
|
||||
|
||||
private static final int[] pattern = new int[] {
|
||||
0b111000011100001110000111,
|
||||
0b111000111110011111000111,
|
||||
0b011100011100001110001110,
|
||||
0b011100000000000000001110,
|
||||
0b001110000000000000011100,
|
||||
0b001110000000000000011100,
|
||||
0b000111000000000000111000,
|
||||
0b000111000000000000111000,
|
||||
0b000011100000000001110000,
|
||||
0b000011100000000001110000,
|
||||
0b000001110000000011100000,
|
||||
0b000001110000000011100000,
|
||||
0b000000111000000111000000,
|
||||
0b000000111000000111000000,
|
||||
0b000000011100001110000000,
|
||||
0b000000011100001110000000,
|
||||
0b000000001110011100000000,
|
||||
0b000000001110011100000000,
|
||||
0b000000000111111000000000,
|
||||
0b000000000111111000000000,
|
||||
0b000000000011110000000000,
|
||||
0b000000000011110000000000,
|
||||
0b000000000001100000000000,
|
||||
0b000000000001100000000000,
|
||||
};
|
||||
|
||||
private static final int patternSize = 24;
|
||||
|
||||
public GenLayerEaglerRivers(long parLong1, GenLayer p) {
|
||||
super(parLong1);
|
||||
this.parent = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getInts(int x, int y, int w, int h) {
|
||||
int[] aint = this.parent.getInts(x, y, w, h);
|
||||
int[] aint1 = IntCache.getIntCache(w * h);
|
||||
|
||||
long a = worldGenSeed * 6364136223846793005L + 1442695040888963407L;
|
||||
long b = ((a & 112104l) == 0) ? (((a & 534l) == 0) ? 1l : 15l) : 746l;
|
||||
for (int yy = 0; yy < h; ++yy) {
|
||||
for (int xx = 0; xx < w; ++xx) {
|
||||
int i = xx + yy * w;
|
||||
aint1[i] = aint[i];
|
||||
long xxx = (long)(x + xx) & 0xFFFFFFFFl;
|
||||
long yyy = (long)(y + yy) & 0xFFFFFFFFl;
|
||||
long hash = a + (xxx / patternSize);
|
||||
hash *= hash * 6364136223846793005L + 1442695040888963407L;
|
||||
hash += (yyy / patternSize);
|
||||
hash *= hash * 6364136223846793005L + 1442695040888963407L;
|
||||
hash += a;
|
||||
if ((hash & b) == 0l) {
|
||||
xxx %= (long)patternSize;
|
||||
yyy %= (long)patternSize;
|
||||
long tmp;
|
||||
switch((int)((hash >>> 16l) & 3l)) {
|
||||
case 1:
|
||||
tmp = xxx;
|
||||
xxx = yyy;
|
||||
yyy = (long)patternSize - tmp - 1l;
|
||||
break;
|
||||
case 2:
|
||||
tmp = xxx;
|
||||
xxx = (long)patternSize - yyy - 1l;
|
||||
yyy = tmp;
|
||||
break;
|
||||
case 3:
|
||||
tmp = xxx;
|
||||
xxx = (long)patternSize - yyy - 1l;
|
||||
yyy = (long)patternSize - tmp - 1l;
|
||||
break;
|
||||
}
|
||||
if((pattern[(int)yyy] & (1 << (int)xxx)) != 0) {
|
||||
aint1[i] = BiomeGenBase.river.biomeID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aint1;
|
||||
}
|
||||
|
||||
}
|
@ -2,8 +2,8 @@ package net.lax1dude.eaglercraft.v1_8.sp.server.socket;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.EaglerOutputStream;
|
||||
@ -48,10 +48,9 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
public final String playerChannel;
|
||||
private EnumConnectionState packetState = EnumConnectionState.HANDSHAKING;
|
||||
private static PacketBuffer temporaryBuffer;
|
||||
private static EaglerOutputStream temporaryOutputStream;
|
||||
private static byte[] compressedPacketTmp;
|
||||
private int debugPacketCounter = 0;
|
||||
private byte[][] recievedPacketBuffer = new byte[16384][];
|
||||
private int recievedPacketBufferCounter = 0;
|
||||
private final List<byte[]> recievedPacketBuffer = new LinkedList<>();
|
||||
private final boolean enableSendCompression;
|
||||
|
||||
private boolean firstPacket = true;
|
||||
@ -69,11 +68,6 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
}
|
||||
this.playerChannel = playerChannel;
|
||||
this.enableSendCompression = !SingleplayerServerController.PLAYER_CHANNEL.equals(playerChannel);
|
||||
if(this.enableSendCompression) {
|
||||
if(temporaryOutputStream == null) {
|
||||
temporaryOutputStream = new EaglerOutputStream(16386);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
@ -97,19 +91,14 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
}
|
||||
|
||||
public void addRecievedPacket(byte[] next) {
|
||||
if(recievedPacketBufferCounter < recievedPacketBuffer.length - 1) {
|
||||
recievedPacketBuffer[recievedPacketBufferCounter++] = next;
|
||||
}else {
|
||||
logger.error("Dropping packets on recievedPacketBuffer for channel \"{}\"! (overflow)", playerChannel);
|
||||
}
|
||||
recievedPacketBuffer.add(next);
|
||||
}
|
||||
|
||||
public void processReceivedPackets() {
|
||||
if(nethandler == null) return;
|
||||
|
||||
|
||||
for(int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
byte[] data = recievedPacketBuffer[i];
|
||||
while(!recievedPacketBuffer.isEmpty()) {
|
||||
byte[] data = recievedPacketBuffer.remove(0);
|
||||
byte[] fullData;
|
||||
|
||||
if(enableSendCompression) {
|
||||
@ -132,7 +121,6 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
ServerPlatformSingleplayer.sendPacket(new IPCPacketData(playerChannel, kickPacketBAO.toByteArray()));
|
||||
closeChannel(new ChatComponentText("Recieved unsuppoorted connection from an Eaglercraft 1.5.2 client!"));
|
||||
firstPacket = false;
|
||||
recievedPacketBufferCounter = 0;
|
||||
return;
|
||||
}
|
||||
firstPacket = false;
|
||||
@ -169,7 +157,6 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
fullData = data;
|
||||
}
|
||||
|
||||
recievedPacketBuffer[i] = null;
|
||||
++debugPacketCounter;
|
||||
try {
|
||||
ByteBuf nettyBuffer = Unpooled.buffer(fullData, fullData.length);
|
||||
@ -206,7 +193,6 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
recievedPacketBufferCounter = 0;
|
||||
}
|
||||
|
||||
public void sendPacket(Packet pkt) {
|
||||
@ -234,22 +220,24 @@ public class IntegratedServerPlayerNetworkManager {
|
||||
int len = temporaryBuffer.readableBytes();
|
||||
if(enableSendCompression) {
|
||||
if(len > compressionThreshold) {
|
||||
temporaryOutputStream.reset();
|
||||
byte[] compressedData;
|
||||
if(compressedPacketTmp == null || compressedPacketTmp.length < len) {
|
||||
compressedPacketTmp = new byte[len];
|
||||
}
|
||||
int cmpLen;
|
||||
try {
|
||||
temporaryOutputStream.write(2);
|
||||
temporaryOutputStream.write((len >>> 24) & 0xFF);
|
||||
temporaryOutputStream.write((len >>> 16) & 0xFF);
|
||||
temporaryOutputStream.write((len >>> 8) & 0xFF);
|
||||
temporaryOutputStream.write(len & 0xFF);
|
||||
try(OutputStream os = EaglerZLIB.newDeflaterOutputStream(temporaryOutputStream)) {
|
||||
temporaryBuffer.readBytes(os, len);
|
||||
}
|
||||
compressedData = temporaryOutputStream.toByteArray();
|
||||
cmpLen = EaglerZLIB.deflateFull(temporaryBuffer.array(), 0, len, compressedPacketTmp, 0, compressedPacketTmp.length);
|
||||
}catch(IOException ex) {
|
||||
logger.error("Failed to compress packet {}!", pkt.getClass().getSimpleName());
|
||||
logger.error(ex);
|
||||
return;
|
||||
}
|
||||
byte[] compressedData = new byte[5 + cmpLen];
|
||||
compressedData[0] = (byte)2;
|
||||
compressedData[1] = (byte)((len >>> 24) & 0xFF);
|
||||
compressedData[2] = (byte)((len >>> 16) & 0xFF);
|
||||
compressedData[3] = (byte)((len >>> 8) & 0xFF);
|
||||
compressedData[4] = (byte)(len & 0xFF);
|
||||
System.arraycopy(compressedPacketTmp, 0, compressedData, 5, cmpLen);
|
||||
if(compressedData.length > fragmentSize) {
|
||||
int fragmentSizeN1 = fragmentSize - 1;
|
||||
for (int j = 1; j < compressedData.length; j += fragmentSizeN1) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.lax1dude.eaglercraft.v1_8.sp.socket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.EnumEaglerConnectionState;
|
||||
import net.lax1dude.eaglercraft.v1_8.internal.IPCPacketData;
|
||||
@ -34,8 +36,7 @@ import net.minecraft.util.IChatComponent;
|
||||
public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkManager {
|
||||
|
||||
private int debugPacketCounter = 0;
|
||||
private byte[][] recievedPacketBuffer = new byte[16384][];
|
||||
private int recievedPacketBufferCounter = 0;
|
||||
private final List<byte[]> recievedPacketBuffer = new LinkedList<>();
|
||||
public boolean isPlayerChannelOpen = false;
|
||||
|
||||
public ClientIntegratedServerNetworkManager(String channel) {
|
||||
@ -65,20 +66,15 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
||||
}
|
||||
|
||||
public void addRecievedPacket(byte[] next) {
|
||||
if(recievedPacketBufferCounter < recievedPacketBuffer.length - 1) {
|
||||
recievedPacketBuffer[recievedPacketBufferCounter++] = next;
|
||||
}else {
|
||||
logger.error("Dropping packets on recievedPacketBuffer for channel \"{}\"! (overflow)", address);
|
||||
}
|
||||
recievedPacketBuffer.add(next);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processReceivedPackets() throws IOException {
|
||||
if(nethandler == null) return;
|
||||
|
||||
for(int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
byte[] next = recievedPacketBuffer[i];
|
||||
recievedPacketBuffer[i] = null;
|
||||
while(!recievedPacketBuffer.isEmpty()) {
|
||||
byte[] next = recievedPacketBuffer.remove(0);
|
||||
++debugPacketCounter;
|
||||
try {
|
||||
ByteBuf nettyBuffer = Unpooled.buffer(next, next.length);
|
||||
@ -115,7 +111,6 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
||||
logger.error(t);
|
||||
}
|
||||
}
|
||||
recievedPacketBufferCounter = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,9 +165,6 @@ public class ClientIntegratedServerNetworkManager extends EaglercraftNetworkMana
|
||||
}
|
||||
|
||||
public void clearRecieveQueue() {
|
||||
for(int i = 0; i < recievedPacketBufferCounter; ++i) {
|
||||
recievedPacketBuffer[i] = null;
|
||||
}
|
||||
recievedPacketBufferCounter = 0;
|
||||
recievedPacketBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user