|
| 1 | +package net.azisaba.interchatmod.fabric; |
| 2 | + |
| 3 | +import com.mojang.brigadier.arguments.StringArgumentType; |
| 4 | +import com.mojang.brigadier.builder.LiteralArgumentBuilder; |
| 5 | +import net.azisaba.interchatmod.common.model.Guild; |
| 6 | +import net.azisaba.interchatmod.common.model.GuildMember; |
| 7 | +import net.azisaba.interchatmod.common.util.Constants; |
| 8 | +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; |
| 9 | +import net.minecraft.command.CommandSource; |
| 10 | +import net.minecraft.text.ClickEvent; |
| 11 | +import net.minecraft.text.HoverEvent; |
| 12 | +import net.minecraft.text.Text; |
| 13 | +import net.minecraft.util.Formatting; |
| 14 | + |
| 15 | +import java.util.Collections; |
| 16 | +import java.util.Locale; |
| 17 | +import java.util.Set; |
| 18 | +import java.util.function.Consumer; |
| 19 | +import java.util.stream.Collectors; |
| 20 | +import java.util.stream.Stream; |
| 21 | + |
| 22 | +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; |
| 23 | +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; |
| 24 | + |
| 25 | +public class Commands { |
| 26 | + public static LiteralArgumentBuilder<FabricClientCommandSource> builderGS() { |
| 27 | + return literal("cgs") |
| 28 | + .then(argument("guild", StringArgumentType.word()) |
| 29 | + .suggests((ctx, builder) -> CommandSource.suggestMatching(Mod.GUILDS.stream().map(Guild::name), builder)) |
| 30 | + .executes(ctx -> executeFocus(ctx.getSource(), StringArgumentType.getString(ctx, "guild"))) |
| 31 | + .then(argument("message", StringArgumentType.greedyString()) |
| 32 | + .executes(ctx -> executeChat(ctx.getSource(), StringArgumentType.getString(ctx, "guild"), StringArgumentType.getString(ctx, "message"))) |
| 33 | + ) |
| 34 | + ); |
| 35 | + } |
| 36 | + |
| 37 | + public static LiteralArgumentBuilder<FabricClientCommandSource> builderG() { |
| 38 | + return literal("cg") |
| 39 | + .then(argument("message", StringArgumentType.greedyString()) |
| 40 | + .executes(ctx -> executeChat(ctx.getSource(), null, StringArgumentType.getString(ctx, "message"))) |
| 41 | + ); |
| 42 | + } |
| 43 | + |
| 44 | + public static LiteralArgumentBuilder<FabricClientCommandSource> builderReconnectInterChat() { |
| 45 | + return literal("reconnectinterchat") |
| 46 | + .executes(ctx -> { |
| 47 | + Mod.reconnect(); |
| 48 | + return 0; |
| 49 | + }) |
| 50 | + .then(argument("apikey", StringArgumentType.greedyString()) |
| 51 | + .executes(ctx -> { |
| 52 | + Mod.CONFIG.apiKey(StringArgumentType.getString(ctx, "apikey")); |
| 53 | + Mod.reconnect(); |
| 54 | + return 0; |
| 55 | + }) |
| 56 | + ); |
| 57 | + } |
| 58 | + |
| 59 | + public static LiteralArgumentBuilder<FabricClientCommandSource> builderGuild() { |
| 60 | + return literal("cguild") |
| 61 | + .then(literal("invite") |
| 62 | + .then(argument("player", StringArgumentType.word()) |
| 63 | + .executes(ctx -> { |
| 64 | + Mod.client.invite(StringArgumentType.getString(ctx, "player")); |
| 65 | + return 0; |
| 66 | + }) |
| 67 | + ) |
| 68 | + ) |
| 69 | + .then(literal("accept") |
| 70 | + .then(argument("guild", StringArgumentType.word()) |
| 71 | + .executes(ctx -> { |
| 72 | + Mod.client.respondInvite(StringArgumentType.getString(ctx, "guild"), true); |
| 73 | + return 0; |
| 74 | + }) |
| 75 | + ) |
| 76 | + ) |
| 77 | + .then(literal("reject") |
| 78 | + .then(argument("guild", StringArgumentType.word()) |
| 79 | + .executes(ctx -> { |
| 80 | + Mod.client.respondInvite(StringArgumentType.getString(ctx, "guild"), false); |
| 81 | + return 0; |
| 82 | + }) |
| 83 | + ) |
| 84 | + ) |
| 85 | + .then(literal("nick") |
| 86 | + .executes(ctx -> { |
| 87 | + Mod.client.nick(null); |
| 88 | + return 0; |
| 89 | + }) |
| 90 | + .then(argument("nickname", StringArgumentType.greedyString()) |
| 91 | + .executes(ctx -> { |
| 92 | + Mod.client.nick(StringArgumentType.getString(ctx, "nickname")); |
| 93 | + return 0; |
| 94 | + }) |
| 95 | + ) |
| 96 | + ) |
| 97 | + .then(literal("jp-on") |
| 98 | + .executes(ctx -> { |
| 99 | + Mod.client.toggleTranslate(true); |
| 100 | + return 0; |
| 101 | + }) |
| 102 | + ) |
| 103 | + .then(literal("jp-off") |
| 104 | + .executes(ctx -> { |
| 105 | + Mod.client.toggleTranslate(false); |
| 106 | + return 0; |
| 107 | + }) |
| 108 | + ) |
| 109 | + .then(literal("role") |
| 110 | + .then(argument("member", StringArgumentType.word()) |
| 111 | + .suggests((ctx, builder) -> { |
| 112 | + var set = Mod.guildMembers.getOrDefault(Mod.client.getSelectedGuild(), Collections.emptySet()); |
| 113 | + return CommandSource.suggestMatching(set.stream().map(GuildMember::name), builder); |
| 114 | + }) |
| 115 | + .then(argument("role", StringArgumentType.word()) |
| 116 | + .suggests((ctx, builder) -> CommandSource.suggestMatching(Stream.of("owner", "moderator", "member"), builder)) |
| 117 | + .executes(ctx -> { |
| 118 | + Mod.client.role(StringArgumentType.getString(ctx, "member"), StringArgumentType.getString(ctx, "role")); |
| 119 | + return 0; |
| 120 | + }) |
| 121 | + ) |
| 122 | + ) |
| 123 | + ) |
| 124 | + .then(literal("toggleinvites") |
| 125 | + .executes(ctx -> { |
| 126 | + Mod.client.toggleInvites(); |
| 127 | + return 0; |
| 128 | + }) |
| 129 | + ) |
| 130 | + .then(literal("hide-guild") |
| 131 | + .executes(ctx -> { |
| 132 | + Mod.client.hideGuild(); |
| 133 | + return 0; |
| 134 | + }) |
| 135 | + ) |
| 136 | + .then(literal("hideall") |
| 137 | + .executes(ctx -> { |
| 138 | + Mod.client.hideAll(""); |
| 139 | + return 0; |
| 140 | + }) |
| 141 | + .then(argument("duration", StringArgumentType.greedyString()) |
| 142 | + .executes(ctx -> { |
| 143 | + Mod.client.hideAll(StringArgumentType.getString(ctx, "duration")); |
| 144 | + return 0; |
| 145 | + }) |
| 146 | + ) |
| 147 | + ) |
| 148 | + .then(literal("format") |
| 149 | + .then(argument("format", StringArgumentType.greedyString()) |
| 150 | + .suggests((ctx, builder) -> CommandSource.suggestMatching(Constants.FORMAT_VARIABLES.stream(), builder)) |
| 151 | + .executes(ctx -> { |
| 152 | + Mod.client.format(StringArgumentType.getString(ctx, "format")); |
| 153 | + return 0; |
| 154 | + }) |
| 155 | + ) |
| 156 | + ) |
| 157 | + .then(literal("info").executes(ctx -> executeInfo(ctx.getSource()))) |
| 158 | + ; |
| 159 | + } |
| 160 | + |
| 161 | + private static int executeInfo(FabricClientCommandSource source) { |
| 162 | + Guild guild = Mod.GUILDS.stream().filter(g -> g.id() == Mod.client.getSelectedGuild()).findAny().orElse(null); |
| 163 | + if (guild == null) { |
| 164 | + source.sendError(Text.literal("無効なギルドが指定されています。/cgs (ギルド)で選択してください。")); |
| 165 | + return 0; |
| 166 | + } |
| 167 | + Set<GuildMember> members = Mod.guildMembers.getOrDefault(guild.id(), Collections.emptySet()); |
| 168 | + source.sendFeedback( |
| 169 | + Text.literal("--- ギルド").formatted(Formatting.GOLD) |
| 170 | + .append(Text.literal(guild.name()).formatted(Formatting.AQUA)) |
| 171 | + .append(Text.literal("の情報 ---").formatted(Formatting.GOLD)) |
| 172 | + ); |
| 173 | + source.sendFeedback( |
| 174 | + Text.literal("メンバー数: ").formatted(Formatting.GOLD) |
| 175 | + .append(Text.literal(String.valueOf(members.size())).formatted(Formatting.RED)) |
| 176 | + .append(Text.literal("/").formatted(Formatting.GOLD)) |
| 177 | + .append(Text.literal(String.valueOf(guild.capacity())).formatted(Formatting.RED)) |
| 178 | + ); |
| 179 | + Consumer<String> sendRole = (role) -> { |
| 180 | + String players = |
| 181 | + members.stream() |
| 182 | + .filter(m -> m.role().equals(role.toUpperCase(Locale.ROOT))) |
| 183 | + .map(GuildMember::name) |
| 184 | + .collect(Collectors.joining(", ")); |
| 185 | + source.sendFeedback( |
| 186 | + Text.literal(role + ": ").formatted(Formatting.GOLD) |
| 187 | + .append(Text.literal(players).formatted(Formatting.WHITE)) |
| 188 | + ); |
| 189 | + }; |
| 190 | + sendRole.accept("Owner"); |
| 191 | + sendRole.accept("Moderator"); |
| 192 | + sendRole.accept("Member"); |
| 193 | + source.sendFeedback(Text.empty()); |
| 194 | + source.sendFeedback( |
| 195 | + Text.literal("公開: ").formatted(Formatting.GOLD) |
| 196 | + .append(Text.literal(String.valueOf(guild.open())).formatted(guild.open() ? Formatting.GREEN : Formatting.RED)) |
| 197 | + ); |
| 198 | + source.sendFeedback( |
| 199 | + Text.literal("チャット形式: ").formatted(Formatting.GOLD) |
| 200 | + .append(Text.literal(guild.format()) |
| 201 | + .formatted(Formatting.WHITE) |
| 202 | + .styled(style -> |
| 203 | + style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal("クリックでコピー"))) |
| 204 | + .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, guild.format())) |
| 205 | + ) |
| 206 | + ) |
| 207 | + ); |
| 208 | + return members.size(); |
| 209 | + } |
| 210 | + |
| 211 | + private static int executeFocus(FabricClientCommandSource source, String guildName) { |
| 212 | + Guild guild = Mod.GUILDS.stream().filter(g -> g.name().equalsIgnoreCase(guildName)).findAny().orElse(null); |
| 213 | + if (guild == null) { |
| 214 | + source.sendError(Text.literal("そんなぎるどないよ " + guildName)); |
| 215 | + return 0; |
| 216 | + } |
| 217 | + Mod.client.selectGuild(guild.id()); |
| 218 | + source.sendFeedback(Text.literal(guild.name() + " にちゃっとするようにしたよ(/cg <めっせーじ>でできるよ)")); |
| 219 | + return 1; |
| 220 | + } |
| 221 | + |
| 222 | + private static int executeChat(FabricClientCommandSource source, String guildName, String message) { |
| 223 | + if (guildName != null) { |
| 224 | + Guild guild = Mod.GUILDS.stream().filter(g -> g.name().equalsIgnoreCase(guildName)).findAny().orElse(null); |
| 225 | + if (guild == null) { |
| 226 | + source.sendError(Text.literal("そんなぎるどないよ " + guildName)); |
| 227 | + return 0; |
| 228 | + } |
| 229 | + Mod.client.sendMessageToGuild(guild.id(), message); |
| 230 | + } else { |
| 231 | + Mod.client.sendMessageToGuild(null, message); |
| 232 | + } |
| 233 | + return 1; |
| 234 | + } |
| 235 | +} |
0 commit comments