Move net packet to kotlin, add more network channels

This commit is contained in:
DBotThePony 2022-08-25 11:27:57 +07:00
parent 69b8115395
commit de7f89186d
Signed by: DBot
GPG Key ID: DCC23B5715498507
39 changed files with 518 additions and 859 deletions

View File

@ -28,8 +28,7 @@ import ru.dbotthepony.mc.otm.item.weapon.AbstractWeaponItem;
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem; import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem;
import ru.dbotthepony.mc.otm.matter.MatterDataKt; import ru.dbotthepony.mc.otm.matter.MatterDataKt;
import ru.dbotthepony.mc.otm.matter.MatterRegistryKt; import ru.dbotthepony.mc.otm.matter.MatterRegistryKt;
import ru.dbotthepony.mc.otm.network.AndroidNetworkChannel; import ru.dbotthepony.mc.otm.network.*;
import ru.dbotthepony.mc.otm.network.MatteryNetworking;
import ru.dbotthepony.mc.otm.registry.*; import ru.dbotthepony.mc.otm.registry.*;
import ru.dbotthepony.mc.otm.storage.*; import ru.dbotthepony.mc.otm.storage.*;
@ -100,8 +99,11 @@ public final class OverdriveThatMatters {
} }
private void setup(final FMLCommonSetupEvent event) { private void setup(final FMLCommonSetupEvent event) {
MatteryNetworking.register();
AndroidNetworkChannel.INSTANCE.register(); AndroidNetworkChannel.INSTANCE.register();
MenuNetworkChannel.INSTANCE.register();
WeaponNetworkChannel.INSTANCE.register();
RegistryNetworkChannel.INSTANCE.register();
WorldNetworkChannel.INSTANCE.register();
ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125")); ITEM_STORAGE = StorageRegistry.register(ItemStackWrapper.class, ItemStackWrapper.EMPTY, new ImpreciseFraction("3.125"));

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.capability;
import mekanism.api.energy.IStrictEnergyHandler; import mekanism.api.energy.IStrictEnergyHandler;
import net.minecraftforge.common.capabilities.*; import net.minecraftforge.common.capabilities.*;
import org.jetbrains.annotations.NotNull;
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive; import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler; import ru.dbotthepony.mc.otm.capability.matter.IMatterHandler;
import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider; import ru.dbotthepony.mc.otm.capability.matter.IMatterTaskProvider;
@ -10,16 +11,43 @@ import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode;
import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode; import ru.dbotthepony.mc.otm.graph.storage.IStorageGraphNode;
import ru.dbotthepony.mc.otm.storage.IStorageStack; import ru.dbotthepony.mc.otm.storage.IStorageStack;
import javax.annotation.Nonnull;
public class MatteryCapability { public class MatteryCapability {
@Nonnull
@NotNull
public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IMatteryEnergyStorage> ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<AndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<AndroidCapability> ANDROID = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IMatterHandler> MATTER = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IMatterHandler> MATTER = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IMatterGraphNode> MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IMatterGraphNode> MATTER_NODE = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IPatternStorage> PATTERN = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IPatternStorage> PATTERN = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IMatterTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IMatterTaskProvider> TASK = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IMatteryDrive<IStorageStack>> DRIVE = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IMatteryDrive<IStorageStack>> DRIVE = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IStorageGraphNode> STORAGE_NODE = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IStorageGraphNode> STORAGE_NODE = CapabilityManager.get(new CapabilityToken<>() {});
@Nonnull
@NotNull
public static final Capability<IStrictEnergyHandler> MEKANISM_ENERGY = CapabilityManager.get(new CapabilityToken<>() {}); public static final Capability<IStrictEnergyHandler> MEKANISM_ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -8,8 +8,8 @@ import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.capability.matter.MatterTask; import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
import ru.dbotthepony.mc.otm.capability.matter.PatternState; import ru.dbotthepony.mc.otm.capability.matter.PatternState;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu; import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import ru.dbotthepony.mc.otm.network.MatteryNetworking; import ru.dbotthepony.mc.otm.menu.ReplicationRequestPacket;
import ru.dbotthepony.mc.otm.network.PatternReplicationRequestPacket; import ru.dbotthepony.mc.otm.network.MenuNetworkChannel;
import ru.dbotthepony.mc.otm.client.screen.panels.*; import ru.dbotthepony.mc.otm.client.screen.panels.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -388,7 +388,7 @@ public class MatterPanelScreen extends MatteryScreen<MatterPanelMenu> {
} }
MatteryNetworking.CHANNEL.sendToServer(new PatternReplicationRequestPacket(state, value)); MenuNetworkChannel.INSTANCE.sendToServer(new ReplicationRequestPacket(state, value));
pattern_frame.remove(); pattern_frame.remove();
}); });

View File

@ -1,30 +0,0 @@
package ru.dbotthepony.mc.otm.menu.data;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
public record ClearPacket(int id) {
public void write(FriendlyByteBuf buffer) {
buffer.writeInt(id);
}
public static ClearPacket read(FriendlyByteBuf buffer) {
return new ClearPacket(buffer.readInt());
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var get = Minecraft.getInstance().player.containerMenu instanceof INetworkedItemViewSupplier supplier && Minecraft.getInstance().player.containerMenu.containerId == id ? supplier.getNetworkedItemView() : null;
if (get == null) {
throw new IllegalStateException("No such item tracker with id " + id);
}
get.clear();
});
}
}

View File

@ -1,11 +0,0 @@
package ru.dbotthepony.mc.otm.menu.data;
import net.minecraft.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public interface INetworkedItemViewSupplier {
NetworkedItemView getNetworkedItemView();
}

View File

@ -1,37 +0,0 @@
package ru.dbotthepony.mc.otm.menu.data;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.inventory.ClickAction;
import net.minecraft.world.inventory.ClickType;
import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
public record InteractPacket(int id, int stack_id, ClickType click, ClickAction action) {
public void write(FriendlyByteBuf buffer) {
buffer.writeInt(id);
buffer.writeInt(stack_id);
buffer.writeEnum(click);
buffer.writeEnum(action);
}
public static InteractPacket read(FriendlyByteBuf buffer) {
var id = buffer.readInt();
var stack = buffer.readInt();
var click = buffer.readEnum(ClickType.class);
var action = buffer.readEnum(ClickAction.class);
return new InteractPacket(id, stack, click, action);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var ply = context.get().getSender();
if (ply.containerMenu instanceof INetworkedItemViewSupplier supplier && ply.containerMenu.containerId == id) {
ply.resetLastActionTime();
supplier.getNetworkedItemView().playerInteract(this);
}
});
}
}

View File

@ -1,40 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import java.util.UUID;
import java.util.function.Supplier;
public record CancelMatterTaskPacket(UUID id) {
public CancelMatterTaskPacket(UUID id) {
this.id = id;
}
public CancelMatterTaskPacket(MatterTask task) {
this(task.id());
}
public void write(FriendlyByteBuf buffer) {
buffer.writeLong(id.getMostSignificantBits());
buffer.writeLong(id.getLeastSignificantBits());
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
var player = context.get().getSender();
if (player.containerMenu instanceof MatterPanelMenu menu) {
menu.receiveTaskCancel(player, id);
}
});
}
public static CancelMatterTaskPacket read(FriendlyByteBuf buffer) {
return new CancelMatterTaskPacket(new UUID(buffer.readLong(), buffer.readLong()));
}
}

View File

@ -1,54 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.matter.MatterTask;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Supplier;
@ParametersAreNonnullByDefault
public record MatterTaskPacket(boolean action, Collection<MatterTask> state) {
public void write(FriendlyByteBuf buffer) {
buffer.writeBoolean(action);
buffer.writeInt(state.size());
for (var state1 : state)
state1.write(buffer);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::playClient));
}
private void playClient() {
if (Minecraft.getInstance().player.containerMenu instanceof MatterPanelMenu menu) {
if (action)
menu.networkTasksUpdated(state);
else
menu.networkTasksRemoved(state);
} else {
OverdriveThatMatters.LOGGER.error("Receive task state list, but no valid container is open / open container is not MatterPanelMenu!");
}
}
public static MatterTaskPacket read(FriendlyByteBuf buffer) {
boolean action = buffer.readBoolean();
int amount = buffer.readInt();
var list = new ArrayList<MatterTask>(amount);
for (int i = 0; i < amount; i++)
list.add(Objects.requireNonNull(MatterTask.read(buffer)));
return new MatterTaskPacket(action, list);
}
}

View File

