You're a bot now
This commit is contained in:
parent
3478f0db06
commit
8ab139b902
9 changed files with 373 additions and 131 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
target/
|
target/
|
||||||
|
out/
|
||||||
!.mvn/wrapper/maven-wrapper.jar
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
!**/src/main/**/target/
|
!**/src/main/**/target/
|
||||||
!**/src/test/**/target/
|
!**/src/test/**/target/
|
||||||
|
|
@ -37,6 +38,15 @@ build/
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
### Other Stuff ###
|
||||||
|
config*.json
|
||||||
|
!config.example.json
|
||||||
|
!**/resources/config.schema.json
|
||||||
|
|
||||||
|
### why would this not be here already ###
|
||||||
|
/logs/
|
||||||
|
|
||||||
/tmp/
|
/tmp/
|
||||||
*.png
|
*.png
|
||||||
*.pgn
|
*.pgn
|
||||||
|
*.gif
|
||||||
6
.idea/misc.xml
generated
6
.idea/misc.xml
generated
|
|
@ -1,5 +1,11 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<list size="2">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="com.freya02.botcommands.api.annotations.CommandMarker" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="com.freya02.botcommands.api.application.slash.annotations.JDASlashCommand" />
|
||||||
|
</list>
|
||||||
|
</component>
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="MavenProjectsManager">
|
<component name="MavenProjectsManager">
|
||||||
<option name="originalFiles">
|
<option name="originalFiles">
|
||||||
|
|
|
||||||
3
config.example.json
Normal file
3
config.example.json
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"token": "CHANGEME"
|
||||||
|
}
|
||||||
51
pom.xml
51
pom.xml
|
|
@ -37,6 +37,57 @@
|
||||||
<artifactId>scrimage-core</artifactId>
|
<artifactId>scrimage-core</artifactId>
|
||||||
<version>4.3.1</version>
|
<version>4.3.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.dv8tion</groupId>
|
||||||
|
<artifactId>JDA</artifactId>
|
||||||
|
<version>5.2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.freya022</groupId>
|
||||||
|
<artifactId>BotCommands</artifactId>
|
||||||
|
<version>2.10.4</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
<version>20231013</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.5.13</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mariadb.jdbc</groupId>
|
||||||
|
<artifactId>mariadb-java-client</artifactId>
|
||||||
|
<version>2.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-dbcp2</artifactId>
|
||||||
|
<version>2.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-dbutils</groupId>
|
||||||
|
<artifactId>commons-dbutils</artifactId>
|
||||||
|
<version>1.8.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>1.5.13</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.protobuf</groupId>
|
||||||
|
<artifactId>protobuf-java</artifactId>
|
||||||
|
<version>4.28.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
package moe.wah;
|
|
||||||
|
|
||||||
import com.github.alexandreroman.chessimage.ChessRenderer;
|
|
||||||
import com.github.alexandreroman.chessimage.ChessThemeLibrary;
|
|
||||||
import com.github.bhlangonijr.chesslib.Board;
|
|
||||||
import com.github.bhlangonijr.chesslib.game.Game;
|
|
||||||
import com.github.bhlangonijr.chesslib.move.Move;
|
|
||||||
import com.github.bhlangonijr.chesslib.move.MoveList;
|
|
||||||
import com.github.bhlangonijr.chesslib.pgn.PgnHolder;
|
|
||||||
import com.sksamuel.scrimage.ImmutableImage;
|
|
||||||
import com.sksamuel.scrimage.nio.StreamingGifWriter;
|
|
||||||
import com.sksamuel.scrimage.nio.StreamingGifWriter.GifStream;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
Files.createDirectories(Paths.get("./temp/"));
|
|
||||||
// Load PGN from file
|
|
||||||
PgnHolder pgn = new PgnHolder("game.pgn");
|
|
||||||
pgnToGif(pgn);
|
|
||||||
}
|
|
||||||
private static void pgnToGif(PgnHolder pgn) throws Exception {
|
|
||||||
ChessRenderer renderer = new ChessRenderer(ChessThemeLibrary.GREEN_THEME, 60);
|
|
||||||
Game game = pgnToGame(pgn);
|
|
||||||
String boardID = String.valueOf(Instant.now().toEpochMilli());
|
|
||||||
game.loadMoveText();
|
|
||||||
System.out.println(game.getTermination());
|
|
||||||
|
|
||||||
MoveList moves = game.getHalfMoves();
|
|
||||||
Board board = new Board();
|
|
||||||
int index = 1;
|
|
||||||
for (Move move : moves) {
|
|
||||||
board.doMove(move);
|
|
||||||
renderBoard(board, renderer, boardID, index);
|
|
||||||
|
|
||||||
// Add 5 extra frames of final board
|
|
||||||
if (index == moves.size()) {
|
|
||||||
for (int x = 0; x < 5; x++) {
|
|
||||||
index++;
|
|
||||||
renderBoard(board, renderer, boardID, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Rendered " + moves.size() + " moves");
|
|
||||||
|
|
||||||
boardToGif(boardID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void renderBoard(Board board, ChessRenderer renderer, String boardID, int index) {
|
|
||||||
String index_padded = String.format("%03d", index);
|
|
||||||
File targetFile = new File("./temp/", "board_" + boardID + "_" + index_padded + ".png");
|
|
||||||
try (FileOutputStream out = new FileOutputStream(targetFile)) {
|
|
||||||
renderer.render(board.getFen(), out);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Error rendering move " + index_padded + ", " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Game pgnToGame(PgnHolder pgn) throws Exception {
|
|
||||||
pgn.loadPgn();
|
|
||||||
return pgn.getGames().getFirst();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a chess board to a GIF
|
|
||||||
* Output file is board_x.gif where x is the boardID
|
|
||||||
* @param boardID ID of the board (UNIX epoch)
|
|
||||||
*/
|
|
||||||
public static void boardToGif(String boardID) throws Exception {
|
|
||||||
List<File> boardFiles = getBoardFiles(new File("./temp/"), boardID);
|
|
||||||
if (boardFiles.isEmpty()) {
|
|
||||||
throw new RuntimeException("No PNG files found for board with ID: " + boardID);
|
|
||||||
}
|
|
||||||
List<BufferedImage> images = new ArrayList<>();
|
|
||||||
for (File file : boardFiles) {
|
|
||||||
BufferedImage image = ImageIO.read(file);
|
|
||||||
images.add(image);
|
|
||||||
}
|
|
||||||
System.out.println("There are " + (long) images.size() + " frames for board " + boardID);
|
|
||||||
String gif_name = "board_" + boardID + ".gif";
|
|
||||||
StreamingGifWriter writer = new StreamingGifWriter(Duration.ofMillis(500), true, false);
|
|
||||||
GifStream gif = writer.prepareStream(gif_name, BufferedImage.TYPE_INT_ARGB);
|
|
||||||
for (BufferedImage image : images) {
|
|
||||||
gif.writeFrame(ImmutableImage.fromAwt(image));
|
|
||||||
}
|
|
||||||
gif.close();
|
|
||||||
System.out.println("Rendered " + gif_name);
|
|
||||||
for (File file : boardFiles) {
|
|
||||||
boolean delete_success = file.delete();
|
|
||||||
if (!delete_success) {
|
|
||||||
System.out.println("Failed to delete " + file.getName() + "!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("Removed " + boardFiles.size() + " temp files");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the PNG files for the specified board
|
|
||||||
* @param directory Directory to search
|
|
||||||
* @param boardID Board ID (UNIX epoch)
|
|
||||||
* @return A list of board Files
|
|
||||||
*/
|
|
||||||
private static List<File> getBoardFiles(File directory, String boardID) {
|
|
||||||
List<File> boardFiles = new ArrayList<>();
|
|
||||||
File[] files = directory.listFiles();
|
|
||||||
assert files != null;
|
|
||||||
Arrays.sort(files);
|
|
||||||
for (File file : files) {
|
|
||||||
if (file.isFile() && file.getName().toLowerCase().endsWith(".png")
|
|
||||||
&& file.getName().startsWith("board_" + boardID)) {
|
|
||||||
boardFiles.add(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return boardFiles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
src/main/java/moe/wah/pgnator/Config.java
Normal file
36
src/main/java/moe/wah/pgnator/Config.java
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
package moe.wah.pgnator;
|
||||||
|
|
||||||
|
import com.freya02.botcommands.api.Logging;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
//You can add more fields in this class, if your input json matches the structure
|
||||||
|
//You will need a valid config.json in the resources folder for this to work
|
||||||
|
public class Config {
|
||||||
|
@SuppressWarnings("unused") private String token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the configuration object for this bot
|
||||||
|
*
|
||||||
|
* @return The config
|
||||||
|
* @throws IOException if the config JSON could not be read
|
||||||
|
*/
|
||||||
|
public static Config readConfig() throws IOException {
|
||||||
|
Logger log = Logging.getLogger();
|
||||||
|
try (InputStream in = new FileInputStream("./config.json")) {
|
||||||
|
Reader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
|
||||||
|
log.info("Loaded config");
|
||||||
|
return new Gson().fromJson(reader, Config.class);
|
||||||
|
} catch (IOException | NullPointerException e) {
|
||||||
|
log.error("Failed to load config.json, does the file exist?");
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/main/java/moe/wah/pgnator/PGNator.java
Normal file
59
src/main/java/moe/wah/pgnator/PGNator.java
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
package moe.wah.pgnator;
|
||||||
|
|
||||||
|
import com.freya02.botcommands.api.CommandsBuilder;
|
||||||
|
import com.freya02.botcommands.api.Logging;
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.JDABuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.*;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class PGNator {
|
||||||
|
private static final Logger log = Logging.getLogger();
|
||||||
|
private static JDA jda;
|
||||||
|
private static Config config;
|
||||||
|
|
||||||
|
private PGNator(JDA jda, Config config) {
|
||||||
|
PGNator.jda = jda;
|
||||||
|
PGNator.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JDA getJDA() {
|
||||||
|
return jda;
|
||||||
|
}
|
||||||
|
public static Logger getLogger() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void start() throws IOException, InterruptedException {
|
||||||
|
config = Config.readConfig();
|
||||||
|
|
||||||
|
final JDA jda = JDABuilder.createLight(config.getToken())
|
||||||
|
.setActivity(Activity.playing("Chess"))
|
||||||
|
.build()
|
||||||
|
.awaitReady();
|
||||||
|
|
||||||
|
// Print some information about the bot
|
||||||
|
log.info("Bot connected as {}", jda.getSelfUser().getAsTag());
|
||||||
|
log.info("The bot is present in the following guilds:");
|
||||||
|
for (Guild guild : jda.getGuildCache()) {
|
||||||
|
log.info("\t- {} ({})", guild.getName(), guild.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
new PGNator(jda, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try {
|
||||||
|
start();
|
||||||
|
jda = getJDA();
|
||||||
|
CommandsBuilder.newBuilder(437970062922612737L)
|
||||||
|
.textCommandBuilder(textCommandsBuilder -> textCommandsBuilder.disableHelpCommand(true))
|
||||||
|
.build(jda, "moe.wah.pgnator.commands"); //Registering listeners is taken care of by the lib
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to start the bot", e);
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
180
src/main/java/moe/wah/pgnator/commands/Pgn2Gif.java
Normal file
180
src/main/java/moe/wah/pgnator/commands/Pgn2Gif.java
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
package moe.wah.pgnator.commands;
|
||||||
|
|
||||||
|
import com.freya02.botcommands.api.annotations.BotPermissions;
|
||||||
|
import com.freya02.botcommands.api.annotations.CommandMarker;
|
||||||
|
import com.freya02.botcommands.api.annotations.UserPermissions;
|
||||||
|
import com.freya02.botcommands.api.application.ApplicationCommand;
|
||||||
|
import com.freya02.botcommands.api.application.annotations.AppOption;
|
||||||
|
import com.freya02.botcommands.api.application.slash.GuildSlashEvent;
|
||||||
|
import com.freya02.botcommands.api.application.slash.annotations.JDASlashCommand;
|
||||||
|
import com.github.alexandreroman.chessimage.ChessRenderer;
|
||||||
|
import com.github.alexandreroman.chessimage.ChessThemeLibrary;
|
||||||
|
import com.github.bhlangonijr.chesslib.Board;
|
||||||
|
import com.github.bhlangonijr.chesslib.game.Game;
|
||||||
|
import com.github.bhlangonijr.chesslib.move.Move;
|
||||||
|
import com.github.bhlangonijr.chesslib.move.MoveList;
|
||||||
|
import com.github.bhlangonijr.chesslib.pgn.PgnHolder;
|
||||||
|
import com.sksamuel.scrimage.ImmutableImage;
|
||||||
|
import com.sksamuel.scrimage.nio.StreamingGifWriter;
|
||||||
|
import moe.wah.pgnator.PGNator;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.utils.FileUpload;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@CommandMarker
|
||||||
|
@BotPermissions(Permission.MESSAGE_SEND_POLLS)
|
||||||
|
@UserPermissions(Permission.MESSAGE_MANAGE)
|
||||||
|
public class Pgn2Gif extends ApplicationCommand {
|
||||||
|
@JDASlashCommand(
|
||||||
|
name = "pgn2gif",
|
||||||
|
description = "Turns a PGN file into a GIF!"
|
||||||
|
)
|
||||||
|
public void pgn2gif(GuildSlashEvent event,
|
||||||
|
@AppOption(name = "pgn_file", description = "PGN file") Message.Attachment attachment) throws Exception {
|
||||||
|
Logger log = PGNator.getLogger();
|
||||||
|
event.deferReply().queue();
|
||||||
|
Files.createDirectories(Paths.get("./temp/pgn/"));
|
||||||
|
File pgnFile = new File("./temp/pgn/" + attachment.getFileName());
|
||||||
|
attachment.getProxy().downloadToFile(pgnFile).thenAccept(file -> {
|
||||||
|
File outputFile;
|
||||||
|
log.info("Wrote {}", file.getAbsolutePath());
|
||||||
|
try {
|
||||||
|
Files.createDirectories(Paths.get("./temp/outputs"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
// Load PGN from file
|
||||||
|
PgnHolder pgn = new PgnHolder("./temp/pgn/" + attachment.getFileName());
|
||||||
|
try {
|
||||||
|
outputFile = pgnToGif(pgn);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//event.getHook().sendMessageFormat("Filename: %s\nSize: %s\nOutput: %s", attachment.getFileName(), String.valueOf(attachment.getSize()), outputFilename).queue();
|
||||||
|
FileUpload fileUpload = FileUpload.fromData(outputFile);
|
||||||
|
event.getHook().sendFiles(fileUpload).queue();
|
||||||
|
log.info("Deleting output gif {}", outputFile.getName());
|
||||||
|
if (!outputFile.delete()) {
|
||||||
|
log.error("Failed to delete {}!", outputFile.getName());
|
||||||
|
}
|
||||||
|
log.info("Deleting PGN {}", pgnFile.getName());
|
||||||
|
if (!pgnFile.delete()) {
|
||||||
|
log.error("Failed to delete {}!", pgnFile.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File pgnToGif(PgnHolder pgn) throws Exception {
|
||||||
|
ChessRenderer renderer = new ChessRenderer(ChessThemeLibrary.GREEN_THEME, 60);
|
||||||
|
Game game = pgnToGame(pgn);
|
||||||
|
String boardID = String.valueOf(Instant.now().toEpochMilli());
|
||||||
|
game.loadMoveText();
|
||||||
|
|
||||||
|
MoveList moves = game.getHalfMoves();
|
||||||
|
Board board = new Board();
|
||||||
|
int index = 1;
|
||||||
|
for (Move move : moves) {
|
||||||
|
board.doMove(move);
|
||||||
|
renderBoard(board, renderer, boardID, index);
|
||||||
|
|
||||||
|
// Add 5 extra frames of final board
|
||||||
|
if (index == moves.size()) {
|
||||||
|
for (int x = 0; x < 5; x++) {
|
||||||
|
index++;
|
||||||
|
renderBoard(board, renderer, boardID, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PGNator.getLogger().info("Rendered {} moves", moves.size());
|
||||||
|
|
||||||
|
return boardToGif(boardID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderBoard(Board board, ChessRenderer renderer, String boardID, int index) {
|
||||||
|
String index_padded = String.format("%03d", index);
|
||||||
|
File targetFile = new File("./temp/outputs", "board_" + boardID + "_" + index_padded + ".png");
|
||||||
|
try (FileOutputStream out = new FileOutputStream(targetFile)) {
|
||||||
|
renderer.render(board.getFen(), out);
|
||||||
|
} catch (IOException e) {
|
||||||
|
PGNator.getLogger().error("Error rendering move {}, {}", index_padded, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Game pgnToGame(PgnHolder pgn) throws Exception {
|
||||||
|
pgn.loadPgn();
|
||||||
|
return pgn.getGames().getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a chess board to a GIF
|
||||||
|
* Output file is board_x.gif where x is the boardID
|
||||||
|
*
|
||||||
|
* @param boardID ID of the board (UNIX epoch)
|
||||||
|
*/
|
||||||
|
public static File boardToGif(String boardID) throws Exception {
|
||||||
|
List<File> boardFiles = getBoardFiles(new File("./temp/outputs/"), boardID);
|
||||||
|
if (boardFiles.isEmpty()) {
|
||||||
|
throw new RuntimeException("No PNG files found for board with ID: " + boardID);
|
||||||
|
}
|
||||||
|
List<BufferedImage> images = new ArrayList<>();
|
||||||
|
for (File file : boardFiles) {
|
||||||
|
BufferedImage image = ImageIO.read(file);
|
||||||
|
images.add(image);
|
||||||
|
}
|
||||||
|
PGNator.getLogger().debug("There are {} frames for board {}", (long) images.size(), boardID);
|
||||||
|
String gif_name = "./temp/outputs/board_" + boardID + ".gif";
|
||||||
|
StreamingGifWriter writer = new StreamingGifWriter(Duration.ofMillis(500), true, false);
|
||||||
|
StreamingGifWriter.GifStream gif = writer.prepareStream(gif_name, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
for (BufferedImage image : images) {
|
||||||
|
gif.writeFrame(ImmutableImage.fromAwt(image));
|
||||||
|
}
|
||||||
|
gif.close();
|
||||||
|
PGNator.getLogger().info("Rendered {}", gif_name);
|
||||||
|
for (File file : boardFiles) {
|
||||||
|
boolean delete_success = file.delete();
|
||||||
|
if (!delete_success) {
|
||||||
|
PGNator.getLogger().error("Failed to delete {}!", file.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PGNator.getLogger().info("Removed {} temp files", boardFiles.size());
|
||||||
|
return new File(gif_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the PNG files for the specified board
|
||||||
|
* @param directory Directory to search
|
||||||
|
* @param boardID Board ID (UNIX epoch)
|
||||||
|
* @return A list of board Files
|
||||||
|
*/
|
||||||
|
private static List<File> getBoardFiles(File directory, String boardID) {
|
||||||
|
List<File> boardFiles = new ArrayList<>();
|
||||||
|
File[] files = directory.listFiles();
|
||||||
|
assert files != null;
|
||||||
|
Arrays.sort(files);
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isFile() && file.getName().toLowerCase().endsWith(".png")
|
||||||
|
&& file.getName().startsWith("board_" + boardID)) {
|
||||||
|
boardFiles.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return boardFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/main/java/moe/wah/pgnator/commands/Ping.java
Normal file
27
src/main/java/moe/wah/pgnator/commands/Ping.java
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
package moe.wah.pgnator.commands;
|
||||||
|
|
||||||
|
import com.freya02.botcommands.api.annotations.CommandMarker;
|
||||||
|
import com.freya02.botcommands.api.application.ApplicationCommand;
|
||||||
|
import com.freya02.botcommands.api.application.slash.GuildSlashEvent;
|
||||||
|
import com.freya02.botcommands.api.application.slash.annotations.JDASlashCommand;
|
||||||
|
import com.freya02.botcommands.api.prefixed.annotations.Category;
|
||||||
|
import com.freya02.botcommands.api.prefixed.annotations.Description;
|
||||||
|
|
||||||
|
@CommandMarker
|
||||||
|
@Category("Utils")
|
||||||
|
@Description("Pong!")
|
||||||
|
public class Ping extends ApplicationCommand {
|
||||||
|
@JDASlashCommand(
|
||||||
|
name = "ping",
|
||||||
|
description = "Pong!"
|
||||||
|
)
|
||||||
|
public void onPing(GuildSlashEvent event) {
|
||||||
|
event.deferReply().queue();
|
||||||
|
|
||||||
|
final long gatewayPing = event.getJDA().getGatewayPing();
|
||||||
|
event.getJDA().getRestPing()
|
||||||
|
.queue(l -> event.getHook()
|
||||||
|
.sendMessageFormat("Gateway ping: **%d ms**\nRest ping: **%d ms**", gatewayPing, l)
|
||||||
|
.queue());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue