Archived
0

Merge branch 'dev/sonar-fix' into development

This commit is contained in:
2019-02-11 16:18:52 +03:00
30 changed files with 203 additions and 259 deletions

View File

@@ -1,7 +1,6 @@
package com.flowpowered.nbt; package com.flowpowered.nbt;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public enum TagType { public enum TagType {

View File

@@ -7,7 +7,6 @@ import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkProvider; import mc.core.world.chunk.ChunkProvider;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -20,7 +19,7 @@ public class AnvilChunkProvider implements ChunkProvider {
public AnvilChunkProvider(String mapPath) { public AnvilChunkProvider(String mapPath) {
Path pathMap = Paths.get(mapPath); Path pathMap = Paths.get(mapPath);
if (Files.exists(pathMap)) { if (pathMap.toFile().exists()) {
log.info("Use Anvil map from \"{}\"", pathMap); log.info("Use Anvil map from \"{}\"", pathMap);
this.setRegionManager(new RegionManager(pathMap.resolve("region"))); this.setRegionManager(new RegionManager(pathMap.resolve("region")));
} else { } else {

View File

@@ -2,7 +2,6 @@ package mc.world.anvil;
import gnu.trove.list.TByteList; import gnu.trove.list.TByteList;
import gnu.trove.list.array.TByteArrayList; import gnu.trove.list.array.TByteArrayList;
import gnu.trove.list.linked.TByteLinkedList;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import mc.core.utils.NibbleArray; import mc.core.utils.NibbleArray;

View File

@@ -7,7 +7,6 @@ import mc.core.utils.CompactedCoords;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@@ -32,7 +31,7 @@ public class RegionManager {
return regions.get(xz); return regions.get(xz);
} else { } else {
Path regionFilePath = regionFilesPath.resolve("r." + x + "." + z + ".mca"); Path regionFilePath = regionFilesPath.resolve("r." + x + "." + z + ".mca");
if (Files.exists(regionFilePath)) { if (regionFilePath.toFile().exists()) {
try { try {
Region region = new Region(regionFilePath.toFile()); Region region = new Region(regionFilePath.toFile());
regions.put(xz, region); regions.put(xz, region);

View File

@@ -19,42 +19,24 @@ public class CoreEventListener {
EventBus.getInstance().registerSubscribes(this); EventBus.getInstance().registerSubscribes(this);
} }
@Subscriber private void processLoadChunks(CS_PlayerMoveEvent event, int cMinX, int cMaxX, int cMinZ, int cMaxZ) {
public void handlerPlayerMoveEvent(CS_PlayerMoveEvent event) {
Chunk chunk;
chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation().toBlockLocation()); // Old chunk
if (chunk == null) return;
int ccX = chunk.getX();
int ccZ = chunk.getZ();
chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation().toBlockLocation()); // Next chunk
if (chunk == null) return;
int ncX = chunk.getX();
int ncZ = chunk.getZ();
if (event.isRecalcChunk() || (ncX != ccX || ncZ != ccZ)) {
final int viewDistance = event.getPlayer().getSettings().getViewDistance() + 1;
int cMinX = chunk.getX() - viewDistance;
int cMaxX = chunk.getX() + viewDistance;
int cMinZ = chunk.getZ() - viewDistance;
int cMaxZ = chunk.getZ() + viewDistance;
SC_ChunkLoadEvent eventChunkLoad = new SC_ChunkLoadEvent(event.getPlayer()); SC_ChunkLoadEvent eventChunkLoad = new SC_ChunkLoadEvent(event.getPlayer());
for (int cZ = cMinZ; cZ <= cMaxZ; cZ++) { for (int cZ = cMinZ; cZ <= cMaxZ; cZ++) {
for (int cX = cMinX; cX <= cMaxX; cX++) { for (int cX = cMinX; cX <= cMaxX; cX++) {
int compressXZ = CompactedCoords.compressXZ(cX, cZ); int compressXZ = CompactedCoords.compressXZ(cX, cZ);
if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) {
if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) { if (!event.getPlayer().getLoadedChunks().contains(compressXZ)) {
eventChunkLoad.getNeedLoadChunks().add(compressXZ); eventChunkLoad.getNeedLoadChunks().add(compressXZ);
event.getPlayer().getLoadedChunks().add(compressXZ); event.getPlayer().getLoadedChunks().add(compressXZ);
} }
} }
} }
}
if (!eventChunkLoad.getNeedLoadChunks().isEmpty()) { if (!eventChunkLoad.getNeedLoadChunks().isEmpty()) {
EventBus.getInstance().post(eventChunkLoad); EventBus.getInstance().post(eventChunkLoad);
} }
}
private void processUnloadChunks(CS_PlayerMoveEvent event, int cMinX, int cMaxX, int cMinZ, int cMaxZ) {
SC_ChunkUnloadEvent eventChunkUnload = new SC_ChunkUnloadEvent(event.getPlayer()); SC_ChunkUnloadEvent eventChunkUnload = new SC_ChunkUnloadEvent(event.getPlayer());
Iterator<Integer> itr = event.getPlayer().getLoadedChunks().iterator(); Iterator<Integer> itr = event.getPlayer().getLoadedChunks().iterator();
while(itr.hasNext()) { while(itr.hasNext()) {
@@ -71,6 +53,30 @@ public class CoreEventListener {
} }
} }
@Subscriber
public void handlerPlayerMoveEvent(CS_PlayerMoveEvent event) {
Chunk chunk;
chunk = event.getPlayer().getWorld().getChunk(event.getOldLocation().toBlockLocation()); // Old chunk
if (chunk == null) return;
int ccX = chunk.getX();
int ccZ = chunk.getZ();
chunk = event.getPlayer().getWorld().getChunk(event.getNewLocation().toBlockLocation()); // Next chunk
if (chunk == null) return;
int ncX = chunk.getX();
int ncZ = chunk.getZ();
if (event.isRecalcChunk() || (ncX != ccX || ncZ != ccZ)) {
final int viewDistance = event.getPlayer().getSettings().getViewDistance() + 1;
final int cMinX = chunk.getX() - viewDistance;
final int cMaxX = chunk.getX() + viewDistance;
final int cMinZ = chunk.getZ() - viewDistance;
final int cMaxZ = chunk.getZ() + viewDistance;
processLoadChunks(event, cMinX, cMaxX, cMinZ, cMaxZ);
processUnloadChunks(event, cMinX, cMaxX, cMinZ, cMaxZ);
}
event.getPlayer().getLocation().setXYZ( event.getPlayer().getLocation().setXYZ(
event.getNewLocation().getX(), event.getNewLocation().getX(),
event.getNewLocation().getY(), event.getNewLocation().getY(),

View File

@@ -3,12 +3,14 @@ package mc.core;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import mc.core.world.block.BlockLocation; import mc.core.world.block.BlockLocation;
@Slf4j
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Data @Data
public class EntityLocation implements Cloneable { public class EntityLocation {
private double x, y, z; private double x, y, z;
private float yaw, pitch; private float yaw, pitch;
@@ -48,13 +50,7 @@ public class EntityLocation implements Cloneable {
return new BlockLocation(getBlockX(), getBlockY(), getBlockZ()); return new BlockLocation(getBlockX(), getBlockY(), getBlockZ());
} }
@Override public EntityLocation copy() {
public EntityLocation clone() { return new EntityLocation(x, y, z, yaw, pitch);
try {
return (EntityLocation) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return ZERO();
}
} }
} }

View File

@@ -7,17 +7,16 @@ import org.apache.commons.io.IOUtils;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext;
import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@Slf4j @Slf4j
public class Main { public class Main {
private static ApplicationContext createContext() { private static ApplicationContext createContext() {
final String springXml = System.getProperty("springConfig", "./spring.xml"); final String springXml = System.getProperty("springConfig", "./spring.xml");
if (!Files.exists(Paths.get(springXml))) { if (!(new File(springXml)).exists()) {
log.info("File \"{}\" not found. Get default config.", springXml); log.info("File \"{}\" not found. Get default config.", springXml);
try (FileOutputStream fos = new FileOutputStream(springXml)) { try (FileOutputStream fos = new FileOutputStream(springXml)) {
IOUtils.copy(Main.class.getResourceAsStream("/spring.xml"), fos); IOUtils.copy(Main.class.getResourceAsStream("/spring.xml"), fos);

View File

@@ -2,7 +2,6 @@ package mc.core.embedded;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.network.Server; import mc.core.network.Server;
import mc.core.network.StartServerException;
@Slf4j @Slf4j
public class FakeServer implements Server { public class FakeServer implements Server {

View File

@@ -31,7 +31,7 @@ public abstract class NetInputStream extends InputStream {
public abstract double readDouble(); public abstract double readDouble();
public abstract String readString(); public abstract String readString();
public abstract UUID readUUID(); public abstract UUID readUUID();
public abstract Tag<?> readNBT(); public abstract Tag readNBT();
public abstract void skipBytes(int count); public abstract void skipBytes(int count);

View File

@@ -1,8 +1,11 @@
package mc.core.utils; package mc.core.utils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class CompactedCoords { public class CompactedCoords {
public static int compressXZ(int x, int z) { public static int compressXZ(int x, int z) {
if (x < Short.MIN_VALUE || x > Short.MAX_VALUE || if (x < Short.MIN_VALUE || x > Short.MAX_VALUE ||

View File

@@ -2,7 +2,6 @@ package mc.core.world;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays; import java.util.Arrays;

View File

@@ -3,11 +3,13 @@ package mc.core.world.block;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Data @Data
public class BlockLocation implements Cloneable { public class BlockLocation {
private int x, y, z; private int x, y, z;
public static BlockLocation ZERO() { public static BlockLocation ZERO() {
@@ -20,13 +22,7 @@ public class BlockLocation implements Cloneable {
this.z = z; this.z = z;
} }
@Override public BlockLocation copy() {
public BlockLocation clone() { return new BlockLocation(x, y, z);
try {
return (BlockLocation) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return ZERO();
}
} }
} }

View File

@@ -37,9 +37,9 @@ class EntityLocationTest {
} }
@Test @Test
void clone_() { void copy() {
EntityLocation locOrig = new EntityLocation(x, y, z, yaw, pitch); EntityLocation locOrig = new EntityLocation(x, y, z, yaw, pitch);
EntityLocation locClone = locOrig.clone(); EntityLocation locClone = locOrig.copy();
assertEquals(locOrig, locClone); assertEquals(locOrig, locClone);
assertNotSame(locOrig, locClone); assertNotSame(locOrig, locClone);
} }

View File

@@ -26,7 +26,7 @@ class ImmutableEntityLocationTest {
@Test @Test
void clone_() { void clone_() {
EntityLocation locOrig = new ImmutableEntityLocation(1d, 2d, 3d, 4f, 5f); EntityLocation locOrig = new ImmutableEntityLocation(1d, 2d, 3d, 4f, 5f);
EntityLocation locClone = locOrig.clone(); EntityLocation locClone = locOrig.copy();
assertEquals(locOrig, locClone); assertEquals(locOrig, locClone);
} }

View File

@@ -31,9 +31,9 @@ class BlockLocationTest {
} }
@Test @Test
void clone_() { void copy() {
BlockLocation locOrig = new BlockLocation(x, y, z); BlockLocation locOrig = new BlockLocation(x, y, z);
BlockLocation locClone = locOrig.clone(); BlockLocation locClone = locOrig.copy();
assertEquals(locOrig, locClone); assertEquals(locOrig, locClone);
} }
} }

View File

@@ -12,7 +12,6 @@ import mc.core.player.PlayerManager;
import mc.core.player.PlayerSettings; import mc.core.player.PlayerSettings;
import mc.core.world.World; import mc.core.world.World;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.*; import java.util.*;
@@ -30,7 +29,7 @@ public class H2PlayerManager implements PlayerManager {
H2Player h2Player = new H2Player(); H2Player h2Player = new H2Player();
h2Player.setName(name); h2Player.setName(name);
h2Player.setUuid(UUID.randomUUID()); h2Player.setUuid(UUID.randomUUID());
h2Player.setLocation(location.clone()); h2Player.setLocation(location.copy());
h2Player.setLoadedChunks(new ArrayList<>()); h2Player.setLoadedChunks(new ArrayList<>());
h2Player.setWorld(world); h2Player.setWorld(world);
h2Player.setSettings(new PlayerSettings()); h2Player.setSettings(new PlayerSettings());

View File

@@ -1,6 +1,7 @@
package mc.core.network.proto_1_12_2; package mc.core.network.proto_1_12_2;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class ByteArrayOutputNetStream extends NetOutputStream_p340 { public class ByteArrayOutputNetStream extends NetOutputStream_p340 {
private ByteArrayOutputStream baos = new ByteArrayOutputStream(); private ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -61,6 +62,11 @@ public class ByteArrayOutputNetStream extends NetOutputStream_p340 {
writeLong(Double.doubleToLongBits(value)); writeLong(Double.doubleToLongBits(value));
} }
@Override
public void close() throws IOException {
baos.close();
}
public int size() { public int size() {
return baos.size(); return baos.size();
} }

View File

@@ -62,7 +62,7 @@ public abstract class NetInputStream_p340 extends NetInputStream {
} }
@Override @Override
public Tag<?> readNBT() { public Tag readNBT() {
if (nbtInputStream == null) { if (nbtInputStream == null) {
try { try {
nbtInputStream = new NBTInputStream(this, false); nbtInputStream = new NBTInputStream(this, false);

View File

@@ -78,7 +78,6 @@ public enum State {
.put(0x0E, PlayerPositionAndLookPacket.class) .put(0x0E, PlayerPositionAndLookPacket.class)
.put(0x0F, PlayerLookPacket.class) .put(0x0F, PlayerLookPacket.class)
.put(0x13, PlayerAbilitiesPacket.class) .put(0x13, PlayerAbilitiesPacket.class)
.put(0x1A, HeldItemChangePacket.class)
.build(), .build(),
ImmutableMap.<Class<? extends SCPacket>, Integer>builder() ImmutableMap.<Class<? extends SCPacket>, Integer>builder()
.put(BossBarPacket.class, 0x0C) .put(BossBarPacket.class, 0x0C)

View File

@@ -17,8 +17,8 @@ public class TeleportManager {
@AllArgsConstructor @AllArgsConstructor
private class TpData { private class TpData {
public Player player; Player player;
public EntityLocation newLocation; EntityLocation newLocation;
// TODO необходимо добавить TimeStamp, что бы понимать, когда клиент отвергнул телепортацию // TODO необходимо добавить TimeStamp, что бы понимать, когда клиент отвергнул телепортацию
// т.е. идея такова: долгое молчание клиента знак отвержения телепортации. // т.е. идея такова: долгое молчание клиента знак отвержения телепортации.
} }
@@ -34,7 +34,7 @@ public class TeleportManager {
teleportId = RAND.nextInt(9999); teleportId = RAND.nextInt(9999);
} while (teleportMap.containsKey(teleportId)); } while (teleportMap.containsKey(teleportId));
teleportMap.put(teleportId, new TpData(player, location.clone())); teleportMap.put(teleportId, new TpData(player, location.copy()));
return teleportId; return teleportId;
} }

View File

@@ -1,13 +0,0 @@
package mc.core.network.proto_1_12_2.packets.clientside;
import mc.core.network.CSPacket;
import mc.core.network.NetInputStream;
public class HeldItemChangePacket implements CSPacket {
private int slot;
@Override
public void readSelf(NetInputStream netStream) {
this.slot = netStream.readShort();
}
}

View File

@@ -13,9 +13,11 @@ import mc.core.world.block.BlockType;
import mc.core.world.chunk.Chunk; import mc.core.world.chunk.Chunk;
import mc.core.world.chunk.ChunkSection; import mc.core.world.chunk.ChunkSection;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/* /*
Packet structure Packet structure
@@ -88,19 +90,13 @@ public class ChunkDataPacket implements SCPacket {
this.sectionList = sectionList; this.sectionList = sectionList;
} }
@Override /**
public void writeSelf(NetOutputStream netStream) { * @return max height chunk
if (sectionList == null && chunk == null) { */
log.warn("Empty chunk data!"); //TODO для такого нужна заглушка private int calcAndWriteBitMask(NetOutputStream netStream) {
return;
}
netStream.writeInt(x); // Chunk X
netStream.writeInt(z); // Chunk Y
netStream.writeBoolean(initChunk); // Init Chunk
int maxH = 0; int maxH = 0;
int bitMask = 0; int bitMask = 0;
if (sectionList == null && chunk != null) { if (sectionList == null && chunk != null) {
for (int h = 15; h >= 0; h--) { for (int h = 15; h >= 0; h--) {
bitMask = bitMask << 1; bitMask = bitMask << 1;
@@ -125,28 +121,27 @@ public class ChunkDataPacket implements SCPacket {
} }
} }
} }
netStream.writeVarInt(bitMask); // Primary Bit Mask netStream.writeVarInt(bitMask); // Primary Bit Mask
final ByteArrayOutputNetStream data = new ByteArrayOutputNetStream(); return maxH;
}
final ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream();
boolean biomeWrite = true;
List<CompoundTag> nbtList = new ArrayList<>();
for (int h = 0; h < maxH; h++) {
ChunkSection chunkSection = null;
private ChunkSection getChunkSection(int h) {
if (chunk != null) { if (chunk != null) {
chunkSection = chunk.getChunkSection(h); return chunk.getChunkSection(h);
} else if (sectionList != null) { } else if (sectionList != null) {
chunkSection = sectionList.remove(0); return sectionList.remove(0);
} }
if (chunkSection == null) { return null;
continue;
} }
private PalettedChunkSection createPalette(final ChunkSection chunkSection,
final List<CompoundTag> nbtList,
final AtomicBoolean biomeWrite,
final ByteArrayOutputNetStream biomes) {
final PalettedChunkSection palettedChunkSection = new PalettedChunkSection(); final PalettedChunkSection palettedChunkSection = new PalettedChunkSection();
for (int y = 0; y < 16; y++) { for (int y = 0; y < 16; y++) {
@@ -164,21 +159,51 @@ public class ChunkDataPacket implements SCPacket {
nbtList.add(nbt); nbtList.add(nbt);
} }
if (biomeWrite) { if (biomeWrite.get()) {
biomes.writeByte(chunk.getBiome( biomes.writeByte(chunk.getBiome(
(chunk.getX() << 4) + x, (chunk.getX() << 4) + x,
(chunk.getZ() << 4) + z (chunk.getZ() << 4) + z
).getId()); ).getId());
if (x == 15 && z == 15) { if (x == 15 && z == 15) {
biomeWrite = false; biomeWrite.set(false);
} }
} }
} }
} }
} }
return palettedChunkSection;
}
@Override
public void writeSelf(NetOutputStream netStream) {
if (sectionList == null && chunk == null) {
log.warn("Empty chunk data!"); //TODO для такого нужна заглушка
return;
}
netStream.writeInt(x); // Chunk X
netStream.writeInt(z); // Chunk Y
netStream.writeBoolean(initChunk); // Init Chunk
final int maxH = calcAndWriteBitMask(netStream);
try (ByteArrayOutputNetStream data = new ByteArrayOutputNetStream();
ByteArrayOutputNetStream biomes = new ByteArrayOutputNetStream()) {
AtomicBoolean biomeWrite = new AtomicBoolean(true);
List<CompoundTag> nbtList = new ArrayList<>();
for (int h = 0; h < maxH; h++) {
final ChunkSection chunkSection = getChunkSection(h);
if (chunkSection == null) {
continue;
}
// <Chunk Section> // <Chunk Section>
palettedChunkSection.writeToNetStream(data); createPalette(chunkSection, nbtList, biomeWrite, biomes)
.writeToNetStream(data);
// </Chunk Section> // </Chunk Section>
} }
// <Biomes> // <Biomes>
@@ -193,6 +218,9 @@ public class ChunkDataPacket implements SCPacket {
netStream.writeNBT(compoundTag); netStream.writeNBT(compoundTag);
} }
// </NBT> // </NBT>
} catch (IOException e) {
log.error("", e);
}
} }
@Override @Override
@@ -240,7 +268,7 @@ public class ChunkDataPacket implements SCPacket {
this.skyLight.set(bx, by, bz, skyLight); this.skyLight.set(bx, by, bz, skyLight);
} }
void writeToNetStream(final NetOutputStream netOutputStream) { private int getBitsPerBlock() {
int bitsPerBlock = 4; int bitsPerBlock = 4;
if (palette.size() > 15) { if (palette.size() > 15) {
if (palette.size() <= 31) if (palette.size() <= 31)
@@ -253,15 +281,12 @@ public class ChunkDataPacket implements SCPacket {
bitsPerBlock = 8; bitsPerBlock = 8;
} }
// <Palette> return bitsPerBlock;
netOutputStream.writeUnsignedByte(bitsPerBlock); // Bits Per Block }
netOutputStream.writeVarInt(palette.size()); // Size of palette
palette.forEach(netOutputStream::writeVarInt); // Palette private void writePalette(final int bitsPerBlock,
// </Palette> final NetOutputStream netOutputStream) {
// <Data Array>
final int dataLength = (4096/*16*16*16*/ * bitsPerBlock) / 64/*size of long in bits*/;
netOutputStream.writeVarInt(dataLength); // Size of Data Array
// <Array>
long value = 0; long value = 0;
int lastPos = 0; int lastPos = 0;
boolean fairy = false; boolean fairy = false;
@@ -296,6 +321,21 @@ public class ChunkDataPacket implements SCPacket {
} }
} }
netOutputStream.writeLong(value); netOutputStream.writeLong(value);
}
void writeToNetStream(final NetOutputStream netOutputStream) {
final int bitsPerBlock = getBitsPerBlock();
// <Palette>
netOutputStream.writeUnsignedByte(bitsPerBlock); // Bits Per Block
netOutputStream.writeVarInt(palette.size()); // Size of palette
palette.forEach(netOutputStream::writeVarInt); // Palette
// </Palette>
// <Data Array>
final int dataLength = (4096/*16*16*16*/ * bitsPerBlock) / 64/*size of long in bits*/;
netOutputStream.writeVarInt(dataLength); // Size of Data Array
// <Array>
writePalette(bitsPerBlock, netOutputStream);
// </Array> // </Array>
// </Data Array> // </Data Array>
// <Block Light> // <Block Light>

View File

@@ -1,63 +0,0 @@
package mc.core.network.proto_1_12_2.serializers;
import mc.core.world.block.BlockLocation;
import static com.google.common.math.IntMath.isPowerOfTwo;
public class BlockLocationSerializer {
private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[] {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
private static final int NUM_X_BITS = 1 + log2(smallestEncompassingPowerOfTwo(30000000));
private static final int NUM_Z_BITS = NUM_X_BITS;
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
private static final int Y_SHIFT = NUM_Z_BITS;
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
/*
* net.minecraft.util.math.MathHelper#log2(int)
*/
private static int log2(int value) {
return log2DeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1);
}
/*
* net.minecraft.util.math.MathHelper#log2DeBruijn(int)
*/
private static int log2DeBruijn(int value) {
value = isPowerOfTwo(value) ? value : smallestEncompassingPowerOfTwo(value);
return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int)((long)value * 125613361L >> 27) & 31];
}
/*
* net.minecraft.util.math.MathHelper#smallestEncompassingPowerOfTwo(int)
*/
private static int smallestEncompassingPowerOfTwo(int value) {
int i = value - 1;
i = i | i >> 1;
i = i | i >> 2;
i = i | i >> 4;
i = i | i >> 8;
i = i | i >> 16;
return i + 1;
}
public static long toLong(BlockLocation location) {
return ((long)location.getX() & X_MASK) << X_SHIFT |
((long)location.getY() & Y_MASK) << Y_SHIFT |
((long)location.getZ() & Z_MASK);
}
public static BlockLocation fromLong(long value) {
BlockLocation location = BlockLocation.ZERO();
fromLong(value, location);
return location;
}
public static void fromLong(long value, BlockLocation location) {
location.setX((int)(value << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS));
location.setY((int)(value << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS));
location.setZ((int)(value << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS));
}
}

View File

@@ -81,4 +81,9 @@ public class ByteArrayInputNetStream extends NetInputStream_p340 {
public void skipBytes(int count) { public void skipBytes(int count) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void close() throws IOException {
bais.close();
}
} }

View File

@@ -1,32 +0,0 @@
package mc.core.network.proto_1_12_2.serializers;
import mc.core.world.block.BlockLocation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.concurrent.ThreadLocalRandom;
import static org.junit.jupiter.api.Assertions.assertEquals;
class BlockLocationSerializerTest {
private static final ThreadLocalRandom rnd = ThreadLocalRandom.current();
private static final int minI = 0, maxI = 10;
private int x, y, z;
@BeforeEach
void before() {
x = rnd.nextInt(minI, maxI);
y = rnd.nextInt(minI, maxI);
z = rnd.nextInt(minI, maxI);
}
@Test
void serialize() {
BlockLocation location = new BlockLocation(x, y, z);
final long serializedCoords = BlockLocationSerializer.toLong(location);
BlockLocation deserLoc = BlockLocationSerializer.fromLong(serializedCoords);
assertEquals(location, deserLoc);
}
}

View File

@@ -32,6 +32,9 @@ public class PacketDecoder extends ReplayingDecoder<CSPacket> {
@Override @Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
State state = ctx.channel().attr(ATTR_STATE).get(); State state = ctx.channel().attr(ATTR_STATE).get();
/* FIXME: SONAR посчитал нужным здесь задействовать try-with-resources
* однако для ByteBuf не существует понятия `close`. Необходимо проанализировать необходимость
* использования реализации интерфейса InputStream и если её нет, то убрать. */
NetInputStream netStream = new WrapperNetInputStream(in); NetInputStream netStream = new WrapperNetInputStream(in);
int packetSize = netStream.readVarInt(); int packetSize = netStream.readVarInt();

View File

@@ -27,6 +27,9 @@ public class PacketEncoder extends MessageToByteEncoder<SCPacket> {
log.debug("Send {}:{}", state, packet); log.debug("Send {}:{}", state, packet);
try { try {
/* FIXME: SONAR посчитал нужным здесь задействовать try-with-resources
* однако для ByteBuf не существует понятия `close`. Необходимо проанализировать необходимость
* использования реализации интерфейса OutputStream и если её нет, то убрать. */
NetOutputStream netStream = new WrapperNetOutputStream(out); NetOutputStream netStream = new WrapperNetOutputStream(out);
netStream.writeVarInt(id); netStream.writeVarInt(id);
packet.writeSelf(netStream); packet.writeSelf(netStream);

View File

@@ -32,6 +32,9 @@ public class PacketPostEncoder extends MessageToByteEncoder<ByteBuf> {
} }
out.ensureWritable(sizeOfPktSize + pktSize); out.ensureWritable(sizeOfPktSize + pktSize);
/* FIXME: SONAR посчитал нужным здесь задействовать try-with-resources
* однако для ByteBuf не существует понятия `close`. Необходимо проанализировать необходимость
* использования реализации интерфейса OutputStream и если её нет, то убрать. */
(new WrapperNetOutputStream(out)).writeVarInt(pktSize); (new WrapperNetOutputStream(out)).writeVarInt(pktSize);
out.writeBytes(msg); out.writeBytes(msg);
} }

View File

@@ -28,7 +28,7 @@ public class PlayerEventListener {
@Subscriber @Subscriber
public void playerChunkLoadHandler(SC_ChunkLoadEvent event) { public void playerChunkLoadHandler(SC_ChunkLoadEvent event) {
if (event.getNeedLoadChunks().size() == 0) return; if (event.getNeedLoadChunks().isEmpty()) return;
final NetChannel channel = event.getPlayer().getChannel(); final NetChannel channel = event.getPlayer().getChannel();
@@ -51,7 +51,7 @@ public class PlayerEventListener {
@Subscriber @Subscriber
public void playerChunkUnloadHandler(SC_ChunkUnloadEvent event) { public void playerChunkUnloadHandler(SC_ChunkUnloadEvent event) {
if (event.getNeedUnloadChunks().size() == 0) return; if (event.getNeedUnloadChunks().isEmpty()) return;
final NetChannel channel = event.getPlayer().getChannel(); final NetChannel channel = event.getPlayer().getChannel();

View File

@@ -74,7 +74,7 @@ public class PlayHandler extends AbstractStateHandler implements PlayStateHandle
return; return;
} }
CS_PlayerMoveEvent event = new CS_PlayerMoveEvent(player, player.getLocation().clone()); CS_PlayerMoveEvent event = new CS_PlayerMoveEvent(player, player.getLocation().copy());
event.setNewLocation(new EntityLocation( event.setNewLocation(new EntityLocation(
packet.getX(), packet.getY(), packet.getZ(), packet.getX(), packet.getY(), packet.getZ(),
player.getLocation().getYaw(), player.getLocation().getYaw(),