Skip to content

Commit 4978a6b

Browse files
authored
Merge pull request #751 from zyxkad/feat/keyboard
Make keyboard works in multiplayer
2 parents 58a92cd + b471dd3 commit 4978a6b

File tree

14 files changed

+184
-99
lines changed

14 files changed

+184
-99
lines changed

src/main/java/de/srendi/advancedperipherals/client/screens/KeyboardScreen.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ public final void removed() {
9595
return;
9696
}
9797
super.removed();
98+
if (this.minecraft.player != null) {
99+
this.keyboardContainer.removed(this.minecraft.player);
100+
}
98101
this.minecraft.keyboardHandler.setSendRepeatsToGui(false);
99102
}
100103

@@ -167,7 +170,11 @@ public boolean mouseScrolled(double x, double y, double direction) {
167170
@Override
168171
public final boolean keyPressed(int key, int scancode, int modifiers) {
169172
if (key == GLFW.GLFW_KEY_ESCAPE) {
170-
super.onClose();
173+
if (this.minecraft.player != null) {
174+
this.minecraft.player.closeContainer();
175+
} else {
176+
super.onClose();
177+
}
171178
return true;
172179
}
173180
// Forward the tab key to the terminal, rather than moving between controls.

src/main/java/de/srendi/advancedperipherals/common/container/KeyboardContainer.java

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,50 @@
2222

2323
public class KeyboardContainer extends BaseContainer implements ComputerMenu {
2424

25+
@Nullable
2526
private final ServerInputState<KeyboardContainer> input;
2627
private final ItemStack keyboardItem;
2728
@Nullable
28-
private ServerComputer computer = null;
29+
private ServerComputer computer;
2930

3031
public KeyboardContainer(int id, Inventory inventory, BlockPos pos, Level level, ItemStack keyboardItem) {
32+
this(id, inventory, pos, level, keyboardItem, null);
33+
}
34+
35+
public KeyboardContainer(int id, Inventory inventory, BlockPos pos, Level level, ItemStack keyboardItem, ServerComputer computer) {
3136
super(APContainerTypes.KEYBOARD_CONTAINER.get(), id, inventory, pos, level);
32-
this.input = new ServerInputState<>(this);
3337
this.keyboardItem = keyboardItem;
3438

39+
if (level.isClientSide) {
40+
this.input = null;
41+
this.computer = null;
42+
return;
43+
}
44+
this.input = new ServerInputState<>(this);
45+
this.computer = computer;
46+
if (computer != null) {
47+
return;
48+
}
3549
CompoundTag data = keyboardItem.getOrCreateTag();
36-
37-
if (!data.getBoolean(KeyboardItem.BOUND_TYPE_TAG)) {
38-
// Cannot use instance ID here since they will change after reload the block
39-
int computerId = keyboardItem.getOrCreateTag().getInt(KeyboardItem.BIND_TAG);
40-
41-
for (ServerComputer computer : ServerContext.get(ServerLifecycleHooks.getCurrentServer()).registry().getComputers()) {
42-
if (computer.getID() == computerId) {
43-
this.computer = computer;
44-
break;
45-
}
50+
if (!data.contains(KeyboardItem.BIND_TAG)) {
51+
return;
52+
}
53+
// Cannot use instance ID here since they will change after reload the block
54+
int computerId = data.getInt(KeyboardItem.BIND_TAG);
55+
for (ServerComputer computr : ServerContext.get(ServerLifecycleHooks.getCurrentServer()).registry().getComputers()) {
56+
if (computr.getID() == computerId) {
57+
this.computer = computr;
58+
break;
4659
}
47-
} else if (data.contains(KeyboardItem.GLASSES_BIND_TAG)) {
48-
computer = ServerContext.get(ServerLifecycleHooks.getCurrentServer()).registry().get(data.getInt(KeyboardItem.GLASSES_BIND_TAG));
4960
}
50-
5161
}
5262

5363
public ItemStack getKeyboardItem() {
5464
return this.keyboardItem;
5565
}
5666

5767
@Override
58-
public boolean stillValid(@NotNull Player playerIn) {
68+
public boolean stillValid(@NotNull Player player) {
5969
return true;
6070
}
6171

@@ -73,6 +83,7 @@ public ServerComputer getComputer() {
7383
return computer;
7484
}
7585

86+
@Nullable
7687
@Override
7788
public ServerInputHandler getInput() {
7889
return input;

src/main/java/de/srendi/advancedperipherals/common/data/EnUsLanguageProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ private void addTooltips() {
149149
addTooltip(APItems.COMPUTER_TOOL.get(), "&7This tool was made to tune our blocks. But for now, it's just a blue useless wrench.");
150150
addTooltip(APItems.MEMORY_CARD.get(), "&7Can save the rights of a player to use it in an inventory manager.");
151151
addTooltip("binding.bound_to", "&7Bound to &b%s&7.");
152-
addTooltip("binding.bound_to_glasses", "&7Bound to Glasses with id &b%s&7.");
153152

154153
}
155154

src/main/java/de/srendi/advancedperipherals/common/items/KeyboardItem.java

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
package de.srendi.advancedperipherals.common.items;
22

33
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
4+
import dan200.computercraft.shared.computer.core.ServerComputer;
45
import de.srendi.advancedperipherals.client.KeyBindings;
56
import de.srendi.advancedperipherals.common.container.KeyboardContainer;
67
import de.srendi.advancedperipherals.common.items.base.BaseItem;
78
import de.srendi.advancedperipherals.common.items.base.IInventoryItem;
89
import de.srendi.advancedperipherals.common.network.APNetworking;
9-
import de.srendi.advancedperipherals.common.network.toclient.KeyboardMouseCapturePacket;
10+
import de.srendi.advancedperipherals.common.network.toserver.GlassesHotkeyPacket;
1011
import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesAccess;
1112
import de.srendi.advancedperipherals.common.smartglasses.modules.IModule;
1213
import de.srendi.advancedperipherals.common.smartglasses.modules.IModuleItem;
1314
import de.srendi.advancedperipherals.common.smartglasses.modules.keyboard.KeyboardModule;
1415
import de.srendi.advancedperipherals.common.util.EnumColor;
1516
import de.srendi.advancedperipherals.common.util.SideHelper;
17+
import net.minecraft.client.player.LocalPlayer;
1618
import net.minecraft.core.BlockPos;
1719
import net.minecraft.nbt.CompoundTag;
20+
import net.minecraft.network.FriendlyByteBuf;
1821
import net.minecraft.network.chat.Component;
19-
import net.minecraft.server.level.ServerPlayer;
2022
import net.minecraft.world.InteractionHand;
2123
import net.minecraft.world.InteractionResult;
2224
import net.minecraft.world.InteractionResultHolder;
@@ -30,7 +32,6 @@
3032
import net.minecraft.world.item.context.UseOnContext;
3133
import net.minecraft.world.level.Level;
3234
import net.minecraft.world.level.block.entity.BlockEntity;
33-
import net.minecraftforge.network.NetworkHooks;
3435
import org.jetbrains.annotations.NotNull;
3536
import org.jetbrains.annotations.Nullable;
3637

@@ -39,8 +40,7 @@
3940
public class KeyboardItem extends BaseItem implements IInventoryItem, IModuleItem {
4041

4142
public static final String BIND_TAG = "bind";
42-
public static final String GLASSES_BIND_TAG = "glasses_id";
43-
public static final String BOUND_TYPE_TAG = "bind_type";
43+
public static final String OPENING_TAG = "KeyboardOpening";
4444

4545
public KeyboardItem() {
4646
super(new Properties().stacksTo(1));
@@ -75,48 +75,27 @@ public InteractionResult useOn(UseOnContext context) {
7575

7676
@Override
7777
public void inventoryTick(ItemStack itemStack, Level level, Entity entity, int inventorySlot, boolean isCurrentItem, @Nullable SmartGlassesAccess access, @Nullable IModule module) {
78-
if (level.isClientSide()) {
78+
if (!level.isClientSide()) {
79+
itemStack.removeTagKey(BIND_TAG);
7980
return;
8081
}
81-
82-
if (access == null || !(module instanceof KeyboardModule keyboadModule)) {
82+
if (!(entity instanceof LocalPlayer player)) {
8383
return;
8484
}
85-
85+
boolean pressed = KeyBindings.GLASSES_HOTKEY_KEYBINDING.isDown();
8686
CompoundTag data = itemStack.getOrCreateTag();
87-
int instanceId = access.getComputer().getInstanceID();
88-
int oldInstanceId = -1;
89-
90-
if (data.contains(GLASSES_BIND_TAG)) {
91-
oldInstanceId = data.getInt(GLASSES_BIND_TAG);
92-
}
93-
94-
if (!data.contains(BOUND_TYPE_TAG) || ((oldInstanceId != -1 && oldInstanceId != instanceId)) || !data.getBoolean(BOUND_TYPE_TAG)) {
95-
data.putBoolean(BOUND_TYPE_TAG, true);
96-
data.putInt(GLASSES_BIND_TAG, access.getComputer().getInstanceID());
97-
data.remove(BIND_TAG);
98-
}
99-
100-
if (!(entity instanceof ServerPlayer serverPlayer)) {
87+
if (data.getBoolean(OPENING_TAG) == pressed) {
10188
return;
10289
}
103-
// TODO: this for sure won't work on dedicated server
104-
if (!KeyBindings.GLASSES_HOTKEY_KEYBINDING.isDown()) {
90+
data.putBoolean(OPENING_TAG, pressed);
91+
if (!pressed) {
10592
return;
10693
}
107-
108-
access.getComputer().queueEvent("keyboard_open");
109-
if (serverPlayer.containerMenu instanceof KeyboardContainer openedKeyboard && openedKeyboard.getKeyboardItem() == itemStack) {
94+
if (player.containerMenu instanceof KeyboardContainer openedKeyboard && openedKeyboard.getKeyboardItem().equals(itemStack)) {
11095
return;
11196
}
112-
113-
NetworkHooks.openScreen(serverPlayer, this.createContainer(serverPlayer, itemStack), buf -> {
114-
buf.writeBlockPos(serverPlayer.blockPosition());
115-
buf.writeItem(itemStack);
116-
});
117-
if (keyboadModule.isCapturingMouse()) {
118-
APNetworking.sendTo(new KeyboardMouseCapturePacket(true), serverPlayer);
119-
}
97+
APNetworking.sendToServer(new GlassesHotkeyPacket("", -1));
98+
return;
12099
}
121100

122101
@Override
@@ -128,7 +107,8 @@ public InteractionResultHolder<ItemStack> use(Level worldIn, Player playerIn, In
128107
if (playerIn.isShiftKeyDown()) {
129108
return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn));
130109
}
131-
if (!playerIn.getItemInHand(handIn).getOrCreateTag().contains(BIND_TAG)) {
110+
CompoundTag data = playerIn.getItemInHand(handIn).getTag();
111+
if (data == null || !data.contains(BIND_TAG)) {
132112
playerIn.displayClientMessage(EnumColor.buildTextComponent(Component.translatable("text.advancedperipherals.keyboard_notbound")), false);
133113
return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn));
134114
}
@@ -140,20 +120,14 @@ public InteractionResultHolder<ItemStack> use(Level worldIn, Player playerIn, In
140120
public void appendHoverText(ItemStack stack, @Nullable Level levelIn, List<Component> tooltip, TooltipFlag flagIn) {
141121
super.appendHoverText(stack, levelIn, tooltip, flagIn);
142122
CompoundTag data = stack.getOrCreateTag();
143-
if (data.contains(BOUND_TYPE_TAG) && !data.getBoolean(BOUND_TYPE_TAG)) {
144-
if (data.contains(BIND_TAG)) {
145-
tooltip.add(EnumColor.buildTextComponent(Component.translatable("item.advancedperipherals.tooltip.binding.bound_to", data.getInt(BIND_TAG))));
146-
}
147-
} else {
148-
if (data.contains(GLASSES_BIND_TAG)) {
149-
tooltip.add(EnumColor.buildTextComponent(Component.translatable("item.advancedperipherals.tooltip.binding.bound_to_glasses", data.getInt(GLASSES_BIND_TAG))));
150-
}
123+
if (data.contains(BIND_TAG)) {
124+
tooltip.add(EnumColor.buildTextComponent(Component.translatable("item.advancedperipherals.tooltip.binding.bound_to", data.getInt(BIND_TAG))));
151125
}
152126
}
153127

154128
private void bind(Player player, ItemStack itemStack, Level world, BlockPos pos) {
155129
CompoundTag data = itemStack.getOrCreateTag();
156-
data.putBoolean(BOUND_TYPE_TAG, false);
130+
data.remove(BIND_TAG);
157131

158132
if (!(world.getBlockEntity(pos) instanceof TileComputerBase computer)) {
159133
// TODO: should it show bind failed message?
@@ -173,7 +147,6 @@ private void bind(Player player, ItemStack itemStack, Level world, BlockPos pos)
173147
private void clear(Player player, ItemStack itemStack) {
174148
CompoundTag data = itemStack.getOrCreateTag();
175149
data.remove(BIND_TAG);
176-
data.putBoolean(BOUND_TYPE_TAG, false);
177150

178151
player.displayClientMessage(EnumColor.buildTextComponent(Component.translatable("text.advancedperipherals.cleared_keyboard")), true);
179152
}
@@ -184,7 +157,7 @@ public MenuProvider createContainer(Player playerEntity, ItemStack itemStack) {
184157
@NotNull
185158
@Override
186159
public Component getDisplayName() {
187-
return Component.literal("");
160+
return Component.empty();
188161
}
189162

190163
@Override
@@ -194,8 +167,29 @@ public AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory pla
194167
};
195168
}
196169

170+
public MenuProvider createContainerWithComputer(Player playerEntity, ItemStack itemStack, ServerComputer computer) {
171+
return new MenuProvider() {
172+
@NotNull
173+
@Override
174+
public Component getDisplayName() {
175+
return Component.empty();
176+
}
177+
178+
@Override
179+
public AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory playerInv, @NotNull Player player) {
180+
return new KeyboardContainer(pContainerId, playerInv, player.blockPosition(), player.getLevel(), itemStack, computer);
181+
}
182+
};
183+
}
184+
185+
@Override
186+
public void writeContainerData(Player player, ItemStack stack, FriendlyByteBuf buf) {
187+
buf.writeBlockPos(player.blockPosition());
188+
buf.writeItem(stack);
189+
}
190+
197191
@Override
198-
public IModule createModule(SmartGlassesAccess access) {
199-
return new KeyboardModule();
192+
public IModule createModule(SmartGlassesAccess access, ItemStack stack) {
193+
return new KeyboardModule(this, stack);
200194
}
201195
}

src/main/java/de/srendi/advancedperipherals/common/items/base/BaseItem.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,14 @@ public BaseItem() {
3434

3535
@Override
3636
public InteractionResultHolder<ItemStack> use(Level worldIn, Player playerIn, InteractionHand handIn) {
37-
if (worldIn.isClientSide)
38-
return new InteractionResultHolder<>(InteractionResult.PASS, playerIn.getItemInHand(handIn));
37+
ItemStack stack = playerIn.getItemInHand(handIn);
38+
if (worldIn.isClientSide) {
39+
return new InteractionResultHolder<>(InteractionResult.PASS, stack);
40+
}
3941
if (this instanceof IInventoryItem inventoryItem) {
4042
ServerPlayer serverPlayerEntity = (ServerPlayer) playerIn;
41-
ItemStack stack = playerIn.getItemInHand(handIn);
42-
NetworkHooks.openScreen(serverPlayerEntity, inventoryItem.createContainer(playerIn, stack), buf -> {
43-
buf.writeBlockPos(playerIn.blockPosition());
44-
buf.writeItem(stack);
45-
});
43+
NetworkHooks.openScreen(serverPlayerEntity, inventoryItem.createContainer(playerIn, stack), buf -> inventoryItem.writeContainerData(playerIn, stack, buf));
44+
return new InteractionResultHolder<>(InteractionResult.SUCCESS, stack);
4645
}
4746
return super.use(worldIn, playerIn, handIn);
4847
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package de.srendi.advancedperipherals.common.items.base;
22

3+
import net.minecraft.network.FriendlyByteBuf;
34
import net.minecraft.world.MenuProvider;
45
import net.minecraft.world.entity.player.Player;
56
import net.minecraft.world.item.ItemStack;
67

78
public interface IInventoryItem {
9+
MenuProvider createContainer(Player player, ItemStack itemStack);
810

9-
MenuProvider createContainer(Player playerEntity, ItemStack itemStack);
10-
11+
void writeContainerData(Player player, ItemStack itemStack, FriendlyByteBuf buf);
1112
}

src/main/java/de/srendi/advancedperipherals/common/network/toclient/KeyboardMouseCapturePacket.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import de.srendi.advancedperipherals.common.network.base.IPacket;
55
import net.minecraft.client.Minecraft;
66
import net.minecraft.network.FriendlyByteBuf;
7-
import net.minecraftforge.api.distmarker.Dist;
8-
import net.minecraftforge.api.distmarker.OnlyIn;
97
import net.minecraftforge.network.NetworkEvent;
108

119
public class KeyboardMouseCapturePacket implements IPacket {
@@ -16,7 +14,6 @@ public KeyboardMouseCapturePacket(boolean enable) {
1614
this.enable = enable;
1715
}
1816

19-
@OnlyIn(Dist.CLIENT)
2017
@Override
2118
public void handle(NetworkEvent.Context context) {
2219
if (!(Minecraft.getInstance().screen instanceof KeyboardScreen screen)) {

src/main/java/de/srendi/advancedperipherals/common/network/toserver/GlassesHotkeyPacket.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import de.srendi.advancedperipherals.common.items.SmartGlassesItem;
44
import de.srendi.advancedperipherals.common.network.base.IPacket;
5+
import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesAccess;
56
import de.srendi.advancedperipherals.common.smartglasses.SmartGlassesComputer;
7+
import de.srendi.advancedperipherals.common.smartglasses.modules.keyboard.KeyboardModule;
68
import net.minecraft.network.FriendlyByteBuf;
79
import net.minecraft.server.MinecraftServer;
810
import net.minecraft.server.level.ServerPlayer;
@@ -29,15 +31,33 @@ public void handle(NetworkEvent.Context context) {
2931
return;
3032
}
3133

34+
ItemStack smartGlasses = null;
35+
SmartGlassesComputer computer = null;
3236
for (ItemStack stack : serverPlayer.getAllSlots()) {
3337
if (stack.getItem() instanceof SmartGlassesItem) {
34-
SmartGlassesComputer computer = SmartGlassesItem.getServerComputer(server, stack);
38+
computer = SmartGlassesItem.getServerComputer(server, stack);
3539
if (computer != null) {
36-
computer.queueEvent("glasses_key_pressed", new Object[]{keyBind, keyPressDuration});
40+
smartGlasses = stack;
3741
break;
3842
}
3943
}
4044
}
45+
if (computer == null) {
46+
return;
47+
}
48+
if (keyPressDuration >= 0) {
49+
computer.queueEvent("glasses_key_pressed", new Object[]{keyBind, keyPressDuration});
50+
return;
51+
}
52+
SmartGlassesAccess glasses = computer.getSmartGlassesAccess();
53+
computer.getModules().values()
54+
.stream()
55+
.filter(KeyboardModule.class::isInstance)
56+
.map(KeyboardModule.class::cast)
57+
.findFirst()
58+
.ifPresent((keyboardModule) -> {
59+
keyboardModule.openKeyboard(glasses);
60+
});
4161
}
4262

4363
@Override

0 commit comments

Comments
 (0)