problem regarding my discord bot coded through jda - java

My bot is stuck printing the output. I check and there was no problem with the logical part as I used the sane logic to make a normal java program. Please help as it is stuck printing the output in discord and I do not know how to solve it.
I also added some unnecessary print functions to find out where the error was. To my surprise, it was just in printing the message which is unusual as I have made bots before and none of them had any errors to just "print" messages.
import javax.security.auth.login.LoginException;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
public class rpsidnfp {
public static JDA jda;
public static void main(String args[]) throws LoginException {
jda = JDABuilder.createDefault("(my token here)").build();
core2 core2obj = new core2();
jda.addEventListener(core2obj);
}
}
The former was my main class.
And below is the core class as it contains all the functions.
package pack.rpsidnfp;
import java.util.Random;
//import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public class core2 extends ListenerAdapter {
public static String prefix = "!";
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
String input = event.getMessage().getContentRaw();
String[] options = {"rock", "paper", "scissors"};
Random robj = new Random();
int rnum = robj.nextInt(options.length);
System.out.println(rnum);
String conf = options[rnum];
event.getChannel().sendMessage(conf);
System.out.println(conf);
String same = prefix + conf;
String win = "congrats, you won!";
String lose = "lmao, you lost";
if(input.equals(same)) {
event.getChannel().sendMessage("we both kept the same thing");
}
else if(input.equals(prefix + options[0])) {
if(conf.equals(options[1])) {
event.getChannel().sendMessage(lose);
}
else if(conf.equals(prefix + options[2])) {
event.getChannel().sendMessage(win);
}
}
else if(input.equals(prefix + options[1])) {
if(conf.equals(options[0])) {
event.getChannel().sendMessage(win);
}
else if(conf.equals(options[2])) {
event.getChannel().sendMessage(lose);
}
}
else if(input.equals(prefix + options[2])) {
if(conf.equals(options[0])) {
event.getChannel().sendMessage(lose);
}
else if(conf.equals(options[2])) {
event.getChannel().sendMessage(win);
}
}
}
}

The sendMessage method returns a MessageAction. You need to call queue() on that RestAction instance.
Additionally, keep in mind that your bot receives its own messages so you should make sure it ignores those. You can add a if (event.getAuthor().isBot()) return; to the start of your listener method.
See Also:
Troubleshooting Guide: Nothing happens when using X
RestAction Guide
MessageListenerExample
JDA README

Related

Comparing an array to a single string output using assertEquals in Java

So I would like to create a simple code that greets people according to the input.
The difficulity I have that I have no idea how to compare a simple string with an array, using arrayEquals (or any equivalent).
This is the way I have created the code - according to a previous project:
Test file:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class test {
#Test
public void ShouldGreet() {
assertEquals("Hello, my friend.", new GreetPeople().greeter(""));
assertEquals("Hello, Bob.", new GreetPeople().greeter("Bob"));
}
}
Actual code:
import java.util.Arrays;
public class GreetPeople {
public String greeter(String[] names) {
if (Arrays.stream(names).count() == 1) {
return("Hello, " + names + ".");
}
return("Hello, my friend.");
}
}
Any kind of help is well appreciated!
The first patameter of greeter is an array:
assertEquals("Hello, my friend.", new GreetPeople().greeter(new String[]{""}));
assertEquals("Hello, Bob.", new GreetPeople().greeter(new String[]{"Bob"}));

School Java Escape Room Program

