Skip to content

Commit 217c945

Browse files
Emulate dialog screens using chest inventories (#1041)
1 parent ead2c6f commit 217c945

25 files changed

+2500
-34
lines changed

common/src/main/java/com/viaversion/viabackwards/api/ViaBackwardsPlatform.java

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,48 +21,49 @@
2121
import com.viaversion.viabackwards.ViaBackwards;
2222
import com.viaversion.viabackwards.ViaBackwardsConfig;
2323
import com.viaversion.viabackwards.api.data.TranslatableMappings;
24-
import com.viaversion.viabackwards.protocol.v1_11to1_10.Protocol1_11To1_10;
25-
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.Protocol1_12To1_11_1;
24+
import com.viaversion.viabackwards.protocol.v1_10to1_9_3.Protocol1_10To1_9_3;
2625
import com.viaversion.viabackwards.protocol.v1_11_1to1_11.Protocol1_11_1To1_11;
27-
import com.viaversion.viabackwards.protocol.v1_12_2to1_12_1.Protocol1_12_2To1_12_1;
28-
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
26+
import com.viaversion.viabackwards.protocol.v1_11to1_10.Protocol1_11To1_10;
2927
import com.viaversion.viabackwards.protocol.v1_12_1to1_12.Protocol1_12_1To1_12;
30-
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1;
31-
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.Protocol1_14To1_13_2;
28+
import com.viaversion.viabackwards.protocol.v1_12_2to1_12_1.Protocol1_12_2To1_12_1;
29+
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.Protocol1_12To1_11_1;
3230
import com.viaversion.viabackwards.protocol.v1_13_1to1_13.Protocol1_13_1To1_13;
31+
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1;
32+
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
33+
import com.viaversion.viabackwards.protocol.v1_14_1to1_14.Protocol1_14_1To1_14;
3334
import com.viaversion.viabackwards.protocol.v1_14_2to1_14_1.Protocol1_14_2To1_14_1;
3435
import com.viaversion.viabackwards.protocol.v1_14_3to1_14_2.Protocol1_14_3To1_14_2;
3536
import com.viaversion.viabackwards.protocol.v1_14_4to1_14_3.Protocol1_14_4To1_14_3;
36-
import com.viaversion.viabackwards.protocol.v1_15to1_14_4.Protocol1_15To1_14_4;
37-
import com.viaversion.viabackwards.protocol.v1_14_1to1_14.Protocol1_14_1To1_14;
38-
import com.viaversion.viabackwards.protocol.v1_15_2to1_15_1.Protocol1_15_2To1_15_1;
39-
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2;
37+
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.Protocol1_14To1_13_2;
4038
import com.viaversion.viabackwards.protocol.v1_15_1to1_15.Protocol1_15_1To1_15;
39+
import com.viaversion.viabackwards.protocol.v1_15_2to1_15_1.Protocol1_15_2To1_15_1;
40+
import com.viaversion.viabackwards.protocol.v1_15to1_14_4.Protocol1_15To1_14_4;
41+
import com.viaversion.viabackwards.protocol.v1_16_1to1_16.Protocol1_16_1To1_16;
4142
import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.Protocol1_16_2To1_16_1;
4243
import com.viaversion.viabackwards.protocol.v1_16_3to1_16_2.Protocol1_16_3To1_16_2;
4344
import com.viaversion.viabackwards.protocol.v1_16_4to1_16_3.Protocol1_16_4To1_16_3;
44-
import com.viaversion.viabackwards.protocol.v1_17to1_16_4.Protocol1_17To1_16_4;
45-
import com.viaversion.viabackwards.protocol.v1_16_1to1_16.Protocol1_16_1To1_16;
46-
import com.viaversion.viabackwards.protocol.v1_18to1_17_1.Protocol1_18To1_17_1;
45+
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2;
4746
import com.viaversion.viabackwards.protocol.v1_17_1to1_17.Protocol1_17_1To1_17;
48-
import com.viaversion.viabackwards.protocol.v1_19to1_18_2.Protocol1_19To1_18_2;
47+
import com.viaversion.viabackwards.protocol.v1_17to1_16_4.Protocol1_17To1_16_4;
4948
import com.viaversion.viabackwards.protocol.v1_18_2to1_18.Protocol1_18_2To1_18;
49+
import com.viaversion.viabackwards.protocol.v1_18to1_17_1.Protocol1_18To1_17_1;
50+
import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19;
5051
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.Protocol1_19_3To1_19_1;
5152
import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.Protocol1_19_4To1_19_3;
52-
import com.viaversion.viabackwards.protocol.v1_21_4to1_21_2.Protocol1_21_4To1_21_2;
53-
import com.viaversion.viabackwards.protocol.v1_20to1_19_4.Protocol1_20To1_19_4;
54-
import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19;
53+
import com.viaversion.viabackwards.protocol.v1_19to1_18_2.Protocol1_19To1_18_2;
54+
import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20;
5555
import com.viaversion.viabackwards.protocol.v1_20_3to1_20_2.Protocol1_20_3To1_20_2;
5656
import com.viaversion.viabackwards.protocol.v1_20_5to1_20_3.Protocol1_20_5To1_20_3;
57-
import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20;
57+
import com.viaversion.viabackwards.protocol.v1_20to1_19_4.Protocol1_20To1_19_4;
5858
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
5959
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.task.PlayerPacketsTickTask;
60+
import com.viaversion.viabackwards.protocol.v1_21_4to1_21_2.Protocol1_21_4To1_21_2;
6061
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.Protocol1_21_5To1_21_4;
61-
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5;
6262
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
63-
import com.viaversion.viabackwards.protocol.v1_9_3to1_9_1.Protocol1_9_3To1_9_1;
64-
import com.viaversion.viabackwards.protocol.v1_10to1_9_3.Protocol1_10To1_9_3;
63+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.task.ChestDialogViewTask;
64+
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5;
6565
import com.viaversion.viabackwards.protocol.v1_9_1to1_9.Protocol1_9_1To1_9;
66+
import com.viaversion.viabackwards.protocol.v1_9_3to1_9_1.Protocol1_9_3To1_9_1;
6667
import com.viaversion.viabackwards.utils.VersionInfo;
6768
import com.viaversion.viaversion.api.Via;
6869
import com.viaversion.viaversion.api.protocol.ProtocolManager;
@@ -158,6 +159,10 @@ default void enable() {
158159
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_2)) {
159160
Via.getPlatform().runRepeatingSync(new PlayerPacketsTickTask(), 1L);
160161
}
162+
163+
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_6)) {
164+
Via.getPlatform().runRepeatingSync(new ChestDialogViewTask(), 20L);
165+
}
161166
}
162167

