diff --git a/src/main/java/net/tylermurphy/ken/command/Responder.java b/src/main/java/net/tylermurphy/ken/command/Responder.java index 014e745..3dfc644 100644 --- a/src/main/java/net/tylermurphy/ken/command/Responder.java +++ b/src/main/java/net/tylermurphy/ken/command/Responder.java @@ -20,7 +20,11 @@ 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.*; +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.*; import net.tylermurphy.ken.command.main.*; import net.tylermurphy.ken.command.music.*; import net.tylermurphy.ken.command.music.Queue; @@ -72,6 +76,9 @@ public class Responder extends ListenerAdapter { new nHentai(), new Rule34(), new Yandere(), + new Money(), + new Slots(), + new Claim(), }; Arrays.stream(objects).forEach(register::register); } diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Claim.java b/src/main/java/net/tylermurphy/ken/command/fun/Claim.java new file mode 100644 index 0000000..bc53b83 --- /dev/null +++ b/src/main/java/net/tylermurphy/ken/command/fun/Claim.java @@ -0,0 +1,44 @@ +package net.tylermurphy.ken.command.fun; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.tylermurphy.ken.Ken; +import net.tylermurphy.ken.command.Response; +import net.tylermurphy.ken.command.annotation.Command; +import org.json.JSONObject; + +import java.awt.*; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +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); + int money = json.getInt("money"); + long claim = json.getLong("claim"); + long currentTime = new Date().getTime(); + long day = 24 * 60 * 60 * 1000; + if(claim+day < currentTime){ + int add = (int)(Math.random()*400)+100; + json.put("money", money+add); + json.put("claim",currentTime); + Ken.getInstance().getDatabase().getEconomyData().setData(guild.getIdLong(), sender.getUser().getIdLong(), json.toString()); + MessageEmbed embed = Ken.getInstance().getDefaultEmbed() + .setColor(Color.green) + .setAuthor("Money Claim", sender.getUser().getAvatarUrl()) + .setDescription("You found " + add + " moneys!") + .build(); + return Response.success(embed); + } else { + long diff = Math.abs(claim+day - currentTime); + long hours = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS); + long minutes = TimeUnit.MINUTES.convert(diff-hours*60*60*1000, TimeUnit.MILLISECONDS); + return Response.error("You can use /claim again in "+hours+"h"+minutes+"m"); + } + } + +} diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Eject.java b/src/main/java/net/tylermurphy/ken/command/fun/Eject.java index eac2a2c..fda1e18 100644 --- a/src/main/java/net/tylermurphy/ken/command/fun/Eject.java +++ b/src/main/java/net/tylermurphy/ken/command/fun/Eject.java @@ -7,7 +7,6 @@ import net.tylermurphy.ken.command.annotation.Option; import net.tylermurphy.ken.command.Response; import net.tylermurphy.ken.image.GifFactory; -import java.io.File; import java.util.List; public class Eject { diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Money.java b/src/main/java/net/tylermurphy/ken/command/fun/Money.java new file mode 100644 index 0000000..7d399e2 --- /dev/null +++ b/src/main/java/net/tylermurphy/ken/command/fun/Money.java @@ -0,0 +1,28 @@ +package net.tylermurphy.ken.command.fun; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.tylermurphy.ken.Ken; +import net.tylermurphy.ken.command.Response; +import net.tylermurphy.ken.command.annotation.Command; +import org.json.JSONObject; + +import java.awt.*; + +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); + int money = json.getInt("money"); + MessageEmbed embed = Ken.getInstance().getDefaultEmbed() + .setColor(Color.green) + .setAuthor("Bank Account", sender.getUser().getAvatarUrl()) + .setDescription("You currently have " + money + " moneys!") + .build(); + return Response.success(embed); + } + +} diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Slots.java b/src/main/java/net/tylermurphy/ken/command/fun/Slots.java new file mode 100644 index 0000000..f03d50c --- /dev/null +++ b/src/main/java/net/tylermurphy/ken/command/fun/Slots.java @@ -0,0 +1,86 @@ +package net.tylermurphy.ken.command.fun; + +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 org.json.JSONObject; + +import java.util.List; + + +public class Slots { + + record Slot(int weight, float full_reward, float half_reward, String emoji){} + + private final Slot[] CHOICES = new Slot[]{ + new Slot(25, 0.75f, 0.50f, ":melon:"), + new Slot(15, 1.00f, 0.75f, ":green_apple:"), + new Slot(15, 1.25f, 1.00f, ":apple:"), + new Slot(15, 2.00f, 1.25f, ":tangerine:"), + new Slot(10, 2.50f, 1.50f, ":mango:"), + new Slot(10, 3.00f, 1.75f, ":lemon:"), + new Slot(10, 5.00f, 2.00f, ":cherries:"), + }; + + @Command(name="slots", description="Bet your money on a slot machine") + @Option(name="amount", description="Amount to bet", type=OptionType.INTEGER, required=true) + public Response execute(Member sender, Guild guild, List 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); + 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"); + } + Slot slot1 = getSlot(0); + Slot slot2 = getSlot(slot1.weight); + Slot slot3 = getSlot(slot2.weight); + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .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"); + if(slot1.emoji.equals(slot2.emoji) && slot1.emoji.equals(slot3.emoji)){ + // 3 of a kind + money += bet * slot2.full_reward; + builder.setFooter("3 of a kind! ("+slot2.full_reward+"x)"); + } else if(slot1.emoji.equals(slot2.emoji) || slot2.emoji.equals(slot3.emoji) || slot1.emoji.equals(slot3.emoji)){ + // 2 of a kind + Slot slot = (slot1.emoji.equals(slot2.emoji) ? slot1 : slot3); + money += bet * slot.half_reward; + builder.setFooter("2 of a kind! ("+slot.half_reward+"x)"); + } else { + // Fail + money -= bet; + builder.setFooter("None of a kind, loose bet."); + } + builder.appendDescription("`New Balance:` "+money); + json.put("money",money); + Ken.getInstance().getDatabase().getEconomyData().setData(guild.getIdLong(), sender.getUser().getIdLong(), json.toString()); + return Response.success(builder.build()); + } + + private Slot getSlot(int pull){ + double rand = (int)(Math.random()*100)+1; + double diff = pull - rand; + if(pull != 0){ + rand = diff > 0 ? rand + diff*Math.random() : rand - diff*Math.random(); + } + int walk = 0; + for(Slot slot : CHOICES){ + if(slot.weight + walk > rand) return slot; + else walk += slot.weight; + } + return CHOICES[CHOICES.length-1]; + } + +} diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java b/src/main/java/net/tylermurphy/ken/command/game/Coinflip.java similarity index 94% rename from src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java rename to src/main/java/net/tylermurphy/ken/command/game/Coinflip.java index d2522c4..7640edf 100644 --- a/src/main/java/net/tylermurphy/ken/command/fun/Coinflip.java +++ b/src/main/java/net/tylermurphy/ken/command/game/Coinflip.java @@ -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.Member; diff --git a/src/main/java/net/tylermurphy/ken/command/fun/Dice.java b/src/main/java/net/tylermurphy/ken/command/game/Dice.java similarity index 97% rename from src/main/java/net/tylermurphy/ken/command/fun/Dice.java rename to src/main/java/net/tylermurphy/ken/command/game/Dice.java index e6d711c..ea180a9 100644 --- a/src/main/java/net/tylermurphy/ken/command/fun/Dice.java +++ b/src/main/java/net/tylermurphy/ken/command/game/Dice.java @@ -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.Member; diff --git a/src/main/java/net/tylermurphy/ken/database/Database.java b/src/main/java/net/tylermurphy/ken/database/Database.java index 2ce1874..8e209fb 100644 --- a/src/main/java/net/tylermurphy/ken/database/Database.java +++ b/src/main/java/net/tylermurphy/ken/database/Database.java @@ -12,6 +12,7 @@ public class Database { private final DatabaseConnection connection; private final SelfRoleTable selfRoleTable; + private final EconomyTable economyTable; public Database(){ if(Ken.getInstance().getConfig().getBoolean("database.sqlite")) { @@ -20,12 +21,17 @@ public class Database { connection = new MySQLConnection(); } selfRoleTable = new SelfRoleTable(this); + economyTable = new EconomyTable(this); } public SelfRoleTable getSelfRoleData(){ return selfRoleTable; } + public EconomyTable getEconomyData(){ + return economyTable; + } + protected Connection connect() throws SQLException { return connection.connect(); } diff --git a/src/main/java/net/tylermurphy/ken/database/EconomyTable.java b/src/main/java/net/tylermurphy/ken/database/EconomyTable.java new file mode 100644 index 0000000..589a204 --- /dev/null +++ b/src/main/java/net/tylermurphy/ken/database/EconomyTable.java @@ -0,0 +1,65 @@ +package net.tylermurphy.ken.database; + +import net.tylermurphy.ken.Ken; +import org.json.JSONObject; + +import java.sql.*; + +public class EconomyTable { + + private final Database database; + + public EconomyTable(Database database){ + + String sql = """ + CREATE TABLE IF NOT EXISTS economy_data ( + guild_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + data TEXT 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 economy_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 economy_data (guild_id, user_id, data) VALUES(?,?,?)"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setLong(1, guildId); + statement.setLong(2, userId); + statement.setString(3, data); + return statement.executeUpdate() != 0; + } catch (SQLException e) { + Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage()); + return false; + } + } + + public JSONObject updateData(long guildId, long userId, 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); + return object; + } + +}