Skip to content

Commit

Permalink
Merge pull request #81 from mircokroon/inventory-fixes
Browse files Browse the repository at this point in the history
Fixed issues with different versions
  • Loading branch information
mircokroon authored Oct 15, 2020
2 parents 66e8b4c + d72e468 commit ae7fbf5
Show file tree
Hide file tree
Showing 22 changed files with 1,083 additions and 122 deletions.
24 changes: 24 additions & 0 deletions src/main/java/game/data/Coordinate3D.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,28 @@ private int withinChunk(int val) {
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
if (!super.equals(o)) {
return false;
}

Coordinate3D that = (Coordinate3D) o;

return y == that.y;
}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + y;
return result;
}
}
18 changes: 18 additions & 0 deletions src/main/java/game/data/WorldManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import game.data.chunk.ChunkFactory;
import game.data.chunk.entity.EntityNames;
import game.data.chunk.palette.BlockColors;
import game.data.chunk.palette.BlockState;
import game.data.chunk.palette.GlobalPalette;
import game.data.container.ContainerManager;
import game.data.container.ItemRegistry;
Expand Down Expand Up @@ -285,6 +286,15 @@ public static void unloadChunk(CoordinateDim2D coordinate) {
}
}

public static BlockState blockStateAt(Coordinate3D coordinate3D) {
Chunk c = WorldManager.getChunk(coordinate3D.globalToChunk().addDimension(Game.getDimension()));

if (c == null) { return null; }

Coordinate3D pos = coordinate3D.withinChunk();
return c.getBlockStateAt(pos);
}

public static void setGlobalPalette(GlobalPalette palette) {
globalPalette = palette;
}
Expand Down Expand Up @@ -324,6 +334,14 @@ public static void setItemRegistry(ItemRegistry items) {
itemRegistry = items;
}

/**
* Mark a chunk and it's region as having unsaved changes.
*/
public static void touchChunk(Chunk c) {
c.touch();
regions.get(c.location.chunkToDimRegion()).touch();
}

/**
* Loop to call save periodically.
*/
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/game/data/chunk/Chunk.java
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,12 @@ public void addInventory(InventoryWindow window) {
tileEntity.add("CustomName", new StringTag(window.getWindowTitle()));
}

}

/**
* Mark this chunk as unsaved.
*/
public void touch() {
this.setSaved(false);
}
}
1 change: 1 addition & 0 deletions src/main/java/game/data/chunk/ChunkBinary.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public static ChunkBinary fromChunk(Chunk chunk) throws IOException {
nbt.write(new DataOutputStream(output));
} catch (Exception ex) {
System.out.println("Unable to write chunk " + chunk.location.getX() + ", " + chunk.location.getZ());
ex.printStackTrace();
return null;
}

Expand Down
9 changes: 8 additions & 1 deletion src/main/java/game/data/chunk/palette/BlockState.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,22 @@ public String getProperty(String name) {
return properties.get(name);
}

