grundlegente Umstellung + Earthdawn Implemntation

This commit is contained in:
Ocame
2025-07-06 16:22:48 +02:00
parent 10c8c9900f
commit e2b9694e09
48 changed files with 1488 additions and 638 deletions

View File

@ -1,355 +0,0 @@
package Serenity;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.*;
public class balance extends ListenerAdapter {
private String prefixPromote;
private String prefixDegradation;
private String prefixDetail;
private String prefixCow;
private String prefixCow2;
public balance() {
this.prefixPromote = "/konto";
this.prefixDegradation = "/pay ";
this.prefixDetail = "/detail";
this.prefixCow = "/cow";
this.prefixCow2 = "/Cattle";
}
@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getMessage().getContentRaw().startsWith("!ende")) { // nur zum Debugen #todo muss wieder raus
event.getJDA().shutdown();
}
if (event.getMessage().getContentRaw().startsWith(this.prefixCow) || event.getMessage().getContentRaw().startsWith(this.prefixCow2)) { // nur zum Debugen #todo muss wieder raus
event.getChannel().sendMessage("NO FUCKING COWS AND COW-LIKE ANIMALS ON THE SHIP!").queue();
}
if ((!event.getMessage().getContentRaw().startsWith(this.prefixPromote) &&
!event.getMessage().getContentRaw().startsWith(this.prefixDegradation) &&
!event.getMessage().getContentRaw().startsWith(this.prefixDetail)) || event.getChannelType() != ChannelType.TEXT) {
return;
}
User author = event.getAuthor();
if (!author.isBot()) {
if (event.getMessage().getContentRaw().startsWith(this.prefixPromote))
this.getInfo(event);
else if (event.getMessage().getContentRaw().startsWith(this.prefixDegradation))
this.addTransaction(event);
else if (event.getMessage().getContentRaw().startsWith(this.prefixDetail))
this.getInfo(event, true);
}
}
private void getInfo(MessageReceivedEvent event) {
this.getInfo(event, false);
}
/**
* Holt Kontostand ab
*
* @param event JDA Event
* @param detail true = Abrufen der Detail, Chronologich, false = gesammt Kontostand
*/
private void getInfo(MessageReceivedEvent event, Boolean detail) {
HttpURLConnection con = null;
//String result = "";
StringBuilder result_test = new StringBuilder("");
DecimalFormat myFormatter = new DecimalFormat();
Map<String, Integer> IdConvert = new HashMap<>();
IdConvert.put("256888865103544321", 2); // Niclos
IdConvert.put("495895196685303818", 3); // Birgit
IdConvert.put("385865287586545676", 7); // Felix
IdConvert.put("493359873480720384", 5); // orko
IdConvert.put("339859242917953537", 4); // christian
IdConvert.put("397055491488088065", 6); // Filip
IdConvert.put(event.getJDA().getSelfUser().getId(), 1); // Schiff
try {
// Zerlgen der Anfrage
String parameter = "";
if (event.getMessage().getMentions().getUsers() .size() > 0) {
if (IdConvert.containsKey(event.getMessage().getMentions().getUsers().get(0).getId()))
parameter = "?id=" + (IdConvert.get(event.getMessage().getMentions().getUsers().get(0).getId()));
} else {
parameter = "?id=1";
}
if (detail) {
parameter += "&detail=1";
}
// aufbau zum REST
URL url = new URL("http://localhost/REST/balance" + parameter);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(3600);
con.setReadTimeout(360);
con.setUseCaches(false);
con.connect();
int status = con.getResponseCode();
switch (status) {
case 200:
case 201: // auswerten der Antwort
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
JSONObject responseJson = new JSONObject(content.toString());
Iterator<String> keys = responseJson.keys();
while (keys.hasNext()) {
String key = keys.next();
if (responseJson.get(key) instanceof JSONObject) {
result_test.append("**").append(((JSONObject) responseJson.get(key)).get("name").toString()).append(":**\n");
result_test.append("```");
if (detail) {
JSONArray transaction = (JSONArray) ((JSONObject) responseJson.get(key)).get("transaction");
for (int i = 0; i < transaction.length(); i++) {
for (int j = 7 - (myFormatter.format(Float.parseFloat(((JSONObject) transaction.get(i)).get("amount").toString()))).length(); j > 0; j--) {
result_test.append(" ");
}
result_test.append( (myFormatter.format(Float.parseFloat(((JSONObject) transaction.get(i)).get("amount").toString()))));
result_test.append(" ").append( ((JSONObject) transaction.get(i)).get("currency_name").toString()).append(" ");
result_test.append(" - ").append(((JSONObject) transaction.get(i)).get("reason").toString());
result_test.append( "\n");
}
result_test.append( "\n-------------------------------------\n");
}
JSONArray balance = (JSONArray) ((JSONObject) responseJson.get(key)).get("balance");
for (int i = 0; i < balance.length(); i++) {
for (int j = 7 - (myFormatter.format(Float.parseFloat(((JSONObject) balance.get(i)).get("amount").toString()))).length(); j > 0; j--) {
result_test.append(" ");
}
result_test.append( (myFormatter.format(Float.parseFloat(((JSONObject) balance.get(i)).get("amount").toString()))));
result_test.append(" ").append( ((JSONObject) balance.get(i)).get("currency_name").toString()).append(" ");
result_test.append( "\n");
}
result_test.append( "```");
}
}
event.getChannel().sendMessage(event.getMember().getAsMention() + "\n" + result_test.toString()).queue();
break;
default:
System.out.println(":(");
}
con.disconnect();
} catch (Exception e) {
System.out.println("problem: " + e.getMessage());
} finally {
if (con != null) { // Verbindung schließen wenn noch offen
try {
con.disconnect();
} catch (Exception ex) {
System.out.println("final fehler");
}
}
}
}
/**
* Fügt neue Transaktion hinzu
*
* @param event JDA Event
*/
private void addTransaction(MessageReceivedEvent event) {
Map<String, Integer> IdConvert = new HashMap<>();
IdConvert.put("256888865103544321", 2); // Niclos
IdConvert.put("495895196685303818", 3); // Birgit
IdConvert.put("385865287586545676", 7); // Felix
IdConvert.put("493359873480720384", 5); // orko
IdConvert.put("339859242917953537", 4); // christian
IdConvert.put("397055491488088065", 6); // Filip
IdConvert.put(event.getJDA().getSelfUser().getId(), 1); // Schiff
Map<String, Integer> currencyConvert = new HashMap<>();
currencyConvert.put("credit", 1);
currencyConvert.put("c", 1);
currencyConvert.put("doller", 2);
currencyConvert.put("d", 2);
currencyConvert.put("$", 2);
currencyConvert.put("platinum", 3);
currencyConvert.put("p", 3);
currencyConvert.put("gold", 4);
currencyConvert.put("g", 4);
currencyConvert.put("silver", 5);
currencyConvert.put("s", 5);
Map<Integer, String> currencyConvert2 = new HashMap<>();
currencyConvert2.put(1, "Credit");
currencyConvert2.put(2, "Doller");
currencyConvert2.put(3, "Platinum");
currencyConvert2.put(4, "Gold");
currencyConvert2.put(5, "Silver");
int[] ids;
StringBuilder result = new StringBuilder("");
boolean allfound = true;
String[] MsgParts;
float ammount;
HttpURLConnection con = null;
try {
// Aufteilen Nachricht in Bennunungen und Rest
String[] MsgParts_exl_Mention = event.getMessage().getContentRaw().split(event.getMessage().getMentionedUsers().get(event.getMessage().getMentionedUsers().size() - 1).getAsMention(), 2);
MsgParts = MsgParts_exl_Mention[1].trim().split(" ");
ids = new int[event.getMessage().getMentionedUsers().size()];
// Pürfen ob Angebe der Währung bekannt ist
if (!currencyConvert.containsKey(MsgParts[1].toLowerCase())) {
event.getChannel().sendMessage(event.getMember().getAsMention() + " " + MsgParts[1] + " ist keine bekannte Währung").queue();
return;
}
// Prüfen ob Zahl legal ist
try {
ammount = Float.parseFloat(MsgParts[0]);
} catch (NumberFormatException e) {
event.getChannel().sendMessage(event.getMember().getAsMention() + " " + MsgParts[MsgParts.length - 2] + " ist keine gültige Zahl").queue();
return;
}
// Prüfen ob alle gennanten Personen zur Zahlung gehören
for (int i = 0; i < event.getMessage().getMentionedUsers().size(); i++) {
if (!IdConvert.containsKey(event.getMessage().getMentionedUsers().get(i).getId())) {
allfound = false;
result.append(" ").append(event.getMessage().getMentionedUsers().get(i).getName());
} else {
ids[i] = IdConvert.get(event.getMessage().getMentionedUsers().get(i).getId());
}
}
if (!allfound) {
event.getChannel().sendMessage(event.getMember().getAsMention() + result.toString() + " wurde(n) nicht gefunden").queue();
return;
}
String reason = MsgParts_exl_Mention[1].trim().substring(MsgParts[0].length() + MsgParts[1].length() + 2);
// Aufbau Payload zur übertragung an REST Schnittstelle
JSONObject payload = new JSONObject();
payload.put("ammount", ammount);
payload.put("currency_id", currencyConvert.get(MsgParts[1].toLowerCase()));
payload.put("ids", ids);
payload.put("reason", reason);
URL url = new URL("http://localhost/REST/balance");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setConnectTimeout(3600);
con.setReadTimeout(3600);
con.setDoInput(true);
con.setDoOutput(true);
con.setDefaultUseCaches(false);
// Übertragen der Payload
OutputStream os = con.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(payload.toString());
writer.flush();
writer.close();
int status = con.getResponseCode();
switch (status) {
case 200:
case 201: // Verarbeiten der Antwort
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
JSONObject responseJson = new JSONObject(content.toString());
Iterator<String> keys = responseJson.keys();
result = new StringBuilder("");
while (keys.hasNext()) {
String key = keys.next();
String id = getKey(IdConvert, Integer.parseInt(key));
if (key.equals("1")) {
result.append("Das Schiff bekommt: ").append(responseJson.get(key)).append(" ").append(currencyConvert2.get(currencyConvert.get(MsgParts[1].toLowerCase()))).append(" ");
} else {
result.append(event.getGuild().getMemberById(id).getAsMention()).append(" bekommt ").append(responseJson.get(key)).append(" ").append(currencyConvert2.get(currencyConvert.get(MsgParts[1].toLowerCase()))).append(" ");
}
}
event.getChannel().sendMessage(event.getMember().getAsMention() + " " + result.toString()).queue();
break;
default:
System.out.println(":(");
}
con.disconnect();
} catch (Exception e) {
System.out.println("problem: " + e.getMessage());
} finally {
if (con != null) { // Verbindung schließen wenn noch offen
try {
con.disconnect();
} catch (Exception ex) {
System.out.println("final fehler");
}
}
}
}
/**
* Sucht in einer Map nach Wert und gibt Schlüßel zurück
* @param map Map mit allen Werten
* @param value gesuchtet wert
* @param <K> erste Typ
* @param <V> zweiter typ
* @return <K,V>|null
*/
private <K, V> K getKey(Map<K, V> map, V value) {
for (Map.Entry<K, V> entry : map.entrySet()) {
if (entry.getValue().equals(value)) {
return entry.getKey();
}
}
return null;
}
}

