Gamemode switching

This commit is contained in:
LOOHP 2020-08-08 03:51:49 +08:00
parent 82a5198e78
commit e6005abc5a
11 changed files with 212 additions and 14 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>Limbo</groupId> <groupId>Limbo</groupId>
<artifactId>Limbo</artifactId> <artifactId>Limbo</artifactId>
<version>0.2.1-ALPHA</version> <version>0.2.2-ALPHA</version>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
<resources> <resources>

View File

@ -42,6 +42,7 @@ import com.loohp.limbo.Utils.ImageUtils;
import com.loohp.limbo.Utils.NetworkUtils; import com.loohp.limbo.Utils.NetworkUtils;
import com.loohp.limbo.World.Schematic; import com.loohp.limbo.World.Schematic;
import com.loohp.limbo.World.World; import com.loohp.limbo.World.World;
import com.loohp.limbo.World.World.Environment;
import net.querz.nbt.io.NBTUtil; import net.querz.nbt.io.NBTUtil;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
@ -285,7 +286,7 @@ public class Limbo {
return null; return null;
} }
World world = Schematic.toWorld(properties.getLevelName().getKey(), (CompoundTag) NBTUtil.read(schem).getTag()); World world = Schematic.toWorld(properties.getLevelName().getKey(), Environment.fromNamespacedKey(properties.getLevelDimension()), (CompoundTag) NBTUtil.read(schem).getTag());
console.sendMessage("Loaded world " + properties.getLevelName() + "!"); console.sendMessage("Loaded world " + properties.getLevelName() + "!");

View File