@ -1,262 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterPacket;
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings;
import ru.dbotthepony.mc.otm.container.ItemFilterSlotPacket;
import ru.dbotthepony.mc.otm.item.weapon.WeaponScopePacket;
import ru.dbotthepony.mc.otm.item.weapon.WeaponFireInputPacket;
import ru.dbotthepony.mc.otm.matter.RegistryPacketClear;
import ru.dbotthepony.mc.otm.matter.RegistryPacketFullUpdate;
import ru.dbotthepony.mc.otm.matter.RegistryPacketRemove;
import ru.dbotthepony.mc.otm.matter.RegistryPacketUpdate;
import ru.dbotthepony.mc.otm.menu.data.*;
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputPacket;
import ru.dbotthepony.mc.otm.menu.widget.NumberPlayerInputPacket;
import ru.dbotthepony.mc.otm.menu.widget.OneWayPlayerInputPacket;
import java.util.Optional;
public class MatteryNetworking {
private static final String PROTOCOL_VERSION = "2";
private static int next_network_id = 0;
public static final SimpleChannel CHANNEL = NetworkRegistry.newSimpleChannel(
new ResourceLocation(OverdriveThatMatters.MOD_ID, "main"),
() -> PROTOCOL_VERSION,
PROTOCOL_VERSION::equals,
PROTOCOL_VERSION::equals
);
public static void send(ServerPlayer ply, Object ...messages) {
if (ply == null) {
for (var message : messages) {
CHANNEL.sendToServer(message);
}
return;
}
var supplier = PacketDistributor.PLAYER.with(() -> ply);
for (var message : messages) {
CHANNEL.send(supplier, message);
}
}
public static void register() {
CHANNEL.registerMessage(
next_network_id++,
PatternGridPacket.class,
PatternGridPacket::write,
PatternGridPacket::read,
PatternGridPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
MatterTaskPacket.class,
MatterTaskPacket::write,
MatterTaskPacket::read,
MatterTaskPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
CancelMatterTaskPacket.class,
CancelMatterTaskPacket::write,
CancelMatterTaskPacket::read,
CancelMatterTaskPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
PatternReplicationRequestPacket.class,
PatternReplicationRequestPacket::write,
PatternReplicationRequestPacket::read,
PatternReplicationRequestPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
RegistryPacketClear.class,
RegistryPacketClear::write,
RegistryPacketClear.Companion::read,
RegistryPacketClear::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
RegistryPacketUpdate.class,
RegistryPacketUpdate::write,
RegistryPacketUpdate.Companion::read,
RegistryPacketUpdate::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
RegistryPacketFullUpdate.class,
RegistryPacketFullUpdate::write,
RegistryPacketFullUpdate.Companion::read,
RegistryPacketFullUpdate::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
RegistryPacketRemove.class,
RegistryPacketRemove::write,
RegistryPacketRemove.Companion::read,
RegistryPacketRemove::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
ClearPacket.class,
ClearPacket::write,
ClearPacket::read,
ClearPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
StackAddPacket.class,
StackAddPacket::write,
StackAddPacket.Companion::read,
StackAddPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
StackChangePacket.class,
StackChangePacket::write,
StackChangePacket.Companion::read,
StackChangePacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
StackRemovePacket.class,
StackRemovePacket::write,
StackRemovePacket.Companion::read,
StackRemovePacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
InteractPacket.class,
InteractPacket::write,
InteractPacket::read,
InteractPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
SetCarriedPacket.class,
SetCarriedPacket::write,
SetCarriedPacket::read,
SetCarriedPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
EnergyCounterPacket.class,
EnergyCounterPacket::write,
EnergyCounterPacket.Companion::read,
EnergyCounterPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
BooleanPlayerInputPacket.class,
BooleanPlayerInputPacket::write,
BooleanPlayerInputPacket.Companion::read,
BooleanPlayerInputPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
OneWayPlayerInputPacket.class,
OneWayPlayerInputPacket::write,
OneWayPlayerInputPacket.Companion::read,
OneWayPlayerInputPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
NumberPlayerInputPacket.class,
NumberPlayerInputPacket::write,
NumberPlayerInputPacket.Companion::read,
NumberPlayerInputPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
MultiByteDataContainerPacket.class,
MultiByteDataContainerPacket::write,
MultiByteDataContainerPacket.Companion::read,
MultiByteDataContainerPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
CHANNEL.registerMessage(
next_network_id++,
WeaponScopePacket.class,
WeaponScopePacket::write,
WeaponScopePacket.Companion::read,
WeaponScopePacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
WeaponFireInputPacket.class,
WeaponFireInputPacket::write,
WeaponFireInputPacket.Companion::read,
WeaponFireInputPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
ItemFilterSlotPacket.class,
ItemFilterSlotPacket::write,
ItemFilterSlotPacket.Companion::read,
ItemFilterSlotPacket::play
// Optional.of(NetworkDirection.)
);
CHANNEL.registerMessage(
next_network_id++,
ItemMonitorPlayerSettings.class,
ItemMonitorPlayerSettings::write,
ItemMonitorPlayerSettings.Companion::read,
ItemMonitorPlayerSettings::play
// Optional.of(NetworkDirection.)
);
}
}

View File

@ -1,62 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.network.FriendlyByteBuf;
import java.math.BigDecimal;
import java.math.BigInteger;
public class NetworkHelper {
public static BigDecimal readDecimal(FriendlyByteBuf buffer) {
int scale = buffer.readInt();
int length = buffer.readByte() & 0xFF;
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++)
bytes[i] = buffer.readByte();
return new BigDecimal(new BigInteger(bytes), scale);
}
public static void writeDecimal(FriendlyByteBuf buffer, BigDecimal value) {
buffer.writeInt(value.scale());
byte[] build = value.unscaledValue().toByteArray();
buffer.writeByte(build.length);
for (byte b : build) buffer.writeByte(b);
}
public static short[] bytesToShorts(byte[] input) {
if (input.length % 2 != 0) {
short[] values = new short[input.length / 2 + 1];
for (int i = 0; i < values.length - 1; i++)
values[i] = (short) ((input[i * 2] & 0xFF) | (input[i * 2 + 1] & 0xFF) << 8);
values[values.length - 1] = input[input.length - 1];
return values;
}
short[] values = new short[input.length / 2];
for (int i = 0; i < values.length; i++)
values[i] = (short) ((input[i * 2] & 0xFF) | (input[i * 2 + 1] & 0xFF) << 8);
return values;
}
public static byte[] shortsToBytes(short[] input) {
return shortsToBytes(input, 0);
}
public static byte[] shortsToBytes(short[] input, int offset) {
byte[] values = new byte[(input.length - offset) * 2];
for (int i = offset; i < input.length; i++) {
int realI = i - offset;
values[realI * 2] = (byte) (input[i] & 0xFF);
values[realI * 2 + 1] = (byte) ((input[i] & 0xFF00) >> 8);
}
return values;
}
}

View File

@ -1,56 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.NetworkEvent;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.capability.matter.PatternState;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.function.Supplier;
@ParametersAreNonnullByDefault
public record PatternGridPacket(boolean action, Collection<PatternState> state) {
public void write(FriendlyByteBuf buffer) {
buffer.writeBoolean(action);
buffer.writeInt(state.size());
for (var state1 : state)
state1.write(buffer);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::playClient));
}
private void playClient() {
if (Minecraft.getInstance().player.containerMenu instanceof MatterPanelMenu menu) {
if (action)
menu.networkPatternsUpdated(state);
else
menu.networkPatternsRemoved(state);
return;
}
OverdriveThatMatters.LOGGER.error("Receive pattern state list, but no valid container is open / container is not MatterPanelMenu!");
}
public static PatternGridPacket read(FriendlyByteBuf buffer) {
boolean action = buffer.readBoolean();
int amount = buffer.readInt();
var list = new ArrayList<PatternState>(amount);
for (int i = 0; i < amount; i++)
list.add(Objects.requireNonNull(PatternState.read(buffer)));
return new PatternGridPacket(action, list);
}
}

View File

@ -1,38 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import ru.dbotthepony.mc.otm.capability.matter.PatternState;
import ru.dbotthepony.mc.otm.menu.MatterPanelMenu;
import java.util.function.Supplier;
public record PatternReplicationRequestPacket(PatternState state, int how_much) {
public PatternReplicationRequestPacket(PatternState state, int how_much) {
this.state = state;
this.how_much = Math.max(1, Math.min(99999, how_much));
}
public void write(FriendlyByteBuf buffer) {
state.write(buffer);
buffer.writeInt(how_much);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
if (state == null)
return;
var ply = context.get().getSender();
if (ply.containerMenu instanceof MatterPanelMenu menu)
menu.requestReplication(ply, state, how_much);
});
}
public static PatternReplicationRequestPacket read(FriendlyByteBuf buffer) {
return new PatternReplicationRequestPacket(PatternState.read(buffer), buffer.readInt());
}
}

View File

@ -1,27 +0,0 @@
package ru.dbotthepony.mc.otm.network;
import net.minecraft.client.Minecraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
public record SetCarriedPacket(ItemStack carried) {
public void write(FriendlyByteBuf buffer) {
buffer.writeItem(carried);
}
public void play(Supplier<NetworkEvent.Context> context) {
context.get().setPacketHandled(true);
context.get().enqueueWork(() -> {
if (Minecraft.getInstance().player.containerMenu != null) {
Minecraft.getInstance().player.containerMenu.setCarried(carried);
}
});
}
public static SetCarriedPacket read(FriendlyByteBuf buffer) {
return new SetCarriedPacket(buffer.readItem());
}
}

View File

@ -12,19 +12,12 @@ import net.minecraft.core.Vec3i
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.LongArrayTag import net.minecraft.nbt.LongArrayTag
import net.minecraft.nbt.Tag import net.minecraft.nbt.Tag
import net.minecraft.network.chat.MutableComponent
import net.minecraft.network.chat.contents.LiteralContents
import net.minecraft.network.chat.contents.TranslatableContents
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.Container import net.minecraft.world.Container
import net.minecraft.world.entity.Entity import net.minecraft.world.entity.Entity
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3 import net.minecraft.world.phys.Vec3
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.IItemHandler
import net.minecraftforge.registries.ForgeRegistries
import net.minecraftforge.registries.IForgeRegistry
import java.util.* import java.util.*
import kotlin.properties.ReadWriteProperty import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty

View File

@ -39,6 +39,11 @@ val MINECRAFT_SERVER: MinecraftServer
return _server ?: throw NullPointerException("Not running a server!") return _server ?: throw NullPointerException("Not running a server!")
} }
val NULLABLE_MINECRAFT_SERVER: MinecraftServer?
get() {
return _server
}
// Flag whenever is server alive // Flag whenever is server alive
// To avoid baby deadlocks caused by minecraft engine design issues // To avoid baby deadlocks caused by minecraft engine design issues
var SERVER_IS_DYING = true var SERVER_IS_DYING = true

View File

