This commit is contained in:
Tyler Murphy 2022-08-28 23:57:17 -04:00
parent 162bfc8994
commit f65981e4b4
35 changed files with 1114 additions and 230 deletions

View file

@ -8,17 +8,19 @@ import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.tylermurphy.ken.command.Responder;
import net.tylermurphy.ken.database.Database;
import net.tylermurphy.ken.music.PlayerManager;
import net.tylermurphy.ken.util.ImageFetcher;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Color;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
@ -32,12 +34,14 @@ public class Ken {
private final YouTube youTube;
private final Responder responder;
private final Database database;
private final ImageFetcher imageFetcher;
private Ken(){
Ken.instance = this;
this.config = Config.create("config.yml");
this.log = LoggerFactory.getLogger(Ken.class);
this.database = new Database();
this.imageFetcher = new ImageFetcher();
try {
api = JDABuilder.createDefault(config.getString("botToken"))
.setActivity(Activity.playing("@Ken | /help"))
@ -91,6 +95,8 @@ public class Ken {
public Database getDatabase() { return database; }
public ImageFetcher getImageFetcher() { return imageFetcher; }
public Role getRoleById(long id) { return api.getRoleById(id); }
public EmbedBuilder getDefaultEmbed() {

View file

@ -1,5 +1,6 @@
package net.tylermurphy.ken.api;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
@ -77,4 +78,16 @@ public abstract class Request {
return null;
}
public static HttpURLConnection getConnection(String link){
try {
final URL url = new URL(link);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0");
return connection;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View file

@ -20,15 +20,18 @@ import net.dv8tion.jda.api.interactions.components.selections.SelectMenu;
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction;
import net.dv8tion.jda.api.utils.FileUpload;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.fun.Claim;
import net.tylermurphy.ken.command.fun.Eject;
import net.tylermurphy.ken.command.fun.Money;
import net.tylermurphy.ken.command.fun.Slots;
import net.tylermurphy.ken.command.game.Claim;
import net.tylermurphy.ken.command.game.Money;
import net.tylermurphy.ken.command.game.Roulette;
import net.tylermurphy.ken.command.game.Slots;
import net.tylermurphy.ken.command.fun.*;
import net.tylermurphy.ken.command.game.*;
import net.tylermurphy.ken.command.main.*;
import net.tylermurphy.ken.command.moderation.*;
import net.tylermurphy.ken.command.music.*;
import net.tylermurphy.ken.command.music.Queue;
import net.tylermurphy.ken.command.nsfw.*;
import net.tylermurphy.ken.command.selfrole.*;
import java.awt.*;
import java.lang.reflect.Method;
@ -79,6 +82,20 @@ public class Responder extends ListenerAdapter {
new Money(),
new Slots(),
new Claim(),
new Headpat(),
new Roulette(),
new GayMeme(),
new CrabRave(),
new Wank(),
new Ban(),
new TempBan(),
new Kick(),
new UnBan(),
new Mute(),
new UnMute(),
new OpenServer(),
new CloseServer(),
new History(),
};
Arrays.stream(objects).forEach(register::register);
}
@ -136,6 +153,7 @@ public class Responder extends ListenerAdapter {
.setTitle(":x: **Error**")
.setDescription(e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
event.replyEmbeds(builder.build()).setEphemeral(true).queue();
e.printStackTrace();
}
}
@ -283,6 +301,7 @@ public class Responder extends ListenerAdapter {
switch (option.getType()) {
case STRING -> args.add(option.getAsString());
case INTEGER -> args.add(option.getAsInt());
case NUMBER -> args.add(option.getAsDouble());
case BOOLEAN -> args.add(option.getAsBoolean());
case USER -> args.add(option.getAsMember());
case CHANNEL -> args.add(option.getAsChannel());

View file

@ -0,0 +1,74 @@
package net.tylermurphy.ken.command.fun;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.Request;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.util.GifSequenceWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class CrabRave {
@Command(name="crabrave", description="Crav rave a server member")
@Option(name="member", description="Server member to rave", type= OptionType.USER, required=true)
public Response execute(Member sender, List<Object> args){
Member ejected = (Member) args.get(0);
try {
byte[] data = generateGif(ejected.getUser());
return Response.success(ejected.getEffectiveName() +" was raved by "+sender.getEffectiveName()).setFile(data, "eject.gif");
} catch (IOException e) {
return Response.error("Failed to generate gif");
}
}
private byte[] generateGif(User u) throws IOException, NullPointerException {
BufferedImage crab = Ken.getInstance().getImageFetcher().getImage("https://cdn.tylermurphy.net/ken/crab.png", true);
BufferedImage avatar = Ken.getInstance().getImageFetcher().getImage(u.getAvatarUrl(), false);
BufferedImage[] frames = new BufferedImage[26];
for(int i = 0; i < frames.length; i++) {
frames[i] = generateFrame(i, avatar, crab);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
GifSequenceWriter writer = new GifSequenceWriter(ios, frames[0].getType(), 10, true);
for (BufferedImage img : frames) {
writer.writeToSequence(img);
}
writer.close();
ios.close();
return baos.toByteArray();
}
private BufferedImage generateFrame(int frame, BufferedImage avatar, BufferedImage crab) {
int w = 500;
int h = 275;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(crab, 500*-frame,0, 13000, 275, null);
g2d.drawImage(avatar,60,175, 75, 75, null);
g2d.setFont(new Font("Dialog", Font.BOLD, 50));
g2d.setColor(Color.black);
g2d.drawString("IS GONE", 180, 225);
g2d.dispose();
return img;
}
}

View file

@ -1,12 +1,21 @@
package net.tylermurphy.ken.command.fun;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.Request;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.image.GifFactory;
import net.tylermurphy.ken.util.GifSequenceWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class Eject {
@ -15,8 +24,79 @@ public class Eject {
@Option(name="member", description="Server member to eject", type=OptionType.USER, required=true)
public Response execute(Member sender, List<Object> args){
Member ejected = (Member) args.get(0);
byte[] data = GifFactory.generateEjectGif(ejected.getUser());
return Response.success(ejected.getEffectiveName() +" was ejected by "+sender.getEffectiveName()).setFile(data, "eject.gif");
try {
byte[] data = generateGif(ejected.getUser());
return Response.success(ejected.getEffectiveName() +" was ejected by "+sender.getEffectiveName()).setFile(data, "eject.gif");
} catch (IOException e) {
return Response.error("Failed to generate gif");
}
}
private byte[] generateGif(User u) throws IOException {
String message;
if (Math.random() > .5)
message = u.getName() + " was An Impostor";
else
message = u.getName() + " was not An Impostor";
BufferedImage space = Ken.getInstance().getImageFetcher().getImage("https://cdn.tylermurphy.net/ken/space.jpg", true);
BufferedImage avatar = Ken.getInstance().getImageFetcher().getImage(u.getAvatarUrl(), false);
BufferedImage[] frames = new BufferedImage[30];
for (int i = 0; i < frames.length; i++) {
frames[i] = generateFrame(message, Math.min(i, 23), 24, space, avatar);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
GifSequenceWriter writer = new GifSequenceWriter(ios, frames[0].getType(), 8, true);
for (BufferedImage img : frames) {
writer.writeToSequence(img);
}
writer.close();
ios.close();
return baos.toByteArray();
}
public BufferedImage generateFrame(String message, int frame, float totalFrames, BufferedImage space1, BufferedImage avatar) {
int w = 600;
int h = 400;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(space1, (int) (-100+100/totalFrames*frame), 0, (int)(w*1.5), (int)(h*1.5), null);
BufferedImage ravater = rotate(avatar, 180/24*frame);
g2d.drawImage(ravater, (w+2*avatar.getWidth()+100)/24*frame-avatar.getWidth()-50, h/2-avatar.getHeight()/2, 150, 150, null);
if(frame > 12) {
int length = (message.length() * (frame-11)/12);
message = message.substring(0, length);
g2d.setFont(new Font("Dialog", Font.BOLD, 25));
FontMetrics fm = g2d.getFontMetrics();
int x = w/2 - fm.stringWidth(message)/2;
int y = h/2;
g2d.drawString(message, x, y);
}
g2d.dispose();
return img;
}
private BufferedImage rotate(BufferedImage img, double angle) {
int w = img.getWidth()+50;
int h = img.getHeight()+50;
BufferedImage rotated = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphic = rotated.createGraphics();
graphic.rotate(Math.toRadians(angle), w/2, h/2);
graphic.drawImage(img, null, w/2-img.getWidth()/2, h/2-img.getHeight()/2);
graphic.dispose();
return rotated;
}
}

View file

@ -0,0 +1,82 @@
package net.tylermurphy.ken.command.fun;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.Request;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.util.GifSequenceWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class GayMeme {
@Command(name="gaymeme", description="Generate a gay meme about a fellow server member")
@Option(name="member", description="Server member to make the meme about", type= OptionType.USER, required=true)
public Response execute(Member sender, List<Object> args){
Member ejected = (Member) args.get(0);
try {
byte[] data = generateGif(ejected.getUser());
return Response.success(sender.getEffectiveName() +" thinks "+ejected.getEffectiveName()+ " is gay!").setFile(data, "eject.gif");
} catch (IOException e) {
return Response.error("Failed to generate gif");
}
}
private byte[] generateGif(User u) throws IOException, NullPointerException {
BufferedImage avatar = Ken.getInstance().getImageFetcher().getImage(u.getAvatarUrl(), false);
BufferedImage background = Ken.getInstance().getImageFetcher().getImage("https://cdn.tylermurphy.net/ken/theMoreYouKnow.png", true);
BufferedImage gay = Ken.getInstance().getImageFetcher().getImage("https://cdn.tylermurphy.net/ken/gay.png", true);
BufferedImage[] frames = new BufferedImage[40];
for(int i = 0; i < frames.length; i++) {
frames[i] = generateFrame(i, avatar, background, gay);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
GifSequenceWriter writer = new GifSequenceWriter(ios, frames[0].getType(), 16, true);
for (BufferedImage img : frames) {
writer.writeToSequence(img);
}
writer.close();
ios.close();
return baos.toByteArray();
}
private BufferedImage generateFrame(int frame, BufferedImage avatar, BufferedImage background, BufferedImage gay) {
int w = 400;
int h = 200;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
if(frame < 25) {
g2d.drawImage(gay, 0, 0, 400, 200, null);
if (frame % 2 == 0) {
g2d.setColor(Color.black);
g2d.fillRect(0, 50, 400, 100);
}
g2d.drawImage(avatar, 150, 50, 100, 100, null);
} else {
g2d.drawImage(background, (400*3)*-Math.min(7, frame-24), 0, 9600, 200, null);
}
g2d.dispose();
return img;
}
}

View file

@ -0,0 +1,84 @@
package net.tylermurphy.ken.command.fun;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.api.Request;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.util.GifSequenceWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class Headpat {
@Command(name="headpat", description="Head pat a fellow server member")
@Option(name="member", description="Server member to head pat", type= OptionType.USER, required=true)
public Response execute(Member sender, List<Object> args){
Member ejected = (Member) args.get(0);
try {
byte[] data = generateGif(ejected.getUser());
return Response.success(sender.getEffectiveName() +" head patted "+ejected.getEffectiveName()).setFile(data, "eject.gif");
} catch (IOException e) {
return Response.error("Failed to generate gif");
}
}
private byte[] generateGif(User u) throws IOException, NullPointerException {
BufferedImage hand = Ken.getInstance().getImageFetcher().getImage("https://cdn.tylermurphy.net/ken/headpat.png", true);
BufferedImage avatar = Ken.getInstance().getImageFetcher().getImage(u.getAvatarUrl(), false);
BufferedImage[] frames = new BufferedImage[5];
for(int i = 0; i < frames.length; i++) {
frames[i] = generateFrame(i, hand, avatar);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
GifSequenceWriter writer = new GifSequenceWriter(ios, frames[0].getType(), 4, true);
for (BufferedImage img : frames) {
writer.writeToSequence(img);
}
writer.close();
ios.close();
return baos.toByteArray();
}
private BufferedImage generateFrame(int frame, BufferedImage hand, BufferedImage avatar){
int w = 400;
int h = 400;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
if(frame == 0)
g2d.drawImage(avatar, 140, 140, 260, 260, null);
else if(frame == 1)
g2d.drawImage(avatar, 120, 160, 280, 240, null);
else if(frame == 2)
g2d.drawImage(avatar, 100, 180, 300, 220, null);
else if(frame == 3)
g2d.drawImage(avatar, 110, 160, 280, 240, null);
else if(frame == 4)
g2d.drawImage(avatar, 130, 140, 260, 260, null);
g2d.drawImage(hand, frame*-400,0, 2000, 400, null);
g2d.dispose();
return img;
}
}

View file

@ -0,0 +1,84 @@
package net.tylermurphy.ken.command.fun;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.util.GifSequenceWriter;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class Wank {
@Command(name="wank", description="Wank to a fellow crew member")
@Option(name="member", description="Server member to wank", type= OptionType.USER, required=true)
public Response execute(Member sender, List<Object> args){
Member ejected = (Member) args.get(0);
try {
byte[] data = generateGif(ejected.getUser());
return Response.success(sender.getEffectiveName() +" wanked to "+ejected.getEffectiveName()).setFile(data, "eject.gif");
} catch (IOException e) {
return Response.error("Failed to generate gif");
}
}
private byte[] generateGif(User u) throws IOException {
BufferedImage wank = Ken.getInstance().getImageFetcher().getImage("https://cdn.tylermurphy.net/ken/laptop.png", true);
BufferedImage avatar = Ken.getInstance().getImageFetcher().getImage(u.getAvatarUrl(), false);
BufferedImage[] frames = new BufferedImage[4];
for (int i = 0; i < frames.length; i++) {
frames[i] = generateFrame(i, rotate(avatar, -35), wank);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
GifSequenceWriter writer = new GifSequenceWriter(ios, frames[0].getType(), 8, true);
for (BufferedImage img : frames) {
writer.writeToSequence(img);
}
writer.close();
ios.close();
return baos.toByteArray();
}
public BufferedImage generateFrame(int frame, BufferedImage avatar, BufferedImage wank) {
int w = 640;
int h = 360;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(avatar, 100, 95, 300, 140, null);
g2d.drawImage(wank, 640*-frame,0, 2560, 360, null);
g2d.dispose();
return img;
}
private BufferedImage rotate(BufferedImage img, double angle) {
int w = img.getWidth()+50;
int h = img.getHeight()+50;
BufferedImage rotated = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphic = rotated.createGraphics();
graphic.rotate(Math.toRadians(angle), w/2, h/2);
graphic.drawImage(img, null, w/2-img.getWidth()/2, h/2-img.getHeight()/2);
graphic.dispose();
return rotated;
}
}

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.fun;
package net.tylermurphy.ken.command.game;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
@ -17,7 +17,7 @@ public class Claim {
@Command(name="claim",description="Claim a random amount of moneys per 24h")
public Response execute(Member sender, Guild guild){
String data = Ken.getInstance().getDatabase().getEconomyData().getData(guild.getIdLong(), sender.getUser().getIdLong());
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(guild.getIdLong(), sender.getUser().getIdLong(), data);
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(data);
int money = json.getInt("money");
long claim = json.getLong("claim");
long currentTime = new Date().getTime();

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.fun;
package net.tylermurphy.ken.command.game;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
@ -15,7 +15,7 @@ public class Money {
@Command(name="money",description="Get the amount of money you have")
public Response execute(Member sender, Guild guild){
String data = Ken.getInstance().getDatabase().getEconomyData().getData(guild.getIdLong(), sender.getUser().getIdLong());
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(guild.getIdLong(), sender.getUser().getIdLong(), data);
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(data);
int money = json.getInt("money");
MessageEmbed embed = Ken.getInstance().getDefaultEmbed()
.setColor(Color.green)

View file

@ -0,0 +1,105 @@
package net.tylermurphy.ken.command.game;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.command.annotation.Selection;
import org.json.JSONObject;
import java.util.List;
public class Roulette {
@Command(name="roulette", description="Bet on a game of roulette")
@Option(name="bet", description="How much you want to bet", type=OptionType.INTEGER, required=true)
@Selection(name="type", description="What type of bet do you want to place", type=OptionType.STRING, choices={"red","black","green","odd","even","high","low","1st dozen","2nd dozen","3rd dozen","first four"}, required=true)
public Response execute(Member sender ,Guild guild, List<Object> args){
String data = Ken.getInstance().getDatabase().getEconomyData().getData(guild.getIdLong(), sender.getUser().getIdLong());
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(data);
int money = json.getInt("money");
int bet = (int)args.get(0);
if(bet < 5){
return Response.error("You cannot bet anything less than 5 moneys");
} else if(bet > money){
return Response.error("You don't have enough moneys to bet this much");
}
String guess = (String)args.get(1);
int rand = (int)(Math.random()*38);
boolean win = switch (guess) {
case "green" -> getColor(rand).equals("green");
case "black" -> getColor(rand).equals("black");
case "red" -> getColor(rand).equals("red");
case "even" -> rand>1 && (rand)%2==1;
case "odd" -> rand>1 && rand%2==0;
case "low" -> rand>=2 && rand<=19;
case "high" -> rand>19;
case "1st dozen" -> rand>=2 && rand<=13;
case "2nd dozen" -> rand>=14 && rand<=25;
case "3rd dozen" -> rand>25;
case "first four" -> rand<3;
default -> false;
};
int rate = getWinRate(guess);
int balance = win ? money -bet + bet * rate : money - bet;
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.setAuthor("Roulette")
.appendDescription("`Balance:` "+money+"\n")
.appendDescription("`Bet:` "+bet+"\n")
.appendDescription(getEmoji(rand) + getNumber(rand)+"\n")
.appendDescription("`New Balance:` "+balance+"\n")
.setFooter(win ? "You win! ("+rate+"x)" : "You loose, bet lost");
json.put("money",balance);
Ken.getInstance().getDatabase().getEconomyData().setData(guild.getIdLong(), sender.getUser().getIdLong(), json.toString());
return Response.success(builder.build());
}
private String getColor(int rand){
boolean even = (rand&2)==1;
if(rand<3) return "green";
if(rand<=10)
if(even) return "black";
else return "red";
else if(rand<=18)
if(even) return "red";
else return "black";
else if(rand<=28)
if(even) return "black";
else return "red";
else
if(even) return "red";
else return "black";
}
private int getWinRate(String guess){
return switch (guess) {
case "green" -> 17;
case "black", "red", "even", "odd", "low", "high" -> 2;
case "1st dozen", "2nd dozen", "3rd dozen" -> 3;
case "first four" -> 6;
default -> 1;
};
}
private String getEmoji(int rand){
String color = getColor(rand);
if(color.equals("green"))
return ":green_square:";
else if(color.equals("red"))
return ":red_square:";
else
return ":black_large_square:";
}
private String getNumber(int rand){
if(rand<2)
return rand == 0 ? "00" : "0";
else
return String.valueOf(rand-1);
}
}

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.fun;
package net.tylermurphy.ken.command.game;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Guild;
@ -31,7 +31,7 @@ public class Slots {
@Option(name="amount", description="Amount to bet", type=OptionType.INTEGER, required=true)
public Response execute(Member sender, Guild guild, List<Object> args){
String data = Ken.getInstance().getDatabase().getEconomyData().getData(guild.getIdLong(), sender.getUser().getIdLong());
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(guild.getIdLong(), sender.getUser().getIdLong(), data);
JSONObject json = Ken.getInstance().getDatabase().getEconomyData().updateData(data);
int money = json.getInt("money");
int bet = (int)args.get(0);
if(bet < 5){
@ -46,9 +46,7 @@ public class Slots {
.setTitle("Slot Machine")
.appendDescription("`Balance:` "+money+"\n")
.appendDescription("`Bet:` "+bet+"\n")
.appendDescription(":black_large_square:".repeat(5)+"\n")
.appendDescription(":black_large_square:" + slot1.emoji + slot2.emoji + slot3.emoji +":black_large_square:\n")
.appendDescription(":black_large_square:".repeat(5)+"\n");
.appendDescription(slot1.emoji + slot2.emoji + slot3.emoji + "\n");
if(slot1.emoji.equals(slot2.emoji) && slot1.emoji.equals(slot3.emoji)){
// 3 of a kind
money += bet * slot2.full_reward;

View file

@ -63,6 +63,14 @@ public class Help {
.appendDescription("**/remove <index>** Remove a song from the queue\n")
.appendDescription("**/nowplaying** See what track is currently playing\n")
.appendDescription("**/queue** View the current song queue\n"),
Ken.getInstance().getDefaultEmbed()
.setAuthor("Command List")
.setTitle(":camera: **Gif Commands**")
.appendDescription("**/crabrave <member>** Crab rave on someone\n")
.appendDescription("**/eject <member>** Eject someone because they are sus\n")
.appendDescription("**/gaymeme <member>** Warn someone that they are gay\n")
.appendDescription("**/headpat <member>** Pat someone on the head\n")
.appendDescription("**/wank <member>** Wank to someone\n"),
Ken.getInstance().getDefaultEmbed()
.setAuthor("Command List")
.setTitle(":game_die: **Game Commands**")
@ -70,7 +78,11 @@ public class Help {
.appendDescription("**/d8** Roll a d8 die\n")
.appendDescription("**/d12** Roll a d12 die\n")
.appendDescription("**/d20** Roll a d20 die\n")
.appendDescription("**/dice <sides>** Roll a dice with set sides\n"),
.appendDescription("**/dice <sides>** Roll a dice with set sides\n")
.appendDescription("**/claim** Claim moneys every 24h\n")
.appendDescription("**/money** Check how much moneys you have\n")
.appendDescription("**/roulette <bet>** Gamble on roulette\n")
.appendDescription("**/slots <bet>** Gamble on slots\n"),
Ken.getInstance().getDefaultEmbed()
.setAuthor("Command List")
.setTitle(":man_detective: **Self Roles**")

View file

@ -0,0 +1,86 @@
package net.tylermurphy.ken.command.moderation;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.PrivateChannel;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.command.annotation.Requirement;
import net.tylermurphy.ken.database.ModerationTable;
import net.tylermurphy.ken.util.Checks;
import org.json.JSONArray;
import org.json.JSONObject;
import java.awt.*;
import java.util.Date;
import java.util.List;
public class Ban {
@Command(name="ban", description="Perm ban a user and delete all messages in past 24h")
@Option(name="member", description="Member to ban", type=OptionType.USER, required=true)
@Option(name="reason", description="Reason to ban", type=OptionType.STRING, required=true)
@Option(name="deletemessages", description="Delete messages from past 24h", type=OptionType.BOOLEAN, required=true)
@Requirement(Permission.BAN_MEMBERS)
public Response execute(Member sender, List<Object> args, Guild guild){
Member target = (Member) args.get(0);
String reason = (String) args.get(1);
boolean purge = (boolean) args.get(2);
if(target == sender){
return Response.error("You are not allowed to do this to yourself");
}
Role low = Checks.getHighestRole(target);
Role high = Checks.getHighestRole(sender);
if(!Checks.getRolePermission(high, low)){
return Response.error("You need a higher role than the target");
}
Role self = Checks.getHighestRole(guild.getSelfMember());
if(!Checks.getRolePermission(self, low)){
return Response.error("I need a higher role than the target");
}
try {
guild.retrieveBan(target).complete();
return Response.error("User is already banned from this server");
} catch (ErrorResponseException ignored) {}
ModerationTable table = Ken.getInstance().getDatabase().getModerationTable();
String data = table.getData(guild.getIdLong(), target.getUser().getIdLong());
JSONObject json = table.updateData(data);
JSONObject status = json.getJSONObject("status");
status.put("type", "ban");
status.put("reason", reason);
status.put("until", 0L);
json.put("status", status);
JSONArray history = json.getJSONArray("history");
history.put(new JSONObject().put("type", "ban").put("reason", reason).put("date",new Date().getTime()));
json.put("history", history);
table.setData(guild.getIdLong(), target.getUser().getIdLong(), json.toString());
PrivateChannel channel = target.getUser().openPrivateChannel().complete();
if(channel != null){
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.setColor(Color.red)
.setTitle("**Banned**")
.appendDescription("You have been permanently banned from "+guild.getName()+"\n")
.appendDescription("`By:` " + sender.getEffectiveName()+"\n")
.appendDescription("`Reason:` " + reason);
channel.sendMessageEmbeds(builder.build()).queue();
}
guild.ban(target,purge ? 1 : 0,reason).queue();
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.appendDescription(String.format("Permanently banned %s for %s", target.getEffectiveName(), reason));
return Response.success(builder.build());
}
}

View file

@ -0,0 +1,4 @@
package net.tylermurphy.ken.command.moderation;
public class CloseServer {
}

View file

@ -0,0 +1,4 @@
package net.tylermurphy.ken.command.moderation;
public class History {
}

View file

@ -0,0 +1,4 @@
package net.tylermurphy.ken.command.moderation;
public class Kick {
}

View file

@ -0,0 +1,4 @@
package net.tylermurphy.ken.command.moderation;
public class Mute {
}

View file

@ -0,0 +1,4 @@
package net.tylermurphy.ken.command.moderation;
public class OpenServer {
}

View file

@ -0,0 +1,109 @@
package net.tylermurphy.ken.command.moderation;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.PrivateChannel;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.command.annotation.Requirement;
import net.tylermurphy.ken.database.ModerationTable;
import net.tylermurphy.ken.util.Checks;
import org.json.JSONArray;
import org.json.JSONObject;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class TempBan {
@Command(name="tempban", description="Temp ban a user and delete all messages in past 24h")
@Option(name="member", description="Member to temp-ban", type= OptionType.USER, required=true)
@Option(name="days", description="Days for temp ban", type= OptionType.INTEGER, required=true)
@Option(name="hours", description="Hours for temp ban", type= OptionType.INTEGER, required=true)
@Option(name="reason", description="Reason to temp-ban", type=OptionType.STRING, required=true)
@Option(name="deletemessages", description="Delete messages from past 24h", type=OptionType.BOOLEAN, required=true)
@Requirement(Permission.BAN_MEMBERS)
public Response execute(Member sender, List<Object> args, Guild guild){
Member target = (Member) args.get(0);
int days = (int) args.get(1);
int hours = (int) args.get(2);
String reason = (String) args.get(3);
boolean purge = (boolean) args.get(4);
if(target == sender){
return Response.error("You are not allowed to do this to yourself");
}
Role low = Checks.getHighestRole(target);
Role high = Checks.getHighestRole(sender);
if(!Checks.getRolePermission(high, low)){
return Response.error("You need a higher role than the target");
}
Role self = Checks.getHighestRole(guild.getSelfMember());
if(!Checks.getRolePermission(self, low)){
return Response.error("I need a higher role than the target");
}
if(hours < 0){
return Response.error("Hours must be 0 or greater");
}
if(days < 0){
return Response.error("Days must be 0 or greater");
}
if(days == 0 && hours == 0){
return Response.error("Time to ban cannot be 0");
}
try {
guild.retrieveBan(target).complete();
return Response.error("User is already banned from this server");
} catch (ErrorResponseException ignored) {}
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DATE, days);
cal.add(Calendar.HOUR, hours);
SimpleDateFormat format = new SimpleDateFormat("L d, y ha zz");
String date = format.format(cal.getTime());
ModerationTable table = Ken.getInstance().getDatabase().getModerationTable();
String data = table.getData(guild.getIdLong(), target.getUser().getIdLong());
JSONObject json = table.updateData(data);
JSONObject status = json.getJSONObject("status");
status.put("type", "temp-ban");
status.put("reason", reason);
status.put("until", cal.getTime().getTime());
json.put("status", status);
JSONArray history = json.getJSONArray("history");
history.put(new JSONObject().put("type", "temp-ban").put("reason", reason).put("date",new Date().getTime()));
json.put("history", history);
table.setData(guild.getIdLong(), target.getUser().getIdLong(), json.toString());
PrivateChannel channel = target.getUser().openPrivateChannel().complete();
if(channel != null){
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.setColor(Color.red)
.setTitle("**Temp Banned**")
.appendDescription("You have been temporarily banned from "+guild.getName()+"\n")
.appendDescription("`By:` " + sender.getEffectiveName()+"\n")
.appendDescription("`Reason:` " + reason)
.appendDescription("`Until:` " + date);
channel.sendMessageEmbeds(builder.build()).queue();
}
guild.ban(target,purge ? 1 : 0,reason).queue();
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.appendDescription(String.format("Temporarily banned %s for %s until %s", target.getEffectiveName(), reason, date));
return Response.success(builder.build());
}
}

View file

@ -0,0 +1,88 @@
package net.tylermurphy.ken.command.moderation;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.tylermurphy.ken.Ken;
import net.tylermurphy.ken.command.Response;
import net.tylermurphy.ken.command.annotation.Command;
import net.tylermurphy.ken.command.annotation.Option;
import net.tylermurphy.ken.command.annotation.Requirement;
import net.tylermurphy.ken.database.ModerationTable;
import org.json.JSONArray;
import org.json.JSONObject;
import java.awt.*;
import java.util.Date;
import java.util.List;
public class UnBan {
@Command(name="unban", description="Unban a user")
@Option(name="username", description="Username", type= OptionType.STRING, required=true)
@Option(name="discriminator", description="Discriminator", type=OptionType.INTEGER, required=true)
@Option(name="reason", description="Reason to unban", type=OptionType.STRING, required=true)
@Requirement(Permission.BAN_MEMBERS)
public Response execute(Member sender, Guild guild, List<Object> args){
String username = (String) args.get(0);
String discriminator = String.valueOf(args.get(1));
String reason = (String) args.get(2);
User target = null;
for(Guild.Ban ban : guild.retrieveBanList()){
User temp = ban.getUser();
if(temp.getName().equals(username) && temp.getDiscriminator().equals(discriminator)){
target = temp;
break;
}
}
if(target == null){
return Response.error("Unable to find this user");
}
if(target == sender.getUser()){
return Response.error("You are not allowed to do this to yourself");
}
try {
guild.retrieveBan(target).complete();
} catch (ErrorResponseException e) {
return Response.error("User is not banned from this server");
}
ModerationTable table = Ken.getInstance().getDatabase().getModerationTable();
String data = table.getData(guild.getIdLong(), target.getIdLong());
JSONObject json = table.updateData(data);
JSONObject status = json.getJSONObject("status");
status.put("type", "None");
status.put("reason", "");
status.put("until", 0L);
json.put("status", status);
JSONArray history = json.getJSONArray("history");
history.put(new JSONObject().put("type", "unban").put("reason", reason).put("date",new Date().getTime()));
json.put("history", history);
table.setData(guild.getIdLong(), target.getIdLong(), json.toString());
PrivateChannel channel = target.openPrivateChannel().complete();
if(channel != null){
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.setColor(Color.green)
.setTitle("**Unbanned**")
.appendDescription("You have been unbanned from "+guild.getName()+"\n")
.appendDescription("`By:` " + sender.getEffectiveName()+"\n")
.appendDescription("`Reason:` " + reason);
channel.sendMessageEmbeds(builder.build()).queue();
}
guild.unban(target).queue();
EmbedBuilder builder = Ken.getInstance().getDefaultEmbed()
.appendDescription(String.format("Unbanned %s for %s", target, reason));
return Response.success(builder.build());
}
}

View file

@ -0,0 +1,4 @@
package net.tylermurphy.ken.command.moderation;
public class UnMute {
}

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.main;
package net.tylermurphy.ken.command.selfrole;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.main;
package net.tylermurphy.ken.command.selfrole;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.main;
package net.tylermurphy.ken.command.selfrole;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.main;
package net.tylermurphy.ken.command.selfrole;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Guild;

View file

@ -1,4 +1,4 @@
package net.tylermurphy.ken.command.main;
package net.tylermurphy.ken.command.selfrole;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.*;

View file

@ -13,6 +13,7 @@ public class Database {
private final DatabaseConnection connection;
private final SelfRoleTable selfRoleTable;
private final EconomyTable economyTable;
private final ModerationTable moderationTable;
public Database(){
if(Ken.getInstance().getConfig().getBoolean("database.sqlite")) {
@ -22,6 +23,7 @@ public class Database {
}
selfRoleTable = new SelfRoleTable(this);
economyTable = new EconomyTable(this);
moderationTable = new ModerationTable(this);
}
public SelfRoleTable getSelfRoleData(){
@ -32,6 +34,8 @@ public class Database {
return economyTable;
}
public ModerationTable getModerationTable() { return moderationTable; }
protected Connection connect() throws SQLException {
return connection.connect();
}

View file

@ -55,7 +55,7 @@ public class EconomyTable {
}
}
public JSONObject updateData(long guildId, long userId, String data) {
public JSONObject updateData(String data) {
JSONObject object = data == null ? new JSONObject() : new JSONObject(data);
if(!object.has("money")) object.put("money", 0);
if(!object.has("claim")) object.put("claim", 0L);

View file

@ -0,0 +1,84 @@
package net.tylermurphy.ken.database;
import net.tylermurphy.ken.Ken;
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.*;
import java.util.function.Consumer;
public class ModerationTable {
private final Database database;
public ModerationTable(Database database){
String sql = """
CREATE TABLE IF NOT EXISTS moderation_data (
guild_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
data TEXT NOT NULL,
until BIGINT NOT NULL,
PRIMARY KEY (guild_id,user_id)
);""";
try(Connection connection = database.connect(); Statement statement = connection.createStatement()) {
statement.executeUpdate(sql);
} catch (SQLException e) {
Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage());
}
this.database = database;
}
public String getData(long guildId, long userId){
String sql = "SELECT * FROM moderation_data WHERE guild_id=? AND user_id=?";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setLong(1, guildId);
statement.setLong(2, userId);
ResultSet rs = statement.executeQuery();
if(rs.next()) return rs.getString("data");
else return null;
} catch (SQLException e) {
Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage());
return null;
}
}
public boolean setData(long guildId, long userId, String data) {
String sql = "INSERT OR REPLACE INTO moderation_data (guild_id, user_id, data, until) VALUES(?,?,?,?)";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setLong(1, guildId);
statement.setLong(2, userId);
statement.setString(3, data);
statement.setLong(4, new JSONObject(data).getJSONObject("status").getLong("until"));
return statement.executeUpdate() != 0;
} catch (SQLException e) {
Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage());
return false;
}
}
public void callOverdue(long date, Consumer<String[]> callback){
String sql = "SELECT * FROM moderation_data WHERE until < ? AND until > 0";
try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setLong(1, date);
ResultSet rs = statement.executeQuery();
while (rs.next()){
String[] data = {String.valueOf(rs.getLong("guild_id")), String.valueOf(rs.getLong("user_id")), rs.getString("data")};
callback.accept(data);
}
} catch (SQLException e) {
Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage());
}
}
public JSONObject updateData(String data) {
JSONObject object = data == null ? new JSONObject() : new JSONObject(data);
if(!object.has("history")) object.put("history", new JSONArray());
if(!object.has("roles")) object.put("roles", new JSONArray());
if(!object.has("status")) object.put("status", new JSONObject().put("type","None").put("until", 0L).put("reason",""));
return object;
}
}

View file

@ -1,131 +0,0 @@
package net.tylermurphy.ken.image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import net.dv8tion.jda.api.entities.User;
public class GifFactory {
public static byte[] generateEjectGif(User u) {
String message;
if(Math.random() > .5)
message = u.getName() + " was An Impostor";
else
message = u.getName() + " was not An Impostor";
BufferedImage space1 = ImageFactory.getImageFromURL("https://cdn.tylermurphy.net/ken/space.jpg");
BufferedImage avatar = ImageFactory.getImageFromURL(u.getAvatarUrl());
BufferedImage[] frames = new BufferedImage[30];
for(int i = 0; i < 30; i++) {
frames[i] = ImageFactory.GenerateEjectFrame(message, Math.min(i, 23), 24, space1, avatar);
}
try {
return generateFromBI(frames);
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
private static byte[] generateFromBI(BufferedImage[] images)
throws IIOException, IOException
{
System.out.println('e');
ImageWriter gifWriter = getWriter();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios = ImageIO.createImageOutputStream(baos);
IIOMetadata metadata = getMetadata(gifWriter);
gifWriter.setOutput(ios);
gifWriter.prepareWriteSequence(null);
for (BufferedImage img: images)
{
IIOImage temp = new IIOImage(img, null, metadata);
gifWriter.writeToSequence(temp, null);
}
gifWriter.endWriteSequence();
ios.close();
System.out.println('e');
return baos.toByteArray();
}
private static ImageWriter getWriter() throws IIOException
{
Iterator<ImageWriter> itr = ImageIO.getImageWritersByFormatName("gif");
if(itr.hasNext())
return itr.next();
throw new IIOException("GIF writer doesn't exist on this JVM!");
}
private static IIOMetadata getMetadata(ImageWriter writer)
throws IIOInvalidTreeException
{
ImageTypeSpecifier img_type = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_ARGB);
IIOMetadata metadata = writer.getDefaultImageMetadata(img_type, null);
String native_format = metadata.getNativeMetadataFormatName();
IIOMetadataNode node_tree = (IIOMetadataNode)metadata.getAsTree(native_format);
IIOMetadataNode graphics_node = getNode("GraphicControlExtension", node_tree);
graphics_node.setAttribute("delayTime", String.valueOf(8));
graphics_node.setAttribute("disposalMethod", "none");
graphics_node.setAttribute("userInputFlag", "FALSE");
makeLoopy(node_tree);
metadata.setFromTree(native_format, node_tree);
return metadata;
}
private static void makeLoopy(IIOMetadataNode root)
{
IIOMetadataNode app_extensions = getNode("ApplicationExtensions", root);
IIOMetadataNode app_node = getNode("ApplicationExtension", app_extensions);
app_node.setAttribute("applicationID", "NETSCAPE");
app_node.setAttribute("authenticationCode", "2.0");
app_node.setUserObject(new byte[]{ 0x1, (byte) (0), (byte) ((0) & 0xFF)});
app_extensions.appendChild(app_node);
root.appendChild(app_extensions);
}
private static IIOMetadataNode getNode(String node_name, IIOMetadataNode root)
{
IIOMetadataNode node;
for (int i = 0; i < root.getLength(); i++)
{
if(root.item(i).getNodeName().compareToIgnoreCase(node_name) == 0)
{
node = (IIOMetadataNode) root.item(i);
return node;
}
}
node = new IIOMetadataNode(node_name);
root.appendChild(node);
return node;
}
}

View file

@ -1,75 +0,0 @@
package net.tylermurphy.ken.image;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.imageio.ImageIO;
public class ImageFactory {
public static BufferedImage GenerateEjectFrame(String message, int frame, float totalFrames, BufferedImage space1, BufferedImage avatar) {
try {
int w = 600;
int h = 400;
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.drawImage(space1, (int) (-100+100/totalFrames*frame), 0, (int)(w*1.5), (int)(h*1.5), null);
BufferedImage ravater = rotate(avatar, 180/24*frame);
g2d.drawImage(ravater, (w+2*avatar.getWidth()+100)/24*frame-avatar.getWidth()-50, h/2-avatar.getHeight()/2, 150, 150, null);
if(frame > 12) {
int length = (message.length() * (frame-11)/12);
message = message.substring(0, length);
g2d.setFont(new Font("Dialog", Font.BOLD, 25));
FontMetrics fm = g2d.getFontMetrics();
int x = w/2 - fm.stringWidth(message)/2;
int y = h/2;
g2d.drawString(message, x, y);
}
return img;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static BufferedImage rotate(BufferedImage bimg, double angle) {
int w = bimg.getWidth()+50;
int h = bimg.getHeight()+50;
BufferedImage rotated = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphic = rotated.createGraphics();
graphic.rotate(Math.toRadians(angle), w/2, h/2);
graphic.drawImage(bimg, null, w/2-bimg.getWidth()/2, h/2-bimg.getHeight()/2);
graphic.dispose();
return rotated;
}
public static BufferedImage getImageFromURL(String link) {
try {
final URL url = new URL(link);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0");
return ImageIO.read(connection.getInputStream());
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View file

@ -0,0 +1,33 @@
package net.tylermurphy.ken.util;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import java.util.List;
public class Checks {
public static Role getHighestRole(Member member) {
if(member == null) {
return null;
}
List<Role> roles = member.getRoles();
if (roles.isEmpty()) {
return null;
}
return roles.stream().min((first, second) -> {
if (first.getPosition() == second.getPosition()) {
return 0;
}
return first.getPosition() > second.getPosition() ? -1 : 1;
}).orElse(null);
}
public static boolean getRolePermission(Role first, Role second){
if(first == null) return false;
if(second == null) return true;
if(!first.getGuild().equals(second.getGuild())) return false;
return first.getPosition() > second.getPosition();
}
}

View file

@ -0,0 +1,75 @@
package net.tylermurphy.ken.util;
import javax.imageio.*;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.RenderedImage;
import java.io.IOException;
public class GifSequenceWriter {
protected ImageWriter writer;
protected ImageWriteParam params;
protected IIOMetadata metadata;
public GifSequenceWriter(ImageOutputStream out, int imageType, int delay, boolean loop) throws IOException {
writer = ImageIO.getImageWritersBySuffix("gif").next();
params = writer.getDefaultWriteParam();
ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imageType);
metadata = writer.getDefaultImageMetadata(imageTypeSpecifier, params);
configureRootMetadata(delay, loop);
writer.setOutput(out);
writer.prepareWriteSequence(null);
}
private void configureRootMetadata(int delay, boolean loop) throws IIOInvalidTreeException {
String metaFormatName = metadata.getNativeMetadataFormatName();
IIOMetadataNode root = (IIOMetadataNode) metadata.getAsTree(metaFormatName);
IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");
graphicsControlExtensionNode.setAttribute("disposalMethod", "restoreToBackgroundColor");
graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
graphicsControlExtensionNode.setAttribute("transparentColorFlag", "TRUE");
graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(delay / 10));
graphicsControlExtensionNode.setAttribute("transparentColorIndex", "3");
IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
commentsNode.setAttribute("CommentExtension", "Created by: https://memorynotfound.com");
IIOMetadataNode appExtensionsNode = getNode(root, "ApplicationExtensions");
IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");
child.setAttribute("applicationID", "NETSCAPE");
child.setAttribute("authenticationCode", "2.0");
int loopContinuously = loop ? 0 : 1;
child.setUserObject(new byte[]{ 0x1, (byte) (loopContinuously & 0xFF), (byte) ((loopContinuously >> 8) & 0xFF)});
appExtensionsNode.appendChild(child);
metadata.setFromTree(metaFormatName, root);
}
private static IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName){
int nNodes = rootNode.getLength();
for (int i = 0; i < nNodes; i++){
if (rootNode.item(i).getNodeName().equalsIgnoreCase(nodeName)){
return (IIOMetadataNode) rootNode.item(i);
}
}
IIOMetadataNode node = new IIOMetadataNode(nodeName);
rootNode.appendChild(node);
return(node);
}
public void writeToSequence(RenderedImage img) throws IOException {
writer.writeToSequence(new IIOImage(img, null, metadata), params);
}
public void close() throws IOException {
writer.endWriteSequence();
}
}

View file

@ -0,0 +1,30 @@
package net.tylermurphy.ken.util;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class ImageFetcher {
private final Map<String,BufferedImage> CACHE = new HashMap<>();
public BufferedImage getImage(String url, boolean cache) throws IOException {
if(CACHE.containsKey(url)) return CACHE.get(url);
HttpURLConnection connection = getConnection(url);
BufferedImage image = ImageIO.read(connection.getInputStream());
if(cache && image != null) CACHE.put(url, image);
return image;
}
private HttpURLConnection getConnection(String link) throws IOException {
final URL url = new URL(link);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0");
return connection;
}
}