View File

@ -1,4 +0,0 @@
package core;
public class Controller {
}

View File

@ -1,42 +0,0 @@
package core;
//import Serenity.balance;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.requests.GatewayIntent;
public class Main {
public static void main(String[] args) {
// Insert your bot's token here
//String token = "NTQ2ODk5MzYwMDEzODc3MjU4.D0u8wA.VfA2vJzundVhCl1-ibDiBaKuA8w";
// iro
String token = "NTQ2NzEwODUwOTIxMjk5OTc5.D0sL6A.1fUd5iBr3eo2tbPXofEqyumDm6w";
JDA jda = JDABuilder.createDefault(token)
.enableIntents(GatewayIntent.MESSAGE_CONTENT)
.setActivity(Activity.playing("mit den Würfeln"))
.setStatus(OnlineStatus.ONLINE)
//.addEventListeners(new dice())
.addEventListeners(new Earthdawn.dice())
.addEventListeners(new Simpleroll.dice())
.addEventListeners(new Shadowrun.dice())
.addEventListeners(new Engel.dice())
.addEventListeners(new Keeproll.dice())
.setAutoReconnect(true)
.build();
//jda.upsertCommand("sr", "Calculate ping of the bot").queue();
// Thread thread = new Thread(new shadowrun(jda));
//thread.start();
}
}

View File

