This repository has been archived by the owner on Jan 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add search bar to the multiplayer server list
- Loading branch information
Showing
7 changed files
with
208 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 5 additions & 2 deletions
7
...lity/duck/PackListWidgetDuckProvider.java → ...hability/duck/ListWidgetDuckProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,20 @@ | ||
package net.onpointcoding.enhancedsearchability.duck; | ||
|
||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; | ||
import net.minecraft.client.gui.screen.pack.PackListWidget; | ||
import net.minecraft.text.Text; | ||
|
||
import java.util.List; | ||
import java.util.function.Supplier; | ||
|
||
public interface PackListWidgetDuckProvider { | ||
public interface ListWidgetDuckProvider { | ||
Text getHeaderText(); | ||
|
||
void filter(Supplier<String> searchTextSupplier); | ||
|
||
List<PackListWidget.ResourcePackEntry> getSyncStore(); | ||
List<PackListWidget.ResourcePackEntry> getSyncStoreRP(); | ||
|
||
List<MultiplayerServerListWidget.ServerEntry> getSyncStoreServer(); | ||
|
||
void hideHeaderAndShift(); | ||
} |
65 changes: 65 additions & 0 deletions
65
src/main/java/net/onpointcoding/enhancedsearchability/mixin/MixinMultiplayerScreen.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package net.onpointcoding.enhancedsearchability.mixin; | ||
|
||
import net.minecraft.client.MinecraftClient; | ||
import net.minecraft.client.gui.screen.Screen; | ||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; | ||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; | ||
import net.minecraft.client.gui.widget.ButtonWidget; | ||
import net.minecraft.client.gui.widget.TextFieldWidget; | ||
import net.minecraft.client.util.math.MatrixStack; | ||
import net.minecraft.text.Text; | ||
import net.minecraft.text.TranslatableText; | ||
import net.onpointcoding.enhancedsearchability.duck.ListWidgetDuckProvider; | ||
import net.onpointcoding.enhancedsearchability.utils.ClearableTextFieldDual; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
@Mixin(MultiplayerScreen.class) | ||
public class MixinMultiplayerScreen extends Screen { | ||
@Shadow | ||
protected MultiplayerServerListWidget serverListWidget; | ||
@Shadow | ||
private boolean initialized; | ||
private TextFieldWidget serverSearchBox; | ||
private ButtonWidget serverClearButton; | ||
|
||
protected MixinMultiplayerScreen(Text title) { | ||
super(title); | ||
} | ||
|
||
@Inject(method = "init", at = @At("TAIL")) | ||
private void injected_init(CallbackInfo ci) { | ||
MinecraftClient mc = MinecraftClient.getInstance(); | ||
ClearableTextFieldDual a = addSearchBox(mc, this.serverListWidget, this.serverSearchBox); | ||
this.serverSearchBox = a.getTextFieldWidget(); | ||
this.serverClearButton = a.getClearButton(); | ||
|
||
if (this.initialized) | ||
setupOriginalServerListOffset(this.serverListWidget); | ||
} | ||
|
||
void setupOriginalServerListOffset(MultiplayerServerListWidget multiplayerServerListWidget) { | ||
if (multiplayerServerListWidget instanceof ListWidgetDuckProvider duck) | ||
duck.hideHeaderAndShift(); | ||
} | ||
|
||
ClearableTextFieldDual addSearchBox(MinecraftClient mc, MultiplayerServerListWidget serverListWidget, TextFieldWidget textFieldWidget) { | ||
textFieldWidget = new TextFieldWidget(mc.textRenderer, serverListWidget.getRowLeft() - 1, 34, serverListWidget.getRowWidth() - 22, 18, textFieldWidget, new TranslatableText("enhancedsearchability.searchbox")); | ||
textFieldWidget.setChangedListener((search) -> { | ||
if (serverListWidget instanceof ListWidgetDuckProvider duckProvider) | ||
duckProvider.filter(() -> search); | ||
}); | ||
this.addSelectableChild(textFieldWidget); | ||
TextFieldWidget finalTextFieldWidget = textFieldWidget; | ||
ButtonWidget clearButton = this.addDrawableChild(new ButtonWidget(serverListWidget.getRowLeft() + serverListWidget.getRowWidth() - 22, 33, 20, 20, new TranslatableText("enhancedsearchability.clearbutton"), buttonWidget -> finalTextFieldWidget.setText(""))); | ||
return new ClearableTextFieldDual(textFieldWidget, clearButton); | ||
} | ||
|
||
@Inject(method = "render", at = @At("TAIL")) | ||
private void injected_render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { | ||
this.serverSearchBox.render(matrices, mouseX, mouseY, delta); | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
.../java/net/onpointcoding/enhancedsearchability/mixin/MixinMultiplayerServerListWidget.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package net.onpointcoding.enhancedsearchability.mixin; | ||
|
||
import net.minecraft.client.MinecraftClient; | ||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; | ||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget; | ||
import net.minecraft.client.gui.screen.pack.PackListWidget; | ||
import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; | ||
import net.minecraft.text.Text; | ||
import net.onpointcoding.enhancedsearchability.duck.ListWidgetDuckProvider; | ||
import org.objectweb.asm.Opcodes; | ||
import org.spongepowered.asm.mixin.Final; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.Redirect; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Locale; | ||
import java.util.function.Supplier; | ||
import java.util.stream.Stream; | ||
|
||
@Mixin(MultiplayerServerListWidget.class) | ||
public class MixinMultiplayerServerListWidget extends AlwaysSelectedEntryListWidget<MultiplayerServerListWidget.Entry> implements ListWidgetDuckProvider { | ||
@Shadow | ||
@Final | ||
private MultiplayerScreen screen; | ||
@Shadow | ||
@Final | ||
private List<MultiplayerServerListWidget.LanServerEntry> lanServers; | ||
@Shadow | ||
@Final | ||
private MultiplayerServerListWidget.Entry scanningEntry; | ||
private final List<MultiplayerServerListWidget.ServerEntry> serverSyncStore = new ArrayList<>(); | ||
private final List<MultiplayerServerListWidget.LanServerEntry> lanServerSyncStore = new ArrayList<>(); | ||
private Supplier<String> searchTextStore = () -> ""; | ||
|
||
public MixinMultiplayerServerListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l, int m) { | ||
super(minecraftClient, i, j, k, l, m); | ||
} | ||
|
||
@Override | ||
public Text getHeaderText() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void filter(Supplier<String> searchTextSupplier) { | ||
searchTextStore = searchTextSupplier; | ||
customAddServerStreamToUI(this.serverSyncStore.stream(), this.lanServerSyncStore.stream(), searchTextStore); | ||
} | ||
|
||
@Inject(method = "updateEntries", at = @At("TAIL")) | ||
private void injected_updateEntries(CallbackInfo ci) { | ||
customAddServerStreamToUI(this.serverSyncStore.stream(), this.lanServerSyncStore.stream(), searchTextStore); | ||
} | ||
|
||
@Redirect(method = "setServers", at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerServerListWidget;servers:Ljava/util/List;", opcode = Opcodes.GETFIELD)) | ||
private List<MultiplayerServerListWidget.ServerEntry> redirectServersList(MultiplayerServerListWidget instance) { | ||
return serverSyncStore; | ||
} | ||
|
||
@Redirect(method = "setLanServers", at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerServerListWidget;lanServers:Ljava/util/List;", opcode = Opcodes.GETFIELD)) | ||
private List<MultiplayerServerListWidget.LanServerEntry> redirectLanServersList(MultiplayerServerListWidget instance) { | ||
return lanServerSyncStore; | ||
} | ||
|
||
private void customAddServerStreamToUI(Stream<MultiplayerServerListWidget.ServerEntry> serverStream, Stream<MultiplayerServerListWidget.LanServerEntry> lanServerStream, Supplier<String> searchTextSupplier) { | ||
String s = searchTextSupplier.get().toLowerCase(Locale.ROOT); | ||
boolean isEmpty = s.equals(""); | ||
|
||
this.children().clear(); | ||
serverStream.forEach(serverEntry -> { | ||
if (isEmpty || serverEntry.getServer().name.toLowerCase(Locale.ROOT).contains(s)) | ||
this.children().add(serverEntry); | ||
}); | ||
this.children().add(this.scanningEntry); | ||
lanServerStream.forEach(lanServerEntry -> { | ||
if (isEmpty || isMatchingLanServer(lanServerEntry, s)) | ||
this.children().add(lanServerEntry); | ||
}); | ||
} | ||
|
||
private boolean isMatchingLanServer(MultiplayerServerListWidget.LanServerEntry lanServerEntry, String s) { | ||
return lanServerEntry.getLanServerEntry().getAddressPort().toLowerCase(Locale.ROOT).contains(s) | ||
|| lanServerEntry.getLanServerEntry().getMotd().toLowerCase(Locale.ROOT).contains(s); | ||
} | ||
|
||
@Override | ||
public List<PackListWidget.ResourcePackEntry> getSyncStoreRP() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public List<MultiplayerServerListWidget.ServerEntry> getSyncStoreServer() { | ||
return serverSyncStore; | ||
} | ||
|
||
@Override | ||
public void hideHeaderAndShift() { | ||
this.top += 25; | ||
} | ||
|
||
@Override | ||
public double getScrollAmount() { | ||
double v = super.getScrollAmount(); | ||
int m = getMaxScroll(); | ||
return v > m ? m : v; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters