diff options
Diffstat (limited to 'src/main/java/net/uomc/mineshaft/resources')
15 files changed, 1305 insertions, 0 deletions
diff --git a/src/main/java/net/uomc/mineshaft/resources/Resource.java b/src/main/java/net/uomc/mineshaft/resources/Resource.java new file mode 100644 index 0000000..1cd508e --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/Resource.java @@ -0,0 +1,145 @@ +package net.uomc.mineshaft.resources; + +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import org.json.JSONObject; + +import com.mouldycheerio.dbot.util.DatabaseUtils; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; + +public class Resource extends JSONObject { + + private static final String SYMBOL = "symbol"; + private static final String NAME = "name"; + private static final String VALUE = "value"; + private ResourceManager resourceManager; + private String tableName; + + public Resource(String name, String symbol, long value, ResourceManager resourceManager) { + super(); + setName(name); + setSymbol(symbol); + setValue(value); + this.resourceManager = resourceManager; + initDB(); + + } + + public Resource(JSONObject jsonObject, ResourceManager resourceManager) { + super(); + this.resourceManager = resourceManager; + jsonObject.keySet().forEach(k -> put(k, jsonObject.get(k))); + initDB(); + } + + public void initDB() { + tableName = getName().split(" ")[0]; + try { + DatabaseUtils.createSimpleKVtable(resourceManager.getDatabasepath(), tableName); + } catch (SQLException e) { + // e.printStackTrace(); + } + } + + public void set(Member member, long value) { + try { + DatabaseUtils.putInKVtable(resourceManager.getDatabasepath(), tableName, member.getId() + ":" + member.getGuild().getId(), value); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public long get(Member member) { + try { + return DatabaseUtils.getInKVtable(resourceManager.getDatabasepath(), tableName, member.getId() + ":" + member.getGuild().getId()); + } catch (SQLException e) { + e.printStackTrace(); + } + return 0l; + } + + public long getValue(String memberid, String guildId) { + try { + return DatabaseUtils.getInKVtable(resourceManager.getDatabasepath(), tableName, memberid + ":" + guildId); + } catch (SQLException e) { + e.printStackTrace(); + } + return 0l; + } + + public long total() { + try { + return DatabaseUtils.getTotal(resourceManager.getDatabasepath(), tableName); + } catch (SQLException e) { + e.printStackTrace(); + } + return 0; + } + + public List<String> getMembersGuilds() { + try { + return DatabaseUtils.listKeys(resourceManager.getDatabasepath(), tableName); + } catch (SQLException e) { + e.printStackTrace(); + } + return Collections.emptyList(); + } + + public List<String> getMembers(Guild guild) { + return getMembersGuilds().stream().filter(m -> guild.getId().equals(m.split(":")[1])).map(m -> m.split(":")[0]).collect(Collectors.toList()); + } + + public void increment(Member member, long amount) { + set(member, get(member) + amount); + } + + public String getName() { + return getString(NAME); + } + + public String getPrettyName() { + return Arrays.stream(getString(NAME).replaceAll("_", " ").split("\\s+")) + .map(word -> word.substring(0, 1).toUpperCase() + word.substring(1)) + .collect(Collectors.joining(" ")); + } + + public void setName(String name) { + put(NAME, name); + } + + public String getSymbol() { + return getString(SYMBOL); + } + + public void setSymbol(String symbol) { + put(SYMBOL, symbol); + } + + public long getValue() { + if (total() <= 0) { + return -1; + } else { + return resourceManager.getPrimaryResource().total() / total(); + } + } + + public void setValue(long value) { + put(VALUE, value); + } + + public String prettyValue(long value) { + return PeelingUtils.amountToString(value) + getSymbol(); + } + + @Override + public String toString() { + return getName(); + } +} diff --git a/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java b/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java new file mode 100644 index 0000000..8c58ab3 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/ResourceManager.java @@ -0,0 +1,224 @@ +package net.uomc.mineshaft.resources; + +import java.io.File; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Timer; +import java.util.TimerTask; + +import org.json.JSONArray; +import org.json.JSONObject; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandController; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.uomc.mineshaft.resources.commands.CreateResourceCommand; +import net.uomc.mineshaft.resources.commands.GiveResourcesCommand; +import net.uomc.mineshaft.resources.commands.LeaderBoardCommand; +import net.uomc.mineshaft.resources.commands.ListResourcesCommand; +import net.uomc.mineshaft.resources.commands.MyResourcesCommand; +import net.uomc.mineshaft.resources.commands.RemoveResourceCommand; +import net.uomc.mineshaft.resources.commands.SetPrimaryResourceCommand; +import net.uomc.mineshaft.resources.commands.ValuesCommand; +import net.uomc.mineshaft.resources.market.MarketCommand; +import net.uomc.mineshaft.resources.market.MarketManager; + +public class ResourceManager { + + private static final String PRIMARY_RESOURCE_KEY = "primary_resource"; + private static final String RESOURCES_KEY = "resources"; + private List<Resource> resources = new ArrayList<Resource>(); + + private File configFile; + private CustomBot bot; + private String databasepath; + + private String primaryResource = "money"; + + private MarketManager marketManager; + + public ResourceManager(CustomBot customBot) { + this.bot = customBot; + configFile = new File(customBot.getDatadir(), "resources_config.json"); + + File database = new File(customBot.getDatadir(), "resources.db"); + databasepath = database.getPath(); + + loadResources(); + + marketManager = new MarketManager(this); + + initCommands(); + } + + private void initCommands() { + CommandController cc = bot.getCommandController(); + + // setup commands + cc.addCommand(new ListResourcesCommand(this)); + cc.addCommand(new CreateResourceCommand(this)); + cc.addCommand(new RemoveResourceCommand(this)); + cc.addCommand(new SetPrimaryResourceCommand(this)); + + MyResourcesCommand myResourcesCommand = new MyResourcesCommand(this); + + cc.addCommand(CommandDetails.from("balance,bal,$,money"), (e, b, args) -> { + Member member = PeelingUtils.getSingleMentionFromArgs(e); + + bot.sendMessage( + e, (member.equals(e.getMember()) ? "You have" : member.getEffectiveName() + " has") + + " **" + getPrimaryResource().prettyValue( + getPrimaryResource().get(member) + ) + "**" + ); + + }); + + // public commands + cc.addCommand(myResourcesCommand); + + cc.addCommand(new GiveResourcesCommand(this)); + //cc.addCommand(new MarketCommand(marketManager)); + + cc.addCommand(new ValuesCommand(this)); + cc.addCommand(new LeaderBoardCommand(this)); + } + + private void loadResources() { + JSONObject loadJSON = PeelingUtils.loadJSON(configFile); + + if (loadJSON.has(RESOURCES_KEY)) { + JSONArray jsonArray = loadJSON.getJSONArray(RESOURCES_KEY); + for (Object o : jsonArray) { + if (o instanceof JSONObject) { + Resource resource = new Resource((JSONObject) o, this); + resources.add(resource); + } + } + } + + if (loadJSON.has(PRIMARY_RESOURCE_KEY)) { + setPrimaryResource(loadJSON.getString(PRIMARY_RESOURCE_KEY)); + } + } + + private void saveResources() { + JSONObject save = new JSONObject(); + save.put(PRIMARY_RESOURCE_KEY, primaryResource); + + resources.forEach(r -> save.append(RESOURCES_KEY, r)); + + PeelingUtils.saveJSONPretty(configFile, save); + } + + public void addResource(Resource resource) { + resources.add(resource); + saveResources(); + } + + public Resource getResource(String input) { + for (Resource resource : resources) { + if (resource.getName().equalsIgnoreCase(input) || resource.getSymbol().equalsIgnoreCase(input)) { + return resource; + } + } + return null; + } + + public List<Resource> listResources() { + return Collections.unmodifiableList(resources); + } + + public boolean removeResource(String name) { + Resource resource = getResource(name); + if (resource != null) { + resources.remove(resource); + saveResources(); + return true; + } else { + return false; + } + } + + public CustomBot getBot() { + return bot; + } + + public void setBot(CustomBot bot) { + this.bot = bot; + } + + public String getDatabasepath() { + return databasepath; + } + + public void setDatabasepath(String databasepath) { + this.databasepath = databasepath; + } + + public Resource getPrimaryResource() { + Resource resource = getResource(primaryResource); + return resource == null ? resources.get(0) : resource; + + } + + public String getPrimaryResourceName() { + return primaryResource; + } + + public void setPrimaryResource(String primaryResource) { + this.primaryResource = primaryResource; + saveResources(); + } + + public List<Resource> getResources() { + return Collections.unmodifiableList(resources); + } + + public long getResource(Member member, String resourceName) { + Resource resource = getResource(resourceName); + if (resource == null) + return 0; + + return resource.get(member); + } + public void setResource(Member member, String resourceName, long amount) { + Resource resource = getResource(resourceName); + if (resource == null) + return; + + resource.set(member, amount); + } + + public void addResource(Member member, String resource, long amount){ + long a = getResource(member, resource); + setResource(member, resource, a + amount); + } + + public void addResources(Member member, Map<String, Long> resources) { + resources.forEach((k, v) -> { + addResource(member, k, v); + }); + } + + public String createResourceList(Map<String, Long> resources) { + StringBuilder string = new StringBuilder(); + resources.entrySet().stream() + .sorted((e1, e2) -> + (int)(e2.getValue() - e1.getValue())) + .forEach((e) -> { + Resource resource = getResource(e.getKey()); + if (resource != null) + string.append(resource.prettyValue(e.getValue()) + "\n"); + }); + return string.toString(); + } +} diff --git a/src/main/java/net/uomc/mineshaft/resources/ResourceTable.java b/src/main/java/net/uomc/mineshaft/resources/ResourceTable.java new file mode 100644 index 0000000..8cce03e --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/ResourceTable.java @@ -0,0 +1,127 @@ +package net.uomc.mineshaft.resources; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.json.JSONObject; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; + +public class ResourceTable extends JSONObject { + public ResourceTable(JSONObject jsonObject) { + super(); + jsonObject.keySet().forEach(k -> put(k, jsonObject.get(k))); + } + + public ResourceTable() { + super(); + } + + public void setResource(Resource resource, long value) { + put(resource.getName(), value); + } + + public long getResource(Resource resource) { + String name = resource.getName(); + if (has(name)) { + return getLong(name); + } + return 0l; + } + + public Map<Resource, Long> getTable(ResourceManager resourceManager) { + HashMap<Resource, Long> hashMap = new HashMap<Resource, Long>(); + Iterator<String> keys = keys(); + while (keys.hasNext()) { + String key = keys.next(); + Resource resource = resourceManager.getResource(key); + if (resource != null) { + long q = getLong(key); + hashMap.put(resource, q); + } + } + + return Collections.unmodifiableMap(hashMap); + } + + public void addToUser(Member user, ResourceManager resourceManager) { + Map<Resource, Long> table = getTable(resourceManager); + table.forEach((resource, q) -> { + resource.increment(user, q); + }); + } + + public void removeFromUser(Member user, ResourceManager resourceManager) { + Map<Resource, Long> table = getTable(resourceManager); + table.forEach((resource, q) -> { + resource.increment(user, -q); + }); + } + + /** + * @param user + * @param resourceManager + * @return list of resources that are lacking + */ + public Map<Resource, Long> doesUserHave(Member user, ResourceManager resourceManager) { + Map<Resource, Long> table = getTable(resourceManager); + Map<Resource, Long> lacking = new HashMap<Resource, Long>(); + table.forEach((resource, q) -> { + if (resource.get(user) < q) { + lacking.put(resource, q - resource.get(user)); + } + }); + + return Collections.unmodifiableMap(lacking); + } + + public String toStringList(ResourceManager resourceManager) { + Map<Resource, Long> table = getTable(resourceManager); + + List<String> parts = new ArrayList<String>(); + table.forEach((r, q) -> parts.add(r.prettyValue(q))); + + return String.join(", ", parts); + } + + public void addResourceTable(ResourceTable table) { + Iterator<String> keys = table.keys(); + while (keys.hasNext()) { + String next = keys.next(); + + put(next, optLong(next) + table.getLong(next)); + } + } + + public ResourceTable negatives() { + ResourceTable negatives = new ResourceTable(); + Iterator<String> keys = keys(); + while (keys.hasNext()) { + String next = keys.next(); + long long1 = getLong(next); + if (long1 < 0) { + negatives.put(next, Math.abs(long1)); + } + } + return negatives; + } + + public ResourceTable postives() { + ResourceTable positives = new ResourceTable(); + Iterator<String> keys = keys(); + while (keys.hasNext()) { + String next = keys.next(); + long long1 = getLong(next); + if (long1 > 0) { + positives.put(next, long1); + } + } + return positives; + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/CreateResourceCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/CreateResourceCommand.java new file mode 100644 index 0000000..a9f0dc6 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/CreateResourceCommand.java @@ -0,0 +1,44 @@ +package net.uomc.mineshaft.resources.commands; + +import java.util.ArrayList; +import java.util.List; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class CreateResourceCommand extends ResourceCommand { + private List<String> questions; + + public CreateResourceCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.hidden("createItem")); + + questions = new ArrayList<String>(); + questions.add("What is the name of this item?"); + questions.add("What is the symbol for this item?"); + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + String ownerid = op.getConfig().getString("ownerid"); + if (ownerid.equals(e.getAuthor().getId())) { + PeelingUtils.askQuestions(e, questions, (responses) -> { + String name = responses.get(0); + String symbol = responses.get(1); + + Resource resource = new Resource(name, symbol, 1, getResourceManager()); + getResourceManager().addResource(resource); + + op.sendMessage(e, "Items", ":white_check_mark: added **" + name + "** to the list of items"); + }); + } else { + op.sendErrorMessage(e, ":x: this command is not intended for you"); + } + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java new file mode 100644 index 0000000..a98a452 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/GiveResourcesCommand.java @@ -0,0 +1,85 @@ +package net.uomc.mineshaft.resources.commands; + +import static java.lang.Math.abs; + +import java.util.Optional; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class GiveResourcesCommand extends ResourceCommand { + + private String usage; + + public GiveResourcesCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.from("give,trade", "Give a user an item", "give [@user] [quantity] [item]")); + usage = "\n`" + getCommandDetails().getUsage() + "`"; + + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + if (args.length > 1) { + String usermention = args[0]; + String quantitystring = args[1]; + String resourcename = getResourceManager().getPrimaryResourceName(); + if (args.length > 2) { + resourcename = args[2]; + } + + boolean generate = false; + String ownerid = op.getConfig().getString("ownerid"); + if (ownerid.equals(e.getAuthor().getId())) { + if (args.length > 3) { + if (args[3].equals("generate")) { + generate = true; + } + } + } + Optional<Member> mentionToUser = PeelingUtils.mentionToMember(usermention, e.getGuild()); + if (mentionToUser.isPresent()) { + Member member = mentionToUser.get(); + try { + long quantity = Long.parseLong(quantitystring); + quantity = abs(quantity); + + Resource resource = getResourceManager().getResource(resourcename); + if (resource != null) { + + if (!generate && quantity > resource.get(e.getMember())) { + op.sendErrorMessage(e,":x: You do not have enough " + resource.getName() + "!"); + } else { + if (!generate) { + resource.increment(e.getMember(), -quantity); + } + resource.increment(member, quantity); + op.sendSuccessMessage(e, ":white_check_mark: You gave " + member.getAsMention() + " " + resource.prettyValue(quantity)); + } + } else { + op.sendErrorMessage(e, ":x: Please provide a valid resource!" + usage); + + } + + } catch (NumberFormatException ex) { + op.sendErrorMessage(e,":x: Please provide a valid quantity!" + usage); + + } + + } else { + op.sendErrorMessage(e, ":x: That user was not found!" + usage); + } + } else { + op.sendErrorMessage(e, ":x: Invalid usage!" + usage); + + } + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/LeaderBoardCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/LeaderBoardCommand.java new file mode 100644 index 0000000..a001577 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/LeaderBoardCommand.java @@ -0,0 +1,50 @@ +package net.uomc.mineshaft.resources.commands; + +import static java.util.stream.Collectors.toMap; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.stream.Collectors; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.ResourceManager; + +public class LeaderBoardCommand extends ResourceCommand { + + public LeaderBoardCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails( + CommandDetails.from("leaderboard,lb,top,best", "Lists the most valuable users", "top [@user]")); + + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + AtomicInteger n = new AtomicInteger(0); + op.sendMessage( + e, "Most Valuable Players", "*ranked by inventory value*\n\n" + String.join( + "\n", getResourceManager().getPrimaryResource().getMembers(e.getGuild()).stream().collect( + toMap( + Function.identity(), + user -> getResourceManager() + .getResources() + .stream() + .map(r -> r.getValue(user, e.getGuild().getId()) * r.getValue()) + .reduce((long) 0, (a, b) -> a + b))) + .entrySet().stream() + .sorted( + (o1, o2) -> Long.compare(o2.getValue(), o1.getValue())) + .limit(10) + .map( + entry -> String.format( + "%d <@%s> (**%s**)", + n.incrementAndGet(), + entry.getKey(), + PeelingUtils.amountToString(entry.getValue()))) + .collect(Collectors.toList()))); + } +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/ListResourcesCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/ListResourcesCommand.java new file mode 100644 index 0000000..cb6c33a --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/ListResourcesCommand.java @@ -0,0 +1,31 @@ +package net.uomc.mineshaft.resources.commands; + +import java.util.List; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class ListResourcesCommand extends ResourceCommand { + + public ListResourcesCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.hidden("listItems")); + + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + List<Resource> resources = getResourceManager().listResources(); + StringBuilder stringBuilder = new StringBuilder(); + resources.forEach(r -> { + stringBuilder.append(r.getSymbol() + " " + r.getName() + "\n"); + }); + + op.sendMessage(e, "Available Items", stringBuilder.toString()); + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/MyResourcesCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/MyResourcesCommand.java new file mode 100644 index 0000000..b172a1e --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/MyResourcesCommand.java @@ -0,0 +1,53 @@ +package net.uomc.mineshaft.resources.commands; + +import java.util.List; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class MyResourcesCommand extends ResourceCommand { + + public MyResourcesCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.from("items,inventory,inv,i", "Lists your current inventory of items", "inventory [@user]")); + + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + List<Resource> resources = getResourceManager().listResources(); + + Member member = PeelingUtils.getSingleMentionFromArgs(e); + boolean your = member.equals(e.getMember()); + StringBuilder stringBuilder = new StringBuilder(); + resources.stream().sorted((r1, r2) -> (int)(r1.get(member) - r2.get(member))).forEach(r -> { + long l = r.get(member); + if (l != 0) { + String v = r.prettyValue(l); + stringBuilder.append("**" + v + "** " + r.getName()); + stringBuilder.append("\n"); + } + }); + String name = (your ? "Your" : member.getEffectiveName() + "'s"); + if (stringBuilder.length() == 0) + stringBuilder.append(name + "inventory is empty"); + + op.sendMessage(e, name + " Inventory", stringBuilder.toString() + "\n*Total value: " + PeelingUtils.amountToString(calculateInventoryValue(member)) + "*"); + } + + public long calculateInventoryValue(Member member) { + return getResourceManager() + .getResources() + .stream() + .map(r -> r.get(member) * r.getValue()) + .reduce((long) 0, (a, b) -> a + b); + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/RemoveResourceCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/RemoveResourceCommand.java new file mode 100644 index 0000000..2fadf27 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/RemoveResourceCommand.java @@ -0,0 +1,46 @@ +package net.uomc.mineshaft.resources.commands; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.Command; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.ResourceManager; + +public class RemoveResourceCommand extends ResourceCommand implements Command { + + public RemoveResourceCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.hidden("removeItem")); + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + String ownerid = op.getConfig().getString("ownerid"); + if (ownerid.equals(e.getAuthor().getId())) { + if (args.length > 0) { + String name = args[0]; + PeelingUtils.askQuestion(e, "Are you sure you want to delete **" + name + "**?\n(warning: all userdata will be lost)\nSend `confirm` to proceed", r -> { + if (r.equalsIgnoreCase("confirm")) { + boolean removeResource = getResourceManager().removeResource(name); + if (removeResource) { + op.sendMessage(e, "removed", "removed the item **" + name + "** from the list of items"); + + } else { + op.sendMessage(e, "not found", ":x: the item **" + name + "** was not found"); + } + } else { + op.sendMessage(e, "cancelled", ":x: operation cancelled"); + + } + }); + } else { + op.sendMessage(e, "incorrect usage", ":x: usage: `.removeResource [name]`"); + } + } else { + op.sendMessage(e, "missing permissions", ":x: this command is not intended for you"); + } + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/ResourceCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/ResourceCommand.java new file mode 100644 index 0000000..9d99e0e --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/ResourceCommand.java @@ -0,0 +1,17 @@ +package net.uomc.mineshaft.resources.commands; + +import com.mouldycheerio.dbot.commands.DetailedCommand; + +import net.uomc.mineshaft.resources.ResourceManager; + +public abstract class ResourceCommand extends DetailedCommand { + private ResourceManager resourceManager; + + public ResourceCommand(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + + public ResourceManager getResourceManager() { + return resourceManager; + } +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/SetPrimaryResourceCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/SetPrimaryResourceCommand.java new file mode 100644 index 0000000..6515d06 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/SetPrimaryResourceCommand.java @@ -0,0 +1,47 @@ +package net.uomc.mineshaft.resources.commands; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class SetPrimaryResourceCommand extends ResourceCommand { + + public SetPrimaryResourceCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.hidden("setPrimaryItem")); + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + String ownerid = op.getConfig().getString("ownerid"); + if (ownerid.equals(e.getAuthor().getId())) { + if (args.length > 0) { + Resource resource = getResourceManager().getResource(args[0]); + if (resource != null) { + PeelingUtils.askQuestion(e, "This will reset all users balance for this item, type `confirm` to continue", r -> { + if (r.equals("confirm")) { + getResourceManager().setPrimaryResource(resource.getName()); + + e.getGuild().loadMembers().onSuccess(members -> { + members.forEach(m -> getResourceManager().getPrimaryResource().set(m, 0)); + }); + + op.sendMessage(e, "primary item", "Set **" + resource.getName() + "** to the primary item"); + } + }); + } else { + op.sendErrorMessage(e, "This item was not found"); + } + } else { + op.sendMessage(e, "primary resource", "This will be the default item that will be used for trading\nUsage: `.setPrimaryResource [item name]`"); + } + } else { + op.sendErrorMessage(e, ":x: this command is not intended for you"); + } + } + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java b/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java new file mode 100644 index 0000000..c094d83 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/commands/ValuesCommand.java @@ -0,0 +1,45 @@ +package net.uomc.mineshaft.resources.commands; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.commands.CommandFail; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class ValuesCommand extends ResourceCommand { + + public ValuesCommand(ResourceManager resourceManager) { + super(resourceManager); + setCommandDetails(CommandDetails.from("marketValue,values,prices", "Show estimated market values of all the items")); + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot b, String[] args) throws CommandFail { + long total = getResourceManager().getPrimaryResource().total(); + + List<Resource> resources = new ArrayList<Resource>(getResourceManager().getResources()); + Collections.sort(resources, (r1, r2) -> Long.compare(r2.getValue(),r1.getValue())); + + StringBuilder stringBuilder = new StringBuilder(); + resources.forEach((r) -> { + long v = r.getValue(); + stringBuilder.append("**1** " + r.getName() + r.getSymbol() + " : "); + if (v < 0) { + stringBuilder.append("**???**"); + } else { + stringBuilder.append("**" + getResourceManager().getPrimaryResource().prettyValue(v) + "**"); + } + stringBuilder.append("\n"); + }); + + b.sendMessage(e, "Estimated Market Values", stringBuilder.toString()); + } + + +} diff --git a/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java b/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java new file mode 100644 index 0000000..47b0536 --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/market/MarketCommand.java @@ -0,0 +1,159 @@ +package net.uomc.mineshaft.resources.market; + +import java.util.List; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.commands.CommandDetails; +import com.mouldycheerio.dbot.commands.DetailedCommand; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; +import net.uomc.mineshaft.resources.market.Offer; + +public class MarketCommand extends DetailedCommand { + private ResourceManager resourceManager; + private MarketManager marketManager; + + public MarketCommand(MarketManager marketManager) { + this.marketManager = marketManager; + this.resourceManager = marketManager.getResourceManager(); + setCommandDetails(CommandDetails.from("market,m", "Buy and sell items at a given quantity on the market", "market sell [items] for [price]")); + + } + + @Override + public void execute(MessageReceivedEvent e, CustomBot op, String[] args) { + + marketManager.processOffers(); + if (args.length == 0) { + // TODO allow multipages with <-, -> + + EmbedBuilder embedBuilder = new EmbedBuilder(); + embedBuilder.setTitle("Market"); + embedBuilder.setColor(op.color); + if (marketManager.getEmbedFields().size() == 0) { + embedBuilder.setDescription("**:x: There are no available offers!**\n" + "Create one with `market sell`"); + e.getMessage().replyEmbeds(embedBuilder.build()).queue(); + } else { + embedBuilder.setDescription("Use `" + op.getPrefixManager().getPrefix(e.getGuild()) + "market buy [id]` to accept an offer"); + PeelingUtils.pagesEmbed(e.getAuthor(), e.getChannel(), embedBuilder, marketManager.getEmbedFields()); + } + + } else if (args.length > 0) { + if (args[0].equals("buy")) { + if (args.length > 1) { + buy(e, op, args); + } else { + op.sendErrorMessage(e,":x: please specify an id!"); + } + } else if (args[0].equals("sell")) { + sell(e, op, args); + } + } + } + + private void sell(MessageReceivedEvent e, CustomBot op, String[] args) { + if (args.length > 5) { + + try { + long sellQ = Math.abs(Long.parseLong(args[1])); + long buyQ = Math.abs(Long.parseLong(args[4])); + String sellRname = args[2]; + Resource sellR = resourceManager.getResource(sellRname); + String buyRname = args[5]; + Resource buyR = resourceManager.getResource(buyRname); + if (sellR != null || buyR != null) { + if (sellR.get(e.getMember()) >= sellQ) { + Offer offer = new Offer(); + + offer.setUserID(e.getAuthor().getId()); + offer.setBuyingQuantity(buyQ); + offer.setBuyingResource(buyR); + offer.setID(Offer.highest + 1); + offer.setSellingQuantity(sellQ); + offer.setSellingResource(sellR); + + marketManager.addOffer(offer); + op.sendSuccessMessage(e, ":white_check_mark: successfully listed **" + offer.getAsString(resourceManager) + "** offer id: `" + offer.getID() + "`"); + } else { + op.sendErrorMessage(e, ":x: You don't have enough " + sellR + " to offer"); + } + } else { + sendSellUsage(e, op); + } + } catch (NumberFormatException ex) { + sendSellUsage(e, op); + } + } else { + sendSellUsage(e, op); + } + } + + private void sendSellUsage(MessageReceivedEvent e, CustomBot op) { + List<Resource> listResources = resourceManager.listResources(); + Resource resource1 = listResources.get(listResources.size() - 1); + Resource resource2 = listResources.get(0); + + int q1 = (int) (Math.random() * 10); + int q2 = (int) (Math.random() * 10); + op.sendMessage( + e, "incorrect usage", + ":x: usage: `market sell [items] for [price]`\ni.e: `market sell " + q1 + " " + resource1.getName() + " for " + q2 + " " + resource2.getName() + "`" + ); + } + + private void buy(MessageReceivedEvent e, CustomBot op, String[] args) { + String id = args[1]; + Offer offer = marketManager.getOffer(id); + if (offer != null) { + offer.getMember(e.getGuild(), seller -> { + if (seller.equals(e.getAuthor())) { + op.sendErrorMessage(e, ":x: you cannot accept your own offer"); + } else { + long buyingQuantity = offer.getBuyingQuantity(); + Resource buyingResource = offer.getBuyingResource(resourceManager); + if (buyingResource.get(e.getMember()) >= buyingQuantity) { + + long sellingQuantity = offer.getSellingQuantity(); + Resource sellingResource = offer.getSellingResource(resourceManager); + + buyingResource.increment(e.getMember(), -buyingQuantity); + sellingResource.increment(e.getMember(), sellingQuantity); + + if (seller != null) { + buyingResource.increment(seller, buyingQuantity); + sellingResource.increment(seller, -sellingQuantity); + } + seller.getUser().openPrivateChannel().queue(pc -> { + pc.sendMessage( + "**" + e.getAuthor().getAsTag() + "** has accepted your market offer: **" + offer.getAsString(resourceManager) + "** [" + offer.getID() + "]" + ) + .queue(); + }); + + String from = ""; + if (seller != null) { + from = " from " + seller.getAsMention(); + } + + marketManager.removeOffer(offer); + op.sendSuccessMessage( + e, ":white_check_mark: successfully bought **" + sellingResource.prettyValue(sellingQuantity) + "** for **" + + buyingResource.prettyValue(buyingQuantity) + "**" + from + ); + + } else { + long have = buyingResource.get(e.getMember()); + long more = buyingQuantity - have; + op.sendErrorMessage(e, ":x: you need **" + buyingResource.prettyValue(more) + "** more to buy this"); + } + } + }); + } else { + op.sendErrorMessage(e, ":x: please specify a valid id!"); + } + } +} diff --git a/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java b/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java new file mode 100644 index 0000000..05517aa --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/market/MarketManager.java @@ -0,0 +1,128 @@ +package net.uomc.mineshaft.resources.market; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import org.json.JSONObject; + +import com.mouldycheerio.dbot.CustomBot; +import com.mouldycheerio.dbot.util.PeelingUtils; + +import net.dv8tion.jda.api.entities.MessageEmbed.Field; +import net.dv8tion.jda.api.entities.User; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; +import net.uomc.mineshaft.resources.market.Offer; + +public class MarketManager { + private ResourceManager resourceManager; + + private List<Offer> offers = new ArrayList<Offer>(); + + private File dataFile; + + private CustomBot bot; + + public MarketManager(net.uomc.mineshaft.resources.ResourceManager resourceManager) { + this.resourceManager = resourceManager; + bot = resourceManager.getBot(); + + dataFile = new File(resourceManager.getBot().getDatadir(), "market.json"); + + load(); + } + + public void load() { + JSONObject loadJSON = PeelingUtils.loadJSON(dataFile); + if (loadJSON.has("offers")) { + loadJSON.getJSONArray("offers").forEach(o -> { + if (o instanceof JSONObject) { + Offer offer = new Offer((JSONObject) o); + offers.add(offer); + } + }); + } + } + + public void save() { + JSONObject jsonObject = new JSONObject(); + for (Offer offer : offers) { + jsonObject.append("offers", offer); + } + + PeelingUtils.saveJSON(dataFile, jsonObject); + } + + public Offer getOffer(String id) { + for (Offer offer : offers) { + if (id.equals(offer.getID() + "")) { + return offer; + } + } + return null; + } + + public void addOffer(Offer offer) { + offers.add(offer); + processOffers(); + } + + public void processOffers() { + // TODO uhhh we should bring this back + //Iterator<Offer> iterator = offers.iterator(); + //while (iterator.hasNext()) { + // Offer offer = iterator.next(); + + // bot.getClient().retrieveUserById(offer.getUserID()).queue(seller -> { + // long quantity = offer.getSellingQuantity(); + // Resource resource = offer.getSellingResource(resourceManager); + // long l = resource.get(seller); + // if (l < quantity) { + + // sendNoLongerValidMessage(offer, seller); + // iterator.remove(); + // } + // }); + //} + + //save(); + } + + private void sendNoLongerValidMessage(Offer offer, User seller) { + seller.openPrivateChannel().queue(pc -> { + pc.sendMessage("Your market offer: **" + offer.getAsString(resourceManager) + "** [" + offer.getID() + "] is no longer valid because you no longer have enough resources to complete it.").queue(); + }); + } + + public void removeOffer(Offer o) { + offers.remove(o); + save(); + } + + public List<Offer> listOffers() { + return Collections.unmodifiableList(offers); + } + + public List<Field> getEmbedFields() { + return listOffers().stream().map( + o -> new Field( + "[" + o.getID() + "] " + + o.getAsString(resourceManager), + "<@" + o.getUserID() + ">", false + ) + ) + .collect(Collectors.toList()); + } + + public ResourceManager getResourceManager() { + return resourceManager; + } + + public void setResourceManager(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } +} diff --git a/src/main/java/net/uomc/mineshaft/resources/market/Offer.java b/src/main/java/net/uomc/mineshaft/resources/market/Offer.java new file mode 100644 index 0000000..9e01acd --- /dev/null +++ b/src/main/java/net/uomc/mineshaft/resources/market/Offer.java @@ -0,0 +1,104 @@ +package net.uomc.mineshaft.resources.market; + +import java.util.function.Consumer; + +import org.json.JSONObject; + + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.uomc.mineshaft.resources.Resource; +import net.uomc.mineshaft.resources.ResourceManager; + +public class Offer extends JSONObject { + private static final String ID = "id"; + private static final String BUYING_QUANTITY = "buying_quantity"; + private static final String SELLING_QUANTITY = "selling_quantity"; + private static final String BUYING_RESOURCE = "buying_resource"; + private static final String SELLING_RESOURCE = "selling_resource"; + private static final String USERID = "userid"; + + public static int highest = 0; + + public Offer() { + super(); + } + + public Offer(JSONObject jsonObject) { + super(); + jsonObject.keySet().forEach(k -> put(k, jsonObject.get(k))); + + if (has(ID)) { + if (getID() >= highest) { + highest = getID(); + } + } + } + + public int getID() { + return getInt(ID); + } + + public void setID(int id) { + put(ID, id); + if (getID() >= highest) { + highest = getID(); + } + } + + public String getUserID() { + return getString(USERID); + } + + public void getMember(Guild guild, Consumer<Member> c) { + c.accept(guild.getMemberById(getUserID())); + } + + public Member getMember(Guild guild) { + return guild.getMemberById(getUserID()); + } + + public void setUserID(String userid) { + put(USERID, userid); + } + + public Resource getSellingResource(ResourceManager resourceManager) { + String string = getString(SELLING_RESOURCE); + return resourceManager.getResource(string); + } + + public void setSellingResource(Resource resource) { + put(SELLING_RESOURCE, resource.getName()); + } + + public Resource getBuyingResource(ResourceManager resourceManager) { + String string = getString(BUYING_RESOURCE); + return resourceManager.getResource(string); + } + + public void setBuyingResource(Resource resource) { + put(BUYING_RESOURCE, resource.getName()); + } + + public long getSellingQuantity() { + return getLong(SELLING_QUANTITY); + } + + public void setSellingQuantity(long q) { + put(SELLING_QUANTITY, q); + } + + public long getBuyingQuantity() { + return getLong(BUYING_QUANTITY); + } + + public void setBuyingQuantity(long q) { + put(BUYING_QUANTITY, q); + } + + public String getAsString(ResourceManager resourceManager) { + return getSellingResource(resourceManager).prettyValue(getSellingQuantity()) + " for " + getBuyingResource(resourceManager).prettyValue(getBuyingQuantity()); + } +} |
