|
@ -5,14 +5,14 @@ import de.yannicpunktdee.yoshibot.command.YoshiCommandContext; |
|
|
import de.yannicpunktdee.yoshibot.main.YoshiBot; |
|
|
import de.yannicpunktdee.yoshibot.main.YoshiBot; |
|
|
import de.yannicpunktdee.yoshibot.utils.Resources; |
|
|
import de.yannicpunktdee.yoshibot.utils.Resources; |
|
|
import net.dv8tion.jda.api.EmbedBuilder; |
|
|
import net.dv8tion.jda.api.EmbedBuilder; |
|
|
import net.dv8tion.jda.api.entities.TextChannel; |
|
|
|
|
|
import net.dv8tion.jda.api.entities.VoiceChannel; |
|
|
import net.dv8tion.jda.api.entities.VoiceChannel; |
|
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.text.similarity.JaccardDistance; |
|
|
|
|
|
|
|
|
import java.awt.Color; |
|
|
import java.awt.Color; |
|
|
import java.io.File; |
|
|
import java.io.File; |
|
|
import java.util.Arrays; |
|
|
import java.util.Arrays; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.Map; |
|
|
|
|
|
import java.util.Objects; |
|
|
import java.util.Objects; |
|
|
import java.util.stream.Collectors; |
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
@ -44,6 +44,11 @@ public class PlayCommand extends YoshiCommand { |
|
|
sendCustomMessage(eb.build()); |
|
|
sendCustomMessage(eb.build()); |
|
|
} else if (context.containsArgument("name")) { |
|
|
} else if (context.containsArgument("name")) { |
|
|
String requestedFile = getBestMatch(context.getArgument("name"), getAllFiles()); |
|
|
String requestedFile = getBestMatch(context.getArgument("name"), getAllFiles()); |
|
|
|
|
|
if(requestedFile == null){ |
|
|
|
|
|
sendErrorMessage(String.format("Konnte keine Audiodatei namens '%s.opus' finden!", |
|
|
|
|
|
context.getArgument("name"))); |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
File file = new File(Resources.getPathToAudioFile(requestedFile)); |
|
|
File file = new File(Resources.getPathToAudioFile(requestedFile)); |
|
|
if (!file.isFile()) { |
|
|
if (!file.isFile()) { |
|
|
sendErrorMessage(String.format("Konnte keine Audiodatei namens '%s.opus' finden!", |
|
|
sendErrorMessage(String.format("Konnte keine Audiodatei namens '%s.opus' finden!", |
|
@ -68,48 +73,17 @@ public class PlayCommand extends YoshiCommand { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private String getBestMatch(String word, List<String> choices) { |
|
|
private String getBestMatch(String word, List<String> choices) { |
|
|
Map<String, Double> hammingDists = |
|
|
|
|
|
choices.parallelStream() |
|
|
|
|
|
.collect(Collectors.toMap(file -> file, |
|
|
|
|
|
file -> (double) maximalMatchingChars(file, word) / |
|
|
|
|
|
Math.max(file.length(), |
|
|
|
|
|
word.length()))); |
|
|
|
|
|
return hammingDists.keySet().stream() |
|
|
|
|
|
.max((file1, file2) -> (int) Math.signum(hammingDists.get(file1) - hammingDists.get(file2))) |
|
|
|
|
|
.orElse(choices.get(0)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private int maximalMatchingChars(String word1, String word2) { |
|
|
|
|
|
int maxMatches = 0; |
|
|
|
|
|
int combinedSize = word1.length() + word2.length() - 1; |
|
|
|
|
|
char[] word1Chars = new char[combinedSize], word2Chars = new char[combinedSize]; |
|
|
|
|
|
for (int i = 0; i < combinedSize; i++) { |
|
|
|
|
|
if (i < word2.length()) { |
|
|
|
|
|
word2Chars[i] = word2.charAt(i); |
|
|
|
|
|
} else { |
|
|
|
|
|
word2Chars[i] = '&'; |
|
|
|
|
|
|
|
|
double bestScore = 1.0; |
|
|
|
|
|
String bestMatching = null; |
|
|
|
|
|
for(String file : choices){ |
|
|
|
|
|
double score = (new JaccardDistance()).apply(word, file); |
|
|
|
|
|
if(score < bestScore){ |
|
|
|
|
|
bestScore = score; |
|
|
|
|
|
bestMatching = file; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
for (int i = 0; i < combinedSize; i++) { |
|
|
|
|
|
for (int j = 0; j < combinedSize; j++) { |
|
|
|
|
|
if (i <= j && j < i + word1.length()) { |
|
|
|
|
|
word1Chars[j] = word1.charAt(j - i); |
|
|
|
|
|
} else { |
|
|
|
|
|
word1Chars[j] = '$'; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
maxMatches = Math.max(getMatchingChars(word1Chars, word2Chars), maxMatches); |
|
|
|
|
|
} |
|
|
|
|
|
return maxMatches; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private int getMatchingChars(char[] word1, char[] word2) { |
|
|
|
|
|
int dist = 0; |
|
|
|
|
|
assert word1.length == word2.length; |
|
|
|
|
|
for (int i = 0; i < word1.length; i++) { |
|
|
|
|
|
dist += word1[i] == word2[i] ? 1 : 0; |
|
|
|
|
|
} |
|
|
|
|
|
return dist; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return bestMatching; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private List<String> getAllFiles() { |
|
|
private List<String> getAllFiles() { |
|
|