I am writing an escape room project for school which has messages such as a greeting, a win message, a loss message, etc. I stored these messages in a text file and then I read the file and store each line into one ArrayList and to access each line by their respective getter method and I use the .get function with their index value. I'm wondering if there is a way to avoid hardcoding the index numbers and on top of that is there a way I can just read the file when the program is run instead of having to make an instance of the class and then for example doing foo.readFile();
import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.util.ArrayList;
//package Stage;
public class EscapeRoom{
ArrayList<String> Messages;
String fileName;
private boolean win = false;
public void readFile() throws FileNotFoundException {
Messages = new ArrayList<String>();
fileName = "test.txt";
File file = new File(fileName);
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()){
Messages.add(scanner.nextLine());
}
scanner.close();
}
public void showGreeting(){
System.out.println(Messages.get(0));
}
public void showDirections(){
System.out.println(Messages.get(1));
}
public void showWin() {
System.out.println(Messages.get(2));
}
public void showLoss() {
System.out.println(Messages.get(3));
}
}
This is exactly what a properties file is for. Here is a file I named prompts.properties:
greeting = "hello, welcome to my game"
win = "you win, yay"
loss = "sorry bro, you lose"
directions = "escape with your life!"
Here is your modified program:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class EscapeRoom {
Properties prompts = null;
public void readFile() throws IOException {
prompts = new Properties();
prompts.load(new FileInputStream("prompts.properties"));
}
public void showGreeting() {
System.out.println(prompts.get("greeting"));
}
public void showDirections() {
System.out.println(prompts.get("directions"));
}
public void showWin() {
System.out.println(prompts.get("win"));
}
public void showLoss() {
System.out.println(prompts.get("loss"));
}
}
Basically to get a named key-value pair you want something like a map. Properties are really a special sort of map that understands a file of records that have the format <key> = <value>.
Here is the documentation on Properties and if you decide to roll your own you would implement the same basic thing with a Map.

Java JFrame String Index Out of Bounds Error

I am making a calculator in Net-beans JFrame and using a Stack to help calculated the variables that are inputted. I seem to have run in to this error StringIndexOutOfBounds: 0 and i can't seem to figure out how to solve it when it happens. Whenever I press the equal button that initiates the Stack the error pops up. I think its something wrong with my Stack but again I can't figure it out. And I really need some fresh eyes on this.
I used/imported swings and .awts but I don't think they are giving me the error here are my swings.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import static java.lang.Math.round;
import java.util.NoSuchElementException;
import java.util.Scanner;
import javax.swing.JFileChooser;
Here is my Stack:
public class StackCalc
{
private LinkedList stackList = new LinkedList();
private int top, maxTop;
public Object removedEle;
public Object topEle;
public StackCalc(int mt)
{
maxTop=mt;
top=-1;
}
public boolean isFull()
{
return top == maxTop-1;
}
public boolean push (Object O)
{
if(!isFull())
{
stackList.addFirst(O);
top++;
return true;
}
else
{
return false;
}
}
public boolean pop()
{
if(!stackList.isEmpty())
{
removedEle= stackList.removeFirst();
top--;
return true;
}
else
{
return false;
}
}
public void getTop()
{
topEle=stackList.getFirst();
}
public boolean isEmpty()
{
return stackList.isEmpty();
}
}
Here is the code that I think is giving me this error
static void processExpR(String exp)
{
boolean advance = true;
String token = " ";
int loc = exp.indexOf(token);
while (loc != -1)
{
if (token.isEmpty()){
return;
}
else if (advance){
token = exp.substring(0,loc);
exp = exp.substring(loc+1);
}
char ch = token.charAt(0);//there is a specific problem with this line
if(Character.isDigit(ch)){
advance = true;
s1R.push(token);
}
else
{
if(s2R.isEmpty())
{
advance = true;
s2R.push(token);
}
else
{
advance = false;
calcR();
}
}
if(advance){
loc = exp.indexOf(" ");
}
}//end of while
if (Character.isDigit(exp.charAt(0)))
{
s1R.push(exp);
}
else
{
s2R.push(exp);
}
while (!s2R.isEmpty())
{
calcR();
}
}
Any help would be much appreciated. I'm like really lost here. Thank you.
The problem comes here:
token = exp.substring(0,loc);
The above line takes a substring from exp. A bit later you do:
char ch = token.charAt(0);//there is a specific problem with this line
And what happens is: the string that you cut from exp and store into token ... is empty. And therefore, when you try to access index 0 of that string you are told: that string doesn't even have an index 0 (and that can only happen if token is empty!).
Thus the answer here is two-fold:
Before doing calls like charAt(someIndex) you better check upfront if your string actually has that index
But in your case, checking alone wouldn't help.
You see, your problem is basically that your logic how you compute your "substring" index is probably wrong.
My suggestion: sit down, and process your input data manually. Meaning: use example input, and manually execute your program. To understand how your counters/index variables look like, to understand what your code is really doing with its input. If you find that too cumbersome, than at least learn using a debugger to do that (but doing it one, two times manually will still tell you more than 50 or 100 answers here on SO!)