public boolean isChest() {
return name.equals("minecraft:chest") || name.equals("minecraft:trapped_chest");
}
public boolean isDoubleChest() {
if (!name.equals("minecraft:chest") && !name.equals("minecraft:trapped_chest")) {
if (!isChest()) {
return false;
}

String type = properties.get("type");
return type.equals("left") || type.equals("right");
}

public boolean hasProperty(String property) {
return properties.get(property) != null;
}

/**
* Convert this palette state to NBT format.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/game/data/chunk/version/Chunk_1_13.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected void setBiomes(int[] biomes) {

@Override
protected void addLevelNbtTags(CompoundTag map) {
map.add("Status", new StringTag("full"));
map.add("Status", new StringTag("postprocessed"));

// empty maps
CompoundTag carvingMasks = new CompoundTag();
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/game/data/chunk/version/Chunk_1_14.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import packets.DataTypeProvider;
import se.llbit.nbt.CompoundTag;
import se.llbit.nbt.SpecificTag;
import se.llbit.nbt.StringTag;

/**
* In 1.14 the chunks are now given a heightmap in the packet. They also no longer contain light information, as
Expand All @@ -20,8 +21,10 @@ public Chunk_1_14(CoordinateDim2D location) {

@Override
protected void addLevelNbtTags(CompoundTag map) {
map.add("Heightmaps", heightMap);
super.addLevelNbtTags(map);

map.add("Heightmaps", heightMap);
map.add("Status", new StringTag("full"));
}

@Override
Expand Down
57 changes: 56 additions & 1 deletion src/main/java/game/data/container/ContainerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import game.Game;
import game.data.Coordinate2D;
import game.data.Coordinate3D;
import game.data.CoordinateDim2D;
import game.data.WorldManager;
import game.data.chunk.Chunk;
import game.data.chunk.palette.BlockState;
import org.apache.commons.lang3.ArrayUtils;

import java.util.HashMap;
import java.util.List;
Expand All @@ -25,6 +27,21 @@ public void lastInteractedWith(Coordinate3D coordinates) {
lastInteractedWith = coordinates;
}

public void openWindow_1_12(int windowId, int numSlots, String windowTitle) {
if (windowId == PLAYER_INVENTORY) {
return;
}

if (lastInteractedWith != null) {
InventoryWindow window = new InventoryWindow(windowTitle, lastInteractedWith, numSlots);

// if a window has 0 slots, ignore it
if (window.getSlotCount() > 0) {
knownWindows.put(windowId, window);
}
}
}

public void openWindow(int windowId, int windowType, String windowTitle) {
if (windowId == PLAYER_INVENTORY) {
return;
Expand Down Expand Up @@ -53,15 +70,53 @@ private void closeWindow(InventoryWindow window) {
if (c == null) { return; }

BlockState block = c.getBlockStateAt(window.getContainerLocation().withinChunk());

if (block == null) { return; }

if (window.getSlotList().size() == 54 && block.isDoubleChest()) {
WorldManager.touchChunk(c);

if (window.getSlotList().size() == 54 && block.hasProperty("type") && block.isDoubleChest()) {
addDoubleChestInventory(block, window);
} else if (window.getSlotList().size() == 54 && !block.hasProperty("type") && block.isChest()) {
handleChest1_12(block, window);
} else {
c.addInventory(window);
}
}

/**
* Handles double chests in 1.12.
*/
private void handleChest1_12(BlockState block, InventoryWindow window) {
Direction facing = Direction.valueOf(block.getProperty("facing").toUpperCase());
Coordinate3D pos = window.getContainerLocation();

Coordinate3D beforePos = pos.add(facing.clockwise().toCoordinate());
BlockState blockBefore = WorldManager.blockStateAt(beforePos);

InventoryWindow[] chests = window.split();

// for some reason the ordering of double chests depends on the direction they are facing in 1.12 (wtf?)
if (facing.equals(Direction.NORTH) || facing.equals(Direction.EAST)) {
ArrayUtils.swap(chests, 0, 1);
}

// if it's the left half of the chest
if (blockBefore == block) {
chests[0].adjustContainerLocation(facing.clockwise().toCoordinate());
} else {
// otherwise it must be the right half ... we don't support triple chests
chests[1].adjustContainerLocation(facing.counterClockwise().toCoordinate());
}


closeWindow(chests[0]);
closeWindow(chests[1]);
}

/**
* Split Window into two halves, for two halves of a double chest.
*/
private void addDoubleChestInventory(BlockState block, InventoryWindow window) {
InventoryWindow[] chests = window.split();
Coordinate2D companionDirection = getCompanionChestDirection(block);
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/game/data/container/InventoryWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ public class InventoryWindow {

Coordinate3D containerLocation;

/**
* Constructor for 1.12, slot count is just given here
*/
InventoryWindow(String windowTitle, Coordinate3D containerLocation, int slotCount) {
this.windowType = -1;
this.windowTitle = windowTitle;
this.containerLocation = containerLocation;

this.slotCount = slotCount;
}

/**
* Constructor for later versions, we need to check the window type against the registry
*/
InventoryWindow(int windowType, String windowTitle, Coordinate3D containerLocation) {
this.windowType = windowType;
this.windowTitle = windowTitle;
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/game/data/container/ItemRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@

import com.google.gson.Gson;

import game.data.chunk.palette.GlobalPalette;
import game.data.registries.RegistriesJson;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class ItemRegistry {
private Map<Integer, String> items;

public static ItemRegistry fromJson(String version) {
InputStream x = GlobalPalette.class.getClassLoader().getResourceAsStream("items-" + version + ".json");
if (x == null) {
return null;
}
Gson g = new Gson();
return g.fromJson(new InputStreamReader(x), ItemRegistry.class);
}

public static ItemRegistry fromRegistry(FileInputStream input) {
if (input == null) { return new ItemRegistry(); }

Expand Down
1 change: 1 addition & 0 deletions src/main/java/game/data/container/Slot.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public Slot(int itemId, byte count, SpecificTag nbt) {
public String toString() {
return "Slot{" +
"itemId=" + itemId +
", Name=" + WorldManager.getItemRegistry().getItemName(itemId) +
", count=" + count +
", nbt=" + nbt +
'}';
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/game/data/container/Slot_1_12.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package game.data.container;

import se.llbit.nbt.CompoundTag;
import se.llbit.nbt.ShortTag;
import se.llbit.nbt.SpecificTag;

public class Slot_1_12 extends Slot {
private int damage;

public Slot_1_12(int itemId, byte count, int damage, SpecificTag nbt) {
super(itemId, count, nbt);

this.damage = damage;
}

@Override
public String toString() {
return "Slot_1_12{" +
super.toString() +
", damage=" + damage +
'}';
}

public CompoundTag toNbt(int index) {
CompoundTag tag = super.toNbt(index);
tag.add("Damage", new ShortTag((short) damage));
return tag;
}
}
6 changes: 6 additions & 0 deletions src/main/java/game/data/region/Region.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,10 @@ public McaFile toFile() {
return new McaFile(regionCoordinates, chunkBinaryMap);
}

/**
* Mark region as having modified chunks.
*/
public void touch() {
this.updatedSinceLastWrite = true;
}
}
8 changes: 7 additions & 1 deletion src/main/java/game/data/registries/RegistryLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ public RegistryLoader(String version) throws IOException, InterruptedException {
* server jar couldn't yet generate reports at this point.
*/
private boolean hasExistingReports() {
return version.equals("1.12.2") || blocksPath.toFile().exists() && registryPath.toFile().exists();
if (version.equals("1.13.2")) {
System.out.println("No item registry for 1.13.2. We won't be able to save chests contents :(");
}

return version.equals("1.12.2") || blocksPath.toFile().exists();
}

/**
Expand Down Expand Up @@ -186,6 +190,8 @@ public MenuRegistry generateMenuRegistry() throws IOException {
public ItemRegistry generateItemRegistry() throws IOException {
if (versionSupportsGenerators()) {
return ItemRegistry.fromRegistry(new FileInputStream(registryPath.toFile()));
} else if (version.equals("1.12.2")) {
return ItemRegistry.fromJson(version);
} else {
return new ItemRegistry();
}
Expand Down
18 changes: 14 additions & 4 deletions src/main/java/packets/DataTypeProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import game.Game;
import game.data.Coordinate3D;
import game.data.container.Slot;
import game.data.container.Slot_1_12;
import packets.version.DataTypeProvider_1_13;
import packets.version.DataTypeProvider_1_14;
import se.llbit.nbt.NamedTag;
import se.llbit.nbt.SpecificTag;
Expand All @@ -27,8 +29,10 @@ public DataTypeProvider(byte[] finalFullPacket) {
}

public static DataTypeProvider ofPacket(byte[] finalFullPacket) {
if (Game.getProtocolVersion() > 404) {
if (Game.getProtocolVersion() >= 477) {
return new DataTypeProvider_1_14(finalFullPacket);
} else if (Game.getProtocolVersion() >= 404) {
return new DataTypeProvider_1_13(finalFullPacket);
} else {
return new DataTypeProvider(finalFullPacket);
}
Expand Down Expand Up @@ -214,11 +218,17 @@ public List<Slot> readSlots(int count) {
return slots;
}

/**
* 1.12 version for slot reading, slightly different from 1.13+
*/
public Slot readSlot() {
if (readBoolean()) {
return new Slot(readVarInt(), readNext(), readNbtTag());
int itemId = readShort();

if (itemId == 0xFFFF) {
return null;
}
return null;

return new Slot_1_12(itemId, readNext(), readShort(), readNbtTag());
}

public static int readOptVarInt(DataTypeProvider provider) {
Expand Down
Loading

0 comments on commit ae7fbf5

Please sign in to comment.