@ -18,7 +18,6 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.CapabilityEnergy
import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.energy.IEnergyStorage
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
@ -28,14 +27,15 @@ import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.WorldNetworkChannel
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.* import java.util.*
import java.util.function.Supplier import java.util.function.Supplier
data class EnergyCounterPacket(val pos: BlockPos, val thisTick: ImpreciseFraction, val total: ImpreciseFraction, val index: Int, val value: ImpreciseFraction) { data class EnergyCounterPacket(val pos: BlockPos, val thisTick: ImpreciseFraction, val total: ImpreciseFraction, val index: Int, val value: ImpreciseFraction) : MatteryPacket {
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeBlockPos(pos) buff.writeBlockPos(pos)
thisTick.write(buff) thisTick.write(buff)
total.write(buff) total.write(buff)
@ -43,7 +43,7 @@ data class EnergyCounterPacket(val pos: BlockPos, val thisTick: ImpreciseFractio
value.write(buff) value.write(buff)
} }
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
@ -459,7 +459,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
historyTick = (historyTick + 1) % history.size historyTick = (historyTick + 1) % history.size
history[historyTick] = ImpreciseFraction.ZERO history[historyTick] = ImpreciseFraction.ZERO
MatteryNetworking.CHANNEL.send(PacketDistributor.NEAR.with(this::distributor), EnergyCounterPacket(blockPos, lastTick, passed, index, accumulated)) WorldNetworkChannel.send(PacketDistributor.NEAR.with(this::distributor), EnergyCounterPacket(blockPos, lastTick, passed, index, accumulated))
} }
fun clientTick() { fun clientTick() {

View File

@ -37,6 +37,7 @@ import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import ru.dbotthepony.mc.otm.storage.* import ru.dbotthepony.mc.otm.storage.*
@ -46,7 +47,7 @@ import java.util.function.Supplier
import kotlin.collections.HashMap import kotlin.collections.HashMap
import kotlin.collections.HashSet import kotlin.collections.HashSet
class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag> { class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag>, MatteryPacket {
enum class RefillSource(val component: Component) { enum class RefillSource(val component: Component) {
// Refill everything from system // Refill everything from system
SYSTEM(TranslatableComponent("otm.gui.item_monitor.refill_source.system")), SYSTEM(TranslatableComponent("otm.gui.item_monitor.refill_source.system")),
@ -112,7 +113,7 @@ class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag> {
craftingAmount = other.craftingAmount craftingAmount = other.craftingAmount
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeEnum(refillSource) buff.writeEnum(refillSource)
buff.writeEnum(resultTarget) buff.writeEnum(resultTarget)
buff.writeEnum(craftingAmount) buff.writeEnum(craftingAmount)
@ -131,7 +132,7 @@ class ItemMonitorPlayerSettings : INBTSerializable<CompoundTag> {
(container.tile as ItemMonitorBlockEntity).setChangedLight() (container.tile as ItemMonitorBlockEntity).setChangedLight()
} }
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
val ply = context.get().sender val ply = context.get().sender

View File

@ -52,15 +52,15 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT) val grid = GridPanel(this, frame, 28f, 16f, GRID_WIDTH * 18f, GRID_HEIGHT * 18f, GRID_WIDTH, GRID_HEIGHT)
val scrollBar = ScrollBarPanel(this, frame, 192f, 14f, 92f) val scrollBar = ScrollBarPanel(this, frame, 192f, 14f, 92f)
scrollBar.setupRowMultiplier { menu.view.itemCount / GRID_WIDTH } scrollBar.setupRowMultiplier { menu.networkedItemView.itemCount / GRID_WIDTH }
views.add(grid) views.add(grid)
views.add(scrollBar) views.add(scrollBar)
for (i in 0 until GRID_WIDTH * GRID_HEIGHT) { for (i in 0 until GRID_WIDTH * GRID_HEIGHT) {
object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) { object : AbstractSlotPanel(this@DriveViewerScreen, grid, 0f, 0f) {
override fun getItemStack(): ItemStack { override fun getItemStack(): ItemStack {
val index = i + scrollBar.getScroll(menu.view.sortedView.size / GRID_WIDTH) val index = i + scrollBar.getScroll(menu.networkedItemView.sortedView.size / GRID_WIDTH)
return menu.view.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
} }
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean { override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
@ -69,7 +69,7 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean { override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
val index = i + scrollBar.getScroll(GRID_WIDTH) val index = i + scrollBar.getScroll(GRID_WIDTH)
menu.view.mouseClick(index, mouse_click_type) menu.networkedItemView.mouseClick(index, mouse_click_type)
return true return true
} }
@ -81,8 +81,8 @@ class DriveViewerScreen(menu: DriveViewerMenu, inventory: Inventory, title: Comp
override fun getItemStackTooltip(stack: ItemStack): List<Component> { override fun getItemStackTooltip(stack: ItemStack): List<Component> {
return super.getItemStackTooltip(stack).also { return super.getItemStackTooltip(stack).also {
it as MutableList<Component> it as MutableList<Component>
val index = i + scrollBar.getScroll(menu.view.sortedView.size / GRID_WIDTH) val index = i + scrollBar.getScroll(menu.networkedItemView.sortedView.size / GRID_WIDTH)
val realStack = menu.view.sortedView.getOrNull(index)!!.stack val realStack = menu.networkedItemView.sortedView.getOrNull(index)!!.stack
it.add(TranslatableComponent("otm.gui.item_amount", realStack.count.toString())) it.add(TranslatableComponent("otm.gui.item_amount", realStack.count.toString()))
} }
} }

View File

@ -10,7 +10,6 @@ import net.minecraft.world.item.Items
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
import ru.dbotthepony.mc.otm.TranslatableComponent import ru.dbotthepony.mc.otm.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
import ru.dbotthepony.mc.otm.client.render.SkinGrid
import ru.dbotthepony.mc.otm.client.render.UVWindingOrder import ru.dbotthepony.mc.otm.client.render.UVWindingOrder
import ru.dbotthepony.mc.otm.client.render.Widgets8 import ru.dbotthepony.mc.otm.client.render.Widgets8
import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.*
@ -40,7 +39,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right frame.width = 178f + frame.dockPadding.left + frame.dockPadding.right
val viewScrollBar = ScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f) val viewScrollBar = ScrollBarPanel(this, topPanel, 28f + ITEM_GRID_WIDTH * 18f + 2f, 16f, ITEM_GRID_HEIGHT * 18f)
viewScrollBar.setupRowMultiplier { equalDownDivision(menu.view.itemCount, ITEM_GRID_WIDTH) } viewScrollBar.setupRowMultiplier { equalDownDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH) }
viewScrollBar.dock = Dock.RIGHT viewScrollBar.dock = Dock.RIGHT
viewScrollBar.setDockMargin(left = 2f) viewScrollBar.setDockMargin(left = 2f)
@ -50,10 +49,10 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) { for (i in 0 until ITEM_GRID_WIDTH * ITEM_GRID_HEIGHT) {
object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) { object : AbstractSlotPanel(this@ItemMonitorScreen, gridPanel) {
private val index get() = i + viewScrollBar.getScroll(equalDownDivision(menu.view.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH private val index get() = i + viewScrollBar.getScroll(equalDownDivision(menu.networkedItemView.itemCount, ITEM_GRID_WIDTH)) * ITEM_GRID_WIDTH
override fun getItemStack(): ItemStack { override fun getItemStack(): ItemStack {
return menu.view.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY return menu.networkedItemView.sortedView.getOrNull(index)?.stack?.item ?: ItemStack.EMPTY
} }
override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean { override fun mouseScrolledInner(mouse_x: Double, mouse_y: Double, scroll: Double): Boolean {
@ -61,14 +60,14 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
} }
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean { override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
menu.view.mouseClick(index, mouse_click_type) menu.networkedItemView.mouseClick(index, mouse_click_type)
return true return true
} }
override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) { override fun innerRender(stack: PoseStack, mouse_x: Float, mouse_y: Float, flag: Float) {
renderSlotBackground(stack, mouse_x, mouse_y, flag) renderSlotBackground(stack, mouse_x, mouse_y, flag)
val itemstack = menu.view.sortedView.getOrNull(index)?.stack ?: ITEM_STORAGE.empty val itemstack = menu.networkedItemView.sortedView.getOrNull(index)?.stack ?: ITEM_STORAGE.empty
renderRegular(stack, itemstack.stack, "") renderRegular(stack, itemstack.stack, "")
@ -94,7 +93,7 @@ class ItemMonitorScreen(menu: ItemMonitorMenu, inventory: Inventory, title: Comp
override fun getItemStackTooltip(stack: ItemStack): List<Component> { override fun getItemStackTooltip(stack: ItemStack): List<Component> {
return super.getItemStackTooltip(stack).also { return super.getItemStackTooltip(stack).also {
it as MutableList<Component> it as MutableList<Component>
val realStack = menu.view.sortedView.getOrNull(index)!!.stack val realStack = menu.networkedItemView.sortedView.getOrNull(index)!!.stack
it.add(TranslatableComponent("otm.gui.stored_amount", realStack.count.formatReadableNumber()).withStyle(ChatFormatting.DARK_GRAY)) it.add(TranslatableComponent("otm.gui.stored_amount", realStack.count.formatReadableNumber()).withStyle(ChatFormatting.DARK_GRAY))
} }
} }

View File

@ -4,7 +4,7 @@ import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
import ru.dbotthepony.mc.otm.container.ItemFilterSlotPacket import ru.dbotthepony.mc.otm.container.ItemFilterSlotPacket
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
open class FilterSlotPanel( open class FilterSlotPanel(
screen: MatteryScreen<*>, screen: MatteryScreen<*>,
@ -21,9 +21,9 @@ open class FilterSlotPanel(
override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean { override fun mouseClickedInner(mouse_x: Double, mouse_y: Double, mouse_click_type: Int): Boolean {
if (screen.menu.carried.isEmpty) { if (screen.menu.carried.isEmpty) {
MatteryNetworking.CHANNEL.sendToServer(ItemFilterSlotPacket(slot.networkID, ItemStack.EMPTY)) MenuNetworkChannel.sendToServer(ItemFilterSlotPacket(slot.networkID, ItemStack.EMPTY))
} else { } else {
MatteryNetworking.CHANNEL.sendToServer(ItemFilterSlotPacket(slot.networkID, screen.menu.carried)) MenuNetworkChannel.sendToServer(ItemFilterSlotPacket(slot.networkID, screen.menu.carried))
} }
return true return true

View File

@ -13,18 +13,19 @@ import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.ifHas import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.set
import java.util.Arrays import java.util.Arrays
import java.util.LinkedList import java.util.LinkedList
import java.util.function.Supplier import java.util.function.Supplier
data class ItemFilterSlotPacket(val slotID: Int, val newValue: ItemStack) { data class ItemFilterSlotPacket(val slotID: Int, val newValue: ItemStack) : MatteryPacket {
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeInt(slotID) buff.writeInt(slotID)
buff.writeItemStack(newValue, true) buff.writeItemStack(newValue, true)
} }
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
if (context.get().sender != null) { if (context.get().sender != null) {

View File

@ -1,12 +1,9 @@
package ru.dbotthepony.mc.otm.item.weapon package ru.dbotthepony.mc.otm.item.weapon
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.*
import com.mojang.math.Vector3f import com.mojang.math.Vector3f
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.client.model.HumanoidModel import net.minecraft.client.model.HumanoidModel
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.block.model.ItemTransforms
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
@ -31,7 +28,8 @@ import ru.dbotthepony.mc.otm.client.render.drawRect
import ru.dbotthepony.mc.otm.client.render.setDrawColor import ru.dbotthepony.mc.otm.client.render.setDrawColor
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.Vector import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.WeaponNetworkChannel
import java.util.* import java.util.*
import java.util.function.Supplier import java.util.function.Supplier
import kotlin.math.PI import kotlin.math.PI
@ -42,19 +40,19 @@ import kotlin.reflect.full.primaryConstructor
private val ItemStack.weaponDataTable get() = tag?.let(::WeaponDataTable) private val ItemStack.weaponDataTable get() = tag?.let(::WeaponDataTable)
enum class WeaponScopePacket(val scope: Boolean) { enum class WeaponScopePacket(val scope: Boolean) : MatteryPacket {
SCOPE_IN(true), SCOPE_OUT(false); SCOPE_IN(true), SCOPE_OUT(false);
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeBoolean(scope) buff.writeBoolean(scope)
} }
fun play(supplier: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
supplier.get().packetHandled = true context.get().packetHandled = true
// TODO: Manual synchronization // TODO: Manual synchronization
supplier.get().enqueueWork { context.get().enqueueWork {
val stack = supplier.get().sender!!.mainHandItem val stack = context.get().sender!!.mainHandItem
val item = stack.item as? AbstractWeaponItem<*> ?: return@enqueueWork val item = stack.item as? AbstractWeaponItem<*> ?: return@enqueueWork
item.dataTable(stack).wantsToScope = scope item.dataTable(stack).wantsToScope = scope
@ -66,19 +64,19 @@ enum class WeaponScopePacket(val scope: Boolean) {
} }
} }
enum class WeaponFireInputPacket(val primary: Boolean) { enum class WeaponFireInputPacket(val primary: Boolean) : MatteryPacket {
PRIMARY(true), SECONDARY(false); PRIMARY(true), SECONDARY(false);
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeBoolean(primary) buff.writeBoolean(primary)
} }
fun play(supplier: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
supplier.get().packetHandled = true context.get().packetHandled = true
// TODO: Manual synchronization // TODO: Manual synchronization
supplier.get().enqueueWork { context.get().enqueueWork {
val stack = supplier.get().sender!!.mainHandItem val stack = context.get().sender!!.mainHandItem
val item = stack.item as? AbstractWeaponItem<*> ?: return@enqueueWork val item = stack.item as? AbstractWeaponItem<*> ?: return@enqueueWork
// Listen server: client and server thread compete for lock // Listen server: client and server thread compete for lock
@ -87,9 +85,9 @@ enum class WeaponFireInputPacket(val primary: Boolean) {
item.dataTable = null item.dataTable = null
if (primary) if (primary)
item.tryPrimaryFire(stack, supplier.get().sender!!) item.tryPrimaryFire(stack, context.get().sender!!)
else else
item.trySecondaryFire(stack, supplier.get().sender!!) item.trySecondaryFire(stack, context.get().sender!!)
(item as AbstractWeaponItem<WeaponDataTable>).dataTable = predictedData (item as AbstractWeaponItem<WeaponDataTable>).dataTable = predictedData
} }
@ -498,17 +496,17 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
if (!dt.wantsToScope && minecraft.options.keyUse.isDown) { if (!dt.wantsToScope && minecraft.options.keyUse.isDown) {
dt.wantsToScope = true dt.wantsToScope = true
MatteryNetworking.CHANNEL.sendToServer(WeaponScopePacket.SCOPE_IN) WeaponNetworkChannel.sendToServer(WeaponScopePacket.SCOPE_IN)
} else if (dt.wantsToScope && !minecraft.options.keyUse.isDown) { } else if (dt.wantsToScope && !minecraft.options.keyUse.isDown) {
dt.wantsToScope = false dt.wantsToScope = false
MatteryNetworking.CHANNEL.sendToServer(WeaponScopePacket.SCOPE_OUT) WeaponNetworkChannel.sendToServer(WeaponScopePacket.SCOPE_OUT)
} }
if (minecraft.options.keyAttack.isDown && (item.primaryAutomatic || !firedPrimary)) { if (minecraft.options.keyAttack.isDown && (item.primaryAutomatic || !firedPrimary)) {
firedPrimary = true firedPrimary = true
if (item.tryPrimaryFire(itemStack, player)) { if (item.tryPrimaryFire(itemStack, player)) {
MatteryNetworking.CHANNEL.sendToServer(WeaponFireInputPacket.PRIMARY) WeaponNetworkChannel.sendToServer(WeaponFireInputPacket.PRIMARY)
} }
} else if (!minecraft.options.keyAttack.isDown) { } else if (!minecraft.options.keyAttack.isDown) {
firedPrimary = false firedPrimary = false
@ -518,7 +516,7 @@ abstract class AbstractWeaponItem<D : WeaponDataTable>(val tables: KClass<D>, ra
firedSecondary = true firedSecondary = true
if (item.trySecondaryFire(itemStack, player)) { if (item.trySecondaryFire(itemStack, player)) {
MatteryNetworking.CHANNEL.sendToServer(WeaponFireInputPacket.SECONDARY) WeaponNetworkChannel.sendToServer(WeaponFireInputPacket.SECONDARY)
} }
} else if (!minecraft.options.keyAttack.isDown) { } else if (!minecraft.options.keyAttack.isDown) {
firedSecondary = false firedSecondary = false

View File

@ -5,6 +5,7 @@ import net.minecraft.ChatFormatting
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.server.dedicated.DedicatedServer import net.minecraft.server.dedicated.DedicatedServer
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.event.entity.player.ItemTooltipEvent import net.minecraftforge.event.entity.player.ItemTooltipEvent
@ -15,24 +16,18 @@ import net.minecraftforge.eventbus.api.SubscribeEvent
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
import org.lwjgl.glfw.GLFW import org.lwjgl.glfw.GLFW
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.orNull import ru.dbotthepony.mc.otm.network.RegistryNetworkChannel
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
import ru.dbotthepony.mc.otm.writeRegistryId
import java.math.BigInteger import java.math.BigInteger
import java.util.function.Supplier import java.util.function.Supplier
internal var building = false internal var building = false
interface MatterTuplePredicate {
fun accept(item: Item): MatterTuple?
}
interface IMatterItem { interface IMatterItem {
fun getMatterValue(stack: ItemStack): MatterTuple? fun getMatterValue(stack: ItemStack): MatterTuple?
fun hasMatterValue(stack: ItemStack) = getMatterValue(stack) != null fun hasMatterValue(stack: ItemStack) = getMatterValue(stack) != null
@ -51,7 +46,7 @@ private val derivedEntries = HashMap<Item, MatterTuple>()
@JvmField @JvmField
val rootEntriesAccess = object : MutableMap<Item, MatterTuple> by rootEntries { val rootEntriesAccess = object : MutableMap<Item, MatterTuple> by rootEntries {
override fun put(key: Item, value: MatterTuple): MatterTuple? { override fun put(key: Item, value: MatterTuple): MatterTuple? {
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketUpdate(MatterRegistryType.ROOT, key, value)) RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), RegistryPacketUpdate(MatterRegistryType.ROOT, key, value))
return rootEntries.put(key, value) return rootEntries.put(key, value)
} }
@ -62,7 +57,7 @@ val rootEntriesAccess = object : MutableMap<Item, MatterTuple> by rootEntries {
val distr = PacketDistributor.ALL.noArg() val distr = PacketDistributor.ALL.noArg()
for ((key, value) in from) { for ((key, value) in from) {
MatteryNetworking.CHANNEL.send(distr, RegistryPacketUpdate(MatterRegistryType.ROOT, key, value)) RegistryNetworkChannel.send(distr, RegistryPacketUpdate(MatterRegistryType.ROOT, key, value))
} }
} }
} }
@ -71,7 +66,7 @@ val rootEntriesAccess = object : MutableMap<Item, MatterTuple> by rootEntries {
val value = rootEntries.remove(key) val value = rootEntries.remove(key)
if (!building && value != null) if (!building && value != null)
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketRemove(MatterRegistryType.ROOT, key)) RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), RegistryPacketRemove(MatterRegistryType.ROOT, key))
return value return value
} }
@ -79,8 +74,8 @@ val rootEntriesAccess = object : MutableMap<Item, MatterTuple> by rootEntries {
override fun clear() { override fun clear() {
rootEntries.clear() rootEntries.clear()
if (!building && server != null) { if (!building && NULLABLE_MINECRAFT_SERVER != null) {
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketClear.ROOT) RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), RegistryPacketClear.ROOT)
} }
} }
} }
@ -94,7 +89,7 @@ val rootEntriesAccess = object : MutableMap<Item, MatterTuple> by rootEntries {
@JvmField @JvmField
val derivedEntriesAccess = object : MutableMap<Item, MatterTuple> by derivedEntries { val derivedEntriesAccess = object : MutableMap<Item, MatterTuple> by derivedEntries {
override fun put(key: Item, value: MatterTuple): MatterTuple? { override fun put(key: Item, value: MatterTuple): MatterTuple? {
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketUpdate(MatterRegistryType.DERIVED, key, value)) RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), RegistryPacketUpdate(MatterRegistryType.DERIVED, key, value))
return derivedEntries.put(key, value) return derivedEntries.put(key, value)
} }
@ -105,7 +100,7 @@ val derivedEntriesAccess = object : MutableMap<Item, MatterTuple> by derivedEntr
val distr = PacketDistributor.ALL.noArg() val distr = PacketDistributor.ALL.noArg()
for ((key, value) in from) { for ((key, value) in from) {
MatteryNetworking.CHANNEL.send(distr, RegistryPacketUpdate(MatterRegistryType.DERIVED, key, value)) RegistryNetworkChannel.send(distr, RegistryPacketUpdate(MatterRegistryType.DERIVED, key, value))
} }
} }
} }
@ -114,7 +109,7 @@ val derivedEntriesAccess = object : MutableMap<Item, MatterTuple> by derivedEntr
val value = derivedEntries.remove(key) val value = derivedEntries.remove(key)
if (!building && value != null) if (!building && value != null)
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketRemove(MatterRegistryType.DERIVED, key)) RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), RegistryPacketRemove(MatterRegistryType.DERIVED, key))
return value return value
} }
@ -122,8 +117,8 @@ val derivedEntriesAccess = object : MutableMap<Item, MatterTuple> by derivedEntr
override fun clear() { override fun clear() {
derivedEntries.clear() derivedEntries.clear()
if (!building && server != null) { if (!building && NULLABLE_MINECRAFT_SERVER != null) {
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketClear.DERIVED) RegistryNetworkChannel.send(PacketDistributor.ALL.noArg(), RegistryPacketClear.DERIVED)
} }
} }
} }
@ -221,29 +216,15 @@ fun getMatterValue(stack: ItemStack): MatterTuple {
return getMatterValue(stack, 0) return getMatterValue(stack, 0)
} }
private var server: DedicatedServer? = null
@SubscribeEvent @SubscribeEvent
@Suppress("unused") @Suppress("unused")
fun onPlayerJoin(event: PlayerEvent.PlayerLoggedInEvent) { fun onPlayerJoin(event: PlayerEvent.PlayerLoggedInEvent) {
if (server != null) { if (NULLABLE_MINECRAFT_SERVER != null) {
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketFullUpdate(MatterRegistryType.ROOT, rootEntries)) RegistryNetworkChannel.send(PacketDistributor.PLAYER.with { event.entity as ServerPlayer }, RegistryPacketFullUpdate(MatterRegistryType.ROOT, rootEntries))
MatteryNetworking.CHANNEL.send(PacketDistributor.ALL.noArg(), RegistryPacketFullUpdate(MatterRegistryType.DERIVED, derivedEntries)) RegistryNetworkChannel.send(PacketDistributor.PLAYER.with { event.entity as ServerPlayer }, RegistryPacketFullUpdate(MatterRegistryType.DERIVED, derivedEntries))
} }
} }
@SubscribeEvent
@Suppress("unused")
fun serverStartRegistry(event: ServerStartedEvent) {
server = event.server as? DedicatedServer
}
@SubscribeEvent
@Suppress("unused")
fun serverStopRegistry(event: ServerStoppingEvent) {
server = null
}
@SubscribeEvent @SubscribeEvent
@Suppress("unused") @Suppress("unused")
fun tooltipEvent(event: ItemTooltipEvent) { fun tooltipEvent(event: ItemTooltipEvent) {
@ -305,8 +286,8 @@ data class MatterTuple(val value: ImpreciseFraction, val complexity: Double): Co
internal enum class MatterRegistryType {ROOT, DERIVED} internal enum class MatterRegistryType {ROOT, DERIVED}
internal class RegistryPacketUpdate(val type: MatterRegistryType, val item: Item, val tuple: MatterTuple) { internal class RegistryPacketUpdate(val type: MatterRegistryType, val item: Item, val tuple: MatterTuple) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
when (type) { when (type) {
@ -324,7 +305,7 @@ internal class RegistryPacketUpdate(val type: MatterRegistryType, val item: Item
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeEnum(type) buff.writeEnum(type)
buff.writeRegistryId(item) buff.writeRegistryId(item)
tuple.write(buff) tuple.write(buff)
@ -337,8 +318,8 @@ internal class RegistryPacketUpdate(val type: MatterRegistryType, val item: Item
} }
} }
internal class RegistryPacketRemove(val type: MatterRegistryType, val item: Item) { internal class RegistryPacketRemove(val type: MatterRegistryType, val item: Item) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
when (type) { when (type) {
@ -356,7 +337,7 @@ internal class RegistryPacketRemove(val type: MatterRegistryType, val item: Item
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeEnum(type) buff.writeEnum(type)
buff.writeRegistryId(item) buff.writeRegistryId(item)
} }
@ -368,8 +349,8 @@ internal class RegistryPacketRemove(val type: MatterRegistryType, val item: Item
} }
} }
internal class RegistryPacketFullUpdate(val type: MatterRegistryType, val map: Map<Item, MatterTuple>) { internal class RegistryPacketFullUpdate(val type: MatterRegistryType, val map: Map<Item, MatterTuple>) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
when (type) { when (type) {
@ -389,7 +370,7 @@ internal class RegistryPacketFullUpdate(val type: MatterRegistryType, val map: M
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeEnum(type) buff.writeEnum(type)
buff.writeInt(map.size) buff.writeInt(map.size)
@ -415,11 +396,11 @@ internal class RegistryPacketFullUpdate(val type: MatterRegistryType, val map: M
} }
} }
internal enum class RegistryPacketClear(val type: MatterRegistryType) { internal enum class RegistryPacketClear(val type: MatterRegistryType) : MatteryPacket {
ROOT(MatterRegistryType.ROOT), ROOT(MatterRegistryType.ROOT),
DERIVED(MatterRegistryType.DERIVED); DERIVED(MatterRegistryType.DERIVED);
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
when (type) { when (type) {
@ -437,7 +418,7 @@ internal enum class RegistryPacketClear(val type: MatterRegistryType) {
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeEnum(type) buff.writeEnum(type)
} }

View File

@ -7,14 +7,13 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.energy.CapabilityEnergy
import ru.dbotthepony.mc.otm.block.entity.storage.DriveViewerBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.DriveViewerBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive
import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.container.ItemFilter
import ru.dbotthepony.mc.otm.ifPresentK import ru.dbotthepony.mc.otm.ifPresentK
import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem import ru.dbotthepony.mc.otm.item.PortableCondensationDriveItem
import ru.dbotthepony.mc.otm.menu.data.INetworkedItemViewSupplier import ru.dbotthepony.mc.otm.menu.data.INetworkedItemViewProvider
import ru.dbotthepony.mc.otm.menu.data.NetworkedItemView import ru.dbotthepony.mc.otm.menu.data.NetworkedItemView
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputWidget import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputWidget
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
@ -28,15 +27,13 @@ class DriveViewerMenu @JvmOverloads constructor(
tile: DriveViewerBlockEntity? = null tile: DriveViewerBlockEntity? = null
) : MatteryPoweredMenu( ) : MatteryPoweredMenu(
MMenus.DRIVE_VIEWER, containerID, inventory, tile MMenus.DRIVE_VIEWER, containerID, inventory, tile
), INetworkedItemViewSupplier { ), INetworkedItemViewProvider {
val view = NetworkedItemView(inventory.player, this, tile == null) override val networkedItemView = NetworkedItemView(inventory.player, this, tile == null)
val driveSlot: MatterySlot val driveSlot: MatterySlot
private val powered: PoweredVirtualComponent<ItemStackWrapper>? private val powered: PoweredVirtualComponent<ItemStackWrapper>?
private var lastDrive: IMatteryDrive<ItemStackWrapper>? = null private var lastDrive: IMatteryDrive<ItemStackWrapper>? = null
override fun getNetworkedItemView() = view
init { init {
val container = tile?.container ?: SimpleContainer(1) val container = tile?.container ?: SimpleContainer(1)
@ -52,7 +49,7 @@ class DriveViewerMenu @JvmOverloads constructor(
tile.getCapability(MatteryCapability.ENERGY).resolve().get() tile.getCapability(MatteryCapability.ENERGY).resolve().get()
) )
view.setComponent(powered) this.networkedItemView.setComponent(powered)
} else { } else {
powered = null powered = null
} }
@ -102,7 +99,7 @@ class DriveViewerMenu @JvmOverloads constructor(
if (prev != lastDrive) { if (prev != lastDrive) {
prev?.let(powered!!::remove) prev?.let(powered!!::remove)
view.clear() this.networkedItemView.clear()
lastDrive?.let(powered!!::add) lastDrive?.let(powered!!::add)
if (lastDrive != null) { if (lastDrive != null) {
@ -133,7 +130,7 @@ class DriveViewerMenu @JvmOverloads constructor(
} }
} }
view.network() this.networkedItemView.network()
} }
} }
@ -143,7 +140,7 @@ class DriveViewerMenu @JvmOverloads constructor(
if (lastDrive != null) if (lastDrive != null)
powered?.remove(lastDrive!!) powered?.remove(lastDrive!!)
view.removed() this.networkedItemView.removed()
} }
override fun quickMoveStack(ply: Player, slotIndex: Int): ItemStack { override fun quickMoveStack(ply: Player, slotIndex: Int): ItemStack {

View File

@ -11,9 +11,9 @@ import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
import ru.dbotthepony.mc.otm.get import ru.dbotthepony.mc.otm.get
import ru.dbotthepony.mc.otm.menu.data.INetworkedItemViewSupplier import ru.dbotthepony.mc.otm.menu.data.INetworkedItemViewProvider
import ru.dbotthepony.mc.otm.menu.data.NetworkedItemView import ru.dbotthepony.mc.otm.menu.data.NetworkedItemView
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
import ru.dbotthepony.mc.otm.storage.* import ru.dbotthepony.mc.otm.storage.*
import java.util.* import java.util.*
@ -77,21 +77,17 @@ class ItemMonitorMenu @JvmOverloads constructor(
p_38852_: Int, p_38852_: Int,
inventory: Inventory, inventory: Inventory,
tile: ItemMonitorBlockEntity? = null tile: ItemMonitorBlockEntity? = null
) : MatteryPoweredMenu(MMenus.ITEM_MONITOR, p_38852_, inventory, tile), INetworkedItemViewSupplier { ) : MatteryPoweredMenu(MMenus.ITEM_MONITOR, p_38852_, inventory, tile), INetworkedItemViewProvider {
val view = NetworkedItemView(inventory.player, this, tile == null) override val networkedItemView = NetworkedItemView(inventory.player, this, tile == null)
val settings: ItemMonitorPlayerSettings = tile?.getSettings(inventory.player as ServerPlayer) ?: ItemMonitorPlayerSettings() val settings: ItemMonitorPlayerSettings = tile?.getSettings(inventory.player as ServerPlayer) ?: ItemMonitorPlayerSettings()
private var settingsNetworked = false private var settingsNetworked = false
override fun getNetworkedItemView(): NetworkedItemView {
return view
}
val craftingResult: MatterySlot val craftingResult: MatterySlot
val craftingSlots: List<MatterySlot> val craftingSlots: List<MatterySlot>
init { init {
if (tile != null) { if (tile != null) {
view.setComponent(tile.poweredView) networkedItemView.setComponent(tile.poweredView)
craftingResult = ResultSlot(tile.craftingResultContainer) craftingResult = ResultSlot(tile.craftingResultContainer)
craftingSlots = Collections.unmodifiableList(Array(9) { MatterySlot(tile.craftingGrid, it) }.asList()) craftingSlots = Collections.unmodifiableList(Array(9) { MatterySlot(tile.craftingGrid, it) }.asList())
} else { } else {
@ -108,25 +104,25 @@ class ItemMonitorMenu @JvmOverloads constructor(
override fun broadcastFullState() { override fun broadcastFullState() {
super.broadcastFullState() super.broadcastFullState()
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { ply as ServerPlayer }, settings) MenuNetworkChannel.send(PacketDistributor.PLAYER.with { ply as ServerPlayer }, settings)
settingsNetworked = true settingsNetworked = true
} }
fun sendSettingsToServer() { fun sendSettingsToServer() {
MatteryNetworking.CHANNEL.sendToServer(settings) MenuNetworkChannel.sendToServer(settings)
} }
override fun removed(p_38940_: Player) { override fun removed(p_38940_: Player) {
super.removed(p_38940_) super.removed(p_38940_)
view.removed() networkedItemView.removed()
} }
override fun broadcastChanges() { override fun broadcastChanges() {
super.broadcastChanges() super.broadcastChanges()
view.network() networkedItemView.network()
if (!settingsNetworked) { if (!settingsNetworked) {
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { ply as ServerPlayer }, settings) MenuNetworkChannel.send(PacketDistributor.PLAYER.with { ply as ServerPlayer }, settings)
settingsNetworked = true settingsNetworked = true
} }
} }
@ -145,7 +141,7 @@ class ItemMonitorMenu @JvmOverloads constructor(
return ItemStack.EMPTY return ItemStack.EMPTY
} }
val leftover = view.provider?.insertStack(ItemStackWrapper(slot.item), false)?.stack ?: slot.item val leftover = networkedItemView.provider?.insertStack(ItemStackWrapper(slot.item), false)?.stack ?: slot.item
if (leftover.count == slot.item.count) { if (leftover.count == slot.item.count) {
return ItemStack.EMPTY return ItemStack.EMPTY
@ -169,7 +165,7 @@ class ItemMonitorMenu @JvmOverloads constructor(
return item return item
} }
remainder = view.provider?.insertStack(ItemStackWrapper(remainder), false)?.stack ?: remainder remainder = networkedItemView.provider?.insertStack(ItemStackWrapper(remainder), false)?.stack ?: remainder
slots[slotIndex].set(remainder) slots[slotIndex].set(remainder)
if (remainder.isEmpty) { if (remainder.isEmpty) {

View File

@ -1,23 +1,131 @@
package ru.dbotthepony.mc.otm.menu package ru.dbotthepony.mc.otm.menu
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.entity.matter.MatterPanelBlockEntity import ru.dbotthepony.mc.otm.block.entity.matter.MatterPanelBlockEntity
import ru.dbotthepony.mc.otm.capability.matter.MatterTask import ru.dbotthepony.mc.otm.capability.matter.MatterTask
import ru.dbotthepony.mc.otm.capability.matter.PatternState import ru.dbotthepony.mc.otm.capability.matter.PatternState
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphListener
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.network.CancelMatterTaskPacket import ru.dbotthepony.mc.otm.network.*
import ru.dbotthepony.mc.otm.network.MatterTaskPacket
import ru.dbotthepony.mc.otm.network.MatteryNetworking
import ru.dbotthepony.mc.otm.network.PatternGridPacket
import ru.dbotthepony.mc.otm.registry.MMenus import ru.dbotthepony.mc.otm.registry.MMenus
import java.util.* import java.util.*
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Supplier
class CancelTaskPacket(val id: UUID) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeUUID(id)
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val sender = context.sender!!
(sender.containerMenu as? MatterPanelMenu)?.receiveTaskCancel(sender, id)
}
}
companion object {
fun read(buff: FriendlyByteBuf): CancelTaskPacket {
return CancelTaskPacket(buff.readUUID())
}
}
}
class PatternsChangePacket(val isUpdate: Boolean, val patterns: Collection<PatternState>) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeBoolean(isUpdate)
buff.writeInt(patterns.size)
for (pattern in patterns) {
pattern.write(buff)
}
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return@enqueueWork
if (isUpdate) {
menu.networkPatternsUpdated(patterns)
} else {
menu.networkPatternsRemoved(patterns)
}
}
}
companion object {
fun read(buff: FriendlyByteBuf): PatternsChangePacket {
val isUpdate = buff.readBoolean()
val size = buff.readInt()
return PatternsChangePacket(isUpdate, ArrayList<PatternState>(size).also {
for (i in 0 until size) it.add(PatternState.read(buff) ?: throw NullPointerException("Unable to read PatternState from network at $i")) })
}
}
}
class TasksChangePacket(val isUpdate: Boolean, val tasks: Collection<MatterTask>) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeBoolean(isUpdate)
buff.writeInt(tasks.size)
for (task in tasks) {
task.write(buff)
}
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val menu = minecraft.player?.containerMenu as? MatterPanelMenu ?: return@enqueueWork
if (isUpdate) {
menu.networkTasksUpdated(tasks)
} else {
menu.networkTasksRemoved(tasks)
}
}
}
companion object {
fun read(buff: FriendlyByteBuf): TasksChangePacket {
val isUpdate = buff.readBoolean()
val size = buff.readInt()
return TasksChangePacket(isUpdate, ArrayList<MatterTask>(size).also {
for (i in 0 until size) it.add(MatterTask.read(buff) ?: throw NullPointerException("Unable to read PatternState from network at $i")) })
}
}
}
class ReplicationRequestPacket(val state: PatternState, amount: Int) : MatteryPacket {
val amount = amount.coerceAtLeast(1).coerceAtMost(99999)
override fun write(buff: FriendlyByteBuf) {
state.write(buff)
buff.writeInt(amount)
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val sender = context.sender ?: return@enqueueWork
val menu = sender.containerMenu as? MatterPanelMenu ?: return@enqueueWork
menu.requestReplication(sender, state, amount)
}
}
}
class MatterPanelMenu @JvmOverloads constructor( class MatterPanelMenu @JvmOverloads constructor(
p_38852_: Int, p_38852_: Int,
@ -25,11 +133,11 @@ class MatterPanelMenu @JvmOverloads constructor(
tile: MatterPanelBlockEntity? = null tile: MatterPanelBlockEntity? = null
) : MatteryMenu(MMenus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener { ) : MatteryMenu(MMenus.MATTER_PANEL, p_38852_, inventory, tile), IMatterGraphListener {
fun taskUpdated(task: MatterTask) { fun taskUpdated(task: MatterTask) {
sendNetwork(MatterTaskPacket(true, listOf(task))) sendNetwork(TasksChangePacket(true, listOf(task)))
} }
fun taskRemoved(task: MatterTask) { fun taskRemoved(task: MatterTask) {
sendNetwork(MatterTaskPacket(false, listOf(task))) sendNetwork(TasksChangePacket(false, listOf(task)))
} }
// client code // client code
@ -111,19 +219,19 @@ class MatterPanelMenu @JvmOverloads constructor(
} }
fun requestTaskCancel(id: UUID) { fun requestTaskCancel(id: UUID) {
MatteryNetworking.CHANNEL.sendToServer(CancelMatterTaskPacket(id)) MenuNetworkChannel.sendToServer(CancelTaskPacket(id))
} }
override fun onPatternAdded(state: PatternState) { override fun onPatternAdded(state: PatternState) {
sendNetwork(PatternGridPacket(true, listOf(state))) sendNetwork(PatternsChangePacket(true, listOf(state)))
} }
override fun onPatternRemoved(state: PatternState) { override fun onPatternRemoved(state: PatternState) {
sendNetwork(PatternGridPacket(false, listOf(state))) sendNetwork(PatternsChangePacket(false, listOf(state)))
} }
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) { override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
sendNetwork(PatternGridPacket(true, listOf(new_state))) sendNetwork(PatternsChangePacket(true, listOf(new_state)))
} }
private var initial_send = false private var initial_send = false
@ -150,7 +258,7 @@ class MatterPanelMenu @JvmOverloads constructor(
} }
private fun sendNetwork(packet: Any) { private fun sendNetwork(packet: Any) {
MatteryNetworking.CHANNEL.send(PacketDistributor.PLAYER.with { inventory.player as ServerPlayer }, packet) MenuNetworkChannel.send(PacketDistributor.PLAYER.with { inventory.player as ServerPlayer }, packet)
} }
fun fullPatternBroadcast() { fun fullPatternBroadcast() {
@ -166,10 +274,10 @@ class MatterPanelMenu @JvmOverloads constructor(
if (grid != null) { if (grid != null) {
initial_send = true initial_send = true
sendNetwork(PatternGridPacket(true, grid.getStoredPatterns())) sendNetwork(PatternsChangePacket(true, grid.getStoredPatterns()))
} }
sendNetwork(MatterTaskPacket(true, tile.allTasks)) sendNetwork(TasksChangePacket(true, tile.allTasks))
} }
} }

