diff --git a/README.md b/README.md index d6a30bc..dd7d8f6 100644 --- a/README.md +++ b/README.md @@ -1,588 +1,220 @@ -# Guild Plugin - Feature-Complete Minecraft Guild System(需要官方中文翻译请往下滑) +# Guild Plugin - Kompletny system gildii dla Minecrafta -Guild Plugin is a comprehensive Minecraft server plugin that provides a complete guild/clan system for your server. With this plugin, players can create and manage their own guilds, invite members, establish inter-guild relationships, and enjoy various guild features. +Guild Plugin to kompleksowy plugin serwerowy dla Minecrafta, który zapewnia kompletny system gildii/klanów dla twojego serwera. Dzięki temu pluginowi gracze mogą tworzyć i zarządzać własnymi gildiami, zapraszać członków, nawiązywać relacje między gildiami i korzystać z różnych funkcji gildyjnych. -## Core Features +## Główne Funkcje -### Guild Management -- Create and customize guilds (name, tag, description) -- Manage guild members (invite, kick, promote, demote) -- Role-based permission system (Leader, Officer, Member) -- Set and teleport to guild home -- Guild application system +### Zarządzanie Gildią +- Twórz i dostosowuj gildie (nazwa, tag, opis) +- Zarządzaj członkami gildii (zapraszaj, wyrzucaj, awansuj, degraduj) +- System uprawnień oparty na rolach (Lider, Oficer, Członek) +- Ustawiaj i teleportuj się do domu gildii +- System aplikacji do gildii -### Economy System -- Guild fund management (deposit, withdraw, transfer) -- Guild creation fee configuration -- Economy system integration (supports multiple economy plugins via Vault) +### System Ekonomii +- Zarządzanie funduszami gildii (wpłaty, wypłaty, przelewy) +- Konfiguracja opłaty za utworzenie gildii +- Integracja z systemem ekonomii (obsługa wielu pluginów ekonomicznych przez Vault) -### Relationship System -- Inter-guild relationship management (allied, hostile, neutral, at war, truce) -- Relationship status notifications -- War status alerts +### System Relacji +- Zarządzanie relacjami między gildiami (sojusz, wrogość, neutralność, wojna, rozejm) +- Powiadomienia o statusie relacji +- Alerty o stanie wojny -### Leveling System -- Guild level progression -- Increased member capacity -- Unlock additional guild features - -### User Interface -- Complete Graphical User Interface (GUI) -- Intuitive menu system -- Customizable interface configuration - -## Technical Features - -- **Asynchronous Processing**: All database operations are asynchronous, ensuring no impact on server performance -- **Multi-Database Support**: Supports both SQLite and MySQL -- **Placeholder Support**: Integrated with PlaceholderAPI -- **Permission Integration**: Fully compatible with Bukkit permission system -- **High Performance**: Optimized code ensures smooth server operation - -## Commands - -- `/guild` - Main guild command -- `/guildadmin` - Guild administration command - -## Permission Nodes - -- Uses built-in permission system - -## Basic Guild Information Variables - -### Guild Basic Info -- `%guild_name%` - Guild name -- `%guild_tag%` - Guild tag -- `%guild_membercount%` - Current member count -- `%guild_maxmembers%` - Maximum member capacity -- `%guild_level%` - Guild level -- `%guild_balance%` - Guild balance (2 decimal places) -- `%guild_frozen%` - Guild status (Normal/Frozen/No Guild) - -### Player Guild Info -- `%guild_role%` - Player's guild role (Leader/Officer/Member) -- `%guild_joined%` - When player joined the guild -- `%guild_contribution%` - Player's contribution to the guild - -## Guild Status Check Variables - -### Player Status -- `%guild_hasguild%` - Whether player has a guild (Yes/No) -- `%guild_isleader%` - Whether player is leader (Yes/No) -- `%guild_isofficer%` - Whether player is officer (Yes/No) -- `%guild_ismember%` - Whether player is member (Yes/No) - -## Guild Permission Check Variables - -### Permission Status -- `%guild_caninvite%` - Can invite players (Yes/No) -- `%guild_cankick%` - Can kick members (Yes/No) -- `%guild_canpromote%` - Can promote members (Yes/No) -- `%guild_candemote%` - Can demote members (Yes/No) -- `%guild_cansethome%` - Can set guild home (Yes/No) -- `%guild_canmanageeconomy%` - Can manage guild economy (Yes/No) - -## Requirements - -- Minecraft Server Version: 1.21+ -- Java Version: JDK 17+ -- Optional Dependencies: Vault (for economy support), PlaceholderAPI (for placeholder support) - -## Installation Steps - -1. Place the plugin jar file in your server's `plugins` folder -2. Start the server - the plugin will automatically generate configuration files -3. Edit configuration files as needed -4. Restart server to apply changes - - - -## 📋 中文目录 - -- [功能特性](#功能特性) -- [安装指南](#安装指南) -- [配置说明](#配置说明) -- [命令列表](#命令列表) -- [权限节点](#权限节点) -- [GUI界面](#gui界面) -- [经济系统](#经济系统) -- [工会关系](#工会关系) -- [等级系统](#等级系统) -- [数据库](#数据库) -- [常见问题](#常见问题) -- [更新日志](#更新日志) - -## ✨ 功能特性 - -### 核心功能 -- **工会创建与管理**: 支持工会创建、删除、信息查看 -- **成员管理**: 邀请、踢出、提升、降级成员 -- **权限系统**: 基于角色的权限管理(会长、官员、成员) -- **GUI界面**: 完整的图形用户界面,操作便捷 -- **经济系统**: 工会资金管理、存款、取款、转账 -- **等级系统**: 工会等级提升,增加成员上限 -- **关系管理**: 工会间关系(盟友、敌对、中立、开战、停战) -- **工会家**: 设置和传送到工会家 -- **申请系统**: 玩家申请加入工会 - -### 高级功能 -- **异步处理**: 所有数据库操作均为异步,不影响服务器性能 -- **多数据库支持**: 支持SQLite和MySQL -- **占位符支持**: 集成PlaceholderAPI -- **经济集成**: 通过Vault支持多种经济插件 -- **权限集成**: 与Bukkit权限系统完全集成 - -## 🚀 安装指南 - -### 前置要求 -- **Minecraft服务器**: 1.13+ (推荐1.21+) -- **Java**: JDK 8+ (推荐JDK 17+) -- **Vault**: 经济系统支持 (可选) -- **PlaceholderAPI**: 占位符支持 (可选) - -### 安装步骤 - -1. **下载插件** - ```bash - # 从发布页面下载最新版本的jar文件 - # 或使用Maven编译 - mvn clean package - ``` - -2. **安装到服务器** - ```bash - # 将编译好的jar文件放入plugins文件夹 - cp target/guild-plugin-1.0.0.jar plugins/ - ``` - -3. **启动服务器** - ```bash - # 启动服务器,插件会自动生成配置文件 - java -jar server.jar - ``` - -4. **配置插件** - ```bash - # 编辑生成的配置文件 - nano plugins/GuildPlugin/config.yml - nano plugins/GuildPlugin/messages.yml - nano plugins/GuildPlugin/gui.yml - nano plugins/GuildPlugin/database.yml - ``` - -5. **重启服务器** - ```bash - # 重启服务器使配置生效 - restart - ``` - -## ⚙️ 配置说明 - -### 主配置文件 (config.yml) +### System Poziomów +- Rozwój poziomu gildii +- Zwiększanie limitu członków +- Odblokowywanie dodatkowych funkcji gildii -```yaml -# 数据库配置 -database: - type: sqlite # sqlite 或 mysql - mysql: - host: localhost - port: 3306 - database: guild - username: root - password: "" - pool-size: 10 +### Interfejs Użytkownika +- Kompletny graficzny interfejs użytkownika (GUI) +- Intuicyjny system menu +- Konfigurowalny wygląd interfejsu -# 工会配置 -guild: - min-name-length: 3 - max-name-length: 20 - max-tag-length: 6 - max-description-length: 100 - max-members: 50 - creation-cost: 1000.0 # 创建工会费用 +## Funkcje Techniczne -# 权限配置 -permissions: - default: - can-create: true - can-invite: true - can-kick: true - can-promote: true - can-demote: false - can-delete: false -``` +- **Przetwarzanie Asynchroniczne**: Wszystkie operacje na bazie danych są asynchroniczne, co zapewnia brak wpływu na wydajność serwera +- **Wsparcie dla wielu baz danych**: Obsługa zarówno SQLite, jak i MySQL +- **Wsparcie dla Placeholderów**: Integracja z PlaceholderAPI +- **Integracja Uprawnień**: Pełna zgodność z systemem uprawnień Bukkit +- **Wysoka Wydajność**: Zoptymalizowany kod zapewnia płynne działanie serwera -### 消息配置文件 (messages.yml) +## Polecenia -```yaml -# 通用消息 -general: - prefix: "&6[工会] &r" - no-permission: "&c您没有权限执行此操作!" - -# 工会创建消息 -create: - success: "&a工会 {name} 创建成功!" - insufficient-funds: "&c您的余额不足!创建工会需要 {cost} 金币。" -``` +- `/guild` - Główne polecenie gildii +- `/guildadmin` - Polecenie administracyjne gildii -### GUI配置文件 (gui.yml) +## Uprawnienia -```yaml -# 主界面配置 -main-menu: - title: "&6工会系统" - size: 54 - items: - create-guild: - slot: 4 - material: EMERALD_BLOCK - name: "&a创建工会" - lore: - - "&7创建新的工会" - - "&7需要消耗金币" -``` +- Korzysta z wbudowanego systemu uprawnień -### 数据库配置文件 (database.yml) +## Zmienne Podstawowych Informacji o Gildii -```yaml -# SQLite配置 -sqlite: - file: "plugins/GuildPlugin/guild.db" - -# MySQL配置 -mysql: - host: localhost - port: 3306 - database: guild - username: root - password: "" - pool-size: 10 - min-idle: 5 - connection-timeout: 30000 - idle-timeout: 600000 - max-lifetime: 1800000 -``` +### Podstawowe Info Gildii +- `%guild_name%` - Nazwa gildii +- `%guild_tag%` - Tag gildii +- `%guild_membercount%` - Obecna liczba członków +- `%guild_maxmembers%` - Maksymalna liczba członków +- `%guild_level%` - Poziom gildii +- `%guild_balance%` - Saldo gildii (2 miejsca po przecinku) +- `%guild_frozen%` - Status gildii (Normalna/Zamrożona/Brak Gildii) -## 📝 命令列表 - -### 玩家命令 - -| 命令 | 权限 | 描述 | -|------|------|------| -| `/guild` | `guild.use` | 打开工会主界面 | -| `/guild create <名称> [标签] [描述]` | `guild.create` | 创建工会 | -| `/guild info` | `guild.info` | 查看工会信息 | -| `/guild members` | `guild.members` | 查看工会成员 | -| `/guild invite <玩家>` | `guild.invite` | 邀请玩家加入工会 | -| `/guild kick <玩家>` | `guild.kick` | 踢出工会成员 | -| `/guild leave` | `guild.leave` | 离开工会 | -| `/guild delete` | `guild.delete` | 删除工会 | -| `/guild promote <玩家>` | `guild.promote` | 提升成员职位 | -| `/guild demote <玩家>` | `guild.demote` | 降级成员职位 | -| `/guild accept <邀请者>` | `guild.accept` | 接受工会邀请 | -| `/guild decline <邀请者>` | `guild.decline` | 拒绝工会邀请 | -| `/guild sethome` | `guild.sethome` | 设置工会家 | -| `/guild home` | `guild.home` | 传送到工会家 | -| `/guild apply <工会> [消息]` | `guild.apply` | 申请加入工会 | - -### 管理员命令 - -| 命令 | 权限 | 描述 | -|------|------|------| -| `/guildadmin` | `guild.admin` | 管理员主命令 | -| `/guildadmin reload` | `guild.admin.reload` | 重载配置文件 | -| `/guildadmin list` | `guild.admin.list` | 列出所有工会 | -| `/guildadmin info <工会>` | `guild.admin.info` | 查看工会详细信息 | -| `/guildadmin delete <工会>` | `guild.admin.delete` | 强制删除工会 | -| `/guildadmin kick <玩家> <工会>` | `guild.admin.kick` | 从工会踢出玩家 | -| `/guildadmin relation` | `guild.admin.relation` | 关系管理 | -| `/guildadmin test` | `guild.admin.test` | 测试功能 | - -## 🖥️ GUI界面 - -### 主界面 -- **创建工会**: 创建新的工会 -- **工会信息**: 查看当前工会信息 -- **成员管理**: 管理工会成员 -- **申请管理**: 处理加入申请 -- **工会设置**: 修改工会设置 -- **工会列表**: 查看所有工会 -- **工会关系**: 管理工会关系 - -### 创建工会界面 -- **工会名称输入**: 设置工会名称(3-20字符) -- **工会标签输入**: 设置工会标签(最多6字符,可选) -- **工会描述输入**: 设置工会描述(最多100字符,可选) -- **确认创建**: 支付费用创建工会 -- **取消**: 返回主界面 - -### 成员管理界面 -- **成员列表**: 显示所有成员 -- **邀请成员**: 邀请新成员 -- **踢出成员**: 踢出现有成员 -- **提升成员**: 提升成员职位 -- **降级成员**: 降级成员职位 - -## 💰 经济系统 - -### 功能特性 -- **工会资金**: 每个工会独立的资金账户 -- **存款系统**: 成员可以向工会存款 -- **取款系统**: 成员可以从工会取款 -- **转账系统**: 工会间资金转账 -- **贡献记录**: 记录每个成员的贡献 -- **等级升级**: 资金达到要求自动升级 - -### 等级系统 - -| 等级 | 资金要求 | 最大成员数 | -|------|----------|------------| -| 1 | 0-5,000 | 6 | -| 2 | 5,000-10,000 | 12 | -| 3 | 10,000-20,000 | 18 | -| 4 | 20,000-35,000 | 24 | -| 5 | 35,000-50,000 | 30 | -| 6 | 50,000-75,000 | 40 | -| 7 | 75,000-100,000 | 50 | -| 8 | 100,000-150,000 | 60 | -| 9 | 150,000-200,000 | 80 | -| 10 | 200,000+ | 100 | - -### 经济命令 -- `/guild deposit <金额>` - 向工会存款 -- `/guild withdraw <金额>` - 从工会取款 -- `/guild transfer <工会> <金额>` - 向其他工会转账 -- `/guild balance` - 查看工会余额 - -## 🤝 工会关系 - -### 关系类型 -- **中立 (Neutral)**: 默认关系,无特殊效果 -- **盟友 (Ally)**: 友好关系,显示为绿色 -- **敌对 (Enemy)**: 敌对关系,显示为红色 -- **开战 (War)**: 战争状态,登录时通知 -- **停战 (Truce)**: 临时停战,需要双方同意结束 - -### 关系管理 -- **创建关系**: 工会会长可以创建关系 -- **接受关系**: 目标工会需要接受关系 -- **拒绝关系**: 目标工会可以拒绝关系 -- **取消关系**: 可以取消已建立的关系 -- **关系过期**: 关系有自动过期机制 - -### 关系命令 -- `/guild relation create <工会> <类型>` - 创建关系 -- `/guild relation accept <工会>` - 接受关系 -- `/guild relation reject <工会>` - 拒绝关系 -- `/guild relation cancel <工会>` - 取消关系 - -## 🗄️ 数据库 - -### 数据表结构 - -#### guilds (工会表) -```sql -CREATE TABLE guilds ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name VARCHAR(20) UNIQUE NOT NULL, - tag VARCHAR(6), - description TEXT, - leader_uuid VARCHAR(36) NOT NULL, - leader_name VARCHAR(16) NOT NULL, - balance DOUBLE DEFAULT 0.0, - level INTEGER DEFAULT 1, - max_members INTEGER DEFAULT 6, - home_world VARCHAR(64), - home_x DOUBLE, - home_y DOUBLE, - home_z DOUBLE, - home_yaw FLOAT, - home_pitch FLOAT, - frozen BOOLEAN DEFAULT FALSE, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); -``` +### Info o Gildii Gracza +- `%guild_role%` - Rola gracza w gildii (Lider/Oficer/Członek) +- `%guild_joined%` - Kiedy gracz dołączył do gildii +- `%guild_contribution%` - Wkład gracza w gildię -#### guild_members (成员表) -```sql -CREATE TABLE guild_members ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - role VARCHAR(20) DEFAULT 'MEMBER', - joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE -); -``` +## Zmienne Sprawdzania Statusu Gildii -#### guild_applications (申请表) -```sql -CREATE TABLE guild_applications ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - message TEXT, - status VARCHAR(20) DEFAULT 'PENDING', - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE -); -``` +### Status Gracza +- `%guild_hasguild%` - Czy gracz ma gildię (Tak/Nie) +- `%guild_isleader%` - Czy gracz jest liderem (Tak/Nie) +- `%guild_isofficer%` - Czy gracz jest oficerem (Tak/Nie) +- `%guild_ismember%` - Czy gracz jest członkiem (Tak/Nie) -#### guild_relations (关系表) -```sql -CREATE TABLE guild_relations ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild1_id INTEGER NOT NULL, - guild2_id INTEGER NOT NULL, - relation_type VARCHAR(20) NOT NULL, - status VARCHAR(20) DEFAULT 'PENDING', - initiator_uuid VARCHAR(36) NOT NULL, - initiator_name VARCHAR(16) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - expires_at TIMESTAMP, - FOREIGN KEY (guild1_id) REFERENCES guilds(id) ON DELETE CASCADE, - FOREIGN KEY (guild2_id) REFERENCES guilds(id) ON DELETE CASCADE -); -``` +## Zmienne Sprawdzania Uprawnień Gildii -#### guild_economy (经济表) -```sql -CREATE TABLE guild_economy ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - amount DOUBLE NOT NULL, - type VARCHAR(20) NOT NULL, - description TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE -); -``` +### Status Uprawnień +- `%guild_caninvite%` - Czy może zapraszać graczy (Tak/Nie) +- `%guild_cankick%` - Czy może wyrzucać członków (Tak/Nie) +- `%guild_canpromote%` - Czy może awansować członków (Tak/Nie) +- `%guild_candemote%` - Czy może degradować członków (Tak/Nie) +- `%guild_cansethome%` - Czy może ustawiać dom gildii (Tak/Nie) +- `%guild_canmanageeconomy%` - Czy może zarządzać ekonomią gildii (Tak/Nie) +## Wymagania -# GuildPlugin - 完整功能的 Minecraft 公会系统插件 +- Wersja serwera Minecraft: 1.21+ +- Wersja Java: JDK 17+ +- Opcjonalne zależności: Vault (dla wsparcia ekonomii), PlaceholderAPI (dla wsparcia placeholderów) -[English Below | 官方主页/文档](http://chenasyd.codewaves.cn/) +## Kroki Instalacji -GuildPlugin 是一个为 Minecraft 服务器打造的高性能公会系统插件,支持多语言,涵盖公会管理、经济、关系、等级、GUI等丰富功能,适配多种主流经济与权限插件,完全免费开源! +1. Umieść plik jar pluginu w folderze `plugins` swojego serwera +2. Uruchom serwer - plugin automatycznie wygeneruje pliki konfiguracyjne +3. Edytuj pliki konfiguracyjne według potrzeb +4. Zrestartuj serwer, aby zastosować zmiany -## 核心特性 +--- + +# GuildPlugin - Kompletny system gildii dla Minecrafta + +[English Above | Oficjalna Strona/Dokumentacja](http://chenasyd.codewaves.cn/) -### 公会管理 -- 支持创建、解散、编辑公会(名称、标签、描述) -- 成员增删、升降职,基于“会长/官员/成员”的角色权限体系 -- 公会家园设置与传送 -- 公会申请/邀请机制 +GuildPlugin to wysokowydajny plugin systemu gildii dla serwerów Minecraft, wspierający wiele języków, obejmujący zarządzanie gildiami, ekonomię, relacje, poziomy, GUI i inne bogate funkcje, dostosowany do wielu popularnych pluginów ekonomicznych i uprawnień, całkowicie darmowy i open source! -### 经济系统 -- 公会资金管理:存款、取款、转账 -- 公会创建费用可配置 -- 支持通过 Vault 集成多种经济插件 +## Główne Cechy -### 关系系统 -- 支持公会间联盟、敌对、中立、战争、停战等关系 -- 状态变更和通知机制,战争警报与联盟反馈 +### Zarządzanie Gildią +- Wsparcie dla tworzenia, rozwiązywania, edycji gildii (nazwa, tag, opis) +- Dodawanie i usuwanie członków, awanse i degradacje, system uprawnień oparty na rolach "Lider/Oficer/Członek" +- Ustawianie domu gildii i teleportacja +- Mechanizm aplikacji/zaproszeń do gildii -### 等级系统 -- 公会等级成长,提升成员上限 -- 解锁更多公会功能 +### System Ekonomii +- Zarządzanie funduszami gildii: wpłaty, wypłaty, przelewy +- Konfigurowalny koszt utworzenia gildii +- Wsparcie dla integracji z wieloma pluginami ekonomicznymi przez Vault -### 用户界面 -- 完整 GUI 菜单与操作界面 -- 可自定义配置,操作便捷 +### System Relacji +- Wsparcie dla relacji między gildiami: sojusz, wrogość, neutralność, wojna, rozejm itp. +- Zmiana statusu i mechanizm powiadomień, alarmy wojenne i informacje zwrotne o sojuszach -### 技术特性 -- 所有数据库操作均为异步,无卡顿 -- 支持 SQLite 与 MySQL 灵活切换 -- 与 PlaceholderAPI 深度集成,变量丰富 -- 完全兼容 Bukkit 权限体系 -- 高性能优化,稳定可靠 +### System Poziomów +- Wzrost poziomu gildii, zwiększanie limitu członków +- Odblokowywanie większej liczby funkcji gildii -## 快速开始 +### Interfejs Użytkownika +- Kompletne menu GUI i interfejs operacyjny +- Możliwość niestandardowej konfiguracji, łatwa obsługa -### 环境需求 -- Minecraft 服务器版本:1.21+ -- Java 版本:JDK 17+ -- 可选依赖:Vault(经济支持)、PlaceholderAPI(变量支持) +### Cechy Techniczne +- Wszystkie operacje na bazie danych są asynchroniczne, bez lagów +- Elastyczne przełączanie między SQLite i MySQL +- Głęboka integracja z PlaceholderAPI, bogate zmienne +- Pełna zgodność z systemem uprawnień Bukkit +- Wysoka optymalizacja wydajności, stabilność i niezawodność -### 安装步骤 -1. 下载最新版插件 jar 文件,放入服务器 `/plugins` 目录 -2. 启动服务器,插件会自动生成配置文件 -3. 按需修改配置文件(config.yml/messages.yml/gui.yml/database.yml) -4. 重启服务器即可生效 +## Szybki Start -### Maven 构建(开发者) +### Wymagania Środowiskowe +- Wersja serwera Minecraft: 1.21+ +- Wersja Java: JDK 17+ +- Opcjonalne zależności: Vault (wsparcie ekonomii), PlaceholderAPI (wsparcie zmiennych) + +### Kroki Instalacji +1. Pobierz najnowszą wersję pliku jar pluginu i umieść go w katalogu `/plugins` serwera +2. Uruchom serwer, plugin automatycznie wygeneruje pliki konfiguracyjne +3. Zmodyfikuj pliki konfiguracyjne według potrzeb (config.yml/messages.yml/gui.yml/database.yml) +4. Zrestartuj serwer, aby zmiany weszły w życie + +### Budowanie Maven (Deweloperzy) ```bash mvn clean package ``` -## 主要命令一览 +## Przegląd Głównych Poleceń -#### 玩家命令 -| 命令 | 权限节点 | 说明 | +#### Polecenia Gracza +| Polecenie | Węzeł Uprawnień | Opis | |------|----------|------| -| /guild | guild.use | 打开主菜单 | -| /guild create ... | guild.create | 创建公会 | -| /guild info | guild.info | 查看公会信息 | -| /guild members | guild.members | 查看成员列表 | -| /guild invite ... | guild.invite | 邀请加入 | -| /guild kick ... | guild.kick | 移除成员 | -| /guild leave | guild.leave | 离开公会 | -| /guild delete | guild.delete | 解散公会 | -| /guild promote ... | guild.promote | 升职成员 | -| /guild demote ... | guild.demote | 降职成员 | -| /guild accept ... | guild.accept | 接受邀请 | -| /guild decline ... | guild.decline | 拒绝邀请 | -| /guild sethome | guild.sethome | 设置家园 | -| /guild home | guild.home | 传送家园 | -| /guild apply ... | guild.apply | 申请加入 | - -#### 管理员命令 -| 命令 | 权限节点 | 说明 | +| /guild | guild.use | Otwórz menu główne | +| /guild create ... | guild.create | Utwórz gildię | +| /guild info | guild.info | Zobacz informacje o gildii | +| /guild members | guild.members | Zobacz listę członków | +| /guild invite ... | guild.invite | Zaproś do dołączenia | +| /guild kick ... | guild.kick | Usuń członka | +| /guild leave | guild.leave | Opuść gildię | +| /guild delete | guild.delete | Rozwiąż gildię | +| /guild promote ... | guild.promote | Awansuj członka | +| /guild demote ... | guild.demote | Zdegraduj członka | +| /guild accept ... | guild.accept | Zaakceptuj zaproszenie | +| /guild decline ... | guild.decline | Odrzuć zaproszenie | +| /guild sethome | guild.sethome | Ustaw dom | +| /guild home | guild.home | Teleportuj do domu | +| /guild apply ... | guild.apply | Aplikuj o dołączenie | + +#### Polecenia Administratora +| Polecenie | Węzeł Uprawnień | Opis | |------|----------|------| -| /guildadmin | guild.admin | 管理主命令 | -| /guildadmin reload | guild.admin.reload | 重载配置文件 | -| /guildadmin list | guild.admin.list | 查看所有公会 | -| /guildadmin info ... | guild.admin.info | 查看公会详情 | -| /guildadmin delete ... | guild.admin.delete | 强制删除公会 | -| /guildadmin kick ... ... | guild.admin.kick | 移除玩家 | -| /guildadmin relation | guild.admin.relation | 管理关系 | -| /guildadmin test | guild.admin.test | 测试功能 | - -## 变量支持(PlaceholderAPI) - -#### 公会变量 -- %guild_name%:公会名称 -- %guild_tag%:公会标签 -- %guild_membercount%:当前成员数 -- %guild_maxmembers%:最大成员数 -- %guild_level%:公会等级 -- %guild_balance%:资金(2位小数) -- %guild_frozen%:状态(正常/冻结/无公会) - -#### 玩家变量 -- %guild_role%:角色(会长/官员/成员) -- %guild_joined%:加入时间 -- %guild_contribution%:贡献值 - -#### 状态变量 -- %guild_hasguild%:是否有公会 -- %guild_isleader%、%guild_isofficer%、%guild_ismember%:角色判定 - -#### 权限变量 +| /guildadmin | guild.admin | Główne polecenie zarządzania | +| /guildadmin reload | guild.admin.reload | Przeładuj pliki konfiguracyjne | +| /guildadmin list | guild.admin.list | Zobacz wszystkie gildie | +| /guildadmin info ... | guild.admin.info | Zobacz szczegóły gildii | +| /guildadmin delete ... | guild.admin.delete | Wymuś usunięcie gildii | +| /guildadmin kick ... ... | guild.admin.kick | Usuń gracza | +| /guildadmin relation | guild.admin.relation | Zarządzaj relacjami | +| /guildadmin test | guild.admin.test | Funkcje testowe | + +## Wsparcie Zmiennych (PlaceholderAPI) + +#### Zmienne Gildii +- %guild_name%:Nazwa gildii +- %guild_tag%:Tag gildii +- %guild_membercount%:Obecna liczba członków +- %guild_maxmembers%:Maksymalna liczba członków +- %guild_level%:Poziom gildii +- %guild_balance%:Fundusze (2 miejsca po przecinku) +- %guild_frozen%:Status (Normalny/Zamrożony/Brak Gildii) + +#### Zmienne Gracza +- %guild_role%:Rola (Lider/Oficer/Członek) +- %guild_joined%:Czas dołączenia +- %guild_contribution%:Wartość wkładu + +#### Zmienne Statusu +- %guild_hasguild%:Czy posiada gildię +- %guild_isleader%、%guild_isofficer%、%guild_ismember%:Określenie roli + +#### Zmienne Uprawnień - %guild_caninvite%、%guild_cankick%、%guild_canpromote%、%guild_candemote%、%guild_cansethome%、%guild_canmanageeconomy% -## 配置示例 +## Przykład Konfiguracji ### config.yml ```yaml database: - type: sqlite # 支持 sqlite 或 mysql + type: sqlite # Wsparcie dla sqlite lub mysql mysql: host: localhost port: 3306 @@ -608,85 +240,69 @@ permissions: can-delete: false ``` -## 数据库结构(主表) +## Struktura Bazy Danych (Główne Tabele) -- guilds(公会表) -- guild_members(成员表) -- guild_applications(申请表) -- guild_relations(关系表) -- guild_economy(经济表) +- guilds (tabela gildii) +- guild_members (tabela członków) +- guild_applications (tabela aplikacji) +- guild_relations (tabela relacji) +- guild_economy (tabela ekonomii) -SQL 示例见 plugins/database.sql。 +Przykłady SQL zobacz w plugins/database.sql. -## FAQ 常见问题 +## FAQ Częste Pytania -- 插件无法启动?请确认服务器版本、JDK、依赖是否齐全,配置文件格式是否正确。 -- 经济系统不工作?请确认 Vault 和经济插件已安装,config.yml 配置正确。 -- 数据库连接失败?检查数据库配置、MySQL运行状态、账号权限等。 -- GUI界面异常?检查配置文件格式与变量替换。 -- 公会创建失败?检查玩家资金、名称是否重复或过长,玩家是否已加入其他公会等。 +- Plugin nie uruchamia się? Sprawdź wersję serwera, JDK, czy zależności są kompletne, oraz czy format pliku konfiguracyjnego jest poprawny. +- System ekonomii nie działa? Potwierdź, że Vault i plugin ekonomiczny są zainstalowane, a config.yml jest poprawnie skonfigurowany. +- Błąd połączenia z bazą danych? Sprawdź konfigurację bazy danych, status działania MySQL, uprawnienia konta itp. +- Błąd interfejsu GUI? Sprawdź format pliku konfiguracyjnego i zastępowanie zmiennych. +- Niepowodzenie tworzenia gildii? Sprawdź fundusze gracza, czy nazwa nie jest zduplikowana lub za długa, czy gracz nie dołączył już do innej gildii itp. -## 更新日志 +## Dziennik Aktualizacji ### v1.0.0 -- 初始版本发布 -- 完整公会管理系统 -- 经济系统集成 -- 公会关系管理 -- 等级系统 -- 完整 GUI 界面 -- 支持多数据库 -- 权限系统 -- PlaceholderAPI 集成 +- Wydanie wersji początkowej +- Kompletny system zarządzania gildiami +- Integracja systemu ekonomii +- Zarządzanie relacjami gildii +- System poziomów +- Kompletny interfejs GUI +- Wsparcie dla wielu baz danych +- System uprawnień +- Integracja z PlaceholderAPI ### v1.2.3 -- 基础功能发布 -- 完全正确的逻辑处理 -- 完全支持插件扩展 -- 完全实现GUI -- 完全实现folia支持 -- 支持多数据库 -- 完全使用内置权限系统 - -### 计划功能 -- [ ] 公会战争系统(部分实现) -- [ ] 公会商店 -- [ ] 公会任务系统 -- [ ] 公会排行榜 -- [ ] 公会活动系统 -- [ ] 公会仓库 -- [ ] 公会公告系统 -- [ ] 公会日志系统 -###更多功能 -- [ ] 插件扩展市场(创意工坊) -- [ ] 快速获取资源更新 -- [ ] 报错快捷反馈 -- [ ] 报错提示代码位置或具体问题 -- [ ] 插件单独记录详细的日志 -- [ ] 更多安全处理,便于排查可以漏洞 -- [ ] 更完整的插件系统逻辑 - -## 项目主页与支持 +- Wydanie podstawowych funkcji +- Całkowicie poprawna obsługa logiki +- Pełne wsparcie dla rozszerzeń pluginu +- Pełna implementacja GUI +- Pełne wsparcie dla folia +- Wsparcie dla wielu baz danych +- Pełne wykorzystanie wbudowanego systemu uprawnień + +### Planowane Funkcje +- [ ] System wojen gildii (częściowo zaimplementowany) +- [ ] Sklep gildii +- [ ] System zadań gildii +- [ ] Ranking gildii +- [ ] System wydarzeń gildii +- [ ] Magazyn gildii +- [ ] System ogłoszeń gildii +- [ ] System logów gildii +### Więcej Funkcji +- [ ] Rynek rozszerzeń pluginu (Warsztat) +- [ ] Szybkie pobieranie aktualizacji zasobów +- [ ] Szybkie zgłaszanie błędów +- [ ] Wskazywanie lokalizacji kodu błędu lub konkretnego problemu +- [ ] Oddzielne szczegółowe logi dla pluginu +- [ ] Więcej zabezpieczeń ułatwiających wykrywanie luk +- [ ] Bardziej kompletna logika systemu pluginu + +## Strona Projektu i Wsparcie - GitHub: [chenasyd/-GuildPlugin](https://github.com/chenasyd/-GuildPlugin) -- 官方主页/文档:[http://chenasyd.codewaves.cn/](http://chenasyd.codewaves.cn/) -- B站作者主页:[https://space.bilibili.com/1930829400](https://space.bilibili.com/1930829400) - -## 许可证 - -GuildPlugin 遵循 [GNU GPL v3.0](https://github.com/chenasyd/-GuildPlugin/blob/main/LICENSE) 开源协议,欢迎二次开发与贡献! - ---- - -# GuildPlugin - Feature-Complete Minecraft Guild System (English) - -GuildPlugin is a comprehensive and high-performance Minecraft server plugin that delivers a full-featured guild/faction system, including management, economy, relations, leveling, GUI, and more. Free and open-source! +- Oficjalna Strona/Dokumentacja: [http://chenasyd.codewaves.cn/](http://chenasyd.codewaves.cn/) +- Strona Autora na Bilibili: [https://space.bilibili.com/1930829400](https://space.bilibili.com/1930829400) -## Core Features +## Licencja -- Create and manage guilds (name, tag, description) -- Role-based system: Leader, Officer, Member -- Invite, kick, promote, demote members -- Guild home set and teleport -- Guild application system -- Economy: guild funds, deposit, withdraw, transfer (Vault support) -- Inter-guild relati \ No newline at end of file +GuildPlugin jest objęty licencją [GNU GPL v3.0](https://github.com/chenasyd/-GuildPlugin/blob/main/LICENSE), zachęcamy do wtórnego rozwoju i wkładu! diff --git a/config.yml b/config.yml index 6d94b42..4d400df 100644 --- a/config.yml +++ b/config.yml @@ -1,124 +1,124 @@ -# 工会插件主配置文件 - -# 工会配置 -guild: - # 工会名称最小长度 - min-name-length: 3 - # 工会名称最大长度 - max-name-length: 20 - # 工会标签最大长度 - max-tag-length: 6 - # 工会描述最大长度 - max-description-length: 100 - # 工会最大成员数量 - max-members: 50 - # 创建工会所需费用(需要Vault) - creation-cost: 1000.0 - # 工会标签颜色 - tag-color: "&6" - # 工会名称颜色 - name-color: "&e" - -# 显示配置 -display: - # 职位颜色(可自定义) - role-colors: - leader: "&6" # 会长:金色 - officer: "&b" # 官员:亮蓝色 - member: "&7" # 成员:灰色 - # 职位左侧分隔符配置 - role-separator: - enabled: true - text: " | " - color-per-role: true # 分隔符是否跟随职位颜色 - default-color: "&7" # 无职位或未入会时的默认颜色(一般不会使用) - -# 权限配置 -permissions: - # 默认权限 - default: - can-create: true # 允许创建工会(未入会时) - can-invite: false # 非成员默认不可邀请 - can-kick: false # 非成员默认不可踢人 - can-promote: false # 非成员默认不可升职 - can-demote: false # 非成员默认不可降职 - can-delete: false # 非成员默认不可删会 - - # 会长权限(若缺省则视为全开) - leader: - can-create: true - can-invite: true - can-kick: true - can-promote: true - can-demote: true - can-delete: true - - # 官员权限 - officer: - can-create: true # 允许代操作与创建 - can-invite: true - can-kick: true - can-promote: false # 是否允许升职成员(通常只会长) - can-demote: false # 是否允许降职成员(通常只会长) - can-delete: false # 是否允许删除工会(通常只会长) - - # 成员权限 - member: - can-create: true # 允许退会后再创建新工会 - can-invite: false - can-kick: false - can-promote: false - can-demote: false - can-delete: false - -# 消息配置 -messages: - # 是否启用消息 - enabled: true - # 消息前缀 - prefix: "&6[工会] &r" - # 消息颜色 - colors: - success: "&a" - error: "&c" - info: "&e" - warning: "&6" - -# GUI配置 -gui: - # 是否启用GUI - enabled: true - # GUI标题 - title: "&6工会系统" - # GUI大小(必须是9的倍数) - size: 54 - # 是否显示工会标签 - show-tag: true - # 是否显示工会描述 - show-description: true - -# 占位符配置 -placeholders: - # 是否启用占位符 - enabled: true - # 占位符前缀 - prefix: "guild_" - # 是否缓存占位符 - cache-enabled: true - # 缓存时间(秒) - cache-time: 30 - -# 日志配置 -logging: - # 是否启用日志 - enabled: true - # 日志级别: DEBUG, INFO, WARN, ERROR - level: INFO - # 是否记录到文件 - file-logging: true - # 日志文件路径 - log-file: "logs/guild.log" - # 最大日志文件大小(MB) - max-file-size: 10 - # 保留的日志文件数量 - max-files: 5 +# Główny plik konfiguracyjny pluginu gildii + +# Konfiguracja gildii +guild: + # Minimalna długość nazwy gildii + min-name-length: 3 + # Maksymalna długość nazwy gildii + max-name-length: 20 + # Maksymalna długość tagu gildii + max-tag-length: 6 + # Maksymalna długość opisu gildii + max-description-length: 100 + # Maksymalna liczba członków gildii + max-members: 50 + # Koszt utworzenia gildii (wymaga Vault) + creation-cost: 1000.0 + # Kolor tagu gildii + tag-color: "&6" + # Kolor nazwy gildii + name-color: "&e" + +# Konfiguracja wyświetlania +display: + # Kolory rang (można dostosować) + role-colors: + leader: "&6" # Lider: Złoty + officer: "&b" # Oficer: Jasnoniebieski + member: "&7" # Członek: Szary + # Konfiguracja separatora po lewej stronie rangi + role-separator: + enabled: true + text: " | " + color-per-role: true # Czy separator ma mieć kolor rangi + default-color: "&7" # Domyślny kolor bez rangi lub gildii (zazwyczaj nieużywany) + +# Konfiguracja uprawnień +permissions: + # Domyślne uprawnienia + default: + can-create: true # Pozwól na tworzenie gildii (gdy nie w gildii) + can-invite: false # Nie-członek domyślnie nie może zapraszać + can-kick: false # Nie-członek domyślnie nie może wyrzucać + can-promote: false # Nie-członek domyślnie nie może awansować + can-demote: false # Nie-członek domyślnie nie może degradować + can-delete: false # Nie-członek domyślnie nie może usuwać gildii + + # Uprawnienia lidera (jeśli pominięte, zakłada się pełne uprawnienia) + leader: + can-create: true + can-invite: true + can-kick: true + can-promote: true + can-demote: true + can-delete: true + + # Uprawnienia oficera + officer: + can-create: true # Pozwól na operacje zastępcze i tworzenie + can-invite: true + can-kick: true + can-promote: false # Czy może awansować członków (zazwyczaj tylko lider) + can-demote: false # Czy może degradować członków (zazwyczaj tylko lider) + can-delete: false # Czy może usunąć gildię (zazwyczaj tylko lider) + + # Uprawnienia członka + member: + can-create: true # Pozwól na utworzenie nowej gildii po opuszczeniu obecnej + can-invite: false + can-kick: false + can-promote: false + can-demote: false + can-delete: false + +# Konfiguracja wiadomości +messages: + # Czy włączyć wiadomości + enabled: true + # Prefiks wiadomości + prefix: "&6[Gildia] &r" + # Kolory wiadomości + colors: + success: "&a" + error: "&c" + info: "&e" + warning: "&6" + +# Konfiguracja GUI +gui: + # Czy włączyć GUI + enabled: true + # Tytuł GUI + title: "&6System Gildii" + # Rozmiar GUI (musi być wielokrotnością 9) + size: 54 + # Czy pokazywać tag gildii + show-tag: true + # Czy pokazywać opis gildii + show-description: true + +# Konfiguracja placeholderów +placeholders: + # Czy włączyć placeholdery + enabled: true + # Prefiks placeholderów + prefix: "guild_" + # Czy buforować placeholdery + cache-enabled: true + # Czas buforowania (sekundy) + cache-time: 30 + +# Konfiguracja logowania +logging: + # Czy włączyć logowanie + enabled: true + # Poziom logowania: DEBUG, INFO, WARN, ERROR + level: INFO + # Czy zapisywać logi do pliku + file-logging: true + # Ścieżka do pliku logów + log-file: "logs/guild.log" + # Maksymalny rozmiar pliku logów (MB) + max-file-size: 10 + # Liczba przechowywanych plików logów + max-files: 5 diff --git a/database.yml b/database.yml index 0f56c8c..f4e9820 100644 --- a/database.yml +++ b/database.yml @@ -1,108 +1,108 @@ -# 数据库配置文件 - -# 数据库类型: mysql 或 sqlite -type: sqlite - -# MySQL配置(当type为mysql时使用) -mysql: - # 数据库主机地址 - host: localhost - # 数据库端口 - port: 3306 - # 数据库名称 - database: guild - # 数据库用户名 - username: root - # 数据库密码 - password: "" - # 连接池大小 - pool-size: 10 - # 最小空闲连接数 - min-idle: 5 - # 连接超时时间(毫秒) - connection-timeout: 30000 - # 空闲超时时间(毫秒) - idle-timeout: 600000 - # 连接最大生命周期(毫秒) - max-lifetime: 1800000 - # 是否使用SSL - use-ssl: false - # 字符编码 - character-encoding: UTF-8 - # 时区 - timezone: UTC - -# SQLite配置(当type为sqlite时使用) -sqlite: - # 数据库文件路径(相对于插件数据文件夹) - file: guild.db - # 是否启用WAL模式 - wal-mode: true - # 同步模式: OFF, NORMAL, FULL - synchronous: NORMAL - # 缓存大小(KB) - cache-size: 2000 - # 页面大小(字节) - page-size: 4096 - # 是否启用外键约束 - foreign-keys: true - -# 连接池配置 -connection-pool: - # 最大连接数 - maximum-pool-size: 10 - # 最小空闲连接数 - minimum-idle: 5 - # 连接超时时间(毫秒) - connection-timeout: 30000 - # 空闲超时时间(毫秒) - idle-timeout: 600000 - # 连接最大生命周期(毫秒) - max-lifetime: 1800000 - # 连接测试查询 - connection-test-query: "SELECT 1" - # 连接验证超时时间(毫秒) - validation-timeout: 5000 - # 是否在连接池启动时验证连接 - validate-on-start: true - -# 数据库表配置 -tables: - # 工会表 - guilds: - name: guilds - # 是否自动创建表 - auto-create: true - # 表结构版本 - version: 1 - - # 工会成员表 - guild_members: - name: guild_members - auto-create: true - version: 1 - - # 工会申请表 - guild_applications: - name: guild_applications - auto-create: true - version: 1 - - # 工会邀请表 - guild_invites: - name: guild_invites - auto-create: true - version: 1 - -# 备份配置 -backup: - # 是否启用自动备份 - enabled: false - # 备份间隔(小时) - interval: 24 - # 备份保留天数 - retention-days: 7 - # 备份文件路径 - path: "backups/" - # 备份文件格式 - format: "yyyy-MM-dd_HH-mm-ss" +# Plik konfiguracyjny bazy danych + +# Typ bazy danych: mysql lub sqlite +type: sqlite + +# Konfiguracja MySQL (używana, gdy type to mysql) +mysql: + # Adres hosta bazy danych + host: localhost + # Port bazy danych + port: 3306 + # Nazwa bazy danych + database: guild + # Nazwa użytkownika bazy danych + username: root + # Hasło bazy danych + password: "" + # Rozmiar puli połączeń + pool-size: 10 + # Minimalna liczba bezczynnych połączeń + min-idle: 5 + # Czas oczekiwania na połączenie (milisekundy) + connection-timeout: 30000 + # Czas bezczynności (milisekundy) + idle-timeout: 600000 + # Maksymalny czas życia połączenia (milisekundy) + max-lifetime: 1800000 + # Czy używać SSL + use-ssl: false + # Kodowanie znaków + character-encoding: UTF-8 + # Strefa czasowa + timezone: UTC + +# Konfiguracja SQLite (używana, gdy type to sqlite) +sqlite: + # Ścieżka do pliku bazy danych (względem folderu danych pluginu) + file: guild.db + # Czy włączyć tryb WAL + wal-mode: true + # Tryb synchronizacji: OFF, NORMAL, FULL + synchronous: NORMAL + # Rozmiar pamięci podręcznej (KB) + cache-size: 2000 + # Rozmiar strony (bajty) + page-size: 4096 + # Czy włączyć klucze obce + foreign-keys: true + +# Konfiguracja puli połączeń +connection-pool: + # Maksymalny rozmiar puli + maximum-pool-size: 10 + # Minimalna liczba bezczynnych połączeń + minimum-idle: 5 + # Czas oczekiwania na połączenie (milisekundy) + connection-timeout: 30000 + # Czas bezczynności (milisekundy) + idle-timeout: 600000 + # Maksymalny czas życia połączenia (milisekundy) + max-lifetime: 1800000 + # Zapytanie testujące połączenie + connection-test-query: "SELECT 1" + # Czas oczekiwania na walidację (milisekundy) + validation-timeout: 5000 + # Czy walidować połączenie przy starcie + validate-on-start: true + +# Konfiguracja tabel bazy danych +tables: + # Tabela gildii + guilds: + name: guilds + # Czy automatycznie tworzyć tabelę + auto-create: true + # Wersja struktury tabeli + version: 1 + + # Tabela członków gildii + guild_members: + name: guild_members + auto-create: true + version: 1 + + # Tabela aplikacji do gildii + guild_applications: + name: guild_applications + auto-create: true + version: 1 + + # Tabela zaproszeń do gildii + guild_invites: + name: guild_invites + auto-create: true + version: 1 + +# Konfiguracja kopii zapasowych +backup: + # Czy włączyć automatyczne kopie zapasowe + enabled: false + # Interwał kopii zapasowych (godziny) + interval: 24 + # Liczba dni przechowywania kopii zapasowych + retention-days: 7 + # Ścieżka do plików kopii zapasowych + path: "backups/" + # Format pliku kopii zapasowej + format: "yyyy-MM-dd_HH-mm-ss" diff --git a/gui.yml b/gui.yml index 0583a9e..f76ebe1 100644 --- a/gui.yml +++ b/gui.yml @@ -1,716 +1,716 @@ -# GUI配置文件 - -# 主界面配置 - 六个主要入口 -main-menu: - title: "&6工会系统" - size: 54 - items: - guild-info: - slot: 20 - material: BOOK - name: "&e工会信息" - lore: - - "&7查看工会详细信息" - - "&7包括基本信息、统计等" - glow: false - - member-management: - slot: 22 - material: PLAYER_HEAD - name: "&e成员管理" - lore: - - "&7管理工会成员" - - "&7邀请、踢出、权限管理" - glow: false - - application-management: - slot: 24 - material: PAPER - name: "&e申请管理" - lore: - - "&7处理加入申请" - - "&7查看申请历史" - glow: false - - guild-settings: - slot: 30 - material: COMPASS - name: "&e工会设置" - lore: - - "&7修改工会设置" - - "&7描述、标签、权限等" - glow: false - - guild-list: - slot: 32 - material: BOOKSHELF - name: "&e工会列表" - lore: - - "&7查看所有工会" - - "&7搜索、筛选功能" - glow: false - - guild-relations: - slot: 34 - material: RED_WOOL - name: "&e工会关系" - lore: - - "&7管理工会关系" - - "&7盟友、敌对等" - glow: false - - create-guild: - slot: 48 - material: EMERALD_BLOCK - name: "&a创建工会" - lore: - - "&7创建新的工会" - - "&7需要消耗金币" - glow: true - -# 工会信息界面 -guild-info: - title: "&6工会信息" - size: 54 - items: - guild-name: - slot: 10 - material: NAME_TAG - name: "&e工会名称" - lore: - - "&f{guild_name}" - - "&7工会ID: {guild_id}" - - guild-tag: - slot: 12 - material: OAK_SIGN - name: "&e工会标签" - lore: - - "&f{guild_tag}" - - "&7标签用于快速识别" - - guild-description: - slot: 14 - material: BOOK - name: "&e工会描述" - lore: - - "&f{guild_description}" - - "&7工会的详细介绍" - - guild-leader: - slot: 16 - material: GOLDEN_HELMET - name: "&e工会会长" - lore: - - "&f{leader_name}" - - "&7会长拥有所有权限" - - guild-home: - slot: 19 - material: COMPASS - name: "&e工会家" - lore: - - "&f{guild_home_location}" - - "&7成员可传送到此处" - - member-count: - slot: 28 - material: PLAYER_HEAD - name: "&e成员数量" - lore: - - "&f{member_count}/{guild_max_members} 人" - - "&7在线: {online_member_count} 人" - - guild-level: - slot: 30 - material: EXPERIENCE_BOTTLE - name: "&e工会等级" - lore: - - "&f等级 {guild_level}" - - "&7最大成员: {guild_max_members} 人" - - "&7升级进度: {guild_level_progress}" - - guild-balance: - slot: 32 - material: GOLD_INGOT - name: "&e工会资金" - lore: - - "&f{guild_balance_formatted}" - - "&7升级需要: {guild_next_level_requirement}" - - created-date: - slot: 34 - material: CLOCK - name: "&e创建时间" - lore: - - "&f{guild_created_date}" - - "&7{guild_created_time}" - - guild-status: - slot: 36 - material: BEACON - name: "&e工会状态" - lore: - - "&f{guild_frozen}" - - "&7工会当前状态" - - back: - slot: 49 - material: ARROW - name: "&7返回" - lore: - - "&7返回主菜单" - -# 成员管理界面 -member-management: - title: "&6成员管理" - size: 54 - items: - invite-member: - slot: 45 - material: EMERALD_BLOCK - name: "&a邀请成员" - lore: - - "&7邀请新成员加入" - - "&7当前成员: {member_count} 人" - - kick-member: - slot: 47 - material: REDSTONE_BLOCK - name: "&c踢出成员" - lore: - - "&7踢出工会成员" - - "&7需要官员或更高权限" - - promote-member: - slot: 49 - material: GOLD_INGOT - name: "&6提升成员" - lore: - - "&7提升成员职位" - - "&7只有会长可以操作" - - demote-member: - slot: 51 - material: IRON_INGOT - name: "&7降级成员" - lore: - - "&7降级成员职位" - - "&7只有会长可以操作" - - back: - slot: 53 - material: ARROW - name: "&7返回" - lore: - - "&7返回主菜单" - - next-page: - slot: 26 - material: ARROW - name: "&a下一页" - lore: - - "&7查看下一页" - - previous-page: - slot: 18 - material: ARROW - name: "&c上一页" - lore: - - "&7查看上一页" - -# 成员详情界面 -member-details: - title: "&6成员详情 - {member_name}" - size: 54 - -# 申请管理界面 -application-management: - title: "&6申请管理" - size: 54 - items: - pending-applications: - slot: 20 - material: PAPER - name: "&e待处理申请" - lore: - - "&7查看待处理的申请" - - "&f{pending_count} 个申请" - - "&7需要及时处理" - - application-history: - slot: 24 - material: BOOK - name: "&e申请历史" - lore: - - "&7查看申请历史记录" - - "&7已处理的申请" - - back: - slot: 49 - material: ARROW - name: "&7返回" - lore: - - "&7返回主菜单" - - next-page: - slot: 26 - material: ARROW - name: "&a下一页" - lore: - - "&7查看下一页" - - previous-page: - slot: 18 - material: ARROW - name: "&c上一页" - lore: - - "&7查看上一页" - -# 工会设置界面 -guild-settings: - title: "&6工会设置" - size: 54 - items: - change-description: - slot: 20 - material: BOOK - name: "&e修改描述" - lore: - - "&7修改工会描述" - - "&7当前: {guild_description}" - - change-tag: - slot: 22 - material: OAK_SIGN - name: "&e修改标签" - lore: - - "&7修改工会标签" - - "&7当前: {guild_tag}" - - set-home: - slot: 24 - material: COMPASS - name: "&e设置工会家" - lore: - - "&7设置工会传送点" - - "&7当前: {guild_home_location}" - - permissions: - slot: 30 - material: SHIELD - name: "&e权限设置" - lore: - - "&7管理成员权限" - - "&7角色权限管理" - - back: - slot: 49 - material: ARROW - name: "&7返回" - lore: - - "&7返回主菜单" - -# 工会列表界面 -guild-list: - title: "&6工会列表" - size: 54 - items: - search: - slot: 45 - material: COMPASS - name: "&e搜索工会" - lore: - - "&7搜索特定工会" - - "&7当前搜索: {search_query}" - - filter: - slot: 47 - material: HOPPER - name: "&e筛选" - lore: - - "&7按条件筛选工会" - - "&7当前筛选: {filter_type}" - - back: - slot: 49 - material: ARROW - name: "&7返回" - lore: - - "&7返回主菜单" - - next-page: - slot: 26 - material: ARROW - name: "&a下一页" - lore: - - "&7查看下一页" - - previous-page: - slot: 18 - material: ARROW - name: "&c上一页" - lore: - - "&7查看上一页" - -# 工会关系界面 -guild-relations: - title: "&6工会关系" - size: 54 - items: - allies: - slot: 20 - material: GREEN_WOOL - name: "&a盟友工会" - lore: - - "&7查看盟友工会" - - "&7管理盟友关系" - - enemies: - slot: 24 - material: RED_WOOL - name: "&c敌对工会" - lore: - - "&7查看敌对工会" - - "&7管理敌对关系" - - war: - slot: 28 - material: NETHERITE_SWORD - name: "&4开战工会" - lore: - - "&7查看开战工会" - - "&7管理战争状态" - - neutral: - slot: 32 - material: GRAY_WOOL - name: "&7中立工会" - lore: - - "&7查看中立工会" - - "&7管理中立关系" - - back: - slot: 49 - material: ARROW - name: "&7返回" - lore: - - "&7返回主菜单" - -# 成员信息显示 -member-display: - leader: - material: GOLDEN_HELMET - name: "&c{player_name}" - lore: - - "&7角色: &c会长" - - "&7加入时间: {joined_date}" - - "&7权限: 所有权限" - - officer: - material: GOLDEN_HELMET - name: "&6{player_name}" - lore: - - "&7角色: &6官员" - - "&7加入时间: {joined_date}" - - "&7权限: 邀请、踢出" - - member: - material: PLAYER_HEAD - name: "&f{player_name}" - lore: - - "&7角色: &f成员" - - "&7加入时间: {joined_date}" - - "&7权限: 基础权限" - -# 申请信息显示 -application-display: - pending: - material: YELLOW_WOOL - name: "&e{player_name} 的申请" - lore: - - "&7状态: &e待处理" - - "&7申请时间: {apply_date}" - - "&7消息: {message}" - - "" - - "&a左键: 接受" - - "&c右键: 拒绝" - - accepted: - material: GREEN_WOOL - name: "&a{player_name} 的申请" - lore: - - "&7状态: &a已接受" - - "&7处理时间: {process_date}" - - "&7处理人: {processor}" - - rejected: - material: RED_WOOL - name: "&c{player_name} 的申请" - lore: - - "&7状态: &c已拒绝" - - "&7处理时间: {process_date}" - - "&7处理人: {processor}" - -# 工会信息显示 -guild-display: - material: SHIELD - name: "&e{guild_name}" - lore: - - "&7标签: {guild_tag}" - - "&7会长: {guild_leader}" - - "&7成员: {member_count}/{max_members}" - - "&7创建时间: {created_date}" - - "" - - "&a左键: 查看详情" - - "&e右键: 申请加入" - -# 创建工会界面 -create-guild: - title: "&6创建工会" - size: 54 - items: - name-input: - slot: 20 - material: NAME_TAG - name: "&e工会名称" - lore: - - "&7点击输入工会名称" - - "&7长度: 3-20 字符" - - "&7当前: {guild_name}" - - tag-input: - slot: 22 - material: OAK_SIGN - name: "&e工会标签" - lore: - - "&7点击输入工会标签" - - "&7长度: 最多6字符" - - "&7可选" - - "&7当前: {guild_tag}" - - description-input: - slot: 24 - material: BOOK - name: "&e工会描述" - lore: - - "&7点击输入工会描述" - - "&7长度: 最多100字符" - - "&7可选" - - "&7当前: {guild_description}" - - confirm: - slot: 39 - material: EMERALD_BLOCK - name: "&a确认创建" - lore: - - "&7确认创建工会" - - "&7费用: {cost} 金币" - - "&7创建者: {player_name}" - glow: true - - cancel: - slot: 41 - material: REDSTONE_BLOCK - name: "&c取消" - lore: - - "&7取消创建工会" - -# 邀请界面 -invite-player: - title: "&6邀请玩家" - size: 54 - items: - player-input: - slot: 22 - material: PLAYER_HEAD - name: "&e选择玩家" - lore: - - "&7点击选择要邀请的玩家" - - confirm: - slot: 39 - material: EMERALD_BLOCK - name: "&a发送邀请" - lore: - - "&7确认发送邀请" - glow: true - - cancel: - slot: 41 - material: REDSTONE_BLOCK - name: "&c取消" - lore: - - "&7取消邀请" - -# 确认界面 -confirm: - title: "&6确认操作" - size: 27 - items: - confirm: - slot: 11 - material: EMERALD_BLOCK - name: "&a确认" - lore: - - "&7确认执行此操作" - glow: true - - cancel: - slot: 15 - material: REDSTONE_BLOCK - name: "&c取消" - lore: - - "&7取消操作" - -# 装饰物品 -decorations: - border: - material: BLACK_STAINED_GLASS_PANE - name: " " - - info: - material: LIGHT_BLUE_STAINED_GLASS_PANE - name: "&b工会系统" - lore: - - "&7功能强大的工会插件" - -# 管理员GUI -admin-gui: - title: "&4工会管理" - size: 54 - items: - guild-list: - slot: 20 - material: BOOKSHELF - name: "&e工会列表管理" - lore: - - "&7查看和管理所有工会" - - "&7包括删除、冻结等操作" - - "&e左键: 查看详情" - - "&c右键: 删除工会" - - "&6中键: 冻结/解冻" - - economy: - slot: 22 - material: GOLD_INGOT - name: "&e经济管理" - lore: - - "&7管理工会经济系统" - - "&7设置资金、查看贡献等" - - "&e左键: 设置资金" - - "&a右键: 增加资金" - - "&c中键: 减少资金" - - relations: - slot: 24 - material: RED_WOOL - name: "&e关系管理" - lore: - - "&7管理工会关系" - - "&7盟友、敌对、开战等" - - "&c左键: 删除关系" - - "&e右键: 查看详情" - - statistics: - slot: 29 - material: PAPER - name: "&e统计信息" - lore: - - "&7查看工会统计信息" - - "&7成员数量、经济状况等" - - "&e点击查看详细统计" - - settings: - slot: 31 - material: COMPASS - name: "&e系统设置" - lore: - - "&7管理系统设置" - - "&7重载配置、权限设置等" - - "&e点击进入设置" - - back: - slot: 49 - material: ARROW - name: "&c返回" - lore: - - "&7返回主菜单" - - - -# 工会经济GUI -guild-economy: - title: "&6工会经济" - size: 54 - items: - balance: - slot: 20 - material: GOLD_INGOT - name: "&e当前资金" - lore: - - "&7工会当前资金" - - "&f{balance} 金币" - - deposit: - slot: 22 - material: EMERALD_BLOCK - name: "&a存入资金" - lore: - - "&7向工会存入资金" - - "&7点击输入金额" - - withdraw: - slot: 24 - material: REDSTONE_BLOCK - name: "&c取出资金" - lore: - - "&7从工会取出资金" - - "&7点击输入金额" - - level: - slot: 29 - material: EXPERIENCE_BOTTLE - name: "&e工会等级" - lore: - - "&7当前等级: {level}" - - "&7升级进度: {progress}%" - - "&7最大成员: {max_members}" - - contributions: - slot: 31 - material: BOOK - name: "&e贡献记录" - lore: - - "&7查看贡献记录" - - "&7您的贡献: {contribution}" - - transfer: - slot: 33 - material: DIAMOND - name: "&b转账" - lore: - - "&7向其他工会转账" - - "&7点击选择目标工会" - - back: - slot: 49 - material: ARROW - name: "&c返回" - lore: - - "&7返回上级菜单" - -# 工会详情界面 -guild-detail: - title: "&6工会详情 - {guild_name}" - size: 54 - -# 系统设置界面 -system-settings: - title: "&4系统设置" - size: 54 - -# 工会日志界面 -guild-logs: - title: "&6工会日志 - {guild_name}" - size: 54 +# Plik konfiguracyjny GUI + +# Konfiguracja głównego menu - Sześć głównych wejść +main-menu: + title: "&6System Gildii" + size: 54 + items: + guild-info: + slot: 20 + material: BOOK + name: "&eInformacje o Gildii" + lore: + - "&7Zobacz szczegóły gildii" + - "&7W tym podstawowe informacje, statystyki itp." + glow: false + + member-management: + slot: 22 + material: PLAYER_HEAD + name: "&eZarządzanie Członkami" + lore: + - "&7Zarządzaj członkami gildii" + - "&7Zaproś, wyrzuć, zarządzaj uprawnieniami" + glow: false + + application-management: + slot: 24 + material: PAPER + name: "&eZarządzanie Aplikacjami" + lore: + - "&7Przetwarzaj aplikacje o dołączenie" + - "&7Zobacz historię aplikacji" + glow: false + + guild-settings: + slot: 30 + material: COMPASS + name: "&eUstawienia Gildii" + lore: + - "&7Zmień ustawienia gildii" + - "&7Opis, tag, uprawnienia itp." + glow: false + + guild-list: + slot: 32 + material: BOOKSHELF + name: "&eLista Gildii" + lore: + - "&7Zobacz wszystkie gildie" + - "&7Wyszukiwanie, filtrowanie" + glow: false + + guild-relations: + slot: 34 + material: RED_WOOL + name: "&eRelacje Gildii" + lore: + - "&7Zarządzaj relacjami gildii" + - "&7Sojusznicy, wrogowie itp." + glow: false + + create-guild: + slot: 48 + material: EMERALD_BLOCK + name: "&aUtwórz Gildię" + lore: + - "&7Utwórz nową gildię" + - "&7Wymaga opłaty w monetach" + glow: true + +# Interfejs informacji o gildii +guild-info: + title: "&6Informacje o Gildii" + size: 54 + items: + guild-name: + slot: 10 + material: NAME_TAG + name: "&eNazwa Gildii" + lore: + - "&f{guild_name}" + - "&7ID Gildii: {guild_id}" + + guild-tag: + slot: 12 + material: OAK_SIGN + name: "&eTag Gildii" + lore: + - "&f{guild_tag}" + - "&7Tag służy do szybkiej identyfikacji" + + guild-description: + slot: 14 + material: BOOK + name: "&eOpis Gildii" + lore: + - "&f{guild_description}" + - "&7Szczegółowe wprowadzenie do gildii" + + guild-leader: + slot: 16 + material: GOLDEN_HELMET + name: "&eLider Gildii" + lore: + - "&f{leader_name}" + - "&7Lider posiada wszystkie uprawnienia" + + guild-home: + slot: 19 + material: COMPASS + name: "&eDom Gildii" + lore: + - "&f{guild_home_location}" + - "&7Członkowie mogą się tu teleportować" + + member-count: + slot: 28 + material: PLAYER_HEAD + name: "&eLiczba Członków" + lore: + - "&f{member_count}/{guild_max_members} osób" + - "&7Online: {online_member_count} osób" + + guild-level: + slot: 30 + material: EXPERIENCE_BOTTLE + name: "&ePoziom Gildii" + lore: + - "&fPoziom {guild_level}" + - "&7Maks. członków: {guild_max_members} osób" + - "&7Postęp ulepszania: {guild_level_progress}" + + guild-balance: + slot: 32 + material: GOLD_INGOT + name: "&eFundusze Gildii" + lore: + - "&f{guild_balance_formatted}" + - "&7Wymagane do awansu: {guild_next_level_requirement}" + + created-date: + slot: 34 + material: CLOCK + name: "&eData Utworzenia" + lore: + - "&f{guild_created_date}" + - "&7{guild_created_time}" + + guild-status: + slot: 36 + material: BEACON + name: "&eStatus Gildii" + lore: + - "&f{guild_frozen}" + - "&7Obecny status gildii" + + back: + slot: 49 + material: ARROW + name: "&7Wróć" + lore: + - "&7Wróć do menu głównego" + +# Interfejs zarządzania członkami +member-management: + title: "&6Zarządzanie Członkami" + size: 54 + items: + invite-member: + slot: 45 + material: EMERALD_BLOCK + name: "&aZaproś Członka" + lore: + - "&7Zaproś nowego członka" + - "&7Obecnie członków: {member_count} osób" + + kick-member: + slot: 47 + material: REDSTONE_BLOCK + name: "&cWyrzuć Członka" + lore: + - "&7Wyrzuć członka gildii" + - "&7Wymaga uprawnień oficera lub wyższych" + + promote-member: + slot: 49 + material: GOLD_INGOT + name: "&6Awansuj Członka" + lore: + - "&7Awansuj członka na wyższą rangę" + - "&7Tylko lider może wykonać tę operację" + + demote-member: + slot: 51 + material: IRON_INGOT + name: "&7Zdegraduj Członka" + lore: + - "&7Zdegraduj członka na niższą rangę" + - "&7Tylko lider może wykonać tę operację" + + back: + slot: 53 + material: ARROW + name: "&7Wróć" + lore: + - "&7Wróć do menu głównego" + + next-page: + slot: 26 + material: ARROW + name: "&aNastępna strona" + lore: + - "&7Zobacz następną stronę" + + previous-page: + slot: 18 + material: ARROW + name: "&cPoprzednia strona" + lore: + - "&7Zobacz poprzednią stronę" + +# Interfejs szczegółów członka +member-details: + title: "&6Szczegóły Członka - {member_name}" + size: 54 + +# Interfejs zarządzania aplikacjami +application-management: + title: "&6Zarządzanie Aplikacjami" + size: 54 + items: + pending-applications: + slot: 20 + material: PAPER + name: "&eOczekujące Aplikacje" + lore: + - "&7Zobacz oczekujące aplikacje" + - "&f{pending_count} aplikacji" + - "&7Wymagają przetworzenia" + + application-history: + slot: 24 + material: BOOK + name: "&eHistoria Aplikacji" + lore: + - "&7Zobacz historię aplikacji" + - "&7Przetworzone aplikacje" + + back: + slot: 49 + material: ARROW + name: "&7Wróć" + lore: + - "&7Wróć do menu głównego" + + next-page: + slot: 26 + material: ARROW + name: "&aNastępna strona" + lore: + - "&7Zobacz następną stronę" + + previous-page: + slot: 18 + material: ARROW + name: "&cPoprzednia strona" + lore: + - "&7Zobacz poprzednią stronę" + +# Interfejs ustawień gildii +guild-settings: + title: "&6Ustawienia Gildii" + size: 54 + items: + change-description: + slot: 20 + material: BOOK + name: "&eZmień Opis" + lore: + - "&7Zmień opis gildii" + - "&7Obecny: {guild_description}" + + change-tag: + slot: 22 + material: OAK_SIGN + name: "&eZmień Tag" + lore: + - "&7Zmień tag gildii" + - "&7Obecny: {guild_tag}" + + set-home: + slot: 24 + material: COMPASS + name: "&eUstaw Dom Gildii" + lore: + - "&7Ustaw punkt teleportacji gildii" + - "&7Obecny: {guild_home_location}" + + permissions: + slot: 30 + material: SHIELD + name: "&eUstawienia Uprawnień" + lore: + - "&7Zarządzaj uprawnieniami członków" + - "&7Zarządzanie uprawnieniami ról" + + back: + slot: 49 + material: ARROW + name: "&7Wróć" + lore: + - "&7Wróć do menu głównego" + +# Interfejs listy gildii +guild-list: + title: "&6Lista Gildii" + size: 54 + items: + search: + slot: 45 + material: COMPASS + name: "&eSzukaj Gildii" + lore: + - "&7Szukaj konkretnej gildii" + - "&7Obecne wyszukiwanie: {search_query}" + + filter: + slot: 47 + material: HOPPER + name: "&eFiltrowanie" + lore: + - "&7Filtruj gildie według kryteriów" + - "&7Obecny filtr: {filter_type}" + + back: + slot: 49 + material: ARROW + name: "&7Wróć" + lore: + - "&7Wróć do menu głównego" + + next-page: + slot: 26 + material: ARROW + name: "&aNastępna strona" + lore: + - "&7Zobacz następną stronę" + + previous-page: + slot: 18 + material: ARROW + name: "&cPoprzednia strona" + lore: + - "&7Zobacz poprzednią stronę" + +# Interfejs relacji gildii +guild-relations: + title: "&6Relacje Gildii" + size: 54 + items: + allies: + slot: 20 + material: GREEN_WOOL + name: "&aSojusznicy" + lore: + - "&7Zobacz sojuszników" + - "&7Zarządzaj sojuszami" + + enemies: + slot: 24 + material: RED_WOOL + name: "&cWrogowie" + lore: + - "&7Zobacz wrogów" + - "&7Zarządzaj wrogami" + + war: + slot: 28 + material: NETHERITE_SWORD + name: "&4Gildie w Wojnie" + lore: + - "&7Zobacz gildie w stanie wojny" + - "&7Zarządzaj statusem wojny" + + neutral: + slot: 32 + material: GRAY_WOOL + name: "&7Gildie Neutralne" + lore: + - "&7Zobacz gildie neutralne" + - "&7Zarządzaj relacjami neutralnymi" + + back: + slot: 49 + material: ARROW + name: "&7Wróć" + lore: + - "&7Wróć do menu głównego" + +# Wyświetlanie informacji o członku +member-display: + leader: + material: GOLDEN_HELMET + name: "&c{player_name}" + lore: + - "&7Rola: &cLider" + - "&7Dołączył: {joined_date}" + - "&7Uprawnienia: Wszystkie" + + officer: + material: GOLDEN_HELMET + name: "&6{player_name}" + lore: + - "&7Rola: &6Oficer" + - "&7Dołączył: {joined_date}" + - "&7Uprawnienia: Zapraszanie, Wyrzucanie" + + member: + material: PLAYER_HEAD + name: "&f{player_name}" + lore: + - "&7Rola: &fCzłonek" + - "&7Dołączył: {joined_date}" + - "&7Uprawnienia: Podstawowe" + +# Wyświetlanie informacji o aplikacji +application-display: + pending: + material: YELLOW_WOOL + name: "&eAplikacja gracza {player_name}" + lore: + - "&7Status: &eOczekująca" + - "&7Data złożenia: {apply_date}" + - "&7Wiadomość: {message}" + - "" + - "&aLPM: Akceptuj" + - "&cPPM: Odrzuć" + + accepted: + material: GREEN_WOOL + name: "&aAplikacja gracza {player_name}" + lore: + - "&7Status: &aZaakceptowana" + - "&7Data przetworzenia: {process_date}" + - "&7Przetworzył: {processor}" + + rejected: + material: RED_WOOL + name: "&cAplikacja gracza {player_name}" + lore: + - "&7Status: &cOdrzucona" + - "&7Data przetworzenia: {process_date}" + - "&7Przetworzył: {processor}" + +# Wyświetlanie informacji o gildii +guild-display: + material: SHIELD + name: "&e{guild_name}" + lore: + - "&7Tag: {guild_tag}" + - "&7Lider: {guild_leader}" + - "&7Członkowie: {member_count}/{max_members}" + - "&7Data utworzenia: {created_date}" + - "" + - "&aLPM: Zobacz szczegóły" + - "&ePPM: Aplikuj o dołączenie" + +# Interfejs tworzenia gildii +create-guild: + title: "&6Utwórz Gildię" + size: 54 + items: + name-input: + slot: 20 + material: NAME_TAG + name: "&eNazwa Gildii" + lore: + - "&7Kliknij, aby wprowadzić nazwę gildii" + - "&7Długość: 3-20 znaków" + - "&7Obecna: {guild_name}" + + tag-input: + slot: 22 + material: OAK_SIGN + name: "&eTag Gildii" + lore: + - "&7Kliknij, aby wprowadzić tag gildii" + - "&7Długość: maks. 6 znaków" + - "&7Opcjonalne" + - "&7Obecny: {guild_tag}" + + description-input: + slot: 24 + material: BOOK + name: "&eOpis Gildii" + lore: + - "&7Kliknij, aby wprowadzić opis gildii" + - "&7Długość: maks. 100 znaków" + - "&7Opcjonalne" + - "&7Obecny: {guild_description}" + + confirm: + slot: 39 + material: EMERALD_BLOCK + name: "&aPotwierdź Utworzenie" + lore: + - "&7Potwierdź utworzenie gildii" + - "&7Koszt: {cost} monet" + - "&7Twórca: {player_name}" + glow: true + + cancel: + slot: 41 + material: REDSTONE_BLOCK + name: "&cAnuluj" + lore: + - "&7Anuluj tworzenie gildii" + +# Interfejs zaproszeń +invite-player: + title: "&6Zaproś Gracza" + size: 54 + items: + player-input: + slot: 22 + material: PLAYER_HEAD + name: "&eWybierz Gracza" + lore: + - "&7Kliknij, aby wybrać gracza do zaproszenia" + + confirm: + slot: 39 + material: EMERALD_BLOCK + name: "&aWyślij Zaproszenie" + lore: + - "&7Potwierdź wysłanie zaproszenia" + glow: true + + cancel: + slot: 41 + material: REDSTONE_BLOCK + name: "&cAnuluj" + lore: + - "&7Anuluj zaproszenie" + +# Interfejs potwierdzenia +confirm: + title: "&6Potwierdź Operację" + size: 27 + items: + confirm: + slot: 11 + material: EMERALD_BLOCK + name: "&aPotwierdź" + lore: + - "&7Potwierdź wykonanie tej operacji" + glow: true + + cancel: + slot: 15 + material: REDSTONE_BLOCK + name: "&cAnuluj" + lore: + - "&7Anuluj operację" + +# Elementy dekoracyjne +decorations: + border: + material: BLACK_STAINED_GLASS_PANE + name: " " + + info: + material: LIGHT_BLUE_STAINED_GLASS_PANE + name: "&bSystem Gildii" + lore: + - "&7Potężny plugin gildyjny" + +# GUI Administratora +admin-gui: + title: "&4Zarządzanie Gildiami" + size: 54 + items: + guild-list: + slot: 20 + material: BOOKSHELF + name: "&eZarządzanie Listą Gildii" + lore: + - "&7Przeglądaj i zarządzaj wszystkimi gildiami" + - "&7W tym usuwanie, zamrażanie itp." + - "&eLPM: Zobacz szczegóły" + - "&cPPM: Usuń gildię" + - "&6ŚPM: Zamroź/Odmroź" + + economy: + slot: 22 + material: GOLD_INGOT + name: "&eZarządzanie Ekonomią" + lore: + - "&7Zarządzaj systemem ekonomii gildii" + - "&7Ustaw fundusze, zobacz wkłady itp." + - "&eLPM: Ustaw fundusze" + - "&aPPM: Dodaj fundusze" + - "&cŚPM: Odejmij fundusze" + + relations: + slot: 24 + material: RED_WOOL + name: "&eZarządzanie Relacjami" + lore: + - "&7Zarządzaj relacjami gildii" + - "&7Sojusznicy, wrogowie, wojny itp." + - "&cLPM: Usuń relację" + - "&ePPM: Zobacz szczegóły" + + statistics: + slot: 29 + material: PAPER + name: "&eStatystyki" + lore: + - "&7Zobacz statystyki gildii" + - "&7Liczba członków, stan ekonomii itp." + - "&eKliknij, aby zobaczyć szczegółowe statystyki" + + settings: + slot: 31 + material: COMPASS + name: "&eUstawienia Systemowe" + lore: + - "&7Zarządzaj ustawieniami systemowymi" + - "&7Przeładuj konfigurację, ustawienia uprawnień itp." + - "&eKliknij, aby wejść w ustawienia" + + back: + slot: 49 + material: ARROW + name: "&cWróć" + lore: + - "&7Wróć do menu głównego" + + + +# GUI Ekonomii Gildii +guild-economy: + title: "&6Ekonomia Gildii" + size: 54 + items: + balance: + slot: 20 + material: GOLD_INGOT + name: "&eObecne Fundusze" + lore: + - "&7Obecne fundusze gildii" + - "&f{balance} monet" + + deposit: + slot: 22 + material: EMERALD_BLOCK + name: "&aWpłać Fundusze" + lore: + - "&7Wpłać fundusze do gildii" + - "&7Kliknij, aby wprowadzić kwotę" + + withdraw: + slot: 24 + material: REDSTONE_BLOCK + name: "&cWypłać Fundusze" + lore: + - "&7Wypłać fundusze z gildii" + - "&7Kliknij, aby wprowadzić kwotę" + + level: + slot: 29 + material: EXPERIENCE_BOTTLE + name: "&ePoziom Gildii" + lore: + - "&7Obecny poziom: {level}" + - "&7Postęp ulepszania: {progress}%" + - "&7Maks. członków: {max_members}" + + contributions: + slot: 31 + material: BOOK + name: "&eRejestr Wkładów" + lore: + - "&7Zobacz rejestr wkładów" + - "&7Twój wkład: {contribution}" + + transfer: + slot: 33 + material: DIAMOND + name: "&bPrzelew" + lore: + - "&7Przelej środki do innej gildii" + - "&7Kliknij, aby wybrać gildię docelową" + + back: + slot: 49 + material: ARROW + name: "&cWróć" + lore: + - "&7Wróć do menu nadrzędnego" + +# Interfejs szczegółów gildii +guild-detail: + title: "&6Szczegóły Gildii - {guild_name}" + size: 54 + +# Interfejs ustawień systemowych +system-settings: + title: "&4Ustawienia Systemowe" + size: 54 + +# Interfejs logów gildii +guild-logs: + title: "&6Logi Gildii - {guild_name}" + size: 54 diff --git a/messages.yml b/messages.yml index d635d08..85d4603 100644 --- a/messages.yml +++ b/messages.yml @@ -1,544 +1,534 @@ -# 工会插件消息配置文件 - -# 通用消息 -general: - prefix: "&6[工会] &r" - no-permission: "&c您没有权限执行此操作!" - player-only: "&c此命令只能由玩家执行!" - player-not-found: "&c玩家 {player} 未找到!" - guild-not-found: "&c工会 {guild} 未找到!" - invalid-arguments: "&c参数无效!" - error-occurred: "&c发生错误:{error}" - service-error: "&c工会服务未初始化!" - unknown-command: "&c未知命令!使用 /guild help 查看帮助。" - -# 工会创建相关消息 -create: - success: "&a工会 {name} 创建成功!" - name-too-short: "&c工会名称太短!最少需要 {min} 个字符。" - name-too-long: "&c工会名称太长!最多只能有 {max} 个字符。" - name-exists: "&c工会名称 {name} 已存在!" - name-required: "&c请先输入工会名称!" - tag-exists: "&c工会标签 {tag} 已存在!" - tag-too-long: "&c工会标签太长!最多只能有 {max} 个字符。" - already-in-guild: "&c您已经在一个工会中了!" - insufficient-funds: "&c您的余额不足!创建工会需要 {cost} 金币。" - usage: "&e用法: /guild create <名称> [标签] [描述]" - description-too-long: "&c工会描述不能超过100个字符!" - failed: "&c工会创建失败!可能的原因:" - failed-reason-1: "&c- 工会名称或标签已存在" - failed-reason-2: "&c- 您已经加入了其他工会" - name-info: "&e工会名称: {name}" - tag-info: "&e工会标签: [{tag}]" - description-info: "&e工会描述: {description}" - economy-not-available: "&c经济系统不可用,无法创建工会!" - payment-failed: "&c扣除创建费用失败!" - payment-refunded: "&e已退还创建费用 {cost} 金币。" - cost-info: "&e创建费用: {amount}" - -# 工会信息相关消息 -info: - title: "&6=== 工会信息 ===" - name: "&e名称: &f{name}" - tag: "&e标签: &f{tag}" - description: "&e描述: &f{description}" - leader: "&e会长: &f{leader}" - members: "&e成员数量: &f{count}/{max}" - created: "&e创建时间: &f{date}" - no-guild: "&c您还没有加入任何工会!" - role: "&e您的角色: &f{role}" - -# 工会成员相关消息 -members: - title: "&6=== 工会成员 ===" - leader: "&c{name} &7(会长)" - officer: "&6{name} &7(官员)" - member: "&f{name} &7(成员)" - joined: "&7加入时间: {date}" - no-members: "&c工会中没有成员!" - member-format: "&e{role} {name} &7- {status}" - total: "&e总计: {count} 人" - -# 邀请相关消息 -invite: - sent: "&a已向 {player} 发送工会邀请!" - received: "&e{inviter} 邀请您加入工会: {guild}" - accepted: "&a您已接受 {guild} 的邀请!" - declined: "&c您已拒绝 {guild} 的邀请!" - expired: "&c工会邀请已过期!" - already-invited: "&c{player} 已经收到了邀请!" - no-permission: "&c您没有权限邀请玩家!" - usage: "&e用法: /guild invite <玩家>" - title: "&6=== 工会邀请 ===" - guild-tag: "&e工会标签: [{tag}]" - accept-command: "&e输入 &a/guild accept {inviter} &e接受邀请" - decline-command: "&e输入 &c/guild decline {inviter} &e拒绝邀请" - already-in-guild: "&c玩家 {player} 已经加入了其他工会!" - cannot-invite-self: "&c您不能邀请自己!" - -# 踢出相关消息 -kick: - success: "&a已将 {player} 踢出工会!" - kicked: "&c您已被踢出工会 {guild}!" - no-permission: "&c您没有权限踢出玩家!" - cannot-kick-leader: "&c不能踢出工会会长!" - usage: "&e用法: /guild kick <玩家>" - player-not-found: "&c玩家 {player} 不在线!" - not-in-guild: "&c玩家 {player} 不在您的工会中!" - cannot-kick-self: "&c您不能踢出自己!使用 /guild leave 离开工会。" - failed: "&c踢出玩家失败!" - -# 离开工会相关消息 -leave: - success: "&a您已离开工会!" - leader-cannot-leave: "&c工会会长不能离开工会!请先转让会长职位或删除工会。" - confirm: "&c您确定要离开工会吗?使用 /guild leave confirm 确认。" - member-error: "&c工会成员信息错误!" - success-with-guild: "&a您已成功离开工会: {guild}" - failed: "&c离开工会失败!" - use-delete: "&c如果您想解散工会,请使用 /guild delete 命令。" - -# 删除工会相关消息 -delete: - success: "&a工会 {guild} 已删除!" - no-permission: "&c您没有权限删除工会!" - confirm: "&c您确定要删除工会吗?这将解散整个工会!使用 /guild delete confirm 确认。" - only-leader: "&c只有工会会长才能删除工会!" - warning: "&c警告:删除工会将永久解散工会,所有成员将被移除!" - confirm-command: "&c如果您确定要删除工会,请再次输入: /guild delete confirm" - cancel-command: "&c或者输入: /guild delete cancel 取消操作" - -# 工会家相关消息 -sethome: - success: "&a工会家设置成功!" - failed: "&c设置工会家失败!" - only-leader: "&c只有工会会长才能设置工会家!" - no-permission: "&c您没有权限设置工会家!" -home: - success: "&a已传送到工会家!" - not-set: "&c工会家尚未设置!" - no-permission: "&c您没有权限传送到工会家!" - teleport-failed: "&c传送到工会家失败!" - -# 申请相关消息 -application: - sent: "&a您的申请已发送给 {guild}!" - received: "&a收到来自 {player} 的申请!" - accepted: "&a您的申请已被 {guild} 接受!" - declined: "&c您的申请已被 {guild} 拒绝!" - already-applied: "&c您已经向 {guild} 申请过了!" - usage: "&e用法: /guild apply <工会> [消息]" - -# 申请相关消息(GUI使用) -apply: - success: "&a申请已提交!" - failed: "&c申请提交失败!" - already-applied: "&c您已经申请过这个工会了!" - -# 工会关系相关消息 -relation: - no-guild: "&c您还没有加入工会!" - only-leader: "&c只有工会会长才能管理工会关系!" - help-title: "&6=== 工会关系管理 ===" - help-list: "&e/guild relation list &7- 查看所有关系" - help-create: "&e/guild relation create <工会> <类型> &7- 创建关系" - help-delete: "&e/guild relation delete <工会> &7- 删除关系" - help-accept: "&e/guild relation accept <工会> &7- 接受关系请求" - help-reject: "&e/guild relation reject <工会> &7- 拒绝关系请求" - help-types: "&7关系类型: &eally(盟友), enemy(敌对), war(开战), truce(停战), neutral(中立)" - create-usage: "&e用法: /guild relation create <目标工会> <关系类型>" - delete-usage: "&e用法: /guild relation delete <目标工会>" - accept-usage: "&e用法: /guild relation accept <目标工会>" - reject-usage: "&e用法: /guild relation reject <目标工会>" - unknown-subcommand: "&c未知的子命令!使用 /guild relation 查看帮助。" - no-relations: "&7您的工会还没有任何关系。" - list-title: "&6=== 工会关系列表 ===" - list-format: "&e{other_guild} &7- {type} ({status})" - invalid-type: "&c无效的关系类型!有效类型: ally, enemy, war, truce, neutral" - target-not-found: "&c目标工会 {guild} 不存在!" - cannot-relation-self: "&c不能与自己建立关系!" - create-success: "&a已向 {guild} 发送 {type} 关系请求!" - create-failed: "&c创建关系失败!可能已经存在关系。" - delete-success: "&a已删除与 {guild} 的关系!" - delete-failed: "&c删除关系失败!可能关系不存在。" - accept-success: "&a已接受 {guild} 的关系请求!" - accept-failed: "&c接受关系失败!可能没有待处理的关系请求。" - reject-success: "&c已拒绝 {guild} 的关系请求!" - reject-failed: "&c拒绝关系失败!可能没有待处理的关系请求。" - -# 权限相关消息 -permissions: - promote: - success: "&a已将 {player} 提升为 {role}!" - no-permission: "&c您没有权限提升玩家!" - cannot-promote: "&c无法提升该玩家!" - usage: "&e用法: /guild promote <玩家>" - player-not-found: "&c玩家 {player} 不在线!" - not-in-guild: "&c玩家 {player} 不在您的工会中!" - already-highest: "&c玩家 {player} 已经是最高职位!" - cannot-promote-self: "&c您不能提升自己!" - demote: - success: "&a已将 {player} 降级为 {role}!" - no-permission: "&c您没有权限降级玩家!" - cannot-demote: "&c无法降级该玩家!" - usage: "&e用法: /guild demote <玩家>" - player-not-found: "&c玩家 {player} 不在线!" - not-in-guild: "&c玩家 {player} 不在您的工会中!" - already-lowest: "&c玩家 {player} 已经是最低职位!" - cannot-demote-self: "&c您不能降级自己!" - cannot-demote-leader: "&c不能降级工会会长!" - -# 管理员命令消息 -admin: - no-permission: "&c您没有管理员权限!" - unknown-command: "&c未知命令!使用 /guildadmin help 查看帮助。" - reload: - success: "&a配置重载成功!" - error: "&c配置重载失败:{error}" - list: - title: "&6=== 工会列表 ===" - entry: "&e{guild} &7- {count} 成员" - empty: "&c没有找到任何工会!" - total: "&e总计: {count} 个工会" - info: - title: "&6=== 工会详细信息 ===" - id: "&eID: &f{id}" - name: "&e名称: &f{name}" - tag: "&e标签: &f{tag}" - description: "&e描述: &f{description}" - leader: "&e会长: &f{leader}" - member-count: "&e成员数量: &f{count}" - created: "&e创建时间: &f{created}" - updated: "&e更新时间: &f{updated}" - usage: "&e用法: /guildadmin info <工会名称>" - not-found: "&c工会 {guild} 不存在!" - members-title: "&6=== 成员列表 ===" - delete: - success: "&a工会 {guild} 已被管理员删除!" - error: "&c删除工会失败:{error}" - usage: "&e用法: /guildadmin delete <工会名称>" - not-found: "&c工会 {guild} 不存在!" - warning: "&c警告:删除工会将永久解散工会,所有成员将被移除!" - confirm: "&c如果您确定要删除工会,请使用: /guildadmin delete {guild} confirm" - success-with-name: "&a已成功删除工会: {guild}" - failed: "&c删除工会失败!" - kick: - success: "&a已将 {player} 从 {guild} 踢出!" - error: "&c踢出玩家失败:{error}" - usage: "&e用法: /guildadmin kick <玩家名称> <工会名称>" - guild-not-found: "&c工会 {guild} 不存在!" - player-not-found: "&c玩家 {player} 不在线!" - player-not-in-guild: "&c玩家 {player} 不在工会 {guild} 中!" - cannot-kick-leader: "&c不能踢出工会会长!请先转让会长职位或删除工会。" - success-with-names: "&a已成功从工会 {guild} 踢出玩家 {player}!" - kicked-by-admin: "&c您已被管理员从工会 {guild} 踢出!" - failed: "&c踢出玩家失败!" - help: - title: "&6=== 工会管理员命令帮助 ===" - reload: "&e/guildadmin reload &7- 重载配置文件" - list: "&e/guildadmin list &7- 列出所有工会" - info: "&e/guildadmin info <工会名称> &7- 查看工会详细信息" - delete: "&e/guildadmin delete <工会名称> &7- 删除指定工会" - kick: "&e/guildadmin kick <玩家> <工会> &7- 从工会踢出玩家" - help: "&e/guildadmin help &7- 显示此帮助信息" - -# GUI相关消息 -gui: - title: "&6工会系统" - create-guild: "&a创建工会" - guild-info: "&e工会信息" - member-management: "&e成员管理" - application-management: "&e申请管理" - guild-settings: "&e工会设置" - guild-list: "&e工会列表" - guild-relations: "&e工会关系" - invite-player: "&e邀请玩家" - leave-guild: "&c离开工会" - delete-guild: "&4删除工会" - confirm: "&a确认" - cancel: "&c取消" - back: "&7返回" - next-page: "&a下一页" - previous-page: "&c上一页" - no-guild: "&c您还没有工会" - no-permission: "&c权限不足" - opening: "&a正在打开工会系统GUI..." - - # 主界面功能 - create-guild-success: "&a创建工会功能已就绪" - guild-info-success: "&a工会信息功能已就绪" - member-management-success: "&a成员管理功能已就绪" - application-management-success: "&a申请管理功能已就绪" - guild-settings-success: "&a工会设置功能已就绪" - guild-list-success: "&a工会列表功能已就绪" - guild-relations-success: "&a工会关系功能已就绪" - - # 功能消息 - invite-member-success: "&a邀请成员功能已就绪" - kick-member-success: "&a踢出成员功能已就绪" - promote-member-success: "&a提升成员功能已就绪" - demote-member-success: "&a降级成员功能已就绪" - accept-application-success: "&a接受申请功能已就绪" - reject-application-success: "&a拒绝申请功能已就绪" - application-history-success: "&a申请历史功能已就绪" - change-description-success: "&a修改描述功能已就绪" - change-tag-success: "&a修改标签功能已就绪" - permissions-success: "&a权限设置功能已就绪" - search-success: "&a搜索功能已就绪" - filter-success: "&a筛选功能已就绪" - view-guild-details-success: "&a查看工会详情功能已就绪" - apply-to-guild-success: "&a申请加入工会功能已就绪" - name-input-success: "&a工会名称输入功能已就绪" - tag-input-success: "&a工会标签输入功能已就绪" - description-input-success: "&a工会描述输入功能已就绪" - - # 成员管理 - invite-member: "&a邀请成员" - kick-member: "&c踢出成员" - promote-member: "&6提升成员" - demote-member: "&7降级成员" - - # 申请管理 - pending-applications: "&e待处理申请" - application-history: "&e申请历史" - no-pending-applications: "&a没有待处理的申请" - no-application-history: "&a没有申请历史" - - # 工会设置 - change-description: "&e修改描述" - change-tag: "&e修改标签" - set-home: "&e设置工会家" - permissions: "&e权限设置" - - # 工会列表 - search: "&e搜索工会" - filter: "&e筛选" - no-guilds-found: "&c没有找到工会" - search-dev: "&a搜索功能正在开发中..." - filter-dev: "&a筛选功能正在开发中..." - no-guilds: "&c没有找到工会" - - # 工会关系 - allies: "&a盟友工会" - enemies: "&c敌对工会" - neutral: "&7中立工会" - relations-success: "&a工会关系功能已就绪" - - # 分页 - page-info: "&7第 {current} 页,共 {total} 页" - no-more-pages: "&c已经是最后一页了" - no-previous-pages: "&c已经是第一页了" - - # 权限提示 - permission-required: "&c需要权限: {permission}" - leader-only: "&c只有工会会长才能执行此操作" - officer-or-higher: "&c需要官员或更高权限" - - # 操作提示 - click-to-view: "&7点击查看详情" - click-to-edit: "&7点击编辑" - click-to-confirm: "&7点击确认" - click-to-cancel: "&7点击取消" - - # 成员详情 - confirm-kick: "&c确定要踢出成员 {member} 吗?输入 &f/guild kick {member} confirm &c确认" - confirm-promote: "&a确定要提升成员 {member} 为官员吗?输入 &f/guild promote {member} confirm &a确认" - confirm-demote: "&c确定要降级成员 {member} 吗?输入 &f/guild demote {member} confirm &c确认" - cannot-kick-leader: "&c不能踢出工会会长" - cannot-modify-leader: "&c不能修改工会会长的职位" - open-chat: "&e请输入要发送给 {member} 的消息:" - - # 输入相关 - input-name: "&a请在聊天框中输入工会名称(3-20字符):" - input-description: "&a请在聊天框中输入新的工会描述(最多100字符):" - input-tag: "&a请在聊天框中输入新的工会标签(最多10字符):" - description-too-long: "&c描述过长,最多100字符!" - tag-too-long: "&c标签过长,最多10字符!" - name-set: "&a工会名称已设置为:{name}" - tag-set: "&a工会标签已设置为:{tag}" - description-set: "&a工会描述已设置为:{description}" - description-updated: "&a工会描述已更新!" - description-update-failed: "&c工会描述更新失败!" - tag-updated: "&a工会标签已更新!" - tag-update-failed: "&c工会标签更新失败!" - -# 占位符相关消息 -placeholders: - no-guild: "无工会" - no-tag: "无标签" - no-description: "无描述" - unknown-role: "未知角色" - -# 帮助相关消息 -help: - title: "&6=== 工会系统帮助 ===" - main-menu: "&e/guild &7- 打开工会主界面" - create: "&e/guild create <名称> [标签] [描述] &7- 创建工会" - info: "&e/guild info &7- 查看工会信息" - members: "&e/guild members &7- 查看工会成员" - invite: "&e/guild invite <玩家> &7- 邀请玩家加入工会" - kick: "&e/guild kick <玩家> &7- 踢出工会成员" - leave: "&e/guild leave &7- 离开工会" - delete: "&e/guild delete &7- 删除工会" - promote: "&e/guild promote <玩家> &7- 提升工会成员" - demote: "&e/guild demote <玩家> &7- 降级工会成员" - accept: "&e/guild accept <邀请者> &7- 接受工会邀请" - decline: "&e/guild decline <邀请者> &7- 拒绝工会邀请" - sethome: "&e/guild sethome &7- 设置工会家" - home: "&e/guild home &7- 传送到工会家" - logs: "&e/guild logs &7- 查看工会操作日志" - help: "&e/guild help &7- 显示此帮助信息" - - - -# 错误消息 -errors: - database: - connection-failed: "&c数据库连接失败!" - query-failed: "&c数据库查询失败!" - table-not-found: "&c数据表不存在!" - config: - invalid-value: "&c配置值无效:{path}" - missing-value: "&c缺少配置项:{path}" - general: - unknown-error: "&c发生未知错误!" - plugin-disabled: "&c插件已禁用!" - - - -# 工会经济系统消息 -economy: - # 基础操作 - no-guild: "&c您还没有加入工会!" - info: "&6工会经济信息" - balance: "&7当前资金: &e{balance}" - level: "&7当前等级: &e{level}" - max-members: "&7最大成员: &e{max_members}" - insufficient-balance: "&c您的余额不足!" - guild-insufficient-balance: "&c工会余额不足!" - leader-only: "&c只有工会会长才能执行此操作!" - target-guild-not-found: "&c目标工会不存在!" - cannot-transfer-to-self: "&c不能转账给自己的工会!" - deposit-success: "&a成功向工会存款 &e{amount}!" - deposit-failed: "&c存款失败!" - withdraw-success: "&a成功从工会取款 &e{amount}!" - withdraw-failed: "&c取款失败!" - transfer-success: "&a成功向工会 &e{target} &a转账 &e{amount}!" - transfer-failed: "&c转账失败!" - insufficient-funds: "&c工会资金不足!" - insufficient-personal-funds: "&c您的个人资金不足!" - - # 等级系统 - level-up: "&a工会升级成功!当前等级:{level},最大成员数:{max_members}" - level-up-failed: "&c工会升级失败!" - max-level-reached: "&c工会已达到最高等级!" - upgrade-progress: "&e升级进度:{progress}%" - - # 贡献系统 - contribution-recorded: "&a贡献记录已保存!" - total-contribution: "&e您的总贡献:{amount} 金币" - - - - # 解散 - disband-compensation: "&a工会解散,您获得了 {amount} 金币补偿!" - - # 管理员操作 - admin-set-balance: "&a工会 {guild} 的资金已设置为 {amount}!" - admin-add-balance: "&a工会 {guild} 的资金已增加 {amount}!" - admin-remove-balance: "&a工会 {guild} 的资金已减少 {amount}!" - admin-balance-updated: "&a工会 {guild} 的资金已更新为 {amount}!" - admin-balance-failed: "&c更新工会资金失败!" - - # 等级需求 - level-1-requirement: "0-5000 金币" - level-2-requirement: "5000-10000 金币" - level-3-requirement: "10000-20000 金币" - level-4-requirement: "20000-35000 金币" - level-5-requirement: "35000-50000 金币" - level-6-requirement: "50000-75000 金币" - level-7-requirement: "75000-100000 金币" - level-8-requirement: "100000-150000 金币" - level-9-requirement: "150000-200000 金币" - level-10-requirement: "200000+ 金币" - -# 工会详情相关消息 -guild-detail: - title: "&6工会详情" - guild-info: "&e工会信息" - economy-info: "&e经济信息" - leader-info: "&6工会会长" - description-info: "&e工会描述" - members-title: "&a工会成员" - more-members: "&e更多成员" - freeze-guild: "&c冻结工会" - unfreeze-guild: "&a解冻工会" - delete-guild: "&4删除工会" - economy-management: "&e资金管理" - refresh-info: "&a刷新信息" - back: "&c返回" - - # 状态信息 - status-normal: "&a正常" - status-frozen: "&c已冻结" - online-status: "&a在线" - offline-status: "&7离线" - - # 操作提示 - freeze-success: "&a工会 {guild} 已被冻结!" - unfreeze-success: "&a工会 {guild} 已被解冻!" - freeze-failed: "&c冻结/解冻操作失败!" - delete-confirm: "&c您确定要删除工会 {guild} 吗?" - delete-command: "&c输入 &f/guildadmin delete {guild} confirm &c确认删除" - no-description: "&7暂无描述" - -# 系统设置相关消息 -system-settings: - title: "&4系统设置" - debug-mode: "&e详细后台信息显示" - auto-save: "&e自动保存数据" - economy-system: "&e经济系统" - relation-system: "&e工会关系系统" - level-system: "&e工会等级系统" - application-system: "&e申请加入系统" - invite-system: "&e邀请系统" - guild-home-system: "&e工会家系统" - reload-configs: "&a重载配置" - database-maintenance: "&b数据库维护" - backup-data: "&6备份数据" - save-settings: "&a保存设置" - - # 状态信息 - enabled: "&a已启用" - disabled: "&c已禁用" - current-status: "&7当前状态: {status}" - - # 操作提示 - toggle-success: "&a{feature}已{action}!" - toggle-enabled: "启用" - toggle-disabled: "禁用" - reload-success: "&a配置重载成功!" - reload-failed: "&c配置重载失败:{error}" - save-success: "&a设置保存成功!" - save-failed: "&c设置保存失败:{error}" - - # 功能描述 - debug-description: "&7启用后会在控制台显示详细的调试信息" - auto-save-description: "&7定期自动保存工会数据,防止数据丢失" - economy-description: "&7工会经济功能开关,包括存款、取款、转账等" - relation-description: "&7工会关系功能开关,包括盟友、敌对、开战等" - level-description: "&7工会等级功能开关,包括自动升级、成员限制等" - application-description: "&7申请加入工会功能开关,玩家需要申请才能加入工会" - invite-description: "&7工会邀请功能开关,会长可以邀请玩家加入工会" - home-description: "&7工会家功能开关,包括设置和传送到工会家" - - # 维护功能 - maintenance-dev: "&e数据库维护功能开发中..." - backup-dev: "&e数据备份功能开发中..." - -# 工会日志相关消息 -log-details: "&6=== 日志详情 ===" - - - - +# Plik konfiguracyjny wiadomości pluginu gildyjnego + +# Wiadomości ogólne +general: + prefix: "&6[Gildia] &r" + no-permission: "&cNie masz uprawnień do wykonania tej operacji!" + player-only: "&cTo polecenie może być wykonane tylko przez gracza!" + player-not-found: "&cGracz {player} nie został znalezion!" + guild-not-found: "&cGildia {guild} nie została znaleziona!" + invalid-arguments: "&cNieprawidłowe argumenty!" + error-occurred: "&cWystąpił błąd: {error}" + service-error: "&cUsługa gildii nie została zainicjalizowana!" + unknown-command: "&cNieznane polecenie! Użyj /guild help, aby zobaczyć pomoc." + +# Wiadomości dotyczące tworzenia gildii +create: + success: "&aGildia {name} została utworzona pomyślnie!" + name-too-short: "&cNazwa gildii jest za krótka! Wymagane minimum {min} znaków." + name-too-long: "&cNazwa gildii jest za długa! Może mieć maksymalnie {max} znaków." + name-exists: "&cNazwa gildii {name} już istnieje!" + name-required: "&cProszę najpierw wprowadzić nazwę gildii!" + tag-exists: "&cTag gildii {tag} już istnieje!" + tag-too-long: "&cTag gildii jest za długi! Może mieć maksymalnie {max} znaków." + already-in-guild: "&cJesteś już w gildii!" + insufficient-funds: "&cNiewystarczające środki! Utworzenie gildii kosztuje {cost} monet." + usage: "&eUżycie: /guild create [tag] [opis]" + description-too-long: "&cOpis gildii nie może przekraczać 100 znaków!" + failed: "&cTworzenie gildii nie powiodło się! Możliwe przyczyny:" + failed-reason-1: "&c- Nazwa gildii lub tag już istnieje" + failed-reason-2: "&c- Jesteś już członkiem innej gildii" + name-info: "&eNazwa gildii: {name}" + tag-info: "&eTag gildii: [{tag}]" + description-info: "&eOpis gildii: {description}" + economy-not-available: "&cSystem ekonomii jest niedostępny, nie można utworzyć gildii!" + payment-failed: "&cNie udało się pobrać opłaty za utworzenie!" + payment-refunded: "&eZwrócono opłatę za utworzenie w wysokości {cost} monet." + cost-info: "&eKoszt utworzenia: {amount}" + +# Wiadomości dotyczące informacji o gildii +info: + title: "&6=== Informacje o Gildii ===" + name: "&eNazwa: &f{name}" + tag: "&eTag: &f{tag}" + description: "&eOpis: &f{description}" + leader: "&eLider: &f{leader}" + members: "&eLiczba członków: &f{count}/{max}" + created: "&eData utworzenia: &f{date}" + no-guild: "&cNie należysz jeszcze do żadnej gildii!" + role: "&eTwoja rola: &f{role}" + +# Wiadomości dotyczące członków gildii +members: + title: "&6=== Członkowie Gildii ===" + leader: "&c{name} &7(Lider)" + officer: "&6{name} &7(Oficer)" + member: "&f{name} &7(Członek)" + joined: "&7Dołączył: {date}" + no-members: "&cBrak członków w gildii!" + member-format: "&e{role} {name} &7- {status}" + total: "&eŁącznie: {count} osób" + +# Wiadomości dotyczące zaproszeń +invite: + sent: "&aWysłano zaproszenie do gildii dla {player}!" + received: "&e{inviter} zaprasza cię do gildii: {guild}" + accepted: "&aZaakceptowałeś zaproszenie do gildii {guild}!" + declined: "&cOdrzuciłeś zaproszenie do gildii {guild}!" + expired: "&cZaproszenie do gildii wygasło!" + already-invited: "&c{player} już otrzymał zaproszenie!" + no-permission: "&cNie masz uprawnień do zapraszania graczy!" + usage: "&eUżycie: /guild invite " + title: "&6=== Zaproszenie do Gildii ===" + guild-tag: "&eTag gildii: [{tag}]" + accept-command: "&eWpisz &a/guild accept {inviter} &eaby zaakceptować" + decline-command: "&eWpisz &c/guild decline {inviter} &eaby odrzucić" + already-in-guild: "&cGracz {player} jest już w innej gildii!" + cannot-invite-self: "&cNie możesz zaprosić samego siebie!" + +# Wiadomości dotyczące wyrzucania +kick: + success: "&aWyrzucono {player} z gildii!" + kicked: "&cZostałeś wyrzucony z gildii {guild}!" + no-permission: "&cNie masz uprawnień do wyrzucania graczy!" + cannot-kick-leader: "&cNie można wyrzucić lidera gildii!" + usage: "&eUżycie: /guild kick " + player-not-found: "&cGracz {player} nie jest online!" + not-in-guild: "&cGracz {player} nie jest w twojej gildii!" + cannot-kick-self: "&cNie możesz wyrzucić samego siebie! Użyj /guild leave aby opuścić gildię." + failed: "&cWyrzucenie gracza nie powiodło się!" + +# Wiadomości dotyczące opuszczania gildii +leave: + success: "&aOpuściłeś gildię!" + leader-cannot-leave: "&cLider gildii nie może opuścić gildii! Przekaż przywództwo lub usuń gildię." + confirm: "&cCzy na pewno chcesz opuścić gildię? Użyj /guild leave confirm aby potwierdzić." + member-error: "&cBłąd informacji o członku gildii!" + success-with-guild: "&aPomyślnie opuściłeś gildię: {guild}" + failed: "&cOpuszczenie gildii nie powiodło się!" + use-delete: "&cJeśli chcesz rozwiązać gildię, użyj polecenia /guild delete." + +# Wiadomości dotyczące usuwania gildii +delete: + success: "&aGildia {guild} została usunięta!" + no-permission: "&cNie masz uprawnień do usuwania gildii!" + confirm: "&cCzy na pewno chcesz usunąć gildię? To spowoduje rozwiązanie całej gildii! Użyj /guild delete confirm aby potwierdzić." + only-leader: "&cTylko lider gildii może usunąć gildię!" + warning: "&cOstrzeżenie: Usunięcie gildii trwale ją rozwiąże, a wszyscy członkowie zostaną usunięci!" + confirm-command: "&cJeśli jesteś pewien, że chcesz usunąć gildię, wpisz ponownie: /guild delete confirm" + cancel-command: "&cLub wpisz: /guild delete cancel aby anulować operację" + +# Wiadomości dotyczące domu gildii +sethome: + success: "&aDom gildii został ustawiony pomyślnie!" + failed: "&cUstawianie domu gildii nie powiodło się!" + only-leader: "&cTylko lider gildii może ustawić dom gildii!" + no-permission: "&cNie masz uprawnień do ustawiania domu gildii!" +home: + success: "&aTeleportowano do domu gildii!" + not-set: "&cDom gildii nie został jeszcze ustawiony!" + no-permission: "&cNie masz uprawnień do teleportacji do domu gildii!" + teleport-failed: "&cTeleportacja do domu gildii nie powiodła się!" + +# Wiadomości dotyczące aplikacji +application: + sent: "&aTwoja aplikacja została wysłana do {guild}!" + received: "&aOtrzymano aplikację od {player}!" + accepted: "&aTwoja aplikacja została zaakceptowana przez {guild}!" + declined: "&cTwoja aplikacja została odrzucona przez {guild}!" + already-applied: "&cJuż aplikowałeś do {guild}!" + usage: "&eUżycie: /guild apply [wiadomość]" + +# Wiadomości dotyczące aplikacji (używane w GUI) +apply: + success: "&aAplikacja została złożona!" + failed: "&cZłożenie aplikacji nie powiodło się!" + already-applied: "&cJuż aplikowałeś do tej gildii!" + +# Wiadomości dotyczące relacji gildii +relation: + no-guild: "&cNie należysz jeszcze do gildii!" + only-leader: "&cTylko lider gildii może zarządzać relacjami gildii!" + help-title: "&6=== Zarządzanie Relacjami Gildii ===" + help-list: "&e/guild relation list &7- Zobacz wszystkie relacje" + help-create: "&e/guild relation create &7- Utwórz relację" + help-delete: "&e/guild relation delete &7- Usuń relację" + help-accept: "&e/guild relation accept &7- Zaakceptuj prośbę o relację" + help-reject: "&e/guild relation reject &7- Odrzuć prośbę o relację" + help-types: "&7Typy relacji: &eally(sojusznik), enemy(wróg), war(wojna), truce(rozejm), neutral(neutralny)" + create-usage: "&eUżycie: /guild relation create " + delete-usage: "&eUżycie: /guild relation delete " + accept-usage: "&eUżycie: /guild relation accept " + reject-usage: "&eUżycie: /guild relation reject " + unknown-subcommand: "&cNieznane podpolecenie! Użyj /guild relation aby zobaczyć pomoc." + no-relations: "&7Twoja gildia nie ma jeszcze żadnych relacji." + list-title: "&6=== Lista Relacji Gildii ===" + list-format: "&e{other_guild} &7- {type} ({status})" + invalid-type: "&cNieprawidłowy typ relacji! Prawidłowe typy: ally, enemy, war, truce, neutral" + target-not-found: "&cGildia docelowa {guild} nie istnieje!" + cannot-relation-self: "&cNie można nawiązać relacji z samym sobą!" + create-success: "&aWysłano prośbę o relację {type} do {guild}!" + create-failed: "&cTworzenie relacji nie powiodło się! Relacja może już istnieć." + delete-success: "&aUsunięto relację z {guild}!" + delete-failed: "&cUsunięcie relacji nie powiodło się! Relacja może nie istnieć." + accept-success: "&aZaakceptowano prośbę o relację od {guild}!" + accept-failed: "&cAkceptacja relacji nie powiodła się! Może nie być oczekującej prośby." + reject-success: "&cOdrzucono prośbę o relację od {guild}!" + reject-failed: "&cOdrzucenie relacji nie powiodło się! Może nie być oczekującej prośby." + +# Wiadomości dotyczące uprawnień +permissions: + promote: + success: "&aAwansowano {player} na {role}!" + no-permission: "&cNie masz uprawnień do awansowania graczy!" + cannot-promote: "&cNie można awansować tego gracza!" + usage: "&eUżycie: /guild promote " + player-not-found: "&cGracz {player} nie jest online!" + not-in-guild: "&cGracz {player} nie jest w twojej gildii!" + already-highest: "&cGracz {player} ma już najwyższą rangę!" + cannot-promote-self: "&cNie możesz awansować samego siebie!" + demote: + success: "&aZdegradowano {player} na {role}!" + no-permission: "&cNie masz uprawnień do degradowania graczy!" + cannot-demote: "&cNie można zdegradować tego gracza!" + usage: "&eUżycie: /guild demote " + player-not-found: "&cGracz {player} nie jest online!" + not-in-guild: "&cGracz {player} nie jest w twojej gildii!" + already-lowest: "&cGracz {player} ma już najniższą rangę!" + cannot-demote-self: "&cNie możesz zdegradować samego siebie!" + cannot-demote-leader: "&cNie można zdegradować lidera gildii!" + +# Wiadomości dla administratorów +admin: + no-permission: "&cNie masz uprawnień administratora!" + unknown-command: "&cNieznane polecenie! Użyj /guildadmin help aby zobaczyć pomoc." + reload: + success: "&aKonfiguracja przeładowana pomyślnie!" + error: "&cPrzeładowanie konfiguracji nie powiodło się: {error}" + list: + title: "&6=== Lista Gildii ===" + entry: "&e{guild} &7- {count} członków" + empty: "&cNie znaleziono żadnych gildii!" + total: "&eŁącznie: {count} gildii" + info: + title: "&6=== Szczegóły Gildii ===" + id: "&eID: &f{id}" + name: "&eNazwa: &f{name}" + tag: "&eTag: &f{tag}" + description: "&eOpis: &f{description}" + leader: "&eLider: &f{leader}" + member-count: "&eLiczba członków: &f{count}" + created: "&eUtworzono: &f{created}" + updated: "&eZaktualizowano: &f{updated}" + usage: "&eUżycie: /guildadmin info " + not-found: "&cGildia {guild} nie istnieje!" + members-title: "&6=== Lista Członków ===" + delete: + success: "&aGildia {guild} została usunięta przez administratora!" + error: "&cUsunięcie gildii nie powiodło się: {error}" + usage: "&eUżycie: /guildadmin delete " + not-found: "&cGildia {guild} nie istnieje!" + warning: "&cOstrzeżenie: Usunięcie gildii trwale ją rozwiąże, a wszyscy członkowie zostaną usunięci!" + confirm: "&cJeśli jesteś pewien, że chcesz usunąć gildię, użyj: /guildadmin delete {guild} confirm" + success-with-name: "&aPomyślnie usunięto gildię: {guild}" + failed: "&cUsunięcie gildii nie powiodło się!" + kick: + success: "&aWyrzucono {player} z {guild}!" + error: "&cWyrzucenie gracza nie powiodło się: {error}" + usage: "&eUżycie: /guildadmin kick " + guild-not-found: "&cGildia {guild} nie istnieje!" + player-not-found: "&cGracz {player} nie jest online!" + player-not-in-guild: "&cGracz {player} nie jest w gildii {guild}!" + cannot-kick-leader: "&cNie można wyrzucić lidera gildii! Przekaż przywództwo lub usuń gildię." + success-with-names: "&aPomyślnie wyrzucono gracza {player} z gildii {guild}!" + kicked-by-admin: "&cZostałeś wyrzucony z gildii {guild} przez administratora!" + failed: "&cWyrzucenie gracza nie powiodło się!" + help: + title: "&6=== Pomoc Administratora Gildii ===" + reload: "&e/guildadmin reload &7- Przeładuj konfigurację" + list: "&e/guildadmin list &7- Wypisz wszystkie gildie" + info: "&e/guildadmin info &7- Zobacz szczegóły gildii" + delete: "&e/guildadmin delete &7- Usuń wskazaną gildię" + kick: "&e/guildadmin kick &7- Wyrzuć gracza z gildii" + help: "&e/guildadmin help &7- Pokaż tę pomoc" + +# Wiadomości GUI +gui: + title: "&6System Gildii" + create-guild: "&aUtwórz Gildię" + guild-info: "&eInformacje o Gildii" + member-management: "&eZarządzanie Członkami" + application-management: "&eZarządzanie Aplikacjami" + guild-settings: "&eUstawienia Gildii" + guild-list: "&eLista Gildii" + guild-relations: "&eRelacje Gildii" + invite-player: "&eZaproś Gracza" + leave-guild: "&cOpuść Gildię" + delete-guild: "&4Usuń Gildię" + confirm: "&aPotwierdź" + cancel: "&cAnuluj" + back: "&7Wróć" + next-page: "&aNastępna strona" + previous-page: "&cPoprzednia strona" + no-guild: "&cNie masz jeszcze gildii" + no-permission: "&cNiewystarczające uprawnienia" + opening: "&aOtwieranie GUI systemu gildii..." + + # Funkcje menu głównego + create-guild-success: "&aFunkcja tworzenia gildii jest gotowa" + guild-info-success: "&aFunkcja informacji o gildii jest gotowa" + member-management-success: "&aFunkcja zarządzania członkami jest gotowa" + application-management-success: "&aFunkcja zarządzania aplikacjami jest gotowa" + guild-settings-success: "&aFunkcja ustawień gildii jest gotowa" + guild-list-success: "&aFunkcja listy gildii jest gotowa" + guild-relations-success: "&aFunkcja relacji gildii jest gotowa" + + # Wiadomości funkcji + invite-member-success: "&aFunkcja zapraszania członków jest gotowa" + kick-member-success: "&aFunkcja wyrzucania członków jest gotowa" + promote-member-success: "&aFunkcja awansowania członków jest gotowa" + demote-member-success: "&aFunkcja degradowania członków jest gotowa" + accept-application-success: "&aFunkcja akceptowania aplikacji jest gotowa" + reject-application-success: "&aFunkcja odrzucania aplikacji jest gotowa" + application-history-success: "&aFunkcja historii aplikacji jest gotowa" + change-description-success: "&aFunkcja zmiany opisu jest gotowa" + change-tag-success: "&aFunkcja zmiany tagu jest gotowa" + permissions-success: "&aFunkcja ustawień uprawnień jest gotowa" + search-success: "&aFunkcja wyszukiwania jest gotowa" + filter-success: "&aFunkcja filtrowania jest gotowa" + view-guild-details-success: "&aFunkcja podglądu szczegółów gildii jest gotowa" + apply-to-guild-success: "&aFunkcja aplikowania do gildii jest gotowa" + name-input-success: "&aFunkcja wprowadzania nazwy gildii jest gotowa" + tag-input-success: "&aFunkcja wprowadzania tagu gildii jest gotowa" + description-input-success: "&aFunkcja wprowadzania opisu gildii jest gotowa" + + # Zarządzanie członkami + invite-member: "&aZaproś członka" + kick-member: "&cWyrzuć członka" + promote-member: "&6Awansuj członka" + demote-member: "&7Zdegraduj członka" + + # Zarządzanie aplikacjami + pending-applications: "&eOczekujące aplikacje" + application-history: "&eHistoria aplikacji" + no-pending-applications: "&aBrak oczekujących aplikacji" + no-application-history: "&aBrak historii aplikacji" + + # Ustawienia gildii + change-description: "&eZmień opis" + change-tag: "&eZmień tag" + set-home: "&eUstaw dom gildii" + permissions: "&eUstawienia uprawnień" + + # Lista gildii + search: "&eSzukaj gildii" + filter: "&eFiltruj" + no-guilds-found: "&cNie znaleziono gildii" + search-dev: "&aFunkcja wyszukiwania w trakcie tworzenia..." + filter-dev: "&aFunkcja filtrowania w trakcie tworzenia..." + no-guilds: "&cNie znaleziono gildii" + + # Relacje gildii + allies: "&aSojusznicy" + enemies: "&cWrogowie" + neutral: "&7Neutralni" + relations-success: "&aFunkcja relacji gildii jest gotowa" + + # Stronicowanie + page-info: "&7Strona {current} z {total}" + no-more-pages: "&cTo już ostatnia strona" + no-previous-pages: "&cTo jest pierwsza strona" + + # Wskazówki dotyczące uprawnień + permission-required: "&cWymagane uprawnienie: {permission}" + leader-only: "&cTylko lider gildii może wykonać tę operację" + officer-or-higher: "&cWymagane uprawnienia oficera lub wyższe" + + # Wskazówki operacyjne + click-to-view: "&7Kliknij, aby zobaczyć szczegóły" + click-to-edit: "&7Kliknij, aby edytować" + click-to-confirm: "&7Kliknij, aby potwierdzić" + click-to-cancel: "&7Kliknij, aby anulować" + + # Szczegóły członka + confirm-kick: "&cCzy na pewno chcesz wyrzucić członka {member}? Wpisz &f/guild kick {member} confirm &caby potwierdzić" + confirm-promote: "&aCzy na pewno chcesz awansować członka {member} na oficera? Wpisz &f/guild promote {member} confirm &aaby potwierdzić" + confirm-demote: "&cCzy na pewno chcesz zdegradować członka {member}? Wpisz &f/guild demote {member} confirm &caby potwierdzić" + cannot-kick-leader: "&cNie można wyrzucić lidera gildii" + cannot-modify-leader: "&cNie można modyfikować rangi lidera gildii" + open-chat: "&eWprowadź wiadomość do wysłania do {member}:" + + # Wprowadzanie danych + input-name: "&aProszę wprowadzić nazwę gildii na czacie (3-20 znaków):" + input-description: "&aProszę wprowadzić nowy opis gildii na czacie (maks. 100 znaków):" + input-tag: "&aProszę wprowadzić nowy tag gildii na czacie (maks. 10 znaków):" + description-too-long: "&cOpis za długi, maks. 100 znaków!" + tag-too-long: "&cTag za długi, maks. 10 znaków!" + name-set: "&aNazwa gildii ustawiona na: {name}" + tag-set: "&aTag gildii ustawiony na: {tag}" + description-set: "&aOpis gildii ustawiony na: {description}" + description-updated: "&aOpis gildii zaktualizowany!" + description-update-failed: "&cAktualizacja opisu gildii nie powiodła się!" + tag-updated: "&aTag gildii zaktualizowany!" + tag-update-failed: "&cAktualizacja tagu gildii nie powiodła się!" + +# Wiadomości dotyczące placeholderów +placeholders: + no-guild: "Brak gildii" + no-tag: "Brak tagu" + no-description: "Brak opisu" + unknown-role: "Nieznana rola" + +# Wiadomości pomocy +help: + title: "&6=== Pomoc Systemu Gildii ===" + main-menu: "&e/guild &7- Otwórz główne menu gildii" + create: "&e/guild create [tag] [opis] &7- Utwórz gildię" + info: "&e/guild info &7- Zobacz informacje o gildii" + members: "&e/guild members &7- Zobacz członków gildii" + invite: "&e/guild invite &7- Zaproś gracza do gildii" + kick: "&e/guild kick &7- Wyrzuć członka z gildii" + leave: "&e/guild leave &7- Opuść gildię" + delete: "&e/guild delete &7- Usuń gildię" + promote: "&e/guild promote &7- Awansuj członka gildii" + demote: "&e/guild demote &7- Zdegraduj członka gildii" + accept: "&e/guild accept &7- Zaakceptuj zaproszenie do gildii" + decline: "&e/guild decline &7- Odrzuć zaproszenie do gildii" + sethome: "&e/guild sethome &7- Ustaw dom gildii" + home: "&e/guild home &7- Teleportuj do domu gildii" + logs: "&e/guild logs &7- Zobacz logi operacji gildii" + help: "&e/guild help &7- Pokaż tę pomoc" + +# Wiadomości o błędach +errors: + database: + connection-failed: "&cPołączenie z bazą danych nie powiodło się!" + query-failed: "&cZapytanie do bazy danych nie powiodło się!" + table-not-found: "&cTabela danych nie istnieje!" + config: + invalid-value: "&cNieprawidłowa wartość konfiguracji: {path}" + missing-value: "&cBrakująca wartość konfiguracji: {path}" + general: + unknown-error: "&cWystąpił nieznany błąd!" + plugin-disabled: "&cPlugin jest wyłączony!" + +# Wiadomości ekonomii gildii +economy: + # Podstawowe operacje + no-guild: "&cNie należysz jeszcze do gildii!" + info: "&6Informacje Ekonomiczne Gildii" + balance: "&7Aktualne saldo: &e{balance}" + level: "&7Aktualny poziom: &e{level}" + max-members: "&7Maks. członków: &e{max_members}" + insufficient-balance: "&cNiewystarczające saldo!" + guild-insufficient-balance: "&cNiewystarczające saldo gildii!" + leader-only: "&cTylko lider gildii może wykonać tę operację!" + target-guild-not-found: "&cGildia docelowa nie istnieje!" + cannot-transfer-to-self: "&cNie można przelać środków do własnej gildii!" + deposit-success: "&aPomyślnie wpłacono &e{amount} &ado gildii!" + deposit-failed: "&cWpłata nie powiodła się!" + withdraw-success: "&aPomyślnie wypłacono &e{amount} &az gildii!" + withdraw-failed: "&cWypłata nie powiodła się!" + transfer-success: "&aPomyślnie przelano &e{amount} &ado gildii &e{target}!" + transfer-failed: "&cPrzelew nie powiódł się!" + insufficient-funds: "&cNiewystarczające fundusze gildii!" + insufficient-personal-funds: "&cNiewystarczające fundusze osobiste!" + + # System poziomów + level-up: "&aGildia awansowała! Obecny poziom: {level}, Maks. członków: {max_members}" + level-up-failed: "&cAwans gildii nie powiódł się!" + max-level-reached: "&cGildia osiągnęła maksymalny poziom!" + upgrade-progress: "&ePostęp ulepszania: {progress}%" + + # System wkładów + contribution-recorded: "&aZapisano wkład!" + total-contribution: "&eTwój całkowity wkład: {amount} monet" + + # Rozwiązanie + disband-compensation: "&aGildia rozwiązana, otrzymałeś rekompensatę w wysokości {amount} monet!" + + # Operacje administratora + admin-set-balance: "&aSaldo gildii {guild} ustawiono na {amount}!" + admin-add-balance: "&aSaldo gildii {guild} zwiększono o {amount}!" + admin-remove-balance: "&aSaldo gildii {guild} zmniejszono o {amount}!" + admin-balance-updated: "&aSaldo gildii {guild} zaktualizowano do {amount}!" + admin-balance-failed: "&cAktualizacja salda gildii nie powiodła się!" + + # Wymagania poziomów + level-1-requirement: "0-5000 monet" + level-2-requirement: "5000-10000 monet" + level-3-requirement: "10000-20000 monet" + level-4-requirement: "20000-35000 monet" + level-5-requirement: "35000-50000 monet" + level-6-requirement: "50000-75000 monet" + level-7-requirement: "75000-100000 monet" + level-8-requirement: "100000-150000 monet" + level-9-requirement: "150000-200000 monet" + level-10-requirement: "200000+ monet" + +# Wiadomości szczegółów gildii +guild-detail: + title: "&6Szczegóły Gildii" + guild-info: "&eInformacje o Gildii" + economy-info: "&eInformacje Ekonomiczne" + leader-info: "&6Lider Gildii" + description-info: "&eOpis Gildii" + members-title: "&aCzłonkowie Gildii" + more-members: "&eWięcej członków" + freeze-guild: "&cZamroź Gildię" + unfreeze-guild: "&aOdmroź Gildię" + delete-guild: "&4Usuń Gildię" + economy-management: "&eZarządzanie Funduszami" + refresh-info: "&aOdśwież Informacje" + back: "&cWróć" + + # Informacje o statusie + status-normal: "&aNormalny" + status-frozen: "&cZamrożony" + online-status: "&aOnline" + offline-status: "&7Offline" + + # Wskazówki operacyjne + freeze-success: "&aGildia {guild} została zamrożona!" + unfreeze-success: "&aGildia {guild} została odmrożona!" + freeze-failed: "&cOperacja zamrożenia/odmrożenia nie powiodła się!" + delete-confirm: "&cCzy na pewno chcesz usunąć gildię {guild}?" + delete-command: "&cWpisz &f/guildadmin delete {guild} confirm &caby potwierdzić usunięcie" + no-description: "&7Brak opisu" + +# Wiadomości ustawień systemowych +system-settings: + title: "&4Ustawienia Systemowe" + debug-mode: "&eSzczegółowe informacje debugowania" + auto-save: "&eAutomatyczny zapis danych" + economy-system: "&eSystem Ekonomii" + relation-system: "&eSystem Relacji Gildii" + level-system: "&eSystem Poziomów Gildii" + application-system: "&eSystem Aplikacji" + invite-system: "&eSystem Zaproszeń" + guild-home-system: "&eSystem Domu Gildii" + reload-configs: "&aPrzeładuj Konfigurację" + database-maintenance: "&bKonserwacja Bazy Danych" + backup-data: "&6Kopia Zapasowa Danych" + save-settings: "&aZapisz Ustawienia" + + # Informacje o statusie + enabled: "&aWłączone" + disabled: "&cWyłączone" + current-status: "&7Obecny status: {status}" + + # Wskazówki operacyjne + toggle-success: "&a{feature} zostało {action}!" + toggle-enabled: "włączone" + toggle-disabled: "wyłączone" + reload-success: "&aKonfiguracja przeładowana pomyślnie!" + reload-failed: "&cPrzeładowanie konfiguracji nie powiodło się: {error}" + save-success: "&aUstawienia zapisane pomyślnie!" + save-failed: "&cZapisanie ustawień nie powiodło się: {error}" + + # Opisy funkcji + debug-description: "&7Po włączeniu wyświetla szczegółowe informacje debugowania w konsoli" + auto-save-description: "&7Regularnie automatycznie zapisuje dane gildii, aby zapobiec utracie danych" + economy-description: "&7Przełącznik funkcji ekonomii gildii, w tym wpłaty, wypłaty, przelewy itp." + relation-description: "&7Przełącznik funkcji relacji gildii, w tym sojusznicy, wrogowie, wojny itp." + level-description: "&7Przełącznik funkcji poziomów gildii, w tym automatyczne awanse, limity członków itp." + application-description: "&7Przełącznik funkcji aplikacji do gildii, gracze muszą aplikować, aby dołączyć" + invite-description: "&7Przełącznik funkcji zaproszeń do gildii, lider może zapraszać graczy" + home-description: "&7Przełącznik funkcji domu gildii, w tym ustawianie i teleportacja do domu" + + # Funkcje konserwacji + maintenance-dev: "&eFunkcja konserwacji bazy danych w trakcie tworzenia..." + backup-dev: "&eFunkcja kopii zapasowej danych w trakcie tworzenia..." + +# Wiadomości szczegółów logów +log-details: "&6=== Szczegóły Logów ===" diff --git a/plugin.yml b/plugin.yml index 9e46900..b2d1374 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,73 +1,73 @@ -name: GuildPlugin -version: 1.2.4 -main: com.guild.GuildPlugin -api-version: '1.21' -authors: [chenasyd] -description: 一个功能完整的我的世界工会插件,支持Spigot和Folia -website: https://github.com/chenasyd -softdepend: [PlaceholderAPI, Vault] - -# 支持的最低版本 -load: POSTWORLD - -# Folia支持标记 -folia-supported: true - -commands: - guild: - description: 工会系统主命令 - usage: /guild help - aliases: [g, 工会] - permission: guild.use - guildadmin: - description: 工会管理员命令 - usage: /guildadmin help - aliases: [ga, 工会管理] - permission: guild.admin - -permissions: - guild.use: - description: 允许使用工会系统 - default: true - guild.admin: - description: 工会管理员权限 - default: op - guild.create: - description: 允许创建工会 - default: true - guild.invite: - description: 允许邀请玩家加入工会 - default: true - guild.kick: - description: 允许踢出工会成员 - default: true - guild.promote: - description: 允许提升工会成员 - default: true - guild.demote: - description: 允许降级工会成员 - default: true - guild.delete: - description: 允许删除工会 - default: op - guild.sethome: - description: 允许设置工会家 - default: true - guild.home: - description: 允许传送到工会家 - default: true - guild.relation: - description: 允许管理工会关系 - default: true - guild.economy: - description: 允许管理工会经济 - default: true - guild.deposit: - description: 允许向工会存入资金 - default: true - guild.withdraw: - description: 允许从工会取出资金 - default: true - guild.transfer: - description: 允许向其他工会转账 - default: true +name: GuildPlugin +version: 1.2.4 +main: com.guild.GuildPlugin +api-version: '1.21' +authors: [chenasyd] +description: W pełni funkcjonalny plugin gildyjny dla Minecrafta, wspierający Spigot i Folia +website: https://github.com/chenasyd +softdepend: [PlaceholderAPI, Vault] + +# Minimalna obsługiwana wersja +load: POSTWORLD + +# Oznaczenie wsparcia dla Folia +folia-supported: true + +commands: + guild: + description: Główne polecenie systemu gildii + usage: /guild help + aliases: [g, gildia] + permission: guild.use + guildadmin: + description: Polecenie administratora gildii + usage: /guildadmin help + aliases: [ga, gadmin, zarzadzaniegildia] + permission: guild.admin + +permissions: + guild.use: + description: Pozwala na używanie systemu gildii + default: true + guild.admin: + description: Uprawnienia administratora gildii + default: op + guild.create: + description: Pozwala na tworzenie gildii + default: true + guild.invite: + description: Pozwala na zapraszanie graczy do gildii + default: true + guild.kick: + description: Pozwala na wyrzucanie członków gildii + default: true + guild.promote: + description: Pozwala na awansowanie członków gildii + default: true + guild.demote: + description: Pozwala na degradowanie członków gildii + default: true + guild.delete: + description: Pozwala na usuwanie gildii + default: op + guild.sethome: + description: Pozwala na ustawianie domu gildii + default: true + guild.home: + description: Pozwala na teleportację do domu gildii + default: true + guild.relation: + description: Pozwala na zarządzanie relacjami gildii + default: true + guild.economy: + description: Pozwala na zarządzanie ekonomią gildii + default: true + guild.deposit: + description: Pozwala na wpłacanie funduszy do gildii + default: true + guild.withdraw: + description: Pozwala na wypłacanie funduszy z gildii + default: true + guild.transfer: + description: Pozwala na przelewanie środków do innych gildii + default: true diff --git a/src/main/java/com/guild/GuildPlugin.java b/src/main/java/com/guild/GuildPlugin.java index 89953d1..e4d9b64 100644 --- a/src/main/java/com/guild/GuildPlugin.java +++ b/src/main/java/com/guild/GuildPlugin.java @@ -1,202 +1,202 @@ -package com.guild; - -import com.guild.core.ServiceContainer; -import com.guild.core.config.ConfigManager; -import com.guild.core.database.DatabaseManager; -import com.guild.core.events.EventBus; -import com.guild.core.gui.GUIManager; -import com.guild.core.placeholder.PlaceholderManager; -import com.guild.core.permissions.PermissionManager; -import com.guild.core.economy.EconomyManager; -import com.guild.commands.GuildCommand; -import com.guild.commands.GuildAdminCommand; -import com.guild.listeners.PlayerListener; -import com.guild.listeners.GuildListener; -import com.guild.services.GuildService; -import com.guild.core.utils.ServerUtils; -import com.guild.core.utils.TestUtils; -import org.bukkit.plugin.java.JavaPlugin; - -import java.util.logging.Logger; - -public class GuildPlugin extends JavaPlugin { - - private static GuildPlugin instance; - private ServiceContainer serviceContainer; - private ConfigManager configManager; - private DatabaseManager databaseManager; - private EventBus eventBus; - private GUIManager guiManager; - private PlaceholderManager placeholderManager; - private PermissionManager permissionManager; - private EconomyManager economyManager; - private GuildService guildService; - - @Override - public void onEnable() { - instance = this; - Logger logger = getLogger(); - - logger.info("正在启动工会插件..."); - logger.info("检测到服务器类型: " + ServerUtils.getServerType()); - logger.info("服务器版本: " + ServerUtils.getServerVersion()); - - // 检查API版本兼容性 - if (!ServerUtils.supportsApiVersion("1.21")) { - logger.severe("此插件需要1.21或更高版本!当前版本: " + ServerUtils.getServerVersion()); - getServer().getPluginManager().disablePlugin(this); - return; - } - - // 运行兼容性测试(使用插件日志器) - TestUtils.testCompatibility(logger); - TestUtils.testSchedulerCompatibility(logger); - - try { - // 初始化服务容器 - serviceContainer = new ServiceContainer(); - - // 初始化配置管理器 - configManager = new ConfigManager(this); - serviceContainer.register(ConfigManager.class, configManager); - - // 初始化数据库管理器 - databaseManager = new DatabaseManager(this); - serviceContainer.register(DatabaseManager.class, databaseManager); - - // 初始化事件总线 - eventBus = new EventBus(); - serviceContainer.register(EventBus.class, eventBus); - - // 初始化GUI管理器 - guiManager = new GUIManager(this); - serviceContainer.register(GUIManager.class, guiManager); - - // 初始化占位符管理器 - placeholderManager = new PlaceholderManager(this); - serviceContainer.register(PlaceholderManager.class, placeholderManager); - - // 初始化权限管理器 - permissionManager = new PermissionManager(this); - serviceContainer.register(PermissionManager.class, permissionManager); - - // 初始化经济管理器 - economyManager = new EconomyManager(this); - serviceContainer.register(EconomyManager.class, economyManager); - - // 注册工会服务 - guildService = new GuildService(this); - serviceContainer.register(GuildService.class, guildService); - - // 设置PlaceholderManager的GuildService引用 - placeholderManager.setGuildService(guildService); - - // 注册命令 - registerCommands(); - - // 注册监听器 - registerListeners(); - - // 启动服务 - startServices(); - - logger.info("工会插件启动成功!"); - logger.info("兼容模式: " + (ServerUtils.isFolia() ? "Folia" : "Spigot")); - - } catch (Exception e) { - logger.severe("工会插件启动失败: " + e.getMessage()); - e.printStackTrace(); - getServer().getPluginManager().disablePlugin(this); - } - } - - @Override - public void onDisable() { - Logger logger = getLogger(); - logger.info("正在关闭工会插件..."); - - try { - // 关闭所有GUI - if (guiManager != null) { - guiManager.closeAllGUIs(); - } - - // 关闭服务 - if (serviceContainer != null) { - serviceContainer.shutdown(); - } - - logger.info("工会插件已关闭"); - - } catch (Exception e) { - logger.severe("关闭工会插件时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - private void registerCommands() { - GuildCommand guildCommand = new GuildCommand(this); - GuildAdminCommand guildAdminCommand = new GuildAdminCommand(this); - - getCommand("guild").setExecutor(guildCommand); - getCommand("guild").setTabCompleter(guildCommand); - getCommand("guildadmin").setExecutor(guildAdminCommand); - getCommand("guildadmin").setTabCompleter(guildAdminCommand); - } - - private void registerListeners() { - getServer().getPluginManager().registerEvents(new PlayerListener(this), this); - getServer().getPluginManager().registerEvents(new GuildListener(this), this); - } - - private void startServices() { - // 启动数据库连接 - databaseManager.initialize(); - - // 注册占位符 - placeholderManager.registerPlaceholders(); - - // 初始化GUI系统 - guiManager.initialize(); - } - - public static GuildPlugin getInstance() { - return instance; - } - - public ServiceContainer getServiceContainer() { - return serviceContainer; - } - - public ConfigManager getConfigManager() { - return configManager; - } - - public DatabaseManager getDatabaseManager() { - return databaseManager; - } - - public EventBus getEventBus() { - return eventBus; - } - - public GUIManager getGuiManager() { - return guiManager; - } - - public PlaceholderManager getPlaceholderManager() { - return placeholderManager; - } - - public PermissionManager getPermissionManager() { - return permissionManager; - } - - public EconomyManager getEconomyManager() { - return economyManager; - } - - public GuildService getGuildService() { - return guildService; - } -} +package com.guild; + +import com.guild.core.ServiceContainer; +import com.guild.core.config.ConfigManager; +import com.guild.core.database.DatabaseManager; +import com.guild.core.events.EventBus; +import com.guild.core.gui.GUIManager; +import com.guild.core.placeholder.PlaceholderManager; +import com.guild.core.permissions.PermissionManager; +import com.guild.core.economy.EconomyManager; +import com.guild.commands.GuildCommand; +import com.guild.commands.GuildAdminCommand; +import com.guild.listeners.PlayerListener; +import com.guild.listeners.GuildListener; +import com.guild.services.GuildService; +import com.guild.core.utils.ServerUtils; +import com.guild.core.utils.TestUtils; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.logging.Logger; + +public class GuildPlugin extends JavaPlugin { + + private static GuildPlugin instance; + private ServiceContainer serviceContainer; + private ConfigManager configManager; + private DatabaseManager databaseManager; + private EventBus eventBus; + private GUIManager guiManager; + private PlaceholderManager placeholderManager; + private PermissionManager permissionManager; + private EconomyManager economyManager; + private GuildService guildService; + + @Override + public void onEnable() { + instance = this; + Logger logger = getLogger(); + + logger.info("Uruchamianie pluginu Gildie..."); + logger.info("Wykryto typ serwera: " + ServerUtils.getServerType()); + logger.info("Wersja serwera: " + ServerUtils.getServerVersion()); + + // Sprawdź kompatybilność wersji API + if (!ServerUtils.supportsApiVersion("1.21")) { + logger.severe("Ten plugin wymaga wersji 1.21 lub nowszej! Obecna wersja: " + ServerUtils.getServerVersion()); + getServer().getPluginManager().disablePlugin(this); + return; + } + + // Uruchom testy kompatybilności (używając loggera pluginu) + TestUtils.testCompatibility(logger); + TestUtils.testSchedulerCompatibility(logger); + + try { + // Inicjalizacja kontenera usług + serviceContainer = new ServiceContainer(); + + // Inicjalizacja menedżera konfiguracji + configManager = new ConfigManager(this); + serviceContainer.register(ConfigManager.class, configManager); + + // Inicjalizacja menedżera bazy danych + databaseManager = new DatabaseManager(this); + serviceContainer.register(DatabaseManager.class, databaseManager); + + // Inicjalizacja szyny zdarzeń + eventBus = new EventBus(); + serviceContainer.register(EventBus.class, eventBus); + + // Inicjalizacja menedżera GUI + guiManager = new GUIManager(this); + serviceContainer.register(GUIManager.class, guiManager); + + // Inicjalizacja menedżera placeholderów + placeholderManager = new PlaceholderManager(this); + serviceContainer.register(PlaceholderManager.class, placeholderManager); + + // Inicjalizacja menedżera uprawnień + permissionManager = new PermissionManager(this); + serviceContainer.register(PermissionManager.class, permissionManager); + + // Inicjalizacja menedżera ekonomii + economyManager = new EconomyManager(this); + serviceContainer.register(EconomyManager.class, economyManager); + + // Rejestracja usługi gildii + guildService = new GuildService(this); + serviceContainer.register(GuildService.class, guildService); + + // Ustaw referencję GuildService w PlaceholderManager + placeholderManager.setGuildService(guildService); + + // Rejestracja komend + registerCommands(); + + // Rejestracja listenerów + registerListeners(); + + // Uruchomienie usług + startServices(); + + logger.info("Plugin Gildie został pomyślnie uruchomiony!"); + logger.info("Tryb kompatybilności: " + (ServerUtils.isFolia() ? "Folia" : "Spigot")); + + } catch (Exception e) { + logger.severe("Nie udało się uruchomić pluginu Gildie: " + e.getMessage()); + e.printStackTrace(); + getServer().getPluginManager().disablePlugin(this); + } + } + + @Override + public void onDisable() { + Logger logger = getLogger(); + logger.info("Zamykanie pluginu Gildie..."); + + try { + // Zamknij wszystkie GUI + if (guiManager != null) { + guiManager.closeAllGUIs(); + } + + // Zamknij usługi + if (serviceContainer != null) { + serviceContainer.shutdown(); + } + + logger.info("Plugin Gildie został wyłączony"); + + } catch (Exception e) { + logger.severe("Wystąpił błąd podczas zamykania pluginu Gildie: " + e.getMessage()); + e.printStackTrace(); + } + } + + private void registerCommands() { + GuildCommand guildCommand = new GuildCommand(this); + GuildAdminCommand guildAdminCommand = new GuildAdminCommand(this); + + getCommand("guild").setExecutor(guildCommand); + getCommand("guild").setTabCompleter(guildCommand); + getCommand("guildadmin").setExecutor(guildAdminCommand); + getCommand("guildadmin").setTabCompleter(guildAdminCommand); + } + + private void registerListeners() { + getServer().getPluginManager().registerEvents(new PlayerListener(this), this); + getServer().getPluginManager().registerEvents(new GuildListener(this), this); + } + + private void startServices() { + // Uruchom połączenie z bazą danych + databaseManager.initialize(); + + // Zarejestruj placeholdery + placeholderManager.registerPlaceholders(); + + // Inicjalizacja systemu GUI + guiManager.initialize(); + } + + public static GuildPlugin getInstance() { + return instance; + } + + public ServiceContainer getServiceContainer() { + return serviceContainer; + } + + public ConfigManager getConfigManager() { + return configManager; + } + + public DatabaseManager getDatabaseManager() { + return databaseManager; + } + + public EventBus getEventBus() { + return eventBus; + } + + public GUIManager getGuiManager() { + return guiManager; + } + + public PlaceholderManager getPlaceholderManager() { + return placeholderManager; + } + + public PermissionManager getPermissionManager() { + return permissionManager; + } + + public EconomyManager getEconomyManager() { + return economyManager; + } + + public GuildService getGuildService() { + return guildService; + } +} diff --git a/src/main/java/com/guild/commands/GuildAdminCommand.java b/src/main/java/com/guild/commands/GuildAdminCommand.java index 29c18f7..5f94987 100644 --- a/src/main/java/com/guild/commands/GuildAdminCommand.java +++ b/src/main/java/com/guild/commands/GuildAdminCommand.java @@ -1,698 +1,698 @@ -package com.guild.commands; - -import com.guild.GuildPlugin; -import com.guild.core.utils.ColorUtils; -import com.guild.gui.AdminGuildGUI; -import com.guild.gui.RelationManagementGUI; -import com.guild.models.Guild; -import com.guild.models.GuildRelation; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -/** - * 工会管理员命令 - */ -public class GuildAdminCommand implements CommandExecutor, TabCompleter { - - private final GuildPlugin plugin; - - public GuildAdminCommand(GuildPlugin plugin) { - this.plugin = plugin; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!sender.hasPermission("guild.admin")) { - sender.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&c您没有权限执行此操作!"))); - return true; - } - - if (args.length == 0) { - if (sender instanceof Player player) { - // 打开管理员GUI - AdminGuildGUI adminGUI = new AdminGuildGUI(plugin); - plugin.getGuiManager().openGUI(player, adminGUI); - } else { - handleHelp(sender); - } - return true; - } - - switch (args[0].toLowerCase()) { - case "list": - handleList(sender, args); - break; - case "info": - handleInfo(sender, args); - break; - case "delete": - handleDelete(sender, args); - break; - case "freeze": - handleFreeze(sender, args); - break; - case "unfreeze": - handleUnfreeze(sender, args); - break; - case "transfer": - handleTransfer(sender, args); - break; - case "economy": - handleEconomy(sender, args); - break; - case "relation": - handleRelation(sender, args); - break; - case "reload": - handleReload(sender); - break; - case "test": - handleTest(sender, args); - break; - case "help": - handleHelp(sender); - break; - default: - sender.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.unknown-command", "&c未知命令!使用 /guildadmin help 查看帮助。"))); - break; - } - - return true; - } - - @Override - public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { - List completions = new ArrayList<>(); - - if (!sender.hasPermission("guild.admin")) { - return completions; - } - - if (args.length == 1) { - completions.addAll(Arrays.asList("list", "info", "delete", "freeze", "unfreeze", "transfer", "economy", "relation", "reload", "help")); - } else if (args.length == 2) { - switch (args[0].toLowerCase()) { - case "info": - case "delete": - case "freeze": - case "unfreeze": - case "transfer": - case "economy": - // 获取所有工会名称 - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - for (Guild guild : guilds) { - completions.add(guild.getName()); - } - }); - break; - case "relation": - completions.addAll(Arrays.asList("list", "create", "delete", "gui")); - break; - } - } else if (args.length == 3) { - switch (args[0].toLowerCase()) { - case "transfer": - // 获取在线玩家 - for (Player player : Bukkit.getOnlinePlayers()) { - completions.add(player.getName()); - } - break; - case "economy": - completions.addAll(Arrays.asList("set", "add", "remove", "info")); - break; - case "relation": - if ("create".equals(args[1])) { - // 第3个参数是第一个工会名称,获取所有工会名称 - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - for (Guild guild : guilds) { - completions.add(guild.getName()); - } - }); - } - break; - } - } else if (args.length == 4) { - switch (args[0].toLowerCase()) { - case "relation": - if ("create".equals(args[1])) { - // 第4个参数是第二个工会名称,获取所有工会名称 - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - for (Guild guild : guilds) { - completions.add(guild.getName()); - } - }); - } - break; - } - } else if (args.length == 5) { - switch (args[0].toLowerCase()) { - case "relation": - if ("create".equals(args[1])) { - // 第5个参数是关系类型 - completions.addAll(Arrays.asList("ally", "enemy", "war", "truce", "neutral")); - } - break; - } - } - - return completions; - } - - private void handleList(CommandSender sender, String[] args) { - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - sender.sendMessage(ColorUtils.colorize("&6=== 工会列表 ===")); - if (guilds.isEmpty()) { - sender.sendMessage(ColorUtils.colorize("&c暂无工会")); - return; - } - - for (Guild guild : guilds) { - String status = guild.isFrozen() ? "&c[冻结]" : "&a[正常]"; - sender.sendMessage(ColorUtils.colorize(String.format("&e%s &7- 会长: &f%s &7- 等级: &f%d &7%s", - guild.getName(), guild.getLeaderName(), guild.getLevel(), status))); - } - }); - } - - private void handleInfo(CommandSender sender, String[] args) { - if (args.length < 2) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin info <工会名称>")); - return; - } - - String guildName = args[1]; - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - - sender.sendMessage(ColorUtils.colorize("&6=== 工会信息 ===")); - sender.sendMessage(ColorUtils.colorize("&e名称: &f" + guild.getName())); - sender.sendMessage(ColorUtils.colorize("&e标签: &f" + (guild.getTag() != null ? guild.getTag() : "无"))); - sender.sendMessage(ColorUtils.colorize("&e会长: &f" + guild.getLeaderName())); - sender.sendMessage(ColorUtils.colorize("&e等级: &f" + guild.getLevel())); - sender.sendMessage(ColorUtils.colorize("&e资金: &f" + guild.getBalance())); - sender.sendMessage(ColorUtils.colorize("&e状态: &f" + (guild.isFrozen() ? "冻结" : "正常"))); - - // 获取成员数量 - plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenAccept(count -> { - sender.sendMessage(ColorUtils.colorize("&e成员数量: &f" + count + "/" + guild.getMaxMembers())); - }); - }); - } - - private void handleDelete(CommandSender sender, String[] args) { - if (args.length < 2) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin delete <工会名称>")); - return; - } - - String guildName = args[1]; - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - - // 强制删除工会 - plugin.getGuildService().deleteGuildAsync(guild.getId(), UUID.randomUUID()).thenAccept(success -> { - if (success) { - sender.sendMessage(ColorUtils.colorize("&a工会 " + guildName + " 已被强制删除!")); - } else { - sender.sendMessage(ColorUtils.colorize("&c删除工会失败!")); - } - }); - }); - } - - private void handleFreeze(CommandSender sender, String[] args) { - if (args.length < 2) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin freeze <工会名称>")); - return; - } - - String guildName = args[1]; - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - - // 冻结工会 - // TODO: 实现冻结功能 - sender.sendMessage(ColorUtils.colorize("&a工会 " + guildName + " 已被冻结!")); - }); - } - - private void handleUnfreeze(CommandSender sender, String[] args) { - if (args.length < 2) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin unfreeze <工会名称>")); - return; - } - - String guildName = args[1]; - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - - // 解冻工会 - // TODO: 实现解冻功能 - sender.sendMessage(ColorUtils.colorize("&a工会 " + guildName + " 已被解冻!")); - }); - } - - private void handleTransfer(CommandSender sender, String[] args) { - if (args.length < 3) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin transfer <工会名称> <新会长>")); - return; - } - - String guildName = args[1]; - String newLeaderName = args[2]; - - Player newLeader = Bukkit.getPlayer(newLeaderName); - if (newLeader == null) { - sender.sendMessage(ColorUtils.colorize("&c玩家 " + newLeaderName + " 不在线!")); - return; - } - - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - - // 检查新会长是否是该工会成员 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), newLeader.getUniqueId()).thenAccept(member -> { - if (member == null) { - sender.sendMessage(ColorUtils.colorize("&c玩家 " + newLeaderName + " 不是该工会成员!")); - return; - } - - // 转让会长 - // TODO: 实现转让功能 - sender.sendMessage(ColorUtils.colorize("&a工会 " + guildName + " 的会长已转让给 " + newLeaderName + "!")); - }); - }); - } - - private void handleEconomy(CommandSender sender, String[] args) { - if (args.length < 4) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin economy <工会名称> <金额>")); - return; - } - - String guildName = args[1]; - String operation = args[2]; - double amount; - - try { - amount = Double.parseDouble(args[3]); - } catch (NumberFormatException e) { - sender.sendMessage(ColorUtils.colorize("&c金额格式错误!")); - return; - } - - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - - final double[] newBalance = {guild.getBalance()}; - switch (operation.toLowerCase()) { - case "set": - newBalance[0] = amount; - break; - case "add": - newBalance[0] += amount; - break; - case "remove": - newBalance[0] -= amount; - if (newBalance[0] < 0) newBalance[0] = 0; - break; - default: - sender.sendMessage(ColorUtils.colorize("&c无效的操作!使用 set|add|remove")); - return; - } - - // 更新工会资金 - plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), newBalance[0]).thenAccept(success -> { - if (success) { - String formattedAmount = plugin.getEconomyManager().format(newBalance[0]); - sender.sendMessage(ColorUtils.colorize("&a工会 " + guildName + " 的资金已更新为: " + formattedAmount)); - } else { - sender.sendMessage(ColorUtils.colorize("&c更新工会资金失败!")); - } - }); - }); - } - - private void handleRelation(CommandSender sender, String[] args) { - if (args.length < 2) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin relation ")); - return; - } - - switch (args[1].toLowerCase()) { - case "gui": - if (sender instanceof Player player) { - // 打开关系管理GUI - RelationManagementGUI relationGUI = new RelationManagementGUI(plugin, player); - plugin.getGuiManager().openGUI(player, relationGUI); - } else { - sender.sendMessage(ColorUtils.colorize("&c此命令只能由玩家执行!")); - } - break; - case "list": - // 显示所有工会关系 - sender.sendMessage(ColorUtils.colorize("&6=== 工会关系列表 ===")); - plugin.getGuildService().getAllGuildsAsync().thenCompose(guilds -> { - List>> relationFutures = new ArrayList<>(); - - for (Guild guild : guilds) { - relationFutures.add(plugin.getGuildService().getGuildRelationsAsync(guild.getId())); - } - - return CompletableFuture.allOf(relationFutures.toArray(new CompletableFuture[0])) - .thenApply(v -> { - List allRelations = new ArrayList<>(); - for (CompletableFuture> future : relationFutures) { - try { - allRelations.addAll(future.get()); - } catch (Exception e) { - plugin.getLogger().warning("获取工会关系时发生错误: " + e.getMessage()); - } - } - return allRelations; - }); - }).thenAccept(relations -> { - if (relations.isEmpty()) { - sender.sendMessage(ColorUtils.colorize("&c暂无工会关系")); - return; - } - - for (GuildRelation relation : relations) { - String status = getRelationStatusText(relation.getStatus()); - String type = getRelationTypeText(relation.getType()); - sender.sendMessage(ColorUtils.colorize(String.format("&e%s ↔ %s &7- %s &7- %s", - relation.getGuild1Name(), relation.getGuild2Name(), type, status))); - } - }); - break; - case "create": - if (args.length < 5) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin relation create <工会1> <工会2> <关系类型>")); - sender.sendMessage(ColorUtils.colorize("&7关系类型: ally|enemy|war|truce|neutral")); - return; - } - handleCreateRelation(sender, args); - break; - case "delete": - if (args.length < 4) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin relation delete <工会1> <工会2>")); - return; - } - handleDeleteRelation(sender, args); - break; - default: - sender.sendMessage(ColorUtils.colorize("&c无效的关系操作!使用 list|create|delete|gui")); - break; - } - } - - private void handleCreateRelation(CommandSender sender, String[] args) { - String guild1Name = args[2]; - String guild2Name = args[3]; - String relationTypeStr = args[4]; - - // 解析关系类型 - GuildRelation.RelationType relationType; - try { - relationType = GuildRelation.RelationType.valueOf(relationTypeStr.toUpperCase()); - } catch (IllegalArgumentException e) { - sender.sendMessage(ColorUtils.colorize("&c无效的关系类型!使用: ally, enemy, war, truce, neutral")); - return; - } - - // 获取两个工会 - CompletableFuture guild1Future = plugin.getGuildService().getGuildByNameAsync(guild1Name); - CompletableFuture guild2Future = plugin.getGuildService().getGuildByNameAsync(guild2Name); - - CompletableFuture.allOf(guild1Future, guild2Future).thenAccept(v -> { - try { - Guild guild1 = guild1Future.get(); - Guild guild2 = guild2Future.get(); - - if (guild1 == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guild1Name + " 不存在!")); - return; - } - if (guild2 == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guild2Name + " 不存在!")); - return; - } - if (guild1.getId() == guild2.getId()) { - sender.sendMessage(ColorUtils.colorize("&c不能与自己建立关系!")); - return; - } - - // 创建关系 - plugin.getGuildService().createGuildRelationAsync( - guild1.getId(), guild2.getId(), - guild1.getName(), guild2.getName(), - relationType, UUID.randomUUID(), "管理员" - ).thenAccept(success -> { - if (success) { - sender.sendMessage(ColorUtils.colorize("&a已创建关系: " + guild1Name + " ↔ " + guild2Name + " (" + getRelationTypeText(relationType) + ")")); - } else { - sender.sendMessage(ColorUtils.colorize("&c创建关系失败!")); - } - }); - - } catch (Exception e) { - sender.sendMessage(ColorUtils.colorize("&c创建关系时发生错误: " + e.getMessage())); - } - }); - } - - private void handleDeleteRelation(CommandSender sender, String[] args) { - String guild1Name = args[2]; - String guild2Name = args[3]; - - // 获取两个工会 - CompletableFuture guild1Future = plugin.getGuildService().getGuildByNameAsync(guild1Name); - CompletableFuture guild2Future = plugin.getGuildService().getGuildByNameAsync(guild2Name); - - CompletableFuture.allOf(guild1Future, guild2Future).thenAccept(v -> { - try { - Guild guild1 = guild1Future.get(); - Guild guild2 = guild2Future.get(); - - if (guild1 == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guild1Name + " 不存在!")); - return; - } - if (guild2 == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guild2Name + " 不存在!")); - return; - } - - // 查找并删除关系 - plugin.getGuildService().getGuildRelationsAsync(guild1.getId()).thenAccept(relations -> { - for (GuildRelation relation : relations) { - if ((relation.getGuild1Id() == guild1.getId() && relation.getGuild2Id() == guild2.getId()) || - (relation.getGuild1Id() == guild2.getId() && relation.getGuild2Id() == guild1.getId())) { - - plugin.getGuildService().deleteGuildRelationAsync(relation.getId()).thenAccept(success -> { - if (success) { - sender.sendMessage(ColorUtils.colorize("&a已删除关系: " + guild1Name + " ↔ " + guild2Name)); - } else { - sender.sendMessage(ColorUtils.colorize("&c删除关系失败!")); - } - }); - return; - } - } - sender.sendMessage(ColorUtils.colorize("&c未找到工会 " + guild1Name + " 和 " + guild2Name + " 之间的关系!")); - }); - - } catch (Exception e) { - sender.sendMessage(ColorUtils.colorize("&c删除关系时发生错误: " + e.getMessage())); - } - }); - } - - private String getRelationStatusText(GuildRelation.RelationStatus status) { - switch (status) { - case PENDING: return "待处理"; - case ACTIVE: return "活跃"; - case EXPIRED: return "已过期"; - case CANCELLED: return "已取消"; - default: return "未知"; - } - } - - private String getRelationTypeText(GuildRelation.RelationType type) { - switch (type) { - case ALLY: return "盟友"; - case ENEMY: return "敌对"; - case WAR: return "开战"; - case TRUCE: return "停战"; - case NEUTRAL: return "中立"; - default: return "未知"; - } - } - - private void handleReload(CommandSender sender) { - try { - plugin.getConfigManager().reloadAllConfigs(); - // 重新加载权限矩阵并清空权限缓存 - plugin.getPermissionManager().reloadFromConfig(); - sender.sendMessage(ColorUtils.colorize("&a配置已重新加载!")); - } catch (Exception e) { - sender.sendMessage(ColorUtils.colorize("&c重新加载配置失败: " + e.getMessage())); - } - } - - private void handleTest(CommandSender sender, String[] args) { - if (args.length < 2) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin test ")); - sender.sendMessage(ColorUtils.colorize("&7test-type: gui, economy, relation")); - return; - } - - String testType = args[1]; - switch (testType.toLowerCase()) { - case "gui": - if (sender instanceof Player player) { - AdminGuildGUI adminGUI = new AdminGuildGUI(plugin); - plugin.getGuiManager().openGUI(player, adminGUI); - sender.sendMessage(ColorUtils.colorize("&a已打开管理员GUI进行测试。")); - } else { - sender.sendMessage(ColorUtils.colorize("&c此命令只能由玩家执行!")); - } - break; - case "economy": - if (args.length < 4) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin test economy <工会名称> <操作> <金额>")); - return; - } - String guildName = args[2]; - String operation = args[3]; - double amount; - try { - amount = Double.parseDouble(args[4]); - } catch (NumberFormatException e) { - sender.sendMessage(ColorUtils.colorize("&c金额格式错误!")); - return; - } - plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { - if (guild == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guildName + " 不存在!")); - return; - } - final double[] newBalance = {guild.getBalance()}; - switch (operation.toLowerCase()) { - case "set": - newBalance[0] = amount; - break; - case "add": - newBalance[0] += amount; - break; - case "remove": - newBalance[0] -= amount; - if (newBalance[0] < 0) newBalance[0] = 0; - break; - default: - sender.sendMessage(ColorUtils.colorize("&c无效的操作!使用 set|add|remove")); - return; - } - plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), newBalance[0]).thenAccept(success -> { - if (success) { - String formattedAmount = plugin.getEconomyManager().format(newBalance[0]); - sender.sendMessage(ColorUtils.colorize("&a工会 " + guildName + " 的资金已更新为: " + formattedAmount)); - } else { - sender.sendMessage(ColorUtils.colorize("&c更新工会资金失败!")); - } - }); - }); - break; - case "relation": - if (args.length < 5) { - sender.sendMessage(ColorUtils.colorize("&c用法: /guildadmin test relation create <工会1> <工会2> <关系类型>")); - sender.sendMessage(ColorUtils.colorize("&7关系类型: ally|enemy|war|truce|neutral")); - return; - } - String guild1NameTest = args[2]; - String guild2NameTest = args[3]; - String relationTypeStrTest = args[4]; - GuildRelation.RelationType relationTypeTest; - try { - relationTypeTest = GuildRelation.RelationType.valueOf(relationTypeStrTest.toUpperCase()); - } catch (IllegalArgumentException e) { - sender.sendMessage(ColorUtils.colorize("&c无效的关系类型!使用: ally, enemy, war, truce, neutral")); - return; - } - plugin.getGuildService().getGuildByNameAsync(guild1NameTest).thenAccept(guild1 -> { - if (guild1 == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guild1NameTest + " 不存在!")); - return; - } - plugin.getGuildService().getGuildByNameAsync(guild2NameTest).thenAccept(guild2 -> { - if (guild2 == null) { - sender.sendMessage(ColorUtils.colorize("&c工会 " + guild2NameTest + " 不存在!")); - return; - } - if (guild1.getId() == guild2.getId()) { - sender.sendMessage(ColorUtils.colorize("&c不能与自己建立关系!")); - return; - } - plugin.getGuildService().createGuildRelationAsync( - guild1.getId(), guild2.getId(), - guild1.getName(), guild2.getName(), - relationTypeTest, UUID.randomUUID(), "管理员" - ).thenAccept(success -> { - if (success) { - sender.sendMessage(ColorUtils.colorize("&a已创建关系: " + guild1NameTest + " ↔ " + guild2NameTest + " (" + getRelationTypeText(relationTypeTest) + ")")); - } else { - sender.sendMessage(ColorUtils.colorize("&c创建关系失败!")); - } - }); - }); - }); - break; - default: - sender.sendMessage(ColorUtils.colorize("&c无效的测试类型!使用 gui, economy, relation")); - break; - } - } - - private void handleHelp(CommandSender sender) { - sender.sendMessage(ColorUtils.colorize("&6=== 工会管理员命令 ===")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin &7- 打开管理员GUI")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin list &7- 列出所有工会")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin info <工会> &7- 查看工会信息")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin delete <工会> &7- 强制删除工会")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin freeze <工会> &7- 冻结工会")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin unfreeze <工会> &7- 解冻工会")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin transfer <工会> <玩家> &7- 转让会长")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin economy <工会> <操作> <金额> &7- 管理工会经济")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin relation <操作> &7- 管理工会关系")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin reload &7- 重新加载配置")); - sender.sendMessage(ColorUtils.colorize("&e/guildadmin help &7- 显示帮助信息")); - } -} +package com.guild.commands; + +import com.guild.GuildPlugin; +import com.guild.core.utils.ColorUtils; +import com.guild.gui.AdminGuildGUI; +import com.guild.gui.RelationManagementGUI; +import com.guild.models.Guild; +import com.guild.models.GuildRelation; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +/** + * Polecenie administratora gildii + */ +public class GuildAdminCommand implements CommandExecutor, TabCompleter { + + private final GuildPlugin plugin; + + public GuildAdminCommand(GuildPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!sender.hasPermission("guild.admin")) { + sender.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&cNie masz uprawnień do wykonania tej operacji!"))); + return true; + } + + if (args.length == 0) { + if (sender instanceof Player player) { + // Otwórz GUI administratora + AdminGuildGUI adminGUI = new AdminGuildGUI(plugin); + plugin.getGuiManager().openGUI(player, adminGUI); + } else { + handleHelp(sender); + } + return true; + } + + switch (args[0].toLowerCase()) { + case "list": + handleList(sender, args); + break; + case "info": + handleInfo(sender, args); + break; + case "delete": + handleDelete(sender, args); + break; + case "freeze": + handleFreeze(sender, args); + break; + case "unfreeze": + handleUnfreeze(sender, args); + break; + case "transfer": + handleTransfer(sender, args); + break; + case "economy": + handleEconomy(sender, args); + break; + case "relation": + handleRelation(sender, args); + break; + case "reload": + handleReload(sender); + break; + case "test": + handleTest(sender, args); + break; + case "help": + handleHelp(sender); + break; + default: + sender.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.unknown-command", "&cNieznane polecenie! Użyj /guildadmin help, aby zobaczyć pomoc."))); + break; + } + + return true; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + List completions = new ArrayList<>(); + + if (!sender.hasPermission("guild.admin")) { + return completions; + } + + if (args.length == 1) { + completions.addAll(Arrays.asList("list", "info", "delete", "freeze", "unfreeze", "transfer", "economy", "relation", "reload", "help")); + } else if (args.length == 2) { + switch (args[0].toLowerCase()) { + case "info": + case "delete": + case "freeze": + case "unfreeze": + case "transfer": + case "economy": + // Pobierz wszystkie nazwy gildii + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + for (Guild guild : guilds) { + completions.add(guild.getName()); + } + }); + break; + case "relation": + completions.addAll(Arrays.asList("list", "create", "delete", "gui")); + break; + } + } else if (args.length == 3) { + switch (args[0].toLowerCase()) { + case "transfer": + // Pobierz graczy online + for (Player player : Bukkit.getOnlinePlayers()) { + completions.add(player.getName()); + } + break; + case "economy": + completions.addAll(Arrays.asList("set", "add", "remove", "info")); + break; + case "relation": + if ("create".equals(args[1])) { + // 3. argument to nazwa pierwszej gildii, pobierz wszystkie nazwy gildii + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + for (Guild guild : guilds) { + completions.add(guild.getName()); + } + }); + } + break; + } + } else if (args.length == 4) { + switch (args[0].toLowerCase()) { + case "relation": + if ("create".equals(args[1])) { + // 4. argument to nazwa drugiej gildii, pobierz wszystkie nazwy gildii + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + for (Guild guild : guilds) { + completions.add(guild.getName()); + } + }); + } + break; + } + } else if (args.length == 5) { + switch (args[0].toLowerCase()) { + case "relation": + if ("create".equals(args[1])) { + // 5. argument to typ relacji + completions.addAll(Arrays.asList("ally", "enemy", "war", "truce", "neutral")); + } + break; + } + } + + return completions; + } + + private void handleList(CommandSender sender, String[] args) { + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + sender.sendMessage(ColorUtils.colorize("&6=== Lista Gildii ===")); + if (guilds.isEmpty()) { + sender.sendMessage(ColorUtils.colorize("&cBrak gildii")); + return; + } + + for (Guild guild : guilds) { + String status = guild.isFrozen() ? "&c[Zamrożona]" : "&a[Normalna]"; + sender.sendMessage(ColorUtils.colorize(String.format("&e%s &7- Lider: &f%s &7- Poziom: &f%d &7%s", + guild.getName(), guild.getLeaderName(), guild.getLevel(), status))); + } + }); + } + + private void handleInfo(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin info ")); + return; + } + + String guildName = args[1]; + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + + sender.sendMessage(ColorUtils.colorize("&6=== Informacje o Gildii ===")); + sender.sendMessage(ColorUtils.colorize("&eNazwa: &f" + guild.getName())); + sender.sendMessage(ColorUtils.colorize("&eTag: &f" + (guild.getTag() != null ? guild.getTag() : "Brak"))); + sender.sendMessage(ColorUtils.colorize("&eLider: &f" + guild.getLeaderName())); + sender.sendMessage(ColorUtils.colorize("&ePoziom: &f" + guild.getLevel())); + sender.sendMessage(ColorUtils.colorize("&eFundusze: &f" + guild.getBalance())); + sender.sendMessage(ColorUtils.colorize("&eStatus: &f" + (guild.isFrozen() ? "Zamrożona" : "Normalna"))); + + // Pobierz liczbę członków + plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenAccept(count -> { + sender.sendMessage(ColorUtils.colorize("&eLiczba członków: &f" + count + "/" + guild.getMaxMembers())); + }); + }); + } + + private void handleDelete(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin delete ")); + return; + } + + String guildName = args[1]; + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + + // Wymuś usunięcie gildii + plugin.getGuildService().deleteGuildAsync(guild.getId(), UUID.randomUUID()).thenAccept(success -> { + if (success) { + sender.sendMessage(ColorUtils.colorize("&aGildia " + guildName + " została wymuszenie usunięta!")); + } else { + sender.sendMessage(ColorUtils.colorize("&cUsunięcie gildii nie powiodło się!")); + } + }); + }); + } + + private void handleFreeze(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin freeze ")); + return; + } + + String guildName = args[1]; + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + + // Zamrożenie gildii + // TODO: Zaimplementuj funkcję zamrażania + sender.sendMessage(ColorUtils.colorize("&aGildia " + guildName + " została zamrożona!")); + }); + } + + private void handleUnfreeze(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin unfreeze ")); + return; + } + + String guildName = args[1]; + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + + // Odmrożenie gildii + // TODO: Zaimplementuj funkcję odmrażania + sender.sendMessage(ColorUtils.colorize("&aGildia " + guildName + " została odmrożona!")); + }); + } + + private void handleTransfer(CommandSender sender, String[] args) { + if (args.length < 3) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin transfer ")); + return; + } + + String guildName = args[1]; + String newLeaderName = args[2]; + + Player newLeader = Bukkit.getPlayer(newLeaderName); + if (newLeader == null) { + sender.sendMessage(ColorUtils.colorize("&cGracz " + newLeaderName + " nie jest online!")); + return; + } + + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + + // Sprawdź, czy nowy lider jest członkiem tej gildii + plugin.getGuildService().getGuildMemberAsync(guild.getId(), newLeader.getUniqueId()).thenAccept(member -> { + if (member == null) { + sender.sendMessage(ColorUtils.colorize("&cGracz " + newLeaderName + " nie jest członkiem tej gildii!")); + return; + } + + // Przekaż lidera + // TODO: Zaimplementuj funkcję przekazywania + sender.sendMessage(ColorUtils.colorize("&aLider gildii " + guildName + " został przekazany graczowi " + newLeaderName + "!")); + }); + }); + } + + private void handleEconomy(CommandSender sender, String[] args) { + if (args.length < 4) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin economy ")); + return; + } + + String guildName = args[1]; + String operation = args[2]; + double amount; + + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException e) { + sender.sendMessage(ColorUtils.colorize("&cFormat kwoty jest nieprawidłowy!")); + return; + } + + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + + final double[] newBalance = {guild.getBalance()}; + switch (operation.toLowerCase()) { + case "set": + newBalance[0] = amount; + break; + case "add": + newBalance[0] += amount; + break; + case "remove": + newBalance[0] -= amount; + if (newBalance[0] < 0) newBalance[0] = 0; + break; + default: + sender.sendMessage(ColorUtils.colorize("&cNieprawidłowa operacja! Użyj set|add|remove")); + return; + } + + // Zaktualizuj fundusze gildii + plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), newBalance[0]).thenAccept(success -> { + if (success) { + String formattedAmount = plugin.getEconomyManager().format(newBalance[0]); + sender.sendMessage(ColorUtils.colorize("&aFundusze gildii " + guildName + " zostały zaktualizowane do: " + formattedAmount)); + } else { + sender.sendMessage(ColorUtils.colorize("&cAktualizacja funduszy gildii nie powiodła się!")); + } + }); + }); + } + + private void handleRelation(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin relation ")); + return; + } + + switch (args[1].toLowerCase()) { + case "gui": + if (sender instanceof Player player) { + // Otwórz GUI zarządzania relacjami + RelationManagementGUI relationGUI = new RelationManagementGUI(plugin, player); + plugin.getGuiManager().openGUI(player, relationGUI); + } else { + sender.sendMessage(ColorUtils.colorize("&cTo polecenie może być wykonane tylko przez gracza!")); + } + break; + case "list": + // Wyświetl wszystkie relacje gildii + sender.sendMessage(ColorUtils.colorize("&6=== Lista Relacji Gildii ===")); + plugin.getGuildService().getAllGuildsAsync().thenCompose(guilds -> { + List>> relationFutures = new ArrayList<>(); + + for (Guild guild : guilds) { + relationFutures.add(plugin.getGuildService().getGuildRelationsAsync(guild.getId())); + } + + return CompletableFuture.allOf(relationFutures.toArray(new CompletableFuture[0])) + .thenApply(v -> { + List allRelations = new ArrayList<>(); + for (CompletableFuture> future : relationFutures) { + try { + allRelations.addAll(future.get()); + } catch (Exception e) { + plugin.getLogger().warning("Błąd podczas pobierania relacji gildii: " + e.getMessage()); + } + } + return allRelations; + }); + }).thenAccept(relations -> { + if (relations.isEmpty()) { + sender.sendMessage(ColorUtils.colorize("&cBrak relacji gildii")); + return; + } + + for (GuildRelation relation : relations) { + String status = getRelationStatusText(relation.getStatus()); + String type = getRelationTypeText(relation.getType()); + sender.sendMessage(ColorUtils.colorize(String.format("&e%s ↔ %s &7- %s &7- %s", + relation.getGuild1Name(), relation.getGuild2Name(), type, status))); + } + }); + break; + case "create": + if (args.length < 5) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin relation create ")); + sender.sendMessage(ColorUtils.colorize("&7Typ relacji: ally|enemy|war|truce|neutral")); + return; + } + handleCreateRelation(sender, args); + break; + case "delete": + if (args.length < 4) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin relation delete ")); + return; + } + handleDeleteRelation(sender, args); + break; + default: + sender.sendMessage(ColorUtils.colorize("&cNieprawidłowa operacja relacji! Użyj list|create|delete|gui")); + break; + } + } + + private void handleCreateRelation(CommandSender sender, String[] args) { + String guild1Name = args[2]; + String guild2Name = args[3]; + String relationTypeStr = args[4]; + + // Parsuj typ relacji + GuildRelation.RelationType relationType; + try { + relationType = GuildRelation.RelationType.valueOf(relationTypeStr.toUpperCase()); + } catch (IllegalArgumentException e) { + sender.sendMessage(ColorUtils.colorize("&cNieprawidłowy typ relacji! Użyj: ally, enemy, war, truce, neutral")); + return; + } + + // Pobierz obie gildie + CompletableFuture guild1Future = plugin.getGuildService().getGuildByNameAsync(guild1Name); + CompletableFuture guild2Future = plugin.getGuildService().getGuildByNameAsync(guild2Name); + + CompletableFuture.allOf(guild1Future, guild2Future).thenAccept(v -> { + try { + Guild guild1 = guild1Future.get(); + Guild guild2 = guild2Future.get(); + + if (guild1 == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guild1Name + " nie istnieje!")); + return; + } + if (guild2 == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guild2Name + " nie istnieje!")); + return; + } + if (guild1.getId() == guild2.getId()) { + sender.sendMessage(ColorUtils.colorize("&cNie można nawiązać relacji z samym sobą!")); + return; + } + + // Utwórz relację + plugin.getGuildService().createGuildRelationAsync( + guild1.getId(), guild2.getId(), + guild1.getName(), guild2.getName(), + relationType, UUID.randomUUID(), "Administrator" + ).thenAccept(success -> { + if (success) { + sender.sendMessage(ColorUtils.colorize("&aUtworzono relację: " + guild1Name + " ↔ " + guild2Name + " (" + getRelationTypeText(relationType) + ")")); + } else { + sender.sendMessage(ColorUtils.colorize("&cUtworzenie relacji nie powiodło się!")); + } + }); + + } catch (Exception e) { + sender.sendMessage(ColorUtils.colorize("&cBłąd podczas tworzenia relacji: " + e.getMessage())); + } + }); + } + + private void handleDeleteRelation(CommandSender sender, String[] args) { + String guild1Name = args[2]; + String guild2Name = args[3]; + + // Pobierz obie gildie + CompletableFuture guild1Future = plugin.getGuildService().getGuildByNameAsync(guild1Name); + CompletableFuture guild2Future = plugin.getGuildService().getGuildByNameAsync(guild2Name); + + CompletableFuture.allOf(guild1Future, guild2Future).thenAccept(v -> { + try { + Guild guild1 = guild1Future.get(); + Guild guild2 = guild2Future.get(); + + if (guild1 == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guild1Name + " nie istnieje!")); + return; + } + if (guild2 == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guild2Name + " nie istnieje!")); + return; + } + + // Znajdź i usuń relację + plugin.getGuildService().getGuildRelationsAsync(guild1.getId()).thenAccept(relations -> { + for (GuildRelation relation : relations) { + if ((relation.getGuild1Id() == guild1.getId() && relation.getGuild2Id() == guild2.getId()) || + (relation.getGuild1Id() == guild2.getId() && relation.getGuild2Id() == guild1.getId())) { + + plugin.getGuildService().deleteGuildRelationAsync(relation.getId()).thenAccept(success -> { + if (success) { + sender.sendMessage(ColorUtils.colorize("&aUsunięto relację: " + guild1Name + " ↔ " + guild2Name)); + } else { + sender.sendMessage(ColorUtils.colorize("&cUsunięcie relacji nie powiodło się!")); + } + }); + return; + } + } + sender.sendMessage(ColorUtils.colorize("&cNie znaleziono relacji między " + guild1Name + " a " + guild2Name + "!")); + }); + + } catch (Exception e) { + sender.sendMessage(ColorUtils.colorize("&cBłąd podczas usuwania relacji: " + e.getMessage())); + } + }); + } + + private String getRelationStatusText(GuildRelation.RelationStatus status) { + switch (status) { + case PENDING: return "Oczekująca"; + case ACTIVE: return "Aktywna"; + case EXPIRED: return "Wygasła"; + case CANCELLED: return "Anulowana"; + default: return "Nieznana"; + } + } + + private String getRelationTypeText(GuildRelation.RelationType type) { + switch (type) { + case ALLY: return "Sojusznik"; + case ENEMY: return "Wróg"; + case WAR: return "Wojna"; + case TRUCE: return "Rozejm"; + case NEUTRAL: return "Neutralny"; + default: return "Nieznany"; + } + } + + private void handleReload(CommandSender sender) { + try { + plugin.getConfigManager().reloadAllConfigs(); + // Przeładuj macierz uprawnień i wyczyść cache uprawnień + plugin.getPermissionManager().reloadFromConfig(); + sender.sendMessage(ColorUtils.colorize("&aKonfiguracja została przeładowana!")); + } catch (Exception e) { + sender.sendMessage(ColorUtils.colorize("&cPrzeładowanie konfiguracji nie powiodło się: " + e.getMessage())); + } + } + + private void handleTest(CommandSender sender, String[] args) { + if (args.length < 2) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin test ")); + sender.sendMessage(ColorUtils.colorize("&7typ-testu: gui, economy, relation")); + return; + } + + String testType = args[1]; + switch (testType.toLowerCase()) { + case "gui": + if (sender instanceof Player player) { + AdminGuildGUI adminGUI = new AdminGuildGUI(plugin); + plugin.getGuiManager().openGUI(player, adminGUI); + sender.sendMessage(ColorUtils.colorize("&aOtwarto GUI administratora do testów.")); + } else { + sender.sendMessage(ColorUtils.colorize("&cTo polecenie może być wykonane tylko przez gracza!")); + } + break; + case "economy": + if (args.length < 4) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin test economy ")); + return; + } + String guildName = args[2]; + String operation = args[3]; + double amount; + try { + amount = Double.parseDouble(args[4]); + } catch (NumberFormatException e) { + sender.sendMessage(ColorUtils.colorize("&cFormat kwoty jest nieprawidłowy!")); + return; + } + plugin.getGuildService().getGuildByNameAsync(guildName).thenAccept(guild -> { + if (guild == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guildName + " nie istnieje!")); + return; + } + final double[] newBalance = {guild.getBalance()}; + switch (operation.toLowerCase()) { + case "set": + newBalance[0] = amount; + break; + case "add": + newBalance[0] += amount; + break; + case "remove": + newBalance[0] -= amount; + if (newBalance[0] < 0) newBalance[0] = 0; + break; + default: + sender.sendMessage(ColorUtils.colorize("&cNieprawidłowa operacja! Użyj set|add|remove")); + return; + } + plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), newBalance[0]).thenAccept(success -> { + if (success) { + String formattedAmount = plugin.getEconomyManager().format(newBalance[0]); + sender.sendMessage(ColorUtils.colorize("&aFundusze gildii " + guildName + " zostały zaktualizowane do: " + formattedAmount)); + } else { + sender.sendMessage(ColorUtils.colorize("&cAktualizacja funduszy gildii nie powiodła się!")); + } + }); + }); + break; + case "relation": + if (args.length < 5) { + sender.sendMessage(ColorUtils.colorize("&cUżycie: /guildadmin test relation create ")); + sender.sendMessage(ColorUtils.colorize("&7Typ relacji: ally|enemy|war|truce|neutral")); + return; + } + String guild1NameTest = args[2]; + String guild2NameTest = args[3]; + String relationTypeStrTest = args[4]; + GuildRelation.RelationType relationTypeTest; + try { + relationTypeTest = GuildRelation.RelationType.valueOf(relationTypeStrTest.toUpperCase()); + } catch (IllegalArgumentException e) { + sender.sendMessage(ColorUtils.colorize("&cNieprawidłowy typ relacji! Użyj: ally, enemy, war, truce, neutral")); + return; + } + plugin.getGuildService().getGuildByNameAsync(guild1NameTest).thenAccept(guild1 -> { + if (guild1 == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guild1NameTest + " nie istnieje!")); + return; + } + plugin.getGuildService().getGuildByNameAsync(guild2NameTest).thenAccept(guild2 -> { + if (guild2 == null) { + sender.sendMessage(ColorUtils.colorize("&cGildia " + guild2NameTest + " nie istnieje!")); + return; + } + if (guild1.getId() == guild2.getId()) { + sender.sendMessage(ColorUtils.colorize("&cNie można nawiązać relacji z samym sobą!")); + return; + } + plugin.getGuildService().createGuildRelationAsync( + guild1.getId(), guild2.getId(), + guild1.getName(), guild2.getName(), + relationTypeTest, UUID.randomUUID(), "Administrator" + ).thenAccept(success -> { + if (success) { + sender.sendMessage(ColorUtils.colorize("&aUtworzono relację: " + guild1NameTest + " ↔ " + guild2NameTest + " (" + getRelationTypeText(relationTypeTest) + ")")); + } else { + sender.sendMessage(ColorUtils.colorize("&cUtworzenie relacji nie powiodło się!")); + } + }); + }); + }); + break; + default: + sender.sendMessage(ColorUtils.colorize("&cNieprawidłowy typ testu! Użyj gui, economy, relation")); + break; + } + } + + private void handleHelp(CommandSender sender) { + sender.sendMessage(ColorUtils.colorize("&6=== Polecenia Administratora Gildii ===")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin &7- Otwórz GUI administratora")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin list &7- Wypisz wszystkie gildie")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin info &7- Zobacz informacje o gildii")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin delete &7- Wymuś usunięcie gildii")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin freeze &7- Zamroź gildię")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin unfreeze &7- Odmroź gildię")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin transfer &7- Przekaż lidera")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin economy &7- Zarządzaj ekonomią gildii")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin relation &7- Zarządzaj relacjami gildii")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin reload &7- Przeładuj konfigurację")); + sender.sendMessage(ColorUtils.colorize("&e/guildadmin help &7- Pokaż informacje o pomocy")); + } +} diff --git a/src/main/java/com/guild/commands/GuildCommand.java b/src/main/java/com/guild/commands/GuildCommand.java index 21f4c60..fda1fdd 100644 --- a/src/main/java/com/guild/commands/GuildCommand.java +++ b/src/main/java/com/guild/commands/GuildCommand.java @@ -1,1685 +1,1682 @@ -package com.guild.commands; - -import com.guild.GuildPlugin; -import com.guild.core.utils.ColorUtils; -import com.guild.gui.MainGuildGUI; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import com.guild.models.GuildRelation; -import com.guild.services.GuildService; -import com.guild.core.utils.CompatibleScheduler; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 工会主命令 - */ -public class GuildCommand implements CommandExecutor, TabCompleter { - - private final GuildPlugin plugin; - - public GuildCommand(GuildPlugin plugin) { - this.plugin = plugin; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!(sender instanceof Player player)) { - sender.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.player-only", "&c此命令只能由玩家执行!"))); - return true; - } - - if (args.length == 0) { - // 打开主GUI - MainGuildGUI mainGuildGUI = new MainGuildGUI(plugin); - plugin.getGuiManager().openGUI(player, mainGuildGUI); - return true; - } - - switch (args[0].toLowerCase()) { - case "create": - handleCreate(player, args); - break; - case "info": - handleInfo(player); - break; - case "members": - handleMembers(player); - break; - case "invite": - handleInvite(player, args); - break; - case "kick": - handleKick(player, args); - break; - case "promote": - handlePromote(player, args); - break; - case "demote": - handleDemote(player, args); - break; - case "accept": - handleAccept(player, args); - break; - case "decline": - handleDecline(player, args); - break; - case "leave": - handleLeave(player); - break; - case "delete": - handleDelete(player); - break; - case "sethome": - handleSetHome(player); - break; - case "home": - handleHome(player); - break; - case "relation": - handleRelation(player, args); - break; - case "economy": - handleEconomy(player, args); - break; - case "deposit": - handleDeposit(player, args); - break; - case "withdraw": - handleWithdraw(player, args); - break; - case "transfer": - handleTransfer(player, args); - break; - case "logs": - handleLogs(player, args); - break; - case "placeholder": - handlePlaceholder(player, args); - break; - case "time": - handleTime(player); - break; - case "help": - handleHelp(player); - break; - default: - player.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.unknown-command", "&c未知命令!使用 /guild help 查看帮助。"))); - break; - } - - return true; - } - - @Override - public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { - List completions = new ArrayList<>(); - - if (args.length == 1) { - List subCommands = Arrays.asList( - "create", "info", "members", "invite", "kick", "promote", "demote", "accept", "decline", "leave", "delete", "sethome", "home", "relation", "economy", "deposit", "withdraw", "transfer", "logs", "placeholder", "time", "help" - ); - - for (String subCommand : subCommands) { - if (subCommand.toLowerCase().startsWith(args[0].toLowerCase())) { - completions.add(subCommand); - } - } - } else if (args.length == 2) { - String subCommand = args[0].toLowerCase(); - - switch (subCommand) { - case "relation": - List relationSubCommands = Arrays.asList("list", "create", "delete", "accept", "reject"); - for (String cmd : relationSubCommands) { - if (cmd.toLowerCase().startsWith(args[1].toLowerCase())) { - completions.add(cmd); - } - } - break; - case "economy": - List economySubCommands = Arrays.asList("info", "deposit", "withdraw", "transfer"); - for (String cmd : economySubCommands) { - if (cmd.toLowerCase().startsWith(args[1].toLowerCase())) { - completions.add(cmd); - } - } - break; - case "invite": - case "kick": - case "promote": - case "demote": - // 获取在线玩家列表 - for (Player player : Bukkit.getOnlinePlayers()) { - if (player.getName().toLowerCase().startsWith(args[1].toLowerCase())) { - completions.add(player.getName()); - } - } - break; - } - } else if (args.length == 3) { - String subCommand = args[0].toLowerCase(); - String subSubCommand = args[1].toLowerCase(); - - if (subCommand.equals("relation") && subSubCommand.equals("create")) { - // 为创建关系提供简单的补全提示 - // 由于异步操作的限制,这里只提供基本的提示 - List suggestions = Arrays.asList("目标工会名称"); - for (String suggestion : suggestions) { - if (suggestion.toLowerCase().startsWith(args[2].toLowerCase())) { - completions.add(suggestion); - } - } - } else if (subCommand.equals("relation") && (subSubCommand.equals("delete") || subSubCommand.equals("accept") || subSubCommand.equals("reject"))) { - // 为关系操作提供简单的补全提示 - // 由于异步操作的限制,这里只提供基本的提示 - List suggestions = Arrays.asList("工会名称"); - for (String suggestion : suggestions) { - if (suggestion.toLowerCase().startsWith(args[2].toLowerCase())) { - completions.add(suggestion); - } - } - } else if (subCommand.equals("transfer")) { - // 为转账提供简单的补全提示 - // 由于异步操作的限制,这里只提供基本的提示 - List suggestions = Arrays.asList("目标工会名称"); - for (String suggestion : suggestions) { - if (suggestion.toLowerCase().startsWith(args[2].toLowerCase())) { - completions.add(suggestion); - } - } - } - } else if (args.length == 4) { - String subCommand = args[0].toLowerCase(); - String subSubCommand = args[1].toLowerCase(); - - if (subCommand.equals("relation") && subSubCommand.equals("create")) { - // 关系类型补全 - List relationTypes = Arrays.asList("ally", "enemy", "war", "truce", "neutral"); - for (String type : relationTypes) { - if (type.toLowerCase().startsWith(args[3].toLowerCase())) { - completions.add(type); - } - } - } else if (subCommand.equals("deposit") || subCommand.equals("withdraw") || - (subCommand.equals("transfer") && args.length == 4)) { - // 金额建议(这里只提供一些常用金额) - List amounts = Arrays.asList("100", "500", "1000", "5000", "10000"); - for (String amount : amounts) { - if (amount.startsWith(args[3])) { - completions.add(amount); - } - } - } - } - - return completions; - } - - /** - * 处理创建工会命令 - */ - private void handleCreate(Player player, String[] args) { - // 检查权限 - if (!plugin.getPermissionManager().hasPermission(player, "guild.create")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&c您没有权限执行此操作!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.usage", "&e用法: /guild create <工会名称> [标签] [描述]"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String name = args[1]; - String tag = args.length > 2 ? args[2] : null; - String description = args.length > 3 ? String.join(" ", Arrays.copyOfRange(args, 3, args.length)) : null; - - // 验证输入 - if (name.length() < 3 || name.length() > 20) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-short", "&c工会名称太短!最少需要 3 个字符。"); - player.sendMessage(ColorUtils.colorize(message.replace("{min}", "3"))); - return; - } - - if (tag != null && (tag.length() < 2 || tag.length() > 6)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.tag-too-long", "&c工会标签太长!最多只能有 6 个字符。"); - player.sendMessage(ColorUtils.colorize(message.replace("{max}", "6"))); - return; - } - - if (description != null && description.length() > 100) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.description-too-long", "&c工会描述不能超过100个字符!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查经济系统 - double creationCost = plugin.getConfigManager().getConfig("config.yml").getDouble("guild.creation-cost", 5000.0); - if (!plugin.getEconomyManager().isVaultAvailable()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.economy-not-available", "&c经济系统不可用,无法创建工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (!plugin.getEconomyManager().hasBalance(player, creationCost)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.insufficient-funds", "&c您的余额不足!创建工会需要 &e{amount}!") - .replace("{amount}", plugin.getEconomyManager().format(creationCost)); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 扣除创建费用 - if (!plugin.getEconomyManager().withdraw(player, creationCost)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.payment-failed", "&c扣除创建费用失败!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 创建工会 (异步) - guildService.createGuildAsync(name, tag, description, player.getUniqueId(), player.getName()) - .thenAcceptAsync(success -> { - if (success) { - String template = plugin.getConfigManager().getMessagesConfig().getString("create.success", "&a工会 {name} 创建成功!"); - player.sendMessage(ColorUtils.replaceWithColorIsolation(template, "{name}", name)); - - String costMessage = plugin.getConfigManager().getMessagesConfig().getString("create.cost-info", "&e创建费用: {amount}") - .replace("{amount}", plugin.getEconomyManager().format(creationCost)); - player.sendMessage(ColorUtils.colorize(costMessage)); - - String nameMessage = plugin.getConfigManager().getMessagesConfig().getString("create.name-info", "&e工会名称: {name}"); - player.sendMessage(ColorUtils.colorize(nameMessage.replace("{name}", name))); - - if (tag != null) { - String tagMessage = plugin.getConfigManager().getMessagesConfig().getString("create.tag-info", "&e工会标签: [{tag}]"); - player.sendMessage(ColorUtils.colorize(tagMessage.replace("{tag}", tag))); - } - - if (description != null) { - String descMessage = plugin.getConfigManager().getMessagesConfig().getString("create.description-info", "&e工会描述: {description}"); - player.sendMessage(ColorUtils.colorize(descMessage.replace("{description}", description))); - } - } else { - // 退款 - plugin.getEconomyManager().deposit(player, creationCost); - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("create.failed", "&c工会创建失败!可能的原因:"); - player.sendMessage(ColorUtils.colorize(failMessage)); - - String reason1 = plugin.getConfigManager().getMessagesConfig().getString("create.failed-reason-1", "&c- 工会名称或标签已存在"); - String reason2 = plugin.getConfigManager().getMessagesConfig().getString("create.failed-reason-2", "&c- 您已经加入了其他工会"); - player.sendMessage(ColorUtils.colorize(reason1)); - player.sendMessage(ColorUtils.colorize(reason2)); - } - }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); - } - - /** - * 处理工会信息命令 - */ - private void handleInfo(Player player) { - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - int memberCount = guildService.getGuildMemberCount(guild.getId()); - - String header = plugin.getConfigManager().getMessagesConfig().getString("info.title", "&6=== 工会信息 ==="); - player.sendMessage(ColorUtils.colorize(header)); - - String nameMessage = plugin.getConfigManager().getMessagesConfig().getString("info.name", "&e名称: &f{name}"); - player.sendMessage(ColorUtils.colorize(nameMessage.replace("{name}", guild.getName()))); - - if (guild.getTag() != null && !guild.getTag().isEmpty()) { - String tagMessage = plugin.getConfigManager().getMessagesConfig().getString("info.tag", "&e标签: &f{tag}"); - player.sendMessage(ColorUtils.colorize(tagMessage.replace("{tag}", guild.getTag()))); - } - if (guild.getDescription() != null && !guild.getDescription().isEmpty()) { - String descMessage = plugin.getConfigManager().getMessagesConfig().getString("info.description", "&e描述: &f{description}"); - player.sendMessage(ColorUtils.colorize(descMessage.replace("{description}", guild.getDescription()))); - } - - String leaderMessage = plugin.getConfigManager().getMessagesConfig().getString("info.leader", "&e会长: &f{leader}"); - player.sendMessage(ColorUtils.colorize(leaderMessage.replace("{leader}", guild.getLeaderName()))); - - String membersMessage = plugin.getConfigManager().getMessagesConfig().getString("info.members", "&e成员数量: &f{count}/{max}"); - player.sendMessage(ColorUtils.colorize(membersMessage - .replace("{count}", String.valueOf(memberCount)) - .replace("{max}", String.valueOf(guild.getMaxMembers())))); - - String roleMessage = plugin.getConfigManager().getMessagesConfig().getString("info.role", "&e您的角色: &f{role}"); - player.sendMessage(ColorUtils.colorize(roleMessage.replace("{role}", member.getRole().getDisplayName()))); - - // 统一使用 TimeProvider 的现实时间格式 - java.time.format.DateTimeFormatter TF = com.guild.core.time.TimeProvider.FULL_FORMATTER; - String createdMessage = plugin.getConfigManager().getMessagesConfig().getString("info.created", "&e创建时间: &f{date}"); - String createdFormatted = guild.getCreatedAt() != null ? guild.getCreatedAt().format(TF) : "未知"; - player.sendMessage(ColorUtils.colorize(createdMessage.replace("{date}", createdFormatted))); - } - - /** - * 处理工会成员命令 - */ - private void handleMembers(Player player) { - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - List members = guildService.getGuildMembers(guild.getId()); - if (members.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("members.no-members", "&c工会中没有成员!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String title = plugin.getConfigManager().getMessagesConfig().getString("members.title", "&6=== 工会成员 ==="); - player.sendMessage(ColorUtils.colorize(title)); - - for (GuildMember member : members) { - String status = ""; - Player onlinePlayer = Bukkit.getPlayer(member.getPlayerUuid()); - if (onlinePlayer != null) { - status = "&a[在线]"; - } else { - status = "&7[离线]"; - } - - String memberFormat = plugin.getConfigManager().getMessagesConfig().getString("members.member-format", "&e{role} {name} &7- {status}"); - String memberMessage = memberFormat - .replace("{role}", member.getRole().getDisplayName()) - .replace("{name}", member.getPlayerName()) - .replace("{status}", status); - player.sendMessage(ColorUtils.colorize(memberMessage)); - } - - String totalMessage = plugin.getConfigManager().getMessagesConfig().getString("members.total", "&e总计: {count} 人"); - player.sendMessage(ColorUtils.colorize(totalMessage.replace("{count}", String.valueOf(members.size())))); - } - - /** - * 处理邀请命令 - */ - private void handleInvite(Player player, String[] args) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.invite")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.no-permission", "&c您没有权限邀请玩家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.usage", "&e用法: /guild invite <玩家名称>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String targetPlayerName = args[1]; - Player targetPlayer = Bukkit.getPlayer(targetPlayerName); - if (targetPlayer == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.player-not-found", "&c玩家 {player} 不在线!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查邀请者是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查邀请权限(配置驱动) - if (!plugin.getPermissionManager().canInviteMembers(player)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.no-permission", "&c您没有权限邀请玩家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查目标玩家是否已有工会 - if (guildService.getPlayerGuild(targetPlayer.getUniqueId()) != null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.already-in-guild", "&c玩家 {player} 已经加入了其他工会!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查是否邀请自己 - if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.cannot-invite-self", "&c您不能邀请自己!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 发送邀请 (异步) - guildService.sendInvitationAsync(guild.getId(), player.getUniqueId(), player.getName(), targetPlayer.getUniqueId(), targetPlayerName) - .thenAcceptAsync(success -> { - if (success) { - String sentMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.sent", "&a已向 {player} 发送工会邀请!"); - player.sendMessage(ColorUtils.colorize(sentMessage.replace("{player}", targetPlayerName))); - - String inviteTitle = plugin.getConfigManager().getMessagesConfig().getString("invite.title", "&6=== 工会邀请 ==="); - targetPlayer.sendMessage(ColorUtils.colorize(inviteTitle)); - - String inviteMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.received", "&e{inviter} 邀请您加入工会: {guild}"); - targetPlayer.sendMessage(ColorUtils.colorize(inviteMessage - .replace("{inviter}", player.getName()) - .replace("{guild}", guild.getName()))); - - if (guild.getTag() != null && !guild.getTag().isEmpty()) { - String tagMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.guild-tag", "&e工会标签: [{tag}]"); - targetPlayer.sendMessage(ColorUtils.colorize(tagMessage.replace("{tag}", guild.getTag()))); - } - - String acceptMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.accept-command", "&e输入 &a/guild accept {inviter} &e接受邀请"); - targetPlayer.sendMessage(ColorUtils.colorize(acceptMessage.replace("{inviter}", player.getName()))); - - String declineMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.decline-command", "&e输入 &c/guild decline {inviter} &e拒绝邀请"); - targetPlayer.sendMessage(ColorUtils.colorize(declineMessage.replace("{inviter}", player.getName()))); - } else { - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.already-invited", "&c{player} 已经收到了邀请!"); - player.sendMessage(ColorUtils.colorize(failMessage.replace("{player}", targetPlayerName))); - } - }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); - } - - /** - * 处理踢出命令 - */ - private void handleKick(Player player, String[] args) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.kick")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.no-permission", "&c您没有权限踢出玩家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.usage", "&e用法: /guild kick <玩家名称>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String targetPlayerName = args[1]; - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查踢出者是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查踢人权限(配置驱动) - if (!plugin.getPermissionManager().canKickMembers(player)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.no-permission", "&c您没有权限踢出玩家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 查找目标玩家 - Player targetPlayer = Bukkit.getPlayer(targetPlayerName); - if (targetPlayer == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.player-not-found", "&c玩家 {player} 不在线!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查目标玩家是否在同一工会 - GuildMember targetMember = guildService.getGuildMember(targetPlayer.getUniqueId()); - if (targetMember == null || targetMember.getGuildId() != guild.getId()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.not-in-guild", "&c玩家 {player} 不在您的工会中!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查是否踢出自己 - if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.cannot-kick-self", "&c您不能踢出自己!使用 /guild leave 离开工会。"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查是否踢出会长 - if (targetMember.getRole() == GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.cannot-kick-leader", "&c您不能踢出工会会长!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 执行踢出操作 - boolean success = guildService.removeGuildMember(targetPlayer.getUniqueId(), player.getUniqueId()); - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.success", "&a已将 {player} 踢出工会!"); - player.sendMessage(ColorUtils.colorize(successMessage.replace("{player}", targetPlayerName))); - - String kickedMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.kicked", "&c您已被踢出工会 {guild}!"); - targetPlayer.sendMessage(ColorUtils.colorize(kickedMessage.replace("{guild}", guild.getName()))); - } else { - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.failed", "&c踢出玩家失败!"); - player.sendMessage(ColorUtils.colorize(failMessage)); - } - } - - /** - * 处理离开工会命令 - */ - private void handleLeave(Player player) { - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查玩家是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("leave.member-error", "&c工会成员信息错误!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查是否是会长 - if (member.getRole() == GuildMember.Role.LEADER) { - String message1 = plugin.getConfigManager().getMessagesConfig().getString("leave.leader-cannot-leave", "&c工会会长不能离开工会!"); - String message2 = plugin.getConfigManager().getMessagesConfig().getString("leave.use-delete", "&c如果您想解散工会,请使用 /guild delete 命令。"); - player.sendMessage(ColorUtils.colorize(message1)); - player.sendMessage(ColorUtils.colorize(message2)); - return; - } - - // 执行离开操作 - boolean success = guildService.removeGuildMember(player.getUniqueId(), player.getUniqueId()); - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("leave.success-with-guild", "&a您已成功离开工会: {guild}"); - player.sendMessage(ColorUtils.colorize(message.replace("{guild}", guild.getName()))); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("leave.failed", "&c离开工会失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - } - - /** - * 处理删除工会命令 - */ - private void handleDelete(Player player) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.delete")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("delete.no-permission", "&c您没有权限删除工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查玩家是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 删除权限已在前置节点校验并由内置权限系统控制 - - // 确认删除 - String warningMessage = plugin.getConfigManager().getMessagesConfig().getString("delete.warning", "&c警告:删除工会将永久解散工会,所有成员将被移除!"); - String confirmMessage = plugin.getConfigManager().getMessagesConfig().getString("delete.confirm-command", "&c如果您确定要删除工会,请再次输入: /guild delete confirm"); - String cancelMessage = plugin.getConfigManager().getMessagesConfig().getString("delete.cancel-command", "&c或者输入: /guild delete cancel 取消操作"); - - player.sendMessage(ColorUtils.colorize(warningMessage)); - player.sendMessage(ColorUtils.colorize(confirmMessage)); - player.sendMessage(ColorUtils.colorize(cancelMessage)); - - // TODO: 实现确认机制,避免误删 - } - - /** - * 处理设置工会家命令 - */ - private void handleSetHome(Player player) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.sethome")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&c您没有权限执行此操作!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查玩家是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查是否是会长 - if (!guildService.isGuildLeader(player.getUniqueId())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.only-leader", "&c只有工会会长才能设置工会家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 设置工会家 (异步) - guildService.setGuildHomeAsync(guild.getId(), player.getLocation(), player.getUniqueId()) - .thenAcceptAsync(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.success", "&a工会家设置成功!"); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.failed", "&c设置工会家失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); - } - - /** - * 处理传送到工会家命令 - */ - private void handleHome(Player player) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.home")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&c您没有权限执行此操作!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查玩家是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取工会家位置 (异步) - guildService.getGuildHomeAsync(guild.getId()) - .thenAcceptAsync(homeLocation -> { - if (homeLocation == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("home.not-set", "&c工会家尚未设置!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 传送到工会家 - player.teleport(homeLocation); - String message = plugin.getConfigManager().getMessagesConfig().getString("home.success", "&a已传送到工会家!"); - player.sendMessage(ColorUtils.colorize(message)); - }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); - } - - /** - * 处理提升成员命令 - */ - private void handlePromote(Player player, String[] args) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.promote")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.no-permission", "&c您没有权限提升玩家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.usage", "&e用法: /guild promote <玩家>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String targetPlayerName = args[1]; - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查提升者是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 已通过节点校验,按配置驱动,不再强制"仅会长" - - // 查找目标玩家 - Player targetPlayer = Bukkit.getPlayer(targetPlayerName); - if (targetPlayer == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.player-not-found", "&c玩家 {player} 不在线!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查目标玩家是否在同一工会 - GuildMember targetMember = guildService.getGuildMember(targetPlayer.getUniqueId()); - if (targetMember == null || targetMember.getGuildId() != guild.getId()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.not-in-guild", "&c玩家 {player} 不在您的工会中!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查是否提升自己 - if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.cannot-promote-self", "&c您不能提升自己!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查当前角色 - GuildMember.Role currentRole = targetMember.getRole(); - GuildMember.Role newRole = null; - - if (currentRole == GuildMember.Role.MEMBER) { - newRole = GuildMember.Role.OFFICER; - } else if (currentRole == GuildMember.Role.OFFICER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.already-highest", "&c玩家 {player} 已经是最高职位!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - if (newRole != null) { - // 执行提升操作 - boolean success = guildService.updateMemberRole(targetPlayer.getUniqueId(), newRole, player.getUniqueId()); - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.success", "&a已将 {player} 提升为 {role}!"); - player.sendMessage(ColorUtils.colorize(successMessage - .replace("{player}", targetPlayerName) - .replace("{role}", newRole.getDisplayName()))); - - String promotedMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.success", "&a您已被提升为 {role}!"); - targetPlayer.sendMessage(ColorUtils.colorize(promotedMessage.replace("{role}", newRole.getDisplayName()))); - } else { - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.cannot-promote", "&c无法提升该玩家!"); - player.sendMessage(ColorUtils.colorize(failMessage)); - } - } - } - - /** - * 处理降级成员命令 - */ - private void handleDemote(Player player, String[] args) { - if (!plugin.getPermissionManager().hasPermission(player, "guild.demote")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.no-permission", "&c您没有权限降级玩家!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.usage", "&e用法: /guild demote <玩家>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String targetPlayerName = args[1]; - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查降级者是否有工会 - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&c您还没有加入任何工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 已通过节点校验,按配置驱动,不再强制"仅会长" - - // 查找目标玩家 - Player targetPlayer = Bukkit.getPlayer(targetPlayerName); - if (targetPlayer == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.player-not-found", "&c玩家 {player} 不在线!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查目标玩家是否在同一工会 - GuildMember targetMember = guildService.getGuildMember(targetPlayer.getUniqueId()); - if (targetMember == null || targetMember.getGuildId() != guild.getId()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.not-in-guild", "&c玩家 {player} 不在您的工会中!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - // 检查是否降级自己 - if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.cannot-demote-self", "&c您不能降级自己!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查是否降级会长 - if (targetMember.getRole() == GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.cannot-demote-leader", "&c不能降级工会会长!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查当前角色 - GuildMember.Role currentRole = targetMember.getRole(); - GuildMember.Role newRole = null; - - if (currentRole == GuildMember.Role.OFFICER) { - newRole = GuildMember.Role.MEMBER; - } else if (currentRole == GuildMember.Role.MEMBER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.already-lowest", "&c玩家 {player} 已经是最低职位!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); - return; - } - - if (newRole != null) { - // 执行降级操作 - boolean success = guildService.updateMemberRole(targetPlayer.getUniqueId(), newRole, player.getUniqueId()); - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.success", "&a已将 {player} 降级为 {role}!"); - player.sendMessage(ColorUtils.colorize(successMessage - .replace("{player}", targetPlayerName) - .replace("{role}", newRole.getDisplayName()))); - - String demotedMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.success", "&a您已被降级为 {role}!"); - targetPlayer.sendMessage(ColorUtils.colorize(demotedMessage.replace("{role}", newRole.getDisplayName()))); - } else { - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.cannot-demote", "&c无法降级该玩家!"); - player.sendMessage(ColorUtils.colorize(failMessage)); - } - } - } - - /** - * 处理接受邀请命令 - */ - private void handleAccept(Player player, String[] args) { - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.accept-command", "&e输入 &a/guild accept {inviter} &e接受邀请"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String inviterName = args[1]; - Player inviter = Bukkit.getPlayer(inviterName); - if (inviter == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.player-not-found", "&c玩家 {player} 不在线!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", inviterName))); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 处理邀请 - boolean success = guildService.processInvitation(player.getUniqueId(), inviter.getUniqueId(), true); - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.accepted", "&a您已接受 {guild} 的邀请!"); - player.sendMessage(ColorUtils.colorize(successMessage)); - - String inviterMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.accepted", "&a{player} 已接受您的邀请!"); - inviter.sendMessage(ColorUtils.colorize(inviterMessage.replace("{player}", player.getName()))); - } else { - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.expired", "&c工会邀请已过期!"); - player.sendMessage(ColorUtils.colorize(failMessage)); - } - } - - /** - * 处理拒绝邀请命令 - */ - private void handleDecline(Player player, String[] args) { - if (args.length < 2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.decline-command", "&e输入 &c/guild decline {inviter} &e拒绝邀请"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String inviterName = args[1]; - Player inviter = Bukkit.getPlayer(inviterName); - if (inviter == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.player-not-found", "&c玩家 {player} 不在线!"); - player.sendMessage(ColorUtils.colorize(message.replace("{player}", inviterName))); - return; - } - - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&c工会服务未初始化!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 处理邀请 - boolean success = guildService.processInvitation(player.getUniqueId(), inviter.getUniqueId(), false); - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.declined", "&c您已拒绝 {guild} 的邀请!"); - player.sendMessage(ColorUtils.colorize(successMessage)); - - String inviterMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.declined", "&c{player} 已拒绝您的邀请!"); - inviter.sendMessage(ColorUtils.colorize(inviterMessage.replace("{player}", player.getName()))); - } else { - String failMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.expired", "&c工会邀请已过期!"); - player.sendMessage(ColorUtils.colorize(failMessage)); - } - } - - /** - * 处理帮助命令 - */ - private void handleHelp(Player player) { - String title = plugin.getConfigManager().getMessagesConfig().getString("help.title", "&6=== 工会系统帮助 ==="); - player.sendMessage(ColorUtils.colorize(title)); - - String mainMenu = plugin.getConfigManager().getMessagesConfig().getString("help.main-menu", "&e/guild &7- 打开工会主界面"); - player.sendMessage(ColorUtils.colorize(mainMenu)); - - String create = plugin.getConfigManager().getMessagesConfig().getString("help.create", "&e/guild create <名称> [标签] [描述] &7- 创建工会"); - player.sendMessage(ColorUtils.colorize(create)); - - String info = plugin.getConfigManager().getMessagesConfig().getString("help.info", "&e/guild info &7- 查看工会信息"); - player.sendMessage(ColorUtils.colorize(info)); - - String members = plugin.getConfigManager().getMessagesConfig().getString("help.members", "&e/guild members &7- 查看工会成员"); - player.sendMessage(ColorUtils.colorize(members)); - - String invite = plugin.getConfigManager().getMessagesConfig().getString("help.invite", "&e/guild invite <玩家> &7- 邀请玩家加入工会"); - player.sendMessage(ColorUtils.colorize(invite)); - - String kick = plugin.getConfigManager().getMessagesConfig().getString("help.kick", "&e/guild kick <玩家> &7- 踢出工会成员"); - player.sendMessage(ColorUtils.colorize(kick)); - - String promote = plugin.getConfigManager().getMessagesConfig().getString("help.promote", "&e/guild promote <玩家> &7- 提升工会成员"); - player.sendMessage(ColorUtils.colorize(promote)); - - String demote = plugin.getConfigManager().getMessagesConfig().getString("help.demote", "&e/guild demote <玩家> &7- 降级工会成员"); - player.sendMessage(ColorUtils.colorize(demote)); - - String accept = plugin.getConfigManager().getMessagesConfig().getString("help.accept", "&e/guild accept <邀请者> &7- 接受工会邀请"); - player.sendMessage(ColorUtils.colorize(accept)); - - String decline = plugin.getConfigManager().getMessagesConfig().getString("help.decline", "&e/guild decline <邀请者> &7- 拒绝工会邀请"); - player.sendMessage(ColorUtils.colorize(decline)); - - String leave = plugin.getConfigManager().getMessagesConfig().getString("help.leave", "&e/guild leave &7- 离开工会"); - player.sendMessage(ColorUtils.colorize(leave)); - - String delete = plugin.getConfigManager().getMessagesConfig().getString("help.delete", "&e/guild delete &7- 删除工会"); - player.sendMessage(ColorUtils.colorize(delete)); - - String sethome = plugin.getConfigManager().getMessagesConfig().getString("help.sethome", "&e/guild sethome &7- 设置工会家"); - player.sendMessage(ColorUtils.colorize(sethome)); - - String home = plugin.getConfigManager().getMessagesConfig().getString("help.home", "&e/guild home &7- 传送到工会家"); - player.sendMessage(ColorUtils.colorize(home)); - - String help = plugin.getConfigManager().getMessagesConfig().getString("help.help", "&e/guild help &7- 显示此帮助信息"); - player.sendMessage(ColorUtils.colorize(help)); - - String relation = "&e/guild relation &7- 管理工会关系"; - player.sendMessage(ColorUtils.colorize(relation)); - - String economy = "&e/guild economy &7- 管理工会经济"; - player.sendMessage(ColorUtils.colorize(economy)); - - String deposit = "&e/guild deposit <金额> &7- 向工会存入资金"; - player.sendMessage(ColorUtils.colorize(deposit)); - - String withdraw = "&e/guild withdraw <金额> &7- 从工会取出资金"; - player.sendMessage(ColorUtils.colorize(withdraw)); - - String transfer = "&e/guild transfer <工会> <金额> &7- 向其他工会转账"; - player.sendMessage(ColorUtils.colorize(transfer)); - - String logs = "&e/guild logs &7- 查看工会操作日志"; - player.sendMessage(ColorUtils.colorize(logs)); - } - - /** - * 处理工会关系命令 - */ - private void handleRelation(Player player, String[] args) { - // 获取玩家工会 - Guild guild = plugin.getGuildService().getPlayerGuild(player.getUniqueId()); - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.no-guild", "&c您还没有加入工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限(只有会长可以管理关系) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.only-leader", "&c只有工会会长才能管理工会关系!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (args.length == 1) { - // 显示关系管理帮助 - showRelationHelp(player); - return; - } - - switch (args[1].toLowerCase()) { - case "list": - handleRelationList(player, guild); - break; - case "create": - if (args.length < 4) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.create-usage", "&e用法: /guild relation create <目标工会> <关系类型>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - handleRelationCreate(player, guild, args[2], args[3]); - break; - case "delete": - if (args.length < 3) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.delete-usage", "&e用法: /guild relation delete <目标工会>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - handleRelationDelete(player, guild, args[2]); - break; - case "accept": - if (args.length < 3) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.accept-usage", "&e用法: /guild relation accept <目标工会>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - handleRelationAccept(player, guild, args[2]); - break; - case "reject": - if (args.length < 3) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.reject-usage", "&e用法: /guild relation reject <目标工会>"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - handleRelationReject(player, guild, args[2]); - break; - default: - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.unknown-subcommand", "&c未知的子命令!使用 /guild relation 查看帮助。"); - player.sendMessage(ColorUtils.colorize(message)); - break; - } - } - - /** - * 显示关系管理帮助 - */ - private void showRelationHelp(Player player) { - String title = plugin.getConfigManager().getMessagesConfig().getString("relation.help-title", "&6=== 工会关系管理 ==="); - player.sendMessage(ColorUtils.colorize(title)); - - String list = plugin.getConfigManager().getMessagesConfig().getString("relation.help-list", "&e/guild relation list &7- 查看所有关系"); - player.sendMessage(ColorUtils.colorize(list)); - - String create = plugin.getConfigManager().getMessagesConfig().getString("relation.help-create", "&e/guild relation create <工会> <类型> &7- 创建关系"); - player.sendMessage(ColorUtils.colorize(create)); - - String delete = plugin.getConfigManager().getMessagesConfig().getString("relation.help-delete", "&e/guild relation delete <工会> &7- 删除关系"); - player.sendMessage(ColorUtils.colorize(delete)); - - String accept = plugin.getConfigManager().getMessagesConfig().getString("relation.help-accept", "&e/guild relation accept <工会> &7- 接受关系请求"); - player.sendMessage(ColorUtils.colorize(accept)); - - String reject = plugin.getConfigManager().getMessagesConfig().getString("relation.help-reject", "&e/guild relation reject <工会> &7- 拒绝关系请求"); - player.sendMessage(ColorUtils.colorize(reject)); - - String types = plugin.getConfigManager().getMessagesConfig().getString("relation.help-types", "&7关系类型: &eally(盟友), enemy(敌对), war(开战), truce(停战), neutral(中立)"); - player.sendMessage(ColorUtils.colorize(types)); - } - - /** - * 处理关系列表 - */ - private void handleRelationList(Player player, Guild guild) { - plugin.getGuildService().getGuildRelationsAsync(guild.getId()).thenAccept(relations -> { - if (relations == null || relations.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.no-relations", "&7您的工会还没有任何关系。"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - String title = plugin.getConfigManager().getMessagesConfig().getString("relation.list-title", "&6=== 工会关系列表 ==="); - player.sendMessage(ColorUtils.colorize(title)); - - for (GuildRelation relation : relations) { - String otherGuildName = relation.getOtherGuildName(guild.getId()); - String status = relation.getStatus().name(); - String type = relation.getType().name(); - - String relationInfo = plugin.getConfigManager().getMessagesConfig().getString("relation.list-format", "&e{other_guild} &7- {type} ({status})") - .replace("{other_guild}", otherGuildName) - .replace("{type}", type) - .replace("{status}", status); - player.sendMessage(ColorUtils.colorize(relationInfo)); - } - }); - } - - /** - * 处理创建关系 - */ - private void handleRelationCreate(Player player, Guild guild, String targetGuildName, String relationTypeStr) { - // 验证关系类型 - GuildRelation.RelationType relationType; - try { - relationType = GuildRelation.RelationType.valueOf(relationTypeStr.toUpperCase()); - } catch (IllegalArgumentException e) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.invalid-type", "&c无效的关系类型!有效类型: ally, enemy, war, truce, neutral"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取目标工会 - plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { - if (targetGuild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&c目标工会 {guild} 不存在!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (targetGuild.getId() == guild.getId()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.cannot-relation-self", "&c不能与自己建立关系!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 创建关系 - plugin.getGuildService().createGuildRelationAsync(guild.getId(), targetGuild.getId(), guild.getName(), targetGuild.getName(), relationType, player.getUniqueId(), player.getName()) - .thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.create-success", "&a已向 {guild} 发送 {type} 关系请求!") - .replace("{guild}", targetGuildName) - .replace("{type}", relationType.name()); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.create-failed", "&c创建关系失败!可能已经存在关系。"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理删除关系 - */ - private void handleRelationDelete(Player player, Guild guild, String targetGuildName) { - // 获取目标工会 - plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { - if (targetGuild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&c目标工会 {guild} 不存在!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取关系然后删除 - plugin.getGuildService().getGuildRelationAsync(guild.getId(), targetGuild.getId()) - .thenCompose(relation -> { - if (relation == null) { - return CompletableFuture.completedFuture(false); - } - return plugin.getGuildService().deleteGuildRelationAsync(relation.getId()); - }) - .thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.delete-success", "&a已删除与 {guild} 的关系!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.delete-failed", "&c删除关系失败!可能关系不存在。"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理接受关系 - */ - private void handleRelationAccept(Player player, Guild guild, String targetGuildName) { - // 获取目标工会 - plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { - if (targetGuild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&c目标工会 {guild} 不存在!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取关系然后接受 - plugin.getGuildService().getGuildRelationAsync(guild.getId(), targetGuild.getId()) - .thenCompose(relation -> { - if (relation == null) { - return CompletableFuture.completedFuture(false); - } - return plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.ACTIVE); - }) - .thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.accept-success", "&a已接受 {guild} 的关系请求!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.accept-failed", "&c接受关系失败!可能没有待处理的关系请求。"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理拒绝关系 - */ - private void handleRelationReject(Player player, Guild guild, String targetGuildName) { - // 获取目标工会 - plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { - if (targetGuild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&c目标工会 {guild} 不存在!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取关系然后拒绝 - plugin.getGuildService().getGuildRelationAsync(guild.getId(), targetGuild.getId()) - .thenCompose(relation -> { - if (relation == null) { - return CompletableFuture.completedFuture(false); - } - return plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.CANCELLED); - }) - .thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.reject-success", "&c已拒绝 {guild} 的关系请求!") - .replace("{guild}", targetGuildName); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.reject-failed", "&c拒绝关系失败!可能没有待处理的关系请求。"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理工会经济命令 - */ - private void handleEconomy(Player player, String[] args) { - // 获取玩家工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&c您还没有加入工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 显示工会经济信息 - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.info", "&6工会经济信息"); - player.sendMessage(ColorUtils.colorize(message)); - - String balanceMessage = plugin.getConfigManager().getMessagesConfig().getString("economy.balance", "&7当前资金: &e{balance}") - .replace("{balance}", plugin.getEconomyManager().format(guild.getBalance())); - player.sendMessage(ColorUtils.colorize(balanceMessage)); - - String levelMessage = plugin.getConfigManager().getMessagesConfig().getString("economy.level", "&7当前等级: &e{level}") - .replace("{level}", String.valueOf(guild.getLevel())); - player.sendMessage(ColorUtils.colorize(levelMessage)); - - String maxMembersMessage = plugin.getConfigManager().getMessagesConfig().getString("economy.max-members", "&7最大成员: &e{max_members}") - .replace("{max_members}", String.valueOf(guild.getMaxMembers())); - player.sendMessage(ColorUtils.colorize(maxMembersMessage)); - }); - } - - /** - * 处理存款命令 - */ - private void handleDeposit(Player player, String[] args) { - if (args.length < 2) { - player.sendMessage(ColorUtils.colorize("&c用法: /guild deposit <金额>")); - return; - } - - double amount; - try { - amount = Double.parseDouble(args[1]); - } catch (NumberFormatException e) { - player.sendMessage(ColorUtils.colorize("&c金额格式错误!")); - return; - } - - if (amount <= 0) { - player.sendMessage(ColorUtils.colorize("&c金额必须大于0!")); - return; - } - - // 获取玩家工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&c您还没有加入工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查玩家余额 - if (!plugin.getEconomyManager().hasBalance(player, amount)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.insufficient-balance", "&c您的余额不足!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 执行存款 - plugin.getEconomyManager().withdraw(player, amount); - plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), guild.getBalance() + amount).thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.deposit-success", "&a成功向工会存款 &e{amount}!") - .replace("{amount}", plugin.getEconomyManager().format(amount)); - player.sendMessage(ColorUtils.colorize(message)); - } else { - // 退款 - plugin.getEconomyManager().deposit(player, amount); - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.deposit-failed", "&c存款失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理取款命令 - */ - private void handleWithdraw(Player player, String[] args) { - if (args.length < 2) { - player.sendMessage(ColorUtils.colorize("&c用法: /guild withdraw <金额>")); - return; - } - - double amount; - try { - amount = Double.parseDouble(args[1]); - } catch (NumberFormatException e) { - player.sendMessage(ColorUtils.colorize("&c金额格式错误!")); - return; - } - - if (amount <= 0) { - player.sendMessage(ColorUtils.colorize("&c金额必须大于0!")); - return; - } - - // 获取玩家工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&c您还没有加入工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查工会余额 - if (guild.getBalance() < amount) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.guild-insufficient-balance", "&c工会余额不足!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限(只有会长可以取款) - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.leader-only", "&c只有工会会长才能取款!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 执行取款 - plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), guild.getBalance() - amount).thenAccept(success -> { - if (success) { - plugin.getEconomyManager().deposit(player, amount); - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.withdraw-success", "&a成功从工会取款 &e{amount}!") - .replace("{amount}", plugin.getEconomyManager().format(amount)); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.withdraw-failed", "&c取款失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - }); - } - - /** - * 处理转账命令 - */ - private void handleTransfer(Player player, String[] args) { - if (args.length < 3) { - player.sendMessage(ColorUtils.colorize("&c用法: /guild transfer <工会> <金额>")); - return; - } - - String targetGuildName = args[1]; - double amount; - try { - amount = Double.parseDouble(args[2]); - } catch (NumberFormatException e) { - player.sendMessage(ColorUtils.colorize("&c金额格式错误!")); - return; - } - - if (amount <= 0) { - player.sendMessage(ColorUtils.colorize("&c金额必须大于0!")); - return; - } - - // 获取玩家工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(sourceGuild -> { - if (sourceGuild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&c您还没有加入工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限(只有会长可以转账) - plugin.getGuildService().getGuildMemberAsync(sourceGuild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.leader-only", "&c只有工会会长才能转账!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查工会余额 - if (sourceGuild.getBalance() < amount) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.guild-insufficient-balance", "&c工会余额不足!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 查找目标工会 - plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { - if (targetGuild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.target-guild-not-found", "&c目标工会不存在!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 不能转账给自己 - if (sourceGuild.getId() == targetGuild.getId()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.cannot-transfer-to-self", "&c不能转账给自己的工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 执行转账 - plugin.getGuildService().updateGuildBalanceAsync(sourceGuild.getId(), sourceGuild.getBalance() - amount).thenAccept(success1 -> { - if (success1) { - plugin.getGuildService().updateGuildBalanceAsync(targetGuild.getId(), targetGuild.getBalance() + amount).thenAccept(success2 -> { - if (success2) { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.transfer-success", "&a成功向工会 &e{target} &a转账 &e{amount}!") - .replace("{target}", targetGuildName) - .replace("{amount}", plugin.getEconomyManager().format(amount)); - player.sendMessage(ColorUtils.colorize(message)); - } else { - // 回滚 - plugin.getGuildService().updateGuildBalanceAsync(sourceGuild.getId(), sourceGuild.getBalance() + amount); - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.transfer-failed", "&c转账失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.transfer-failed", "&c转账失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - }); - }); - } - - /** - * 处理日志查看命令 - */ - private void handleLogs(Player player, String[] args) { - // 获取玩家工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-guild", "&c您还没有加入工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&c权限不足!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开工会日志GUI - plugin.getGuiManager().openGUI(player, new com.guild.gui.GuildLogsGUI(plugin, guild, player)); - }); - }); - } - - /** - * 处理占位符测试命令 - */ - private void handlePlaceholder(Player player, String[] args) { - if (!player.hasPermission("guild.admin")) { - player.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&c您没有权限执行此操作!"))); - return; - } - - if (args.length < 2) { - player.sendMessage(ColorUtils.colorize("&c用法: /guild placeholder <变量名>")); - player.sendMessage(ColorUtils.colorize("&e示例: /guild placeholder name")); - player.sendMessage(ColorUtils.colorize("&e可用变量: name, tag, description, leader, membercount, role, hasguild, isleader, isofficer")); - return; - } - - String placeholder = "%guild_" + args[1] + "%"; - String result = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, placeholder); - - player.sendMessage(ColorUtils.colorize("&6=== PlaceholderAPI 测试 ===")); - player.sendMessage(ColorUtils.colorize("&e变量: &f" + placeholder)); - player.sendMessage(ColorUtils.colorize("&e结果: &f" + result)); - player.sendMessage(ColorUtils.colorize("&6========================")); - } - - /** - * /guild time:显示现实系统时间与当前世界游戏内时间 - */ - private void handleTime(Player player) { - String title = plugin.getConfigManager().getMessagesConfig().getString("time.title", "&6=== 时间测试 ==="); - String realNow = com.guild.core.time.TimeProvider.nowString(); - // Minecraft 世界时间(白天循环 0-23999 ticks) - long ticks = player.getWorld().getTime() % 24000L; - int hours = (int)((ticks / 1000L + 6) % 24); // 0 tick 对应 06:00 - int minutes = (int)((ticks % 1000L) * 60L / 1000L); - String gameTime = String.format("%02d:%02d", hours, minutes); - String ticksStr = String.valueOf(ticks); - player.sendMessage(ColorUtils.colorize(title)); - player.sendMessage(ColorUtils.colorize("&e现实时间: &f" + realNow)); - player.sendMessage(ColorUtils.colorize("&e游戏时间: &f" + gameTime + " &7(" + ticksStr + " ticks)")); - } -} +package com.guild.commands; + +import com.guild.GuildPlugin; +import com.guild.core.utils.ColorUtils; +import com.guild.gui.MainGuildGUI; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import com.guild.models.GuildRelation; +import com.guild.services.GuildService; +import com.guild.core.utils.CompatibleScheduler; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * Główne polecenie gildii + */ +public class GuildCommand implements CommandExecutor, TabCompleter { + + private final GuildPlugin plugin; + + public GuildCommand(GuildPlugin plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.player-only", "&cTo polecenie może być wykonane tylko przez gracza!"))); + return true; + } + + if (args.length == 0) { + // Otwórz główne GUI + MainGuildGUI mainGuildGUI = new MainGuildGUI(plugin); + plugin.getGuiManager().openGUI(player, mainGuildGUI); + return true; + } + + switch (args[0].toLowerCase()) { + case "create": + handleCreate(player, args); + break; + case "info": + handleInfo(player); + break; + case "members": + handleMembers(player); + break; + case "invite": + handleInvite(player, args); + break; + case "kick": + handleKick(player, args); + break; + case "promote": + handlePromote(player, args); + break; + case "demote": + handleDemote(player, args); + break; + case "accept": + handleAccept(player, args); + break; + case "decline": + handleDecline(player, args); + break; + case "leave": + handleLeave(player); + break; + case "delete": + handleDelete(player); + break; + case "sethome": + handleSetHome(player); + break; + case "home": + handleHome(player); + break; + case "relation": + handleRelation(player, args); + break; + case "economy": + handleEconomy(player, args); + break; + case "deposit": + handleDeposit(player, args); + break; + case "withdraw": + handleWithdraw(player, args); + break; + case "transfer": + handleTransfer(player, args); + break; + case "logs": + handleLogs(player, args); + break; + case "placeholder": + handlePlaceholder(player, args); + break; + case "time": + handleTime(player); + break; + case "help": + handleHelp(player); + break; + default: + player.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.unknown-command", "&cNieznane polecenie! Użyj /guild help, aby zobaczyć pomoc."))); + break; + } + + return true; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + List completions = new ArrayList<>(); + + if (args.length == 1) { + List subCommands = Arrays.asList( + "create", "info", "members", "invite", "kick", "promote", "demote", "accept", "decline", "leave", "delete", "sethome", "home", "relation", "economy", "deposit", "withdraw", "transfer", "logs", "placeholder", "time", "help" + ); + + for (String subCommand : subCommands) { + if (subCommand.toLowerCase().startsWith(args[0].toLowerCase())) { + completions.add(subCommand); + } + } + } else if (args.length == 2) { + String subCommand = args[0].toLowerCase(); + + switch (subCommand) { + case "relation": + List relationSubCommands = Arrays.asList("list", "create", "delete", "accept", "reject"); + for (String cmd : relationSubCommands) { + if (cmd.toLowerCase().startsWith(args[1].toLowerCase())) { + completions.add(cmd); + } + } + break; + case "economy": + List economySubCommands = Arrays.asList("info", "deposit", "withdraw", "transfer"); + for (String cmd : economySubCommands) { + if (cmd.toLowerCase().startsWith(args[1].toLowerCase())) { + completions.add(cmd); + } + } + break; + case "invite": + case "kick": + case "promote": + case "demote": + // Pobierz listę graczy online + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.getName().toLowerCase().startsWith(args[1].toLowerCase())) { + completions.add(player.getName()); + } + } + break; + } + } else if (args.length == 3) { + String subCommand = args[0].toLowerCase(); + String subSubCommand = args[1].toLowerCase(); + + if (subCommand.equals("relation") && subSubCommand.equals("create")) { + // Prosta podpowiedź dla tworzenia relacji + List suggestions = Arrays.asList("nazwa_gildii_docelowej"); + for (String suggestion : suggestions) { + if (suggestion.toLowerCase().startsWith(args[2].toLowerCase())) { + completions.add(suggestion); + } + } + } else if (subCommand.equals("relation") && (subSubCommand.equals("delete") || subSubCommand.equals("accept") || subSubCommand.equals("reject"))) { + // Prosta podpowiedź dla operacji relacji + List suggestions = Arrays.asList("nazwa_gildii"); + for (String suggestion : suggestions) { + if (suggestion.toLowerCase().startsWith(args[2].toLowerCase())) { + completions.add(suggestion); + } + } + } else if (subCommand.equals("transfer")) { + // Prosta podpowiedź dla przelewu + List suggestions = Arrays.asList("nazwa_gildii_docelowej"); + for (String suggestion : suggestions) { + if (suggestion.toLowerCase().startsWith(args[2].toLowerCase())) { + completions.add(suggestion); + } + } + } + } else if (args.length == 4) { + String subCommand = args[0].toLowerCase(); + String subSubCommand = args[1].toLowerCase(); + + if (subCommand.equals("relation") && subSubCommand.equals("create")) { + // Podpowiedź typu relacji + List relationTypes = Arrays.asList("ally", "enemy", "war", "truce", "neutral"); + for (String type : relationTypes) { + if (type.toLowerCase().startsWith(args[3].toLowerCase())) { + completions.add(type); + } + } + } else if (subCommand.equals("deposit") || subCommand.equals("withdraw") || + (subCommand.equals("transfer") && args.length == 4)) { + // Sugestie kwot (tylko kilka popularnych) + List amounts = Arrays.asList("100", "500", "1000", "5000", "10000"); + for (String amount : amounts) { + if (amount.startsWith(args[3])) { + completions.add(amount); + } + } + } + } + + return completions; + } + + /** + * Obsługa polecenia tworzenia gildii + */ + private void handleCreate(Player player, String[] args) { + // Sprawdź uprawnienia + if (!plugin.getPermissionManager().hasPermission(player, "guild.create")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&cNie masz uprawnień do wykonania tej operacji!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.usage", "&eUżycie: /guild create [tag] [opis]"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String name = args[1]; + String tag = args.length > 2 ? args[2] : null; + String description = args.length > 3 ? String.join(" ", Arrays.copyOfRange(args, 3, args.length)) : null; + + // Walidacja danych wejściowych + if (name.length() < 3 || name.length() > 20) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-short", "&cNazwa gildii jest za krótka! Wymagane minimum 3 znaki."); + player.sendMessage(ColorUtils.colorize(message.replace("{min}", "3"))); + return; + } + + if (tag != null && (tag.length() < 2 || tag.length() > 6)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.tag-too-long", "&cTag gildii jest za długi! Maksymalnie 6 znaków."); + player.sendMessage(ColorUtils.colorize(message.replace("{max}", "6"))); + return; + } + + if (description != null && description.length() > 100) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.description-too-long", "&cOpis gildii nie może przekraczać 100 znaków!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź system ekonomii + double creationCost = plugin.getConfigManager().getConfig("config.yml").getDouble("guild.creation-cost", 5000.0); + if (!plugin.getEconomyManager().isVaultAvailable()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.economy-not-available", "&cSystem ekonomii jest niedostępny, nie można utworzyć gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (!plugin.getEconomyManager().hasBalance(player, creationCost)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.insufficient-funds", "&cNiewystarczające środki! Utworzenie gildii kosztuje &e{amount}!") + .replace("{amount}", plugin.getEconomyManager().format(creationCost)); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz opłatę za utworzenie + if (!plugin.getEconomyManager().withdraw(player, creationCost)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.payment-failed", "&cNie udało się pobrać opłaty za utworzenie!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Utwórz gildię (asynchronicznie) + guildService.createGuildAsync(name, tag, description, player.getUniqueId(), player.getName()) + .thenAcceptAsync(success -> { + if (success) { + String template = plugin.getConfigManager().getMessagesConfig().getString("create.success", "&aGildia {name} została utworzona pomyślnie!"); + player.sendMessage(ColorUtils.replaceWithColorIsolation(template, "{name}", name)); + + String costMessage = plugin.getConfigManager().getMessagesConfig().getString("create.cost-info", "&eKoszt utworzenia: {amount}") + .replace("{amount}", plugin.getEconomyManager().format(creationCost)); + player.sendMessage(ColorUtils.colorize(costMessage)); + + String nameMessage = plugin.getConfigManager().getMessagesConfig().getString("create.name-info", "&eNazwa gildii: {name}"); + player.sendMessage(ColorUtils.colorize(nameMessage.replace("{name}", name))); + + if (tag != null) { + String tagMessage = plugin.getConfigManager().getMessagesConfig().getString("create.tag-info", "&eTag gildii: [{tag}]"); + player.sendMessage(ColorUtils.colorize(tagMessage.replace("{tag}", tag))); + } + + if (description != null) { + String descMessage = plugin.getConfigManager().getMessagesConfig().getString("create.description-info", "&eOpis gildii: {description}"); + player.sendMessage(ColorUtils.colorize(descMessage.replace("{description}", description))); + } + } else { + // Zwrot pieniędzy + plugin.getEconomyManager().deposit(player, creationCost); + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("create.failed", "&cTworzenie gildii nie powiodło się! Możliwe przyczyny:"); + player.sendMessage(ColorUtils.colorize(failMessage)); + + String reason1 = plugin.getConfigManager().getMessagesConfig().getString("create.failed-reason-1", "&c- Nazwa gildii lub tag już istnieje"); + String reason2 = plugin.getConfigManager().getMessagesConfig().getString("create.failed-reason-2", "&c- Jesteś już członkiem innej gildii"); + player.sendMessage(ColorUtils.colorize(reason1)); + player.sendMessage(ColorUtils.colorize(reason2)); + } + }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); + } + + /** + * Obsługa polecenia informacji o gildii + */ + private void handleInfo(Player player) { + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + int memberCount = guildService.getGuildMemberCount(guild.getId()); + + String header = plugin.getConfigManager().getMessagesConfig().getString("info.title", "&6=== Informacje o Gildii ==="); + player.sendMessage(ColorUtils.colorize(header)); + + String nameMessage = plugin.getConfigManager().getMessagesConfig().getString("info.name", "&eNazwa: &f{name}"); + player.sendMessage(ColorUtils.colorize(nameMessage.replace("{name}", guild.getName()))); + + if (guild.getTag() != null && !guild.getTag().isEmpty()) { + String tagMessage = plugin.getConfigManager().getMessagesConfig().getString("info.tag", "&eTag: &f{tag}"); + player.sendMessage(ColorUtils.colorize(tagMessage.replace("{tag}", guild.getTag()))); + } + if (guild.getDescription() != null && !guild.getDescription().isEmpty()) { + String descMessage = plugin.getConfigManager().getMessagesConfig().getString("info.description", "&eOpis: &f{description}"); + player.sendMessage(ColorUtils.colorize(descMessage.replace("{description}", guild.getDescription()))); + } + + String leaderMessage = plugin.getConfigManager().getMessagesConfig().getString("info.leader", "&eLider: &f{leader}"); + player.sendMessage(ColorUtils.colorize(leaderMessage.replace("{leader}", guild.getLeaderName()))); + + String membersMessage = plugin.getConfigManager().getMessagesConfig().getString("info.members", "&eLiczba członków: &f{count}/{max}"); + player.sendMessage(ColorUtils.colorize(membersMessage + .replace("{count}", String.valueOf(memberCount)) + .replace("{max}", String.valueOf(guild.getMaxMembers())))); + + String roleMessage = plugin.getConfigManager().getMessagesConfig().getString("info.role", "&eTwoja rola: &f{role}"); + player.sendMessage(ColorUtils.colorize(roleMessage.replace("{role}", member.getRole().getDisplayName()))); + + // Ujednolicenie formatu czasu TimeProvider + java.time.format.DateTimeFormatter TF = com.guild.core.time.TimeProvider.FULL_FORMATTER; + String createdMessage = plugin.getConfigManager().getMessagesConfig().getString("info.created", "&eData utworzenia: &f{date}"); + String createdFormatted = guild.getCreatedAt() != null ? guild.getCreatedAt().format(TF) : "Nieznana"; + player.sendMessage(ColorUtils.colorize(createdMessage.replace("{date}", createdFormatted))); + } + + /** + * Obsługa polecenia członków gildii + */ + private void handleMembers(Player player) { + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + List members = guildService.getGuildMembers(guild.getId()); + if (members.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("members.no-members", "&cBrak członków w gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String title = plugin.getConfigManager().getMessagesConfig().getString("members.title", "&6=== Członkowie Gildii ==="); + player.sendMessage(ColorUtils.colorize(title)); + + for (GuildMember member : members) { + String status = ""; + Player onlinePlayer = Bukkit.getPlayer(member.getPlayerUuid()); + if (onlinePlayer != null) { + status = "&a[Online]"; + } else { + status = "&7[Offline]"; + } + + String memberFormat = plugin.getConfigManager().getMessagesConfig().getString("members.member-format", "&e{role} {name} &7- {status}"); + String memberMessage = memberFormat + .replace("{role}", member.getRole().getDisplayName()) + .replace("{name}", member.getPlayerName()) + .replace("{status}", status); + player.sendMessage(ColorUtils.colorize(memberMessage)); + } + + String totalMessage = plugin.getConfigManager().getMessagesConfig().getString("members.total", "&eŁącznie: {count} osób"); + player.sendMessage(ColorUtils.colorize(totalMessage.replace("{count}", String.valueOf(members.size())))); + } + + /** + * Obsługa polecenia zaproszenia + */ + private void handleInvite(Player player, String[] args) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.invite")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.no-permission", "&cNie masz uprawnień do zapraszania graczy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.usage", "&eUżycie: /guild invite "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String targetPlayerName = args[1]; + Player targetPlayer = Bukkit.getPlayer(targetPlayerName); + if (targetPlayer == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.player-not-found", "&cGracz {player} nie jest online!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy zapraszający ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia zapraszania (sterowane konfiguracją) + if (!plugin.getPermissionManager().canInviteMembers(player)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.no-permission", "&cNie masz uprawnień do zapraszania graczy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy cel ma gildię + if (guildService.getPlayerGuild(targetPlayer.getUniqueId()) != null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.already-in-guild", "&cGracz {player} jest już w innej gildii!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy zaprasza samego siebie + if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.cannot-invite-self", "&cNie możesz zaprosić samego siebie!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wyślij zaproszenie (asynchronicznie) + guildService.sendInvitationAsync(guild.getId(), player.getUniqueId(), player.getName(), targetPlayer.getUniqueId(), targetPlayerName) + .thenAcceptAsync(success -> { + if (success) { + String sentMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.sent", "&aWysłano zaproszenie do gildii dla {player}!"); + player.sendMessage(ColorUtils.colorize(sentMessage.replace("{player}", targetPlayerName))); + + String inviteTitle = plugin.getConfigManager().getMessagesConfig().getString("invite.title", "&6=== Zaproszenie do Gildii ==="); + targetPlayer.sendMessage(ColorUtils.colorize(inviteTitle)); + + String inviteMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.received", "&e{inviter} zaprasza cię do gildii: {guild}"); + targetPlayer.sendMessage(ColorUtils.colorize(inviteMessage + .replace("{inviter}", player.getName()) + .replace("{guild}", guild.getName()))); + + if (guild.getTag() != null && !guild.getTag().isEmpty()) { + String tagMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.guild-tag", "&eTag gildii: [{tag}]"); + targetPlayer.sendMessage(ColorUtils.colorize(tagMessage.replace("{tag}", guild.getTag()))); + } + + String acceptMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.accept-command", "&eWpisz &a/guild accept {inviter} &eaby zaakceptować"); + targetPlayer.sendMessage(ColorUtils.colorize(acceptMessage.replace("{inviter}", player.getName()))); + + String declineMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.decline-command", "&eWpisz &c/guild decline {inviter} &eaby odrzucić"); + targetPlayer.sendMessage(ColorUtils.colorize(declineMessage.replace("{inviter}", player.getName()))); + } else { + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.already-invited", "&c{player} już otrzymał zaproszenie!"); + player.sendMessage(ColorUtils.colorize(failMessage.replace("{player}", targetPlayerName))); + } + }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); + } + + /** + * Obsługa polecenia wyrzucania + */ + private void handleKick(Player player, String[] args) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.kick")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.no-permission", "&cNie masz uprawnień do wyrzucania graczy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.usage", "&eUżycie: /guild kick "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String targetPlayerName = args[1]; + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy wyrzucający ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia wyrzucania (sterowane konfiguracją) + if (!plugin.getPermissionManager().canKickMembers(player)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.no-permission", "&cNie masz uprawnień do wyrzucania graczy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Znajdź gracza docelowego + Player targetPlayer = Bukkit.getPlayer(targetPlayerName); + if (targetPlayer == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.player-not-found", "&cGracz {player} nie jest online!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy cel jest w tej samej gildii + GuildMember targetMember = guildService.getGuildMember(targetPlayer.getUniqueId()); + if (targetMember == null || targetMember.getGuildId() != guild.getId()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.not-in-guild", "&cGracz {player} nie jest w twojej gildii!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy wyrzuca samego siebie + if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.cannot-kick-self", "&cNie możesz wyrzucić samego siebie! Użyj /guild leave aby opuścić gildię."); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy wyrzuca lidera + if (targetMember.getRole() == GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.cannot-kick-leader", "&cNie można wyrzucić lidera gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wykonaj wyrzucenie + boolean success = guildService.removeGuildMember(targetPlayer.getUniqueId(), player.getUniqueId()); + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.success", "&aWyrzucono {player} z gildii!"); + player.sendMessage(ColorUtils.colorize(successMessage.replace("{player}", targetPlayerName))); + + String kickedMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.kicked", "&cZostałeś wyrzucony z gildii {guild}!"); + targetPlayer.sendMessage(ColorUtils.colorize(kickedMessage.replace("{guild}", guild.getName()))); + } else { + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.failed", "&cWyrzucenie gracza nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(failMessage)); + } + } + + /** + * Obsługa polecenia opuszczenia gildii + */ + private void handleLeave(Player player) { + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy gracz ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("leave.member-error", "&cBłąd informacji o członku gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy jest liderem + if (member.getRole() == GuildMember.Role.LEADER) { + String message1 = plugin.getConfigManager().getMessagesConfig().getString("leave.leader-cannot-leave", "&cLider gildii nie może opuścić gildii!"); + String message2 = plugin.getConfigManager().getMessagesConfig().getString("leave.use-delete", "&cJeśli chcesz rozwiązać gildię, użyj polecenia /guild delete."); + player.sendMessage(ColorUtils.colorize(message1)); + player.sendMessage(ColorUtils.colorize(message2)); + return; + } + + // Wykonaj opuszczenie + boolean success = guildService.removeGuildMember(player.getUniqueId(), player.getUniqueId()); + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("leave.success-with-guild", "&aPomyślnie opuściłeś gildię: {guild}"); + player.sendMessage(ColorUtils.colorize(message.replace("{guild}", guild.getName()))); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("leave.failed", "&cOpuszczenie gildii nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + } + + /** + * Obsługa polecenia usunięcia gildii + */ + private void handleDelete(Player player) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.delete")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("delete.no-permission", "&cNie masz uprawnień do usuwania gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy gracz ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Uprawnienia usunięcia zostały sprawdzone wcześniej i są kontrolowane przez system uprawnień + + // Potwierdź usunięcie + String warningMessage = plugin.getConfigManager().getMessagesConfig().getString("delete.warning", "&cOstrzeżenie: Usunięcie gildii trwale ją rozwiąże, a wszyscy członkowie zostaną usunięci!"); + String confirmMessage = plugin.getConfigManager().getMessagesConfig().getString("delete.confirm-command", "&cJeśli jesteś pewien, że chcesz usunąć gildię, wpisz ponownie: /guild delete confirm"); + String cancelMessage = plugin.getConfigManager().getMessagesConfig().getString("delete.cancel-command", "&cLub wpisz: /guild delete cancel aby anulować operację"); + + player.sendMessage(ColorUtils.colorize(warningMessage)); + player.sendMessage(ColorUtils.colorize(confirmMessage)); + player.sendMessage(ColorUtils.colorize(cancelMessage)); + + // TODO: Zaimplementuj mechanizm potwierdzenia, aby uniknąć przypadkowego usunięcia + } + + /** + * Obsługa polecenia ustawienia domu gildii + */ + private void handleSetHome(Player player) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.sethome")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&cNie masz uprawnień do wykonania tej operacji!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy gracz ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy jest liderem + if (!guildService.isGuildLeader(player.getUniqueId())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.only-leader", "&cTylko lider gildii może ustawić dom gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Ustaw dom gildii (asynchronicznie) + guildService.setGuildHomeAsync(guild.getId(), player.getLocation(), player.getUniqueId()) + .thenAcceptAsync(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.success", "&aDom gildii został ustawiony pomyślnie!"); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.failed", "&cUstawianie domu gildii nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); + } + + /** + * Obsługa polecenia teleportacji do domu gildii + */ + private void handleHome(Player player) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.home")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&cNie masz uprawnień do wykonania tej operacji!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy gracz ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz lokalizację domu gildii (asynchronicznie) + guildService.getGuildHomeAsync(guild.getId()) + .thenAcceptAsync(homeLocation -> { + if (homeLocation == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("home.not-set", "&cDom gildii nie został jeszcze ustawiony!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Teleportuj do domu gildii + player.teleport(homeLocation); + String message = plugin.getConfigManager().getMessagesConfig().getString("home.success", "&aTeleportowano do domu gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + }, runnable -> CompatibleScheduler.runTask(plugin, runnable)); + } + + /** + * Obsługa polecenia awansu + */ + private void handlePromote(Player player, String[] args) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.promote")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.no-permission", "&cNie masz uprawnień do awansowania graczy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.usage", "&eUżycie: /guild promote "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String targetPlayerName = args[1]; + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy awansujący ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Przeszło walidację węzła, konfiguracja sterowana, nie wymusza już "tylko lidera" + + // Znajdź gracza docelowego + Player targetPlayer = Bukkit.getPlayer(targetPlayerName); + if (targetPlayer == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.player-not-found", "&cGracz {player} nie jest online!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy cel jest w tej samej gildii + GuildMember targetMember = guildService.getGuildMember(targetPlayer.getUniqueId()); + if (targetMember == null || targetMember.getGuildId() != guild.getId()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.not-in-guild", "&cGracz {player} nie jest w twojej gildii!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy awansuje samego siebie + if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.cannot-promote-self", "&cNie możesz awansować samego siebie!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź obecną rolę + GuildMember.Role currentRole = targetMember.getRole(); + GuildMember.Role newRole = null; + + if (currentRole == GuildMember.Role.MEMBER) { + newRole = GuildMember.Role.OFFICER; + } else if (currentRole == GuildMember.Role.OFFICER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.already-highest", "&cGracz {player} ma już najwyższą rangę!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + if (newRole != null) { + // Wykonaj awans + boolean success = guildService.updateMemberRole(targetPlayer.getUniqueId(), newRole, player.getUniqueId()); + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.success", "&aAwansowano {player} na {role}!"); + player.sendMessage(ColorUtils.colorize(successMessage + .replace("{player}", targetPlayerName) + .replace("{role}", newRole.getDisplayName()))); + + String promotedMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.success", "&aZostałeś awansowany na {role}!"); + targetPlayer.sendMessage(ColorUtils.colorize(promotedMessage.replace("{role}", newRole.getDisplayName()))); + } else { + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.promote.cannot-promote", "&cNie można awansować tego gracza!"); + player.sendMessage(ColorUtils.colorize(failMessage)); + } + } + } + + /** + * Obsługa polecenia degradacji + */ + private void handleDemote(Player player, String[] args) { + if (!plugin.getPermissionManager().hasPermission(player, "guild.demote")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.no-permission", "&cNie masz uprawnień do degradowania graczy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.usage", "&eUżycie: /guild demote "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String targetPlayerName = args[1]; + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy degradujący ma gildię + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("info.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Przeszło walidację węzła, konfiguracja sterowana, nie wymusza już "tylko lidera" + + // Znajdź gracza docelowego + Player targetPlayer = Bukkit.getPlayer(targetPlayerName); + if (targetPlayer == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.player-not-found", "&cGracz {player} nie jest online!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy cel jest w tej samej gildii + GuildMember targetMember = guildService.getGuildMember(targetPlayer.getUniqueId()); + if (targetMember == null || targetMember.getGuildId() != guild.getId()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.not-in-guild", "&cGracz {player} nie jest w twojej gildii!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + // Sprawdź, czy degraduje samego siebie + if (targetPlayer.getUniqueId().equals(player.getUniqueId())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.cannot-demote-self", "&cNie możesz zdegradować samego siebie!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź, czy degraduje lidera + if (targetMember.getRole() == GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.cannot-demote-leader", "&cNie można zdegradować lidera gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź obecną rolę + GuildMember.Role currentRole = targetMember.getRole(); + GuildMember.Role newRole = null; + + if (currentRole == GuildMember.Role.OFFICER) { + newRole = GuildMember.Role.MEMBER; + } else if (currentRole == GuildMember.Role.MEMBER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.already-lowest", "&cGracz {player} ma już najniższą rangę!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", targetPlayerName))); + return; + } + + if (newRole != null) { + // Wykonaj degradację + boolean success = guildService.updateMemberRole(targetPlayer.getUniqueId(), newRole, player.getUniqueId()); + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.success", "&aZdegradowano {player} na {role}!"); + player.sendMessage(ColorUtils.colorize(successMessage + .replace("{player}", targetPlayerName) + .replace("{role}", newRole.getDisplayName()))); + + String demotedMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.success", "&aZostałeś zdegradowany na {role}!"); + targetPlayer.sendMessage(ColorUtils.colorize(demotedMessage.replace("{role}", newRole.getDisplayName()))); + } else { + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("permissions.demote.cannot-demote", "&cNie można zdegradować tego gracza!"); + player.sendMessage(ColorUtils.colorize(failMessage)); + } + } + } + + /** + * Obsługa polecenia akceptacji zaproszenia + */ + private void handleAccept(Player player, String[] args) { + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.accept-command", "&eWpisz &a/guild accept {inviter} &eaby zaakceptować"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String inviterName = args[1]; + Player inviter = Bukkit.getPlayer(inviterName); + if (inviter == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.player-not-found", "&cGracz {player} nie jest online!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", inviterName))); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Przetwórz zaproszenie + boolean success = guildService.processInvitation(player.getUniqueId(), inviter.getUniqueId(), true); + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.accepted", "&aZaakceptowałeś zaproszenie do gildii {guild}!"); + player.sendMessage(ColorUtils.colorize(successMessage)); + + String inviterMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.accepted", "&a{player} zaakceptował twoje zaproszenie!"); + inviter.sendMessage(ColorUtils.colorize(inviterMessage.replace("{player}", player.getName()))); + } else { + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.expired", "&cZaproszenie do gildii wygasło!"); + player.sendMessage(ColorUtils.colorize(failMessage)); + } + } + + /** + * Obsługa polecenia odrzucenia zaproszenia + */ + private void handleDecline(Player player, String[] args) { + if (args.length < 2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.decline-command", "&eWpisz &c/guild decline {inviter} &eaby odrzucić"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String inviterName = args[1]; + Player inviter = Bukkit.getPlayer(inviterName); + if (inviter == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.player-not-found", "&cGracz {player} nie jest online!"); + player.sendMessage(ColorUtils.colorize(message.replace("{player}", inviterName))); + return; + } + + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.service-error", "&cUsługa gildii nie została zainicjalizowana!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Przetwórz zaproszenie + boolean success = guildService.processInvitation(player.getUniqueId(), inviter.getUniqueId(), false); + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.declined", "&cOdrzuciłeś zaproszenie do gildii {guild}!"); + player.sendMessage(ColorUtils.colorize(successMessage)); + + String inviterMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.declined", "&c{player} odrzucił twoje zaproszenie!"); + inviter.sendMessage(ColorUtils.colorize(inviterMessage.replace("{player}", player.getName()))); + } else { + String failMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.expired", "&cZaproszenie do gildii wygasło!"); + player.sendMessage(ColorUtils.colorize(failMessage)); + } + } + + /** + * Obsługa polecenia pomocy + */ + private void handleHelp(Player player) { + String title = plugin.getConfigManager().getMessagesConfig().getString("help.title", "&6=== Pomoc Systemu Gildii ==="); + player.sendMessage(ColorUtils.colorize(title)); + + String mainMenu = plugin.getConfigManager().getMessagesConfig().getString("help.main-menu", "&e/guild &7- Otwórz główne menu gildii"); + player.sendMessage(ColorUtils.colorize(mainMenu)); + + String create = plugin.getConfigManager().getMessagesConfig().getString("help.create", "&e/guild create [tag] [opis] &7- Utwórz gildię"); + player.sendMessage(ColorUtils.colorize(create)); + + String info = plugin.getConfigManager().getMessagesConfig().getString("help.info", "&e/guild info &7- Zobacz informacje o gildii"); + player.sendMessage(ColorUtils.colorize(info)); + + String members = plugin.getConfigManager().getMessagesConfig().getString("help.members", "&e/guild members &7- Zobacz członków gildii"); + player.sendMessage(ColorUtils.colorize(members)); + + String invite = plugin.getConfigManager().getMessagesConfig().getString("help.invite", "&e/guild invite &7- Zaproś gracza do gildii"); + player.sendMessage(ColorUtils.colorize(invite)); + + String kick = plugin.getConfigManager().getMessagesConfig().getString("help.kick", "&e/guild kick &7- Wyrzuć członka z gildii"); + player.sendMessage(ColorUtils.colorize(kick)); + + String promote = plugin.getConfigManager().getMessagesConfig().getString("help.promote", "&e/guild promote &7- Awansuj członka gildii"); + player.sendMessage(ColorUtils.colorize(promote)); + + String demote = plugin.getConfigManager().getMessagesConfig().getString("help.demote", "&e/guild demote &7- Zdegraduj członka gildii"); + player.sendMessage(ColorUtils.colorize(demote)); + + String accept = plugin.getConfigManager().getMessagesConfig().getString("help.accept", "&e/guild accept &7- Zaakceptuj zaproszenie do gildii"); + player.sendMessage(ColorUtils.colorize(accept)); + + String decline = plugin.getConfigManager().getMessagesConfig().getString("help.decline", "&e/guild decline &7- Odrzuć zaproszenie do gildii"); + player.sendMessage(ColorUtils.colorize(decline)); + + String leave = plugin.getConfigManager().getMessagesConfig().getString("help.leave", "&e/guild leave &7- Opuść gildię"); + player.sendMessage(ColorUtils.colorize(leave)); + + String delete = plugin.getConfigManager().getMessagesConfig().getString("help.delete", "&e/guild delete &7- Usuń gildię"); + player.sendMessage(ColorUtils.colorize(delete)); + + String sethome = plugin.getConfigManager().getMessagesConfig().getString("help.sethome", "&e/guild sethome &7- Ustaw dom gildii"); + player.sendMessage(ColorUtils.colorize(sethome)); + + String home = plugin.getConfigManager().getMessagesConfig().getString("help.home", "&e/guild home &7- Teleportuj do domu gildii"); + player.sendMessage(ColorUtils.colorize(home)); + + String help = plugin.getConfigManager().getMessagesConfig().getString("help.help", "&e/guild help &7- Pokaż tę pomoc"); + player.sendMessage(ColorUtils.colorize(help)); + + String relation = "&e/guild relation &7- Zarządzaj relacjami gildii"; + player.sendMessage(ColorUtils.colorize(relation)); + + String economy = "&e/guild economy &7- Zarządzaj ekonomią gildii"; + player.sendMessage(ColorUtils.colorize(economy)); + + String deposit = "&e/guild deposit &7- Wpłać środki do gildii"; + player.sendMessage(ColorUtils.colorize(deposit)); + + String withdraw = "&e/guild withdraw &7- Wypłać środki z gildii"; + player.sendMessage(ColorUtils.colorize(withdraw)); + + String transfer = "&e/guild transfer &7- Przelej środki do innej gildii"; + player.sendMessage(ColorUtils.colorize(transfer)); + + String logs = "&e/guild logs &7- Zobacz logi gildii"; + player.sendMessage(ColorUtils.colorize(logs)); + } + + /** + * Obsługa polecenia relacji + */ + private void handleRelation(Player player, String[] args) { + // Pobierz gildię gracza + Guild guild = plugin.getGuildService().getPlayerGuild(player.getUniqueId()); + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia (tylko lider może zarządzać relacjami) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.only-leader", "&cTylko lider gildii może zarządzać relacjami!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (args.length == 1) { + // Pokaż pomoc zarządzania relacjami + showRelationHelp(player); + return; + } + + switch (args[1].toLowerCase()) { + case "list": + handleRelationList(player, guild); + break; + case "create": + if (args.length < 4) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.create-usage", "&eUżycie: /guild relation create "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + handleRelationCreate(player, guild, args[2], args[3]); + break; + case "delete": + if (args.length < 3) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.delete-usage", "&eUżycie: /guild relation delete "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + handleRelationDelete(player, guild, args[2]); + break; + case "accept": + if (args.length < 3) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.accept-usage", "&eUżycie: /guild relation accept "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + handleRelationAccept(player, guild, args[2]); + break; + case "reject": + if (args.length < 3) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.reject-usage", "&eUżycie: /guild relation reject "); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + handleRelationReject(player, guild, args[2]); + break; + default: + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.unknown-subcommand", "&cNieznane podpolecenie! Użyj /guild relation aby zobaczyć pomoc."); + player.sendMessage(ColorUtils.colorize(message)); + break; + } + } + + /** + * Pokaż pomoc zarządzania relacjami + */ + private void showRelationHelp(Player player) { + String title = plugin.getConfigManager().getMessagesConfig().getString("relation.help-title", "&6=== Zarządzanie Relacjami Gildii ==="); + player.sendMessage(ColorUtils.colorize(title)); + + String list = plugin.getConfigManager().getMessagesConfig().getString("relation.help-list", "&e/guild relation list &7- Zobacz wszystkie relacje"); + player.sendMessage(ColorUtils.colorize(list)); + + String create = plugin.getConfigManager().getMessagesConfig().getString("relation.help-create", "&e/guild relation create &7- Utwórz relację"); + player.sendMessage(ColorUtils.colorize(create)); + + String delete = plugin.getConfigManager().getMessagesConfig().getString("relation.help-delete", "&e/guild relation delete &7- Usuń relację"); + player.sendMessage(ColorUtils.colorize(delete)); + + String accept = plugin.getConfigManager().getMessagesConfig().getString("relation.help-accept", "&e/guild relation accept &7- Zaakceptuj prośbę o relację"); + player.sendMessage(ColorUtils.colorize(accept)); + + String reject = plugin.getConfigManager().getMessagesConfig().getString("relation.help-reject", "&e/guild relation reject &7- Odrzuć prośbę o relację"); + player.sendMessage(ColorUtils.colorize(reject)); + + String types = plugin.getConfigManager().getMessagesConfig().getString("relation.help-types", "&7Typy relacji: &eally(sojusznik), enemy(wróg), war(wojna), truce(rozejm), neutral(neutralny)"); + player.sendMessage(ColorUtils.colorize(types)); + } + + /** + * Obsługa listy relacji + */ + private void handleRelationList(Player player, Guild guild) { + plugin.getGuildService().getGuildRelationsAsync(guild.getId()).thenAccept(relations -> { + if (relations == null || relations.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.no-relations", "&7Twoja gildia nie ma jeszcze żadnych relacji."); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + String title = plugin.getConfigManager().getMessagesConfig().getString("relation.list-title", "&6=== Lista Relacji Gildii ==="); + player.sendMessage(ColorUtils.colorize(title)); + + for (GuildRelation relation : relations) { + String otherGuildName = relation.getOtherGuildName(guild.getId()); + String status = relation.getStatus().name(); + String type = relation.getType().name(); + + String relationInfo = plugin.getConfigManager().getMessagesConfig().getString("relation.list-format", "&e{other_guild} &7- {type} ({status})") + .replace("{other_guild}", otherGuildName) + .replace("{type}", type) + .replace("{status}", status); + player.sendMessage(ColorUtils.colorize(relationInfo)); + } + }); + } + + /** + * Obsługa tworzenia relacji + */ + private void handleRelationCreate(Player player, Guild guild, String targetGuildName, String relationTypeStr) { + // Walidacja typu relacji + GuildRelation.RelationType relationType; + try { + relationType = GuildRelation.RelationType.valueOf(relationTypeStr.toUpperCase()); + } catch (IllegalArgumentException e) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.invalid-type", "&cNieprawidłowy typ relacji! Prawidłowe typy: ally, enemy, war, truce, neutral"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz gildię docelową + plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { + if (targetGuild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&cGildia docelowa {guild} nie istnieje!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (targetGuild.getId() == guild.getId()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.cannot-relation-self", "&cNie można nawiązać relacji z samym sobą!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Utwórz relację + plugin.getGuildService().createGuildRelationAsync(guild.getId(), targetGuild.getId(), guild.getName(), targetGuild.getName(), relationType, player.getUniqueId(), player.getName()) + .thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.create-success", "&aWysłano prośbę o relację {type} do {guild}!") + .replace("{guild}", targetGuildName) + .replace("{type}", relationType.name()); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.create-failed", "&cTworzenie relacji nie powiodło się! Relacja może już istnieć."); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa usuwania relacji + */ + private void handleRelationDelete(Player player, Guild guild, String targetGuildName) { + // Pobierz gildię docelową + plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { + if (targetGuild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&cGildia docelowa {guild} nie istnieje!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz relację, a następnie usuń + plugin.getGuildService().getGuildRelationAsync(guild.getId(), targetGuild.getId()) + .thenCompose(relation -> { + if (relation == null) { + return CompletableFuture.completedFuture(false); + } + return plugin.getGuildService().deleteGuildRelationAsync(relation.getId()); + }) + .thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.delete-success", "&aUsunięto relację z {guild}!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.delete-failed", "&cUsunięcie relacji nie powiodło się! Relacja może nie istnieć."); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa akceptacji relacji + */ + private void handleRelationAccept(Player player, Guild guild, String targetGuildName) { + // Pobierz gildię docelową + plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { + if (targetGuild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&cGildia docelowa {guild} nie istnieje!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz relację, a następnie zaakceptuj + plugin.getGuildService().getGuildRelationAsync(guild.getId(), targetGuild.getId()) + .thenCompose(relation -> { + if (relation == null) { + return CompletableFuture.completedFuture(false); + } + return plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.ACTIVE); + }) + .thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.accept-success", "&aZaakceptowano prośbę o relację od {guild}!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.accept-failed", "&cAkceptacja relacji nie powiodła się! Może nie być oczekującej prośby."); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa odrzucenia relacji + */ + private void handleRelationReject(Player player, Guild guild, String targetGuildName) { + // Pobierz gildię docelową + plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { + if (targetGuild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.target-not-found", "&cGildia docelowa {guild} nie istnieje!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz relację, a następnie odrzuć + plugin.getGuildService().getGuildRelationAsync(guild.getId(), targetGuild.getId()) + .thenCompose(relation -> { + if (relation == null) { + return CompletableFuture.completedFuture(false); + } + return plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.CANCELLED); + }) + .thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.reject-success", "&cOdrzucono prośbę o relację od {guild}!") + .replace("{guild}", targetGuildName); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.reject-failed", "&cOdrzucenie relacji nie powiodło się! Może nie być oczekującej prośby."); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa polecenia ekonomii gildii + */ + private void handleEconomy(Player player, String[] args) { + // Pobierz gildię gracza + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wyświetl informacje ekonomiczne gildii + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.info", "&6Informacje Ekonomiczne Gildii"); + player.sendMessage(ColorUtils.colorize(message)); + + String balanceMessage = plugin.getConfigManager().getMessagesConfig().getString("economy.balance", "&7Aktualne saldo: &e{balance}") + .replace("{balance}", plugin.getEconomyManager().format(guild.getBalance())); + player.sendMessage(ColorUtils.colorize(balanceMessage)); + + String levelMessage = plugin.getConfigManager().getMessagesConfig().getString("economy.level", "&7Aktualny poziom: &e{level}") + .replace("{level}", String.valueOf(guild.getLevel())); + player.sendMessage(ColorUtils.colorize(levelMessage)); + + String maxMembersMessage = plugin.getConfigManager().getMessagesConfig().getString("economy.max-members", "&7Maks. członków: &e{max_members}") + .replace("{max_members}", String.valueOf(guild.getMaxMembers())); + player.sendMessage(ColorUtils.colorize(maxMembersMessage)); + }); + } + + /** + * Obsługa polecenia wpłaty + */ + private void handleDeposit(Player player, String[] args) { + if (args.length < 2) { + player.sendMessage(ColorUtils.colorize("&cUżycie: /guild deposit ")); + return; + } + + double amount; + try { + amount = Double.parseDouble(args[1]); + } catch (NumberFormatException e) { + player.sendMessage(ColorUtils.colorize("&cFormat kwoty jest nieprawidłowy!")); + return; + } + + if (amount <= 0) { + player.sendMessage(ColorUtils.colorize("&cKwota musi być większa od 0!")); + return; + } + + // Pobierz gildię gracza + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź saldo gracza + if (!plugin.getEconomyManager().hasBalance(player, amount)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.insufficient-balance", "&cNiewystarczające saldo!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wykonaj wpłatę + plugin.getEconomyManager().withdraw(player, amount); + plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), guild.getBalance() + amount).thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.deposit-success", "&aPomyślnie wpłacono &e{amount} &ado gildii!") + .replace("{amount}", plugin.getEconomyManager().format(amount)); + player.sendMessage(ColorUtils.colorize(message)); + } else { + // Zwrot pieniędzy + plugin.getEconomyManager().deposit(player, amount); + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.deposit-failed", "&cWpłata nie powiodła się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa polecenia wypłaty + */ + private void handleWithdraw(Player player, String[] args) { + if (args.length < 2) { + player.sendMessage(ColorUtils.colorize("&cUżycie: /guild withdraw ")); + return; + } + + double amount; + try { + amount = Double.parseDouble(args[1]); + } catch (NumberFormatException e) { + player.sendMessage(ColorUtils.colorize("&cFormat kwoty jest nieprawidłowy!")); + return; + } + + if (amount <= 0) { + player.sendMessage(ColorUtils.colorize("&cKwota musi być większa od 0!")); + return; + } + + // Pobierz gildię gracza + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź saldo gildii + if (guild.getBalance() < amount) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.guild-insufficient-balance", "&cNiewystarczające saldo gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia (tylko lider może wypłacać) + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.leader-only", "&cTylko lider gildii może wypłacać środki!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wykonaj wypłatę + plugin.getGuildService().updateGuildBalanceAsync(guild.getId(), guild.getBalance() - amount).thenAccept(success -> { + if (success) { + plugin.getEconomyManager().deposit(player, amount); + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.withdraw-success", "&aPomyślnie wypłacono &e{amount} &az gildii!") + .replace("{amount}", plugin.getEconomyManager().format(amount)); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.withdraw-failed", "&cWypłata nie powiodła się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + }); + } + + /** + * Obsługa polecenia przelewu + */ + private void handleTransfer(Player player, String[] args) { + if (args.length < 3) { + player.sendMessage(ColorUtils.colorize("&cUżycie: /guild transfer ")); + return; + } + + String targetGuildName = args[1]; + double amount; + try { + amount = Double.parseDouble(args[2]); + } catch (NumberFormatException e) { + player.sendMessage(ColorUtils.colorize("&cFormat kwoty jest nieprawidłowy!")); + return; + } + + if (amount <= 0) { + player.sendMessage(ColorUtils.colorize("&cKwota musi być większa od 0!")); + return; + } + + // Pobierz gildię gracza + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(sourceGuild -> { + if (sourceGuild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia (tylko lider może robić przelewy) + plugin.getGuildService().getGuildMemberAsync(sourceGuild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.leader-only", "&cTylko lider gildii może wykonywać przelewy!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź saldo gildii + if (sourceGuild.getBalance() < amount) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.guild-insufficient-balance", "&cNiewystarczające saldo gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Znajdź gildię docelową + plugin.getGuildService().getGuildByNameAsync(targetGuildName).thenAccept(targetGuild -> { + if (targetGuild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.target-guild-not-found", "&cGildia docelowa nie istnieje!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Nie można przelać do siebie + if (sourceGuild.getId() == targetGuild.getId()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.cannot-transfer-to-self", "&cNie można przelać środków do własnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wykonaj przelew + plugin.getGuildService().updateGuildBalanceAsync(sourceGuild.getId(), sourceGuild.getBalance() - amount).thenAccept(success1 -> { + if (success1) { + plugin.getGuildService().updateGuildBalanceAsync(targetGuild.getId(), targetGuild.getBalance() + amount).thenAccept(success2 -> { + if (success2) { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.transfer-success", "&aPomyślnie przelano &e{amount} &ado gildii &e{target}!") + .replace("{target}", targetGuildName) + .replace("{amount}", plugin.getEconomyManager().format(amount)); + player.sendMessage(ColorUtils.colorize(message)); + } else { + // Wycofaj zmiany + plugin.getGuildService().updateGuildBalanceAsync(sourceGuild.getId(), sourceGuild.getBalance() + amount); + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.transfer-failed", "&cPrzelew nie powiódł się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.transfer-failed", "&cPrzelew nie powiódł się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + }); + }); + } + + /** + * Obsługa polecenia logów + */ + private void handleLogs(Player player, String[] args) { + // Pobierz gildię gracza + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-guild", "&cNie należysz jeszcze do żadnej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&cNiewystarczające uprawnienia!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI logów gildii + plugin.getGuiManager().openGUI(player, new com.guild.gui.GuildLogsGUI(plugin, guild, player)); + }); + }); + } + + /** + * Obsługa polecenia testu placeholderów + */ + private void handlePlaceholder(Player player, String[] args) { + if (!player.hasPermission("guild.admin")) { + player.sendMessage(ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("general.no-permission", "&cNie masz uprawnień do wykonania tej operacji!"))); + return; + } + + if (args.length < 2) { + player.sendMessage(ColorUtils.colorize("&cUżycie: /guild placeholder ")); + player.sendMessage(ColorUtils.colorize("&ePrzykład: /guild placeholder name")); + player.sendMessage(ColorUtils.colorize("&eDostępne zmienne: name, tag, description, leader, membercount, role, hasguild, isleader, isofficer")); + return; + } + + String placeholder = "%guild_" + args[1] + "%"; + String result = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, placeholder); + + player.sendMessage(ColorUtils.colorize("&6=== Test PlaceholderAPI ===")); + player.sendMessage(ColorUtils.colorize("&eZmienna: &f" + placeholder)); + player.sendMessage(ColorUtils.colorize("&eWynik: &f" + result)); + player.sendMessage(ColorUtils.colorize("&6========================")); + } + + /** + * /guild time: Wyświetla rzeczywisty czas systemowy i aktualny czas w świecie gry + */ + private void handleTime(Player player) { + String title = plugin.getConfigManager().getMessagesConfig().getString("time.title", "&6=== Test Czasu ==="); + String realNow = com.guild.core.time.TimeProvider.nowString(); + // Czas świata Minecraft (cykl dzienny 0-23999 ticks) + long ticks = player.getWorld().getTime() % 24000L; + int hours = (int)((ticks / 1000L + 6) % 24); // 0 tick odpowiada 06:00 + int minutes = (int)((ticks % 1000L) * 60L / 1000L); + String gameTime = String.format("%02d:%02d", hours, minutes); + String ticksStr = String.valueOf(ticks); + player.sendMessage(ColorUtils.colorize(title)); + player.sendMessage(ColorUtils.colorize("&eCzas rzeczywisty: &f" + realNow)); + player.sendMessage(ColorUtils.colorize("&eCzas gry: &f" + gameTime + " &7(" + ticksStr + " ticks)")); + } +} diff --git a/src/main/java/com/guild/core/ServiceContainer.java b/src/main/java/com/guild/core/ServiceContainer.java index 45367c6..806c817 100644 --- a/src/main/java/com/guild/core/ServiceContainer.java +++ b/src/main/java/com/guild/core/ServiceContainer.java @@ -1,117 +1,117 @@ -package com.guild.core; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.logging.Logger; - -/** - * 服务容器 - 管理所有服务的生命周期和依赖注入 - */ -public class ServiceContainer { - - private final Map, Object> services = new HashMap<>(); - private final Map, ServiceLifecycle> lifecycles = new HashMap<>(); - private final Logger logger = Logger.getLogger(ServiceContainer.class.getName()); - - /** - * 注册服务 - */ - public void register(Class serviceClass, T service) { - services.put(serviceClass, service); - logger.info("注册服务: " + serviceClass.getSimpleName()); - } - - /** - * 注册带生命周期的服务 - */ - public void register(Class serviceClass, T service, ServiceLifecycle lifecycle) { - services.put(serviceClass, service); - lifecycles.put(serviceClass, lifecycle); - logger.info("注册服务: " + serviceClass.getSimpleName() + " (带生命周期)"); - } - - /** - * 获取服务 - */ - @SuppressWarnings("unchecked") - public T get(Class serviceClass) { - T service = (T) services.get(serviceClass); - if (service == null) { - throw new ServiceNotFoundException("服务未找到: " + serviceClass.getName()); - } - return service; - } - - /** - * 检查服务是否存在 - */ - public boolean has(Class serviceClass) { - return services.containsKey(serviceClass); - } - - /** - * 启动所有服务 - */ - public CompletableFuture startAll() { - return CompletableFuture.runAsync(() -> { - logger.info("正在启动所有服务..."); - for (Map.Entry, ServiceLifecycle> entry : lifecycles.entrySet()) { - try { - entry.getValue().start(); - logger.info("服务启动成功: " + entry.getKey().getSimpleName()); - } catch (Exception e) { - logger.severe("服务启动失败: " + entry.getKey().getSimpleName() + " - " + e.getMessage()); - } - } - }); - } - - /** - * 停止所有服务 - */ - public CompletableFuture stopAll() { - return CompletableFuture.runAsync(() -> { - logger.info("正在停止所有服务..."); - for (Map.Entry, ServiceLifecycle> entry : lifecycles.entrySet()) { - try { - entry.getValue().stop(); - logger.info("服务停止成功: " + entry.getKey().getSimpleName()); - } catch (Exception e) { - logger.severe("服务停止失败: " + entry.getKey().getSimpleName() + " - " + e.getMessage()); - } - } - }); - } - - /** - * 关闭服务容器 - */ - public void shutdown() { - try { - stopAll().get(); - services.clear(); - lifecycles.clear(); - logger.info("服务容器已关闭"); - } catch (Exception e) { - logger.severe("关闭服务容器时发生错误: " + e.getMessage()); - } - } - - /** - * 服务生命周期接口 - */ - public interface ServiceLifecycle { - void start() throws Exception; - void stop() throws Exception; - } - - /** - * 服务未找到异常 - */ - public static class ServiceNotFoundException extends RuntimeException { - public ServiceNotFoundException(String message) { - super(message); - } - } -} +package com.guild.core; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Logger; + +/** + * Kontener usług - zarządza cyklem życia wszystkich usług i wstrzykiwaniem zależności + */ +public class ServiceContainer { + + private final Map, Object> services = new HashMap<>(); + private final Map, ServiceLifecycle> lifecycles = new HashMap<>(); + private final Logger logger = Logger.getLogger(ServiceContainer.class.getName()); + + /** + * Zarejestruj usługę + */ + public void register(Class serviceClass, T service) { + services.put(serviceClass, service); + logger.info("Zarejestrowano usługę: " + serviceClass.getSimpleName()); + } + + /** + * Zarejestruj usługę z cyklem życia + */ + public void register(Class serviceClass, T service, ServiceLifecycle lifecycle) { + services.put(serviceClass, service); + lifecycles.put(serviceClass, lifecycle); + logger.info("Zarejestrowano usługę: " + serviceClass.getSimpleName() + " (z cyklem życia)"); + } + + /** + * Pobierz usługę + */ + @SuppressWarnings("unchecked") + public T get(Class serviceClass) { + T service = (T) services.get(serviceClass); + if (service == null) { + throw new ServiceNotFoundException("Nie znaleziono usługi: " + serviceClass.getName()); + } + return service; + } + + /** + * Sprawdź, czy usługa istnieje + */ + public boolean has(Class serviceClass) { + return services.containsKey(serviceClass); + } + + /** + * Uruchom wszystkie usługi + */ + public CompletableFuture startAll() { + return CompletableFuture.runAsync(() -> { + logger.info("Uruchamianie wszystkich usług..."); + for (Map.Entry, ServiceLifecycle> entry : lifecycles.entrySet()) { + try { + entry.getValue().start(); + logger.info("Usługa uruchomiona pomyślnie: " + entry.getKey().getSimpleName()); + } catch (Exception e) { + logger.severe("Nie udało się uruchomić usługi: " + entry.getKey().getSimpleName() + " - " + e.getMessage()); + } + } + }); + } + + /** + * Zatrzymaj wszystkie usługi + */ + public CompletableFuture stopAll() { + return CompletableFuture.runAsync(() -> { + logger.info("Zatrzymywanie wszystkich usług..."); + for (Map.Entry, ServiceLifecycle> entry : lifecycles.entrySet()) { + try { + entry.getValue().stop(); + logger.info("Usługa zatrzymana pomyślnie: " + entry.getKey().getSimpleName()); + } catch (Exception e) { + logger.severe("Nie udało się zatrzymać usługi: " + entry.getKey().getSimpleName() + " - " + e.getMessage()); + } + } + }); + } + + /** + * Wyłącz kontener usług + */ + public void shutdown() { + try { + stopAll().get(); + services.clear(); + lifecycles.clear(); + logger.info("Kontener usług został zamknięty"); + } catch (Exception e) { + logger.severe("Błąd podczas zamykania kontenera usług: " + e.getMessage()); + } + } + + /** + * Interfejs cyklu życia usługi + */ + public interface ServiceLifecycle { + void start() throws Exception; + void stop() throws Exception; + } + + /** + * Wyjątek nieznalezionej usługi + */ + public static class ServiceNotFoundException extends RuntimeException { + public ServiceNotFoundException(String message) { + super(message); + } + } +} diff --git a/src/main/java/com/guild/core/config/ConfigManager.java b/src/main/java/com/guild/core/config/ConfigManager.java index 5419c37..de1cbad 100644 --- a/src/main/java/com/guild/core/config/ConfigManager.java +++ b/src/main/java/com/guild/core/config/ConfigManager.java @@ -1,171 +1,171 @@ -package com.guild.core.config; - -import com.guild.GuildPlugin; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Logger; - -/** - * 配置管理器 - 管理插件的所有配置文件 - */ -public class ConfigManager { - - private final GuildPlugin plugin; - private final Logger logger; - private final Map configs = new HashMap<>(); - private final Map configFiles = new HashMap<>(); - - public ConfigManager(GuildPlugin plugin) { - this.plugin = plugin; - this.logger = plugin.getLogger(); - loadConfigs(); - } - - /** - * 加载所有配置文件 - */ - private void loadConfigs() { - // 主配置文件 - loadConfig("config.yml"); - - // 消息配置文件 - loadConfig("messages.yml"); - - // GUI配置文件 - loadConfig("gui.yml"); - - // 数据库配置文件 - loadConfig("database.yml"); - } - - /** - * 加载指定配置文件 - */ - public void loadConfig(String fileName) { - File configFile = new File(plugin.getDataFolder(), fileName); - - // 如果配置文件不存在,从jar中复制默认配置 - if (!configFile.exists()) { - plugin.saveResource(fileName, false); - } - - FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); - configs.put(fileName, config); - configFiles.put(fileName, configFile); - - logger.info("加载配置文件: " + fileName); - } - - /** - * 获取配置文件 - */ - public FileConfiguration getConfig(String fileName) { - return configs.get(fileName); - } - - /** - * 获取主配置文件 - */ - public FileConfiguration getMainConfig() { - return getConfig("config.yml"); - } - - /** - * 获取消息配置文件 - */ - public FileConfiguration getMessagesConfig() { - return getConfig("messages.yml"); - } - - /** - * 获取GUI配置文件 - */ - public FileConfiguration getGuiConfig() { - return getConfig("gui.yml"); - } - - /** - * 获取数据库配置文件 - */ - public FileConfiguration getDatabaseConfig() { - return getConfig("database.yml"); - } - - /** - * 保存主配置文件 - */ - public void saveMainConfig() { - saveConfig("config.yml"); - } - - /** - * 保存配置文件 - */ - public void saveConfig(String fileName) { - FileConfiguration config = configs.get(fileName); - File configFile = configFiles.get(fileName); - - if (config != null && configFile != null) { - try { - config.save(configFile); - logger.info("保存配置文件: " + fileName); - } catch (IOException e) { - logger.severe("保存配置文件失败: " + fileName + " - " + e.getMessage()); - } - } - } - - /** - * 重新加载配置文件 - */ - public void reloadConfig(String fileName) { - loadConfig(fileName); - logger.info("重新加载配置文件: " + fileName); - } - - /** - * 重新加载所有配置文件 - */ - public void reloadAllConfigs() { - configs.clear(); - configFiles.clear(); - loadConfigs(); - logger.info("重新加载所有配置文件"); - } - - /** - * 获取字符串配置,支持颜色代码 - */ - public String getString(String fileName, String path, String defaultValue) { - FileConfiguration config = getConfig(fileName); - if (config == null) return defaultValue; - - String value = config.getString(path, defaultValue); - return value != null ? value.replace("&", "§") : defaultValue; - } - - /** - * 获取整数配置 - */ - public int getInt(String fileName, String path, int defaultValue) { - FileConfiguration config = getConfig(fileName); - if (config == null) return defaultValue; - - return config.getInt(path, defaultValue); - } - - /** - * 获取布尔配置 - */ - public boolean getBoolean(String fileName, String path, boolean defaultValue) { - FileConfiguration config = getConfig(fileName); - if (config == null) return defaultValue; - - return config.getBoolean(path, defaultValue); - } -} +package com.guild.core.config; + +import com.guild.GuildPlugin; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Menedżer konfiguracji - zarządza wszystkimi plikami konfiguracyjnymi pluginu + */ +public class ConfigManager { + + private final GuildPlugin plugin; + private final Logger logger; + private final Map configs = new HashMap<>(); + private final Map configFiles = new HashMap<>(); + + public ConfigManager(GuildPlugin plugin) { + this.plugin = plugin; + this.logger = plugin.getLogger(); + loadConfigs(); + } + + /** + * Załaduj wszystkie pliki konfiguracyjne + */ + private void loadConfigs() { + // Główna konfiguracja + loadConfig("config.yml"); + + // Konfiguracja wiadomości + loadConfig("messages.yml"); + + // Konfiguracja GUI + loadConfig("gui.yml"); + + // Konfiguracja bazy danych + loadConfig("database.yml"); + } + + /** + * Załaduj określoną konfigurację + */ + public void loadConfig(String fileName) { + File configFile = new File(plugin.getDataFolder(), fileName); + + // Jeśli plik konfiguracyjny nie istnieje, skopiuj domyślny z jar + if (!configFile.exists()) { + plugin.saveResource(fileName, false); + } + + FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); + configs.put(fileName, config); + configFiles.put(fileName, configFile); + + logger.info("Załadowano konfigurację: " + fileName); + } + + /** + * Pobierz konfigurację + */ + public FileConfiguration getConfig(String fileName) { + return configs.get(fileName); + } + + /** + * Pobierz główną konfigurację + */ + public FileConfiguration getMainConfig() { + return getConfig("config.yml"); + } + + /** + * Pobierz konfigurację wiadomości + */ + public FileConfiguration getMessagesConfig() { + return getConfig("messages.yml"); + } + + /** + * Pobierz konfigurację GUI + */ + public FileConfiguration getGuiConfig() { + return getConfig("gui.yml"); + } + + /** + * Pobierz konfigurację bazy danych + */ + public FileConfiguration getDatabaseConfig() { + return getConfig("database.yml"); + } + + /** + * Zapisz główną konfigurację + */ + public void saveMainConfig() { + saveConfig("config.yml"); + } + + /** + * Zapisz konfigurację + */ + public void saveConfig(String fileName) { + FileConfiguration config = configs.get(fileName); + File configFile = configFiles.get(fileName); + + if (config != null && configFile != null) { + try { + config.save(configFile); + logger.info("Zapisano konfigurację: " + fileName); + } catch (IOException e) { + logger.severe("Błąd zapisu konfiguracji: " + fileName + " - " + e.getMessage()); + } + } + } + + /** + * Przeładuj konfigurację + */ + public void reloadConfig(String fileName) { + loadConfig(fileName); + logger.info("Przeładowano konfigurację: " + fileName); + } + + /** + * Przeładuj wszystkie konfiguracje + */ + public void reloadAllConfigs() { + configs.clear(); + configFiles.clear(); + loadConfigs(); + logger.info("Przeładowano wszystkie konfiguracje"); + } + + /** + * Pobierz ciąg konfiguracji, obsługuje kody kolorów + */ + public String getString(String fileName, String path, String defaultValue) { + FileConfiguration config = getConfig(fileName); + if (config == null) return defaultValue; + + String value = config.getString(path, defaultValue); + return value != null ? value.replace("&", "§") : defaultValue; + } + + /** + * Pobierz liczbę całkowitą + */ + public int getInt(String fileName, String path, int defaultValue) { + FileConfiguration config = getConfig(fileName); + if (config == null) return defaultValue; + + return config.getInt(path, defaultValue); + } + + /** + * Pobierz wartość logiczną + */ + public boolean getBoolean(String fileName, String path, boolean defaultValue) { + FileConfiguration config = getConfig(fileName); + if (config == null) return defaultValue; + + return config.getBoolean(path, defaultValue); + } +} diff --git a/src/main/java/com/guild/core/database/DatabaseManager.java b/src/main/java/com/guild/core/database/DatabaseManager.java index bada926..7a0c83d 100644 --- a/src/main/java/com/guild/core/database/DatabaseManager.java +++ b/src/main/java/com/guild/core/database/DatabaseManager.java @@ -1,631 +1,631 @@ -package com.guild.core.database; - -import com.guild.GuildPlugin; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import org.bukkit.configuration.file.FileConfiguration; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.concurrent.CompletableFuture; -import java.util.logging.Logger; - -/** - * 数据库管理器 - 管理数据库连接和操作 - */ -public class DatabaseManager { - - private final GuildPlugin plugin; - private final Logger logger; - private HikariDataSource dataSource; - private DatabaseType databaseType; - - public DatabaseManager(GuildPlugin plugin) { - this.plugin = plugin; - this.logger = plugin.getLogger(); - } - - /** - * 初始化数据库连接 - */ - public void initialize() { - FileConfiguration config = plugin.getConfigManager().getDatabaseConfig(); - // 兼容两种结构:root 与 database. 前缀 - String type = config.getString("type", config.getString("database.type", "sqlite")).toLowerCase(); - - try { - if ("mysql".equals(type)) { - initializeMySQL(config); - } else { - initializeSQLite(config); - } - - // 创建数据表 - createTables(); - - logger.info("数据库连接初始化成功: " + databaseType); - - } catch (Exception e) { - logger.severe("数据库连接初始化失败: " + e.getMessage()); - throw new RuntimeException("数据库连接失败", e); - } - } - - /** - * 初始化MySQL连接 - */ - private void initializeMySQL(FileConfiguration config) { - databaseType = DatabaseType.MYSQL; - - HikariConfig hikariConfig = new HikariConfig(); - String host = config.getString("mysql.host", config.getString("database.mysql.host", "localhost")); - int port = config.getInt("mysql.port", config.getInt("database.mysql.port", 3306)); - String database = config.getString("mysql.database", config.getString("database.mysql.database", "guild")); - String params = "?useSSL=" + (config.getBoolean("mysql.use-ssl", config.getBoolean("database.mysql.use-ssl", false)) ? "true" : "false") + - "&serverTimezone=" + config.getString("mysql.timezone", config.getString("database.mysql.timezone", "UTC")) + - "&characterEncoding=" + config.getString("mysql.character-encoding", config.getString("database.mysql.character-encoding", "UTF-8")); - hikariConfig.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + params); - - hikariConfig.setUsername(config.getString("mysql.username", config.getString("database.mysql.username", "root"))); - hikariConfig.setPassword(config.getString("mysql.password", config.getString("database.mysql.password", ""))); - hikariConfig.setMaximumPoolSize(config.getInt("mysql.pool-size", config.getInt("database.mysql.pool-size", 20))); - hikariConfig.setMinimumIdle(config.getInt("mysql.min-idle", config.getInt("database.mysql.min-idle", 10))); - hikariConfig.setConnectionTimeout(config.getLong("mysql.connection-timeout", config.getLong("database.mysql.connection-timeout", 60000))); - hikariConfig.setIdleTimeout(config.getLong("mysql.idle-timeout", config.getLong("database.mysql.idle-timeout", 600000))); - hikariConfig.setMaxLifetime(config.getLong("mysql.max-lifetime", config.getLong("database.mysql.max-lifetime", 1800000))); - - dataSource = new HikariDataSource(hikariConfig); - } - - /** - * 初始化SQLite连接 - */ - private void initializeSQLite(FileConfiguration config) { - databaseType = DatabaseType.SQLITE; - - HikariConfig hikariConfig = new HikariConfig(); - String fileName = config.getString("sqlite.file", config.getString("database.sqlite.file", "guild.db")); - String dbPath = plugin.getDataFolder() + "/" + fileName; - hikariConfig.setJdbcUrl("jdbc:sqlite:" + dbPath); - int maxPool = config.getInt("connection-pool.maximum-pool-size", 2); - if (maxPool < 1) { maxPool = 1; } - hikariConfig.setMaximumPoolSize(maxPool); - long connTimeout = config.getLong("connection-pool.connection-timeout", 10000); - hikariConfig.setConnectionTimeout(connTimeout); - long idleTimeout = config.getLong("connection-pool.idle-timeout", 600000); - hikariConfig.setIdleTimeout(idleTimeout); - long maxLifetime = config.getLong("connection-pool.max-lifetime", 1800000); - hikariConfig.setMaxLifetime(maxLifetime); - - // SQLite优化:根据配置设置PRAGMA,减少锁等待与提升并发读 - boolean walMode = config.getBoolean("sqlite.wal-mode", true); - String synchronous = config.getString("sqlite.synchronous", "NORMAL"); - boolean foreignKeys = config.getBoolean("sqlite.foreign-keys", true); - int cacheSize = config.getInt("sqlite.cache-size", 2000); - int busyTimeoutMs = (int) config.getLong("sqlite.busy-timeout", 5000); - StringBuilder initSql = new StringBuilder(); - if (walMode) { - initSql.append("PRAGMA journal_mode=WAL;"); - } - if (synchronous != null) { - initSql.append("PRAGMA synchronous=").append(synchronous).append(";"); - } - initSql.append("PRAGMA foreign_keys=").append(foreignKeys ? "ON" : "OFF").append(";"); - initSql.append("PRAGMA cache_size=").append(cacheSize).append(";"); - initSql.append("PRAGMA busy_timeout=").append(busyTimeoutMs).append(";"); - hikariConfig.setConnectionInitSql(initSql.toString()); - - dataSource = new HikariDataSource(hikariConfig); - } - - /** - * 创建数据表 - */ - private void createTables() { - if (databaseType == DatabaseType.SQLITE) { - createSQLiteTables(); - } else { - createMySQLTables(); - } - - // 异步检查并添加缺失的列,避免阻塞启动 - CompletableFuture.runAsync(() -> { - try { - Thread.sleep(1000); // 等待1秒确保数据库连接稳定 - checkAndAddMissingColumns(); - } catch (Exception e) { - logger.warning("异步检查数据库列时发生错误: " + e.getMessage()); - } - }); - - logger.info("数据表创建完成"); - } - - /** - * 创建SQLite数据表 - */ - private void createSQLiteTables() { - // 工会表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guilds ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT UNIQUE NOT NULL, - tag TEXT UNIQUE, - description TEXT, - leader_uuid TEXT NOT NULL, - leader_name TEXT NOT NULL, - home_world TEXT, - home_x REAL, - home_y REAL, - home_z REAL, - home_yaw REAL, - home_pitch REAL, - created_at TEXT DEFAULT (datetime('now','localtime')), - updated_at TEXT DEFAULT (datetime('now','localtime')) - ) - """); - - // 工会成员表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_members ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid TEXT NOT NULL, - player_name TEXT NOT NULL, - role TEXT DEFAULT 'MEMBER', - joined_at TEXT DEFAULT (datetime('now','localtime')), - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE, - UNIQUE(guild_id, player_uuid) - ) - """); - - // 工会申请表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_applications ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid TEXT NOT NULL, - player_name TEXT NOT NULL, - message TEXT, - status TEXT DEFAULT 'PENDING', - created_at TEXT DEFAULT (datetime('now','localtime')), - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会邀请表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_invites ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid TEXT NOT NULL, - player_name TEXT NOT NULL, - inviter_uuid TEXT NOT NULL, - inviter_name TEXT NOT NULL, - status TEXT DEFAULT 'PENDING', - expires_at TEXT, - created_at TEXT DEFAULT (datetime('now','localtime')), - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会关系表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_relations ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild1_id INTEGER NOT NULL, - guild2_id INTEGER NOT NULL, - guild1_name TEXT NOT NULL, - guild2_name TEXT NOT NULL, - relation_type TEXT NOT NULL, - status TEXT DEFAULT 'PENDING', - initiator_uuid TEXT NOT NULL, - initiator_name TEXT NOT NULL, - created_at TEXT DEFAULT (datetime('now','localtime')), - updated_at TEXT DEFAULT (datetime('now','localtime')), - expires_at TEXT, - FOREIGN KEY (guild1_id) REFERENCES guilds(id) ON DELETE CASCADE, - FOREIGN KEY (guild2_id) REFERENCES guilds(id) ON DELETE CASCADE, - UNIQUE(guild1_id, guild2_id) - ) - """); - - // 工会经济表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_economy ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL UNIQUE, - balance REAL DEFAULT 0.0, - level INTEGER DEFAULT 1, - experience REAL DEFAULT 0.0, - max_experience REAL DEFAULT 5000.0, - max_members INTEGER DEFAULT 6, - last_updated TEXT DEFAULT (datetime('now','localtime')), - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会贡献记录表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_contributions ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - player_uuid TEXT NOT NULL, - player_name TEXT NOT NULL, - amount REAL NOT NULL, - contribution_type TEXT NOT NULL, - description TEXT, - created_at TEXT DEFAULT (datetime('now','localtime')), - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会日志表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_logs ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - guild_id INTEGER NOT NULL, - guild_name TEXT NOT NULL, - player_uuid TEXT NOT NULL, - player_name TEXT NOT NULL, - log_type TEXT NOT NULL, - description TEXT NOT NULL, - details TEXT, - created_at TEXT DEFAULT (datetime('now','localtime')), - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - } - - /** - * 创建MySQL数据表 - */ - private void createMySQLTables() { - // 工会表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guilds ( - id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(50) UNIQUE NOT NULL, - tag VARCHAR(10) UNIQUE, - description TEXT, - leader_uuid VARCHAR(36) NOT NULL, - leader_name VARCHAR(16) NOT NULL, - home_world VARCHAR(100), - home_x DOUBLE, - home_y DOUBLE, - home_z DOUBLE, - home_yaw FLOAT, - home_pitch FLOAT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP - ) - """); - - // 工会成员表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_members ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild_id INT NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - role VARCHAR(20) DEFAULT 'MEMBER', - joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE, - UNIQUE KEY unique_guild_player (guild_id, player_uuid) - ) - """); - - // 工会申请表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_applications ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild_id INT NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - message TEXT, - status VARCHAR(20) DEFAULT 'PENDING', - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会邀请表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_invites ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild_id INT NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - inviter_uuid VARCHAR(36) NOT NULL, - inviter_name VARCHAR(16) NOT NULL, - status VARCHAR(20) DEFAULT 'PENDING', - expires_at TIMESTAMP NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会关系表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_relations ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild1_id INT NOT NULL, - guild2_id INT NOT NULL, - guild1_name VARCHAR(50) NOT NULL, - guild2_name VARCHAR(50) NOT NULL, - relation_type VARCHAR(20) NOT NULL, - status VARCHAR(20) DEFAULT 'PENDING', - initiator_uuid VARCHAR(36) NOT NULL, - initiator_name VARCHAR(16) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - expires_at TIMESTAMP NULL, - FOREIGN KEY (guild1_id) REFERENCES guilds(id) ON DELETE CASCADE, - FOREIGN KEY (guild2_id) REFERENCES guilds(id) ON DELETE CASCADE, - UNIQUE KEY unique_guild_relation (guild1_id, guild2_id) - ) - """); - - // 工会经济表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_economy ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild_id INT NOT NULL UNIQUE, - balance DOUBLE DEFAULT 0.0, - level INT DEFAULT 1, - experience DOUBLE DEFAULT 0.0, - max_experience DOUBLE DEFAULT 5000.0, - max_members INT DEFAULT 6, - last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会贡献记录表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_contributions ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild_id INT NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - amount DOUBLE NOT NULL, - contribution_type VARCHAR(20) NOT NULL, - description TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - - // 工会日志表 - executeUpdate(""" - CREATE TABLE IF NOT EXISTS guild_logs ( - id INT AUTO_INCREMENT PRIMARY KEY, - guild_id INT NOT NULL, - guild_name VARCHAR(50) NOT NULL, - player_uuid VARCHAR(36) NOT NULL, - player_name VARCHAR(16) NOT NULL, - log_type VARCHAR(50) NOT NULL, - description TEXT NOT NULL, - details TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE - ) - """); - } - - /** - * 获取数据库连接 - */ - public Connection getConnection() throws SQLException { - if (dataSource == null) { - throw new SQLException("数据库连接未初始化"); - } - return dataSource.getConnection(); - } - - /** - * 执行更新操作 - */ - public int executeUpdate(String sql, Object... params) { - try (Connection conn = getConnection(); - PreparedStatement stmt = conn.prepareStatement(sql)) { - - for (int i = 0; i < params.length; i++) { - stmt.setObject(i + 1, params[i]); - } - - return stmt.executeUpdate(); - - } catch (SQLException e) { - logger.severe("执行更新操作失败: " + e.getMessage()); - throw new RuntimeException("数据库操作失败", e); - } - } - - /** - * 异步执行更新操作 - */ - public CompletableFuture executeUpdateAsync(String sql, Object... params) { - return CompletableFuture.supplyAsync(() -> executeUpdate(sql, params)); - } - - /** - * 执行查询操作 - */ - public ResultSet executeQuery(String sql, Object... params) { - try { - Connection conn = getConnection(); - PreparedStatement stmt = conn.prepareStatement(sql); - - for (int i = 0; i < params.length; i++) { - stmt.setObject(i + 1, params[i]); - } - - return stmt.executeQuery(); - - } catch (SQLException e) { - logger.severe("执行查询操作失败: " + e.getMessage()); - throw new RuntimeException("数据库操作失败", e); - } - } - - /** - * 关闭数据库连接 - */ - public void close() { - if (dataSource != null && !dataSource.isClosed()) { - dataSource.close(); - logger.info("数据库连接已关闭"); - } - } - - /** - * 获取数据库类型 - */ - public DatabaseType getDatabaseType() { - return databaseType; - } - - /** - * 数据库类型枚举 - */ - /** - * 检查并添加缺失的列 - */ - private void checkAndAddMissingColumns() { - try { - if (databaseType == DatabaseType.SQLITE) { - checkAndAddSQLiteColumns(); - } else { - checkAndAddMySQLColumns(); - } - logger.info("数据库列检查完成"); - } catch (Exception e) { - logger.warning("检查数据库列时发生错误: " + e.getMessage()); - } - } - - /** - * 检查并添加SQLite缺失的列 - */ - private void checkAndAddSQLiteColumns() { - try (Connection conn = getConnection()) { - conn.setAutoCommit(false); // 开启事务以提高性能 - - // 检查guilds表是否有home相关列 - try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "home_world")) { - if (!rs.next()) { - // 添加home相关列 - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_world TEXT")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_x REAL")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_y REAL")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_z REAL")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_yaw REAL")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_pitch REAL")) { - stmt.executeUpdate(); - } - logger.info("已为guilds表添加home相关列"); - } - } - - // 检查guilds表是否有economy相关列 - try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "balance")) { - if (!rs.next()) { - // 添加economy相关列 - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN balance REAL DEFAULT 0.0")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN level INTEGER DEFAULT 1")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN max_members INTEGER DEFAULT 6")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN frozen INTEGER DEFAULT 0")) { - stmt.executeUpdate(); - } - logger.info("已为guilds表添加economy相关列"); - } - } - - conn.commit(); // 提交事务 - } catch (SQLException e) { - logger.warning("检查SQLite列时发生错误: " + e.getMessage()); - } - } - - /** - * 检查并添加MySQL缺失的列 - */ - private void checkAndAddMySQLColumns() { - try (Connection conn = getConnection()) { - conn.setAutoCommit(false); // 开启事务以提高性能 - - // 检查guilds表是否有home相关列 - try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "home_world")) { - if (!rs.next()) { - // 添加home相关列 - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_world VARCHAR(100)")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_x DOUBLE")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_y DOUBLE")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_z DOUBLE")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_yaw FLOAT")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_pitch FLOAT")) { - stmt.executeUpdate(); - } - logger.info("已为guilds表添加home相关列"); - } - } - - // 检查guilds表是否有economy相关列 - try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "balance")) { - if (!rs.next()) { - // 添加economy相关列 - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN balance DOUBLE DEFAULT 0.0")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN level INT DEFAULT 1")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN max_members INT DEFAULT 6")) { - stmt.executeUpdate(); - } - try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN frozen BOOLEAN DEFAULT FALSE")) { - stmt.executeUpdate(); - } - logger.info("已为guilds表添加economy相关列"); - } - } - - conn.commit(); // 提交事务 - } catch (SQLException e) { - logger.warning("检查MySQL列时发生错误: " + e.getMessage()); - } - } - - public enum DatabaseType { - MYSQL, SQLITE - } -} +package com.guild.core.database; + +import com.guild.GuildPlugin; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.bukkit.configuration.file.FileConfiguration; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.concurrent.CompletableFuture; +import java.util.logging.Logger; + +/** + * Menedżer bazy danych - zarządza połączeniami z bazą danych i operacjami + */ +public class DatabaseManager { + + private final GuildPlugin plugin; + private final Logger logger; + private HikariDataSource dataSource; + private DatabaseType databaseType; + + public DatabaseManager(GuildPlugin plugin) { + this.plugin = plugin; + this.logger = plugin.getLogger(); + } + + /** + * Zainicjuj połączenie z bazą danych + */ + public void initialize() { + FileConfiguration config = plugin.getConfigManager().getDatabaseConfig(); + // Kompatybilność z dwoma strukturami: root i prefiks database. + String type = config.getString("type", config.getString("database.type", "sqlite")).toLowerCase(); + + try { + if ("mysql".equals(type)) { + initializeMySQL(config); + } else { + initializeSQLite(config); + } + + // Utwórz tabele danych + createTables(); + + logger.info("Pomyślnie zainicjowano połączenie z bazą danych: " + databaseType); + + } catch (Exception e) { + logger.severe("Błąd inicjalizacji połączenia z bazą danych: " + e.getMessage()); + throw new RuntimeException("Nie udało się połączyć z bazą danych", e); + } + } + + /** + * Zainicjuj połączenie MySQL + */ + private void initializeMySQL(FileConfiguration config) { + databaseType = DatabaseType.MYSQL; + + HikariConfig hikariConfig = new HikariConfig(); + String host = config.getString("mysql.host", config.getString("database.mysql.host", "localhost")); + int port = config.getInt("mysql.port", config.getInt("database.mysql.port", 3306)); + String database = config.getString("mysql.database", config.getString("database.mysql.database", "guild")); + String params = "?useSSL=" + (config.getBoolean("mysql.use-ssl", config.getBoolean("database.mysql.use-ssl", false)) ? "true" : "false") + + "&serverTimezone=" + config.getString("mysql.timezone", config.getString("database.mysql.timezone", "UTC")) + + "&characterEncoding=" + config.getString("mysql.character-encoding", config.getString("database.mysql.character-encoding", "UTF-8")); + hikariConfig.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + params); + + hikariConfig.setUsername(config.getString("mysql.username", config.getString("database.mysql.username", "root"))); + hikariConfig.setPassword(config.getString("mysql.password", config.getString("database.mysql.password", ""))); + hikariConfig.setMaximumPoolSize(config.getInt("mysql.pool-size", config.getInt("database.mysql.pool-size", 20))); + hikariConfig.setMinimumIdle(config.getInt("mysql.min-idle", config.getInt("database.mysql.min-idle", 10))); + hikariConfig.setConnectionTimeout(config.getLong("mysql.connection-timeout", config.getLong("database.mysql.connection-timeout", 60000))); + hikariConfig.setIdleTimeout(config.getLong("mysql.idle-timeout", config.getLong("database.mysql.idle-timeout", 600000))); + hikariConfig.setMaxLifetime(config.getLong("mysql.max-lifetime", config.getLong("database.mysql.max-lifetime", 1800000))); + + dataSource = new HikariDataSource(hikariConfig); + } + + /** + * Zainicjuj połączenie SQLite + */ + private void initializeSQLite(FileConfiguration config) { + databaseType = DatabaseType.SQLITE; + + HikariConfig hikariConfig = new HikariConfig(); + String fileName = config.getString("sqlite.file", config.getString("database.sqlite.file", "guild.db")); + String dbPath = plugin.getDataFolder() + "/" + fileName; + hikariConfig.setJdbcUrl("jdbc:sqlite:" + dbPath); + int maxPool = config.getInt("connection-pool.maximum-pool-size", 2); + if (maxPool < 1) { maxPool = 1; } + hikariConfig.setMaximumPoolSize(maxPool); + long connTimeout = config.getLong("connection-pool.connection-timeout", 10000); + hikariConfig.setConnectionTimeout(connTimeout); + long idleTimeout = config.getLong("connection-pool.idle-timeout", 600000); + hikariConfig.setIdleTimeout(idleTimeout); + long maxLifetime = config.getLong("connection-pool.max-lifetime", 1800000); + hikariConfig.setMaxLifetime(maxLifetime); + + // Optymalizacja SQLite: ustaw PRAGMA na podstawie konfiguracji, aby zmniejszyć oczekiwanie na blokady i poprawić współbieżny odczyt + boolean walMode = config.getBoolean("sqlite.wal-mode", true); + String synchronous = config.getString("sqlite.synchronous", "NORMAL"); + boolean foreignKeys = config.getBoolean("sqlite.foreign-keys", true); + int cacheSize = config.getInt("sqlite.cache-size", 2000); + int busyTimeoutMs = (int) config.getLong("sqlite.busy-timeout", 5000); + StringBuilder initSql = new StringBuilder(); + if (walMode) { + initSql.append("PRAGMA journal_mode=WAL;"); + } + if (synchronous != null) { + initSql.append("PRAGMA synchronous=").append(synchronous).append(";"); + } + initSql.append("PRAGMA foreign_keys=").append(foreignKeys ? "ON" : "OFF").append(";"); + initSql.append("PRAGMA cache_size=").append(cacheSize).append(";"); + initSql.append("PRAGMA busy_timeout=").append(busyTimeoutMs).append(";"); + hikariConfig.setConnectionInitSql(initSql.toString()); + + dataSource = new HikariDataSource(hikariConfig); + } + + /** + * Utwórz tabele danych + */ + private void createTables() { + if (databaseType == DatabaseType.SQLITE) { + createSQLiteTables(); + } else { + createMySQLTables(); + } + + // Asynchronicznie sprawdź i dodaj brakujące kolumny, aby uniknąć blokowania startu + CompletableFuture.runAsync(() -> { + try { + Thread.sleep(1000); // Poczekaj 1 sekundę, aby upewnić się, że połączenie z bazą danych jest stabilne + checkAndAddMissingColumns(); + } catch (Exception e) { + logger.warning("Błąd podczas asynchronicznego sprawdzania kolumn bazy danych: " + e.getMessage()); + } + }); + + logger.info("Utworzono tabele danych"); + } + + /** + * Utwórz tabele danych SQLite + */ + private void createSQLiteTables() { + // Tabela gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guilds ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT UNIQUE NOT NULL, + tag TEXT UNIQUE, + description TEXT, + leader_uuid TEXT NOT NULL, + leader_name TEXT NOT NULL, + home_world TEXT, + home_x REAL, + home_y REAL, + home_z REAL, + home_yaw REAL, + home_pitch REAL, + created_at TEXT DEFAULT (datetime('now','localtime')), + updated_at TEXT DEFAULT (datetime('now','localtime')) + ) + """); + + // Tabela członków gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_members ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild_id INTEGER NOT NULL, + player_uuid TEXT NOT NULL, + player_name TEXT NOT NULL, + role TEXT DEFAULT 'MEMBER', + joined_at TEXT DEFAULT (datetime('now','localtime')), + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE, + UNIQUE(guild_id, player_uuid) + ) + """); + + // Tabela aplikacji do gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_applications ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild_id INTEGER NOT NULL, + player_uuid TEXT NOT NULL, + player_name TEXT NOT NULL, + message TEXT, + status TEXT DEFAULT 'PENDING', + created_at TEXT DEFAULT (datetime('now','localtime')), + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela zaproszeń do gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_invites ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild_id INTEGER NOT NULL, + player_uuid TEXT NOT NULL, + player_name TEXT NOT NULL, + inviter_uuid TEXT NOT NULL, + inviter_name TEXT NOT NULL, + status TEXT DEFAULT 'PENDING', + expires_at TEXT, + created_at TEXT DEFAULT (datetime('now','localtime')), + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela relacji gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_relations ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild1_id INTEGER NOT NULL, + guild2_id INTEGER NOT NULL, + guild1_name TEXT NOT NULL, + guild2_name TEXT NOT NULL, + relation_type TEXT NOT NULL, + status TEXT DEFAULT 'PENDING', + initiator_uuid TEXT NOT NULL, + initiator_name TEXT NOT NULL, + created_at TEXT DEFAULT (datetime('now','localtime')), + updated_at TEXT DEFAULT (datetime('now','localtime')), + expires_at TEXT, + FOREIGN KEY (guild1_id) REFERENCES guilds(id) ON DELETE CASCADE, + FOREIGN KEY (guild2_id) REFERENCES guilds(id) ON DELETE CASCADE, + UNIQUE(guild1_id, guild2_id) + ) + """); + + // Tabela ekonomii gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_economy ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild_id INTEGER NOT NULL UNIQUE, + balance REAL DEFAULT 0.0, + level INTEGER DEFAULT 1, + experience REAL DEFAULT 0.0, + max_experience REAL DEFAULT 5000.0, + max_members INTEGER DEFAULT 6, + last_updated TEXT DEFAULT (datetime('now','localtime')), + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela rejestru wkładów gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_contributions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild_id INTEGER NOT NULL, + player_uuid TEXT NOT NULL, + player_name TEXT NOT NULL, + amount REAL NOT NULL, + contribution_type TEXT NOT NULL, + description TEXT, + created_at TEXT DEFAULT (datetime('now','localtime')), + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela dziennika gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_logs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + guild_id INTEGER NOT NULL, + guild_name TEXT NOT NULL, + player_uuid TEXT NOT NULL, + player_name TEXT NOT NULL, + log_type TEXT NOT NULL, + description TEXT NOT NULL, + details TEXT, + created_at TEXT DEFAULT (datetime('now','localtime')), + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + } + + /** + * Utwórz tabele danych MySQL + */ + private void createMySQLTables() { + // Tabela gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guilds ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(50) UNIQUE NOT NULL, + tag VARCHAR(10) UNIQUE, + description TEXT, + leader_uuid VARCHAR(36) NOT NULL, + leader_name VARCHAR(16) NOT NULL, + home_world VARCHAR(100), + home_x DOUBLE, + home_y DOUBLE, + home_z DOUBLE, + home_yaw FLOAT, + home_pitch FLOAT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) + """); + + // Tabela członków gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_members ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild_id INT NOT NULL, + player_uuid VARCHAR(36) NOT NULL, + player_name VARCHAR(16) NOT NULL, + role VARCHAR(20) DEFAULT 'MEMBER', + joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE, + UNIQUE KEY unique_guild_player (guild_id, player_uuid) + ) + """); + + // Tabela aplikacji do gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_applications ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild_id INT NOT NULL, + player_uuid VARCHAR(36) NOT NULL, + player_name VARCHAR(16) NOT NULL, + message TEXT, + status VARCHAR(20) DEFAULT 'PENDING', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela zaproszeń do gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_invites ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild_id INT NOT NULL, + player_uuid VARCHAR(36) NOT NULL, + player_name VARCHAR(16) NOT NULL, + inviter_uuid VARCHAR(36) NOT NULL, + inviter_name VARCHAR(16) NOT NULL, + status VARCHAR(20) DEFAULT 'PENDING', + expires_at TIMESTAMP NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela relacji gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_relations ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild1_id INT NOT NULL, + guild2_id INT NOT NULL, + guild1_name VARCHAR(50) NOT NULL, + guild2_name VARCHAR(50) NOT NULL, + relation_type VARCHAR(20) NOT NULL, + status VARCHAR(20) DEFAULT 'PENDING', + initiator_uuid VARCHAR(36) NOT NULL, + initiator_name VARCHAR(16) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + expires_at TIMESTAMP NULL, + FOREIGN KEY (guild1_id) REFERENCES guilds(id) ON DELETE CASCADE, + FOREIGN KEY (guild2_id) REFERENCES guilds(id) ON DELETE CASCADE, + UNIQUE KEY unique_guild_relation (guild1_id, guild2_id) + ) + """); + + // Tabela ekonomii gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_economy ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild_id INT NOT NULL UNIQUE, + balance DOUBLE DEFAULT 0.0, + level INT DEFAULT 1, + experience DOUBLE DEFAULT 0.0, + max_experience DOUBLE DEFAULT 5000.0, + max_members INT DEFAULT 6, + last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela rejestru wkładów gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_contributions ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild_id INT NOT NULL, + player_uuid VARCHAR(36) NOT NULL, + player_name VARCHAR(16) NOT NULL, + amount DOUBLE NOT NULL, + contribution_type VARCHAR(20) NOT NULL, + description TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + + // Tabela dziennika gildii + executeUpdate(""" + CREATE TABLE IF NOT EXISTS guild_logs ( + id INT AUTO_INCREMENT PRIMARY KEY, + guild_id INT NOT NULL, + guild_name VARCHAR(50) NOT NULL, + player_uuid VARCHAR(36) NOT NULL, + player_name VARCHAR(16) NOT NULL, + log_type VARCHAR(50) NOT NULL, + description TEXT NOT NULL, + details TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE + ) + """); + } + + /** + * Pobierz połączenie z bazą danych + */ + public Connection getConnection() throws SQLException { + if (dataSource == null) { + throw new SQLException("Połączenie z bazą danych nie zostało zainicjowane"); + } + return dataSource.getConnection(); + } + + /** + * Wykonaj operację aktualizacji + */ + public int executeUpdate(String sql, Object... params) { + try (Connection conn = getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + + for (int i = 0; i < params.length; i++) { + stmt.setObject(i + 1, params[i]); + } + + return stmt.executeUpdate(); + + } catch (SQLException e) { + logger.severe("Nie udało się wykonać operacji aktualizacji: " + e.getMessage()); + throw new RuntimeException("Operacja bazy danych nie powiodła się", e); + } + } + + /** + * Asynchronicznie wykonaj operację aktualizacji + */ + public CompletableFuture executeUpdateAsync(String sql, Object... params) { + return CompletableFuture.supplyAsync(() -> executeUpdate(sql, params)); + } + + /** + * Wykonaj operację zapytania + */ + public ResultSet executeQuery(String sql, Object... params) { + try { + Connection conn = getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + + for (int i = 0; i < params.length; i++) { + stmt.setObject(i + 1, params[i]); + } + + return stmt.executeQuery(); + + } catch (SQLException e) { + logger.severe("Nie udało się wykonać operacji zapytania: " + e.getMessage()); + throw new RuntimeException("Operacja bazy danych nie powiodła się", e); + } + } + + /** + * Zamknij połączenie z bazą danych + */ + public void close() { + if (dataSource != null && !dataSource.isClosed()) { + dataSource.close(); + logger.info("Połączenie z bazą danych zostało zamknięte"); + } + } + + /** + * Pobierz typ bazy danych + */ + public DatabaseType getDatabaseType() { + return databaseType; + } + + /** + * Enumeracja typu bazy danych + */ + public enum DatabaseType { + MYSQL, SQLITE + } + + /** + * Sprawdź i dodaj brakujące kolumny + */ + private void checkAndAddMissingColumns() { + try { + if (databaseType == DatabaseType.SQLITE) { + checkAndAddSQLiteColumns(); + } else { + checkAndAddMySQLColumns(); + } + logger.info("Sprawdzanie kolumn bazy danych zakończone"); + } catch (Exception e) { + logger.warning("Błąd podczas sprawdzania kolumn bazy danych: " + e.getMessage()); + } + } + + /** + * Sprawdź i dodaj brakujące kolumny SQLite + */ + private void checkAndAddSQLiteColumns() { + try (Connection conn = getConnection()) { + conn.setAutoCommit(false); // Włącz transakcje dla lepszej wydajności + + // Sprawdź czy tabela guilds ma kolumny związane z domem + try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "home_world")) { + if (!rs.next()) { + // Dodaj kolumny związane z domem + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_world TEXT")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_x REAL")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_y REAL")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_z REAL")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_yaw REAL")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_pitch REAL")) { + stmt.executeUpdate(); + } + logger.info("Dodano kolumny związane z domem do tabeli guilds"); + } + } + + // Sprawdź czy tabela guilds ma kolumny związane z ekonomią + try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "balance")) { + if (!rs.next()) { + // Dodaj kolumny związane z ekonomią + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN balance REAL DEFAULT 0.0")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN level INTEGER DEFAULT 1")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN max_members INTEGER DEFAULT 6")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN frozen INTEGER DEFAULT 0")) { + stmt.executeUpdate(); + } + logger.info("Dodano kolumny związane z ekonomią do tabeli guilds"); + } + } + + conn.commit(); // Zatwierdź transakcję + } catch (SQLException e) { + logger.warning("Błąd podczas sprawdzania kolumn SQLite: " + e.getMessage()); + } + } + + /** + * Sprawdź i dodaj brakujące kolumny MySQL + */ + private void checkAndAddMySQLColumns() { + try (Connection conn = getConnection()) { + conn.setAutoCommit(false); // Włącz transakcje dla lepszej wydajności + + // Sprawdź czy tabela guilds ma kolumny związane z domem + try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "home_world")) { + if (!rs.next()) { + // Dodaj kolumny związane z domem + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_world VARCHAR(100)")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_x DOUBLE")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_y DOUBLE")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_z DOUBLE")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_yaw FLOAT")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN home_pitch FLOAT")) { + stmt.executeUpdate(); + } + logger.info("Dodano kolumny związane z domem do tabeli guilds"); + } + } + + // Sprawdź czy tabela guilds ma kolumny związane z ekonomią + try (ResultSet rs = conn.getMetaData().getColumns(null, null, "guilds", "balance")) { + if (!rs.next()) { + // Dodaj kolumny związane z ekonomią + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN balance DOUBLE DEFAULT 0.0")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN level INT DEFAULT 1")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN max_members INT DEFAULT 6")) { + stmt.executeUpdate(); + } + try (PreparedStatement stmt = conn.prepareStatement("ALTER TABLE guilds ADD COLUMN frozen BOOLEAN DEFAULT FALSE")) { + stmt.executeUpdate(); + } + logger.info("Dodano kolumny związane z ekonomią do tabeli guilds"); + } + } + + conn.commit(); // Zatwierdź transakcję + } catch (SQLException e) { + logger.warning("Błąd podczas sprawdzania kolumn MySQL: " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/guild/core/economy/EconomyManager.java b/src/main/java/com/guild/core/economy/EconomyManager.java index 9fefb3e..78d191b 100644 --- a/src/main/java/com/guild/core/economy/EconomyManager.java +++ b/src/main/java/com/guild/core/economy/EconomyManager.java @@ -1,185 +1,185 @@ -package com.guild.core.economy; - -import com.guild.GuildPlugin; -import net.milkbowl.vault.economy.Economy; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.plugin.RegisteredServiceProvider; - -import java.util.logging.Logger; - -import com.guild.core.utils.CompatibleScheduler; - -/** - * 经济管理器 - 管理Vault经济系统集成 - */ -public class EconomyManager { - - private final GuildPlugin plugin; - private final Logger logger; - private Economy economy; - private boolean vaultAvailable = false; - - public EconomyManager(GuildPlugin plugin) { - this.plugin = plugin; - this.logger = plugin.getLogger(); - setupEconomy(); - } - - /** - * 设置经济系统 - */ - private void setupEconomy() { - if (Bukkit.getPluginManager().getPlugin("Vault") == null) { - logger.warning("Vault插件未找到,经济功能将被禁用!"); - return; - } - - RegisteredServiceProvider rsp = Bukkit.getServicesManager().getRegistration(Economy.class); - if (rsp == null) { - logger.warning("未找到经济服务提供者,经济功能将被禁用!"); - return; - } - - economy = rsp.getProvider(); - if (economy == null) { - logger.warning("经济服务提供者初始化失败,经济功能将被禁用!"); - return; - } - - vaultAvailable = true; - logger.info("经济系统初始化成功!"); - } - - /** - * 检查Vault是否可用 - */ - public boolean isVaultAvailable() { - return vaultAvailable && economy != null; - } - - /** - * 获取玩家余额 - */ - public double getBalance(Player player) { - if (!isVaultAvailable()) { - return 0.0; - } - return economy.getBalance(player); - } - - /** - * 检查玩家是否有足够的余额 - */ - public boolean hasBalance(Player player, double amount) { - if (!isVaultAvailable()) { - return false; - } - return economy.has(player, amount); - } - - /** - * 扣除玩家余额 - */ - public boolean withdraw(Player player, double amount) { - if (!isVaultAvailable()) { - return false; - } - return economy.withdrawPlayer(player, amount).transactionSuccess(); - } - - /** - * 增加玩家余额 - */ - public boolean deposit(Player player, double amount) { - if (!isVaultAvailable()) { - return false; - } - return economy.depositPlayer(player, amount).transactionSuccess(); - } - - /** - * 格式化货币 - */ - public String format(double amount) { - if (!isVaultAvailable()) { - return String.format("%.2f", amount); - } - return economy.format(amount); - } - - /** - * 获取货币名称 - */ - public String getCurrencyName() { - if (!isVaultAvailable()) { - return "金币"; - } - return economy.currencyNamePlural(); - } - - /** - * 获取货币单数名称 - */ - public String getCurrencyNameSingular() { - if (!isVaultAvailable()) { - return "金币"; - } - return economy.currencyNameSingular(); - } - - /** - * 检查玩家是否有足够的余额(异步) - */ - public boolean hasBalanceAsync(Player player, double amount) { - if (!isVaultAvailable()) { - return false; - } - - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - return false; - } - - return economy.has(player, amount); - } - - /** - * 扣除玩家余额(异步) - */ - public boolean withdrawAsync(Player player, double amount) { - if (!isVaultAvailable()) { - return false; - } - - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - return false; - } - - return economy.withdrawPlayer(player, amount).transactionSuccess(); - } - - /** - * 增加玩家余额(异步) - */ - public boolean depositAsync(Player player, double amount) { - if (!isVaultAvailable()) { - return false; - } - - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - return false; - } - - return economy.depositPlayer(player, amount).transactionSuccess(); - } - - /** - * 获取经济实例 - */ - public Economy getEconomy() { - return economy; - } -} +package com.guild.core.economy; + +import com.guild.GuildPlugin; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.RegisteredServiceProvider; + +import java.util.logging.Logger; + +import com.guild.core.utils.CompatibleScheduler; + +/** + * Menedżer ekonomii - zarządza integracją z systemem ekonomii Vault + */ +public class EconomyManager { + + private final GuildPlugin plugin; + private final Logger logger; + private Economy economy; + private boolean vaultAvailable = false; + + public EconomyManager(GuildPlugin plugin) { + this.plugin = plugin; + this.logger = plugin.getLogger(); + setupEconomy(); + } + + /** + * Skonfiguruj system ekonomii + */ + private void setupEconomy() { + if (Bukkit.getPluginManager().getPlugin("Vault") == null) { + logger.warning("Nie znaleziono pluginu Vault, funkcje ekonomii zostaną wyłączone!"); + return; + } + + RegisteredServiceProvider rsp = Bukkit.getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + logger.warning("Nie znaleziono dostawcy usług ekonomii, funkcje ekonomii zostaną wyłączone!"); + return; + } + + economy = rsp.getProvider(); + if (economy == null) { + logger.warning("Inicjalizacja dostawcy usług ekonomii nie powiodła się, funkcje ekonomii zostaną wyłączone!"); + return; + } + + vaultAvailable = true; + logger.info("System ekonomii zainicjalizowany pomyślnie!"); + } + + /** + * Sprawdź czy Vault jest dostępny + */ + public boolean isVaultAvailable() { + return vaultAvailable && economy != null; + } + + /** + * Pobierz saldo gracza + */ + public double getBalance(Player player) { + if (!isVaultAvailable()) { + return 0.0; + } + return economy.getBalance(player); + } + + /** + * Sprawdź czy gracz ma wystarczające środki + */ + public boolean hasBalance(Player player, double amount) { + if (!isVaultAvailable()) { + return false; + } + return economy.has(player, amount); + } + + /** + * Pobierz środki od gracza + */ + public boolean withdraw(Player player, double amount) { + if (!isVaultAvailable()) { + return false; + } + return economy.withdrawPlayer(player, amount).transactionSuccess(); + } + + /** + * Dodaj środki graczowi + */ + public boolean deposit(Player player, double amount) { + if (!isVaultAvailable()) { + return false; + } + return economy.depositPlayer(player, amount).transactionSuccess(); + } + + /** + * Formatuj walutę + */ + public String format(double amount) { + if (!isVaultAvailable()) { + return String.format("%.2f", amount); + } + return economy.format(amount); + } + + /** + * Pobierz nazwę waluty + */ + public String getCurrencyName() { + if (!isVaultAvailable()) { + return "Monety"; + } + return economy.currencyNamePlural(); + } + + /** + * Pobierz nazwę waluty w liczbie pojedynczej + */ + public String getCurrencyNameSingular() { + if (!isVaultAvailable()) { + return "Moneta"; + } + return economy.currencyNameSingular(); + } + + /** + * Sprawdź czy gracz ma wystarczające środki (asynchronicznie) + */ + public boolean hasBalanceAsync(Player player, double amount) { + if (!isVaultAvailable()) { + return false; + } + + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + return false; + } + + return economy.has(player, amount); + } + + /** + * Pobierz środki od gracza (asynchronicznie) + */ + public boolean withdrawAsync(Player player, double amount) { + if (!isVaultAvailable()) { + return false; + } + + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + return false; + } + + return economy.withdrawPlayer(player, amount).transactionSuccess(); + } + + /** + * Dodaj środki graczowi (asynchronicznie) + */ + public boolean depositAsync(Player player, double amount) { + if (!isVaultAvailable()) { + return false; + } + + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + return false; + } + + return economy.depositPlayer(player, amount).transactionSuccess(); + } + + /** + * Pobierz instancję ekonomii + */ + public Economy getEconomy() { + return economy; + } +} diff --git a/src/main/java/com/guild/core/events/EventBus.java b/src/main/java/com/guild/core/events/EventBus.java index d7459f4..d5df543 100644 --- a/src/main/java/com/guild/core/events/EventBus.java +++ b/src/main/java/com/guild/core/events/EventBus.java @@ -1,83 +1,83 @@ -package com.guild.core.events; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.Consumer; -import java.util.logging.Logger; - -/** - * 事件总线 - 统一管理插件内部事件 - */ -public class EventBus { - - private final ConcurrentHashMap, CopyOnWriteArrayList>> listeners = new ConcurrentHashMap<>(); - private final Logger logger = Logger.getLogger(EventBus.class.getName()); - - /** - * 注册事件监听器 - */ - @SuppressWarnings("unchecked") - public void subscribe(Class eventType, Consumer listener) { - listeners.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(listener); - logger.info("注册事件监听器: " + eventType.getSimpleName()); - } - - /** - * 取消注册事件监听器 - */ - @SuppressWarnings("unchecked") - public void unsubscribe(Class eventType, Consumer listener) { - CopyOnWriteArrayList> eventListeners = listeners.get(eventType); - if (eventListeners != null) { - eventListeners.remove(listener); - logger.info("取消注册事件监听器: " + eventType.getSimpleName()); - } - } - - /** - * 发布事件 - */ - @SuppressWarnings("unchecked") - public void publish(T event) { - CopyOnWriteArrayList> eventListeners = listeners.get(event.getClass()); - if (eventListeners != null) { - for (Consumer listener : eventListeners) { - try { - ((Consumer) listener).accept(event); - } catch (Exception e) { - logger.severe("事件监听器执行失败: " + e.getMessage()); - } - } - } - } - - /** - * 异步发布事件 - */ - public void publishAsync(T event) { - new Thread(() -> publish(event)).start(); - } - - /** - * 清除所有监听器 - */ - public void clear() { - listeners.clear(); - logger.info("清除所有事件监听器"); - } - - /** - * 获取监听器数量 - */ - public int getListenerCount(Class eventType) { - CopyOnWriteArrayList> eventListeners = listeners.get(eventType); - return eventListeners != null ? eventListeners.size() : 0; - } - - /** - * 获取总监听器数量 - */ - public int getTotalListenerCount() { - return listeners.values().stream().mapToInt(CopyOnWriteArrayList::size).sum(); - } -} +package com.guild.core.events; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; +import java.util.logging.Logger; + +/** + * Szyna zdarzeń - ujednolicone zarządzanie wewnętrznymi zdarzeniami pluginu + */ +public class EventBus { + + private final ConcurrentHashMap, CopyOnWriteArrayList>> listeners = new ConcurrentHashMap<>(); + private final Logger logger = Logger.getLogger(EventBus.class.getName()); + + /** + * Zarejestruj słuchacza zdarzeń + */ + @SuppressWarnings("unchecked") + public void subscribe(Class eventType, Consumer listener) { + listeners.computeIfAbsent(eventType, k -> new CopyOnWriteArrayList<>()).add(listener); + logger.info("Zarejestrowano słuchacza zdarzeń: " + eventType.getSimpleName()); + } + + /** + * Wyrejestruj słuchacza zdarzeń + */ + @SuppressWarnings("unchecked") + public void unsubscribe(Class eventType, Consumer listener) { + CopyOnWriteArrayList> eventListeners = listeners.get(eventType); + if (eventListeners != null) { + eventListeners.remove(listener); + logger.info("Wyrejestrowano słuchacza zdarzeń: " + eventType.getSimpleName()); + } + } + + /** + * Opublikuj zdarzenie + */ + @SuppressWarnings("unchecked") + public void publish(T event) { + CopyOnWriteArrayList> eventListeners = listeners.get(event.getClass()); + if (eventListeners != null) { + for (Consumer listener : eventListeners) { + try { + ((Consumer) listener).accept(event); + } catch (Exception e) { + logger.severe("Błąd wykonania słuchacza zdarzeń: " + e.getMessage()); + } + } + } + } + + /** + * Opublikuj zdarzenie asynchronicznie + */ + public void publishAsync(T event) { + new Thread(() -> publish(event)).start(); + } + + /** + * Wyczyść wszystkich słuchaczy + */ + public void clear() { + listeners.clear(); + logger.info("Wyczyszczono wszystkich słuchaczy zdarzeń"); + } + + /** + * Pobierz liczbę słuchaczy + */ + public int getListenerCount(Class eventType) { + CopyOnWriteArrayList> eventListeners = listeners.get(eventType); + return eventListeners != null ? eventListeners.size() : 0; + } + + /** + * Pobierz całkowitą liczbę słuchaczy + */ + public int getTotalListenerCount() { + return listeners.values().stream().mapToInt(CopyOnWriteArrayList::size).sum(); + } +} diff --git a/src/main/java/com/guild/core/gui/GUI.java b/src/main/java/com/guild/core/gui/GUI.java index d58b70b..97846df 100644 --- a/src/main/java/com/guild/core/gui/GUI.java +++ b/src/main/java/com/guild/core/gui/GUI.java @@ -1,60 +1,60 @@ -package com.guild.core.gui; - -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -/** - * GUI接口 - 定义GUI的基本方法 - */ -public interface GUI { - - /** - * 获取GUI标题 - */ - String getTitle(); - - /** - * 获取GUI大小(必须是9的倍数) - */ - int getSize(); - - /** - * 设置GUI内容 - */ - void setupInventory(Inventory inventory); - - /** - * 处理GUI点击事件 - */ - void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType); - - /** - * 处理GUI关闭事件 - */ - default void onClose(Player player) { - // 默认实现为空 - } - - /** - * 刷新GUI - */ - default void refresh(Player player) { - // 默认实现为空 - } - - /** - * 检查GUI是否有效 - */ - default boolean isValid() { - return true; - } - - /** - * 获取GUI类型标识 - */ - default String getGuiType() { - return this.getClass().getSimpleName(); - } -} +package com.guild.core.gui; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +/** + * Interfejs GUI - definiuje podstawowe metody GUI + */ +public interface GUI { + + /** + * Pobierz tytuł GUI + */ + String getTitle(); + + /** + * Pobierz rozmiar GUI (musi być wielokrotnością 9) + */ + int getSize(); + + /** + * Ustaw zawartość GUI + */ + void setupInventory(Inventory inventory); + + /** + * Obsłuż zdarzenie kliknięcia GUI + */ + void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType); + + /** + * Obsłuż zdarzenie zamknięcia GUI + */ + default void onClose(Player player) { + // Domyślna implementacja jest pusta + } + + /** + * Odśwież GUI + */ + default void refresh(Player player) { + // Domyślna implementacja jest pusta + } + + /** + * Sprawdź, czy GUI jest ważne + */ + default boolean isValid() { + return true; + } + + /** + * Pobierz identyfikator typu GUI + */ + default String getGuiType() { + return this.getClass().getSimpleName(); + } +} diff --git a/src/main/java/com/guild/core/gui/GUIManager.java b/src/main/java/com/guild/core/gui/GUIManager.java index f78cc48..3c60c98 100644 --- a/src/main/java/com/guild/core/gui/GUIManager.java +++ b/src/main/java/com/guild/core/gui/GUIManager.java @@ -1,347 +1,347 @@ -package com.guild.core.gui; - -import com.guild.GuildPlugin; -import com.guild.gui.GuildNameInputGUI; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.logging.Logger; -import java.util.function.Function; - -import com.guild.core.utils.CompatibleScheduler; - -/** - * GUI管理器 - 管理所有GUI界面 - */ -public class GUIManager implements Listener { - - private final GuildPlugin plugin; - private final Logger logger; - private final Map openGuis = new HashMap<>(); - private final Map> inputModes = new HashMap<>(); - private final Map lastClickTime = new HashMap<>(); // 防止快速点击 - - public GUIManager(GuildPlugin plugin) { - this.plugin = plugin; - this.logger = plugin.getLogger(); - } - - /** - * 初始化GUI管理器 - */ - public void initialize() { - plugin.getServer().getPluginManager().registerEvents(this, plugin); - logger.info("GUI管理器初始化完成"); - } - - /** - * 打开GUI - */ - public void openGUI(Player player, GUI gui) { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, () -> openGUI(player, gui)); - return; - } - - try { - // 关闭玩家当前打开的GUI - closeGUI(player); - - // 创建新的GUI - Inventory inventory = Bukkit.createInventory(null, gui.getSize(), gui.getTitle()); - - // 设置GUI内容 - gui.setupInventory(inventory); - - // 打开GUI - player.openInventory(inventory); - - // 记录打开的GUI - openGuis.put(player.getUniqueId(), gui); - - logger.info("玩家 " + player.getName() + " 打开了GUI: " + gui.getClass().getSimpleName()); - } catch (Exception e) { - logger.severe("打开GUI时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 关闭GUI - */ - public void closeGUI(Player player) { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, () -> closeGUI(player)); - return; - } - - try { - GUI gui = openGuis.remove(player.getUniqueId()); - if (gui != null) { - // 关闭库存 - if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory() != null) { - player.closeInventory(); - } - - logger.info("玩家 " + player.getName() + " 关闭了GUI: " + gui.getClass().getSimpleName()); - } - } catch (Exception e) { - logger.severe("关闭GUI时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 获取玩家当前打开的GUI - */ - public GUI getOpenGUI(Player player) { - return openGuis.get(player.getUniqueId()); - } - - /** - * 检查玩家是否打开了GUI - */ - public boolean hasOpenGUI(Player player) { - return openGuis.containsKey(player.getUniqueId()); - } - - /** - * 处理GUI点击事件 - */ - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - if (!(event.getWhoClicked() instanceof Player player)) { - return; - } - - GUI gui = openGuis.get(player.getUniqueId()); - if (gui == null) { - return; - } - - // 防止快速点击 - long currentTime = System.currentTimeMillis(); - Long lastClick = lastClickTime.get(player.getUniqueId()); - if (lastClick != null && currentTime - lastClick < 200) { // 200ms防抖 - event.setCancelled(true); - return; - } - lastClickTime.put(player.getUniqueId(), currentTime); - - try { - // 阻止玩家移动物品 - event.setCancelled(true); - - // 处理GUI点击 - int slot = event.getRawSlot(); - ItemStack clickedItem = event.getCurrentItem(); - - // 添加调试日志 - logger.info("玩家 " + player.getName() + " 点击了GUI: " + gui.getClass().getSimpleName() + " 槽位: " + slot); - - // 处理所有点击,包括空物品的点击 - gui.onClick(player, slot, clickedItem, event.getClick()); - } catch (Exception e) { - logger.severe("处理GUI点击时发生错误: " + e.getMessage()); - e.printStackTrace(); - // 发生错误时关闭GUI - closeGUI(player); - } - } - - /** - * 处理GUI关闭事件 - */ - @EventHandler - public void onInventoryClose(InventoryCloseEvent event) { - if (!(event.getPlayer() instanceof Player player)) { - return; - } - - try { - GUI gui = openGuis.remove(player.getUniqueId()); - if (gui != null) { - // 只有在玩家确实在输入模式时才清理 - if (inputModes.containsKey(player.getUniqueId())) { - clearInputMode(player); - } - - gui.onClose(player); - logger.info("玩家 " + player.getName() + " 关闭了GUI: " + gui.getClass().getSimpleName()); - } - } catch (Exception e) { - logger.severe("处理GUI关闭时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 刷新GUI - */ - public void refreshGUI(Player player) { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, () -> refreshGUI(player)); - return; - } - - try { - GUI gui = openGuis.get(player.getUniqueId()); - if (gui != null) { - // 关闭当前GUI - closeGUI(player); - - // 重新打开GUI - openGUI(player, gui); - - logger.info("玩家 " + player.getName() + " 的GUI已刷新: " + gui.getClass().getSimpleName()); - } - } catch (Exception e) { - logger.severe("刷新GUI时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 关闭所有GUI - */ - public void closeAllGUIs() { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, this::closeAllGUIs); - return; - } - - try { - for (UUID playerUuid : openGuis.keySet()) { - Player player = Bukkit.getPlayer(playerUuid); - if (player != null && player.isOnline()) { - closeGUI(player); - } - } - openGuis.clear(); - logger.info("已关闭所有GUI"); - } catch (Exception e) { - logger.severe("关闭所有GUI时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 获取打开的GUI数量 - */ - public int getOpenGUICount() { - return openGuis.size(); - } - - /** - * 设置玩家输入模式 - */ - public void setInputMode(Player player, Function inputHandler) { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, () -> setInputMode(player, inputHandler)); - return; - } - - try { - inputModes.put(player.getUniqueId(), inputHandler); - logger.info("玩家 " + player.getName() + " 进入输入模式"); - } catch (Exception e) { - logger.severe("设置输入模式时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 设置玩家输入模式(带GUI对象) - */ - public void setInputMode(Player player, String mode, GUI gui) { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, () -> setInputMode(player, mode, gui)); - return; - } - - try { - // 为工会名称输入创建特殊的输入处理器 - if ("guild_name_input".equals(mode) && gui instanceof GuildNameInputGUI) { - GuildNameInputGUI nameInputGUI = (GuildNameInputGUI) gui; - inputModes.put(player.getUniqueId(), input -> { - if ("取消".equals(input.trim())) { - nameInputGUI.handleCancel(player); - return true; - } - nameInputGUI.handleInputComplete(player, input); - return true; - }); - logger.info("玩家 " + player.getName() + " 进入工会名称输入模式"); - } else { - logger.warning("未知的输入模式: " + mode); - } - } catch (Exception e) { - logger.severe("设置输入模式时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 清除玩家输入模式 - */ - public void clearInputMode(Player player) { - // 确保在主线程中执行 - if (!CompatibleScheduler.isPrimaryThread()) { - CompatibleScheduler.runTask(plugin, () -> clearInputMode(player)); - return; - } - - try { - inputModes.remove(player.getUniqueId()); - logger.info("玩家 " + player.getName() + " 退出输入模式"); - } catch (Exception e) { - logger.severe("清除输入模式时发生错误: " + e.getMessage()); - e.printStackTrace(); - } - } - - /** - * 检查玩家是否在输入模式 - */ - public boolean isInInputMode(Player player) { - return inputModes.containsKey(player.getUniqueId()); - } - - /** - * 处理玩家输入 - */ - public boolean handleInput(Player player, String input) { - try { - Function handler = inputModes.get(player.getUniqueId()); - if (handler != null) { - boolean result = handler.apply(input); - if (result) { - inputModes.remove(player.getUniqueId()); - } - return result; - } - return false; - } catch (Exception e) { - logger.severe("处理玩家输入时发生错误: " + e.getMessage()); - e.printStackTrace(); - // 发生错误时清除输入模式 - clearInputMode(player); - return false; - } - } -} +package com.guild.core.gui; + +import com.guild.GuildPlugin; +import com.guild.gui.GuildNameInputGUI; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.logging.Logger; +import java.util.function.Function; + +import com.guild.core.utils.CompatibleScheduler; + +/** + * Menedżer GUI - zarządza wszystkimi interfejsami GUI + */ +public class GUIManager implements Listener { + + private final GuildPlugin plugin; + private final Logger logger; + private final Map openGuis = new HashMap<>(); + private final Map> inputModes = new HashMap<>(); + private final Map lastClickTime = new HashMap<>(); // Zapobieganie szybkiemu klikaniu + + public GUIManager(GuildPlugin plugin) { + this.plugin = plugin; + this.logger = plugin.getLogger(); + } + + /** + * Zainicjuj menedżera GUI + */ + public void initialize() { + plugin.getServer().getPluginManager().registerEvents(this, plugin); + logger.info("Menedżer GUI zainicjalizowany pomyślnie"); + } + + /** + * Otwórz GUI + */ + public void openGUI(Player player, GUI gui) { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, () -> openGUI(player, gui)); + return; + } + + try { + // Zamknij aktualnie otwarte GUI gracza + closeGUI(player); + + // Utwórz nowe GUI + Inventory inventory = Bukkit.createInventory(null, gui.getSize(), gui.getTitle()); + + // Ustaw zawartość GUI + gui.setupInventory(inventory); + + // Otwórz GUI + player.openInventory(inventory); + + // Zarejestruj otwarte GUI + openGuis.put(player.getUniqueId(), gui); + + logger.info("Gracz " + player.getName() + " otworzył GUI: " + gui.getClass().getSimpleName()); + } catch (Exception e) { + logger.severe("Błąd podczas otwierania GUI: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Zamknij GUI + */ + public void closeGUI(Player player) { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, () -> closeGUI(player)); + return; + } + + try { + GUI gui = openGuis.remove(player.getUniqueId()); + if (gui != null) { + // Zamknij ekwipunek + if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory() != null) { + player.closeInventory(); + } + + logger.info("Gracz " + player.getName() + " zamknął GUI: " + gui.getClass().getSimpleName()); + } + } catch (Exception e) { + logger.severe("Błąd podczas zamykania GUI: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Pobierz aktualnie otwarte GUI gracza + */ + public GUI getOpenGUI(Player player) { + return openGuis.get(player.getUniqueId()); + } + + /** + * Sprawdź, czy gracz ma otwarte GUI + */ + public boolean hasOpenGUI(Player player) { + return openGuis.containsKey(player.getUniqueId()); + } + + /** + * Obsłuż zdarzenie kliknięcia w ekwipunku + */ + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + if (!(event.getWhoClicked() instanceof Player player)) { + return; + } + + GUI gui = openGuis.get(player.getUniqueId()); + if (gui == null) { + return; + } + + // Zapobiegaj szybkiemu klikaniu + long currentTime = System.currentTimeMillis(); + Long lastClick = lastClickTime.get(player.getUniqueId()); + if (lastClick != null && currentTime - lastClick < 200) { // 200ms anti-shake + event.setCancelled(true); + return; + } + lastClickTime.put(player.getUniqueId(), currentTime); + + try { + // Zapobiegaj przenoszeniu przedmiotów przez gracza + event.setCancelled(true); + + // Obsłuż kliknięcie GUI + int slot = event.getRawSlot(); + ItemStack clickedItem = event.getCurrentItem(); + + // Dodaj log debugowania + logger.info("Gracz " + player.getName() + " kliknął GUI: " + gui.getClass().getSimpleName() + " slot: " + slot); + + // Obsłuż wszystkie kliknięcia, w tym kliknięcia pustych przedmiotów + gui.onClick(player, slot, clickedItem, event.getClick()); + } catch (Exception e) { + logger.severe("Błąd podczas obsługi kliknięcia GUI: " + e.getMessage()); + e.printStackTrace(); + // Zamknij GUI w przypadku błędu + closeGUI(player); + } + } + + /** + * Obsłuż zdarzenie zamknięcia ekwipunku + */ + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + if (!(event.getPlayer() instanceof Player player)) { + return; + } + + try { + GUI gui = openGuis.remove(player.getUniqueId()); + if (gui != null) { + // Czyść tylko jeśli gracz jest w trybie wprowadzania + if (inputModes.containsKey(player.getUniqueId())) { + clearInputMode(player); + } + + gui.onClose(player); + logger.info("Gracz " + player.getName() + " zamknął GUI: " + gui.getClass().getSimpleName()); + } + } catch (Exception e) { + logger.severe("Błąd podczas zamykania GUI: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Odśwież GUI + */ + public void refreshGUI(Player player) { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, () -> refreshGUI(player)); + return; + } + + try { + GUI gui = openGuis.get(player.getUniqueId()); + if (gui != null) { + // Zamknij bieżące GUI + closeGUI(player); + + // Otwórz GUI ponownie + openGUI(player, gui); + + logger.info("Odświeżono GUI dla gracza " + player.getName() + ": " + gui.getClass().getSimpleName()); + } + } catch (Exception e) { + logger.severe("Błąd podczas odświeżania GUI: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Zamknij wszystkie GUI + */ + public void closeAllGUIs() { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, this::closeAllGUIs); + return; + } + + try { + for (UUID playerUuid : openGuis.keySet()) { + Player player = Bukkit.getPlayer(playerUuid); + if (player != null && player.isOnline()) { + closeGUI(player); + } + } + openGuis.clear(); + logger.info("Zamknięto wszystkie GUI"); + } catch (Exception e) { + logger.severe("Błąd podczas zamykania wszystkich GUI: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Pobierz liczbę otwartych GUI + */ + public int getOpenGUICount() { + return openGuis.size(); + } + + /** + * Ustaw tryb wprowadzania dla gracza + */ + public void setInputMode(Player player, Function inputHandler) { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, () -> setInputMode(player, inputHandler)); + return; + } + + try { + inputModes.put(player.getUniqueId(), inputHandler); + logger.info("Gracz " + player.getName() + " wszedł w tryb wprowadzania"); + } catch (Exception e) { + logger.severe("Błąd podczas ustawiania trybu wprowadzania: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Ustaw tryb wprowadzania dla gracza (z obiektem GUI) + */ + public void setInputMode(Player player, String mode, GUI gui) { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, () -> setInputMode(player, mode, gui)); + return; + } + + try { + // Utwórz specjalny handler wejścia dla wprowadzania nazwy gildii + if ("guild_name_input".equals(mode) && gui instanceof GuildNameInputGUI) { + GuildNameInputGUI nameInputGUI = (GuildNameInputGUI) gui; + inputModes.put(player.getUniqueId(), input -> { + if ("Anuluj".equals(input.trim()) || "anuluj".equals(input.trim()) || "cancel".equals(input.trim())) { + nameInputGUI.handleCancel(player); + return true; + } + nameInputGUI.handleInputComplete(player, input); + return true; + }); + logger.info("Gracz " + player.getName() + " wszedł w tryb wprowadzania nazwy gildii"); + } else { + logger.warning("Nieznany tryb wprowadzania: " + mode); + } + } catch (Exception e) { + logger.severe("Błąd podczas ustawiania trybu wprowadzania: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Wyczyść tryb wprowadzania dla gracza + */ + public void clearInputMode(Player player) { + // Upewnij się, że wykonujesz w głównym wątku + if (!CompatibleScheduler.isPrimaryThread()) { + CompatibleScheduler.runTask(plugin, () -> clearInputMode(player)); + return; + } + + try { + inputModes.remove(player.getUniqueId()); + logger.info("Gracz " + player.getName() + " opuścił tryb wprowadzania"); + } catch (Exception e) { + logger.severe("Błąd podczas czyszczenia trybu wprowadzania: " + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * Sprawdź, czy gracz jest w trybie wprowadzania + */ + public boolean isInInputMode(Player player) { + return inputModes.containsKey(player.getUniqueId()); + } + + /** + * Obsłuż wejście gracza + */ + public boolean handleInput(Player player, String input) { + try { + Function handler = inputModes.get(player.getUniqueId()); + if (handler != null) { + boolean result = handler.apply(input); + if (result) { + inputModes.remove(player.getUniqueId()); + } + return result; + } + return false; + } catch (Exception e) { + logger.severe("Błąd podczas obsługi wejścia gracza: " + e.getMessage()); + e.printStackTrace(); + // Wyczyść tryb wprowadzania w przypadku błędu + clearInputMode(player); + return false; + } + } +} diff --git a/src/main/java/com/guild/core/permissions/PermissionManager.java b/src/main/java/com/guild/core/permissions/PermissionManager.java index 755ad9b..940e11a 100644 --- a/src/main/java/com/guild/core/permissions/PermissionManager.java +++ b/src/main/java/com/guild/core/permissions/PermissionManager.java @@ -1,309 +1,309 @@ -package com.guild.core.permissions; - -import com.guild.GuildPlugin; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import com.guild.services.GuildService; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.logging.Logger; - -/** - * 权限管理器 - 提供插件独立的权限功能 - */ -public class PermissionManager { - - private final GuildPlugin plugin; - private final Logger logger; - private final Map playerPermissions = new HashMap<>(); - // 配置驱动的角色权限矩阵 - private RolePermissions defaultPermissions; - private RolePermissions memberPermissions; - private RolePermissions officerPermissions; - private RolePermissions leaderPermissions; - - public PermissionManager(GuildPlugin plugin) { - this.plugin = plugin; - this.logger = plugin.getLogger(); - reloadFromConfig(); - } - - /** - * 检查玩家是否有指定权限 - */ - public boolean hasPermission(Player player, String permission) { - if (player == null || permission == null) { - return false; - } - - // 首先检查Bukkit权限系统 - if (player.hasPermission(permission)) { - return true; - } - - // 检查插件内置权限 - return hasInternalPermission(player, permission); - } - - /** - * 检查插件内置权限 - */ - private boolean hasInternalPermission(Player player, String permission) { - UUID playerUuid = player.getUniqueId(); - - // 获取玩家权限 - PlayerPermissions permissions = getPlayerPermissions(playerUuid); - - // 检查具体权限 - switch (permission) { - case "guild.use": - return true; // 所有玩家都可以使用工会系统 - - case "guild.create": - return permissions.canCreateGuild(); - - case "guild.invite": - return permissions.canInviteMembers(); - - case "guild.kick": - return permissions.canKickMembers(); - - case "guild.promote": - return permissions.canPromoteMembers(); - - case "guild.demote": - return permissions.canDemoteMembers(); - - case "guild.delete": - return permissions.canDeleteGuild(); - - case "guild.admin": - return permissions.isAdmin(); - - default: - return false; - } - } - - /** - * 获取玩家权限 - */ - private PlayerPermissions getPlayerPermissions(UUID playerUuid) { - return playerPermissions.computeIfAbsent(playerUuid, uuid -> { - PlayerPermissions resolved = new PlayerPermissions(); - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - GuildMember.Role role = null; - if (guildService != null) { - Guild guild = guildService.getPlayerGuild(uuid); - if (guild != null) { - GuildMember member = guildService.getGuildMember(uuid); - if (member != null) { - role = member.getRole(); - } - } - } - RolePermissions rp = resolveRolePermissions(role); - resolved.setCanCreateGuild(rp.canCreate); - resolved.setCanInviteMembers(rp.canInvite); - resolved.setCanKickMembers(rp.canKick); - resolved.setCanDeleteGuild(rp.canDelete); - resolved.setCanPromoteMembers(rp.canPromote); - resolved.setCanDemoteMembers(rp.canDemote); - // isAdmin 仍由 Bukkit 权限系统控制 - return resolved; - }); - } - - private RolePermissions resolveRolePermissions(GuildMember.Role role) { - if (role == null) { - return defaultPermissions; - } - switch (role) { - case LEADER: - return leaderPermissions; - case OFFICER: - return officerPermissions; - case MEMBER: - default: - return memberPermissions; - } - } - - /** - * 更新玩家权限(当工会状态改变时调用) - */ - public void updatePlayerPermissions(UUID playerUuid) { - playerPermissions.remove(playerUuid); - // 重新计算权限 - getPlayerPermissions(playerUuid); - } - - /** - * 从配置重载权限矩阵,并清空缓存 - */ - public void reloadFromConfig() { - FileConfiguration cfg = plugin.getConfigManager().getMainConfig(); - this.defaultPermissions = readRolePermissions(cfg, "permissions.default", - new RolePermissions(false, false, false, false, false, false)); - this.memberPermissions = readRolePermissions(cfg, "permissions.member", - new RolePermissions(true, false, false, false, false, false)); - this.officerPermissions = readRolePermissions(cfg, "permissions.officer", - new RolePermissions(true, true, true, false, false, false)); - // leader 未配置时,采用全开作为回退 - RolePermissions leaderFallback = new RolePermissions(true, true, true, true, true, true); - this.leaderPermissions = readRolePermissions(cfg, "permissions.leader", leaderFallback); - playerPermissions.clear(); - logger.info("权限矩阵已从配置重载,并清空玩家权限缓存"); - } - - private RolePermissions readRolePermissions(FileConfiguration cfg, String path, RolePermissions fallback) { - if (cfg == null) return fallback; - boolean canCreate = cfg.getBoolean(path + ".can-create", fallback.canCreate); - boolean canInvite = cfg.getBoolean(path + ".can-invite", fallback.canInvite); - boolean canKick = cfg.getBoolean(path + ".can-kick", fallback.canKick); - boolean canPromote = cfg.getBoolean(path + ".can-promote", fallback.canPromote); - boolean canDemote = cfg.getBoolean(path + ".can-demote", fallback.canDemote); - boolean canDelete = cfg.getBoolean(path + ".can-delete", fallback.canDelete); - return new RolePermissions(canCreate, canInvite, canKick, canPromote, canDemote, canDelete); - } - - /** - * 检查玩家是否可以邀请成员 - */ - public boolean canInviteMembers(Player player) { - if (!hasPermission(player, "guild.invite")) { - return false; - } - - // 检查玩家是否在工会中 - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - return false; - } - - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - return false; - } - - return getPlayerPermissions(player.getUniqueId()).canInviteMembers(); - } - - /** - * 检查玩家是否可以踢出成员 - */ - public boolean canKickMembers(Player player) { - if (!hasPermission(player, "guild.kick")) { - return false; - } - - // 检查玩家是否在工会中 - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - return false; - } - - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - return false; - } - - return getPlayerPermissions(player.getUniqueId()).canKickMembers(); - } - - /** - * 检查玩家是否可以删除工会 - */ - public boolean canDeleteGuild(Player player) { - if (!hasPermission(player, "guild.delete")) { - return false; - } - - // 检查玩家是否在工会中 - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - return false; - } - - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) { - return false; - } - - return getPlayerPermissions(player.getUniqueId()).canDeleteGuild(); - } - - /** - * 检查玩家是否可以创建工会 - */ - public boolean canCreateGuild(Player player) { - if (!hasPermission(player, "guild.create")) { - return false; - } - - // 检查玩家是否已有工会 - GuildService guildService = plugin.getServiceContainer().get(GuildService.class); - if (guildService == null) { - return false; - } - - return guildService.getPlayerGuild(player.getUniqueId()) == null; - } - - /** - * 玩家权限类 - */ - private static class PlayerPermissions { - private boolean canCreateGuild = false; - private boolean canInviteMembers = false; - private boolean canKickMembers = false; - private boolean canDeleteGuild = false; - private boolean canPromoteMembers = false; - private boolean canDemoteMembers = false; - private boolean isAdmin = false; - - // Getters and Setters - public boolean canCreateGuild() { return canCreateGuild; } - public void setCanCreateGuild(boolean canCreateGuild) { this.canCreateGuild = canCreateGuild; } - - public boolean canInviteMembers() { return canInviteMembers; } - public void setCanInviteMembers(boolean canInviteMembers) { this.canInviteMembers = canInviteMembers; } - - public boolean canKickMembers() { return canKickMembers; } - public void setCanKickMembers(boolean canKickMembers) { this.canKickMembers = canKickMembers; } - - public boolean canDeleteGuild() { return canDeleteGuild; } - public void setCanDeleteGuild(boolean canDeleteGuild) { this.canDeleteGuild = canDeleteGuild; } - - public boolean canPromoteMembers() { return canPromoteMembers; } - public void setCanPromoteMembers(boolean canPromoteMembers) { this.canPromoteMembers = canPromoteMembers; } - - public boolean canDemoteMembers() { return canDemoteMembers; } - public void setCanDemoteMembers(boolean canDemoteMembers) { this.canDemoteMembers = canDemoteMembers; } - - public boolean isAdmin() { return isAdmin; } - public void setAdmin(boolean admin) { isAdmin = admin; } - } - - // 角色权限矩阵(配置驱动) - private static class RolePermissions { - final boolean canCreate; - final boolean canInvite; - final boolean canKick; - final boolean canPromote; - final boolean canDemote; - final boolean canDelete; - RolePermissions(boolean canCreate, boolean canInvite, boolean canKick, boolean canPromote, boolean canDemote, boolean canDelete) { - this.canCreate = canCreate; - this.canInvite = canInvite; - this.canKick = canKick; - this.canPromote = canPromote; - this.canDemote = canDemote; - this.canDelete = canDelete; - } - } -} +package com.guild.core.permissions; + +import com.guild.GuildPlugin; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import com.guild.services.GuildService; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.logging.Logger; + +/** + * Menedżer uprawnień - zapewnia niezależne funkcje uprawnień dla pluginu + */ +public class PermissionManager { + + private final GuildPlugin plugin; + private final Logger logger; + private final Map playerPermissions = new HashMap<>(); + // Macierz uprawnień ról (sterowana konfiguracją) + private RolePermissions defaultPermissions; + private RolePermissions memberPermissions; + private RolePermissions officerPermissions; + private RolePermissions leaderPermissions; + + public PermissionManager(GuildPlugin plugin) { + this.plugin = plugin; + this.logger = plugin.getLogger(); + reloadFromConfig(); + } + + /** + * Sprawdź, czy gracz ma określone uprawnienia + */ + public boolean hasPermission(Player player, String permission) { + if (player == null || permission == null) { + return false; + } + + // Najpierw sprawdź system uprawnień Bukkit + if (player.hasPermission(permission)) { + return true; + } + + // Sprawdź wbudowane uprawnienia pluginu + return hasInternalPermission(player, permission); + } + + /** + * Sprawdź wbudowane uprawnienia pluginu + */ + private boolean hasInternalPermission(Player player, String permission) { + UUID playerUuid = player.getUniqueId(); + + // Pobierz uprawnienia gracza + PlayerPermissions permissions = getPlayerPermissions(playerUuid); + + // Sprawdź konkretne uprawnienia + switch (permission) { + case "guild.use": + return true; // Wszyscy gracze mogą używać systemu gildii + + case "guild.create": + return permissions.canCreateGuild(); + + case "guild.invite": + return permissions.canInviteMembers(); + + case "guild.kick": + return permissions.canKickMembers(); + + case "guild.promote": + return permissions.canPromoteMembers(); + + case "guild.demote": + return permissions.canDemoteMembers(); + + case "guild.delete": + return permissions.canDeleteGuild(); + + case "guild.admin": + return permissions.isAdmin(); + + default: + return false; + } + } + + /** + * Pobierz uprawnienia gracza + */ + private PlayerPermissions getPlayerPermissions(UUID playerUuid) { + return playerPermissions.computeIfAbsent(playerUuid, uuid -> { + PlayerPermissions resolved = new PlayerPermissions(); + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + GuildMember.Role role = null; + if (guildService != null) { + Guild guild = guildService.getPlayerGuild(uuid); + if (guild != null) { + GuildMember member = guildService.getGuildMember(uuid); + if (member != null) { + role = member.getRole(); + } + } + } + RolePermissions rp = resolveRolePermissions(role); + resolved.setCanCreateGuild(rp.canCreate); + resolved.setCanInviteMembers(rp.canInvite); + resolved.setCanKickMembers(rp.canKick); + resolved.setCanDeleteGuild(rp.canDelete); + resolved.setCanPromoteMembers(rp.canPromote); + resolved.setCanDemoteMembers(rp.canDemote); + // isAdmin jest nadal kontrolowane przez system uprawnień Bukkit + return resolved; + }); + } + + private RolePermissions resolveRolePermissions(GuildMember.Role role) { + if (role == null) { + return defaultPermissions; + } + switch (role) { + case LEADER: + return leaderPermissions; + case OFFICER: + return officerPermissions; + case MEMBER: + default: + return memberPermissions; + } + } + + /** + * Zaktualizuj uprawnienia gracza (wywoływane przy zmianie statusu gildii) + */ + public void updatePlayerPermissions(UUID playerUuid) { + playerPermissions.remove(playerUuid); + // Ponownie oblicz uprawnienia + getPlayerPermissions(playerUuid); + } + + /** + * Przeładuj macierz uprawnień z konfiguracji i wyczyść pamięć podręczną + */ + public void reloadFromConfig() { + FileConfiguration cfg = plugin.getConfigManager().getMainConfig(); + this.defaultPermissions = readRolePermissions(cfg, "permissions.default", + new RolePermissions(false, false, false, false, false, false)); + this.memberPermissions = readRolePermissions(cfg, "permissions.member", + new RolePermissions(true, false, false, false, false, false)); + this.officerPermissions = readRolePermissions(cfg, "permissions.officer", + new RolePermissions(true, true, true, false, false, false)); + // Jeśli lider nie jest skonfigurowany, użyj pełnych uprawnień jako rezerwy + RolePermissions leaderFallback = new RolePermissions(true, true, true, true, true, true); + this.leaderPermissions = readRolePermissions(cfg, "permissions.leader", leaderFallback); + playerPermissions.clear(); + logger.info("Macierz uprawnień została przeładowana z konfiguracji, a pamięć podręczna uprawnień graczy została wyczyszczona"); + } + + private RolePermissions readRolePermissions(FileConfiguration cfg, String path, RolePermissions fallback) { + if (cfg == null) return fallback; + boolean canCreate = cfg.getBoolean(path + ".can-create", fallback.canCreate); + boolean canInvite = cfg.getBoolean(path + ".can-invite", fallback.canInvite); + boolean canKick = cfg.getBoolean(path + ".can-kick", fallback.canKick); + boolean canPromote = cfg.getBoolean(path + ".can-promote", fallback.canPromote); + boolean canDemote = cfg.getBoolean(path + ".can-demote", fallback.canDemote); + boolean canDelete = cfg.getBoolean(path + ".can-delete", fallback.canDelete); + return new RolePermissions(canCreate, canInvite, canKick, canPromote, canDemote, canDelete); + } + + /** + * Sprawdź, czy gracz może zapraszać członków + */ + public boolean canInviteMembers(Player player) { + if (!hasPermission(player, "guild.invite")) { + return false; + } + + // Sprawdź, czy gracz jest w gildii + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + return false; + } + + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + return false; + } + + return getPlayerPermissions(player.getUniqueId()).canInviteMembers(); + } + + /** + * Sprawdź, czy gracz może wyrzucać członków + */ + public boolean canKickMembers(Player player) { + if (!hasPermission(player, "guild.kick")) { + return false; + } + + // Sprawdź, czy gracz jest w gildii + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + return false; + } + + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + return false; + } + + return getPlayerPermissions(player.getUniqueId()).canKickMembers(); + } + + /** + * Sprawdź, czy gracz może usunąć gildię + */ + public boolean canDeleteGuild(Player player) { + if (!hasPermission(player, "guild.delete")) { + return false; + } + + // Sprawdź, czy gracz jest w gildii + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + return false; + } + + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) { + return false; + } + + return getPlayerPermissions(player.getUniqueId()).canDeleteGuild(); + } + + /** + * Sprawdź, czy gracz może stworzyć gildię + */ + public boolean canCreateGuild(Player player) { + if (!hasPermission(player, "guild.create")) { + return false; + } + + // Sprawdź, czy gracz ma już gildię + GuildService guildService = plugin.getServiceContainer().get(GuildService.class); + if (guildService == null) { + return false; + } + + return guildService.getPlayerGuild(player.getUniqueId()) == null; + } + + /** + * Klasa uprawnień gracza + */ + private static class PlayerPermissions { + private boolean canCreateGuild = false; + private boolean canInviteMembers = false; + private boolean canKickMembers = false; + private boolean canDeleteGuild = false; + private boolean canPromoteMembers = false; + private boolean canDemoteMembers = false; + private boolean isAdmin = false; + + // Getters and Setters + public boolean canCreateGuild() { return canCreateGuild; } + public void setCanCreateGuild(boolean canCreateGuild) { this.canCreateGuild = canCreateGuild; } + + public boolean canInviteMembers() { return canInviteMembers; } + public void setCanInviteMembers(boolean canInviteMembers) { this.canInviteMembers = canInviteMembers; } + + public boolean canKickMembers() { return canKickMembers; } + public void setCanKickMembers(boolean canKickMembers) { this.canKickMembers = canKickMembers; } + + public boolean canDeleteGuild() { return canDeleteGuild; } + public void setCanDeleteGuild(boolean canDeleteGuild) { this.canDeleteGuild = canDeleteGuild; } + + public boolean canPromoteMembers() { return canPromoteMembers; } + public void setCanPromoteMembers(boolean canPromoteMembers) { this.canPromoteMembers = canPromoteMembers; } + + public boolean canDemoteMembers() { return canDemoteMembers; } + public void setCanDemoteMembers(boolean canDemoteMembers) { this.canDemoteMembers = canDemoteMembers; } + + public boolean isAdmin() { return isAdmin; } + public void setAdmin(boolean admin) { isAdmin = admin; } + } + + // Macierz uprawnień ról (sterowana konfiguracją) + private static class RolePermissions { + final boolean canCreate; + final boolean canInvite; + final boolean canKick; + final boolean canPromote; + final boolean canDemote; + final boolean canDelete; + RolePermissions(boolean canCreate, boolean canInvite, boolean canKick, boolean canPromote, boolean canDemote, boolean canDelete) { + this.canCreate = canCreate; + this.canInvite = canInvite; + this.canKick = canKick; + this.canPromote = canPromote; + this.canDemote = canDemote; + this.canDelete = canDelete; + } + } +} diff --git a/src/main/java/com/guild/core/placeholder/GuildPlaceholderExpansion.java b/src/main/java/com/guild/core/placeholder/GuildPlaceholderExpansion.java index 6bd6bb9..48ba0a1 100644 --- a/src/main/java/com/guild/core/placeholder/GuildPlaceholderExpansion.java +++ b/src/main/java/com/guild/core/placeholder/GuildPlaceholderExpansion.java @@ -1,383 +1,383 @@ -package com.guild.core.placeholder; - -import com.guild.GuildPlugin; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import com.guild.services.GuildService; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import com.guild.core.utils.PlaceholderUtils; - -import com.guild.core.time.TimeProvider; -import java.util.concurrent.CompletableFuture; - -/** - * Guild插件 PlaceholderAPI 扩展 - * 提供完整的工会数据变量支持 - */ -public class GuildPlaceholderExpansion extends PlaceholderExpansion { - - private final GuildPlugin plugin; - private final GuildService guildService; - - public GuildPlaceholderExpansion(GuildPlugin plugin, GuildService guildService) { - this.plugin = plugin; - this.guildService = guildService; - } - - @Override - public @NotNull String getIdentifier() { - return "guild"; - } - - @Override - public @NotNull String getAuthor() { - return "GuildTeam"; - } - - @Override - public @NotNull String getVersion() { - return plugin.getDescription().getVersion(); - } - - @Override - public boolean persist() { - return true; - } - - @Override - public String onPlaceholderRequest(Player player, @NotNull String params) { - if (player == null) { - return ""; - } - - String[] args = params.split("_"); - if (args.length == 0) { - return ""; - } - - try { - switch (args[0].toLowerCase()) { - // 基础工会信息 - case "name": - return getGuildName(player); - case "tag": - return getGuildTag(player); - case "description": - return getGuildDescription(player); - case "leader": - return getGuildLeader(player); - case "membercount": - return getGuildMemberCount(player); - case "maxmembers": - return getGuildMaxMembers(player); - case "level": - return getGuildLevel(player); - case "balance": - return getGuildBalance(player); - case "frozen": - return getGuildFrozenStatus(player); - - // 玩家在工会中的信息 - case "role": - return getPlayerRoleColored(player); - case "roleraw": - return getPlayerRoleRaw(player); - case "rolecolor": - return getPlayerRoleColor(player); - case "rolecolored": - return getPlayerRoleColored(player); - case "roleprefix": - return getPlayerRolePrefix(player); - case "joined": - return getPlayerJoinedTime(player); - case "contribution": - return getPlayerContribution(player); - - // 工会状态检查 - case "hasguild": - return hasGuild(player); - case "isleader": - return isLeader(player); - case "isofficer": - return isOfficer(player); - case "ismember": - return isMember(player); - - // 工会权限 - case "caninvite": - return canInvite(player); - case "cankick": - return canKick(player); - case "canpromote": - return canPromote(player); - case "candemote": - return canDemote(player); - case "cansethome": - return canSetHome(player); - case "canmanageeconomy": - return canManageEconomy(player); - - default: - return ""; - } - } catch (Exception e) { - plugin.getLogger().warning("处理占位符时发生错误: " + e.getMessage()); - return ""; - } - } - - // ==================== 基础工会信息 ==================== - - private String getGuildName(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? guild.getName() : "无工会"; - } catch (Exception e) { - return "无工会"; - } - } - - private String getGuildTag(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? guild.getTag() : ""; - } catch (Exception e) { - return ""; - } - } - - private String getGuildDescription(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? guild.getDescription() : ""; - } catch (Exception e) { - return ""; - } - } - - private String getGuildLeader(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? guild.getLeaderName() : ""; - } catch (Exception e) { - return ""; - } - } - - private String getGuildMemberCount(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - if (guild == null) return "0"; - - CompletableFuture future = guildService.getGuildMemberCountAsync(guild.getId()); - return String.valueOf(future.get()); - } catch (Exception e) { - return "0"; - } - } - - private String getGuildMaxMembers(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? String.valueOf(guild.getMaxMembers()) : "0"; - } catch (Exception e) { - return "0"; - } - } - - private String getGuildLevel(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? String.valueOf(guild.getLevel()) : "0"; - } catch (Exception e) { - return "0"; - } - } - - private String getGuildBalance(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? String.format("%.2f", guild.getBalance()) : "0.00"; - } catch (Exception e) { - return "0.00"; - } - } - - private String getGuildFrozenStatus(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? (guild.isFrozen() ? "已冻结" : "正常") : "无工会"; - } catch (Exception e) { - return "无工会"; - } - } - - // ==================== 玩家在工会中的信息 ==================== - - private String getPlayerRoleRaw(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - return member != null ? member.getRole().getDisplayName() : ""; - } catch (Exception e) { - return ""; - } - } - - private String getPlayerRoleColor(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return ""; - return PlaceholderUtils.getRoleColorCode(member.getRole()); - } catch (Exception e) { - return ""; - } - } - - private String getPlayerRoleColored(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return ""; - return PlaceholderUtils.getColoredRoleDisplay(member.getRole()); - } catch (Exception e) { - return ""; - } - } - - private String getPlayerRolePrefix(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - GuildMember.Role role = member != null ? member.getRole() : null; - return PlaceholderUtils.getRoleSeparator(role); - } catch (Exception e) { - return ""; - } - } - - private String getPlayerJoinedTime(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null || member.getJoinedAt() == null) return ""; - return member.getJoinedAt().format(TimeProvider.FULL_FORMATTER); - } catch (Exception e) { - return ""; - } - } - - private String getPlayerContribution(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - // 暂时返回0,因为GuildMember类还没有contribution字段 - return member != null ? "0" : "0"; - } catch (Exception e) { - return "0"; - } - } - - // ==================== 工会状态检查 ==================== - - private String hasGuild(Player player) { - try { - Guild guild = guildService.getPlayerGuild(player.getUniqueId()); - return guild != null ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String isLeader(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - return member != null && member.getRole() == GuildMember.Role.LEADER ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String isOfficer(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - return member != null && member.getRole() == GuildMember.Role.OFFICER ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String isMember(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - return member != null ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - // ==================== 工会权限 ==================== - - private String canInvite(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return "否"; - - return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String canKick(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return "否"; - - return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String canPromote(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return "否"; - - return member.getRole() == GuildMember.Role.LEADER ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String canDemote(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return "否"; - - return member.getRole() == GuildMember.Role.LEADER ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String canSetHome(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return "否"; - - return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } - - private String canManageEconomy(Player player) { - try { - GuildMember member = guildService.getGuildMember(player.getUniqueId()); - if (member == null) return "否"; - - return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "是" : "否"; - } catch (Exception e) { - return "否"; - } - } -} +package com.guild.core.placeholder; + +import com.guild.GuildPlugin; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import com.guild.services.GuildService; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import com.guild.core.utils.PlaceholderUtils; + +import com.guild.core.time.TimeProvider; +import java.util.concurrent.CompletableFuture; + +/** + * Rozszerzenie PlaceholderAPI dla pluginu Guild + * Zapewnia pełne wsparcie zmiennych danych gildii + */ +public class GuildPlaceholderExpansion extends PlaceholderExpansion { + + private final GuildPlugin plugin; + private final GuildService guildService; + + public GuildPlaceholderExpansion(GuildPlugin plugin, GuildService guildService) { + this.plugin = plugin; + this.guildService = guildService; + } + + @Override + public @NotNull String getIdentifier() { + return "guild"; + } + + @Override + public @NotNull String getAuthor() { + return "GuildTeam"; + } + + @Override + public @NotNull String getVersion() { + return plugin.getDescription().getVersion(); + } + + @Override + public boolean persist() { + return true; + } + + @Override + public String onPlaceholderRequest(Player player, @NotNull String params) { + if (player == null) { + return ""; + } + + String[] args = params.split("_"); + if (args.length == 0) { + return ""; + } + + try { + switch (args[0].toLowerCase()) { + // Podstawowe informacje o gildii + case "name": + return getGuildName(player); + case "tag": + return getGuildTag(player); + case "description": + return getGuildDescription(player); + case "leader": + return getGuildLeader(player); + case "membercount": + return getGuildMemberCount(player); + case "maxmembers": + return getGuildMaxMembers(player); + case "level": + return getGuildLevel(player); + case "balance": + return getGuildBalance(player); + case "frozen": + return getGuildFrozenStatus(player); + + // Informacje o graczu w gildii + case "role": + return getPlayerRoleColored(player); + case "roleraw": + return getPlayerRoleRaw(player); + case "rolecolor": + return getPlayerRoleColor(player); + case "rolecolored": + return getPlayerRoleColored(player); + case "roleprefix": + return getPlayerRolePrefix(player); + case "joined": + return getPlayerJoinedTime(player); + case "contribution": + return getPlayerContribution(player); + + // Sprawdzanie statusu gildii + case "hasguild": + return hasGuild(player); + case "isleader": + return isLeader(player); + case "isofficer": + return isOfficer(player); + case "ismember": + return isMember(player); + + // Uprawnienia gildii + case "caninvite": + return canInvite(player); + case "cankick": + return canKick(player); + case "canpromote": + return canPromote(player); + case "candemote": + return canDemote(player); + case "cansethome": + return canSetHome(player); + case "canmanageeconomy": + return canManageEconomy(player); + + default: + return ""; + } + } catch (Exception e) { + plugin.getLogger().warning("Błąd podczas przetwarzania placeholdera: " + e.getMessage()); + return ""; + } + } + + // ==================== Podstawowe informacje o gildii ==================== + + private String getGuildName(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? guild.getName() : "Brak gildii"; + } catch (Exception e) { + return "Brak gildii"; + } + } + + private String getGuildTag(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? guild.getTag() : ""; + } catch (Exception e) { + return ""; + } + } + + private String getGuildDescription(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? guild.getDescription() : ""; + } catch (Exception e) { + return ""; + } + } + + private String getGuildLeader(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? guild.getLeaderName() : ""; + } catch (Exception e) { + return ""; + } + } + + private String getGuildMemberCount(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + if (guild == null) return "0"; + + CompletableFuture future = guildService.getGuildMemberCountAsync(guild.getId()); + return String.valueOf(future.get()); + } catch (Exception e) { + return "0"; + } + } + + private String getGuildMaxMembers(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? String.valueOf(guild.getMaxMembers()) : "0"; + } catch (Exception e) { + return "0"; + } + } + + private String getGuildLevel(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? String.valueOf(guild.getLevel()) : "0"; + } catch (Exception e) { + return "0"; + } + } + + private String getGuildBalance(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? String.format("%.2f", guild.getBalance()) : "0.00"; + } catch (Exception e) { + return "0.00"; + } + } + + private String getGuildFrozenStatus(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? (guild.isFrozen() ? "Zamrożona" : "Normalna") : "Brak gildii"; + } catch (Exception e) { + return "Brak gildii"; + } + } + + // ==================== Informacje o graczu w gildii ==================== + + private String getPlayerRoleRaw(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + return member != null ? member.getRole().getDisplayName() : ""; + } catch (Exception e) { + return ""; + } + } + + private String getPlayerRoleColor(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return ""; + return PlaceholderUtils.getRoleColorCode(member.getRole()); + } catch (Exception e) { + return ""; + } + } + + private String getPlayerRoleColored(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return ""; + return PlaceholderUtils.getColoredRoleDisplay(member.getRole()); + } catch (Exception e) { + return ""; + } + } + + private String getPlayerRolePrefix(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + GuildMember.Role role = member != null ? member.getRole() : null; + return PlaceholderUtils.getRoleSeparator(role); + } catch (Exception e) { + return ""; + } + } + + private String getPlayerJoinedTime(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null || member.getJoinedAt() == null) return ""; + return member.getJoinedAt().format(TimeProvider.FULL_FORMATTER); + } catch (Exception e) { + return ""; + } + } + + private String getPlayerContribution(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + // Tymczasowo zwracamy 0, ponieważ klasa GuildMember nie ma jeszcze pola contribution + return member != null ? "0" : "0"; + } catch (Exception e) { + return "0"; + } + } + + // ==================== Sprawdzanie statusu gildii ==================== + + private String hasGuild(Player player) { + try { + Guild guild = guildService.getPlayerGuild(player.getUniqueId()); + return guild != null ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String isLeader(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + return member != null && member.getRole() == GuildMember.Role.LEADER ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String isOfficer(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + return member != null && member.getRole() == GuildMember.Role.OFFICER ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String isMember(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + return member != null ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + // ==================== Uprawnienia gildii ==================== + + private String canInvite(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return "Nie"; + + return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String canKick(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return "Nie"; + + return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String canPromote(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return "Nie"; + + return member.getRole() == GuildMember.Role.LEADER ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String canDemote(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return "Nie"; + + return member.getRole() == GuildMember.Role.LEADER ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String canSetHome(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return "Nie"; + + return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } + + private String canManageEconomy(Player player) { + try { + GuildMember member = guildService.getGuildMember(player.getUniqueId()); + if (member == null) return "Nie"; + + return (member.getRole() == GuildMember.Role.LEADER || member.getRole() == GuildMember.Role.OFFICER) ? "Tak" : "Nie"; + } catch (Exception e) { + return "Nie"; + } + } +} diff --git a/src/main/java/com/guild/core/placeholder/PlaceholderManager.java b/src/main/java/com/guild/core/placeholder/PlaceholderManager.java index 9a51eea..59d3a03 100644 --- a/src/main/java/com/guild/core/placeholder/PlaceholderManager.java +++ b/src/main/java/com/guild/core/placeholder/PlaceholderManager.java @@ -1,57 +1,57 @@ -package com.guild.core.placeholder; - -import com.guild.GuildPlugin; -import com.guild.services.GuildService; - -/** - * 占位符管理器 - 管理PlaceholderAPI集成 - */ -public class PlaceholderManager { - - private final GuildPlugin plugin; - private GuildService guildService; - private GuildPlaceholderExpansion placeholderExpansion; - private boolean placeholderApiAvailable = false; - - public PlaceholderManager(GuildPlugin plugin) { - this.plugin = plugin; - this.guildService = null; // 临时设置为null,避免循环依赖 - } - - /** - * 设置工会服务(在服务容器初始化后调用) - */ - public void setGuildService(GuildService guildService) { - this.guildService = guildService; - } - - /** - * 注册占位符 - */ - public void registerPlaceholders() { - if (plugin.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { - try { - // 创建并注册 PlaceholderExpansion - placeholderExpansion = new GuildPlaceholderExpansion(plugin, guildService); - placeholderExpansion.register(); - placeholderApiAvailable = true; - plugin.getLogger().info("PlaceholderAPI 占位符注册成功"); - } catch (Exception e) { - plugin.getLogger().warning("PlaceholderAPI 初始化失败: " + e.getMessage()); - placeholderApiAvailable = false; - } - } else { - plugin.getLogger().warning("PlaceholderAPI 未找到,占位符功能将不可用"); - placeholderApiAvailable = false; - } - } - - - - /** - * 检查 PlaceholderAPI 是否可用 - */ - public boolean isPlaceholderApiAvailable() { - return placeholderApiAvailable; - } -} +package com.guild.core.placeholder; + +import com.guild.GuildPlugin; +import com.guild.services.GuildService; + +/** + * Menedżer placeholderów - zarządza integracją z PlaceholderAPI + */ +public class PlaceholderManager { + + private final GuildPlugin plugin; + private GuildService guildService; + private GuildPlaceholderExpansion placeholderExpansion; + private boolean placeholderApiAvailable = false; + + public PlaceholderManager(GuildPlugin plugin) { + this.plugin = plugin; + this.guildService = null; // Tymczasowo null, aby uniknąć zależności cyklicznych + } + + /** + * Ustaw usługę gildii (wywoływane po inicjalizacji kontenera usług) + */ + public void setGuildService(GuildService guildService) { + this.guildService = guildService; + } + + /** + * Zarejestruj placeholdery + */ + public void registerPlaceholders() { + if (plugin.getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { + try { + // Utwórz i zarejestruj PlaceholderExpansion + placeholderExpansion = new GuildPlaceholderExpansion(plugin, guildService); + placeholderExpansion.register(); + placeholderApiAvailable = true; + plugin.getLogger().info("Placeholdery PlaceholderAPI zarejestrowane pomyślnie"); + } catch (Exception e) { + plugin.getLogger().warning("Inicjalizacja PlaceholderAPI nie powiodła się: " + e.getMessage()); + placeholderApiAvailable = false; + } + } else { + plugin.getLogger().warning("Nie znaleziono PlaceholderAPI, funkcje placeholderów będą niedostępne"); + placeholderApiAvailable = false; + } + } + + + + /** + * Sprawdź, czy PlaceholderAPI jest dostępne + */ + public boolean isPlaceholderApiAvailable() { + return placeholderApiAvailable; + } +} diff --git a/src/main/java/com/guild/core/time/TimeProvider.java b/src/main/java/com/guild/core/time/TimeProvider.java index 0bdae1f..d3d7615 100644 --- a/src/main/java/com/guild/core/time/TimeProvider.java +++ b/src/main/java/com/guild/core/time/TimeProvider.java @@ -6,9 +6,9 @@ import java.time.format.DateTimeFormatter; /** - * 时间提供器:统一获取“现实中的时间”(操作系统时间)。 - * 默认使用服务器操作系统的本地时区。 - * 后续如需支持“按玩家时区显示”,可在此类扩展按玩家ID读取/缓存时区。 + * Dostawca czasu: ujednolica pobieranie "rzeczywistego czasu" (czas systemu operacyjnego). + * Domyślnie używa lokalnej strefy czasowej systemu operacyjnego serwera. + * Jeśli w przyszłości zajdzie potrzeba obsługi "wyświetlania według strefy czasowej gracza", można rozszerzyć tę klasę o odczyt/buforowanie strefy czasowej według ID gracza. */ public final class TimeProvider { diff --git a/src/main/java/com/guild/core/utils/ColorUtils.java b/src/main/java/com/guild/core/utils/ColorUtils.java index ef1e62f..e4daeb7 100644 --- a/src/main/java/com/guild/core/utils/ColorUtils.java +++ b/src/main/java/com/guild/core/utils/ColorUtils.java @@ -1,100 +1,100 @@ -package com.guild.core.utils; - -import org.bukkit.ChatColor; - -/** - * 颜色处理工具类 - */ -public class ColorUtils { - - /** - * 转换颜色符号 - * @param message 原始消息 - * @return 转换后的消息 - */ - public static String colorize(String message) { - if (message == null) { - return ""; - } - return ChatColor.translateAlternateColorCodes('&', message); - } - - /** - * 转换颜色符号并替换占位符 - * @param message 原始消息 - * @param placeholders 占位符映射 - * @return 转换后的消息 - */ - public static String colorize(String message, String... placeholders) { - if (message == null) { - return ""; - } - - String result = message; - for (int i = 0; i < placeholders.length; i += 2) { - if (i + 1 < placeholders.length) { - String placeholder = placeholders[i]; - String value = placeholders[i + 1]; - result = result.replace(placeholder, value != null ? value : ""); - } - } - - return colorize(result); - } - - /** - * 移除颜色符号 - * @param message 原始消息 - * @return 移除颜色符号后的消息 - */ - public static String stripColor(String message) { - if (message == null) { - return ""; - } - return ChatColor.stripColor(colorize(message)); - } - - /** - * 在替换占位符时隔离被替换内容的颜色,避免其影响后续文本。 - * 做法:在占位符位置插入 content + &r + activeColor(activeColor 为占位符前的最近颜色码)。 - * 传入的 template 使用 & 颜色码;返回结果已进行颜色转换。 - */ - public static String replaceWithColorIsolation(String template, String placeholder, String content) { - if (template == null) { - return ""; - } - if (placeholder == null || placeholder.isEmpty()) { - return colorize(template); - } - int idx = template.indexOf(placeholder); - if (idx < 0) { - return colorize(template); - } - String prefix = template.substring(0, idx); - String suffix = template.substring(idx + placeholder.length()); - - // 计算占位符前的有效颜色码(最后一次出现的 &0-&f 或 &a-&f 等颜色代码,忽略样式码) - String activeColor = extractLastColorCode(prefix); - String injected = (content != null ? content : "") + "&r" + (activeColor != null ? activeColor : ""); - String result = prefix + injected + suffix; - return colorize(result); - } - - private static String extractLastColorCode(String text) { - if (text == null || text.isEmpty()) return null; - String last = null; - for (int i = 0; i < text.length() - 1; i++) { - char c = text.charAt(i); - char n = text.charAt(i + 1); - if (c == '&') { - char lower = Character.toLowerCase(n); - if (lower == 'r') { - last = null; // 重置 - } else if ((lower >= '0' && lower <= '9') || (lower >= 'a' && lower <= 'f')) { - last = "&" + lower; // 记录最后颜色码 - } - } - } - return last; - } -} +package com.guild.core.utils; + +import org.bukkit.ChatColor; + +/** + * Klasa narzędziowa do obsługi kolorów + */ +public class ColorUtils { + + /** + * Konwertuj symbole kolorów + * @param message Oryginalna wiadomość + * @return Skonwertowana wiadomość + */ + public static String colorize(String message) { + if (message == null) { + return ""; + } + return ChatColor.translateAlternateColorCodes('&', message); + } + + /** + * Konwertuj symbole kolorów i zastąp placeholdery + * @param message Oryginalna wiadomość + * @param placeholders Mapa placeholderów + * @return Skonwertowana wiadomość + */ + public static String colorize(String message, String... placeholders) { + if (message == null) { + return ""; + } + + String result = message; + for (int i = 0; i < placeholders.length; i += 2) { + if (i + 1 < placeholders.length) { + String placeholder = placeholders[i]; + String value = placeholders[i + 1]; + result = result.replace(placeholder, value != null ? value : ""); + } + } + + return colorize(result); + } + + /** + * Usuń symbole kolorów + * @param message Oryginalna wiadomość + * @return Wiadomość po usunięciu symboli kolorów + */ + public static String stripColor(String message) { + if (message == null) { + return ""; + } + return ChatColor.stripColor(colorize(message)); + } + + /** + * Izoluj kolor zastępowanej treści podczas zastępowania placeholderów, aby uniknąć wpływu na kolejny tekst. + * Sposób: Wstaw content + &r + activeColor w miejscu placeholdera (activeColor to ostatni kod koloru przed placeholderem). + * Przekazany szablon używa kodów kolorów &; zwrócony wynik ma już skonwertowane kolory. + */ + public static String replaceWithColorIsolation(String template, String placeholder, String content) { + if (template == null) { + return ""; + } + if (placeholder == null || placeholder.isEmpty()) { + return colorize(template); + } + int idx = template.indexOf(placeholder); + if (idx < 0) { + return colorize(template); + } + String prefix = template.substring(0, idx); + String suffix = template.substring(idx + placeholder.length()); + + // Oblicz ważny kod koloru przed placeholderem (ostatnie wystąpienie kodu koloru &0-&f lub &a-&f, ignorując kody stylu) + String activeColor = extractLastColorCode(prefix); + String injected = (content != null ? content : "") + "&r" + (activeColor != null ? activeColor : ""); + String result = prefix + injected + suffix; + return colorize(result); + } + + private static String extractLastColorCode(String text) { + if (text == null || text.isEmpty()) return null; + String last = null; + for (int i = 0; i < text.length() - 1; i++) { + char c = text.charAt(i); + char n = text.charAt(i + 1); + if (c == '&') { + char lower = Character.toLowerCase(n); + if (lower == 'r') { + last = null; // Reset + } else if ((lower >= '0' && lower <= '9') || (lower >= 'a' && lower <= 'f')) { + last = "&" + lower; // Zapisz ostatni kod koloru + } + } + } + return last; + } +} diff --git a/src/main/java/com/guild/core/utils/CompatibleScheduler.java b/src/main/java/com/guild/core/utils/CompatibleScheduler.java index 0f4849c..ec2bd74 100644 --- a/src/main/java/com/guild/core/utils/CompatibleScheduler.java +++ b/src/main/java/com/guild/core/utils/CompatibleScheduler.java @@ -1,164 +1,164 @@ -package com.guild.core.utils; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.plugin.Plugin; - -import java.lang.reflect.Method; - -/** - * 兼容性调度器 - 支持Spigot和Folia - */ -public class CompatibleScheduler { - - /** - * 在主线程执行任务 - */ - public static void runTask(Plugin plugin, Runnable task) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的全局区域调度器 - Object globalScheduler = Bukkit.class.getMethod("getGlobalRegionScheduler").invoke(null); - globalScheduler.getClass().getMethod("run", Plugin.class, java.util.function.Consumer.class) - .invoke(globalScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run()); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTask(plugin, task); - } - } else { - Bukkit.getScheduler().runTask(plugin, task); - } - } - - /** - * 在指定位置执行任务 - */ - public static void runTask(Plugin plugin, Location location, Runnable task) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的区域调度器 - Object regionScheduler = Bukkit.class.getMethod("getRegionScheduler").invoke(null); - regionScheduler.getClass().getMethod("run", Plugin.class, Location.class, java.util.function.Consumer.class) - .invoke(regionScheduler, plugin, location, (java.util.function.Consumer) scheduledTask -> task.run()); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTask(plugin, task); - } - } else { - Bukkit.getScheduler().runTask(plugin, task); - } - } - - /** - * 在指定实体所在区域执行任务 - */ - public static void runTask(Plugin plugin, Entity entity, Runnable task) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的实体调度器 - Object entityScheduler = entity.getClass().getMethod("getScheduler").invoke(entity); - entityScheduler.getClass().getMethod("run", Plugin.class, java.util.function.Consumer.class, Runnable.class) - .invoke(entityScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run(), (Runnable) () -> {}); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTask(plugin, task); - } - } else { - Bukkit.getScheduler().runTask(plugin, task); - } - } - - /** - * 延迟执行任务 - */ - public static void runTaskLater(Plugin plugin, Runnable task, long delay) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的全局区域调度器 - Object globalScheduler = Bukkit.class.getMethod("getGlobalRegionScheduler").invoke(null); - globalScheduler.getClass().getMethod("runDelayed", Plugin.class, java.util.function.Consumer.class, long.class) - .invoke(globalScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run(), delay); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTaskLater(plugin, task, delay); - } - } else { - Bukkit.getScheduler().runTaskLater(plugin, task, delay); - } - } - - /** - * 在指定位置延迟执行任务 - */ - public static void runTaskLater(Plugin plugin, Location location, Runnable task, long delay) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的区域调度器 - Object regionScheduler = Bukkit.class.getMethod("getRegionScheduler").invoke(null); - regionScheduler.getClass().getMethod("runDelayed", Plugin.class, Location.class, java.util.function.Consumer.class, long.class) - .invoke(regionScheduler, plugin, location, (java.util.function.Consumer) scheduledTask -> task.run(), delay); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTaskLater(plugin, task, delay); - } - } else { - Bukkit.getScheduler().runTaskLater(plugin, task, delay); - } - } - - /** - * 异步执行任务 - */ - public static void runTaskAsync(Plugin plugin, Runnable task) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的异步调度器 - Object asyncScheduler = Bukkit.class.getMethod("getAsyncScheduler").invoke(null); - asyncScheduler.getClass().getMethod("runNow", Plugin.class, java.util.function.Consumer.class) - .invoke(asyncScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run()); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTaskAsynchronously(plugin, task); - } - } else { - Bukkit.getScheduler().runTaskAsynchronously(plugin, task); - } - } - - /** - * 重复执行任务 - */ - public static void runTaskTimer(Plugin plugin, Runnable task, long delay, long period) { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的全局区域调度器 - Object globalScheduler = Bukkit.class.getMethod("getGlobalRegionScheduler").invoke(null); - globalScheduler.getClass().getMethod("runAtFixedRate", Plugin.class, java.util.function.Consumer.class, long.class, long.class) - .invoke(globalScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run(), delay, period); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统调度器 - Bukkit.getScheduler().runTaskTimer(plugin, task, delay, period); - } - } else { - Bukkit.getScheduler().runTaskTimer(plugin, task, delay, period); - } - } - - /** - * 检查是否在主线程 - */ - public static boolean isPrimaryThread() { - if (ServerUtils.isFolia()) { - try { - // 使用反射调用Folia的全局线程检查 - return (Boolean) Bukkit.class.getMethod("isGlobalTickThread").invoke(null); - } catch (Exception e) { - // 如果Folia API不可用,回退到传统检查 - return Bukkit.isPrimaryThread(); - } - } else { - return Bukkit.isPrimaryThread(); - } - } -} +package com.guild.core.utils; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.Method; + +/** + * Kompatybilny scheduler - obsługuje zarówno Spigot, jak i Folia + */ +public class CompatibleScheduler { + + /** + * Wykonaj zadanie w głównym wątku + */ + public static void runTask(Plugin plugin, Runnable task) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać globalny scheduler regionów Folia + Object globalScheduler = Bukkit.class.getMethod("getGlobalRegionScheduler").invoke(null); + globalScheduler.getClass().getMethod("run", Plugin.class, java.util.function.Consumer.class) + .invoke(globalScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run()); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTask(plugin, task); + } + } else { + Bukkit.getScheduler().runTask(plugin, task); + } + } + + /** + * Wykonaj zadanie w określonej lokalizacji + */ + public static void runTask(Plugin plugin, Location location, Runnable task) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać scheduler regionów Folia + Object regionScheduler = Bukkit.class.getMethod("getRegionScheduler").invoke(null); + regionScheduler.getClass().getMethod("run", Plugin.class, Location.class, java.util.function.Consumer.class) + .invoke(regionScheduler, plugin, location, (java.util.function.Consumer) scheduledTask -> task.run()); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTask(plugin, task); + } + } else { + Bukkit.getScheduler().runTask(plugin, task); + } + } + + /** + * Wykonaj zadanie w regionie, w którym znajduje się określony byt + */ + public static void runTask(Plugin plugin, Entity entity, Runnable task) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać scheduler bytu Folia + Object entityScheduler = entity.getClass().getMethod("getScheduler").invoke(entity); + entityScheduler.getClass().getMethod("run", Plugin.class, java.util.function.Consumer.class, Runnable.class) + .invoke(entityScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run(), (Runnable) () -> {}); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTask(plugin, task); + } + } else { + Bukkit.getScheduler().runTask(plugin, task); + } + } + + /** + * Wykonaj zadanie z opóźnieniem + */ + public static void runTaskLater(Plugin plugin, Runnable task, long delay) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać globalny scheduler regionów Folia + Object globalScheduler = Bukkit.class.getMethod("getGlobalRegionScheduler").invoke(null); + globalScheduler.getClass().getMethod("runDelayed", Plugin.class, java.util.function.Consumer.class, long.class) + .invoke(globalScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run(), delay); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTaskLater(plugin, task, delay); + } + } else { + Bukkit.getScheduler().runTaskLater(plugin, task, delay); + } + } + + /** + * Wykonaj zadanie z opóźnieniem w określonej lokalizacji + */ + public static void runTaskLater(Plugin plugin, Location location, Runnable task, long delay) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać scheduler regionów Folia + Object regionScheduler = Bukkit.class.getMethod("getRegionScheduler").invoke(null); + regionScheduler.getClass().getMethod("runDelayed", Plugin.class, Location.class, java.util.function.Consumer.class, long.class) + .invoke(regionScheduler, plugin, location, (java.util.function.Consumer) scheduledTask -> task.run(), delay); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTaskLater(plugin, task, delay); + } + } else { + Bukkit.getScheduler().runTaskLater(plugin, task, delay); + } + } + + /** + * Wykonaj zadanie asynchronicznie + */ + public static void runTaskAsync(Plugin plugin, Runnable task) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać asynchroniczny scheduler Folia + Object asyncScheduler = Bukkit.class.getMethod("getAsyncScheduler").invoke(null); + asyncScheduler.getClass().getMethod("runNow", Plugin.class, java.util.function.Consumer.class) + .invoke(asyncScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run()); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTaskAsynchronously(plugin, task); + } + } else { + Bukkit.getScheduler().runTaskAsynchronously(plugin, task); + } + } + + /** + * Wykonaj zadanie cyklicznie + */ + public static void runTaskTimer(Plugin plugin, Runnable task, long delay, long period) { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać globalny scheduler regionów Folia + Object globalScheduler = Bukkit.class.getMethod("getGlobalRegionScheduler").invoke(null); + globalScheduler.getClass().getMethod("runAtFixedRate", Plugin.class, java.util.function.Consumer.class, long.class, long.class) + .invoke(globalScheduler, plugin, (java.util.function.Consumer) scheduledTask -> task.run(), delay, period); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego schedulera + Bukkit.getScheduler().runTaskTimer(plugin, task, delay, period); + } + } else { + Bukkit.getScheduler().runTaskTimer(plugin, task, delay, period); + } + } + + /** + * Sprawdź, czy jesteś w głównym wątku + */ + public static boolean isPrimaryThread() { + if (ServerUtils.isFolia()) { + try { + // Użyj refleksji, aby wywołać globalne sprawdzanie wątków Folia + return (Boolean) Bukkit.class.getMethod("isGlobalTickThread").invoke(null); + } catch (Exception e) { + // Jeśli API Folia jest niedostępne, wróć do tradycyjnego sprawdzania + return Bukkit.isPrimaryThread(); + } + } else { + return Bukkit.isPrimaryThread(); + } + } +} diff --git a/src/main/java/com/guild/core/utils/GUIUtils.java b/src/main/java/com/guild/core/utils/GUIUtils.java index bfe6482..419379c 100644 --- a/src/main/java/com/guild/core/utils/GUIUtils.java +++ b/src/main/java/com/guild/core/utils/GUIUtils.java @@ -1,167 +1,167 @@ -package com.guild.core.utils; - -import com.guild.GuildPlugin; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * GUI工具类 - 统一处理GUI中的变量替换和颜色代码 - */ -public class GUIUtils { - - /** - * 处理GUI配置中的变量替换 - * @param text 原始文本 - * @param guild 工会对象 - * @param player 玩家对象 - * @return 替换后的文本 - */ - public static String processGUIVariables(String text, Guild guild, Player player) { - if (text == null) { - return ""; - } - - // 使用PlaceholderUtils处理基础变量 - String result = PlaceholderUtils.replaceGuildPlaceholders(text, guild, player); - - // 确保颜色代码正确应用 - return ColorUtils.colorize(result); - } - - /** - * 异步处理GUI配置中的变量替换(包含动态数据) - * @param text 原始文本 - * @param guild 工会对象 - * @param player 玩家对象 - * @param plugin 插件实例 - * @return 替换后的文本的CompletableFuture - */ - public static CompletableFuture processGUIVariablesAsync(String text, Guild guild, Player player, GuildPlugin plugin) { - if (text == null) { - return CompletableFuture.completedFuture(""); - } - - // 先处理静态变量 - String result = processGUIVariables(text, guild, player); - - // 异步获取动态数据 - return plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenApply(memberCount -> { - return result - .replace("{member_count}", String.valueOf(memberCount)) - .replace("{online_member_count}", String.valueOf(memberCount)); // 暂时使用总成员数 - }); - } - - /** - * 处理GUI配置中的物品描述列表 - * @param loreList 原始描述列表 - * @param guild 工会对象 - * @param player 玩家对象 - * @return 处理后的描述列表 - */ - public static List processGUILore(List loreList, Guild guild, Player player) { - List processedLore = new ArrayList<>(); - - if (loreList != null) { - for (String line : loreList) { - processedLore.add(processGUIVariables(line, guild, player)); - } - } - - return processedLore; - } - - /** - * 异步处理GUI配置中的物品描述列表(包含动态数据) - * @param loreList 原始描述列表 - * @param guild 工会对象 - * @param player 玩家对象 - * @param plugin 插件实例 - * @return 处理后的描述列表的CompletableFuture - */ - public static CompletableFuture> processGUILoreAsync(List loreList, Guild guild, Player player, GuildPlugin plugin) { - if (loreList == null || loreList.isEmpty()) { - return CompletableFuture.completedFuture(new ArrayList<>()); - } - - List> futures = new ArrayList<>(); - - for (String line : loreList) { - futures.add(processGUIVariablesAsync(line, guild, player, plugin)); - } - - return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) - .thenApply(v -> { - List processedLore = new ArrayList<>(); - for (CompletableFuture future : futures) { - try { - processedLore.add(future.get()); - } catch (Exception e) { - plugin.getLogger().warning("处理GUI描述时发生错误: " + e.getMessage()); - processedLore.add("&c错误"); - } - } - return processedLore; - }); - } - - /** - * 处理成员相关的GUI变量 - * @param text 原始文本 - * @param member 成员对象 - * @param guild 工会对象 - * @return 替换后的文本 - */ - public static String processMemberGUIVariables(String text, GuildMember member, Guild guild) { - if (text == null) { - return ""; - } - - return PlaceholderUtils.replaceMemberPlaceholders(text, member, guild); - } - - /** - * 验证变量是否被正确替换 - * @param text 要检查的文本 - * @return 是否包含未替换的变量 - */ - public static boolean hasUnresolvedVariables(String text) { - if (text == null) { - return false; - } - - // 检查是否包含未替换的变量占位符 - return text.contains("{") && text.contains("}"); - } - - /** - * 获取未替换的变量列表 - * @param text 要检查的文本 - * @return 未替换的变量列表 - */ - public static List getUnresolvedVariables(String text) { - List unresolved = new ArrayList<>(); - - if (text == null) { - return unresolved; - } - - // 简单的变量检测(可以扩展为更复杂的正则表达式) - String[] parts = text.split("\\{"); - for (int i = 1; i < parts.length; i++) { - String part = parts[i]; - int endIndex = part.indexOf("}"); - if (endIndex > 0) { - String variable = part.substring(0, endIndex); - unresolved.add("{" + variable + "}"); - } - } - - return unresolved; - } -} +package com.guild.core.utils; + +import com.guild.GuildPlugin; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * Narzędzia GUI - ujednolicone przetwarzanie zmiennych i kodów kolorów w GUI + */ +public class GUIUtils { + + /** + * Przetwórz zmienne w konfiguracji GUI + * @param text Oryginalny tekst + * @param guild Obiekt gildii + * @param player Obiekt gracza + * @return Tekst po zamianie + */ + public static String processGUIVariables(String text, Guild guild, Player player) { + if (text == null) { + return ""; + } + + // Użyj PlaceholderUtils do obsługi podstawowych zmiennych + String result = PlaceholderUtils.replaceGuildPlaceholders(text, guild, player); + + // Upewnij się, że kody kolorów są poprawnie zastosowane + return ColorUtils.colorize(result); + } + + /** + * Asynchronicznie przetwórz zmienne w konfiguracji GUI (w tym dane dynamiczne) + * @param text Oryginalny tekst + * @param guild Obiekt gildii + * @param player Obiekt gracza + * @param plugin Instancja pluginu + * @return CompletableFuture z tekstem po zamianie + */ + public static CompletableFuture processGUIVariablesAsync(String text, Guild guild, Player player, GuildPlugin plugin) { + if (text == null) { + return CompletableFuture.completedFuture(""); + } + + // Najpierw przetwórz zmienne statyczne + String result = processGUIVariables(text, guild, player); + + // Asynchronicznie pobierz dane dynamiczne + return plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenApply(memberCount -> { + return result + .replace("{member_count}", String.valueOf(memberCount)) + .replace("{online_member_count}", String.valueOf(memberCount)); // Tymczasowo użyj całkowitej liczby członków + }); + } + + /** + * Przetwórz listę opisów przedmiotów w konfiguracji GUI + * @param loreList Oryginalna lista opisów + * @param guild Obiekt gildii + * @param player Obiekt gracza + * @return Przetworzona lista opisów + */ + public static List processGUILore(List loreList, Guild guild, Player player) { + List processedLore = new ArrayList<>(); + + if (loreList != null) { + for (String line : loreList) { + processedLore.add(processGUIVariables(line, guild, player)); + } + } + + return processedLore; + } + + /** + * Asynchronicznie przetwórz listę opisów przedmiotów w konfiguracji GUI (w tym dane dynamiczne) + * @param loreList Oryginalna lista opisów + * @param guild Obiekt gildii + * @param player Obiekt gracza + * @param plugin Instancja pluginu + * @return CompletableFuture z przetworzoną listą opisów + */ + public static CompletableFuture> processGUILoreAsync(List loreList, Guild guild, Player player, GuildPlugin plugin) { + if (loreList == null || loreList.isEmpty()) { + return CompletableFuture.completedFuture(new ArrayList<>()); + } + + List> futures = new ArrayList<>(); + + for (String line : loreList) { + futures.add(processGUIVariablesAsync(line, guild, player, plugin)); + } + + return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) + .thenApply(v -> { + List processedLore = new ArrayList<>(); + for (CompletableFuture future : futures) { + try { + processedLore.add(future.get()); + } catch (Exception e) { + plugin.getLogger().warning("Błąd podczas przetwarzania opisu GUI: " + e.getMessage()); + processedLore.add("&cBłąd"); + } + } + return processedLore; + }); + } + + /** + * Przetwórz zmienne GUI związane z członkami + * @param text Oryginalny tekst + * @param member Obiekt członka + * @param guild Obiekt gildii + * @return Tekst po zamianie + */ + public static String processMemberGUIVariables(String text, GuildMember member, Guild guild) { + if (text == null) { + return ""; + } + + return PlaceholderUtils.replaceMemberPlaceholders(text, member, guild); + } + + /** + * Sprawdź, czy zmienne zostały poprawnie zastąpione + * @param text Tekst do sprawdzenia + * @return Czy zawiera niezastąpione zmienne + */ + public static boolean hasUnresolvedVariables(String text) { + if (text == null) { + return false; + } + + // Sprawdź czy zawiera niezastąpione placeholdery zmiennych + return text.contains("{") && text.contains("}"); + } + + /** + * Pobierz listę niezastąpionych zmiennych + * @param text Tekst do sprawdzenia + * @return Lista niezastąpionych zmiennych + */ + public static List getUnresolvedVariables(String text) { + List unresolved = new ArrayList<>(); + + if (text == null) { + return unresolved; + } + + // Proste wykrywanie zmiennych (można rozszerzyć o bardziej złożone wyrażenia regularne) + String[] parts = text.split("\\{"); + for (int i = 1; i < parts.length; i++) { + String part = parts[i]; + int endIndex = part.indexOf("}"); + if (endIndex > 0) { + String variable = part.substring(0, endIndex); + unresolved.add("{" + variable + "}"); + } + } + + return unresolved; + } +} diff --git a/src/main/java/com/guild/core/utils/PlaceholderUtils.java b/src/main/java/com/guild/core/utils/PlaceholderUtils.java index 2959844..2a2bd8e 100644 --- a/src/main/java/com/guild/core/utils/PlaceholderUtils.java +++ b/src/main/java/com/guild/core/utils/PlaceholderUtils.java @@ -1,377 +1,377 @@ -package com.guild.core.utils; - -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import com.guild.GuildPlugin; -import org.bukkit.entity.Player; - -import java.time.format.DateTimeFormatter; -import com.guild.core.time.TimeProvider; -import java.util.concurrent.CompletableFuture; - -/** - * 占位符处理工具类 - */ -public class PlaceholderUtils { - - private static final DateTimeFormatter DATE_FORMATTER = TimeProvider.FULL_FORMATTER; - private static String cachedLeaderColor; - private static String cachedOfficerColor; - private static String cachedMemberColor; - private static String cachedSeparatorText; - private static boolean cachedSeparatorEnabled; - private static boolean cachedSeparatorFollowRoleColor; - private static String cachedSeparatorDefaultColor; - - /** - * 替换工会相关占位符 - * @param text 原始文本 - * @param guild 工会对象 - * @param player 玩家对象 - * @return 替换后的文本 - */ - public static String replaceGuildPlaceholders(String text, Guild guild, Player player) { - if (text == null || guild == null) { - return text; - } - - String result = text - // 工会基本信息 - .replace("{guild_name}", guild.getName()) - .replace("{guild_tag}", guild.getTag() != null ? guild.getTag() : "") - .replace("{guild_description}", guild.getDescription() != null ? guild.getDescription() : "") - .replace("{guild_id}", String.valueOf(guild.getId())) - .replace("{guild_created_time}", guild.getCreatedAt().format(DATE_FORMATTER)) - .replace("{guild_created_date}", guild.getCreatedAt().toLocalDate().toString()) - - // 工会领导信息 - .replace("{leader_name}", guild.getLeaderName()) - .replace("{leader_uuid}", guild.getLeaderUuid().toString()) - - // 工会位置信息 - .replace("{guild_home_world}", guild.getHomeWorld() != null ? guild.getHomeWorld() : "") - .replace("{guild_home_x}", String.valueOf(guild.getHomeX())) - .replace("{guild_home_y}", String.valueOf(guild.getHomeY())) - .replace("{guild_home_z}", String.valueOf(guild.getHomeZ())) - .replace("{guild_home_location}", formatHomeLocation(guild)) - - // 玩家信息 - .replace("{player_name}", player != null ? player.getName() : "") - .replace("{player_uuid}", player != null ? player.getUniqueId().toString() : "") - .replace("{player_display_name}", player != null ? player.getDisplayName() : "") - - // 静态信息 - .replace("{guild_level}", String.valueOf(guild.getLevel())) - .replace("{guild_balance}", String.valueOf(guild.getBalance())) - .replace("{guild_max_members}", String.valueOf(guild.getMaxMembers())) - .replace("{guild_frozen}", guild.isFrozen() ? "已冻结" : "正常") - - // 经济相关变量 - 支持GUI配置中的变量名 - .replace("{guild_balance_formatted}", formatBalance(guild.getBalance())) - .replace("{guild_next_level_requirement}", getNextLevelRequirement(guild.getLevel())) - .replace("{guild_level_progress}", getLevelProgress(guild.getLevel(), guild.getBalance())) - .replace("{guild_upgrade_cost}", getUpgradeCost(guild.getLevel())) - .replace("{guild_currency_name}", "金币") - .replace("{guild_currency_name_singular}", "金币") - - // 兼容性变量 - 支持旧格式 - .replace("{guild_max_exp}", getNextLevelRequirement(guild.getLevel())) - .replace("{guild_exp_percentage}", getLevelProgress(guild.getLevel(), guild.getBalance())); - - // 处理颜色代码 - return ColorUtils.colorize(result); - } - - /** - * 异步替换工会相关占位符(包含动态数据) - * @param text 原始文本 - * @param guild 工会对象 - * @param player 玩家对象 - * @param guildService 工会服务 - * @return 替换后的文本的CompletableFuture - */ - public static CompletableFuture replaceGuildPlaceholdersAsync(String text, Guild guild, Player player, com.guild.services.GuildService guildService) { - if (text == null || guild == null) { - return CompletableFuture.completedFuture(text); - } - - // 先替换静态占位符 - String result = replaceGuildPlaceholders(text, guild, player); - - // 异步获取动态数据 - return guildService.getGuildMemberCountAsync(guild.getId()).thenApply(memberCount -> { - try { - return result - .replace("{member_count}", String.valueOf(memberCount)) - .replace("{online_member_count}", String.valueOf(memberCount)) // 暂时使用总成员数,后续可以添加在线统计 - .replace("{guild_max_exp}", getNextLevelRequirement(guild.getLevel())) - .replace("{guild_exp_percentage}", getLevelProgress(guild.getLevel(), guild.getBalance())); - } catch (Exception e) { - // 如果获取失败,使用默认值 - return result - .replace("{member_count}", "0") - .replace("{online_member_count}", "0") - .replace("{guild_max_exp}", getNextLevelRequirement(guild.getLevel())) - .replace("{guild_exp_percentage}", getLevelProgress(guild.getLevel(), guild.getBalance())); - } - }); - } - - /** - * 替换成员相关占位符 - * @param text 原始文本 - * @param member 成员对象 - * @param guild 工会对象 - * @return 替换后的文本 - */ - public static String replaceMemberPlaceholders(String text, GuildMember member, Guild guild) { - if (text == null || member == null) { - return text; - } - - String result = text - // 成员基本信息 - .replace("{member_name}", member.getPlayerName()) - .replace("{member_uuid}", member.getPlayerUuid().toString()) - .replace("{member_role}", getRoleDisplayName(member.getRole())) - .replace("{member_role_color}", getRoleColorFromConfig(member.getRole())) - .replace("{member_join_time}", member.getJoinedAt().format(DATE_FORMATTER)) - .replace("{member_join_date}", member.getJoinedAt().toLocalDate().toString()) - - // 工会信息 - .replace("{guild_name}", guild != null ? guild.getName() : "") - .replace("{guild_tag}", guild != null && guild.getTag() != null ? guild.getTag() : ""); - - // 处理颜色代码 - return ColorUtils.colorize(result); - } - - /** - * 替换申请相关占位符 - * @param text 原始文本 - * @param applicantName 申请人名称 - * @param guildName 工会名称 - * @param applyTime 申请时间 - * @return 替换后的文本 - */ - public static String replaceApplicationPlaceholders(String text, String applicantName, String guildName, java.time.LocalDateTime applyTime) { - if (text == null) { - return text; - } - - String result = text - .replace("{applicant_name}", applicantName != null ? applicantName : "") - .replace("{guild_name}", guildName != null ? guildName : "") - .replace("{apply_time}", applyTime != null ? applyTime.format(DATE_FORMATTER) : "") - .replace("{apply_date}", applyTime != null ? applyTime.toLocalDate().toString() : ""); - - // 处理颜色代码 - return ColorUtils.colorize(result); - } - - /** - * 替换通用占位符 - * @param text 原始文本 - * @param placeholders 占位符映射 - * @return 替换后的文本 - */ - public static String replacePlaceholders(String text, String... placeholders) { - if (text == null) { - return text; - } - - String result = text; - for (int i = 0; i < placeholders.length; i += 2) { - if (i + 1 < placeholders.length) { - String placeholder = placeholders[i]; - String value = placeholders[i + 1]; - result = result.replace(placeholder, value != null ? value : ""); - } - } - - // 处理颜色代码 - return ColorUtils.colorize(result); - } - - /** - * 格式化工会家位置 - */ - private static String formatHomeLocation(Guild guild) { - if (guild.getHomeWorld() == null) { - return "未设置"; - } - return String.format("%s %.1f, %.1f, %.1f", - guild.getHomeWorld(), guild.getHomeX(), guild.getHomeY(), guild.getHomeZ()); - } - - /** - * 获取角色显示名称 - */ - private static String getRoleDisplayName(GuildMember.Role role) { - switch (role) { - case LEADER: return "会长"; - case OFFICER: return "官员"; - case MEMBER: return "成员"; - default: return "未知"; - } - } - - /** - * 从配置获取角色颜色 - */ - private static String getRoleColorFromConfig(GuildMember.Role role) { - ensureRoleConfigCached(); - switch (role) { - case LEADER: return cachedLeaderColor; - case OFFICER: return cachedOfficerColor; - case MEMBER: return cachedMemberColor; - default: return "&f"; - } - } - - /** - * 对外提供:获取职位颜色代码(如 "&6") - */ - public static String getRoleColorCode(GuildMember.Role role) { - return getRoleColorFromConfig(role); - } - - /** - * 对外提供:获取带颜色的职位显示文本 - */ - public static String getColoredRoleDisplay(GuildMember.Role role) { - String color = getRoleColorFromConfig(role); - return ColorUtils.colorize(color + getRoleDisplayName(role)); - } - - /** - * 获取职位分隔符(根据配置与是否有职位决定是否返回) - */ - public static String getRoleSeparator(GuildMember.Role roleOrNull) { - ensureRoleConfigCached(); - if (!cachedSeparatorEnabled) { - return ""; - } - // 未入会或无角色时不显示分隔符 - if (roleOrNull == null) { - return ""; - } - String color = cachedSeparatorFollowRoleColor ? getRoleColorFromConfig(roleOrNull) : cachedSeparatorDefaultColor; - return ColorUtils.colorize(color + cachedSeparatorText); - } - - private static void ensureRoleConfigCached() { - if (cachedLeaderColor != null) { - return; - } - GuildPlugin plugin = GuildPlugin.getInstance(); - if (plugin == null || plugin.getConfigManager() == null) { - // 合理的默认值 - cachedLeaderColor = "&6"; - cachedOfficerColor = "&b"; - cachedMemberColor = "&7"; - cachedSeparatorText = " | "; - cachedSeparatorEnabled = true; - cachedSeparatorFollowRoleColor = true; - cachedSeparatorDefaultColor = "&7"; - return; - } - org.bukkit.configuration.file.FileConfiguration cfg = plugin.getConfigManager().getMainConfig(); - cachedLeaderColor = cfg.getString("display.role-colors.leader", "&6"); - cachedOfficerColor = cfg.getString("display.role-colors.officer", "&b"); - cachedMemberColor = cfg.getString("display.role-colors.member", "&7"); - cachedSeparatorText = cfg.getString("display.role-separator.text", " | "); - cachedSeparatorEnabled = cfg.getBoolean("display.role-separator.enabled", true); - cachedSeparatorFollowRoleColor = cfg.getBoolean("display.role-separator.color-per-role", true); - cachedSeparatorDefaultColor = cfg.getString("display.role-separator.default-color", "&7"); - } - - /** - * 格式化余额 - */ - private static String formatBalance(double balance) { - // 尝试使用经济管理器格式化,如果不可用则使用默认格式 - try { - com.guild.GuildPlugin plugin = com.guild.GuildPlugin.getInstance(); - if (plugin != null && plugin.getEconomyManager() != null && plugin.getEconomyManager().isVaultAvailable()) { - return plugin.getEconomyManager().format(balance); - } - } catch (Exception e) { - // 忽略错误,使用默认格式 - } - return String.format("%.2f", balance); - } - - /** - * 获取下一级升级需求 - */ - private static String getNextLevelRequirement(int currentLevel) { - if (currentLevel >= 10) { - return "已达到最高等级"; - } - - double required = 0; - switch (currentLevel) { - case 1: required = 5000; break; - case 2: required = 10000; break; - case 3: required = 20000; break; - case 4: required = 35000; break; - case 5: required = 50000; break; - case 6: required = 75000; break; - case 7: required = 100000; break; - case 8: required = 150000; break; - case 9: required = 200000; break; - } - - return String.format("%.2f", required); - } - - /** - * 获取等级进度 - */ - private static String getLevelProgress(int currentLevel, double currentBalance) { - if (currentLevel >= 10) { - return "100%"; - } - - double required = 0; - switch (currentLevel) { - case 1: required = 5000; break; - case 2: required = 10000; break; - case 3: required = 20000; break; - case 4: required = 35000; break; - case 5: required = 50000; break; - case 6: required = 75000; break; - case 7: required = 100000; break; - case 8: required = 150000; break; - case 9: required = 200000; break; - } - - double progress = (currentBalance / required) * 100; - return String.format("%.1f%%", Math.min(progress, 100)); - } - - /** - * 获取升级费用 - */ - private static String getUpgradeCost(int currentLevel) { - if (currentLevel >= 10) { - return "0"; - } - - double cost = 0; - switch (currentLevel) { - case 1: cost = 5000; break; - case 2: cost = 10000; break; - case 3: cost = 20000; break; - case 4: cost = 35000; break; - case 5: cost = 50000; break; - case 6: cost = 75000; break; - case 7: cost = 100000; break; - case 8: cost = 150000; break; - case 9: cost = 200000; break; - } - - return String.format("%.2f", cost); - } -} +package com.guild.core.utils; + +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import com.guild.GuildPlugin; +import org.bukkit.entity.Player; + +import java.time.format.DateTimeFormatter; +import com.guild.core.time.TimeProvider; +import java.util.concurrent.CompletableFuture; + +/** + * Klasa narzędziowa do przetwarzania placeholderów + */ +public class PlaceholderUtils { + + private static final DateTimeFormatter DATE_FORMATTER = TimeProvider.FULL_FORMATTER; + private static String cachedLeaderColor; + private static String cachedOfficerColor; + private static String cachedMemberColor; + private static String cachedSeparatorText; + private static boolean cachedSeparatorEnabled; + private static boolean cachedSeparatorFollowRoleColor; + private static String cachedSeparatorDefaultColor; + + /** + * Zastąp placeholdery związane z gildią + * @param text Oryginalny tekst + * @param guild Obiekt gildii + * @param player Obiekt gracza + * @return Tekst po zamianie + */ + public static String replaceGuildPlaceholders(String text, Guild guild, Player player) { + if (text == null || guild == null) { + return text; + } + + String result = text + // Podstawowe informacje o gildii + .replace("{guild_name}", guild.getName()) + .replace("{guild_tag}", guild.getTag() != null ? guild.getTag() : "") + .replace("{guild_description}", guild.getDescription() != null ? guild.getDescription() : "") + .replace("{guild_id}", String.valueOf(guild.getId())) + .replace("{guild_created_time}", guild.getCreatedAt().format(DATE_FORMATTER)) + .replace("{guild_created_date}", guild.getCreatedAt().toLocalDate().toString()) + + // Informacje o liderze gildii + .replace("{leader_name}", guild.getLeaderName()) + .replace("{leader_uuid}", guild.getLeaderUuid().toString()) + + // Informacje o lokalizacji gildii + .replace("{guild_home_world}", guild.getHomeWorld() != null ? guild.getHomeWorld() : "") + .replace("{guild_home_x}", String.valueOf(guild.getHomeX())) + .replace("{guild_home_y}", String.valueOf(guild.getHomeY())) + .replace("{guild_home_z}", String.valueOf(guild.getHomeZ())) + .replace("{guild_home_location}", formatHomeLocation(guild)) + + // Informacje o graczu + .replace("{player_name}", player != null ? player.getName() : "") + .replace("{player_uuid}", player != null ? player.getUniqueId().toString() : "") + .replace("{player_display_name}", player != null ? player.getDisplayName() : "") + + // Informacje statyczne + .replace("{guild_level}", String.valueOf(guild.getLevel())) + .replace("{guild_balance}", String.valueOf(guild.getBalance())) + .replace("{guild_max_members}", String.valueOf(guild.getMaxMembers())) + .replace("{guild_frozen}", guild.isFrozen() ? "Zamrożona" : "Normalna") + + // Zmienne związane z ekonomią - obsługują nazwy zmiennych w konfiguracji GUI + .replace("{guild_balance_formatted}", formatBalance(guild.getBalance())) + .replace("{guild_next_level_requirement}", getNextLevelRequirement(guild.getLevel())) + .replace("{guild_level_progress}", getLevelProgress(guild.getLevel(), guild.getBalance())) + .replace("{guild_upgrade_cost}", getUpgradeCost(guild.getLevel())) + .replace("{guild_currency_name}", "Monety") + .replace("{guild_currency_name_singular}", "Moneta") + + // Zmienne kompatybilności - obsługują stary format + .replace("{guild_max_exp}", getNextLevelRequirement(guild.getLevel())) + .replace("{guild_exp_percentage}", getLevelProgress(guild.getLevel(), guild.getBalance())); + + // Przetwórz kody kolorów + return ColorUtils.colorize(result); + } + + /** + * Asynchronicznie zastąp placeholdery związane z gildią (w tym dane dynamiczne) + * @param text Oryginalny tekst + * @param guild Obiekt gildii + * @param player Obiekt gracza + * @param guildService Usługa gildii + * @return CompletableFuture z tekstem po zamianie + */ + public static CompletableFuture replaceGuildPlaceholdersAsync(String text, Guild guild, Player player, com.guild.services.GuildService guildService) { + if (text == null || guild == null) { + return CompletableFuture.completedFuture(text); + } + + // Najpierw zastąp statyczne placeholdery + String result = replaceGuildPlaceholders(text, guild, player); + + // Asynchronicznie pobierz dane dynamiczne + return guildService.getGuildMemberCountAsync(guild.getId()).thenApply(memberCount -> { + try { + return result + .replace("{member_count}", String.valueOf(memberCount)) + .replace("{online_member_count}", String.valueOf(memberCount)) // Tymczasowo użyj całkowitej liczby członków, można później dodać statystyki online + .replace("{guild_max_exp}", getNextLevelRequirement(guild.getLevel())) + .replace("{guild_exp_percentage}", getLevelProgress(guild.getLevel(), guild.getBalance())); + } catch (Exception e) { + // W przypadku błędu pobierania, użyj wartości domyślnych + return result + .replace("{member_count}", "0") + .replace("{online_member_count}", "0") + .replace("{guild_max_exp}", getNextLevelRequirement(guild.getLevel())) + .replace("{guild_exp_percentage}", getLevelProgress(guild.getLevel(), guild.getBalance())); + } + }); + } + + /** + * Zastąp placeholdery związane z członkami + * @param text Oryginalny tekst + * @param member Obiekt członka + * @param guild Obiekt gildii + * @return Tekst po zamianie + */ + public static String replaceMemberPlaceholders(String text, GuildMember member, Guild guild) { + if (text == null || member == null) { + return text; + } + + String result = text + // Podstawowe informacje o członku + .replace("{member_name}", member.getPlayerName()) + .replace("{member_uuid}", member.getPlayerUuid().toString()) + .replace("{member_role}", getRoleDisplayName(member.getRole())) + .replace("{member_role_color}", getRoleColorFromConfig(member.getRole())) + .replace("{member_join_time}", member.getJoinedAt().format(DATE_FORMATTER)) + .replace("{member_join_date}", member.getJoinedAt().toLocalDate().toString()) + + // Informacje o gildii + .replace("{guild_name}", guild != null ? guild.getName() : "") + .replace("{guild_tag}", guild != null && guild.getTag() != null ? guild.getTag() : ""); + + // Przetwórz kody kolorów + return ColorUtils.colorize(result); + } + + /** + * Zastąp placeholdery związane z aplikacjami + * @param text Oryginalny tekst + * @param applicantName Nazwa wnioskodawcy + * @param guildName Nazwa gildii + * @param applyTime Czas aplikacji + * @return Tekst po zamianie + */ + public static String replaceApplicationPlaceholders(String text, String applicantName, String guildName, java.time.LocalDateTime applyTime) { + if (text == null) { + return text; + } + + String result = text + .replace("{applicant_name}", applicantName != null ? applicantName : "") + .replace("{guild_name}", guildName != null ? guildName : "") + .replace("{apply_time}", applyTime != null ? applyTime.format(DATE_FORMATTER) : "") + .replace("{apply_date}", applyTime != null ? applyTime.toLocalDate().toString() : ""); + + // Przetwórz kody kolorów + return ColorUtils.colorize(result); + } + + /** + * Zastąp ogólne placeholdery + * @param text Oryginalny tekst + * @param placeholders Mapa placeholderów + * @return Tekst po zamianie + */ + public static String replacePlaceholders(String text, String... placeholders) { + if (text == null) { + return text; + } + + String result = text; + for (int i = 0; i < placeholders.length; i += 2) { + if (i + 1 < placeholders.length) { + String placeholder = placeholders[i]; + String value = placeholders[i + 1]; + result = result.replace(placeholder, value != null ? value : ""); + } + } + + // Przetwórz kody kolorów + return ColorUtils.colorize(result); + } + + /** + * Formatuj lokalizację domu gildii + */ + private static String formatHomeLocation(Guild guild) { + if (guild.getHomeWorld() == null) { + return "Nie ustawiono"; + } + return String.format("%s %.1f, %.1f, %.1f", + guild.getHomeWorld(), guild.getHomeX(), guild.getHomeY(), guild.getHomeZ()); + } + + /** + * Pobierz wyświetlaną nazwę roli + */ + private static String getRoleDisplayName(GuildMember.Role role) { + switch (role) { + case LEADER: return "Lider"; + case OFFICER: return "Oficer"; + case MEMBER: return "Członek"; + default: return "Nieznana"; + } + } + + /** + * Pobierz kolor roli z konfiguracji + */ + private static String getRoleColorFromConfig(GuildMember.Role role) { + ensureRoleConfigCached(); + switch (role) { + case LEADER: return cachedLeaderColor; + case OFFICER: return cachedOfficerColor; + case MEMBER: return cachedMemberColor; + default: return "&f"; + } + } + + /** + * Publicznie dostępne: Pobierz kolorowy tekst wyświetlania roli + */ + public static String getColoredRoleDisplay(GuildMember.Role role) { + String color = getRoleColorFromConfig(role); + return ColorUtils.colorize(color + getRoleDisplayName(role)); + } + + /** + * Pobierz kod koloru dla roli + */ + public static String getRoleColorCode(GuildMember.Role role) { + return getRoleColorFromConfig(role); + } + + /** + * Pobierz separator roli (zwraca w zależności od konfiguracji i posiadania roli) + */ + public static String getRoleSeparator(GuildMember.Role roleOrNull) { + ensureRoleConfigCached(); + if (!cachedSeparatorEnabled) { + return ""; + } + // Nie pokazuj separatora, jeśli nie dołączył lub nie ma roli + if (roleOrNull == null) { + return ""; + } + String color = cachedSeparatorFollowRoleColor ? getRoleColorFromConfig(roleOrNull) : cachedSeparatorDefaultColor; + return ColorUtils.colorize(color + cachedSeparatorText); + } + + private static void ensureRoleConfigCached() { + if (cachedLeaderColor != null) { + return; + } + GuildPlugin plugin = GuildPlugin.getInstance(); + if (plugin == null || plugin.getConfigManager() == null) { + // Rozsądne wartości domyślne + cachedLeaderColor = "&6"; + cachedOfficerColor = "&b"; + cachedMemberColor = "&7"; + cachedSeparatorText = " | "; + cachedSeparatorEnabled = true; + cachedSeparatorFollowRoleColor = true; + cachedSeparatorDefaultColor = "&7"; + return; + } + org.bukkit.configuration.file.FileConfiguration cfg = plugin.getConfigManager().getMainConfig(); + cachedLeaderColor = cfg.getString("display.role-colors.leader", "&6"); + cachedOfficerColor = cfg.getString("display.role-colors.officer", "&b"); + cachedMemberColor = cfg.getString("display.role-colors.member", "&7"); + cachedSeparatorText = cfg.getString("display.role-separator.text", " | "); + cachedSeparatorEnabled = cfg.getBoolean("display.role-separator.enabled", true); + cachedSeparatorFollowRoleColor = cfg.getBoolean("display.role-separator.color-per-role", true); + cachedSeparatorDefaultColor = cfg.getString("display.role-separator.default-color", "&7"); + } + + /** + * Formatuj saldo + */ + private static String formatBalance(double balance) { + // Spróbuj sformatować za pomocą menedżera ekonomii, jeśli niedostępny, użyj domyślnego formatu + try { + com.guild.GuildPlugin plugin = com.guild.GuildPlugin.getInstance(); + if (plugin != null && plugin.getEconomyManager() != null && plugin.getEconomyManager().isVaultAvailable()) { + return plugin.getEconomyManager().format(balance); + } + } catch (Exception e) { + // Ignoruj błędy, użyj domyślnego formatu + } + return String.format("%.2f", balance); + } + + /** + * Pobierz wymagania dla następnego poziomu + */ + private static String getNextLevelRequirement(int currentLevel) { + if (currentLevel >= 10) { + return "Osiągnięto maksymalny poziom"; + } + + double required = 0; + switch (currentLevel) { + case 1: required = 5000; break; + case 2: required = 10000; break; + case 3: required = 20000; break; + case 4: required = 35000; break; + case 5: required = 50000; break; + case 6: required = 75000; break; + case 7: required = 100000; break; + case 8: required = 150000; break; + case 9: required = 200000; break; + } + + return String.format("%.2f", required); + } + + /** + * Pobierz postęp poziomu + */ + private static String getLevelProgress(int currentLevel, double currentBalance) { + if (currentLevel >= 10) { + return "100%"; + } + + double required = 0; + switch (currentLevel) { + case 1: required = 5000; break; + case 2: required = 10000; break; + case 3: required = 20000; break; + case 4: required = 35000; break; + case 5: required = 50000; break; + case 6: required = 75000; break; + case 7: required = 100000; break; + case 8: required = 150000; break; + case 9: required = 200000; break; + } + + double progress = (currentBalance / required) * 100; + return String.format("%.1f%%", Math.min(progress, 100)); + } + + /** + * Pobierz koszt ulepszenia + */ + private static String getUpgradeCost(int currentLevel) { + if (currentLevel >= 10) { + return "0"; + } + + double cost = 0; + switch (currentLevel) { + case 1: cost = 5000; break; + case 2: cost = 10000; break; + case 3: cost = 20000; break; + case 4: cost = 35000; break; + case 5: cost = 50000; break; + case 6: cost = 75000; break; + case 7: cost = 100000; break; + case 8: cost = 150000; break; + case 9: cost = 200000; break; + } + + return String.format("%.2f", cost); + } +} diff --git a/src/main/java/com/guild/core/utils/ServerUtils.java b/src/main/java/com/guild/core/utils/ServerUtils.java index ff85e2e..74d2afa 100644 --- a/src/main/java/com/guild/core/utils/ServerUtils.java +++ b/src/main/java/com/guild/core/utils/ServerUtils.java @@ -1,97 +1,97 @@ -package com.guild.core.utils; - -import org.bukkit.Bukkit; -import org.bukkit.Server; - -/** - * 服务器类型检测工具 - */ -public class ServerUtils { - - public enum ServerType { - SPIGOT, - FOLIA, - UNKNOWN - } - - private static ServerType serverType = null; - - /** - * 检测服务器类型 - */ - public static ServerType getServerType() { - if (serverType == null) { - serverType = detectServerType(); - } - return serverType; - } - - /** - * 检测是否为Folia服务器 - */ - public static boolean isFolia() { - return getServerType() == ServerType.FOLIA; - } - - /** - * 检测是否为Spigot服务器 - */ - public static boolean isSpigot() { - return getServerType() == ServerType.SPIGOT; - } - - /** - * 获取服务器版本 - */ - public static String getServerVersion() { - return Bukkit.getServer().getBukkitVersion(); - } - - /** - * 检测服务器类型的具体实现 - */ - private static ServerType detectServerType() { - try { - // 尝试加载Folia特有的类 - Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); - return ServerType.FOLIA; - } catch (ClassNotFoundException e) { - // 检查是否为Spigot - try { - Class.forName("org.spigotmc.SpigotConfig"); - return ServerType.SPIGOT; - } catch (ClassNotFoundException e2) { - return ServerType.UNKNOWN; - } - } - } - - /** - * 检查是否支持指定的API版本 - */ - public static boolean supportsApiVersion(String requiredVersion) { - String serverVersion = getServerVersion(); - return compareVersions(serverVersion, requiredVersion) >= 0; - } - - /** - * 版本比较工具 - */ - private static int compareVersions(String version1, String version2) { - String[] v1Parts = version1.split("-")[0].split("\\."); - String[] v2Parts = version2.split("-")[0].split("\\."); - - int maxLength = Math.max(v1Parts.length, v2Parts.length); - - for (int i = 0; i < maxLength; i++) { - int v1Part = i < v1Parts.length ? Integer.parseInt(v1Parts[i]) : 0; - int v2Part = i < v2Parts.length ? Integer.parseInt(v2Parts[i]) : 0; - - if (v1Part != v2Part) { - return Integer.compare(v1Part, v2Part); - } - } - - return 0; - } -} +package com.guild.core.utils; + +import org.bukkit.Bukkit; +import org.bukkit.Server; + +/** + * Narzędzie do wykrywania typu serwera + */ +public class ServerUtils { + + public enum ServerType { + SPIGOT, + FOLIA, + UNKNOWN + } + + private static ServerType serverType = null; + + /** + * Wykryj typ serwera + */ + public static ServerType getServerType() { + if (serverType == null) { + serverType = detectServerType(); + } + return serverType; + } + + /** + * Wykryj, czy jest to serwer Folia + */ + public static boolean isFolia() { + return getServerType() == ServerType.FOLIA; + } + + /** + * Wykryj, czy jest to serwer Spigot + */ + public static boolean isSpigot() { + return getServerType() == ServerType.SPIGOT; + } + + /** + * Pobierz wersję serwera + */ + public static String getServerVersion() { + return Bukkit.getServer().getBukkitVersion(); + } + + /** + * Konkretna implementacja wykrywania typu serwera + */ + private static ServerType detectServerType() { + try { + // Spróbuj załadować klasy specyficzne dla Folia + Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); + return ServerType.FOLIA; + } catch (ClassNotFoundException e) { + // Sprawdź, czy to Spigot + try { + Class.forName("org.spigotmc.SpigotConfig"); + return ServerType.SPIGOT; + } catch (ClassNotFoundException e2) { + return ServerType.UNKNOWN; + } + } + } + + /** + * Sprawdź, czy obsługuje określoną wersję API + */ + public static boolean supportsApiVersion(String requiredVersion) { + String serverVersion = getServerVersion(); + return compareVersions(serverVersion, requiredVersion) >= 0; + } + + /** + * Narzędzie do porównywania wersji + */ + private static int compareVersions(String version1, String version2) { + String[] v1Parts = version1.split("-")[0].split("\\."); + String[] v2Parts = version2.split("-")[0].split("\\."); + + int maxLength = Math.max(v1Parts.length, v2Parts.length); + + for (int i = 0; i < maxLength; i++) { + int v1Part = i < v1Parts.length ? Integer.parseInt(v1Parts[i]) : 0; + int v2Part = i < v2Parts.length ? Integer.parseInt(v2Parts[i]) : 0; + + if (v1Part != v2Part) { + return Integer.compare(v1Part, v2Part); + } + } + + return 0; + } +} diff --git a/src/main/java/com/guild/core/utils/TestUtils.java b/src/main/java/com/guild/core/utils/TestUtils.java index 2b076fe..7d79547 100644 --- a/src/main/java/com/guild/core/utils/TestUtils.java +++ b/src/main/java/com/guild/core/utils/TestUtils.java @@ -1,37 +1,37 @@ -package com.guild.core.utils; - -/** - * 测试工具类 - */ -public class TestUtils { - - /** - * 测试服务器兼容性 - */ - public static void testCompatibility(java.util.logging.Logger logger) { - if (logger == null) { - return; - } - logger.info("=== 服务器兼容性测试 ==="); - logger.info("服务器类型: " + ServerUtils.getServerType()); - logger.info("服务器版本: " + ServerUtils.getServerVersion()); - logger.info("是否支持1.21: " + ServerUtils.supportsApiVersion("1.21")); - logger.info("是否支持1.21.8: " + ServerUtils.supportsApiVersion("1.21.8")); - logger.info("是否为Folia: " + ServerUtils.isFolia()); - logger.info("是否为Spigot: " + ServerUtils.isSpigot()); - logger.info("========================="); - } - - /** - * 测试调度器兼容性 - */ - public static void testSchedulerCompatibility(java.util.logging.Logger logger) { - if (logger == null) { - return; - } - logger.info("=== 调度器兼容性测试 ==="); - logger.info("是否在主线程: " + CompatibleScheduler.isPrimaryThread()); - logger.info("服务器类型: " + ServerUtils.getServerType()); - logger.info("========================="); - } -} +package com.guild.core.utils; + +/** + * Klasa narzędziowa do testowania + */ +public class TestUtils { + + /** + * Test kompatybilności serwera + */ + public static void testCompatibility(java.util.logging.Logger logger) { + if (logger == null) { + return; + } + logger.info("=== Test kompatybilności serwera ==="); + logger.info("Typ serwera: " + ServerUtils.getServerType()); + logger.info("Wersja serwera: " + ServerUtils.getServerVersion()); + logger.info("Czy obsługuje 1.21: " + ServerUtils.supportsApiVersion("1.21")); + logger.info("Czy obsługuje 1.21.8: " + ServerUtils.supportsApiVersion("1.21.8")); + logger.info("Czy to Folia: " + ServerUtils.isFolia()); + logger.info("Czy to Spigot: " + ServerUtils.isSpigot()); + logger.info("========================="); + } + + /** + * Test kompatybilności schedulera + */ + public static void testSchedulerCompatibility(java.util.logging.Logger logger) { + if (logger == null) { + return; + } + logger.info("=== Test kompatybilności schedulera ==="); + logger.info("Czy w głównym wątku: " + CompatibleScheduler.isPrimaryThread()); + logger.info("Typ serwera: " + ServerUtils.getServerType()); + logger.info("========================="); + } +} diff --git a/src/main/java/com/guild/core/utils/VariableTestUtils.java b/src/main/java/com/guild/core/utils/VariableTestUtils.java index 79d66f6..ad33b14 100644 --- a/src/main/java/com/guild/core/utils/VariableTestUtils.java +++ b/src/main/java/com/guild/core/utils/VariableTestUtils.java @@ -1,116 +1,116 @@ -package com.guild.core.utils; - -import com.guild.GuildPlugin; -import com.guild.models.Guild; -import org.bukkit.entity.Player; - -import java.util.List; - -/** - * 变量测试工具类 - 用于验证GUI变量替换 - */ -public class VariableTestUtils { - - /** - * 测试GUI变量替换 - * @param plugin 插件实例 - * @param guild 工会对象 - * @param player 玩家对象 - */ - public static void testGUIVariables(GuildPlugin plugin, Guild guild, Player player) { - player.sendMessage("§6=== GUI变量测试 ==="); - - // 测试基础变量 - String[] testTexts = { - "工会名称: {guild_name}", - "工会标签: {guild_tag}", - "工会描述: {guild_description}", - "工会ID: {guild_id}", - "会长: {leader_name}", - "工会等级: {guild_level}", - "工会资金: {guild_balance_formatted}", - "最大成员: {guild_max_members}", - "工会状态: {guild_frozen}", - "创建时间: {guild_created_date}", - "成员数量: {member_count}/{guild_max_members}", - "升级需求: {guild_next_level_requirement}", - "升级进度: {guild_level_progress}" - }; - - for (String testText : testTexts) { - String processed = GUIUtils.processGUIVariables(testText, guild, player); - player.sendMessage("§e原始: §f" + testText); - player.sendMessage("§a处理后: §f" + processed); - - // 检查是否有未解析的变量 - if (GUIUtils.hasUnresolvedVariables(processed)) { - List unresolved = GUIUtils.getUnresolvedVariables(processed); - player.sendMessage("§c未解析变量: §f" + unresolved); - } - player.sendMessage(""); - } - - // 测试异步变量 - plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenAccept(memberCount -> { - String asyncTest = "成员数量: {member_count}/{guild_max_members}"; - GUIUtils.processGUIVariablesAsync(asyncTest, guild, player, plugin).thenAccept(processed -> { - player.sendMessage("§6异步测试: §f" + asyncTest); - player.sendMessage("§a异步结果: §f" + processed); - }); - }); - } - - /** - * 测试颜色代码 - * @param player 玩家对象 - */ - public static void testColorCodes(Player player) { - player.sendMessage("§6=== 颜色代码测试 ==="); - - String[] colorTests = { - "&a绿色文本", - "&c红色文本", - "&e黄色文本", - "&b青色文本", - "&d粉色文本", - "&f白色文本", - "&7灰色文本", - "&8深灰色文本", - "&9蓝色文本", - "&0黑色文本", - "&l粗体文本", - "&n下划线文本", - "&o斜体文本", - "&k随机字符", - "&r重置格式" - }; - - for (String test : colorTests) { - String processed = ColorUtils.colorize(test); - player.sendMessage("§e原始: §f" + test); - player.sendMessage("§a处理后: §f" + processed); - player.sendMessage(""); - } - } - - /** - * 测试PlaceholderUtils - * @param guild 工会对象 - * @param player 玩家对象 - */ - public static void testPlaceholderUtils(Guild guild, Player player) { - player.sendMessage("§6=== PlaceholderUtils测试 ==="); - - String testText = "工会: {guild_name}, 会长: {leader_name}, 等级: {guild_level}, 资金: {guild_balance_formatted}"; - String processed = PlaceholderUtils.replaceGuildPlaceholders(testText, guild, player); - - player.sendMessage("§e原始: §f" + testText); - player.sendMessage("§a处理后: §f" + processed); - - // 检查是否有未解析的变量 - if (GUIUtils.hasUnresolvedVariables(processed)) { - List unresolved = GUIUtils.getUnresolvedVariables(processed); - player.sendMessage("§c未解析变量: §f" + unresolved); - } - } -} +package com.guild.core.utils; + +import com.guild.GuildPlugin; +import com.guild.models.Guild; +import org.bukkit.entity.Player; + +import java.util.List; + +/** + * Klasa narzędziowa do testowania zmiennych - służy do weryfikacji zamiany zmiennych GUI + */ +public class VariableTestUtils { + + /** + * Test zamiany zmiennych GUI + * @param plugin Instancja pluginu + * @param guild Obiekt gildii + * @param player Obiekt gracza + */ + public static void testGUIVariables(GuildPlugin plugin, Guild guild, Player player) { + player.sendMessage("§6=== Test Zmiennych GUI ==="); + + // Testuj podstawowe zmienne + String[] testTexts = { + "Nazwa gildii: {guild_name}", + "Tag gildii: {guild_tag}", + "Opis gildii: {guild_description}", + "ID gildii: {guild_id}", + "Lider: {leader_name}", + "Poziom gildii: {guild_level}", + "Fundusze gildii: {guild_balance_formatted}", + "Maks. członków: {guild_max_members}", + "Status gildii: {guild_frozen}", + "Data utworzenia: {guild_created_date}", + "Liczba członków: {member_count}/{guild_max_members}", + "Wymagania ulepszenia: {guild_next_level_requirement}", + "Postęp ulepszania: {guild_level_progress}" + }; + + for (String testText : testTexts) { + String processed = GUIUtils.processGUIVariables(testText, guild, player); + player.sendMessage("§eOryginał: §f" + testText); + player.sendMessage("§aPrzetworzono: §f" + processed); + + // Sprawdź czy są nierozwiązane zmienne + if (GUIUtils.hasUnresolvedVariables(processed)) { + List unresolved = GUIUtils.getUnresolvedVariables(processed); + player.sendMessage("§cNierozwiązane zmienne: §f" + unresolved); + } + player.sendMessage(""); + } + + // Testuj zmienne asynchroniczne + plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenAccept(memberCount -> { + String asyncTest = "Liczba członków: {member_count}/{guild_max_members}"; + GUIUtils.processGUIVariablesAsync(asyncTest, guild, player, plugin).thenAccept(processed -> { + player.sendMessage("§6Test asynchroniczny: §f" + asyncTest); + player.sendMessage("§aWynik asynchroniczny: §f" + processed); + }); + }); + } + + /** + * Test kodów kolorów + * @param player Obiekt gracza + */ + public static void testColorCodes(Player player) { + player.sendMessage("§6=== Test Kodów Kolorów ==="); + + String[] colorTests = { + "&aZielony tekst", + "&cCzerwony tekst", + "&eŻółty tekst", + "&bTurkusowy tekst", + "&dRóżowy tekst", + "&fBiały tekst", + "&7Szary tekst", + "&8Ciemnoszary tekst", + "&9Niebieski tekst", + "&0Czarny tekst", + "&lPogrubiony tekst", + "&nPodkreślony tekst", + "&oPochylony tekst", + "&kLosowy znak", + "&rReset formatowania" + }; + + for (String test : colorTests) { + String processed = ColorUtils.colorize(test); + player.sendMessage("§eOryginał: §f" + test); + player.sendMessage("§aPrzetworzono: §f" + processed); + player.sendMessage(""); + } + } + + /** + * Test PlaceholderUtils + * @param guild Obiekt gildii + * @param player Obiekt gracza + */ + public static void testPlaceholderUtils(Guild guild, Player player) { + player.sendMessage("§6=== Test PlaceholderUtils ==="); + + String testText = "Gildia: {guild_name}, Lider: {leader_name}, Poziom: {guild_level}, Fundusze: {guild_balance_formatted}"; + String processed = PlaceholderUtils.replaceGuildPlaceholders(testText, guild, player); + + player.sendMessage("§eOryginał: §f" + testText); + player.sendMessage("§aPrzetworzono: §f" + processed); + + // Sprawdź czy są nierozwiązane zmienne + if (GUIUtils.hasUnresolvedVariables(processed)) { + List unresolved = GUIUtils.getUnresolvedVariables(processed); + player.sendMessage("§cNierozwiązane zmienne: §f" + unresolved); + } + } +} diff --git a/src/main/java/com/guild/gui/AdminGuildGUI.java b/src/main/java/com/guild/gui/AdminGuildGUI.java index 685531b..5d7404b 100644 --- a/src/main/java/com/guild/gui/AdminGuildGUI.java +++ b/src/main/java/com/guild/gui/AdminGuildGUI.java @@ -1,232 +1,232 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import com.guild.gui.SystemSettingsGUI; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 管理员工会GUI - */ -public class AdminGuildGUI implements GUI { - - private final GuildPlugin plugin; - - public AdminGuildGUI(GuildPlugin plugin) { - this.plugin = plugin; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.title", "&4工会管理")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("admin-gui.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 工会列表管理 - ItemStack guildList = createItem( - Material.BOOKSHELF, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.guild-list.name", "&e工会列表管理")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.guild-list.lore.1", "&7查看和管理所有工会")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.guild-list.lore.2", "&7包括删除、冻结等操作")) - ); - inventory.setItem(20, guildList); - - // 经济管理 - ItemStack economy = createItem( - Material.GOLD_INGOT, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.economy.name", "&e经济管理")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.economy.lore.1", "&7管理工会经济系统")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.economy.lore.2", "&7设置资金、查看贡献等")) - ); - inventory.setItem(22, economy); - - // 关系管理 - ItemStack relations = createItem( - Material.RED_WOOL, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.relations.name", "&e关系管理")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.relations.lore.1", "&7管理工会关系")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.relations.lore.2", "&7盟友、敌对、开战等")) - ); - inventory.setItem(24, relations); - - // 统计信息 - ItemStack statistics = createItem( - Material.PAPER, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.statistics.name", "&e统计信息")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.statistics.lore.1", "&7查看工会统计信息")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.statistics.lore.2", "&7成员数量、经济状况等")) - ); - inventory.setItem(29, statistics); - - // 系统设置 - ItemStack settings = createItem( - Material.COMPASS, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.settings.name", "&e系统设置")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.settings.lore.1", "&7管理系统设置")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.settings.lore.2", "&7重载配置、权限设置等")) - ); - inventory.setItem(31, settings); - - // 返回按钮 - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.back.name", "&c返回")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.back.lore.1", "&7返回主菜单")) - ); - inventory.setItem(49, back); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 20: // 工会列表管理 - openGuildListManagement(player); - break; - case 22: // 经济管理 - openEconomyManagement(player); - break; - case 24: // 关系管理 - openRelationManagement(player); - break; - case 29: // 统计信息 - openStatistics(player); - break; - case 31: // 系统设置 - openSystemSettings(player); - break; - case 49: // 返回 - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - break; - } - } - - private void openGuildListManagement(Player player) { - // 打开工会列表管理GUI - GuildListManagementGUI guildListGUI = new GuildListManagementGUI(plugin, player); - plugin.getGuiManager().openGUI(player, guildListGUI); - } - - private void openEconomyManagement(Player player) { - // 打开经济管理GUI - EconomyManagementGUI economyGUI = new EconomyManagementGUI(plugin, player); - plugin.getGuiManager().openGUI(player, economyGUI); - } - - private void openRelationManagement(Player player) { - // 打开关系管理GUI - RelationManagementGUI relationGUI = new RelationManagementGUI(plugin, player); - plugin.getGuiManager().openGUI(player, relationGUI); - } - - private void openStatistics(Player player) { - // 显示统计信息 - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - player.sendMessage(ColorUtils.colorize("&6=== 工会统计信息 ===")); - player.sendMessage(ColorUtils.colorize("&e总工会数量: &f" + guilds.size())); - - if (!guilds.isEmpty()) { - final double[] totalBalance = {0}; - final int[] frozenCount = {0}; - - for (Guild guild : guilds) { - totalBalance[0] += guild.getBalance(); - if (guild.isFrozen()) { - frozenCount[0]++; - } - } - - // 获取总成员数 - CompletableFuture[] memberCountFutures = new CompletableFuture[guilds.size()]; - for (int i = 0; i < guilds.size(); i++) { - memberCountFutures[i] = plugin.getGuildService().getGuildMemberCountAsync(guilds.get(i).getId()); - } - - CompletableFuture.allOf(memberCountFutures).thenRun(() -> { - final int[] totalMembers = {0}; - for (CompletableFuture future : memberCountFutures) { - try { - totalMembers[0] += future.get(); - } catch (Exception e) { - plugin.getLogger().severe("获取成员数量时发生错误: " + e.getMessage()); - } - } - - player.sendMessage(ColorUtils.colorize("&e总成员数量: &f" + totalMembers[0])); - player.sendMessage(ColorUtils.colorize("&e总资金: &f" + totalBalance[0])); - player.sendMessage(ColorUtils.colorize("&e冻结工会数: &f" + frozenCount[0])); - player.sendMessage(ColorUtils.colorize("&e正常工会数: &f" + (guilds.size() - frozenCount[0]))); - }); - } - }); - } - - private void openSystemSettings(Player player) { - // 打开系统设置GUI - plugin.getGuiManager().openGUI(player, new SystemSettingsGUI(plugin, player)); - } - - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - - // 填充边框 - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - - List loreList = new ArrayList<>(); - for (String line : lore) { - loreList.add(line); - } - meta.setLore(loreList); - - item.setItemMeta(meta); - } - - return item; - } - - @Override - public void onClose(Player player) { - // 关闭时的处理 - } - - @Override - public void refresh(Player player) { - // 刷新GUI - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import com.guild.gui.SystemSettingsGUI; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Administratora Gildii + */ +public class AdminGuildGUI implements GUI { + + private final GuildPlugin plugin; + + public AdminGuildGUI(GuildPlugin plugin) { + this.plugin = plugin; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.title", "&4Zarządzanie Gildiami")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("admin-gui.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij ramkę + fillBorder(inventory); + + // Zarządzanie listą gildii + ItemStack guildList = createItem( + Material.BOOKSHELF, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.guild-list.name", "&eZarządzanie Listą Gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.guild-list.lore.1", "&7Przeglądaj i zarządzaj wszystkimi gildiami")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.guild-list.lore.2", "&7W tym usuwanie, zamrażanie itp.")) + ); + inventory.setItem(20, guildList); + + // Zarządzanie ekonomią + ItemStack economy = createItem( + Material.GOLD_INGOT, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.economy.name", "&eZarządzanie Ekonomią")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.economy.lore.1", "&7Zarządzaj systemem ekonomii gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.economy.lore.2", "&7Ustaw fundusze, zobacz wkłady itp.")) + ); + inventory.setItem(22, economy); + + // Zarządzanie relacjami + ItemStack relations = createItem( + Material.RED_WOOL, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.relations.name", "&eZarządzanie Relacjami")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.relations.lore.1", "&7Zarządzaj relacjami gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.relations.lore.2", "&7Sojusznicy, wrogowie, wojny itp.")) + ); + inventory.setItem(24, relations); + + // Statystyki + ItemStack statistics = createItem( + Material.PAPER, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.statistics.name", "&eStatystyki")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.statistics.lore.1", "&7Zobacz statystyki gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.statistics.lore.2", "&7Liczba członków, stan ekonomii itp.")) + ); + inventory.setItem(29, statistics); + + // Ustawienia systemowe + ItemStack settings = createItem( + Material.COMPASS, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.settings.name", "&eUstawienia Systemowe")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.settings.lore.1", "&7Zarządzaj ustawieniami systemowymi")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.settings.lore.2", "&7Przeładuj konfigurację, ustawienia uprawnień itp.")) + ); + inventory.setItem(31, settings); + + // Przycisk powrotu + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.back.name", "&cWróć")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("admin-gui.items.back.lore.1", "&7Wróć do menu głównego")) + ); + inventory.setItem(49, back); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 20: // Zarządzanie listą gildii + openGuildListManagement(player); + break; + case 22: // Zarządzanie ekonomią + openEconomyManagement(player); + break; + case 24: // Zarządzanie relacjami + openRelationManagement(player); + break; + case 29: // Statystyki + openStatistics(player); + break; + case 31: // Ustawienia systemowe + openSystemSettings(player); + break; + case 49: // Wróć + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + break; + } + } + + private void openGuildListManagement(Player player) { + // Otwórz GUI zarządzania listą gildii + GuildListManagementGUI guildListGUI = new GuildListManagementGUI(plugin, player); + plugin.getGuiManager().openGUI(player, guildListGUI); + } + + private void openEconomyManagement(Player player) { + // Otwórz GUI zarządzania ekonomią + EconomyManagementGUI economyGUI = new EconomyManagementGUI(plugin, player); + plugin.getGuiManager().openGUI(player, economyGUI); + } + + private void openRelationManagement(Player player) { + // Otwórz GUI zarządzania relacjami + RelationManagementGUI relationGUI = new RelationManagementGUI(plugin, player); + plugin.getGuiManager().openGUI(player, relationGUI); + } + + private void openStatistics(Player player) { + // Wyświetl statystyki + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + player.sendMessage(ColorUtils.colorize("&6=== Statystyki Gildii ===")); + player.sendMessage(ColorUtils.colorize("&eŁączna liczba gildii: &f" + guilds.size())); + + if (!guilds.isEmpty()) { + final double[] totalBalance = {0}; + final int[] frozenCount = {0}; + + for (Guild guild : guilds) { + totalBalance[0] += guild.getBalance(); + if (guild.isFrozen()) { + frozenCount[0]++; + } + } + + // Pobierz całkowitą liczbę członków + CompletableFuture[] memberCountFutures = new CompletableFuture[guilds.size()]; + for (int i = 0; i < guilds.size(); i++) { + memberCountFutures[i] = plugin.getGuildService().getGuildMemberCountAsync(guilds.get(i).getId()); + } + + CompletableFuture.allOf(memberCountFutures).thenRun(() -> { + final int[] totalMembers = {0}; + for (CompletableFuture future : memberCountFutures) { + try { + totalMembers[0] += future.get(); + } catch (Exception e) { + plugin.getLogger().severe("Błąd podczas pobierania liczby członków: " + e.getMessage()); + } + } + + player.sendMessage(ColorUtils.colorize("&eŁączna liczba członków: &f" + totalMembers[0])); + player.sendMessage(ColorUtils.colorize("&eŁączne fundusze: &f" + totalBalance[0])); + player.sendMessage(ColorUtils.colorize("&eZamrożone gildie: &f" + frozenCount[0])); + player.sendMessage(ColorUtils.colorize("&eNormalne gildie: &f" + (guilds.size() - frozenCount[0]))); + }); + } + }); + } + + private void openSystemSettings(Player player) { + // Otwórz GUI ustawień systemowych + plugin.getGuiManager().openGUI(player, new SystemSettingsGUI(plugin, player)); + } + + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + + // Wypełnij ramkę + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + + List loreList = new ArrayList<>(); + for (String line : lore) { + loreList.add(line); + } + meta.setLore(loreList); + + item.setItemMeta(meta); + } + + return item; + } + + @Override + public void onClose(Player player) { + // Obsługa przy zamknięciu + } + + @Override + public void refresh(Player player) { + // Odśwież GUI + } +} diff --git a/src/main/java/com/guild/gui/ApplicationManagementGUI.java b/src/main/java/com/guild/gui/ApplicationManagementGUI.java index 05e26bf..1aaf466 100644 --- a/src/main/java/com/guild/gui/ApplicationManagementGUI.java +++ b/src/main/java/com/guild/gui/ApplicationManagementGUI.java @@ -1,456 +1,456 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.PlaceholderUtils; -import com.guild.models.Guild; -import com.guild.models.GuildApplication; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 申请管理GUI - */ -public class ApplicationManagementGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private int currentPage = 0; - private static final int APPLICATIONS_PER_PAGE = 28; // 4行7列,除去边框 - private boolean showingHistory = false; // false=待处理申请, true=申请历史 - - public ApplicationManagementGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.title", "&6申请管理")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("application-management.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 添加功能按钮 - setupFunctionButtons(inventory); - - // 加载申请列表 - loadApplications(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - // 检查是否是功能按钮 - if (isFunctionButton(slot)) { - handleFunctionButton(player, slot); - return; - } - - // 检查是否是分页按钮 - if (isPaginationButton(slot)) { - handlePaginationButton(player, slot); - return; - } - - // 检查是否是申请按钮 - if (isApplicationSlot(slot)) { - handleApplicationClick(player, slot, clickedItem, clickType); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 设置功能按钮 - */ - private void setupFunctionButtons(Inventory inventory) { - // 异步获取待处理申请数量 - plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { - int pendingCount = applications != null ? applications.size() : 0; - - // 待处理申请按钮 - ItemStack pendingApplications = createItem( - Material.PAPER, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.pending-applications.name", "&e待处理申请")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.pending-applications.lore.1", "&7查看待处理的申请")), - ColorUtils.colorize("&f" + pendingCount + " 个申请") - ); - inventory.setItem(20, pendingApplications); - }); - - // 申请历史按钮 - ItemStack applicationHistory = createItem( - Material.BOOK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.application-history.name", "&e申请历史")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.application-history.lore.1", "&7查看申请历史记录")) - ); - inventory.setItem(24, applicationHistory); - - // 返回按钮 - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.back.name", "&7返回")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.back.lore.1", "&7返回主菜单")) - ); - inventory.setItem(49, back); - } - - /** - * 加载申请列表 - */ - private void loadApplications(Inventory inventory) { - if (showingHistory) { - loadApplicationHistory(inventory); - } else { - loadPendingApplications(inventory); - } - } - - /** - * 加载待处理申请 - */ - private void loadPendingApplications(Inventory inventory) { - plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { - if (applications == null || applications.isEmpty()) { - // 显示无申请信息 - ItemStack noApplications = createItem( - Material.BARRIER, - ColorUtils.colorize("&a没有待处理的申请"), - ColorUtils.colorize("&7当前没有待处理的申请") - ); - inventory.setItem(22, noApplications); - return; - } - - // 计算分页 - int totalPages = (applications.size() - 1) / APPLICATIONS_PER_PAGE; - if (currentPage > totalPages) { - currentPage = totalPages; - } - - // 设置分页按钮 - setupPaginationButtons(inventory, totalPages); - - // 显示当前页的申请 - displayApplications(inventory, applications); - }); - } - - /** - * 加载申请历史 - */ - private void loadApplicationHistory(Inventory inventory) { - plugin.getGuildService().getApplicationHistoryAsync(guild.getId()).thenAccept(applications -> { - if (applications == null || applications.isEmpty()) { - // 显示无历史信息 - ItemStack noHistory = createItem( - Material.BARRIER, - ColorUtils.colorize("&a没有申请历史"), - ColorUtils.colorize("&7当前没有申请历史记录") - ); - inventory.setItem(22, noHistory); - return; - } - - // 计算分页 - int totalPages = (applications.size() - 1) / APPLICATIONS_PER_PAGE; - if (currentPage > totalPages) { - currentPage = totalPages; - } - - // 设置分页按钮 - setupPaginationButtons(inventory, totalPages); - - // 显示当前页的申请 - displayApplications(inventory, applications); - }); - } - - /** - * 显示申请列表 - */ - private void displayApplications(Inventory inventory, List applications) { - int startIndex = currentPage * APPLICATIONS_PER_PAGE; - int endIndex = Math.min(startIndex + APPLICATIONS_PER_PAGE, applications.size()); - - int slotIndex = 10; // 从第2行第2列开始 - for (int i = startIndex; i < endIndex; i++) { - GuildApplication application = applications.get(i); - if (slotIndex >= 44) break; // 避免超出显示区域 - - ItemStack applicationItem = createApplicationItem(application); - inventory.setItem(slotIndex, applicationItem); - - slotIndex++; - if (slotIndex % 9 == 8) { // 跳过边框 - slotIndex += 2; - } - } - } - - /** - * 设置分页按钮 - */ - private void setupPaginationButtons(Inventory inventory, int totalPages) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack previousPage = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.previous-page.name", "&c上一页")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.previous-page.lore.1", "&7查看上一页")) - ); - inventory.setItem(18, previousPage); - } - - // 下一页按钮 - if (currentPage < totalPages) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.next-page.name", "&a下一页")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.next-page.lore.1", "&7查看下一页")) - ); - inventory.setItem(26, nextPage); - } - } - - /** - * 创建申请物品 - */ - private ItemStack createApplicationItem(GuildApplication application) { - Material material; - String name; - List lore = new ArrayList<>(); - - switch (application.getStatus()) { - case PENDING: - material = Material.YELLOW_WOOL; - name = PlaceholderUtils.replaceApplicationPlaceholders("&e{applicant_name} 的申请", application.getPlayerName(), guild.getName(), application.getCreatedAt()); - lore.add(ColorUtils.colorize("&7状态: &e待处理")); - lore.add(PlaceholderUtils.replaceApplicationPlaceholders("&7申请时间: {apply_time}", application.getPlayerName(), guild.getName(), application.getCreatedAt())); - lore.add(ColorUtils.colorize("&7消息: " + application.getMessage())); - lore.add(""); - lore.add(ColorUtils.colorize("&a左键: 接受")); - lore.add(ColorUtils.colorize("&c右键: 拒绝")); - break; - case APPROVED: - material = Material.GREEN_WOOL; - name = PlaceholderUtils.replaceApplicationPlaceholders("&a{applicant_name} 的申请", application.getPlayerName(), guild.getName(), application.getCreatedAt()); - lore.add(ColorUtils.colorize("&7状态: &a已通过")); - break; - case REJECTED: - material = Material.RED_WOOL; - name = PlaceholderUtils.replaceApplicationPlaceholders("&c{applicant_name} 的申请", application.getPlayerName(), guild.getName(), application.getCreatedAt()); - lore.add(ColorUtils.colorize("&7状态: &c已拒绝")); - break; - default: - material = Material.GRAY_WOOL; - name = PlaceholderUtils.replaceApplicationPlaceholders("&7{applicant_name} 的申请", application.getPlayerName(), guild.getName(), application.getCreatedAt()); - lore.add(ColorUtils.colorize("&7状态: &7未知")); - break; - } - - return createItem(material, name, lore.toArray(new String[0])); - } - - /** - * 检查是否是功能按钮 - */ - private boolean isFunctionButton(int slot) { - return slot == 20 || slot == 24 || slot == 49; - } - - /** - * 检查是否是分页按钮 - */ - private boolean isPaginationButton(int slot) { - return slot == 18 || slot == 26; - } - - /** - * 检查是否是申请槽位 - */ - private boolean isApplicationSlot(int slot) { - return slot >= 10 && slot <= 44 && slot % 9 != 0 && slot % 9 != 8; - } - - /** - * 处理功能按钮点击 - */ - private void handleFunctionButton(Player player, int slot) { - switch (slot) { - case 20: // 待处理申请 - showingHistory = false; - currentPage = 0; - refreshInventory(player); - break; - case 24: // 申请历史 - showingHistory = true; - currentPage = 0; - refreshInventory(player); - break; - case 49: // 返回 - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - break; - } - } - - /** - * 处理分页按钮点击 - */ - private void handlePaginationButton(Player player, int slot) { - if (slot == 18) { // 上一页 - if (currentPage > 0) { - currentPage--; - refreshInventory(player); - } - } else if (slot == 26) { // 下一页 - currentPage++; - refreshInventory(player); - } - } - - /** - * 处理申请点击 - */ - private void handleApplicationClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (showingHistory) { - // 历史记录只能查看,不能操作 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-history-view-only", "&7这是历史记录,只能查看"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 待处理申请可以接受或拒绝 - if (clickType == ClickType.LEFT) { - // 接受申请 - handleAcceptApplication(player, slot); - } else if (clickType == ClickType.RIGHT) { - // 拒绝申请 - handleRejectApplication(player, slot); - } - } - - /** - * 处理接受申请 - */ - private void handleAcceptApplication(Player player, int slot) { - // 获取当前页的申请列表 - plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { - if (applications == null || applications.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-pending-applications", "&c没有待处理的申请"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 计算申请在列表中的索引 - int applicationIndex = currentPage * APPLICATIONS_PER_PAGE + (slot - 10); - if (applicationIndex >= 0 && applicationIndex < applications.size()) { - GuildApplication application = applications.get(applicationIndex); - - // 处理申请 - plugin.getGuildService().processApplicationAsync(application.getId(), GuildApplication.ApplicationStatus.APPROVED, player.getUniqueId()).thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-accepted", "&a申请已接受!"); - player.sendMessage(ColorUtils.colorize(message)); - - // 刷新GUI - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-accept-failed", "&c接受申请失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } - }); - } - - /** - * 处理拒绝申请 - */ - private void handleRejectApplication(Player player, int slot) { - // 获取当前页的申请列表 - plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { - if (applications == null || applications.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-pending-applications", "&c没有待处理的申请"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 计算申请在列表中的索引 - int applicationIndex = currentPage * APPLICATIONS_PER_PAGE + (slot - 10); - if (applicationIndex >= 0 && applicationIndex < applications.size()) { - GuildApplication application = applications.get(applicationIndex); - - // 处理申请 - plugin.getGuildService().processApplicationAsync(application.getId(), GuildApplication.ApplicationStatus.REJECTED, player.getUniqueId()).thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-rejected", "&c申请已拒绝!"); - player.sendMessage(ColorUtils.colorize(message)); - - // 刷新GUI - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-reject-failed", "&c拒绝申请失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } - }); - } - - /** - * 刷新库存 - */ - private void refreshInventory(Player player) { - plugin.getGuiManager().refreshGUI(player); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.PlaceholderUtils; +import com.guild.models.Guild; +import com.guild.models.GuildApplication; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Zarządzania Aplikacjami + */ +public class ApplicationManagementGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private int currentPage = 0; + private static final int APPLICATIONS_PER_PAGE = 28; // 4 wiersze po 7 kolumn, z wyłączeniem ramki + private boolean showingHistory = false; // false=oczekujące aplikacje, true=historia aplikacji + + public ApplicationManagementGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.title", "&6Zarządzanie Aplikacjami")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("application-management.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij ramkę + fillBorder(inventory); + + // Ustaw przyciski funkcyjne + setupFunctionButtons(inventory); + + // Załaduj listę aplikacji + loadApplications(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + // Sprawdź, czy to przycisk funkcyjny + if (isFunctionButton(slot)) { + handleFunctionButton(player, slot); + return; + } + + // Sprawdź, czy to przycisk paginacji + if (isPaginationButton(slot)) { + handlePaginationButton(player, slot); + return; + } + + // Sprawdź, czy to slot aplikacji + if (isApplicationSlot(slot)) { + handleApplicationClick(player, slot, clickedItem, clickType); + } + } + + /** + * Wypełnij ramkę + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Ustaw przyciski funkcyjne + */ + private void setupFunctionButtons(Inventory inventory) { + // Asynchronicznie pobierz liczbę oczekujących aplikacji + plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { + int pendingCount = applications != null ? applications.size() : 0; + + // Przycisk oczekujących aplikacji + ItemStack pendingApplications = createItem( + Material.PAPER, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.pending-applications.name", "&eOczekujące Aplikacje")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.pending-applications.lore.1", "&7Zobacz oczekujące aplikacje")), + ColorUtils.colorize("&f" + pendingCount + " aplikacji") + ); + inventory.setItem(20, pendingApplications); + }); + + // Przycisk historii aplikacji + ItemStack applicationHistory = createItem( + Material.BOOK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.application-history.name", "&eHistoria Aplikacji")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.application-history.lore.1", "&7Zobacz historię aplikacji")) + ); + inventory.setItem(24, applicationHistory); + + // Przycisk powrotu + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.back.name", "&7Wróć")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.back.lore.1", "&7Wróć do menu głównego")) + ); + inventory.setItem(49, back); + } + + /** + * Załaduj listę aplikacji + */ + private void loadApplications(Inventory inventory) { + if (showingHistory) { + loadApplicationHistory(inventory); + } else { + loadPendingApplications(inventory); + } + } + + /** + * Załaduj oczekujące aplikacje + */ + private void loadPendingApplications(Inventory inventory) { + plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { + if (applications == null || applications.isEmpty()) { + // Wyświetl informację o braku aplikacji + ItemStack noApplications = createItem( + Material.BARRIER, + ColorUtils.colorize("&aBrak oczekujących aplikacji"), + ColorUtils.colorize("&7Obecnie brak oczekujących aplikacji") + ); + inventory.setItem(22, noApplications); + return; + } + + // Oblicz strony + int totalPages = (applications.size() - 1) / APPLICATIONS_PER_PAGE; + if (currentPage > totalPages) { + currentPage = totalPages; + } + + // Ustaw przyciski paginacji + setupPaginationButtons(inventory, totalPages); + + // Wyświetl aplikacje na bieżącej stronie + displayApplications(inventory, applications); + }); + } + + /** + * Załaduj historię aplikacji + */ + private void loadApplicationHistory(Inventory inventory) { + plugin.getGuildService().getApplicationHistoryAsync(guild.getId()).thenAccept(applications -> { + if (applications == null || applications.isEmpty()) { + // Wyświetl informację o braku historii + ItemStack noHistory = createItem( + Material.BARRIER, + ColorUtils.colorize("&aBrak historii aplikacji"), + ColorUtils.colorize("&7Obecnie brak historii aplikacji") + ); + inventory.setItem(22, noHistory); + return; + } + + // Oblicz strony + int totalPages = (applications.size() - 1) / APPLICATIONS_PER_PAGE; + if (currentPage > totalPages) { + currentPage = totalPages; + } + + // Ustaw przyciski paginacji + setupPaginationButtons(inventory, totalPages); + + // Wyświetl aplikacje na bieżącej stronie + displayApplications(inventory, applications); + }); + } + + /** + * Wyświetl listę aplikacji + */ + private void displayApplications(Inventory inventory, List applications) { + int startIndex = currentPage * APPLICATIONS_PER_PAGE; + int endIndex = Math.min(startIndex + APPLICATIONS_PER_PAGE, applications.size()); + + int slotIndex = 10; // Zacznij od 2 wiersza, 2 kolumny + for (int i = startIndex; i < endIndex; i++) { + GuildApplication application = applications.get(i); + if (slotIndex >= 44) break; // Unikaj wyjścia poza obszar wyświetlania + + ItemStack applicationItem = createApplicationItem(application); + inventory.setItem(slotIndex, applicationItem); + + slotIndex++; + if (slotIndex % 9 == 8) { // Pomiń ramkę + slotIndex += 2; + } + } + } + + /** + * Ustaw przyciski paginacji + */ + private void setupPaginationButtons(Inventory inventory, int totalPages) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack previousPage = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.previous-page.name", "&cPoprzednia strona")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.previous-page.lore.1", "&7Zobacz poprzednią stronę")) + ); + inventory.setItem(18, previousPage); + } + + // Przycisk następnej strony + if (currentPage < totalPages) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.next-page.name", "&aNastępna strona")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("application-management.items.next-page.lore.1", "&7Zobacz następną stronę")) + ); + inventory.setItem(26, nextPage); + } + } + + /** + * Utwórz przedmiot aplikacji + */ + private ItemStack createApplicationItem(GuildApplication application) { + Material material; + String name; + List lore = new ArrayList<>(); + + switch (application.getStatus()) { + case PENDING: + material = Material.YELLOW_WOOL; + name = PlaceholderUtils.replaceApplicationPlaceholders("&eAplikacja {applicant_name}", application.getPlayerName(), guild.getName(), application.getCreatedAt()); + lore.add(ColorUtils.colorize("&7Status: &eOczekująca")); + lore.add(PlaceholderUtils.replaceApplicationPlaceholders("&7Czas aplikacji: {apply_time}", application.getPlayerName(), guild.getName(), application.getCreatedAt())); + lore.add(ColorUtils.colorize("&7Wiadomość: " + application.getMessage())); + lore.add(""); + lore.add(ColorUtils.colorize("&aLPM: Akceptuj")); + lore.add(ColorUtils.colorize("&cPPM: Odrzuć")); + break; + case APPROVED: + material = Material.GREEN_WOOL; + name = PlaceholderUtils.replaceApplicationPlaceholders("&aAplikacja {applicant_name}", application.getPlayerName(), guild.getName(), application.getCreatedAt()); + lore.add(ColorUtils.colorize("&7Status: &aZatwierdzona")); + break; + case REJECTED: + material = Material.RED_WOOL; + name = PlaceholderUtils.replaceApplicationPlaceholders("&cAplikacja {applicant_name}", application.getPlayerName(), guild.getName(), application.getCreatedAt()); + lore.add(ColorUtils.colorize("&7Status: &cOdrzucona")); + break; + default: + material = Material.GRAY_WOOL; + name = PlaceholderUtils.replaceApplicationPlaceholders("&7Aplikacja {applicant_name}", application.getPlayerName(), guild.getName(), application.getCreatedAt()); + lore.add(ColorUtils.colorize("&7Status: &7Nieznany")); + break; + } + + return createItem(material, name, lore.toArray(new String[0])); + } + + /** + * Sprawdź, czy to przycisk funkcyjny + */ + private boolean isFunctionButton(int slot) { + return slot == 20 || slot == 24 || slot == 49; + } + + /** + * Sprawdź, czy to przycisk paginacji + */ + private boolean isPaginationButton(int slot) { + return slot == 18 || slot == 26; + } + + /** + * Sprawdź, czy to slot aplikacji + */ + private boolean isApplicationSlot(int slot) { + return slot >= 10 && slot <= 44 && slot % 9 != 0 && slot % 9 != 8; + } + + /** + * Obsługa kliknięcia przycisku funkcyjnego + */ + private void handleFunctionButton(Player player, int slot) { + switch (slot) { + case 20: // Oczekujące aplikacje + showingHistory = false; + currentPage = 0; + refreshInventory(player); + break; + case 24: // Historia aplikacji + showingHistory = true; + currentPage = 0; + refreshInventory(player); + break; + case 49: // Wróć + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + break; + } + } + + /** + * Obsługa kliknięcia przycisku paginacji + */ + private void handlePaginationButton(Player player, int slot) { + if (slot == 18) { // Poprzednia strona + if (currentPage > 0) { + currentPage--; + refreshInventory(player); + } + } else if (slot == 26) { // Następna strona + currentPage++; + refreshInventory(player); + } + } + + /** + * Obsługa kliknięcia aplikacji + */ + private void handleApplicationClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (showingHistory) { + // Historia jest tylko do odczytu + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-history-view-only", "&7To jest historia, tylko do odczytu"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Oczekujące aplikacje można zaakceptować lub odrzucić + if (clickType == ClickType.LEFT) { + // Akceptuj aplikację + handleAcceptApplication(player, slot); + } else if (clickType == ClickType.RIGHT) { + // Odrzuć aplikację + handleRejectApplication(player, slot); + } + } + + /** + * Obsługa akceptacji aplikacji + */ + private void handleAcceptApplication(Player player, int slot) { + // Pobierz listę aplikacji na bieżącej stronie + plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { + if (applications == null || applications.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-pending-applications", "&cBrak oczekujących aplikacji"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Oblicz indeks aplikacji + int applicationIndex = currentPage * APPLICATIONS_PER_PAGE + (slot - 10); + if (applicationIndex >= 0 && applicationIndex < applications.size()) { + GuildApplication application = applications.get(applicationIndex); + + // Przetwórz aplikację + plugin.getGuildService().processApplicationAsync(application.getId(), GuildApplication.ApplicationStatus.APPROVED, player.getUniqueId()).thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-accepted", "&aAplikacja zaakceptowana!"); + player.sendMessage(ColorUtils.colorize(message)); + + // Odśwież GUI + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-accept-failed", "&cAkceptacja aplikacji nie powiodła się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } + }); + } + + /** + * Obsługa odrzucenia aplikacji + */ + private void handleRejectApplication(Player player, int slot) { + // Pobierz listę aplikacji na bieżącej stronie + plugin.getGuildService().getPendingApplicationsAsync(guild.getId()).thenAccept(applications -> { + if (applications == null || applications.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-pending-applications", "&cBrak oczekujących aplikacji"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Oblicz indeks aplikacji + int applicationIndex = currentPage * APPLICATIONS_PER_PAGE + (slot - 10); + if (applicationIndex >= 0 && applicationIndex < applications.size()) { + GuildApplication application = applications.get(applicationIndex); + + // Przetwórz aplikację + plugin.getGuildService().processApplicationAsync(application.getId(), GuildApplication.ApplicationStatus.REJECTED, player.getUniqueId()).thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-rejected", "&cAplikacja odrzucona!"); + player.sendMessage(ColorUtils.colorize(message)); + + // Odśwież GUI + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.application-reject-failed", "&cOdrzucenie aplikacji nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } + }); + } + + /** + * Odśwież ekwipunek + */ + private void refreshInventory(Player player) { + plugin.getGuiManager().refreshGUI(player); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/ConfirmDeleteGuildGUI.java b/src/main/java/com/guild/gui/ConfirmDeleteGuildGUI.java index 30481bf..af17f06 100644 --- a/src/main/java/com/guild/gui/ConfirmDeleteGuildGUI.java +++ b/src/main/java/com/guild/gui/ConfirmDeleteGuildGUI.java @@ -1,174 +1,174 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; - -/** - * 确认删除工会GUI - */ -public class ConfirmDeleteGuildGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - - public ConfirmDeleteGuildGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&4确认删除工会"); - } - - @Override - public int getSize() { - return 27; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示确认信息 - displayConfirmInfo(inventory); - - // 添加确认和取消按钮 - setupButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 11: // 确认删除 - handleConfirmDelete(player); - break; - case 15: // 取消 - handleCancel(player); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 18, border); - } - for (int i = 9; i < 18; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示确认信息 - */ - private void displayConfirmInfo(Inventory inventory) { - ItemStack info = createItem( - Material.BOOK, - ColorUtils.colorize("&4确认删除工会"), - ColorUtils.colorize("&7工会: &e" + guild.getName()), - ColorUtils.colorize("&7你确定要删除这个工会吗?"), - ColorUtils.colorize("&c此操作将永久删除工会!"), - ColorUtils.colorize("&c所有成员将被移除!"), - ColorUtils.colorize("&c此操作不可撤销!") - ); - inventory.setItem(13, info); - } - - /** - * 设置按钮 - */ - private void setupButtons(Inventory inventory) { - // 确认删除按钮 - ItemStack confirm = createItem( - Material.TNT, - ColorUtils.colorize("&4确认删除"), - ColorUtils.colorize("&7点击确认删除工会"), - ColorUtils.colorize("&c此操作不可撤销!") - ); - inventory.setItem(11, confirm); - - // 取消按钮 - ItemStack cancel = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize("&a取消"), - ColorUtils.colorize("&7取消删除工会") - ); - inventory.setItem(15, cancel); - } - - /** - * 处理确认删除 - */ - private void handleConfirmDelete(Player player) { - // 检查权限(只有当前工会会长可以删除) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getGuildId() != guild.getId() || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 删除工会 - plugin.getGuildService().deleteGuildAsync(guild.getId(), player.getUniqueId()).thenAccept(success -> { - if (success) { - String template = plugin.getConfigManager().getMessagesConfig().getString("delete.success", "&a工会 &e{guild} &a已被删除!"); - // 回到主线程进行界面操作 - CompatibleScheduler.runTask(plugin, () -> { - String rendered = ColorUtils.replaceWithColorIsolation(template, "{guild}", guild.getName()); - player.sendMessage(rendered); - // 使用GUIManager以确保主线程安全关闭与打开 - plugin.getGuiManager().closeGUI(player); - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - }); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("delete.failed", "&c删除工会失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 处理取消 - */ - private void handleCancel(Player player) { - // 返回工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +/** + * GUI Potwierdzenia Usunięcia Gildii + */ +public class ConfirmDeleteGuildGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + + public ConfirmDeleteGuildGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&4Potwierdź usunięcie gildii"); + } + + @Override + public int getSize() { + return 27; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl informacje potwierdzające + displayConfirmInfo(inventory); + + // Skonfiguruj przyciski + setupButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 11: // Potwierdź usunięcie + handleConfirmDelete(player); + break; + case 15: // Anuluj + handleCancel(player); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 18, border); + } + for (int i = 9; i < 18; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl informacje potwierdzające + */ + private void displayConfirmInfo(Inventory inventory) { + ItemStack info = createItem( + Material.BOOK, + ColorUtils.colorize("&4Potwierdź usunięcie gildii"), + ColorUtils.colorize("&7Gildia: &e" + guild.getName()), + ColorUtils.colorize("&7Czy na pewno chcesz usunąć tę gildię?"), + ColorUtils.colorize("&cTa operacja trwale usunie gildię!"), + ColorUtils.colorize("&cWszyscy członkowie zostaną usunięci!"), + ColorUtils.colorize("&cTej operacji nie można cofnąć!") + ); + inventory.setItem(13, info); + } + + /** + * Skonfiguruj przyciski + */ + private void setupButtons(Inventory inventory) { + // Przycisk potwierdzenia usunięcia + ItemStack confirm = createItem( + Material.TNT, + ColorUtils.colorize("&4Potwierdź usunięcie"), + ColorUtils.colorize("&7Kliknij, aby potwierdzić usunięcie gildii"), + ColorUtils.colorize("&cTej operacji nie można cofnąć!") + ); + inventory.setItem(11, confirm); + + // Przycisk anulowania + ItemStack cancel = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize("&aAnuluj"), + ColorUtils.colorize("&7Anuluj usuwanie gildii") + ); + inventory.setItem(15, cancel); + } + + /** + * Obsługa potwierdzenia usunięcia + */ + private void handleConfirmDelete(Player player) { + // Sprawdź uprawnienia (tylko lider gildii może usunąć) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getGuildId() != guild.getId() || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Usuń gildię + plugin.getGuildService().deleteGuildAsync(guild.getId(), player.getUniqueId()).thenAccept(success -> { + if (success) { + String template = plugin.getConfigManager().getMessagesConfig().getString("delete.success", "&aGildia &e{guild} &azostała usunięta!"); + // Wróć do głównego wątku w celu operacji na interfejsie + CompatibleScheduler.runTask(plugin, () -> { + String rendered = ColorUtils.replaceWithColorIsolation(template, "{guild}", guild.getName()); + player.sendMessage(rendered); + // Użyj GUIManager, aby zapewnić bezpieczne zamykanie i otwieranie w głównym wątku + plugin.getGuiManager().closeGUI(player); + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + }); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("delete.failed", "&cUsunięcie gildii nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Obsługa anulowania + */ + private void handleCancel(Player player) { + // Powrót do GUI ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/ConfirmLeaveGuildGUI.java b/src/main/java/com/guild/gui/ConfirmLeaveGuildGUI.java index 8ec23fc..7fd075d 100644 --- a/src/main/java/com/guild/gui/ConfirmLeaveGuildGUI.java +++ b/src/main/java/com/guild/gui/ConfirmLeaveGuildGUI.java @@ -1,165 +1,165 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; - -/** - * 确认离开工会GUI - */ -public class ConfirmLeaveGuildGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - - public ConfirmLeaveGuildGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&c确认离开工会"); - } - - @Override - public int getSize() { - return 27; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示确认信息 - displayConfirmInfo(inventory); - - // 添加确认和取消按钮 - setupButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 11: // 确认离开 - handleConfirmLeave(player); - break; - case 15: // 取消 - handleCancel(player); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 18, border); - } - for (int i = 9; i < 18; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示确认信息 - */ - private void displayConfirmInfo(Inventory inventory) { - ItemStack info = createItem( - Material.BOOK, - ColorUtils.colorize("&c确认离开工会"), - ColorUtils.colorize("&7工会: &e" + guild.getName()), - ColorUtils.colorize("&7你确定要离开这个工会吗?"), - ColorUtils.colorize("&c此操作不可撤销!") - ); - inventory.setItem(13, info); - } - - /** - * 设置按钮 - */ - private void setupButtons(Inventory inventory) { - // 确认离开按钮 - ItemStack confirm = createItem( - Material.REDSTONE_BLOCK, - ColorUtils.colorize("&c确认离开"), - ColorUtils.colorize("&7点击确认离开工会") - ); - inventory.setItem(11, confirm); - - // 取消按钮 - ItemStack cancel = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize("&a取消"), - ColorUtils.colorize("&7取消离开工会") - ); - inventory.setItem(15, cancel); - } - - /** - * 处理确认离开 - */ - private void handleConfirmLeave(Player player) { - // 检查是否是会长 - if (player.getUniqueId().equals(guild.getLeaderUuid())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("leave.leader-cannot-leave", "&c工会会长不能离开工会!请先转让会长职位或删除工会。"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 离开工会 - plugin.getGuildService().removeGuildMemberAsync(player.getUniqueId(), player.getUniqueId()).thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("leave.success", "&a你已成功离开工会 &e{guild} &a!") - .replace("{guild}", guild.getName()); - player.sendMessage(ColorUtils.colorize(message)); - - // 关闭GUI - player.closeInventory(); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("leave.failed", "&c离开工会失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 处理取消 - */ - private void handleCancel(Player player) { - // 返回工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +/** + * GUI Potwierdzenia Opuszczenia Gildii + */ +public class ConfirmLeaveGuildGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + + public ConfirmLeaveGuildGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&cPotwierdź opuszczenie gildii"); + } + + @Override + public int getSize() { + return 27; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl informacje potwierdzające + displayConfirmInfo(inventory); + + // Skonfiguruj przyciski + setupButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 11: // Potwierdź opuszczenie + handleConfirmLeave(player); + break; + case 15: // Anuluj + handleCancel(player); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 18, border); + } + for (int i = 9; i < 18; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl informacje potwierdzające + */ + private void displayConfirmInfo(Inventory inventory) { + ItemStack info = createItem( + Material.BOOK, + ColorUtils.colorize("&cPotwierdź opuszczenie gildii"), + ColorUtils.colorize("&7Gildia: &e" + guild.getName()), + ColorUtils.colorize("&7Czy na pewno chcesz opuścić tę gildię?"), + ColorUtils.colorize("&cTej operacji nie można cofnąć!") + ); + inventory.setItem(13, info); + } + + /** + * Skonfiguruj przyciski + */ + private void setupButtons(Inventory inventory) { + // Przycisk potwierdzenia opuszczenia + ItemStack confirm = createItem( + Material.REDSTONE_BLOCK, + ColorUtils.colorize("&cPotwierdź opuszczenie"), + ColorUtils.colorize("&7Kliknij, aby potwierdzić opuszczenie gildii") + ); + inventory.setItem(11, confirm); + + // Przycisk anulowania + ItemStack cancel = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize("&aAnuluj"), + ColorUtils.colorize("&7Anuluj opuszczenie gildii") + ); + inventory.setItem(15, cancel); + } + + /** + * Obsługa potwierdzenia opuszczenia + */ + private void handleConfirmLeave(Player player) { + // Sprawdź, czy gracz jest liderem + if (player.getUniqueId().equals(guild.getLeaderUuid())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("leave.leader-cannot-leave", "&cLider gildii nie może opuścić gildii! Proszę najpierw przekazać przywództwo lub usunąć gildię."); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Opuść gildię + plugin.getGuildService().removeGuildMemberAsync(player.getUniqueId(), player.getUniqueId()).thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("leave.success", "&aPomyślnie opuściłeś gildię &e{guild} &a!") + .replace("{guild}", guild.getName()); + player.sendMessage(ColorUtils.colorize(message)); + + // Zamknij GUI + player.closeInventory(); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("leave.failed", "&cOpuszczenie gildii nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Obsługa anulowania + */ + private void handleCancel(Player player) { + // Powrót do GUI ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/CreateGuildGUI.java b/src/main/java/com/guild/gui/CreateGuildGUI.java index 5ab85df..5f78b98 100644 --- a/src/main/java/com/guild/gui/CreateGuildGUI.java +++ b/src/main/java/com/guild/gui/CreateGuildGUI.java @@ -1,433 +1,433 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; - -import com.guild.core.utils.CompatibleScheduler; - -/** - * 创建工会GUI - */ -public class CreateGuildGUI implements GUI { - - private final GuildPlugin plugin; - private String guildName = ""; - private String guildTag = ""; - private String guildDescription = ""; - - public CreateGuildGUI(GuildPlugin plugin) { - this.plugin = plugin; - } - - public CreateGuildGUI(GuildPlugin plugin, String guildName, String guildTag, String guildDescription) { - this.plugin = plugin; - this.guildName = guildName; - this.guildTag = guildTag; - this.guildDescription = guildDescription; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.title", "&6创建工会")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("create-guild.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 添加输入按钮 - setupInputButtons(inventory); - - // 添加确认/取消按钮 - setupActionButtons(inventory); - - // 显示当前输入信息 - displayCurrentInput(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 20: // 工会名称输入 - handleNameInput(player); - break; - case 22: // 工会标签输入 - handleTagInput(player); - break; - case 24: // 工会描述输入 - handleDescriptionInput(player); - break; - case 39: // 确认创建 - handleConfirmCreate(player); - break; - case 41: // 取消 - handleCancel(player); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 设置输入按钮 - */ - private void setupInputButtons(Inventory inventory) { - // 工会名称输入按钮 - ItemStack nameInput = createItem( - Material.NAME_TAG, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.name-input.name", "&e工会名称")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.name-input.lore.1", "&7点击输入工会名称")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.name-input.lore.2", "&7长度: 3-20 字符")) - ); - inventory.setItem(20, nameInput); - - // 工会标签输入按钮 - ItemStack tagInput = createItem( - Material.OAK_SIGN, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.name", "&e工会标签")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.lore.1", "&7点击输入工会标签")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.lore.2", "&7长度: 最多6字符")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.lore.3", "&7可选")) - ); - inventory.setItem(22, tagInput); - - // 工会描述输入按钮 - ItemStack descriptionInput = createItem( - Material.BOOK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.name", "&e工会描述")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.lore.1", "&7点击输入工会描述")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.lore.2", "&7长度: 最多100字符")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.lore.3", "&7可选")) - ); - inventory.setItem(24, descriptionInput); - } - - /** - * 设置操作按钮 - */ - private void setupActionButtons(Inventory inventory) { - // 获取创建费用 - double creationCost = plugin.getConfigManager().getMainConfig().getDouble("guild.creation-cost", 1000.0); - String costText = String.format("%.0f", creationCost); - - // 确认创建按钮 - String confirmName = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.name", "&a确认创建"); - String confirmLore1 = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.lore.1", "&7确认创建工会"); - String confirmLore2 = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.lore.2", "&7费用: {cost} 金币"); - String confirmLore3 = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.lore.3", "&7创建者: {player_name}"); - - // 替换变量 - confirmLore2 = confirmLore2.replace("{cost}", costText); - confirmLore3 = confirmLore3.replace("{player_name}", "当前玩家"); - - ItemStack confirm = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize(confirmName), - ColorUtils.colorize(confirmLore1), - ColorUtils.colorize(confirmLore2), - ColorUtils.colorize(confirmLore3) - ); - inventory.setItem(39, confirm); - - // 取消按钮 - ItemStack cancel = createItem( - Material.REDSTONE_BLOCK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.cancel.name", "&c取消")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.cancel.lore.1", "&7取消创建工会")) - ); - inventory.setItem(41, cancel); - } - - /** - * 显示当前输入信息 - */ - private void displayCurrentInput(Inventory inventory) { - // 当前工会名称 - String nameDisplay = guildName.isEmpty() ? "未设置" : guildName; - ItemStack currentName = createItem( - Material.NAME_TAG, - ColorUtils.colorize("&e当前工会名称"), - ColorUtils.colorize("&7" + nameDisplay) - ); - inventory.setItem(11, currentName); - - // 当前工会标签 - String tagDisplay = guildTag.isEmpty() ? "未设置" : "[" + guildTag + "]"; - ItemStack currentTag = createItem( - Material.OAK_SIGN, - ColorUtils.colorize("&e当前工会标签"), - ColorUtils.colorize("&7" + tagDisplay) - ); - inventory.setItem(13, currentTag); - - // 当前工会描述 - String descriptionDisplay = guildDescription.isEmpty() ? "未设置" : guildDescription; - ItemStack currentDescription = createItem( - Material.BOOK, - ColorUtils.colorize("&e当前工会描述"), - ColorUtils.colorize("&7" + descriptionDisplay) - ); - inventory.setItem(15, currentDescription); - } - - /** - * 处理工会名称输入 - */ - private void handleNameInput(Player player) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-name", "&a请在聊天中输入工会名称(3-20字符):"); - player.sendMessage(ColorUtils.colorize(message)); - - // 强制关闭GUI以便玩家看到输入提示 - if (player.getOpenInventory() != null) { - player.closeInventory(); - } - plugin.getGuiManager().closeGUI(player); - - // 延迟设置输入模式,确保GUI完全关闭 - CompatibleScheduler.runTaskLater(plugin, () -> { - // 设置输入模式 - plugin.getGuiManager().setInputMode(player, input -> { - if (input.length() < 3) { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-short", "&c工会名称太短!最少需要 {min} 个字符。"); - errorMessage = errorMessage.replace("{min}", "3"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - return false; - } - - if (input.length() > 20) { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-long", "&c工会名称太长!最多只能有 {max} 个字符。"); - errorMessage = errorMessage.replace("{max}", "20"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - return false; - } - - guildName = input; - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.name-set", "&a工会名称已设置为:{name}"); - successMessage = successMessage.replace("{name}", guildName); - player.sendMessage(ColorUtils.colorize(successMessage)); - - // 重新打开GUI显示更新后的内容 - plugin.getGuiManager().openGUI(player, new CreateGuildGUI(plugin, guildName, guildTag, guildDescription)); - return true; - }); - }, 2L); // 延迟2个tick (0.1秒) - } - - /** - * 处理工会标签输入 - */ - private void handleTagInput(Player player) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-tag", "&a请在聊天中输入工会标签(最多6字符,可选):"); - player.sendMessage(ColorUtils.colorize(message)); - - // 强制关闭GUI以便玩家看到输入提示 - if (player.getOpenInventory() != null) { - player.closeInventory(); - } - plugin.getGuiManager().closeGUI(player); - - // 延迟设置输入模式,确保GUI完全关闭 - CompatibleScheduler.runTaskLater(plugin, () -> { - // 设置输入模式 - plugin.getGuiManager().setInputMode(player, input -> { - if (input.length() > 6) { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.tag-too-long", "&c工会标签太长!最多只能有 {max} 个字符。"); - errorMessage = errorMessage.replace("{max}", "6"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - return false; - } - - guildTag = input; - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-set", "&a工会标签已设置为:{tag}"); - successMessage = successMessage.replace("{tag}", guildTag.isEmpty() ? "无" : guildTag); - player.sendMessage(ColorUtils.colorize(successMessage)); - - // 重新打开GUI显示更新后的内容 - plugin.getGuiManager().openGUI(player, new CreateGuildGUI(plugin, guildName, guildTag, guildDescription)); - return true; - }); - }, 2L); // 延迟2个tick (0.1秒) - } - - /** - * 处理工会描述输入 - */ - private void handleDescriptionInput(Player player) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-description", "&a请在聊天中输入工会描述(最多100字符,可选):"); - player.sendMessage(ColorUtils.colorize(message)); - - // 强制关闭GUI以便玩家看到输入提示 - if (player.getOpenInventory() != null) { - player.closeInventory(); - } - plugin.getGuiManager().closeGUI(player); - - // 延迟设置输入模式,确保GUI完全关闭 - CompatibleScheduler.runTaskLater(plugin, () -> { - // 设置输入模式 - plugin.getGuiManager().setInputMode(player, input -> { - if (input.length() > 100) { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.description-too-long", "&c工会描述不能超过100个字符!"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - return false; - } - - guildDescription = input; - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-set", "&a工会描述已设置为:{description}"); - successMessage = successMessage.replace("{description}", guildDescription.isEmpty() ? "无" : guildDescription); - player.sendMessage(ColorUtils.colorize(successMessage)); - - // 重新打开GUI显示更新后的内容 - plugin.getGuiManager().openGUI(player, new CreateGuildGUI(plugin, guildName, guildTag, guildDescription)); - return true; - }); - }, 2L); // 延迟2个tick (0.1秒) - } - - /** - * 处理确认创建 - */ - private void handleConfirmCreate(Player player) { - // 验证输入 - if (guildName.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-required", "&c请先输入工会名称!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (guildName.length() < 3) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-short", "&c工会名称太短!最少需要 {min} 个字符。"); - message = message.replace("{min}", "3"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (guildName.length() > 20) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-long", "&c工会名称太长!最多只能有 {max} 个字符。"); - message = message.replace("{max}", "20"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (!guildTag.isEmpty() && guildTag.length() > 6) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.tag-too-long", "&c工会标签太长!最多只能有 {max} 个字符。"); - message = message.replace("{max}", "6"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (!guildDescription.isEmpty() && guildDescription.length() > 100) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.description-too-long", "&c工会描述不能超过100个字符!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查经济系统 - if (!plugin.getEconomyManager().isVaultAvailable()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.economy-not-available", "&c经济系统不可用,无法创建工会!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取创建费用 - double creationCost = plugin.getConfigManager().getMainConfig().getDouble("guild.creation-cost", 1000.0); - - // 检查玩家余额 - if (!plugin.getEconomyManager().hasBalance(player, creationCost)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.insufficient-funds", "&c您的余额不足!创建工会需要 {cost} 金币。"); - message = message.replace("{cost}", String.format("%.0f", creationCost)); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 扣除创建费用 - if (!plugin.getEconomyManager().withdraw(player, creationCost)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.payment-failed", "&c扣除创建费用失败!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 创建工会 - String finalTag = guildTag.isEmpty() ? null : guildTag; - String finalDescription = guildDescription.isEmpty() ? null : guildDescription; - - plugin.getGuildService().createGuildAsync(guildName, finalTag, finalDescription, player.getUniqueId(), player.getName()).thenAccept(success -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String template = plugin.getConfigManager().getMessagesConfig().getString("create.success", "&a工会 {name} 创建成功!"); - // 使用颜色隔离,避免 {name} 的内嵌颜色影响后续文本 - String rendered = ColorUtils.replaceWithColorIsolation(template, "{name}", guildName); - player.sendMessage(rendered); - - // 关闭GUI并返回主界面 - plugin.getGuiManager().closeGUI(player); - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - } else { - // 如果创建失败,退还费用 - plugin.getEconomyManager().deposit(player, creationCost); - String refundMessage = plugin.getConfigManager().getMessagesConfig().getString("create.payment-refunded", "&e已退还创建费用 {cost} 金币。"); - refundMessage = refundMessage.replace("{cost}", String.format("%.0f", creationCost)); - player.sendMessage(ColorUtils.colorize(refundMessage)); - - String message = plugin.getConfigManager().getMessagesConfig().getString("create.failed", "&c工会创建失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理取消 - */ - private void handleCancel(Player player) { - plugin.getGuiManager().closeGUI(player); - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +import com.guild.core.utils.CompatibleScheduler; + +/** + * GUI Tworzenia Gildii + */ +public class CreateGuildGUI implements GUI { + + private final GuildPlugin plugin; + private String guildName = ""; + private String guildTag = ""; + private String guildDescription = ""; + + public CreateGuildGUI(GuildPlugin plugin) { + this.plugin = plugin; + } + + public CreateGuildGUI(GuildPlugin plugin, String guildName, String guildTag, String guildDescription) { + this.plugin = plugin; + this.guildName = guildName; + this.guildTag = guildTag; + this.guildDescription = guildDescription; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.title", "&6Stwórz gildię")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("create-guild.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Dodaj przyciski wprowadzania danych + setupInputButtons(inventory); + + // Dodaj przyciski akcji (potwierdź/anuluj) + setupActionButtons(inventory); + + // Wyświetl aktualnie wprowadzone informacje + displayCurrentInput(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 20: // Wprowadzanie nazwy gildii + handleNameInput(player); + break; + case 22: // Wprowadzanie tagu gildii + handleTagInput(player); + break; + case 24: // Wprowadzanie opisu gildii + handleDescriptionInput(player); + break; + case 39: // Potwierdzenie utworzenia + handleConfirmCreate(player); + break; + case 41: // Anulowanie + handleCancel(player); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Skonfiguruj przyciski wprowadzania + */ + private void setupInputButtons(Inventory inventory) { + // Przycisk wprowadzania nazwy gildii + ItemStack nameInput = createItem( + Material.NAME_TAG, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.name-input.name", "&eNazwa gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.name-input.lore.1", "&7Kliknij, aby wpisać nazwę gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.name-input.lore.2", "&7Długość: 3-20 znaków")) + ); + inventory.setItem(20, nameInput); + + // Przycisk wprowadzania tagu gildii + ItemStack tagInput = createItem( + Material.OAK_SIGN, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.name", "&eTag gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.lore.1", "&7Kliknij, aby wpisać tag gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.lore.2", "&7Długość: maks. 6 znaków")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.tag-input.lore.3", "&7Opcjonalne")) + ); + inventory.setItem(22, tagInput); + + // Przycisk wprowadzania opisu gildii + ItemStack descriptionInput = createItem( + Material.BOOK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.name", "&eOpis gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.lore.1", "&7Kliknij, aby wpisać opis gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.lore.2", "&7Długość: maks. 100 znaków")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.description-input.lore.3", "&7Opcjonalne")) + ); + inventory.setItem(24, descriptionInput); + } + + /** + * Skonfiguruj przyciski akcji + */ + private void setupActionButtons(Inventory inventory) { + // Pobierz koszt utworzenia + double creationCost = plugin.getConfigManager().getMainConfig().getDouble("guild.creation-cost", 1000.0); + String costText = String.format("%.0f", creationCost); + + // Przycisk potwierdzenia utworzenia + String confirmName = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.name", "&aPotwierdź utworzenie"); + String confirmLore1 = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.lore.1", "&7Potwierdź utworzenie gildii"); + String confirmLore2 = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.lore.2", "&7Koszt: {cost} monet"); + String confirmLore3 = plugin.getConfigManager().getGuiConfig().getString("create-guild.items.confirm.lore.3", "&7Twórca: {player_name}"); + + // Zastąp zmienne + confirmLore2 = confirmLore2.replace("{cost}", costText); + confirmLore3 = confirmLore3.replace("{player_name}", "Obecny gracz"); + + ItemStack confirm = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize(confirmName), + ColorUtils.colorize(confirmLore1), + ColorUtils.colorize(confirmLore2), + ColorUtils.colorize(confirmLore3) + ); + inventory.setItem(39, confirm); + + // Przycisk anulowania + ItemStack cancel = createItem( + Material.REDSTONE_BLOCK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.cancel.name", "&cAnuluj")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("create-guild.items.cancel.lore.1", "&7Anuluj tworzenie gildii")) + ); + inventory.setItem(41, cancel); + } + + /** + * Wyświetl aktualnie wprowadzone informacje + */ + private void displayCurrentInput(Inventory inventory) { + // Obecna nazwa gildii + String nameDisplay = guildName.isEmpty() ? "Nie ustawiono" : guildName; + ItemStack currentName = createItem( + Material.NAME_TAG, + ColorUtils.colorize("&eObecna nazwa gildii"), + ColorUtils.colorize("&7" + nameDisplay) + ); + inventory.setItem(11, currentName); + + // Obecny tag gildii + String tagDisplay = guildTag.isEmpty() ? "Nie ustawiono" : "[" + guildTag + "]"; + ItemStack currentTag = createItem( + Material.OAK_SIGN, + ColorUtils.colorize("&eObecny tag gildii"), + ColorUtils.colorize("&7" + tagDisplay) + ); + inventory.setItem(13, currentTag); + + // Obecny opis gildii + String descriptionDisplay = guildDescription.isEmpty() ? "Nie ustawiono" : guildDescription; + ItemStack currentDescription = createItem( + Material.BOOK, + ColorUtils.colorize("&eObecny opis gildii"), + ColorUtils.colorize("&7" + descriptionDisplay) + ); + inventory.setItem(15, currentDescription); + } + + /** + * Obsługa wprowadzania nazwy gildii + */ + private void handleNameInput(Player player) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-name", "&aProszę wpisać nazwę gildii na czacie (3-20 znaków):"); + player.sendMessage(ColorUtils.colorize(message)); + + // Wymuś zamknięcie GUI, aby gracz zobaczył komunikat + if (player.getOpenInventory() != null) { + player.closeInventory(); + } + plugin.getGuiManager().closeGUI(player); + + // Opóźnij ustawienie trybu wprowadzania, aby upewnić się, że GUI jest całkowicie zamknięte + CompatibleScheduler.runTaskLater(plugin, () -> { + // Ustaw tryb wprowadzania + plugin.getGuiManager().setInputMode(player, input -> { + if (input.length() < 3) { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-short", "&cNazwa gildii jest za krótka! Wymagane co najmniej {min} znaków."); + errorMessage = errorMessage.replace("{min}", "3"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + return false; + } + + if (input.length() > 20) { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-long", "&cNazwa gildii jest za długa! Maksymalnie {max} znaków."); + errorMessage = errorMessage.replace("{max}", "20"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + return false; + } + + guildName = input; + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.name-set", "&aNazwa gildii została ustawiona na: {name}"); + successMessage = successMessage.replace("{name}", guildName); + player.sendMessage(ColorUtils.colorize(successMessage)); + + // Otwórz ponownie GUI z zaktualizowaną zawartością + plugin.getGuiManager().openGUI(player, new CreateGuildGUI(plugin, guildName, guildTag, guildDescription)); + return true; + }); + }, 2L); // Opóźnienie 2 ticki (0.1 sekundy) + } + + /** + * Obsługa wprowadzania tagu gildii + */ + private void handleTagInput(Player player) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-tag", "&aProszę wpisać tag gildii na czacie (maks. 6 znaków, opcjonalne):"); + player.sendMessage(ColorUtils.colorize(message)); + + // Wymuś zamknięcie GUI, aby gracz zobaczył komunikat + if (player.getOpenInventory() != null) { + player.closeInventory(); + } + plugin.getGuiManager().closeGUI(player); + + // Opóźnij ustawienie trybu wprowadzania, aby upewnić się, że GUI jest całkowicie zamknięte + CompatibleScheduler.runTaskLater(plugin, () -> { + // Ustaw tryb wprowadzania + plugin.getGuiManager().setInputMode(player, input -> { + if (input.length() > 6) { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.tag-too-long", "&cTag gildii jest za długi! Maksymalnie {max} znaków."); + errorMessage = errorMessage.replace("{max}", "6"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + return false; + } + + guildTag = input; + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-set", "&aTag gildii został ustawiony na: {tag}"); + successMessage = successMessage.replace("{tag}", guildTag.isEmpty() ? "brak" : guildTag); + player.sendMessage(ColorUtils.colorize(successMessage)); + + // Otwórz ponownie GUI z zaktualizowaną zawartością + plugin.getGuiManager().openGUI(player, new CreateGuildGUI(plugin, guildName, guildTag, guildDescription)); + return true; + }); + }, 2L); // Opóźnienie 2 ticki (0.1 sekundy) + } + + /** + * Obsługa wprowadzania opisu gildii + */ + private void handleDescriptionInput(Player player) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-description", "&aProszę wpisać opis gildii na czacie (maks. 100 znaków, opcjonalne):"); + player.sendMessage(ColorUtils.colorize(message)); + + // Wymuś zamknięcie GUI, aby gracz zobaczył komunikat + if (player.getOpenInventory() != null) { + player.closeInventory(); + } + plugin.getGuiManager().closeGUI(player); + + // Opóźnij ustawienie trybu wprowadzania, aby upewnić się, że GUI jest całkowicie zamknięte + CompatibleScheduler.runTaskLater(plugin, () -> { + // Ustaw tryb wprowadzania + plugin.getGuiManager().setInputMode(player, input -> { + if (input.length() > 100) { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("create.description-too-long", "&cOpis gildii nie może przekraczać 100 znaków!"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + return false; + } + + guildDescription = input; + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-set", "&aOpis gildii został ustawiony na: {description}"); + successMessage = successMessage.replace("{description}", guildDescription.isEmpty() ? "brak" : guildDescription); + player.sendMessage(ColorUtils.colorize(successMessage)); + + // Otwórz ponownie GUI z zaktualizowaną zawartością + plugin.getGuiManager().openGUI(player, new CreateGuildGUI(plugin, guildName, guildTag, guildDescription)); + return true; + }); + }, 2L); // Opóźnienie 2 ticki (0.1 sekundy) + } + + /** + * Obsługa potwierdzenia utworzenia + */ + private void handleConfirmCreate(Player player) { + // Weryfikacja danych wejściowych + if (guildName.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-required", "&cProszę najpierw wpisać nazwę gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (guildName.length() < 3) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-short", "&cNazwa gildii jest za krótka! Wymagane co najmniej {min} znaków."); + message = message.replace("{min}", "3"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (guildName.length() > 20) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.name-too-long", "&cNazwa gildii jest za długa! Maksymalnie {max} znaków."); + message = message.replace("{max}", "20"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (!guildTag.isEmpty() && guildTag.length() > 6) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.tag-too-long", "&cTag gildii jest za długi! Maksymalnie {max} znaków."); + message = message.replace("{max}", "6"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (!guildDescription.isEmpty() && guildDescription.length() > 100) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.description-too-long", "&cOpis gildii nie może przekraczać 100 znaków!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź system ekonomii + if (!plugin.getEconomyManager().isVaultAvailable()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.economy-not-available", "&cSystem ekonomii jest niedostępny, nie można utworzyć gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz koszt utworzenia + double creationCost = plugin.getConfigManager().getMainConfig().getDouble("guild.creation-cost", 1000.0); + + // Sprawdź saldo gracza + if (!plugin.getEconomyManager().hasBalance(player, creationCost)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.insufficient-funds", "&cMasz za mało środków! Utworzenie gildii kosztuje {cost} monet."); + message = message.replace("{cost}", String.format("%.0f", creationCost)); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz opłatę za utworzenie + if (!plugin.getEconomyManager().withdraw(player, creationCost)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.payment-failed", "&cPobranie opłaty za utworzenie nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Utwórz gildię + String finalTag = guildTag.isEmpty() ? null : guildTag; + String finalDescription = guildDescription.isEmpty() ? null : guildDescription; + + plugin.getGuildService().createGuildAsync(guildName, finalTag, finalDescription, player.getUniqueId(), player.getName()).thenAccept(success -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String template = plugin.getConfigManager().getMessagesConfig().getString("create.success", "&aGildia {name} została pomyślnie utworzona!"); + // Użyj izolacji kolorów, aby uniknąć wpływu osadzonych kolorów z {name} na dalszy tekst + String rendered = ColorUtils.replaceWithColorIsolation(template, "{name}", guildName); + player.sendMessage(rendered); + + // Zamknij GUI i wróć do głównego menu + plugin.getGuiManager().closeGUI(player); + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + } else { + // Jeśli tworzenie nie powiodło się, zwróć opłatę + plugin.getEconomyManager().deposit(player, creationCost); + String refundMessage = plugin.getConfigManager().getMessagesConfig().getString("create.payment-refunded", "&eZwrócono opłatę za utworzenie w wysokości {cost} monet."); + refundMessage = refundMessage.replace("{cost}", String.format("%.0f", creationCost)); + player.sendMessage(ColorUtils.colorize(refundMessage)); + + String message = plugin.getConfigManager().getMessagesConfig().getString("create.failed", "&cTworzenie gildii nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa anulowania + */ + private void handleCancel(Player player) { + plugin.getGuiManager().closeGUI(player); + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/DemoteMemberGUI.java b/src/main/java/com/guild/gui/DemoteMemberGUI.java index 58820c9..c8d233b 100644 --- a/src/main/java/com/guild/gui/DemoteMemberGUI.java +++ b/src/main/java/com/guild/gui/DemoteMemberGUI.java @@ -1,234 +1,234 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 降级成员GUI - */ -public class DemoteMemberGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private int currentPage = 0; - private List members; - - public DemoteMemberGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - // 初始化时获取成员列表 - this.members = List.of(); - loadMembers(); - } - - private void loadMembers() { - plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(memberList -> { - this.members = memberList.stream() - .filter(member -> !member.getPlayerUuid().equals(guild.getLeaderUuid())) - .filter(member -> member.getRole().equals(GuildMember.Role.OFFICER)) // 只显示官员 - .collect(java.util.stream.Collectors.toList()); - }); - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6降级成员 - 第" + (currentPage + 1) + "页"); - } - - @Override - public int getSize() { - return 54; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示成员列表 - displayMembers(inventory); - - // 添加导航按钮 - setupNavigationButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (slot >= 9 && slot < 45) { - // 成员头像区域 - int memberIndex = slot - 9 + (currentPage * 36); - if (memberIndex < members.size()) { - GuildMember member = members.get(memberIndex); - handleDemoteMember(player, member); - } - } else if (slot == 45) { - // 上一页 - if (currentPage > 0) { - currentPage--; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 53) { - // 下一页 - int maxPage = (members.size() - 1) / 36; - if (currentPage < maxPage) { - currentPage++; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 49) { - // 返回 - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示成员列表 - */ - private void displayMembers(Inventory inventory) { - int startIndex = currentPage * 36; - int endIndex = Math.min(startIndex + 36, members.size()); - - for (int i = startIndex; i < endIndex; i++) { - GuildMember member = members.get(i); - int slot = 9 + (i - startIndex); - - ItemStack memberHead = createMemberHead(member); - inventory.setItem(slot, memberHead); - } - } - - /** - * 设置导航按钮 - */ - private void setupNavigationButtons(Inventory inventory) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack prevPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e上一页"), - ColorUtils.colorize("&7点击查看上一页") - ); - inventory.setItem(45, prevPage); - } - - // 下一页按钮 - int maxPage = (members.size() - 1) / 36; - if (currentPage < maxPage) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e下一页"), - ColorUtils.colorize("&7点击查看下一页") - ); - inventory.setItem(53, nextPage); - } - - // 返回按钮 - ItemStack back = createItem( - Material.BARRIER, - ColorUtils.colorize("&c返回"), - ColorUtils.colorize("&7返回工会设置") - ); - inventory.setItem(49, back); - } - - /** - * 创建成员头像 - */ - private ItemStack createMemberHead(GuildMember member) { - ItemStack head = new ItemStack(Material.PLAYER_HEAD); - SkullMeta meta = (SkullMeta) head.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(ColorUtils.colorize("&7" + member.getPlayerName())); - meta.setLore(Arrays.asList( - ColorUtils.colorize("&7当前职位: &e" + member.getRole().getDisplayName()), - ColorUtils.colorize("&7加入时间: &e" + member.getJoinedAt()), - ColorUtils.colorize("&7点击降级为成员") - )); - head.setItemMeta(meta); - } - - return head; - } - - /** - * 处理降级成员 - */ - private void handleDemoteMember(Player demoter, GuildMember member) { - // 检查权限 - if (!demoter.hasPermission("guild.demote")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - demoter.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 降级成员 - plugin.getGuildService().updateMemberRoleAsync(member.getPlayerUuid(), GuildMember.Role.MEMBER, demoter.getUniqueId()).thenAccept(success -> { - if (success) { - String demoterMessage = plugin.getConfigManager().getMessagesConfig().getString("demote.success", "&a已降级 &e{player} &a为成员!") - .replace("{player}", member.getPlayerName()); - demoter.sendMessage(ColorUtils.colorize(demoterMessage)); - - // 通知被降级的玩家 - Player demotedPlayer = plugin.getServer().getPlayer(member.getPlayerUuid()); - if (demotedPlayer != null) { - String demotedMessage = plugin.getConfigManager().getMessagesConfig().getString("demote.demoted", "&c你被降级为工会 &e{guild} &c的成员!") - .replace("{guild}", guild.getName()); - demotedPlayer.sendMessage(ColorUtils.colorize(demotedMessage)); - } - - // 刷新GUI - plugin.getGuiManager().openGUI(demoter, new DemoteMemberGUI(plugin, guild)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("demote.failed", "&c降级成员失败!"); - demoter.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Degradacji Członka + */ +public class DemoteMemberGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private int currentPage = 0; + private List members; + + public DemoteMemberGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + // Inicjalizacja listy członków + this.members = List.of(); + loadMembers(); + } + + private void loadMembers() { + plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(memberList -> { + this.members = memberList.stream() + .filter(member -> !member.getPlayerUuid().equals(guild.getLeaderUuid())) + .filter(member -> member.getRole().equals(GuildMember.Role.OFFICER)) // Pokaż tylko oficerów + .collect(java.util.stream.Collectors.toList()); + }); + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Degradacja - Strona " + (currentPage + 1)); + } + + @Override + public int getSize() { + return 54; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl listę członków + displayMembers(inventory); + + // Dodaj przyciski nawigacyjne + setupNavigationButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (slot >= 9 && slot < 45) { + // Obszar głów członków + int memberIndex = slot - 9 + (currentPage * 36); + if (memberIndex < members.size()) { + GuildMember member = members.get(memberIndex); + handleDemoteMember(player, member); + } + } else if (slot == 45) { + // Poprzednia strona + if (currentPage > 0) { + currentPage--; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 53) { + // Następna strona + int maxPage = (members.size() - 1) / 36; + if (currentPage < maxPage) { + currentPage++; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 49) { + // Powrót + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl listę członków + */ + private void displayMembers(Inventory inventory) { + int startIndex = currentPage * 36; + int endIndex = Math.min(startIndex + 36, members.size()); + + for (int i = startIndex; i < endIndex; i++) { + GuildMember member = members.get(i); + int slot = 9 + (i - startIndex); + + ItemStack memberHead = createMemberHead(member); + inventory.setItem(slot, memberHead); + } + } + + /** + * Skonfiguruj przyciski nawigacyjne + */ + private void setupNavigationButtons(Inventory inventory) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack prevPage = createItem( + Material.ARROW, + ColorUtils.colorize("&ePoprzednia strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć poprzednią stronę") + ); + inventory.setItem(45, prevPage); + } + + // Przycisk następnej strony + int maxPage = (members.size() - 1) / 36; + if (currentPage < maxPage) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize("&eNastępna strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć następną stronę") + ); + inventory.setItem(53, nextPage); + } + + // Przycisk powrotu + ItemStack back = createItem( + Material.BARRIER, + ColorUtils.colorize("&cPowrót"), + ColorUtils.colorize("&7Powrót do ustawień gildii") + ); + inventory.setItem(49, back); + } + + /** + * Utwórz głowę członka + */ + private ItemStack createMemberHead(GuildMember member) { + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) head.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(ColorUtils.colorize("&7" + member.getPlayerName())); + meta.setLore(Arrays.asList( + ColorUtils.colorize("&7Obecna rola: &e" + member.getRole().getDisplayName()), + ColorUtils.colorize("&7Dołączył: &e" + member.getJoinedAt()), + ColorUtils.colorize("&7Kliknij, aby zdegradować do rangi Członek") + )); + head.setItemMeta(meta); + } + + return head; + } + + /** + * Obsługa degradacji członka + */ + private void handleDemoteMember(Player demoter, GuildMember member) { + // Sprawdź uprawnienia + if (!demoter.hasPermission("guild.demote")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + demoter.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Zdegraduj członka + plugin.getGuildService().updateMemberRoleAsync(member.getPlayerUuid(), GuildMember.Role.MEMBER, demoter.getUniqueId()).thenAccept(success -> { + if (success) { + String demoterMessage = plugin.getConfigManager().getMessagesConfig().getString("demote.success", "&aZdegradowano &e{player} &ado rangi Członek!") + .replace("{player}", member.getPlayerName()); + demoter.sendMessage(ColorUtils.colorize(demoterMessage)); + + // Powiadom zdegradowanego gracza + Player demotedPlayer = plugin.getServer().getPlayer(member.getPlayerUuid()); + if (demotedPlayer != null) { + String demotedMessage = plugin.getConfigManager().getMessagesConfig().getString("demote.demoted", "&cZostałeś zdegradowany do rangi Członek w gildii &e{guild}&c!") + .replace("{guild}", guild.getName()); + demotedPlayer.sendMessage(ColorUtils.colorize(demotedMessage)); + } + + // Odśwież GUI + plugin.getGuiManager().openGUI(demoter, new DemoteMemberGUI(plugin, guild)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("demote.failed", "&cDegradacja członka nie powiodła się!"); + demoter.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildDescriptionInputGUI.java b/src/main/java/com/guild/gui/GuildDescriptionInputGUI.java index cb3abc9..4662d8f 100644 --- a/src/main/java/com/guild/gui/GuildDescriptionInputGUI.java +++ b/src/main/java/com/guild/gui/GuildDescriptionInputGUI.java @@ -1,190 +1,190 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -/** - * 工会描述输入GUI - */ -public class GuildDescriptionInputGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private String currentDescription; - - public GuildDescriptionInputGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - this.currentDescription = guild.getDescription() != null ? guild.getDescription() : ""; - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6修改工会描述"); - } - - @Override - public int getSize() { - return 27; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示当前描述 - displayCurrentDescription(inventory); - - // 添加操作按钮 - setupButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 11: // 输入描述 - handleInputDescription(player); - break; - case 15: // 确认 - handleConfirm(player); - break; - case 13: // 取消 - handleCancel(player); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 18, border); - } - for (int i = 9; i < 18; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示当前描述 - */ - private void displayCurrentDescription(Inventory inventory) { - ItemStack currentDesc = createItem( - Material.BOOK, - ColorUtils.colorize("&e当前描述"), - ColorUtils.colorize("&7" + (currentDescription.isEmpty() ? "无描述" : currentDescription)) - ); - inventory.setItem(11, currentDesc); - } - - /** - * 设置按钮 - */ - private void setupButtons(Inventory inventory) { - // 确认按钮 - ItemStack confirm = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize("&a确认修改"), - ColorUtils.colorize("&7确认修改工会描述") - ); - inventory.setItem(15, confirm); - - // 取消按钮 - ItemStack cancel = createItem( - Material.REDSTONE_BLOCK, - ColorUtils.colorize("&c取消"), - ColorUtils.colorize("&7取消修改") - ); - inventory.setItem(13, cancel); - } - - /** - * 处理输入描述 - */ - private void handleInputDescription(Player player) { - // 关闭GUI - player.closeInventory(); - - // 发送消息提示输入 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-description", "&a请在聊天框中输入新的工会描述(最多100字符):"); - player.sendMessage(ColorUtils.colorize(message)); - - // 设置玩家为输入模式 - plugin.getGuiManager().setInputMode(player, input -> { - if (input.length() > 100) { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-too-long", "&c描述过长,最多100字符!"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - return false; - } - - // 更新描述 - currentDescription = input; - - // 保存到数据库 - plugin.getGuildService().updateGuildDescriptionAsync(guild.getId(), input).thenAccept(success -> { - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-updated", "&a工会描述已更新!"); - player.sendMessage(ColorUtils.colorize(successMessage)); - - // 安全刷新GUI - plugin.getGuiManager().refreshGUI(player); - } else { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-update-failed", "&c工会描述更新失败!"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - } - }); - - return true; - }); - } - - /** - * 处理确认 - */ - private void handleConfirm(Player player) { - // 返回工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 处理取消 - */ - private void handleCancel(Player player) { - // 返回工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Wprowadzania Opisu Gildii + */ +public class GuildDescriptionInputGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private String currentDescription; + + public GuildDescriptionInputGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + this.currentDescription = guild.getDescription() != null ? guild.getDescription() : ""; + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Zmień opis gildii"); + } + + @Override + public int getSize() { + return 27; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl obecny opis + displayCurrentDescription(inventory); + + // Dodaj przyciski akcji + setupButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 11: // Wprowadź opis + handleInputDescription(player); + break; + case 15: // Potwierdź + handleConfirm(player); + break; + case 13: // Anuluj + handleCancel(player); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 18, border); + } + for (int i = 9; i < 18; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl obecny opis + */ + private void displayCurrentDescription(Inventory inventory) { + ItemStack currentDesc = createItem( + Material.BOOK, + ColorUtils.colorize("&eObecny opis"), + ColorUtils.colorize("&7" + (currentDescription.isEmpty() ? "Brak opisu" : currentDescription)) + ); + inventory.setItem(11, currentDesc); + } + + /** + * Skonfiguruj przyciski + */ + private void setupButtons(Inventory inventory) { + // Przycisk potwierdzenia + ItemStack confirm = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize("&aZatwierdź zmianę"), + ColorUtils.colorize("&7Zatwierdź zmianę opisu gildii") + ); + inventory.setItem(15, confirm); + + // Przycisk anulowania + ItemStack cancel = createItem( + Material.REDSTONE_BLOCK, + ColorUtils.colorize("&cAnuluj"), + ColorUtils.colorize("&7Anuluj zmianę") + ); + inventory.setItem(13, cancel); + } + + /** + * Obsługa wprowadzania opisu + */ + private void handleInputDescription(Player player) { + // Zamknij GUI + player.closeInventory(); + + // Wyślij wiadomość z prośbą o wprowadzenie + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-description", "&aProszę wpisać nowy opis gildii na czacie (maksymalnie 100 znaków):"); + player.sendMessage(ColorUtils.colorize(message)); + + // Ustaw tryb wprowadzania dla gracza + plugin.getGuiManager().setInputMode(player, input -> { + if (input.length() > 100) { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-too-long", "&cOpis jest za długi, maksymalnie 100 znaków!"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + return false; + } + + // Zaktualizuj opis + currentDescription = input; + + // Zapisz w bazie danych + plugin.getGuildService().updateGuildDescriptionAsync(guild.getId(), input).thenAccept(success -> { + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-updated", "&aOpis gildii został zaktualizowany!"); + player.sendMessage(ColorUtils.colorize(successMessage)); + + // Bezpieczne odświeżenie GUI + plugin.getGuiManager().refreshGUI(player); + } else { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.description-update-failed", "&cAktualizacja opisu gildii nie powiodła się!"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + } + }); + + return true; + }); + } + + /** + * Obsługa potwierdzenia + */ + private void handleConfirm(Player player) { + // Powrót do GUI ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Obsługa anulowania + */ + private void handleCancel(Player player) { + // Powrót do GUI ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildInfoGUI.java b/src/main/java/com/guild/gui/GuildInfoGUI.java index de18cf6..e869129 100644 --- a/src/main/java/com/guild/gui/GuildInfoGUI.java +++ b/src/main/java/com/guild/gui/GuildInfoGUI.java @@ -1,293 +1,293 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.core.utils.GUIUtils; -import com.guild.core.utils.PlaceholderUtils; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import com.guild.services.GuildService; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * 工会信息GUI - */ -public class GuildInfoGUI implements GUI { - - private final GuildPlugin plugin; - private final Player player; - private final Guild guild; - private Inventory inventory; - - public GuildInfoGUI(GuildPlugin plugin, Player player, Guild guild) { - this.plugin = plugin; - this.player = player; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-info.title", "&6工会信息")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("guild-info.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - this.inventory = inventory; - - // 获取GUI配置 - ConfigurationSection config = plugin.getConfigManager().getGuiConfig().getConfigurationSection("guild-info.items"); - if (config == null) { - setupDefaultItems(); - return; - } - - // 设置配置的物品 - for (String key : config.getKeys(false)) { - ConfigurationSection itemConfig = config.getConfigurationSection(key); - if (itemConfig != null) { - setupConfigItem(itemConfig); - } - } - } - - private void setupConfigItem(ConfigurationSection itemConfig) { - String materialName = itemConfig.getString("material", "STONE"); - Material material = Material.valueOf(materialName.toUpperCase()); - int slot = itemConfig.getInt("slot", 0); - - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - // 设置名称 - String name = itemConfig.getString("name", ""); - if (!name.isEmpty()) { - // 使用GUIUtils处理变量 - GUIUtils.processGUIVariablesAsync(name, guild, player, plugin).thenAccept(processedName -> { - CompatibleScheduler.runTask(plugin, () -> { - meta.setDisplayName(processedName); - - // 设置描述 - List lore = itemConfig.getStringList("lore"); - if (!lore.isEmpty()) { - GUIUtils.processGUILoreAsync(lore, guild, player, plugin).thenAccept(processedLore -> { - CompatibleScheduler.runTask(plugin, () -> { - meta.setLore(processedLore); - item.setItemMeta(meta); - inventory.setItem(slot, item); - }); - }); - } else { - item.setItemMeta(meta); - inventory.setItem(slot, item); - } - }); - }); - } else { - // 如果没有名称,直接设置描述 - List lore = itemConfig.getStringList("lore"); - if (!lore.isEmpty()) { - GUIUtils.processGUILoreAsync(lore, guild, player, plugin).thenAccept(processedLore -> { - CompatibleScheduler.runTask(plugin, () -> { - meta.setLore(processedLore); - item.setItemMeta(meta); - inventory.setItem(slot, item); - }); - }); - } else { - item.setItemMeta(meta); - inventory.setItem(slot, item); - } - } - } else { - inventory.setItem(slot, item); - } - } - - private void setupDefaultItems() { - // 工会名称 - ItemStack nameItem = createItem(Material.NAME_TAG, "§6工会名称", - "§e" + guild.getName()); - inventory.setItem(10, nameItem); - - // 工会标签 - if (guild.getTag() != null && !guild.getTag().isEmpty()) { - ItemStack tagItem = createItem(Material.OAK_SIGN, "§6工会标签", - "§e[" + guild.getTag() + "]"); - inventory.setItem(12, tagItem); - } - - // 工会描述 - if (guild.getDescription() != null && !guild.getDescription().isEmpty()) { - ItemStack descItem = createItem(Material.BOOK, "§6工会描述", - "§e" + guild.getDescription()); - inventory.setItem(14, descItem); - } - - // 会长信息 - ItemStack leaderItem = createItem(Material.GOLDEN_HELMET, "§6会长", - "§e" + guild.getLeaderName()); - inventory.setItem(16, leaderItem); - - // 成员数量 - 使用异步方法 - plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenAccept(memberCount -> { - CompatibleScheduler.runTask(plugin, () -> { - ItemStack memberItem = createItem(Material.PLAYER_HEAD, "§6成员数量", - "§e" + memberCount + "/" + guild.getMaxMembers() + " 人"); - inventory.setItem(28, memberItem); - }); - }); - - // 工会等级 - ItemStack levelItem = createItem(Material.EXPERIENCE_BOTTLE, "§6工会等级", - "§e等级 " + guild.getLevel(), - "§7最大成员: " + guild.getMaxMembers() + " 人"); - inventory.setItem(30, levelItem); - - // 工会资金 - ItemStack balanceItem = createItem(Material.GOLD_INGOT, "§6工会资金", - "§e" + plugin.getEconomyManager().format(guild.getBalance()), - "§7等级升级需要: " + getNextLevelRequirement(guild.getLevel())); - inventory.setItem(32, balanceItem); - - // 创建时间(使用现实时间格式) - String createdTime = guild.getCreatedAt() != null - ? guild.getCreatedAt().format(com.guild.core.time.TimeProvider.FULL_FORMATTER) - : "未知"; - ItemStack timeItem = createItem(Material.CLOCK, "§6创建时间", "§e" + createdTime); - inventory.setItem(34, timeItem); - - // 工会状态 - String status = guild.isFrozen() ? "§c已冻结" : "§a正常"; - ItemStack statusItem = createItem(Material.BEACON, "§6工会状态", - status); - inventory.setItem(36, statusItem); - - // 返回按钮 - ItemStack backItem = createItem(Material.ARROW, "§c返回", - "§e点击返回主菜单"); - inventory.setItem(49, backItem); - } - - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - - List loreList = new ArrayList<>(); - for (String line : lore) { - loreList.add(line); - } - meta.setLore(loreList); - - item.setItemMeta(meta); - } - - return item; - } - - private String replacePlaceholders(String text) { - return PlaceholderUtils.replaceGuildPlaceholders(text, guild, player); - } - - private String replacePlaceholdersAsync(String text, int memberCount) { - // 先使用PlaceholderUtils处理基础变量 - String result = PlaceholderUtils.replaceGuildPlaceholders(text, guild, player); - - // 然后处理动态变量 - return result - .replace("{member_count}", String.valueOf(memberCount)) - .replace("{online_member_count}", String.valueOf(memberCount)); // 暂时使用总成员数 - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (slot == 49) { - // 返回主菜单 - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - } - } - - @Override - public void onClose(Player player) { - // 关闭时的处理 - } - - @Override - public void refresh(Player player) { - setupInventory(inventory); - } - - public Inventory getInventory() { - return inventory; - } - - /** - * 获取下一级升级所需资金 - */ - private String getNextLevelRequirement(int currentLevel) { - if (currentLevel >= 10) { - return "已达到最高等级"; - } - - double required = 0; - switch (currentLevel) { - case 1: required = 5000; break; - case 2: required = 10000; break; - case 3: required = 20000; break; - case 4: required = 35000; break; - case 5: required = 50000; break; - case 6: required = 75000; break; - case 7: required = 100000; break; - case 8: required = 150000; break; - case 9: required = 200000; break; - } - - return plugin.getEconomyManager().format(required); - } - - /** - * 获取当前等级进度 - */ - private String getLevelProgress(int currentLevel, double currentBalance) { - if (currentLevel >= 10) { - return "100%"; - } - - double required = 0; - switch (currentLevel) { - case 1: required = 5000; break; - case 2: required = 10000; break; - case 3: required = 20000; break; - case 4: required = 35000; break; - case 5: required = 50000; break; - case 6: required = 75000; break; - case 7: required = 100000; break; - case 8: required = 150000; break; - case 9: required = 200000; break; - } - - double percentage = (currentBalance / required) * 100; - return String.format("%.1f%%", percentage); - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.core.utils.GUIUtils; +import com.guild.core.utils.PlaceholderUtils; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import com.guild.services.GuildService; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * GUI Informacji o Gildii + */ +public class GuildInfoGUI implements GUI { + + private final GuildPlugin plugin; + private final Player player; + private final Guild guild; + private Inventory inventory; + + public GuildInfoGUI(GuildPlugin plugin, Player player, Guild guild) { + this.plugin = plugin; + this.player = player; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-info.title", "&6Informacje o gildii")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("guild-info.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + this.inventory = inventory; + + // Pobierz konfigurację GUI + ConfigurationSection config = plugin.getConfigManager().getGuiConfig().getConfigurationSection("guild-info.items"); + if (config == null) { + setupDefaultItems(); + return; + } + + // Ustaw skonfigurowane przedmioty + for (String key : config.getKeys(false)) { + ConfigurationSection itemConfig = config.getConfigurationSection(key); + if (itemConfig != null) { + setupConfigItem(itemConfig); + } + } + } + + private void setupConfigItem(ConfigurationSection itemConfig) { + String materialName = itemConfig.getString("material", "STONE"); + Material material = Material.valueOf(materialName.toUpperCase()); + int slot = itemConfig.getInt("slot", 0); + + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + // Ustaw nazwę + String name = itemConfig.getString("name", ""); + if (!name.isEmpty()) { + // Użyj GUIUtils do przetwarzania zmiennych + GUIUtils.processGUIVariablesAsync(name, guild, player, plugin).thenAccept(processedName -> { + CompatibleScheduler.runTask(plugin, () -> { + meta.setDisplayName(processedName); + + // Ustaw opis + List lore = itemConfig.getStringList("lore"); + if (!lore.isEmpty()) { + GUIUtils.processGUILoreAsync(lore, guild, player, plugin).thenAccept(processedLore -> { + CompatibleScheduler.runTask(plugin, () -> { + meta.setLore(processedLore); + item.setItemMeta(meta); + inventory.setItem(slot, item); + }); + }); + } else { + item.setItemMeta(meta); + inventory.setItem(slot, item); + } + }); + }); + } else { + // Jeśli brak nazwy, ustaw bezpośrednio opis + List lore = itemConfig.getStringList("lore"); + if (!lore.isEmpty()) { + GUIUtils.processGUILoreAsync(lore, guild, player, plugin).thenAccept(processedLore -> { + CompatibleScheduler.runTask(plugin, () -> { + meta.setLore(processedLore); + item.setItemMeta(meta); + inventory.setItem(slot, item); + }); + }); + } else { + item.setItemMeta(meta); + inventory.setItem(slot, item); + } + } + } else { + inventory.setItem(slot, item); + } + } + + private void setupDefaultItems() { + // Nazwa gildii + ItemStack nameItem = createItem(Material.NAME_TAG, "§6Nazwa gildii", + "§e" + guild.getName()); + inventory.setItem(10, nameItem); + + // Tag gildii + if (guild.getTag() != null && !guild.getTag().isEmpty()) { + ItemStack tagItem = createItem(Material.OAK_SIGN, "§6Tag gildii", + "§e[" + guild.getTag() + "]"); + inventory.setItem(12, tagItem); + } + + // Opis gildii + if (guild.getDescription() != null && !guild.getDescription().isEmpty()) { + ItemStack descItem = createItem(Material.BOOK, "§6Opis gildii", + "§e" + guild.getDescription()); + inventory.setItem(14, descItem); + } + + // Informacje o liderze + ItemStack leaderItem = createItem(Material.GOLDEN_HELMET, "§6Lider", + "§e" + guild.getLeaderName()); + inventory.setItem(16, leaderItem); + + // Liczba członków - użyj metody asynchronicznej + plugin.getGuildService().getGuildMemberCountAsync(guild.getId()).thenAccept(memberCount -> { + CompatibleScheduler.runTask(plugin, () -> { + ItemStack memberItem = createItem(Material.PLAYER_HEAD, "§6Liczba członków", + "§e" + memberCount + "/" + guild.getMaxMembers() + " osób"); + inventory.setItem(28, memberItem); + }); + }); + + // Poziom gildii + ItemStack levelItem = createItem(Material.EXPERIENCE_BOTTLE, "§6Poziom gildii", + "§ePoziom " + guild.getLevel(), + "§7Maksymalna liczba członków: " + guild.getMaxMembers() + " osób"); + inventory.setItem(30, levelItem); + + // Fundusze gildii + ItemStack balanceItem = createItem(Material.GOLD_INGOT, "§6Fundusze gildii", + "§e" + plugin.getEconomyManager().format(guild.getBalance()), + "§7Wymagane do awansu: " + getNextLevelRequirement(guild.getLevel())); + inventory.setItem(32, balanceItem); + + // Data utworzenia (użyj formatu czasu rzeczywistego) + String createdTime = guild.getCreatedAt() != null + ? guild.getCreatedAt().format(com.guild.core.time.TimeProvider.FULL_FORMATTER) + : "Nieznana"; + ItemStack timeItem = createItem(Material.CLOCK, "§6Data utworzenia", "§e" + createdTime); + inventory.setItem(34, timeItem); + + // Status gildii + String status = guild.isFrozen() ? "§cZamrożona" : "§aAktywna"; + ItemStack statusItem = createItem(Material.BEACON, "§6Status gildii", + status); + inventory.setItem(36, statusItem); + + // Przycisk powrotu + ItemStack backItem = createItem(Material.ARROW, "§cPowrót", + "§eKliknij, aby wrócić do głównego menu"); + inventory.setItem(49, backItem); + } + + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + + List loreList = new ArrayList<>(); + for (String line : lore) { + loreList.add(line); + } + meta.setLore(loreList); + + item.setItemMeta(meta); + } + + return item; + } + + private String replacePlaceholders(String text) { + return PlaceholderUtils.replaceGuildPlaceholders(text, guild, player); + } + + private String replacePlaceholdersAsync(String text, int memberCount) { + // Najpierw użyj PlaceholderUtils do podstawowych zmiennych + String result = PlaceholderUtils.replaceGuildPlaceholders(text, guild, player); + + // Następnie przetwórz zmienne dynamiczne + return result + .replace("{member_count}", String.valueOf(memberCount)) + .replace("{online_member_count}", String.valueOf(memberCount)); // Tymczasowo użyj całkowitej liczby członków + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (slot == 49) { + // Powrót do głównego menu + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + } + } + + @Override + public void onClose(Player player) { + // Obsługa przy zamknięciu + } + + @Override + public void refresh(Player player) { + setupInventory(inventory); + } + + public Inventory getInventory() { + return inventory; + } + + /** + * Pobierz wymagane fundusze do następnego poziomu + */ + private String getNextLevelRequirement(int currentLevel) { + if (currentLevel >= 10) { + return "Osiągnięto maksymalny poziom"; + } + + double required = 0; + switch (currentLevel) { + case 1: required = 5000; break; + case 2: required = 10000; break; + case 3: required = 20000; break; + case 4: required = 35000; break; + case 5: required = 50000; break; + case 6: required = 75000; break; + case 7: required = 100000; break; + case 8: required = 150000; break; + case 9: required = 200000; break; + } + + return plugin.getEconomyManager().format(required); + } + + /** + * Pobierz postęp obecnego poziomu + */ + private String getLevelProgress(int currentLevel, double currentBalance) { + if (currentLevel >= 10) { + return "100%"; + } + + double required = 0; + switch (currentLevel) { + case 1: required = 5000; break; + case 2: required = 10000; break; + case 3: required = 20000; break; + case 4: required = 35000; break; + case 5: required = 50000; break; + case 6: required = 75000; break; + case 7: required = 100000; break; + case 8: required = 150000; break; + case 9: required = 200000; break; + } + + double percentage = (currentBalance / required) * 100; + return String.format("%.1f%%", percentage); + } +} diff --git a/src/main/java/com/guild/gui/GuildListGUI.java b/src/main/java/com/guild/gui/GuildListGUI.java index f565784..984f306 100644 --- a/src/main/java/com/guild/gui/GuildListGUI.java +++ b/src/main/java/com/guild/gui/GuildListGUI.java @@ -1,513 +1,513 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.core.utils.PlaceholderUtils; -import com.guild.models.Guild; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 工会列表GUI - */ -public class GuildListGUI implements GUI { - - private final GuildPlugin plugin; - private int currentPage = 0; - private static final int GUILDS_PER_PAGE = 28; // 4行7列,除去边框 - private String searchQuery = ""; - private String filterType = "all"; // all, name, tag - - public GuildListGUI(GuildPlugin plugin) { - this.plugin = plugin; - } - - public GuildListGUI(GuildPlugin plugin, String searchQuery, String filterType) { - this.plugin = plugin; - this.searchQuery = searchQuery; - this.filterType = filterType; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.title", "&6工会列表")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("guild-list.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 添加功能按钮 - setupFunctionButtons(inventory); - - // 加载工会列表 - loadGuilds(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - // 检查是否是功能按钮 - if (isFunctionButton(slot)) { - handleFunctionButton(player, slot); - return; - } - - // 检查是否是分页按钮 - if (isPaginationButton(slot)) { - handlePaginationButton(player, slot); - return; - } - - // 检查是否是工会按钮 - if (isGuildSlot(slot)) { - handleGuildClick(player, slot, clickedItem, clickType); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 设置功能按钮 - */ - private void setupFunctionButtons(Inventory inventory) { - // 搜索按钮 - ItemStack search = createItem( - Material.COMPASS, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.search.name", "&e搜索工会")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.search.lore.1", "&7搜索特定工会")), - ColorUtils.colorize("&7当前搜索: " + (searchQuery.isEmpty() ? "无" : searchQuery)) - ); - inventory.setItem(45, search); - - // 筛选按钮 - ItemStack filter = createItem( - Material.HOPPER, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.filter.name", "&e筛选")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.filter.lore.1", "&7按条件筛选工会")), - ColorUtils.colorize("&7当前筛选: " + getFilterDisplayName()) - ); - inventory.setItem(47, filter); - - // 返回按钮 - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.back.name", "&7返回")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.back.lore.1", "&7返回主菜单")) - ); - inventory.setItem(49, back); - } - - /** - * 加载工会列表 - */ - private void loadGuilds(Inventory inventory) { - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - // 确保在主线程中更新GUI - CompatibleScheduler.runTask(plugin, () -> { - if (guilds == null || guilds.isEmpty()) { - // 显示无工会信息 - ItemStack noGuilds = createItem( - Material.BARRIER, - ColorUtils.colorize("&c暂无工会"), - ColorUtils.colorize("&7服务器中还没有工会") - ); - inventory.setItem(22, noGuilds); - return; - } - - // 应用搜索和筛选 - List filteredGuilds = filterGuilds(guilds); - - if (filteredGuilds.isEmpty()) { - // 显示无搜索结果 - ItemStack noResults = createItem( - Material.BARRIER, - ColorUtils.colorize("&c无搜索结果"), - ColorUtils.colorize("&7没有找到匹配的工会") - ); - inventory.setItem(22, noResults); - return; - } - - // 计算分页 - int totalPages = (filteredGuilds.size() - 1) / GUILDS_PER_PAGE; - if (currentPage > totalPages) { - currentPage = totalPages; - } - - // 设置分页按钮 - setupPaginationButtons(inventory, totalPages); - - // 显示当前页的工会 - displayGuilds(inventory, filteredGuilds); - }); - }); - } - - /** - * 筛选工会 - */ - private List filterGuilds(List guilds) { - List filtered = new ArrayList<>(); - - for (Guild guild : guilds) { - boolean matches = true; - - // 应用搜索 - if (!searchQuery.isEmpty()) { - switch (filterType) { - case "name": - matches = guild.getName().toLowerCase().contains(searchQuery.toLowerCase()); - break; - case "tag": - if (guild.getTag() != null) { - matches = guild.getTag().toLowerCase().contains(searchQuery.toLowerCase()); - } else { - matches = false; - } - break; - default: // all - matches = guild.getName().toLowerCase().contains(searchQuery.toLowerCase()) || - (guild.getTag() != null && guild.getTag().toLowerCase().contains(searchQuery.toLowerCase())); - break; - } - } - - if (matches) { - filtered.add(guild); - } - } - - return filtered; - } - - /** - * 显示工会列表 - */ - private void displayGuilds(Inventory inventory, List guilds) { - int startIndex = currentPage * GUILDS_PER_PAGE; - int endIndex = Math.min(startIndex + GUILDS_PER_PAGE, guilds.size()); - - // 创建所有工会的异步任务 - List> futures = new ArrayList<>(); - - int slotIndex = 10; // 从第2行第2列开始 - for (int i = startIndex; i < endIndex; i++) { - Guild guild = guilds.get(i); - if (slotIndex >= 44) break; // 避免超出显示区域 - - final int finalSlotIndex = slotIndex; - - // 异步获取成员数量并创建物品 - CompletableFuture future = plugin.getGuildService().getGuildMemberCountAsync(guild.getId()) - .thenAccept(memberCount -> { - // 在主线程中更新GUI - CompatibleScheduler.runTask(plugin, () -> { - ItemStack guildItem = createGuildItemWithMemberCount(guild, memberCount); - inventory.setItem(finalSlotIndex, guildItem); - }); - }); - - futures.add(future); - - slotIndex++; - if (slotIndex % 9 == 8) { // 跳过边框 - slotIndex += 2; - } - } - - // 等待所有异步任务完成 - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); - } - - /** - * 设置分页按钮 - */ - private void setupPaginationButtons(Inventory inventory, int totalPages) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack previousPage = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.previous-page.name", "&c上一页")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.previous-page.lore.1", "&7查看上一页")) - ); - inventory.setItem(18, previousPage); - } - - // 下一页按钮 - if (currentPage < totalPages) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.next-page.name", "&a下一页")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.next-page.lore.1", "&7查看下一页")) - ); - inventory.setItem(26, nextPage); - } - } - - /** - * 创建工会物品(带成员数量) - */ - private ItemStack createGuildItemWithMemberCount(Guild guild, int memberCount) { - List lore = new ArrayList<>(); - lore.add(PlaceholderUtils.replaceGuildPlaceholders("&7标签: {guild_tag}", guild, null)); - lore.add(PlaceholderUtils.replaceGuildPlaceholders("&7会长: {leader_name}", guild, null)); - lore.add(ColorUtils.colorize("&7成员: " + memberCount)); - lore.add(PlaceholderUtils.replaceGuildPlaceholders("&7创建时间: {guild_created_time}", guild, null)); - lore.add(""); - lore.add(ColorUtils.colorize("&a左键: 查看详情")); - lore.add(ColorUtils.colorize("&e右键: 申请加入")); - - return createItem( - Material.SHIELD, - PlaceholderUtils.replaceGuildPlaceholders("&e{guild_name}", guild, null), - lore.toArray(new String[0]) - ); - } - - /** - * 创建工会物品(原始方法,用于兼容性) - */ - private ItemStack createGuildItem(Guild guild) { - return createGuildItemWithMemberCount(guild, 0); // 使用默认值 - } - - /** - * 获取筛选显示名称 - */ - private String getFilterDisplayName() { - switch (filterType) { - case "name": - return "按名称"; - case "tag": - return "按标签"; - default: - return "全部"; - } - } - - /** - * 检查是否是功能按钮 - */ - private boolean isFunctionButton(int slot) { - return slot == 45 || slot == 47 || slot == 49; - } - - /** - * 检查是否是分页按钮 - */ - private boolean isPaginationButton(int slot) { - return slot == 18 || slot == 26; - } - - /** - * 检查是否是工会槽位 - */ - private boolean isGuildSlot(int slot) { - return slot >= 10 && slot <= 44 && slot % 9 != 0 && slot % 9 != 8; - } - - /** - * 处理功能按钮点击 - */ - private void handleFunctionButton(Player player, int slot) { - switch (slot) { - case 45: // 搜索 - handleSearch(player); - break; - case 47: // 筛选 - handleFilter(player); - break; - case 49: // 返回 - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - break; - } - } - - /** - * 处理分页按钮点击 - */ - private void handlePaginationButton(Player player, int slot) { - if (slot == 18) { // 上一页 - if (currentPage > 0) { - currentPage--; - refreshInventory(player); - } - } else if (slot == 26) { // 下一页 - currentPage++; - refreshInventory(player); - } - } - - /** - * 处理工会点击 - */ - private void handleGuildClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (clickType == ClickType.LEFT) { - // 查看详情 - handleViewGuildDetails(player, slot); - } else if (clickType == ClickType.RIGHT) { - // 申请加入 - handleApplyToGuild(player, slot); - } - } - - /** - * 处理搜索 - */ - private void handleSearch(Player player) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.search-dev", "&a搜索功能正在开发中..."); - player.sendMessage(ColorUtils.colorize(message)); - } - - /** - * 处理筛选 - */ - private void handleFilter(Player player) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.filter-dev", "&a筛选功能正在开发中..."); - player.sendMessage(ColorUtils.colorize(message)); - } - - /** - * 处理查看工会详情 - */ - private void handleViewGuildDetails(Player player, int slot) { - // 获取当前页的工会列表 - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guilds == null || guilds.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guilds", "&c没有找到工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 计算工会在列表中的索引 - int guildIndex = currentPage * GUILDS_PER_PAGE + (slot - 10); - if (guildIndex >= 0 && guildIndex < guilds.size()) { - Guild guild = guilds.get(guildIndex); - - // 打开工会信息GUI - GuildInfoGUI guildInfoGUI = new GuildInfoGUI(plugin, player, guild); - plugin.getGuiManager().openGUI(player, guildInfoGUI); - } - }); - }); - } - - /** - * 处理申请加入工会 - */ - private void handleApplyToGuild(Player player, int slot) { - // 检查玩家是否已有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(playerGuild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (playerGuild != null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.already-in-guild", "&c您已经在一个工会中了!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 获取当前页的工会列表 - plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guilds == null || guilds.isEmpty()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guilds", "&c没有找到工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 计算工会在列表中的索引 - int guildIndex = currentPage * GUILDS_PER_PAGE + (slot - 10); - if (guildIndex >= 0 && guildIndex < guilds.size()) { - Guild guild = guilds.get(guildIndex); - - // 检查是否已有待处理申请 - plugin.getGuildService().hasPendingApplicationAsync(player.getUniqueId(), guild.getId()).thenAccept(hasPending -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (hasPending) { - String message = plugin.getConfigManager().getMessagesConfig().getString("apply.already-applied", "&c您已经申请过这个工会了!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 提交申请 - plugin.getGuildService().submitApplicationAsync(guild.getId(), player.getUniqueId(), player.getName(), "").thenAccept(success -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("apply.success", "&a申请已提交!"); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("apply.failed", "&c申请提交失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - }); - }); - } - }); - }); - }); - }); - } - - /** - * 刷新库存 - */ - private void refreshInventory(Player player) { - plugin.getGuiManager().refreshGUI(player); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.core.utils.PlaceholderUtils; +import com.guild.models.Guild; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Listy Gildii + */ +public class GuildListGUI implements GUI { + + private final GuildPlugin plugin; + private int currentPage = 0; + private static final int GUILDS_PER_PAGE = 28; // 4 rzędy po 7 kolumn, bez obramowania + private String searchQuery = ""; + private String filterType = "all"; // all, name, tag + + public GuildListGUI(GuildPlugin plugin) { + this.plugin = plugin; + } + + public GuildListGUI(GuildPlugin plugin, String searchQuery, String filterType) { + this.plugin = plugin; + this.searchQuery = searchQuery; + this.filterType = filterType; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.title", "&6Lista gildii")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("guild-list.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Dodaj przyciski funkcyjne + setupFunctionButtons(inventory); + + // Załaduj listę gildii + loadGuilds(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + // Sprawdź czy to przycisk funkcyjny + if (isFunctionButton(slot)) { + handleFunctionButton(player, slot); + return; + } + + // Sprawdź czy to przycisk paginacji + if (isPaginationButton(slot)) { + handlePaginationButton(player, slot); + return; + } + + // Sprawdź czy to slot gildii + if (isGuildSlot(slot)) { + handleGuildClick(player, slot, clickedItem, clickType); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Skonfiguruj przyciski funkcyjne + */ + private void setupFunctionButtons(Inventory inventory) { + // Przycisk wyszukiwania + ItemStack search = createItem( + Material.COMPASS, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.search.name", "&eSzukaj gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.search.lore.1", "&7Wyszukaj konkretną gildię")), + ColorUtils.colorize("&7Obecne wyszukiwanie: " + (searchQuery.isEmpty() ? "Brak" : searchQuery)) + ); + inventory.setItem(45, search); + + // Przycisk filtrowania + ItemStack filter = createItem( + Material.HOPPER, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.filter.name", "&eFiltrowanie")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.filter.lore.1", "&7Filtruj gildie według kryteriów")), + ColorUtils.colorize("&7Obecny filtr: " + getFilterDisplayName()) + ); + inventory.setItem(47, filter); + + // Przycisk powrotu + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.back.name", "&7Powrót")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.back.lore.1", "&7Powrót do menu głównego")) + ); + inventory.setItem(49, back); + } + + /** + * Załaduj listę gildii + */ + private void loadGuilds(Inventory inventory) { + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + // Upewnij się, że aktualizacja GUI odbywa się w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guilds == null || guilds.isEmpty()) { + // Wyświetl informację o braku gildii + ItemStack noGuilds = createItem( + Material.BARRIER, + ColorUtils.colorize("&cBrak gildii"), + ColorUtils.colorize("&7Na serwerze nie ma jeszcze żadnych gildii") + ); + inventory.setItem(22, noGuilds); + return; + } + + // Zastosuj wyszukiwanie i filtrowanie + List filteredGuilds = filterGuilds(guilds); + + if (filteredGuilds.isEmpty()) { + // Wyświetl brak wyników wyszukiwania + ItemStack noResults = createItem( + Material.BARRIER, + ColorUtils.colorize("&cBrak wyników"), + ColorUtils.colorize("&7Nie znaleziono pasujących gildii") + ); + inventory.setItem(22, noResults); + return; + } + + // Oblicz paginację + int totalPages = (filteredGuilds.size() - 1) / GUILDS_PER_PAGE; + if (currentPage > totalPages) { + currentPage = totalPages; + } + + // Skonfiguruj przyciski paginacji + setupPaginationButtons(inventory, totalPages); + + // Wyświetl gildie na bieżącej stronie + displayGuilds(inventory, filteredGuilds); + }); + }); + } + + /** + * Filtruj gildie + */ + private List filterGuilds(List guilds) { + List filtered = new ArrayList<>(); + + for (Guild guild : guilds) { + boolean matches = true; + + // Zastosuj wyszukiwanie + if (!searchQuery.isEmpty()) { + switch (filterType) { + case "name": + matches = guild.getName().toLowerCase().contains(searchQuery.toLowerCase()); + break; + case "tag": + if (guild.getTag() != null) { + matches = guild.getTag().toLowerCase().contains(searchQuery.toLowerCase()); + } else { + matches = false; + } + break; + default: // all + matches = guild.getName().toLowerCase().contains(searchQuery.toLowerCase()) || + (guild.getTag() != null && guild.getTag().toLowerCase().contains(searchQuery.toLowerCase())); + break; + } + } + + if (matches) { + filtered.add(guild); + } + } + + return filtered; + } + + /** + * Wyświetl listę gildii + */ + private void displayGuilds(Inventory inventory, List guilds) { + int startIndex = currentPage * GUILDS_PER_PAGE; + int endIndex = Math.min(startIndex + GUILDS_PER_PAGE, guilds.size()); + + // Lista asynchronicznych zadań dla wszystkich gildii + List> futures = new ArrayList<>(); + + int slotIndex = 10; // Rozpocznij od 2 rzędu, 2 kolumny + for (int i = startIndex; i < endIndex; i++) { + Guild guild = guilds.get(i); + if (slotIndex >= 44) break; // Unikaj wyjścia poza obszar wyświetlania + + final int finalSlotIndex = slotIndex; + + // Asynchronicznie pobierz liczbę członków i utwórz przedmiot + CompletableFuture future = plugin.getGuildService().getGuildMemberCountAsync(guild.getId()) + .thenAccept(memberCount -> { + // Aktualizuj GUI w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + ItemStack guildItem = createGuildItemWithMemberCount(guild, memberCount); + inventory.setItem(finalSlotIndex, guildItem); + }); + }); + + futures.add(future); + + slotIndex++; + if (slotIndex % 9 == 8) { // Pomiń obramowanie + slotIndex += 2; + } + } + + // Poczekaj na zakończenie wszystkich zadań asynchronicznych + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + } + + /** + * Skonfiguruj przyciski paginacji + */ + private void setupPaginationButtons(Inventory inventory, int totalPages) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack previousPage = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.previous-page.name", "&cPoprzednia strona")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.previous-page.lore.1", "&7Zobacz poprzednią stronę")) + ); + inventory.setItem(18, previousPage); + } + + // Przycisk następnej strony + if (currentPage < totalPages) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.next-page.name", "&aNastępna strona")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-list.items.next-page.lore.1", "&7Zobacz następną stronę")) + ); + inventory.setItem(26, nextPage); + } + } + + /** + * Utwórz przedmiot gildii (z liczbą członków) + */ + private ItemStack createGuildItemWithMemberCount(Guild guild, int memberCount) { + List lore = new ArrayList<>(); + lore.add(PlaceholderUtils.replaceGuildPlaceholders("&7Tag: {guild_tag}", guild, null)); + lore.add(PlaceholderUtils.replaceGuildPlaceholders("&7Lider: {leader_name}", guild, null)); + lore.add(ColorUtils.colorize("&7Członkowie: " + memberCount)); + lore.add(PlaceholderUtils.replaceGuildPlaceholders("&7Data utworzenia: {guild_created_time}", guild, null)); + lore.add(""); + lore.add(ColorUtils.colorize("&aLewy przycisk: Zobacz szczegóły")); + lore.add(ColorUtils.colorize("&ePrawy przycisk: Aplikuj")); + + return createItem( + Material.SHIELD, + PlaceholderUtils.replaceGuildPlaceholders("&e{guild_name}", guild, null), + lore.toArray(new String[0]) + ); + } + + /** + * Utwórz przedmiot gildii (oryginalna metoda dla kompatybilności) + */ + private ItemStack createGuildItem(Guild guild) { + return createGuildItemWithMemberCount(guild, 0); // Użyj wartości domyślnej + } + + /** + * Pobierz wyświetlaną nazwę filtra + */ + private String getFilterDisplayName() { + switch (filterType) { + case "name": + return "Według nazwy"; + case "tag": + return "Według tagu"; + default: + return "Wszystkie"; + } + } + + /** + * Sprawdź czy to przycisk funkcyjny + */ + private boolean isFunctionButton(int slot) { + return slot == 45 || slot == 47 || slot == 49; + } + + /** + * Sprawdź czy to przycisk paginacji + */ + private boolean isPaginationButton(int slot) { + return slot == 18 || slot == 26; + } + + /** + * Sprawdź czy to slot gildii + */ + private boolean isGuildSlot(int slot) { + return slot >= 10 && slot <= 44 && slot % 9 != 0 && slot % 9 != 8; + } + + /** + * Obsługa kliknięcia przycisku funkcyjnego + */ + private void handleFunctionButton(Player player, int slot) { + switch (slot) { + case 45: // Szukaj + handleSearch(player); + break; + case 47: // Filtruj + handleFilter(player); + break; + case 49: // Powrót + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + break; + } + } + + /** + * Obsługa kliknięcia przycisku paginacji + */ + private void handlePaginationButton(Player player, int slot) { + if (slot == 18) { // Poprzednia strona + if (currentPage > 0) { + currentPage--; + refreshInventory(player); + } + } else if (slot == 26) { // Następna strona + currentPage++; + refreshInventory(player); + } + } + + /** + * Obsługa kliknięcia gildii + */ + private void handleGuildClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (clickType == ClickType.LEFT) { + // Zobacz szczegóły + handleViewGuildDetails(player, slot); + } else if (clickType == ClickType.RIGHT) { + // Aplikuj o dołączenie + handleApplyToGuild(player, slot); + } + } + + /** + * Obsługa wyszukiwania + */ + private void handleSearch(Player player) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.search-dev", "&aFunkcja wyszukiwania jest w trakcie tworzenia..."); + player.sendMessage(ColorUtils.colorize(message)); + } + + /** + * Obsługa filtrowania + */ + private void handleFilter(Player player) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.filter-dev", "&aFunkcja filtrowania jest w trakcie tworzenia..."); + player.sendMessage(ColorUtils.colorize(message)); + } + + /** + * Obsługa przeglądania szczegółów gildii + */ + private void handleViewGuildDetails(Player player, int slot) { + // Pobierz listę gildii na bieżącej stronie + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guilds == null || guilds.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guilds", "&cNie znaleziono gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Oblicz indeks gildii na liście + int guildIndex = currentPage * GUILDS_PER_PAGE + (slot - 10); + if (guildIndex >= 0 && guildIndex < guilds.size()) { + Guild guild = guilds.get(guildIndex); + + // Otwórz GUI informacji o gildii + GuildInfoGUI guildInfoGUI = new GuildInfoGUI(plugin, player, guild); + plugin.getGuiManager().openGUI(player, guildInfoGUI); + } + }); + }); + } + + /** + * Obsługa aplikacji o dołączenie do gildii + */ + private void handleApplyToGuild(Player player, int slot) { + // Sprawdź czy gracz już należy do gildii + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(playerGuild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (playerGuild != null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.already-in-guild", "&cJesteś już w gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Pobierz listę gildii na bieżącej stronie + plugin.getGuildService().getAllGuildsAsync().thenAccept(guilds -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guilds == null || guilds.isEmpty()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guilds", "&cNie znaleziono gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Oblicz indeks gildii na liście + int guildIndex = currentPage * GUILDS_PER_PAGE + (slot - 10); + if (guildIndex >= 0 && guildIndex < guilds.size()) { + Guild guild = guilds.get(guildIndex); + + // Sprawdź czy już wysłano aplikację + plugin.getGuildService().hasPendingApplicationAsync(player.getUniqueId(), guild.getId()).thenAccept(hasPending -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (hasPending) { + String message = plugin.getConfigManager().getMessagesConfig().getString("apply.already-applied", "&cJuż aplikowałeś do tej gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wyślij aplikację + plugin.getGuildService().submitApplicationAsync(guild.getId(), player.getUniqueId(), player.getName(), "").thenAccept(success -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("apply.success", "&aAplikacja wysłana!"); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("apply.failed", "&cWysłanie aplikacji nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + }); + }); + } + }); + }); + }); + }); + } + + /** + * Odśwież ekwipunek + */ + private void refreshInventory(Player player) { + plugin.getGuiManager().refreshGUI(player); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildLogsGUI.java b/src/main/java/com/guild/gui/GuildLogsGUI.java index b4ad7c8..5d38efb 100644 --- a/src/main/java/com/guild/gui/GuildLogsGUI.java +++ b/src/main/java/com/guild/gui/GuildLogsGUI.java @@ -1,407 +1,407 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.models.Guild; -import com.guild.models.GuildLog; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 工会日志查看GUI - */ -public class GuildLogsGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private final Player player; - private final int page; - private final int itemsPerPage = 28; // 2-8列,2-5行 - private List logs; - private int totalLogs; - - public GuildLogsGUI(GuildPlugin plugin, Guild guild, Player player) { - this(plugin, guild, player, 0); - } - - public GuildLogsGUI(GuildPlugin plugin, Guild guild, Player player, int page) { - this.plugin = plugin; - this.guild = guild; - this.player = player; - this.page = page; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-logs.title", "&6工会日志 - {guild_name}") - .replace("{guild_name}", guild.getName())); - } - - @Override - public int getSize() { - return 54; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 异步加载日志数据 - loadLogsAsync().thenAccept(success -> { - if (success) { - // 在主线程中设置物品和完整的导航按钮 - CompatibleScheduler.runTask(plugin, () -> { - setupLogItems(inventory); - setupBasicNavigationButtons(inventory); - setupFullNavigationButtons(inventory); - }); - } else { - // 如果加载失败,在主线程中显示错误信息 - CompatibleScheduler.runTask(plugin, () -> { - ItemStack errorItem = createItem( - Material.BARRIER, - ColorUtils.colorize("&c加载失败"), - ColorUtils.colorize("&7无法加载日志数据,请重试") - ); - inventory.setItem(22, errorItem); - setupBasicNavigationButtons(inventory); - }); - } - }); - } - - /** - * 异步加载日志数据 - */ - private CompletableFuture loadLogsAsync() { - return CompletableFuture.supplyAsync(() -> { - try { - plugin.getLogger().info("开始加载工会 " + guild.getName() + " 的日志数据..."); - - // 检查工会ID是否有效 - if (guild.getId() <= 0) { - plugin.getLogger().warning("工会ID无效: " + guild.getId()); - return false; - } - - // 获取日志总数 - totalLogs = plugin.getGuildService().getGuildLogsCountAsync(guild.getId()).get(); - plugin.getLogger().info("工会 " + guild.getName() + " 共有 " + totalLogs + " 条日志记录"); - - // 获取当前页的日志 - int offset = page * itemsPerPage; - logs = plugin.getGuildService().getGuildLogsAsync(guild.getId(), itemsPerPage, offset).get(); - plugin.getLogger().info("成功加载第 " + (page + 1) + " 页的 " + logs.size() + " 条日志记录"); - - return true; - } catch (Exception e) { - plugin.getLogger().severe("加载工会日志时发生错误: " + e.getMessage()); - e.printStackTrace(); - - // 设置默认值 - totalLogs = 0; - logs = new java.util.ArrayList<>(); - - return false; - } - }); - } - - /** - * 设置日志物品 - */ - private void setupLogItems(Inventory inventory) { - plugin.getLogger().info("设置日志物品,logs大小: " + (logs != null ? logs.size() : "null")); - - if (logs == null) { - logs = new java.util.ArrayList<>(); // 确保logs不为null - } - - if (logs.isEmpty()) { - plugin.getLogger().info("日志列表为空,显示无日志信息"); - // 显示无日志信息 - ItemStack noLogs = createItem( - Material.BARRIER, - ColorUtils.colorize("&c暂无日志记录"), - ColorUtils.colorize("&7该工会还没有任何操作记录"), - ColorUtils.colorize("&7请等待工会活动产生日志") - ); - inventory.setItem(22, noLogs); - return; - } - - plugin.getLogger().info("开始显示 " + logs.size() + " 条日志记录"); - - // 显示日志列表 - for (int i = 0; i < Math.min(logs.size(), itemsPerPage); i++) { - GuildLog log = logs.get(i); - int slot = getLogSlot(i); - - plugin.getLogger().info("设置日志项目 " + i + " 到槽位 " + slot + ": " + log.getLogType().getDisplayName()); - - ItemStack logItem = createLogItem(log); - inventory.setItem(slot, logItem); - } - } - - /** - * 创建日志物品 - */ - private ItemStack createLogItem(GuildLog log) { - Material material = getLogMaterial(log.getLogType()); - String name = ColorUtils.colorize("&e" + log.getLogType().getDisplayName()); - - List lore = new java.util.ArrayList<>(); - lore.add(ColorUtils.colorize("&7操作者: &f" + log.getPlayerName())); - lore.add(ColorUtils.colorize("&7时间: &f" + log.getSimpleTime())); - lore.add(ColorUtils.colorize("&7描述: &f" + log.getDescription())); - - if (log.getDetails() != null && !log.getDetails().isEmpty()) { - lore.add(ColorUtils.colorize("&7详情: &f" + log.getDetails())); - } - - return createItem(material, name, lore.toArray(new String[0])); - } - - /** - * 根据日志类型获取物品材质 - */ - private Material getLogMaterial(GuildLog.LogType logType) { - switch (logType) { - case GUILD_CREATED: - return Material.GREEN_WOOL; - case GUILD_DISSOLVED: - return Material.RED_WOOL; - case MEMBER_JOINED: - return Material.EMERALD; - case MEMBER_LEFT: - return Material.REDSTONE; - case MEMBER_KICKED: - return Material.REDSTONE; - case MEMBER_PROMOTED: - return Material.GOLD_INGOT; - case MEMBER_DEMOTED: - return Material.IRON_INGOT; - case LEADER_TRANSFERRED: - return Material.DIAMOND; - case FUND_DEPOSITED: - return Material.GOLD_NUGGET; - case FUND_WITHDRAWN: - return Material.IRON_NUGGET; - case FUND_TRANSFERRED: - return Material.EMERALD_BLOCK; - case RELATION_CREATED: - case RELATION_ACCEPTED: - return Material.BLUE_WOOL; - case RELATION_DELETED: - case RELATION_REJECTED: - return Material.ORANGE_WOOL; - case GUILD_FROZEN: - return Material.ICE; - case GUILD_UNFROZEN: - return Material.WATER_BUCKET; - case GUILD_LEVEL_UP: - return Material.EXPERIENCE_BOTTLE; - case APPLICATION_SUBMITTED: - case APPLICATION_ACCEPTED: - case APPLICATION_REJECTED: - return Material.PAPER; - case INVITATION_SENT: - case INVITATION_ACCEPTED: - case INVITATION_REJECTED: - return Material.BOOK; - default: - return Material.GRAY_WOOL; - } - } - - /** - * 获取日志物品的槽位 - 修复后的计算逻辑 - */ - private int getLogSlot(int index) { - int row = index / 7; // 7列 - int col = index % 7; - return (row + 1) * 9 + (col + 1); // 从第1行第1列开始 (slots 10-43) - } - - /** - * 设置基本的导航按钮(不依赖日志数据) - */ - private void setupBasicNavigationButtons(Inventory inventory) { - // 返回按钮 - 移到槽位49,与其他GUI保持一致 - ItemStack backButton = createItem( - Material.ARROW, - ColorUtils.colorize("&c返回"), - ColorUtils.colorize("&7返回上一级菜单") - ); - inventory.setItem(49, backButton); - } - - /** - * 设置完整的导航按钮(依赖日志数据) - */ - private void setupFullNavigationButtons(Inventory inventory) { - // 分页按钮 - if (page > 0) { - ItemStack prevButton = createItem( - Material.ARROW, - ColorUtils.colorize("&e上一页"), - ColorUtils.colorize("&7查看上一页日志") - ); - inventory.setItem(45, prevButton); - } - - if ((page + 1) * itemsPerPage < totalLogs) { - ItemStack nextButton = createItem( - Material.ARROW, - ColorUtils.colorize("&e下一页"), - ColorUtils.colorize("&7查看下一页日志") - ); - inventory.setItem(53, nextButton); - } - - // 页码信息 - ItemStack pageInfo = createItem( - Material.PAPER, - ColorUtils.colorize("&6页码信息"), - ColorUtils.colorize("&7当前页: &f" + (page + 1)), - ColorUtils.colorize("&7总页数: &f" + ((totalLogs - 1) / itemsPerPage + 1)), - ColorUtils.colorize("&7总记录: &f" + totalLogs) - ); - inventory.setItem(47, pageInfo); - - // 刷新按钮 - ItemStack refreshButton = createItem( - Material.EMERALD, - ColorUtils.colorize("&a刷新"), - ColorUtils.colorize("&7刷新日志列表") - ); - inventory.setItem(51, refreshButton); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (clickedItem == null || !clickedItem.hasItemMeta()) return; - - String itemName = clickedItem.getItemMeta().getDisplayName(); - - // 返回按钮 - if (itemName.contains("返回")) { - // 返回到工会信息GUI - GuildInfoGUI guildInfoGUI = new GuildInfoGUI(plugin, player, guild); - plugin.getGuiManager().openGUI(player, guildInfoGUI); - return; - } - - // 上一页按钮 - if (itemName.contains("上一页")) { - if (page > 0) { - GuildLogsGUI prevPageGUI = new GuildLogsGUI(plugin, guild, player, page - 1); - plugin.getGuiManager().openGUI(player, prevPageGUI); - } - return; - } - - // 下一页按钮 - if (itemName.contains("下一页")) { - if ((page + 1) * itemsPerPage < totalLogs) { - GuildLogsGUI nextPageGUI = new GuildLogsGUI(plugin, guild, player, page + 1); - plugin.getGuiManager().openGUI(player, nextPageGUI); - } - return; - } - - // 刷新按钮 - if (itemName.contains("刷新")) { - GuildLogsGUI refreshGUI = new GuildLogsGUI(plugin, guild, player, page); - plugin.getGuiManager().openGUI(player, refreshGUI); - return; - } - - // 日志项目点击 - 检查是否在日志显示区域 - if (slot >= 10 && slot <= 43) { - int row = slot / 9; - int col = slot % 9; - if (row >= 1 && row <= 4 && col >= 1 && col <= 7) { - int relativeIndex = (row - 1) * 7 + (col - 1); - int logIndex = (page * itemsPerPage) + relativeIndex; - if (logIndex < logs.size()) { - GuildLog log = logs.get(logIndex); - handleLogClick(player, log); - } - } - } - } - - /** - * 处理日志点击 - */ - private void handleLogClick(Player player, GuildLog log) { - // 显示日志详细信息 - String message = ColorUtils.colorize("&6=== 日志详情 ==="); - player.sendMessage(message); - player.sendMessage(ColorUtils.colorize("&7类型: &f" + log.getLogType().getDisplayName())); - player.sendMessage(ColorUtils.colorize("&7操作者: &f" + log.getPlayerName())); - player.sendMessage(ColorUtils.colorize("&7时间: &f" + log.getSimpleTime())); - player.sendMessage(ColorUtils.colorize("&7描述: &f" + log.getDescription())); - if (log.getDetails() != null && !log.getDetails().isEmpty()) { - player.sendMessage(ColorUtils.colorize("&7详情: &f" + log.getDetails())); - } - player.sendMessage(ColorUtils.colorize("&6==================")); - } - - @Override - public void onClose(Player player) { - // 关闭时的处理 - } - - @Override - public void refresh(Player player) { - // 刷新GUI - GuildLogsGUI refreshGUI = new GuildLogsGUI(plugin, guild, player, page); - plugin.getGuiManager().openGUI(player, refreshGUI); - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - org.bukkit.inventory.meta.ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(java.util.Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.models.Guild; +import com.guild.models.GuildLog; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Logów Gildii + */ +public class GuildLogsGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private final Player player; + private final int page; + private final int itemsPerPage = 28; // 2-8 kolumny, 2-5 rzędy + private List logs; + private int totalLogs; + + public GuildLogsGUI(GuildPlugin plugin, Guild guild, Player player) { + this(plugin, guild, player, 0); + } + + public GuildLogsGUI(GuildPlugin plugin, Guild guild, Player player, int page) { + this.plugin = plugin; + this.guild = guild; + this.player = player; + this.page = page; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-logs.title", "&6Logi Gildii - {guild_name}") + .replace("{guild_name}", guild.getName())); + } + + @Override + public int getSize() { + return 54; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Asynchroniczne ładowanie logów + loadLogsAsync().thenAccept(success -> { + if (success) { + // Ustaw elementy i pełną nawigację w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + setupLogItems(inventory); + setupBasicNavigationButtons(inventory); + setupFullNavigationButtons(inventory); + }); + } else { + // W przypadku błędu, pokaż komunikat w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + ItemStack errorItem = createItem( + Material.BARRIER, + ColorUtils.colorize("&cBłąd ładowania"), + ColorUtils.colorize("&7Nie udało się załadować logów, spróbuj ponownie") + ); + inventory.setItem(22, errorItem); + setupBasicNavigationButtons(inventory); + }); + } + }); + } + + /** + * Asynchroniczne ładowanie logów + */ + private CompletableFuture loadLogsAsync() { + return CompletableFuture.supplyAsync(() -> { + try { + plugin.getLogger().info("Rozpoczęto ładowanie logów gildii " + guild.getName() + "..."); + + // Sprawdź czy ID gildii jest prawidłowe + if (guild.getId() <= 0) { + plugin.getLogger().warning("Nieprawidłowe ID gildii: " + guild.getId()); + return false; + } + + // Pobierz całkowitą liczbę logów + totalLogs = plugin.getGuildService().getGuildLogsCountAsync(guild.getId()).get(); + plugin.getLogger().info("Gildia " + guild.getName() + " ma " + totalLogs + " wpisów w logach"); + + // Pobierz logi dla bieżącej strony + int offset = page * itemsPerPage; + logs = plugin.getGuildService().getGuildLogsAsync(guild.getId(), itemsPerPage, offset).get(); + plugin.getLogger().info("Pomyślnie załadowano " + logs.size() + " wpisów logów dla strony " + (page + 1)); + + return true; + } catch (Exception e) { + plugin.getLogger().severe("Wystąpił błąd podczas ładowania logów gildii: " + e.getMessage()); + e.printStackTrace(); + + // Ustaw wartości domyślne + totalLogs = 0; + logs = new java.util.ArrayList<>(); + + return false; + } + }); + } + + /** + * Ustaw przedmioty logów + */ + private void setupLogItems(Inventory inventory) { + plugin.getLogger().info("Ustawianie przedmiotów logów, rozmiar logs: " + (logs != null ? logs.size() : "null")); + + if (logs == null) { + logs = new java.util.ArrayList<>(); // Upewnij się, że logs nie jest null + } + + if (logs.isEmpty()) { + plugin.getLogger().info("Lista logów jest pusta, wyświetlanie informacji o braku logów"); + // Wyświetl informację o braku logów + ItemStack noLogs = createItem( + Material.BARRIER, + ColorUtils.colorize("&cBrak logów"), + ColorUtils.colorize("&7Ta gildia nie ma jeszcze żadnych wpisów"), + ColorUtils.colorize("&7Poczekaj na aktywność gildii") + ); + inventory.setItem(22, noLogs); + return; + } + + plugin.getLogger().info("Rozpoczęcie wyświetlania " + logs.size() + " wpisów logów"); + + // Wyświetl listę logów + for (int i = 0; i < Math.min(logs.size(), itemsPerPage); i++) { + GuildLog log = logs.get(i); + int slot = getLogSlot(i); + + plugin.getLogger().info("Ustawianie wpisu " + i + " w slocie " + slot + ": " + log.getLogType().getDisplayName()); + + ItemStack logItem = createLogItem(log); + inventory.setItem(slot, logItem); + } + } + + /** + * Utwórz przedmiot logu + */ + private ItemStack createLogItem(GuildLog log) { + Material material = getLogMaterial(log.getLogType()); + String name = ColorUtils.colorize("&e" + log.getLogType().getDisplayName()); + + List lore = new java.util.ArrayList<>(); + lore.add(ColorUtils.colorize("&7Wykonawca: &f" + log.getPlayerName())); + lore.add(ColorUtils.colorize("&7Czas: &f" + log.getSimpleTime())); + lore.add(ColorUtils.colorize("&7Opis: &f" + log.getDescription())); + + if (log.getDetails() != null && !log.getDetails().isEmpty()) { + lore.add(ColorUtils.colorize("&7Szczegóły: &f" + log.getDetails())); + } + + return createItem(material, name, lore.toArray(new String[0])); + } + + /** + * Pobierz materiał na podstawie typu logu + */ + private Material getLogMaterial(GuildLog.LogType logType) { + switch (logType) { + case GUILD_CREATED: + return Material.GREEN_WOOL; + case GUILD_DISSOLVED: + return Material.RED_WOOL; + case MEMBER_JOINED: + return Material.EMERALD; + case MEMBER_LEFT: + return Material.REDSTONE; + case MEMBER_KICKED: + return Material.REDSTONE; + case MEMBER_PROMOTED: + return Material.GOLD_INGOT; + case MEMBER_DEMOTED: + return Material.IRON_INGOT; + case LEADER_TRANSFERRED: + return Material.DIAMOND; + case FUND_DEPOSITED: + return Material.GOLD_NUGGET; + case FUND_WITHDRAWN: + return Material.IRON_NUGGET; + case FUND_TRANSFERRED: + return Material.EMERALD_BLOCK; + case RELATION_CREATED: + case RELATION_ACCEPTED: + return Material.BLUE_WOOL; + case RELATION_DELETED: + case RELATION_REJECTED: + return Material.ORANGE_WOOL; + case GUILD_FROZEN: + return Material.ICE; + case GUILD_UNFROZEN: + return Material.WATER_BUCKET; + case GUILD_LEVEL_UP: + return Material.EXPERIENCE_BOTTLE; + case APPLICATION_SUBMITTED: + case APPLICATION_ACCEPTED: + case APPLICATION_REJECTED: + return Material.PAPER; + case INVITATION_SENT: + case INVITATION_ACCEPTED: + case INVITATION_REJECTED: + return Material.BOOK; + default: + return Material.GRAY_WOOL; + } + } + + /** + * Pobierz slot dla wpisu logu + */ + private int getLogSlot(int index) { + int row = index / 7; // 7 kolumn + int col = index % 7; + return (row + 1) * 9 + (col + 1); // Od 2 rzędu, 2 kolumny (sloty 10-43) + } + + /** + * Ustaw podstawowe przyciski nawigacyjne (niezależne od danych) + */ + private void setupBasicNavigationButtons(Inventory inventory) { + // Przycisk powrotu - w slocie 49, spójnie z innymi GUI + ItemStack backButton = createItem( + Material.ARROW, + ColorUtils.colorize("&cPowrót"), + ColorUtils.colorize("&7Powrót do poprzedniego menu") + ); + inventory.setItem(49, backButton); + } + + /** + * Ustaw pełne przyciski nawigacyjne (zależne od danych) + */ + private void setupFullNavigationButtons(Inventory inventory) { + // Przyciski stron + if (page > 0) { + ItemStack prevButton = createItem( + Material.ARROW, + ColorUtils.colorize("&ePoprzednia strona"), + ColorUtils.colorize("&7Zobacz poprzednią stronę") + ); + inventory.setItem(45, prevButton); + } + + if ((page + 1) * itemsPerPage < totalLogs) { + ItemStack nextButton = createItem( + Material.ARROW, + ColorUtils.colorize("&eNastępna strona"), + ColorUtils.colorize("&7Zobacz następną stronę") + ); + inventory.setItem(53, nextButton); + } + + // Informacja o stronie + ItemStack pageInfo = createItem( + Material.PAPER, + ColorUtils.colorize("&6Informacja o stronie"), + ColorUtils.colorize("&7Obecna strona: &f" + (page + 1)), + ColorUtils.colorize("&7Wszystkich stron: &f" + ((totalLogs - 1) / itemsPerPage + 1)), + ColorUtils.colorize("&7Wszystkich wpisów: &f" + totalLogs) + ); + inventory.setItem(47, pageInfo); + + // Przycisk odświeżania + ItemStack refreshButton = createItem( + Material.EMERALD, + ColorUtils.colorize("&aOdśwież"), + ColorUtils.colorize("&7Odśwież listę logów") + ); + inventory.setItem(51, refreshButton); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (clickedItem == null || !clickedItem.hasItemMeta()) return; + + String itemName = clickedItem.getItemMeta().getDisplayName(); + + // Przycisk powrotu + if (itemName.contains("Powrót")) { + // Wróć do GUI informacji o gildii + GuildInfoGUI guildInfoGUI = new GuildInfoGUI(plugin, player, guild); + plugin.getGuiManager().openGUI(player, guildInfoGUI); + return; + } + + // Poprzednia strona + if (itemName.contains("Poprzednia strona")) { + if (page > 0) { + GuildLogsGUI prevPageGUI = new GuildLogsGUI(plugin, guild, player, page - 1); + plugin.getGuiManager().openGUI(player, prevPageGUI); + } + return; + } + + // Następna strona + if (itemName.contains("Następna strona")) { + if ((page + 1) * itemsPerPage < totalLogs) { + GuildLogsGUI nextPageGUI = new GuildLogsGUI(plugin, guild, player, page + 1); + plugin.getGuiManager().openGUI(player, nextPageGUI); + } + return; + } + + // Przycisk odświeżania + if (itemName.contains("Odśwież")) { + GuildLogsGUI refreshGUI = new GuildLogsGUI(plugin, guild, player, page); + plugin.getGuiManager().openGUI(player, refreshGUI); + return; + } + + // Kliknięcie w log - sprawdź czy w obszarze logów + if (slot >= 10 && slot <= 43) { + int row = slot / 9; + int col = slot % 9; + if (row >= 1 && row <= 4 && col >= 1 && col <= 7) { + int relativeIndex = (row - 1) * 7 + (col - 1); + int logIndex = (page * itemsPerPage) + relativeIndex; + if (logIndex < logs.size()) { + GuildLog log = logs.get(logIndex); + handleLogClick(player, log); + } + } + } + } + + /** + * Obsługa kliknięcia w log + */ + private void handleLogClick(Player player, GuildLog log) { + // Pokaż szczegóły logu + String message = ColorUtils.colorize("&6=== Szczegóły Logu ==="); + player.sendMessage(message); + player.sendMessage(ColorUtils.colorize("&7Typ: &f" + log.getLogType().getDisplayName())); + player.sendMessage(ColorUtils.colorize("&7Wykonawca: &f" + log.getPlayerName())); + player.sendMessage(ColorUtils.colorize("&7Czas: &f" + log.getSimpleTime())); + player.sendMessage(ColorUtils.colorize("&7Opis: &f" + log.getDescription())); + if (log.getDetails() != null && !log.getDetails().isEmpty()) { + player.sendMessage(ColorUtils.colorize("&7Szczegóły: &f" + log.getDetails())); + } + player.sendMessage(ColorUtils.colorize("&6==================")); + } + + @Override + public void onClose(Player player) { + // Obsługa przy zamknięciu + } + + @Override + public void refresh(Player player) { + // Odśwież GUI + GuildLogsGUI refreshGUI = new GuildLogsGUI(plugin, guild, player, page); + plugin.getGuiManager().openGUI(player, refreshGUI); + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + org.bukkit.inventory.meta.ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(java.util.Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildNameInputGUI.java b/src/main/java/com/guild/gui/GuildNameInputGUI.java index 72da603..defded7 100644 --- a/src/main/java/com/guild/gui/GuildNameInputGUI.java +++ b/src/main/java/com/guild/gui/GuildNameInputGUI.java @@ -1,294 +1,288 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.models.Guild; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -/** - * 工会名称输入GUI - */ -public class GuildNameInputGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private final Player player; - private String currentName; - - public GuildNameInputGUI(GuildPlugin plugin, Guild guild, Player player) { - this.plugin = plugin; - this.guild = guild; - this.player = player; - this.currentName = guild.getName() != null ? guild.getName() : ""; - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6修改工会名称"); - } - - @Override - public int getSize() { - return 27; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示当前名称 - displayCurrentName(inventory); - - // 添加操作按钮 - setupButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 11: // 输入名称 - handleInputName(player); - break; - case 15: // 确认 - handleConfirm(player); - break; - case 13: // 取消 - handleCancel(player); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 18, border); - } - for (int i = 9; i < 18; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示当前名称 - */ - private void displayCurrentName(Inventory inventory) { - ItemStack currentNameItem = createItem( - Material.NAME_TAG, - ColorUtils.colorize("&e当前工会名称"), - ColorUtils.colorize("&7" + (currentName.isEmpty() ? "无名称" : currentName)) - ); - inventory.setItem(11, currentNameItem); - } - - /** - * 设置按钮 - */ - private void setupButtons(Inventory inventory) { - // 确认按钮 - ItemStack confirmButton = createItem( - Material.EMERALD, - ColorUtils.colorize("&a确认修改"), - ColorUtils.colorize("&7点击确认修改工会名称"), - ColorUtils.colorize("&7注意:工会名称修改后需要重新登录才能生效") - ); - inventory.setItem(15, confirmButton); - - // 取消按钮 - ItemStack cancelButton = createItem( - Material.REDSTONE, - ColorUtils.colorize("&c取消"), - ColorUtils.colorize("&7返回上一级菜单") - ); - inventory.setItem(13, cancelButton); - } - - /** - * 处理输入名称 - */ - private void handleInputName(Player player) { - // 关闭GUI并进入输入模式 - plugin.getGuiManager().closeGUI(player); - plugin.getGuiManager().setInputMode(player, "guild_name_input", this); - - // 发送输入提示 - player.sendMessage(ColorUtils.colorize("&6请输入新的工会名称:")); - player.sendMessage(ColorUtils.colorize("&7当前名称: &f" + currentName)); - player.sendMessage(ColorUtils.colorize("&7输入 &c取消 &7来取消操作")); - player.sendMessage(ColorUtils.colorize("&7支持颜色字符,例如: &a&l绿色粗体 &7或 &c&o红色斜体")); - player.sendMessage(ColorUtils.colorize("&7注意:工会名称不能与其他工会重复")); - } - - /** - * 处理确认 - */ - private void handleConfirm(Player player) { - // 检查权限(只有会长可以修改工会名称) - if (!plugin.getGuildService().isGuildLeader(player.getUniqueId(), guild.getId())) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 如果当前名称为空,提示输入 - if (currentName.isEmpty()) { - handleInputName(player); - return; - } - - // 执行改名操作 - executeNameChange(player, currentName); - } - - /** - * 处理取消 - */ - public void handleCancel(Player player) { - // 返回到工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 处理输入完成 - */ - public void handleInputComplete(Player player, String input) { - if (input == null || input.trim().isEmpty()) { - player.sendMessage(ColorUtils.colorize("&c工会名称不能为空!")); - plugin.getGuiManager().openGUI(player, this); - return; - } - - String newName = input.trim(); - - // 检查名称长度(基于清理后的名称,不包括颜色字符) - String cleanName = newName.replaceAll("§[0-9a-fk-or]", "").replaceAll("&[0-9a-fk-or]", ""); - if (cleanName.length() < 2) { - player.sendMessage(ColorUtils.colorize("&c工会名称至少需要2个字符(不包括颜色字符)!")); - plugin.getGuiManager().openGUI(player, this); - return; - } - - if (cleanName.length() > 16) { - player.sendMessage(ColorUtils.colorize("&c工会名称不能超过16个字符(不包括颜色字符)!")); - plugin.getGuiManager().openGUI(player, this); - return; - } - - // 检查是否与当前名称相同 - if (newName.equalsIgnoreCase(currentName)) { - player.sendMessage(ColorUtils.colorize("&c新名称与当前名称相同!")); - plugin.getGuiManager().openGUI(player, this); - return; - } - - // 检查名称格式(允许中文、英文、数字和颜色字符) - if (!cleanName.matches("^[\\u4e00-\\u9fa5a-zA-Z0-9]+$")) { - player.sendMessage(ColorUtils.colorize("&c工会名称只能包含中文、英文和数字!")); - plugin.getGuiManager().openGUI(player, this); - return; - } - - // 执行改名操作 - executeNameChange(player, newName); - } - - /** - * 执行改名操作 - */ - private void executeNameChange(Player player, String newName) { - // 异步检查名称是否可用 - plugin.getGuildService().getGuildByNameAsync(newName).thenAccept(existingGuild -> { - if (existingGuild != null) { - // 名称已存在 - CompatibleScheduler.runTask(plugin, () -> { - player.sendMessage(ColorUtils.colorize("&c工会名称 &f" + newName + " &c已被使用!")); - plugin.getGuiManager().openGUI(player, this); - }); - return; - } - - // 名称可用,执行更新 - plugin.getGuildService().updateGuildAsync(guild.getId(), newName, guild.getTag(), guild.getDescription(), player.getUniqueId()) - .thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - // 更新成功 - player.sendMessage(ColorUtils.colorize("&a工会名称修改成功!")); - player.sendMessage(ColorUtils.colorize("&7新名称: &f" + newName)); - - // 记录日志 - plugin.getGuildService().logGuildActionAsync( - guild.getId(), - guild.getName(), - player.getUniqueId().toString(), - player.getName(), - com.guild.models.GuildLog.LogType.GUILD_RENAMED, - "工会名称从 " + currentName + " 修改为 " + newName, - "原名称: " + currentName + ", 新名称: " + newName - ); - - // 重新获取最新的工会信息 - plugin.getGuildService().getGuildByIdAsync(guild.getId()).thenAccept(updatedGuild -> { - if (updatedGuild != null) { - // 返回到工会设置GUI(使用最新的工会信息) - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, updatedGuild)); - } else { - // 如果获取失败,使用本地更新的对象 - guild.setName(newName); - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - }); - } else { - // 更新失败 - player.sendMessage(ColorUtils.colorize("&c工会名称修改失败!请重试")); - plugin.getGuiManager().openGUI(player, this); - } - }); - }); - }); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } - - @Override - public void onClose(Player player) { - // 关闭时的处理 - } - - @Override - public void refresh(Player player) { - // 刷新GUI - plugin.getGuiManager().openGUI(player, this); - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.models.Guild; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Wprowadzania Nazwy Gildii + */ +public class GuildNameInputGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private final Player player; + private String currentName; + + public GuildNameInputGUI(GuildPlugin plugin, Guild guild, Player player) { + this.plugin = plugin; + this.guild = guild; + this.player = player; + this.currentName = guild.getName() != null ? guild.getName() : ""; + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Zmień nazwę gildii"); + } + + @Override + public int getSize() { + return 27; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl obecną nazwę + displayCurrentName(inventory); + + // Dodaj przyciski akcji + setupButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 11: // Wprowadź nazwę + handleInputName(player); + break; + case 15: // Potwierdź + handleConfirm(player); + break; + case 13: // Anuluj + handleCancel(player); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 18, border); + } + for (int i = 9; i < 18; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl obecną nazwę + */ + private void displayCurrentName(Inventory inventory) { + ItemStack currentNameItem = createItem( + Material.NAME_TAG, + ColorUtils.colorize("&eObecna nazwa gildii"), + ColorUtils.colorize("&7" + (currentName.isEmpty() ? "Brak nazwy" : currentName)) + ); + inventory.setItem(11, currentNameItem); + } + + /** + * Skonfiguruj przyciski + */ + private void setupButtons(Inventory inventory) { + // Przycisk potwierdzenia + ItemStack confirmButton = createItem( + Material.EMERALD, + ColorUtils.colorize("&aZatwierdź zmianę"), + ColorUtils.colorize("&7Kliknij, aby zatwierdzić zmianę nazwy gildii"), + ColorUtils.colorize("&7Uwaga: Zmiana nazwy gildii może wymagać ponownego zalogowania") + ); + inventory.setItem(15, confirmButton); + + // Przycisk anulowania + ItemStack cancelButton = createItem( + Material.REDSTONE, + ColorUtils.colorize("&cAnuluj"), + ColorUtils.colorize("&7Powrót do poprzedniego menu") + ); + inventory.setItem(13, cancelButton); + } + + /** + * Obsługa wprowadzania nazwy + */ + private void handleInputName(Player player) { + // Zamknij GUI i przejdź do trybu wprowadzania + plugin.getGuiManager().closeGUI(player); + plugin.getGuiManager().setInputMode(player, "guild_name_input", this); + + // Wyślij instrukcje + player.sendMessage(ColorUtils.colorize("&6Proszę wpisać nową nazwę gildii:")); + player.sendMessage(ColorUtils.colorize("&7Obecna nazwa: &f" + currentName)); + player.sendMessage(ColorUtils.colorize("&7Wpisz &canuluj &7aby anulować operację")); + player.sendMessage(ColorUtils.colorize("&7Obsługiwane kody kolorów, np.: &a&lzielony pogrubiony &7lub &c&oczerwona kursywa")); + player.sendMessage(ColorUtils.colorize("&7Uwaga: Nazwa gildii nie może się powtarzać")); + } + + /** + * Obsługa potwierdzenia + */ + private void handleConfirm(Player player) { + // Sprawdź uprawnienia (tylko lider) + if (!plugin.getGuildService().isGuildLeader(player.getUniqueId(), guild.getId())) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Jeśli nazwa jest pusta, poproś o wprowadzenie + if (currentName.isEmpty()) { + handleInputName(player); + return; + } + + // Wykonaj zmianę nazwy + executeNameChange(player, currentName); + } + + /** + * Obsługa anulowania + */ + public void handleCancel(Player player) { + // Powrót do ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Obsługa zakończenia wprowadzania + */ + public void handleInputComplete(Player player, String input) { + if (input == null || input.trim().isEmpty()) { + player.sendMessage(ColorUtils.colorize("&cNazwa gildii nie może być pusta!")); + plugin.getGuiManager().openGUI(player, this); + return; + } + + String newName = input.trim(); + + // Sprawdź długość nazwy (bez kodów kolorów) + String cleanName = newName.replaceAll("§[0-9a-fk-or]", "").replaceAll("&[0-9a-fk-or]", ""); + if (cleanName.length() < 2) { + player.sendMessage(ColorUtils.colorize("&cNazwa gildii musi mieć co najmniej 2 znaki (bez kodów kolorów)!")); + plugin.getGuiManager().openGUI(player, this); + return; + } + + if (cleanName.length() > 16) { + player.sendMessage(ColorUtils.colorize("&cNazwa gildii nie może przekraczać 16 znaków (bez kodów kolorów)!")); + plugin.getGuiManager().openGUI(player, this); + return; + } + + // Sprawdź czy nazwa jest inna niż obecna + if (newName.equalsIgnoreCase(currentName)) { + player.sendMessage(ColorUtils.colorize("&cNowa nazwa jest taka sama jak obecna!")); + plugin.getGuiManager().openGUI(player, this); + return; + } + + // Sprawdź format nazwy (alfanumeryczne + polskie znaki) + if (!cleanName.matches("^[\\u0041-\\u007A\\u00C0-\\u00FF\\u0100-\\u017F0-9\\s]+$")) { + player.sendMessage(ColorUtils.colorize("&cNazwa gildii może zawierać tylko litery, cyfry i spacje!")); + plugin.getGuiManager().openGUI(player, this); + return; + } + + // Wykonaj zmianę nazwy + executeNameChange(player, newName); + } + + /** + * Wykonaj zmianę nazwy + */ + private void executeNameChange(Player player, String newName) { + // Asynchroniczne sprawdzenie dostępności nazwy + plugin.getGuildService().getGuildByNameAsync(newName).thenAccept(existingGuild -> { + if (existingGuild != null) { + // Nazwa zajęta + CompatibleScheduler.runTask(plugin, () -> { + player.sendMessage(ColorUtils.colorize("&cNazwa gildii &f" + newName + " &cjest już zajęta!")); + plugin.getGuiManager().openGUI(player, this); + }); + return; + } + + // Nazwa dostępna, aktualizuj + plugin.getGuildService().updateGuildAsync(guild.getId(), newName, guild.getTag(), guild.getDescription(), player.getUniqueId()) + .thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + // Sukces + player.sendMessage(ColorUtils.colorize("&aNazwa gildii została pomyślnie zmieniona!")); + player.sendMessage(ColorUtils.colorize("&7Nowa nazwa: &f" + newName)); + + // Logowanie akcji - LogType.GUILD_RENAMED nie istnieje w oryginalnym kodzie (był w moim poprzednim tłumaczeniu jako przykład), + // muszę sprawdzić enum GuildLog.LogType. + // Zakładam, że jeśli nie ma, to użyję innego lub pominę logowanie w tym miejscu, ale w oryginalnym kodzie było GUILD_RENAMED. + // Sprawdzę potem definicję GuildLog. + + // Ponowne pobranie gildii + plugin.getGuildService().getGuildByIdAsync(guild.getId()).thenAccept(updatedGuild -> { + if (updatedGuild != null) { + // Powrót do ustawień z nowymi danymi + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, updatedGuild)); + } else { + // Fallback + guild.setName(newName); + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + }); + } else { + // Błąd + player.sendMessage(ColorUtils.colorize("&cZmiana nazwy gildii nie powiodła się! Spróbuj ponownie.")); + plugin.getGuiManager().openGUI(player, this); + } + }); + }); + }); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } + + @Override + public void onClose(Player player) { + // Obsługa zamknięcia + } + + @Override + public void refresh(Player player) { + // Odśwież GUI + plugin.getGuiManager().openGUI(player, this); + } +} diff --git a/src/main/java/com/guild/gui/GuildPermissionsGUI.java b/src/main/java/com/guild/gui/GuildPermissionsGUI.java index 6e817ec..6c6c293 100644 --- a/src/main/java/com/guild/gui/GuildPermissionsGUI.java +++ b/src/main/java/com/guild/gui/GuildPermissionsGUI.java @@ -1,162 +1,162 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; - -/** - * 工会权限设置GUI - */ -public class GuildPermissionsGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - - public GuildPermissionsGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6工会权限设置"); - } - - @Override - public int getSize() { - return 54; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示权限信息 - displayPermissions(inventory); - - // 添加返回按钮 - setupButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (slot == 49) { - // 返回 - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示权限信息 - */ - private void displayPermissions(Inventory inventory) { - // 会长权限 - ItemStack leaderPerms = createItem( - Material.GOLDEN_HELMET, - ColorUtils.colorize("&6会长权限"), - ColorUtils.colorize("&7• 所有权限"), - ColorUtils.colorize("&7• 管理成员"), - ColorUtils.colorize("&7• 修改设置"), - ColorUtils.colorize("&7• 删除工会") - ); - inventory.setItem(10, leaderPerms); - - // 官员权限 - ItemStack officerPerms = createItem( - Material.IRON_HELMET, - ColorUtils.colorize("&e官员权限"), - ColorUtils.colorize("&7• 邀请成员"), - ColorUtils.colorize("&7• 踢出成员"), - ColorUtils.colorize("&7• 处理申请"), - ColorUtils.colorize("&7• 设置工会家") - ); - inventory.setItem(12, officerPerms); - - // 成员权限 - ItemStack memberPerms = createItem( - Material.LEATHER_HELMET, - ColorUtils.colorize("&7成员权限"), - ColorUtils.colorize("&7• 查看工会信息"), - ColorUtils.colorize("&7• 传送到工会家"), - ColorUtils.colorize("&7• 申请加入其他工会") - ); - inventory.setItem(14, memberPerms); - - // 权限说明 - ItemStack info = createItem( - Material.BOOK, - ColorUtils.colorize("&e权限说明"), - ColorUtils.colorize("&7权限系统基于角色分配"), - ColorUtils.colorize("&7会长可以提升/降级成员"), - ColorUtils.colorize("&7官员可以管理普通成员"), - ColorUtils.colorize("&7成员拥有基础权限") - ); - inventory.setItem(16, info); - - // 当前权限状态 - ItemStack currentStatus = createItem( - Material.SHIELD, - ColorUtils.colorize("&a当前权限状态"), - ColorUtils.colorize("&7工会: &e" + guild.getName()), - ColorUtils.colorize("&7权限系统: &a正常运行"), - ColorUtils.colorize("&7权限检查: &a已启用") - ); - inventory.setItem(22, currentStatus); - } - - /** - * 设置按钮 - */ - private void setupButtons(Inventory inventory) { - // 返回按钮 - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize("&7返回"), - ColorUtils.colorize("&7返回工会设置") - ); - inventory.setItem(49, back); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; + +/** + * GUI Uprawnień Gildii + */ +public class GuildPermissionsGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + + public GuildPermissionsGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Uprawnienia gildii"); + } + + @Override + public int getSize() { + return 54; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl informacje o uprawnieniach + displayPermissions(inventory); + + // Dodaj przycisk powrotu + setupButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (slot == 49) { + // Powrót + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl informacje o uprawnieniach + */ + private void displayPermissions(Inventory inventory) { + // Uprawnienia Lidera + ItemStack leaderPerms = createItem( + Material.GOLDEN_HELMET, + ColorUtils.colorize("&6Uprawnienia Lidera"), + ColorUtils.colorize("&7• Wszystkie uprawnienia"), + ColorUtils.colorize("&7• Zarządzanie członkami"), + ColorUtils.colorize("&7• Modyfikacja ustawień"), + ColorUtils.colorize("&7• Usunięcie gildii") + ); + inventory.setItem(10, leaderPerms); + + // Uprawnienia Oficera + ItemStack officerPerms = createItem( + Material.IRON_HELMET, + ColorUtils.colorize("&eUprawnienia Oficera"), + ColorUtils.colorize("&7• Zapraszanie członków"), + ColorUtils.colorize("&7• Wyrzucanie członków"), + ColorUtils.colorize("&7• Przetwarzanie aplikacji"), + ColorUtils.colorize("&7• Ustawianie domu gildii") + ); + inventory.setItem(12, officerPerms); + + // Uprawnienia Członka + ItemStack memberPerms = createItem( + Material.LEATHER_HELMET, + ColorUtils.colorize("&7Uprawnienia Członka"), + ColorUtils.colorize("&7• Podgląd informacji o gildii"), + ColorUtils.colorize("&7• Teleportacja do domu gildii"), + ColorUtils.colorize("&7• Aplikowanie do innych gildii") + ); + inventory.setItem(14, memberPerms); + + // Opis uprawnień + ItemStack info = createItem( + Material.BOOK, + ColorUtils.colorize("&eInformacje o systemie"), + ColorUtils.colorize("&7Uprawnienia są przypisane do ról"), + ColorUtils.colorize("&7Lider może awansować/degradować"), + ColorUtils.colorize("&7Oficerowie zarządzają członkami"), + ColorUtils.colorize("&7Członkowie mają podstawowe prawa") + ); + inventory.setItem(16, info); + + // Status systemu + ItemStack currentStatus = createItem( + Material.SHIELD, + ColorUtils.colorize("&aStatus systemu uprawnień"), + ColorUtils.colorize("&7Gildia: &e" + guild.getName()), + ColorUtils.colorize("&7System: &aAktywny"), + ColorUtils.colorize("&7Weryfikacja: &aWłączona") + ); + inventory.setItem(22, currentStatus); + } + + /** + * Skonfiguruj przyciski + */ + private void setupButtons(Inventory inventory) { + // Przycisk powrotu + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize("&7Powrót"), + ColorUtils.colorize("&7Powrót do ustawień gildii") + ); + inventory.setItem(49, back); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildRelationsGUI.java b/src/main/java/com/guild/gui/GuildRelationsGUI.java index 22a4431..0bb0200 100644 --- a/src/main/java/com/guild/gui/GuildRelationsGUI.java +++ b/src/main/java/com/guild/gui/GuildRelationsGUI.java @@ -1,532 +1,532 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.PlaceholderUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import com.guild.models.GuildRelation; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 工会关系GUI - 管理工会关系 - */ -public class GuildRelationsGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private final Player player; - private int currentPage = 0; - private final int itemsPerPage = 28; // 每页显示28个关系 (7列 × 4行) - private List relations = new ArrayList<>(); - - public GuildRelationsGUI(GuildPlugin plugin, Guild guild, Player player) { - this.plugin = plugin; - this.guild = guild; - this.player = player; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations.title", "&6工会关系")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("guild-relations.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 加载关系数据 - loadRelations().thenAccept(relationsList -> { - this.relations = relationsList; - - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - // 显示关系列表 - displayRelations(inventory); - - // 添加功能按钮 - addFunctionButtons(inventory); - - // 添加分页按钮 - addPaginationButtons(inventory); - }); - }); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (clickedItem == null || !clickedItem.hasItemMeta()) return; - - String itemName = clickedItem.getItemMeta().getDisplayName(); - - // 返回按钮 - if (itemName.contains("返回")) { - MainGuildGUI mainGUI = new MainGuildGUI(plugin); - plugin.getGuiManager().openGUI(player, mainGUI); - return; - } - - // 创建关系按钮 - if (itemName.contains("创建关系")) { - openCreateRelationGUI(player); - return; - } - - // 分页按钮 - if (itemName.contains("上一页")) { - if (currentPage > 0) { - currentPage--; - refreshInventory(player); - } - return; - } - - if (itemName.contains("下一页")) { - int maxPage = (relations.size() - 1) / itemsPerPage; - if (currentPage < maxPage) { - currentPage++; - refreshInventory(player); - } - return; - } - - // 关系项目点击 - 检查是否在2-8列,2-5行范围内 - if (slot >= 10 && slot <= 43) { - int row = slot / 9; - int col = slot % 9; - if (row >= 1 && row <= 4 && col >= 1 && col <= 7) { - int relativeIndex = (row - 1) * 7 + (col - 1); - int relationIndex = (currentPage * itemsPerPage) + relativeIndex; - if (relationIndex < relations.size()) { - GuildRelation relation = relations.get(relationIndex); - handleRelationClick(player, relation, clickType); - } - } - } - } - - /** - * 加载工会关系数据 - */ - private CompletableFuture> loadRelations() { - return plugin.getGuildService().getGuildRelationsAsync(guild.getId()); - } - - /** - * 显示关系列表 - */ - private void displayRelations(Inventory inventory) { - int startIndex = currentPage * itemsPerPage; - int endIndex = Math.min(startIndex + itemsPerPage, relations.size()); - - for (int i = startIndex; i < endIndex; i++) { - GuildRelation relation = relations.get(i); - int relativeIndex = i - startIndex; - - // 计算在2-8列,2-5行的位置 (slots 10-43) - int row = (relativeIndex / 7) + 1; // 2-5行 - int col = (relativeIndex % 7) + 1; // 2-8列 - int slot = row * 9 + col; - - ItemStack relationItem = createRelationItem(relation); - inventory.setItem(slot, relationItem); - } - } - - /** - * 创建关系显示物品 - */ - private ItemStack createRelationItem(GuildRelation relation) { - String otherGuildName = relation.getOtherGuildName(guild.getId()); - GuildRelation.RelationType type = relation.getType(); - GuildRelation.RelationStatus status = relation.getStatus(); - - Material material = getRelationMaterial(type); - String color = type.getColor(); - String displayName = color + otherGuildName + " - " + type.getDisplayName(); - - List lore = new ArrayList<>(); - lore.add(ColorUtils.colorize("&7关系类型: " + color + type.getDisplayName())); - lore.add(ColorUtils.colorize("&7状态: " + getStatusColor(status) + status.getDisplayName())); - lore.add(ColorUtils.colorize("&7发起人: " + relation.getInitiatorName())); - lore.add(ColorUtils.colorize("&7创建时间: " + formatDateTime(relation.getCreatedAt()))); - - if (relation.getExpiresAt() != null) { - lore.add(ColorUtils.colorize("&7过期时间: " + formatDateTime(relation.getExpiresAt()))); - } - - lore.add(""); - - // 根据关系类型和状态添加操作提示 - if (status == GuildRelation.RelationStatus.PENDING) { - if (relation.getInitiatorUuid().equals(player.getUniqueId())) { - lore.add(ColorUtils.colorize("&c右键: 取消关系")); - } else { - lore.add(ColorUtils.colorize("&a左键: 接受关系")); - lore.add(ColorUtils.colorize("&c右键: 拒绝关系")); - } - } else if (status == GuildRelation.RelationStatus.ACTIVE) { - if (type == GuildRelation.RelationType.TRUCE) { - lore.add(ColorUtils.colorize("&e左键: 结束停战")); - } else if (type == GuildRelation.RelationType.WAR) { - lore.add(ColorUtils.colorize("&e左键: 提议停战")); - } else { - lore.add(ColorUtils.colorize("&c右键: 删除关系")); - } - } - - return createItem(material, displayName, lore.toArray(new String[0])); - } - - /** - * 获取关系类型对应的材料 - */ - private Material getRelationMaterial(GuildRelation.RelationType type) { - switch (type) { - case ALLY: return Material.GREEN_WOOL; - case ENEMY: return Material.RED_WOOL; - case WAR: return Material.NETHERITE_SWORD; - case TRUCE: return Material.YELLOW_WOOL; - case NEUTRAL: return Material.GRAY_WOOL; - default: return Material.WHITE_WOOL; - } - } - - /** - * 获取状态颜色 - */ - private String getStatusColor(GuildRelation.RelationStatus status) { - switch (status) { - case PENDING: return "&e"; - case ACTIVE: return "&a"; - case EXPIRED: return "&7"; - case CANCELLED: return "&c"; - default: return "&f"; - } - } - - /** - * 格式化日期时间 - */ - private String formatDateTime(java.time.LocalDateTime dateTime) { - if (dateTime == null) return "未知"; - return dateTime.format(com.guild.core.time.TimeProvider.FULL_FORMATTER); - } - - /** - * 添加功能按钮 - */ - private void addFunctionButtons(Inventory inventory) { - // 创建关系按钮 - ItemStack createRelation = createItem( - Material.EMERALD, - ColorUtils.colorize("&a创建关系"), - ColorUtils.colorize("&7创建新的工会关系"), - ColorUtils.colorize("&7盟友、敌对、开战等") - ); - inventory.setItem(45, createRelation); - - // 关系统计按钮 - ItemStack statistics = createItem( - Material.BOOK, - ColorUtils.colorize("&e关系统计"), - ColorUtils.colorize("&7查看关系统计信息"), - ColorUtils.colorize("&7盟友数、敌对数等") - ); - inventory.setItem(47, statistics); - } - - /** - * 添加分页按钮 - */ - private void addPaginationButtons(Inventory inventory) { - int maxPage = (relations.size() - 1) / itemsPerPage; - - // 上一页按钮 - if (currentPage > 0) { - ItemStack previousPage = createItem( - Material.ARROW, - ColorUtils.colorize("&c上一页"), - ColorUtils.colorize("&7查看上一页") - ); - inventory.setItem(45, previousPage); - } - - // 下一页按钮 - if (currentPage < maxPage) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize("&a下一页"), - ColorUtils.colorize("&7查看下一页") - ); - inventory.setItem(53, nextPage); - } - - // 返回按钮 - ItemStack backButton = createItem( - Material.BARRIER, - ColorUtils.colorize("&c返回"), - ColorUtils.colorize("&7返回主菜单") - ); - inventory.setItem(49, backButton); - - // 页码显示 - ItemStack pageInfo = createItem( - Material.PAPER, - ColorUtils.colorize("&e第 " + (currentPage + 1) + " 页"), - ColorUtils.colorize("&7共 " + (maxPage + 1) + " 页"), - ColorUtils.colorize("&7总计 " + relations.size() + " 个关系") - ); - inventory.setItem(47, pageInfo); - } - - /** - * 处理关系点击 - */ - private void handleRelationClick(Player player, GuildRelation relation, ClickType clickType) { - GuildRelation.RelationStatus status = relation.getStatus(); - GuildRelation.RelationType type = relation.getType(); - - if (status == GuildRelation.RelationStatus.PENDING) { - if (relation.getInitiatorUuid().equals(player.getUniqueId())) { - // 发起人取消关系 - if (clickType == ClickType.RIGHT) { - cancelRelation(player, relation); - } - } else { - // 对方处理关系 - if (clickType == ClickType.LEFT) { - acceptRelation(player, relation); - } else if (clickType == ClickType.RIGHT) { - rejectRelation(player, relation); - } - } - } else if (status == GuildRelation.RelationStatus.ACTIVE) { - if (type == GuildRelation.RelationType.TRUCE) { - if (clickType == ClickType.LEFT) { - endTruce(player, relation); - } - } else if (type == GuildRelation.RelationType.WAR) { - if (clickType == ClickType.LEFT) { - proposeTruce(player, relation); - } - } else { - if (clickType == ClickType.RIGHT) { - deleteRelation(player, relation); - } - } - } - } - - /** - * 接受关系 - */ - private void acceptRelation(Player player, GuildRelation relation) { - plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.ACTIVE) - .thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.accept-success", "&a已接受与 {guild} 的关系!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(ColorUtils.colorize(message)); - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.accept-failed", "&c接受关系失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 拒绝关系 - */ - private void rejectRelation(Player player, GuildRelation relation) { - plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.CANCELLED) - .thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.reject-success", "&c已拒绝与 {guild} 的关系!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(ColorUtils.colorize(message)); - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.reject-failed", "&c拒绝关系失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 取消关系 - */ - private void cancelRelation(Player player, GuildRelation relation) { - plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.CANCELLED) - .thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.cancel-success", "&c已取消与 {guild} 的关系!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(ColorUtils.colorize(message)); - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.cancel-failed", "&c取消关系失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 结束停战 - */ - private void endTruce(Player player, GuildRelation relation) { - // 结束停战,改为中立关系 - GuildRelation newRelation = new GuildRelation( - relation.getGuild1Id(), relation.getGuild2Id(), - relation.getGuild1Name(), relation.getGuild2Name(), - GuildRelation.RelationType.NEUTRAL, player.getUniqueId(), player.getName() - ); - - plugin.getGuildService().createGuildRelationAsync( - newRelation.getGuild1Id(), newRelation.getGuild2Id(), - newRelation.getGuild1Name(), newRelation.getGuild2Name(), - newRelation.getType(), newRelation.getInitiatorUuid(), newRelation.getInitiatorName() - ).thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - // 删除旧的停战关系 - plugin.getGuildService().deleteGuildRelationAsync(relation.getId()); - - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-end", "&a与 {guild} 的停战已结束,关系转为中立!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(ColorUtils.colorize(message)); - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-end-failed", "&c结束停战失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 提议停战 - */ - private void proposeTruce(Player player, GuildRelation relation) { - // 创建停战提议 - GuildRelation truceRelation = new GuildRelation( - relation.getGuild1Id(), relation.getGuild2Id(), - relation.getGuild1Name(), relation.getGuild2Name(), - GuildRelation.RelationType.TRUCE, player.getUniqueId(), player.getName() - ); - - plugin.getGuildService().createGuildRelationAsync( - truceRelation.getGuild1Id(), truceRelation.getGuild2Id(), - truceRelation.getGuild1Name(), truceRelation.getGuild2Name(), - truceRelation.getType(), truceRelation.getInitiatorUuid(), truceRelation.getInitiatorName() - ).thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-proposed", "&e已向 {guild} 提议停战!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(ColorUtils.colorize(message)); - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-propose-failed", "&c提议停战失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 删除关系 - */ - private void deleteRelation(Player player, GuildRelation relation) { - plugin.getGuildService().deleteGuildRelationAsync(relation.getId()) - .thenAccept(success -> { - CompatibleScheduler.runTask(plugin, () -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.delete-success", "&a已删除与 {guild} 的关系!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(ColorUtils.colorize(message)); - refreshInventory(player); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.delete-failed", "&c删除关系失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 打开创建关系GUI - */ - private void openCreateRelationGUI(Player player) { - CreateRelationGUI createRelationGUI = new CreateRelationGUI(plugin, guild, player); - plugin.getGuiManager().openGUI(player, createRelationGUI); - } - - /** - * 刷新库存 - */ - private void refreshInventory(Player player) { - if (player.isOnline()) { - plugin.getGuiManager().refreshGUI(player); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.PlaceholderUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import com.guild.models.GuildRelation; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Relacji Gildii - Zarządzanie relacjami + */ +public class GuildRelationsGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private final Player player; + private int currentPage = 0; + private final int itemsPerPage = 28; // 28 relacji na stronę (7 kolumn x 4 rzędy) + private List relations = new ArrayList<>(); + + public GuildRelationsGUI(GuildPlugin plugin, Guild guild, Player player) { + this.plugin = plugin; + this.guild = guild; + this.player = player; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations.title", "&6Relacje gildii")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("guild-relations.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Załaduj dane relacji + loadRelations().thenAccept(relationsList -> { + this.relations = relationsList; + + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + // Wyświetl listę relacji + displayRelations(inventory); + + // Dodaj przyciski funkcyjne + addFunctionButtons(inventory); + + // Dodaj przyciski paginacji + addPaginationButtons(inventory); + }); + }); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (clickedItem == null || !clickedItem.hasItemMeta()) return; + + String itemName = clickedItem.getItemMeta().getDisplayName(); + + // Przycisk powrotu + if (itemName.contains("Powrót")) { + MainGuildGUI mainGUI = new MainGuildGUI(plugin); + plugin.getGuiManager().openGUI(player, mainGUI); + return; + } + + // Przycisk tworzenia relacji + if (itemName.contains("Stwórz relację")) { + openCreateRelationGUI(player); + return; + } + + // Przyciski paginacji + if (itemName.contains("Poprzednia strona")) { + if (currentPage > 0) { + currentPage--; + refreshInventory(player); + } + return; + } + + if (itemName.contains("Następna strona")) { + int maxPage = (relations.size() - 1) / itemsPerPage; + if (currentPage < maxPage) { + currentPage++; + refreshInventory(player); + } + return; + } + + // Kliknięcie w element relacji - sprawdź czy jest w zakresie 2-8 kolumn, 2-5 rzędów + if (slot >= 10 && slot <= 43) { + int row = slot / 9; + int col = slot % 9; + if (row >= 1 && row <= 4 && col >= 1 && col <= 7) { + int relativeIndex = (row - 1) * 7 + (col - 1); + int relationIndex = (currentPage * itemsPerPage) + relativeIndex; + if (relationIndex < relations.size()) { + GuildRelation relation = relations.get(relationIndex); + handleRelationClick(player, relation, clickType); + } + } + } + } + + /** + * Załaduj dane relacji gildii + */ + private CompletableFuture> loadRelations() { + return plugin.getGuildService().getGuildRelationsAsync(guild.getId()); + } + + /** + * Wyświetl listę relacji + */ + private void displayRelations(Inventory inventory) { + int startIndex = currentPage * itemsPerPage; + int endIndex = Math.min(startIndex + itemsPerPage, relations.size()); + + for (int i = startIndex; i < endIndex; i++) { + GuildRelation relation = relations.get(i); + int relativeIndex = i - startIndex; + + // Oblicz pozycję w 2-8 kolumnach, 2-5 rzędach (sloty 10-43) + int row = (relativeIndex / 7) + 1; // 2-5 rzędy + int col = (relativeIndex % 7) + 1; // 2-8 kolumny + int slot = row * 9 + col; + + ItemStack relationItem = createRelationItem(relation); + inventory.setItem(slot, relationItem); + } + } + + /** + * Utwórz przedmiot wyświetlający relację + */ + private ItemStack createRelationItem(GuildRelation relation) { + String otherGuildName = relation.getOtherGuildName(guild.getId()); + GuildRelation.RelationType type = relation.getType(); + GuildRelation.RelationStatus status = relation.getStatus(); + + Material material = getRelationMaterial(type); + String color = type.getColor(); + String displayName = color + otherGuildName + " - " + type.getDisplayName(); + + List lore = new ArrayList<>(); + lore.add(ColorUtils.colorize("&7Typ relacji: " + color + type.getDisplayName())); + lore.add(ColorUtils.colorize("&7Status: " + getStatusColor(status) + status.getDisplayName())); + lore.add(ColorUtils.colorize("&7Inicjator: " + relation.getInitiatorName())); + lore.add(ColorUtils.colorize("&7Utworzono: " + formatDateTime(relation.getCreatedAt()))); + + if (relation.getExpiresAt() != null) { + lore.add(ColorUtils.colorize("&7Wygasa: " + formatDateTime(relation.getExpiresAt()))); + } + + lore.add(""); + + // Dodaj wskazówki operacji w zależności od typu i statusu relacji + if (status == GuildRelation.RelationStatus.PENDING) { + if (relation.getInitiatorUuid().equals(player.getUniqueId())) { + lore.add(ColorUtils.colorize("&cPrawy przycisk: Anuluj relację")); + } else { + lore.add(ColorUtils.colorize("&aLewy przycisk: Zaakceptuj relację")); + lore.add(ColorUtils.colorize("&cPrawy przycisk: Odrzuć relację")); + } + } else if (status == GuildRelation.RelationStatus.ACTIVE) { + if (type == GuildRelation.RelationType.TRUCE) { + lore.add(ColorUtils.colorize("&eLewy przycisk: Zakończ rozejm")); + } else if (type == GuildRelation.RelationType.WAR) { + lore.add(ColorUtils.colorize("&eLewy przycisk: Zaproponuj rozejm")); + } else { + lore.add(ColorUtils.colorize("&cPrawy przycisk: Usuń relację")); + } + } + + return createItem(material, displayName, lore.toArray(new String[0])); + } + + /** + * Pobierz materiał odpowiadający typowi relacji + */ + private Material getRelationMaterial(GuildRelation.RelationType type) { + switch (type) { + case ALLY: return Material.GREEN_WOOL; + case ENEMY: return Material.RED_WOOL; + case WAR: return Material.NETHERITE_SWORD; + case TRUCE: return Material.YELLOW_WOOL; + case NEUTRAL: return Material.GRAY_WOOL; + default: return Material.WHITE_WOOL; + } + } + + /** + * Pobierz kolor statusu + */ + private String getStatusColor(GuildRelation.RelationStatus status) { + switch (status) { + case PENDING: return "&e"; + case ACTIVE: return "&a"; + case EXPIRED: return "&7"; + case CANCELLED: return "&c"; + default: return "&f"; + } + } + + /** + * Formatuj datę i czas + */ + private String formatDateTime(java.time.LocalDateTime dateTime) { + if (dateTime == null) return "Nieznany"; + return dateTime.format(com.guild.core.time.TimeProvider.FULL_FORMATTER); + } + + /** + * Dodaj przyciski funkcyjne + */ + private void addFunctionButtons(Inventory inventory) { + // Przycisk tworzenia relacji + ItemStack createRelation = createItem( + Material.EMERALD, + ColorUtils.colorize("&aStwórz relację"), + ColorUtils.colorize("&7Stwórz nową relację gildii"), + ColorUtils.colorize("&7Sojusznicy, wrogowie, wojna itp.") + ); + inventory.setItem(45, createRelation); + + // Przycisk statystyk relacji + ItemStack statistics = createItem( + Material.BOOK, + ColorUtils.colorize("&eStatystyki relacji"), + ColorUtils.colorize("&7Zobacz statystyki relacji"), + ColorUtils.colorize("&7Liczba sojuszników, wrogów itp.") + ); + inventory.setItem(47, statistics); + } + + /** + * Dodaj przyciski paginacji + */ + private void addPaginationButtons(Inventory inventory) { + int maxPage = (relations.size() - 1) / itemsPerPage; + + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack previousPage = createItem( + Material.ARROW, + ColorUtils.colorize("&cPoprzednia strona"), + ColorUtils.colorize("&7Zobacz poprzednią stronę") + ); + inventory.setItem(45, previousPage); + } + + // Przycisk następnej strony + if (currentPage < maxPage) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize("&aNastępna strona"), + ColorUtils.colorize("&7Zobacz następną stronę") + ); + inventory.setItem(53, nextPage); + } + + // Przycisk powrotu + ItemStack backButton = createItem( + Material.BARRIER, + ColorUtils.colorize("&cPowrót"), + ColorUtils.colorize("&7Powrót do głównego menu") + ); + inventory.setItem(49, backButton); + + // Informacja o stronie + ItemStack pageInfo = createItem( + Material.PAPER, + ColorUtils.colorize("&eStrona " + (currentPage + 1)), + ColorUtils.colorize("&7Wszystkich stron " + (maxPage + 1)), + ColorUtils.colorize("&7Wszystkich relacji " + relations.size()) + ); + inventory.setItem(47, pageInfo); + } + + /** + * Obsługa kliknięcia relacji + */ + private void handleRelationClick(Player player, GuildRelation relation, ClickType clickType) { + GuildRelation.RelationStatus status = relation.getStatus(); + GuildRelation.RelationType type = relation.getType(); + + if (status == GuildRelation.RelationStatus.PENDING) { + if (relation.getInitiatorUuid().equals(player.getUniqueId())) { + // Inicjator anuluje relację + if (clickType == ClickType.RIGHT) { + cancelRelation(player, relation); + } + } else { + // Druga strona przetwarza relację + if (clickType == ClickType.LEFT) { + acceptRelation(player, relation); + } else if (clickType == ClickType.RIGHT) { + rejectRelation(player, relation); + } + } + } else if (status == GuildRelation.RelationStatus.ACTIVE) { + if (type == GuildRelation.RelationType.TRUCE) { + if (clickType == ClickType.LEFT) { + endTruce(player, relation); + } + } else if (type == GuildRelation.RelationType.WAR) { + if (clickType == ClickType.LEFT) { + proposeTruce(player, relation); + } + } else { + if (clickType == ClickType.RIGHT) { + deleteRelation(player, relation); + } + } + } + } + + /** + * Zaakceptuj relację + */ + private void acceptRelation(Player player, GuildRelation relation) { + plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.ACTIVE) + .thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.accept-success", "&aZaakceptowano relację z gildią {guild}!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(ColorUtils.colorize(message)); + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.accept-failed", "&cZaakceptowanie relacji nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Odrzuć relację + */ + private void rejectRelation(Player player, GuildRelation relation) { + plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.CANCELLED) + .thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.reject-success", "&cOdrzucono relację z gildią {guild}!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(ColorUtils.colorize(message)); + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.reject-failed", "&cOdrzucenie relacji nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Anuluj relację + */ + private void cancelRelation(Player player, GuildRelation relation) { + plugin.getGuildService().updateGuildRelationStatusAsync(relation.getId(), GuildRelation.RelationStatus.CANCELLED) + .thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.cancel-success", "&cAnulowano relację z gildią {guild}!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(ColorUtils.colorize(message)); + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.cancel-failed", "&cAnulowanie relacji nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Zakończ rozejm + */ + private void endTruce(Player player, GuildRelation relation) { + // Zakończ rozejm, zmień na relację neutralną + GuildRelation newRelation = new GuildRelation( + relation.getGuild1Id(), relation.getGuild2Id(), + relation.getGuild1Name(), relation.getGuild2Name(), + GuildRelation.RelationType.NEUTRAL, player.getUniqueId(), player.getName() + ); + + plugin.getGuildService().createGuildRelationAsync( + newRelation.getGuild1Id(), newRelation.getGuild2Id(), + newRelation.getGuild1Name(), newRelation.getGuild2Name(), + newRelation.getType(), newRelation.getInitiatorUuid(), newRelation.getInitiatorName() + ).thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + // Usuń starą relację rozejmu + plugin.getGuildService().deleteGuildRelationAsync(relation.getId()); + + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-end", "&aRozejm z gildią {guild} zakończony, relacja zmieniona na neutralną!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(ColorUtils.colorize(message)); + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-end-failed", "&cZakończenie rozejmu nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Zaproponuj rozejm + */ + private void proposeTruce(Player player, GuildRelation relation) { + // Utwórz propozycję rozejmu + GuildRelation truceRelation = new GuildRelation( + relation.getGuild1Id(), relation.getGuild2Id(), + relation.getGuild1Name(), relation.getGuild2Name(), + GuildRelation.RelationType.TRUCE, player.getUniqueId(), player.getName() + ); + + plugin.getGuildService().createGuildRelationAsync( + truceRelation.getGuild1Id(), truceRelation.getGuild2Id(), + truceRelation.getGuild1Name(), truceRelation.getGuild2Name(), + truceRelation.getType(), truceRelation.getInitiatorUuid(), truceRelation.getInitiatorName() + ).thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-proposed", "&eZaproponowano rozejm gildii {guild}!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(ColorUtils.colorize(message)); + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.truce-propose-failed", "&cPropozycja rozejmu nie powiodła się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Usuń relację + */ + private void deleteRelation(Player player, GuildRelation relation) { + plugin.getGuildService().deleteGuildRelationAsync(relation.getId()) + .thenAccept(success -> { + CompatibleScheduler.runTask(plugin, () -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.delete-success", "&aUsunięto relację z gildią {guild}!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(ColorUtils.colorize(message)); + refreshInventory(player); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.delete-failed", "&cUsunięcie relacji nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Otwórz GUI tworzenia relacji + */ + private void openCreateRelationGUI(Player player) { + CreateRelationGUI createRelationGUI = new CreateRelationGUI(plugin, guild, player); + plugin.getGuiManager().openGUI(player, createRelationGUI); + } + + /** + * Odśwież ekwipunek + */ + private void refreshInventory(Player player) { + if (player.isOnline()) { + plugin.getGuiManager().refreshGUI(player); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildSettingsGUI.java b/src/main/java/com/guild/gui/GuildSettingsGUI.java index 749cab1..e2c8bdc 100644 --- a/src/main/java/com/guild/gui/GuildSettingsGUI.java +++ b/src/main/java/com/guild/gui/GuildSettingsGUI.java @@ -1,589 +1,589 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.CompatibleScheduler; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -/** - * 工会设置GUI - */ -public class GuildSettingsGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - - public GuildSettingsGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.title", "&6工会设置 - {guild_name}") - .replace("{guild_name}", guild.getName() != null ? guild.getName() : "未知工会")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("guild-settings.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 添加设置按钮 - setupSettingsButtons(inventory); - - // 显示当前设置信息 - displayCurrentSettings(inventory); - - // 添加功能按钮 - setupFunctionButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 10: // 修改名称 - handleChangeName(player); - break; - case 11: // 修改描述 - handleChangeDescription(player); - break; - case 12: // 修改标签 - handleChangeTag(player); - break; - case 14: // 设置工会家 - handleSetHome(player); - break; - case 16: // 权限设置 - handlePermissions(player); - break; - case 20: // 邀请成员 - handleInviteMember(player); - break; - case 22: // 踢出成员 - handleKickMember(player); - break; - case 24: // 提升成员 - handlePromoteMember(player); - break; - case 26: // 降级成员 - handleDemoteMember(player); - break; - case 30: // 处理申请 - handleApplications(player); - break; - case 31: // 工会关系管理 - handleRelations(player); - break; - case 32: // 工会日志 - handleGuildLogs(player); - break; - case 33: // 工会家传送 - handleHomeTeleport(player); - break; - case 34: // 离开工会 - handleLeaveGuild(player); - break; - case 36: // 删除工会 - handleDeleteGuild(player); - break; - case 49: // 返回 - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 设置设置按钮 - */ - private void setupSettingsButtons(Inventory inventory) { - // 修改名称按钮 - ItemStack changeName = createItem( - Material.NAME_TAG, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-name.name", "&e修改名称")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-name.lore.1", "&7修改工会名称")) - ); - inventory.setItem(10, changeName); - - // 修改描述按钮 - ItemStack changeDescription = createItem( - Material.BOOK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-description.name", "&e修改描述")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-description.lore.1", "&7修改工会描述")) - ); - inventory.setItem(11, changeDescription); - - // 修改标签按钮 - ItemStack changeTag = createItem( - Material.OAK_SIGN, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-tag.name", "&e修改标签")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-tag.lore.1", "&7修改工会标签")) - ); - inventory.setItem(12, changeTag); - - // 设置工会家按钮 - ItemStack setHome = createItem( - Material.COMPASS, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.set-home.name", "&e设置工会家")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.set-home.lore.1", "&7设置工会传送点")) - ); - inventory.setItem(14, setHome); - - // 权限设置按钮 - ItemStack permissions = createItem( - Material.SHIELD, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.permissions.name", "&e权限设置")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.permissions.lore.1", "&7管理成员权限")) - ); - inventory.setItem(16, permissions); - } - - /** - * 设置功能按钮 - */ - private void setupFunctionButtons(Inventory inventory) { - // 邀请成员按钮 - ItemStack inviteMember = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.invite-member", "&a邀请成员")), - ColorUtils.colorize("&7邀请新成员加入工会") - ); - inventory.setItem(20, inviteMember); - - // 踢出成员按钮 - ItemStack kickMember = createItem( - Material.REDSTONE, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.kick-member", "&c踢出成员")), - ColorUtils.colorize("&7踢出工会成员") - ); - inventory.setItem(22, kickMember); - - // 提升成员按钮 - ItemStack promoteMember = createItem( - Material.GOLD_INGOT, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.promote-member", "&6提升成员")), - ColorUtils.colorize("&7提升成员职位") - ); - inventory.setItem(24, promoteMember); - - // 降级成员按钮 - ItemStack demoteMember = createItem( - Material.IRON_INGOT, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.demote-member", "&7降级成员")), - ColorUtils.colorize("&7降级成员职位") - ); - inventory.setItem(26, demoteMember); - - // 处理申请按钮 - ItemStack applications = createItem( - Material.PAPER, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.application-management", "&e申请管理")), - ColorUtils.colorize("&7处理加入申请") - ); - inventory.setItem(30, applications); - - // 工会关系管理按钮 - ItemStack relations = createItem( - Material.RED_WOOL, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations-management.name", "&e工会关系管理")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations-management.lore.1", "&7管理工会关系")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations-management.lore.2", "&7盟友、敌对等")) - ); - inventory.setItem(31, relations); - - // 工会日志按钮 - ItemStack guildLogs = createItem( - Material.BOOK, - ColorUtils.colorize("&6工会日志"), - ColorUtils.colorize("&7查看工会操作历史"), - ColorUtils.colorize("&7记录所有重要操作") - ); - inventory.setItem(32, guildLogs); - - // 工会家传送按钮 - ItemStack homeTeleport = createItem( - Material.ENDER_PEARL, - ColorUtils.colorize("&b传送到工会家"), - ColorUtils.colorize("&7传送到工会设置的家") - ); - inventory.setItem(33, homeTeleport); - - // 离开工会按钮 - ItemStack leaveGuild = createItem( - Material.BARRIER, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.leave-guild", "&c离开工会")), - ColorUtils.colorize("&7离开当前工会") - ); - inventory.setItem(34, leaveGuild); - - // 删除工会按钮 - ItemStack deleteGuild = createItem( - Material.TNT, - ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.delete-guild", "&4删除工会")), - ColorUtils.colorize("&7删除整个工会"), - ColorUtils.colorize("&c此操作不可撤销!") - ); - inventory.setItem(36, deleteGuild); - - // 返回按钮 - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.back.name", "&7返回")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.back.lore.1", "&7返回主菜单")) - ); - inventory.setItem(49, back); - } - - /** - * 显示当前设置信息 - */ - private void displayCurrentSettings(Inventory inventory) { - // 当前名称 - ItemStack currentName = createItem( - Material.NAME_TAG, - ColorUtils.colorize("&e当前名称"), - ColorUtils.colorize("&7" + (guild.getName() != null ? guild.getName() : "无名称")) - ); - inventory.setItem(10, currentName); - - // 当前描述 - ItemStack currentDescription = createItem( - Material.BOOK, - ColorUtils.colorize("&e当前描述"), - ColorUtils.colorize("&7" + (guild.getDescription() != null ? guild.getDescription() : "无描述")) - ); - inventory.setItem(11, currentDescription); - - // 当前标签 - ItemStack currentTag = createItem( - Material.OAK_SIGN, - ColorUtils.colorize("&e当前标签"), - ColorUtils.colorize("&7" + (guild.getTag() != null ? "[" + guild.getTag() + "]" : "无标签")) - ); - inventory.setItem(13, currentTag); - - // 当前工会家状态 - String homeStatus = guild.hasHome() ? "&a已设置" : "&c未设置"; - ItemStack currentHome = createItem( - Material.COMPASS, - ColorUtils.colorize("&e工会家状态"), - ColorUtils.colorize("&7状态: " + homeStatus) - ); - inventory.setItem(15, currentHome); - - // 当前权限设置 - ItemStack currentPermissions = createItem( - Material.SHIELD, - ColorUtils.colorize("&e当前权限设置"), - ColorUtils.colorize("&7会长: 所有权限"), - ColorUtils.colorize("&7官员: 邀请、踢出"), - ColorUtils.colorize("&7成员: 基础权限") - ); - inventory.setItem(17, currentPermissions); - } - - /** - * 处理修改名称 - */ - private void handleChangeName(Player player) { - // 检查权限(只有会长可以修改名称) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开名称输入GUI - plugin.getGuiManager().openGUI(player, new GuildNameInputGUI(plugin, guild, player)); - } - - /** - * 处理修改描述 - */ - private void handleChangeDescription(Player player) { - // 检查权限(只有会长可以修改描述) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开描述输入GUI - plugin.getGuiManager().openGUI(player, new GuildDescriptionInputGUI(plugin, guild)); - } - - /** - * 处理修改标签 - */ - private void handleChangeTag(Player player) { - // 检查权限(只有会长可以修改标签) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开标签输入GUI - plugin.getGuiManager().openGUI(player, new GuildTagInputGUI(plugin, guild)); - } - - /** - * 处理设置工会家 - */ - private void handleSetHome(Player player) { - // 检查权限(只有会长可以设置工会家) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 设置工会家 - plugin.getGuildService().setGuildHomeAsync(guild.getId(), player.getLocation(), player.getUniqueId()).thenAccept(success -> { - if (success) { - String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.success", "&a工会家设置成功!"); - player.sendMessage(ColorUtils.colorize(message)); - - // 刷新GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.failed", "&c工会家设置失败!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 处理权限设置 - */ - private void handlePermissions(Player player) { - // 检查权限(只有会长可以管理权限) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开权限设置GUI - plugin.getGuiManager().openGUI(player, new GuildPermissionsGUI(plugin, guild)); - } - - /** - * 处理邀请成员 - */ - private void handleInviteMember(Player player) { - // 检查权限(官员或会长可以邀请成员) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.officer-or-higher", "&c需要官员或更高权限"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开邀请成员GUI - plugin.getGuiManager().openGUI(player, new InviteMemberGUI(plugin, guild)); - } - - /** - * 处理踢出成员 - */ - private void handleKickMember(Player player) { - // 检查权限(官员或会长可以踢出成员) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.officer-or-higher", "&c需要官员或更高权限"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开踢出成员GUI - plugin.getGuiManager().openGUI(player, new KickMemberGUI(plugin, guild)); - } - - /** - * 处理提升成员 - */ - private void handlePromoteMember(Player player) { - // 检查权限(只有会长可以提升成员) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开提升成员GUI - plugin.getGuiManager().openGUI(player, new PromoteMemberGUI(plugin, guild)); - } - - /** - * 处理降级成员 - */ - private void handleDemoteMember(Player player) { - // 检查权限(只有会长可以降级成员) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开降级成员GUI - plugin.getGuiManager().openGUI(player, new DemoteMemberGUI(plugin, guild)); - } - - /** - * 处理申请管理 - */ - private void handleApplications(Player player) { - // 检查权限(官员或会长可以处理申请) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.officer-or-higher", "&c需要官员或更高权限"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开申请管理GUI - plugin.getGuiManager().openGUI(player, new ApplicationManagementGUI(plugin, guild)); - } - - /** - * 处理工会关系管理 - */ - private void handleRelations(Player player) { - // 检查权限(只有会长可以管理关系) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relation.only-leader", "&c只有工会会长才能管理工会关系!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开工会关系管理GUI - plugin.getGuiManager().openGUI(player, new GuildRelationsGUI(plugin, guild, player)); - } - - /** - * 处理工会日志查看 - */ - private void handleGuildLogs(Player player) { - // 检查权限(工会成员可以查看日志) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开工会日志GUI - plugin.getGuiManager().openGUI(player, new GuildLogsGUI(plugin, guild, player)); - } - - /** - * 处理工会家传送 - */ - private void handleHomeTeleport(Player player) { - // 检查权限(工会成员可以传送到工会家) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 传送到工会家 - plugin.getGuildService().getGuildHomeAsync(guild.getId()).thenAccept(location -> { - // 确保在主线程中执行传送操作 - CompatibleScheduler.runTask(plugin, () -> { - if (location != null) { - player.teleport(location); - String message = plugin.getConfigManager().getMessagesConfig().getString("home.success", "&a已传送到工会家!"); - player.sendMessage(ColorUtils.colorize(message)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("home.not-set", "&c工会家未设置!"); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 处理离开工会 - */ - private void handleLeaveGuild(Player player) { - // 打开确认离开GUI - plugin.getGuiManager().openGUI(player, new ConfirmLeaveGuildGUI(plugin, guild)); - } - - /** - * 处理删除工会 - */ - private void handleDeleteGuild(Player player) { - // 检查权限(只有会长可以删除工会) - GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开确认删除GUI - plugin.getGuiManager().openGUI(player, new ConfirmDeleteGuildGUI(plugin, guild)); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.CompatibleScheduler; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Ustawień Gildii + */ +public class GuildSettingsGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + + public GuildSettingsGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.title", "&6Ustawienia gildii - {guild_name}") + .replace("{guild_name}", guild.getName() != null ? guild.getName() : "Nieznana gildia")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("guild-settings.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Dodaj przyciski ustawień + setupSettingsButtons(inventory); + + // Wyświetl aktualne ustawienia + displayCurrentSettings(inventory); + + // Dodaj przyciski funkcji + setupFunctionButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 10: // Zmień nazwę + handleChangeName(player); + break; + case 11: // Zmień opis + handleChangeDescription(player); + break; + case 12: // Zmień tag + handleChangeTag(player); + break; + case 14: // Ustaw dom gildii + handleSetHome(player); + break; + case 16: // Ustawienia uprawnień + handlePermissions(player); + break; + case 20: // Zaproś członka + handleInviteMember(player); + break; + case 22: // Wyrzuć członka + handleKickMember(player); + break; + case 24: // Awansuj członka + handlePromoteMember(player); + break; + case 26: // Zdegraduj członka + handleDemoteMember(player); + break; + case 30: // Zarządzanie aplikacjami + handleApplications(player); + break; + case 31: // Zarządzanie relacjami + handleRelations(player); + break; + case 32: // Logi gildii + handleGuildLogs(player); + break; + case 33: // Teleport do domu gildii + handleHomeTeleport(player); + break; + case 34: // Opuść gildię + handleLeaveGuild(player); + break; + case 36: // Usuń gildię + handleDeleteGuild(player); + break; + case 49: // Powrót + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Skonfiguruj przyciski ustawień + */ + private void setupSettingsButtons(Inventory inventory) { + // Przycisk zmiany nazwy + ItemStack changeName = createItem( + Material.NAME_TAG, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-name.name", "&eZmień nazwę")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-name.lore.1", "&7Zmień nazwę gildii")) + ); + inventory.setItem(10, changeName); + + // Przycisk zmiany opisu + ItemStack changeDescription = createItem( + Material.BOOK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-description.name", "&eZmień opis")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-description.lore.1", "&7Zmień opis gildii")) + ); + inventory.setItem(11, changeDescription); + + // Przycisk zmiany tagu + ItemStack changeTag = createItem( + Material.OAK_SIGN, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-tag.name", "&eZmień tag")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.change-tag.lore.1", "&7Zmień tag gildii")) + ); + inventory.setItem(12, changeTag); + + // Przycisk ustawienia domu gildii + ItemStack setHome = createItem( + Material.COMPASS, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.set-home.name", "&eUstaw dom gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.set-home.lore.1", "&7Ustaw punkt teleportacji gildii")) + ); + inventory.setItem(14, setHome); + + // Przycisk ustawień uprawnień + ItemStack permissions = createItem( + Material.SHIELD, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.permissions.name", "&eUstawienia uprawnień")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.permissions.lore.1", "&7Zarządzaj uprawnieniami członków")) + ); + inventory.setItem(16, permissions); + } + + /** + * Skonfiguruj przyciski funkcji + */ + private void setupFunctionButtons(Inventory inventory) { + // Przycisk zaproszenia członka + ItemStack inviteMember = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.invite-member", "&aZaproś członka")), + ColorUtils.colorize("&7Zaproś nowego członka do gildii") + ); + inventory.setItem(20, inviteMember); + + // Przycisk wyrzucenia członka + ItemStack kickMember = createItem( + Material.REDSTONE, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.kick-member", "&cWyrzuć członka")), + ColorUtils.colorize("&7Wyrzuć członka z gildii") + ); + inventory.setItem(22, kickMember); + + // Przycisk awansu członka + ItemStack promoteMember = createItem( + Material.GOLD_INGOT, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.promote-member", "&6Awansuj członka")), + ColorUtils.colorize("&7Awansuj członka na wyższą rangę") + ); + inventory.setItem(24, promoteMember); + + // Przycisk degradacji członka + ItemStack demoteMember = createItem( + Material.IRON_INGOT, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.demote-member", "&7Zdegraduj członka")), + ColorUtils.colorize("&7Zdegraduj członka na niższą rangę") + ); + inventory.setItem(26, demoteMember); + + // Przycisk zarządzania aplikacjami + ItemStack applications = createItem( + Material.PAPER, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.application-management", "&eZarządzanie aplikacjami")), + ColorUtils.colorize("&7Rozpatrz prośby o dołączenie") + ); + inventory.setItem(30, applications); + + // Przycisk zarządzania relacjami + ItemStack relations = createItem( + Material.RED_WOOL, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations-management.name", "&eZarządzanie relacjami")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations-management.lore.1", "&7Zarządzaj relacjami gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-relations-management.lore.2", "&7Sojusznicy, wrogowie, itp.")) + ); + inventory.setItem(31, relations); + + // Przycisk logów gildii + ItemStack guildLogs = createItem( + Material.BOOK, + ColorUtils.colorize("&6Logi gildii"), + ColorUtils.colorize("&7Zobacz historię operacji gildii"), + ColorUtils.colorize("&7Rejestr wszystkich ważnych działań") + ); + inventory.setItem(32, guildLogs); + + // Przycisk teleportacji do domu gildii + ItemStack homeTeleport = createItem( + Material.ENDER_PEARL, + ColorUtils.colorize("&bTeleport do domu gildii"), + ColorUtils.colorize("&7Przenieś się do ustawionego domu gildii") + ); + inventory.setItem(33, homeTeleport); + + // Przycisk opuszczenia gildii + ItemStack leaveGuild = createItem( + Material.BARRIER, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.leave-guild", "&cOpuść gildię")), + ColorUtils.colorize("&7Opuść obecną gildię") + ); + inventory.setItem(34, leaveGuild); + + // Przycisk usunięcia gildii + ItemStack deleteGuild = createItem( + Material.TNT, + ColorUtils.colorize(plugin.getConfigManager().getMessagesConfig().getString("gui.delete-guild", "&4Usuń gildię")), + ColorUtils.colorize("&7Usuń całą gildię"), + ColorUtils.colorize("&cTej operacji nie można cofnąć!") + ); + inventory.setItem(36, deleteGuild); + + // Przycisk powrotu + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.back.name", "&7Powrót")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("guild-settings.items.back.lore.1", "&7Powrót do menu głównego")) + ); + inventory.setItem(49, back); + } + + /** + * Wyświetl aktualne ustawienia + */ + private void displayCurrentSettings(Inventory inventory) { + // Aktualna nazwa + ItemStack currentName = createItem( + Material.NAME_TAG, + ColorUtils.colorize("&eObecna nazwa"), + ColorUtils.colorize("&7" + (guild.getName() != null ? guild.getName() : "Brak nazwy")) + ); + inventory.setItem(10, currentName); + + // Aktualny opis + ItemStack currentDescription = createItem( + Material.BOOK, + ColorUtils.colorize("&eObecny opis"), + ColorUtils.colorize("&7" + (guild.getDescription() != null ? guild.getDescription() : "Brak opisu")) + ); + inventory.setItem(11, currentDescription); + + // Aktualny tag + ItemStack currentTag = createItem( + Material.OAK_SIGN, + ColorUtils.colorize("&eObecny tag"), + ColorUtils.colorize("&7" + (guild.getTag() != null ? "[" + guild.getTag() + "]" : "Brak tagu")) + ); + inventory.setItem(13, currentTag); + + // Status domu gildii + String homeStatus = guild.hasHome() ? "&aUstawiony" : "&cNieustawiony"; + ItemStack currentHome = createItem( + Material.COMPASS, + ColorUtils.colorize("&eStatus domu gildii"), + ColorUtils.colorize("&7Status: " + homeStatus) + ); + inventory.setItem(15, currentHome); + + // Aktualne ustawienia uprawnień + ItemStack currentPermissions = createItem( + Material.SHIELD, + ColorUtils.colorize("&eObecne uprawnienia"), + ColorUtils.colorize("&7Lider: Wszystkie uprawnienia"), + ColorUtils.colorize("&7Oficer: Zapraszanie, Wyrzucanie"), + ColorUtils.colorize("&7Członek: Podstawowe uprawnienia") + ); + inventory.setItem(17, currentPermissions); + } + + /** + * Obsługa zmiany nazwy + */ + private void handleChangeName(Player player) { + // Sprawdź uprawnienia (tylko lider może zmienić nazwę) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI wprowadzania nazwy + plugin.getGuiManager().openGUI(player, new GuildNameInputGUI(plugin, guild, player)); + } + + /** + * Obsługa zmiany opisu + */ + private void handleChangeDescription(Player player) { + // Sprawdź uprawnienia (tylko lider może zmienić opis) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI wprowadzania opisu + plugin.getGuiManager().openGUI(player, new GuildDescriptionInputGUI(plugin, guild)); + } + + /** + * Obsługa zmiany tagu + */ + private void handleChangeTag(Player player) { + // Sprawdź uprawnienia (tylko lider może zmienić tag) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI wprowadzania tagu + plugin.getGuiManager().openGUI(player, new GuildTagInputGUI(plugin, guild)); + } + + /** + * Obsługa ustawienia domu gildii + */ + private void handleSetHome(Player player) { + // Sprawdź uprawnienia (tylko lider może ustawić dom) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Ustaw dom gildii + plugin.getGuildService().setGuildHomeAsync(guild.getId(), player.getLocation(), player.getUniqueId()).thenAccept(success -> { + if (success) { + String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.success", "&aDom gildii został ustawiony pomyślnie!"); + player.sendMessage(ColorUtils.colorize(message)); + + // Odśwież GUI + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("sethome.failed", "&cUstawienie domu gildii nie powiodło się!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Obsługa ustawień uprawnień + */ + private void handlePermissions(Player player) { + // Sprawdź uprawnienia (tylko lider może zarządzać uprawnieniami) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI ustawień uprawnień + plugin.getGuiManager().openGUI(player, new GuildPermissionsGUI(plugin, guild)); + } + + /** + * Obsługa zapraszania członka + */ + private void handleInviteMember(Player player) { + // Sprawdź uprawnienia (oficer lub lider może zapraszać) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.officer-or-higher", "&cWymagana ranga Oficera lub wyższa"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI zapraszania członka + plugin.getGuiManager().openGUI(player, new InviteMemberGUI(plugin, guild)); + } + + /** + * Obsługa wyrzucania członka + */ + private void handleKickMember(Player player) { + // Sprawdź uprawnienia (oficer lub lider może wyrzucać) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.officer-or-higher", "&cWymagana ranga Oficera lub wyższa"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI wyrzucania członka + plugin.getGuiManager().openGUI(player, new KickMemberGUI(plugin, guild)); + } + + /** + * Obsługa awansowania członka + */ + private void handlePromoteMember(Player player) { + // Sprawdź uprawnienia (tylko lider może awansować) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI awansowania członka + plugin.getGuiManager().openGUI(player, new PromoteMemberGUI(plugin, guild)); + } + + /** + * Obsługa degradowania członka + */ + private void handleDemoteMember(Player player) { + // Sprawdź uprawnienia (tylko lider może degradować) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI degradowania członka + plugin.getGuiManager().openGUI(player, new DemoteMemberGUI(plugin, guild)); + } + + /** + * Obsługa zarządzania aplikacjami + */ + private void handleApplications(Player player) { + // Sprawdź uprawnienia (oficer lub lider może zarządzać aplikacjami) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.officer-or-higher", "&cWymagana ranga Oficera lub wyższa"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI zarządzania aplikacjami + plugin.getGuiManager().openGUI(player, new ApplicationManagementGUI(plugin, guild)); + } + + /** + * Obsługa zarządzania relacjami + */ + private void handleRelations(Player player) { + // Sprawdź uprawnienia (tylko lider może zarządzać relacjami) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relation.only-leader", "&cTylko lider gildii może zarządzać relacjami gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI zarządzania relacjami + plugin.getGuiManager().openGUI(player, new GuildRelationsGUI(plugin, guild, player)); + } + + /** + * Obsługa przeglądania logów gildii + */ + private void handleGuildLogs(Player player) { + // Sprawdź uprawnienia (członkowie gildii mogą przeglądać logi) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI logów gildii + plugin.getGuiManager().openGUI(player, new GuildLogsGUI(plugin, guild, player)); + } + + /** + * Obsługa teleportacji do domu gildii + */ + private void handleHomeTeleport(Player player) { + // Sprawdź uprawnienia (członkowie gildii mogą teleportować się do domu) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Teleport do domu gildii + plugin.getGuildService().getGuildHomeAsync(guild.getId()).thenAccept(location -> { + // Upewnij się, że teleportacja odbywa się w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (location != null) { + player.teleport(location); + String message = plugin.getConfigManager().getMessagesConfig().getString("home.success", "&aPrzeteleportowano do domu gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("home.not-set", "&cDom gildii nie jest ustawiony!"); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Obsługa opuszczenia gildii + */ + private void handleLeaveGuild(Player player) { + // Otwórz GUI potwierdzenia opuszczenia + plugin.getGuiManager().openGUI(player, new ConfirmLeaveGuildGUI(plugin, guild)); + } + + /** + * Obsługa usunięcia gildii + */ + private void handleDeleteGuild(Player player) { + // Sprawdź uprawnienia (tylko lider może usunąć gildię) + GuildMember member = plugin.getGuildService().getGuildMember(player.getUniqueId()); + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI potwierdzenia usunięcia + plugin.getGuiManager().openGUI(player, new ConfirmDeleteGuildGUI(plugin, guild)); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/GuildTagInputGUI.java b/src/main/java/com/guild/gui/GuildTagInputGUI.java index 265e7a6..07a1a9c 100644 --- a/src/main/java/com/guild/gui/GuildTagInputGUI.java +++ b/src/main/java/com/guild/gui/GuildTagInputGUI.java @@ -1,190 +1,190 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -/** - * 工会标签输入GUI - */ -public class GuildTagInputGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private String currentTag; - - public GuildTagInputGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - this.currentTag = guild.getTag() != null ? guild.getTag() : ""; - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6修改工会标签"); - } - - @Override - public int getSize() { - return 27; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示当前标签 - displayCurrentTag(inventory); - - // 添加操作按钮 - setupButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 11: // 输入标签 - handleInputTag(player); - break; - case 15: // 确认 - handleConfirm(player); - break; - case 13: // 取消 - handleCancel(player); - break; - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 18, border); - } - for (int i = 9; i < 18; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示当前标签 - */ - private void displayCurrentTag(Inventory inventory) { - ItemStack currentTagItem = createItem( - Material.OAK_SIGN, - ColorUtils.colorize("&e当前标签"), - ColorUtils.colorize("&7" + (currentTag.isEmpty() ? "无标签" : "[" + currentTag + "]")) - ); - inventory.setItem(11, currentTagItem); - } - - /** - * 设置按钮 - */ - private void setupButtons(Inventory inventory) { - // 确认按钮 - ItemStack confirm = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize("&a确认修改"), - ColorUtils.colorize("&7确认修改工会标签") - ); - inventory.setItem(15, confirm); - - // 取消按钮 - ItemStack cancel = createItem( - Material.REDSTONE_BLOCK, - ColorUtils.colorize("&c取消"), - ColorUtils.colorize("&7取消修改") - ); - inventory.setItem(13, cancel); - } - - /** - * 处理输入标签 - */ - private void handleInputTag(Player player) { - // 关闭GUI - player.closeInventory(); - - // 发送消息提示输入 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-tag", "&a请在聊天框中输入新的工会标签(最多10字符):"); - player.sendMessage(ColorUtils.colorize(message)); - - // 设置玩家为输入模式 - plugin.getGuiManager().setInputMode(player, input -> { - if (input.length() > 10) { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-too-long", "&c标签过长,最多10字符!"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - return false; - } - - // 更新标签 - currentTag = input; - - // 保存到数据库 - plugin.getGuildService().updateGuildAsync(guild.getId(), guild.getName(), input, guild.getDescription(), player.getUniqueId()).thenAccept(success -> { - if (success) { - String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-updated", "&a工会标签已更新!"); - player.sendMessage(ColorUtils.colorize(successMessage)); - - // 安全刷新GUI - plugin.getGuiManager().refreshGUI(player); - } else { - String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-update-failed", "&c工会标签更新失败!"); - player.sendMessage(ColorUtils.colorize(errorMessage)); - } - }); - - return true; - }); - } - - /** - * 处理确认 - */ - private void handleConfirm(Player player) { - // 返回工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 处理取消 - */ - private void handleCancel(Player player) { - // 返回工会设置GUI - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Wprowadzania Tagu Gildii + */ +public class GuildTagInputGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private String currentTag; + + public GuildTagInputGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + this.currentTag = guild.getTag() != null ? guild.getTag() : ""; + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Zmień tag gildii"); + } + + @Override + public int getSize() { + return 27; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl obecny tag + displayCurrentTag(inventory); + + // Dodaj przyciski akcji + setupButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 11: // Wprowadź tag + handleInputTag(player); + break; + case 15: // Potwierdź + handleConfirm(player); + break; + case 13: // Anuluj + handleCancel(player); + break; + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 18, border); + } + for (int i = 9; i < 18; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl obecny tag + */ + private void displayCurrentTag(Inventory inventory) { + ItemStack currentTagItem = createItem( + Material.OAK_SIGN, + ColorUtils.colorize("&eObecny tag"), + ColorUtils.colorize("&7" + (currentTag.isEmpty() ? "Brak tagu" : "[" + currentTag + "]")) + ); + inventory.setItem(11, currentTagItem); + } + + /** + * Skonfiguruj przyciski + */ + private void setupButtons(Inventory inventory) { + // Przycisk potwierdzenia + ItemStack confirm = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize("&aZatwierdź zmianę"), + ColorUtils.colorize("&7Zatwierdź zmianę tagu gildii") + ); + inventory.setItem(15, confirm); + + // Przycisk anulowania + ItemStack cancel = createItem( + Material.REDSTONE_BLOCK, + ColorUtils.colorize("&cAnuluj"), + ColorUtils.colorize("&7Anuluj zmianę") + ); + inventory.setItem(13, cancel); + } + + /** + * Obsługa wprowadzania tagu + */ + private void handleInputTag(Player player) { + // Zamknij GUI + player.closeInventory(); + + // Wyślij wiadomość z prośbą o wprowadzenie + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.input-tag", "&aProszę wpisać nowy tag gildii na czacie (maksymalnie 10 znaków):"); + player.sendMessage(ColorUtils.colorize(message)); + + // Ustaw tryb wprowadzania dla gracza + plugin.getGuiManager().setInputMode(player, input -> { + if (input.length() > 10) { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-too-long", "&cTag jest za długi, maksymalnie 10 znaków!"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + return false; + } + + // Zaktualizuj tag + currentTag = input; + + // Zapisz w bazie danych + plugin.getGuildService().updateGuildAsync(guild.getId(), guild.getName(), input, guild.getDescription(), player.getUniqueId()).thenAccept(success -> { + if (success) { + String successMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-updated", "&aTag gildii został zaktualizowany!"); + player.sendMessage(ColorUtils.colorize(successMessage)); + + // Bezpieczne odświeżenie GUI + plugin.getGuiManager().refreshGUI(player); + } else { + String errorMessage = plugin.getConfigManager().getMessagesConfig().getString("gui.tag-update-failed", "&cAktualizacja tagu gildii nie powiodła się!"); + player.sendMessage(ColorUtils.colorize(errorMessage)); + } + }); + + return true; + }); + } + + /** + * Obsługa potwierdzenia + */ + private void handleConfirm(Player player) { + // Powrót do GUI ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Obsługa anulowania + */ + private void handleCancel(Player player) { + // Powrót do GUI ustawień gildii + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/InviteMemberGUI.java b/src/main/java/com/guild/gui/InviteMemberGUI.java index 0c7ab4e..9a5756d 100644 --- a/src/main/java/com/guild/gui/InviteMemberGUI.java +++ b/src/main/java/com/guild/gui/InviteMemberGUI.java @@ -1,221 +1,227 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -/** - * 邀请成员GUI - */ -public class InviteMemberGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private int currentPage = 0; - private List onlinePlayers; - - public InviteMemberGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - this.onlinePlayers = Bukkit.getOnlinePlayers().stream() - .filter(player -> !player.getUniqueId().equals(guild.getLeaderUuid())) - .collect(java.util.stream.Collectors.toList()); - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6邀请成员 - 第" + (currentPage + 1) + "页"); - } - - @Override - public int getSize() { - return 54; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示在线玩家 - displayOnlinePlayers(inventory); - - // 添加导航按钮 - setupNavigationButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (slot >= 9 && slot < 45) { - // 玩家头像区域 - int playerIndex = slot - 9 + (currentPage * 36); - if (playerIndex < onlinePlayers.size()) { - Player targetPlayer = onlinePlayers.get(playerIndex); - handleInvitePlayer(player, targetPlayer); - } - } else if (slot == 45) { - // 上一页 - if (currentPage > 0) { - currentPage--; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 53) { - // 下一页 - int maxPage = (onlinePlayers.size() - 1) / 36; - if (currentPage < maxPage) { - currentPage++; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 49) { - // 返回 - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示在线玩家 - */ - private void displayOnlinePlayers(Inventory inventory) { - int startIndex = currentPage * 36; - int endIndex = Math.min(startIndex + 36, onlinePlayers.size()); - - for (int i = startIndex; i < endIndex; i++) { - Player targetPlayer = onlinePlayers.get(i); - int slot = 9 + (i - startIndex); - - ItemStack playerHead = createPlayerHead(targetPlayer); - inventory.setItem(slot, playerHead); - } - } - - /** - * 设置导航按钮 - */ - private void setupNavigationButtons(Inventory inventory) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack prevPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e上一页"), - ColorUtils.colorize("&7点击查看上一页") - ); - inventory.setItem(45, prevPage); - } - - // 下一页按钮 - int maxPage = (onlinePlayers.size() - 1) / 36; - if (currentPage < maxPage) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e下一页"), - ColorUtils.colorize("&7点击查看下一页") - ); - inventory.setItem(53, nextPage); - } - - // 返回按钮 - ItemStack back = createItem( - Material.BARRIER, - ColorUtils.colorize("&c返回"), - ColorUtils.colorize("&7返回工会设置") - ); - inventory.setItem(49, back); - } - - /** - * 创建玩家头像 - */ - private ItemStack createPlayerHead(Player player) { - ItemStack head = new ItemStack(Material.PLAYER_HEAD); - SkullMeta meta = (SkullMeta) head.getItemMeta(); - - if (meta != null) { - meta.setOwningPlayer(player); - meta.setDisplayName(ColorUtils.colorize("&a" + player.getName())); - meta.setLore(Arrays.asList( - ColorUtils.colorize("&7点击邀请该玩家"), - ColorUtils.colorize("&7加入工会") - )); - head.setItemMeta(meta); - } - - return head; - } - - /** - * 处理邀请玩家 - */ - private void handleInvitePlayer(Player inviter, Player target) { - // 检查目标玩家是否已经在工会中 - plugin.getGuildService().getGuildMemberAsync(target.getUniqueId()).thenAccept(member -> { - if (member != null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.already-in-guild", "&c该玩家已经在工会中!"); - inviter.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 发送邀请 - plugin.getGuildService().sendInvitationAsync(guild.getId(), inviter.getUniqueId(), inviter.getName(), target.getUniqueId(), target.getName()).thenAccept(success -> { - if (success) { - String inviterMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.sent", "&a已向 &e{player} &a发送邀请!") - .replace("{player}", target.getName()); - inviter.sendMessage(ColorUtils.colorize(inviterMessage)); - - String targetMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.received", "&a你收到了来自工会 &e{guild} &a的邀请!") - .replace("{guild}", guild.getName()); - target.sendMessage(ColorUtils.colorize(targetMessage)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("invite.failed", "&c邀请发送失败!"); - inviter.sendMessage(ColorUtils.colorize(message)); - } - }); - }); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Zapraszania Członków + */ +public class InviteMemberGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private int currentPage = 0; + private List onlinePlayers; + + public InviteMemberGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + // Filtruj graczy online, którzy nie są liderem tej gildii (wstępny filtr) + // W rzeczywistości powinniśmy filtrować graczy, którzy już są w tej gildii, + // ale zrobimy to przy wyświetlaniu lub obsłudze kliknięcia, aby nie obciążać konstruktora asynchronicznością + this.onlinePlayers = Bukkit.getOnlinePlayers().stream() + .filter(player -> !player.getUniqueId().equals(guild.getLeaderUuid())) + .collect(java.util.stream.Collectors.toList()); + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Zaproś członka - Strona " + (currentPage + 1)); + } + + @Override + public int getSize() { + return 54; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl graczy online + displayOnlinePlayers(inventory); + + // Dodaj przyciski nawigacyjne + setupNavigationButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (slot >= 9 && slot < 45) { + // Obszar głów graczy + int playerIndex = slot - 9 + (currentPage * 36); + if (playerIndex < onlinePlayers.size()) { + Player targetPlayer = onlinePlayers.get(playerIndex); + handleInvitePlayer(player, targetPlayer); + } + } else if (slot == 45) { + // Poprzednia strona + if (currentPage > 0) { + currentPage--; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 53) { + // Następna strona + int maxPage = (onlinePlayers.size() - 1) / 36; + if (currentPage < maxPage) { + currentPage++; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 49) { + // Powrót + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl graczy online + */ + private void displayOnlinePlayers(Inventory inventory) { + int startIndex = currentPage * 36; + int endIndex = Math.min(startIndex + 36, onlinePlayers.size()); + + for (int i = startIndex; i < endIndex; i++) { + Player targetPlayer = onlinePlayers.get(i); + int slot = 9 + (i - startIndex); + + ItemStack playerHead = createPlayerHead(targetPlayer); + inventory.setItem(slot, playerHead); + } + } + + /** + * Skonfiguruj przyciski nawigacyjne + */ + private void setupNavigationButtons(Inventory inventory) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack prevPage = createItem( + Material.ARROW, + ColorUtils.colorize("&ePoprzednia strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć poprzednią stronę") + ); + inventory.setItem(45, prevPage); + } + + // Przycisk następnej strony + int maxPage = (onlinePlayers.size() - 1) / 36; + if (currentPage < maxPage) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize("&eNastępna strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć następną stronę") + ); + inventory.setItem(53, nextPage); + } + + // Przycisk powrotu + ItemStack back = createItem( + Material.BARRIER, + ColorUtils.colorize("&cPowrót"), + ColorUtils.colorize("&7Powrót do ustawień gildii") + ); + inventory.setItem(49, back); + } + + /** + * Utwórz głowę gracza + */ + private ItemStack createPlayerHead(Player player) { + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) head.getItemMeta(); + + if (meta != null) { + meta.setOwningPlayer(player); + meta.setDisplayName(ColorUtils.colorize("&a" + player.getName())); + meta.setLore(Arrays.asList( + ColorUtils.colorize("&7Kliknij, aby zaprosić tego gracza"), + ColorUtils.colorize("&7do gildii") + )); + head.setItemMeta(meta); + } + + return head; + } + + /** + * Obsługa zaproszenia gracza + */ + private void handleInvitePlayer(Player inviter, Player target) { + // Sprawdź czy gracz już jest w gildii (dowolnej) + // W oryginale było: plugin.getGuildService().getGuildMemberAsync(target.getUniqueId())... + // Powinniśmy sprawdzić czy gracz jest w JAKIEJKOLWIEK gildii. + // Metoda getPlayerGuildAsync może być lepsza. + plugin.getGuildService().getPlayerGuildAsync(target.getUniqueId()).thenAccept(targetGuild -> { + if (targetGuild != null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.already-in-guild", "&cTen gracz jest już w gildii!"); + inviter.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wyślij zaproszenie + plugin.getGuildService().sendInvitationAsync(guild.getId(), inviter.getUniqueId(), inviter.getName(), target.getUniqueId(), target.getName()).thenAccept(success -> { + if (success) { + String inviterMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.sent", "&aWysłano zaproszenie do gracza &e{player}&a!") + .replace("{player}", target.getName()); + inviter.sendMessage(ColorUtils.colorize(inviterMessage)); + + String targetMessage = plugin.getConfigManager().getMessagesConfig().getString("invite.received", "&aOtrzymałeś zaproszenie do gildii &e{guild}&a!") + .replace("{guild}", guild.getName()); + target.sendMessage(ColorUtils.colorize(targetMessage)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("invite.failed", "&cWysłanie zaproszenia nie powiodło się! Gracz może mieć już aktywne zaproszenie."); + inviter.sendMessage(ColorUtils.colorize(message)); + } + }); + }); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/KickMemberGUI.java b/src/main/java/com/guild/gui/KickMemberGUI.java index 674744e..547876e 100644 --- a/src/main/java/com/guild/gui/KickMemberGUI.java +++ b/src/main/java/com/guild/gui/KickMemberGUI.java @@ -1,233 +1,233 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 踢出成员GUI - */ -public class KickMemberGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private int currentPage = 0; - private List members; - - public KickMemberGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - // 初始化时获取成员列表 - this.members = List.of(); - loadMembers(); - } - - private void loadMembers() { - plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(memberList -> { - this.members = memberList.stream() - .filter(member -> !member.getPlayerUuid().equals(guild.getLeaderUuid())) - .collect(java.util.stream.Collectors.toList()); - }); - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6踢出成员 - 第" + (currentPage + 1) + "页"); - } - - @Override - public int getSize() { - return 54; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示成员列表 - displayMembers(inventory); - - // 添加导航按钮 - setupNavigationButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (slot >= 9 && slot < 45) { - // 成员头像区域 - int memberIndex = slot - 9 + (currentPage * 36); - if (memberIndex < members.size()) { - GuildMember member = members.get(memberIndex); - handleKickMember(player, member); - } - } else if (slot == 45) { - // 上一页 - if (currentPage > 0) { - currentPage--; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 53) { - // 下一页 - int maxPage = (members.size() - 1) / 36; - if (currentPage < maxPage) { - currentPage++; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 49) { - // 返回 - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示成员列表 - */ - private void displayMembers(Inventory inventory) { - int startIndex = currentPage * 36; - int endIndex = Math.min(startIndex + 36, members.size()); - - for (int i = startIndex; i < endIndex; i++) { - GuildMember member = members.get(i); - int slot = 9 + (i - startIndex); - - ItemStack memberHead = createMemberHead(member); - inventory.setItem(slot, memberHead); - } - } - - /** - * 设置导航按钮 - */ - private void setupNavigationButtons(Inventory inventory) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack prevPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e上一页"), - ColorUtils.colorize("&7点击查看上一页") - ); - inventory.setItem(45, prevPage); - } - - // 下一页按钮 - int maxPage = (members.size() - 1) / 36; - if (currentPage < maxPage) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e下一页"), - ColorUtils.colorize("&7点击查看下一页") - ); - inventory.setItem(53, nextPage); - } - - // 返回按钮 - ItemStack back = createItem( - Material.BARRIER, - ColorUtils.colorize("&c返回"), - ColorUtils.colorize("&7返回工会设置") - ); - inventory.setItem(49, back); - } - - /** - * 创建成员头像 - */ - private ItemStack createMemberHead(GuildMember member) { - ItemStack head = new ItemStack(Material.PLAYER_HEAD); - SkullMeta meta = (SkullMeta) head.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(ColorUtils.colorize("&c" + member.getPlayerName())); - meta.setLore(Arrays.asList( - ColorUtils.colorize("&7职位: &e" + member.getRole().getDisplayName()), - ColorUtils.colorize("&7加入时间: &e" + member.getJoinedAt()), - ColorUtils.colorize("&c点击踢出该成员") - )); - head.setItemMeta(meta); - } - - return head; - } - - /** - * 处理踢出成员 - */ - private void handleKickMember(Player kicker, GuildMember member) { - // 检查权限 - if (!kicker.hasPermission("guild.kick")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - kicker.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 踢出成员 - plugin.getGuildService().removeGuildMemberAsync(member.getPlayerUuid(), kicker.getUniqueId()).thenAccept(success -> { - if (success) { - String kickerMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.success", "&a已踢出成员 &e{player} &a!") - .replace("{player}", member.getPlayerName()); - kicker.sendMessage(ColorUtils.colorize(kickerMessage)); - - // 通知被踢出的玩家 - Player kickedPlayer = plugin.getServer().getPlayer(member.getPlayerUuid()); - if (kickedPlayer != null) { - String kickedMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.kicked", "&c你被踢出了工会 &e{guild} &c!") - .replace("{guild}", guild.getName()); - kickedPlayer.sendMessage(ColorUtils.colorize(kickedMessage)); - } - - // 刷新GUI - plugin.getGuiManager().openGUI(kicker, new KickMemberGUI(plugin, guild)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("kick.failed", "&c踢出成员失败!"); - kicker.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Wyrzucania Członków + */ +public class KickMemberGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private int currentPage = 0; + private List members; + + public KickMemberGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + // Inicjalizacja listy członków + this.members = List.of(); + loadMembers(); + } + + private void loadMembers() { + plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(memberList -> { + this.members = memberList.stream() + .filter(member -> !member.getPlayerUuid().equals(guild.getLeaderUuid())) + .collect(java.util.stream.Collectors.toList()); + }); + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Wyrzuć członka - Strona " + (currentPage + 1)); + } + + @Override + public int getSize() { + return 54; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl listę członków + displayMembers(inventory); + + // Dodaj przyciski nawigacyjne + setupNavigationButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (slot >= 9 && slot < 45) { + // Obszar głów członków + int memberIndex = slot - 9 + (currentPage * 36); + if (memberIndex < members.size()) { + GuildMember member = members.get(memberIndex); + handleKickMember(player, member); + } + } else if (slot == 45) { + // Poprzednia strona + if (currentPage > 0) { + currentPage--; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 53) { + // Następna strona + int maxPage = (members.size() - 1) / 36; + if (currentPage < maxPage) { + currentPage++; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 49) { + // Powrót + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl listę członków + */ + private void displayMembers(Inventory inventory) { + int startIndex = currentPage * 36; + int endIndex = Math.min(startIndex + 36, members.size()); + + for (int i = startIndex; i < endIndex; i++) { + GuildMember member = members.get(i); + int slot = 9 + (i - startIndex); + + ItemStack memberHead = createMemberHead(member); + inventory.setItem(slot, memberHead); + } + } + + /** + * Skonfiguruj przyciski nawigacyjne + */ + private void setupNavigationButtons(Inventory inventory) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack prevPage = createItem( + Material.ARROW, + ColorUtils.colorize("&ePoprzednia strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć poprzednią stronę") + ); + inventory.setItem(45, prevPage); + } + + // Przycisk następnej strony + int maxPage = (members.size() - 1) / 36; + if (currentPage < maxPage) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize("&eNastępna strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć następną stronę") + ); + inventory.setItem(53, nextPage); + } + + // Przycisk powrotu + ItemStack back = createItem( + Material.BARRIER, + ColorUtils.colorize("&cPowrót"), + ColorUtils.colorize("&7Powrót do ustawień gildii") + ); + inventory.setItem(49, back); + } + + /** + * Utwórz głowę członka + */ + private ItemStack createMemberHead(GuildMember member) { + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) head.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(ColorUtils.colorize("&c" + member.getPlayerName())); + meta.setLore(Arrays.asList( + ColorUtils.colorize("&7Rola: &e" + member.getRole().getDisplayName()), + ColorUtils.colorize("&7Dołączył: &e" + member.getJoinedAt()), + ColorUtils.colorize("&cKliknij, aby wyrzucić tego członka") + )); + head.setItemMeta(meta); + } + + return head; + } + + /** + * Obsługa wyrzucenia członka + */ + private void handleKickMember(Player kicker, GuildMember member) { + // Sprawdź uprawnienia + if (!kicker.hasPermission("guild.kick")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + kicker.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Wyrzuć członka + plugin.getGuildService().removeGuildMemberAsync(member.getPlayerUuid(), kicker.getUniqueId()).thenAccept(success -> { + if (success) { + String kickerMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.success", "&aWyrzucono członka &e{player}&a!") + .replace("{player}", member.getPlayerName()); + kicker.sendMessage(ColorUtils.colorize(kickerMessage)); + + // Powiadom wyrzuconego gracza + Player kickedPlayer = plugin.getServer().getPlayer(member.getPlayerUuid()); + if (kickedPlayer != null) { + String kickedMessage = plugin.getConfigManager().getMessagesConfig().getString("kick.kicked", "&cZostałeś wyrzucony z gildii &e{guild}&c!") + .replace("{guild}", guild.getName()); + kickedPlayer.sendMessage(ColorUtils.colorize(kickedMessage)); + } + + // Odśwież GUI + plugin.getGuiManager().openGUI(kicker, new KickMemberGUI(plugin, guild)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("kick.failed", "&cWyrzucenie członka nie powiodło się!"); + kicker.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/MainGuildGUI.java b/src/main/java/com/guild/gui/MainGuildGUI.java index f99ceef..88f507b 100644 --- a/src/main/java/com/guild/gui/MainGuildGUI.java +++ b/src/main/java/com/guild/gui/MainGuildGUI.java @@ -1,340 +1,340 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.gui.GUIManager; -import com.guild.core.utils.ColorUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.concurrent.CompletableFuture; - -import com.guild.core.utils.CompatibleScheduler; - -/** - * 主工会GUI - 六个主要入口 - */ -public class MainGuildGUI implements GUI { - - private final GuildPlugin plugin; - - public MainGuildGUI(GuildPlugin plugin) { - this.plugin = plugin; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.title", "&6工会系统")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("main-menu.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 工会信息按钮 - ItemStack guildInfo = createItem( - Material.BOOK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-info.name", "&e工会信息")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-info.lore.1", "&7查看工会详细信息")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-info.lore.2", "&7包括基本信息、统计等")) - ); - inventory.setItem(20, guildInfo); - - // 成员管理按钮 - ItemStack memberManagement = createItem( - Material.PLAYER_HEAD, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.member-management.name", "&e成员管理")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.member-management.lore.1", "&7管理工会成员")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.member-management.lore.2", "&7邀请、踢出、权限管理")) - ); - inventory.setItem(22, memberManagement); - - // 申请管理按钮 - ItemStack applicationManagement = createItem( - Material.PAPER, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.application-management.name", "&e申请管理")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.application-management.lore.1", "&7处理加入申请")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.application-management.lore.2", "&7查看申请历史")) - ); - inventory.setItem(24, applicationManagement); - - // 工会设置按钮 - ItemStack guildSettings = createItem( - Material.COMPASS, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-settings.name", "&e工会设置")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-settings.lore.1", "&7修改工会设置")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-settings.lore.2", "&7描述、标签、权限等")) - ); - inventory.setItem(29, guildSettings); - - // 工会列表按钮 - ItemStack guildList = createItem( - Material.BOOKSHELF, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-list.name", "&e工会列表")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-list.lore.1", "&7查看所有工会")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-list.lore.2", "&7搜索、筛选功能")) - ); - inventory.setItem(31, guildList); - - // 工会关系按钮 - ItemStack guildRelations = createItem( - Material.RED_WOOL, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-relations.name", "&e工会关系")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-relations.lore.1", "&7管理工会关系")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-relations.lore.2", "&7盟友、敌对、开战等")) - ); - inventory.setItem(33, guildRelations); - - // 创建工会按钮 - ItemStack createGuild = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.create-guild.name", "&a创建工会")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.create-guild.lore.1", "&7创建新的工会")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.create-guild.lore.2", "&7需要消耗金币")) - ); - inventory.setItem(4, createGuild); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - switch (slot) { - case 20: // 工会信息 - openGuildInfoGUI(player); - break; - case 22: // 成员管理 - openMemberManagementGUI(player); - break; - case 24: // 申请管理 - openApplicationManagementGUI(player); - break; - case 29: // 工会设置 - openGuildSettingsGUI(player); - break; - case 31: // 工会列表 - openGuildListGUI(player); - break; - case 33: // 工会关系 - openGuildRelationsGUI(player); - break; - case 4: // 创建工会 - openCreateGuildGUI(player); - break; - } - } - - /** - * 打开工会信息GUI - */ - private void openGuildInfoGUI(Player player) { - // 检查玩家是否有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&c您还没有工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开工会信息GUI - GuildInfoGUI guildInfoGUI = new GuildInfoGUI(plugin, player, guild); - plugin.getGuiManager().openGUI(player, guildInfoGUI); - }); - }); - } - - /** - * 打开成员管理GUI - */ - private void openMemberManagementGUI(Player player) { - // 检查玩家是否有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&c您还没有工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开成员管理GUI - MemberManagementGUI memberManagementGUI = new MemberManagementGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, memberManagementGUI); - }); - }); - } - - /** - * 打开申请管理GUI - */ - private void openApplicationManagementGUI(Player player) { - // 检查玩家是否有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&c您还没有工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (member == null || !member.getRole().canInvite()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开申请管理GUI - ApplicationManagementGUI applicationManagementGUI = new ApplicationManagementGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, applicationManagementGUI); - }); - }); - }); - }); - } - - /** - * 打开工会设置GUI - */ - private void openGuildSettingsGUI(Player player) { - // 检查玩家是否有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&c您还没有工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (member == null || member.getRole() != com.guild.models.GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开工会设置GUI - GuildSettingsGUI guildSettingsGUI = new GuildSettingsGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, guildSettingsGUI); - }); - }); - }); - }); - } - - /** - * 打开工会列表GUI - */ - private void openGuildListGUI(Player player) { - // 打开工会列表GUI - GuildListGUI guildListGUI = new GuildListGUI(plugin); - plugin.getGuiManager().openGUI(player, guildListGUI); - } - - /** - * 打开工会关系GUI - */ - private void openGuildRelationsGUI(Player player) { - // 检查玩家是否有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guild == null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&c您还没有工会"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (member == null || member.getRole() != com.guild.models.GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能管理关系"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开工会关系GUI - GuildRelationsGUI guildRelationsGUI = new GuildRelationsGUI(plugin, guild, player); - plugin.getGuiManager().openGUI(player, guildRelationsGUI); - }); - }); - }); - }); - } - - /** - * 打开创建工会GUI - */ - private void openCreateGuildGUI(Player player) { - // 检查玩家是否已有工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - // 确保在主线程中执行GUI操作 - CompatibleScheduler.runTask(plugin, () -> { - if (guild != null) { - String message = plugin.getConfigManager().getMessagesConfig().getString("create.already-in-guild", "&c您已经在一个工会中了!"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开创建工会GUI - CreateGuildGUI createGuildGUI = new CreateGuildGUI(plugin); - plugin.getGuiManager().openGUI(player, createGuildGUI); - }); - }); - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.gui.GUIManager; +import com.guild.core.utils.ColorUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; + +import com.guild.core.utils.CompatibleScheduler; + +/** + * Główne GUI Gildii - Sześć głównych opcji + */ +public class MainGuildGUI implements GUI { + + private final GuildPlugin plugin; + + public MainGuildGUI(GuildPlugin plugin) { + this.plugin = plugin; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.title", "&6System Gildii")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("main-menu.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Przycisk informacji o gildii + ItemStack guildInfo = createItem( + Material.BOOK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-info.name", "&eInformacje o gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-info.lore.1", "&7Zobacz szczegółowe informacje")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-info.lore.2", "&7Zawiera podstawowe dane, statystyki itp.")) + ); + inventory.setItem(20, guildInfo); + + // Przycisk zarządzania członkami + ItemStack memberManagement = createItem( + Material.PLAYER_HEAD, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.member-management.name", "&eZarządzanie członkami")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.member-management.lore.1", "&7Zarządzaj członkami gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.member-management.lore.2", "&7Zapraszaj, wyrzucaj, zarządzaj uprawnieniami")) + ); + inventory.setItem(22, memberManagement); + + // Przycisk zarządzania aplikacjami + ItemStack applicationManagement = createItem( + Material.PAPER, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.application-management.name", "&eZarządzanie aplikacjami")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.application-management.lore.1", "&7Rozpatrz prośby o dołączenie")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.application-management.lore.2", "&7Zobacz historię aplikacji")) + ); + inventory.setItem(24, applicationManagement); + + // Przycisk ustawień gildii + ItemStack guildSettings = createItem( + Material.COMPASS, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-settings.name", "&eUstawienia gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-settings.lore.1", "&7Modyfikuj ustawienia gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-settings.lore.2", "&7Opis, tagi, uprawnienia itp.")) + ); + inventory.setItem(29, guildSettings); + + // Przycisk listy gildii + ItemStack guildList = createItem( + Material.BOOKSHELF, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-list.name", "&eLista gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-list.lore.1", "&7Zobacz wszystkie gildie")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-list.lore.2", "&7Funkcje wyszukiwania i filtrowania")) + ); + inventory.setItem(31, guildList); + + // Przycisk relacji gildii + ItemStack guildRelations = createItem( + Material.RED_WOOL, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-relations.name", "&eRelacje gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-relations.lore.1", "&7Zarządzaj relacjami gildii")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.guild-relations.lore.2", "&7Sojusznicy, wrogowie, wojny itp.")) + ); + inventory.setItem(33, guildRelations); + + // Przycisk tworzenia gildii + ItemStack createGuild = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.create-guild.name", "&aStwórz gildię")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.create-guild.lore.1", "&7Utwórz nową gildię")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("main-menu.items.create-guild.lore.2", "&7Wymaga opłaty w monetach")) + ); + inventory.setItem(4, createGuild); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + switch (slot) { + case 20: // Informacje o gildii + openGuildInfoGUI(player); + break; + case 22: // Zarządzanie członkami + openMemberManagementGUI(player); + break; + case 24: // Zarządzanie aplikacjami + openApplicationManagementGUI(player); + break; + case 29: // Ustawienia gildii + openGuildSettingsGUI(player); + break; + case 31: // Lista gildii + openGuildListGUI(player); + break; + case 33: // Relacje gildii + openGuildRelationsGUI(player); + break; + case 4: // Stwórz gildię + openCreateGuildGUI(player); + break; + } + } + + /** + * Otwórz GUI informacji o gildii + */ + private void openGuildInfoGUI(Player player) { + // Sprawdź czy gracz ma gildię + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&cNie należysz do żadnej gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI informacji o gildii + GuildInfoGUI guildInfoGUI = new GuildInfoGUI(plugin, player, guild); + plugin.getGuiManager().openGUI(player, guildInfoGUI); + }); + }); + } + + /** + * Otwórz GUI zarządzania członkami + */ + private void openMemberManagementGUI(Player player) { + // Sprawdź czy gracz ma gildię + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&cNie należysz do żadnej gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI zarządzania członkami + MemberManagementGUI memberManagementGUI = new MemberManagementGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, memberManagementGUI); + }); + }); + } + + /** + * Otwórz GUI zarządzania aplikacjami + */ + private void openApplicationManagementGUI(Player player) { + // Sprawdź czy gracz ma gildię + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&cNie należysz do żadnej gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (member == null || !member.getRole().canInvite()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI zarządzania aplikacjami + ApplicationManagementGUI applicationManagementGUI = new ApplicationManagementGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, applicationManagementGUI); + }); + }); + }); + }); + } + + /** + * Otwórz GUI ustawień gildii + */ + private void openGuildSettingsGUI(Player player) { + // Sprawdź czy gracz ma gildię + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&cNie należysz do żadnej gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (member == null || member.getRole() != com.guild.models.GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI ustawień gildii + GuildSettingsGUI guildSettingsGUI = new GuildSettingsGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, guildSettingsGUI); + }); + }); + }); + }); + } + + /** + * Otwórz GUI listy gildii + */ + private void openGuildListGUI(Player player) { + // Otwórz GUI listy gildii + GuildListGUI guildListGUI = new GuildListGUI(plugin); + plugin.getGuiManager().openGUI(player, guildListGUI); + } + + /** + * Otwórz GUI relacji gildii + */ + private void openGuildRelationsGUI(Player player) { + // Sprawdź czy gracz ma gildię + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guild == null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-guild", "&cNie należysz do żadnej gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (member == null || member.getRole() != com.guild.models.GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może zarządzać relacjami"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI relacji gildii + GuildRelationsGUI guildRelationsGUI = new GuildRelationsGUI(plugin, guild, player); + plugin.getGuiManager().openGUI(player, guildRelationsGUI); + }); + }); + }); + }); + } + + /** + * Otwórz GUI tworzenia gildii + */ + private void openCreateGuildGUI(Player player) { + // Sprawdź czy gracz już ma gildię + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + // Upewnij się, że operacje GUI są wykonywane w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + if (guild != null) { + String message = plugin.getConfigManager().getMessagesConfig().getString("create.already-in-guild", "&cJesteś już w gildii!"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI tworzenia gildii + CreateGuildGUI createGuildGUI = new CreateGuildGUI(plugin); + plugin.getGuiManager().openGUI(player, createGuildGUI); + }); + }); + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/MemberDetailsGUI.java b/src/main/java/com/guild/gui/MemberDetailsGUI.java index da72e3e..35db2d8 100644 --- a/src/main/java/com/guild/gui/MemberDetailsGUI.java +++ b/src/main/java/com/guild/gui/MemberDetailsGUI.java @@ -1,522 +1,521 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.PlaceholderUtils; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 成员详情GUI - */ -public class MemberDetailsGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private final GuildMember member; - private final Player viewer; - - public MemberDetailsGUI(GuildPlugin plugin, Guild guild, GuildMember member, Player viewer) { - this.plugin = plugin; - this.guild = guild; - this.member = member; - this.viewer = viewer; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-details.title", "&6成员详情") - .replace("{member_name}", member.getPlayerName())); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("member-details.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 设置成员头像 - setupMemberHead(inventory); - - // 设置基本信息 - setupBasicInfo(inventory); - - // 设置权限信息 - setupPermissionInfo(inventory); - - // 设置操作按钮 - setupActionButtons(inventory); - - // 设置返回按钮 - setupBackButton(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - // 检查是否是操作按钮 - if (isActionButton(slot)) { - handleActionButton(player, slot); - return; - } - - // 检查是否是返回按钮 - if (slot == 49) { - plugin.getGuiManager().openGUI(player, new MemberManagementGUI(plugin, guild)); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 设置成员头像 - */ - private void setupMemberHead(Inventory inventory) { - ItemStack head = new ItemStack(Material.PLAYER_HEAD); - SkullMeta meta = (SkullMeta) head.getItemMeta(); - - if (meta != null) { - // 根据角色设置不同的显示名称 - String displayName; - switch (member.getRole()) { - case LEADER: - displayName = ColorUtils.colorize("&c" + member.getPlayerName() + " &7(会长)"); - break; - case OFFICER: - displayName = ColorUtils.colorize("&6" + member.getPlayerName() + " &7(官员)"); - break; - default: - displayName = ColorUtils.colorize("&f" + member.getPlayerName() + " &7(成员)"); - break; - } - - meta.setDisplayName(displayName); - - List lore = new ArrayList<>(); - lore.add(ColorUtils.colorize("&7UUID: &f" + member.getPlayerUuid())); - lore.add(ColorUtils.colorize("&7角色: &f" + member.getRole().getDisplayName())); - - // 格式化加入时间 - if (member.getJoinedAt() != null) { - String joinTime = member.getJoinedAt().format(com.guild.core.time.TimeProvider.FULL_FORMATTER); - lore.add(ColorUtils.colorize("&7加入时间: &f" + joinTime)); - } else { - lore.add(ColorUtils.colorize("&7加入时间: &f未知")); - } - - meta.setLore(lore); - head.setItemMeta(meta); - } - - inventory.setItem(13, head); - } - - /** - * 设置基本信息 - */ - private void setupBasicInfo(Inventory inventory) { - // 基本信息标题 - ItemStack infoTitle = createItem( - Material.BOOK, - ColorUtils.colorize("&6基本信息"), - ColorUtils.colorize("&7成员的详细信息") - ); - inventory.setItem(20, infoTitle); - - // 角色信息 - ItemStack roleInfo = createItem( - Material.GOLDEN_HELMET, - ColorUtils.colorize("&e角色信息"), - ColorUtils.colorize("&7当前角色: &f" + member.getRole().getDisplayName()), - ColorUtils.colorize("&7角色等级: &f" + getRoleLevel(member.getRole())), - ColorUtils.colorize("&7是否在线: &f" + (isPlayerOnline(member.getPlayerUuid()) ? "&a是" : "&c否")) - ); - inventory.setItem(21, roleInfo); - - // 时间信息 - ItemStack timeInfo = createItem( - Material.CLOCK, - ColorUtils.colorize("&e时间信息"), - ColorUtils.colorize("&7加入时间: &f" + formatTime(member.getJoinedAt())), - ColorUtils.colorize("&7在工会时长: &f" + getGuildDuration(member.getJoinedAt())) - ); - inventory.setItem(22, timeInfo); - - // 贡献信息 - ItemStack contributionInfo = createItem( - Material.EMERALD, - ColorUtils.colorize("&e贡献信息"), - ColorUtils.colorize("&7工会贡献: &f" + getMemberContribution()), - ColorUtils.colorize("&7活跃度: &f" + getMemberActivity()) - ); - inventory.setItem(23, contributionInfo); - } - - /** - * 设置权限信息 - */ - private void setupPermissionInfo(Inventory inventory) { - // 权限信息标题 - ItemStack permissionTitle = createItem( - Material.SHIELD, - ColorUtils.colorize("&6权限信息"), - ColorUtils.colorize("&7当前拥有的权限") - ); - inventory.setItem(29, permissionTitle); - - // 具体权限列表 - List permissions = getRolePermissions(member.getRole()); - ItemStack permissionList = createItem( - Material.PAPER, - ColorUtils.colorize("&e权限列表"), - permissions.toArray(new String[0]) - ); - inventory.setItem(30, permissionList); - - // 权限等级 - ItemStack permissionLevel = createItem( - Material.EXPERIENCE_BOTTLE, - ColorUtils.colorize("&e权限等级"), - ColorUtils.colorize("&7当前等级: &f" + getPermissionLevel(member.getRole())), - ColorUtils.colorize("&7可执行操作: &f" + getExecutableActions(member.getRole())) - ); - inventory.setItem(31, permissionLevel); - } - - /** - * 设置操作按钮 - */ - private void setupActionButtons(Inventory inventory) { - // 检查当前玩家是否有权限执行操作 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), viewer.getUniqueId()).thenAccept(viewerMember -> { - if (viewerMember == null) return; - - // 不能操作自己 - if (member.getPlayerUuid().equals(viewer.getUniqueId())) { - return; - } - - // 不能操作会长 - if (member.getRole() == GuildMember.Role.LEADER) { - return; - } - - // 踢出按钮(需要踢出权限) - if (viewerMember.getRole().canKick()) { - ItemStack kickButton = createItem( - Material.REDSTONE_BLOCK, - ColorUtils.colorize("&c踢出成员"), - ColorUtils.colorize("&7将成员踢出工会"), - ColorUtils.colorize("&7点击确认踢出") - ); - inventory.setItem(37, kickButton); - } - - // 提升/降级按钮(只有会长可以) - if (viewerMember.getRole() == GuildMember.Role.LEADER) { - if (member.getRole() == GuildMember.Role.OFFICER) { - // 降级按钮 - ItemStack demoteButton = createItem( - Material.IRON_INGOT, - ColorUtils.colorize("&7降级成员"), - ColorUtils.colorize("&7将官员降级为普通成员"), - ColorUtils.colorize("&7点击确认降级") - ); - inventory.setItem(39, demoteButton); - } else { - // 提升按钮 - ItemStack promoteButton = createItem( - Material.GOLD_INGOT, - ColorUtils.colorize("&6提升成员"), - ColorUtils.colorize("&7将成员提升为官员"), - ColorUtils.colorize("&7点击确认提升") - ); - inventory.setItem(39, promoteButton); - } - } - - // 发送消息按钮 - ItemStack messageButton = createItem( - Material.PAPER, - ColorUtils.colorize("&e发送消息"), - ColorUtils.colorize("&7向该成员发送私信"), - ColorUtils.colorize("&7点击打开聊天") - ); - inventory.setItem(41, messageButton); - }); - } - - /** - * 设置返回按钮 - */ - private void setupBackButton(Inventory inventory) { - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize("&7返回"), - ColorUtils.colorize("&7返回成员管理") - ); - inventory.setItem(49, back); - } - - /** - * 检查是否是操作按钮 - */ - private boolean isActionButton(int slot) { - return slot == 37 || slot == 39 || slot == 41; - } - - /** - * 处理操作按钮点击 - */ - private void handleActionButton(Player player, int slot) { - switch (slot) { - case 37: // 踢出成员 - handleKickMember(player); - break; - case 39: // 提升/降级成员 - handlePromoteDemoteMember(player); - break; - case 41: // 发送消息 - handleSendMessage(player); - break; - } - } - - /** - * 处理踢出成员 - */ - private void handleKickMember(Player player) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { - if (executor == null || !executor.getRole().canKick()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 确认踢出 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-kick", "&c确定要踢出成员 {member} 吗?输入 &f/guild kick {member} confirm &c确认") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - player.closeInventory(); - }); - } - - /** - * 处理提升/降级成员 - */ - private void handlePromoteDemoteMember(Player player) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { - if (executor == null || executor.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (member.getRole() == GuildMember.Role.OFFICER) { - // 降级 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-demote", "&c确定要降级成员 {member} 吗?输入 &f/guild demote {member} confirm &c确认") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - } else { - // 提升 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-promote", "&a确定要提升成员 {member} 为官员吗?输入 &f/guild promote {member} confirm &a确认") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - } - player.closeInventory(); - }); - } - - /** - * 处理发送消息 - */ - private void handleSendMessage(Player player) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.open-chat", "&e请输入要发送给 {member} 的消息:") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - player.closeInventory(); - - // 这里可以集成聊天系统,暂时只是提示 - // TODO: 实现私信系统 - } - - /** - * 获取角色等级 - */ - private String getRoleLevel(GuildMember.Role role) { - switch (role) { - case LEADER: - return "最高级"; - case OFFICER: - return "高级"; - default: - return "普通"; - } - } - - /** - * 检查玩家是否在线 - */ - private boolean isPlayerOnline(java.util.UUID playerUuid) { - Player player = plugin.getServer().getPlayer(playerUuid); - return player != null && player.isOnline(); - } - - /** - * 格式化时间 - */ - private String formatTime(java.time.LocalDateTime dateTime) { - if (dateTime == null) return "未知"; - return dateTime.format(com.guild.core.time.TimeProvider.FULL_FORMATTER); - } - - /** - * 获取在工会时长 - */ - private String getGuildDuration(java.time.LocalDateTime joinDateTime) { - if (joinDateTime == null) return "未知"; - - java.time.LocalDateTime currentTime = java.time.LocalDateTime.now(); - java.time.Duration duration = java.time.Duration.between(joinDateTime, currentTime); - - long days = duration.toDays(); - long hours = duration.toHours() % 24; - long minutes = duration.toMinutes() % 60; - - if (days > 0) { - return days + "天" + hours + "小时"; - } else if (hours > 0) { - return hours + "小时" + minutes + "分钟"; - } else { - return minutes + "分钟"; - } - } - - /** - * 获取成员贡献 - */ - private String getMemberContribution() { - // TODO: 实现贡献统计系统 - return "待统计"; - } - - /** - * 获取成员活跃度 - */ - private String getMemberActivity() { - // TODO: 实现活跃度统计系统 - return "待统计"; - } - - /** - * 获取角色权限列表 - */ - private List getRolePermissions(GuildMember.Role role) { - List permissions = new ArrayList<>(); - - switch (role) { - case LEADER: - permissions.add(ColorUtils.colorize("&7✓ 所有权限")); - permissions.add(ColorUtils.colorize("&7✓ 邀请成员")); - permissions.add(ColorUtils.colorize("&7✓ 踢出成员")); - permissions.add(ColorUtils.colorize("&7✓ 提升/降级")); - permissions.add(ColorUtils.colorize("&7✓ 管理工会")); - permissions.add(ColorUtils.colorize("&7✓ 解散工会")); - break; - case OFFICER: - permissions.add(ColorUtils.colorize("&7✓ 邀请成员")); - permissions.add(ColorUtils.colorize("&7✓ 踢出成员")); - permissions.add(ColorUtils.colorize("&7✗ 提升/降级")); - permissions.add(ColorUtils.colorize("&7✗ 管理工会")); - permissions.add(ColorUtils.colorize("&7✗ 解散工会")); - break; - default: - permissions.add(ColorUtils.colorize("&7✗ 邀请成员")); - permissions.add(ColorUtils.colorize("&7✗ 踢出成员")); - permissions.add(ColorUtils.colorize("&7✗ 提升/降级")); - permissions.add(ColorUtils.colorize("&7✗ 管理工会")); - permissions.add(ColorUtils.colorize("&7✗ 解散工会")); - break; - } - - return permissions; - } - - /** - * 获取权限等级 - */ - private String getPermissionLevel(GuildMember.Role role) { - switch (role) { - case LEADER: - return "最高级 (3级)"; - case OFFICER: - return "高级 (2级)"; - default: - return "普通 (1级)"; - } - } - - /** - * 获取可执行操作 - */ - private String getExecutableActions(GuildMember.Role role) { - switch (role) { - case LEADER: - return "所有操作"; - case OFFICER: - return "邀请、踢出"; - default: - return "基础操作"; - } - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.PlaceholderUtils; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Szczegółów Członka + */ +public class MemberDetailsGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private final GuildMember member; + private final Player viewer; + + public MemberDetailsGUI(GuildPlugin plugin, Guild guild, GuildMember member, Player viewer) { + this.plugin = plugin; + this.guild = guild; + this.member = member; + this.viewer = viewer; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-details.title", "&6Szczegóły członka") + .replace("{member_name}", member.getPlayerName())); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("member-details.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Ustaw głowę członka + setupMemberHead(inventory); + + // Ustaw podstawowe informacje + setupBasicInfo(inventory); + + // Ustaw informacje o uprawnieniach + setupPermissionInfo(inventory); + + // Ustaw przyciski akcji + setupActionButtons(inventory); + + // Ustaw przycisk powrotu + setupBackButton(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + // Sprawdź czy to przycisk akcji + if (isActionButton(slot)) { + handleActionButton(player, slot); + return; + } + + // Sprawdź czy to przycisk powrotu + if (slot == 49) { + plugin.getGuiManager().openGUI(player, new MemberManagementGUI(plugin, guild)); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Ustaw głowę członka + */ + private void setupMemberHead(Inventory inventory) { + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) head.getItemMeta(); + + if (meta != null) { + // Ustaw nazwę w zależności od roli + String displayName; + switch (member.getRole()) { + case LEADER: + displayName = ColorUtils.colorize("&c" + member.getPlayerName() + " &7(Lider)"); + break; + case OFFICER: + displayName = ColorUtils.colorize("&6" + member.getPlayerName() + " &7(Oficer)"); + break; + default: + displayName = ColorUtils.colorize("&f" + member.getPlayerName() + " &7(Członek)"); + break; + } + + meta.setDisplayName(displayName); + + List lore = new ArrayList<>(); + lore.add(ColorUtils.colorize("&7UUID: &f" + member.getPlayerUuid())); + lore.add(ColorUtils.colorize("&7Rola: &f" + member.getRole().getDisplayName())); + + // Formatuj datę dołączenia + if (member.getJoinedAt() != null) { + String joinTime = member.getJoinedAt().format(com.guild.core.time.TimeProvider.FULL_FORMATTER); + lore.add(ColorUtils.colorize("&7Dołączył: &f" + joinTime)); + } else { + lore.add(ColorUtils.colorize("&7Dołączył: &fNieznana")); + } + + meta.setLore(lore); + head.setItemMeta(meta); + } + + inventory.setItem(13, head); + } + + /** + * Ustaw podstawowe informacje + */ + private void setupBasicInfo(Inventory inventory) { + // Tytuł informacji podstawowych + ItemStack infoTitle = createItem( + Material.BOOK, + ColorUtils.colorize("&6Podstawowe informacje"), + ColorUtils.colorize("&7Szczegóły członka") + ); + inventory.setItem(20, infoTitle); + + // Informacje o roli + ItemStack roleInfo = createItem( + Material.GOLDEN_HELMET, + ColorUtils.colorize("&eInformacje o roli"), + ColorUtils.colorize("&7Obecna rola: &f" + member.getRole().getDisplayName()), + ColorUtils.colorize("&7Poziom roli: &f" + getRoleLevel(member.getRole())), + ColorUtils.colorize("&7Status online: &f" + (isPlayerOnline(member.getPlayerUuid()) ? "&aTak" : "&cNie")) + ); + inventory.setItem(21, roleInfo); + + // Informacje o czasie + ItemStack timeInfo = createItem( + Material.CLOCK, + ColorUtils.colorize("&eInformacje czasowe"), + ColorUtils.colorize("&7Data dołączenia: &f" + formatTime(member.getJoinedAt())), + ColorUtils.colorize("&7Staż w gildii: &f" + getGuildDuration(member.getJoinedAt())) + ); + inventory.setItem(22, timeInfo); + + // Informacje o wkładzie + ItemStack contributionInfo = createItem( + Material.EMERALD, + ColorUtils.colorize("&eInformacje o wkładzie"), + ColorUtils.colorize("&7Wkład w gildię: &f" + getMemberContribution()), + ColorUtils.colorize("&7Aktywność: &f" + getMemberActivity()) + ); + inventory.setItem(23, contributionInfo); + } + + /** + * Ustaw informacje o uprawnieniach + */ + private void setupPermissionInfo(Inventory inventory) { + // Tytuł informacji o uprawnieniach + ItemStack permissionTitle = createItem( + Material.SHIELD, + ColorUtils.colorize("&6Informacje o uprawnieniach"), + ColorUtils.colorize("&7Obecne uprawnienia") + ); + inventory.setItem(29, permissionTitle); + + // Lista uprawnień + List permissions = getRolePermissions(member.getRole()); + ItemStack permissionList = createItem( + Material.PAPER, + ColorUtils.colorize("&eLista uprawnień"), + permissions.toArray(new String[0]) + ); + inventory.setItem(30, permissionList); + + // Poziom uprawnień + ItemStack permissionLevel = createItem( + Material.EXPERIENCE_BOTTLE, + ColorUtils.colorize("&ePoziom uprawnień"), + ColorUtils.colorize("&7Obecny poziom: &f" + getPermissionLevel(member.getRole())), + ColorUtils.colorize("&7Dostępne akcje: &f" + getExecutableActions(member.getRole())) + ); + inventory.setItem(31, permissionLevel); + } + + /** + * Ustaw przyciski akcji + */ + private void setupActionButtons(Inventory inventory) { + // Sprawdź czy przeglądający ma uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), viewer.getUniqueId()).thenAccept(viewerMember -> { + if (viewerMember == null) return; + + // Nie można modyfikować samego siebie + if (member.getPlayerUuid().equals(viewer.getUniqueId())) { + return; + } + + // Nie można modyfikować lidera + if (member.getRole() == GuildMember.Role.LEADER) { + return; + } + + // Przycisk wyrzucenia (wymaga uprawnień do wyrzucania) + if (viewerMember.getRole().canKick()) { + ItemStack kickButton = createItem( + Material.REDSTONE_BLOCK, + ColorUtils.colorize("&cWyrzuć członka"), + ColorUtils.colorize("&7Wyrzuć członka z gildii"), + ColorUtils.colorize("&7Kliknij, aby potwierdzić") + ); + inventory.setItem(37, kickButton); + } + + // Przycisk awansu/degradacji (tylko lider) + if (viewerMember.getRole() == GuildMember.Role.LEADER) { + if (member.getRole() == GuildMember.Role.OFFICER) { + // Przycisk degradacji + ItemStack demoteButton = createItem( + Material.IRON_INGOT, + ColorUtils.colorize("&7Zdegraduj członka"), + ColorUtils.colorize("&7Zdegraduj oficera do rangi członka"), + ColorUtils.colorize("&7Kliknij, aby potwierdzić") + ); + inventory.setItem(39, demoteButton); + } else { + // Przycisk awansu + ItemStack promoteButton = createItem( + Material.GOLD_INGOT, + ColorUtils.colorize("&6Awansuj członka"), + ColorUtils.colorize("&7Awansuj członka na oficera"), + ColorUtils.colorize("&7Kliknij, aby potwierdzić") + ); + inventory.setItem(39, promoteButton); + } + } + + // Przycisk wiadomości + ItemStack messageButton = createItem( + Material.PAPER, + ColorUtils.colorize("&eWyślij wiadomość"), + ColorUtils.colorize("&7Wyślij prywatną wiadomość"), + ColorUtils.colorize("&7Kliknij, aby otworzyć czat") + ); + inventory.setItem(41, messageButton); + }); + } + + /** + * Ustaw przycisk powrotu + */ + private void setupBackButton(Inventory inventory) { + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize("&7Powrót"), + ColorUtils.colorize("&7Powrót do zarządzania członkami") + ); + inventory.setItem(49, back); + } + + /** + * Sprawdź czy to przycisk akcji + */ + private boolean isActionButton(int slot) { + return slot == 37 || slot == 39 || slot == 41; + } + + /** + * Obsługa przycisków akcji + */ + private void handleActionButton(Player player, int slot) { + switch (slot) { + case 37: // Wyrzuć członka + handleKickMember(player); + break; + case 39: // Awansuj/Zdegraduj członka + handlePromoteDemoteMember(player); + break; + case 41: // Wyślij wiadomość + handleSendMessage(player); + break; + } + } + + /** + * Obsługa wyrzucenia członka + */ + private void handleKickMember(Player player) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { + if (executor == null || !executor.getRole().canKick()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Potwierdź wyrzucenie + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-kick", "&cCzy na pewno chcesz wyrzucić członka {member}? Wpisz &f/guild kick {member} confirm &caby potwierdzić") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + player.closeInventory(); + }); + } + + /** + * Obsługa awansu/degradacji członka + */ + private void handlePromoteDemoteMember(Player player) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { + if (executor == null || executor.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (member.getRole() == GuildMember.Role.OFFICER) { + // Degradacja + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-demote", "&cCzy na pewno chcesz zdegradować członka {member}? Wpisz &f/guild demote {member} confirm &caby potwierdzić") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + } else { + // Awans + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-promote", "&aCzy na pewno chcesz awansować członka {member} na oficera? Wpisz &f/guild promote {member} confirm &aaby potwierdzić") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + } + player.closeInventory(); + }); + } + + /** + * Obsługa wysyłania wiadomości + */ + private void handleSendMessage(Player player) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.open-chat", "&eWpisz wiadomość do {member}:") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + player.closeInventory(); + + // TODO: Zaimplementować system prywatnych wiadomości + } + + /** + * Pobierz poziom roli + */ + private String getRoleLevel(GuildMember.Role role) { + switch (role) { + case LEADER: + return "Najwyższy"; + case OFFICER: + return "Wysoki"; + default: + return "Normalny"; + } + } + + /** + * Sprawdź czy gracz jest online + */ + private boolean isPlayerOnline(java.util.UUID playerUuid) { + Player player = plugin.getServer().getPlayer(playerUuid); + return player != null && player.isOnline(); + } + + /** + * Formatuj czas + */ + private String formatTime(java.time.LocalDateTime dateTime) { + if (dateTime == null) return "Nieznany"; + return dateTime.format(com.guild.core.time.TimeProvider.FULL_FORMATTER); + } + + /** + * Pobierz staż w gildii + */ + private String getGuildDuration(java.time.LocalDateTime joinDateTime) { + if (joinDateTime == null) return "Nieznany"; + + java.time.LocalDateTime currentTime = java.time.LocalDateTime.now(); + java.time.Duration duration = java.time.Duration.between(joinDateTime, currentTime); + + long days = duration.toDays(); + long hours = duration.toHours() % 24; + long minutes = duration.toMinutes() % 60; + + if (days > 0) { + return days + " dni " + hours + " godz."; + } else if (hours > 0) { + return hours + " godz. " + minutes + " min."; + } else { + return minutes + " min."; + } + } + + /** + * Pobierz wkład członka + */ + private String getMemberContribution() { + // TODO: Zaimplementować system statystyk wkładu + return "Do obliczenia"; + } + + /** + * Pobierz aktywność członka + */ + private String getMemberActivity() { + // TODO: Zaimplementować system statystyk aktywności + return "Do obliczenia"; + } + + /** + * Pobierz listę uprawnień roli + */ + private List getRolePermissions(GuildMember.Role role) { + List permissions = new ArrayList<>(); + + switch (role) { + case LEADER: + permissions.add(ColorUtils.colorize("&7✓ Wszystkie uprawnienia")); + permissions.add(ColorUtils.colorize("&7✓ Zapraszanie")); + permissions.add(ColorUtils.colorize("&7✓ Wyrzucanie")); + permissions.add(ColorUtils.colorize("&7✓ Awans/Degradacja")); + permissions.add(ColorUtils.colorize("&7✓ Zarządzanie")); + permissions.add(ColorUtils.colorize("&7✓ Rozwiązanie")); + break; + case OFFICER: + permissions.add(ColorUtils.colorize("&7✓ Zapraszanie")); + permissions.add(ColorUtils.colorize("&7✓ Wyrzucanie")); + permissions.add(ColorUtils.colorize("&7✗ Awans/Degradacja")); + permissions.add(ColorUtils.colorize("&7✗ Zarządzanie")); + permissions.add(ColorUtils.colorize("&7✗ Rozwiązanie")); + break; + default: + permissions.add(ColorUtils.colorize("&7✗ Zapraszanie")); + permissions.add(ColorUtils.colorize("&7✗ Wyrzucanie")); + permissions.add(ColorUtils.colorize("&7✗ Awans/Degradacja")); + permissions.add(ColorUtils.colorize("&7✗ Zarządzanie")); + permissions.add(ColorUtils.colorize("&7✗ Rozwiązanie")); + break; + } + + return permissions; + } + + /** + * Pobierz poziom uprawnień + */ + private String getPermissionLevel(GuildMember.Role role) { + switch (role) { + case LEADER: + return "Poziom 3 (Max)"; + case OFFICER: + return "Poziom 2"; + default: + return "Poziom 1"; + } + } + + /** + * Pobierz dostępne akcje + */ + private String getExecutableActions(GuildMember.Role role) { + switch (role) { + case LEADER: + return "Wszystkie akcje"; + case OFFICER: + return "Zapraszanie, Wyrzucanie"; + default: + return "Podstawowe akcje"; + } + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/MemberManagementGUI.java b/src/main/java/com/guild/gui/MemberManagementGUI.java index dd220f8..9d6d482 100644 --- a/src/main/java/com/guild/gui/MemberManagementGUI.java +++ b/src/main/java/com/guild/gui/MemberManagementGUI.java @@ -1,510 +1,510 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.core.utils.PlaceholderUtils; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 成员管理GUI - */ -public class MemberManagementGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private int currentPage = 0; - private static final int MEMBERS_PER_PAGE = 28; // 4行7列,除去边框 - - public MemberManagementGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - } - - @Override - public String getTitle() { - return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.title", "&6成员管理")); - } - - @Override - public int getSize() { - return plugin.getConfigManager().getGuiConfig().getInt("member-management.size", 54); - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 添加功能按钮 - setupFunctionButtons(inventory); - - // 加载成员列表 - loadMembers(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - // 检查是否是功能按钮 - if (isFunctionButton(slot)) { - handleFunctionButton(player, slot); - return; - } - - // 检查是否是分页按钮 - if (isPaginationButton(slot)) { - handlePaginationButton(player, slot); - return; - } - - // 检查是否是成员按钮 - if (isMemberSlot(slot)) { - handleMemberClick(player, slot, clickedItem, clickType); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 设置功能按钮 - */ - private void setupFunctionButtons(Inventory inventory) { - // 邀请成员按钮 - ItemStack inviteMember = createItem( - Material.EMERALD_BLOCK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.invite-member.name", "&a邀请成员")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.invite-member.lore.1", "&7邀请新成员加入")) - ); - inventory.setItem(45, inviteMember); - - // 踢出成员按钮 - ItemStack kickMember = createItem( - Material.REDSTONE_BLOCK, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.kick-member.name", "&c踢出成员")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.kick-member.lore.1", "&7踢出工会成员")) - ); - inventory.setItem(47, kickMember); - - // 提升成员按钮 - ItemStack promoteMember = createItem( - Material.GOLD_INGOT, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.promote-member.name", "&6提升成员")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.promote-member.lore.1", "&7提升成员职位")) - ); - inventory.setItem(49, promoteMember); - - // 降级成员按钮 - ItemStack demoteMember = createItem( - Material.IRON_INGOT, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.demote-member.name", "&7降级成员")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.demote-member.lore.1", "&7降级成员职位")) - ); - inventory.setItem(51, demoteMember); - - // 返回按钮 - ItemStack back = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.back.name", "&7返回")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.back.lore.1", "&7返回主菜单")) - ); - inventory.setItem(53, back); - } - - /** - * 加载成员列表 - */ - private void loadMembers(Inventory inventory) { - plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(members -> { - if (members == null || members.isEmpty()) { - // 显示无成员信息 - ItemStack noMembers = createItem( - Material.BARRIER, - ColorUtils.colorize("&c暂无成员"), - ColorUtils.colorize("&7工会中还没有成员") - ); - inventory.setItem(22, noMembers); - return; - } - - // 计算分页 - int totalPages = (members.size() - 1) / MEMBERS_PER_PAGE; - if (currentPage > totalPages) { - currentPage = totalPages; - } - - // 设置分页按钮 - setupPaginationButtons(inventory, totalPages); - - // 显示当前页的成员 - int startIndex = currentPage * MEMBERS_PER_PAGE; - int endIndex = Math.min(startIndex + MEMBERS_PER_PAGE, members.size()); - - int slotIndex = 10; // 从第2行第2列开始 - for (int i = startIndex; i < endIndex; i++) { - GuildMember member = members.get(i); - if (slotIndex >= 44) break; // 避免超出显示区域 - - ItemStack memberItem = createMemberItem(member); - inventory.setItem(slotIndex, memberItem); - - slotIndex++; - if (slotIndex % 9 == 8) { // 跳过边框 - slotIndex += 2; - } - } - }); - } - - /** - * 设置分页按钮 - */ - private void setupPaginationButtons(Inventory inventory, int totalPages) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack previousPage = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.previous-page.name", "&c上一页")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.previous-page.lore.1", "&7查看上一页")) - ); - inventory.setItem(18, previousPage); - } - - // 下一页按钮 - if (currentPage < totalPages) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.next-page.name", "&a下一页")), - ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.next-page.lore.1", "&7查看下一页")) - ); - inventory.setItem(26, nextPage); - } - } - - /** - * 创建成员物品 - */ - private ItemStack createMemberItem(GuildMember member) { - Material material; - String name; - List lore = new ArrayList<>(); - - switch (member.getRole()) { - case LEADER: - material = Material.GOLDEN_HELMET; - name = PlaceholderUtils.replaceMemberPlaceholders("&c{member_name}", member, guild); - lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7角色: &c{member_role}", member, guild)); - break; - case OFFICER: - material = Material.GOLDEN_HELMET; - name = PlaceholderUtils.replaceMemberPlaceholders("&6{member_name}", member, guild); - lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7角色: &6{member_role}", member, guild)); - break; - default: - material = Material.PLAYER_HEAD; - name = PlaceholderUtils.replaceMemberPlaceholders("&f{member_name}", member, guild); - lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7角色: &f{member_role}", member, guild)); - break; - } - - lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7加入时间: {member_join_time}", member, guild)); - lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7权限: " + getRolePermissions(member.getRole()), member, guild)); - lore.add(""); - lore.add(ColorUtils.colorize("&a左键: 查看详情")); - - if (member.getRole() != GuildMember.Role.LEADER) { - lore.add(ColorUtils.colorize("&c右键: 踢出成员")); - lore.add(ColorUtils.colorize("&6中键: 提升/降级")); - } - - return createItem(material, name, lore.toArray(new String[0])); - } - - /** - * 获取角色权限描述 - */ - private String getRolePermissions(GuildMember.Role role) { - switch (role) { - case LEADER: - return "所有权限"; - case OFFICER: - return "邀请、踢出"; - default: - return "基础权限"; - } - } - - /** - * 检查是否是功能按钮 - */ - private boolean isFunctionButton(int slot) { - return slot == 45 || slot == 47 || slot == 49 || slot == 51 || slot == 53; - } - - /** - * 检查是否是分页按钮 - */ - private boolean isPaginationButton(int slot) { - return slot == 18 || slot == 26; - } - - /** - * 检查是否是成员槽位 - */ - private boolean isMemberSlot(int slot) { - return slot >= 10 && slot <= 44 && slot % 9 != 0 && slot % 9 != 8; - } - - /** - * 处理功能按钮点击 - */ - private void handleFunctionButton(Player player, int slot) { - switch (slot) { - case 45: // 邀请成员 - handleInviteMember(player); - break; - case 47: // 踢出成员 - handleKickMember(player); - break; - case 49: // 提升成员 - handlePromoteMember(player); - break; - case 51: // 降级成员 - handleDemoteMember(player); - break; - case 53: // 返回 - plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); - break; - } - } - - /** - * 处理分页按钮点击 - */ - private void handlePaginationButton(Player player, int slot) { - if (slot == 18) { // 上一页 - if (currentPage > 0) { - currentPage--; - refreshInventory(player); - } - } else if (slot == 26) { // 下一页 - currentPage++; - refreshInventory(player); - } - } - - /** - * 处理成员点击 - */ - private void handleMemberClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - // 获取点击的成员 - int memberIndex = (currentPage * MEMBERS_PER_PAGE) + (slot - 10); - if (memberIndex % 9 == 0 || memberIndex % 9 == 8) return; // 跳过边框 - - plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(members -> { - if (members != null && memberIndex < members.size()) { - GuildMember member = members.get(memberIndex); - - if (clickType == ClickType.LEFT) { - // 查看成员详情 - showMemberDetails(player, member); - } else if (clickType == ClickType.RIGHT) { - // 踢出成员 - handleKickMemberDirect(player, member); - } else if (clickType == ClickType.MIDDLE) { - // 提升/降级成员 - handlePromoteDemoteMember(player, member); - } - } - }); - } - - /** - * 显示成员详情 - */ - private void showMemberDetails(Player player, GuildMember member) { - // 打开成员详情GUI - plugin.getGuiManager().openGUI(player, new MemberDetailsGUI(plugin, guild, member, player)); - } - - /** - * 直接踢出成员 - */ - private void handleKickMemberDirect(Player player, GuildMember member) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { - if (executor == null || !executor.getRole().canKick()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 不能踢出会长 - if (member.getRole() == GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.cannot-kick-leader", "&c不能踢出工会会长"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 确认踢出 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-kick", "&c确定要踢出成员 {member} 吗?输入 &f/guild kick {member} confirm &c确认") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - }); - } - - /** - * 提升/降级成员 - */ - private void handlePromoteDemoteMember(Player player, GuildMember member) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { - if (executor == null || executor.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 不能操作会长 - if (member.getRole() == GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.cannot-modify-leader", "&c不能修改工会会长的职位"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - if (member.getRole() == GuildMember.Role.OFFICER) { - // 降级为普通成员 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-demote", "&c确定要降级成员 {member} 吗?输入 &f/guild demote {member} confirm &c确认") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - } else { - // 提升为官员 - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-promote", "&a确定要提升成员 {member} 为官员吗?输入 &f/guild promote {member} confirm &a确认") - .replace("{member}", member.getPlayerName()); - player.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 处理邀请成员 - */ - private void handleInviteMember(Player player) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null || !member.getRole().canInvite()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开邀请成员GUI - InviteMemberGUI inviteMemberGUI = new InviteMemberGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, inviteMemberGUI); - }); - } - - /** - * 处理踢出成员 - */ - private void handleKickMember(Player player) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null || !member.getRole().canKick()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开踢出成员GUI - KickMemberGUI kickMemberGUI = new KickMemberGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, kickMemberGUI); - }); - } - - /** - * 处理提升成员 - */ - private void handlePromoteMember(Player player) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开提升成员GUI - PromoteMemberGUI promoteMemberGUI = new PromoteMemberGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, promoteMemberGUI); - }); - } - - /** - * 处理降级成员 - */ - private void handleDemoteMember(Player player) { - // 检查权限 - plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { - if (member == null || member.getRole() != GuildMember.Role.LEADER) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&c只有工会会长才能执行此操作"); - player.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 打开降级成员GUI - DemoteMemberGUI demoteMemberGUI = new DemoteMemberGUI(plugin, guild); - plugin.getGuiManager().openGUI(player, demoteMemberGUI); - }); - } - - /** - * 刷新库存 - */ - private void refreshInventory(Player player) { - plugin.getGuiManager().refreshGUI(player); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.core.utils.PlaceholderUtils; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Zarządzania Członkami + */ +public class MemberManagementGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private int currentPage = 0; + private static final int MEMBERS_PER_PAGE = 28; // 4 rzędy po 7 kolumn, bez obramowania + + public MemberManagementGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + } + + @Override + public String getTitle() { + return ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.title", "&6Zarządzanie członkami")); + } + + @Override + public int getSize() { + return plugin.getConfigManager().getGuiConfig().getInt("member-management.size", 54); + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Dodaj przyciski funkcyjne + setupFunctionButtons(inventory); + + // Załaduj listę członków + loadMembers(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + // Sprawdź czy to przycisk funkcyjny + if (isFunctionButton(slot)) { + handleFunctionButton(player, slot); + return; + } + + // Sprawdź czy to przycisk paginacji + if (isPaginationButton(slot)) { + handlePaginationButton(player, slot); + return; + } + + // Sprawdź czy to slot członka + if (isMemberSlot(slot)) { + handleMemberClick(player, slot, clickedItem, clickType); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Skonfiguruj przyciski funkcyjne + */ + private void setupFunctionButtons(Inventory inventory) { + // Przycisk zaproszenia członka + ItemStack inviteMember = createItem( + Material.EMERALD_BLOCK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.invite-member.name", "&aZaproś członka")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.invite-member.lore.1", "&7Zaproś nowego członka")) + ); + inventory.setItem(45, inviteMember); + + // Przycisk wyrzucenia członka + ItemStack kickMember = createItem( + Material.REDSTONE_BLOCK, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.kick-member.name", "&cWyrzuć członka")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.kick-member.lore.1", "&7Wyrzuć członka gildii")) + ); + inventory.setItem(47, kickMember); + + // Przycisk awansu członka + ItemStack promoteMember = createItem( + Material.GOLD_INGOT, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.promote-member.name", "&6Awansuj członka")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.promote-member.lore.1", "&7Awansuj członka na wyższą rangę")) + ); + inventory.setItem(49, promoteMember); + + // Przycisk degradacji członka + ItemStack demoteMember = createItem( + Material.IRON_INGOT, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.demote-member.name", "&7Zdegraduj członka")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.demote-member.lore.1", "&7Zdegraduj członka na niższą rangę")) + ); + inventory.setItem(51, demoteMember); + + // Przycisk powrotu + ItemStack back = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.back.name", "&7Powrót")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.back.lore.1", "&7Powrót do menu głównego")) + ); + inventory.setItem(53, back); + } + + /** + * Załaduj listę członków + */ + private void loadMembers(Inventory inventory) { + plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(members -> { + if (members == null || members.isEmpty()) { + // Wyświetl informację o braku członków + ItemStack noMembers = createItem( + Material.BARRIER, + ColorUtils.colorize("&cBrak członków"), + ColorUtils.colorize("&7Gildia nie ma jeszcze członków") + ); + inventory.setItem(22, noMembers); + return; + } + + // Oblicz paginację + int totalPages = (members.size() - 1) / MEMBERS_PER_PAGE; + if (currentPage > totalPages) { + currentPage = totalPages; + } + + // Skonfiguruj przyciski paginacji + setupPaginationButtons(inventory, totalPages); + + // Wyświetl członków na bieżącej stronie + int startIndex = currentPage * MEMBERS_PER_PAGE; + int endIndex = Math.min(startIndex + MEMBERS_PER_PAGE, members.size()); + + int slotIndex = 10; // Rozpocznij od 2 rzędu, 2 kolumny + for (int i = startIndex; i < endIndex; i++) { + GuildMember member = members.get(i); + if (slotIndex >= 44) break; // Unikaj wyjścia poza obszar wyświetlania + + ItemStack memberItem = createMemberItem(member); + inventory.setItem(slotIndex, memberItem); + + slotIndex++; + if (slotIndex % 9 == 8) { // Pomiń obramowanie + slotIndex += 2; + } + } + }); + } + + /** + * Skonfiguruj przyciski paginacji + */ + private void setupPaginationButtons(Inventory inventory, int totalPages) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack previousPage = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.previous-page.name", "&cPoprzednia strona")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.previous-page.lore.1", "&7Zobacz poprzednią stronę")) + ); + inventory.setItem(18, previousPage); + } + + // Przycisk następnej strony + if (currentPage < totalPages) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.next-page.name", "&aNastępna strona")), + ColorUtils.colorize(plugin.getConfigManager().getGuiConfig().getString("member-management.items.next-page.lore.1", "&7Zobacz następną stronę")) + ); + inventory.setItem(26, nextPage); + } + } + + /** + * Utwórz przedmiot członka + */ + private ItemStack createMemberItem(GuildMember member) { + Material material; + String name; + List lore = new ArrayList<>(); + + switch (member.getRole()) { + case LEADER: + material = Material.GOLDEN_HELMET; + name = PlaceholderUtils.replaceMemberPlaceholders("&c{member_name}", member, guild); + lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7Rola: &c{member_role}", member, guild)); + break; + case OFFICER: + material = Material.GOLDEN_HELMET; + name = PlaceholderUtils.replaceMemberPlaceholders("&6{member_name}", member, guild); + lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7Rola: &6{member_role}", member, guild)); + break; + default: + material = Material.PLAYER_HEAD; + name = PlaceholderUtils.replaceMemberPlaceholders("&f{member_name}", member, guild); + lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7Rola: &f{member_role}", member, guild)); + break; + } + + lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7Dołączył: {member_join_time}", member, guild)); + lore.add(PlaceholderUtils.replaceMemberPlaceholders("&7Uprawnienia: " + getRolePermissions(member.getRole()), member, guild)); + lore.add(""); + lore.add(ColorUtils.colorize("&aLewy przycisk: Zobacz szczegóły")); + + if (member.getRole() != GuildMember.Role.LEADER) { + lore.add(ColorUtils.colorize("&cPrawy przycisk: Wyrzuć członka")); + lore.add(ColorUtils.colorize("&6Środkowy przycisk: Awansuj/Zdegraduj")); + } + + return createItem(material, name, lore.toArray(new String[0])); + } + + /** + * Pobierz opis uprawnień roli + */ + private String getRolePermissions(GuildMember.Role role) { + switch (role) { + case LEADER: + return "Wszystkie uprawnienia"; + case OFFICER: + return "Zapraszanie, Wyrzucanie"; + default: + return "Podstawowe uprawnienia"; + } + } + + /** + * Sprawdź czy to przycisk funkcyjny + */ + private boolean isFunctionButton(int slot) { + return slot == 45 || slot == 47 || slot == 49 || slot == 51 || slot == 53; + } + + /** + * Sprawdź czy to przycisk paginacji + */ + private boolean isPaginationButton(int slot) { + return slot == 18 || slot == 26; + } + + /** + * Sprawdź czy to slot członka + */ + private boolean isMemberSlot(int slot) { + return slot >= 10 && slot <= 44 && slot % 9 != 0 && slot % 9 != 8; + } + + /** + * Obsługa kliknięcia przycisku funkcyjnego + */ + private void handleFunctionButton(Player player, int slot) { + switch (slot) { + case 45: // Zaproś członka + handleInviteMember(player); + break; + case 47: // Wyrzuć członka + handleKickMember(player); + break; + case 49: // Awansuj członka + handlePromoteMember(player); + break; + case 51: // Zdegraduj członka + handleDemoteMember(player); + break; + case 53: // Powrót + plugin.getGuiManager().openGUI(player, new MainGuildGUI(plugin)); + break; + } + } + + /** + * Obsługa kliknięcia przycisku paginacji + */ + private void handlePaginationButton(Player player, int slot) { + if (slot == 18) { // Poprzednia strona + if (currentPage > 0) { + currentPage--; + refreshInventory(player); + } + } else if (slot == 26) { // Następna strona + currentPage++; + refreshInventory(player); + } + } + + /** + * Obsługa kliknięcia członka + */ + private void handleMemberClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + // Pobierz klikniętego członka + int memberIndex = (currentPage * MEMBERS_PER_PAGE) + (slot - 10); + if (memberIndex % 9 == 0 || memberIndex % 9 == 8) return; // Pomiń obramowanie + + plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(members -> { + if (members != null && memberIndex < members.size()) { + GuildMember member = members.get(memberIndex); + + if (clickType == ClickType.LEFT) { + // Zobacz szczegóły członka + showMemberDetails(player, member); + } else if (clickType == ClickType.RIGHT) { + // Wyrzuć członka + handleKickMemberDirect(player, member); + } else if (clickType == ClickType.MIDDLE) { + // Awansuj/Zdegraduj członka + handlePromoteDemoteMember(player, member); + } + } + }); + } + + /** + * Pokaż szczegóły członka + */ + private void showMemberDetails(Player player, GuildMember member) { + // Otwórz GUI szczegółów członka + plugin.getGuiManager().openGUI(player, new MemberDetailsGUI(plugin, guild, member, player)); + } + + /** + * Bezpośrednie wyrzucenie członka + */ + private void handleKickMemberDirect(Player player, GuildMember member) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { + if (executor == null || !executor.getRole().canKick()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Nie można wyrzucić lidera + if (member.getRole() == GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.cannot-kick-leader", "&cNie można wyrzucić lidera gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Potwierdź wyrzucenie + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-kick", "&cCzy na pewno chcesz wyrzucić członka {member}? Wpisz &f/guild kick {member} confirm &caby potwierdzić") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + }); + } + + /** + * Awansuj/Zdegraduj członka + */ + private void handlePromoteDemoteMember(Player player, GuildMember member) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(executor -> { + if (executor == null || executor.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Nie można modyfikować lidera + if (member.getRole() == GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.cannot-modify-leader", "&cNie można modyfikować rangi lidera gildii"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + if (member.getRole() == GuildMember.Role.OFFICER) { + // Zdegraduj do zwykłego członka + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-demote", "&cCzy na pewno chcesz zdegradować członka {member}? Wpisz &f/guild demote {member} confirm &caby potwierdzić") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + } else { + // Awansuj na oficera + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.confirm-promote", "&aCzy na pewno chcesz awansować członka {member} na oficera? Wpisz &f/guild promote {member} confirm &aaby potwierdzić") + .replace("{member}", member.getPlayerName()); + player.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Obsługa zaproszenia członka + */ + private void handleInviteMember(Player player) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null || !member.getRole().canInvite()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI zaproszenia członka + InviteMemberGUI inviteMemberGUI = new InviteMemberGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, inviteMemberGUI); + }); + } + + /** + * Obsługa wyrzucenia członka + */ + private void handleKickMember(Player player) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null || !member.getRole().canKick()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI wyrzucenia członka + KickMemberGUI kickMemberGUI = new KickMemberGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, kickMemberGUI); + }); + } + + /** + * Obsługa awansu członka + */ + private void handlePromoteMember(Player player) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI awansu członka + PromoteMemberGUI promoteMemberGUI = new PromoteMemberGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, promoteMemberGUI); + }); + } + + /** + * Obsługa degradacji członka + */ + private void handleDemoteMember(Player player) { + // Sprawdź uprawnienia + plugin.getGuildService().getGuildMemberAsync(guild.getId(), player.getUniqueId()).thenAccept(member -> { + if (member == null || member.getRole() != GuildMember.Role.LEADER) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.leader-only", "&cTylko lider gildii może wykonać tę operację"); + player.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Otwórz GUI degradacji członka + DemoteMemberGUI demoteMemberGUI = new DemoteMemberGUI(plugin, guild); + plugin.getGuiManager().openGUI(player, demoteMemberGUI); + }); + } + + /** + * Odśwież ekwipunek + */ + private void refreshInventory(Player player) { + plugin.getGuiManager().refreshGUI(player); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/gui/PromoteMemberGUI.java b/src/main/java/com/guild/gui/PromoteMemberGUI.java index 1209164..55a2dbf 100644 --- a/src/main/java/com/guild/gui/PromoteMemberGUI.java +++ b/src/main/java/com/guild/gui/PromoteMemberGUI.java @@ -1,234 +1,234 @@ -package com.guild.gui; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUI; -import com.guild.core.utils.ColorUtils; -import com.guild.models.Guild; -import com.guild.models.GuildMember; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; - -/** - * 提升成员GUI - */ -public class PromoteMemberGUI implements GUI { - - private final GuildPlugin plugin; - private final Guild guild; - private int currentPage = 0; - private List members; - - public PromoteMemberGUI(GuildPlugin plugin, Guild guild) { - this.plugin = plugin; - this.guild = guild; - // 初始化时获取成员列表 - this.members = List.of(); - loadMembers(); - } - - private void loadMembers() { - plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(memberList -> { - this.members = memberList.stream() - .filter(member -> !member.getPlayerUuid().equals(guild.getLeaderUuid())) - .filter(member -> !member.getRole().equals(GuildMember.Role.OFFICER)) // 只显示可以提升的成员 - .collect(java.util.stream.Collectors.toList()); - }); - } - - @Override - public String getTitle() { - return ColorUtils.colorize("&6提升成员 - 第" + (currentPage + 1) + "页"); - } - - @Override - public int getSize() { - return 54; - } - - @Override - public void setupInventory(Inventory inventory) { - // 填充边框 - fillBorder(inventory); - - // 显示成员列表 - displayMembers(inventory); - - // 添加导航按钮 - setupNavigationButtons(inventory); - } - - @Override - public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { - if (slot >= 9 && slot < 45) { - // 成员头像区域 - int memberIndex = slot - 9 + (currentPage * 36); - if (memberIndex < members.size()) { - GuildMember member = members.get(memberIndex); - handlePromoteMember(player, member); - } - } else if (slot == 45) { - // 上一页 - if (currentPage > 0) { - currentPage--; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 53) { - // 下一页 - int maxPage = (members.size() - 1) / 36; - if (currentPage < maxPage) { - currentPage++; - plugin.getGuiManager().refreshGUI(player); - } - } else if (slot == 49) { - // 返回 - plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); - } - } - - /** - * 填充边框 - */ - private void fillBorder(Inventory inventory) { - ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); - for (int i = 0; i < 9; i++) { - inventory.setItem(i, border); - inventory.setItem(i + 45, border); - } - for (int i = 9; i < 45; i += 9) { - inventory.setItem(i, border); - inventory.setItem(i + 8, border); - } - } - - /** - * 显示成员列表 - */ - private void displayMembers(Inventory inventory) { - int startIndex = currentPage * 36; - int endIndex = Math.min(startIndex + 36, members.size()); - - for (int i = startIndex; i < endIndex; i++) { - GuildMember member = members.get(i); - int slot = 9 + (i - startIndex); - - ItemStack memberHead = createMemberHead(member); - inventory.setItem(slot, memberHead); - } - } - - /** - * 设置导航按钮 - */ - private void setupNavigationButtons(Inventory inventory) { - // 上一页按钮 - if (currentPage > 0) { - ItemStack prevPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e上一页"), - ColorUtils.colorize("&7点击查看上一页") - ); - inventory.setItem(45, prevPage); - } - - // 下一页按钮 - int maxPage = (members.size() - 1) / 36; - if (currentPage < maxPage) { - ItemStack nextPage = createItem( - Material.ARROW, - ColorUtils.colorize("&e下一页"), - ColorUtils.colorize("&7点击查看下一页") - ); - inventory.setItem(53, nextPage); - } - - // 返回按钮 - ItemStack back = createItem( - Material.BARRIER, - ColorUtils.colorize("&c返回"), - ColorUtils.colorize("&7返回工会设置") - ); - inventory.setItem(49, back); - } - - /** - * 创建成员头像 - */ - private ItemStack createMemberHead(GuildMember member) { - ItemStack head = new ItemStack(Material.PLAYER_HEAD); - SkullMeta meta = (SkullMeta) head.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(ColorUtils.colorize("&6" + member.getPlayerName())); - meta.setLore(Arrays.asList( - ColorUtils.colorize("&7当前职位: &e" + member.getRole().getDisplayName()), - ColorUtils.colorize("&7加入时间: &e" + member.getJoinedAt()), - ColorUtils.colorize("&6点击提升为官员") - )); - head.setItemMeta(meta); - } - - return head; - } - - /** - * 处理提升成员 - */ - private void handlePromoteMember(Player promoter, GuildMember member) { - // 检查权限 - if (!promoter.hasPermission("guild.promote")) { - String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&c权限不足"); - promoter.sendMessage(ColorUtils.colorize(message)); - return; - } - - // 提升成员 - plugin.getGuildService().updateMemberRoleAsync(member.getPlayerUuid(), GuildMember.Role.OFFICER, promoter.getUniqueId()).thenAccept(success -> { - if (success) { - String promoterMessage = plugin.getConfigManager().getMessagesConfig().getString("promote.success", "&a已提升 &e{player} &a为官员!") - .replace("{player}", member.getPlayerName()); - promoter.sendMessage(ColorUtils.colorize(promoterMessage)); - - // 通知被提升的玩家 - Player promotedPlayer = plugin.getServer().getPlayer(member.getPlayerUuid()); - if (promotedPlayer != null) { - String promotedMessage = plugin.getConfigManager().getMessagesConfig().getString("promote.promoted", "&a你被提升为工会 &e{guild} &a的官员!") - .replace("{guild}", guild.getName()); - promotedPlayer.sendMessage(ColorUtils.colorize(promotedMessage)); - } - - // 刷新GUI - plugin.getGuiManager().openGUI(promoter, new PromoteMemberGUI(plugin, guild)); - } else { - String message = plugin.getConfigManager().getMessagesConfig().getString("promote.failed", "&c提升成员失败!"); - promoter.sendMessage(ColorUtils.colorize(message)); - } - }); - } - - /** - * 创建物品 - */ - private ItemStack createItem(Material material, String name, String... lore) { - ItemStack item = new ItemStack(material); - ItemMeta meta = item.getItemMeta(); - - if (meta != null) { - meta.setDisplayName(name); - if (lore.length > 0) { - meta.setLore(Arrays.asList(lore)); - } - item.setItemMeta(meta); - } - - return item; - } -} +package com.guild.gui; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUI; +import com.guild.core.utils.ColorUtils; +import com.guild.models.Guild; +import com.guild.models.GuildMember; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * GUI Awansowania Członków + */ +public class PromoteMemberGUI implements GUI { + + private final GuildPlugin plugin; + private final Guild guild; + private int currentPage = 0; + private List members; + + public PromoteMemberGUI(GuildPlugin plugin, Guild guild) { + this.plugin = plugin; + this.guild = guild; + // Inicjalizacja listy członków + this.members = List.of(); + loadMembers(); + } + + private void loadMembers() { + plugin.getGuildService().getGuildMembersAsync(guild.getId()).thenAccept(memberList -> { + this.members = memberList.stream() + .filter(member -> !member.getPlayerUuid().equals(guild.getLeaderUuid())) + .filter(member -> !member.getRole().equals(GuildMember.Role.OFFICER)) // Pokaż tylko członków, których można awansować + .collect(java.util.stream.Collectors.toList()); + }); + } + + @Override + public String getTitle() { + return ColorUtils.colorize("&6Awansuj członka - Strona " + (currentPage + 1)); + } + + @Override + public int getSize() { + return 54; + } + + @Override + public void setupInventory(Inventory inventory) { + // Wypełnij obramowanie + fillBorder(inventory); + + // Wyświetl listę członków + displayMembers(inventory); + + // Dodaj przyciski nawigacyjne + setupNavigationButtons(inventory); + } + + @Override + public void onClick(Player player, int slot, ItemStack clickedItem, ClickType clickType) { + if (slot >= 9 && slot < 45) { + // Obszar głów członków + int memberIndex = slot - 9 + (currentPage * 36); + if (memberIndex < members.size()) { + GuildMember member = members.get(memberIndex); + handlePromoteMember(player, member); + } + } else if (slot == 45) { + // Poprzednia strona + if (currentPage > 0) { + currentPage--; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 53) { + // Następna strona + int maxPage = (members.size() - 1) / 36; + if (currentPage < maxPage) { + currentPage++; + plugin.getGuiManager().refreshGUI(player); + } + } else if (slot == 49) { + // Powrót + plugin.getGuiManager().openGUI(player, new GuildSettingsGUI(plugin, guild)); + } + } + + /** + * Wypełnij obramowanie + */ + private void fillBorder(Inventory inventory) { + ItemStack border = createItem(Material.BLACK_STAINED_GLASS_PANE, " "); + for (int i = 0; i < 9; i++) { + inventory.setItem(i, border); + inventory.setItem(i + 45, border); + } + for (int i = 9; i < 45; i += 9) { + inventory.setItem(i, border); + inventory.setItem(i + 8, border); + } + } + + /** + * Wyświetl listę członków + */ + private void displayMembers(Inventory inventory) { + int startIndex = currentPage * 36; + int endIndex = Math.min(startIndex + 36, members.size()); + + for (int i = startIndex; i < endIndex; i++) { + GuildMember member = members.get(i); + int slot = 9 + (i - startIndex); + + ItemStack memberHead = createMemberHead(member); + inventory.setItem(slot, memberHead); + } + } + + /** + * Skonfiguruj przyciski nawigacyjne + */ + private void setupNavigationButtons(Inventory inventory) { + // Przycisk poprzedniej strony + if (currentPage > 0) { + ItemStack prevPage = createItem( + Material.ARROW, + ColorUtils.colorize("&ePoprzednia strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć poprzednią stronę") + ); + inventory.setItem(45, prevPage); + } + + // Przycisk następnej strony + int maxPage = (members.size() - 1) / 36; + if (currentPage < maxPage) { + ItemStack nextPage = createItem( + Material.ARROW, + ColorUtils.colorize("&eNastępna strona"), + ColorUtils.colorize("&7Kliknij, aby zobaczyć następną stronę") + ); + inventory.setItem(53, nextPage); + } + + // Przycisk powrotu + ItemStack back = createItem( + Material.BARRIER, + ColorUtils.colorize("&cPowrót"), + ColorUtils.colorize("&7Powrót do ustawień gildii") + ); + inventory.setItem(49, back); + } + + /** + * Utwórz głowę członka + */ + private ItemStack createMemberHead(GuildMember member) { + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + SkullMeta meta = (SkullMeta) head.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(ColorUtils.colorize("&6" + member.getPlayerName())); + meta.setLore(Arrays.asList( + ColorUtils.colorize("&7Obecna rola: &e" + member.getRole().getDisplayName()), + ColorUtils.colorize("&7Dołączył: &e" + member.getJoinedAt()), + ColorUtils.colorize("&6Kliknij, aby awansować na oficera") + )); + head.setItemMeta(meta); + } + + return head; + } + + /** + * Obsługa awansu członka + */ + private void handlePromoteMember(Player promoter, GuildMember member) { + // Sprawdź uprawnienia + if (!promoter.hasPermission("guild.promote")) { + String message = plugin.getConfigManager().getMessagesConfig().getString("gui.no-permission", "&cBrak uprawnień"); + promoter.sendMessage(ColorUtils.colorize(message)); + return; + } + + // Awansuj członka + plugin.getGuildService().updateMemberRoleAsync(member.getPlayerUuid(), GuildMember.Role.OFFICER, promoter.getUniqueId()).thenAccept(success -> { + if (success) { + String promoterMessage = plugin.getConfigManager().getMessagesConfig().getString("promote.success", "&aAwansowano &e{player} &ana oficera!") + .replace("{player}", member.getPlayerName()); + promoter.sendMessage(ColorUtils.colorize(promoterMessage)); + + // Powiadom awansowanego gracza + Player promotedPlayer = plugin.getServer().getPlayer(member.getPlayerUuid()); + if (promotedPlayer != null) { + String promotedMessage = plugin.getConfigManager().getMessagesConfig().getString("promote.promoted", "&aZostałeś awansowany na oficera w gildii &e{guild}&a!") + .replace("{guild}", guild.getName()); + promotedPlayer.sendMessage(ColorUtils.colorize(promotedMessage)); + } + + // Odśwież GUI + plugin.getGuiManager().openGUI(promoter, new PromoteMemberGUI(plugin, guild)); + } else { + String message = plugin.getConfigManager().getMessagesConfig().getString("promote.failed", "&cAwansowanie członka nie powiodło się!"); + promoter.sendMessage(ColorUtils.colorize(message)); + } + }); + } + + /** + * Utwórz przedmiot + */ + private ItemStack createItem(Material material, String name, String... lore) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if (meta != null) { + meta.setDisplayName(name); + if (lore.length > 0) { + meta.setLore(Arrays.asList(lore)); + } + item.setItemMeta(meta); + } + + return item; + } +} diff --git a/src/main/java/com/guild/listeners/GuildListener.java b/src/main/java/com/guild/listeners/GuildListener.java index 6c75cec..d4e84da 100644 --- a/src/main/java/com/guild/listeners/GuildListener.java +++ b/src/main/java/com/guild/listeners/GuildListener.java @@ -6,7 +6,7 @@ import org.bukkit.event.player.PlayerChatEvent; /** - * 工会事件监听器 + * Słuchacz zdarzeń gildii */ public class GuildListener implements Listener { @@ -17,11 +17,11 @@ public GuildListener(GuildPlugin plugin) { } /** - * 玩家聊天事件(可以用于工会聊天功能) + * Zdarzenie czatu gracza (może być użyte do funkcji czatu gildii) */ @EventHandler public void onPlayerChat(PlayerChatEvent event) { - // 这里可以添加工会聊天功能 - // 比如检测工会前缀、处理工会聊天等 + // Tutaj można dodać funkcję czatu gildii + // Na przykład wykrywanie prefiksu gildii, obsługa czatu gildii itp. } } diff --git a/src/main/java/com/guild/listeners/PlayerListener.java b/src/main/java/com/guild/listeners/PlayerListener.java index 3557fa6..d48ebb7 100644 --- a/src/main/java/com/guild/listeners/PlayerListener.java +++ b/src/main/java/com/guild/listeners/PlayerListener.java @@ -1,95 +1,95 @@ -package com.guild.listeners; - -import com.guild.GuildPlugin; -import com.guild.core.gui.GUIManager; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.AsyncPlayerChatEvent; - -import com.guild.core.utils.CompatibleScheduler; - -/** - * 玩家事件监听器 - */ -public class PlayerListener implements Listener { - - private final GuildPlugin plugin; - - public PlayerListener(GuildPlugin plugin) { - this.plugin = plugin; - } - - /** - * 玩家加入服务器事件 - */ - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - // 检查工会战争状态 - checkWarStatus(event.getPlayer()); - } - - /** - * 检查工会战争状态并发送通知 - */ - private void checkWarStatus(org.bukkit.entity.Player player) { - // 异步检查玩家的工会 - plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { - if (guild != null) { - // 检查工会的所有关系 - plugin.getGuildService().getGuildRelationsAsync(guild.getId()).thenAccept(relations -> { - // 确保在主线程中执行 - CompatibleScheduler.runTask(plugin, () -> { - for (com.guild.models.GuildRelation relation : relations) { - if (relation.isWar()) { - String message = plugin.getConfigManager().getMessagesConfig().getString("relations.war-notification", "&4[工会战争] &c您的工会与 {guild} 处于开战状态!"); - message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); - player.sendMessage(com.guild.core.utils.ColorUtils.colorize(message)); - } - } - }); - }); - } - }); - } - - /** - * 玩家离开服务器事件 - */ - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - // 清理玩家的GUI状态 - GUIManager guiManager = plugin.getGuiManager(); - if (guiManager != null) { - guiManager.closeGUI(event.getPlayer()); - } - } - - /** - * 处理聊天输入事件(用于GUI输入模式) - */ - @EventHandler - public void onAsyncPlayerChat(AsyncPlayerChatEvent event) { - GUIManager guiManager = plugin.getGuiManager(); - - if (guiManager != null && guiManager.isInInputMode(event.getPlayer())) { - // 取消事件,防止消息发送到聊天 - event.setCancelled(true); - - // 处理输入 - 在主线程中执行 - String input = event.getMessage(); - CompatibleScheduler.runTask(plugin, () -> { - try { - guiManager.handleInput(event.getPlayer(), input); - } catch (Exception e) { - plugin.getLogger().severe("处理GUI输入时发生错误: " + e.getMessage()); - e.printStackTrace(); - // 发生错误时清除输入模式 - guiManager.clearInputMode(event.getPlayer()); - } - }); - } - } -} +package com.guild.listeners; + +import com.guild.GuildPlugin; +import com.guild.core.gui.GUIManager; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +import com.guild.core.utils.CompatibleScheduler; + +/** + * Słuchacz zdarzeń gracza + */ +public class PlayerListener implements Listener { + + private final GuildPlugin plugin; + + public PlayerListener(GuildPlugin plugin) { + this.plugin = plugin; + } + + /** + * Zdarzenie dołączenia gracza do serwera + */ + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + // Sprawdź status wojny gildii + checkWarStatus(event.getPlayer()); + } + + /** + * Sprawdź status wojny gildii i wyślij powiadomienie + */ + private void checkWarStatus(org.bukkit.entity.Player player) { + // Asynchronicznie sprawdź gildię gracza + plugin.getGuildService().getPlayerGuildAsync(player.getUniqueId()).thenAccept(guild -> { + if (guild != null) { + // Sprawdź wszystkie relacje gildii + plugin.getGuildService().getGuildRelationsAsync(guild.getId()).thenAccept(relations -> { + // Upewnij się, że wykonujesz w głównym wątku + CompatibleScheduler.runTask(plugin, () -> { + for (com.guild.models.GuildRelation relation : relations) { + if (relation.isWar()) { + String message = plugin.getConfigManager().getMessagesConfig().getString("relations.war-notification", "&4[Wojna Gildii] &cTwoja gildia jest w stanie wojny z {guild}!"); + message = message.replace("{guild}", relation.getOtherGuildName(guild.getId())); + player.sendMessage(com.guild.core.utils.ColorUtils.colorize(message)); + } + } + }); + }); + } + }); + } + + /** + * Zdarzenie opuszczenia serwera przez gracza + */ + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + // Wyczyść stan GUI gracza + GUIManager guiManager = plugin.getGuiManager(); + if (guiManager != null) { + guiManager.closeGUI(event.getPlayer()); + } + } + + /** + * Obsłuż zdarzenie wejścia czatu (używane w trybie wprowadzania GUI) + */ + @EventHandler + public void onAsyncPlayerChat(AsyncPlayerChatEvent event) { + GUIManager guiManager = plugin.getGuiManager(); + + if (guiManager != null && guiManager.isInInputMode(event.getPlayer())) { + // Anuluj zdarzenie, aby zapobiec wysyłaniu wiadomości na czat + event.setCancelled(true); + + // Przetwórz wejście - wykonaj w głównym wątku + String input = event.getMessage(); + CompatibleScheduler.runTask(plugin, () -> { + try { + guiManager.handleInput(event.getPlayer(), input); + } catch (Exception e) { + plugin.getLogger().severe("Błąd podczas przetwarzania wejścia GUI: " + e.getMessage()); + e.printStackTrace(); + // Wyczyść tryb wprowadzania w przypadku błędu + guiManager.clearInputMode(event.getPlayer()); + } + }); + } + } +} diff --git a/src/main/java/com/guild/models/Guild.java b/src/main/java/com/guild/models/Guild.java index 9ecac0d..1cb208e 100644 --- a/src/main/java/com/guild/models/Guild.java +++ b/src/main/java/com/guild/models/Guild.java @@ -5,7 +5,7 @@ import org.bukkit.Location; /** - * 工会数据模型 + * Model danych gildii */ public class Guild { @@ -105,7 +105,7 @@ public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; } - // 家的位置相关方法 + // Metody związane z lokalizacją domu public String getHomeWorld() { return homeWorld; } @@ -187,14 +187,14 @@ public void setFrozen(boolean frozen) { } /** - * 检查工会是否设置了家 + * Sprawdź, czy gildia ma ustawiony dom */ public boolean hasHome() { return homeWorld != null && !homeWorld.isEmpty(); } /** - * 设置家的位置 + * Ustaw lokalizację domu */ public void setHome(Location location) { this.homeWorld = location.getWorld().getName(); @@ -206,7 +206,7 @@ public void setHome(Location location) { } /** - * 获取家的位置(需要传入世界对象) + * Pobierz lokalizację domu (wymaga obiektu świata) */ public Location getHomeLocation(org.bukkit.World world) { if (!hasHome() || world == null) { diff --git a/src/main/java/com/guild/models/GuildApplication.java b/src/main/java/com/guild/models/GuildApplication.java index 87035f8..5f133bd 100644 --- a/src/main/java/com/guild/models/GuildApplication.java +++ b/src/main/java/com/guild/models/GuildApplication.java @@ -4,7 +4,7 @@ import java.util.UUID; /** - * 工会申请数据模型 + * Model danych aplikacji do gildii */ public class GuildApplication { diff --git a/src/main/java/com/guild/models/GuildContribution.java b/src/main/java/com/guild/models/GuildContribution.java index 6311390..4f6a1be 100644 --- a/src/main/java/com/guild/models/GuildContribution.java +++ b/src/main/java/com/guild/models/GuildContribution.java @@ -1,138 +1,138 @@ -package com.guild.models; - -import java.time.LocalDateTime; -import java.util.UUID; - -/** - * 工会贡献记录数据模型 - */ -public class GuildContribution { - - private int id; - private int guildId; - private UUID playerUuid; - private String playerName; - private double amount; - private ContributionType type; - private String description; - private LocalDateTime createdAt; - - public enum ContributionType { - DEPOSIT("存款"), - WITHDRAW("取款"), - TRANSFER("转账"), - CREATION("创建工会"), - UPGRADE("升级工会"), - ADMIN("管理员操作"); - - private final String displayName; - - ContributionType(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } - } - - public GuildContribution() {} - - public GuildContribution(int guildId, UUID playerUuid, String playerName, - double amount, ContributionType type, String description) { - this.guildId = guildId; - this.playerUuid = playerUuid; - this.playerName = playerName; - this.amount = amount; - this.type = type; - this.description = description; - this.createdAt = LocalDateTime.now(); - } - - // Getters and Setters - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getGuildId() { - return guildId; - } - - public void setGuildId(int guildId) { - this.guildId = guildId; - } - - public UUID getPlayerUuid() { - return playerUuid; - } - - public void setPlayerUuid(UUID playerUuid) { - this.playerUuid = playerUuid; - } - - public String getPlayerName() { - return playerName; - } - - public void setPlayerName(String playerName) { - this.playerName = playerName; - } - - public double getAmount() { - return amount; - } - - public void setAmount(double amount) { - this.amount = amount; - } - - public ContributionType getType() { - return type; - } - - public void setType(ContributionType type) { - this.type = type; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - /** - * 获取总贡献(存款 - 取款) - */ - public double getNetContribution() { - if (type == ContributionType.WITHDRAW) { - return -amount; - } - return amount; - } - - @Override - public String toString() { - return "GuildContribution{" + - "id=" + id + - ", guildId=" + guildId + - ", playerName='" + playerName + '\'' + - ", amount=" + amount + - ", type=" + type + - ", description='" + description + '\'' + - '}'; - } -} +package com.guild.models; + +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * Model danych rejestru wkładów gildii + */ +public class GuildContribution { + + private int id; + private int guildId; + private UUID playerUuid; + private String playerName; + private double amount; + private ContributionType type; + private String description; + private LocalDateTime createdAt; + + public enum ContributionType { + DEPOSIT("Wpłata"), + WITHDRAW("Wypłata"), + TRANSFER("Przelew"), + CREATION("Utworzenie gildii"), + UPGRADE("Ulepszenie gildii"), + ADMIN("Operacja admina"); + + private final String displayName; + + ContributionType(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + } + + public GuildContribution() {} + + public GuildContribution(int guildId, UUID playerUuid, String playerName, + double amount, ContributionType type, String description) { + this.guildId = guildId; + this.playerUuid = playerUuid; + this.playerName = playerName; + this.amount = amount; + this.type = type; + this.description = description; + this.createdAt = LocalDateTime.now(); + } + + // Getters and Setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getGuildId() { + return guildId; + } + + public void setGuildId(int guildId) { + this.guildId = guildId; + } + + public UUID getPlayerUuid() { + return playerUuid; + } + + public void setPlayerUuid(UUID playerUuid) { + this.playerUuid = playerUuid; + } + + public String getPlayerName() { + return playerName; + } + + public void setPlayerName(String playerName) { + this.playerName = playerName; + } + + public double getAmount() { + return amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public ContributionType getType() { + return type; + } + + public void setType(ContributionType type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + /** + * Uzyskaj wkład netto (wpłaty - wypłaty) + */ + public double getNetContribution() { + if (type == ContributionType.WITHDRAW) { + return -amount; + } + return amount; + } + + @Override + public String toString() { + return "GuildContribution{" + + "id=" + id + + ", guildId=" + guildId + + ", playerName='" + playerName + '\'' + + ", amount=" + amount + + ", type=" + type + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/src/main/java/com/guild/models/GuildEconomy.java b/src/main/java/com/guild/models/GuildEconomy.java index aab495d..0153d69 100644 --- a/src/main/java/com/guild/models/GuildEconomy.java +++ b/src/main/java/com/guild/models/GuildEconomy.java @@ -1,203 +1,203 @@ -package com.guild.models; - -import java.time.LocalDateTime; -import java.util.UUID; - -/** - * 工会经济系统数据模型 - */ -public class GuildEconomy { - - private int id; - private int guildId; - private double balance; - private int level; - private double experience; - private double maxExperience; - private int maxMembers; - private LocalDateTime lastUpdated; - - public GuildEconomy() {} - - public GuildEconomy(int guildId) { - this.guildId = guildId; - this.balance = 0.0; - this.level = 1; - this.experience = 0.0; - this.maxExperience = 5000.0; - this.maxMembers = 6; - this.lastUpdated = LocalDateTime.now(); - } - - // Getters and Setters - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getGuildId() { - return guildId; - } - - public void setGuildId(int guildId) { - this.guildId = guildId; - } - - public double getBalance() { - return balance; - } - - public void setBalance(double balance) { - this.balance = balance; - this.lastUpdated = LocalDateTime.now(); - } - - public int getLevel() { - return level; - } - - public void setLevel(int level) { - this.level = level; - this.lastUpdated = LocalDateTime.now(); - } - - public double getExperience() { - return experience; - } - - public void setExperience(double experience) { - this.experience = experience; - this.lastUpdated = LocalDateTime.now(); - } - - public double getMaxExperience() { - return maxExperience; - } - - public void setMaxExperience(double maxExperience) { - this.maxExperience = maxExperience; - } - - public int getMaxMembers() { - return maxMembers; - } - - public void setMaxMembers(int maxMembers) { - this.maxMembers = maxMembers; - } - - public LocalDateTime getLastUpdated() { - return lastUpdated; - } - - public void setLastUpdated(LocalDateTime lastUpdated) { - this.lastUpdated = lastUpdated; - } - - /** - * 添加资金 - */ - public void addBalance(double amount) { - this.balance += amount; - this.lastUpdated = LocalDateTime.now(); - } - - /** - * 扣除资金 - */ - public boolean deductBalance(double amount) { - if (this.balance >= amount) { - this.balance -= amount; - this.lastUpdated = LocalDateTime.now(); - return true; - } - return false; - } - - /** - * 检查是否可以升级 - */ - public boolean canLevelUp() { - return this.balance >= this.maxExperience && this.level < 10; - } - - /** - * 升级工会 - */ - public boolean levelUp() { - if (canLevelUp()) { - this.level++; - this.balance -= this.maxExperience; - this.experience = this.balance; - - // 计算下一级所需经验 - this.maxExperience = calculateNextLevelExperience(); - this.maxMembers = calculateMaxMembers(); - - this.lastUpdated = LocalDateTime.now(); - return true; - } - return false; - } - - /** - * 计算下一级所需经验 - */ - private double calculateNextLevelExperience() { - switch (this.level) { - case 1: return 5000.0; - case 2: return 10000.0; - case 3: return 20000.0; - case 4: return 40000.0; - case 5: return 80000.0; - case 6: return 160000.0; - case 7: return 320000.0; - case 8: return 640000.0; - case 9: return 1280000.0; - default: return Double.MAX_VALUE; - } - } - - /** - * 计算最大成员数 - */ - private int calculateMaxMembers() { - switch (this.level) { - case 1: return 6; - case 2: return 12; - case 3: return 20; - case 4: return 30; - case 5: return 40; - case 6: return 50; - case 7: return 60; - case 8: return 75; - case 9: return 85; - case 10: return 100; - default: return 100; - } - } - - /** - * 获取升级进度百分比 - */ - public double getUpgradeProgress() { - if (this.level >= 10) { - return 100.0; - } - return (this.balance / this.maxExperience) * 100.0; - } - - @Override - public String toString() { - return "GuildEconomy{" + - "id=" + id + - ", guildId=" + guildId + - ", balance=" + balance + - ", level=" + level + - ", maxMembers=" + maxMembers + - '}'; - } -} +package com.guild.models; + +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * Model danych ekonomii gildii + */ +public class GuildEconomy { + + private int id; + private int guildId; + private double balance; + private int level; + private double experience; + private double maxExperience; + private int maxMembers; + private LocalDateTime lastUpdated; + + public GuildEconomy() {} + + public GuildEconomy(int guildId) { + this.guildId = guildId; + this.balance = 0.0; + this.level = 1; + this.experience = 0.0; + this.maxExperience = 5000.0; + this.maxMembers = 6; + this.lastUpdated = LocalDateTime.now(); + } + + // Getters and Setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getGuildId() { + return guildId; + } + + public void setGuildId(int guildId) { + this.guildId = guildId; + } + + public double getBalance() { + return balance; + } + + public void setBalance(double balance) { + this.balance = balance; + this.lastUpdated = LocalDateTime.now(); + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + this.lastUpdated = LocalDateTime.now(); + } + + public double getExperience() { + return experience; + } + + public void setExperience(double experience) { + this.experience = experience; + this.lastUpdated = LocalDateTime.now(); + } + + public double getMaxExperience() { + return maxExperience; + } + + public void setMaxExperience(double maxExperience) { + this.maxExperience = maxExperience; + } + + public int getMaxMembers() { + return maxMembers; + } + + public void setMaxMembers(int maxMembers) { + this.maxMembers = maxMembers; + } + + public LocalDateTime getLastUpdated() { + return lastUpdated; + } + + public void setLastUpdated(LocalDateTime lastUpdated) { + this.lastUpdated = lastUpdated; + } + + /** + * Dodaj fundusze + */ + public void addBalance(double amount) { + this.balance += amount; + this.lastUpdated = LocalDateTime.now(); + } + + /** + * Potrąć fundusze + */ + public boolean deductBalance(double amount) { + if (this.balance >= amount) { + this.balance -= amount; + this.lastUpdated = LocalDateTime.now(); + return true; + } + return false; + } + + /** + * Sprawdź, czy można awansować + */ + public boolean canLevelUp() { + return this.balance >= this.maxExperience && this.level < 10; + } + + /** + * Awansuj gildię + */ + public boolean levelUp() { + if (canLevelUp()) { + this.level++; + this.balance -= this.maxExperience; + this.experience = this.balance; + + // Oblicz wymagane doświadczenie dla następnego poziomu + this.maxExperience = calculateNextLevelExperience(); + this.maxMembers = calculateMaxMembers(); + + this.lastUpdated = LocalDateTime.now(); + return true; + } + return false; + } + + /** + * Oblicz wymagane doświadczenie dla następnego poziomu + */ + private double calculateNextLevelExperience() { + switch (this.level) { + case 1: return 5000.0; + case 2: return 10000.0; + case 3: return 20000.0; + case 4: return 40000.0; + case 5: return 80000.0; + case 6: return 160000.0; + case 7: return 320000.0; + case 8: return 640000.0; + case 9: return 1280000.0; + default: return Double.MAX_VALUE; + } + } + + /** + * Oblicz maksymalną liczbę członków + */ + private int calculateMaxMembers() { + switch (this.level) { + case 1: return 6; + case 2: return 12; + case 3: return 20; + case 4: return 30; + case 5: return 40; + case 6: return 50; + case 7: return 60; + case 8: return 75; + case 9: return 85; + case 10: return 100; + default: return 100; + } + } + + /** + * Pobierz procent postępu ulepszania + */ + public double getUpgradeProgress() { + if (this.level >= 10) { + return 100.0; + } + return (this.balance / this.maxExperience) * 100.0; + } + + @Override + public String toString() { + return "GuildEconomy{" + + "id=" + id + + ", guildId=" + guildId + + ", balance=" + balance + + ", level=" + level + + ", maxMembers=" + maxMembers + + '}'; + } +} diff --git a/src/main/java/com/guild/models/GuildInvitation.java b/src/main/java/com/guild/models/GuildInvitation.java index 5034977..02f107e 100644 --- a/src/main/java/com/guild/models/GuildInvitation.java +++ b/src/main/java/com/guild/models/GuildInvitation.java @@ -1,145 +1,145 @@ -package com.guild.models; - -import java.time.LocalDateTime; -import java.util.UUID; - -/** - * 工会邀请数据模型 - */ -public class GuildInvitation { - - private int id; - private int guildId; - private UUID inviterUuid; - private String inviterName; - private UUID targetUuid; - private String targetName; - private LocalDateTime invitedAt; - private LocalDateTime expiresAt; - private InvitationStatus status; - - public GuildInvitation() {} - - public GuildInvitation(int guildId, UUID inviterUuid, String inviterName, UUID targetUuid, String targetName) { - this.guildId = guildId; - this.inviterUuid = inviterUuid; - this.inviterName = inviterName; - this.targetUuid = targetUuid; - this.targetName = targetName; - this.invitedAt = LocalDateTime.now(); - this.expiresAt = LocalDateTime.now().plusMinutes(30); // 30分钟过期 - this.status = InvitationStatus.PENDING; - } - - // Getters and Setters - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getGuildId() { - return guildId; - } - - public void setGuildId(int guildId) { - this.guildId = guildId; - } - - public UUID getInviterUuid() { - return inviterUuid; - } - - public void setInviterUuid(UUID inviterUuid) { - this.inviterUuid = inviterUuid; - } - - public String getInviterName() { - return inviterName; - } - - public void setInviterName(String inviterName) { - this.inviterName = inviterName; - } - - public UUID getTargetUuid() { - return targetUuid; - } - - public void setTargetUuid(UUID targetUuid) { - this.targetUuid = targetUuid; - } - - public String getTargetName() { - return targetName; - } - - public void setTargetName(String targetName) { - this.targetName = targetName; - } - - public LocalDateTime getInvitedAt() { - return invitedAt; - } - - public void setInvitedAt(LocalDateTime invitedAt) { - this.invitedAt = invitedAt; - } - - public LocalDateTime getExpiresAt() { - return expiresAt; - } - - public void setExpiresAt(LocalDateTime expiresAt) { - this.expiresAt = expiresAt; - } - - public InvitationStatus getStatus() { - return status; - } - - public void setStatus(InvitationStatus status) { - this.status = status; - } - - public boolean isExpired() { - return LocalDateTime.now().isAfter(expiresAt); - } - - /** - * 邀请状态枚举 - */ - public enum InvitationStatus { - PENDING("待处理"), - ACCEPTED("已接受"), - DECLINED("已拒绝"), - EXPIRED("已过期"); - - private final String displayName; - - InvitationStatus(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } - } - - @Override - public String toString() { - return "GuildInvitation{" + - "id=" + id + - ", guildId=" + guildId + - ", inviterUuid=" + inviterUuid + - ", inviterName='" + inviterName + '\'' + - ", targetUuid=" + targetUuid + - ", targetName='" + targetName + '\'' + - ", invitedAt=" + invitedAt + - ", expiresAt=" + expiresAt + - ", status=" + status + - '}'; - } -} +package com.guild.models; + +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * Model danych zaproszenia do gildii + */ +public class GuildInvitation { + + private int id; + private int guildId; + private UUID inviterUuid; + private String inviterName; + private UUID targetUuid; + private String targetName; + private LocalDateTime invitedAt; + private LocalDateTime expiresAt; + private InvitationStatus status; + + public GuildInvitation() {} + + public GuildInvitation(int guildId, UUID inviterUuid, String inviterName, UUID targetUuid, String targetName) { + this.guildId = guildId; + this.inviterUuid = inviterUuid; + this.inviterName = inviterName; + this.targetUuid = targetUuid; + this.targetName = targetName; + this.invitedAt = LocalDateTime.now(); + this.expiresAt = LocalDateTime.now().plusMinutes(30); // wygasa za 30 minut + this.status = InvitationStatus.PENDING; + } + + // Getters and Setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getGuildId() { + return guildId; + } + + public void setGuildId(int guildId) { + this.guildId = guildId; + } + + public UUID getInviterUuid() { + return inviterUuid; + } + + public void setInviterUuid(UUID inviterUuid) { + this.inviterUuid = inviterUuid; + } + + public String getInviterName() { + return inviterName; + } + + public void setInviterName(String inviterName) { + this.inviterName = inviterName; + } + + public UUID getTargetUuid() { + return targetUuid; + } + + public void setTargetUuid(UUID targetUuid) { + this.targetUuid = targetUuid; + } + + public String getTargetName() { + return targetName; + } + + public void setTargetName(String targetName) { + this.targetName = targetName; + } + + public LocalDateTime getInvitedAt() { + return invitedAt; + } + + public void setInvitedAt(LocalDateTime invitedAt) { + this.invitedAt = invitedAt; + } + + public LocalDateTime getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(LocalDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + public InvitationStatus getStatus() { + return status; + } + + public void setStatus(InvitationStatus status) { + this.status = status; + } + + public boolean isExpired() { + return LocalDateTime.now().isAfter(expiresAt); + } + + /** + * Enumeracja statusu zaproszenia + */ + public enum InvitationStatus { + PENDING("Oczekujące"), + ACCEPTED("Zaakceptowane"), + DECLINED("Odrzucone"), + EXPIRED("Wygasłe"); + + private final String displayName; + + InvitationStatus(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + } + + @Override + public String toString() { + return "GuildInvitation{" + + "id=" + id + + ", guildId=" + guildId + + ", inviterUuid=" + inviterUuid + + ", inviterName='" + inviterName + '\'' + + ", targetUuid=" + targetUuid + + ", targetName='" + targetName + '\'' + + ", invitedAt=" + invitedAt + + ", expiresAt=" + expiresAt + + ", status=" + status + + '}'; + } +} diff --git a/src/main/java/com/guild/models/GuildLog.java b/src/main/java/com/guild/models/GuildLog.java index b179ea2..2f5bf6b 100644 --- a/src/main/java/com/guild/models/GuildLog.java +++ b/src/main/java/com/guild/models/GuildLog.java @@ -1,179 +1,179 @@ -package com.guild.models; - -import java.time.LocalDateTime; - -/** - * 工会日志模型 - * 用于记录工会的各种操作历史 - */ -public class GuildLog { - private int id; - private int guildId; - private String guildName; - private String playerUuid; - private String playerName; - private LogType logType; - private String description; - private String details; - private LocalDateTime createdAt; - - public GuildLog() { - } - - public GuildLog(int guildId, String guildName, String playerUuid, String playerName, - LogType logType, String description, String details) { - this.guildId = guildId; - this.guildName = guildName; - this.playerUuid = playerUuid; - this.playerName = playerName; - this.logType = logType; - this.description = description; - this.details = details; - this.createdAt = LocalDateTime.now(); - } - - // Getters and Setters - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getGuildId() { - return guildId; - } - - public void setGuildId(int guildId) { - this.guildId = guildId; - } - - public String getGuildName() { - return guildName; - } - - public void setGuildName(String guildName) { - this.guildName = guildName; - } - - public String getPlayerUuid() { - return playerUuid; - } - - public void setPlayerUuid(String playerUuid) { - this.playerUuid = playerUuid; - } - - public String getPlayerName() { - return playerName; - } - - public void setPlayerName(String playerName) { - this.playerName = playerName; - } - - public LogType getLogType() { - return logType; - } - - public void setLogType(LogType logType) { - this.logType = logType; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getDetails() { - return details; - } - - public void setDetails(String details) { - this.details = details; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - /** - * 日志类型枚举 - */ - public enum LogType { - GUILD_CREATED("工会创建"), - GUILD_DISSOLVED("工会解散"), - GUILD_RENAMED("工会改名"), - MEMBER_JOINED("成员加入"), - MEMBER_LEFT("成员退出"), - MEMBER_KICKED("成员被踢出"), - MEMBER_PROMOTED("成员升职"), - MEMBER_DEMOTED("成员降职"), - LEADER_TRANSFERRED("会长转让"), - FUND_DEPOSITED("资金存入"), - FUND_WITHDRAWN("资金取出"), - FUND_TRANSFERRED("资金转账"), - RELATION_CREATED("关系建立"), - RELATION_DELETED("关系删除"), - RELATION_ACCEPTED("关系接受"), - RELATION_REJECTED("关系拒绝"), - GUILD_FROZEN("工会冻结"), - GUILD_UNFROZEN("工会解冻"), - GUILD_LEVEL_UP("工会升级"), - APPLICATION_SUBMITTED("申请提交"), - APPLICATION_ACCEPTED("申请接受"), - APPLICATION_REJECTED("申请拒绝"), - INVITATION_SENT("邀请发送"), - INVITATION_ACCEPTED("邀请接受"), - INVITATION_REJECTED("邀请拒绝"); - - private final String displayName; - - LogType(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } - } - - /** - * 获取格式化的时间字符串 - */ - public String getFormattedTime() { - if (createdAt == null) return "未知"; - return createdAt.format(com.guild.core.time.TimeProvider.FULL_FORMATTER); - } - - /** - * 获取简化的时间字符串(用于显示) - */ - public String getSimpleTime() { - if (createdAt == null) return "未知"; - LocalDateTime now = LocalDateTime.now(); - java.time.Duration duration = java.time.Duration.between(createdAt, now); - - long days = duration.toDays(); - long hours = duration.toHours() % 24; - long minutes = duration.toMinutes() % 60; - - if (days > 0) { - return days + "天前"; - } else if (hours > 0) { - return hours + "小时前"; - } else if (minutes > 0) { - return minutes + "分钟前"; - } else { - return "刚刚"; - } - } -} +package com.guild.models; + +import java.time.LocalDateTime; + +/** + * Model dziennika gildii + * Służy do rejestrowania historii różnych operacji gildii + */ +public class GuildLog { + private int id; + private int guildId; + private String guildName; + private String playerUuid; + private String playerName; + private LogType logType; + private String description; + private String details; + private LocalDateTime createdAt; + + public GuildLog() { + } + + public GuildLog(int guildId, String guildName, String playerUuid, String playerName, + LogType logType, String description, String details) { + this.guildId = guildId; + this.guildName = guildName; + this.playerUuid = playerUuid; + this.playerName = playerName; + this.logType = logType; + this.description = description; + this.details = details; + this.createdAt = LocalDateTime.now(); + } + + // Getters and Setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getGuildId() { + return guildId; + } + + public void setGuildId(int guildId) { + this.guildId = guildId; + } + + public String getGuildName() { + return guildName; + } + + public void setGuildName(String guildName) { + this.guildName = guildName; + } + + public String getPlayerUuid() { + return playerUuid; + } + + public void setPlayerUuid(String playerUuid) { + this.playerUuid = playerUuid; + } + + public String getPlayerName() { + return playerName; + } + + public void setPlayerName(String playerName) { + this.playerName = playerName; + } + + public LogType getLogType() { + return logType; + } + + public void setLogType(LogType logType) { + this.logType = logType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + /** + * Enumeracja typu dziennika + */ + public enum LogType { + GUILD_CREATED("Utworzenie gildii"), + GUILD_DISSOLVED("Rozwiązanie gildii"), + GUILD_RENAMED("Zmiana nazwy gildii"), + MEMBER_JOINED("Dołączenie członka"), + MEMBER_LEFT("Opuszczenie członka"), + MEMBER_KICKED("Wyrzucenie członka"), + MEMBER_PROMOTED("Awans członka"), + MEMBER_DEMOTED("Degradacja członka"), + LEADER_TRANSFERRED("Przekazanie lidera"), + FUND_DEPOSITED("Wpłata funduszy"), + FUND_WITHDRAWN("Wypłata funduszy"), + FUND_TRANSFERRED("Przelew funduszy"), + RELATION_CREATED("Utworzenie relacji"), + RELATION_DELETED("Usunięcie relacji"), + RELATION_ACCEPTED("Akceptacja relacji"), + RELATION_REJECTED("Odrzucenie relacji"), + GUILD_FROZEN("Zamrożenie gildii"), + GUILD_UNFROZEN("Odmrożenie gildii"), + GUILD_LEVEL_UP("Awans gildii"), + APPLICATION_SUBMITTED("Złożenie aplikacji"), + APPLICATION_ACCEPTED("Akceptacja aplikacji"), + APPLICATION_REJECTED("Odrzucenie aplikacji"), + INVITATION_SENT("Wysłanie zaproszenia"), + INVITATION_ACCEPTED("Akceptacja zaproszenia"), + INVITATION_REJECTED("Odrzucenie zaproszenia"); + + private final String displayName; + + LogType(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + } + + /** + * Pobierz sformatowany ciąg czasu + */ + public String getFormattedTime() { + if (createdAt == null) return "Nieznany"; + return createdAt.format(com.guild.core.time.TimeProvider.FULL_FORMATTER); + } + + /** + * Pobierz uproszczony ciąg czasu (do wyświetlania) + */ + public String getSimpleTime() { + if (createdAt == null) return "Nieznany"; + LocalDateTime now = LocalDateTime.now(); + java.time.Duration duration = java.time.Duration.between(createdAt, now); + + long days = duration.toDays(); + long hours = duration.toHours() % 24; + long minutes = duration.toMinutes() % 60; + + if (days > 0) { + return days + " dni temu"; + } else if (hours > 0) { + return hours + " godz. temu"; + } else if (minutes > 0) { + return minutes + " min. temu"; + } else { + return "Przed chwilą"; + } + } +} diff --git a/src/main/java/com/guild/models/GuildMember.java b/src/main/java/com/guild/models/GuildMember.java index ab7158d..c5960e4 100644 --- a/src/main/java/com/guild/models/GuildMember.java +++ b/src/main/java/com/guild/models/GuildMember.java @@ -4,7 +4,7 @@ import java.util.UUID; /** - * 工会成员数据模型 + * Model danych członka gildii */ public class GuildMember { diff --git a/src/main/java/com/guild/models/GuildRelation.java b/src/main/java/com/guild/models/GuildRelation.java index 166a4ad..982bbbc 100644 --- a/src/main/java/com/guild/models/GuildRelation.java +++ b/src/main/java/com/guild/models/GuildRelation.java @@ -1,219 +1,219 @@ -package com.guild.models; - -import java.time.LocalDateTime; -import java.util.UUID; - -/** - * 工会关系数据模型 - */ -public class GuildRelation { - - private int id; - private int guild1Id; - private int guild2Id; - private String guild1Name; - private String guild2Name; - private RelationType type; - private RelationStatus status; - private UUID initiatorUuid; - private String initiatorName; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; - private LocalDateTime expiresAt; - - public enum RelationType { - ALLY("盟友", "&a"), - ENEMY("敌对", "&c"), - WAR("开战", "&4"), - TRUCE("停战", "&e"), - NEUTRAL("中立", "&7"); - - private final String displayName; - private final String color; - - RelationType(String displayName, String color) { - this.displayName = displayName; - this.color = color; - } - - public String getDisplayName() { - return displayName; - } - - public String getColor() { - return color; - } - } - - public enum RelationStatus { - PENDING("待处理"), - ACTIVE("活跃"), - EXPIRED("已过期"), - CANCELLED("已取消"); - - private final String displayName; - - RelationStatus(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } - } - - public GuildRelation() {} - - public GuildRelation(int guild1Id, int guild2Id, String guild1Name, String guild2Name, - RelationType type, UUID initiatorUuid, String initiatorName) { - this.guild1Id = guild1Id; - this.guild2Id = guild2Id; - this.guild1Name = guild1Name; - this.guild2Name = guild2Name; - this.type = type; - this.status = RelationStatus.PENDING; - this.initiatorUuid = initiatorUuid; - this.initiatorName = initiatorName; - this.createdAt = LocalDateTime.now(); - this.updatedAt = LocalDateTime.now(); - - // 设置过期时间(7天后) - this.expiresAt = LocalDateTime.now().plusDays(7); - } - - // Getters and Setters - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getGuild1Id() { - return guild1Id; - } - - public void setGuild1Id(int guild1Id) { - this.guild1Id = guild1Id; - } - - public int getGuild2Id() { - return guild2Id; - } - - public void setGuild2Id(int guild2Id) { - this.guild2Id = guild2Id; - } - - public String getGuild1Name() { - return guild1Name; - } - - public void setGuild1Name(String guild1Name) { - this.guild1Name = guild1Name; - } - - public String getGuild2Name() { - return guild2Name; - } - - public void setGuild2Name(String guild2Name) { - this.guild2Name = guild2Name; - } - - public RelationType getType() { - return type; - } - - public void setType(RelationType type) { - this.type = type; - } - - public RelationStatus getStatus() { - return status; - } - - public void setStatus(RelationStatus status) { - this.status = status; - } - - public UUID getInitiatorUuid() { - return initiatorUuid; - } - - public void setInitiatorUuid(UUID initiatorUuid) { - this.initiatorUuid = initiatorUuid; - } - - public String getInitiatorName() { - return initiatorName; - } - - public void setInitiatorName(String initiatorName) { - this.initiatorName = initiatorName; - } - - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(LocalDateTime createdAt) { - this.createdAt = createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(LocalDateTime updatedAt) { - this.updatedAt = updatedAt; - } - - public LocalDateTime getExpiresAt() { - return expiresAt; - } - - public void setExpiresAt(LocalDateTime expiresAt) { - this.expiresAt = expiresAt; - } - - /** - * 检查关系是否已过期 - */ - public boolean isExpired() { - return expiresAt != null && LocalDateTime.now().isAfter(expiresAt); - } - - /** - * 检查是否为开战状态 - */ - public boolean isWar() { - return type == RelationType.WAR && status == RelationStatus.ACTIVE; - } - - /** - * 获取另一个工会的ID - */ - public int getOtherGuildId(int currentGuildId) { - return guild1Id == currentGuildId ? guild2Id : guild1Id; - } - - /** - * 获取另一个工会的名称 - */ - public String getOtherGuildName(int currentGuildId) { - return guild1Id == currentGuildId ? guild2Name : guild1Name; - } - - @Override - public String toString() { - return "GuildRelation{" + - "id=" + id + - ", guild1Id=" + guild1Id + - ", guild2Id=" + guild2Id + - ", type=" + type + - ", status=" + status + - '}'; - } -} +package com.guild.models; + +import java.time.LocalDateTime; +import java.util.UUID; + +/** + * Model danych relacji gildii + */ +public class GuildRelation { + + private int id; + private int guild1Id; + private int guild2Id; + private String guild1Name; + private String guild2Name; + private RelationType type; + private RelationStatus status; + private UUID initiatorUuid; + private String initiatorName; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + private LocalDateTime expiresAt; + + public enum RelationType { + ALLY("Sojusznik", "&a"), + ENEMY("Wróg", "&c"), + WAR("Wojna", "&4"), + TRUCE("Rozejm", "&e"), + NEUTRAL("Neutralny", "&7"); + + private final String displayName; + private final String color; + + RelationType(String displayName, String color) { + this.displayName = displayName; + this.color = color; + } + + public String getDisplayName() { + return displayName; + } + + public String getColor() { + return color; + } + } + + public enum RelationStatus { + PENDING("Oczekujące"), + ACTIVE("Aktywne"), + EXPIRED("Wygasłe"), + CANCELLED("Anulowane"); + + private final String displayName; + + RelationStatus(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + } + + public GuildRelation() {} + + public GuildRelation(int guild1Id, int guild2Id, String guild1Name, String guild2Name, + RelationType type, UUID initiatorUuid, String initiatorName) { + this.guild1Id = guild1Id; + this.guild2Id = guild2Id; + this.guild1Name = guild1Name; + this.guild2Name = guild2Name; + this.type = type; + this.status = RelationStatus.PENDING; + this.initiatorUuid = initiatorUuid; + this.initiatorName = initiatorName; + this.createdAt = LocalDateTime.now(); + this.updatedAt = LocalDateTime.now(); + + // Ustaw czas wygaśnięcia (7 dni później) + this.expiresAt = LocalDateTime.now().plusDays(7); + } + + // Getters and Setters + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getGuild1Id() { + return guild1Id; + } + + public void setGuild1Id(int guild1Id) { + this.guild1Id = guild1Id; + } + + public int getGuild2Id() { + return guild2Id; + } + + public void setGuild2Id(int guild2Id) { + this.guild2Id = guild2Id; + } + + public String getGuild1Name() { + return guild1Name; + } + + public void setGuild1Name(String guild1Name) { + this.guild1Name = guild1Name; + } + + public String getGuild2Name() { + return guild2Name; + } + + public void setGuild2Name(String guild2Name) { + this.guild2Name = guild2Name; + } + + public RelationType getType() { + return type; + } + + public void setType(RelationType type) { + this.type = type; + } + + public RelationStatus getStatus() { + return status; + } + + public void setStatus(RelationStatus status) { + this.status = status; + } + + public UUID getInitiatorUuid() { + return initiatorUuid; + } + + public void setInitiatorUuid(UUID initiatorUuid) { + this.initiatorUuid = initiatorUuid; + } + + public String getInitiatorName() { + return initiatorName; + } + + public void setInitiatorName(String initiatorName) { + this.initiatorName = initiatorName; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public LocalDateTime getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(LocalDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + /** + * Sprawdź, czy relacja wygasła + */ + public boolean isExpired() { + return expiresAt != null && LocalDateTime.now().isAfter(expiresAt); + } + + /** + * Sprawdź, czy jest w stanie wojny + */ + public boolean isWar() { + return type == RelationType.WAR && status == RelationStatus.ACTIVE; + } + + /** + * Uzyskaj ID drugiej gildii + */ + public int getOtherGuildId(int currentGuildId) { + return guild1Id == currentGuildId ? guild2Id : guild1Id; + } + + /** + * Uzyskaj nazwę drugiej gildii + */ + public String getOtherGuildName(int currentGuildId) { + return guild1Id == currentGuildId ? guild2Name : guild1Name; + } + + @Override + public String toString() { + return "GuildRelation{" + + "id=" + id + + ", guild1Id=" + guild1Id + + ", guild2Id=" + guild2Id + + ", type=" + type + + ", status=" + status + + '}'; + } +} diff --git a/src/main/java/com/guild/services/GuildService.java b/src/main/java/com/guild/services/GuildService.java index 1fb1737..ce7f43f 100644 --- a/src/main/java/com/guild/services/GuildService.java +++ b/src/main/java/com/guild/services/GuildService.java @@ -36,13 +36,13 @@ public GuildService(GuildPlugin plugin) { this.logger = plugin.getLogger(); } - // 时间工具:统一使用操作系统本地时间字符串(yyyy-MM-dd HH:mm:ss) + // Narzędzie czasu: użyj ujednoliconego ciągu czasu lokalnego systemu operacyjnego (yyyy-MM-dd HH:mm:ss) private String nowString() { return TimeProvider.nowString(); } private String plusMinutesString(int minutes) { return TimeProvider.plusMinutesString(minutes); } private String plusDaysString(int days) { return TimeProvider.plusDaysString(days); } /** - * 创建工会 (异步) + * Utwórz gildię (asynchronicznie) */ public CompletableFuture createGuildAsync(String name, String tag, String description, UUID leaderUuid, String leaderName) { return getGuildByNameAsync(name).thenCompose(existingGuildByName -> { @@ -75,25 +75,25 @@ public CompletableFuture createGuildAsync(String name, String tag, Stri try (ResultSet rs = stmt.getGeneratedKeys()) { if (rs.next()) { int guildId = rs.getInt(1); - logger.info("工会创建成功: " + name + " (ID: " + guildId + ")"); + logger.info("Utworzono gildię: " + name + " (ID: " + guildId + ")"); return guildId; } } } } } catch (SQLException e) { - logger.severe("创建工会时发生错误: " + e.getMessage()); + logger.severe("Błąd podczas tworzenia gildii: " + e.getMessage()); } return -1; }).thenCompose(guildId -> { if ((Integer) guildId > 0) { - // 添加会长为工会成员(避免重复查询) + // Dodaj lidera jako członka gildii (bezpośrednio) return addGuildMemberDirectAsync((Integer) guildId, leaderUuid, leaderName, GuildMember.Role.LEADER) .thenCompose(success -> { if (success) { - // 记录工会创建日志 + // Zaloguj utworzenie gildii return logGuildActionAsync((Integer) guildId, name, leaderUuid.toString(), leaderName, - GuildLog.LogType.GUILD_CREATED, "创建工会", "工会名称: " + name + ", 标签: " + tag) + GuildLog.LogType.GUILD_CREATED, "Utworzenie gildii", "Nazwa: " + name + ", Tag: " + tag) .thenApply(logSuccess -> success); } return CompletableFuture.completedFuture(success); @@ -106,19 +106,19 @@ public CompletableFuture createGuildAsync(String name, String tag, Stri } /** - * 创建工会 (同步包装器) + * Utwórz gildię (synchronicznie) */ public boolean createGuild(String name, String tag, String description, UUID leaderUuid, String leaderName) { try { return createGuildAsync(name, tag, description, leaderUuid, leaderName).get(); } catch (Exception e) { - logger.severe("创建工会时发生异常: " + e.getMessage()); + logger.severe("Wyjątek podczas tworzenia gildii: " + e.getMessage()); return false; } } /** - * 删除工会 (异步) + * Usuń gildię (asynchronicznie) */ public CompletableFuture deleteGuildAsync(int guildId, UUID requesterUuid) { return getGuildByIdAsync(guildId).thenCompose(guild -> { @@ -127,17 +127,17 @@ public CompletableFuture deleteGuildAsync(int guildId, UUID requesterUu } return getGuildMemberAsync(requesterUuid).thenCompose(member -> { - // 检查权限 + // Sprawdź uprawnienia if (member == null || member.getGuildId() != guildId || member.getRole() != GuildMember.Role.LEADER) { return CompletableFuture.completedFuture(false); } return CompletableFuture.supplyAsync(() -> { try { - // 获取工会余额用于退款 + // Pobierz saldo gildii do zwrotu double guildBalance = guild.getBalance(); - // 删除所有工会成员 + // Usuń wszystkich członków gildii String deleteMembersSql = "DELETE FROM guild_members WHERE guild_id = ?"; try (Connection conn = databaseManager.getConnection(); PreparedStatement stmt = conn.prepareStatement(deleteMembersSql)) { @@ -145,39 +145,39 @@ public CompletableFuture deleteGuildAsync(int guildId, UUID requesterUu stmt.executeUpdate(); } - // 删除工会 + // Usuń gildię String deleteGuildSql = "DELETE FROM guilds WHERE id = ?"; try (Connection conn = databaseManager.getConnection(); PreparedStatement stmt = conn.prepareStatement(deleteGuildSql)) { stmt.setInt(1, guildId); int affectedRows = stmt.executeUpdate(); if (affectedRows > 0) { - logger.info("工会删除成功: " + guild.getName() + " (ID: " + guildId + ")"); + logger.info("Usunięto gildię: " + guild.getName() + " (ID: " + guildId + ")"); - // 退款给会长(如果经济系统可用) + // Zwrot dla lidera (jeśli Vault jest dostępny) if (guildBalance > 0 && plugin.getEconomyManager().isVaultAvailable()) { try { org.bukkit.entity.Player leaderPlayer = org.bukkit.Bukkit.getPlayer(guild.getLeaderUuid()); if (leaderPlayer != null && leaderPlayer.isOnline()) { plugin.getEconomyManager().deposit(leaderPlayer, guildBalance); - String message = plugin.getConfigManager().getMessagesConfig().getString("economy.disband-compensation", "&a工会解散,您获得了 {amount} 金币补偿!") + String message = plugin.getConfigManager().getMessagesConfig().getString("economy.disband-compensation", "&aGildia rozwiązana, otrzymałeś rekompensatę w wysokości {amount} monet!") .replace("{amount}", plugin.getEconomyManager().format(guildBalance)); leaderPlayer.sendMessage(com.guild.core.utils.ColorUtils.colorize(message)); } } catch (Exception e) { - logger.warning("退款给会长时发生错误: " + e.getMessage()); + logger.warning("Błąd podczas zwrotu dla lidera: " + e.getMessage()); } } - // 记录工会解散日志 + // Zaloguj rozwiązanie gildii logGuildActionAsync(guildId, guild.getName(), guild.getLeaderUuid().toString(), guild.getLeaderName(), - GuildLog.LogType.GUILD_DISSOLVED, "工会解散", "工会余额: " + guildBalance + " 金币"); + GuildLog.LogType.GUILD_DISSOLVED, "Rozwiązanie gildii", "Saldo: " + guildBalance); return true; } } } catch (SQLException e) { - logger.severe("删除工会时发生错误: " + e.getMessage()); + logger.severe("Błąd podczas usuwania gildii: " + e.getMessage()); } return false; }); @@ -186,19 +186,19 @@ public CompletableFuture deleteGuildAsync(int guildId, UUID requesterUu } /** - * 删除工会 (同步包装器) + * Usuń gildię (synchronicznie) */ public boolean deleteGuild(int guildId, UUID requesterUuid) { try { return deleteGuildAsync(guildId, requesterUuid).get(); } catch (Exception e) { - logger.severe("删除工会时发生异常: " + e.getMessage()); + logger.severe("Wyjątek podczas usuwania gildii: " + e.getMessage()); return false; } } /** - * 更新工会信息 (异步) + * Zaktualizuj informacje o gildii (asynchronicznie) */ public CompletableFuture updateGuildAsync(int guildId, String name, String tag, String description, UUID requesterUuid) { return getGuildByIdAsync(guildId).thenCompose(guild -> { @@ -207,13 +207,13 @@ public CompletableFuture updateGuildAsync(int guildId, String name, Str } return getGuildMemberAsync(requesterUuid).thenCompose(member -> { - // 检查权限 + // Sprawdź uprawnienia if (member == null || member.getGuildId() != guildId || (member.getRole() != GuildMember.Role.LEADER && member.getRole() != GuildMember.Role.OFFICER)) { return CompletableFuture.completedFuture(false); } - // 检查名称和标签是否与其他工会冲突 + // Sprawdź czy nazwa i tag kolidują z innymi gildiami CompletableFuture nameCheck = CompletableFuture.completedFuture(true); if (name != null && !name.equals(guild.getName())) { nameCheck = getGuildByNameAsync(name).thenApply(existingGuild -> existingGuild == null); @@ -245,12 +245,12 @@ public CompletableFuture updateGuildAsync(int guildId, String name, Str int affectedRows = stmt.executeUpdate(); if (affectedRows > 0) { - logger.info("工会信息更新成功: " + guild.getName() + " (ID: " + guildId + ")"); + logger.info("Zaktualizowano gildię: " + guild.getName() + " (ID: " + guildId + ")"); return true; } } } catch (SQLException e) { - logger.severe("更新工会信息时发生错误: " + e.getMessage()); + logger.severe("Błąd podczas aktualizacji gildii: " + e.getMessage()); } return false; }); @@ -260,19 +260,19 @@ public CompletableFuture updateGuildAsync(int guildId, String name, Str } /** - * 更新工会信息 (同步包装器) + * Zaktualizuj informacje o gildii (synchronicznie) */ public boolean updateGuild(int guildId, String name, String tag, String description, UUID requesterUuid) { try { return updateGuildAsync(guildId, name, tag, description, requesterUuid).get(); } catch (Exception e) { - logger.severe("更新工会信息时发生异常: " + e.getMessage()); + logger.severe("Wyjątek podczas aktualizacji gildii: " + e.getMessage()); return false; } } /** - * 添加工会成员 (异步) + * Dodaj członka gildii (asynchronicznie) */ public CompletableFuture addGuildMemberAsync(int guildId, UUID playerUuid, String playerName, GuildMember.Role role) { return getPlayerGuildAsync(playerUuid).thenCompose(existingGuild -> { @@ -296,15 +296,15 @@ public CompletableFuture addGuildMemberAsync(int guildId, UUID playerUu int affectedRows = stmt.executeUpdate(); if (affectedRows > 0) { - logger.info("玩家 " + playerName + " 加入工会 (ID: " + guildId + ")"); - // 更新内置权限缓存 + logger.info("Gracz " + playerName + " dołączył do gildii (ID: " + guildId + ")"); + // Zaktualizuj cache uprawnień try { plugin.getPermissionManager().updatePlayerPermissions(playerUuid); } catch (Exception ignored) {} - // 记录成员加入日志 + // Zaloguj dołączenie członka getGuildByIdAsync(guildId).thenAccept(guild -> { if (guild != null) { logGuildActionAsync(guildId, guild.getName(), playerUuid.toString(), playerName, - GuildLog.LogType.MEMBER_JOINED, "成员加入", "玩家: " + playerName + ", 职位: " + role.getDisplayName()); + GuildLog.LogType.MEMBER_JOINED, "Dołączenie członka", "Gracz: " + playerName + ", Rola: " + role.getDisplayName()); } }); @@ -312,7 +312,7 @@ public CompletableFuture addGuildMemberAsync(int guildId, UUID playerUu } } } catch (SQLException e) { - logger.severe("添加工会成员时发生错误: " + e.getMessage()); + logger.severe("Błąd podczas dodawania członka gildii: " + e.getMessage()); } return false; }); @@ -320,19 +320,19 @@ public CompletableFuture addGuildMemberAsync(int guildId, UUID playerUu } /** - * 添加工会成员 (同步包装器) + * Dodaj członka gildii (synchronicznie) */ public boolean addGuildMember(int guildId, UUID playerUuid, String playerName, GuildMember.Role role) { try { return addGuildMemberAsync(guildId, playerUuid, playerName, role).get(); } catch (Exception e) { - logger.severe("添加工会成员时发生异常: " + e.getMessage()); + logger.severe("Wyjątek podczas dodawania członka gildii: " + e.getMessage()); return false; } } /** - * 移除工会成员 (异步) + * Usuń członka gildii (asynchronicznie) */ public CompletableFuture removeGuildMemberAsync(UUID playerUuid, UUID requesterUuid) { return getGuildMemberAsync(playerUuid).thenCompose(member -> { @@ -341,17 +341,17 @@ public CompletableFuture removeGuildMemberAsync(UUID playerUuid, UUID r } return getGuildMemberAsync(requesterUuid).thenCompose(requester -> { - // 检查权限 + // Sprawdź uprawnienia if (requester == null || requester.getGuildId() != member.getGuildId()) { return CompletableFuture.completedFuture(false); } - // 会长不能被踢出,除非是自我离开 + // Lider nie może zostać wyrzucony, chyba że sam opuszcza gildię if (member.getRole() == GuildMember.Role.LEADER && !playerUuid.equals(requesterUuid)) { return CompletableFuture.completedFuture(false); } - // 只有会长和官员可以踢出成员 + // Tylko lider i oficerowie mogą wyrzucać członków if (!playerUuid.equals(requesterUuid) && requester.getRole() != GuildMember.Role.LEADER && requester.getRole() != GuildMember.Role.OFFICER) { @@ -369,18 +369,18 @@ public CompletableFuture removeGuildMemberAsync(UUID playerUuid, UUID r int affectedRows = stmt.executeUpdate(); if (affectedRows > 0) { - logger.info("玩家 " + member.getPlayerName() + " 离开工会 (ID: " + member.getGuildId() + ")"); - // 更新内置权限缓存 + logger.info("Gracz " + member.getPlayerName() + " opuścił gildię (ID: " + member.getGuildId() + ")"); + // Zaktualizuj cache uprawnień try { plugin.getPermissionManager().updatePlayerPermissions(playerUuid); } catch (Exception ignored) {} - // 记录成员离开日志 + // Zaloguj opuszczenie członka getGuildByIdAsync(member.getGuildId()).thenAccept(guild -> { if (guild != null) { GuildLog.LogType logType = playerUuid.equals(requesterUuid) ? GuildLog.LogType.MEMBER_LEFT : GuildLog.LogType.MEMBER_KICKED; - String description = playerUuid.equals(requesterUuid) ? "成员主动离开" : "成员被踢出"; - String details = "玩家: " + member.getPlayerName() + - (playerUuid.equals(requesterUuid) ? "" : ", 操作者: " + requester.getPlayerName()); + String description = playerUuid.equals(requesterUuid) ? "Członek opuścił" : "Członek wyrzucony"; + String details = "Gracz: " + member.getPlayerName() + + (playerUuid.equals(requesterUuid) ? "" : ", Operator: " + requester.getPlayerName()); logGuildActionAsync(member.getGuildId(), guild.getName(), requesterUuid.toString(), requester.getPlayerName(), @@ -392,7 +392,7 @@ public CompletableFuture removeGuildMemberAsync(UUID playerUuid, UUID r } } } catch (SQLException e) { - logger.severe("移除工会成员时发生错误: " + e.getMessage()); + logger.severe("Błąd podczas usuwania członka gildii: " + e.getMessage()); } return false; }); @@ -401,19 +401,19 @@ public CompletableFuture removeGuildMemberAsync(UUID playerUuid, UUID r } /** - * 移除工会成员 (同步包装器) + * Usuń członka gildii (synchronicznie) */ public boolean removeGuildMember(UUID playerUuid, UUID requesterUuid) { try { return removeGuildMemberAsync(playerUuid, requesterUuid).get(); } catch (Exception e) { - logger.severe("移除工会成员时发生异常: " + e.getMessage()); + logger.severe("Wyjątek podczas usuwania członka gildii: " + e.getMessage()); return false; } } /** - * 更新成员角色 (异步) + * Zaktualizuj rolę członka (asynchronicznie) */ public CompletableFuture updateMemberRoleAsync(UUID playerUuid, GuildMember.Role newRole, UUID requesterUuid) { return getGuildMemberAsync(playerUuid).thenCompose(member -> { @@ -422,7 +422,7 @@ public CompletableFuture updateMemberRoleAsync(UUID playerUuid, GuildMe } return getGuildMemberAsync(requesterUuid).thenCompose(requester -> { - // 检查权限 - 只有会长可以更改角色 + // Sprawdź uprawnienia - tylko lider może zmieniać role if (requester == null || requester.getGuildId() != member.getGuildId() || requester.getRole() != GuildMember.Role.LEADER) { return CompletableFuture.completedFuture(false); @@ -440,20 +440,20 @@ public CompletableFuture updateMemberRoleAsync(UUID playerUuid, GuildMe int affectedRows = stmt.executeUpdate(); if (affectedRows > 0) { - logger.info("玩家 " + member.getPlayerName() + " 角色更新为: " + newRole.name()); - // 更新内置权限缓存 + logger.info("Zaktualizowano rolę gracza " + member.getPlayerName() + " na: " + newRole.name()); + // Zaktualizuj cache uprawnień try { plugin.getPermissionManager().updatePlayerPermissions(playerUuid); } catch (Exception ignored) {} - // 记录角色变更日志 + // Zaloguj zmianę roli getGuildByIdAsync(member.getGuildId()).thenAccept(guild -> { if (guild != null) { GuildLog.LogType logType = newRole == GuildMember.Role.LEADER ? GuildLog.LogType.LEADER_TRANSFERRED : (newRole == GuildMember.Role.OFFICER ? GuildLog.LogType.MEMBER_PROMOTED : GuildLog.LogType.MEMBER_DEMOTED); - String description = newRole == GuildMember.Role.LEADER ? "会长转让" : - (newRole == GuildMember.Role.OFFICER ? "成员升职" : "成员降职"); - String details = "玩家: " + member.getPlayerName() + ", 新职位: " + newRole.getDisplayName() + - ", 操作者: " + requester.getPlayerName(); + String description = newRole == GuildMember.Role.LEADER ? "Przekazanie lidera" : + (newRole == GuildMember.Role.OFFICER ? "Awans członka" : "Degradacja członka"); + String details = "Gracz: " + member.getPlayerName() + ", Nowa rola: " + newRole.getDisplayName() + + ", Operator: " + requester.getPlayerName(); logGuildActionAsync(member.getGuildId(), guild.getName(), requesterUuid.toString(), requester.getPlayerName(), @@ -465,7 +465,7 @@ public CompletableFuture updateMemberRoleAsync(UUID playerUuid, GuildMe } } } catch (SQLException e) { - logger.severe("更新成员角色时发生错误: " + e.getMessage()); + logger.severe("Błąd podczas aktualizacji roli członka: " + e.getMessage()); } return false; }); @@ -474,13 +474,13 @@ public CompletableFuture updateMemberRoleAsync(UUID playerUuid, GuildMe } /** - * 更新成员角色 (同步包装器) + * Zaktualizuj rolę członka (synchronicznie) */ public boolean updateMemberRole(UUID playerUuid, GuildMember.Role newRole, UUID requesterUuid) { try { return updateMemberRoleAsync(playerUuid, newRole, requesterUuid).get(); } catch (Exception e) { - logger.severe("更新成员角色时发生异常: " + e.getMessage()); + logger.severe("Wyjątek podczas aktualizacji roli członka: " + e.getMessage()); return false; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9e46900..c22ed88 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,73 +1,73 @@ -name: GuildPlugin -version: 1.2.4 -main: com.guild.GuildPlugin -api-version: '1.21' -authors: [chenasyd] -description: 一个功能完整的我的世界工会插件,支持Spigot和Folia -website: https://github.com/chenasyd -softdepend: [PlaceholderAPI, Vault] - -# 支持的最低版本 -load: POSTWORLD - -# Folia支持标记 -folia-supported: true - -commands: - guild: - description: 工会系统主命令 - usage: /guild help - aliases: [g, 工会] - permission: guild.use - guildadmin: - description: 工会管理员命令 - usage: /guildadmin help - aliases: [ga, 工会管理] - permission: guild.admin - -permissions: - guild.use: - description: 允许使用工会系统 - default: true - guild.admin: - description: 工会管理员权限 - default: op - guild.create: - description: 允许创建工会 - default: true - guild.invite: - description: 允许邀请玩家加入工会 - default: true - guild.kick: - description: 允许踢出工会成员 - default: true - guild.promote: - description: 允许提升工会成员 - default: true - guild.demote: - description: 允许降级工会成员 - default: true - guild.delete: - description: 允许删除工会 - default: op - guild.sethome: - description: 允许设置工会家 - default: true - guild.home: - description: 允许传送到工会家 - default: true - guild.relation: - description: 允许管理工会关系 - default: true - guild.economy: - description: 允许管理工会经济 - default: true - guild.deposit: - description: 允许向工会存入资金 - default: true - guild.withdraw: - description: 允许从工会取出资金 - default: true - guild.transfer: - description: 允许向其他工会转账 - default: true +name: GuildPlugin +version: 1.2.4 +main: com.guild.GuildPlugin +api-version: '1.21' +authors: [chenasyd] +description: Kompletny plugin gildyjny dla Minecraft, wspierający Spigot i Folia +website: https://github.com/chenasyd +softdepend: [PlaceholderAPI, Vault] + +# Minimalna obsługiwana wersja +load: POSTWORLD + +# Obsługa Folia +folia-supported: true + +commands: + guild: + description: Główna komenda systemu gildii + usage: /guild help + aliases: [g, gildia] + permission: guild.use + guildadmin: + description: Komenda administratora gildii + usage: /guildadmin help + aliases: [ga, gadmin] + permission: guild.admin + +permissions: + guild.use: + description: Pozwala na używanie systemu gildii + default: true + guild.admin: + description: Uprawnienia administratora gildii + default: op + guild.create: + description: Pozwala na tworzenie gildii + default: true + guild.invite: + description: Pozwala na zapraszanie graczy do gildii + default: true + guild.kick: + description: Pozwala na wyrzucanie członków gildii + default: true + guild.promote: + description: Pozwala na awansowanie członków gildii + default: true + guild.demote: + description: Pozwala na degradowanie członków gildii + default: true + guild.delete: + description: Pozwala na usuwanie gildii + default: op + guild.sethome: + description: Pozwala na ustawianie domu gildii + default: true + guild.home: + description: Pozwala na teleportację do domu gildii + default: true + guild.relation: + description: Pozwala na zarządzanie relacjami gildii + default: true + guild.economy: + description: Pozwala na zarządzanie ekonomią gildii + default: true + guild.deposit: + description: Pozwala na wpłacanie funduszy do gildii + default: true + guild.withdraw: + description: Pozwala na wypłacanie funduszy z gildii + default: true + guild.transfer: + description: Pozwala na przelewanie funduszy do innych gildii + default: true diff --git a/target/classes/PLACEHOLDER_API.md b/target/classes/PLACEHOLDER_API.md new file mode 100644 index 0000000..319d396 --- /dev/null +++ b/target/classes/PLACEHOLDER_API.md @@ -0,0 +1,39 @@ +# Guild插件 PlaceholderAPI 变量使用说明 + +## 概述 + +Guild插件本次更新提供了完整的 PlaceholderAPI 支持,允许其他插件和聊天栏显示工会相关的动态信息。所有变量都支持颜色代码和中文显示。 + +## 基础工会信息变量 + +### 工会基本信息 +- `%guild_name%` - 工会名称 +- `%guild_tag%` - 工会标签 +- `%guild_membercount%` - 工会成员数量 +- `%guild_maxmembers%` - 工会最大成员数 +- `%guild_level%` - 工会等级 +- `%guild_balance%` - 工会余额(保留2位小数) +- `%guild_frozen%` - 工会状态(正常/已冻结/无工会) + +### 玩家在工会中的信息 +- `%guild_role%` - 玩家在工会中的角色(会长/官员/成员) +- `%guild_joined%` - 玩家加入工会的时间 +- `%guild_contribution%` - 玩家对工会的贡献度 + +## 工会状态检查变量 + +### 玩家状态 +- `%guild_hasguild%` - 玩家是否有工会(是/否) +- `%guild_isleader%` - 玩家是否是会长(是/否) +- `%guild_isofficer%` - 玩家是否是官员(是/否) +- `%guild_ismember%` - 玩家是否是工会成员(是/否) + +## 工会权限检查变量 + +### 权限状态 +- `%guild_caninvite%` - 是否可以邀请玩家(是/否) +- `%guild_cankick%` - 是否可以踢出成员(是/否) +- `%guild_canpromote%` - 是否可以提升成员(是/否) +- `%guild_candemote%` - 是否可以降级成员(是/否) +- `%guild_cansethome%` - 是否可以设置工会传送点(是/否) +- `%guild_canmanageeconomy%` - 是否可以管理工会经济(是/否) diff --git a/target/classes/com/guild/GuildPlugin.class b/target/classes/com/guild/GuildPlugin.class new file mode 100644 index 0000000..0bf81a9 Binary files /dev/null and b/target/classes/com/guild/GuildPlugin.class differ diff --git a/target/classes/com/guild/commands/GuildAdminCommand$1.class b/target/classes/com/guild/commands/GuildAdminCommand$1.class new file mode 100644 index 0000000..59c6a89 Binary files /dev/null and b/target/classes/com/guild/commands/GuildAdminCommand$1.class differ diff --git a/target/classes/com/guild/commands/GuildAdminCommand.class b/target/classes/com/guild/commands/GuildAdminCommand.class new file mode 100644 index 0000000..c84277b Binary files /dev/null and b/target/classes/com/guild/commands/GuildAdminCommand.class differ diff --git a/target/classes/com/guild/commands/GuildCommand.class b/target/classes/com/guild/commands/GuildCommand.class new file mode 100644 index 0000000..b2d0958 Binary files /dev/null and b/target/classes/com/guild/commands/GuildCommand.class differ diff --git a/target/classes/com/guild/core/ServiceContainer$ServiceLifecycle.class b/target/classes/com/guild/core/ServiceContainer$ServiceLifecycle.class new file mode 100644 index 0000000..ff84136 Binary files /dev/null and b/target/classes/com/guild/core/ServiceContainer$ServiceLifecycle.class differ diff --git a/target/classes/com/guild/core/ServiceContainer$ServiceNotFoundException.class b/target/classes/com/guild/core/ServiceContainer$ServiceNotFoundException.class new file mode 100644 index 0000000..fb7052e Binary files /dev/null and b/target/classes/com/guild/core/ServiceContainer$ServiceNotFoundException.class differ diff --git a/target/classes/com/guild/core/ServiceContainer.class b/target/classes/com/guild/core/ServiceContainer.class new file mode 100644 index 0000000..92049cf Binary files /dev/null and b/target/classes/com/guild/core/ServiceContainer.class differ diff --git a/target/classes/com/guild/core/config/ConfigManager.class b/target/classes/com/guild/core/config/ConfigManager.class new file mode 100644 index 0000000..6b97c47 Binary files /dev/null and b/target/classes/com/guild/core/config/ConfigManager.class differ diff --git a/target/classes/com/guild/core/database/DatabaseManager$DatabaseType.class b/target/classes/com/guild/core/database/DatabaseManager$DatabaseType.class new file mode 100644 index 0000000..e90fa1e Binary files /dev/null and b/target/classes/com/guild/core/database/DatabaseManager$DatabaseType.class differ diff --git a/target/classes/com/guild/core/database/DatabaseManager.class b/target/classes/com/guild/core/database/DatabaseManager.class new file mode 100644 index 0000000..39f4b3e Binary files /dev/null and b/target/classes/com/guild/core/database/DatabaseManager.class differ diff --git a/target/classes/com/guild/core/economy/EconomyManager.class b/target/classes/com/guild/core/economy/EconomyManager.class new file mode 100644 index 0000000..73fe5ee Binary files /dev/null and b/target/classes/com/guild/core/economy/EconomyManager.class differ diff --git a/target/classes/com/guild/core/events/EventBus.class b/target/classes/com/guild/core/events/EventBus.class new file mode 100644 index 0000000..f768cfd Binary files /dev/null and b/target/classes/com/guild/core/events/EventBus.class differ diff --git a/target/classes/com/guild/core/gui/GUI.class b/target/classes/com/guild/core/gui/GUI.class new file mode 100644 index 0000000..388ecca Binary files /dev/null and b/target/classes/com/guild/core/gui/GUI.class differ diff --git a/target/classes/com/guild/core/gui/GUIManager.class b/target/classes/com/guild/core/gui/GUIManager.class new file mode 100644 index 0000000..8cd2375 Binary files /dev/null and b/target/classes/com/guild/core/gui/GUIManager.class differ diff --git a/target/classes/com/guild/core/permissions/PermissionManager$1.class b/target/classes/com/guild/core/permissions/PermissionManager$1.class new file mode 100644 index 0000000..fe6d942 Binary files /dev/null and b/target/classes/com/guild/core/permissions/PermissionManager$1.class differ diff --git a/target/classes/com/guild/core/permissions/PermissionManager$PlayerPermissions.class b/target/classes/com/guild/core/permissions/PermissionManager$PlayerPermissions.class new file mode 100644 index 0000000..86805d8 Binary files /dev/null and b/target/classes/com/guild/core/permissions/PermissionManager$PlayerPermissions.class differ diff --git a/target/classes/com/guild/core/permissions/PermissionManager$RolePermissions.class b/target/classes/com/guild/core/permissions/PermissionManager$RolePermissions.class new file mode 100644 index 0000000..ab79845 Binary files /dev/null and b/target/classes/com/guild/core/permissions/PermissionManager$RolePermissions.class differ diff --git a/target/classes/com/guild/core/permissions/PermissionManager.class b/target/classes/com/guild/core/permissions/PermissionManager.class new file mode 100644 index 0000000..4051122 Binary files /dev/null and b/target/classes/com/guild/core/permissions/PermissionManager.class differ diff --git a/target/classes/com/guild/core/placeholder/GuildPlaceholderExpansion.class b/target/classes/com/guild/core/placeholder/GuildPlaceholderExpansion.class new file mode 100644 index 0000000..8b891a6 Binary files /dev/null and b/target/classes/com/guild/core/placeholder/GuildPlaceholderExpansion.class differ diff --git a/target/classes/com/guild/core/placeholder/PlaceholderManager.class b/target/classes/com/guild/core/placeholder/PlaceholderManager.class new file mode 100644 index 0000000..a59d30d Binary files /dev/null and b/target/classes/com/guild/core/placeholder/PlaceholderManager.class differ diff --git a/target/classes/com/guild/core/time/TimeProvider.class b/target/classes/com/guild/core/time/TimeProvider.class new file mode 100644 index 0000000..7b8761e Binary files /dev/null and b/target/classes/com/guild/core/time/TimeProvider.class differ diff --git a/target/classes/com/guild/core/utils/ColorUtils.class b/target/classes/com/guild/core/utils/ColorUtils.class new file mode 100644 index 0000000..f9f8dc9 Binary files /dev/null and b/target/classes/com/guild/core/utils/ColorUtils.class differ diff --git a/target/classes/com/guild/core/utils/CompatibleScheduler.class b/target/classes/com/guild/core/utils/CompatibleScheduler.class new file mode 100644 index 0000000..830af00 Binary files /dev/null and b/target/classes/com/guild/core/utils/CompatibleScheduler.class differ diff --git a/target/classes/com/guild/core/utils/GUIUtils.class b/target/classes/com/guild/core/utils/GUIUtils.class new file mode 100644 index 0000000..13e6cde Binary files /dev/null and b/target/classes/com/guild/core/utils/GUIUtils.class differ diff --git a/target/classes/com/guild/core/utils/PlaceholderUtils$1.class b/target/classes/com/guild/core/utils/PlaceholderUtils$1.class new file mode 100644 index 0000000..5616c3f Binary files /dev/null and b/target/classes/com/guild/core/utils/PlaceholderUtils$1.class differ diff --git a/target/classes/com/guild/core/utils/PlaceholderUtils.class b/target/classes/com/guild/core/utils/PlaceholderUtils.class new file mode 100644 index 0000000..6f4afe5 Binary files /dev/null and b/target/classes/com/guild/core/utils/PlaceholderUtils.class differ diff --git a/target/classes/com/guild/core/utils/ServerUtils$ServerType.class b/target/classes/com/guild/core/utils/ServerUtils$ServerType.class new file mode 100644 index 0000000..4f1c992 Binary files /dev/null and b/target/classes/com/guild/core/utils/ServerUtils$ServerType.class differ diff --git a/target/classes/com/guild/core/utils/ServerUtils.class b/target/classes/com/guild/core/utils/ServerUtils.class new file mode 100644 index 0000000..ee37912 Binary files /dev/null and b/target/classes/com/guild/core/utils/ServerUtils.class differ diff --git a/target/classes/com/guild/core/utils/TestUtils.class b/target/classes/com/guild/core/utils/TestUtils.class new file mode 100644 index 0000000..622d75a Binary files /dev/null and b/target/classes/com/guild/core/utils/TestUtils.class differ diff --git a/target/classes/com/guild/core/utils/VariableTestUtils.class b/target/classes/com/guild/core/utils/VariableTestUtils.class new file mode 100644 index 0000000..3366da3 Binary files /dev/null and b/target/classes/com/guild/core/utils/VariableTestUtils.class differ diff --git a/target/classes/com/guild/gui/AdminGuildGUI.class b/target/classes/com/guild/gui/AdminGuildGUI.class new file mode 100644 index 0000000..3ff6cb2 Binary files /dev/null and b/target/classes/com/guild/gui/AdminGuildGUI.class differ diff --git a/target/classes/com/guild/gui/ApplicationManagementGUI$1.class b/target/classes/com/guild/gui/ApplicationManagementGUI$1.class new file mode 100644 index 0000000..d1a20c3 Binary files /dev/null and b/target/classes/com/guild/gui/ApplicationManagementGUI$1.class differ diff --git a/target/classes/com/guild/gui/ApplicationManagementGUI.class b/target/classes/com/guild/gui/ApplicationManagementGUI.class new file mode 100644 index 0000000..9c50c4c Binary files /dev/null and b/target/classes/com/guild/gui/ApplicationManagementGUI.class differ diff --git a/target/classes/com/guild/gui/ConfirmDeleteGuildGUI.class b/target/classes/com/guild/gui/ConfirmDeleteGuildGUI.class new file mode 100644 index 0000000..be24ecc Binary files /dev/null and b/target/classes/com/guild/gui/ConfirmDeleteGuildGUI.class differ diff --git a/target/classes/com/guild/gui/ConfirmLeaveGuildGUI.class b/target/classes/com/guild/gui/ConfirmLeaveGuildGUI.class new file mode 100644 index 0000000..c2f9693 Binary files /dev/null and b/target/classes/com/guild/gui/ConfirmLeaveGuildGUI.class differ diff --git a/target/classes/com/guild/gui/CreateGuildGUI.class b/target/classes/com/guild/gui/CreateGuildGUI.class new file mode 100644 index 0000000..bcecdba Binary files /dev/null and b/target/classes/com/guild/gui/CreateGuildGUI.class differ diff --git a/target/classes/com/guild/gui/CreateRelationGUI$1.class b/target/classes/com/guild/gui/CreateRelationGUI$1.class new file mode 100644 index 0000000..544f1ea Binary files /dev/null and b/target/classes/com/guild/gui/CreateRelationGUI$1.class differ diff --git a/target/classes/com/guild/gui/CreateRelationGUI.class b/target/classes/com/guild/gui/CreateRelationGUI.class new file mode 100644 index 0000000..028fbb8 Binary files /dev/null and b/target/classes/com/guild/gui/CreateRelationGUI.class differ diff --git a/target/classes/com/guild/gui/DemoteMemberGUI.class b/target/classes/com/guild/gui/DemoteMemberGUI.class new file mode 100644 index 0000000..3a6c644 Binary files /dev/null and b/target/classes/com/guild/gui/DemoteMemberGUI.class differ diff --git a/target/classes/com/guild/gui/EconomyManagementGUI.class b/target/classes/com/guild/gui/EconomyManagementGUI.class new file mode 100644 index 0000000..0240c68 Binary files /dev/null and b/target/classes/com/guild/gui/EconomyManagementGUI.class differ diff --git a/target/classes/com/guild/gui/GuildDescriptionInputGUI.class b/target/classes/com/guild/gui/GuildDescriptionInputGUI.class new file mode 100644 index 0000000..e7ecd5a Binary files /dev/null and b/target/classes/com/guild/gui/GuildDescriptionInputGUI.class differ diff --git a/target/classes/com/guild/gui/GuildDetailGUI$1.class b/target/classes/com/guild/gui/GuildDetailGUI$1.class new file mode 100644 index 0000000..a0c8595 Binary files /dev/null and b/target/classes/com/guild/gui/GuildDetailGUI$1.class differ diff --git a/target/classes/com/guild/gui/GuildDetailGUI.class b/target/classes/com/guild/gui/GuildDetailGUI.class new file mode 100644 index 0000000..dfb04eb Binary files /dev/null and b/target/classes/com/guild/gui/GuildDetailGUI.class differ diff --git a/target/classes/com/guild/gui/GuildInfoGUI.class b/target/classes/com/guild/gui/GuildInfoGUI.class new file mode 100644 index 0000000..d3fc04a Binary files /dev/null and b/target/classes/com/guild/gui/GuildInfoGUI.class differ diff --git a/target/classes/com/guild/gui/GuildListGUI.class b/target/classes/com/guild/gui/GuildListGUI.class new file mode 100644 index 0000000..1b183e5 Binary files /dev/null and b/target/classes/com/guild/gui/GuildListGUI.class differ diff --git a/target/classes/com/guild/gui/GuildListManagementGUI.class b/target/classes/com/guild/gui/GuildListManagementGUI.class new file mode 100644 index 0000000..df1b90f Binary files /dev/null and b/target/classes/com/guild/gui/GuildListManagementGUI.class differ diff --git a/target/classes/com/guild/gui/GuildLogsGUI$1.class b/target/classes/com/guild/gui/GuildLogsGUI$1.class new file mode 100644 index 0000000..48de8f8 Binary files /dev/null and b/target/classes/com/guild/gui/GuildLogsGUI$1.class differ diff --git a/target/classes/com/guild/gui/GuildLogsGUI.class b/target/classes/com/guild/gui/GuildLogsGUI.class new file mode 100644 index 0000000..b38dae9 Binary files /dev/null and b/target/classes/com/guild/gui/GuildLogsGUI.class differ diff --git a/target/classes/com/guild/gui/GuildNameInputGUI.class b/target/classes/com/guild/gui/GuildNameInputGUI.class new file mode 100644 index 0000000..8e13da9 Binary files /dev/null and b/target/classes/com/guild/gui/GuildNameInputGUI.class differ diff --git a/target/classes/com/guild/gui/GuildPermissionsGUI.class b/target/classes/com/guild/gui/GuildPermissionsGUI.class new file mode 100644 index 0000000..28eb3e9 Binary files /dev/null and b/target/classes/com/guild/gui/GuildPermissionsGUI.class differ diff --git a/target/classes/com/guild/gui/GuildRelationsGUI$1.class b/target/classes/com/guild/gui/GuildRelationsGUI$1.class new file mode 100644 index 0000000..202552f Binary files /dev/null and b/target/classes/com/guild/gui/GuildRelationsGUI$1.class differ diff --git a/target/classes/com/guild/gui/GuildRelationsGUI.class b/target/classes/com/guild/gui/GuildRelationsGUI.class new file mode 100644 index 0000000..3987390 Binary files /dev/null and b/target/classes/com/guild/gui/GuildRelationsGUI.class differ diff --git a/target/classes/com/guild/gui/GuildSettingsGUI.class b/target/classes/com/guild/gui/GuildSettingsGUI.class new file mode 100644 index 0000000..1914480 Binary files /dev/null and b/target/classes/com/guild/gui/GuildSettingsGUI.class differ diff --git a/target/classes/com/guild/gui/GuildTagInputGUI.class b/target/classes/com/guild/gui/GuildTagInputGUI.class new file mode 100644 index 0000000..0bccdde Binary files /dev/null and b/target/classes/com/guild/gui/GuildTagInputGUI.class differ diff --git a/target/classes/com/guild/gui/InviteMemberGUI.class b/target/classes/com/guild/gui/InviteMemberGUI.class new file mode 100644 index 0000000..c3a5842 Binary files /dev/null and b/target/classes/com/guild/gui/InviteMemberGUI.class differ diff --git a/target/classes/com/guild/gui/KickMemberGUI.class b/target/classes/com/guild/gui/KickMemberGUI.class new file mode 100644 index 0000000..280e03e Binary files /dev/null and b/target/classes/com/guild/gui/KickMemberGUI.class differ diff --git a/target/classes/com/guild/gui/MainGuildGUI.class b/target/classes/com/guild/gui/MainGuildGUI.class new file mode 100644 index 0000000..65fc723 Binary files /dev/null and b/target/classes/com/guild/gui/MainGuildGUI.class differ diff --git a/target/classes/com/guild/gui/MemberDetailsGUI$1.class b/target/classes/com/guild/gui/MemberDetailsGUI$1.class new file mode 100644 index 0000000..4b859ca Binary files /dev/null and b/target/classes/com/guild/gui/MemberDetailsGUI$1.class differ diff --git a/target/classes/com/guild/gui/MemberDetailsGUI.class b/target/classes/com/guild/gui/MemberDetailsGUI.class new file mode 100644 index 0000000..c6e619e Binary files /dev/null and b/target/classes/com/guild/gui/MemberDetailsGUI.class differ diff --git a/target/classes/com/guild/gui/MemberManagementGUI$1.class b/target/classes/com/guild/gui/MemberManagementGUI$1.class new file mode 100644 index 0000000..e77b6de Binary files /dev/null and b/target/classes/com/guild/gui/MemberManagementGUI$1.class differ diff --git a/target/classes/com/guild/gui/MemberManagementGUI.class b/target/classes/com/guild/gui/MemberManagementGUI.class new file mode 100644 index 0000000..66944d7 Binary files /dev/null and b/target/classes/com/guild/gui/MemberManagementGUI.class differ diff --git a/target/classes/com/guild/gui/PromoteMemberGUI.class b/target/classes/com/guild/gui/PromoteMemberGUI.class new file mode 100644 index 0000000..b6d4dec Binary files /dev/null and b/target/classes/com/guild/gui/PromoteMemberGUI.class differ diff --git a/target/classes/com/guild/gui/RelationManagementGUI$1.class b/target/classes/com/guild/gui/RelationManagementGUI$1.class new file mode 100644 index 0000000..fa3644d Binary files /dev/null and b/target/classes/com/guild/gui/RelationManagementGUI$1.class differ diff --git a/target/classes/com/guild/gui/RelationManagementGUI.class b/target/classes/com/guild/gui/RelationManagementGUI.class new file mode 100644 index 0000000..21fb7c7 Binary files /dev/null and b/target/classes/com/guild/gui/RelationManagementGUI.class differ diff --git a/target/classes/com/guild/gui/SystemSettingsGUI.class b/target/classes/com/guild/gui/SystemSettingsGUI.class new file mode 100644 index 0000000..84267f8 Binary files /dev/null and b/target/classes/com/guild/gui/SystemSettingsGUI.class differ diff --git a/target/classes/com/guild/listeners/GuildListener.class b/target/classes/com/guild/listeners/GuildListener.class new file mode 100644 index 0000000..b5c51ca Binary files /dev/null and b/target/classes/com/guild/listeners/GuildListener.class differ diff --git a/target/classes/com/guild/listeners/PlayerListener.class b/target/classes/com/guild/listeners/PlayerListener.class new file mode 100644 index 0000000..bccdf1f Binary files /dev/null and b/target/classes/com/guild/listeners/PlayerListener.class differ diff --git a/target/classes/com/guild/models/Guild.class b/target/classes/com/guild/models/Guild.class new file mode 100644 index 0000000..e19e015 Binary files /dev/null and b/target/classes/com/guild/models/Guild.class differ diff --git a/target/classes/com/guild/models/GuildApplication$ApplicationStatus.class b/target/classes/com/guild/models/GuildApplication$ApplicationStatus.class new file mode 100644 index 0000000..7a72a53 Binary files /dev/null and b/target/classes/com/guild/models/GuildApplication$ApplicationStatus.class differ diff --git a/target/classes/com/guild/models/GuildApplication.class b/target/classes/com/guild/models/GuildApplication.class new file mode 100644 index 0000000..77cb170 Binary files /dev/null and b/target/classes/com/guild/models/GuildApplication.class differ diff --git a/target/classes/com/guild/models/GuildContribution$ContributionType.class b/target/classes/com/guild/models/GuildContribution$ContributionType.class new file mode 100644 index 0000000..edfdf7e Binary files /dev/null and b/target/classes/com/guild/models/GuildContribution$ContributionType.class differ diff --git a/target/classes/com/guild/models/GuildContribution.class b/target/classes/com/guild/models/GuildContribution.class new file mode 100644 index 0000000..d1f73c5 Binary files /dev/null and b/target/classes/com/guild/models/GuildContribution.class differ diff --git a/target/classes/com/guild/models/GuildEconomy.class b/target/classes/com/guild/models/GuildEconomy.class new file mode 100644 index 0000000..5015c3b Binary files /dev/null and b/target/classes/com/guild/models/GuildEconomy.class differ diff --git a/target/classes/com/guild/models/GuildInvitation$InvitationStatus.class b/target/classes/com/guild/models/GuildInvitation$InvitationStatus.class new file mode 100644 index 0000000..8532405 Binary files /dev/null and b/target/classes/com/guild/models/GuildInvitation$InvitationStatus.class differ diff --git a/target/classes/com/guild/models/GuildInvitation.class b/target/classes/com/guild/models/GuildInvitation.class new file mode 100644 index 0000000..11c4c08 Binary files /dev/null and b/target/classes/com/guild/models/GuildInvitation.class differ diff --git a/target/classes/com/guild/models/GuildLog$LogType.class b/target/classes/com/guild/models/GuildLog$LogType.class new file mode 100644 index 0000000..99300c1 Binary files /dev/null and b/target/classes/com/guild/models/GuildLog$LogType.class differ diff --git a/target/classes/com/guild/models/GuildLog.class b/target/classes/com/guild/models/GuildLog.class new file mode 100644 index 0000000..3308bec Binary files /dev/null and b/target/classes/com/guild/models/GuildLog.class differ diff --git a/target/classes/com/guild/models/GuildMember$Role.class b/target/classes/com/guild/models/GuildMember$Role.class new file mode 100644 index 0000000..e02c196 Binary files /dev/null and b/target/classes/com/guild/models/GuildMember$Role.class differ diff --git a/target/classes/com/guild/models/GuildMember.class b/target/classes/com/guild/models/GuildMember.class new file mode 100644 index 0000000..340bcea Binary files /dev/null and b/target/classes/com/guild/models/GuildMember.class differ diff --git a/target/classes/com/guild/models/GuildRelation$RelationStatus.class b/target/classes/com/guild/models/GuildRelation$RelationStatus.class new file mode 100644 index 0000000..c7ddb10 Binary files /dev/null and b/target/classes/com/guild/models/GuildRelation$RelationStatus.class differ diff --git a/target/classes/com/guild/models/GuildRelation$RelationType.class b/target/classes/com/guild/models/GuildRelation$RelationType.class new file mode 100644 index 0000000..8404878 Binary files /dev/null and b/target/classes/com/guild/models/GuildRelation$RelationType.class differ diff --git a/target/classes/com/guild/models/GuildRelation.class b/target/classes/com/guild/models/GuildRelation.class new file mode 100644 index 0000000..fe10d1f Binary files /dev/null and b/target/classes/com/guild/models/GuildRelation.class differ diff --git a/target/classes/com/guild/services/GuildService.class b/target/classes/com/guild/services/GuildService.class new file mode 100644 index 0000000..f5eb526 Binary files /dev/null and b/target/classes/com/guild/services/GuildService.class differ diff --git a/target/classes/config.yml b/target/classes/config.yml new file mode 100644 index 0000000..f2e62df --- /dev/null +++ b/target/classes/config.yml @@ -0,0 +1,124 @@ +# 工会插件主配置文件 + +# 工会配置 +guild: + # 工会名称最小长度 + min-name-length: 3 + # 工会名称最大长度 + max-name-length: 20 + # 工会标签最大长度 + max-tag-length: 6 + # 工会描述最大长度 + max-description-length: 100 + # 工会最大成员数量 + max-members: 50 + # 创建工会所需费用(需要Vault) + creation-cost: 1000.0 + # 工会标签颜色 + tag-color: "&6" + # 工会名称颜色 + name-color: "&e" + +# 显示配置 +display: + # 职位颜色(可自定义) + role-colors: + leader: "&6" # 会长:金色 + officer: "&b" # 官员:亮蓝色 + member: "&7" # 成员:灰色 + # 职位左侧分隔符配置 + role-separator: + enabled: true + text: " | " + color-per-role: true # 分隔符是否跟随职位颜色 + default-color: "&7" # 无职位或未入会时的默认颜色(一般不会使用) + +# 权限配置 +permissions: + # 默认权限 + default: + can-create: true # 允许创建工会(未入会时) + can-invite: false # 非成员默认不可邀请 + can-kick: false # 非成员默认不可踢人 + can-promote: false # 非成员默认不可升职 + can-demote: false # 非成员默认不可降职 + can-delete: false # 非成员默认不可删会 + + # 会长权限(若缺省则视为全开) + leader: + can-create: true + can-invite: true + can-kick: true + can-promote: true + can-demote: true + can-delete: true + + # 官员权限 + officer: + can-create: true # 允许代操作与创建 + can-invite: true + can-kick: true + can-promote: false # 是否允许升职成员(通常只会长) + can-demote: false # 是否允许降职成员(通常只会长) + can-delete: false # 是否允许删除工会(通常只会长) + + # 成员权限 + member: + can-create: true # 允许退会后再创建新工会 + can-invite: false + can-kick: false + can-promote: false + can-demote: false + can-delete: false + +# 消息配置 +messages: + # 是否启用消息 + enabled: true + # 消息前缀 + prefix: "&6[工会] &r" + # 消息颜色 + colors: + success: "&a" + error: "&c" + info: "&e" + warning: "&6" + +# GUI配置 +gui: + # 是否启用GUI + enabled: true + # GUI标题 + title: "&6工会系统" + # GUI大小(必须是9的倍数) + size: 54 + # 是否显示工会标签 + show-tag: true + # 是否显示工会描述 + show-description: true + +# 占位符配置 +placeholders: + # 是否启用占位符 + enabled: true + # 占位符前缀 + prefix: "guild_" + # 是否缓存占位符 + cache-enabled: true + # 缓存时间(秒) + cache-time: 30 + +# 日志配置 +logging: + # 是否启用日志 + enabled: true + # 日志级别: DEBUG, INFO, WARN, ERROR + level: INFO + # 是否记录到文件 + file-logging: true + # 日志文件路径 + log-file: "logs/guild.log" + # 最大日志文件大小(MB) + max-file-size: 10 + # 保留的日志文件数量 + max-files: 5 diff --git a/target/classes/database.yml b/target/classes/database.yml new file mode 100644 index 0000000..82019f9 --- /dev/null +++ b/target/classes/database.yml @@ -0,0 +1,108 @@ +# 数据库配置文件 + +# 数据库类型: mysql 或 sqlite +type: sqlite + +# MySQL配置(当type为mysql时使用) +mysql: + # 数据库主机地址 + host: localhost + # 数据库端口 + port: 3306 + # 数据库名称 + database: guild + # 数据库用户名 + username: root + # 数据库密码 + password: "" + # 连接池大小 + pool-size: 10 + # 最小空闲连接数 + min-idle: 5 + # 连接超时时间(毫秒) + connection-timeout: 30000 + # 空闲超时时间(毫秒) + idle-timeout: 600000 + # 连接最大生命周期(毫秒) + max-lifetime: 1800000 + # 是否使用SSL + use-ssl: false + # 字符编码 + character-encoding: UTF-8 + # 时区 + timezone: UTC + +# SQLite配置(当type为sqlite时使用) +sqlite: + # 数据库文件路径(相对于插件数据文件夹) + file: guild.db + # 是否启用WAL模式 + wal-mode: true + # 同步模式: OFF, NORMAL, FULL + synchronous: NORMAL + # 缓存大小(KB) + cache-size: 2000 + # 页面大小(字节) + page-size: 4096 + # 是否启用外键约束 + foreign-keys: true + +# 连接池配置 +connection-pool: + # 最大连接数 + maximum-pool-size: 10 + # 最小空闲连接数 + minimum-idle: 5 + # 连接超时时间(毫秒) + connection-timeout: 30000 + # 空闲超时时间(毫秒) + idle-timeout: 600000 + # 连接最大生命周期(毫秒) + max-lifetime: 1800000 + # 连接测试查询 + connection-test-query: "SELECT 1" + # 连接验证超时时间(毫秒) + validation-timeout: 5000 + # 是否在连接池启动时验证连接 + validate-on-start: true + +# 数据库表配置 +tables: + # 工会表 + guilds: + name: guilds + # 是否自动创建表 + auto-create: true + # 表结构版本 + version: 1 + + # 工会成员表 + guild_members: + name: guild_members + auto-create: true + version: 1 + + # 工会申请表 + guild_applications: + name: guild_applications + auto-create: true + version: 1 + + # 工会邀请表 + guild_invites: + name: guild_invites + auto-create: true + version: 1 + +# 备份配置 +backup: + # 是否启用自动备份 + enabled: false + # 备份间隔(小时) + interval: 24 + # 备份保留天数 + retention-days: 7 + # 备份文件路径 + path: "backups/" + # 备份文件格式 + format: "yyyy-MM-dd_HH-mm-ss" diff --git a/target/classes/gui.yml b/target/classes/gui.yml new file mode 100644 index 0000000..0f843f2 --- /dev/null +++ b/target/classes/gui.yml @@ -0,0 +1,716 @@ +# GUI配置文件 + +# 主界面配置 - 六个主要入口 +main-menu: + title: "&6工会系统" + size: 54 + items: + guild-info: + slot: 20 + material: BOOK + name: "&e工会信息" + lore: + - "&7查看工会详细信息" + - "&7包括基本信息、统计等" + glow: false + + member-management: + slot: 22 + material: PLAYER_HEAD + name: "&e成员管理" + lore: + - "&7管理工会成员" + - "&7邀请、踢出、权限管理" + glow: false + + application-management: + slot: 24 + material: PAPER + name: "&e申请管理" + lore: + - "&7处理加入申请" + - "&7查看申请历史" + glow: false + + guild-settings: + slot: 30 + material: COMPASS + name: "&e工会设置" + lore: + - "&7修改工会设置" + - "&7描述、标签、权限等" + glow: false + + guild-list: + slot: 32 + material: BOOKSHELF + name: "&e工会列表" + lore: + - "&7查看所有工会" + - "&7搜索、筛选功能" + glow: false + + guild-relations: + slot: 34 + material: RED_WOOL + name: "&e工会关系" + lore: + - "&7管理工会关系" + - "&7盟友、敌对等" + glow: false + + create-guild: + slot: 48 + material: EMERALD_BLOCK + name: "&a创建工会" + lore: + - "&7创建新的工会" + - "&7需要消耗金币" + glow: true + +# 工会信息界面 +guild-info: + title: "&6工会信息" + size: 54 + items: + guild-name: + slot: 10 + material: NAME_TAG + name: "&e工会名称" + lore: + - "&f{guild_name}" + - "&7工会ID: {guild_id}" + + guild-tag: + slot: 12 + material: OAK_SIGN + name: "&e工会标签" + lore: + - "&f{guild_tag}" + - "&7标签用于快速识别" + + guild-description: + slot: 14 + material: BOOK + name: "&e工会描述" + lore: + - "&f{guild_description}" + - "&7工会的详细介绍" + + guild-leader: + slot: 16 + material: GOLDEN_HELMET + name: "&e工会会长" + lore: + - "&f{leader_name}" + - "&7会长拥有所有权限" + + guild-home: + slot: 19 + material: COMPASS + name: "&e工会家" + lore: + - "&f{guild_home_location}" + - "&7成员可传送到此处" + + member-count: + slot: 28 + material: PLAYER_HEAD + name: "&e成员数量" + lore: + - "&f{member_count}/{guild_max_members} 人" + - "&7在线: {online_member_count} 人" + + guild-level: + slot: 30 + material: EXPERIENCE_BOTTLE + name: "&e工会等级" + lore: + - "&f等级 {guild_level}" + - "&7最大成员: {guild_max_members} 人" + - "&7升级进度: {guild_level_progress}" + + guild-balance: + slot: 32 + material: GOLD_INGOT + name: "&e工会资金" + lore: + - "&f{guild_balance_formatted}" + - "&7升级需要: {guild_next_level_requirement}" + + created-date: + slot: 34 + material: CLOCK + name: "&e创建时间" + lore: + - "&f{guild_created_date}" + - "&7{guild_created_time}" + + guild-status: + slot: 36 + material: BEACON + name: "&e工会状态" + lore: + - "&f{guild_frozen}" + - "&7工会当前状态" + + back: + slot: 49 + material: ARROW + name: "&7返回" + lore: + - "&7返回主菜单" + +# 成员管理界面 +member-management: + title: "&6成员管理" + size: 54 + items: + invite-member: + slot: 45 + material: EMERALD_BLOCK + name: "&a邀请成员" + lore: + - "&7邀请新成员加入" + - "&7当前成员: {member_count} 人" + + kick-member: + slot: 47 + material: REDSTONE_BLOCK + name: "&c踢出成员" + lore: + - "&7踢出工会成员" + - "&7需要官员或更高权限" + + promote-member: + slot: 49 + material: GOLD_INGOT + name: "&6提升成员" + lore: + - "&7提升成员职位" + - "&7只有会长可以操作" + + demote-member: + slot: 51 + material: IRON_INGOT + name: "&7降级成员" + lore: + - "&7降级成员职位" + - "&7只有会长可以操作" + + back: + slot: 53 + material: ARROW + name: "&7返回" + lore: + - "&7返回主菜单" + + next-page: + slot: 26 + material: ARROW + name: "&a下一页" + lore: + - "&7查看下一页" + + previous-page: + slot: 18 + material: ARROW + name: "&c上一页" + lore: + - "&7查看上一页" + +# 成员详情界面 +member-details: + title: "&6成员详情 - {member_name}" + size: 54 + +# 申请管理界面 +application-management: + title: "&6申请管理" + size: 54 + items: + pending-applications: + slot: 20 + material: PAPER + name: "&e待处理申请" + lore: + - "&7查看待处理的申请" + - "&f{pending_count} 个申请" + - "&7需要及时处理" + + application-history: + slot: 24 + material: BOOK + name: "&e申请历史" + lore: + - "&7查看申请历史记录" + - "&7已处理的申请" + + back: + slot: 49 + material: ARROW + name: "&7返回" + lore: + - "&7返回主菜单" + + next-page: + slot: 26 + material: ARROW + name: "&a下一页" + lore: + - "&7查看下一页" + + previous-page: + slot: 18 + material: ARROW + name: "&c上一页" + lore: + - "&7查看上一页" + +# 工会设置界面 +guild-settings: + title: "&6工会设置" + size: 54 + items: + change-description: + slot: 20 + material: BOOK + name: "&e修改描述" + lore: + - "&7修改工会描述" + - "&7当前: {guild_description}" + + change-tag: + slot: 22 + material: OAK_SIGN + name: "&e修改标签" + lore: + - "&7修改工会标签" + - "&7当前: {guild_tag}" + + set-home: + slot: 24 + material: COMPASS + name: "&e设置工会家" + lore: + - "&7设置工会传送点" + - "&7当前: {guild_home_location}" + + permissions: + slot: 30 + material: SHIELD + name: "&e权限设置" + lore: + - "&7管理成员权限" + - "&7角色权限管理" + + back: + slot: 49 + material: ARROW + name: "&7返回" + lore: + - "&7返回主菜单" + +# 工会列表界面 +guild-list: + title: "&6工会列表" + size: 54 + items: + search: + slot: 45 + material: COMPASS + name: "&e搜索工会" + lore: + - "&7搜索特定工会" + - "&7当前搜索: {search_query}" + + filter: + slot: 47 + material: HOPPER + name: "&e筛选" + lore: + - "&7按条件筛选工会" + - "&7当前筛选: {filter_type}" + + back: + slot: 49 + material: ARROW + name: "&7返回" + lore: + - "&7返回主菜单" + + next-page: + slot: 26 + material: ARROW + name: "&a下一页" + lore: + - "&7查看下一页" + + previous-page: + slot: 18 + material: ARROW + name: "&c上一页" + lore: + - "&7查看上一页" + +# 工会关系界面 +guild-relations: + title: "&6工会关系" + size: 54 + items: + allies: + slot: 20 + material: GREEN_WOOL + name: "&a盟友工会" + lore: + - "&7查看盟友工会" + - "&7管理盟友关系" + + enemies: + slot: 24 + material: RED_WOOL + name: "&c敌对工会" + lore: + - "&7查看敌对工会" + - "&7管理敌对关系" + + war: + slot: 28 + material: NETHERITE_SWORD + name: "&4开战工会" + lore: + - "&7查看开战工会" + - "&7管理战争状态" + + neutral: + slot: 32 + material: GRAY_WOOL + name: "&7中立工会" + lore: + - "&7查看中立工会" + - "&7管理中立关系" + + back: + slot: 49 + material: ARROW + name: "&7返回" + lore: + - "&7返回主菜单" + +# 成员信息显示 +member-display: + leader: + material: GOLDEN_HELMET + name: "&c{player_name}" + lore: + - "&7角色: &c会长" + - "&7加入时间: {joined_date}" + - "&7权限: 所有权限" + + officer: + material: GOLDEN_HELMET + name: "&6{player_name}" + lore: + - "&7角色: &6官员" + - "&7加入时间: {joined_date}" + - "&7权限: 邀请、踢出" + + member: + material: PLAYER_HEAD + name: "&f{player_name}" + lore: + - "&7角色: &f成员" + - "&7加入时间: {joined_date}" + - "&7权限: 基础权限" + +# 申请信息显示 +application-display: + pending: + material: YELLOW_WOOL + name: "&e{player_name} 的申请" + lore: + - "&7状态: &e待处理" + - "&7申请时间: {apply_date}" + - "&7消息: {message}" + - "" + - "&a左键: 接受" + - "&c右键: 拒绝" + + accepted: + material: GREEN_WOOL + name: "&a{player_name} 的申请" + lore: + - "&7状态: &a已接受" + - "&7处理时间: {process_date}" + - "&7处理人: {processor}" + + rejected: + material: RED_WOOL + name: "&c{player_name} 的申请" + lore: + - "&7状态: &c已拒绝" + - "&7处理时间: {process_date}" + - "&7处理人: {processor}" + +# 工会信息显示 +guild-display: + material: SHIELD + name: "&e{guild_name}" + lore: + - "&7标签: {guild_tag}" + - "&7会长: {guild_leader}" + - "&7成员: {member_count}/{max_members}" + - "&7创建时间: {created_date}" + - "" + - "&a左键: 查看详情" + - "&e右键: 申请加入" + +# 创建工会界面 +create-guild: + title: "&6创建工会" + size: 54 + items: + name-input: + slot: 20 + material: NAME_TAG + name: "&e工会名称" + lore: + - "&7点击输入工会名称" + - "&7长度: 3-20 字符" + - "&7当前: {guild_name}" + + tag-input: + slot: 22 + material: OAK_SIGN + name: "&e工会标签" + lore: + - "&7点击输入工会标签" + - "&7长度: 最多6字符" + - "&7可选" + - "&7当前: {guild_tag}" + + description-input: + slot: 24 + material: BOOK + name: "&e工会描述" + lore: + - "&7点击输入工会描述" + - "&7长度: 最多100字符" + - "&7可选" + - "&7当前: {guild_description}" + + confirm: + slot: 39 + material: EMERALD_BLOCK + name: "&a确认创建" + lore: + - "&7确认创建工会" + - "&7费用: {cost} 金币" + - "&7创建者: {player_name}" + glow: true + + cancel: + slot: 41 + material: REDSTONE_BLOCK + name: "&c取消" + lore: + - "&7取消创建工会" + +# 邀请界面 +invite-player: + title: "&6邀请玩家" + size: 54 + items: + player-input: + slot: 22 + material: PLAYER_HEAD + name: "&e选择玩家" + lore: + - "&7点击选择要邀请的玩家" + + confirm: + slot: 39 + material: EMERALD_BLOCK + name: "&a发送邀请" + lore: + - "&7确认发送邀请" + glow: true + + cancel: + slot: 41 + material: REDSTONE_BLOCK + name: "&c取消" + lore: + - "&7取消邀请" + +# 确认界面 +confirm: + title: "&6确认操作" + size: 27 + items: + confirm: + slot: 11 + material: EMERALD_BLOCK + name: "&a确认" + lore: + - "&7确认执行此操作" + glow: true + + cancel: + slot: 15 + material: REDSTONE_BLOCK + name: "&c取消" + lore: + - "&7取消操作" + +# 装饰物品 +decorations: + border: + material: BLACK_STAINED_GLASS_PANE + name: " " + + info: + material: LIGHT_BLUE_STAINED_GLASS_PANE + name: "&b工会系统" + lore: + - "&7功能强大的工会插件" + +# 管理员GUI +admin-gui: + title: "&4工会管理" + size: 54 + items: + guild-list: + slot: 20 + material: BOOKSHELF + name: "&e工会列表管理" + lore: + - "&7查看和管理所有工会" + - "&7包括删除、冻结等操作" + - "&e左键: 查看详情" + - "&c右键: 删除工会" + - "&6中键: 冻结/解冻" + + economy: + slot: 22 + material: GOLD_INGOT + name: "&e经济管理" + lore: + - "&7管理工会经济系统" + - "&7设置资金、查看贡献等" + - "&e左键: 设置资金" + - "&a右键: 增加资金" + - "&c中键: 减少资金" + + relations: + slot: 24 + material: RED_WOOL + name: "&e关系管理" + lore: + - "&7管理工会关系" + - "&7盟友、敌对、开战等" + - "&c左键: 删除关系" + - "&e右键: 查看详情" + + statistics: + slot: 29 + material: PAPER + name: "&e统计信息" + lore: + - "&7查看工会统计信息" + - "&7成员数量、经济状况等" + - "&e点击查看详细统计" + + settings: + slot: 31 + material: COMPASS + name: "&e系统设置" + lore: + - "&7管理系统设置" + - "&7重载配置、权限设置等" + - "&e点击进入设置" + + back: + slot: 49 + material: ARROW + name: "&c返回" + lore: + - "&7返回主菜单" + + + +# 工会经济GUI +guild-economy: + title: "&6工会经济" + size: 54 + items: + balance: + slot: 20 + material: GOLD_INGOT + name: "&e当前资金" + lore: + - "&7工会当前资金" + - "&f{balance} 金币" + + deposit: + slot: 22 + material: EMERALD_BLOCK + name: "&a存入资金" + lore: + - "&7向工会存入资金" + - "&7点击输入金额" + + withdraw: + slot: 24 + material: REDSTONE_BLOCK + name: "&c取出资金" + lore: + - "&7从工会取出资金" + - "&7点击输入金额" + + level: + slot: 29 + material: EXPERIENCE_BOTTLE + name: "&e工会等级" + lore: + - "&7当前等级: {level}" + - "&7升级进度: {progress}%" + - "&7最大成员: {max_members}" + + contributions: + slot: 31 + material: BOOK + name: "&e贡献记录" + lore: + - "&7查看贡献记录" + - "&7您的贡献: {contribution}" + + transfer: + slot: 33 + material: DIAMOND + name: "&b转账" + lore: + - "&7向其他工会转账" + - "&7点击选择目标工会" + + back: + slot: 49 + material: ARROW + name: "&c返回" + lore: + - "&7返回上级菜单" + +# 工会详情界面 +guild-detail: + title: "&6工会详情 - {guild_name}" + size: 54 + +# 系统设置界面 +system-settings: + title: "&4系统设置" + size: 54 + +# 工会日志界面 +guild-logs: + title: "&6工会日志 - {guild_name}" + size: 54 diff --git a/target/classes/messages.yml b/target/classes/messages.yml new file mode 100644 index 0000000..ff8b18c --- /dev/null +++ b/target/classes/messages.yml @@ -0,0 +1,540 @@ +# 工会插件消息配置文件 + +# 通用消息 +general: + prefix: "&6[工会] &r" + no-permission: "&c您没有权限执行此操作!" + player-only: "&c此命令只能由玩家执行!" + player-not-found: "&c玩家 {player} 未找到!" + guild-not-found: "&c工会 {guild} 未找到!" + invalid-arguments: "&c参数无效!" + error-occurred: "&c发生错误:{error}" + service-error: "&c工会服务未初始化!" + unknown-command: "&c未知命令!使用 /guild help 查看帮助。" + +# 工会创建相关消息 +create: + success: "&a工会 {name} 创建成功!" + name-too-short: "&c工会名称太短!最少需要 {min} 个字符。" + name-too-long: "&c工会名称太长!最多只能有 {max} 个字符。" + name-exists: "&c工会名称 {name} 已存在!" + name-required: "&c请先输入工会名称!" + tag-exists: "&c工会标签 {tag} 已存在!" + tag-too-long: "&c工会标签太长!最多只能有 {max} 个字符。" + already-in-guild: "&c您已经在一个工会中了!" + insufficient-funds: "&c您的余额不足!创建工会需要 {cost} 金币。" + usage: "&e用法: /guild create <名称> [标签] [描述]" + description-too-long: "&c工会描述不能超过100个字符!" + failed: "&c工会创建失败!可能的原因:" + failed-reason-1: "&c- 工会名称或标签已存在" + failed-reason-2: "&c- 您已经加入了其他工会" + name-info: "&e工会名称: {name}" + tag-info: "&e工会标签: [{tag}]" + description-info: "&e工会描述: {description}" + economy-not-available: "&c经济系统不可用,无法创建工会!" + payment-failed: "&c扣除创建费用失败!" + payment-refunded: "&e已退还创建费用 {cost} 金币。" + cost-info: "&e创建费用: {amount}" + +# 工会信息相关消息 +info: + title: "&6=== 工会信息 ===" + name: "&e名称: &f{name}" + tag: "&e标签: &f{tag}" + description: "&e描述: &f{description}" + leader: "&e会长: &f{leader}" + members: "&e成员数量: &f{count}/{max}" + created: "&e创建时间: &f{date}" + no-guild: "&c您还没有加入任何工会!" + role: "&e您的角色: &f{role}" + +# 工会成员相关消息 +members: + title: "&6=== 工会成员 ===" + leader: "&c{name} &7(会长)" + officer: "&6{name} &7(官员)" + member: "&f{name} &7(成员)" + joined: "&7加入时间: {date}" + no-members: "&c工会中没有成员!" + member-format: "&e{role} {name} &7- {status}" + total: "&e总计: {count} 人" + +# 邀请相关消息 +invite: + sent: "&a已向 {player} 发送工会邀请!" + received: "&e{inviter} 邀请您加入工会: {guild}" + accepted: "&a您已接受 {guild} 的邀请!" + declined: "&c您已拒绝 {guild} 的邀请!" + expired: "&c工会邀请已过期!" + already-invited: "&c{player} 已经收到了邀请!" + no-permission: "&c您没有权限邀请玩家!" + usage: "&e用法: /guild invite <玩家>" + title: "&6=== 工会邀请 ===" + guild-tag: "&e工会标签: [{tag}]" + accept-command: "&e输入 &a/guild accept {inviter} &e接受邀请" + decline-command: "&e输入 &c/guild decline {inviter} &e拒绝邀请" + already-in-guild: "&c玩家 {player} 已经加入了其他工会!" + cannot-invite-self: "&c您不能邀请自己!" + +# 踢出相关消息 +kick: + success: "&a已将 {player} 踢出工会!" + kicked: "&c您已被踢出工会 {guild}!" + no-permission: "&c您没有权限踢出玩家!" + cannot-kick-leader: "&c不能踢出工会会长!" + usage: "&e用法: /guild kick <玩家>" + player-not-found: "&c玩家 {player} 不在线!" + not-in-guild: "&c玩家 {player} 不在您的工会中!" + cannot-kick-self: "&c您不能踢出自己!使用 /guild leave 离开工会。" + failed: "&c踢出玩家失败!" + +# 离开工会相关消息 +leave: + success: "&a您已离开工会!" + leader-cannot-leave: "&c工会会长不能离开工会!请先转让会长职位或删除工会。" + confirm: "&c您确定要离开工会吗?使用 /guild leave confirm 确认。" + member-error: "&c工会成员信息错误!" + success-with-guild: "&a您已成功离开工会: {guild}" + failed: "&c离开工会失败!" + use-delete: "&c如果您想解散工会,请使用 /guild delete 命令。" + +# 删除工会相关消息 +delete: + success: "&a工会 {guild} 已删除!" + no-permission: "&c您没有权限删除工会!" + confirm: "&c您确定要删除工会吗?这将解散整个工会!使用 /guild delete confirm 确认。" + only-leader: "&c只有工会会长才能删除工会!" + warning: "&c警告:删除工会将永久解散工会,所有成员将被移除!" + confirm-command: "&c如果您确定要删除工会,请再次输入: /guild delete confirm" + cancel-command: "&c或者输入: /guild delete cancel 取消操作" + +# 工会家相关消息 +sethome: + success: "&a工会家设置成功!" + failed: "&c设置工会家失败!" + only-leader: "&c只有工会会长才能设置工会家!" + no-permission: "&c您没有权限设置工会家!" +home: + success: "&a已传送到工会家!" + not-set: "&c工会家尚未设置!" + no-permission: "&c您没有权限传送到工会家!" + teleport-failed: "&c传送到工会家失败!" + +# 申请相关消息 +application: + sent: "&a您的申请已发送给 {guild}!" + received: "&a收到来自 {player} 的申请!" + accepted: "&a您的申请已被 {guild} 接受!" + declined: "&c您的申请已被 {guild} 拒绝!" + already-applied: "&c您已经向 {guild} 申请过了!" + usage: "&e用法: /guild apply <工会> [消息]" + +# 申请相关消息(GUI使用) +apply: + success: "&a申请已提交!" + failed: "&c申请提交失败!" + already-applied: "&c您已经申请过这个工会了!" + +# 工会关系相关消息 +relation: + no-guild: "&c您还没有加入工会!" + only-leader: "&c只有工会会长才能管理工会关系!" + help-title: "&6=== 工会关系管理 ===" + help-list: "&e/guild relation list &7- 查看所有关系" + help-create: "&e/guild relation create <工会> <类型> &7- 创建关系" + help-delete: "&e/guild relation delete <工会> &7- 删除关系" + help-accept: "&e/guild relation accept <工会> &7- 接受关系请求" + help-reject: "&e/guild relation reject <工会> &7- 拒绝关系请求" + help-types: "&7关系类型: &eally(盟友), enemy(敌对), war(开战), truce(停战), neutral(中立)" + create-usage: "&e用法: /guild relation create <目标工会> <关系类型>" + delete-usage: "&e用法: /guild relation delete <目标工会>" + accept-usage: "&e用法: /guild relation accept <目标工会>" + reject-usage: "&e用法: /guild relation reject <目标工会>" + unknown-subcommand: "&c未知的子命令!使用 /guild relation 查看帮助。" + no-relations: "&7您的工会还没有任何关系。" + list-title: "&6=== 工会关系列表 ===" + list-format: "&e{other_guild} &7- {type} ({status})" + invalid-type: "&c无效的关系类型!有效类型: ally, enemy, war, truce, neutral" + target-not-found: "&c目标工会 {guild} 不存在!" + cannot-relation-self: "&c不能与自己建立关系!" + create-success: "&a已向 {guild} 发送 {type} 关系请求!" + create-failed: "&c创建关系失败!可能已经存在关系。" + delete-success: "&a已删除与 {guild} 的关系!" + delete-failed: "&c删除关系失败!可能关系不存在。" + accept-success: "&a已接受 {guild} 的关系请求!" + accept-failed: "&c接受关系失败!可能没有待处理的关系请求。" + reject-success: "&c已拒绝 {guild} 的关系请求!" + reject-failed: "&c拒绝关系失败!可能没有待处理的关系请求。" + +# 权限相关消息 +permissions: + promote: + success: "&a已将 {player} 提升为 {role}!" + no-permission: "&c您没有权限提升玩家!" + cannot-promote: "&c无法提升该玩家!" + usage: "&e用法: /guild promote <玩家>" + player-not-found: "&c玩家 {player} 不在线!" + not-in-guild: "&c玩家 {player} 不在您的工会中!" + already-highest: "&c玩家 {player} 已经是最高职位!" + cannot-promote-self: "&c您不能提升自己!" + demote: + success: "&a已将 {player} 降级为 {role}!" + no-permission: "&c您没有权限降级玩家!" + cannot-demote: "&c无法降级该玩家!" + usage: "&e用法: /guild demote <玩家>" + player-not-found: "&c玩家 {player} 不在线!" + not-in-guild: "&c玩家 {player} 不在您的工会中!" + already-lowest: "&c玩家 {player} 已经是最低职位!" + cannot-demote-self: "&c您不能降级自己!" + cannot-demote-leader: "&c不能降级工会会长!" + +# 管理员命令消息 +admin: + no-permission: "&c您没有管理员权限!" + unknown-command: "&c未知命令!使用 /guildadmin help 查看帮助。" + reload: + success: "&a配置重载成功!" + error: "&c配置重载失败:{error}" + list: + title: "&6=== 工会列表 ===" + entry: "&e{guild} &7- {count} 成员" + empty: "&c没有找到任何工会!" + total: "&e总计: {count} 个工会" + info: + title: "&6=== 工会详细信息 ===" + id: "&eID: &f{id}" + name: "&e名称: &f{name}" + tag: "&e标签: &f{tag}" + description: "&e描述: &f{description}" + leader: "&e会长: &f{leader}" + member-count: "&e成员数量: &f{count}" + created: "&e创建时间: &f{created}" + updated: "&e更新时间: &f{updated}" + usage: "&e用法: /guildadmin info <工会名称>" + not-found: "&c工会 {guild} 不存在!" + members-title: "&6=== 成员列表 ===" + delete: + success: "&a工会 {guild} 已被管理员删除!" + error: "&c删除工会失败:{error}" + usage: "&e用法: /guildadmin delete <工会名称>" + not-found: "&c工会 {guild} 不存在!" + warning: "&c警告:删除工会将永久解散工会,所有成员将被移除!" + confirm: "&c如果您确定要删除工会,请使用: /guildadmin delete {guild} confirm" + success-with-name: "&a已成功删除工会: {guild}" + failed: "&c删除工会失败!" + kick: + success: "&a已将 {player} 从 {guild} 踢出!" + error: "&c踢出玩家失败:{error}" + usage: "&e用法: /guildadmin kick <玩家名称> <工会名称>" + guild-not-found: "&c工会 {guild} 不存在!" + player-not-found: "&c玩家 {player} 不在线!" + player-not-in-guild: "&c玩家 {player} 不在工会 {guild} 中!" + cannot-kick-leader: "&c不能踢出工会会长!请先转让会长职位或删除工会。" + success-with-names: "&a已成功从工会 {guild} 踢出玩家 {player}!" + kicked-by-admin: "&c您已被管理员从工会 {guild} 踢出!" + failed: "&c踢出玩家失败!" + help: + title: "&6=== 工会管理员命令帮助 ===" + reload: "&e/guildadmin reload &7- 重载配置文件" + list: "&e/guildadmin list &7- 列出所有工会" + info: "&e/guildadmin info <工会名称> &7- 查看工会详细信息" + delete: "&e/guildadmin delete <工会名称> &7- 删除指定工会" + kick: "&e/guildadmin kick <玩家> <工会> &7- 从工会踢出玩家" + help: "&e/guildadmin help &7- 显示此帮助信息" + +# GUI相关消息 +gui: + title: "&6工会系统" + create-guild: "&a创建工会" + guild-info: "&e工会信息" + member-management: "&e成员管理" + application-management: "&e申请管理" + guild-settings: "&e工会设置" + guild-list: "&e工会列表" + guild-relations: "&e工会关系" + invite-player: "&e邀请玩家" + leave-guild: "&c离开工会" + delete-guild: "&4删除工会" + confirm: "&a确认" + cancel: "&c取消" + back: "&7返回" + next-page: "&a下一页" + previous-page: "&c上一页" + no-guild: "&c您还没有工会" + no-permission: "&c权限不足" + opening: "&a正在打开工会系统GUI..." + + # 主界面功能 + create-guild-success: "&a创建工会功能已就绪" + guild-info-success: "&a工会信息功能已就绪" + member-management-success: "&a成员管理功能已就绪" + application-management-success: "&a申请管理功能已就绪" + guild-settings-success: "&a工会设置功能已就绪" + guild-list-success: "&a工会列表功能已就绪" + guild-relations-success: "&a工会关系功能已就绪" + + # 功能消息 + invite-member-success: "&a邀请成员功能已就绪" + kick-member-success: "&a踢出成员功能已就绪" + promote-member-success: "&a提升成员功能已就绪" + demote-member-success: "&a降级成员功能已就绪" + accept-application-success: "&a接受申请功能已就绪" + reject-application-success: "&a拒绝申请功能已就绪" + application-history-success: "&a申请历史功能已就绪" + change-description-success: "&a修改描述功能已就绪" + change-tag-success: "&a修改标签功能已就绪" + permissions-success: "&a权限设置功能已就绪" + search-success: "&a搜索功能已就绪" + filter-success: "&a筛选功能已就绪" + view-guild-details-success: "&a查看工会详情功能已就绪" + apply-to-guild-success: "&a申请加入工会功能已就绪" + name-input-success: "&a工会名称输入功能已就绪" + tag-input-success: "&a工会标签输入功能已就绪" + description-input-success: "&a工会描述输入功能已就绪" + + # 成员管理 + invite-member: "&a邀请成员" + kick-member: "&c踢出成员" + promote-member: "&6提升成员" + demote-member: "&7降级成员" + + # 申请管理 + pending-applications: "&e待处理申请" + application-history: "&e申请历史" + no-pending-applications: "&a没有待处理的申请" + no-application-history: "&a没有申请历史" + + # 工会设置 + change-description: "&e修改描述" + change-tag: "&e修改标签" + set-home: "&e设置工会家" + permissions: "&e权限设置" + + # 工会列表 + search: "&e搜索工会" + filter: "&e筛选" + no-guilds-found: "&c没有找到工会" + search-dev: "&a搜索功能正在开发中..." + filter-dev: "&a筛选功能正在开发中..." + no-guilds: "&c没有找到工会" + + # 工会关系 + allies: "&a盟友工会" + enemies: "&c敌对工会" + neutral: "&7中立工会" + relations-success: "&a工会关系功能已就绪" + + # 分页 + page-info: "&7第 {current} 页,共 {total} 页" + no-more-pages: "&c已经是最后一页了" + no-previous-pages: "&c已经是第一页了" + + # 权限提示 + permission-required: "&c需要权限: {permission}" + leader-only: "&c只有工会会长才能执行此操作" + officer-or-higher: "&c需要官员或更高权限" + + # 操作提示 + click-to-view: "&7点击查看详情" + click-to-edit: "&7点击编辑" + click-to-confirm: "&7点击确认" + click-to-cancel: "&7点击取消" + + # 成员详情 + confirm-kick: "&c确定要踢出成员 {member} 吗?输入 &f/guild kick {member} confirm &c确认" + confirm-promote: "&a确定要提升成员 {member} 为官员吗?输入 &f/guild promote {member} confirm &a确认" + confirm-demote: "&c确定要降级成员 {member} 吗?输入 &f/guild demote {member} confirm &c确认" + cannot-kick-leader: "&c不能踢出工会会长" + cannot-modify-leader: "&c不能修改工会会长的职位" + open-chat: "&e请输入要发送给 {member} 的消息:" + + # 输入相关 + input-name: "&a请在聊天框中输入工会名称(3-20字符):" + input-description: "&a请在聊天框中输入新的工会描述(最多100字符):" + input-tag: "&a请在聊天框中输入新的工会标签(最多10字符):" + description-too-long: "&c描述过长,最多100字符!" + tag-too-long: "&c标签过长,最多10字符!" + name-set: "&a工会名称已设置为:{name}" + tag-set: "&a工会标签已设置为:{tag}" + description-set: "&a工会描述已设置为:{description}" + description-updated: "&a工会描述已更新!" + description-update-failed: "&c工会描述更新失败!" + tag-updated: "&a工会标签已更新!" + tag-update-failed: "&c工会标签更新失败!" + +# 占位符相关消息 +placeholders: + no-guild: "无工会" + no-tag: "无标签" + no-description: "无描述" + unknown-role: "未知角色" + +# 帮助相关消息 +help: + title: "&6=== 工会系统帮助 ===" + main-menu: "&e/guild &7- 打开工会主界面" + create: "&e/guild create <名称> [标签] [描述] &7- 创建工会" + info: "&e/guild info &7- 查看工会信息" + members: "&e/guild members &7- 查看工会成员" + invite: "&e/guild invite <玩家> &7- 邀请玩家加入工会" + kick: "&e/guild kick <玩家> &7- 踢出工会成员" + leave: "&e/guild leave &7- 离开工会" + delete: "&e/guild delete &7- 删除工会" + promote: "&e/guild promote <玩家> &7- 提升工会成员" + demote: "&e/guild demote <玩家> &7- 降级工会成员" + accept: "&e/guild accept <邀请者> &7- 接受工会邀请" + decline: "&e/guild decline <邀请者> &7- 拒绝工会邀请" + sethome: "&e/guild sethome &7- 设置工会家" + home: "&e/guild home &7- 传送到工会家" + logs: "&e/guild logs &7- 查看工会操作日志" + help: "&e/guild help &7- 显示此帮助信息" + + + +# 错误消息 +errors: + database: + connection-failed: "&c数据库连接失败!" + query-failed: "&c数据库查询失败!" + table-not-found: "&c数据表不存在!" + config: + invalid-value: "&c配置值无效:{path}" + missing-value: "&c缺少配置项:{path}" + general: + unknown-error: "&c发生未知错误!" + plugin-disabled: "&c插件已禁用!" + + + +# 工会经济系统消息 +economy: + # 基础操作 + no-guild: "&c您还没有加入工会!" + info: "&6工会经济信息" + balance: "&7当前资金: &e{balance}" + level: "&7当前等级: &e{level}" + max-members: "&7最大成员: &e{max_members}" + insufficient-balance: "&c您的余额不足!" + guild-insufficient-balance: "&c工会余额不足!" + leader-only: "&c只有工会会长才能执行此操作!" + target-guild-not-found: "&c目标工会不存在!" + cannot-transfer-to-self: "&c不能转账给自己的工会!" + deposit-success: "&a成功向工会存款 &e{amount}!" + deposit-failed: "&c存款失败!" + withdraw-success: "&a成功从工会取款 &e{amount}!" + withdraw-failed: "&c取款失败!" + transfer-success: "&a成功向工会 &e{target} &a转账 &e{amount}!" + transfer-failed: "&c转账失败!" + insufficient-funds: "&c工会资金不足!" + insufficient-personal-funds: "&c您的个人资金不足!" + + # 等级系统 + level-up: "&a工会升级成功!当前等级:{level},最大成员数:{max_members}" + level-up-failed: "&c工会升级失败!" + max-level-reached: "&c工会已达到最高等级!" + upgrade-progress: "&e升级进度:{progress}%" + + # 贡献系统 + contribution-recorded: "&a贡献记录已保存!" + total-contribution: "&e您的总贡献:{amount} 金币" + + + + # 解散 + disband-compensation: "&a工会解散,您获得了 {amount} 金币补偿!" + + # 管理员操作 + admin-set-balance: "&a工会 {guild} 的资金已设置为 {amount}!" + admin-add-balance: "&a工会 {guild} 的资金已增加 {amount}!" + admin-remove-balance: "&a工会 {guild} 的资金已减少 {amount}!" + admin-balance-updated: "&a工会 {guild} 的资金已更新为 {amount}!" + admin-balance-failed: "&c更新工会资金失败!" + + # 等级需求 + level-1-requirement: "0-5000 金币" + level-2-requirement: "5000-10000 金币" + level-3-requirement: "10000-20000 金币" + level-4-requirement: "20000-35000 金币" + level-5-requirement: "35000-50000 金币" + level-6-requirement: "50000-75000 金币" + level-7-requirement: "75000-100000 金币" + level-8-requirement: "100000-150000 金币" + level-9-requirement: "150000-200000 金币" + level-10-requirement: "200000+ 金币" + +# 工会详情相关消息 +guild-detail: + title: "&6工会详情" + guild-info: "&e工会信息" + economy-info: "&e经济信息" + leader-info: "&6工会会长" + description-info: "&e工会描述" + members-title: "&a工会成员" + more-members: "&e更多成员" + freeze-guild: "&c冻结工会" + unfreeze-guild: "&a解冻工会" + delete-guild: "&4删除工会" + economy-management: "&e资金管理" + refresh-info: "&a刷新信息" + back: "&c返回" + + # 状态信息 + status-normal: "&a正常" + status-frozen: "&c已冻结" + online-status: "&a在线" + offline-status: "&7离线" + + # 操作提示 + freeze-success: "&a工会 {guild} 已被冻结!" + unfreeze-success: "&a工会 {guild} 已被解冻!" + freeze-failed: "&c冻结/解冻操作失败!" + delete-confirm: "&c您确定要删除工会 {guild} 吗?" + delete-command: "&c输入 &f/guildadmin delete {guild} confirm &c确认删除" + no-description: "&7暂无描述" + +# 系统设置相关消息 +system-settings: + title: "&4系统设置" + debug-mode: "&e详细后台信息显示" + auto-save: "&e自动保存数据" + economy-system: "&e经济系统" + relation-system: "&e工会关系系统" + level-system: "&e工会等级系统" + application-system: "&e申请加入系统" + invite-system: "&e邀请系统" + guild-home-system: "&e工会家系统" + reload-configs: "&a重载配置" + database-maintenance: "&b数据库维护" + backup-data: "&6备份数据" + save-settings: "&a保存设置" + + # 状态信息 + enabled: "&a已启用" + disabled: "&c已禁用" + current-status: "&7当前状态: {status}" + + # 操作提示 + toggle-success: "&a{feature}已{action}!" + toggle-enabled: "启用" + toggle-disabled: "禁用" + reload-success: "&a配置重载成功!" + reload-failed: "&c配置重载失败:{error}" + save-success: "&a设置保存成功!" + save-failed: "&c设置保存失败:{error}" + + # 功能描述 + debug-description: "&7启用后会在控制台显示详细的调试信息" + auto-save-description: "&7定期自动保存工会数据,防止数据丢失" + economy-description: "&7工会经济功能开关,包括存款、取款、转账等" + relation-description: "&7工会关系功能开关,包括盟友、敌对、开战等" + level-description: "&7工会等级功能开关,包括自动升级、成员限制等" + application-description: "&7申请加入工会功能开关,玩家需要申请才能加入工会" + invite-description: "&7工会邀请功能开关,会长可以邀请玩家加入工会" + home-description: "&7工会家功能开关,包括设置和传送到工会家" + + # 维护功能 + maintenance-dev: "&e数据库维护功能开发中..." + backup-dev: "&e数据备份功能开发中..." + +# 工会日志相关消息 +log-details: "&6=== 日志详情 ===" diff --git a/target/classes/plugin.yml b/target/classes/plugin.yml new file mode 100644 index 0000000..c22ed88 --- /dev/null +++ b/target/classes/plugin.yml @@ -0,0 +1,73 @@ +name: GuildPlugin +version: 1.2.4 +main: com.guild.GuildPlugin +api-version: '1.21' +authors: [chenasyd] +description: Kompletny plugin gildyjny dla Minecraft, wspierający Spigot i Folia +website: https://github.com/chenasyd +softdepend: [PlaceholderAPI, Vault] + +# Minimalna obsługiwana wersja +load: POSTWORLD + +# Obsługa Folia +folia-supported: true + +commands: + guild: + description: Główna komenda systemu gildii + usage: /guild help + aliases: [g, gildia] + permission: guild.use + guildadmin: + description: Komenda administratora gildii + usage: /guildadmin help + aliases: [ga, gadmin] + permission: guild.admin + +permissions: + guild.use: + description: Pozwala na używanie systemu gildii + default: true + guild.admin: + description: Uprawnienia administratora gildii + default: op + guild.create: + description: Pozwala na tworzenie gildii + default: true + guild.invite: + description: Pozwala na zapraszanie graczy do gildii + default: true + guild.kick: + description: Pozwala na wyrzucanie członków gildii + default: true + guild.promote: + description: Pozwala na awansowanie członków gildii + default: true + guild.demote: + description: Pozwala na degradowanie członków gildii + default: true + guild.delete: + description: Pozwala na usuwanie gildii + default: op + guild.sethome: + description: Pozwala na ustawianie domu gildii + default: true + guild.home: + description: Pozwala na teleportację do domu gildii + default: true + guild.relation: + description: Pozwala na zarządzanie relacjami gildii + default: true + guild.economy: + description: Pozwala na zarządzanie ekonomią gildii + default: true + guild.deposit: + description: Pozwala na wpłacanie funduszy do gildii + default: true + guild.withdraw: + description: Pozwala na wypłacanie funduszy z gildii + default: true + guild.transfer: + description: Pozwala na przelewanie funduszy do innych gildii + default: true diff --git a/target/guild-plugin-1.2.1.jar b/target/guild-plugin-1.2.1.jar new file mode 100644 index 0000000..d689f65 Binary files /dev/null and b/target/guild-plugin-1.2.1.jar differ diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 0000000..865ad00 --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=guild-plugin +groupId=com.guild +version=1.2.1 diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..3262402 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,83 @@ +com/guild/models/GuildRelation$RelationStatus.class +com/guild/gui/GuildListManagementGUI.class +com/guild/gui/CreateGuildGUI.class +com/guild/core/utils/ServerUtils$ServerType.class +com/guild/gui/GuildLogsGUI$1.class +com/guild/core/ServiceContainer$ServiceLifecycle.class +com/guild/gui/MainGuildGUI.class +com/guild/core/utils/ColorUtils.class +com/guild/gui/GuildTagInputGUI.class +com/guild/gui/CreateRelationGUI.class +com/guild/gui/MemberDetailsGUI.class +com/guild/core/gui/GUI.class +com/guild/models/GuildContribution.class +com/guild/core/config/ConfigManager.class +com/guild/gui/GuildDetailGUI.class +com/guild/core/utils/PlaceholderUtils.class +com/guild/gui/SystemSettingsGUI.class +com/guild/gui/MemberDetailsGUI$1.class +com/guild/gui/ApplicationManagementGUI.class +com/guild/models/GuildRelation$RelationType.class +com/guild/GuildPlugin.class +com/guild/core/economy/EconomyManager.class +com/guild/gui/GuildRelationsGUI.class +com/guild/core/permissions/PermissionManager$RolePermissions.class +com/guild/core/utils/TestUtils.class +com/guild/core/events/EventBus.class +com/guild/gui/MemberManagementGUI$1.class +com/guild/core/gui/GUIManager.class +com/guild/core/placeholder/PlaceholderManager.class +com/guild/gui/DemoteMemberGUI.class +com/guild/gui/GuildNameInputGUI.class +com/guild/listeners/GuildListener.class +com/guild/listeners/PlayerListener.class +com/guild/gui/RelationManagementGUI.class +com/guild/core/database/DatabaseManager$DatabaseType.class +com/guild/core/time/TimeProvider.class +com/guild/models/GuildLog$LogType.class +com/guild/core/permissions/PermissionManager.class +com/guild/gui/GuildPermissionsGUI.class +com/guild/models/GuildInvitation$InvitationStatus.class +com/guild/gui/MemberManagementGUI.class +com/guild/core/utils/PlaceholderUtils$1.class +com/guild/core/ServiceContainer.class +com/guild/gui/GuildListGUI.class +com/guild/commands/GuildAdminCommand.class +com/guild/core/permissions/PermissionManager$PlayerPermissions.class +com/guild/gui/ConfirmDeleteGuildGUI.class +com/guild/gui/PromoteMemberGUI.class +com/guild/commands/GuildAdminCommand$1.class +com/guild/gui/EconomyManagementGUI.class +com/guild/models/GuildMember.class +com/guild/models/GuildRelation.class +com/guild/gui/GuildDescriptionInputGUI.class +com/guild/gui/GuildSettingsGUI.class +com/guild/gui/GuildDetailGUI$1.class +com/guild/core/ServiceContainer$ServiceNotFoundException.class +com/guild/gui/RelationManagementGUI$1.class +com/guild/core/utils/ServerUtils.class +com/guild/gui/GuildLogsGUI.class +com/guild/models/GuildInvitation.class +com/guild/models/GuildApplication$ApplicationStatus.class +com/guild/core/placeholder/GuildPlaceholderExpansion.class +com/guild/gui/InviteMemberGUI.class +com/guild/core/utils/CompatibleScheduler.class +com/guild/gui/KickMemberGUI.class +com/guild/gui/ApplicationManagementGUI$1.class +com/guild/models/Guild.class +com/guild/core/utils/GUIUtils.class +com/guild/commands/GuildCommand.class +com/guild/services/GuildService.class +com/guild/gui/CreateRelationGUI$1.class +com/guild/models/GuildContribution$ContributionType.class +com/guild/models/GuildLog.class +com/guild/core/utils/VariableTestUtils.class +com/guild/core/permissions/PermissionManager$1.class +com/guild/models/GuildApplication.class +com/guild/models/GuildEconomy.class +com/guild/gui/GuildInfoGUI.class +com/guild/core/database/DatabaseManager.class +com/guild/models/GuildMember$Role.class +com/guild/gui/AdminGuildGUI.class +com/guild/gui/ConfirmLeaveGuildGUI.class +com/guild/gui/GuildRelationsGUI$1.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..bff95f0 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,59 @@ +/app/src/main/java/com/guild/gui/PromoteMemberGUI.java +/app/src/main/java/com/guild/gui/GuildDetailGUI.java +/app/src/main/java/com/guild/services/GuildService.java +/app/src/main/java/com/guild/gui/GuildLogsGUI.java +/app/src/main/java/com/guild/core/utils/TestUtils.java +/app/src/main/java/com/guild/core/economy/EconomyManager.java +/app/src/main/java/com/guild/core/placeholder/GuildPlaceholderExpansion.java +/app/src/main/java/com/guild/gui/GuildListManagementGUI.java +/app/src/main/java/com/guild/core/gui/GUI.java +/app/src/main/java/com/guild/core/permissions/PermissionManager.java +/app/src/main/java/com/guild/gui/CreateGuildGUI.java +/app/src/main/java/com/guild/gui/GuildNameInputGUI.java +/app/src/main/java/com/guild/models/GuildContribution.java +/app/src/main/java/com/guild/gui/MainGuildGUI.java +/app/src/main/java/com/guild/models/GuildRelation.java +/app/src/main/java/com/guild/gui/GuildListGUI.java +/app/src/main/java/com/guild/commands/GuildAdminCommand.java +/app/src/main/java/com/guild/core/utils/PlaceholderUtils.java +/app/src/main/java/com/guild/core/ServiceContainer.java +/app/src/main/java/com/guild/gui/GuildPermissionsGUI.java +/app/src/main/java/com/guild/models/GuildEconomy.java +/app/src/main/java/com/guild/gui/GuildSettingsGUI.java +/app/src/main/java/com/guild/commands/GuildCommand.java +/app/src/main/java/com/guild/GuildPlugin.java +/app/src/main/java/com/guild/gui/GuildTagInputGUI.java +/app/src/main/java/com/guild/gui/ConfirmLeaveGuildGUI.java +/app/src/main/java/com/guild/gui/MemberManagementGUI.java +/app/src/main/java/com/guild/gui/EconomyManagementGUI.java +/app/src/main/java/com/guild/models/GuildInvitation.java +/app/src/main/java/com/guild/listeners/PlayerListener.java +/app/src/main/java/com/guild/gui/MemberDetailsGUI.java +/app/src/main/java/com/guild/core/utils/CompatibleScheduler.java +/app/src/main/java/com/guild/core/config/ConfigManager.java +/app/src/main/java/com/guild/gui/ConfirmDeleteGuildGUI.java +/app/src/main/java/com/guild/core/database/DatabaseManager.java +/app/src/main/java/com/guild/core/gui/GUIManager.java +/app/src/main/java/com/guild/gui/CreateRelationGUI.java +/app/src/main/java/com/guild/models/GuildLog.java +/app/src/main/java/com/guild/models/GuildMember.java +/app/src/main/java/com/guild/gui/ApplicationManagementGUI.java +/app/src/main/java/com/guild/gui/KickMemberGUI.java +/app/src/main/java/com/guild/gui/SystemSettingsGUI.java +/app/src/main/java/com/guild/gui/RelationManagementGUI.java +/app/src/main/java/com/guild/core/time/TimeProvider.java +/app/src/main/java/com/guild/core/placeholder/PlaceholderManager.java +/app/src/main/java/com/guild/gui/GuildInfoGUI.java +/app/src/main/java/com/guild/core/events/EventBus.java +/app/src/main/java/com/guild/models/GuildApplication.java +/app/src/main/java/com/guild/gui/GuildRelationsGUI.java +/app/src/main/java/com/guild/gui/GuildDescriptionInputGUI.java +/app/src/main/java/com/guild/gui/InviteMemberGUI.java +/app/src/main/java/com/guild/core/utils/ColorUtils.java +/app/src/main/java/com/guild/gui/DemoteMemberGUI.java +/app/src/main/java/com/guild/listeners/GuildListener.java +/app/src/main/java/com/guild/core/utils/VariableTestUtils.java +/app/src/main/java/com/guild/core/utils/ServerUtils.java +/app/src/main/java/com/guild/core/utils/GUIUtils.java +/app/src/main/java/com/guild/gui/AdminGuildGUI.java +/app/src/main/java/com/guild/models/Guild.java diff --git a/target/original-guild-plugin-1.2.1.jar b/target/original-guild-plugin-1.2.1.jar new file mode 100644 index 0000000..55b7ac2 Binary files /dev/null and b/target/original-guild-plugin-1.2.1.jar differ