Режим игры решает сервер: клиент больше не ломает блоки сам
This commit is contained in:
@@ -102,6 +102,22 @@ public final class Packets {
|
||||
*/
|
||||
public static final int LAUNCHER_AUTH = 0x1A;
|
||||
|
||||
/**
|
||||
* The player's game mode, changed while the player is in the world.
|
||||
*
|
||||
* The mode arrives with the world join and can be changed afterwards, the
|
||||
* way a server changes it. What a player may do about blocks follows from
|
||||
* it: in survival the player breaks nothing, in creative the player
|
||||
* breaks what they look at.
|
||||
*/
|
||||
public static final int SET_GAME_MODE = 0x1B;
|
||||
|
||||
/** Survival: the player cannot break blocks at all. */
|
||||
public static final int GAMEMODE_SURVIVAL = 0;
|
||||
|
||||
/** Creative: the player breaks the block they are looking at. */
|
||||
public static final int GAMEMODE_CREATIVE = 1;
|
||||
|
||||
public static final int DISCONNECT = 0x7F;
|
||||
|
||||
/** The client introducing itself, and naming the account it wants. */
|
||||
@@ -465,8 +481,11 @@ public final class Packets {
|
||||
public final int viewDistance;
|
||||
public final int worldHeight;
|
||||
|
||||
/** The game mode the player starts in. */
|
||||
public final int gameMode;
|
||||
|
||||
public WorldJoin(int entityId, long seed, double spawnX, double spawnY,
|
||||
double spawnZ, int viewDistance, int worldHeight) {
|
||||
double spawnZ, int viewDistance, int worldHeight, int gameMode) {
|
||||
this.entityId = entityId;
|
||||
this.seed = seed;
|
||||
this.spawnX = spawnX;
|
||||
@@ -474,6 +493,7 @@ public final class Packets {
|
||||
this.spawnZ = spawnZ;
|
||||
this.viewDistance = viewDistance;
|
||||
this.worldHeight = worldHeight;
|
||||
this.gameMode = gameMode;
|
||||
}
|
||||
|
||||
public Buf write() {
|
||||
@@ -483,6 +503,7 @@ public final class Packets {
|
||||
buf.writePosition(this.spawnX, this.spawnY, this.spawnZ);
|
||||
buf.writeVarInt(this.viewDistance);
|
||||
buf.writeVarInt(this.worldHeight);
|
||||
buf.writeVarInt(this.gameMode);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -491,7 +512,7 @@ public final class Packets {
|
||||
long seed = in.readVarLong();
|
||||
double[] spawn = in.readPosition();
|
||||
return new WorldJoin(entityId, seed, spawn[0], spawn[1], spawn[2],
|
||||
in.readVarInt(), in.readVarInt());
|
||||
in.readVarInt(), in.readVarInt(), in.readVarInt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,6 +771,31 @@ public final class Packets {
|
||||
}
|
||||
}
|
||||
|
||||
/** The game mode of one player. */
|
||||
public static final class GameMode implements Packet {
|
||||
|
||||
public final int mode;
|
||||
|
||||
public GameMode(int mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/** True when the player may break blocks. */
|
||||
public boolean creative() {
|
||||
return this.mode == GAMEMODE_CREATIVE;
|
||||
}
|
||||
|
||||
public Buf write() {
|
||||
Buf buf = new Buf(8);
|
||||
buf.writeVarInt(this.mode);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static GameMode read(Buf in) {
|
||||
return new GameMode(in.readVarInt());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The launcher's session, as the game server sees it.
|
||||
*
|
||||
@@ -807,6 +853,7 @@ public final class Packets {
|
||||
map.put(Integer.valueOf(ENTITY_SPAWN), "EntitySpawn");
|
||||
map.put(Integer.valueOf(ENTITY_REMOVE), "EntityRemove");
|
||||
map.put(Integer.valueOf(LAUNCHER_AUTH), "LauncherAuth");
|
||||
map.put(Integer.valueOf(SET_GAME_MODE), "GameMode");
|
||||
map.put(Integer.valueOf(DISCONNECT), "Disconnect");
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -417,7 +417,8 @@ public final class ProtocolTest {
|
||||
yes("a fresh join carries no position", !freshBack.hasPosition);
|
||||
|
||||
Packets.WorldJoin world =
|
||||
new Packets.WorldJoin(7, 1234567890123L, 0.5D, 64.0D, 0.5D, 8, 256);
|
||||
new Packets.WorldJoin(7, 1234567890123L, 0.5D, 64.0D, 0.5D, 8, 256,
|
||||
Packets.GAMEMODE_CREATIVE);
|
||||
Packets.WorldJoin worldBack =
|
||||
Packets.WorldJoin.read(new Buf(world.write().toByteArray()));
|
||||
eq("entity id", Integer.valueOf(7), Integer.valueOf(worldBack.entityId));
|
||||
@@ -425,6 +426,16 @@ public final class ProtocolTest {
|
||||
eq("view distance", Integer.valueOf(8), Integer.valueOf(worldBack.viewDistance));
|
||||
eq("world height", Integer.valueOf(256), Integer.valueOf(worldBack.worldHeight));
|
||||
eq("spawn x", Double.valueOf(0.5D), Double.valueOf(worldBack.spawnX));
|
||||
eq("game mode", Integer.valueOf(Packets.GAMEMODE_CREATIVE),
|
||||
Integer.valueOf(worldBack.gameMode));
|
||||
|
||||
Packets.GameMode mode = new Packets.GameMode(Packets.GAMEMODE_SURVIVAL);
|
||||
Packets.GameMode modeBack = Packets.GameMode.read(new Buf(mode.write().toByteArray()));
|
||||
eq("survival comes back", Integer.valueOf(Packets.GAMEMODE_SURVIVAL),
|
||||
Integer.valueOf(modeBack.mode));
|
||||
yes("survival cannot break blocks", !modeBack.creative());
|
||||
yes("creative can break blocks",
|
||||
new Packets.GameMode(Packets.GAMEMODE_CREATIVE).creative());
|
||||
|
||||
Packets.BlockChange change = new Packets.BlockChange(-100, 70, 250, Blocks.STONE);
|
||||
Packets.BlockChange changeBack =
|
||||
@@ -528,6 +539,7 @@ public final class ProtocolTest {
|
||||
Packets.WORLD_JOIN, Packets.CHUNK_DATA, Packets.BLOCK_CHANGE,
|
||||
Packets.PLAYER_MOVE, Packets.ENTITY_MOVE, Packets.PING, Packets.PONG,
|
||||
Packets.ENTITY_SPAWN, Packets.ENTITY_REMOVE, Packets.LAUNCHER_AUTH,
|
||||
Packets.SET_GAME_MODE,
|
||||
Packets.DISCONNECT,
|
||||
};
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user