View File

@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.container.ItemFilter
import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot import ru.dbotthepony.mc.otm.container.ItemFilterNetworkSlot
import ru.dbotthepony.mc.otm.menu.data.MultiByteDataContainer import ru.dbotthepony.mc.otm.menu.data.MultiByteDataContainer
import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget import ru.dbotthepony.mc.otm.menu.widget.AbstractWidget
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
import java.util.Collections import java.util.Collections
abstract class MatteryMenu @JvmOverloads protected constructor( abstract class MatteryMenu @JvmOverloads protected constructor(
@ -148,7 +148,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
for (data in multiByteContainers) { for (data in multiByteContainers) {
if (data.dirty) { if (data.dirty) {
data.dirty = false data.dirty = false
MatteryNetworking.CHANNEL.send(playerPacketDistributor, data.makePacket()) MenuNetworkChannel.send(playerPacketDistributor, data.makePacket())
} }
} }
@ -160,7 +160,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
val packet = slot.sendChanges() val packet = slot.sendChanges()
if (packet != null) { if (packet != null) {
MatteryNetworking.CHANNEL.send(consumer, packet) MenuNetworkChannel.send(consumer, packet)
} }
} }
} }
@ -171,7 +171,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
} }
for (data in multiByteContainers) { for (data in multiByteContainers) {
MatteryNetworking.CHANNEL.send(playerPacketDistributor, data.makePacket()) MenuNetworkChannel.send(playerPacketDistributor, data.makePacket())
} }
super.broadcastFullState() super.broadcastFullState()
@ -182,7 +182,7 @@ abstract class MatteryMenu @JvmOverloads protected constructor(
val packet = slot.sendChanges(true) val packet = slot.sendChanges(true)
if (packet != null) { if (packet != null) {
MatteryNetworking.CHANNEL.send(consumer, packet) MenuNetworkChannel.send(consumer, packet)
} }
} }
} }