JAVA/SPIGOT: How can I make a variable called from non static classes?

I'm very new with Java and was introduced to it by creating Minecraft plugins. I am currently using Spigot and want a variable to be accessed through another class. In this plugin, I want players to be able to create a Hero that has certain abilities. The two classes that I use are below.
package me.placerwiz;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class Moba extends JavaPlugin {
StompCooldown a;
#Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new MenuClick(this), this);
new PlayerListener(this);
new StompAbility(this);
getLogger().info("This plugin has been enabled!");
a = new StompCooldown(this);
a.runTaskTimer(this, 20, 20);
getCommand("pearl").setExecutor(new WarpAbility());
getCommand("menu").setExecutor(this);
}
#Override
public void onDisable() {
}
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("Menu") && sender instanceof Player) {
Player player = (Player) sender;
player.openInventory(Menu.getMenu());
return true;
}
return false;
}
public static void sircunningham1_1(String args[]) {
SirCunningham_1_1 getLoadout = new SirCunningham_1_1();
getLoadout.heroChosen();
}
public static void sircunningham2_1(String args[]) {
SirCunningham_2_1 getLoadout = new SirCunningham_2_1();
getLoadout.heroChosen();
}
public void gotHero(String heroChoice) {
if (heroChoice == "") {
}
}
public boolean heroTest(CommandSender sender, Command cmd, String label, String[] args) {
if (cmd.getName().equalsIgnoreCase("hero") && sender instanceof Player) {
Player player = (Player) sender;
player.openInventory(Menu.getMenu());
return true;
}
return false;
}}
The code above is my main class, Moba. In this code, a variable called heroChoice is received from the other class. The only problem from this is that I want the code to get what the player has selected as the hero. When it gets the hero, I want it to get the hero that the player has selected. Is there anyway I can get a variable sent to the Moba class after the player clicks on the final inventory item. It might need to use this class where the player selects the final ability for the hero "Sir Cunningham". (See code below)
package me.placerwiz;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class SirCunningham_2_1{
static String hero;
public static Inventory getMenu(){
Inventory inv = Bukkit.createInventory(null, 18, ChatColor.GREEN + ChatColor.BOLD.toString() + "Choose ultimate ability!");
ItemStack item = new ItemStack(Material.IRON_BOOTS);
ItemMeta meta = item.getItemMeta();
List<String> lore = new ArrayList<String>();
lore.add(" ");
lore.add(ChatColor.YELLOW + "Thoughts of glory inspire your team to");
lore.add(ChatColor.YELLOW + " win this battle! Everyone on your team");
lore.add(ChatColor.YELLOW + " gains a buff!");
meta.setLore(lore);
meta.setDisplayName(ChatColor.GOLD + ChatColor.BOLD.toString() + "Glory");
item.setItemMeta(meta);
inv.addItem(item);
return inv;
}
#EventHandler
public static void onClick(InventoryClickEvent event) {
if (!ChatColor.stripColor(event.getInventory().getName()).equalsIgnoreCase("Choose ultimate ability!"))
return;
Player player = (Player) event.getWhoClicked();
event.setCancelled(true);
if(event.getCurrentItem()==null || event.getCurrentItem().getType()==Material.AIR || !event.getCurrentItem().hasItemMeta()){
player.closeInventory();
return;
}
if(event.getCurrentItem().getType() == Material.IRON_BOOTS){
player.closeInventory();
String hero = "SirCunnigham_2_1";
player.openInventory(Customizer.getMenu());
}
else{
player.sendMessage(ChatColor.GREEN + "[" + ChatColor.YELLOW + "MOBA" + ChatColor.GREEN + "]" + ChatColor.GOLD + "-Under Construction-");
player.closeInventory();
}
}
public static void heroChosen(){
String heroChoice = hero;
Moba sendLoadout = new Moba();
sendLoadout.gotHero(heroChoice);
}
}
All I need to get this to work is to have the String hero (from the if event above) to equal the String heroChoice. Thanks for reading this far and I hope this will get solved. It means a lot to me!
Do not "hide" a variable! You have a static variable named "hero" of type String but you have created another one with the same type and the same name of the static one. So you want to get the name of the hero.
Declaring that variable static you make that variable equal to all of the instances of that class.
Keep reading if you want to know the real solution.
Note, using OOP (Object-Oriented Programming) is a more efficient way to do this.
From what I understood from the question, you want associate an hero name to a player.
You can simply do it with an HashMap.
public static HashMap<Player,String> playerHero = new HashMap<Player,String>();
or if you're using Java 8
public static HashMap<Player,String> playerHero = new HashMap<>();
To add a player AND a hero name do
MyClass.playerHero.put(player, heroName);
To get the heroName from the player:
MyClass.playerHero.get(player);
To get the players from the heroName:
You can make a method:
public static List<Player> getPlayers(String heroName){
List<Player> players = new ArrayList<Player>();
for(Map.Entry<Player,String> e : MyClass.playerHero.entrySet()){
if(e.getValue().equalsIgnoreCase(heroName)){
players.add(e.getKey());
}
}
return players;
}
All these variables are static, so we can access them with MyClass.variableName
All these methods are static, so we can access them with MyClass.method(parameters);
Hope this helped!
You could use the static modifier for heroChoice and all methods that work with your variable, but this is not best practice because in many cases you will not be able to use static and even for this case, you can't make the Bukkit API's EventHandlers static. So what do you do? Its simple.
Use OOP, pass instance of invoking object's variable through constructor
Every object can have constructors, the constructors contain code that will be run when an instance of that object is created. You can also pass paremters to a constructor just like you would a method. As a result, you can simply pass the variable you want from one class into the constructor of the other and store it. For example:
class Car { //my class Car
double topSpeedMPH; //when a Car is created, it needs to get a top speed
public Car(double topSpeedMPH) { //public constructor for Car, requires a double parameter
this.topSpeedMPH = topSpeedMPH; //set the class' topSpeedMPH variable to the local one
}
}
Then in the invoking code:
double speed = 10;
Car fordFusion = new Car(speed);
So for your code specifically:
class Moba {
String heroChoice; //Moba has heroChoice stored
public Moba(String choice) { //Moba constructor, requires a String (which is the choice)
this.heroChoice = choice; //stores the parameter String to use later
}
}
class SirCunningham_2_1 {
public void heroChosen(){
String heroChoice = hero;
Moba sendLoadout = new Moba(heroChoice);
sendLoadout.gotHero(heroChoice);
}
}
Another solution: Use OOP, pass instance of the entire invoking object through constructor using this keyword
The previous solution is great for just one variable, but what if I wanted to be able to access multiple variables from another object? It would be rather inconvenient to make each of them individual parameters. Luckily, there is a good way to do this. Simply pass the entire instance through. The following example (using Car again) shows it:
class Motor {
Car myCar;
double topSpeed;
double accel;
public Motor(Car c) { //require instance of car
this.myCar = c;
this.topSpeed = myCar.topSpeed; //get values from instance
this.accel = myCar.secondsTo60;
}
}
class Car {
Motor m;
double topSpeed = 108;
double secondsTo60 = 8;
int seats = 4;
public Car() {
m = new Motor(this); //use this keyword to pass entire instance
}
void startEngine() {
System.out.println("Vroom Vroom!");
}
}
A big advantage to this solution is that I could even use methods from the other class:
public Motor(Car c) { //require instance of car
this.myCar = c;
this.topSpeed = myCar.topSpeed; //get values from instance
this.accel = myCar.secondsTo60;
myCar.startEngine();
}

