diff --git a/.idea/misc.xml b/.idea/misc.xml
index ec55a2e..9d0bbd3 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 81526cf..55c33c0 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -3,7 +3,9 @@
+
+
diff --git a/.idea/modules/MCTools.main.iml b/.idea/modules/MCTools.main.iml
index 2e14514..356a8e3 100644
--- a/.idea/modules/MCTools.main.iml
+++ b/.idea/modules/MCTools.main.iml
@@ -14,4 +14,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Minecraft_Server.xml b/.idea/runConfigurations/Minecraft_Server.xml
index 9710d0e..aff153d 100644
--- a/.idea/runConfigurations/Minecraft_Server.xml
+++ b/.idea/runConfigurations/Minecraft_Server.xml
@@ -12,5 +12,5 @@
-
+
\ No newline at end of file
diff --git a/src/main/java/com/expvintl/mctools/MCToolsClient.java b/src/main/java/com/expvintl/mctools/MCToolsClient.java
index a0cc78d..bc646f7 100644
--- a/src/main/java/com/expvintl/mctools/MCToolsClient.java
+++ b/src/main/java/com/expvintl/mctools/MCToolsClient.java
@@ -3,6 +3,8 @@ package com.expvintl.mctools;
import com.expvintl.mctools.commands.*;
import com.expvintl.mctools.modules.BetterTooltip;
import com.expvintl.mctools.modules.PlayerListTextLatency;
+import com.expvintl.mctools.texthud.MCInfo;
+import com.expvintl.mctools.texthud.PotionInfo;
import com.expvintl.mctools.utils.Utils;
import com.mojang.brigadier.CommandDispatcher;
import net.fabricmc.api.ClientModInitializer;
@@ -21,87 +23,19 @@ import net.minecraft.util.math.Vec3d;
public class MCToolsClient implements ClientModInitializer {
- private static int infoY=1;
@Override
public void onInitializeClient() {
//初始化命令注册回调
ClientCommandRegistrationCallback.EVENT.register(MCToolsClient::registerCommands);
- HudRenderCallback.EVENT.register(MCToolsClient::drawHUD);
+ HudRenderCallback.EVENT.register(MCInfo::drawHUD);
+ HudRenderCallback.EVENT.register(PotionInfo::drawHUD);
InitModules();
}
public void InitModules(){
BetterTooltip.INSTANCE.init();
PlayerListTextLatency.INSTANCE.init();
}
- private static String gameDayToRealTimeFormat(long gameDays) {
- // 游戏 1 小时等于 20 分钟
- long totalMinutes = gameDays * 20;
- long days = totalMinutes / (60 * 24); // 计算天数
- long remainingMinutesAfterDays = totalMinutes % (60 * 24);
-
- long hours = remainingMinutesAfterDays / 60; // 计算小时数
- long minutes = remainingMinutesAfterDays % 60; // 计算剩余分钟数
-
- StringBuilder timeString = new StringBuilder();
-
- if (days > 0) {
- timeString.append(days).append(" 天");
- }
- if (hours > 0) {
- if (!timeString.isEmpty()) {
- timeString.append(" ");
- }
- timeString.append(hours).append(" 小时");
- }
- if (minutes > 0 || timeString.isEmpty()) {
- if (!timeString.isEmpty()) {
- timeString.append(" ");
- }
- timeString.append(minutes).append(" 分钟");
- }
-
- return timeString.toString();
- }
- private static void drawHUD(DrawContext drawContext, RenderTickCounter v) {
- MinecraftClient mc=MinecraftClient.getInstance();
- //跳过调试
- if(mc.getDebugHud().shouldShowDebugHud()||mc.options.hudHidden) return;
-
- if(mc.world!=null&&mc.player!=null) {
- infoY=1;
- int selfPing=0;
- ClientPlayerEntity p=mc.player;
- if(mc.getNetworkHandler()!=null&&mc.getNetworkHandler().getPlayerListEntry(mc.player.getGameProfile().getId())!=null) {
- selfPing=mc.getNetworkHandler().getPlayerListEntry(mc.player.getGameProfile().getId()).getLatency();
- }
- Vec3d playerPos=p.getPos();
- AddText(drawContext,String.format("%d FPS",mc.getCurrentFps()));
- AddText(drawContext,String.format("Ping: %d 毫秒",selfPing));
- AddText(drawContext,String.format("亮度:%d",mc.world.getLightLevel(p.getBlockPos())));
- AddText(drawContext,String.format("当前维度:%s", Utils.getCurrentDimensionName()));
- AddText(drawContext,String.format("当前群系:%s",Utils.getCurrentBiomeName()));
- if(Utils.getCurrentDimensionName().equals("下界")){
- AddText(drawContext,String.format("X:%.2f Y:%.2f Z:%.2f (主世界 X:%.2f Z:%.2f)",playerPos.x,playerPos.y,playerPos.z,playerPos.x*8,playerPos.z*8));
- }else if(Utils.getCurrentDimensionName().equals("主世界")){
- AddText(drawContext,String.format("X:%.2f Y:%.2f Z:%.2f (下界 X:%.2f Z:%.2f)",playerPos.x,playerPos.y,playerPos.z,playerPos.x/8,playerPos.z/8));
- }else{
- AddText(drawContext,String.format("X:%.2f Y:%.2f Z:%.2f",playerPos.x,playerPos.y,playerPos.z));
- }
- AddText(drawContext,String.format("世界时间: %d天 (%s)",mc.world.getTimeOfDay()/24000,gameDayToRealTimeFormat(mc.world.getTimeOfDay()/24000)));
- AddText(drawContext,String.format("当前区块: [%d,%d]",mc.player.getChunkPos().x,mc.player.getChunkPos().z));
- AddText(drawContext,String.format("本地难度:%.2f",mc.world.getLocalDifficulty(mc.player.getBlockPos()).getLocalDifficulty()));
- ItemStack currentItem=p.getInventory().getMainHandStack();
- if(currentItem!=null&¤tItem.isDamageable()){
- AddText(drawContext,String.format("耐久度:%d/%d",currentItem.getMaxDamage()-currentItem.getDamage(),currentItem.getMaxDamage()));
- }
- }
- }
- private static void AddText(DrawContext drawContext,String text){
- TextRenderer renderer=MinecraftClient.getInstance().textRenderer;
- drawContext.drawText(renderer,text,0,infoY,Colors.WHITE,false);
- infoY+=10;
- }
private static void registerCommands(CommandDispatcher dispatcher, CommandRegistryAccess registryAccess) {
//注册命令
CFullbirghtCommand.register(dispatcher);
@@ -112,6 +46,6 @@ public class MCToolsClient implements ClientModInitializer {
CQServerPluginsCommand.register(dispatcher);
CNoFallPacketCommand.register(dispatcher);
CFindBlockCommand.register(dispatcher);
- CFastDropCommand.register(dispatcher);
+ CFastDropCommand.register(dispatcher,registryAccess);
}
}
diff --git a/src/main/java/com/expvintl/mctools/commands/CFastDropCommand.java b/src/main/java/com/expvintl/mctools/commands/CFastDropCommand.java
index 6539bf1..b7b6d77 100644
--- a/src/main/java/com/expvintl/mctools/commands/CFastDropCommand.java
+++ b/src/main/java/com/expvintl/mctools/commands/CFastDropCommand.java
@@ -1,27 +1,79 @@
package com.expvintl.mctools.commands;
-import com.expvintl.mctools.mixin.interfaces.SimpleOptionAccessor;
import com.expvintl.mctools.utils.PlayerUtils;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.command.argument.ItemStackArgumentType;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
+import net.minecraft.registry.Registries;
import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class CFastDropCommand {
public static List- trashItem=new ArrayList<>();
- public static void register(CommandDispatcher dispatcher){
+ public static void register(CommandDispatcher dispatcher , CommandRegistryAccess access){
dispatcher.register(literal("cfastdrop").executes(CFastDropCommand::execute));
+ dispatcher.register(literal("cfastdrop").then(literal("list").executes((context -> {
+ StringBuilder sb=new StringBuilder();
+ sb.append("已添加:\n");
+ for(Item i:trashItem){
+ sb.append(i.getName().getString()).append(",");
+ }
+ context.getSource().getPlayer().sendMessage(Text.literal(sb.toString()));
+ return Command.SINGLE_SUCCESS;
+ }))));
+ dispatcher.register(literal("cfastdrop").then(literal("clear").executes((context -> {
+ trashItem.clear();
+ context.getSource().getPlayer().sendMessage(Text.literal("已清除全部物品!"));
+ return Command.SINGLE_SUCCESS;
+ }))));
+ dispatcher.register(literal("cfastdrop").then(literal("del").then(argument("物品", ItemStackArgumentType.itemStack(access)).suggests(((context, builder) -> suggestItems(builder))).executes(cmd->{
+ Item item=ItemStackArgumentType.getItemStackArgument(cmd,"物品").getItem();
+ if (item != Items.AIR) { // 确保找到的物品是有效的
+ if (trashItem.contains(item)) {
+ trashItem.remove(item);
+ cmd.getSource().getPlayer().sendMessage(Text.literal("已移除 " + item.getName().getString()));
+ }else{
+ cmd.getSource().getPlayer().sendMessage(Text.literal("没有找到 " + item.getName().getString()));
+ }
+ }else{
+ cmd.getSource().getPlayer().sendMessage(Text.literal("无效物品!"));
+ return 0;
+ }
+ return Command.SINGLE_SUCCESS;
+ }))));
+ dispatcher.register(literal("cfastdrop").then(literal("add").then(argument("物品", ItemStackArgumentType.itemStack(access)).suggests(((context, builder) -> suggestItems(builder))).executes(cmd->{
+ Item item=ItemStackArgumentType.getItemStackArgument(cmd,"物品").getItem();
+ if (item != Items.AIR) { // 确保找到的物品是有效的
+ if(trashItem.contains(item)){
+ cmd.getSource().getPlayer().sendMessage(Text.literal( item.getName().getString() + " 已存在!"));
+ }else {
+ trashItem.add(item);
+ cmd.getSource().getPlayer().sendMessage(Text.literal("已添加 " + item.getName().getString() + " 到垃圾物品列表"));
+ }
+ }else{
+ cmd.getSource().getPlayer().sendMessage(Text.literal("无效物品!"));
+ return 0;
+ }
+ return Command.SINGLE_SUCCESS;
+ }))));
trashItem.add(Items.COBBLESTONE);
trashItem.add(Items.GRANITE);//花岗岩
trashItem.add(Items.ANDESITE);//安山岩
@@ -35,8 +87,17 @@ public class CFastDropCommand {
trashItem.add(Items.DANDELION);
trashItem.add(Items.SUNFLOWER);
trashItem.add(Items.CORNFLOWER);
+ trashItem.add(Items.TUFF); //凝灰岩
+ trashItem.add(Items.DEEPSLATE); //深板岩
+ trashItem.add(Items.SANDSTONE); //砂岩
+ trashItem.add(Items.DEEPSLATE_BRICKS);//深板岩砖
+ trashItem.add(Items.COBBLED_DEEPSLATE); //深板岩圆石
+ }
+ private static CompletableFuture suggestItems(SuggestionsBuilder builder) {
+ // 遍历所有注册的物品并将其添加到建议列表中
+ Registries.ITEM.getIds().forEach(id -> builder.suggest(id.toString()));
+ return builder.buildFuture();
}
-
private static int execute(CommandContext context) {
ClientPlayerEntity player=context.getSource().getPlayer();
if(player==null){
diff --git a/src/main/java/com/expvintl/mctools/mixin/hud/ChatHudMixin.java b/src/main/java/com/expvintl/mctools/mixin/hud/ChatHudMixin.java
index e823f8f..d3f0f00 100644
--- a/src/main/java/com/expvintl/mctools/mixin/hud/ChatHudMixin.java
+++ b/src/main/java/com/expvintl/mctools/mixin/hud/ChatHudMixin.java
@@ -11,6 +11,7 @@ import net.minecraft.client.gui.hud.ChatHudLine;
import net.minecraft.text.OrderedText;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(ChatHud.class)
public class ChatHudMixin {
diff --git a/src/main/java/com/expvintl/mctools/mixin/hud/PlayerListHudMixin.java b/src/main/java/com/expvintl/mctools/mixin/hud/PlayerListHudMixin.java
index 9ecc1ce..e8f7e20 100644
--- a/src/main/java/com/expvintl/mctools/mixin/hud/PlayerListHudMixin.java
+++ b/src/main/java/com/expvintl/mctools/mixin/hud/PlayerListHudMixin.java
@@ -12,6 +12,7 @@ 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.ModifyArg;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -25,6 +26,7 @@ public class PlayerListHudMixin {
private void getPlayerName(PlayerListEntry entry, CallbackInfoReturnable info){
if(Utils.isReady()){
Text name=entry.getDisplayName();
+ if(MinecraftClient.getInstance().player==null||name==null) return;
if(entry.getProfile().getId().toString().equals(MinecraftClient.getInstance().player.getGameProfile().getId().toString())){
info.setReturnValue(Text.literal(name.getString()).setStyle(name.getStyle().withColor(0xff0000)));
}
@@ -35,4 +37,10 @@ public class PlayerListHudMixin {
private void onRenderLatencyIcon(DrawContext draw, int width, int x, int y, PlayerListEntry entry, CallbackInfo info){
MCEventBus.INSTANCE.post(RenderLatencyIconEvent.get(draw,width,x,y,entry,info));
}
+
+ //强制启用Tab列表玩家头像
+ @ModifyVariable(method = "render",at = @At(value = "STORE",ordinal = 0),ordinal = 0)
+ private boolean hackShowPlayerHeadIcon(boolean b1){
+ return true;
+ }
}
diff --git a/src/main/java/com/expvintl/mctools/texthud/MCInfo.java b/src/main/java/com/expvintl/mctools/texthud/MCInfo.java
new file mode 100644
index 0000000..d42e96c
--- /dev/null
+++ b/src/main/java/com/expvintl/mctools/texthud/MCInfo.java
@@ -0,0 +1,78 @@
+package com.expvintl.mctools.texthud;
+
+import com.expvintl.mctools.utils.DrawUtils;
+import com.expvintl.mctools.utils.Utils;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.render.RenderTickCounter;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Colors;
+import net.minecraft.util.math.Vec3d;
+
+public class MCInfo {
+ private static String gameDayToRealTimeFormat(long gameDays) {
+ // 游戏 1 小时等于 20 分钟
+ long totalMinutes = gameDays * 20;
+
+ long days = totalMinutes / (60 * 24); // 计算天数
+ long remainingMinutesAfterDays = totalMinutes % (60 * 24);
+
+ long hours = remainingMinutesAfterDays / 60; // 计算小时数
+ long minutes = remainingMinutesAfterDays % 60; // 计算剩余分钟数
+
+ StringBuilder timeString = new StringBuilder();
+
+ if (days > 0) {
+ timeString.append(days).append(" 天");
+ }
+ if (hours > 0) {
+ if (!timeString.isEmpty()) {
+ timeString.append(" ");
+ }
+ timeString.append(hours).append(" 小时");
+ }
+ if (minutes > 0 || timeString.isEmpty()) {
+ if (!timeString.isEmpty()) {
+ timeString.append(" ");
+ }
+ timeString.append(minutes).append(" 分钟");
+ }
+
+ return timeString.toString();
+ }
+ public static void drawHUD(DrawContext drawContext, RenderTickCounter v) {
+ MinecraftClient mc=MinecraftClient.getInstance();
+ //跳过调试
+ if(mc.getDebugHud().shouldShowDebugHud()||mc.options.hudHidden) return;
+ if(mc.world!=null&&mc.player!=null) {
+ DrawUtils.leftTextY =1;
+ int selfPing=0;
+ ClientPlayerEntity p=mc.player;
+ if(mc.getNetworkHandler()!=null&&mc.getNetworkHandler().getPlayerListEntry(mc.player.getGameProfile().getId())!=null) {
+ selfPing=mc.getNetworkHandler().getPlayerListEntry(mc.player.getGameProfile().getId()).getLatency();
+ }
+ Vec3d playerPos=p.getPos();
+ DrawUtils.AddLeftText(drawContext,String.format("%d FPS",mc.getCurrentFps()));
+ DrawUtils.AddLeftText(drawContext,String.format("Ping: %d 毫秒",selfPing));
+ DrawUtils.AddLeftText(drawContext,String.format("亮度:%d",mc.world.getLightLevel(p.getBlockPos())));
+ DrawUtils.AddLeftText(drawContext,String.format("当前维度:%s", Utils.getCurrentDimensionName()));
+ DrawUtils.AddLeftText(drawContext,String.format("当前群系:%s",Utils.getCurrentBiomeName()));
+ if(Utils.getCurrentDimensionName().equals("下界")){
+ DrawUtils.AddLeftText(drawContext,String.format("X:%.2f Y:%.2f Z:%.2f (主世界 X:%.2f Z:%.2f)",playerPos.x,playerPos.y,playerPos.z,playerPos.x*8,playerPos.z*8));
+ }else if(Utils.getCurrentDimensionName().equals("主世界")){
+ DrawUtils.AddLeftText(drawContext,String.format("X:%.2f Y:%.2f Z:%.2f (下界 X:%.2f Z:%.2f)",playerPos.x,playerPos.y,playerPos.z,playerPos.x/8,playerPos.z/8));
+ }else{
+ DrawUtils.AddLeftText(drawContext,String.format("X:%.2f Y:%.2f Z:%.2f",playerPos.x,playerPos.y,playerPos.z));
+ }
+ DrawUtils.AddLeftText(drawContext,String.format("世界时间: %d天 (%s)",mc.world.getTimeOfDay()/24000,gameDayToRealTimeFormat(mc.world.getTimeOfDay()/24000)));
+ DrawUtils.AddLeftText(drawContext,String.format("当前区块: [%d,%d]",mc.player.getChunkPos().x,mc.player.getChunkPos().z));
+ DrawUtils.AddLeftText(drawContext,String.format("本地难度:%.2f",mc.world.getLocalDifficulty(mc.player.getBlockPos()).getLocalDifficulty()));
+ ItemStack currentItem=p.getInventory().getMainHandStack();
+ if(currentItem!=null&¤tItem.isDamageable()){
+ DrawUtils.AddLeftText(drawContext,String.format("耐久度:%d/%d",currentItem.getMaxDamage()-currentItem.getDamage(),currentItem.getMaxDamage()));
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/expvintl/mctools/texthud/PotionInfo.java b/src/main/java/com/expvintl/mctools/texthud/PotionInfo.java
new file mode 100644
index 0000000..295ba93
--- /dev/null
+++ b/src/main/java/com/expvintl/mctools/texthud/PotionInfo.java
@@ -0,0 +1,41 @@
+package com.expvintl.mctools.texthud;
+
+import com.expvintl.mctools.utils.DrawUtils;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.render.RenderTickCounter;
+import net.minecraft.client.resource.language.I18n;
+import net.minecraft.entity.effect.StatusEffectInstance;
+import net.minecraft.util.Colors;
+
+import java.util.Collection;
+
+public class PotionInfo {
+ public static void drawHUD(DrawContext drawContext, RenderTickCounter v) {
+ MinecraftClient mc=MinecraftClient.getInstance();
+ //跳过调试
+ if(mc.getDebugHud().shouldShowDebugHud()||mc.options.hudHidden) return;
+
+ if(mc.world!=null&&mc.player!=null) {
+ DrawUtils.rightBottomY=1;
+ Collection effects=mc.player.getStatusEffects();
+ for(StatusEffectInstance instance:effects){
+ DrawUtils.AddRightBottomText(drawContext,String.format("%s%d (%s)", I18n.translate(instance.getTranslationKey()),
+ instance.getAmplifier()+1,
+ instance.isInfinite()?"无限":formatPotionDuration(instance.getDuration())));
+ }
+ }
+ }
+ public static String formatPotionDuration(int ticks) {
+ int totalSeconds = ticks / 20; // 将ticks转换为秒
+ int hours = totalSeconds / 3600; // 1小时 = 3600秒
+ int minutes = (totalSeconds % 3600) / 60; // 获取剩余的分钟
+ int seconds = totalSeconds % 60; // 获取剩余的秒数
+
+ if (hours > 0) {
+ return String.format("%d:%02d:%02d", hours, minutes, seconds);
+ } else {
+ return String.format("%02d:%02d", minutes, seconds);
+ }
+ }
+}
diff --git a/src/main/java/com/expvintl/mctools/utils/DrawUtils.java b/src/main/java/com/expvintl/mctools/utils/DrawUtils.java
new file mode 100644
index 0000000..0ee749c
--- /dev/null
+++ b/src/main/java/com/expvintl/mctools/utils/DrawUtils.java
@@ -0,0 +1,26 @@
+package com.expvintl.mctools.utils;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.util.Colors;
+
+public class DrawUtils {
+ public static int leftTextY=1;
+ public static int rightTextY=1;
+ public static int rightBottomY=1;
+ public static void AddLeftText(DrawContext drawContext, String text){
+ MinecraftClient mc=MinecraftClient.getInstance();
+ drawContext.drawText(mc.textRenderer,text,0,leftTextY, Colors.WHITE,false);
+ leftTextY+=10;
+ }
+ public static void AddRightText(DrawContext drawContext, String text){
+ MinecraftClient mc=MinecraftClient.getInstance();
+ drawContext.drawText(mc.textRenderer,text,drawContext.getScaledWindowWidth()-2-mc.textRenderer.getWidth(text),rightTextY, Colors.WHITE,false);
+ rightTextY+=10;
+ }
+ public static void AddRightBottomText(DrawContext drawContext, String text){
+ MinecraftClient mc=MinecraftClient.getInstance();
+ drawContext.drawText(mc.textRenderer,text,drawContext.getScaledWindowWidth()-2-mc.textRenderer.getWidth(text),drawContext.getScaledWindowHeight()-10-rightBottomY, Colors.WHITE,false);
+ rightBottomY+=10;
+ }
+}