Skip to content

Commit

Permalink
Fixed networking synchronisation
Browse files Browse the repository at this point in the history
  • Loading branch information
Redblueflame committed Jun 27, 2020
1 parent 760b9cd commit 9bbf6cb
Show file tree
Hide file tree
Showing 34 changed files with 526 additions and 414 deletions.
2 changes: 1 addition & 1 deletion src/main/java/com/redblueflame/herbocraft/HerboCraft.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class HerboCraft implements ModInitializer {
// Utils
public static Gson GSON;
public static TurretLooter LOOTS;
private static Logger LOGGER = LogManager.getLogger();
public static Logger LOGGER = LogManager.getLogger();

public static Tag<Item> SEEDS;
public static Tag<Item> BASE_SEEDS;
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/com/redblueflame/herbocraft/HerboCraftClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.redblueflame.herbocraft;

import com.redblueflame.herbocraft.blocks.AbstractProgressBlockEntity;
import com.redblueflame.herbocraft.entities.renderer.SnowTurretRenderer;
import com.redblueflame.herbocraft.entities.renderer.TurretBaseRenderer;
import com.redblueflame.herbocraft.entities.renderer.WitherTurretRenderer;
Expand Down Expand Up @@ -59,5 +60,43 @@ public void onInitializeClient() {
}
});
});
// Register the initial load
ClientSidePacketRegistry.INSTANCE.register(HerboCraftPackets.STATE_CHANGE, ((packetContext, packetByteBuf) -> {
BlockPos pos = packetByteBuf.readBlockPos();
boolean isWorking = packetByteBuf.readBoolean();
int targetWork = packetByteBuf.readInt();
packetContext.getTaskQueue().execute(() -> {
assert MinecraftClient.getInstance().world != null;
AbstractProgressBlockEntity blockEntity = (AbstractProgressBlockEntity) MinecraftClient.getInstance().world.getBlockEntity(pos);
if (blockEntity == null) {
HerboCraft.LOGGER.error("The block entity you're trying to change does not exist on the client !");
return;
}
if (isWorking) {
blockEntity.isWorking = true;
blockEntity.targetWork = targetWork;
} else {
blockEntity.resetWork();
}
});
}));
ClientSidePacketRegistry.INSTANCE.register(HerboCraftPackets.SEND_STATUS, ((packetContext, packetByteBuf) -> {
BlockPos pos = packetByteBuf.readBlockPos();
int targetWork = packetByteBuf.readInt();
int currentWork = packetByteBuf.readInt();
packetContext.getTaskQueue().execute(() -> {
assert MinecraftClient.getInstance().world != null;
AbstractProgressBlockEntity blockEntity = (AbstractProgressBlockEntity) MinecraftClient.getInstance().world.getBlockEntity(pos);
if (blockEntity == null) {
HerboCraft.LOGGER.error("The block entity you're trying to change does nos exist on the client !");
return;
}
blockEntity.targetWork = targetWork;
blockEntity.currentWork = currentWork;
if (targetWork != 0) {
blockEntity.state = (int) ((targetWork/(float)currentWork)*255F);
}
});
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@
public class HerboCraftPackets {
public static final Identifier WATERING_CAN_USAGE_PACKET = new Identifier("herbocraft", "watering_can_usage");
public static final Identifier WATERING_PARTICLE_PACKET = new Identifier("herbocraft", "watering_particle");
public static final Identifier STATE_CHANGE = new Identifier("herbocraft", "state_change");
public static final Identifier SEND_STATUS = new Identifier("herbocraft", "send_state");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.redblueflame.herbocraft.blocks;

import com.redblueflame.herbocraft.HerboCraft;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

@SuppressWarnings("deprecation")
public abstract class AbstractProgressBlock extends AbstractUpgradableBlock implements BlockEntityProvider {
protected AbstractProgressBlock(Settings settings) {
super(settings);
}

@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if (!world.isClient) {
// Sync the server with client for the state of the block.
AbstractProgressBlockEntity blockEntity = (AbstractProgressBlockEntity) world.getBlockEntity(pos);
if (blockEntity == null) {
HerboCraft.LOGGER.error("There were an error while getting the blockentity. Please check your input.");
return ActionResult.PASS;
}
blockEntity.sendBlockProgressPacket(player);
}
return ActionResult.PASS;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package com.redblueflame.herbocraft.blocks;

import com.redblueflame.herbocraft.HerboCraftPackets;
import com.redblueflame.herbocraft.utils.PlayerContainerStream;
import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Tickable;

public abstract class AbstractProgressBlockEntity extends BlockEntity implements Tickable, Progress {
public boolean isWorking;
public int targetWork;
public int currentWork;
public int state;

public AbstractProgressBlockEntity(BlockEntityType<?> type) {
super(type);
isWorking = false;
targetWork = 0;
currentWork = 0;
state = 0;
}

@Override
public void tick() {
if (world != null && !world.isClient) {
// We have to check for the server, is it's on the client, we will have problems.
if (isWorking && targetWork != 0) {
currentWork += 1;
state = (int) (((float)currentWork / targetWork) * 255F);
if (currentWork >= targetWork) {
resetWork();
finishWork();
}
} else {
if (getInventory() != null && this.checkWork()) {
targetWork = estimateWork();
setWorking();
}
}
} else if (isWorking) {
// On the client, we can add the currentWork for display
currentWork += 1;
state = (int) (((float)currentWork / targetWork) * 255F);
}
}

@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
isWorking = tag.getBoolean("isWorking");
targetWork = tag.getInt("targetWork");
currentWork = tag.getInt("currentWork");
if (targetWork != 0) {
this.state = currentWork/targetWork;
}
}

@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
tag.putBoolean("isWorking", isWorking);
tag.putInt("targetWork", targetWork);
tag.putInt("currentWork", currentWork);
return tag;
}

@Override
public void resetWork() {
isWorking = false;
// Send the update to clients
if (world != null && !world.isClient) {
sendStateChangePacket();
}
targetWork = 0;
currentWork = 0;
state = 0;
}

private void setWorking() {
isWorking = true;
if (world != null && !world.isClient) {
sendStateChangePacket();
}
currentWork = 0;
}

protected void registerEvents() {
if (getInventory() != null) {
getInventory().addListener(this::onInventoryUpdate);
}
}

private void onInventoryUpdate(Inventory inventory) {
if (inventoryUpdate(inventory)) {
resetWork();
}
}
// region Packets
private void sendStateChangePacket() {
PacketByteBuf passedData = new PacketByteBuf(Unpooled.buffer());
passedData.writeBlockPos(pos);
passedData.writeBoolean(isWorking);
passedData.writeInt(targetWork);
PlayerContainerStream.GetPlayerWatchingContainer(world, pos, this.getContainerClass()).forEach(playerEntity ->
ServerSidePacketRegistry.INSTANCE.sendToPlayer(playerEntity, HerboCraftPackets.STATE_CHANGE, passedData));
}

protected void sendBlockProgressPacket() {
PacketByteBuf passedData = new PacketByteBuf(Unpooled.buffer());
passedData.writeBlockPos(pos);
passedData.writeInt(targetWork);
passedData.writeInt(currentWork);
PlayerContainerStream.GetPlayerWatchingContainer(world, pos, this.getContainerClass()).forEach(playerEntity ->
ServerSidePacketRegistry.INSTANCE.sendToPlayer(playerEntity, HerboCraftPackets.SEND_STATUS, passedData));
}

protected void sendBlockProgressPacket(PlayerEntity e) {
PacketByteBuf passedData = new PacketByteBuf(Unpooled.buffer());
passedData.writeBlockPos(pos);
passedData.writeInt(targetWork);
passedData.writeInt(currentWork);
ServerSidePacketRegistry.INSTANCE.sendToPlayer(e, HerboCraftPackets.SEND_STATUS, passedData);
}
// endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import net.minecraft.world.BlockView;
import net.minecraft.world.World;

public class GrowthController extends AbstractUpgradableBlock implements BlockEntityProvider {
public class GrowthController extends AbstractProgressBlock {
public GrowthController(Settings settings) {
super(settings);
setDefaultState(this.stateManager.getDefaultState().with(Properties.HORIZONTAL_FACING, Direction.NORTH));
Expand All @@ -34,6 +34,7 @@ public BlockEntity createBlockEntity(BlockView world) {
@SuppressWarnings("deprecation")
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
super.onUse(state, world, pos, player, hand, hit);
if (!world.isClient) {
ContainerProviderRegistry.INSTANCE.openContainer(HerboCraft.GROWTH_CONTROLLER_CONTAINER, player, (buffer) -> {
buffer.writeText(new TranslatableText(this.getTranslationKey()));
Expand Down
Loading

0 comments on commit 9bbf6cb

Please sign in to comment.