Browse Source

Initial Commit

paul
yl60lepu 4 years ago
commit
79272efd9a
28 changed files with 1664 additions and 0 deletions
  1. +6
    -0
      .gitattributes
  2. +196
    -0
      .gitignore
  3. +11
    -0
      README.md
  4. +38
    -0
      app/build.gradle
  5. +30
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioController.java
  6. +28
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioControllerManager.java
  7. +39
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioLoadResultHandlerImpl.java
  8. +25
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioPlayerListener.java
  9. +37
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioSendHandlerImpl.java
  10. +43
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommand.java
  11. +288
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandContext.java
  12. +106
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandDistributor.java
  13. +15
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/HelpCommand.java
  14. +140
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/JokeCommand.java
  15. +46
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java
  16. +15
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/SayCommand.java
  17. +23
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/StopCommand.java
  18. +44
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandLine.java
  19. +39
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandListener.java
  20. +29
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/main/Main.java
  21. +77
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/main/Resources.java
  22. +99
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java
  23. +0
    -0
      app/src/main/resources/.gitkeep
  24. BIN
      gradle/wrapper/gradle-wrapper.jar
  25. +5
    -0
      gradle/wrapper/gradle-wrapper.properties
  26. +185
    -0
      gradlew
  27. +89
    -0
      gradlew.bat
  28. +11
    -0
      settings.gradle

+ 6
- 0
.gitattributes View File

@ -0,0 +1,6 @@
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# These are explicitly windows files and should use crlf
*.bat text eol=crlf

+ 196
- 0
.gitignore View File