View File

@ -1,11 +1,8 @@
package ru.dbotthepony.mc.otm.menu.data package ru.dbotthepony.mc.otm.menu.data
import net.minecraft.world.inventory.ContainerData
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.network.NetworkHelper
import java.util.zip.CRC32
class FractionDataContainer : ComplexDataContainer<Fraction>(128) { class FractionDataContainer : ComplexDataContainer<Fraction>(128) {
companion object { companion object {

View File

@ -4,18 +4,19 @@ import net.minecraft.client.Minecraft
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MatteryPacket
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.function.Supplier import java.util.function.Supplier
class MultiByteDataContainerPacket(val slotID: Int, val offset: Int, val payload: ByteArray) { class MultiByteDataContainerPacket(val slotID: Int, val offset: Int, val payload: ByteArray) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
(Minecraft.getInstance().player?.containerMenu as? MatteryMenu)?.getDataContainer(slotID)?.handle(this) (Minecraft.getInstance().player?.containerMenu as? MatteryMenu)?.getDataContainer(slotID)?.handle(this)
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeInt(slotID) buff.writeInt(slotID)
buff.writeInt(offset) buff.writeInt(offset)
buff.writeByteArray(payload) buff.writeByteArray(payload)

View File

@ -12,25 +12,73 @@ import net.minecraft.world.inventory.ClickType
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.readBigInteger import ru.dbotthepony.mc.otm.core.readBigInteger
import ru.dbotthepony.mc.otm.core.writeBigInteger import ru.dbotthepony.mc.otm.core.writeBigInteger
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.*
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
import ru.dbotthepony.mc.otm.registryName import ru.dbotthepony.mc.otm.registryName
import ru.dbotthepony.mc.otm.storage.* import ru.dbotthepony.mc.otm.storage.*
import java.math.BigInteger import java.math.BigInteger
import java.util.* import java.util.*
import java.util.function.Supplier import java.util.function.Supplier
class StackAddPacket(val containerId: Int, val id: Int, val stack: ItemStackWrapper) { interface INetworkedItemViewProvider {
fun write(buffer: FriendlyByteBuf) { val networkedItemView: NetworkedItemView
buffer.writeInt(containerId)
buffer.writeInt(id)
buffer.writeBigItem(stack)
} }
fun play(context: Supplier<NetworkEvent.Context>) { class ItemViewInteractPacket(val stackID: Int, val type: ClickType, val action: ClickAction) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeInt(stackID)
buff.writeEnum(type)
buff.writeEnum(action)
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
val sender = context.sender ?: return@enqueueWork
sender.resetLastActionTime()
(sender.containerMenu as? INetworkedItemViewProvider)?.networkedItemView?.playerInteract(this)
}
}
companion object {
fun read(buff: FriendlyByteBuf): ItemViewInteractPacket {
return ItemViewInteractPacket(buff.readInt(), buff.readEnum(ClickType::class.java), buff.readEnum(ClickAction::class.java))
}
}
}
object ClearItemViewPacket : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
// NO-OP
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.packetHandled = true
context.enqueueWork {
(minecraft.player?.containerMenu as? INetworkedItemViewProvider)?.networkedItemView?.clear()
}
}
fun read(buff: FriendlyByteBuf): ClearItemViewPacket {
return ClearItemViewPacket
}
fun send(ply: ServerPlayer) {
MenuNetworkChannel.send(ply, this)
}
}
class StackAddPacket(val containerId: Int, val id: Int, val stack: ItemStackWrapper) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeInt(containerId)
buff.writeInt(id)
buff.writeBigItem(stack)
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
@ -38,7 +86,7 @@ class StackAddPacket(val containerId: Int, val id: Int, val stack: ItemStackWrap
if (get.containerId != containerId) if (get.containerId != containerId)
return@enqueueWork return@enqueueWork
val view = (get as? INetworkedItemViewSupplier)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $containerId") val view = (get as? INetworkedItemViewProvider)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $containerId")
if (view.localState.containsKey(id)) { if (view.localState.containsKey(id)) {
throw IllegalStateException("Item tracker $containerId already has stack with id of $id") throw IllegalStateException("Item tracker $containerId already has stack with id of $id")
@ -81,14 +129,14 @@ class StackAddPacket(val containerId: Int, val id: Int, val stack: ItemStackWrap
} }
} }
class StackChangePacket(val id: Int, val stackID: Int, val newCount: BigInteger) { class StackChangePacket(val id: Int, val stackID: Int, val newCount: BigInteger) : MatteryPacket {
fun write(buffer: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buffer.writeInt(id) buff.writeInt(id)
buffer.writeInt(stackID) buff.writeInt(stackID)
buffer.writeBigInteger(newCount) buff.writeBigInteger(newCount)
} }
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
@ -96,7 +144,7 @@ class StackChangePacket(val id: Int, val stackID: Int, val newCount: BigInteger)
if (get.containerId != id) if (get.containerId != id)
return@enqueueWork return@enqueueWork
val view = (get as? INetworkedItemViewSupplier)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $id") val view = (get as? INetworkedItemViewProvider)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $id")
val state = view.localState[stackID] ?: throw IllegalStateException("No such stack with id $stackID in $view") val state = view.localState[stackID] ?: throw IllegalStateException("No such stack with id $stackID in $view")
state.stack.count = newCount state.stack.count = newCount
@ -114,13 +162,13 @@ class StackChangePacket(val id: Int, val stackID: Int, val newCount: BigInteger)
} }
} }
class StackRemovePacket(val id: Int, val stackID: Int) { class StackRemovePacket(val id: Int, val stackID: Int) : MatteryPacket {
fun write(buffer: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buffer.writeInt(id) buff.writeInt(id)
buffer.writeInt(stackID) buff.writeInt(stackID)
} }
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork val get = Minecraft.getInstance().player?.containerMenu ?: return@enqueueWork
@ -128,7 +176,7 @@ class StackRemovePacket(val id: Int, val stackID: Int) {
if (get.containerId != id) if (get.containerId != id)
return@enqueueWork return@enqueueWork
val view = (get as? INetworkedItemViewSupplier)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $id") val view = (get as? INetworkedItemViewProvider)?.networkedItemView ?: throw IllegalStateException("No such item tracker with id $id")
val obj = view.localState.remove(stackID) ?: throw IllegalStateException("No such stack with id $stackID in $view") val obj = view.localState.remove(stackID) ?: throw IllegalStateException("No such stack with id $stackID in $view")
view.sortedView.remove(obj) view.sortedView.remove(obj)
view.resort() view.resort()
@ -203,9 +251,8 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
val type = val type =
if (mouse_click_type == InputConstants.MOUSE_BUTTON_MIDDLE) ClickType.CLONE else if (Screen.hasShiftDown()) ClickType.QUICK_MOVE else ClickType.PICKUP if (mouse_click_type == InputConstants.MOUSE_BUTTON_MIDDLE) ClickType.CLONE else if (Screen.hasShiftDown()) ClickType.QUICK_MOVE else ClickType.PICKUP
MatteryNetworking.send( MenuNetworkChannel.sendToServer(
null, ItemViewInteractPacket(if (index >= list.size) -1 else list[index].id, type, action)
InteractPacket(menu.containerId, if (index >= list.size) -1 else list[index].id, type, action)
) )
} }
@ -261,39 +308,43 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
if (!remote) { if (!remote) {
networkBacklog.clear() networkBacklog.clear()
networkBacklog.add(ClearPacket(menu.containerId)) networkBacklog.add(ClearItemViewPacket)
} }
} }
fun network() { fun network() {
check(!remote) { "Not a server" } check(!remote) { "Not a server" }
val consumer = PacketDistributor.PLAYER.with { ply as ServerPlayer } val consumer = PacketDistributor.PLAYER.with { ply as ServerPlayer }
for (packet in networkBacklog) MatteryNetworking.CHANNEL.send(consumer, packet)
for (packet in networkBacklog) {
MenuNetworkChannel.send(consumer, packet)
}
networkBacklog.clear() networkBacklog.clear()
} }
fun playerInteract(packet: InteractPacket) { fun playerInteract(packet: ItemViewInteractPacket) {
val provider = provider ?: return val provider = provider ?: return
val click = packet.click val click = packet.type
val action = packet.action val action = packet.action
val stack_id = packet.stack_id val stackId = packet.stackID
if (click == ClickType.CLONE) { if (click == ClickType.CLONE) {
if (stack_id < 0 || !ply.abilities.instabuild) return if (stackId < 0 || !ply.abilities.instabuild) return
val state = get(stack_id) ?: return val state = get(stackId) ?: return
val copy = state.stack.stack.also { it.count = it.maxStackSize } val copy = state.stack.stack.also { it.count = it.maxStackSize }
ply.containerMenu.carried = copy ply.containerMenu.carried = copy
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(ply.containerMenu.carried)) MenuNetworkChannel.send(ply as ServerPlayer, SetCarriedPacket(ply.containerMenu.carried))
ply.containerMenu.setRemoteCarried(ply.containerMenu.carried.copy()) ply.containerMenu.setRemoteCarried(ply.containerMenu.carried.copy())
return return
} }
if (click == ClickType.QUICK_MOVE && stack_id > -1) { if (click == ClickType.QUICK_MOVE && stackId > -1) {
val state = get(stack_id) ?: return val state = get(stackId) ?: return
val amount = val amount =
if (action == ClickAction.PRIMARY) if (action == ClickAction.PRIMARY)
@ -323,7 +374,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
if (amount == carried.count) { if (amount == carried.count) {
val stack = provider.insertStack(ItemStackWrapper(menu.carried), false).stack val stack = provider.insertStack(ItemStackWrapper(menu.carried), false).stack
menu.carried = stack menu.carried = stack
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(menu.carried)) MenuNetworkChannel.send(ply as ServerPlayer, SetCarriedPacket(menu.carried))
menu.setRemoteCarried(menu.carried.copy()) menu.setRemoteCarried(menu.carried.copy())
} }
} else { } else {
@ -332,12 +383,12 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
if (provider.insertStack(ItemStackWrapper(copy), false).isEmpty) { if (provider.insertStack(ItemStackWrapper(copy), false).isEmpty) {
menu.carried.shrink(1) menu.carried.shrink(1)
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(menu.carried)) MenuNetworkChannel.send(ply as ServerPlayer, SetCarriedPacket(menu.carried))
menu.setRemoteCarried(menu.carried.copy()) menu.setRemoteCarried(menu.carried.copy())
} }
} }
} else if (stack_id > -1) { } else if (stackId > -1) {
val state = get(stack_id) ?: return val state = get(stackId) ?: return
val amount = val amount =
if (action == ClickAction.PRIMARY) if (action == ClickAction.PRIMARY)
@ -347,7 +398,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote:
val extracted = provider.extractStack(state.upstreamId!!, amount.toBigInteger(), false) val extracted = provider.extractStack(state.upstreamId!!, amount.toBigInteger(), false)
menu.carried = extracted.stack menu.carried = extracted.stack
MatteryNetworking.send(ply as ServerPlayer, SetCarriedPacket(menu.carried)) MenuNetworkChannel.send(ply as ServerPlayer, SetCarriedPacket(menu.carried))
menu.setRemoteCarried(menu.carried.copy()) menu.setRemoteCarried(menu.carried.copy())
} }
} }

