Archived
0

Merged in dmitriymx/location-refactory (pull request #5)

Dmitriymx/location refactory
This commit is contained in:
2018-08-10 13:12:41 +00:00
committed by Daniil Glazko
23 changed files with 262 additions and 203 deletions

View File

@@ -35,8 +35,9 @@ subprojects {
/* Components */ /* Components */
compile (group: 'org.projectlombok', name: 'lombok', version: '1.16.16') compile (group: 'org.projectlombok', name: 'lombok', version: '1.16.16')
compile 'com.flowpowered:flow-nbt:1.0.0' //Named Binary Tags
testCompile 'junit:junit:4.12' /* Test */
testCompile (group: 'junit', name: 'junit', version: '4.12')
} }
task copyDep(type: Copy) { task copyDep(type: Copy) {

View File

@@ -0,0 +1,34 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-08-08
*/
package mc.core;
import lombok.Getter;
import lombok.Setter;
import mc.core.world.World;
public class EntityLocation extends Location implements Cloneable {
@Getter
@Setter
private float yaw, pitch;
public EntityLocation(double x, double y, double z, float yaw, float pitch, World world) {
super(x, y, z, world);
setYawPitch(yaw, pitch);
}
public void setYawPitch(float yaw, float pitch) {
this.yaw = yaw;
this.pitch = pitch;
}
public void setYawPitch(EntityLocation entityLocation) {
setYawPitch(entityLocation.yaw, entityLocation.pitch);
}
@Override
public EntityLocation clone() {
return (EntityLocation) super.clone();
}
}

View File

@@ -1,12 +1,12 @@
/* /*
* DmitriyMX <dimon550@gmail.com> * DmitriyMX <dimon550@gmail.com>
* 2018-04-15 * 2018-08-08
*/ */
package mc.core; package mc.core;
import lombok.Data; import lombok.Getter;
import lombok.Setter;
import mc.core.exception.ResourceUnloadedException; import mc.core.exception.ResourceUnloadedException;
import mc.core.world.Region;
import mc.core.world.World; import mc.core.world.World;
import mc.core.world.chunk.Chunk; import mc.core.world.chunk.Chunk;
@@ -14,77 +14,39 @@ import java.io.Serializable;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@Data public class Location implements Serializable, Cloneable {
public class Location implements Serializable{ @Getter
@Setter
private double x, y, z; private double x, y, z;
private Reference<World> world; private Reference<World> refWorld;
private static int floor_double(double value) {
int i = (int)value;
return value < (double)i ? i - 1 : i;
}
public static Location copyOf(Location location) {
return new Location(
location.x,
location.y,
location.z,
location.getWorld()
);
}
public Location (double x, double y, double z, World world) { public Location (double x, double y, double z, World world) {
this.x = x; setXYZ(x, y, z);
this.y = y; setWorld(world);
this.z = z;
this.world = new WeakReference<>(world);
} }
public Location (double x, double y, double z) { public void setXYZ(double x, double y, double z) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
} }
public static Location startPointLocation () { public void setXYZ(Location location) {
return new Location(0,10,0, null); setXYZ(location.x, location.y, location.z);
} }
public Location(long compactValue) { public World getWorld() {
set(compactValue); if (refWorld == null) {
this.world = new WeakReference<>(null); return null;
} else if (refWorld.get() == null) {
throw new ResourceUnloadedException("You're trying to get unloaded world");
} else {
return refWorld.get();
}
} }
public Location(long compactValue, World world) { public void setWorld (World world) {
set(compactValue); this.refWorld = new WeakReference<>(world);
this.world = new WeakReference<>(world);
}
public void set(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void set(Location location) {
this.x = location.x;
this.y = location.y;
this.z = location.z;
}
public void set(long compactValue) {
this.x = compactValue >> 38;
this.y = (compactValue >> 26) & 0xFFF;
this.z = compactValue << 38 >> 38; // is normal?
}
public Location diff(Location location) {
return new Location(
this.x - location.x,
this.y - location.y,
this.z - location.z,
this.getWorld().equals(location.getWorld()) ? this.getWorld() : null
);
} }
public int getBlockX() { public int getBlockX() {
@@ -99,29 +61,23 @@ public class Location implements Serializable{
return (int) z; return (int) z;
} }
public long toLong() {
return ((floor_double(x) & 0x3FFFFFF) << 38)
| ((floor_double(y) & 0xFFF) << 26)
| (floor_double(z) & 0x3FFFFFF);
}
public World getWorld () {
if (world == null) {
return null;
}
if (world.get() == null) {
throw new ResourceUnloadedException("You're trying to get unloaded world");
}
return this.world.get();
}
public void setWorld (World world) {
this.world = new WeakReference<>(world);
}
public Chunk getChunk() { public Chunk getChunk() {
Region region = getWorld().getRegion((int) (x / 256), (int) (z / 256)); World world;
return region.getChunk((int) ((x % 256) / 16), (int) ((z % 256) / 16)); if ((world = getWorld()) == null) {
return null;
} else {
return world.getRegion((int) (x / 256), (int) (z / 256))
.getChunk((int) ((x % 256) / 16), (int) ((z % 256) / 16));
}
} }
@Override
public Location clone() {
try {
return (Location) super.clone();
} catch (CloneNotSupportedException e) { // такое в нашем случае вообще возможно?
e.printStackTrace();
return null;
}
}
} }

View File

@@ -1,14 +0,0 @@
package mc.core;
import lombok.AllArgsConstructor;
import lombok.Data;
import mc.core.player.Look;
import java.io.Serializable;
@Data
@AllArgsConstructor
public class WarpPosition implements Serializable {
private Location location;
private Look look;
}

View File

@@ -4,11 +4,10 @@
*/ */
package mc.core.embedded; package mc.core.embedded;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.chat.MessageType; import mc.core.chat.MessageType;
import mc.core.network.NetChannel; import mc.core.network.NetChannel;
import mc.core.network.SCPacket; import mc.core.network.SCPacket;
import mc.core.player.Look;
import mc.core.player.Player; import mc.core.player.Player;
import mc.core.player.PlayerManager; import mc.core.player.PlayerManager;
import mc.core.text.Text; import mc.core.text.Text;
@@ -52,7 +51,7 @@ public class FakePlayerManager implements PlayerManager {
private static final NetChannel FAKE_NET_CHANNEL = new FakeNetChannet(); private static final NetChannel FAKE_NET_CHANNEL = new FakeNetChannet();
@Override @Override
public Player createPlayer(String name, Location defaultLocation, Look defaultLook) { public Player createPlayer(String name, EntityLocation defaultLocation) {
return null; return null;
} }

View File

@@ -7,7 +7,7 @@ package mc.core.events;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.Setter; import lombok.Setter;
import mc.core.player.Look; import mc.core.EntityLocation;
import mc.core.player.Player; import mc.core.player.Player;
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -15,5 +15,5 @@ import mc.core.player.Player;
@Setter @Setter
public class PlayerLookEvent extends EventBase { public class PlayerLookEvent extends EventBase {
private final Player player; private final Player player;
private Look newLook; private EntityLocation newLook;
} }

View File

@@ -7,7 +7,7 @@ package mc.core.player;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.Config; import mc.core.Config;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.network.BroadcastNetChannel; import mc.core.network.BroadcastNetChannel;
import mc.core.network.NetChannel; import mc.core.network.NetChannel;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -31,13 +31,13 @@ public class InMemoryPlayerManager implements PlayerManager, Runnable {
} }
@Override @Override
public Player createPlayer(String name, Location defaultLocation, Look defaultLook) { public Player createPlayer(String name, EntityLocation defaultLocation) {
SimplePlayer player = new SimplePlayer(); SimplePlayer player = new SimplePlayer();
player.setId(rand.nextInt(10000)); player.setId(rand.nextInt(10000));
player.setUUID(UUID.nameUUIDFromBytes(name.getBytes())); player.setUUID(UUID.nameUUIDFromBytes(name.getBytes()));
player.setName(name); player.setName(name);
player.getLocation().set(defaultLocation); player.getLocation().setXYZ(defaultLocation);
player.getLook().set(defaultLook); player.getLocation().setYawPitch(defaultLocation);
player.setSettings(new PlayerSettings()); player.setSettings(new PlayerSettings());
synchronized (lock) { synchronized (lock) {

View File

@@ -1,21 +0,0 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-22
*/
package mc.core.player;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
@Data
@AllArgsConstructor
public class Look implements Serializable{
private float yaw, pitch;
public void set(Look look) {
this.yaw = look.yaw;
this.pitch = look.pitch;
}
}

View File

@@ -4,7 +4,7 @@
*/ */
package mc.core.player; package mc.core.player;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.network.NetChannel; import mc.core.network.NetChannel;
import java.util.UUID; import java.util.UUID;
@@ -18,9 +18,7 @@ public interface Player {
NetChannel getChannel(); NetChannel getChannel();
void setChannel(NetChannel channel); void setChannel(NetChannel channel);
Location getLocation(); EntityLocation getLocation();
Look getLook();
boolean isFlying(); boolean isFlying();
void setFlying(boolean value); void setFlying(boolean value);

View File

@@ -4,14 +4,14 @@
*/ */
package mc.core.player; package mc.core.player;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.network.NetChannel; import mc.core.network.NetChannel;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
public interface PlayerManager { public interface PlayerManager {
Player createPlayer(String name, Location defaultLocation, Look defaultLook); Player createPlayer(String name, EntityLocation defaultLocation);
void joinServer(Player player); void joinServer(Player player);
void leftServer(Player player); void leftServer(Player player);
Optional<Player> getPlayer(String name); Optional<Player> getPlayer(String name);

View File

@@ -5,7 +5,7 @@
package mc.core.player; package mc.core.player;
import lombok.Data; import lombok.Data;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.network.NetChannel; import mc.core.network.NetChannel;
import java.util.UUID; import java.util.UUID;
@@ -17,17 +17,13 @@ public class SimplePlayer implements Player {
private String name; private String name;
private boolean online = false; private boolean online = false;
private NetChannel channel; private NetChannel channel;
private Location location = new Location(0, 0, 0); private EntityLocation location = new EntityLocation(0d, 0d, 0d, 0f, 0f, null);
private Look look = new Look(0, 0);
private boolean flying = false; private boolean flying = false;
private PlayerSettings settings; private PlayerSettings settings;
public void setLocation(Location location) { public void setLocation(EntityLocation location) {
this.location.set(location); this.location.setXYZ(location);
} this.location.setYawPitch(location);
public void setLook(Look look) {
this.look.set(look);
} }
@Override @Override

View File

@@ -4,7 +4,7 @@
*/ */
package mc.core.world; package mc.core.world;
import mc.core.WarpPosition; import mc.core.EntityLocation;
import mc.core.nbt.Taggable; import mc.core.nbt.Taggable;
import java.io.Serializable; import java.io.Serializable;
@@ -45,8 +45,8 @@ public interface World extends Taggable, Serializable{
UUID getWorldId(); UUID getWorldId();
IWorldType getWorldType(); IWorldType getWorldType();
WarpPosition getSpawn(); EntityLocation getSpawn();
void setSpawn(WarpPosition location); void setSpawn(EntityLocation location);
ChunkSection getChunk(int x, int y, int z); ChunkSection getChunk(int x, int y, int z);
void setChunk(int x, int y, int z, ChunkSection chunkSection); void setChunk(int x, int y, int z, ChunkSection chunkSection);

View File

@@ -22,7 +22,7 @@ public class BlockFactory {
private class EmbeddedBlock extends AbstractBlock { private class EmbeddedBlock extends AbstractBlock {
EmbeddedBlock(BlockType type, int meta, int x, int y, int z) { EmbeddedBlock(BlockType type, int meta, int x, int y, int z) {
super(type, meta); super(type, meta);
super.setLocation(new Location(x,y,z)); super.setLocation(new Location(x,y,z, null));
} }
} }
} }

View File

@@ -0,0 +1,100 @@
package mc.core;
import com.flowpowered.nbt.Tag;
import mc.core.world.ChunkSection;
import mc.core.world.IWorldType;
import mc.core.world.Region;
import mc.core.world.World;
import org.junit.Assert;
import org.junit.Test;
import java.util.UUID;
import java.util.stream.Stream;
public class EntityLocationTest {
@Test
public void cloneTest() {
World dummyWorld = new World() {
@Override
public UUID getWorldId() {
return null;
}
@Override
public IWorldType getWorldType() {
return null;
}
@Override
public EntityLocation getSpawn() {
return null;
}
@Override
public void setSpawn(EntityLocation location) {
}
@Override
public ChunkSection getChunk(int x, int y, int z) {
return null;
}
@Override
public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
}
@Override
public Region getRegion(int x, int z) {
return null;
}
@Override
public void setRegion(int x, int z, Region region) {
}
@Override
public int getSeed() {
return 0;
}
@Override
public String getName() {
return null;
}
@Override
public void setName(String name) {
}
@Override
public Tag<?> getTag(String name) {
return null;
}
@Override
public void setTag(Tag<?> tag) {
}
@Override
public Stream<Tag<?>> tagStream() {
return null;
}
};
EntityLocation firstLocation = new EntityLocation(10, 20, 30, 40, 50, dummyWorld);
Assert.assertSame("Lost world reference before cloning", dummyWorld, firstLocation.getWorld());
EntityLocation locationClone = firstLocation.clone();
Assert.assertEquals("X mismatch", firstLocation.getX(), locationClone.getX(), 0);
Assert.assertEquals("Y mismatch", firstLocation.getY(), locationClone.getY(), 0);
Assert.assertEquals("Z mismatch", firstLocation.getZ(), locationClone.getZ(), 0);
Assert.assertEquals("Pitch mismatch", firstLocation.getPitch(), locationClone.getPitch(), 0);
Assert.assertEquals("Yaw mismatch", firstLocation.getYaw(), locationClone.getYaw(), 0);
Assert.assertSame("World mismatch (accidental clone of the World object?)", firstLocation.getWorld(), locationClone.getWorld());
}
}

View File

@@ -7,9 +7,7 @@ package mc.world.flat;
import com.flowpowered.nbt.Tag; import com.flowpowered.nbt.Tag;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.WarpPosition;
import mc.core.player.Look;
import mc.core.world.*; import mc.core.world.*;
import java.util.UUID; import java.util.UUID;
@@ -26,7 +24,7 @@ public class FlatWorld implements World {
@Getter @Getter
@Setter @Setter
private WarpPosition spawn = new WarpPosition(new Location(0, 6, 0), new Look(0, 0)); private EntityLocation spawn = new EntityLocation(0d, 6d, 0d, 0f, 0f, this);
private ChunkSection chunkSection = new SimpleChunkSection(); private ChunkSection chunkSection = new SimpleChunkSection();
@Override @Override

View File

@@ -2,7 +2,7 @@ package mc.world.generated_world.serialization;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.WarpPosition; import mc.core.EntityLocation;
import mc.core.world.World; import mc.core.world.World;
import mc.world.generated_world.world.CubicWorld; import mc.world.generated_world.world.CubicWorld;
@@ -55,7 +55,7 @@ public class WorldReaderWriter {
@Data @Data
public static class WorldInfo implements Serializable { public static class WorldInfo implements Serializable {
private WarpPosition spawn; private EntityLocation spawn;
private String name; private String name;
private int seed; private int seed;
} }

View File

@@ -5,16 +5,8 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.Direction; import mc.core.Direction;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.WarpPosition; import mc.core.world.*;
import mc.core.player.Look;
import mc.core.world.ChunkSection;
import mc.core.world.IWorldType;
import mc.core.world.Region;
import mc.core.world.World;
import mc.core.world.WorldGenerator;
import mc.core.world.block.BlockType;
import mc.core.world.chunk.Chunk;
import mc.world.generated_world.serialization.RegionReaderWriter; import mc.world.generated_world.serialization.RegionReaderWriter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -28,7 +20,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Stream; import java.util.stream.Stream;
import static mc.world.generated_world.WorldConstants.*; import static mc.world.generated_world.WorldConstants.REGION_FILE_NAME_TEMPLATE;
/* /*
* NORTH * NORTH
@@ -61,7 +53,7 @@ public class CubicWorld implements World {
@Getter @Getter
private final UUID worldId; private final UUID worldId;
private final int seed; private final int seed;
private volatile WarpPosition warpPosition; private volatile EntityLocation spawn;
private final transient Object spawnLocationLock = new Object(); private final transient Object spawnLocationLock = new Object();
private final Map<String, Tag<?>> nbtTagMap = new HashMap<>(); private final Map<String, Tag<?>> nbtTagMap = new HashMap<>();
@Getter@Setter @Getter@Setter
@@ -89,19 +81,24 @@ public class CubicWorld implements World {
@Override @Override
public IWorldType getWorldType() { public IWorldType getWorldType() {
return null; return null; //FIXME
} }
@Override @Override
public WarpPosition getSpawn() { public EntityLocation getSpawn() {
/* FIXME */ /* FIXME */
return new WarpPosition(new Location(0, 100, 0), new Look(0, 0)); if (spawn == null) {
log.warn("Spawn is not defined! Set default spawn: [8, 128, 8]");
setSpawn(new EntityLocation(8d, 128d, 8d, 0f, 0f, this));
}
return spawn;
} }
@Override @Override
public void setSpawn(WarpPosition warpPosition) { public void setSpawn(EntityLocation entityLocation) {
synchronized (spawnLocationLock) { synchronized (spawnLocationLock) {
this.warpPosition = warpPosition; entityLocation.setWorld(this);
this.spawn = entityLocation;
} }
} }
@@ -113,7 +110,7 @@ public class CubicWorld implements World {
@Override @Override
public void setChunk(int x, int y, int z, ChunkSection chunkSection) { public void setChunk(int x, int y, int z, ChunkSection chunkSection) {
throw new UnsupportedOperationException();
} }
@Override @Override

View File

@@ -5,7 +5,7 @@
package mc.core.network.proto_1_12_2; package mc.core.network.proto_1_12_2;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.player.Player; import mc.core.player.Player;
import java.util.HashMap; import java.util.HashMap;
@@ -22,7 +22,7 @@ public class TeleportManager {
@AllArgsConstructor @AllArgsConstructor
private class TpData { private class TpData {
public Player player; public Player player;
public Location newLocation; public EntityLocation newLocation;
// TODO необходимо добавить TimeStamp, что бы понимать, когда клиент отвергнул телепортацию // TODO необходимо добавить TimeStamp, что бы понимать, когда клиент отвергнул телепортацию
// т.е. идея такова: долгое молчание клиента знак отвержения телепортации. // т.е. идея такова: долгое молчание клиента знак отвержения телепортации.
} }
@@ -32,20 +32,21 @@ public class TeleportManager {
private TeleportManager() {} private TeleportManager() {}
public int append(Player player, Location location) { public int append(Player player, EntityLocation location) {
int teleportId; int teleportId;
do { do {
teleportId = RAND.nextInt(9999); teleportId = RAND.nextInt(9999);
} while (teleportMap.containsKey(teleportId)); } while (teleportMap.containsKey(teleportId));
teleportMap.put(teleportId, new TpData(player, Location.copyOf(location))); teleportMap.put(teleportId, new TpData(player, location.clone()));
return teleportId; return teleportId;
} }
public void apply(int teleportId) { public void apply(int teleportId) {
if (teleportMap.containsKey(teleportId)) { if (teleportMap.containsKey(teleportId)) {
TpData data = teleportMap.remove(teleportId); TpData data = teleportMap.remove(teleportId);
data.player.getLocation().set(data.newLocation); data.player.getLocation().setXYZ(data.newLocation);
data.player.getLocation().setYawPitch(data.newLocation);
} }
} }

View File

@@ -8,17 +8,18 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.network.*; import mc.core.network.CSPacket;
import mc.core.player.Look; import mc.core.network.NetInputStream;
import mc.core.network.NetOutputStream;
import mc.core.network.SCPacket;
@NoArgsConstructor @NoArgsConstructor
@Getter @Getter
@Setter @Setter
@ToString @ToString
public class PlayerPositionAndLookPacket implements SCPacket, CSPacket { public class PlayerPositionAndLookPacket implements SCPacket, CSPacket {
private Location location; private EntityLocation location;
private Look look;
private int teleportId; private int teleportId;
private boolean onGround = false; private boolean onGround = false;
@@ -27,9 +28,9 @@ public class PlayerPositionAndLookPacket implements SCPacket, CSPacket {
netStream.writeDouble(location.getX()); netStream.writeDouble(location.getX());
netStream.writeDouble(location.getY()); netStream.writeDouble(location.getY());
netStream.writeDouble(location.getZ()); netStream.writeDouble(location.getZ());
netStream.writeFloat(look.getYaw()); netStream.writeFloat(location.getYaw());
netStream.writeFloat(look.getPitch()); netStream.writeFloat(location.getPitch());
netStream.writeByte(0); // It's a bitfield, X/Y/Z/Y_ROT/X_ROT. If X is set, the x value is relative and not absolute. netStream.writeByte(0); // It's a bitfield, X/Y/Z/Y_ROT/X_ROT. If X is setXYZ, the x value is relative and not absolute.
/* X - 0x01 /* X - 0x01
* Y - 0x02 * Y - 0x02
* Z - 0x04 * Z - 0x04
@@ -41,15 +42,13 @@ public class PlayerPositionAndLookPacket implements SCPacket, CSPacket {
@Override @Override
public void readSelf(NetInputStream netStream) { public void readSelf(NetInputStream netStream) {
this.location = new Location( this.location = new EntityLocation(
netStream.readDouble(),
netStream.readDouble(), netStream.readDouble(),
netStream.readDouble(), netStream.readDouble(),
netStream.readDouble()
);
this.look = new Look(
netStream.readFloat(), netStream.readFloat(),
netStream.readFloat() netStream.readFloat(),
null
); );
this.onGround = netStream.readBoolean(); this.onGround = netStream.readBoolean();

View File

@@ -8,7 +8,7 @@ import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import mc.core.Location; import mc.core.EntityLocation;
import mc.core.network.NetOutputStream; import mc.core.network.NetOutputStream;
import mc.core.network.SCPacket; import mc.core.network.SCPacket;
@@ -17,10 +17,21 @@ import mc.core.network.SCPacket;
@Setter @Setter
@ToString @ToString
public class SpawnPositionPacket implements SCPacket { public class SpawnPositionPacket implements SCPacket {
private Location location; private EntityLocation location;
private int floor_double(double value) {
int i = (int)value;
return value < (double)i ? i - 1 : i;
}
private long location2long(EntityLocation entityLocation) {
return ((floor_double(entityLocation.getX()) & 0x3FFFFFF) << 38)
| ((floor_double(entityLocation.getY()) & 0xFFF) << 26)
| (floor_double(entityLocation.getZ()) & 0x3FFFFFF);
}
@Override @Override
public void writeSelf(NetOutputStream netStream) { public void writeSelf(NetOutputStream netStream) {
netStream.writeLong(location.toLong()); netStream.writeLong(location2long(location));
} }
} }

View File

@@ -21,7 +21,13 @@ public class TabCompletePacket implements CSPacket {
this.hasPosition = netStream.readBoolean(); this.hasPosition = netStream.readBoolean();
if (this.hasPosition) { if (this.hasPosition) {
this.location = new Location(netStream.readLong()); long compactValue = netStream.readLong();
double x = compactValue >> 38;
double y = (compactValue >> 26) & 0xFFF;
double z = compactValue << 38 >> 38; // is normal?
this.location = new Location(x, y, z, null);
} }
} }
} }

View File

@@ -47,8 +47,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
Player player = playerManager.getPlayer(packet.getPlayerName()) Player player = playerManager.getPlayer(packet.getPlayerName())
.orElseGet(() -> playerManager.createPlayer( .orElseGet(() -> playerManager.createPlayer(
packet.getPlayerName(), packet.getPlayerName(),
world.getSpawn().getLocation(), world.getSpawn()));
world.getSpawn().getLook()));
channel.writeAndFlush(new LoginSuccessPacket( channel.writeAndFlush(new LoginSuccessPacket(
player.getUUID(), player.getUUID(),
@@ -62,12 +61,12 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
pkt1.setMode(PlayerMode.CREATIVE); pkt1.setMode(PlayerMode.CREATIVE);
pkt1.setDimension(0/*Overworld*/); pkt1.setDimension(0/*Overworld*/);
pkt1.setDifficulty(0/*Peaceful*/); pkt1.setDifficulty(0/*Peaceful*/);
pkt1.setLevelType("flat"); pkt1.setLevelType("flat"); //FIXME
channel.write(pkt1); channel.write(pkt1);
// Spawn Position // Spawn Position
SpawnPositionPacket pkt2 = new SpawnPositionPacket(); SpawnPositionPacket pkt2 = new SpawnPositionPacket();
pkt2.setLocation(world.getSpawn().getLocation()); pkt2.setLocation(world.getSpawn());
channel.write(pkt2); channel.write(pkt2);
// Player Abilities // Player Abilities
@@ -83,14 +82,13 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
ChunkDataPacket pkt8 = new ChunkDataPacket(); ChunkDataPacket pkt8 = new ChunkDataPacket();
pkt8.setX(0); pkt8.setX(0);
pkt8.setZ(0); pkt8.setZ(0);
pkt8.getChunks().add(world.getChunk(0, 0, 0)); pkt8.getChunks().add(world.getChunk(0, 0,0));
pkt8.setInitChunk(true); pkt8.setInitChunk(true);
channel.writeAndFlush(pkt8); channel.writeAndFlush(pkt8);
// Player Position And Look // Player Position And Look
PlayerPositionAndLookPacket pkt4 = new PlayerPositionAndLookPacket(); PlayerPositionAndLookPacket pkt4 = new PlayerPositionAndLookPacket();
pkt4.setLocation(player.getLocation()); pkt4.setLocation(player.getLocation());
pkt4.setLook(player.getLook());
pkt4.setTeleportId(TeleportManager.getInstance().append(player, player.getLocation())); pkt4.setTeleportId(TeleportManager.getInstance().append(player, player.getLocation()));
channel.writeAndFlush(pkt4); channel.writeAndFlush(pkt4);
@@ -106,7 +104,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
playerData.setPing(0); playerData.setPing(0);
playerData.setHasDisplayName(true); playerData.setHasDisplayName(true);
playerData.setDisplayName(Text.builder() playerData.setDisplayName(Text.builder()
.append(Text.of(TextColor.RED, TextStyle.BOLD, player.getName().substring(0, 1))) .append(Text.of(TextColor.RED, TextStyle.BOLD, player.getName().substring(0,1)))
.append(Text.of(TextColor.WHITE, player.getName().substring(1))) .append(Text.of(TextColor.WHITE, player.getName().substring(1)))
.build() .build()
); );

View File

@@ -52,8 +52,8 @@ public class PlayHandler extends AbstractStateHandler implements PlayStateHandle
@Handler @Handler
public void onPositionAndLook(Channel channel, PlayerPositionAndLookPacket packet) { public void onPositionAndLook(Channel channel, PlayerPositionAndLookPacket packet) {
Player player = channel.attr(ATTR_PLAYER).get(); Player player = channel.attr(ATTR_PLAYER).get();
player.getLocation().set(packet.getLocation()); player.getLocation().setXYZ(packet.getLocation());
player.getLook().set(packet.getLook()); player.getLocation().setYawPitch(packet.getLocation());
} }
@Handler @Handler