@ -0,0 +1,196 @@
# ---> Java
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
.idea
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# ---> Eclipse
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
.project
# ---> Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
# ---> JetBrains
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
.idea/artifacts
.idea/compiler.xml
.idea/jarRepositories.xml
.idea/modules.xml
.idea/*.iml
.idea/modules
*.iml
*.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# ---> Gradle
.gradle
**/build/
!src/**/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Cache of project
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
.classpath
app/src/main/resources/*
!app/src/main/resources/.gitkeep

+ 11
- 0
README.md View File

@ -0,0 +1,11 @@
# YoshiBot
Ein in Java geschriebener Discordbot, der lustige Sachen kann.
##Einrichtung
Ordner app/src/main/resources anlegen und darein die Config.properties anlegen. Diese sollte folgende Werte enthalten:
- jda_builder_string -> Client Secret
- audio_source_directory -> Verzeichnis, in dem die Audio-Dateien liegen, auch unter Windows mit / anstatt \ (dieses Verzeichnis sollte natürlich existieren)
- restrict_commands_to_channel -> Textkanalname, auf dem die Botkommandos empfangen werden

+ 38
- 0
app/build.gradle View File

@ -0,0 +1,38 @@
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.8.3/userguide/building_java_projects.html
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
}
repositories {
// Use JCenter for resolving dependencies.
jcenter()
}
dependencies {
// Use JUnit test framework.
testImplementation 'junit:junit:4.13'
// This dependency is used by the application.
implementation 'com.google.guava:guava:29.0-jre'
implementation group: 'org.json', name: 'json', version: '20210307'
implementation 'net.dv8tion:JDA:4.2.0_247'
implementation 'com.sedmelluq:lavaplayer:1.3.73'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
}
application {
// Define the main class for the application.
mainClass = 'de.yannicpunktdee.yoshibot.main.Main'
}

+ 30
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioController.java View File

@ -0,0 +1,30 @@
package de.yannicpunktdee.yoshibot.audio;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.entities.Guild;
public class AudioController {
private Guild guild;
private AudioPlayer audioPlayer;
public AudioController(Guild guild) {
this.guild = guild;
this.audioPlayer = YoshiBot.audioPlayerManager.createPlayer();
audioPlayer.addListener(new AudioPlayerListener(guild.getAudioManager()));
this.guild.getAudioManager().setSendingHandler(new AudioSendHandlerImpl(audioPlayer));
}
public Guild getGuild() {
return guild;
}
public AudioPlayer getAudioPlayer() {
return audioPlayer;
}
}

+ 28
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioControllerManager.java View File

@ -0,0 +1,28 @@
package de.yannicpunktdee.yoshibot.audio;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
public class AudioControllerManager {
public Map<Long, AudioController> audioController;
public AudioControllerManager() {
audioController = new ConcurrentHashMap<Long, AudioController>();
}
public AudioController getController(long guildId) {
AudioController ac = null;
if(audioController.containsKey(guildId))
ac = audioController.get(guildId);
else {
ac = new AudioController(YoshiBot.jda.getGuildById(guildId));
audioController.put(guildId, ac);
}
return ac;
}
}

+ 39
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioLoadResultHandlerImpl.java View File

@ -0,0 +1,39 @@
package de.yannicpunktdee.yoshibot.audio;
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
public class AudioLoadResultHandlerImpl implements AudioLoadResultHandler {
private AudioController audioController;
public AudioLoadResultHandlerImpl(AudioController audioController) {
this.audioController = audioController;
}
@Override
public void trackLoaded(AudioTrack track) {
audioController.getAudioPlayer().playTrack(track);
}
@Override
public void playlistLoaded(AudioPlaylist playlist) {
System.out.println("Kann aktuell noch keine Playlists abspielen");
}
@Override
public void noMatches() {
System.out.println("Nothing found");
}
@Override
public void loadFailed(FriendlyException exception) {
System.out.println("Loading failed");
}
}

+ 25
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioPlayerListener.java View File

@ -0,0 +1,25 @@
package de.yannicpunktdee.yoshibot.audio;
import com.sedmelluq.discord.lavaplayer.player.event.AudioEvent;
import com.sedmelluq.discord.lavaplayer.player.event.AudioEventListener;
import net.dv8tion.jda.api.managers.AudioManager;
public class AudioPlayerListener implements AudioEventListener {
private AudioManager audioManager;
public AudioPlayerListener(AudioManager audioManager) {
this.audioManager = audioManager;
}
@Override
public void onEvent(AudioEvent event) {
if(event.player.getPlayingTrack() == null) {
event.player.stopTrack();
audioManager.closeAudioConnection();
}
}
}

+ 37
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioSendHandlerImpl.java View File

@ -0,0 +1,37 @@
package de.yannicpunktdee.yoshibot.audio;
import java.nio.ByteBuffer;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.audio.AudioSendHandler;
public class AudioSendHandlerImpl implements AudioSendHandler {
private AudioPlayer audioPlayer;
private AudioFrame lastFrame;
public AudioSendHandlerImpl(AudioPlayer audioPlayer) {
this.audioPlayer = audioPlayer;
}
@Override
public boolean canProvide() {
lastFrame = audioPlayer.provide();
return lastFrame != null;
}
@Override
public ByteBuffer provide20MsAudio() {
return ByteBuffer.wrap(lastFrame.getData());
}
@Override
public boolean isOpus() {
return true;
}
}

+ 43
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommand.java View File

@ -0,0 +1,43 @@
package de.yannicpunktdee.yoshibot.command;
/**
* Abstrakte Superklasse für alle Kommandos.
* @author Yannic Link
*/
public abstract class YoshiCommand {
protected final String[] requiredArguments = {};
/**
* Der Kontext mit dem das Kommando aufgerufen wurde.
*/
protected YoshiCommandContext context;
/**
* Erzeugt ein neues Kommando, führt es aber noch nicht aus. Es wird ermittelt, ob die Argumentenkombination
* valide ist und das isOk-Flag gesetzt. Im Fehlerfall wird eine Fehleremeldung spezifiziert.
* @param context Der Kontext mit dem das Kommando aufgerufen wurde.
*/
public YoshiCommand(YoshiCommandContext context) {
this.context = context;
}
/**
* Führt das Kommando aus.
* @return True, wenn Ausführung erfolgreich. False, wenn Ausführung fehlgeschlagen. Fehlermeldung wird in
* errorMessage spezifiziert.
*/
public boolean execute() {
if(!context.containsArguments(requiredArguments)){
sendMessage("Fehlende Argumente");
return false;
}
return true;
}
protected void sendMessage(String message) {
context.getEvent().getTextChannel().sendMessage(message).queue();
}
}

+ 288
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandContext.java View File