Event listener/ Scanner in Gridworld

I'm trying to control Bugs in GridWorld. I have tried two ways of doing this, neither of which have actually moved or turned the bug. They both compile but nothing happens.
Here is the Bug that will be controlled:
package info.gridworld.actor;
import info.gridworld.grid.*;
import info.gridworld.grid.Location;
import java.awt.Color;
public class MazeBug extends Bug {
public MazeBug() {
super(Color.blue);
}
public void forward(){
Grid<Actor> gr = getGrid();
if (gr == null)
return;
Location loc = getLocation();
Location next = loc.getAdjacentLocation(getDirection());
if (gr.isValid(next))
moveTo(next);
else
removeSelfFromGrid();
}
public void turnRight(){
setDirection(getDirection() + Location.RIGHT);
}
public void turnLeft(){
setDirection(getDirection() + Location.LEFT);
}
}
Here is the first way that I tried controlling the bugs with the keys W,A, and D using Scanner (not sure if I used scanner correctly)
package info.gridworld.actor;
import java.util.Scanner;
import info.gridworld.grid.*;
public class KeyTests extends Actor
{
public static ActorWorld world = new ActorWorld(new BoundedGrid<Actor>(20, 20));
public static MazeBug currentBug;
public static void main(String[] args) {
world.show();
world.add(new Location(1,11),new MazeBug());
while(true){
Scanner k = new Scanner(System.in);
String buttonpress = k.nextLine();
if (buttonpress.equals("w"))
currentBug.forward();
if (buttonpress.equals("d"))
currentBug.turnRight();
if (buttonpress.equals("a"))
currentBug.turnLeft();
}
}
}
Here is the 2nd way I tried to control the bug
package info.gridworld.actor;
import info.gridworld.grid.*;
public class KeyTests extends Actor
{
public static ActorWorld world = new ActorWorld(new BoundedGrid<Actor>(20, 20));
public static MazeBug currentBug;
public static void main(String[] args) {
world.add(new Location(1,11),new MazeBug());
java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new java.awt.KeyEventDispatcher() {
public boolean dispatchKeyEvent(java.awt.event.KeyEvent event) {
String key = javax.swing.KeyStroke.getKeyStrokeForEvent(event).toString();
if (key.equals("w"))
currentBug.forward();
if (key.equals("d"))
currentBug.turnRight();
if (key.equals("a"))
currentBug.turnLeft();
world.show();
return true;
}
});
world.show();
}
}
Thanks for any help in advanced
I am almost positive that your problem is that you put your controlling code in the Runner instead of your Bug's act method.
When GridWorld steps all it does is call each Actor's act method, so if your Actor has an unpopulated method it will just call the parent, or do nothing. Your runner, since it is not an 'Actor' has no act method, and after the first run is never looked at again.
Try this in your MazeBug:
public void act()
{
java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new java.awt.KeyEventDispatcher() {
public boolean dispatchKeyEvent(java.awt.event.KeyEvent event) {
String key = javax.swing.KeyStroke.getKeyStrokeForEvent(event).toString();
if (key.equals("w"))
forward();
if (key.equals("d"))
turnRight();
if (key.equals("a"))
turnLeft();
return true;
}
});
}
Note: I have never used EventListeners so can't help with that code.

Categories