I'm trying to create a plugin for minecraft bukkit servers. The goal is to read the string on the first line of an html page. If the result is True it will execute a command.
Here is the code I have right now:
import java.net.URLConnection;
import java.util.Scanner;
import java.util.logging.Logger;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class main extends JavaPlugin{
public final Logger logger = Logger.getLogger("Minecraft");
public void onEnable(){
logger.info("[First] Has Been Enabled.");
}
public void onDisable(){
logger.info("[First] Has Been Disabled.");
}
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
Player player = (Player) sender;
if(commandLabel.equalsIgnoreCase("hello")){
player.sendMessage(ChatColor.GOLD + "Hello");
}
else if(commandLabel.equalsIgnoreCase("world")){
player.sendMessage(ChatColor.GOLD + "World");
}
else if(commandLabel.equalsIgnoreCase("coolman")){
player.setPlayerListName("coolman");
}
else if(commandLabel.equalsIgnoreCase("vote")){
String sourceLine = null;
// The URL address of the page to open.
URL address = new URL("http://www.koolflashgames.com/test.php");
// Open the address and create a BufferedReader with the source code.
InputStreamReader pageInput = new InputStreamReader(address.openStream());
BufferedReader source = new BufferedReader(pageInput);
// Append each new HTML line into one string. Add a tab character.
try {
sourceLine = source.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(sourceLine == "False"){
player.sendMessage("Thanks for voting!");
}
}
return false;
}
}
Creates the following error in the log:
2012-11-02 16:18:30 [SEVERE] null
org.bukkit.command.CommandException: Unhandled exception executing command 'vote' in plugin first v1.0
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46)
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:180)
at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:502)
at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.java:915)
at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:828)
at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:810)
at net.minecraft.server.Packet3Chat.handle(Packet3Chat.java:44)
at net.minecraft.server.NetworkManager.b(NetworkManager.java:282)
at net.minecraft.server.NetServerHandler.d(NetServerHandler.java:111)
at net.minecraft.server.ServerConnection.b(SourceFile:35)
at net.minecraft.server.DedicatedServerConnection.b(SourceFile:30)
at net.minecraft.server.MinecraftServer.q(MinecraftServer.java:561)
at net.minecraft.server.DedicatedServer.q(DedicatedServer.java:213)
at net.minecraft.server.MinecraftServer.p(MinecraftServer.java:474)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:406)
at net.minecraft.server.ThreadServerApplication.run(SourceFile:539)
Caused by: java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at me.storminmormon30.first.main.onCommand(main.java:43)
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
... 15 more
Looks like the error is somewhere else:
Unhandled exception executing command 'vote'
I don't see that command in the code snippet you have given
You should split each command into it's own class and register in in the plugin.yml, What I would do, is in the onEnable() method, set something like this:
getCommand("command").setExecutor(new CommandExecutor());
That will split off all of the commands into their own class, which would work better, and I would suggest it.
The issue with your code looks like a NPE in your class main on line 43 (its in your onEnable() method)
Related
I am trying to register a bukkit Command on the other Command.
So I want to make "/command1" to register "/command2" so command 2 only can execute after I executed command 1.
I tried for like 10 hours by now to do that, at the moment I am able to register a command without making it into the plugin.yml and that works, just the second command does not get registered.
Main class:
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.plugin.SimplePluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.Field;
public class Main extends JavaPlugin {
#Getter
CommandMap commandMap;
#Override
public void onEnable() {
loadCommandMap();
this.commandMap.register("command1", new FirstCommand(this));
}
private void loadCommandMap() {
try {
if (Bukkit.getPluginManager() instanceof SimplePluginManager) {
Field f = SimplePluginManager.class.getDeclaredField("commandMap");
f.setAccessible(true);
this.commandMap = (CommandMap) f.get(Bukkit.getPluginManager());
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
FirstCommand:
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class FirstCommand extends Command {
private Main plugin;
public FirstCommand(Main plugin) {
super("command1");
this.plugin = plugin;
}
#Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
plugin.getCommandMap().register("command2", new SecondCommand());
sender.sendMessage("Command 1.");
return true;
}
}
Second Command:
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class SecondCommand extends Command {
public SecondCommand() {
super("command2");
}
#Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
sender.sendMessage("Command 2");
return true;
}
}
I really hope someone knows why the first command gets registered but the second one does not.
You could try to not register them at runtime, but enable them at runtime.
You can use global, static variables (for example in the main class of your app), e.g.
// in your class "Main"
public static boolean isCommand2Enabled = false;
and when command1 is called, you set it to true
Main.isCommand2Enabled = true;
Your command2 must now only check whether it has already been activated and can be executed:
if(!Main.isCommand2Enabled) {
// I am not activated yet and must return
return false;
}
But I am not quite sure if you might try to define the name of command2 first when command1 is executed (variable command name). You should then maybe use a fixed command and only make the corresponding argument variable.
I don't really understand what you are talking about, but I think this may help you...
Bukkit Tutorial - Registering Commands At Runtime
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I've a bug on my Spigot Plugin, a null pointer is return when i try to do /samrandom true/false. This is my code :
Main class:
package com.vandendaelen.simpleautomessage;
import java.io.File;
import java.util.List;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import com.vandendaelen.simpleautomessage.Commands.CommandSamRandom;
import com.vandendaelen.simpleautomessage.Commands.CommandSamTime;
public class SimpleAutoMessage extends JavaPlugin {
public static final String RANDOM_CONFIG ="Random enabled";
private int iMessages = 0;
#Override
public void onDisable() {
// TODO Auto-generated method stub
super.onDisable();
}
#Override
public void onEnable() {
System.out.println("Waw, an amazing plugin powered by LotuxPunk ! :-)");
this.getCommand("samtime").setExecutor(new CommandSamTime(this));
this.getCommand("samrandom").setExecutor(new CommandSamRandom(this, RANDOM_CONFIG));
createConfig();
this.getConfig().addDefault(RANDOM_CONFIG, false);
this.getConfig().options().copyDefaults(true);
saveConfig();
//Enable display of messages
if(getConfig().getBoolean("Enable")) {
if(getConfig().getBoolean(RANDOM_CONFIG)) {
messageRandomDisplayer();
} else {
messageDisplayer();
}
}
}
private void createConfig() {
try {
if (!getDataFolder().exists()) {
getDataFolder().mkdirs();
}
File file = new File(getDataFolder(), "config.yml");
if (!file.exists()) {
getLogger().info("Config.yml not found, creating!");
saveDefaultConfig();
} else {
getLogger().info("Config.yml found, loading!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
...
}
Command class :
package com.vandendaelen.simpleautomessage.Commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
public class CommandSamRandom implements CommandExecutor {
private String RANDOM_CONFIG;
private Plugin plugin;
public CommandSamRandom(Plugin pl, String r) {
pl = plugin;
RANDOM_CONFIG = r;
//System.out.println(plugin.getConfig().getBoolean(RANDOM_CONFIG));
}
#Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player p = (Player)sender;
if(args[0]!="") {
Boolean randomEnabled = Boolean.parseBoolean(args[0]);
if(p.hasPermission("simpleautomessage.setrandom")||p.isOp()) {
plugin.getConfig().set(RANDOM_CONFIG, randomEnabled);
if(randomEnabled) {
p.sendMessage("§2Random enabled");
} else {
p.sendMessage("§4Random disabled");
}
plugin.saveConfig();
plugin.reloadConfig();
return true;
}
}
return false;
}
}
Config file :
#Time between 2 messages (minutes)
Time: 15
#Auto-Messages !
Enable: true
#Broadcast randomly your messages
Random enabled: false
Messages:
- "A simple string"
- "Another string"
- "Don't forget to support/rate LotuxPunk on Curse/Bukkit website !"
Result :
[20:56:05 INFO]: LotuxPunk issued server command: /samrandom true
[20:56:05 ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'samrandom' in plugin SimpleAutoMessage v0.5
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot.jar:git-Spigot-d21162c-61e0c69]
at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot.jar:git-Spigot-d21162c-61e0c69]
...
Caused by: java.lang.NullPointerException
at com.vandendaelen.simpleautomessage.Commands.CommandSamRandom.onCommand(CommandSamRandom.java:26) ~[?:?]
at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-d21162c-61e0c69]
... 15 more
Anyone can help me please ? :)
The line 26 is
plugin.getConfig().set(RANDOM_CONFIG, randomEnabled);
Your problem is in the Constructor:
private Plugin plugin;
public CommandSamRandom(Plugin pl, String r) {
pl = plugin;
}
You assign the value of your not yet initialized field pluginto the parameter pl insterad of the other way round.
It helps to explicitly use this.plugin when you try to access an instance field to make this more obvious.
I'm trying to create a java.util.List from an existing .txt file, when the list is created and filled with the java.util.String from the .txt file I would like to print it to the console to test if the List is filled. I have tried a lot but I always keep getting the same error.
The layout of the project is as following: Module (QaA), src(WriteTest.java and testfile.txt).
The testfile.txt contains the following:
Sentence one testing
Sentence two testing
Sentence three testing
Sentence four testing
the WriteTest Class:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
public class WriteTest {
public static void main(String[] args) throws IOException {
Path testPath = Paths.get("src/testfile.txt");
try {
List<String> lines = Files.readAllLines(testPath);
for (String line : lines) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The following errors are received:
java.nio.file.NoSuchFileException: src\testfile.txt
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)
at java.nio.file.Files.newInputStream(Files.java:152)
at java.nio.file.Files.newBufferedReader(Files.java:2784)
at java.nio.file.Files.readAllLines(Files.java:3202)
at java.nio.file.Files.readAllLines(Files.java:3242)
at WriteTest.main(WriteTest.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
I have found another reason why I had loads of errors. The location of my .txt file should not have been within the src. I tried moving it out, parallel to my module, and there it was detectable.
Your code had error on my workspace, I changed the readAllLines as you see below, and added toAbsolutePath for the path
public static void main(String[] args) throws IOException
{
Path testPath = Paths.get("src/testfile.txt").toAbsolutePath();
System.out.println("path:\t" + testPath);
try
{
Charset cs = Charset.defaultCharset();
List<String> lines = Files.readAllLines(testPath, cs);
for (String line : lines)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
Make the changes as below to get the given file path.
Path testPath = Paths.get(System.getProperty("user.dir")+"src/testfile.txt");
When I research things on the internet I like to copy and paste certain paragraphs so I could review them later on.
I'm trying to write a program that would continuously check the clipboard for text content and write it to a text file any time it is renewed.
In the following test of the program I had "public class Clipboard" in my clipboard before running the program and the exception happened when I copied text from netbeans (The IDE I was using to run the program) while the program was running:
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestClipboard {
public static void main(String[] args) {
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
String initial = "";
while(true) {
try {
String paste = c.getContents(null).getTransferData(DataFlavor.stringFlavor).toString();
if(!paste.equals(initial)) {
System.out.println(paste);
initial = paste;
}
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(TestClipboard.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The output:
public class TestClipboard
Exception in thread "main" java.lang.IllegalStateException: cannot open system clipboard
at sun.awt.windows.WClipboard.openClipboard(Native Method)
at sun.awt.datatransfer.ClipboardTransferable.<init>(ClipboardTransferable.java:78)
at sun.awt.datatransfer.SunClipboard.getContents(SunClipboard.java:144)
at delete.TestClipboard.main(TestClipboard.java:21)
Java Result: 1
BUILD SUCCESSFUL (total time: 34 seconds)
Why can't it open the system clipboard?
Does the getSystemClipboard() method not have global scope? - In other words, can I not get the clipboard's contents if the copy operation was performed in an internet browser?
You appear to be trying to read from the clipboard while another process is updating to it (or some such).
I fixed by:
Requesting an instance of the Clipboard within the loop
Adding a Thread.sleep into the while-loop
For example...
public class TestClipboard {
public static void main(String[] args) {
String initial = "";
while (true) {
try {
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
String paste = c.getContents(null).getTransferData(DataFlavor.stringFlavor).toString();
if (!paste.equals(initial)) {
System.out.println(paste);
initial = paste;
}
} catch (UnsupportedFlavorException | IOException ex) {
Logger.getLogger(TestClipboard.class.getName()).log(Level.SEVERE, null, ex);
}
try {
Thread.sleep(40);
} catch (InterruptedException ex) {
}
}
}
}
It should be noted that it won't stop it from happening, it will only reduce the number of occurrences. When it is thrown, you could (just about) ignore and try again...
I tried to execute a small hive query from Java, but it is failing with below error, bur when I copy the same query and run on terminal it is giving me the result.
Can someone help me on this.
Java Code:
Runtime.getRuntime().exec("hive -e 'show databases;'");
Error thrown:
FAILED: ParseException line 1:5 cannot recognize input near '<EOF>' '<EOF>' '<EOF>' in ddl statement
Regards,
GHK.
I have been working with this Java problem for a while, and I believe I have solved this problem. Basically the reason you are failing is because the environment variables are not ser up properly. put the following in your /home/<username>/.bash_profile file and restart your machine to fix this.
HIVE_HOME=/usr/lib/hive
export HIVE_HOME
PATH=$PATH:$HIVE_HOME/bin/hive
export PATH
This will ensure that they get set up properly.
However while this will get rid of the error it still won't show you a list of databases because the process that runs the hive command will run in the background, not on the console the main program is running from. The following code will let you redirect the outputs of the program to the console that the main program is running from.
package testing.console;
import java.io.IOException;
import java.lang.ProcessBuilder;
import java.util.Map;
import testing.console.OutputRedirector;
//This Works
public class ConsoleTester {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
ProcessBuilder hiveProcessBuilder = new ProcessBuilder("hive", "-e",
"show databases");
String path = processEnv.get("PATH");
Process hiveProcess = hiveProcessBuilder.start();
OutputRedirector outRedirect = new OutputRedirector(
hiveProcess.getInputStream(), "HIVE_OUTPUT");
OutputRedirector outToConsole = new OutputRedirector(
hiveProcess.getErrorStream(), "HIVE_LOG");
outRedirect.start();
outToConsole.start();
}
}
And the OutputRedirector class used to get the output to console.
package testing.console;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class OutputRedirector extends Thread {
InputStream is;
String type;
public OutputRedirector(InputStream is, String type){
this.is = is;
this.type = type;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + "> " + line);
}
} catch (IOException ioE) {
}
}
}