@ -0,0 +1,288 @@
package de.yannicpunktdee.yoshibot.command;
import java.util.HashMap;
import java.util.Map;
import de.yannicpunktdee.yoshibot.command.YoshiCommandDistributor.Action;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;;
/**
* Parst einen Eingabestring, entscheidet ob er ein Kommando ist und zerlegt ihn in seine Bestandteile.
* Kommandos besitzen einen Status, der Auskunft gibt, ob Fehler beim Parsen des Eingabestrings aufgetreten
* sind oder der String gar kein Kommando war. Außerdem wird bei erfolgreich geparsten Kommandos eine Aktion
* festgelegt, die das Kommando ausführen soll, sowie die Argumente mit welcher das Kommando ausgeführt wird.
* Außerdem enthalten ist eine Referenz auf Ursprungs-User und -TextChannel.
* @author Yannic Link
*/
public class YoshiCommandContext {
/**
* Repräsentiert einen Status, den eine YoshiCommand-Instanz hat, nachdem der Eingabestring eingelesen
* und geparst wurde. Sofern der Status nicht OK ist, ist diese Instanz entweder kein Kommando oder
* besitzt eine fehlerhafte Syntax.
*/
public static enum State {
/**
* Das Kommando wurde erfolgreich geparst und besitzt keine Syntaxfehler.
*/
OK,
/**
* Der Eingabestring war kein Kommando für den Yoshi-Bot.
*/
NO_COMMAND,
/**
* Im Kommando wurde keine Aktion spezifiziert.
*/
NO_ACTION,
/**
* Die angegebene Aktion existiert nicht.
*/
UNKNOWN_ACTION,
/**
* Das Kommando hatt einen Syntaxfehler.
*/
BAD_SYNTAX
}
/**
* Hilfskonstrukt. Beschreibt den Zustand vom Parser.
*/
private static enum ReadingState{
/**
* Der Parser ist dabei festzustellen, ob es sich um ein Kommando handelt.
*/
VERIFYING,
/**
* Zwischenzustand zwischen VERIFYING und READING_ACTION.
*/
AFTER_VERIFY,
/**
* Der Parser liest die Action ein.
*/
READING_ACTION,
/**
* Zustand nach READING_ACTION, READING_VALUE oder READING_STRING).
*/
INTERMEDIATE,
/**
* Der Parser ist dabei einen Argumentenkey einzulesen.
*/
READING_KEY,
/**
* Der Parser hat gerade einen Argumentenkey eingelesen.
*/
AFTER_KEY,
/**
* Der Parser liest gerade einen Argumentenwert ein.
*/
READING_VALUE,
/**
* Der Parser liest gerade einen zusammenhängenden Argumentenwert ein.
*/
READING_STRING
};
/**
* Das Präfix, mit dem Yoshi-Bot-Kommandos beginnen.
*/
public static final String PREFIX = "::yoshi";
/**
* Der (Fehler-)Status, den der Parser nach Einlesen des Eingabestrings angenommen hat.
*/
private State state;
/**
* Die im Eingabesting spezifizierte Aktion.
*/
private Action action;
/**
* Eine Map, die die Key-Werte der Argumente (ohne Bindestrich) auf dessen Werte abbildet.
*/
private Map<String, String> arguments;
private MessageReceivedEvent event;
/**
* Erzeugt aus einem unbearbeiteten Eingabestring ein Kommando. Nach dem parsen enthält die state-Variable
* den Endzustand des Parsers.
* @param argumentsString Ein unbearbeiteter Eingabestring
* @param user Der Benutzer, der das Kommando geschickt hat.
* @param channel Der Textchannel in den das Kommando geschickt wurde.
*/
public YoshiCommandContext(String argumentsString, MessageReceivedEvent event) {
this.event = event;
argumentsString = argumentsString.trim();
arguments = new HashMap<String, String>();
ReadingState readingState = ReadingState.VERIFYING;
String currentKey = null;
int startPos = 0;
int length = argumentsString.length();
for(int position = 0; position < length; position++) {
char currentChar = argumentsString.charAt(position);
switch(readingState) {
case VERIFYING:
if(!Character.isWhitespace(currentChar)) continue;
if(!argumentsString.substring(0, position).equals(PREFIX)) {
state = State.NO_COMMAND;
return;
}
readingState = ReadingState.AFTER_VERIFY;
continue;
case AFTER_VERIFY:
if(Character.isWhitespace(currentChar)) continue;
if(currentChar == '-'){
state = State.NO_ACTION;
return;
}
startPos = position;
readingState = ReadingState.READING_ACTION;
continue;
case READING_ACTION:
if(!Character.isWhitespace(currentChar)) continue;
try{
action = Action.valueOf(argumentsString.substring(startPos, position).toUpperCase());
readingState = ReadingState.INTERMEDIATE;
} catch(IllegalArgumentException e) {
state = State.UNKNOWN_ACTION;
return;
}
continue;
case INTERMEDIATE:
if(Character.isWhitespace(currentChar)) continue;
if(currentChar != '-' || currentChar == '"') {
state = State.BAD_SYNTAX;
return;
}
startPos = position + 1;
readingState = ReadingState.READING_KEY;
continue;
case READING_KEY:
if(!Character.isWhitespace(currentChar)) continue;
currentKey = argumentsString.substring(startPos, position);
readingState = ReadingState.AFTER_KEY;
continue;
case AFTER_KEY:
if(Character.isWhitespace(currentChar)) continue;
if(currentChar == '-') {
arguments.put(currentKey, null);
startPos = position + 1;
readingState = ReadingState.READING_KEY;
} else if(currentChar == '"'){
startPos = position + 1;
readingState = ReadingState.READING_STRING;
} else {
startPos = position;
readingState = ReadingState.READING_VALUE;
}
continue;
case READING_VALUE:
if(!Character.isWhitespace(currentChar)) continue;
arguments.put(currentKey, argumentsString.substring(startPos, position));
readingState = ReadingState.INTERMEDIATE;
continue;
case READING_STRING:
if(currentChar != '"') continue;
if(argumentsString.charAt(position - 1) == '\\') continue;
arguments.put(currentKey, argumentsString.substring(startPos, position));
readingState = ReadingState.INTERMEDIATE;
continue;
}
}
switch(readingState) {
case INTERMEDIATE:
state = State.OK;
return;
case VERIFYING:
if(argumentsString.equals(PREFIX)) {
action = Action.HELP;
state = State.OK;
}else {
state = State.NO_COMMAND;
}
return;
case READING_ACTION:
try{
action = Action.valueOf(argumentsString.substring(startPos).toUpperCase());
readingState = ReadingState.INTERMEDIATE;
} catch(IllegalArgumentException e) {
state = State.UNKNOWN_ACTION;
return;
}
state = State.OK;
return;
case READING_KEY:
arguments.put(argumentsString.substring(startPos), null);
state = State.OK;
return;
case READING_VALUE:
arguments.put(currentKey, argumentsString.substring(startPos));
state = State.OK;
return;
default:
break;
}
}
/**
* Prüft, ob der Eingabestring ein valides Kommando war.
*/
public boolean isValid() {
return state.equals(State.OK);
}
/**
* Gibt den (Fehler-)Status des Parsers zurück.
*/
public State getState() {
return state;
}
/**
* Gibt die im Kommando spezifizierte Aktion zurück. null, wenn status fehlerhaft oder kein Kommando.
*/
public Action getAction() {
return action;
}
/**
* Prüft, ob das Kommando mit Argumenten aufgerufen wurde.
*/
public boolean hasArguments() {
return !arguments.isEmpty();
}
/**
* Prüft, ob alle Key-Werte in der Argumentenliste vorhanden sind.
* @param args Liste von den auf Existenz zu überprüfenden Argumenten.
*/
public boolean containsArguments(String[] args) {
for(String arg : args) {
if(!arguments.containsKey(arg)) {
return false;
}
}
return true;
}
/**
* Gibt den Wert eines Arguments zurück.
* @param arg Name des Arguments.
*/
public String getArgument(String arg) {
if(!arguments.containsKey(arg)) return null;
return arguments.get(arg);
}
public MessageReceivedEvent getEvent() {
return event;
}
}

