first commit

This commit is contained in:
Patrick
2026-05-01 18:54:57 +02:00
commit 3820e45f0a
127 changed files with 14283 additions and 0 deletions
@@ -0,0 +1,195 @@
package de.winniepat.citrus.client;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.*;
import de.winniepat.citrus.Client;
import de.winniepat.citrus.cosmetics.capes.*;
import de.winniepat.citrus.cosmetics.capes.sync.CapeSyncManager;
import de.winniepat.citrus.cosmetics.wings.ClientWingManager;
import de.winniepat.citrus.managers.ClientRegistrationManager;
import de.winniepat.citrus.gui.*;
import icyllis.modernui.mc.MuiModApi;
import net.fabricmc.fabric.api.client.command.v2.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.Text;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.UUID;
public class ClientCommands {
public static void register() {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
LiteralArgumentBuilder<FabricClientCommandSource> citrusCommand =
LiteralArgumentBuilder.<FabricClientCommandSource>literal("citrus")
.executes(context -> {
context.getSource().sendFeedback(Text.literal("§f#### §aCitrus §7- by WinniePatGG §f####"));
context.getSource().sendFeedback(Text.literal("§7Version: §7" + Client.CLIENT_BUILD));
context.getSource().sendFeedback(Text.literal(""));
context.getSource().sendFeedback(Text.literal("§7Available commands:"));
context.getSource().sendFeedback(Text.literal("§e/citrus cape set <cape_name> §7- Set your cape"));
context.getSource().sendFeedback(Text.literal("§e/citrus cape reload §7- Reload available capes from cdn"));
context.getSource().sendFeedback(Text.literal(""));
context.getSource().sendFeedback(Text.literal("§e/citrus capesync clearcache §7- Clear cape sync cache"));
context.getSource().sendFeedback(Text.literal("§e/citrus capesync forcefetch §7- Force fetch capes for all players"));
context.getSource().sendFeedback(Text.literal(""));
context.getSource().sendFeedback(Text.literal("§e/citrus wings toggle §7- Toggle wings visibility"));
context.getSource().sendFeedback(Text.literal("§e/citrus wings set <wing_type> §7- Set your wing type"));
context.getSource().sendFeedback(Text.literal("§e/citrus wings list §7- List available wing types"));
context.getSource().sendFeedback(Text.literal(""));
context.getSource().sendFeedback(Text.literal("§e/citrus status §7- Show Citrus status"));
context.getSource().sendFeedback(Text.literal("§e/citrus screen <name> §7- Open a client screen"));
return 1;
});
citrusCommand.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("screen")
.then(RequiredArgumentBuilder
.<FabricClientCommandSource, String>argument("name", StringArgumentType.word())
.suggests((context, builder) -> {
builder.suggest("showcase");
builder.suggest("friends");
builder.suggest("profiles");
builder.suggest("hud");
builder.suggest("menu");
return builder.buildFuture();
})
.executes(context -> {
String name = StringArgumentType.getString(context, "name").toLowerCase();
MinecraftClient client = MinecraftClient.getInstance();
client.execute(() -> {
switch (name) {
case "friends" -> client.setScreen(MuiModApi.get().createScreen(new FriendsFragment(), null, client.currentScreen));
case "profiles" -> client.setScreen(MuiModApi.get().createScreen(new ProfileScreen(), null, client.currentScreen));
case "hud" -> client.setScreen(MuiModApi.get().createScreen(new HudEditorFragment(), null, client.currentScreen));
case "menu" -> client.setScreen(MuiModApi.get().createScreen(new MainMenuScreen(), null, null));
case "showcase" -> client.setScreen(MuiModApi.get().createScreen(new TestScreen(), null, client.currentScreen));
default -> context.getSource().sendError(Text.literal("§cUnknown screen: §e" + name));
}
});
return 1;
})
)
);
citrusCommand.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("cape")
.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("set")
.then(RequiredArgumentBuilder
.<FabricClientCommandSource, String>argument("cape_name", StringArgumentType.string())
.suggests((context, builder) -> {
builder.suggest("none");
builder.suggest("auto");
for (String cape : CapeHandler.getAvailableCapes()) {
builder.suggest(cape);
}
return builder.buildFuture();
})
.executes(context -> {
String capeName = StringArgumentType.getString(context, "cape_name");
MinecraftClient client = MinecraftClient.getInstance();
if (client.player == null) {
context.getSource().sendError(Text.literal("§cYou must be in-game!"));
return 0;
}
if (CapeHandler.capeExists(capeName)) {
CapeHandler.setLocalPlayerCape(capeName, false);
context.getSource().sendFeedback(Text.literal("§aCape set to: §e" + capeName));
} else {
context.getSource().sendError(Text.literal("§cUnknown cape: " + capeName));
}
return 1;
})
)
)
.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("reload")
.executes(context -> {
context.getSource().sendFeedback(Text.literal("§aReloading capes..."));
CapeHandler.reloadCapes();
return 1;
})
)
);
citrusCommand.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("capesync")
.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("clearcache")
.executes(context -> {
CapeSyncManager.clearAllCache();
context.getSource().sendFeedback(Text.literal("§aCache cleared."));
return 1;
})
)
.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("forcefetch")
.executes(context -> {
MinecraftClient client = MinecraftClient.getInstance();
if (client.player == null || client.world == null) {
context.getSource().sendError(Text.literal("§cYou must be in-game!"));
return 0;
}
List<UUID> playerUUIDs = client.world.getPlayers().stream()
.filter(p -> p != client.player)
.map(PlayerEntity::getUuid)
.toList();
CapeSyncManager.batchFetchCapes(playerUUIDs);
context.getSource().sendFeedback(Text.literal(
"§aFetching capes for §e" + playerUUIDs.size() + "§a players..."
));
return 1;
})
)
);
citrusCommand.then(LiteralArgumentBuilder.<FabricClientCommandSource>literal("status")
.executes(context -> {
context.getSource().sendFeedback(Text.literal("--- §aCitrus Status §7---"));
context.getSource().sendFeedback(Text.literal(""));
boolean healthy = CapeSyncManager.isIsHealthy();
String serverHealth = healthy
? "§ahealthy"
: "§cexperiencing issues or is offline";
context.getSource().sendFeedback(Text.literal("CapeSync Server: " + serverHealth));
int capesAvailable = CapeHandler.getAvailableCapes().size();
context.getSource().sendFeedback(Text.literal("§aCapes available: §e" + capesAvailable));
MinecraftClient client = MinecraftClient.getInstance();
if (client.player != null) {
String activeWings = de.winniepat.citrus.cosmetics.wings.ClientWingManager.getActiveWings(client.player.getUuid());
boolean wingsVisible = ClientWingManager.areWingsVisible(client.player.getUuid());
String wingStatus = "§aWing type: §e" + activeWings + "§a, " + (wingsVisible ? "§avisible" : "§chidden");
context.getSource().sendFeedback(Text.literal(wingStatus));
}
String registrationStatus = getRegistrationStatus(healthy);
context.getSource().sendFeedback(Text.literal("Registration: " + registrationStatus));
return 1;
})
);
dispatcher.register(citrusCommand);
});
}
private static @NotNull String getRegistrationStatus(boolean healthy) {
boolean registered = ClientRegistrationManager.isRegistered();
String registrationStatus = registered
? "§aYou are registered with the Citrus API"
: "§cYou are not registered with the Citrus API";
if (!healthy && registered) {
registrationStatus += " §7(§eStatus may be inaccurate because Backend has issues or is offline§7)";
}
return registrationStatus;
}
}