package com.github.steveice10.mc.protocol.packet.ingame.server;

import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.setting.Difficulty;
import com.github.steveice10.mc.protocol.data.game.world.WorldType;
import com.github.steveice10.mc.protocol.packet.MinecraftPacket;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;

import java.io.IOException;

public class ServerJoinGamePacket extends MinecraftPacket {
    private int entityId;
    private boolean hardcore;
    private GameMode gamemode;
    private int dimension;
    private Difficulty difficulty;
    private int maxPlayers;
    private WorldType worldType;
    private boolean reducedDebugInfo;

    @SuppressWarnings("unused")
    private ServerJoinGamePacket() {
    }

    public ServerJoinGamePacket(int entityId, boolean hardcore, GameMode gamemode, int dimension, Difficulty difficulty, int maxPlayers, WorldType worldType, boolean reducedDebugInfo) {
        this.entityId = entityId;
        this.hardcore = hardcore;
        this.gamemode = gamemode;
        this.dimension = dimension;
        this.difficulty = difficulty;
        this.maxPlayers = maxPlayers;
        this.worldType = worldType;
        this.reducedDebugInfo = reducedDebugInfo;
    }

    public int getEntityId() {
        return this.entityId;
    }

    public boolean getHardcore() {
        return this.hardcore;
    }

    public GameMode getGameMode() {
        return this.gamemode;
    }

    public int getDimension() {
        return this.dimension;
    }

    public Difficulty getDifficulty() {
        return this.difficulty;
    }

    public int getMaxPlayers() {
        return this.maxPlayers;
    }

    public WorldType getWorldType() {
        return this.worldType;
    }

    public boolean getReducedDebugInfo() {
        return this.reducedDebugInfo;
    }

    @Override
    public void read(NetInput in) throws IOException {
        this.entityId = in.readInt();
        int gamemode = in.readUnsignedByte();
        this.hardcore = (gamemode & 8) == 8;
        gamemode &= -9;
        this.gamemode = MagicValues.key(GameMode.class, gamemode);
        this.dimension = in.readInt();
        this.difficulty = MagicValues.key(Difficulty.class, in.readUnsignedByte());
        this.maxPlayers = in.readUnsignedByte();
        this.worldType = MagicValues.key(WorldType.class, in.readString().toLowerCase());
        this.reducedDebugInfo = in.readBoolean();
    }

    @Override
    public void write(NetOutput out) throws IOException {
        out.writeInt(this.entityId);
        int gamemode = MagicValues.value(Integer.class, this.gamemode);
        if(this.hardcore) {
            gamemode |= 8;
        }

        out.writeByte(gamemode);
        out.writeInt(this.dimension);
        out.writeByte(MagicValues.value(Integer.class, this.difficulty));
        out.writeByte(this.maxPlayers);
        out.writeString(MagicValues.value(String.class, this.worldType));
        out.writeBoolean(this.reducedDebugInfo);
    }
}

@@ -709,43 +709,8 @@
 on;%0A
-    private Difficulty difficulty;%0A
     
@@ -762,24 +762,54 @@
  worldType;%0A
+    private int viewDistance;%0A
     private 
@@ -1012,31 +1012,8 @@
 ion,
- Difficulty difficulty,
  int
@@ -1045,16 +1045,34 @@
 rldType,
+ int viewDistance,
  boolean
@@ -1234,46 +1234,8 @@
 on;%0A
-        this.difficulty = difficulty;%0A
     
@@ -1300,24 +1300,66 @@
  worldType;%0A
+        this.viewDistance = viewDistance;%0A
         this
@@ -1690,87 +1690,8 @@
  %7D%0A%0A
-    public Difficulty getDifficulty() %7B%0A        return this.difficulty;%0A    %7D%0A%0A
     
@@ -1826,32 +1826,103 @@
 rldType;%0A    %7D%0A%0A
+    public int getViewDistance() %7B%0A        return viewDistance;%0A    %7D%0A%0A
     public boole
@@ -2325,92 +2325,8 @@
 ();%0A
-        this.difficulty = MagicValues.key(Difficulty.class, in.readUnsignedByte());%0A
     
@@ -2456,24 +2456,69 @@
 werCase());%0A
+        this.viewDistance = in.readVarInt();%0A
         this
@@ -2884,82 +2884,8 @@
 n);%0A
-        out.writeByte(MagicValues.value(Integer.class, this.difficulty));%0A
     
@@ -2990,24 +2990,68 @@
 orldType));%0A
+        out.writeVarInt(this.viewDistance);%0A
         out.

Update ServerJoinGamePacket