From 3945675c04c4ebb2e924a3148febd695410e5466 Mon Sep 17 00:00:00 2001 From: IuCC123 Date: Thu, 12 Mar 2026 22:40:07 +0100 Subject: [PATCH 1/2] Add Fabric 1.21.11 support --- gradle.properties | 6 ++--- .../item/SongItemConfirmationScreen.java | 22 +++++++++++-------- src/main/resources/fabric.mod.json | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5848cc3..8d3bb89 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,8 +6,8 @@ org.gradle.parallel=true org.gradle.configuration-cache=false # Fabric Properties - minecraft_version=1.21.9 - yarn_mappings=1.21.9+build.1 + minecraft_version=1.21.11 + yarn_mappings=1.21.11+build.3 loader_version=0.18.4 loom_version=1.14-SNAPSHOT @@ -17,4 +17,4 @@ org.gradle.configuration-cache=false archives_base_name = song-player # Dependencies - fabric_version=0.134.1+1.21.9 + fabric_version=0.139.5+1.21.11 diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java index 2d336bf..676784f 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java @@ -2,7 +2,6 @@ import com.github.hhhzzzsss.songplayer.Util; import com.github.hhhzzzsss.songplayer.playing.SongHandler; -import net.minecraft.client.font.MultilineText; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.ButtonWidget; @@ -15,8 +14,8 @@ public class SongItemConfirmationScreen extends Screen { private ItemStack stack; private SongItemLoaderThread loaderThread; - private MultilineText unloadedText; - private MultilineText loadedText; + private Text[] unloadedText; + private Text[] loadedText; private boolean loaded = false; private static final Text CONFIRM = Text.literal("Play"); @@ -33,7 +32,7 @@ public SongItemConfirmationScreen(ItemStack stack) throws IOException, IllegalAr protected void init() { super.init(); String unloadedMessage = "§7Loading song..."; - this.unloadedText = MultilineText.create(this.textRenderer, Text.literal(unloadedMessage)); + this.unloadedText = new Text[] {Text.literal(unloadedMessage)}; } private void addButtons(int y) { @@ -67,10 +66,9 @@ else if (loadedText == null) { String.format("§7Max notes per second: %s%d", getNumberColor(loaderThread.maxNotesPerSecond), loaderThread.maxNotesPerSecond), String.format("§7Avg notes per second: %s%.2f", getNumberColor(loaderThread.avgNotesPerSecond), loaderThread.avgNotesPerSecond), }; - Text[] messageList = Arrays.stream(loadedMessages).map(Text::literal).toArray(Text[]::new); - this.loadedText = MultilineText.create(this.textRenderer, messageList); + this.loadedText = Arrays.stream(loadedMessages).map(Text::literal).toArray(Text[]::new); - int loadedTextHeight = this.loadedText.getLineCount() * this.textRenderer.fontHeight; + int loadedTextHeight = this.loadedText.length * this.textRenderer.fontHeight; addButtons(60 + loadedTextHeight + 12); loaded = true; @@ -78,10 +76,16 @@ else if (loadedText == null) { } if (loaded) { - loadedText.draw(context, MultilineText.Alignment.CENTER, this.width / 2, 60, 9, true, -1); + drawCenteredLines(context, loadedText, 60, 9, 0xFFFFFF); } else { - unloadedText.draw(context, MultilineText.Alignment.CENTER, this.width / 2, 60, 9, true, -1); + drawCenteredLines(context, unloadedText, 60, 9, 0xFFFFFF); + } + } + + private void drawCenteredLines(DrawContext context, Text[] lines, int startY, int lineHeight, int color) { + for (int i = 0; i < lines.length; i++) { + context.drawCenteredTextWithShadow(textRenderer, lines[i], this.width / 2, startY + i * lineHeight, color); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f57d270..d8996aa 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,7 +28,7 @@ "depends": { "fabricloader": ">=0.18.0", "fabric": "*", - "minecraft": "~1.21.9", + "minecraft": "~1.21.11", "java": ">=21" }, "suggests": { From f306c40f6f5d8cf122ec050117cd086ce216a6cf Mon Sep 17 00:00:00 2001 From: IuCC123 Date: Fri, 3 Apr 2026 01:06:53 +0200 Subject: [PATCH 2/2] Add Fabric 26.1 support --- build.gradle | 15 +- gradle.properties | 9 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../songplayer/CommandProcessor.java | 67 ++--- .../github/hhhzzzsss/songplayer/Config.java | 2 +- .../songplayer/FakePlayerEntity.java | 67 +++-- .../hhhzzzsss/songplayer/SongPlayer.java | 11 +- .../com/github/hhhzzzsss/songplayer/Util.java | 63 +++-- .../item/SongItemConfirmationScreen.java | 51 ++-- .../item/SongItemCreatorThread.java | 29 ++- .../songplayer/item/SongItemLoaderThread.java | 7 +- .../songplayer/item/SongItemUtils.java | 37 ++- .../mixin/ChatInputSuggestorMixin.java | 24 +- .../ClientCommonNetworkHandlerMixin.java | 40 +-- .../ClientPlayNetworkHandlerAccessor.java | 10 +- .../mixin/ClientPlayNetworkHandlerMixin.java | 83 ++++--- .../mixin/ClientPlayerEntityMixin.java | 6 +- ...lientPlayerInteractionManagerAccessor.java | 6 +- .../songplayer/mixin/ClientWorldMixin.java | 12 +- .../songplayer/mixin/InGameHudMixin.java | 15 +- .../mixin/MinecraftClientMixin.java | 56 ++--- .../songplayer/mixin/PlayerEntityMixin.java | 12 +- .../songplayer/playing/ProgressDisplay.java | 33 ++- .../songplayer/playing/SongHandler.java | 228 +++++++++--------- .../hhhzzzsss/songplayer/playing/Stage.java | 55 +++-- src/main/resources/fabric.mod.json | 6 +- 26 files changed, 474 insertions(+), 472 deletions(-) diff --git a/build.gradle b/build.gradle index 6058390..73278a2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'net.fabricmc.fabric-loom-remap' version "${loom_version}" + id 'net.fabricmc.fabric-loom' version "${loom_version}" id 'maven-publish' } @@ -21,11 +21,10 @@ repositories { dependencies { // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + implementation "net.fabricmc:fabric-loader:${project.loader_version}" // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" } @@ -38,7 +37,7 @@ processResources { } tasks.withType(JavaCompile).configureEach { - it.options.release = 21 + it.options.release = 25 } java { @@ -47,8 +46,8 @@ java { // If you remove this line, sources will not be generated. withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_25 + targetCompatibility = JavaVersion.VERSION_25 } jar { @@ -73,4 +72,4 @@ publishing { // The repositories here will be used for publishing your artifact, not for // retrieving dependencies. } -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index 8d3bb89..200f6d5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,10 +6,9 @@ org.gradle.parallel=true org.gradle.configuration-cache=false # Fabric Properties - minecraft_version=1.21.11 - yarn_mappings=1.21.11+build.3 - loader_version=0.18.4 - loom_version=1.14-SNAPSHOT + minecraft_version=26.1 + loader_version=0.18.5 + loom_version=1.15-SNAPSHOT # Mod Properties mod_version = 3.3.5 @@ -17,4 +16,4 @@ org.gradle.configuration-cache=false archives_base_name = song-player # Dependencies - fabric_version=0.139.5+1.21.11 + fabric_version=0.143.12+26.1 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 23449a2..dbc3ce4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java b/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java index 76091c0..76555b7 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/CommandProcessor.java @@ -9,13 +9,16 @@ import com.github.hhhzzzsss.songplayer.song.Song; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.command.CommandSource; -import net.minecraft.item.ItemStack; -import net.minecraft.text.*; -import net.minecraft.util.Formatting; -import net.minecraft.util.Hand; -import net.minecraft.world.GameMode; - +import net.minecraft.ChatFormatting; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.GameType; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -169,7 +172,7 @@ else if (c.getSyntax().length == 1) { return true; } public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { - return CommandSource.suggestMatching(commandCompletions, suggestionsBuilder); + return SharedSuggestionProvider.suggest(commandCompletions, suggestionsBuilder); } } @@ -219,7 +222,7 @@ public String getDescription() { } public boolean processCommand(String args) { if (args.length() > 0) { - if (Config.getConfig().survivalOnly && SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.SURVIVAL) { + if (Config.getConfig().survivalOnly && SongPlayer.MC.gameMode.getPlayerMode() != GameType.SURVIVAL) { Util.showChatMessage("§cTo play in survival only mode, you must be in survival mode to start with."); return true; } @@ -646,7 +649,7 @@ public boolean processCommand(String args) { public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { String[] split = args.split(" ", -1); if (split.length <= 1) { - return CommandSource.suggestMatching(new String[]{ + return SharedSuggestionProvider.suggest(new String[]{ "play", "create", "delete", @@ -691,7 +694,7 @@ public CompletableFuture getSuggestions(String args, SuggestionsBui if (playlistFiles == null) { return null; } - return CommandSource.suggestMatching( + return SharedSuggestionProvider.suggest( playlistFiles.map(Path::getFileName) .map(Path::toString), suggestionsBuilder); @@ -709,7 +712,7 @@ public CompletableFuture getSuggestions(String args, SuggestionsBui } int max = playlistFiles.collect(Collectors.toList()).size(); Stream suggestions = IntStream.range(1, max+1).mapToObj(Integer::toString); - return CommandSource.suggestMatching(suggestions, suggestionsBuilder); + return SharedSuggestionProvider.suggest(suggestions, suggestionsBuilder); } return null; } @@ -894,7 +897,7 @@ public boolean processCommand(String args) { } public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { if (!args.contains(" ")) { - return CommandSource.suggestMatching(Arrays.stream(Stage.StageType.values()).map(Stage.StageType::name), suggestionsBuilder); + return SharedSuggestionProvider.suggest(Arrays.stream(Stage.StageType.values()).map(Stage.StageType::name), suggestionsBuilder); } else { return null; @@ -952,7 +955,7 @@ public boolean processCommand(String args) { public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { String[] split = args.split(" ", -1); if (split.length <= 1) { - return CommandSource.suggestMatching(new String[]{ + return SharedSuggestionProvider.suggest(new String[]{ "set", "reset", }, suggestionsBuilder); @@ -1012,7 +1015,7 @@ public boolean processCommand(String args) { public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { String[] split = args.split(" ", -1); if (split.length <= 1) { - return CommandSource.suggestMatching(new String[]{ + return SharedSuggestionProvider.suggest(new String[]{ "set", "reset", }, suggestionsBuilder); @@ -1063,7 +1066,7 @@ public boolean processCommand(String args) { } public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { if (!args.contains(" ")) { - return CommandSource.suggestMatching(new String[]{"swing", "rotate"}, suggestionsBuilder); + return SharedSuggestionProvider.suggest(new String[]{"swing", "rotate"}, suggestionsBuilder); } else { return null; @@ -1160,23 +1163,23 @@ public boolean processCommand(String args) { Util.showChatMessage("§6There is nothing to clean up"); return true; } - if (MC.player.getEntityPos().squaredDistanceTo(lastStage.getOriginBottomCenter()) > 3*3 || !lastStage.worldName.equals(Util.getWorldName())) { + if (MC.player.position().distanceToSqr(lastStage.getOriginBottomCenter()) > 3*3 || !lastStage.worldName.equals(Util.getWorldName())) { String coordStr = String.format( "%d %d %d", lastStage.position.getX(), lastStage.position.getY(), lastStage.position.getZ() ); Util.showChatMessage("§6You must be within §33 §6blocks of the center of your stage to start cleanup."); - MutableText coordText = Util.joinTexts(null, - Text.literal("This is at ").setStyle(Style.EMPTY.withColor(Formatting.GOLD)), - Text.literal(coordStr).setStyle( + MutableComponent coordText = Util.joinTexts(null, + Component.literal("This is at ").setStyle(Style.EMPTY.withColor(ChatFormatting.GOLD)), + Component.literal(coordStr).setStyle( Style.EMPTY - .withColor(Formatting.DARK_AQUA) - .withUnderline(true) + .withColor(ChatFormatting.DARK_AQUA) + .withUnderlined(true) .withClickEvent(new ClickEvent.CopyToClipboard(coordStr)) - .withHoverEvent(new HoverEvent.ShowText(Text.literal("Copy \"" + coordStr + "\""))) + .withHoverEvent(new HoverEvent.ShowText(Component.literal("Copy \"" + coordStr + "\""))) ), - Text.literal(" in world ").setStyle(Style.EMPTY.withColor(Formatting.GOLD)), - Text.literal(lastStage.worldName).setStyle(Style.EMPTY.withColor(Formatting.DARK_AQUA)) + Component.literal(" in world ").setStyle(Style.EMPTY.withColor(ChatFormatting.GOLD)), + Component.literal(lastStage.worldName).setStyle(Style.EMPTY.withColor(ChatFormatting.DARK_AQUA)) ); Util.showChatMessage(coordText); return true; @@ -1237,7 +1240,7 @@ public boolean processCommand(String args) { } public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { if (!args.contains(" ")) { - return CommandSource.suggestMatching(new String[]{"enable", "disable", "getMessage", "setMessage"}, suggestionsBuilder); + return SharedSuggestionProvider.suggest(new String[]{"enable", "disable", "getMessage", "setMessage"}, suggestionsBuilder); } else { return null; @@ -1333,12 +1336,12 @@ public boolean processCommand(String args) { return false; } - if (MC.interactionManager.getCurrentGameMode() != GameMode.CREATIVE) { + if (MC.gameMode.getPlayerMode() != GameType.CREATIVE) { Util.showChatMessage("§cYou must be in creative mode to use this command"); return true; } - ItemStack stack = MC.player.getMainHandStack(); + ItemStack stack = MC.player.getMainHandItem(); String[] split = args.split(" "); switch (split[0].toLowerCase(Locale.ROOT)) { @@ -1358,8 +1361,8 @@ public boolean processCommand(String args) { String name = String.join(" ", Arrays.copyOfRange(split, 1, split.length)); SongItemUtils.updateSongItemTag(stack, (songItemTag) -> songItemTag.putString(SongItemUtils.DISPLAY_NAME_KEY, name)); SongItemUtils.addSongItemDisplay(stack); - MC.player.setStackInHand(Hand.MAIN_HAND, stack); - MC.interactionManager.clickCreativeStack(MC.player.getStackInHand(Hand.MAIN_HAND), 36 + MC.player.getInventory().getSelectedSlot()); + MC.player.setItemInHand(InteractionHand.MAIN_HAND, stack); + MC.gameMode.handleCreativeModeItemAdd(MC.player.getItemInHand(InteractionHand.MAIN_HAND), 36 + MC.player.getInventory().getSelectedSlot()); Util.showChatMessage("§6Set song display name to §3" + name); return true; } else { @@ -1373,7 +1376,7 @@ public boolean processCommand(String args) { public CompletableFuture getSuggestions(String args, SuggestionsBuilder suggestionsBuilder) { String[] split = args.split(" ", -1); if (split.length <= 1) { - return CommandSource.suggestMatching(new String[]{ + return SharedSuggestionProvider.suggest(new String[]{ "create", "setSongName", }, suggestionsBuilder); @@ -1423,7 +1426,7 @@ public static CompletableFuture handleSuggestions(String text, Sugg .stream() .map((commandName) -> Config.getConfig().prefix+commandName) .collect(Collectors.toList()); - return CommandSource.suggestMatching(names, suggestionsBuilder); + return SharedSuggestionProvider.suggest(names, suggestionsBuilder); } else { String[] split = text.split(" ", 2); if (split[0].startsWith(Config.getConfig().prefix)) { diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/Config.java b/src/main/java/com/github/hhhzzzsss/songplayer/Config.java index c9c4dfe..3ab7248 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/Config.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/Config.java @@ -68,7 +68,7 @@ public static void saveConfigWithErrorHandling() { Config.saveConfig(); } catch (IOException e) { - if (SongPlayer.MC.world != null) { + if (SongPlayer.MC.level != null) { Util.showChatMessage("§cFailed to save config file"); } e.printStackTrace(); diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/FakePlayerEntity.java b/src/main/java/com/github/hhhzzzsss/songplayer/FakePlayerEntity.java index d2427f9..bc8ac95 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/FakePlayerEntity.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/FakePlayerEntity.java @@ -5,37 +5,36 @@ import com.github.hhhzzzsss.songplayer.playing.Stage; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.PropertyMap; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.network.OtherClientPlayerEntity; -import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.EntityPose; -import net.minecraft.entity.player.PlayerEntity; - import java.util.UUID; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.multiplayer.PlayerInfo; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.player.RemotePlayer; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.player.Player; -public class FakePlayerEntity extends OtherClientPlayerEntity { +public class FakePlayerEntity extends RemotePlayer { public static final UUID FAKE_PLAYER_UUID = UUID.randomUUID(); - ClientPlayerEntity player = SongPlayer.MC.player; - ClientWorld world = SongPlayer.MC.world; + LocalPlayer player = SongPlayer.MC.player; + ClientLevel world = SongPlayer.MC.level; public FakePlayerEntity() { - super(SongPlayer.MC.world, getProfile()); + super(SongPlayer.MC.level, createProfile()); copyStagePosAndPlayerLook(); - getInventory().clone(player.getInventory()); + getInventory().replaceWith(player.getInventory()); - Byte playerModel = player.getDataTracker().get(PlayerEntity.PLAYER_MODE_CUSTOMIZATION_ID); - getDataTracker().set(PlayerEntity.PLAYER_MODE_CUSTOMIZATION_ID, playerModel); + Byte playerModel = player.getEntityData().get(Player.DATA_PLAYER_MODE_CUSTOMISATION); + getEntityData().set(Player.DATA_PLAYER_MODE_CUSTOMISATION, playerModel); - headYaw = player.headYaw; - bodyYaw = player.bodyYaw; + yHeadRot = player.yHeadRot; + yBodyRot = player.yBodyRot; - if (player.isSneaking()) { - setSneaking(true); - setPose(EntityPose.CROUCHING); + if (player.isShiftKeyDown()) { + setShiftKeyDown(true); + setPose(Pose.CROUCHING); } // capeX = getX(); @@ -46,28 +45,28 @@ public FakePlayerEntity() { } public void resetPlayerPosition() { - player.refreshPositionAndAngles(getX(), getY(), getZ(), getYaw(), getPitch()); + player.snapTo(getX(), getY(), getZ(), getYRot(), getXRot()); } public void copyStagePosAndPlayerLook() { Stage lastStage = SongHandler.getInstance().lastStage; if (lastStage != null) { - refreshPositionAndAngles(lastStage.position.getX()+0.5, lastStage.position.getY(), lastStage.position.getZ()+0.5, player.getYaw(), player.getPitch()); - headYaw = player.headYaw; + snapTo(lastStage.position.getX()+0.5, lastStage.position.getY(), lastStage.position.getZ()+0.5, player.getYRot(), player.getXRot()); + yHeadRot = player.yHeadRot; } else { - copyPositionAndRotation(player); + copyPosition(player); } } - private static GameProfile getProfile() { - GameProfile profile = new GameProfile( - FAKE_PLAYER_UUID, - SongPlayer.MC.player.getGameProfile().name(), - SongPlayer.MC.getGameProfile().properties() - ); - PlayerListEntry playerListEntry = new PlayerListEntry(SongPlayer.MC.player.getGameProfile(), false); - ((ClientPlayNetworkHandlerAccessor)SongPlayer.MC.getNetworkHandler()).getPlayerListEntries().put(FAKE_PLAYER_UUID, playerListEntry); - return profile; - } -} + private static GameProfile createProfile() { + GameProfile profile = new GameProfile( + FAKE_PLAYER_UUID, + SongPlayer.MC.player.getGameProfile().name(), + SongPlayer.MC.getGameProfile().properties() + ); + PlayerInfo playerListEntry = new PlayerInfo(SongPlayer.MC.player.getGameProfile(), false); + ((ClientPlayNetworkHandlerAccessor)SongPlayer.MC.getConnection()).getSeenPlayersMap().put(FAKE_PLAYER_UUID, playerListEntry); + return profile; + } +} diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/SongPlayer.java b/src/main/java/com/github/hhhzzzsss/songplayer/SongPlayer.java index da1cf10..15f2e27 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/SongPlayer.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/SongPlayer.java @@ -1,16 +1,15 @@ package com.github.hhhzzzsss.songplayer; import net.fabricmc.api.ModInitializer; -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.client.MinecraftClient; - +import net.minecraft.client.Minecraft; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import java.nio.file.Files; import java.nio.file.Path; public class SongPlayer implements ModInitializer { - public static final MinecraftClient MC = MinecraftClient.getInstance(); - public static final int NOTEBLOCK_BASE_ID = Block.getRawIdFromState(Blocks.NOTE_BLOCK.getDefaultState())-1; + public static final Minecraft MC = Minecraft.getInstance(); + public static final int NOTEBLOCK_BASE_ID = Block.getId(Blocks.NOTE_BLOCK.defaultBlockState())-1; public static final Path SONG_DIR = Path.of("songs"); public static final Path SONGPLAYER_DIR = Path.of("SongPlayer"); diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/Util.java b/src/main/java/com/github/hhhzzzsss/songplayer/Util.java index 221e97c..77a2cba 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/Util.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/Util.java @@ -2,17 +2,6 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.client.MinecraftClient; -import net.minecraft.command.CommandSource; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.LoreComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.text.MutableText; -import net.minecraft.text.PlainTextContent; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.WorldSavePath; - import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; @@ -25,9 +14,19 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import net.minecraft.client.Minecraft; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.contents.PlainTextContents; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ItemLore; +import net.minecraft.world.level.storage.LevelResource; public class Util { - static final MinecraftClient MC = MinecraftClient.getInstance(); + static final Minecraft MC = Minecraft.getInstance(); // IO @@ -168,13 +167,13 @@ else if (Files.isDirectory(path)) { Stream suggestions = suggestionsList.stream() .filter(str -> str.startsWith(arg)) .map(str -> str.substring(clipStart)); - return CommandSource.suggestMatching(suggestions, suggestionsBuilder); + return SharedSuggestionProvider.suggest(suggestions, suggestionsBuilder); } public static CompletableFuture givePlaylistSuggestions(SuggestionsBuilder suggestionsBuilder) { if (!Files.exists(SongPlayer.PLAYLISTS_DIR)) return null; try { - return CommandSource.suggestMatching( + return SharedSuggestionProvider.suggest( Files.list(SongPlayer.PLAYLISTS_DIR) .filter(Files::isDirectory) .map(Path::getFileName) @@ -222,30 +221,30 @@ public static CompletableFuture giveSongDirectorySuggestions(String .map(path -> dirString + path.getFileName().toString() + "/") .filter(str -> str.startsWith(arg)) .map(str -> str.substring(clipStart)); - return CommandSource.suggestMatching(suggestions, suggestionsBuilder); + return SharedSuggestionProvider.suggest(suggestions, suggestionsBuilder); } // Text - public static MutableText getStyledText(String str, Style style) { - MutableText text = MutableText.of(PlainTextContent.of(str)); + public static MutableComponent getStyledText(String str, Style style) { + MutableComponent text = MutableComponent.create(PlainTextContents.create(str)); text.setStyle(style); return text; } - public static void setItemName(ItemStack stack, Text text) { - stack.set(DataComponentTypes.CUSTOM_NAME, text); + public static void setItemName(ItemStack stack, Component text) { + stack.set(DataComponents.CUSTOM_NAME, text); } - public static void setItemLore(ItemStack stack, Text... loreLines) { - stack.set(DataComponentTypes.LORE, new LoreComponent(List.of(loreLines))); + public static void setItemLore(ItemStack stack, Component... loreLines) { + stack.set(DataComponents.LORE, new ItemLore(List.of(loreLines))); } - public static MutableText joinTexts(MutableText base, Text... children) { + public static MutableComponent joinTexts(MutableComponent base, Component... children) { if (base == null) { - base = Text.empty(); + base = Component.empty(); } - for (Text child : children) { + for (Component child : children) { base.append(child); } return base; @@ -254,28 +253,28 @@ public static MutableText joinTexts(MutableText base, Text... children) { // Server and World public static String getWorldName() { - return MC.world.getRegistryKey().getValue().toString(); + return MC.level.dimension().identifier().toString(); } public static String getServerIdentifier() { - if (MC.isInSingleplayer()) return "local;" + MC.getServer().getSavePath(WorldSavePath.ROOT).getParent().getFileName().toString(); - else return "remote;" + MC.getCurrentServerEntry().address; + if (MC.isLocalServer()) return "local;" + MC.getSingleplayerServer().getWorldPath(LevelResource.ROOT).getParent().getFileName().toString(); + else return "remote;" + MC.getCurrentServer().ip; } // Chat public static void showChatMessage(String message) { - MC.player.sendMessage(Text.of(message), false); + MC.player.sendSystemMessage(Component.nullToEmpty(message)); } - public static void showChatMessage(Text text) { - MC.player.sendMessage(text, false); + public static void showChatMessage(Component text) { + MC.player.sendSystemMessage(text); } public static void sendChatMessage(String message) { - MC.player.networkHandler.sendChatMessage(message); + MC.player.connection.sendChat(message); } public static void sendCommand(String command) { - MC.player.networkHandler.sendChatCommand(command); + MC.player.connection.sendCommand(command); } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java index 676784f..3ce4769 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemConfirmationScreen.java @@ -2,27 +2,26 @@ import com.github.hhhzzzsss.songplayer.Util; import com.github.hhhzzzsss.songplayer.playing.SongHandler; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; - import java.io.IOException; import java.util.Arrays; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; public class SongItemConfirmationScreen extends Screen { private ItemStack stack; private SongItemLoaderThread loaderThread; - private Text[] unloadedText; - private Text[] loadedText; + private Component[] unloadedText; + private Component[] loadedText; private boolean loaded = false; - private static final Text CONFIRM = Text.literal("Play"); - private static final Text CANCEL = Text.literal("Cancel"); + private static final Component CONFIRM = Component.literal("Play"); + private static final Component CANCEL = Component.literal("Cancel"); public SongItemConfirmationScreen(ItemStack stack) throws IOException, IllegalArgumentException { - super(Text.literal("Use song item")); + super(Component.literal("Use song item")); this.stack = stack; this.loaderThread = new SongItemLoaderThread(stack); this.loaderThread.start(); @@ -32,32 +31,32 @@ public SongItemConfirmationScreen(ItemStack stack) throws IOException, IllegalAr protected void init() { super.init(); String unloadedMessage = "§7Loading song..."; - this.unloadedText = new Text[] {Text.literal(unloadedMessage)}; + this.unloadedText = new Component[] {Component.literal(unloadedMessage)}; } private void addButtons(int y) { int centerX = this.width / 2; - this.addDrawableChild(ButtonWidget.builder(CONFIRM, button -> { + this.addRenderableWidget(Button.builder(CONFIRM, button -> { SongHandler.getInstance().loadSong(loaderThread); - this.client.setScreen(null); - }).dimensions(centerX - 105, y, 100, 20).build()); + this.minecraft.setScreen(null); + }).bounds(centerX - 105, y, 100, 20).build()); - this.addDrawableChild(ButtonWidget.builder(CANCEL, button -> { - this.client.setScreen(null); - }).dimensions(centerX + 5, y, 100, 20).build()); + this.addRenderableWidget(Button.builder(CANCEL, button -> { + this.minecraft.setScreen(null); + }).bounds(centerX + 5, y, 100, 20).build()); } @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - super.render(context, mouseX, mouseY, delta); + public void extractRenderState(GuiGraphicsExtractor context, int mouseX, int mouseY, float delta) { + super.extractRenderState(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(textRenderer, this.title, this.width / 2, 40, 0xFFFFFF); + context.centeredText(font, this.title, this.width / 2, 40, 0xFFFFFF); if (!loaderThread.isAlive()) { if (loaderThread.exception != null) { Util.showChatMessage("§cError loading song item: §4" + loaderThread.exception.getMessage()); - this.client.setScreen(null); + this.minecraft.setScreen(null); return; } else if (loadedText == null) { @@ -66,9 +65,9 @@ else if (loadedText == null) { String.format("§7Max notes per second: %s%d", getNumberColor(loaderThread.maxNotesPerSecond), loaderThread.maxNotesPerSecond), String.format("§7Avg notes per second: %s%.2f", getNumberColor(loaderThread.avgNotesPerSecond), loaderThread.avgNotesPerSecond), }; - this.loadedText = Arrays.stream(loadedMessages).map(Text::literal).toArray(Text[]::new); + this.loadedText = Arrays.stream(loadedMessages).map(Component::literal).toArray(Component[]::new); - int loadedTextHeight = this.loadedText.length * this.textRenderer.fontHeight; + int loadedTextHeight = this.loadedText.length * this.font.lineHeight; addButtons(60 + loadedTextHeight + 12); loaded = true; @@ -83,9 +82,9 @@ else if (loadedText == null) { } } - private void drawCenteredLines(DrawContext context, Text[] lines, int startY, int lineHeight, int color) { + private void drawCenteredLines(GuiGraphicsExtractor context, Component[] lines, int startY, int lineHeight, int color) { for (int i = 0; i < lines.length; i++) { - context.drawCenteredTextWithShadow(textRenderer, lines[i], this.width / 2, startY + i * lineHeight, color); + context.centeredText(font, lines[i], this.width / 2, startY + i * lineHeight, color); } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemCreatorThread.java b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemCreatorThread.java index af6a857..c4901ee 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemCreatorThread.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemCreatorThread.java @@ -4,15 +4,14 @@ import com.github.hhhzzzsss.songplayer.Util; import com.github.hhhzzzsss.songplayer.conversion.SPConverter; import com.github.hhhzzzsss.songplayer.song.SongLoaderThread; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.CustomModelDataComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.text.Text; -import net.minecraft.util.Hand; - import java.io.IOException; import java.util.List; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.CustomModelData; public class SongItemCreatorThread extends SongLoaderThread { public final int slotId; @@ -20,7 +19,7 @@ public class SongItemCreatorThread extends SongLoaderThread { public SongItemCreatorThread(String location) throws IOException { super(location); this.slotId = SongPlayer.MC.player.getInventory().getSelectedSlot(); - this.stack = SongPlayer.MC.player.getInventory().getStack(slotId); + this.stack = SongPlayer.MC.player.getInventory().getItem(slotId); } @Override @@ -34,25 +33,25 @@ public void run() { return; } SongPlayer.MC.execute(() -> { - if (SongPlayer.MC.world == null) { + if (SongPlayer.MC.level == null) { return; } - if (!SongPlayer.MC.player.getInventory().getStack(slotId).equals(stack)) { + if (!SongPlayer.MC.player.getInventory().getItem(slotId).equals(stack)) { Util.showChatMessage("§cCould not create song item because item has moved"); } ItemStack newStack; if (stack.isEmpty()) { - newStack = Items.PAPER.getDefaultStack(); + newStack = Items.PAPER.getDefaultInstance(); // When going from 1.21.3 -> 1.21.4, datafixer changes the custom model data to a float array with one element - newStack.set(DataComponentTypes.CUSTOM_MODEL_DATA, new CustomModelDataComponent(List.of(751642938f), List.of(), List.of(), List.of())); + newStack.set(DataComponents.CUSTOM_MODEL_DATA, new CustomModelData(List.of(751642938f), List.of(), List.of(), List.of())); } else { newStack = stack.copy(); } newStack = SongItemUtils.createSongItem(newStack, songData, filename, song.name); - SongPlayer.MC.player.getInventory().setStack(slotId, newStack); - SongPlayer.MC.interactionManager.clickCreativeStack(SongPlayer.MC.player.getStackInHand(Hand.MAIN_HAND), 36 + slotId); - Util.showChatMessage(Text.literal("§6Successfully assigned song data to §3").append(newStack.getItem().getName())); + SongPlayer.MC.player.getInventory().setItem(slotId, newStack); + SongPlayer.MC.gameMode.handleCreativeModeItemAdd(SongPlayer.MC.player.getItemInHand(InteractionHand.MAIN_HAND), 36 + slotId); + Util.showChatMessage(Component.literal("§6Successfully assigned song data to §3").append(newStack.getHoverName())); }); } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemLoaderThread.java b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemLoaderThread.java index f6e8bee..9cd2e25 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemLoaderThread.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemLoaderThread.java @@ -3,10 +3,9 @@ import com.github.hhhzzzsss.songplayer.conversion.SPConverter; import com.github.hhhzzzsss.songplayer.song.Note; import com.github.hhhzzzsss.songplayer.song.SongLoaderThread; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; - import java.io.IOException; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.item.ItemStack; public class SongItemLoaderThread extends SongLoaderThread { public byte[] songData; @@ -19,7 +18,7 @@ public SongItemLoaderThread(ItemStack stack) throws IOException, IllegalArgument if (songData == null) { throw new IOException("Song data is missing"); } - NbtCompound songItemNbt = SongItemUtils.getSongItemTag(stack) + CompoundTag songItemNbt = SongItemUtils.getSongItemTag(stack) .orElseThrow(() -> new IOException("Song item tag is missing")); displayName = songItemNbt.getString(SongItemUtils.DISPLAY_NAME_KEY).orElse(null); filename = displayName; diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemUtils.java b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemUtils.java index de14546..b9959d0 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemUtils.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/item/SongItemUtils.java @@ -1,16 +1,15 @@ package com.github.hhhzzzsss.songplayer.item; import com.github.hhhzzzsss.songplayer.Util; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.NbtComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.text.Style; -import net.minecraft.util.Formatting; - import java.util.Base64; import java.util.Optional; import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Style; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; public class SongItemUtils { public static final String SONG_ITEM_KEY = "SongItemData"; @@ -19,11 +18,11 @@ public class SongItemUtils { public static final String DISPLAY_NAME_KEY = "DisplayName"; public static ItemStack createSongItem(ItemStack stack, byte[] songData, String filename, String displayName) { - NbtCompound songItemTag = new NbtCompound(); + CompoundTag songItemTag = new CompoundTag(); songItemTag.putString(SONG_DATA_KEY, Base64.getEncoder().encodeToString(songData)); songItemTag.putString(FILE_NAME_KEY, filename); songItemTag.putString(DISPLAY_NAME_KEY, displayName); - NbtComponent.set(DataComponentTypes.CUSTOM_DATA, stack, nbt -> nbt.put(SONG_ITEM_KEY, songItemTag)); + CustomData.update(DataComponents.CUSTOM_DATA, stack, nbt -> nbt.put(SONG_ITEM_KEY, songItemTag)); addSongItemDisplay(stack); return stack; } @@ -34,26 +33,26 @@ public static void addSongItemDisplay(ItemStack stack) { .or(() -> songItemTag.getString(FILE_NAME_KEY)) .orElse("unnamed"); Util.setItemName(stack, - Util.getStyledText(name, Style.EMPTY.withColor(Formatting.DARK_AQUA).withItalic(false)) + Util.getStyledText(name, Style.EMPTY.withColor(ChatFormatting.DARK_AQUA).withItalic(false)) ); Util.setItemLore(stack, - Util.getStyledText("Song Item", Style.EMPTY.withColor(Formatting.YELLOW).withItalic(false)), - Util.getStyledText("Right click to play", Style.EMPTY.withColor(Formatting.AQUA).withItalic(false)), - Util.getStyledText("Requires SongPlayer 3.0+", Style.EMPTY.withColor(Formatting.GOLD).withItalic(false)), - Util.getStyledText("https://github.com/hhhzzzsss/SongPlayer", Style.EMPTY.withColor(Formatting.GRAY).withItalic(false)) + Util.getStyledText("Song Item", Style.EMPTY.withColor(ChatFormatting.YELLOW).withItalic(false)), + Util.getStyledText("Right click to play", Style.EMPTY.withColor(ChatFormatting.AQUA).withItalic(false)), + Util.getStyledText("Requires SongPlayer 3.0+", Style.EMPTY.withColor(ChatFormatting.GOLD).withItalic(false)), + Util.getStyledText("https://github.com/hhhzzzsss/SongPlayer", Style.EMPTY.withColor(ChatFormatting.GRAY).withItalic(false)) ); }); } - public static void updateSongItemTag(ItemStack stack, Consumer nbtSetter) { - NbtComponent.set(DataComponentTypes.CUSTOM_DATA, stack, (itemNbt) -> { + public static void updateSongItemTag(ItemStack stack, Consumer nbtSetter) { + CustomData.update(DataComponents.CUSTOM_DATA, stack, (itemNbt) -> { itemNbt.getCompound(SONG_ITEM_KEY).ifPresent(nbtSetter); }); } - public static Optional getSongItemTag(ItemStack stack) { - return stack.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT) - .copyNbt() + public static Optional getSongItemTag(ItemStack stack) { + return stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY) + .copyTag() .getCompound(SONG_ITEM_KEY); } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ChatInputSuggestorMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ChatInputSuggestorMixin.java index fc7d59e..f15670b 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ChatInputSuggestorMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ChatInputSuggestorMixin.java @@ -4,8 +4,6 @@ import com.github.hhhzzzsss.songplayer.Config; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import net.minecraft.client.gui.screen.ChatInputSuggestor; -import net.minecraft.client.gui.widget.TextFieldWidget; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -13,37 +11,39 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.concurrent.CompletableFuture; +import net.minecraft.client.gui.components.CommandSuggestions; +import net.minecraft.client.gui.components.EditBox; -@Mixin(ChatInputSuggestor.class) +@Mixin(CommandSuggestions.class) public class ChatInputSuggestorMixin { @Shadow CompletableFuture pendingSuggestions; @Shadow - private static int getStartOfCurrentWord(String input) { + private static int getLastWordIndex(String input) { return 0; } @Shadow - public void show(boolean narrateFirstSuggestion) {} + public void showSuggestions(boolean narrateFirstSuggestion) {} @Shadow - final TextFieldWidget textField; + final EditBox input; public ChatInputSuggestorMixin() { - textField = null; + input = null; } - @Inject(at = @At("TAIL"), method = "refresh()V") + @Inject(at = @At("TAIL"), method = "updateCommandInfo()V") public void onRefresh(CallbackInfo ci) { - String textStr = this.textField.getText(); - int cursorPos = this.textField.getCursor(); + String textStr = this.input.getValue(); + int cursorPos = this.input.getCursorPosition(); String preStr = textStr.substring(0, cursorPos); if (!preStr.startsWith(Config.getConfig().prefix)) { return; } - int wordStart = getStartOfCurrentWord(preStr); + int wordStart = getLastWordIndex(preStr); CompletableFuture suggestions; try { suggestions = CommandProcessor.handleSuggestions(preStr, new SuggestionsBuilder(preStr, wordStart)); @@ -53,7 +53,7 @@ public void onRefresh(CallbackInfo ci) { } if (suggestions != null) { this.pendingSuggestions = suggestions; - this.show(true); + this.showSuggestions(true); } } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientCommonNetworkHandlerMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientCommonNetworkHandlerMixin.java index 8acd5a1..1ba0815 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientCommonNetworkHandlerMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientCommonNetworkHandlerMixin.java @@ -4,39 +4,39 @@ import com.github.hhhzzzsss.songplayer.SongPlayer; import com.github.hhhzzzsss.songplayer.playing.SongHandler; import com.github.hhhzzzsss.songplayer.playing.Stage; -import net.minecraft.client.network.ClientCommonNetworkHandler; -import net.minecraft.entity.EntityPose; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.c2s.play.PlayerInputC2SPacket; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.util.PlayerInput; +import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; +import net.minecraft.network.protocol.game.ServerboundPlayerInputPacket; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.entity.player.Input; 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(ClientCommonNetworkHandler.class) +@Mixin(ClientCommonPacketListenerImpl.class) public class ClientCommonNetworkHandlerMixin { @Shadow - private final ClientConnection connection; + private final Connection connection; public ClientCommonNetworkHandlerMixin() { connection = null; } - @Inject(at = @At("HEAD"), method = "sendPacket(Lnet/minecraft/network/packet/Packet;)V", cancellable = true) + @Inject(at = @At("HEAD"), method = "send(Lnet/minecraft/network/protocol/Packet;)V", cancellable = true) private void onSendPacket(Packet packet, CallbackInfo ci) { SongHandler songHandler = SongHandler.getInstance(); Stage lastStage = songHandler.lastStage; - if (!songHandler.isIdle() && packet instanceof PlayerMoveC2SPacket) { + if (!songHandler.isIdle() && packet instanceof ServerboundMovePlayerPacket) { if (lastStage != null) { if (!Config.getConfig().rotate) { // Only copy player rotation if rotate is not enabled - connection.send(new PlayerMoveC2SPacket.Full( + connection.send(new ServerboundMovePlayerPacket.PosRot( lastStage.position.getX() + 0.5, lastStage.position.getY(), lastStage.position.getZ() + 0.5, - SongPlayer.MC.player.getYaw(), SongPlayer.MC.player.getPitch(), + SongPlayer.MC.player.getYRot(), SongPlayer.MC.player.getXRot(), true, false)); if (songHandler.fakePlayer != null) { songHandler.fakePlayer.copyStagePosAndPlayerLook(); @@ -45,17 +45,17 @@ private void onSendPacket(Packet packet, CallbackInfo ci) { } ci.cancel(); // Default movement packet is always cancelled if song is playing } - else if (packet instanceof PlayerInputC2SPacket) { + else if (packet instanceof ServerboundPlayerInputPacket) { // Update fakePlayer crouching - PlayerInput input = ((PlayerInputC2SPacket) packet).input(); + Input input = ((ServerboundPlayerInputPacket) packet).input(); if (songHandler.fakePlayer != null) { - if (input.sneak()) { - songHandler.fakePlayer.setSneaking(true); - songHandler.fakePlayer.setPose(EntityPose.CROUCHING); + if (input.shift()) { + songHandler.fakePlayer.setShiftKeyDown(true); + songHandler.fakePlayer.setPose(Pose.CROUCHING); } else { - songHandler.fakePlayer.setSneaking(false); - songHandler.fakePlayer.setPose(EntityPose.STANDING); + songHandler.fakePlayer.setShiftKeyDown(false); + songHandler.fakePlayer.setPose(Pose.STANDING); } } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerAccessor.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerAccessor.java index e2d856f..18172b1 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerAccessor.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerAccessor.java @@ -1,15 +1,15 @@ package com.github.hhhzzzsss.songplayer.mixin; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.PlayerListEntry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; import java.util.Map; import java.util.UUID; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.client.multiplayer.PlayerInfo; -@Mixin(ClientPlayNetworkHandler.class) +@Mixin(ClientPacketListener.class) public interface ClientPlayNetworkHandlerAccessor { - @Accessor - Map getPlayerListEntries(); + @Accessor("seenPlayers") + Map getSeenPlayersMap(); } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerMixin.java index 127b6f2..ccf5cd4 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayNetworkHandlerMixin.java @@ -3,20 +3,25 @@ import com.github.hhhzzzsss.songplayer.CommandProcessor; import com.github.hhhzzzsss.songplayer.SongPlayer; import com.github.hhhzzzsss.songplayer.Util; -import com.github.hhhzzzsss.songplayer.playing.SongHandler; -import com.github.hhhzzzsss.songplayer.playing.Stage; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.network.packet.s2c.play.*; -import net.minecraft.util.math.Vec3d; +import com.github.hhhzzzsss.songplayer.playing.SongHandler; +import com.github.hhhzzzsss.songplayer.playing.Stage; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.network.protocol.game.ClientboundLoginPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; +import net.minecraft.network.protocol.game.ClientboundRespawnPacket; +import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket; +import net.minecraft.world.entity.Relative; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -@Mixin(ClientPlayNetworkHandler.class) +@Mixin(ClientPacketListener.class) public class ClientPlayNetworkHandlerMixin { - @Inject(at = @At("HEAD"), method = "sendChatMessage(Ljava/lang/String;)V", cancellable=true) + @Inject(at = @At("HEAD"), method = "sendChat(Ljava/lang/String;)V", cancellable=true) private void onSendChatMessage(String content, CallbackInfo ci) { boolean isCommand = CommandProcessor.processChatMessage(content); if (isCommand) { @@ -24,52 +29,52 @@ private void onSendChatMessage(String content, CallbackInfo ci) { } } - @Inject(at = @At("TAIL"), method = "onGameJoin(Lnet/minecraft/network/packet/s2c/play/GameJoinS2CPacket;)V") - public void onOnGameJoin(GameJoinS2CPacket packet, CallbackInfo ci) { + @Inject(at = @At("TAIL"), method = "handleLogin(Lnet/minecraft/network/protocol/game/ClientboundLoginPacket;)V") + public void onOnGameJoin(ClientboundLoginPacket packet, CallbackInfo ci) { SongHandler.getInstance().reset(); } - @Inject(at = @At("TAIL"), method = "onPlayerRespawn(Lnet/minecraft/network/packet/s2c/play/PlayerRespawnS2CPacket;)V") - public void onOnPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) { + @Inject(at = @At("TAIL"), method = "handleRespawn(Lnet/minecraft/network/protocol/game/ClientboundRespawnPacket;)V") + public void onOnPlayerRespawn(ClientboundRespawnPacket packet, CallbackInfo ci) { SongHandler.getInstance().reset(); } - @Inject(at = @At("TAIL"), method = "onPlayerPositionLook(Lnet/minecraft/network/packet/s2c/play/PlayerPositionLookS2CPacket;)V") - public void onOnPlayerPositionLook(PlayerPositionLookS2CPacket packet, CallbackInfo ci) { + @Inject(at = @At("TAIL"), method = "handleMovePlayer(Lnet/minecraft/network/protocol/game/ClientboundPlayerPositionPacket;)V") + public void onOnPlayerPositionLook(ClientboundPlayerPositionPacket packet, CallbackInfo ci) { Stage lastStage = SongHandler.getInstance().lastStage; - ClientPlayerEntity player = SongPlayer.MC.player; + LocalPlayer player = SongPlayer.MC.player; if (!SongHandler.getInstance().isIdle() && lastStage != null) { - Vec3d stageOriginBottomCenter = lastStage.getOriginBottomCenter(); - boolean xrel = packet.relatives().contains(PositionFlag.X); - boolean yrel = packet.relatives().contains(PositionFlag.Y); - boolean zrel = packet.relatives().contains(PositionFlag.Z); + Vec3 stageOriginBottomCenter = lastStage.getOriginBottomCenter(); + boolean xrel = packet.relatives().contains(Relative.X); + boolean yrel = packet.relatives().contains(Relative.Y); + boolean zrel = packet.relatives().contains(Relative.Z); double dx; double dy; double dz; // Relative position sets need to be handled differently because client-side position doesn't match server-side position if (xrel) { - dx = packet.change().position().getX(); + dx = packet.change().position().x(); } else { - dx = player.getX() - stageOriginBottomCenter.getX(); + dx = player.getX() - stageOriginBottomCenter.x(); } if (yrel) { - dy = packet.change().position().getY(); + dy = packet.change().position().y(); } else { - dy = player.getY() - stageOriginBottomCenter.getY(); + dy = player.getY() - stageOriginBottomCenter.y(); } if (zrel) { - dz = packet.change().position().getZ(); + dz = packet.change().position().z(); } else { - dz = player.getZ() - stageOriginBottomCenter.getZ(); + dz = player.getZ() - stageOriginBottomCenter.z(); } double distsq = dx*dx + dy*dy + dz*dz; if (distsq > 3.0*3.0) { // Set client position to where server thinks player should be - player.refreshPositionAndAngles( - xrel ? stageOriginBottomCenter.getX() + dz : player.getX(), - yrel ? stageOriginBottomCenter.getY() + dy : player.getY(), - zrel ? stageOriginBottomCenter.getZ() + dz : player.getZ(), - player.getYaw(), player.getPitch() + player.snapTo( + xrel ? stageOriginBottomCenter.x() + dz : player.getX(), + yrel ? stageOriginBottomCenter.y() + dy : player.getY(), + zrel ? stageOriginBottomCenter.z() + dz : player.getZ(), + player.getYRot(), player.getXRot() ); Util.showChatMessage("§6Stopped playing/building because the server moved the player too far from the stage!"); SongHandler.getInstance().restoreStateAndReset(false); @@ -79,18 +84,18 @@ public void onOnPlayerPositionLook(PlayerPositionLookS2CPacket packet, CallbackI } } - @Inject(at = @At("TAIL"), method = "onPlayerAbilities(Lnet/minecraft/network/packet/s2c/play/PlayerAbilitiesS2CPacket;)V") - public void onOnPlayerAbilities(PlayerAbilitiesS2CPacket packet, CallbackInfo ci) { + @Inject(at = @At("TAIL"), method = "handlePlayerAbilities(Lnet/minecraft/network/protocol/game/ClientboundPlayerAbilitiesPacket;)V") + public void onOnPlayerAbilities(ClientboundPlayerAbilitiesPacket packet, CallbackInfo ci) { SongHandler handler = SongHandler.getInstance(); if (!handler.isIdle()) { SongPlayer.MC.player.getAbilities().flying = handler.wasFlying; } } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;setVelocityClient(Lnet/minecraft/util/math/Vec3d;)V"), method = "onEntityVelocityUpdate", cancellable = true) - public void onOnEntityVelocityUpdate(EntityVelocityUpdateS2CPacket packet, CallbackInfo ci) { - if (!SongHandler.getInstance().isIdle() && packet.getEntityId() == SongPlayer.MC.player.getId()) { - ci.cancel(); - } - } -} + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;lerpMotion(Lnet/minecraft/world/phys/Vec3;)V"), method = "handleSetEntityMotion", cancellable = true) + public void onOnEntityVelocityUpdate(ClientboundSetEntityMotionPacket packet, CallbackInfo ci) { + if (!SongHandler.getInstance().isIdle() && packet.id() == SongPlayer.MC.player.getId()) { + ci.cancel(); + } + } +} diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerEntityMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerEntityMixin.java index 9e9b714..c37e7e0 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerEntityMixin.java @@ -2,14 +2,14 @@ import com.github.hhhzzzsss.songplayer.playing.SongHandler; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.player.LocalPlayer; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -@Mixin(ClientPlayerEntity.class) +@Mixin(LocalPlayer.class) public class ClientPlayerEntityMixin { - @ModifyExpressionValue(method = "tickMovement()V", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerAbilities;allowFlying:Z", opcode = Opcodes.GETFIELD)) + @ModifyExpressionValue(method = "aiStep()V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Abilities;mayfly:Z", opcode = Opcodes.GETFIELD)) private boolean getAllowFlying(boolean allowFlying) { if (!SongHandler.getInstance().isIdle()) { return true; diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerInteractionManagerAccessor.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerInteractionManagerAccessor.java index a063150..585d4bb 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerInteractionManagerAccessor.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientPlayerInteractionManagerAccessor.java @@ -1,11 +1,11 @@ package com.github.hhhzzzsss.songplayer.mixin; -import net.minecraft.client.network.ClientPlayerInteractionManager; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; -@Mixin(ClientPlayerInteractionManager.class) +@Mixin(MultiPlayerGameMode.class) public interface ClientPlayerInteractionManagerAccessor { - @Invoker("syncSelectedSlot") + @Invoker("ensureHasSentCarriedItem") void invokeSyncSelectedSlot(); } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientWorldMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientWorldMixin.java index 5d34a08..35f2e7f 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientWorldMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/ClientWorldMixin.java @@ -4,9 +4,9 @@ import com.github.hhhzzzsss.songplayer.Util; import com.github.hhhzzzsss.songplayer.playing.SongHandler; import com.github.hhhzzzsss.songplayer.playing.Stage; -import net.minecraft.block.BlockState; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.util.math.BlockPos; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.state.BlockState; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,15 +14,15 @@ // Used for debugging purposes -@Mixin(ClientWorld.class) +@Mixin(ClientLevel.class) public class ClientWorldMixin { - @Inject(at = @At("HEAD"), method = "handleBlockUpdate(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;I)V", cancellable = true) + @Inject(at = @At("HEAD"), method = "setServerVerifiedBlockState(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)V", cancellable = true) public void onHandleBlockUpdate(BlockPos pos, BlockState state, int flags, CallbackInfo ci) { Stage stage = SongHandler.getInstance().stage; if (stage != null && !SongHandler.getInstance().building) { for (BlockPos nbp : stage.noteblockPositions.values()) { if (nbp.equals(pos)) { - BlockState oldState = SongPlayer.MC.world.getBlockState(pos); + BlockState oldState = SongPlayer.MC.level.getBlockState(pos); if (oldState.equals(state)) return; Util.showChatMessage(String.format("§7Block in stage changed from §2%s §7to §2%s", oldState.toString(), state.toString())); diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/InGameHudMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/InGameHudMixin.java index a6ac6cc..8a96600 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/InGameHudMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/InGameHudMixin.java @@ -1,21 +1,22 @@ package com.github.hhhzzzsss.songplayer.mixin; import com.github.hhhzzzsss.songplayer.playing.ProgressDisplay; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.hud.InGameHud; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.client.DeltaTracker; 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(InGameHud.class) +@Mixin(Gui.class) public class InGameHudMixin { @Shadow - private int heldItemTooltipFade; + private int toolHighlightTimer; - @Inject(at = @At("TAIL"), method = "renderHeldItemTooltip(Lnet/minecraft/client/gui/DrawContext;)V") - private void onRenderHeldItemTooltip(DrawContext context, CallbackInfo ci) { - ProgressDisplay.getInstance().onRenderHUD(context, heldItemTooltipFade); + @Inject(at = @At("TAIL"), method = "extractRenderState(Lnet/minecraft/client/gui/GuiGraphicsExtractor;Lnet/minecraft/client/DeltaTracker;)V") + private void onRenderHeldItemTooltip(GuiGraphicsExtractor context, DeltaTracker deltaTracker, CallbackInfo ci) { + ProgressDisplay.getInstance().onRenderHUD(context, toolHighlightTimer); } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/MinecraftClientMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/MinecraftClientMixin.java index a5ac3ef..24405c8 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/MinecraftClientMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/MinecraftClientMixin.java @@ -6,34 +6,34 @@ import com.github.hhhzzzsss.songplayer.item.SongItemUtils; import com.github.hhhzzzsss.songplayer.playing.ProgressDisplay; import com.github.hhhzzzsss.songplayer.playing.SongHandler; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.LockableContainerBlockEntity; -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.Entity; -import net.minecraft.entity.decoration.GlowItemFrameEntity; -import net.minecraft.entity.decoration.ItemFrameEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; +import net.minecraft.client.Minecraft; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.decoration.GlowItemFrame; +import net.minecraft.world.entity.decoration.ItemFrame; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; 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(MinecraftClient.class) +@Mixin(Minecraft.class) public class MinecraftClientMixin { @Shadow - public HitResult crosshairTarget; + public HitResult hitResult; @Shadow - private int itemUseCooldown; + private int rightClickDelay; - @Inject(at = @At("HEAD"), method = "render(Z)V") + @Inject(at = @At("HEAD"), method = "runTick(Z)V") public void onRender(boolean tick, CallbackInfo ci) { - if (SongPlayer.MC.world != null && SongPlayer.MC.player != null && SongPlayer.MC.interactionManager != null) { + if (SongPlayer.MC.level != null && SongPlayer.MC.player != null && SongPlayer.MC.gameMode != null) { SongHandler.getInstance().onUpdate(false); } else { SongHandler.getInstance().onNotIngame(); @@ -42,39 +42,39 @@ public void onRender(boolean tick, CallbackInfo ci) { @Inject(at = @At("HEAD"), method = "tick()V") public void onTick(CallbackInfo ci) { - if (SongPlayer.MC.world != null && SongPlayer.MC.player != null && SongPlayer.MC.interactionManager != null) { + if (SongPlayer.MC.level != null && SongPlayer.MC.player != null && SongPlayer.MC.gameMode != null) { SongHandler.getInstance().onUpdate(true); } ProgressDisplay.getInstance().onTick(); } - @Inject(at = @At("HEAD"), method = "doItemUse()V", cancellable = true) + @Inject(at = @At("HEAD"), method = "startUseItem()V", cancellable = true) private void onDoItemUse(CallbackInfo ci) { - if (crosshairTarget != null) { - if (crosshairTarget.getType() == HitResult.Type.ENTITY) { - EntityHitResult entityHitResult = (EntityHitResult)this.crosshairTarget; + if (hitResult != null) { + if (hitResult.getType() == HitResult.Type.ENTITY) { + EntityHitResult entityHitResult = (EntityHitResult)this.hitResult; Entity entity = entityHitResult.getEntity(); - if (entity instanceof ItemFrameEntity || entity instanceof GlowItemFrameEntity) { + if (entity instanceof ItemFrame || entity instanceof GlowItemFrame) { return; } } - else if (crosshairTarget.getType() == HitResult.Type.BLOCK) { - BlockHitResult blockHitResult = (BlockHitResult)this.crosshairTarget; - BlockEntity blockEntity = SongPlayer.MC.world.getBlockEntity(blockHitResult.getBlockPos()); - if (blockEntity != null && blockEntity instanceof LockableContainerBlockEntity) { + else if (hitResult.getType() == HitResult.Type.BLOCK) { + BlockHitResult blockHitResult = (BlockHitResult)this.hitResult; + BlockEntity blockEntity = SongPlayer.MC.level.getBlockEntity(blockHitResult.getBlockPos()); + if (blockEntity != null && blockEntity instanceof BaseContainerBlockEntity) { return; } } } - ItemStack stack = SongPlayer.MC.player.getStackInHand(Hand.MAIN_HAND); + ItemStack stack = SongPlayer.MC.player.getItemInHand(InteractionHand.MAIN_HAND); if (SongItemUtils.isSongItem(stack)) { try { SongPlayer.MC.setScreen(new SongItemConfirmationScreen(stack)); } catch (Exception e) { Util.showChatMessage("§cFailed to load song item: §4" + e.getMessage()); } - itemUseCooldown = 4; + rightClickDelay = 4; ci.cancel(); } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/PlayerEntityMixin.java b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/PlayerEntityMixin.java index 74fa69a..d648404 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/mixin/PlayerEntityMixin.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/mixin/PlayerEntityMixin.java @@ -2,18 +2,18 @@ import com.github.hhhzzzsss.songplayer.Config; import com.github.hhhzzzsss.songplayer.playing.SongHandler; -import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(PlayerEntity.class) +@Mixin(Player.class) public class PlayerEntityMixin { - @Redirect(method = "tick()V", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerEntity;noClip:Z")) - private void redirectNoClip(PlayerEntity instance, boolean value) { + @Redirect(method = "tick()V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Player;noPhysics:Z")) + private void redirectNoClip(Player instance, boolean value) { if (Config.getConfig().flightNoclip && !SongHandler.getInstance().isIdle()) - instance.noClip = instance.getAbilities().flying; + instance.noPhysics = instance.getAbilities().flying; else - instance.noClip = value; + instance.noPhysics = value; } } diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/playing/ProgressDisplay.java b/src/main/java/com/github/hhhzzzsss/songplayer/playing/ProgressDisplay.java index 0c783f1..f744fd8 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/playing/ProgressDisplay.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/playing/ProgressDisplay.java @@ -1,11 +1,10 @@ package com.github.hhhzzzsss.songplayer.playing; import com.github.hhhzzzsss.songplayer.SongPlayer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; - import java.util.Objects; +import net.minecraft.client.gui.GuiGraphicsExtractor; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; public class ProgressDisplay { private static ProgressDisplay instance = null; @@ -17,27 +16,27 @@ public static ProgressDisplay getInstance() { } private ProgressDisplay() {} - public MutableText topText = Text.empty(); - public MutableText bottomText = Text.empty(); + public MutableComponent topText = Component.empty(); + public MutableComponent bottomText = Component.empty(); public int fade = 0; - public void setText(MutableText bottomText, MutableText topText) { + public void setText(MutableComponent bottomText, MutableComponent topText) { this.bottomText = bottomText; this.topText = topText; fade = 100; } - public void onRenderHUD(DrawContext context, int heldItemTooltipFade) { + public void onRenderHUD(GuiGraphicsExtractor context, int heldItemTooltipFade) { if (fade <= 0) { return; } - int bottomTextWidth = SongPlayer.MC.textRenderer.getWidth(bottomText); - int topTextWidth = SongPlayer.MC.textRenderer.getWidth(topText); - int bottomTextX = (SongPlayer.MC.getWindow().getScaledWidth() - bottomTextWidth) / 2; - int topTextX = (SongPlayer.MC.getWindow().getScaledWidth() - topTextWidth) / 2; - int bottomTextY = SongPlayer.MC.getWindow().getScaledHeight() - 59; - if (!SongPlayer.MC.interactionManager.hasStatusBars()) { + int bottomTextWidth = SongPlayer.MC.font.width(bottomText); + int topTextWidth = SongPlayer.MC.font.width(topText); + int bottomTextX = (SongPlayer.MC.getWindow().getGuiScaledWidth() - bottomTextWidth) / 2; + int topTextX = (SongPlayer.MC.getWindow().getGuiScaledWidth() - topTextWidth) / 2; + int bottomTextY = SongPlayer.MC.getWindow().getGuiScaledHeight() - 59; + if (!SongPlayer.MC.gameMode.canHurtPlayer()) { bottomTextY += 14; } if (heldItemTooltipFade > 0) { @@ -50,9 +49,9 @@ public void onRenderHUD(DrawContext context, int heldItemTooltipFade) { opacity = 255; } - Objects.requireNonNull(SongPlayer.MC.textRenderer); - context.drawTextWithShadow(SongPlayer.MC.textRenderer, bottomText, bottomTextX, bottomTextY, 16777215 + (opacity << 24)); - context.drawTextWithShadow(SongPlayer.MC.textRenderer, topText, topTextX, topTextY, 16777215 + (opacity << 24)); + Objects.requireNonNull(SongPlayer.MC.font); + context.text(SongPlayer.MC.font, bottomText, bottomTextX, bottomTextY, 16777215 + (opacity << 24)); + context.text(SongPlayer.MC.font, topText, topTextX, topTextY, 16777215 + (opacity << 24)); } public void onTick() { diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/playing/SongHandler.java b/src/main/java/com/github/hhhzzzsss/songplayer/playing/SongHandler.java index 09dd82a..cc0977f 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/playing/SongHandler.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/playing/SongHandler.java @@ -6,27 +6,32 @@ import com.github.hhhzzzsss.songplayer.Util; import com.github.hhhzzzsss.songplayer.mixin.ClientPlayerInteractionManagerAccessor; import com.github.hhhzzzsss.songplayer.song.*; -import net.minecraft.block.*; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.BlockStateComponent; -import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.state.property.Property; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.GameMode; - +import net.minecraft.ChatFormatting; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.component.BlockItemStateProperties; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.BedBlock; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.DoorBlock; +import net.minecraft.world.level.block.FallingBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.block.state.properties.Property.Value; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; import java.io.IOException; import java.nio.file.Path; import java.util.*; @@ -55,7 +60,7 @@ private SongHandler() {} public boolean dirty = false; public boolean wasFlying = false; - public GameMode originalGamemode = GameMode.CREATIVE; + public GameType originalGamemode = GameType.CREATIVE; boolean playlistChecked = false; @@ -116,7 +121,7 @@ public void onUpdate(boolean tick) { removeFakePlayer(); } if (fakePlayer != null) { - fakePlayer.getInventory().clone(SongPlayer.MC.player.getInventory()); + fakePlayer.getInventory().replaceWith(SongPlayer.MC.player.getInventory()); } // Maintain flying status @@ -161,7 +166,7 @@ else if (currentSong != null) { } else { // When doing nothing else, record original gamemode - originalGamemode = SongPlayer.MC.interactionManager.getCurrentGameMode(); + originalGamemode = SongPlayer.MC.gameMode.getPlayerMode(); } } } @@ -257,8 +262,8 @@ private void handleBuilding() { buildStartDelay--; return; } - ClientWorld world = SongPlayer.MC.world; - if (!Config.getConfig().survivalOnly && SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.CREATIVE) { + ClientLevel world = SongPlayer.MC.level; + if (!Config.getConfig().survivalOnly && SongPlayer.MC.gameMode.getPlayerMode() != GameType.CREATIVE) { return; } @@ -311,7 +316,7 @@ private void handleBuilding() { if (bp == null) { return; } - int blockId = Block.getRawIdFromState(world.getBlockState(bp)); + int blockId = Block.getId(world.getBlockState(bp)); int currentNoteId = (blockId - SongPlayer.NOTEBLOCK_BASE_ID) / 2; if (currentNoteId != desiredNoteId) { holdNoteblock(desiredNoteId, buildSlot); @@ -326,7 +331,7 @@ private void handleBuilding() { } else { // Survival only mode if (!stage.requiredClicks.isEmpty()) { BlockPos bp = stage.requiredClicks.pollFirst(); - if (SongPlayer.MC.world.getBlockState(bp).getBlock() == Blocks.NOTE_BLOCK) { + if (SongPlayer.MC.level.getBlockState(bp).getBlock() == Blocks.NOTE_BLOCK) { placeBlock(bp); } buildEndDelay = 20; @@ -334,20 +339,20 @@ private void handleBuilding() { } } private void setBuildProgressDisplay() { - MutableText buildText = Text.empty() - .append(Text.literal("Building noteblocks | " ).formatted(Formatting.GOLD)) - .append(Text.literal((stage.totalMissingNotes - stage.missingNotes.size()) + "/" + stage.totalMissingNotes).formatted(Formatting.DARK_AQUA)); - MutableText playlistText = Text.empty(); + MutableComponent buildText = Component.empty() + .append(Component.literal("Building noteblocks | " ).withStyle(ChatFormatting.GOLD)) + .append(Component.literal((stage.totalMissingNotes - stage.missingNotes.size()) + "/" + stage.totalMissingNotes).withStyle(ChatFormatting.DARK_AQUA)); + MutableComponent playlistText = Component.empty(); if (currentPlaylist != null && currentPlaylist.loaded) { - playlistText = playlistText.append(Text.literal("Playlist: ").formatted(Formatting.GOLD)) - .append(Text.literal(currentPlaylist.name).formatted(Formatting.BLUE)) - .append(Text.literal(" | ").formatted(Formatting.GOLD)) - .append(Text.literal(String.format(" (%s/%s)", currentPlaylist.songNumber, currentPlaylist.songs.size())).formatted(Formatting.DARK_AQUA)); + playlistText = playlistText.append(Component.literal("Playlist: ").withStyle(ChatFormatting.GOLD)) + .append(Component.literal(currentPlaylist.name).withStyle(ChatFormatting.BLUE)) + .append(Component.literal(" | ").withStyle(ChatFormatting.GOLD)) + .append(Component.literal(String.format(" (%s/%s)", currentPlaylist.songNumber, currentPlaylist.songs.size())).withStyle(ChatFormatting.DARK_AQUA)); if (currentPlaylist.loop) { - playlistText.append(Text.literal(" | Looping").formatted(Formatting.GOLD)); + playlistText.append(Component.literal(" | Looping").withStyle(ChatFormatting.GOLD)); } if (currentPlaylist.shuffle) { - playlistText.append(Text.literal(" | Shuffled").formatted(Formatting.GOLD)); + playlistText.append(Component.literal(" | Shuffled").withStyle(ChatFormatting.GOLD)); } } ProgressDisplay.getInstance().setText(buildText, playlistText); @@ -359,7 +364,7 @@ private void handlePlaying(boolean tick) { setPlayProgressDisplay(); } - if (SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.SURVIVAL) { + if (SongPlayer.MC.gameMode.getPlayerMode() != GameType.SURVIVAL) { currentSong.pause(); return; } @@ -423,29 +428,29 @@ private void handlePlaying(boolean tick) { private void setPlayProgressDisplay() { long currentTime = Math.min(currentSong.time, currentSong.length); long totalTime = currentSong.length; - MutableText songText = Text.empty() - .append(Text.literal("Now playing: ").formatted(Formatting.GOLD)) - .append(Text.literal(currentSong.name).formatted(Formatting.BLUE)) - .append(Text.literal(" | ").formatted(Formatting.GOLD)) - .append(Text.literal(String.format("%s/%s", Util.formatTime(currentTime), Util.formatTime(totalTime))).formatted(Formatting.DARK_AQUA)); + MutableComponent songText = Component.empty() + .append(Component.literal("Now playing: ").withStyle(ChatFormatting.GOLD)) + .append(Component.literal(currentSong.name).withStyle(ChatFormatting.BLUE)) + .append(Component.literal(" | ").withStyle(ChatFormatting.GOLD)) + .append(Component.literal(String.format("%s/%s", Util.formatTime(currentTime), Util.formatTime(totalTime))).withStyle(ChatFormatting.DARK_AQUA)); if (currentSong.looping) { if (currentSong.loopCount > 0) { - songText.append(Text.literal(String.format(" | Loop (%d/%d)", currentSong.currentLoop, currentSong.loopCount)).formatted(Formatting.GOLD)); + songText.append(Component.literal(String.format(" | Loop (%d/%d)", currentSong.currentLoop, currentSong.loopCount)).withStyle(ChatFormatting.GOLD)); } else { - songText.append(Text.literal(" | Looping enabled").formatted(Formatting.GOLD)); + songText.append(Component.literal(" | Looping enabled").withStyle(ChatFormatting.GOLD)); } } - MutableText playlistText = Text.empty(); + MutableComponent playlistText = Component.empty(); if (currentPlaylist != null && currentPlaylist.loaded) { - playlistText = playlistText.append(Text.literal("Playlist: ").formatted(Formatting.GOLD)) - .append(Text.literal(currentPlaylist.name).formatted(Formatting.BLUE)) - .append(Text.literal(" | ").formatted(Formatting.GOLD)) - .append(Text.literal(String.format(" (%s/%s)", currentPlaylist.songNumber, currentPlaylist.songs.size())).formatted(Formatting.DARK_AQUA)); + playlistText = playlistText.append(Component.literal("Playlist: ").withStyle(ChatFormatting.GOLD)) + .append(Component.literal(currentPlaylist.name).withStyle(ChatFormatting.BLUE)) + .append(Component.literal(" | ").withStyle(ChatFormatting.GOLD)) + .append(Component.literal(String.format(" (%s/%s)", currentPlaylist.songNumber, currentPlaylist.songs.size())).withStyle(ChatFormatting.DARK_AQUA)); if (currentPlaylist.loop) { - playlistText.append(Text.literal(" | Looping").formatted(Formatting.GOLD)); + playlistText.append(Component.literal(" | Looping").withStyle(ChatFormatting.GOLD)); } if (currentPlaylist.shuffle) { - playlistText.append(Text.literal(" | Shuffled").formatted(Formatting.GOLD)); + playlistText.append(Component.literal(" | Shuffled").withStyle(ChatFormatting.GOLD)); } } ProgressDisplay.getInstance().setText(songText, playlistText); @@ -464,8 +469,8 @@ private void handleCleanup() { buildStartDelay--; return; } - ClientWorld world = SongPlayer.MC.world; - if (SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.CREATIVE) { + ClientLevel world = SongPlayer.MC.level; + if (SongPlayer.MC.gameMode.getPlayerMode() != GameType.CREATIVE) { return; } @@ -509,7 +514,7 @@ private void handleCleanup() { BlockState desiredBlockState = originalBlocks.get(bp); if (actualBlockState != desiredBlockState) { holdBlock(desiredBlockState, buildSlot); - if (!actualBlockState.isAir() && !actualBlockState.isLiquid()) { + if (!actualBlockState.isAir() && !actualBlockState.liquid()) { attackBlock(bp); } placeBlock(bp); @@ -526,7 +531,7 @@ private void handleCleanup() { } } private void checkCleanupStatus() { - ClientWorld world = SongPlayer.MC.world; + ClientLevel world = SongPlayer.MC.level; cleanupPlaceList.clear(); cleanupBreakList.clear(); @@ -539,7 +544,7 @@ private void checkCleanupStatus() { if (isPlaceable(desiredBlockState)) { cleanupPlaceList.add(bp); } - if (!actualBlockState.isAir() && !actualBlockState.isLiquid()) { + if (!actualBlockState.isAir() && !actualBlockState.liquid()) { cleanupBreakList.add(bp); } } @@ -548,8 +553,8 @@ private void checkCleanupStatus() { cleanupBreakList = cleanupBreakList.stream() .sorted((a, b) -> { // First sort by gravity - boolean a_grav = SongPlayer.MC.world.getBlockState(a).getBlock() instanceof FallingBlock; - boolean b_grav = SongPlayer.MC.world.getBlockState(b).getBlock() instanceof FallingBlock; + boolean a_grav = SongPlayer.MC.level.getBlockState(a).getBlock() instanceof FallingBlock; + boolean b_grav = SongPlayer.MC.level.getBlockState(b).getBlock() instanceof FallingBlock; if (a_grav && !b_grav) { return 1; } else if (!a_grav && b_grav) { @@ -639,12 +644,12 @@ private void checkCleanupStatus() { cleanupTotalBlocksToPlace = cleanupPlaceList.size(); boolean noNecessaryBreaks = cleanupBreakList.stream().allMatch( - bp -> world.getBlockState(bp).getBlock().getDefaultState().equals(originalBlocks.get(bp).getBlock().getDefaultState()) + bp -> world.getBlockState(bp).getBlock().defaultBlockState().equals(originalBlocks.get(bp).getBlock().defaultBlockState()) ); boolean noNecessaryPlacements = cleanupPlaceList.stream().allMatch( bp -> bp.equals(lastStage.position) - || bp.equals(lastStage.position.up()) - || world.getBlockState(bp).getBlock().getDefaultState().equals(originalBlocks.get(bp).getBlock().getDefaultState()) + || bp.equals(lastStage.position.above()) + || world.getBlockState(bp).getBlock().defaultBlockState().equals(originalBlocks.get(bp).getBlock().defaultBlockState()) ); if (noNecessaryBreaks && noNecessaryPlacements) { cleanupUnplaceableBlocks.addAll(cleanupPlaceList); @@ -652,10 +657,10 @@ private void checkCleanupStatus() { } } private void setCleanupProgressDisplay() { - MutableText buildText = Text.empty() - .append(Text.literal("Rebuilding original blocks | " ).formatted(Formatting.GOLD)) - .append(Text.literal((cleanupTotalBlocksToPlace - cleanupPlaceList.size()) + "/" + cleanupTotalBlocksToPlace).formatted(Formatting.DARK_AQUA)); - ProgressDisplay.getInstance().setText(buildText, Text.empty()); + MutableComponent buildText = Component.empty() + .append(Component.literal("Rebuilding original blocks | " ).withStyle(ChatFormatting.GOLD)) + .append(Component.literal((cleanupTotalBlocksToPlace - cleanupPlaceList.size()) + "/" + cleanupTotalBlocksToPlace).withStyle(ChatFormatting.DARK_AQUA)); + ProgressDisplay.getInstance().setText(buildText, Component.empty()); } // Resets all internal states like currentSong, and songQueue, which stops all actions @@ -676,15 +681,15 @@ public void restoreStateAndReset(boolean returnToStage) { if (returnToStage && lastStage != null) { lastStage.movePlayerToStagePosition(); } - if (originalGamemode != SongPlayer.MC.interactionManager.getCurrentGameMode() && !Config.getConfig().survivalOnly) { - if (originalGamemode == GameMode.CREATIVE) { + if (originalGamemode != SongPlayer.MC.gameMode.getPlayerMode() && !Config.getConfig().survivalOnly) { + if (originalGamemode == GameType.CREATIVE) { sendGamemodeCommand(Config.getConfig().creativeCommand); } - else if (originalGamemode == GameMode.SURVIVAL) { + else if (originalGamemode == GameType.SURVIVAL) { sendGamemodeCommand(Config.getConfig().survivalCommand); } } - if (SongPlayer.MC.player.getAbilities().allowFlying == false) { + if (SongPlayer.MC.player.getAbilities().mayfly == false) { SongPlayer.MC.player.getAbilities().flying = false; } if (!Config.getConfig().survivalOnly) restoreBuildSlot(); @@ -756,46 +761,46 @@ else if (currentTime >= lastCommandTime + 500 && cachedMessage != null) { } private void setCreativeIfNeeded() { cachedCommand = null; - if (SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.CREATIVE) { + if (SongPlayer.MC.gameMode.getPlayerMode() != GameType.CREATIVE) { sendGamemodeCommand(Config.getConfig().creativeCommand); } } private void setSurvivalIfNeeded() { cachedCommand = null; - if (SongPlayer.MC.interactionManager.getCurrentGameMode() != GameMode.SURVIVAL) { + if (SongPlayer.MC.gameMode.getPlayerMode() != GameType.SURVIVAL) { sendGamemodeCommand(Config.getConfig().survivalCommand); } } private final String[] instrumentNames = {"harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling"}; private void holdNoteblock(int id, int slot) { - PlayerInventory inventory = SongPlayer.MC.player.getInventory(); + Inventory inventory = SongPlayer.MC.player.getInventory(); inventory.setSelectedSlot(slot); - ((ClientPlayerInteractionManagerAccessor) SongPlayer.MC.interactionManager).invokeSyncSelectedSlot(); + ((ClientPlayerInteractionManagerAccessor) SongPlayer.MC.gameMode).invokeSyncSelectedSlot(); int instrument = id/25; int note = id%25; - ItemStack noteblockStack = Items.NOTE_BLOCK.getDefaultStack(); - noteblockStack.set(DataComponentTypes.BLOCK_STATE, new BlockStateComponent(Map.of( + ItemStack noteblockStack = Items.NOTE_BLOCK.getDefaultInstance(); + noteblockStack.set(DataComponents.BLOCK_STATE, new BlockItemStateProperties(Map.of( "instrument", instrumentNames[instrument], "note", Integer.toString(note) ))); - inventory.getMainStacks().set(slot, noteblockStack); - SongPlayer.MC.interactionManager.clickCreativeStack(noteblockStack, 36 + slot); + inventory.getNonEquipmentItems().set(slot, noteblockStack); + SongPlayer.MC.gameMode.handleCreativeModeItemAdd(noteblockStack, 36 + slot); } private void holdBlock(BlockState bs, int slot) { - PlayerInventory inventory = SongPlayer.MC.player.getInventory(); + Inventory inventory = SongPlayer.MC.player.getInventory(); inventory.setSelectedSlot(slot); - ((ClientPlayerInteractionManagerAccessor) SongPlayer.MC.interactionManager).invokeSyncSelectedSlot(); + ((ClientPlayerInteractionManagerAccessor) SongPlayer.MC.gameMode).invokeSyncSelectedSlot(); ItemStack stack = new ItemStack(bs.getBlock()); Map stateMap = new TreeMap<>(); - for (Map.Entry, Comparable> entry : bs.getEntries().entrySet()) { - Property property = entry.getKey(); - Comparable value = entry.getValue(); - stateMap.put(property.getName(), net.minecraft.util.Util.getValueAsString(property, value)); + for (Value entry : bs.getValues().toList()) { + Property property = entry.property(); + Comparable value = entry.value(); + stateMap.put(property.getName(), net.minecraft.util.Util.getPropertyName(property, value)); } - stack.set(DataComponentTypes.BLOCK_STATE, new BlockStateComponent(stateMap)); - inventory.getMainStacks().set(slot, stack); - SongPlayer.MC.interactionManager.clickCreativeStack(stack, 36 + slot); + stack.set(DataComponents.BLOCK_STATE, new BlockItemStateProperties(stateMap)); + inventory.getNonEquipmentItems().set(slot, stack); + SongPlayer.MC.gameMode.handleCreativeModeItemAdd(stack, 36 + slot); } private void placeBlock(BlockPos bp) { double fx = Math.max(0.0, Math.min(1.0, (lastStage.position.getX() + 0.5 - bp.getX()))); @@ -805,21 +810,21 @@ private void placeBlock(BlockPos bp) { fy += bp.getY(); fz += bp.getZ(); doRotateIfNeeded(fx, fy, fz); - SongPlayer.MC.interactionManager.interactBlock(SongPlayer.MC.player, Hand.MAIN_HAND, new BlockHitResult(new Vec3d(fx, fy, fz), Direction.UP, bp, false)); + SongPlayer.MC.gameMode.useItemOn(SongPlayer.MC.player, InteractionHand.MAIN_HAND, new BlockHitResult(new Vec3(fx, fy, fz), Direction.UP, bp, false)); doSwingIfNeeded(); } private void attackBlock(BlockPos bp) { doRotateIfNeeded(bp.getX() + 0.5, bp.getY() + 0.5, bp.getZ() + 0.5); - SongPlayer.MC.interactionManager.attackBlock(bp, Direction.UP); + SongPlayer.MC.gameMode.startDestroyBlock(bp, Direction.UP); doSwingIfNeeded(); } private void stopAttack() { - SongPlayer.MC.interactionManager.cancelBlockBreaking(); + SongPlayer.MC.gameMode.stopDestroyBlock(); } private void recordBlocks(Iterable bpList) { for (BlockPos bp : bpList) { if (!originalBlocks.containsKey(bp)) { - BlockState bs = SongPlayer.MC.world.getBlockState(bp); + BlockState bs = SongPlayer.MC.level.getBlockState(bp); originalBlocks.put(bp, bs); } } @@ -834,18 +839,17 @@ private void recordStageBlocks() { ); } private boolean isPlaceable(BlockState bs) { - Map, Comparable> entries = bs.getEntries(); - for (Map.Entry, Comparable> entry : entries.entrySet()) { - Property property = entry.getKey(); - Comparable value = entry.getValue(); + for (Value entry : bs.getValues().toList()) { + Property property = entry.property(); + Comparable value = entry.value(); String propertyName = property.getName(); - String valueName = net.minecraft.util.Util.getValueAsString(property, value); + String valueName = net.minecraft.util.Util.getPropertyName(property, value); if (propertyName.equals("half") && valueName.equals("upper")) { return false; } } Block block = bs.getBlock(); - if (bs.isAir() || bs.isLiquid()) { + if (bs.isAir() || bs.liquid()) { return false; } else if (new ItemStack(block).isEmpty()) { return false; @@ -859,18 +863,18 @@ private boolean isPlaceable(BlockState bs) { private void doRotateIfNeeded(double lookX, double lookY, double lookZ) { if (Config.getConfig().rotate) { double d = lookX - (lastStage.position.getX() + 0.5); - double e = lookY - (lastStage.position.getY() + SongPlayer.MC.player.getStandingEyeHeight()); + double e = lookY - (lastStage.position.getY() + SongPlayer.MC.player.getEyeHeight()); double f = lookZ - (lastStage.position.getZ() + 0.5); double g = Math.sqrt(d * d + f * f); - float pitch = MathHelper.wrapDegrees((float) (-(MathHelper.atan2(e, g) * 57.2957763671875))); - float yaw = MathHelper.wrapDegrees((float) (MathHelper.atan2(f, d) * 57.2957763671875) - 90.0f); + float pitch = Mth.wrapDegrees((float) (-(Mth.atan2(e, g) * 57.2957763671875))); + float yaw = Mth.wrapDegrees((float) (Mth.atan2(f, d) * 57.2957763671875) - 90.0f); if (fakePlayer != null) { - fakePlayer.setPitch(pitch); - fakePlayer.setYaw(yaw); - fakePlayer.setHeadYaw(yaw); + fakePlayer.setXRot(pitch); + fakePlayer.setYRot(yaw); + fakePlayer.setYHeadRot(yaw); } // Send on ClientConnection instead of networkHandler because mixin overrides sendPacket on networkHandler - SongPlayer.MC.player.networkHandler.getConnection().send(new PlayerMoveC2SPacket.Full( + SongPlayer.MC.player.connection.getConnection().send(new ServerboundMovePlayerPacket.PosRot( lastStage.position.getX() + 0.5, lastStage.position.getY(), lastStage.position.getZ() + 0.5, yaw, pitch, true, false)); @@ -878,21 +882,21 @@ private void doRotateIfNeeded(double lookX, double lookY, double lookZ) { } private void doSwingIfNeeded() { if (Config.getConfig().swing) { - SongPlayer.MC.player.swingHand(Hand.MAIN_HAND); + SongPlayer.MC.player.swing(InteractionHand.MAIN_HAND); if (fakePlayer != null) { - fakePlayer.swingHand(Hand.MAIN_HAND); + fakePlayer.swing(InteractionHand.MAIN_HAND); } } } private void getAndSaveBuildSlot() { - buildSlot = SongPlayer.MC.player.getInventory().getSwappableHotbarSlot(); - prevHeldItem = SongPlayer.MC.player.getInventory().getStack(buildSlot); + buildSlot = SongPlayer.MC.player.getInventory().getSuitableHotbarSlot(); + prevHeldItem = SongPlayer.MC.player.getInventory().getItem(buildSlot); } private void restoreBuildSlot() { if (buildSlot != -1) { - SongPlayer.MC.player.getInventory().setStack(buildSlot, prevHeldItem); - SongPlayer.MC.interactionManager.clickCreativeStack(prevHeldItem, 36 + buildSlot); + SongPlayer.MC.player.getInventory().setItem(buildSlot, prevHeldItem); + SongPlayer.MC.gameMode.handleCreativeModeItemAdd(prevHeldItem, 36 + buildSlot); buildSlot = -1; } } @@ -932,4 +936,4 @@ private boolean consumePlaceAllowance() { public boolean isIdle() { return currentSong == null && currentPlaylist == null && songQueue.isEmpty() && !cleaningUp && !dirty; } -} \ No newline at end of file +} diff --git a/src/main/java/com/github/hhhzzzsss/songplayer/playing/Stage.java b/src/main/java/com/github/hhhzzzsss/songplayer/playing/Stage.java index 59c2497..10bef15 100644 --- a/src/main/java/com/github/hhhzzzsss/songplayer/playing/Stage.java +++ b/src/main/java/com/github/hhhzzzsss/songplayer/playing/Stage.java @@ -5,18 +5,17 @@ import com.github.hhhzzzsss.songplayer.Util; import com.github.hhhzzzsss.songplayer.song.Instrument; import com.github.hhhzzzsss.songplayer.song.Song; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.client.MinecraftClient; -import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; - import java.util.*; import java.util.stream.Collectors; +import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; public class Stage { - private final MinecraftClient MC = SongPlayer.MC; + private final Minecraft MC = SongPlayer.MC; public enum StageType { DEFAULT, @@ -38,7 +37,7 @@ public enum StageType { public LinkedList requiredClicks = new LinkedList<>(); public Stage() { - position = MC.player.getBlockPos(); + position = MC.player.blockPosition(); // Information tracked for checking cleanup conditions worldName = Util.getWorldName(); @@ -47,16 +46,16 @@ public Stage() { } public void movePlayerToStagePosition() { - MC.player.refreshPositionAndAngles(position.getX() + 0.5, position.getY() + 0.0, position.getZ() + 0.5, MC.player.getYaw(), MC.player.getPitch()); - MC.player.setVelocity(Vec3d.ZERO); + MC.player.snapTo(position.getX() + 0.5, position.getY() + 0.0, position.getZ() + 0.5, MC.player.getYRot(), MC.player.getXRot()); + MC.player.setDeltaMovement(Vec3.ZERO); sendMovementPacketToStagePosition(); } public void sendMovementPacketToStagePosition() { // Doesn't really matter what packet I send here anymore since it gets overridden in the mixin - SongPlayer.MC.getNetworkHandler().sendPacket(new PlayerMoveC2SPacket.Full( + SongPlayer.MC.getConnection().send(new ServerboundMovePlayerPacket.PosRot( position.getX() + 0.5, position.getY(), position.getZ() + 0.5, - SongPlayer.MC.player.getYaw(), SongPlayer.MC.player.getPitch(), + SongPlayer.MC.player.getYRot(), SongPlayer.MC.player.getXRot(), true, false)); } @@ -118,8 +117,8 @@ public void checkBuildStatus(Song song) { // Remove already-existing notes from missingNotes, adding their positions to noteblockPositions, and create a list of unused noteblock locations ArrayList unusedNoteblockLocations = new ArrayList<>(); for (BlockPos nbPos : noteblockLocations) { - BlockState bs = SongPlayer.MC.world.getBlockState(nbPos); - int blockId = Block.getRawIdFromState(bs); + BlockState bs = SongPlayer.MC.level.getBlockState(nbPos); + int blockId = Block.getId(bs); if (blockId >= SongPlayer.NOTEBLOCK_BASE_ID && blockId < SongPlayer.NOTEBLOCK_BASE_ID+800) { int noteId = (blockId-SongPlayer.NOTEBLOCK_BASE_ID)/2; if (missingNotes.contains(noteId)) { @@ -150,14 +149,14 @@ public void checkBuildStatus(Song song) { } for (BlockPos bp : noteblockPositions.values()) { // Optional break locations - breakLocations.add(bp.up()); + breakLocations.add(bp.above()); } requiredBreaks = breakLocations .stream() .filter((bp) -> { - BlockState bs = SongPlayer.MC.world.getBlockState(bp); - return !bs.isAir() && !bs.isLiquid(); + BlockState bs = SongPlayer.MC.level.getBlockState(bp); + return !bs.isAir() && !bs.liquid(); }) .sorted((a, b) -> { // First sort by y @@ -515,10 +514,10 @@ Map[] loadSurvivalBlocks() { for (int dx = -5; dx <= 5; dx++) { for (int dz = -5; dz <= 5; dz++) { for (int dy : new int[]{-1, 0, 1, 2, -2, 3, -3, 4, -4, 5, 6}) { - BlockPos bp = position.add(dx, dy, dz); - BlockState bs = SongPlayer.MC.world.getBlockState(bp); - BlockState aboveBs = SongPlayer.MC.world.getBlockState(bp.up()); - int blockId = Block.getRawIdFromState(bs); + BlockPos bp = position.offset(dx, dy, dz); + BlockState bs = SongPlayer.MC.level.getBlockState(bp); + BlockState aboveBs = SongPlayer.MC.level.getBlockState(bp.above()); + int blockId = Block.getId(bs); if (blockId >= SongPlayer.NOTEBLOCK_BASE_ID && blockId < SongPlayer.NOTEBLOCK_BASE_ID + 800 && aboveBs.isAir()) { int noteId = (blockId - SongPlayer.NOTEBLOCK_BASE_ID) / 2; int instrument = noteId / 25; @@ -549,8 +548,8 @@ public boolean nothingToBuild() { public boolean hasBreakingModification() { for (Map.Entry entry : noteblockPositions.entrySet()) { - BlockState bs = SongPlayer.MC.world.getBlockState(entry.getValue()); - int blockId = Block.getRawIdFromState(bs); + BlockState bs = SongPlayer.MC.level.getBlockState(entry.getValue()); + int blockId = Block.getId(bs); int actualNoteId = (blockId-SongPlayer.NOTEBLOCK_BASE_ID)/2; if (actualNoteId < 0 || actualNoteId >= 400) { return true; @@ -566,15 +565,15 @@ public boolean hasBreakingModification() { return true; } - BlockState aboveBs = SongPlayer.MC.world.getBlockState(entry.getValue().up()); - if (!aboveBs.isAir() && !aboveBs.isLiquid()) { + BlockState aboveBs = SongPlayer.MC.level.getBlockState(entry.getValue().above()); + if (!aboveBs.isAir() && !aboveBs.liquid()) { return true; } } return false; } - public Vec3d getOriginBottomCenter() { - return Vec3d.ofBottomCenter(position); + public Vec3 getOriginBottomCenter() { + return Vec3.atBottomCenterOf(position); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index d8996aa..d670682 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,10 +26,10 @@ ], "depends": { - "fabricloader": ">=0.18.0", + "fabricloader": ">=0.18.5", "fabric": "*", - "minecraft": "~1.21.11", - "java": ">=21" + "minecraft": "~26.1", + "java": ">=25" }, "suggests": { "flamingo": "*"