@ -1,83 +0,0 @@
package core;
import java.io.*;
import java.util.Properties;
public class config {
public String token;
public String GameWatching = "Den NinjaSäuen zu";
public String targetRole = "Ninjasau";
public String authorizedRole = "Chief Ninjasau";
public String userNotFound = "Benutzer nicht gefunden";
public String noPrivilegs = "Du bist nicht berechtigt den Befehl auszuführen";
public String hasGroup = "%Member% hat bereits die Gruppe %Group%";
public String becameGroup = "%Member% wurde der Gruppe %Group% zugeteilt";
public String notInGroup = "%Member% ist nicht in der Gruppe %Group%";
public String removeGroup = "%Member% wurde aus der Gruppe %Group% entfernt";
public void readConfig() {
FileInputStream input = null;
OutputStream output = null;
Properties config = new Properties();
try {
File f = new File("config.cfg");
if (f.isFile() && f.canRead()) {
input = new FileInputStream("config.cfg");
config.load(input);
if(config.containsKey("token"))
this.token = config.getProperty("token");
if(config.containsKey("GameWatching"))
this.GameWatching = config.getProperty("GameWatching");
if(config.containsKey("targetRole"))
this.targetRole = config.getProperty("targetRole");
if(config.containsKey("authorizedRole"))
this.authorizedRole = config.getProperty("authorizedRole");
if(config.containsKey("userNotFound"))
this.userNotFound = config.getProperty("userNotFound");
if(config.containsKey("noPrivilegs"))
this.noPrivilegs = config.getProperty("noPrivilegs");
if(config.containsKey("hasGroup"))
this.hasGroup = config.getProperty("hasGroup");
if(config.containsKey("becameGroup"))
this.becameGroup = config.getProperty("becameGroup");
if(config.containsKey("notInGroup"))
this.notInGroup = config.getProperty("notInGroup");
if(config.containsKey("removeGroup"))
this.removeGroup = config.getProperty("removeGroup");
}
else {
output = new FileOutputStream("config.cfg");
config.setProperty("targetRole", this.targetRole);
config.setProperty("authorizedRole", this.authorizedRole);
config.setProperty("userNotFound", this.userNotFound);
config.setProperty("noPrivilegs", this.noPrivilegs);
config.setProperty("hasGroup", this.hasGroup);
config.setProperty("becameGroup", this.becameGroup);
config.setProperty("notInGroup", this.notInGroup);
config.setProperty("removeGroup", this.removeGroup);
config.store(output, null);
}
} catch (Exception e) {
}
finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

View File

@ -1,8 +0,0 @@
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<GridPane fx:controller="core.Controller"
xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>

View File

@ -1,8 +1,5 @@
package DB;
package de.ocame.wuerfelbot.DB;
import net.dv8tion.jda.api.JDA;
import javax.security.auth.login.LoginException;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;

View File

@ -0,0 +1,173 @@
package de.ocame.wuerfelbot.Earthdawn;
import de.ocame.wuerfelbot.commands.ICommand;
import de.ocame.wuerfelbot.core.LoggerUtil;
import de.ocame.wuerfelbot.output.DiceOutputFormatter;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EarthdawnCommand implements ICommand {
private final EarthdawnLogic earthdawnLogic;
private final DiceOutputFormatter outputFormatter;
public EarthdawnCommand() {
this.earthdawnLogic = new EarthdawnLogic();
this.outputFormatter = new DiceOutputFormatter();
}
@Override
public String getName() {
return "ed";
}
@Override
public String getDescription() {
return "Führt eine Earthdawn-Probe durch (Stufe + optional Karma oder Weihewürfel).";
}
@Override
public void executeSlash(SlashCommandInteractionEvent event) {
Integer stufe = event.getOption("stufe").getAsInt(); // "stufe" ist der Name der Option
Integer karma = event.getOption("karma") != null ? event.getOption("karma").getAsInt() : 0; // "karma" ist optional
Integer meisterkarma = event.getOption("meisterkarma") != null ? event.getOption("meisterkarma").getAsInt() : 0;
Integer weiheJ = event.getOption("weihe-j") != null ? event.getOption("weihe-j").getAsInt() : 0;
Integer weiheA = event.getOption("weihe-a") != null ? event.getOption("weihe-a").getAsInt() : 0;
Integer weiheV = event.getOption("weihe-v") != null ? event.getOption("weihe-v").getAsInt() : 0;
if (stufe < 1) {
event.reply(outputFormatter.formatError("Die Stufe muss mindestens 1 sein.")).setEphemeral(true).queue();
return;
}
if (karma < 0 || meisterkarma < 0 || weiheJ < 0 || weiheA < 0 || weiheV < 0) {
event.reply(outputFormatter.formatError("Zusatzwürfel dürfen nicht negativ sein.")).setEphemeral(true).queue();
return;
}
try {
EarthdawnLogic.EarthdawnResult result = earthdawnLogic.performEarthdawnRoll(stufe, karma, meisterkarma, weiheJ, weiheA, weiheV);
EmbedBuilder response = outputFormatter.DCDefaultOutput(getEffectiveName(event) + result.getTitle(), result.getDescription(), result.isGlitch());
event.deferReply().queue();
//event.reply(response).queue();
//event.getChannel().sendMessageEmbeds(response.build()).queue();
event.getHook().editOriginalEmbeds(response.build()).queue();
// event.replyEmbeds(response.build()).queue();
} catch (Exception e) {
LoggerUtil.log("error", "EDCommand", "Fehler bei Earthdawn-Probe: " + e.getMessage());
event.reply(outputFormatter.formatError("Ein Fehler ist bei der Earthdawn-Probe aufgetreten.")).setEphemeral(true).queue();
}
}
@Override
public void executeText(MessageReceivedEvent event, String[] args) {
if (args.length < 1) {
event.getChannel().sendMessage(outputFormatter.formatError("Verwendung: `!ed <stufe> [karma]`")).queue();
return;
}
Integer stufe = 0;
Integer karma = 0;
Integer meisterkarma = 0;
Integer weiheJ = 0;
Integer weiheA = 0;
Integer weiheV = 0;
boolean stufeParsed = false;
for (int i = 0; i < args.length; i++) {
String currentElement = args[i].trim().toLowerCase(); // Leerzeichen in Elementen entfernen
if (currentElement.isEmpty()) {
continue; // Leere Elemente überspringen
}
// 1. Stufe parsen (nur einmal ganz am Anfang)
if (!stufeParsed && currentElement.matches("^\\d+$")) {
stufe = Integer.parseInt(currentElement);
stufeParsed = true;
continue; // Stufe wurde geparst, gehe zum nächsten Element
} else if (!stufeParsed && currentElement.matches("^\\d+.*")) {
Pattern pattern = Pattern.compile("^(\\d+)");
Matcher matcher = pattern.matcher(currentElement);
matcher.find();
stufe = Integer.parseInt(matcher.group(1));
stufeParsed = true;
currentElement = currentElement.replaceAll("^\\d+", "");
}
karma += parseCharacterStat(currentElement, 'k');
meisterkarma += parseCharacterStat(currentElement, 'm');
weiheJ += parseCharacterStat(currentElement, 'j');
weiheA += parseCharacterStat(currentElement, 'a');
weiheV += parseCharacterStat(currentElement, 'v');
}
if (stufe < 1) {
event.getChannel().sendMessage(outputFormatter.formatError("Die Stufe muss mindestens 1 sein.")).queue();
return;
}
try {
EarthdawnLogic.EarthdawnResult result = earthdawnLogic.performEarthdawnRoll(stufe, karma, meisterkarma, weiheJ, weiheA, weiheV);
EmbedBuilder response = outputFormatter.DCDefaultOutput(getEffectiveName(event) + result.getTitle(), result.getDescription(), result.isGlitch());
event.getChannel().sendMessageEmbeds(response.build()).queue();
} catch (Exception e) {
LoggerUtil.log("error", "EDCommand", "Fehler bei Earthdawn-Probe: " + e.getMessage());
event.getChannel().sendMessage(outputFormatter.formatError("Ein Fehler ist bei der Earthdawn-Probe aufgetreten.")).queue();
}
}
@Override
public CommandData getSlashCommandData() {
return Commands.slash(getName(), getDescription())
.addOption(OptionType.INTEGER, "stufe", "Stufe der Probe", true)
.addOption(OptionType.INTEGER, "karma", "Optionale Anzahl der Karma (W6-Würfel)", false)
.addOption(OptionType.INTEGER, "meisterkarma", "Optionale Anzahl der Meister-Karma (W8-Würfel)", false)
.addOption(OptionType.INTEGER, "weihe-j", "Optionale Anzahl der Jünger-Weihewürfe (W4-Würfel)", false)
.addOption(OptionType.INTEGER, "weihe-a", "Optionale Anzahl der Anhänger-Weihewürfel (W6-Würfel)", false)
.addOption(OptionType.INTEGER, "weihe-v", "Optionale Anzahl der Vorbild-Weihewürfel (W8-Würfel)", false);
}
private String getEffectiveName(MessageReceivedEvent event) {
if (event.getMember() == null) {
return "";
}
return event.getMember().getEffectiveName() + " ";
}
private String getEffectiveName(SlashCommandInteractionEvent event) {
if (event.getMember() == null) {
return "";
}
return event.getMember().getEffectiveName() + " ";
}
private static int parseCharacterStat(String currentElement, char targetChar) {
int result = 0;
Pattern pattern = Pattern.compile("((" + targetChar + "+) *(\\d*))");
Matcher matcher = pattern.matcher(currentElement);
if (matcher.find()) {
if (matcher.group(2).length() == 1 && !matcher.group(3).isEmpty()) { // nur die K
result += Integer.parseInt(matcher.group(3));
}
else {
result += matcher.group(2).length();
}
}
return result;
}
}

View File

@ -0,0 +1,409 @@
package de.ocame.wuerfelbot.Earthdawn;
import java.util.*;
public class EarthdawnLogic {
private final Random random;
private int w4;
private int w6;
private int w8;
private int w10;
private int w12;
private int w20;
private int karma;
private int meisterkarma;
private int weiheA;
private int weiheJ;
private int weiheV;
private boolean glitches;
private int resultInt;
private int modifier;
StringBuilder resultStructur;
public EarthdawnLogic() {
this.random = new Random();
reset();
}
public EarthdawnLogic reset() {
w4 = 0;
w6 = 0;
w8 = 0;
w10 = 0;
w12 = 0;
w20 = 0;
karma = 0;
meisterkarma = 0;
weiheJ = 0;
weiheA = 0;
weiheV = 0;
modifier = 0;
glitches = true;
resultInt = 0;
resultStructur = new StringBuilder();
return this;
}
/**
* Führt eine Earthdawn-Würfelprobe durch.
* Würfelt eine bestimmte Anzahl an Ws Abhänig von Stufe und optional Würfeln (z.b. Karma).
*
* @param stufe Die Stufe die Gewürfelt werden soll (Stufe). Muss >= 1 sein.
* @param karma Die Anzahl der W6 (Karma), die gewürfelt werden sollen. Muss >= 0 sein.
* @param meisterkarma Die Anzahl der W8 (Karma), die gewürfelt werden sollen. Muss >= 0 sein.
* @param weiheJ Die Anzahl der W4 (Weihe Juenger), die gewürfelt werden sollen. Muss >= 0 sein.
* @param weiheA Die Anzahl der W6 (Weihe Anheanger), die gewürfelt werden sollen. Muss >= 0 sein.
* @param weiheV Die Anzahl der W8 (Weihe Vorbild), die gewürfelt werden sollen. Muss >= 0 sein.
* @return Ein {@link EarthdawnResult}-Objekt mit den einzelnen Würfelergebnissen und Summen.
* @throws IllegalArgumentException Wenn stufe < 1 oder optionale < 0 ist.
*/
public EarthdawnResult performEarthdawnRoll(int stufe, int karma, int meisterkarma, int weiheJ, int weiheA, int weiheV) {
if (stufe < 1) {
throw new IllegalArgumentException("Die Stufe muss mindestens 1 sein.");
}
if (karma < 0) {
throw new IllegalArgumentException("Karma kann nicht negativ sein.");
}
if (meisterkarma < 0) {
throw new IllegalArgumentException("Meister-Karma kann nicht negativ sein");
}
if (weiheJ < 0) {
throw new IllegalArgumentException("Jünger-Weihewürfe kann nicht negativ sein.");
}
if (weiheA < 0) {
throw new IllegalArgumentException("Anhänger-Weihewürfe kann nicht negativ sein.");
}
if (weiheV < 0) {
throw new IllegalArgumentException("Vorbild-Weihewürfe kann nicht negativ sein.");
}
reset();
// Parameter in Würfel Konvertieren
calcStufe(stufe);
this.setKarma(karma);
this.setMeisterkarma(meisterkarma);
this.setWeiheJ(weiheJ);
this.setWeiheA(weiheA);
this.setWeiheV(weiheV);
// Würfelarten durchgehen und Würfeln, Sonderwürfel werden imm am Schluss abgearbeitet
StringBuilder resultConstruction = new StringBuilder();
List<DiceRollAction> rollsToPerform = new ArrayList<>();
if (w4 > 0) rollsToPerform.add(new DiceRollAction(w4, 4, null));
if (w6 > 0) rollsToPerform.add(new DiceRollAction(w6, 6, null));
if (w8 > 0) rollsToPerform.add(new DiceRollAction(w8, 8, null));
if (w10 > 0) rollsToPerform.add(new DiceRollAction(w10, 10, null));
if (w12 > 0) rollsToPerform.add(new DiceRollAction(w12, 12, null));
if (w20 > 0) rollsToPerform.add(new DiceRollAction(w20, 20, null));
// Sonderwürfel
if (karma > 0) rollsToPerform.add(new DiceRollAction(karma, 6, "Karma"));
if (meisterkarma > 0) rollsToPerform.add(new DiceRollAction(meisterkarma, 8, "Meisterkarma"));
if (weiheJ > 0) rollsToPerform.add(new DiceRollAction(weiheJ, 4, "Jünger"));
if (weiheA > 0) rollsToPerform.add(new DiceRollAction(weiheA, 6, "Anhänger"));
if (weiheV > 0) rollsToPerform.add(new DiceRollAction(weiheV, 8, "Vorbild"));
for (DiceRollAction action : rollsToPerform) {
rollDice(action.count, action.sides);
if (!resultConstruction.isEmpty()) {
resultConstruction.append(" + ");
}
if (action.label != null) {
resultConstruction.append(action.count).append("w").append(action.sides).append(" (").append(action.label).append(")");
} else {
resultConstruction.append(action.count).append("w").append(action.sides);
}
}
// Modifikator separat behandeln, da er nicht gewürfelt wird
if (modifier != 0) {
resultInt += modifier; // Addiere den Modifikator zur Gesamtsum
if (!resultConstruction.isEmpty()) {
resultConstruction.append(modifier > 0 ? " + " : " - "); // Füge + oder - hinzu
}
resultConstruction.append(Math.abs(modifier)); // Zeige den absoluten Wert an
}
return new EarthdawnResult(resultStructur.toString(), resultInt, resultConstruction.toString(), isGlitches());
}
/**
* Eine innere Klasse, die das Ergebnis einer Earthdawn-Probe kapselt.
* Dies macht die Rückgabe mehrerer Werte einfacher und lesbarer.
*/
public static class EarthdawnResult {
private final String resultStructur;
private final String resultInt;
private final String resultConstruction;
private final boolean glitch;
public boolean isGlitch() {
return glitch;
}
public EarthdawnResult(String resultStructur, int resultInt, String resultConstruction, boolean glitch) {
this.resultStructur = resultStructur;
this.resultInt = String.valueOf(resultInt);
this.glitch = glitch;
this.resultConstruction = resultConstruction;
}
public String getResultStructur() {
return resultStructur;
}
public String getResultInt() {
return resultInt;
}
public String getDescription() {
return "(" + resultStructur + ")";
}
public String getTitle() {
String message = "%rolls%: %hits%";
return message.replace("%rolls%", resultConstruction).replace("%hits%", resultInt);
}
}
/**
* Berechnet die benutzten Würfel anhand der Stufe
*
* @param stufe
*/
private void calcStufe(int stufe) {
switch (stufe) {
case 1:
this.setW4(1).setModifier(-2);
break;
case 2:
this.setW4(1).setModifier(-1);
break;
case 3:
this.setW4(1);
break;
case 4:
this.setW6(1);
break;
case 5:
this.setW8(1);
break;
case 6:
this.setW10(1);
break;
case 7:
this.setW12(1);
break;
case 8:
this.setW6(2);
break;
case 9:
this.setW8(1).setW6(1);
break;
case 10:
this.setW8(2);
break;
case 11:
this.setW10(1).setW8(1);
break;
case 12:
this.setW10(2);
case 13:
this.setW12(1).setW10(1);
break;
case 14:
this.setW12(2);
break;
case 15:
this.setW12(1).setW6(2);
break;
case 16:
this.setW12(1).setW8(1).setW6(1);
break;
case 17:
this.setW12(1).setW8(2);
break;
case 18:
this.setW12(1).setW10(1).setW8(1);
break;
default:
int w20 = 0;
w20 = (stufe-8)/11;
switch ((stufe-8)%11) {
case 0:
this.setW20(w20).setW6(2);
break;
case 1:
this.setW20(w20).setW8(1).setW6(1);
break;
case 2:
this.setW20(w20).setW8(2);
break;
case 3:
this.setW20(w20).setW10(1).setW8(1);
break;
case 4:
this.setW20(w20).setW10(2);
break;
case 5:
this.setW20(w20).setW12(1).setW10(1);
break;
case 6:
this.setW20(w20).setW12(2);
break;
case 7:
this.setW20(w20).setW12(1).setW6(2);
break;
case 8:
this.setW20(w20).setW12(1).setW8(1).setW6(1);
break;
case 9:
this.setW20(w20).setW12(1).setW8(2);
break;
case 10:
this.setW20(w20).setW12(1).setW10(1).setW8(1);
break;
}
}
/*
diceList[30] = "2W20+2W6";
diceList[31] = "2W20+W8+W6";
diceList[32] = "2W20+2W8";
diceList[33] = "2W20+W10+W8";
diceList[34] = "2W20+2W10";
diceList[35] = "2W20+W12+W10";
diceList[36] = "2W20+2W12";
diceList[37] = "2W20+W12+2W6";
diceList[38] = "2W20+W12+W8+W6";
diceList[39] = "2W20+W12+2W8";
diceList[40] = "2W20+W12+W10+W8";
*/
}
public EarthdawnLogic setW4(int w4) {
this.w4 = w4;
return this;
}
public EarthdawnLogic setW6(int w6) {
this.w6 = w6;
return this;
}
public EarthdawnLogic setW8(int w8) {
this.w8 = w8;
return this;
}
public EarthdawnLogic setW10(int w10) {
this.w10 = w10;
return this;
}
public EarthdawnLogic setW12(int w12) {
this.w12 = w12;
return this;
}
public EarthdawnLogic setW20(int w20) {
this.w20 = w20;
return this;
}
public EarthdawnLogic setKarma(int karma) {
this.karma = karma;
return this;
}
public EarthdawnLogic setMeisterkarma(int meisterkarma) {
this.meisterkarma = meisterkarma;
return this;
}
public EarthdawnLogic setWeiheA(int weiheA) {
this.weiheA = weiheA;
return this;
}
public EarthdawnLogic setWeiheJ(int weiheJ) {
this.weiheJ = weiheJ;
return this;
}
public EarthdawnLogic setWeiheV(int weiheV) {
this.weiheV = weiheV;
return this;
}
public boolean isGlitches() {
return glitches;
}
public EarthdawnLogic setGlitches(boolean glitches) {
this.glitches = glitches;
return this;
}
public EarthdawnLogic setModifier(int modifier) {
this.modifier = modifier;
return this;
}
private void rollDice(int numberOfDice, int diceart) {
int dice;
for(int i = 0; i < numberOfDice; i++) {
dice = random.nextInt(diceart);
if(resultStructur.length() > 0) {
resultStructur.append(" ");
}
resultStructur.append(dice+1);
resultStructur.append("/");
resultStructur.append(diceart);
resultInt += dice+1;
if(dice+1 == diceart)
i--;
if(dice > 0)
glitches = false;
}
}
static class DiceRollAction {
int count;
int sides;
String label; // Optionaler Beschreibungslabel
public DiceRollAction(int count, int sides, String label) {
this.count = count;
this.sides = sides;
this.label = label;
}
}
}

View File

@ -1,36 +1,24 @@
package Earthdawn;
package de.ocame.wuerfelbot.Earthdawn;
import Shadowrun.db_connect;
import Shadowrun.help;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.awt.*;
import java.lang.reflect.Array;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class dice extends ListenerAdapter {
private final String prefixSr;
private String prefixIni;
private final language langDe = new language("de");
private final language langEn = new language("en");
private final help helpDe = new help("de");
private final help helpEn = new help("En");
private language activLang;
private help activHelp;
private final db_connect db;
@ -43,19 +31,6 @@ public class dice extends ListenerAdapter {
this.prefixSr = "/ed";
//this.prefixIni = "/ini";
helpDe.add("Alle Befehle können in einen Channel geschrieben werden oder per Direkt Nachricht gesendet");
helpDe.add(this.prefixSr + "Zahl", "Würfelt Zahl x W6. Gewürfelte 5. und 6. Werden als Erfolge gezählt, 1. als Misserfolge.\n" +
"Erreicht oder übersteigt die Anzhal der 1. die hälfte der gewürfelten Würfel, zählt dies als ein Patzer. Gibt es mind. 1 Erfolg wird die Markierung der Ausgabe Gelb." +
"wird aber kein Erfolg gewürfelt zählt dies als Kritischer Patzer und die Markierung wird Rot **Wichtig: Vor- und Nachteile die Einfluss auf die Patzer Changse haben werden nicht berücksichtigt");
helpDe.add(this.prefixSr + "+ Zahl", "Gleich wie bei " + this.prefixSr + "Zahl. Mit dem Unterschied dass alle gewürfelten 6. ein zuzätlichen Würfel generien.");
helpDe.add(this.prefixSr + " Zahl_1 + Zahl_2", "Würfelt Zahl_2 x W6 und addiert Zahl_1 hinzu, um die Initative zu bestimmen");
//helpDe.add(this.prefixIni + " Zahl_1 + Zahl_2", "Synonym für " + this.prefixSr + " Zahl_1 + Zahl_2");
this.db = new db_connect();
}
@ -85,7 +60,7 @@ public class dice extends ListenerAdapter {
author.isBot();
if (true) {
if (event.getMessage().getContentRaw().startsWith(this.prefixSr))
this.srroll(event);
this.roll(event);
}
}
@ -95,68 +70,7 @@ public class dice extends ListenerAdapter {
*
* @param event JDA Event
*/
private void rollTest(MessageReceivedEvent event) {
EmbedBuilder test = new EmbedBuilder();
test.setTitle("Das ist ein Test");
test.setColor(Color.red);
test.setDescription("Text " + getAsMention(event));
int[] verteilung = new int[6];
int[] verteilung2 = new int[6];
int[] verteilung3 = new int[6];
int dice1, dice2, dice3;
try {
String[] MsgParts_exl_Mention = event.getMessage().getContentRaw().split(" ");
int rounds = Integer.parseInt(MsgParts_exl_Mention[1]);
if(rounds <= 0) {
event.getChannel().sendMessage("Nope").queue();
return;
}
for(int i = 0; i < rounds; i++) {
dice1 = new Random().nextInt(6);
dice2 = new SecureRandom().nextInt(6);
//dice3 = new ThreadLocalRandom().current().nextInt(6);
dice3 = ThreadLocalRandom.current().nextInt(0, 6);
verteilung[dice1]++;
verteilung2[dice2]++;
verteilung3[dice3]++;
}
for(int i = 0; i < 6; i++) {
float pro = verteilung[i]*100f/rounds;
test.addField(Integer.toString(i+1), verteilung[i] + " - " + String.format("%.2f", pro) + "%", true);
}
test.addBlankField(false);
for(int i = 0; i < 6; i++) {
float pro = verteilung2[i]*100f/rounds;
test.addField(Integer.toString(i+1), verteilung2[i] + " - " + String.format("%.2f", pro) + "%", true);
}
test.addBlankField(false);
for(int i = 0; i < 6; i++) {
float pro = verteilung3[i]*100f/rounds;
test.addField(Integer.toString(i+1), verteilung3[i] + " - " + String.format("%.2f", pro) + "%", true);
}
event.getChannel().sendMessage(test.build().toString()).queue();
}
catch (NumberFormatException e) {
event.getChannel().sendMessage("Nope").queue();
}
catch (Exception e) {
System.out.println("problem: " + e.getMessage());
}
}
/**
* rolltest
*
* @param event JDA Event
*/
private void srroll(MessageReceivedEvent event) {
private void roll(MessageReceivedEvent event) {
EmbedBuilder outputBox = new EmbedBuilder();

View File

@ -1,4 +1,4 @@
package Earthdawn;
package de.ocame.wuerfelbot.Earthdawn;
import java.io.*;
import java.util.Properties;

View File

@ -1,4 +1,4 @@
package Earthdawn;
package de.ocame.wuerfelbot.Earthdawn;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;

View File

@ -1,4 +1,4 @@
package Earthdawn;
package de.ocame.wuerfelbot.Earthdawn;
import java.util.Random;

View File

@ -1,4 +1,4 @@
package Engel;
package de.ocame.wuerfelbot.Engel;
public class arcana {
private final String name;

View File

@ -1,8 +1,7 @@
package Engel;
package de.ocame.wuerfelbot.Engel;
import net.dv8tion.jda.api.EmbedBuilder;
import java.awt.*;
import java.util.Random;
public class arcanaList {

View File

@ -1,8 +1,8 @@
package Engel;
package de.ocame.wuerfelbot.Engel;
import Shadowrun.db_connect;
import Simpleroll.help;
import Simpleroll.language;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import de.ocame.wuerfelbot.Simpleroll.help;
import de.ocame.wuerfelbot.Simpleroll.language;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.User;
@ -12,7 +12,6 @@ import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class dice extends ListenerAdapter {

View File

@ -1,4 +1,4 @@
package Engel;
package de.ocame.wuerfelbot.Engel;
import java.io.*;
import java.util.Properties;

View File

@ -1,8 +1,8 @@
package Keeproll;
package de.ocame.wuerfelbot.Keeproll;
import Shadowrun.db_connect;
import Simpleroll.help;
import Simpleroll.language;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import de.ocame.wuerfelbot.Simpleroll.help;
import de.ocame.wuerfelbot.Simpleroll.language;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.User;

View File

@ -1,4 +1,4 @@
package Keeproll;
package de.ocame.wuerfelbot.Keeproll;
import java.util.Random;

View File

@ -1,6 +1,5 @@
package Shadowrun;
package de.ocame.wuerfelbot.Shadowrun;
import javax.print.DocFlavor;
import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -8,7 +7,7 @@ import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class db_connect extends DB.base {
public class db_connect extends de.ocame.wuerfelbot.DB.base {
Connection conn;
public db_connect() {

View File

@ -1,16 +1,13 @@
package Shadowrun;
package de.ocame.wuerfelbot.Shadowrun;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.restaction.*;
import java.awt.*;

View File

@ -1,4 +1,4 @@
package Simpleroll;
package de.ocame.wuerfelbot.Shadowrun;
public class help {

View File

@ -1,4 +1,4 @@
package Shadowrun;
package de.ocame.wuerfelbot.Shadowrun;
import java.io.*;
import java.util.Properties;

View File

@ -1,4 +1,4 @@
package Shadowrun;
package de.ocame.wuerfelbot.Shadowrun;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;

View File

@ -1,6 +1,6 @@
package Simpleroll;
package de.ocame.wuerfelbot.Simpleroll;
import Shadowrun.db_connect;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
@ -10,7 +10,6 @@ import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class dice extends ListenerAdapter {

View File

@ -1,6 +1,6 @@
package Simpleroll;
package de.ocame.wuerfelbot.Simpleroll;
import Shadowrun.db_connect;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.User;
@ -227,9 +227,9 @@ public class diceOld extends ListenerAdapter {
result.append("Ich kann aktuell folgent Wüfe:\n");
result.append("**/r** bzw. **/roll** für Allgemeine würfe. Ohne eine angabe vom Würfeltyp wird ein W6 benuzt\n\n");
result.append("**/sr** für Shadowrun 5\n\n");
result.append("**/ed** für Earthdawn 4\n\n");
result.append("**/e** bzw **/engel** für die Arcane Version von Engel\n\n");
result.append("**/sr** für de.ocame.wuerfelbot.Shadowrun 5\n\n");
result.append("**/ed** für de.ocame.wuerfelbot.Earthdawn 4\n\n");
result.append("**/e** bzw **/engel** für die Arcane Version von de.ocame.wuerfelbot.Engel\n\n");
result.append("**/l5r** bzw **/keep** für Legend of the 5 Rings\n");
outputBox.setDescription(result);

View File

@ -1,6 +1,4 @@
package Shadowrun;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
package de.ocame.wuerfelbot.Simpleroll;
public class help {

View File

@ -1,4 +1,4 @@
package Simpleroll;
package de.ocame.wuerfelbot.Simpleroll;
import java.io.*;
import java.util.Properties;

View File

@ -1,6 +1,4 @@
package Simpleroll;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
package de.ocame.wuerfelbot.Simpleroll;
import java.util.Random;
import java.util.regex.Matcher;

View File

@ -1,4 +1,4 @@
package Simpleroll;
package de.ocame.wuerfelbot.Simpleroll;
public class subpart {
private StringBuilder bodyOutput;

View File

@ -1,4 +1,4 @@
package Socket;
package de.ocame.wuerfelbot.Socket;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
@ -27,7 +27,7 @@ public class shadowrun implements Runnable{
public void run() {
int port = 11112;
try (ServerSocket listener = new ServerSocket(port)) {
System.out.println("Socket Server laeuft...");
System.out.println("de.ocame.wuerfelbot.Socket Server laeuft...");
ExecutorService pool = Executors.newFixedThreadPool(20);
while (true) {
pool.execute(new iniEcho(listener.accept(), jda));

View File

@ -1,8 +1,8 @@
package Vampire;
package de.ocame.wuerfelbot.Vampire;
import Shadowrun.db_connect;
import Simpleroll.help;
import Simpleroll.language;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import de.ocame.wuerfelbot.Simpleroll.help;
import de.ocame.wuerfelbot.Simpleroll.language;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.User;

View File

@ -1,4 +1,4 @@
package Vampire;
package de.ocame.wuerfelbot.Vampire;
import java.util.Random;

View File

@ -0,0 +1,113 @@
package de.ocame.wuerfelbot.commands;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class CommandListener extends ListenerAdapter {
private final String prefix;
private final CommandManager commandManager;
public CommandListener(CommandManager commandManager, String prefix) {
this.commandManager = commandManager;
this.prefix = prefix;
}
public void onMessageReceivedX(MessageReceivedEvent event) {
if ((!event.getMessage().getContentRaw().startsWith(this.prefix))
|| (event.getChannelType() != ChannelType.TEXT && event.getChannelType() != ChannelType.PRIVATE)) {
return;
}
User author = event.getAuthor();
author.isBot();
/*if (true) {
if (event.getMessage().getContentRaw().startsWith(this.prefixSr))
this.roll(event);
}*/
}
/**
* Behandelt Slash-Befehle.
* Dies ist die empfohlene Methode zur Befehlsverarbeitung in modernen Discord-Bots.
*/
@Override
public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
// Ignoriere Bots, damit dein Bot nicht auf Befehle von anderen Bots reagiert
if (event.getUser().isBot()) {
return;
}
// Delegiere das Event an den CommandManager
// Der CommandManager ist dafür zuständig, den passenden ICommand zu finden und auszuführen.
commandManager.handleSlashCommand(event);
}
/**
* Behandelt traditionelle Text-Befehle.
* Dies ist nützlich für ältere Bots oder spezifische Anwendungsfälle.
*/
@Override
public void onMessageReceived(MessageReceivedEvent event) {
// Ignoriere Bots
if (event.getAuthor().isBot()) {
//return; // ausgemacht für christian
}
String messageContent = event.getMessage().getContentRaw();
// Überprüfe, ob die Nachricht mit dem definierten Präfix beginnt
if (messageContent.startsWith(prefix)) {
// Entferne den Präfix und teile die Nachricht in Befehl und Argumente
String[] args = messageContent.substring(prefix.length()).trim().split("\\s+");
if (args.length == 0) {
return; // Leere Nachricht nach Präfix
}
String commandName = args[0].toLowerCase(); // Der Befehlsname (z.B. "roll", "ed")
// Erzeuge ein neues Array für die Argumente ohne den Befehlsnamen
String[] commandArgs = new String[args.length - 1];
System.arraycopy(args, 1, commandArgs, 0, args.length - 1);
// Delegiere den Text-Befehl an den CommandManager
commandManager.handleTextMessage(event, commandName, commandArgs);
}
}
/**
* Optional: Methode zur Registrierung von Slash-Befehlen beim Start des Bots.
* Diese Methode könnte auch in DiscordBot.java oder CommandManager.java liegen.
* Hier nur als Beispiel, wie sie im Listener aussehen könnte, wenn er dafür zuständig wäre.
*/
public void registerSlashCommands() {
// Erstelle eine Liste von Befehlen, die du registrieren möchtest
// Diese Befehle sollten den Definitionen in deinen ICommand-Implementierungen entsprechen
// CommandData rollCommand = Commands.slash("roll", "Würfelt eine Zahl")
// .addOption(OptionType.STRING, "notation", "Die Würfelnotation, z.B. 1d6", true);
//
// CommandData edCommand = Commands.slash("ed", "Führt eine Earthdawn-Operation aus")
// .addOption(OptionType.INTEGER, "zahl", "Eine Zahl für die Earthdawn-Operation", true);
//
// commandManager.getJda().updateCommands() // Für globale Befehle
// .addCommands(rollCommand, edCommand)
// .queue();
// Oder für Gilden-spezifische Befehle (schneller zu testen):
// Guild guild = commandManager.getJda().getGuildById("DEINE_GILDE_ID");
// if (guild != null) {
// guild.updateCommands()
// .addCommands(rollCommand, edCommand)
// .queue();
// }
}
}

View File

@ -0,0 +1,146 @@
package de.ocame.wuerfelbot.commands;
import de.ocame.wuerfelbot.Earthdawn.EarthdawnCommand;
import de.ocame.wuerfelbot.core.LoggerUtil;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData; // Wichtig für die Registrierung
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
public class CommandManager {
private final Map<String, ICommand> commands;
private final JDA jda; // Referenz zur JDA-Instanz, um Befehle zu registrieren
public CommandManager(JDA jda) {
this.jda = jda;
this.commands = new HashMap<>();
registerCommands(); // Befehle beim Start registrieren
}
/**
* Registriert alle Befehle des Bots.
* Hier werden die konkreten Implementierungen der ICommand-Schnittstelle hinzugefügt.
*/
private void registerCommands() {
// Füge deine Befehlsimplementierungen hier hinzu
//addCommand(new SimpleRollCommand());
addCommand(new EarthdawnCommand());
// Hier können wir auch die Slash-Befehle bei Discord registrieren
updateSlashCommands();
}
/**
* Fügt einen Befehl zur internen Map hinzu.
* @param command Die Instanz des zu registrierenden Befehls.
*/
private void addCommand(ICommand command) {
if (commands.containsKey(command.getName())) {
LoggerUtil.log("warn", "ComMan", "Befehl '" + command.getName() + "' ist bereits registriert und wird überschrieben.");
}
commands.put(command.getName().toLowerCase(), command); // Befehlsnamen klein speichern für konsistente Suche
LoggerUtil.log("info", "ComMan", "Befehl registriert: " + command.getName());
}
/**
* Behandelt einen eingehenden Slash-Befehl.
* Sucht den passenden Befehl und führt ihn aus.
*
* @param event Das SlashCommandInteractionEvent von JDA.
*/
public void handleSlashCommand(SlashCommandInteractionEvent event) {
String commandName = event.getName().toLowerCase();
ICommand command = commands.get(commandName);
if (command != null) {
try {
// Führe den Befehl aus
command.executeSlash(event);
} catch (Exception e) {
LoggerUtil.log("error", "ComMan", "Fehler beim Ausführen von Slash-Befehl '" + commandName + "': " + e.getMessage());
event.reply("Hoppla! Beim Ausführen des Befehls ist ein Fehler aufgetreten.").setEphemeral(true).queue();
}
} else {
// Dies sollte bei Slash-Befehlen eigentlich nicht vorkommen,
// da Discord nur registrierte Befehle sendet.
event.reply("Unbekannter Slash-Befehl: " + commandName).setEphemeral(true).queue();
LoggerUtil.log("warn", "ComMan", "Unbekannter Slash-Befehl empfangen: " + commandName);
}
}
/**
* Behandelt einen eingehenden Text-Befehl.
* Sucht den passenden Befehl und führt ihn aus.
*
* @param event Das MessageReceivedEvent von JDA.
* @param commandName Der Name des Befehls (ohne Präfix).
* @param args Die Argumente des Befehls.
*/
public void handleTextMessage(MessageReceivedEvent event, String commandName, String[] args) {
ICommand command = commands.get(commandName);
if (command != null) {
try {
// Führe den Befehl aus
command.executeText(event, args);
} catch (Exception e) {
LoggerUtil.log("error", "ComMan", "Fehler beim Ausführen von Text-Befehl '" + commandName + "': " + e.getMessage());
event.getChannel().sendMessage("Hoppla! Beim Ausführen des Befehls ist ein Fehler aufgetreten.").queue();
}
} else {
event.getChannel().sendMessage("Unbekannter Befehl: `" + commandName + "`").queue();
LoggerUtil.log("error", "ComMan", "Unbekannter Text-Befehl empfangen: " + commandName);
}
}
/**
* Registriert oder aktualisiert die Slash-Befehle bei Discord.
* Diese Methode sollte beim Start des Bots einmalig aufgerufen werden.
*/
public void updateSlashCommands() {
// Sammle alle CommandData-Objekte von den registrierten Befehlen
Set<CommandData> slashCommandData = commands.values().stream()
.map(ICommand::getSlashCommandData) // Ruft die Methode im ICommand Interface auf
.filter(Objects::nonNull) // Nur Befehle, die auch SlashCommandData liefern
.collect(Collectors.toSet());
if (slashCommandData.isEmpty()) {
LoggerUtil.log("warn", "ComMan", "Keine Slash-Befehle zum Registrieren gefunden.");
return;
}
// Beispiel: Registriere globale Befehle
// Für Entwicklung und schnelle Tests empfiehlt es sich, gilden-spezifische Befehle zu nutzen.
// jda.updateCommands().addCommands(slashCommandData).queue();
// Beispiel: Registriere gilden-spezifische Befehle (empfohlen für Entwicklung)
// Ersetze "DEINE_GILDE_ID" durch die tatsächliche ID deiner Test-Gilde.
String guildId = System.getenv("404979829537243148"); // Aus Umgebungsvariable lesen
if (guildId != null && !guildId.isEmpty()) {
jda.getGuildById(guildId)
.updateCommands()
.addCommands(slashCommandData)
.queue(
success -> LoggerUtil.log("info", "ComMan", "Slash-Befehle für Gilde " + guildId + " erfolgreich aktualisiert."),
failure -> LoggerUtil.log("error", "ComMan", "Fehler beim Aktualisieren der Slash-Befehle für Gilde " + guildId + ": " + failure.getMessage())
);
} else {
// Wenn keine Gilden-ID konfiguriert ist, globale Befehle registrieren
jda.updateCommands()
.addCommands(slashCommandData)
.queue(
success -> LoggerUtil.log("info", "ComMan", "Globale Slash-Befehle erfolgreich aktualisiert."),
failure -> LoggerUtil.log("error", "ComMan", "Fehler beim Aktualisieren der globalen Slash-Befehle: " + failure.getMessage())
);
}
LoggerUtil.log("info", "ComMan", "Registrierungsanfrage für " + slashCommandData.size() + " Slash-Befehle gesendet.");
}
}

View File

@ -0,0 +1,53 @@
package de.ocame.wuerfelbot.commands;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
public interface ICommand {
/**
* Gibt den Namen des Befehls zurück.
* Dieser Name wird sowohl für Slash-Befehle als auch für Text-Befehle verwendet
* und sollte eindeutig sein (z.B. "roll", "ed").
*
* @return Der Name des Befehls.
*/
String getName();
/**
* Gibt eine kurze Beschreibung des Befehls zurück.
* Diese Beschreibung wird in der Discord-UI für Slash-Befehle angezeigt.
*
* @return Eine kurze Beschreibung des Befehls.
*/
String getDescription();
/**
* Führt die Logik des Befehls aus, wenn er als Slash-Befehl empfangen wird.
* Implementierungen sollten hier die spezifische Befehlslogik verarbeiten und auf das Event antworten.
*
* @param event Das {@link SlashCommandInteractionEvent}, das von JDA ausgelöst wurde.
*/
void executeSlash(SlashCommandInteractionEvent event);
/**
* Führt die Logik des Befehls aus, wenn er als traditioneller Text-Befehl empfangen wird.
* Diese Methode ist optional, falls dein Bot nur Slash-Befehle unterstützt.
* Implementierungen sollten hier die spezifische Befehlslogik verarbeiten und im Kanal antworten.
*
* @param event Das {@link MessageReceivedEvent}, das von JDA ausgelöst wurde.
* @param args Ein Array von Strings, das die Argumente des Befehls enthält (ohne den Befehlsnamen selbst).
*/
void executeText(MessageReceivedEvent event, String[] args);
/**
* Gibt die {@link CommandData} zurück, die zur Registrierung des Slash-Befehls bei Discord benötigt wird.
* Jede Befehlsimplementierung, die ein Slash-Befehl sein soll, muss diese Methode implementieren,
* um die Struktur des Befehls (Name, Beschreibung, Optionen) zu definieren.
* Wenn ein Befehl kein Slash-Befehl ist, kann diese Methode {@code null} zurückgeben.
*
* @return Ein {@link CommandData}-Objekt für den Slash-Befehl oder {@code null}, wenn es kein Slash-Befehl ist.
*/
CommandData getSlashCommandData();
}

View File

@ -0,0 +1,66 @@
package de.ocame.wuerfelbot.core;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ConfigLoader {
private final Properties properties;
public ConfigLoader() {
properties = new Properties();
try (FileInputStream input = new FileInputStream("shadowrun.cfg")) {
properties.load(input);
} catch (IOException e) {
LoggerUtil.log("info", "ConfigLoader", "Konfigurationsdatei konnte nicht geladen werden: " + e.getMessage());
e.printStackTrace();
}
LoggerUtil.log("info", "ConfigLoader", "Konfigurationsdatei wurde geladen");
}
public String getToken() {
return properties.getProperty("api.token");
}
public String getUsername() {
return properties.getProperty("ff.username");
}
public String getPassword() {
return properties.getProperty("ff.password");
}
public String getFfFavList() {
return properties.getProperty("ff.favList");
}
public Long getDebugChannel() {
return Long.parseLong(properties.getProperty("debug.Channel"));
}
public boolean getFFActive() {
return Boolean.parseBoolean(properties.getProperty("ff.active", "true"));
}
public String getMySQLHost() {
return properties.getProperty("mysql.host", "localhost");
}
public String getMySQLPort() {
return properties.getProperty("mysql.port", "3306");
}
public String getMySQLUsername() {
return properties.getProperty("mysql.username", "");
}
public String getMySQLPassword() {
return properties.getProperty("mysql.password", "");
}
public String getMySQLDatabase() {
return properties.getProperty("mysql.database", "fuchsbot");
}
}

View File

@ -0,0 +1,99 @@
package de.ocame.wuerfelbot.core;
import de.ocame.wuerfelbot.commands.CommandListener;
import de.ocame.wuerfelbot.commands.CommandManager;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.ChunkingFilter;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.dv8tion.jda.api.hooks.ListenerAdapter; // JDA ListenerAdapter
import net.dv8tion.jda.api.exceptions.InvalidTokenException; // Für Token-Fehler
import javax.security.auth.login.LoginException; // Für Login-Fehler
public class DiscordBot {
private JDA jda;
private final String botToken;
private final String testGuildId; // Für gilden-spezifische Slash-Befehle
private CommandManager commandManager;
public DiscordBot(String botToken, String testGuildId) {
this.botToken = botToken;
this.testGuildId = testGuildId; // Kann null sein, wenn nicht verwendet
}
/**
* Startet den Discord Bot.
* Initialisiert JDA, registriert Listener und Befehle.
* @throws LoginException Wenn der Bot-Token ungültig ist oder ein Anmeldefehler auftritt.
* @throws InterruptedException Wenn der Thread beim Warten auf den Bot unterbrochen wird.
*/
public void start() throws LoginException, InterruptedException, InvalidTokenException {
// Konfiguriere JDABuilder mit notwendigen Intents
// Intents sind Berechtigungen, die dein Bot für bestimmte Events benötigt.
JDABuilder builder = JDABuilder.createDefault(botToken)
.enableIntents(
GatewayIntent.MESSAGE_CONTENT, // Für Text-Befehle (Nachrichteninhalt lesen)
GatewayIntent.GUILD_MESSAGES, // Für Nachrichten in Gilden
GatewayIntent.GUILD_MEMBERS, // Für Zugriff auf Mitgliederinformationen (falls benötigt)
GatewayIntent.GUILD_PRESENCES // Für Präsenzinformationen (falls benötigt)
)
// Empfohlen für größere Bots, um Caching zu optimieren
.setMemberCachePolicy(MemberCachePolicy.ALL)
.setChunkingFilter(ChunkingFilter.ALL)
.setStatus(OnlineStatus.ONLINE) // Setze den Online-Status
.setActivity(Activity.playing("mit den Würfeln")); // Setze eine Aktivität
// Baue die JDA-Instanz. Dies blockiert, bis der Bot bereit ist.
this.jda = builder.build();
// Warte, bis JDA vollständig geladen und verbunden ist
jda.awaitReady();
// Initialisiere den CommandManager mit der JDA-Instanz
this.commandManager = new CommandManager(jda);
// Erstelle und registriere den CommandListener
// Der Präfix für Text-Befehle ist hier auf "!" gesetzt.
CommandListener commandListener = new CommandListener(commandManager, "/");
jda.addEventListener(commandListener);
LoggerUtil.log("info", "DiscordBot", "JDA ist bereit. Bot ist online!");
// Registriere Slash-Befehle beim Start.
// Dies wird nun vom CommandManager übernommen, der eine Referenz auf JDA hat.
// Der CommandManager wird seine eigene updateSlashCommands() Methode aufrufen.
// commandManager.updateSlashCommands(); // Wird bereits im CommandManager-Konstruktor aufgerufen
}
/**
* Fährt den Discord Bot sauber herunter.
*/
public void shutdown() {
if (jda != null) {
jda.shutdownNow(); // Beendet JDA sofort
LoggerUtil.log("info", "DiscordBot", "JDA Instanz wurde heruntergefahren.");
}
}
/**
* Gibt die JDA-Instanz zurück.
* @return Die {@link JDA}-Instanz.
*/
public JDA getJda() {
return jda;
}
/**
* Gibt den CommandManager zurück.
* @return Den {@link CommandManager}.
*/
public CommandManager getCommandManager() {
return commandManager;
}
}

View File

@ -0,0 +1,39 @@
package de.ocame.wuerfelbot.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerUtil {
//private static final Logger logger = LoggerFactory.getLogger(LoggerUtil.class);
/**
* Erstellt einen Logeintrag basierend auf Typ, Modul und Nachricht.
*
* @param logType Der Typ des Logs: "trace", "debug", "info", "warn", "error".
* @param module Der Name des Moduls oder Kontextes.
* @param message Die Nachricht, die geloggt werden soll.
*/
public static void log(String logType, String module, String message) {
Logger logger = LoggerFactory.getLogger(module);
switch (logType.toLowerCase()) {
case "trace":
logger.trace(message);
break;
case "debug":
logger.debug(message);
break;
case "info":
logger.info(message);
break;
case "warn":
logger.warn(message);
break;
case "error":
logger.error(message);
break;
default:
logger.warn("Unbekannter Log-Typ: {}. Nachricht: {}", logType, message);
}
}
}

View File

@ -0,0 +1,66 @@
package de.ocame.wuerfelbot.core;
//import Serenity.balance;
import de.ocame.wuerfelbot.core.ConfigLoader;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.requests.GatewayIntent;
public class Main {
public static void main(String[] args) {
ConfigLoader configLoader = new ConfigLoader();
String token = configLoader.getToken();
try {
// Erstelle eine neue Instanz deines DiscordBots
LoggerUtil.log("info", "Main", "Discord Bot wird gestartet...");
DiscordBot bot = new DiscordBot(token, null);
bot.start(); // Starte den Bot
LoggerUtil.log("info", "Main", "Bot ist online und bereit!" );
// Du könntest hier einen Hook hinzufügen, um den Bot sauber herunterzufahren,
// wenn das Programm beendet wird.
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
LoggerUtil.log("info", "Main", "Bot wird heruntergefahren...");
bot.shutdown();
LoggerUtil.log("info", "Main", "Bot wurde heruntergefahren.");
}));
} catch (Exception e) {
LoggerUtil.log("error", "Main", "Ein schwerwiegender Fehler ist beim Starten des Bots aufgetreten: " + e.getMessage());
e.printStackTrace();
}
/*
JDA jda = JDABuilder.createDefault(token)
.enableIntents(GatewayIntent.MESSAGE_CONTENT)
.setActivity(Activity.playing("mit den Würfeln"))
.setStatus(OnlineStatus.ONLINE)
//.addEventListeners(new dice())
.addEventListeners(new de.ocame.wuerfelbot.Earthdawn.dice())
.addEventListeners(new de.ocame.wuerfelbot.Simpleroll.dice())
.addEventListeners(new de.ocame.wuerfelbot.Shadowrun.dice())
.addEventListeners(new de.ocame.wuerfelbot.Engel.dice())
.addEventListeners(new de.ocame.wuerfelbot.Keeproll.dice())
.setAutoReconnect(true)
.build();
*/
// Thread thread = new Thread(new shadowrun(jda));
//thread.start();
}
}

View File

@ -0,0 +1,41 @@
package de.ocame.wuerfelbot.dicebase;
import java.util.List;
public class DiceResult {
private final List<Integer> rolls;
private final int total;
private final String breakdown;
private final boolean glitch;
public DiceResult(List<Integer> rolls, int total, String breakdown, boolean glitch) {
this.rolls = rolls;
this.total = total;
this.breakdown = breakdown;
this.glitch = glitch;
}
public List<Integer> getRolls() {
return rolls;
}
public int getTotal() {
return total;
}
public String getBreakdown() {
return breakdown;
}
public boolean isGlitch() {
return glitch;
}
@Override
public String toString() {
return "Ergebnis: " + total + "\n" +
"Würfe: " + rolls + "\n" +
"Details: " + breakdown +
(glitch ? "\n Patzer erkannt!" : "");
}
}

View File

@ -0,0 +1,24 @@
package de.ocame.wuerfelbot.dicebase;
import de.ocame.wuerfelbot.dicebase.DiceResult;
public interface DiceSystem {
/**
* Gibt den internen Namen des Systems zurück, z.B. "earthdawn" oder "shadowrun".
*/
String getName();
/**
* Führt einen Wurf mit dem angegebenen Nutzereingabe-String aus.
* @param input Der Eingabestring, z.B. "5" für Earthdawn-Stufe 5 oder "4w6+1" für klassische Systeme.
* @return Ein DiceResult-Objekt mit allen relevanten Würfelinformationen.
*/
DiceResult roll(String input);
/**
* Gibt eine kurze Beschreibung oder Hilfe zu diesem Würfelsystem zurück.
*/
default String getDescription() {
return "Kein Beschreibungstext verfügbar.";
}
}

View File

@ -0,0 +1,96 @@
package de.ocame.wuerfelbot.dicebase;
import de.ocame.wuerfelbot.Earthdawn.language;
import de.ocame.wuerfelbot.Earthdawn.messageInterpreter;
import de.ocame.wuerfelbot.Earthdawn.step;
import de.ocame.wuerfelbot.Shadowrun.db_connect;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
public class dice extends ListenerAdapter {
private final String prefixSr;
private final language langDe = new language("de");
private final language langEn = new language("en");
private language activLang;
private final db_connect db;
private final Map<String, String> channelList = new HashMap<>();
private final step dieRoll = new step();
public dice() {
this.prefixSr = "/ed";
//this.prefixIni = "/ini";
this.db = new db_connect();
}
@Override
public void onMessageReceived(MessageReceivedEvent event) {
if ((!event.getMessage().getContentRaw().startsWith(this.prefixSr))
|| (event.getChannelType() != ChannelType.TEXT && event.getChannelType() != ChannelType.PRIVATE)) {
return;
}
if(!channelList.containsKey(event.getChannel().getId())) {
Map<String, String> Einstellungen = db.getChannelSettings(event.getChannel().getId());
channelList.put(event.getChannel().getId(), Einstellungen.get("lang"));
}
switch (channelList.get(event.getChannel().getId())) {
case "de":
activLang = langDe;
break;
case "en":
activLang = langEn;
break;
default:
activLang = langDe;
}
User author = event.getAuthor();
author.isBot();
if (true) {
if (event.getMessage().getContentRaw().startsWith(this.prefixSr))
this.roll(event);
}
}
/**
*
*
* @param event JDA Event
*/
private void roll(MessageReceivedEvent event) {
}
private String getEffectiveName(MessageReceivedEvent event) {
if(event.getMember() == null) {
return "";
}
return event.getMember().getEffectiveName() + " ";
}
private String getAsMention(MessageReceivedEvent event) {
if(event.getMember() == null) {
return "";
}
return event.getMember().getAsMention() + " ";
}
}

View File

@ -0,0 +1,39 @@
package de.ocame.wuerfelbot.dicebase.output;
import java.awt.*;
public class OutputContentElement {
private final String message;
private final String image;
private final Color color;
public OutputContentElement(String message) {
this.message = message;
this.image = null;
this.color = new Color(36, 153, 245);
}
public OutputContentElement(String message, String image) {
this.message = message;
this.image = image;
this.color = new Color(36, 153, 245);
}
public OutputContentElement(String message, String image, Color color) {
this.message = message;
this.image = image;
this.color = color;
}
public String getMessage() {
return message;
}
public String getImage() {
return image;
}
public Color getColor() {
return color;
}
}

View File

@ -0,0 +1,53 @@
package de.ocame.wuerfelbot.output;
import net.dv8tion.jda.api.EmbedBuilder;
import java.awt.*;
public class DiceOutputFormatter {
/**
* Formatiert das Ergebnis in einer Standart Discord-Ausgabe.
*
* @param glitch True = rote Balken sonst Grüner.
* @param title Überschrift der Box.
* @param description Inhalt der Box z.b. Würfelergebnise.
* @return Eine formatierte String-Nachricht für Discord.
*/
public EmbedBuilder DCDefaultOutput(String title, String description, boolean glitch) {
EmbedBuilder outputBox = new EmbedBuilder();
if(glitch) { // Patzer
outputBox.setColor(Color.red);
}
else { // Erfolg
outputBox.setColor(Color.green);
}
outputBox.setTitle(title);
outputBox.setDescription(description);
return outputBox;
}
/**
* Formatiert ein allgemeines Würfelergebnis.
* @param result Das Ergebnis des Würfels.
* @param notation Die Würfelnotation (z.B. "1d6").
* @return Der formatierte String.
*/
public String formatRollResult(int result, String notation) {
return String.format("Du hast mit %s eine **%d** gewürfelt.", notation, result);
}
/**
* Formatiert eine Fehlermeldung.
* @param message Die Fehlermeldung.
* @return Der formatierte String.
*/
public String formatError(String message) {
return String.format("❌ Fehler: %s", message);
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{dd.MM.YY HH:mm:ss.SSS} %boldCyan(%-34.-34thread) %red(%10.10X{jda.shard}) %boldGreen(%-15.-15logger{0}) %highlight(%-6level) %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>