View File

@ -4,12 +4,13 @@ import net.minecraft.network.FriendlyByteBuf
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.data.BooleanDataContainer import ru.dbotthepony.mc.otm.menu.data.BooleanDataContainer
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
import java.util.function.Supplier import java.util.function.Supplier
import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KMutableProperty0
class BooleanPlayerInputPacket(val id: Int, val value: Boolean) { class BooleanPlayerInputPacket(val id: Int, val value: Boolean) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
@ -17,7 +18,7 @@ class BooleanPlayerInputPacket(val id: Int, val value: Boolean) {
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeInt(id) buff.writeInt(id)
buff.writeBoolean(value) buff.writeBoolean(value)
} }
@ -70,7 +71,7 @@ class BooleanPlayerInputWidget(menu: MatteryMenu) : AbstractWidget(menu) {
fun asClient(): BooleanPlayerInputWidget { fun asClient(): BooleanPlayerInputWidget {
supplier = null supplier = null
clicker = { clicker = {
MatteryNetworking.CHANNEL.sendToServer(BooleanPlayerInputPacket(slotID, it)) MenuNetworkChannel.sendToServer(BooleanPlayerInputPacket(slotID, it))
} }
return this return this

View File

@ -4,13 +4,12 @@ import net.minecraft.network.FriendlyByteBuf
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer import ru.dbotthepony.mc.otm.menu.data.BigDecimalDataContainer
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.*
import ru.dbotthepony.mc.otm.network.NetworkHelper
import java.math.BigDecimal import java.math.BigDecimal
import java.util.function.Supplier import java.util.function.Supplier
class NumberPlayerInputPacket(val id: Int, val value: BigDecimal) { class NumberPlayerInputPacket(val id: Int, val value: BigDecimal) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
@ -18,14 +17,14 @@ class NumberPlayerInputPacket(val id: Int, val value: BigDecimal) {
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeInt(id) buff.writeInt(id)
NetworkHelper.writeDecimal(buff, value) buff.writeDecimal(value)
} }
companion object { companion object {
fun read(buff: FriendlyByteBuf): NumberPlayerInputPacket { fun read(buff: FriendlyByteBuf): NumberPlayerInputPacket {
return NumberPlayerInputPacket(buff.readInt(), NetworkHelper.readDecimal(buff)) return NumberPlayerInputPacket(buff.readInt(), buff.readDecimal())
} }
} }
} }
@ -57,7 +56,7 @@ class NumberPlayerInputWidget(menu: MatteryMenu) : AbstractWidget(menu) {
supplier = null supplier = null
consumer = { consumer = {
MatteryNetworking.CHANNEL.sendToServer(NumberPlayerInputPacket(slotID, it)) MenuNetworkChannel.sendToServer(NumberPlayerInputPacket(slotID, it))
} }
return this return this

View File

@ -3,11 +3,12 @@ package ru.dbotthepony.mc.otm.menu.widget
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraftforge.network.NetworkEvent import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.menu.MatteryMenu import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MatteryNetworking import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
import java.util.function.Supplier import java.util.function.Supplier
class OneWayPlayerInputPacket(val id: Int) { class OneWayPlayerInputPacket(val id: Int) : MatteryPacket {
fun play(context: Supplier<NetworkEvent.Context>) { override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true context.get().packetHandled = true
context.get().enqueueWork { context.get().enqueueWork {
@ -15,7 +16,7 @@ class OneWayPlayerInputPacket(val id: Int) {
} }
} }
fun write(buff: FriendlyByteBuf) { override fun write(buff: FriendlyByteBuf) {
buff.writeInt(id) buff.writeInt(id)
} }
@ -33,7 +34,7 @@ class OneWayPlayerInputWidget(menu: MatteryMenu, clicker: (() -> Unit)? = null)
if (clicker != null) { if (clicker != null) {
this.clicker = clicker this.clicker = clicker
} else { } else {
this.clicker = { MatteryNetworking.CHANNEL.sendToServer(OneWayPlayerInputPacket(slotID)) } this.clicker = { MenuNetworkChannel.sendToServer(OneWayPlayerInputPacket(slotID)) }
} }
} }

View File

@ -11,10 +11,34 @@ import net.minecraftforge.network.NetworkRegistry
import net.minecraftforge.network.PacketDistributor import net.minecraftforge.network.PacketDistributor
import net.minecraftforge.network.simple.SimpleChannel import net.minecraftforge.network.simple.SimpleChannel
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Optional import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.function.BiConsumer import java.util.function.BiConsumer
import java.util.function.Supplier import java.util.function.Supplier
fun Supplier<NetworkEvent.Context>.enqueueWork(lambda: Runnable): CompletableFuture<Void> = get().enqueueWork(lambda)
fun Supplier<NetworkEvent.Context>.enqueueWork(lambda: () -> Unit): CompletableFuture<Void> = get().enqueueWork(lambda)
var Supplier<NetworkEvent.Context>.packetHandled: Boolean
get() = get().packetHandled
set(value) { get().packetHandled = value }
val Supplier<NetworkEvent.Context>.sender: ServerPlayer?
get() = get().sender
fun FriendlyByteBuf.writeDecimal(value: BigDecimal) {
writeInt(value.scale())
writeByteArray(value.unscaledValue().toByteArray())
}
fun FriendlyByteBuf.readDecimal(): BigDecimal {
val scale = readInt()
val bytes = readByteArray()
return BigDecimal(BigInteger(bytes), scale)
}
interface MatteryPacket { interface MatteryPacket {
fun write(buff: FriendlyByteBuf) fun write(buff: FriendlyByteBuf)
fun play(context: Supplier<NetworkEvent.Context>) fun play(context: Supplier<NetworkEvent.Context>)

View File

@ -0,0 +1,69 @@
package ru.dbotthepony.mc.otm.network
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.NetworkDirection
import net.minecraftforge.network.NetworkEvent
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.container.ItemFilterSlotPacket
import ru.dbotthepony.mc.otm.menu.CancelTaskPacket
import ru.dbotthepony.mc.otm.menu.PatternsChangePacket
import ru.dbotthepony.mc.otm.menu.TasksChangePacket
import ru.dbotthepony.mc.otm.menu.data.*
import ru.dbotthepony.mc.otm.menu.widget.BooleanPlayerInputPacket
import ru.dbotthepony.mc.otm.menu.widget.NumberPlayerInputPacket
import ru.dbotthepony.mc.otm.menu.widget.OneWayPlayerInputPacket
import java.util.function.Supplier
class SetCarriedPacket(val item: ItemStack) : MatteryPacket {
override fun write(buff: FriendlyByteBuf) {
buff.writeItem(item)
}
override fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true
context.get().enqueueWork { minecraft.player?.containerMenu?.carried = item }
}
companion object {
fun read(buff: FriendlyByteBuf): SetCarriedPacket {
return SetCarriedPacket(buff.readItem())
}
}
}
object MenuNetworkChannel : MatteryNetworkChannel(
version = "1",
name = "menu"
) {
fun register() {
add(SetCarriedPacket::class.java, SetCarriedPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(ItemFilterSlotPacket::class.java, ItemFilterSlotPacket.Companion::read)
// networked view
add(ClearItemViewPacket::class.java, ClearItemViewPacket::read, NetworkDirection.PLAY_TO_CLIENT)
add(ItemViewInteractPacket::class.java, ItemViewInteractPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
add(StackAddPacket::class.java, StackAddPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
add(StackChangePacket::class.java, StackChangePacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
add(StackRemovePacket::class.java, StackRemovePacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
// container data
add(MultiByteDataContainerPacket::class.java, MultiByteDataContainerPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
// Player input in menus
add(NumberPlayerInputPacket::class.java, NumberPlayerInputPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(OneWayPlayerInputPacket::class.java, OneWayPlayerInputPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(BooleanPlayerInputPacket::class.java, BooleanPlayerInputPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
// menu specific
// Item monitor
add(ItemMonitorPlayerSettings::class.java, ItemMonitorPlayerSettings.Companion::read)
// matter panel menu
add(CancelTaskPacket::class.java, CancelTaskPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
add(PatternsChangePacket::class.java, PatternsChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(TasksChangePacket::class.java, TasksChangePacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
}
}

View File

@ -0,0 +1,19 @@
package ru.dbotthepony.mc.otm.network
import net.minecraftforge.network.NetworkDirection
import ru.dbotthepony.mc.otm.matter.RegistryPacketClear
import ru.dbotthepony.mc.otm.matter.RegistryPacketFullUpdate
import ru.dbotthepony.mc.otm.matter.RegistryPacketRemove
import ru.dbotthepony.mc.otm.matter.RegistryPacketUpdate
object RegistryNetworkChannel : MatteryNetworkChannel(
version = "1",
name = "registry"
) {
fun register() {
add(RegistryPacketRemove::class.java, RegistryPacketRemove.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(RegistryPacketClear::class.java, RegistryPacketClear.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(RegistryPacketFullUpdate::class.java, RegistryPacketFullUpdate.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
add(RegistryPacketUpdate::class.java, RegistryPacketUpdate.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
}
}

View File

@ -0,0 +1,15 @@
package ru.dbotthepony.mc.otm.network
import net.minecraftforge.network.NetworkDirection
import ru.dbotthepony.mc.otm.item.weapon.WeaponFireInputPacket
import ru.dbotthepony.mc.otm.item.weapon.WeaponScopePacket
object WeaponNetworkChannel : MatteryNetworkChannel(
version = "1",
name = "weapon"
) {
fun register() {
add(WeaponScopePacket::class.java, WeaponScopePacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
add(WeaponFireInputPacket::class.java, WeaponFireInputPacket.Companion::read, NetworkDirection.PLAY_TO_SERVER)
}
}

View File

@ -0,0 +1,13 @@
package ru.dbotthepony.mc.otm.network
import net.minecraftforge.network.NetworkDirection
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterPacket
object WorldNetworkChannel : MatteryNetworkChannel(
version = "1",
name = "world"
) {
fun register() {
add(EnergyCounterPacket::class.java, EnergyCounterPacket.Companion::read, NetworkDirection.PLAY_TO_CLIENT)
}
}

View File

@ -4,8 +4,6 @@ import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import ru.dbotthepony.mc.otm.core.Fraction import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer
import ru.dbotthepony.mc.otm.network.NetworkHelper
import kotlin.experimental.and
object NetworkingTests { object NetworkingTests {
@Test @Test
@ -24,25 +22,4 @@ object NetworkingTests {
container.handle(container.makePacket()) container.handle(container.makePacket())
assert(container.value.compareTo(frac) == 0) { "${container.value} != $frac" } assert(container.value.compareTo(frac) == 0) { "${container.value} != $frac" }
} }
@Test
@DisplayName("Test NetworkHelper byte/short transition")
fun networkHelper() {
var bytes = byteArrayOf(7, 8, -10)
var shorts = NetworkHelper.bytesToShorts(bytes)
assert(shorts.size == 2) { "Shorts array is not size of 2, but size of ${shorts.size}" }
assert((shorts[0].toInt() and 0xFF).toByte() == bytes[0]) { "${shorts[0] and 0xFF} != ${bytes[0]} ${shorts.joinToString()}" }
assert(((shorts[0].toInt() and 0xFF00) shr 8).toByte() == bytes[1]) { "${(shorts[0].toInt() and 0xFF00) shr 8} != ${bytes[1]} ${shorts.joinToString()}" }
assert((shorts[1].toInt() and 0xFF).toByte() == bytes[2]) { "${shorts[1] and 0xFF} != ${bytes[2]} ${shorts.joinToString()}" }
bytes = byteArrayOf(7, 8, -10, 4)
shorts = NetworkHelper.bytesToShorts(bytes)
assert(shorts.size == 2) { "Shorts array is not size of 2, but size of ${shorts.size}" }
assert((shorts[0].toInt() and 0xFF).toByte() == bytes[0]) { "${shorts[0] and 0xFF} != ${bytes[0]} ${shorts.joinToString()}" }
assert(((shorts[0].toInt() and 0xFF00) shr 8).toByte() == bytes[1]) { "${(shorts[0].toInt() and 0xFF00) shr 8} != ${bytes[1]} ${shorts.joinToString()}" }
assert((shorts[1].toInt() and 0xFF).toByte() == bytes[2]) { "${shorts[1] and 0xFF} != ${bytes[2]} ${shorts.joinToString()}" }
assert(((shorts[1].toInt() and 0xFF00) shr 8).toByte() == bytes[3]) { "${(shorts[1].toInt() and 0xFF00) shr 8} != ${bytes[3]} ${shorts.joinToString()}" }
}
} }