@ -9,7 +9,10 @@ import com.loohp.limbo.Events.PlayerChatEvent;
import com.loohp.limbo.Location.Location; import com.loohp.limbo.Location.Location;
import com.loohp.limbo.Server.ClientConnection; import com.loohp.limbo.Server.ClientConnection;
import com.loohp.limbo.Server.Packets.PacketPlayOutChat; import com.loohp.limbo.Server.Packets.PacketPlayOutChat;
import com.loohp.limbo.Server.Packets.PacketPlayOutGameState;
import com.loohp.limbo.Server.Packets.PacketPlayOutPositionAndLook; import com.loohp.limbo.Server.Packets.PacketPlayOutPositionAndLook;
import com.loohp.limbo.Server.Packets.PacketPlayOutRespawn;
import com.loohp.limbo.Utils.GameMode;
import com.loohp.limbo.World.World; import com.loohp.limbo.World.World;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -22,6 +25,7 @@ public class Player implements CommandSender {
private final String username; private final String username;
private final UUID uuid; private final UUID uuid;
private GameMode gamemode;
private int entityId; private int entityId;
@ -35,10 +39,32 @@ public class Player implements CommandSender {
this.location = location.clone(); this.location = location.clone();
} }
public GameMode getGamemode() {
return gamemode;
}
public void setGamemode(GameMode gamemode) {
if (!this.gamemode.equals(gamemode)) {
try {
PacketPlayOutGameState state = new PacketPlayOutGameState(3, gamemode.getId());
clientConnection.sendPacket(state);
} catch (IOException e) {
e.printStackTrace();
}
}
this.gamemode = gamemode;
}
@Deprecated
public void setGamemodeSilent(GameMode gamemode) {
this.gamemode = gamemode;
}
public World getWorld() { public World getWorld() {
return location.clone().getWorld(); return location.clone().getWorld();
} }
@Deprecated
public void setEntityId(int entityId) { public void setEntityId(int entityId) {
this.entityId = entityId; this.entityId = entityId;
} }
@ -77,8 +103,11 @@ public class Player implements CommandSender {
public void teleport(Location location) { public void teleport(Location location) {
try { try {
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), if (!this.location.getWorld().equals(location.getWorld())) {
location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1); PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), 0, gamemode, false, false, true);
clientConnection.sendPacket(respawn);
}
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1);
clientConnection.sendPacket(positionLook); clientConnection.sendPacket(positionLook);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -57,6 +57,7 @@ import com.loohp.limbo.Utils.CustomStringUtils;
import com.loohp.limbo.Utils.DataTypeIO; import com.loohp.limbo.Utils.DataTypeIO;
import com.loohp.limbo.Utils.MojangAPIUtils; import com.loohp.limbo.Utils.MojangAPIUtils;
import com.loohp.limbo.Utils.MojangAPIUtils.SkinResponse; import com.loohp.limbo.Utils.MojangAPIUtils.SkinResponse;
import com.loohp.limbo.Utils.NamespacedKey;
import com.loohp.limbo.World.BlockPosition; import com.loohp.limbo.World.BlockPosition;
import com.loohp.limbo.World.DimensionRegistry; import com.loohp.limbo.World.DimensionRegistry;
import com.loohp.limbo.World.World; import com.loohp.limbo.World.World;
@ -154,6 +155,7 @@ public class ClientConnection extends Thread {
} catch (IOException e) {} } catch (IOException e) {}
} }
@SuppressWarnings("deprecation")
@Override @Override
public void run() { public void run() {
running = true; running = true;
@ -258,8 +260,9 @@ public class ClientConnection extends Thread {
TimeUnit.MILLISECONDS.sleep(500); TimeUnit.MILLISECONDS.sleep(500);
ServerProperties p = Limbo.getInstance().getServerProperties(); ServerProperties p = Limbo.getInstance().getServerProperties();
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, p.getDefaultGamemode(), new String[] {p.getLevelName().toString()}, DimensionRegistry.getCodec(), p.getLevelDimension().toString(), p.getLevelName().toString(), 0, (byte) p.getMaxPlayers(), 8, p.isReducedDebugInfo(), true, false, false); PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, p.getDefaultGamemode(), Limbo.getInstance().getWorlds().stream().map(each -> new NamespacedKey(each.getName()).toString()).collect(Collectors.toList()).toArray(new String[Limbo.getInstance().getWorlds().size()]), DimensionRegistry.getCodec(), p.getWorldSpawn().getWorld(), 0, (byte) p.getMaxPlayers(), 8, p.isReducedDebugInfo(), true, false, false);
sendPacket(join); sendPacket(join);
player.setGamemodeSilent(p.getDefaultGamemode());
Location s = p.getWorldSpawn(); Location s = p.getWorldSpawn();

View File

@ -0,0 +1,37 @@
package com.loohp.limbo.Server.Packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class PacketPlayOutGameState extends PacketOut {
private int reason;
private float value;
public PacketPlayOutGameState(int reason, float value) {
this.reason = reason;
this.value = value;
}
public int getReason() {
return reason;
}
public float getValue() {
return value;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
output.writeByte(reason);
output.writeFloat(value);
return buffer.toByteArray();
}
}

View File

@ -7,6 +7,8 @@ import java.nio.charset.StandardCharsets;
import com.loohp.limbo.Utils.DataTypeIO; import com.loohp.limbo.Utils.DataTypeIO;
import com.loohp.limbo.Utils.GameMode; import com.loohp.limbo.Utils.GameMode;
import com.loohp.limbo.Utils.NamespacedKey;
import com.loohp.limbo.World.World;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
@ -28,7 +30,7 @@ public class PacketPlayOutLogin extends PacketOut {
private boolean isFlat; private boolean isFlat;
public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode,
String[] worldsNames, CompoundTag dimensionCodec, String dimension, String worldName, long hashedSeed, String[] worldsNames, CompoundTag dimensionCodec, World world, long hashedSeed,
byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug,
boolean isFlat) { boolean isFlat) {
this.entityId = entityId; this.entityId = entityId;
@ -36,8 +38,8 @@ public class PacketPlayOutLogin extends PacketOut {
this.gamemode = gamemode; this.gamemode = gamemode;
this.worldsNames = worldsNames; this.worldsNames = worldsNames;
this.dimensionCodec = dimensionCodec; this.dimensionCodec = dimensionCodec;
this.dimension = dimension; this.dimension = world.getEnvironment().getNamespacedKey().toString();
this.worldName = worldName; this.worldName = new NamespacedKey(world.getName()).toString();
this.hashedSeed = hashedSeed; this.hashedSeed = hashedSeed;
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
this.viewDistance = viewDistance; this.viewDistance = viewDistance;

View File

@ -0,0 +1,80 @@
package com.loohp.limbo.Server.Packets;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import com.loohp.limbo.Utils.DataTypeIO;
import com.loohp.limbo.Utils.GameMode;
import com.loohp.limbo.Utils.NamespacedKey;
import com.loohp.limbo.World.World;
public class PacketPlayOutRespawn extends PacketOut {
private String dimension;
private String worldName;
private long hashedSeed;
private GameMode gamemode;
private boolean isDebug;
private boolean isFlat;
private boolean copyMetaData;
public PacketPlayOutRespawn(World world, long hashedSeed, GameMode gamemode, boolean isDebug,
boolean isFlat, boolean copyMetaData) {
this.dimension = world.getEnvironment().getNamespacedKey().toString();
this.worldName = new NamespacedKey(world.getName()).toString();
this.hashedSeed = hashedSeed;
this.gamemode = gamemode;
this.isDebug = isDebug;
this.isFlat = isFlat;
this.copyMetaData = copyMetaData;
}
public String getDimension() {
return dimension;
}
public String getWorldName() {
return worldName;
}
public long getHashedSeed() {
return hashedSeed;
}
public GameMode getGamemode() {
return gamemode;
}
public boolean isDebug() {
return isDebug;
}
public boolean isFlat() {
return isFlat;
}
public boolean isCopyMetaData() {
return copyMetaData;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeString(output, dimension, StandardCharsets.UTF_8);
DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8);
output.writeLong(hashedSeed);
output.writeByte((byte) gamemode.getId());
output.writeByte((byte) gamemode.getId());
output.writeBoolean(isDebug);
output.writeBoolean(isFlat);
output.writeBoolean(copyMetaData);
return buffer.toByteArray();
}
}

View File

@ -5,6 +5,7 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import com.loohp.limbo.Utils.SchematicConvertionUtils; import com.loohp.limbo.Utils.SchematicConvertionUtils;
import com.loohp.limbo.World.World.Environment;
import net.querz.mca.Chunk; import net.querz.mca.Chunk;
import net.querz.nbt.tag.CompoundTag; import net.querz.nbt.tag.CompoundTag;
@ -13,7 +14,7 @@ import net.querz.nbt.tag.ListTag;
public class Schematic { public class Schematic {
public static World toWorld(String name, CompoundTag nbt) { public static World toWorld(String name, Environment environment, CompoundTag nbt) {
short width = nbt.getShort("Width"); short width = nbt.getShort("Width");
short length = nbt.getShort("Length"); short length = nbt.getShort("Length");
short height = nbt.getShort("Height"); short height = nbt.getShort("Height");
@ -25,7 +26,7 @@ public class Schematic {
mapping.put(palette.getInt(key), key); mapping.put(palette.getInt(key), key);
} }
World world = new World(name, width, length); World world = new World(name, width, length, environment);
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < length; z++) {

View File

@ -1,5 +1,6 @@
package com.loohp.limbo.World; package com.loohp.limbo.World;
import com.loohp.limbo.Utils.NamespacedKey;
import com.loohp.limbo.Utils.SchematicConvertionUtils; import com.loohp.limbo.Utils.SchematicConvertionUtils;
import net.querz.mca.Chunk; import net.querz.mca.Chunk;
@ -9,19 +10,31 @@ import net.querz.nbt.tag.ListTag;
public class World { public class World {
private String name; private String name;
private Environment environment;
private Chunk[][] chunks; private Chunk[][] chunks;
public World(String name, int width, int length) { public World(String name, int width, int length, Environment environment) {
this.name = name; this.name = name;
this.environment = environment;
this.chunks = new Chunk[(width >> 4) + 1][(length >> 4) + 1]; this.chunks = new Chunk[(width >> 4) + 1][(length >> 4) + 1];
for (int x = 0; x < chunks.length; x++) { for (int x = 0; x < chunks.length; x++) {
for (int z = 0; z < chunks[x].length; z++) { for (int z = 0; z < chunks[x].length; z++) {
chunks[x][z] = Chunk.newChunk(); chunks[x][z] = Chunk.newChunk();
Chunk chunk = chunks[x][z]; Chunk chunk = chunks[x][z];
chunk.cleanupPalettesAndBlockStates(); chunk.cleanupPalettesAndBlockStates();
CompoundTag heightMap = new CompoundTag(); CompoundTag heightMap = new CompoundTag();
heightMap.putLongArray("MOTION_BLOCKING", new long[] {1371773531765642314L,1389823183635651148L,1371738278539598925L,1389823183635388492L,1353688558756731469L,1389823114781694027L,1317765589597723213L,1371773531899860042L,1389823183635651149L,1371773462911685197L,1389823183635650636L,1353688626805119565L,1371773531900123211L,1335639250618849869L,1371738278674077258L,1389823114781694028L,1353723811310638154L,1371738278674077259L,1335674228429068364L,1335674228429067338L,1335674228698027594L,1317624576693539402L,1335709481520370249L,1299610178184057417L,1335638906349064264L,1299574993811968586L,1299574924958011464L,1299610178184056904L,1299574924958011464L,1299610109330100296L,1299574924958011464L,1299574924823793736L,1299574924958011465L,1281525273222484040L,1299574924958011464L,1281525273222484040L,9548107335L}); heightMap.putLongArray("MOTION_BLOCKING",
new long[] { 1371773531765642314L, 1389823183635651148L, 1371738278539598925L,
1389823183635388492L, 1353688558756731469L, 1389823114781694027L, 1317765589597723213L,
1371773531899860042L, 1389823183635651149L, 1371773462911685197L, 1389823183635650636L,
1353688626805119565L, 1371773531900123211L, 1335639250618849869L, 1371738278674077258L,
1389823114781694028L, 1353723811310638154L, 1371738278674077259L, 1335674228429068364L,
1335674228429067338L, 1335674228698027594L, 1317624576693539402L, 1335709481520370249L,
1299610178184057417L, 1335638906349064264L, 1299574993811968586L, 1299574924958011464L,
1299610178184056904L, 1299574924958011464L, 1299610109330100296L, 1299574924958011464L,
1299574924823793736L, 1299574924958011465L, 1281525273222484040L, 1299574924958011464L,
1281525273222484040L, 9548107335L });
chunk.setHeightMaps(heightMap); chunk.setHeightMaps(heightMap);
chunk.setBiomes(new int[256]); chunk.setBiomes(new int[256]);
chunk.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class)); chunk.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class));
@ -50,4 +63,33 @@ public class World {
public String getName() { public String getName() {
return name; return name;
} }
public Environment getEnvironment() {
return environment;
}
public enum Environment {
NORMAL(new NamespacedKey("minecraft:overworld")),
NETHER(new NamespacedKey("minecraft:the_nether")),
END(new NamespacedKey("minecraft:the_end"));
NamespacedKey key;
Environment(NamespacedKey key) {
this.key = key;
}
public NamespacedKey getNamespacedKey() {
return key;
}
public static Environment fromNamespacedKey(NamespacedKey key) {
for (Environment each : Environment.values()) {
if (each.getNamespacedKey().equals(key)) {
return each;
}
}
return null;
}
}
} }

View File

@ -34,7 +34,9 @@
"PacketPlayOutDisconnect": "0x1A", "PacketPlayOutDisconnect": "0x1A",
"PacketPlayOutPluginMessaging": "0x17", "PacketPlayOutPluginMessaging": "0x17",
"PacketPlayOutTabComplete": "0x10", "PacketPlayOutTabComplete": "0x10",
"PacketPlayOutDeclareCommands": "0x11" "PacketPlayOutDeclareCommands": "0x11",
"PacketPlayOutRespawn": "0x3A",
"PacketPlayOutGameState": "0x1E"
}, },
"StatusIn": { "StatusIn": {
"0x01": "PacketStatusInPing", "0x01": "PacketStatusInPing",

View File

@ -3,6 +3,7 @@ groups:
- limboserver.stop - limboserver.stop
- limboserver.kick - limboserver.kick
- limboserver.say - limboserver.say
- limboserver.gamemode
default: default:
- limboserver.spawn - limboserver.spawn