Upload folder via GUI - src
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package de.ticketsystem.manager;
|
||||
|
||||
import de.ticketsystem.TicketPlugin;
|
||||
import de.ticketsystem.model.FaqCategory;
|
||||
import de.ticketsystem.model.FaqEntry;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@@ -10,28 +11,40 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages FAQ entries stored in faqs.yml.
|
||||
* Manages FAQ entries and FAQ categories stored in faqs.yml.
|
||||
*
|
||||
* Admins can add, edit and delete FAQs in-game.
|
||||
* All changes are saved immediately to faqs.yml.
|
||||
* faqs.yml wird beim ersten Start automatisch mit Beispiel-Kategorien und -FAQs generiert.
|
||||
* Admins können Kategorien und FAQs direkt in-game verwalten (GUI + Befehle).
|
||||
*
|
||||
* faqs.yml layout:
|
||||
* faqs.yml Layout:
|
||||
*
|
||||
* categories:
|
||||
* tickets:
|
||||
* name: "Tickets"
|
||||
* color: "&b"
|
||||
* description: "Fragen zum Ticket-System"
|
||||
*
|
||||
* faqs:
|
||||
* 1:
|
||||
* question: "Wie erstelle ich ein Ticket?"
|
||||
* answer: "Nutze /ticket create [Kategorie] [Beschreibung]."
|
||||
* 2:
|
||||
* question: "..."
|
||||
* answer: "..."
|
||||
* answer: "Nutze /ticket create ..."
|
||||
* category: "tickets"
|
||||
*
|
||||
* Material und Textur der Kategorie-Items werden NICHT hier gespeichert –
|
||||
* sie werden zentral in config.yml unter gui-settings.faq.category-head-item gesteuert.
|
||||
*/
|
||||
public class FaqManager {
|
||||
|
||||
private final TicketPlugin plugin;
|
||||
private final File faqFile;
|
||||
private YamlConfiguration faqConfig;
|
||||
private final List<FaqEntry> entries = new ArrayList<>();
|
||||
private int nextId = 1;
|
||||
public static final String UNCATEGORIZED_KEY = "__none__";
|
||||
|
||||
private final TicketPlugin plugin;
|
||||
private final File faqFile;
|
||||
private YamlConfiguration faqConfig;
|
||||
|
||||
private final List<FaqEntry> entries = new ArrayList<>();
|
||||
private final LinkedHashMap<String, FaqCategory> categories = new LinkedHashMap<>();
|
||||
|
||||
private int nextId = 1;
|
||||
|
||||
public FaqManager(TicketPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -43,6 +56,7 @@ public class FaqManager {
|
||||
|
||||
private void load() {
|
||||
entries.clear();
|
||||
categories.clear();
|
||||
nextId = 1;
|
||||
|
||||
if (!faqFile.exists()) {
|
||||
@@ -59,16 +73,37 @@ public class FaqManager {
|
||||
}
|
||||
|
||||
faqConfig = YamlConfiguration.loadConfiguration(faqFile);
|
||||
ConfigurationSection section = faqConfig.getConfigurationSection("faqs");
|
||||
|
||||
if (section != null) {
|
||||
for (String key : section.getKeys(false)) {
|
||||
// ── 1. Kategorien laden ───────────────────────────────────────────
|
||||
ConfigurationSection catSection = faqConfig.getConfigurationSection("categories");
|
||||
if (catSection != null && !catSection.getKeys(false).isEmpty()) {
|
||||
for (String key : catSection.getKeys(false)) {
|
||||
ConfigurationSection cat = catSection.getConfigurationSection(key);
|
||||
if (cat == null) continue;
|
||||
String name = cat.getString("name", capitalize(key));
|
||||
String color = cat.getString("color", "&7");
|
||||
String desc = cat.getString("description", "");
|
||||
categories.put(key.toLowerCase(), new FaqCategory(key, name, color, desc));
|
||||
}
|
||||
if (plugin.isDebug()) {
|
||||
plugin.getLogger().info("[FaqManager] " + categories.size()
|
||||
+ " FAQ-Kategorie(n) geladen: " + String.join(", ", categories.keySet()));
|
||||
}
|
||||
}
|
||||
|
||||
// ── 2. FAQ-Einträge laden ─────────────────────────────────────────
|
||||
ConfigurationSection faqSection = faqConfig.getConfigurationSection("faqs");
|
||||
if (faqSection != null) {
|
||||
for (String key : faqSection.getKeys(false)) {
|
||||
try {
|
||||
int id = Integer.parseInt(key);
|
||||
String question = faqConfig.getString("faqs." + key + ".question", "");
|
||||
String answer = faqConfig.getString("faqs." + key + ".answer", "");
|
||||
String category = faqConfig.getString("faqs." + key + ".category", null);
|
||||
if (!question.isBlank() && !answer.isBlank()) {
|
||||
entries.add(new FaqEntry(id, question, answer));
|
||||
FaqEntry entry = new FaqEntry(id, question, answer);
|
||||
entry.setCategoryKey(normalizeCategoryKey(category));
|
||||
entries.add(entry);
|
||||
if (id >= nextId) nextId = id + 1;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
@@ -82,31 +117,56 @@ public class FaqManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes the example FAQs into a freshly created faqs.yml. */
|
||||
private void loadDefaults() {
|
||||
faqConfig.options().header(
|
||||
"FAQ-System – faqs.yml\n" +
|
||||
"Wird automatisch generiert. Kategorien sind optional.\n" +
|
||||
"Material/Textur der Kategorie-Items: config.yml → gui-settings.faq.category-head-item"
|
||||
);
|
||||
|
||||
writeCategory("general", "Allgemein", "&e", "Allgemeine Fragen zum Server");
|
||||
writeCategory("rules", "Regeln", "&c", "Fragen zu den Server-Regeln");
|
||||
writeCategory("gameplay", "Gameplay", "&a", "Fragen zum Spielgeschehen");
|
||||
writeCategory("tickets", "Tickets", "&b", "Fragen zum Ticket-System");
|
||||
|
||||
categories.put("general", new FaqCategory("general", "Allgemein", "&e", "Allgemeine Fragen zum Server"));
|
||||
categories.put("rules", new FaqCategory("rules", "Regeln", "&c", "Fragen zu den Server-Regeln"));
|
||||
categories.put("gameplay", new FaqCategory("gameplay", "Gameplay", "&a", "Fragen zum Spielgeschehen"));
|
||||
categories.put("tickets", new FaqCategory("tickets", "Tickets", "&b", "Fragen zum Ticket-System"));
|
||||
|
||||
writeEntry(1, "Wie erstelle ich ein Ticket?",
|
||||
"Nutze den Befehl /ticket create [Kategorie] [Prio][Beschreibung] um ein neues Ticket zu erstellen.");
|
||||
"Nutze den Befehl /ticket create [Kategorie] [Prio] <Beschreibung>.", "tickets");
|
||||
writeEntry(2, "Wie lange dauert die Bearbeitung?",
|
||||
"Unser Support-Team bearbeitet Tickets so schnell wie möglich. Bitte habe etwas Geduld.");
|
||||
"Unser Support-Team bearbeitet Tickets so schnell wie möglich.", "tickets");
|
||||
writeEntry(3, "Kann ich mein Ticket löschen?",
|
||||
"Ja! Öffne /ticket list und klicke auf dein Ticket, um es aus der Übersicht zu entfernen.");
|
||||
"Ja! Öffne /ticket list und klicke auf dein Ticket.", "tickets");
|
||||
writeEntry(4, "Wie kann ich meinen Support bewerten?",
|
||||
"Nach dem Schließen eines Tickets kannst du mit /ticket rate <ID> good/bad eine Bewertung abgeben.");
|
||||
"Mit /ticket rate <ID> good/bad nach dem Schließen.", "tickets");
|
||||
nextId = 5;
|
||||
// Sync entries list with what we just wrote – Text muss identisch sein!
|
||||
entries.add(new FaqEntry(1, "Wie erstelle ich ein Ticket?",
|
||||
"Nutze den Befehl /ticket create [Kategorie] [Prio][Beschreibung] um ein neues Ticket zu erstellen."));
|
||||
entries.add(new FaqEntry(2, "Wie lange dauert die Bearbeitung?",
|
||||
"Unser Support-Team bearbeitet Tickets so schnell wie möglich. Bitte habe etwas Geduld."));
|
||||
entries.add(new FaqEntry(3, "Kann ich mein Ticket löschen?",
|
||||
"Ja! Öffne /ticket list und klicke auf dein Ticket, um es aus der Übersicht zu entfernen."));
|
||||
entries.add(new FaqEntry(4, "Wie kann ich meinen Support bewerten?",
|
||||
"Nach dem Schließen eines Tickets kannst du mit /ticket rate <ID> good/bad eine Bewertung abgeben."));
|
||||
|
||||
for (int i = 1; i <= 4; i++) {
|
||||
String q = faqConfig.getString("faqs." + i + ".question", "");
|
||||
String a = faqConfig.getString("faqs." + i + ".answer", "");
|
||||
FaqEntry e = new FaqEntry(i, q, a);
|
||||
e.setCategoryKey("tickets");
|
||||
entries.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeEntry(int id, String question, String answer) {
|
||||
// ── YAML-Hilfsmethoden ─────────────────────────────────────────────────
|
||||
|
||||
private void writeCategory(String key, String name, String color, String description) {
|
||||
faqConfig.set("categories." + key + ".name", name);
|
||||
faqConfig.set("categories." + key + ".color", color);
|
||||
faqConfig.set("categories." + key + ".description", description);
|
||||
}
|
||||
|
||||
private void writeEntry(int id, String question, String answer, String categoryKey) {
|
||||
faqConfig.set("faqs." + id + ".question", question);
|
||||
faqConfig.set("faqs." + id + ".answer", answer);
|
||||
if (categoryKey != null && !categoryKey.equals(UNCATEGORIZED_KEY)) {
|
||||
faqConfig.set("faqs." + id + ".category", categoryKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void save() {
|
||||
@@ -117,54 +177,130 @@ public class FaqManager {
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────── Public API ────────────────────────────────
|
||||
// ─────────────────────────── Public API – Kategorien ───────────────────
|
||||
|
||||
/** Returns an unmodifiable view of all FAQ entries in ID order. */
|
||||
public List<FaqEntry> getAll() {
|
||||
return Collections.unmodifiableList(entries);
|
||||
public boolean hasCategoriesEnabled() { return !categories.isEmpty(); }
|
||||
|
||||
public List<FaqCategory> getAllCategories() {
|
||||
return Collections.unmodifiableList(new ArrayList<>(categories.values()));
|
||||
}
|
||||
|
||||
/** Looks up an entry by its numeric ID. Returns null if not found. */
|
||||
public FaqEntry getById(int id) {
|
||||
return entries.stream().filter(e -> e.getId() == id).findFirst().orElse(null);
|
||||
public FaqCategory getCategoryByKey(String key) {
|
||||
if (key == null) return null;
|
||||
return categories.get(key.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new FAQ entry and saves immediately.
|
||||
* Fügt eine neue Kategorie hinzu und speichert sofort.
|
||||
*
|
||||
* @param question The question text.
|
||||
* @param answer The answer text.
|
||||
* @return The newly created {@link FaqEntry}.
|
||||
* @return null wenn der Schlüssel bereits existiert, sonst die neue FaqCategory.
|
||||
*/
|
||||
public FaqEntry add(String question, String answer) {
|
||||
int id = nextId++;
|
||||
FaqEntry entry = new FaqEntry(id, question, answer);
|
||||
entries.add(entry);
|
||||
writeEntry(id, question, answer);
|
||||
public FaqCategory addCategory(String key, String name, String color, String description) {
|
||||
String lowerKey = key.toLowerCase().replaceAll("\\s+", "_");
|
||||
if (categories.containsKey(lowerKey)) return null;
|
||||
FaqCategory cat = new FaqCategory(lowerKey, name, color, description);
|
||||
categories.put(lowerKey, cat);
|
||||
writeCategory(lowerKey, name, color, description);
|
||||
save();
|
||||
return entry;
|
||||
return cat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits an existing FAQ entry and saves immediately.
|
||||
* Bearbeitet eine bestehende Kategorie und speichert sofort.
|
||||
*
|
||||
* @return true if the entry was found and updated, false otherwise.
|
||||
* @return true wenn gefunden und aktualisiert.
|
||||
*/
|
||||
public boolean edit(int id, String question, String answer) {
|
||||
FaqEntry entry = getById(id);
|
||||
if (entry == null) return false;
|
||||
entry.setQuestion(question);
|
||||
entry.setAnswer(answer);
|
||||
writeEntry(id, question, answer);
|
||||
public boolean editCategory(String key, String name, String color, String description) {
|
||||
String lowerKey = key.toLowerCase();
|
||||
if (!categories.containsKey(lowerKey)) return false;
|
||||
FaqCategory updated = new FaqCategory(lowerKey, name, color, description);
|
||||
categories.put(lowerKey, updated);
|
||||
writeCategory(lowerKey, name, color, description);
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a FAQ entry and saves immediately.
|
||||
* Löscht eine Kategorie. FAQs dieser Kategorie werden auf UNCATEGORIZED_KEY gesetzt.
|
||||
*
|
||||
* @return true if the entry was found and deleted, false otherwise.
|
||||
* @return true wenn gefunden und gelöscht.
|
||||
*/
|
||||
public boolean deleteCategory(String key) {
|
||||
String lowerKey = key.toLowerCase();
|
||||
if (!categories.containsKey(lowerKey)) return false;
|
||||
categories.remove(lowerKey);
|
||||
faqConfig.set("categories." + lowerKey, null);
|
||||
// FAQs dieser Kategorie auf "keine Kategorie" setzen
|
||||
for (FaqEntry entry : entries) {
|
||||
if (lowerKey.equals(entry.getCategoryKey())) {
|
||||
entry.setCategoryKey(UNCATEGORIZED_KEY);
|
||||
faqConfig.set("faqs." + entry.getId() + ".category", null);
|
||||
}
|
||||
}
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<FaqEntry> getByCategory(String categoryKey) {
|
||||
String normalizedKey = normalizeCategoryKey(categoryKey);
|
||||
List<FaqEntry> result = new ArrayList<>();
|
||||
for (FaqEntry e : entries) {
|
||||
if (normalizedKey.equals(e.getCategoryKey())) result.add(e);
|
||||
}
|
||||
return Collections.unmodifiableList(result);
|
||||
}
|
||||
|
||||
public int countByCategory(String categoryKey) {
|
||||
return getByCategory(categoryKey).size();
|
||||
}
|
||||
|
||||
// ─────────────────────────── Public API – Einträge ─────────────────────
|
||||
|
||||
public List<FaqEntry> getAll() { return Collections.unmodifiableList(entries); }
|
||||
|
||||
public FaqEntry getById(int id) {
|
||||
return entries.stream().filter(e -> e.getId() == id).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public FaqEntry add(String question, String answer, String categoryKey) {
|
||||
int id = nextId++;
|
||||
String normalizedKey = normalizeCategoryKey(categoryKey);
|
||||
FaqEntry entry = new FaqEntry(id, question, answer);
|
||||
entry.setCategoryKey(normalizedKey);
|
||||
entries.add(entry);
|
||||
writeEntry(id, question, answer, normalizedKey);
|
||||
save();
|
||||
return entry;
|
||||
}
|
||||
|
||||
public FaqEntry add(String question, String answer) {
|
||||
return add(question, answer, null);
|
||||
}
|
||||
|
||||
public boolean edit(int id, String question, String answer) {
|
||||
FaqEntry entry = getById(id);
|
||||
if (entry == null) return false;
|
||||
entry.setQuestion(question);
|
||||
entry.setAnswer(answer);
|
||||
writeEntry(id, question, answer, entry.getCategoryKey());
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean setCategory(int id, String categoryKey) {
|
||||
FaqEntry entry = getById(id);
|
||||
if (entry == null) return false;
|
||||
String normalizedKey = normalizeCategoryKey(categoryKey);
|
||||
entry.setCategoryKey(normalizedKey);
|
||||
if (normalizedKey.equals(UNCATEGORIZED_KEY)) {
|
||||
faqConfig.set("faqs." + id + ".category", null);
|
||||
} else {
|
||||
faqConfig.set("faqs." + id + ".category", normalizedKey);
|
||||
}
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean delete(int id) {
|
||||
FaqEntry entry = getById(id);
|
||||
if (entry == null) return false;
|
||||
@@ -174,8 +310,20 @@ public class FaqManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Reloads FAQs from faqs.yml without restarting the server. */
|
||||
public void reload() {
|
||||
load();
|
||||
public void reload() { load(); }
|
||||
|
||||
// ─────────────────────────── Hilfsmethoden ─────────────────────────────
|
||||
|
||||
private String normalizeCategoryKey(String key) {
|
||||
if (key == null || key.isBlank()) return UNCATEGORIZED_KEY;
|
||||
String lower = key.toLowerCase();
|
||||
if (lower.equals(UNCATEGORIZED_KEY)) return UNCATEGORIZED_KEY;
|
||||
if (!categories.isEmpty() && !categories.containsKey(lower)) return UNCATEGORIZED_KEY;
|
||||
return lower;
|
||||
}
|
||||
|
||||
private static String capitalize(String s) {
|
||||
if (s == null || s.isEmpty()) return s;
|
||||
return Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user