Skip to content
This repository was archived by the owner on Apr 20, 2023. It is now read-only.

Commit d6cfe94

Browse files
Make the width of the version dropdown dynamic and fix doesServerKnow (#518)
* Make the width of the version dropdown dynamic * Fix doesServerKnow * Fix items not getting added back to the creative inventory Also applies to items not getting removed if you joined a newer server first. * Handle blocks older than 1.12.2 properly as well * Suppress conversion warnings --------- Co-authored-by: Joseph Burton <[email protected]>
1 parent be7871c commit d6cfe94

File tree

9 files changed

+117
-56
lines changed

9 files changed

+117
-56
lines changed

src/main/java/net/earthcomputer/multiconnect/impl/DropDownWidget.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
package net.earthcomputer.multiconnect.impl;
22

33
import com.mojang.blaze3d.systems.RenderSystem;
4-
import com.mojang.blaze3d.vertex.BufferBuilder;
5-
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
6-
import com.mojang.blaze3d.vertex.PoseStack;
7-
import com.mojang.blaze3d.vertex.Tesselator;
8-
import com.mojang.blaze3d.vertex.VertexFormat;
9-
import java.util.ArrayList;
10-
import java.util.List;
11-
import java.util.function.Consumer;
12-
import java.util.function.Function;
4+
import com.mojang.blaze3d.vertex.*;
135
import net.minecraft.client.Minecraft;
146
import net.minecraft.client.gui.Font;
157
import net.minecraft.client.gui.components.AbstractButton;
@@ -19,6 +11,11 @@
1911
import net.minecraft.network.chat.Component;
2012
import net.minecraft.util.Mth;
2113

14+
import java.util.ArrayList;
15+
import java.util.List;
16+
import java.util.function.Consumer;
17+
import java.util.function.Function;
18+
2219
public class DropDownWidget<T> extends AbstractButton {
2320

2421
private static final int DROP_DOWN_ELEMENT_HEIGHT = 20;
@@ -47,6 +44,14 @@ public DropDownWidget(int x, int y, int width, int height, T initialValue, Funct
4744
this.value = initialValue;
4845
}
4946

47+
public Function<T, Component> getLabelExtractor() {
48+
return labelExtractor;
49+
}
50+
51+
public Function<T, Component> getCategoryLabelExtractor() {
52+
return categoryLabelExtractor;
53+
}
54+
5055
public DropDownWidget<T> setCategoryLabelExtractor(Function<T, Component> categoryLabelExtractor) {
5156
this.categoryLabelExtractor = categoryLabelExtractor;
5257
return this;

src/main/java/net/earthcomputer/multiconnect/impl/Utils.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
package net.earthcomputer.multiconnect.impl;
22

33
import com.google.common.cache.Cache;
4-
import net.earthcomputer.multiconnect.api.ThreadSafe;
54
import net.earthcomputer.multiconnect.api.IProtocol;
5+
import net.earthcomputer.multiconnect.api.ThreadSafe;
66
import net.earthcomputer.multiconnect.connect.ConnectionMode;
77
import net.earthcomputer.multiconnect.protocols.ProtocolRegistry;
88
import net.minecraft.ChatFormatting;
9+
import net.minecraft.client.Minecraft;
910
import net.minecraft.client.gui.screens.Screen;
1011
import net.minecraft.network.chat.Component;
1112
import net.minecraft.network.chat.MutableComponent;
13+
1214
import java.lang.ref.Cleaner;
1315
import java.lang.ref.WeakReference;
1416
import java.lang.reflect.Array;
15-
import java.util.*;
17+
import java.util.ArrayList;
18+
import java.util.BitSet;
19+
import java.util.Comparator;
20+
import java.util.List;
1621
import java.util.concurrent.Executors;
1722
import java.util.concurrent.ScheduledExecutorService;
1823
import java.util.concurrent.ScheduledFuture;
@@ -65,6 +70,7 @@ public static DropDownWidget<IProtocol> createVersionDropdown(Screen screen, IPr
6570
for (IProtocol protocol : ProtocolRegistry.getProtocols()) {
6671
populateDropdown(versionDropDown, protocol);
6772
}
73+
versionDropDown.setX(screen.width - 5 - versionDropDown.getWidth());
6874

6975
return versionDropDown;
7076
}
@@ -80,15 +86,24 @@ private static MutableComponent getMajorReleaseNameText(IProtocolExt protocol) {
8086
private static void populateDropdown(DropDownWidget<IProtocol> versionDropDown, IProtocol protocol) {
8187
if (protocol.isMajorRelease()) {
8288
var category = versionDropDown.add(protocol);
89+
var maxWidth = getWidth(versionDropDown, protocol);
8390
List<IProtocol> children = protocol.getMinorReleases();
8491
if (children.size() > 1) {
8592
for (IProtocol child : children) {
8693
category.add(child);
94+
maxWidth = Math.max(maxWidth, getWidth(versionDropDown, child));
8795
}
8896
}
97+
if (maxWidth + 30 > versionDropDown.getWidth()) {
98+
versionDropDown.setWidth(maxWidth + 30);
99+
}
89100
}
90101
}
91102

103+
private static int getWidth(DropDownWidget<IProtocol> versionDropDown, IProtocol protocol) {
104+
return Minecraft.getInstance().font.width(versionDropDown.getCategoryLabelExtractor().apply(protocol));
105+
}
106+
92107
@ThreadSafe
93108
public static void leftShift(BitSet bitSet, int n) {
94109
if (n < 0) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.earthcomputer.multiconnect.mixin.bridge;
2+
3+
import net.earthcomputer.multiconnect.impl.ConnectionInfo;
4+
import net.minecraft.world.flag.FeatureFlagSet;
5+
import net.minecraft.world.item.CreativeModeTabs;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.injection.At;
8+
import org.spongepowered.asm.mixin.injection.Inject;
9+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
10+
11+
@Mixin(CreativeModeTabs.class)
12+
public class CreativeModeTabsMixin {
13+
private static int protocolValue = Integer.MIN_VALUE;
14+
15+
@Inject(method = "wouldRebuildSameContents", at = @At("HEAD"), cancellable = true)
16+
private static void alsoCheckProtocolVersion(FeatureFlagSet featureFlagSet, boolean bl, CallbackInfoReturnable<Boolean> cir) {
17+
if (protocolValue != ConnectionInfo.protocolVersion) {
18+
protocolValue = ConnectionInfo.protocolVersion;
19+
cir.setReturnValue(false);
20+
}
21+
}
22+
}

src/main/java/net/earthcomputer/multiconnect/mixin/connect/DirectJoinServerScreenMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.mojang.blaze3d.vertex.PoseStack;
44
import net.earthcomputer.multiconnect.api.IProtocol;
55
import net.earthcomputer.multiconnect.connect.ConnectionMode;
6-
import net.earthcomputer.multiconnect.impl.DropDownWidget;
76
import net.earthcomputer.multiconnect.connect.ServersExt;
7+
import net.earthcomputer.multiconnect.impl.DropDownWidget;
88
import net.earthcomputer.multiconnect.impl.IProtocolExt;
99
import net.earthcomputer.multiconnect.impl.Utils;
1010
import net.minecraft.client.gui.components.EditBox;
@@ -52,7 +52,7 @@ private void onTick(CallbackInfo ci) {
5252

5353
@Inject(method = "render", at = @At("RETURN"))
5454
private void drawScreen(PoseStack matrixStack, int mouseX, int mouseY, float delta, CallbackInfo ci) {
55-
font.drawShadow(matrixStack, multiconnect_forceProtocolLabel, width - 85 - font.width(multiconnect_forceProtocolLabel), 11, 0xFFFFFF);
55+
font.drawShadow(matrixStack, multiconnect_forceProtocolLabel, width - multiconnect_protocolSelector.getWidth() - 10 - font.width(multiconnect_forceProtocolLabel), 11, 0xFFFFFF);
5656
multiconnect_protocolSelector.render(matrixStack, mouseX, mouseY, delta);
5757
}
5858

src/main/java/net/earthcomputer/multiconnect/mixin/connect/DisconnectedScreenMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.google.common.collect.ImmutableSet;
44
import com.mojang.blaze3d.vertex.PoseStack;
55
import net.earthcomputer.multiconnect.api.IProtocol;
6-
import net.earthcomputer.multiconnect.impl.DropDownWidget;
76
import net.earthcomputer.multiconnect.connect.ServersExt;
7+
import net.earthcomputer.multiconnect.impl.DropDownWidget;
88
import net.earthcomputer.multiconnect.impl.Utils;
99
import net.earthcomputer.multiconnect.protocols.ProtocolRegistry;
1010
import net.minecraft.client.Minecraft;
@@ -69,7 +69,7 @@ private void addButtons(CallbackInfo ci) {
6969
@Inject(method = "render", at = @At("RETURN"))
7070
private void onRender(PoseStack matrixStack, int mouseX, int mouseY, float delta, CallbackInfo ci) {
7171
if (multiconnect_isProtocolReason) {
72-
font.drawShadow(matrixStack, multiconnect_forceProtocolLabel, width - 85 - font.width(multiconnect_forceProtocolLabel), 11, 0xFFFFFF);
72+
font.drawShadow(matrixStack, multiconnect_forceProtocolLabel, width - multiconnect_protocolSelector.getWidth() - 10 - font.width(multiconnect_forceProtocolLabel), 11, 0xFFFFFF);
7373
multiconnect_protocolSelector.render(matrixStack, mouseX, mouseY, delta);
7474
}
7575
}

src/main/java/net/earthcomputer/multiconnect/mixin/connect/EditServerScreenMixin.java

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

33
import com.mojang.blaze3d.vertex.PoseStack;
44
import net.earthcomputer.multiconnect.api.IProtocol;
5-
import net.earthcomputer.multiconnect.impl.DropDownWidget;
65
import net.earthcomputer.multiconnect.connect.ServersExt;
6+
import net.earthcomputer.multiconnect.impl.DropDownWidget;
77
import net.earthcomputer.multiconnect.impl.Utils;
88
import net.minecraft.client.gui.screens.EditServerScreen;
99
import net.minecraft.client.gui.screens.Screen;
@@ -39,7 +39,7 @@ private void createButtons(CallbackInfo ci) {
3939

4040
@Inject(method = "render", at = @At("RETURN"))
4141
private void drawScreen(PoseStack stack, int mouseX, int mouseY, float delta, CallbackInfo ci) {
42-
font.drawShadow(stack, multiconnect_forceProtocolLabel, width - 85 - font.width(multiconnect_forceProtocolLabel), 11, 0xFFFFFF);
42+
font.drawShadow(stack, multiconnect_forceProtocolLabel, width - multiconnect_protocolSelector.getWidth() - 10 - font.width(multiconnect_forceProtocolLabel), 11, 0xFFFFFF);
4343
multiconnect_protocolSelector.render(stack, mouseX, mouseY, delta);
4444
}
4545

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# this is a comment
22

3-
serverside-blockconnections: true
3+
serverside-blockconnections: true
4+
suppress-conversion-warnings: true

src/main/resources/multiconnect.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"bridge.Connection1Mixin",
1010
"bridge.ConnectionMixin",
1111
"bridge.CreativeModeTabItemDisplayBuilderMixin",
12+
"bridge.CreativeModeTabsMixin",
1213
"bridge.MinecraftAccessor",
1314
"bridge.MinecraftMixin",
1415
"bridge.ParticleEngineMixin",

via-translator/src/main/java/net/earthcomputer/multiconnect/impl/via/ViaMulticonnectTranslator.java

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import com.viaversion.viaversion.api.data.FullMappings;
88
import com.viaversion.viaversion.api.data.MappingData;
99
import com.viaversion.viaversion.api.data.Mappings;
10+
import com.viaversion.viaversion.api.minecraft.item.DataItem;
11+
import com.viaversion.viaversion.api.minecraft.item.Item;
1012
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
1113
import com.viaversion.viaversion.api.type.Type;
1214
import com.viaversion.viaversion.connection.UserConnectionImpl;
@@ -18,6 +20,8 @@
1820
import io.netty.buffer.ByteBuf;
1921
import io.netty.channel.Channel;
2022
import io.netty.util.AttributeKey;
23+
import it.unimi.dsi.fastutil.ints.Int2IntMap;
24+
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
2125
import net.earthcomputer.multiconnect.api.IMulticonnectTranslator;
2226
import net.earthcomputer.multiconnect.api.IMulticonnectTranslatorApi;
2327
import net.minecraft.client.Minecraft;
@@ -28,8 +32,6 @@
2832
import org.jetbrains.annotations.Nullable;
2933
import org.slf4j.Logger;
3034

31-
import java.util.BitSet;
32-
3335
public class ViaMulticonnectTranslator implements IMulticonnectTranslator {
3436
private static final Logger LOGGER = LogUtils.getLogger();
3537
private static final AttributeKey<UserConnection> VIA_USER_CONNECTION_KEY = AttributeKey.valueOf("multiconnect.via_user_connection");
@@ -92,42 +94,43 @@ public void postPipelineModifiers(Channel channel) {
9294
}
9395
}
9496

95-
private static BitSet invertMappings(Mappings mappings) {
96-
BitSet result = new BitSet(mappings.mappedSize());
97+
private static Int2IntMap invertMappings(Mappings mappings) {
98+
Int2IntMap result = new Int2IntOpenHashMap(mappings.mappedSize());
9799
for (int oldId = 0; oldId < mappings.size(); oldId++) {
98100
int newId = mappings.getNewId(oldId);
99101
if (newId != -1) {
100-
result.set(newId);
102+
result.put(newId, oldId);
101103
}
102104
}
103105
return result;
104106
}
105107

106-
private static BitSet getInverseMappings(Channel channel, AttributeKey<BitSet> key, Mappings mappings) {
108+
private static Int2IntMap getInverseMappings(Channel channel, AttributeKey<Int2IntMap> key, Mappings mappings) {
107109
if (mappings == null) {
108110
return null;
109111
}
110112

111-
BitSet result = channel.attr(key).get();
113+
Int2IntMap result = channel.attr(key).get();
112114
if (result == null) {
113115
channel.attr(key).set(result = invertMappings(mappings));
114116
}
115117
return result;
116118
}
117119

118-
private static final AttributeKey<BitSet> INV_BLOCK_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invBlockMappings");
119-
private static final AttributeKey<BitSet> INV_ENTITY_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invEntityMappings");
120-
private static final AttributeKey<BitSet> INV_ENCHANTMENT_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invEnchantmentMappings");
121-
private static final AttributeKey<BitSet> INV_ARGUMENT_TYPE_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invArgumentTypeMappings");
122-
private static final AttributeKey<BitSet> INV_BLOCK_ENTITY_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invBlockEntityMappings");
123-
private static final AttributeKey<BitSet> INV_PAINTING_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invPaintingMappings");
124-
private static final AttributeKey<BitSet> INV_PARTICLE_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invParticleMappings");
125-
private static final AttributeKey<BitSet> INV_SOUND_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invSoundMappings");
126-
private static final AttributeKey<BitSet> INV_STATISTICS_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invStatisticsMappings");
120+
private static final AttributeKey<Int2IntMap> INV_BLOCK_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invBlockMappings");
121+
private static final AttributeKey<Int2IntMap> INV_ENTITY_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invEntityMappings");
122+
private static final AttributeKey<Int2IntMap> INV_ENCHANTMENT_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invEnchantmentMappings");
123+
private static final AttributeKey<Int2IntMap> INV_ARGUMENT_TYPE_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invArgumentTypeMappings");
124+
private static final AttributeKey<Int2IntMap> INV_BLOCK_ENTITY_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invBlockEntityMappings");
125+
private static final AttributeKey<Int2IntMap> INV_PAINTING_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invPaintingMappings");
126+
private static final AttributeKey<Int2IntMap> INV_PARTICLE_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invParticleMappings");
127+
private static final AttributeKey<Int2IntMap> INV_SOUND_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invSoundMappings");
128+
private static final AttributeKey<Int2IntMap> INV_STATISTICS_MAPPINGS_KEY = AttributeKey.valueOf("multiconnect.invStatisticsMappings");
127129

128130
@Override
129131
public boolean doesServerKnow(String registry, String entry) {
130132
int id = getRegistryId(registry, entry);
133+
if (registry.equals("minecraft:item") && id == 1) return true; // Stone *always* exists
131134

132135
Channel channel = api.getCurrentChannel();
133136
if (channel == null) {
@@ -137,36 +140,50 @@ public boolean doesServerKnow(String registry, String entry) {
137140
if (connection == null) {
138141
return true;
139142
}
140-
MappingData mappingData = connection.getProtocolInfo().getPipeline().getMappingData();
141-
if (mappingData == null) {
142-
return true;
143-
}
143+
for (final var protocol : connection.getProtocolInfo().getPipeline().pipes()) {
144+
if (registry.equals("minecraft:item")) {
145+
final var itemRewriter = protocol.getItemRewriter();
146+
if (itemRewriter != null) {
147+
final Item newItem = itemRewriter.handleItemToServer(new DataItem(id, (byte)1, (short)0, null));
148+
if (newItem != null) {
149+
id = newItem.identifier();
150+
if (id == 1) return false;
151+
continue;
152+
}
153+
}
154+
}
144155

145-
return switch (registry) {
146-
case "minecraft:block" -> doesServerKnow(channel, INV_BLOCK_MAPPINGS_KEY, mappingData.getBlockMappings(), id);
147-
case "minecraft:item" -> mappingData.getOldItemId(id) != -1;
148-
case "minecraft:entity_type" -> doesServerKnow(channel, INV_ENTITY_MAPPINGS_KEY, mappingData.getEntityMappings(), id);
149-
case "minecraft:enchantment" -> doesServerKnow(channel, INV_ENCHANTMENT_MAPPINGS_KEY, mappingData.getEnchantmentMappings(), id);
150-
case "minecraft:command_argument_type" -> doesServerKnow(channel, INV_ARGUMENT_TYPE_MAPPINGS_KEY, mappingData.getArgumentTypeMappings(), id);
151-
case "minecraft:block_entity_type" -> doesServerKnow(channel, INV_BLOCK_ENTITY_MAPPINGS_KEY, mappingData.getBlockEntityMappings(), id);
152-
case "minecraft:painting_variant" -> doesServerKnow(channel, INV_PAINTING_MAPPINGS_KEY, mappingData.getPaintingMappings(), id);
153-
case "minecraft:particle_type" -> doesServerKnow(channel, INV_PARTICLE_MAPPINGS_KEY, mappingData.getParticleMappings(), id);
154-
case "minecraft:sound_event" -> doesServerKnow(channel, INV_SOUND_MAPPINGS_KEY, mappingData.getSoundMappings(), id);
155-
case "minecraft:custom_stat" -> doesServerKnow(channel, INV_STATISTICS_MAPPINGS_KEY, mappingData.getStatisticsMappings(), id);
156-
default -> true;
157-
};
156+
MappingData mappingData = protocol.getMappingData();
157+
if (mappingData == null) continue;
158+
159+
id = switch (registry) {
160+
case "minecraft:block" -> getOldId(channel, INV_BLOCK_MAPPINGS_KEY, mappingData.getBlockMappings(), id);
161+
case "minecraft:item" -> mappingData.getOldItemId(id);
162+
case "minecraft:entity_type" -> getOldId(channel, INV_ENTITY_MAPPINGS_KEY, mappingData.getEntityMappings(), id);
163+
case "minecraft:enchantment" -> getOldId(channel, INV_ENCHANTMENT_MAPPINGS_KEY, mappingData.getEnchantmentMappings(), id);
164+
case "minecraft:command_argument_type" -> getOldId(channel, INV_ARGUMENT_TYPE_MAPPINGS_KEY, mappingData.getArgumentTypeMappings(), id);
165+
case "minecraft:block_entity_type" -> getOldId(channel, INV_BLOCK_ENTITY_MAPPINGS_KEY, mappingData.getBlockEntityMappings(), id);
166+
case "minecraft:painting_variant" -> getOldId(channel, INV_PAINTING_MAPPINGS_KEY, mappingData.getPaintingMappings(), id);
167+
case "minecraft:particle_type" -> getOldId(channel, INV_PARTICLE_MAPPINGS_KEY, mappingData.getParticleMappings(), id);
168+
case "minecraft:sound_event" -> getOldId(channel, INV_SOUND_MAPPINGS_KEY, mappingData.getSoundMappings(), id);
169+
case "minecraft:custom_stat" -> getOldId(channel, INV_STATISTICS_MAPPINGS_KEY, mappingData.getStatisticsMappings(), id);
170+
default -> id;
171+
};
172+
if (id == -1 || (registry.equals("minecraft:item") && id == 1)) return false;
173+
}
174+
return true;
158175
}
159176

160-
private static boolean doesServerKnow(Channel channel, AttributeKey<BitSet> key, @Nullable FullMappings mappings, int id) {
177+
private static int getOldId(Channel channel, AttributeKey<Int2IntMap> key, @Nullable FullMappings mappings, int id) {
161178
if (mappings == null) {
162-
return true;
179+
return id;
163180
}
164-
return doesServerKnow(channel, key, mappings.mappings(), id);
181+
return getOldId(channel, key, mappings.mappings(), id);
165182
}
166183

167-
private static boolean doesServerKnow(Channel channel, AttributeKey<BitSet> key, @Nullable Mappings mappings, int id) {
184+
private static int getOldId(Channel channel, AttributeKey<Int2IntMap> key, @Nullable Mappings mappings, int id) {
168185
if (mappings == null) {
169-
return true;
186+
return id;
170187
}
171188
return getInverseMappings(channel, key, mappings).get(id);
172189
}

0 commit comments

Comments
 (0)