diff --git a/src/main/java/com/createcivilization/capitol/common/config/CapitolConfig.java b/src/main/java/com/createcivilization/capitol/common/config/CapitolConfig.java index cf465a3..e04639c 100644 --- a/src/main/java/com/createcivilization/capitol/common/config/CapitolConfig.java +++ b/src/main/java/com/createcivilization/capitol/common/config/CapitolConfig.java @@ -48,6 +48,14 @@ public class CapitolConfig { public static final ModConfigSpec.ConfigValue> BLOCK_PLACE_EXCEPTIONS; public static final ModConfigSpec.ConfigValue> ITEM_USE_EXCEPTIONS; + // Roles + + public static final ModConfigSpec.BooleanValue DISPLAY_TAGS_IN_CHAT; + public static final ModConfigSpec.BooleanValue DISPLAY_TAGS_IN_TAB_LIST; + + // Teams + public static final ModConfigSpec.IntValue TEAM_TAG_MAX_LENGTH; + public enum ListType { ONLY, ALL_BUT @@ -169,6 +177,26 @@ public enum ListType { builder.pop(); + builder.comment("Role settings").push("roles"); + + DISPLAY_TAGS_IN_CHAT = builder + .comment("Whether chat messages with have the players team tag attached.") + .define("displayTagsInChat", true); + + DISPLAY_TAGS_IN_TAB_LIST = builder + .comment("Whether the tab list will have the players team tag attached.") + .define("displayTagsInTabList", true); + + builder.pop(); + + builder.comment("Role settings").push("team"); + + TEAM_TAG_MAX_LENGTH = builder + .comment("Max length for a team to have as a tag.") + .defineInRange("teamTagMaxLength", 3, 0, 16); + + builder.pop(); + SPEC = builder.build(); } } diff --git a/src/main/java/com/createcivilization/capitol/common/data/TeamRole.java b/src/main/java/com/createcivilization/capitol/common/data/TeamRole.java index 3b21122..fe91971 100644 --- a/src/main/java/com/createcivilization/capitol/common/data/TeamRole.java +++ b/src/main/java/com/createcivilization/capitol/common/data/TeamRole.java @@ -1,10 +1,11 @@ package com.createcivilization.capitol.common.data; +import java.awt.*; import java.sql.ResultSet; import java.sql.SQLException; import java.util.UUID; -public record TeamRole(int id, UUID teamId, String name, long permissions) { +public record TeamRole(int id, UUID teamId, String name, long permissions, Color color) { public static final String OWNER_ROLE_NAME = "owner"; public static final String DEFAULT_ROLE_NAME = "default"; @@ -22,11 +23,17 @@ public boolean hasPermission(Permission perm) { } public static TeamRole fromResultSet(ResultSet rs) throws SQLException { + Color color = null; + if (rs.getInt("color") != -1) { + color = new Color(rs.getInt("color")); + } + return new TeamRole( rs.getInt("id"), UUID.fromString(rs.getString("team_id")), rs.getString("name"), - rs.getLong("permissions") + rs.getLong("permissions"), + color ); } diff --git a/src/main/java/com/createcivilization/capitol/common/managers/DatabaseManager.java b/src/main/java/com/createcivilization/capitol/common/managers/DatabaseManager.java index 66eceb0..95d7cfb 100644 --- a/src/main/java/com/createcivilization/capitol/common/managers/DatabaseManager.java +++ b/src/main/java/com/createcivilization/capitol/common/managers/DatabaseManager.java @@ -67,6 +67,7 @@ private static void createTables() throws SQLException { "team_id TEXT NOT NULL," + "name TEXT NOT NULL," + "permissions INTEGER NOT NULL DEFAULT 0," + + "color INTEGER NOT NULL DEFAULT -1,"+ "UNIQUE (team_id, name)," + "FOREIGN KEY (team_id) REFERENCES teams (id) ON DELETE CASCADE)" ); diff --git a/src/main/java/com/createcivilization/capitol/common/modules/database/CapitolDatabase.java b/src/main/java/com/createcivilization/capitol/common/modules/database/CapitolDatabase.java index 0c52f20..21705f8 100644 --- a/src/main/java/com/createcivilization/capitol/common/modules/database/CapitolDatabase.java +++ b/src/main/java/com/createcivilization/capitol/common/modules/database/CapitolDatabase.java @@ -8,9 +8,11 @@ import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; +import java.awt.*; import java.sql.*; import java.time.Instant; import java.util.*; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; public class CapitolDatabase extends Database { @@ -78,19 +80,31 @@ public void setTeamPermissions(Team team, long permissions) { * @param team the team this role belongs to * @param name the role name (e.g. "owner", "default") * @param permissions the bitfield of {@link Permission} flags + * @param color the color this role will override to for nation tags */ - public void addRole(Team team, String name, long permissions) { + public void addRole(Team team, String name, long permissions, Color color) { try (PreparedStatement ps = getConnection().prepareStatement( - "INSERT INTO team_roles (team_id, name, permissions) VALUES (?, ?, ?)")) { + "INSERT INTO team_roles (team_id, name, permissions, color) VALUES (?, ?, ?, ?)")) { ps.setString(1, team.getId().toString()); ps.setString(2, name); ps.setLong(3, permissions); + ps.setInt(4, color == null ? -1 : color.getRGB()); // -1 if the role has no associated color ps.execute(); } catch (SQLException e) { Capitol.LOGGER.error("Error while adding role to database.", e); throw new RuntimeException(e); } } + /** + * Inserts a new role into the {@code team_roles} table. + * + * @param team the team this role belongs to + * @param name the role name (e.g. "owner", "default") + * @param permissions the bitfield of {@link Permission} flags + */ + public void addRole(Team team, String name, long permissions) { + addRole(team, name, permissions, null); + } /** * Retrieves a role by its auto-incremented database ID. @@ -200,6 +214,19 @@ public void updateRoleName(Team team, String roleName, String newName) { } } + public void updateRoleColor(Team team, String roleName, Color color) { + try (PreparedStatement ps = getConnection().prepareStatement( + "UPDATE team_roles SET color = ? WHERE team_id = ? AND name = ?")) { + ps.setInt(1, color == null ? -1 : color.getRGB()); + ps.setString(2, team.getId().toString()); + ps.setString(3, roleName); + ps.execute(); + } catch (SQLException e) { + Capitol.LOGGER.error("Error while updating role color in database.", e); + throw new RuntimeException(e); + } + } + /** * Deletes a role by team and role name. * @@ -308,7 +335,7 @@ public void addTeam(Team team) { throw new RuntimeException(e); } - addRole(team, TeamRole.OWNER_ROLE_NAME, TeamRole.ownerPermissions()); + addRole(team, TeamRole.OWNER_ROLE_NAME, TeamRole.ownerPermissions(), new Color(0x800080)); addRole(team, TeamRole.DEFAULT_ROLE_NAME, TeamRole.defaultPermissions()); } diff --git a/src/main/java/com/createcivilization/capitol/server/commands/claim/ClaimCommand.java b/src/main/java/com/createcivilization/capitol/server/commands/claim/ClaimCommand.java index d8899b7..880ef68 100644 --- a/src/main/java/com/createcivilization/capitol/server/commands/claim/ClaimCommand.java +++ b/src/main/java/com/createcivilization/capitol/server/commands/claim/ClaimCommand.java @@ -175,10 +175,10 @@ private static int auto(CommandContext context) { if (AutoClaimEvents.isAutoClaimer(player)) { AutoClaimEvents.removeAutoClaimer(player); - context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.claim.auto_claim.stop").withStyle(ChatFormatting.GREEN), true); + context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.claim.auto_claiming.stop").withStyle(ChatFormatting.GREEN), true); } else { AutoClaimEvents.updateAutoClaimer(player); - context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.claim.auto_claim.start").withStyle(ChatFormatting.GREEN), true); + context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.claim.auto_claiming.start").withStyle(ChatFormatting.GREEN), true); } return 1; } diff --git a/src/main/java/com/createcivilization/capitol/server/commands/help/HelpCommand.java b/src/main/java/com/createcivilization/capitol/server/commands/help/HelpCommand.java index ba66b4f..d90fc50 100644 --- a/src/main/java/com/createcivilization/capitol/server/commands/help/HelpCommand.java +++ b/src/main/java/com/createcivilization/capitol/server/commands/help/HelpCommand.java @@ -31,7 +31,7 @@ private static int showHelp(CommandContext context) { msg.append(entry("/capitol team invite ", Component.translatable("commands.capitol.help.team.invite"))); msg.append(entry("/capitol team kick ", Component.translatable("commands.capitol.help.team.kick"))); msg.append(entry("/capitol team disband", Component.translatable("commands.capitol.help.team.disband"))); - msg.append(entry("/capitol team role edit remove|rename|assign|permission", Component.translatable("commands.capitol.help.team.role.edit"))); + msg.append(entry("/capitol team role edit remove|rename|assign|permission|list", Component.translatable("commands.capitol.help.team.role.edit"))); msg.append(entry("/capitol team role create ", Component.translatable("commands.capitol.help.team.role.create"))); msg.append(entry("/capitol team protection ", Component.translatable("commands.capitol.help.team.protection"))); msg.append(entry("/capitol team player permission ", Component.translatable("commands.capitol.help.team.player.permission"))); diff --git a/src/main/java/com/createcivilization/capitol/server/commands/invite/InviteCommand.java b/src/main/java/com/createcivilization/capitol/server/commands/invite/InviteCommand.java index 2c4fad9..43f9ff9 100644 --- a/src/main/java/com/createcivilization/capitol/server/commands/invite/InviteCommand.java +++ b/src/main/java/com/createcivilization/capitol/server/commands/invite/InviteCommand.java @@ -38,7 +38,7 @@ public static LiteralArgumentBuilder register() { } private static int acceptInvite(CommandContext context) { - Player player = context.getSource().getPlayer(); + ServerPlayer player = context.getSource().getPlayer(); if (player == null) return 0; Team team = resolveInvitedTeam(context, player); @@ -48,6 +48,9 @@ private static int acceptInvite(CommandContext context) { DatabaseManager.database.addPlayerToTeam(player, team, role); InviteHandler.clearInvites(player); + player.refreshDisplayName(); + player.refreshTabListName(); // needs to be a ServerPlayer for this. + MutableComponent joinMsg = Component.translatable("commands.capitol.invites.join.announcement", Component.literal(player.getName().getString()).withStyle(ChatFormatting.WHITE), Component.literal(team.getName()).withStyle(ChatFormatting.GOLD)) diff --git a/src/main/java/com/createcivilization/capitol/server/commands/team/TeamCommand.java b/src/main/java/com/createcivilization/capitol/server/commands/team/TeamCommand.java index 9dcd61f..b3f7de3 100644 --- a/src/main/java/com/createcivilization/capitol/server/commands/team/TeamCommand.java +++ b/src/main/java/com/createcivilization/capitol/server/commands/team/TeamCommand.java @@ -1,5 +1,6 @@ package com.createcivilization.capitol.server.commands.team; +import com.createcivilization.capitol.common.config.CapitolConfig; import com.createcivilization.capitol.common.data.*; import com.createcivilization.capitol.common.managers.DatabaseManager; import com.createcivilization.capitol.common.modules.database.CapitolDatabase; @@ -198,6 +199,11 @@ private static int createTeam(CommandContext context) { ).replace("#", ""); String tag = StringArgumentType.getString(context, "tag"); + if (tag.length() > CapitolConfig.TEAM_TAG_MAX_LENGTH.get()) { + context.getSource().sendFailure(Component.translatable("commands.capitol.team.create.tag_too_long", CapitolConfig.TEAM_TAG_MAX_LENGTH.get()).withStyle(ChatFormatting.RED)); + return 0; + } + String description; try { description = StringArgumentType.getString(context, "description"); @@ -339,4 +345,8 @@ private static int confirmDisband(CommandContext context) { context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.disband.success").withStyle(ChatFormatting.GREEN), true); return 1; } + + public static Map getNamedColors() { + return NAMED_COLORS; + } } \ No newline at end of file diff --git a/src/main/java/com/createcivilization/capitol/server/commands/team/TeamRoleCommand.java b/src/main/java/com/createcivilization/capitol/server/commands/team/TeamRoleCommand.java index d7b7912..805f274 100644 --- a/src/main/java/com/createcivilization/capitol/server/commands/team/TeamRoleCommand.java +++ b/src/main/java/com/createcivilization/capitol/server/commands/team/TeamRoleCommand.java @@ -10,13 +10,18 @@ import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; +import net.minecraft.network.chat.*; import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.GameProfileCache; +import java.awt.*; import java.util.List; import java.util.Objects; import java.util.Optional; +import static com.createcivilization.capitol.common.managers.DatabaseManager.database; + class TeamRoleCommand { static LiteralArgumentBuilder register() { @@ -26,52 +31,111 @@ static LiteralArgumentBuilder register() { .executes(TeamRoleCommand::createRole))) .then(Commands.literal("edit") .then(Commands.argument("role_name", StringArgumentType.word()) - .suggests((context, builder) -> { - CapitolDatabase database = DatabaseManager.database; - Team team = database.getPlayerTeam(context.getSource().getPlayer()); - if (team == null) { - builder.suggest("YOU ARE NOT IN A TEAM"); + .suggests((context, builder) -> { + CapitolDatabase database = DatabaseManager.database; + Team team = database.getPlayerTeam(context.getSource().getPlayer()); + if (team == null) { + builder.suggest(Component.translatable("commands.capitol.not_in_team_error").toString()); + return builder.buildFuture(); + } + List roles = database.getTeamRoles(team); + for (TeamRole role : roles) { + builder.suggest(role.name()); + } return builder.buildFuture(); - } - List roles = database.getTeamRoles(team); - for (TeamRole role : roles) { - builder.suggest(role.name()); - } - return builder.buildFuture(); - }) - .then(Commands.literal("assign") - .then(Commands.argument("player", StringArgumentType.string()) - .suggests((context, builder) -> { - CapitolDatabase database = DatabaseManager.database; - Team team = database.getPlayerTeam(context.getSource().getPlayer()); - if (team == null) { - builder.suggest("YOU ARE NOT IN A TEAM"); + }) + .then(Commands.literal("assign") + .then(Commands.argument("player", StringArgumentType.string()) + .suggests((context, builder) -> { + CapitolDatabase database = DatabaseManager.database; + Team team = database.getPlayerTeam(context.getSource().getPlayer()); + if (team == null) { + builder.suggest(Component.translatable("commands.capitol.not_in_team_error").toString()); + return builder.buildFuture(); + } + List members = database.getTeamMembers(team); + GameProfileCache profileCache = context.getSource().getServer().getProfileCache(); + for (TeamMember member : members) { + profileCache.get(member.playerUUID()).ifPresent( + gameProfile -> builder.suggest(gameProfile.getName()) + ); + } return builder.buildFuture(); - } - List members = database.getTeamMembers(team); - GameProfileCache profileCache = context.getSource().getServer().getProfileCache(); - for (TeamMember member : members) { - profileCache.get(member.playerUUID()).ifPresent( - gameProfile -> builder.suggest(gameProfile.getName()) - ); - } - return builder.buildFuture(); - }) - .executes(TeamRoleCommand::assignRole))) - .then(Commands.literal("permission") - .then(Commands.argument("permission_value", StringArgumentType.word()) - .suggests((context, builder) -> { - for (Permission perm : Permission.values()) { - builder.suggest(perm.name().toLowerCase()); - } - return builder.buildFuture(); - }) - .executes(TeamRoleCommand::editRolePerms))) - .then(Commands.literal("name") - .then(Commands.argument("new_name", StringArgumentType.string()) - .executes(TeamRoleCommand::editRoleName))) - .then(Commands.literal("remove") - .executes(TeamRoleCommand::removeRole)))); + }) + .executes(TeamRoleCommand::assignRole))) + .then(Commands.literal("permission") + .then(Commands.argument("permission_value", StringArgumentType.word()) + .suggests((context, builder) -> { + for (Permission perm : Permission.values()) { + builder.suggest(perm.name().toLowerCase()); + } + return builder.buildFuture(); + }) + .executes(TeamRoleCommand::editRolePerms))) + .then(Commands.literal("list").executes(TeamRoleCommand::viewRolePermList)) + .then(Commands.literal("name") + .then(Commands.argument("new_name", StringArgumentType.string()) + .executes(TeamRoleCommand::editRoleName))) + .then(Commands.literal("remove") + .executes(TeamRoleCommand::removeRole)) + .then(Commands.literal("color") + .then(Commands.argument("new_color", StringArgumentType.string()) + .suggests((context, builder) -> { + TeamCommand.getNamedColors().keySet().forEach(builder::suggest); + builder.suggest("none"); + return builder.buildFuture(); + }) + .executes(TeamRoleCommand::setColor))) + )); + + } + + private static int setColor(CommandContext context) { + CapitolDatabase database = DatabaseManager.database; + var player = context.getSource().getPlayer(); + if (player == null) { + return failCommand(context, "commands.capitol.command_source_was_console_error"); + } + + Team team = database.getPlayerTeam(player); + if (team == null) { + return failCommand(context, "commands.capitol.not_in_team_error"); + } + + if (!Permission.MANAGE_ROLES.hasPermission(database.getPlayerPermission(player, team))) { + return failCommand(context, "commands.capitol.team.role.no_manage_permission"); + } + String roleName = StringArgumentType.getString(context, "role_name"); + + TeamRole role = database.getRoleByName(team, roleName); + + if (role == null) { + return failCommand(context, "commands.capitol.team.role.color.failure", roleName, team.getName()); + } + + if (StringArgumentType.getString(context, "new_color").equalsIgnoreCase("none")) { + database.updateRoleColor(team, roleName, null); + + context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.role.color.clear.success", + Component.literal(roleName).withStyle(ChatFormatting.AQUA)), true); + } else { + String hex = TeamCommand.getNamedColors().getOrDefault( + StringArgumentType.getString(context, "new_color").toLowerCase(), + StringArgumentType.getString(context, "new_color") + ).replace("#", ""); + Color color = new Color(Integer.parseInt(hex, 16), true); + + database.updateRoleColor(team, roleName, color); + + context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.role.color.success", + Component.literal(roleName).withStyle(ChatFormatting.AQUA), + Component.literal(hex).withStyle(style -> style.withColor(TextColor.fromRgb(color.getRGB()))) + .withStyle(ChatFormatting.GRAY)), true); + } + + refreshTeamPlayers(context, team); + + return 1; } private static int createRole(CommandContext context) { @@ -93,8 +157,8 @@ private static int createRole(CommandContext context) { database.addRole(team, roleName, 0); context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.role.create.success", - Component.literal(roleName).withStyle(ChatFormatting.AQUA), - Component.literal(team.getName()).withStyle(ChatFormatting.GOLD)) + Component.literal(roleName).withStyle(ChatFormatting.AQUA), + Component.literal(team.getName()).withStyle(ChatFormatting.GOLD)) .withStyle(ChatFormatting.GRAY), true); return 1; } @@ -132,8 +196,10 @@ private static int removeRole(CommandContext context) { database.deleteRole(team, roleName); + refreshTeamPlayers(context, team); + context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.role.remove.success", - Component.literal(roleName).withStyle(ChatFormatting.AQUA)) + Component.literal(roleName).withStyle(ChatFormatting.AQUA)) .withStyle(ChatFormatting.GRAY), true); return 1; } @@ -182,9 +248,16 @@ private static int assignRole(CommandContext context) { database.updatePlayerRole(gameProfile.getId(), team, role); + ServerPlayer target = context.getSource().getServer().getPlayerList().getPlayer(gameProfile.getId()); // Specifically refreshes the targeted player + if (target != null) { + target.refreshTabListName(); + target.refreshDisplayName(); + } + + context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.role.assign.success", - Component.literal(gameProfile.getName()).withStyle(ChatFormatting.WHITE), - Component.literal(roleName).withStyle(ChatFormatting.AQUA)) + Component.literal(gameProfile.getName()).withStyle(ChatFormatting.WHITE), + Component.literal(roleName).withStyle(ChatFormatting.AQUA)) .withStyle(ChatFormatting.GRAY), true); return 1; } @@ -225,8 +298,8 @@ private static int editRoleName(CommandContext context) { database.updateRoleName(team, roleName, newRoleName); context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.team.role.name.success", - Component.literal(roleName).withStyle(ChatFormatting.AQUA), - Component.literal(newRoleName).withStyle(ChatFormatting.AQUA)) + Component.literal(roleName).withStyle(ChatFormatting.AQUA), + Component.literal(newRoleName).withStyle(ChatFormatting.AQUA)) .withStyle(ChatFormatting.GRAY), true); return 1; } @@ -270,14 +343,67 @@ private static int editRolePerms(CommandContext context) { database.updateRolePermissions(team, roleName, rolePerms); context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.permission_toggle", - Component.literal(permissionName.toLowerCase()).withStyle(ChatFormatting.AQUA), - Component.literal(roleName).withStyle(ChatFormatting.GOLD), - Component.literal(String.valueOf(oldState)).withStyle(oldState ? ChatFormatting.GREEN : ChatFormatting.RED), - Component.literal(String.valueOf(newState)).withStyle(newState ? ChatFormatting.GREEN : ChatFormatting.RED)) + Component.literal(permissionName.toLowerCase()).withStyle(ChatFormatting.AQUA), + Component.literal(roleName).withStyle(ChatFormatting.GOLD), + Component.literal(String.valueOf(oldState)).withStyle(oldState ? ChatFormatting.GREEN : ChatFormatting.RED), + Component.literal(String.valueOf(newState)).withStyle(newState ? ChatFormatting.GREEN : ChatFormatting.RED)) .withStyle(ChatFormatting.GRAY), true); return 1; } + private static int viewRolePermList(CommandContext context) { + CapitolDatabase database = DatabaseManager.database; + ServerPlayer player = context.getSource().getPlayer(); + if (player == null) { + return failCommand(context, "commands.capitol.not_player"); + } + Team team = database.getPlayerTeam(player); + if (team == null) { + return failCommand(context, "commands.capitol.not_in_team_error"); + } + + String roleName = StringArgumentType.getString(context, "role_name"); + TeamRole role = database.getRoleByName(team, roleName); + + if (role == null) { + return failCommand(context, "commands.capitol.team.role.not_found", roleName, team.getName()); + } + + context.getSource().sendSuccess(() -> + Component.translatable("commands.capitol.team.role.permission_list.role").append(roleName).withStyle(ChatFormatting.GOLD) + , false); + + for (Permission perm : Permission.values()) { + MutableComponent comp = Component.literal("[").append(perm.hasPermission(role.permissions()) ? Component.literal("✔").withStyle(ChatFormatting.GREEN) : Component.literal("❌").withStyle(ChatFormatting.RED)).append("]"); + comp.withStyle(s -> s.withClickEvent( + new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/capitol team role edit %s permission %s", roleName, perm.name().toLowerCase())) + ).withHoverEvent( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("commands.capitol.team.role.permission_list.hover")) + )); + context.getSource().sendSuccess(() -> + comp.append(Component.literal(" ").withStyle(ChatFormatting.GOLD)).append(Component.literal(perm.name()).withStyle(ChatFormatting.WHITE)) + , false); + } + + /*context.getSource().sendSuccess(() -> Component.translatable("commands.capitol.permission_toggle", + Component.literal(permissionName.toLowerCase()).withStyle(ChatFormatting.AQUA), + Component.literal(roleName).withStyle(ChatFormatting.GOLD), + Component.literal(String.valueOf(oldState)).withStyle(oldState ? ChatFormatting.GREEN : ChatFormatting.RED), + Component.literal(String.valueOf(newState)).withStyle(newState ? ChatFormatting.GREEN : ChatFormatting.RED)) + .withStyle(ChatFormatting.GRAY), true);*/ + return 1; + } + + public static void refreshTeamPlayers(CommandContext context, Team team) { + for (TeamMember member : database.getTeamMembers(team)) { + ServerPlayer online = context.getSource().getServer().getPlayerList().getPlayer(member.playerUUID()); + if (online != null) { + online.refreshDisplayName(); + online.refreshTabListName(); + } + } + } + static int failCommand(CommandContext context, String key, Object... args) { context.getSource().sendFailure(Component.translatable(key, args).withStyle(ChatFormatting.RED)); return 0; diff --git a/src/main/java/com/createcivilization/capitol/server/events/AutoClaimEvents.java b/src/main/java/com/createcivilization/capitol/server/events/AutoClaimEvents.java index 70385db..23fe886 100644 --- a/src/main/java/com/createcivilization/capitol/server/events/AutoClaimEvents.java +++ b/src/main/java/com/createcivilization/capitol/server/events/AutoClaimEvents.java @@ -32,7 +32,7 @@ public static void onEntityEnterSection(EntityEvent.EnteringSection event) { } if (isAutoClaimer(player)) { if (Calendar.getInstance().getTimeInMillis() - autoClaimingPlayers.get(player.getUUID()) < CapitolConfig.AUTO_CLAIM_COOLDOWN.get() * 1000) { - player.displayClientMessage(Component.translatable("commands.capitol.claim.auto_claim.too_fast").withStyle(ChatFormatting.RED), false); + player.displayClientMessage(Component.translatable("commands.capitol.claim.auto_claiming.too_fast").withStyle(ChatFormatting.RED), false); return; } diff --git a/src/main/java/com/createcivilization/capitol/server/events/NameFormatEvents.java b/src/main/java/com/createcivilization/capitol/server/events/NameFormatEvents.java new file mode 100644 index 0000000..6677809 --- /dev/null +++ b/src/main/java/com/createcivilization/capitol/server/events/NameFormatEvents.java @@ -0,0 +1,61 @@ +package com.createcivilization.capitol.server.events; + +import com.createcivilization.capitol.Capitol; +import com.createcivilization.capitol.common.config.CapitolConfig; +import com.createcivilization.capitol.common.data.Team; +import com.createcivilization.capitol.common.data.TeamRole; +import com.createcivilization.capitol.common.managers.DatabaseManager; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextColor; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; + +@EventBusSubscriber(modid = Capitol.MOD_ID, value = Dist.DEDICATED_SERVER) +public class NameFormatEvents { + @SubscribeEvent + public static void onNameFormat(PlayerEvent.NameFormat event) { // Mainly for chat messages + if (!CapitolConfig.DISPLAY_TAGS_IN_CHAT.get()) { + return; + } + + Team team = DatabaseManager.database.getPlayerTeam(event.getEntity().getUUID()); + if (team == null) { + return; + } + TeamRole role = DatabaseManager.database.getPlayerRole(event.getEntity(), team); + + Component prevName = event.getDisplayname(); // the spelling mistake in getDisplayname instead of getDisplayName lmao + Component tag = getTag(team, role); + event.setDisplayname(Component.literal("").append(tag).append(" ").append(prevName)); + } + + @SubscribeEvent + public static void onTabListNameFormat(PlayerEvent.TabListNameFormat event) { // Only for tab list + if (!CapitolConfig.DISPLAY_TAGS_IN_TAB_LIST.get()) { + return; + } + + Team team = DatabaseManager.database.getPlayerTeam(event.getEntity().getUUID()); + if (team == null) { + return; + } + TeamRole role = DatabaseManager.database.getPlayerRole(event.getEntity(), team); + + Component tag = getTag(team, role); + event.setDisplayName(Component.literal("[").append(tag).append("] ").append(event.getEntity().getName())); + } + + public static Component getTag(Team team, TeamRole role) { + TextColor color; + + if (role.color() != null) { + color = TextColor.fromRgb(role.color().getRGB()); + } else { + color = TextColor.fromRgb(team.getColor().getRGB()); + } + + return Component.literal(team.getTag()).withStyle(style -> style.withColor(color)); + } +} diff --git a/src/main/resources/assets/capitol/lang/en_us.json b/src/main/resources/assets/capitol/lang/en_us.json index 515e35d..8063940 100644 --- a/src/main/resources/assets/capitol/lang/en_us.json +++ b/src/main/resources/assets/capitol/lang/en_us.json @@ -18,7 +18,8 @@ "gui.journeymap.capitol.claim_chunk": "Claim chunk", "gui.journeymap.capitol.unclaim_chunk": "Unclaim chunk", -"commands.capitol.not_in_team_error": "You are not in any team", + "commands.capitol.not_player": "You must be a player to run this command.", + "commands.capitol.not_in_team_error": "You are not in any team", "commands.capitol.no_player_found": "There is no player called %s", "commands.capitol.player_not_in_team": "%s is not a member of %s", "commands.capitol.invalid_permission": "%s is not a valid permission.", @@ -38,6 +39,7 @@ "commands.capitol.team.create.already_in_team": "You are already in a team, please leave before creating a new one", "commands.capitol.team.create.name_exists": "A team with that name already exists.", + "commands.capitol.team.create.tag_too_long": "Tag is too long, max length of %d", "commands.capitol.team.create.invalid_color": "Invalid hex color: #%s", "commands.capitol.team.create.success": "Team %s created!", @@ -72,6 +74,12 @@ "commands.capitol.team.role.edit.no_default": "You cannot edit default role name.", "commands.capitol.team.role.name.success": "Renamed role %s → %s", + "commands.capitol.team.role.color.success": "Set role %s's color to %s", + "commands.capitol.team.role.color.clear.success": "Cleared role %s's color", + + "commands.capitol.team.role.permission_list.role": "Role: ", + "commands.capitol.team.role.permission_list.hover": "Click to swap permissions", + "commands.capitol.team.player.no_permission": "You do not have permission to manage individual permissions", "commands.capitol.team.player.perms.reset": "Individual permissions for %s reset to role defaults.",