163168
/**

common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/EntityPacketRewriter1_19.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ public void register() {
190190
}
191191
}
192192
if (!found) {
193-
throw new IllegalStateException("Could not find dimension " + dimensionKey + " in dimension registry");
193+
throw new IllegalArgumentException("Could not find dimension " + dimensionKey + " in dimension registry");
194194
}
195195

196196
// Add biome category and track biomes

common/src/main/java/com/viaversion/viabackwards/protocol/v1_21_6to1_21_5/Protocol1_21_6To1_21_5.java

Lines changed: 181 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,26 @@
1717
*/
1818
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5;
1919

20+
import com.viaversion.nbt.tag.CompoundTag;
21+
import com.viaversion.nbt.tag.Tag;
2022
import com.viaversion.viabackwards.api.BackwardsProtocol;
2123
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
2224
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
2325
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
26+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
27+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.ChestDialogViewProvider;
28+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.DialogViewProvider;
2429
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter.BlockItemPacketRewriter1_21_6;
2530
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter.ComponentRewriter1_21_6;
2631
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter.EntityPacketRewriter1_21_6;
32+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
33+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ClickEvents;
34+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.RegistryAndTags;
35+
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ServerLinks;
36+
import com.viaversion.viaversion.api.Via;
2737
import com.viaversion.viaversion.api.connection.UserConnection;
2838
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
39+
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
2940
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
3041
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
3142
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
@@ -52,6 +63,7 @@
5263
import com.viaversion.viaversion.rewriter.ParticleRewriter;
5364
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
5465
import com.viaversion.viaversion.rewriter.TagRewriter;
66+
import com.viaversion.viaversion.util.Key;
5567
import com.viaversion.viaversion.util.SerializerVersion;
5668

5769
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
@@ -73,9 +85,8 @@ public Protocol1_21_6To1_21_5() {
7385
protected void registerPackets() {
7486
super.registerPackets();
7587

76-
tagRewriter.removeTags("dialog");
77-
tagRewriter.registerGeneric(ClientboundPackets1_21_6.UPDATE_TAGS);
78-
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS);
88+
registerClientbound(ClientboundPackets1_21_6.UPDATE_TAGS, this::updateTags);
89+
registerClientbound(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS, this::updateTags);
7990

8091
final SoundRewriter<ClientboundPacket1_21_6> soundRewriter = new SoundRewriter<>(this);
8192
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_6.SOUND);
@@ -121,17 +132,180 @@ public void handleArgument(final PacketWrapper wrapper, final String argumentTyp
121132
wrapper.write(Types.VAR_INT, (int) difficulty);
122133
});
123134