+ 106
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandDistributor.java View File

@ -0,0 +1,106 @@
package de.yannicpunktdee.yoshibot.command;
import de.yannicpunktdee.yoshibot.command.commands.HelpCommand;
import de.yannicpunktdee.yoshibot.command.commands.JokeCommand;
import de.yannicpunktdee.yoshibot.command.commands.PlayCommand;
import de.yannicpunktdee.yoshibot.command.commands.SayCommand;
import de.yannicpunktdee.yoshibot.command.commands.StopCommand;
/**
* Unterscheidet nach der spezifizierten Action welche YoshiCommand-Kindklasse zum Ausführen des Kommandos
* verwendet wird.
* @author Yannic Link
*/
public class YoshiCommandDistributor {
/**
* Führt das jeweils zuständige Kommando aus.
* @param context
*/
public static void distribute(YoshiCommandContext context) {
switch(context.getState()) {
case NO_ACTION:
context.getEvent().getTextChannel().sendMessage("Im letzten Befehl wurde keine Aktion spezifiziert. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
case UNKNOWN_ACTION:
context.getEvent().getTextChannel().sendMessage("Im letzten Befehl wurde eine unbekannte Aktion angegeben. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
case BAD_SYNTAX:
context.getEvent().getTextChannel().sendMessage("Der letzte Befehl hatte ein falsches Format. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
default:
break;
}
YoshiCommand command = null;
switch(context.getAction()) {
case STOP:
command = new StopCommand(context);
break;
case HELP:
command = new HelpCommand(context);
break;
case JOKE:
command = new JokeCommand(context);
break;
case SAY:
command = new SayCommand(context);
break;
case PLAY:
command = new PlayCommand(context);
break;
default:
context.getEvent().getTextChannel().sendMessage("Dieses Kommando existiert noch nicht.").queue();
break;
}
if(command != null) command.execute();
}
/**
* Enthlt alle mglichen Aktionen, die der Yoshi-Bot ausfhren kann.
* @author Yannic Link
*/
public enum Action {
/**
* Sende eine Hilfe-Nachricht, in der die Benutzung des Yoshi-Bots dokumentiert ist.
*/
HELP,
/**
* Fahre den Yoshi-Bot herunter (nur mit speziellen Berechtigungen mglich).
*/
STOP,
/**
* Erzählt einen Jokus.
*/
JOKE,
/**
* Gib die Nachricht -message aus. ber die Option -out [text|voice] wird angegeben, ob die Nachricht
* per Textnachricht oder als Text-To-Speech ausgegeben wird. Mit -channel lsst sich der Ausgabechannel
* bestimmen. Standardmig wird die Ausgabe in den Textchannel zurckgesendet, aus dem das Kommando kam.
*/
SAY,
/**
* Listet alle zugewiesenen Ressourcen auf. Mit der Option -type [all|link|audio|video] lsst sich das Format
* der Ressource spezifizieren.
*/
LIST,
/**
* Gibt eine vorhandene Ressource -name aus. (Vorhandene Ressourcen lassen sich mit der Aktion LIST anzeigen).
* ber den Parameter -type [link|audio|video] lsst sich der Typ der Ressource spezifizieren. Ein Link wird
* ber in den per -channel spezifizierten (default=Ursprungskanal) Textkanal geschickt. Eine Audiodatei
* wird ber den per -channel spezifizierten (default=Aktueller Kanal) Voice-Channel ausgegeben. Ein Video
* wird ber den per -channel spezifizierten (default=Aktueller Kanal) Voice-Channel abgespielt.
*/
PLAY,
/**
* Lscht die Ressource, die ber -name spezifiziert wurde. Mit -type wird der Ressourcentyp festgelegt.
*/
DELETE
}
}

+ 15
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/HelpCommand.java View File

@ -0,0 +1,15 @@
package de.yannicpunktdee.yoshibot.command.commands;
import de.yannicpunktdee.yoshibot.command.YoshiCommand;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
public class HelpCommand extends YoshiCommand {
public HelpCommand(YoshiCommandContext context) {
super(context);
}
@Override
public boolean execute() {return true;}
}

+ 140
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/JokeCommand.java View File

@ -0,0 +1,140 @@
package de.yannicpunktdee.yoshibot.command.commands;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Random;
import org.apache.commons.lang3.StringEscapeUtils;
import org.json.JSONException;
import org.json.JSONObject;
import de.yannicpunktdee.yoshibot.command.YoshiCommand;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.entities.TextChannel;
/**
* Schickt einen zufälligen Jokus aus einer zufällig ausgewählten Quelle in den Textchannel.
* @author Yannic Link
*/
@SuppressWarnings("deprecation")
public class JokeCommand extends YoshiCommand {
/**
* Erstellt einen neuen JokeCommand.
*/
public JokeCommand(YoshiCommandContext context) {
super(context);
}
/**
* {@inheritDoc}
*/
@Override public synchronized boolean execute() {
String message = "Jokus";
Random random = new Random();
int number = random.nextInt(3);
switch(number) {
case 0: message = jokeApi(); break;
case 1: message = officialJokeApi(); break;
case 2: message = chuckNorris(); break;
default: message = "Jokus"; break;
}
if(context.containsArguments(new String[] {"channel"})) {
String arg = context.getArgument("channel");
if(arg == null) {
sendMessage("Es wurde kein channel angegeben.");
return false;
}
List<TextChannel> channels = YoshiBot.jda.getTextChannelsByName(context.getArgument("channel"), true);
if(channels.isEmpty()) {
sendMessage("Der Kanalname konnte nicht gefunden werden.");
return false;
}
channels.get(0).sendMessage(message).queue();
}else {
sendMessage(message);
}
return true;
}
private String getFromURL(String url) throws IOException {
StringBuilder response = new StringBuilder("");
HttpURLConnection con = null;
try{
con = (HttpURLConnection)(new URL(url)).openConnection();
con.setRequestMethod("GET");
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while((line = br.readLine()) != null) {
response.append(StringEscapeUtils.unescapeHtml4(line));
}
br.close();
}catch(IOException e) {
return null;
}finally {
if(con != null) con.disconnect();
}
return response.toString();
}
private String chuckNorris() {
String url = "http://api.icndb.com/jokes/random";
JSONObject json = null;
try {
String raw = getFromURL(url);
json = new JSONObject(raw);
return json.getJSONObject("value").getString("joke");
}catch(JSONException | IOException e) {
return "Konnte keinen Jokus von \"" + url + "\" laden.";
}
}
private String officialJokeApi() {
String url = "https://official-joke-api.appspot.com/jokes/random";
JSONObject json = null;
try {
String raw = getFromURL(url);
json = new JSONObject(raw);
String result = json.getString("setup");
result += " - ";
result += json.getString("punchline");
return result;
}catch(JSONException | IOException e) {
return "Konnte keinen Jokus von \"" + url + "\" laden.";
}
}
private String jokeApi() {
String url = "https://v2.jokeapi.dev/joke/any";
JSONObject json = null;
try {
String raw = getFromURL(url);
json = new JSONObject(raw);
String result = json.getString("setup");
result += " - ";
result += json.getString("delivery");
return result;
}catch(JSONException | IOException e) {
return "Konnte keinen Jokus von \"" + url + "\" laden.";
}
}
}

+ 46
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java View File

@ -0,0 +1,46 @@
package de.yannicpunktdee.yoshibot.command.commands;
import java.util.List;
import de.yannicpunktdee.yoshibot.audio.AudioController;
import de.yannicpunktdee.yoshibot.audio.AudioLoadResultHandlerImpl;
import de.yannicpunktdee.yoshibot.command.YoshiCommand;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
import de.yannicpunktdee.yoshibot.main.Resources;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.entities.VoiceChannel;
public class PlayCommand extends YoshiCommand {
protected final String[] requiredArguments = new String[] {"channel", "name"};
public PlayCommand(YoshiCommandContext context) {
super(context);
}
@Override
public boolean execute() {
if(!super.execute()) return false;
List<VoiceChannel> channels = YoshiBot.jda.getVoiceChannelsByName(context.getArgument("channel"), true);
if(!(channels.size() > 0)) {
context.getEvent().getTextChannel().sendMessage("Der Kanalname konnte nicht gefunden werden.").queue();
return false;
}
VoiceChannel vc = channels.get(0);
String fileName = Resources.getAudioFilePath(context.getArgument("name"));
if(fileName == null) {
context.getEvent().getTextChannel().sendMessage("Audio konnte nicht gefunden werden.").queue();
return false;
}
AudioController ac = YoshiBot.audioControllerManager.getController(vc.getGuild().getIdLong());
vc.getGuild().getAudioManager().openAudioConnection(vc);
YoshiBot.audioPlayerManager.loadItem(fileName, new AudioLoadResultHandlerImpl(ac));
return true;
}
}

+ 15
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/SayCommand.java View File

@ -0,0 +1,15 @@
package de.yannicpunktdee.yoshibot.command.commands;
import de.yannicpunktdee.yoshibot.command.YoshiCommand;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
public class SayCommand extends YoshiCommand {
public SayCommand(YoshiCommandContext context) {
super(context);
}
@Override
public boolean execute() {return true;}
}

+ 23
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/StopCommand.java View File

@ -0,0 +1,23 @@
package de.yannicpunktdee.yoshibot.command.commands;
import de.yannicpunktdee.yoshibot.command.YoshiCommand;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
public class StopCommand extends YoshiCommand {
protected final String[] requiredArguments = {"please", "uwu"};
public StopCommand(YoshiCommandContext context) {
super(context);
}
@Override
public boolean execute() {
if(!super.execute()) return false;
YoshiBot.stop();
return true;
}
}

+ 44
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandLine.java View File

@ -0,0 +1,44 @@
package de.yannicpunktdee.yoshibot.listeners;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
public class CommandLine extends Thread implements Runnable {
private BufferedReader reader;
/**
* Nicht manuell aufrufen. Wird einmalig in startYoshiBot in einem neuen Thread aufgerufen und reagiert
* auf administrative Konsoleneingaben außerhalb von Discord.
*/
@Override public void run() {
String line = "";
reader = new BufferedReader(new InputStreamReader(System.in));
try {
System.out.print("> ");
while((line = reader.readLine()) != null) {
line = line.trim();
if(line.equalsIgnoreCase("exit")) {
YoshiBot.stop();
return;
}
System.out.print("> ");
}
} catch(IOException e) {
System.err.println("Es ist eine IOException aufgetreten.");
}
}
public void stopCommandLine() {
try {
reader.close();
interrupt();
} catch (IOException e) {
System.err.println("Fehler beim Schließen des Readers.");
}
}
}

+ 39
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandListener.java View File

@ -0,0 +1,39 @@
package de.yannicpunktdee.yoshibot.listeners;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
import de.yannicpunktdee.yoshibot.main.Resources;
import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
/**
* Lauscht auf eingehende Nachrichten und leitet diese an die YoshiBot.executeCommand-Methode weiter,
* falls es sich um ein Kommando handelt.
* @author Yannic Link
*/
public class CommandListener extends ListenerAdapter {
/**
* {@inheritDoc}
*/
@Override public void onMessageReceived(MessageReceivedEvent event) {
if(!event.isFromType(ChannelType.TEXT)) return;
if(event.getAuthor().isBot()) return;
if(Resources.getRestrictCommandsToChannel() != null
&& !Resources.getRestrictCommandsToChannel().equalsIgnoreCase(event.getTextChannel().getName()))
return;
String raw = event.getMessage().getContentRaw().trim();
if(!raw.startsWith(YoshiCommandContext.PREFIX)) return;
YoshiCommandContext context = new YoshiCommandContext(raw, event);
if(!context.getState().equals(YoshiCommandContext.State.NO_COMMAND)) YoshiBot.executeCommand(context);
return;
}
}

+ 29
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/main/Main.java View File

@ -0,0 +1,29 @@
package de.yannicpunktdee.yoshibot.main;
import java.net.URISyntaxException;
import javax.security.auth.login.LoginException;
/**
* Main-Klasse und Startpunkt für die Bot-Applikation.
* @author Yannic Link
*/
public class Main {
/**
* Eintrittspunkt für die Applikation. Erzeugen eines neuen Yoshi-Bots und Starten.
* @param args Aufrufargumente. Werden später zum Konfigurieren genutzt.
* @throws URISyntaxException
*/
public static void main(String[] args) throws URISyntaxException {
System.out.println("Starte Applikation.\n");
YoshiBot.init((args.length > 0)? args[0] : null);
try {
YoshiBot.start();
}catch(LoginException e) {
System.err.println("Es ist ein Fehler beim Login aufgetreten.");
}
}
}

+ 77
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/main/Resources.java View File

@ -0,0 +1,77 @@
package de.yannicpunktdee.yoshibot.main;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
public class Resources {
private static final String default_propertiesFilePath = "Config.properties";
private static String propertiesFilePath = default_propertiesFilePath;
private static Properties propertiesFile;
private static String jda_builder_string;
private static final String default_audio_source_directory = "rsc/audio/";
private static String audio_source_directory = default_audio_source_directory;
private static final String default_restrict_commands_to_channel = null;
private static String restrict_commands_to_channel = default_restrict_commands_to_channel;
public synchronized static void init(String pathToConfig) {
if(pathToConfig != null) propertiesFilePath = pathToConfig;
if(!(new File(propertiesFilePath)).exists()) propertiesFilePath = default_propertiesFilePath;
propertiesFile = new Properties();
try {
propertiesFile.load(Resources.class.getClassLoader().getResourceAsStream(propertiesFilePath));
System.out.println("Properties-Datei erfolgreich geladen.");
} catch (IOException e) {
System.err.println("Es wurde keine Config-Datei gefunden. Benutze Standards.");
return;
}
initJdaBuilderString();
initAudio();
initChannelRestrict();
}
private static void initJdaBuilderString() {
if(!propertiesFile.containsKey("jda_builder_string")) {
System.err.println("Es wurde kein jda_builder_string gefunden.");
YoshiBot.stop();
} else jda_builder_string = propertiesFile.getProperty("jda_builder_string");
}
public static String getJdaBuilderString() {
return jda_builder_string;
}
private static void initAudio() {
if(!propertiesFile.containsKey("audio_source_directory")) return;
String dir = propertiesFile.getProperty("audio_source_directory");
File file = new File(dir);
if(!file.exists() || !file.isDirectory()){
System.err.println("Das Audio-Verzeichnis wurde nicht gefunden");
return;
}
audio_source_directory = dir;
}
public static String getAudioFilePath(String name) {
name = audio_source_directory + (audio_source_directory.endsWith("/")? "" : "/") + name + ".opus";
System.out.println("Dateiname: " + name);
if((new File(name)).exists()) return name;
else return null;
}
private static void initChannelRestrict() {
if(propertiesFile.containsKey("restrict_commands_to_channel"))
restrict_commands_to_channel = propertiesFile.getProperty("restrict_commands_to_channel");
}
public static String getRestrictCommandsToChannel() {
return restrict_commands_to_channel;
}
}

+ 99
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java View File

@ -0,0 +1,99 @@
package de.yannicpunktdee.yoshibot.main;
import javax.security.auth.login.LoginException;
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
import com.sedmelluq.discord.lavaplayer.source.local.LocalAudioSourceManager;
import de.yannicpunktdee.yoshibot.audio.AudioControllerManager;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
import de.yannicpunktdee.yoshibot.command.YoshiCommandDistributor;
import de.yannicpunktdee.yoshibot.listeners.CommandLine;
import de.yannicpunktdee.yoshibot.listeners.CommandListener;
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;
/**
* Repräsentiert einen Yoshi-Bot. Der Bot initialisiert alle Ressourcen und schaltet sich in der
* startYoshiBot-Methode online und beginnt dann zu lauschen. Parallel lauscht ein Thread auf
* Konsoleneingaben für administrative Zwecke, die nicht über den Chat erledigt werden sollten.
* @author Yannic Link
*/
public class YoshiBot {
private static CommandLine commandLineThread;
/**
* Erlaubt es einige Einstellungen vor und nach der Erzeugung eines Bots vorzunehmen.
*/
public static JDABuilder jdaBuilder;
/**
* Instanz vom aktuell laufenden Bot.
*/
public static JDA jda;
/**
* LavaPlayer AudioPlayerManager.
*/
public static AudioPlayerManager audioPlayerManager;
public static AudioControllerManager audioControllerManager;
/**
* Initialisiert alle dynamisch hinzugefügten und statischen Ressourcen. Startet aber nicht
* den Bot selbst.
*/
public static void init(String configPath) {
Resources.init(configPath);
}
/**
* Startet den Bot und schaltet ihn online. Beginnt auf Konsoleneingaben für administrative
* Zwecke zu lauschen.
* @throws LoginException Falls das Token ungültig ist.
*/
public static void start() throws LoginException {
System.out.println("Starte YoshiBot.");
jdaBuilder = JDABuilder.createDefault(Resources.getJdaBuilderString());
jdaBuilder.addEventListeners(new CommandListener());
audioPlayerManager = new DefaultAudioPlayerManager();
audioPlayerManager.registerSourceManager(new LocalAudioSourceManager());
AudioSourceManagers.registerRemoteSources(audioPlayerManager);
audioControllerManager = new AudioControllerManager();
jda = jdaBuilder.build();
jdaBuilder.setActivity(Activity.playing("Haare waschen."));
jdaBuilder.setStatus(OnlineStatus.ONLINE);
System.out.println("YoshiBot online.");
commandLineThread = new CommandLine();
commandLineThread.start();
}
public static synchronized void stop() {
commandLineThread.stopCommandLine();
System.out.println("Beende YoshiBot ...");
jdaBuilder.setStatus(OnlineStatus.OFFLINE);
jda.shutdown();
System.out.println("YoshiBot offline.");
}
/**
* Leitet den Context an den CommandDistributor weiter.
* @param command Der Kontext für das Kommando.
*/
public static void executeCommand(YoshiCommandContext command) {
YoshiCommandDistributor.distribute(command);
}
}

+ 0
- 0
app/src/main/resources/.gitkeep View File


BIN
gradle/wrapper/gradle-wrapper.jar View File


+ 5
- 0
gradle/wrapper/gradle-wrapper.properties View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

+ 185
- 0
gradlew View File

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

+ 89
- 0
gradlew.bat View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

+ 11
- 0
settings.gradle View File

@ -0,0 +1,11 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/6.8.3/userguide/multi_project_builds.html
*/
rootProject.name = 'YoshiBot'
include('app')

Loading…
Cancel
Save