135+
// Are you sure you want to see this? This is your last chance to turn back.
136+
registerClientbound(ClientboundPackets1_21_6.SHOW_DIALOG, null, wrapper -> {
137+
wrapper.cancel();
138+
139+
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
140+
final ServerLinks serverLinks = wrapper.user().get(ServerLinks.class);
141+
final int id = wrapper.read(Types.VAR_INT) - 1;
142+
CompoundTag tag;
143+
if (id == -1) {
144+
tag = (CompoundTag) wrapper.read(Types.TAG);
145+
} else {
146+
tag = registryAndTags.fromRegistry(id);
147+
}
148+
149+
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
150+
provider.openDialog(wrapper.user(), new Dialog(registryAndTags, serverLinks, tag));
151+
});
152+
registerClientbound(ClientboundConfigurationPackets1_21_6.SHOW_DIALOG, null, wrapper -> {
153+
wrapper.cancel();
154+
155+
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
156+
final ServerLinks serverLinks = wrapper.user().get(ServerLinks.class);
157+
final CompoundTag tag = (CompoundTag) wrapper.read(Types.TAG);
158+
159+
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
160+
provider.openDialog(wrapper.user(), new Dialog(registryAndTags, serverLinks, tag));
161+
});
162+
registerClientbound(ClientboundPackets1_21_6.CLEAR_DIALOG, null, this::clearDialog);
163+
registerClientbound(ClientboundConfigurationPackets1_21_6.CLEAR_DIALOG, null, this::clearDialog);
164+
165+
registerClientbound(ClientboundPackets1_21_6.SERVER_LINKS, this::storeServerLinks);
166+
registerClientbound(ClientboundConfigurationPackets1_21_6.SERVER_LINKS, this::storeServerLinks);
167+
168+
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND, wrapper -> {
169+
final String command = wrapper.passthrough(Types.STRING);
170+
171+
final ClickEvents clickEvents = wrapper.user().get(ClickEvents.class);
172+
if (clickEvents.handleChatCommand(wrapper.user(), command)) {
173+
wrapper.cancel();
174+
}
175+
});
176+
177+
// The ones below are specific to the chest dialog view provider
178+
registerServerbound(ServerboundPackets1_21_5.CONTAINER_CLOSE, wrapper -> {
179+
final ChestDialogStorage storage = wrapper.user().get(ChestDialogStorage.class);
180+
if (storage == null) {
181+
return;
182+
}
183+
184+
final ChestDialogViewProvider provider = (ChestDialogViewProvider) Via.getManager().getProviders().get(DialogViewProvider.class);
185+
186+
if (storage.phase() == ChestDialogStorage.Phase.ANVIL_VIEW) {
187+
wrapper.cancel();
188+
189+
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.DIALOG_VIEW);
190+
return;
191+
}
192+
193+
if (storage.phase() == ChestDialogStorage.Phase.WAITING_FOR_RESPONSE) {
194+
wrapper.cancel();
195+
if (storage.closeButtonEnabled()) {
196+
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.DIALOG_VIEW);
197+
} else {
198+
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.WAITING_FOR_RESPONSE);
199+
}
200+
return;
201+
}
202+
203+
final boolean allowClosing = storage.allowClosing();
204+
if (!allowClosing) {
205+
wrapper.cancel();
206+
if (storage.dialog().canCloseWithEscape()) {
207+
provider.clickButton(wrapper.user(), Dialog.AfterAction.CLOSE, storage.dialog().actionButton());
208+
} else {
209+
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.DIALOG_VIEW);
210+
}
211+
}
212+
storage.setAllowClosing(false);
213+
});
214+
registerServerbound(ServerboundPackets1_21_5.RENAME_ITEM, wrapper -> {
215+
final ChestDialogStorage storage = wrapper.user().get(ChestDialogStorage.class);
216+
if (storage == null || storage.phase() != ChestDialogStorage.Phase.ANVIL_VIEW) {
217+
return;
218+
}
219+
220+
wrapper.cancel();
221+
final String name = wrapper.read(Types.STRING);
222+
223+
final ChestDialogViewProvider provider = (ChestDialogViewProvider) Via.getManager().getProviders().get(DialogViewProvider.class);
224+
provider.updateAnvilText(wrapper.user(), name);
225+
});
226+
appendServerbound(ServerboundPackets1_21_5.CONTAINER_CLICK, wrapper -> {
227+
final ChestDialogViewProvider provider = (ChestDialogViewProvider) Via.getManager().getProviders().get(DialogViewProvider.class);
228+
if (provider == null) {
229+
return;
230+
}
231+
232+
final int containerId = wrapper.get(Types.VAR_INT, 0);
233+
final int slot = wrapper.get(Types.SHORT, 0);
234+
final byte button = wrapper.get(Types.BYTE, 0);
235+
final int mode = wrapper.get(Types.VAR_INT, 2);
236+
if (provider.clickDialog(wrapper.user(), containerId, slot, button, mode)) {
237+
wrapper.cancel();
238+
}
239+
});
240+
124241
cancelClientbound(ClientboundPackets1_21_6.TRACKED_WAYPOINT);
125-
cancelClientbound(ClientboundPackets1_21_6.CLEAR_DIALOG);
126-
cancelClientbound(ClientboundPackets1_21_6.SHOW_DIALOG);
127-
cancelClientbound(ClientboundConfigurationPackets1_21_6.CLEAR_DIALOG);
128-
cancelClientbound(ClientboundConfigurationPackets1_21_6.SHOW_DIALOG);
242+
}
243+
244+
private void clearDialog(final PacketWrapper wrapper) {
245+
wrapper.cancel();
246+
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
247+
provider.closeDialog(wrapper.user());
248+
}
249+
250+
private void updateTags(final PacketWrapper wrapper) {
251+
tagRewriter.handleGeneric(wrapper);
252+
wrapper.resetReader();
253+
254+
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
255+
final int length = wrapper.passthrough(Types.VAR_INT);
256+
for (int i = 0; i < length; i++) {
257+
final String registryKey = wrapper.read(Types.STRING);
258+
final boolean dialog = "dialog".equals(Key.stripMinecraftNamespace(registryKey));
259+
if (dialog) {
260+
final int tagsSize = wrapper.read(Types.VAR_INT);
261+
for (int j = 0; j < tagsSize; j++) {
262+
final String key = wrapper.read(Types.STRING);
263+
final int[] ids = wrapper.read(Types.VAR_INT_ARRAY_PRIMITIVE);
264+
registryAndTags.storeTags(key, ids);
265+
}
266+
} else {
267+
wrapper.write(Types.STRING, registryKey); // Write back
268+
final int tagsSize = wrapper.passthrough(Types.VAR_INT);
269+
for (int j = 0; j < tagsSize; j++) {
270+
wrapper.passthrough(Types.STRING);
271+
wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE);
272+
}
273+
}
274+
}
275+
276+
if (registryAndTags.tagsSent()) {
277+
wrapper.set(Types.VAR_INT, 0, length - 1); // Dialog tags have been read, remove from size
278+
}
279+
}
280+
281+
private void storeServerLinks(final PacketWrapper wrapper) {
282+
final ServerLinks serverLinks = new ServerLinks();
283+
final int length = wrapper.passthrough(Types.VAR_INT);
284+
for (int i = 0; i < length; i++) {
285+
if (wrapper.passthrough(Types.BOOLEAN)) {
286+
final int id = wrapper.passthrough(Types.VAR_INT);
287+
final String url = wrapper.passthrough(Types.STRING);
288+
serverLinks.storeLink(id, url);
289+
} else {
290+
final Tag tag = wrapper.passthrough(Types.COMPOUND_TAG);
291+
final String url = wrapper.passthrough(Types.STRING);
292+
serverLinks.storeLink(tag, url);
293+
}
294+
}
295+
wrapper.user().put(serverLinks);
129296
}
130297

131298
@Override
132299
public void init(final UserConnection user) {
133300
addEntityTracker(user, new EntityTrackerBase(user, EntityTypes1_21_6.PLAYER));
134301
addItemHasher(user, new ItemHasherBase(this, user, SerializerVersion.V1_21_5, SerializerVersion.V1_21_5));
302+
user.put(new RegistryAndTags());
303+
user.put(new ClickEvents());
304+
}
305+
306+
@Override
307+
public void register(final ViaProviders providers) {
308+
providers.register(DialogViewProvider.class, new ChestDialogViewProvider(this));
135309
}
136310

137311
@Override

0 commit comments

Comments
 (0)