I need execute command from Spigot in BungeeCord, but I don't know how to. I use a more function... for example Forward Channel, Message Channel, BungeeCord.getInstance().dispatchCommand, ProxyServer.getInstance().dispatchCommand. None of this options not work. By the way BungeeCord[..].dispatchCommand i ProxyServer send error in console. I use BungeeCord API in a first time. I was looking for more options, maybe I used a bad api.
You will have to use the Messaging Channels directly from Spigot and send information to BungeeCord with that.
Here is a little example on how you want to do this :
ByteArrayOutputStream b = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(b);
try {
out.writeUTF("Message");
out.writeUTF("ALL");
out.writeUTF("/alert Testing command distance");
} catch(Exception e) {
e.printStackTrace();
}
p.sendPluginMessage(getPlugin(), "BungeeCord", b.toByteArray());
You can of course change the information you want to send, here is the official wiki about messaging channels : https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/#message
PS: You have to register the Channel in your onEnable()
this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
The title basically says it all but just but to reiterate:
I need my Java program to kill itself (dispose w/e) if a specific external program launches.
My java program uses a global hook that listens for mouse input, when I remote into a clients computer the mouse listener/GUI that my program creates can cause all kinds of issues with the mouse if used I'm while connected. To handle this I need my program to automatically "turn off" when the screen-connect application we use launches.
I am already using a global hook to capture mouse input, is there something similar I could use for system events maybe?
Depending on the version of windows respectively Java you are using there are various libraries you could be using to simply regularly "scan" the operating system for a list of running processes.
If something shows up that you don't like, simply react using System.exit for example.
In your first program, just create a new Thread and let it run. Put this code in the run method:
try {
ServerSocket socket = new ServerSocket(1111); // the paramater is a port and you can choose any port you want
socket.accept();
socket.close();
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
This will wait for a connection and once the connection is made, it will close itself. That is because the accept method that waits for a connection blocks until there is a connection made. That's why you put it in another thread.
After it recieves the connection it will unblock so the code will continue and exit the program! And it MUST be in another friend so it doesn't block your application!
In the second application, in the beginning just make a connection!
To make a connection use this code:
try (Socket socket = new Socket("localhost" ,1111);){
socket.close();
} catch (IOException e) {
}
This will connect it and once it does, the first program will close. Now just continue on with this program! If you don't understand the sockets the best, then check out this link. It is awesomely explained:
https://www.javaworld.com/article/2077322/core-java/core-java-sockets-programming-in-java-a-tutorial.html
I am looking for a bit of efficient code that can assist me in monitoring if a com port is still open using the RX/TX libraries.
Lets say I have a hardware device that communicates to the PC using a virtual com port and that device can be plugged in and out at any time. I want to show a connection status on the pc.
I have tried this with something like a buffered reader below and it registered that the device gets disconnected but I have to re-open the port from scratch in another method.
I am looking from something short like comPort.isOpen () or something?
// Set the value of is running
Start.isRunning = true;
// Check to see if the device is connected
while (Start.isRunning) {
// Try to connect to the device
try {
// Create a Buffered Reader
BufferedReader reader = new BufferedReader(
new InputStreamReader(serialPort.getInputStream()));
// Read the output
if (Character.toString((char) reader.read()).equalsIgnoreCase(
"^")) {
// Set the connected flag
Start.CONNECTED_FLAG = true;
// Set the connected fag
AddComponents.TFconnected.setText("Connected");
}
// Close the reader
reader.close();
// Let the thread sleep
Thread.sleep(500);
}
// Catch a error if the device is disconnected
catch (Exception err) {
// Set the connected flag
Start.CONNECTED_FLAG = false;
// Set the connected fag
AddComponents.TFconnected.setText("Disconnected");
// Let the thread sleep
Thread.sleep(500);
}
}
Disclaimer: Consider this a partial answer because I do not have intimate knowledge of the workings of serial ports, and my tests could not produce anything useful. Posting here regardless in the hopes any of this is helpful.
Unfortunately, as far as I know, there is no way to receive any kind of "connection / disconnection" event messages. Sadly, as I am not intimately familiar with the workings of serial ports, I cannot give you a full and proper explanation. However, from some research, one of the answers posted in that forum had this to say:
There's no event by the system to inform you of [a disconnection event] because that would require exclusive use of the COM port. If you have a SerialPort object created and have opened a port you should get a CDChanged when a devices is plugged in and unplugged from the serial port. That assumes the device follows the pins standards; not all devices do.
Note that the poster, and the link I've provided, are discussing this within the context of C#. However this seems to be related to how the ports work in general, regardless of language, so I am somewhat confident the same can be applied to RXTX Java.
There are some events you can attempt to listen for. In my tests I was only ever able to receive the DATA_AVAILABLE event, however my setup is a bit different (Raspberry PI) and I can't at the moment physically disconnect the device from the port, I can only attempt to block the device file (which may explain the failure of my test).
If you would like to attempt the event listening yourself, have your class implement SerialPortListener, register for the desired events, check the events in your serialEvent method. Here is an example:
public class YourClass implements SerialPortListener{
private SerialPort serialPort;
// ... serial port gets set up at some point ...
public void registerEvents(){
serialPort.addEventListener(this);
// listen to all the events
serialPort.notifyOnBreakInterrupt(true);
serialPort.notifyOnCarrierDetect(true);
serialPort.notifyOnCTS(true);
serialPort.notifyOnDataAvailable(true);
serialPort.notifyOnDSR(true);
serialPort.notifyOnFramingError(true);
serialPort.notifyOnOutputEmpty(true);
serialPort.notifyOnOverrunError(true);
serialPort.notifyOnParityError(true);
serialPort.notifyOnRingIndicator(true);
}
#Override
public void serialEvent(SerialPortEvent event) {
System.out.println("Received event. Type: " + event.getEventType() + ", old value: " + event.getOldValue() + ", new value: " + event.getNewValue());
}
}
If that ultimately fails, I believe the only other alternative is similar to your current solution; attempt to read from the port, and if it fails, consider it disconnected, and set your indicator accordingly. At each iteration, if it is disconnected, attempt to reconnect; if reconnect succeeds, reset your indicator to "connected".
Sorry I cannot be of more assistance. Hopefully some of that may lead to something useful.
Side Note:
If you want to DRY up your code slightly, put the Thread.sleep(500) in a finally block instead, since it appears to be executed regardless.
I am currently trying to make a litlle handy tool, you see I am a network administrator and my boss told me that he wanted me to monitor the network and block certain sites and ip for some game servers, so for the monitoring part we are going to redirect all traffic on the network to a server where we can monitor the traffic before sending it to the gateway.
For this we are going to use arpspoof in linux and I have finished a solution for the blocking of sites and servers, and what I am going to make is a GUI that makes it easier for me to handle and control these things and when I tried running arpspoof from java using a ProcessBuilder it does not work and I get no output?
It also does not enter the while loop. I can't really think of more to write atm, but if I can think of more I will update this thread.
My code:
new Thread() {
public void run() {
try {
System.out.println("running arpspoof...");
Process prb = new ProcessBuilder("gksudo", "arpspoof", "-i", "wlan0", Gateway).start();
InputStream is = prb.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println("Output: " + line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
I have never used gksudo, but I googled it and it says it's a GUI version of sudo. I'm guessing that you just launched a GUI app which does not write anything to stdout and which does not return. If so, then the code is doing what I would expect. It is blocking until the process writes a line of text that it can read - which never occurs so it blocks indefinitely.
First test your ProcessBuilder code using a trivial command like "echo" to make sure your Java code is working as expected. Then work your way back. Try running your program as root so you don't need the sudo argument and see if that works. Then finally try to run it using sudo instead of gksudo.
I think #user is on the right track, but there are a couple of other possible explanations.
The gksudo command could be asking for a password. I'm not sure where it would ask, but there's a good chance that it won't be the "stdout" stream of the "gksudo" process.
If "gksudo" or the command that you are "gksudo"-ing fails to launch, there is a good chance that it will write an error message to its "stderr" stream. But you are not reading "stderr".
To help diagnose this, you need to try the following:
Look in the log file that for "sudo" - it is "/var/log/secure" on my box.
Use "ps -efl" (or similar) to see what processes exist while your application is blocked waiting for output. (If that is happening ...)
Look to see if "gksudo" is prompting for a password in an unexpected place.
Try temporarily tweaking the "sudoers" file to allow the "arpspoof" command to be "sudo"-ed without a password.
I've been using RXTX for about a year now, without too many problems. I just started a new program to interact with a new piece of hardware, so I reused the connect() method I've used on my other projects, but I have a weird problem I've never seen before.
The Problem
The device works fine, because when I connect with HyperTerminal, I send things and receive what I expect, and Serial Port Monitor(SPM) reflects this.
However, when I run the simple HyperTerminal-clone I wrote to diagnose the problem I'm having with my main app, bytes are sent, according to SPM, but nothing is received, and my SerialPortEventListener never fires. Even when I check for available data in the main loop, reader.ready() returns false. If I ignore this check, then I get an exception, details below.
Relevant section of connect() method
// Configure and open port
port = (SerialPort) CommPortIdentifier.getPortIdentifier(name)
.open(owner,1000)
port.setSerialPortParams(baud, databits, stopbits, parity);
port.setFlowControlMode(fc_mode);
final BufferedReader br = new BufferedReader(
new InputStreamReader(
port.getInputStream(),
"US-ASCII"));
// Add listener to print received characters to screen
port.addEventListener(new SerialPortEventListener(){
public void serialEvent(SerialPortEvent ev) {
try {
System.out.println("Received: "+br.readLine());
} catch (IOException e) { e.printStackTrace(); }
}
});
port.notifyOnDataAvailable();
Exception
java.io.IOException: Underlying input stream returned zero bytes
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:268)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.read(BufferedReader.java:157)
at <my code>
The big question (again)
I think I've eliminated all possible hardware problems, so what could be wrong with my code, or the RXTX library?
Edit: something interesting
When I open HyperTerminal after sending a bunch of commands from java that should have gotten responses, all of the responses appear immediately, as if they had been put in the buffer somewhere, but unavailable.
Edit 2: Tried something new, same results
I ran the code example found here, with the same results. No data came in, but when I switched to a new program, it came all at once.
Edit 3
The hardware is fine, and even a different computer has the same problem. I am not using any sort of USB adapter.
I've started using PortMon, too, and it's giving me some interesting results. HyperTerminal and RXTX are not using the same settings, and RXTX always polls the port, unlike HyperTerminal, but I still can't see what settings would affect this. As soon as I can isolate the configuration from the constant polling, I'll post my PortMon logs.
Edit 4
Is it possible that some sort of Windows update in the last 3 months could have caused this? It has screwed up one of my MATLAB mex-based programs once.
Edit 5
I've also noticed some things that are different between HyperTerminal, RXTX, and a separate program I found that communicates with the device (but doesn't do what I want, which is why I'm rolling my own program)
HyperTerminal - set to no flow control, but Serial Port Monitor's RTS and DTR indicators are green
Other program - not sure what settings it thinks it's using, but only SPM's RTS indicator is green
RXTX - no matter what flow control I set, only SPM's CTS and DTR indicators are on.
From Serial Port Monitor's help files (paraphrased):
the indicators display the state of the serial control lines
RTS - Request To Send
CTS - Clear To Send
DTR - Data Terminal Ready
OK, sorry it's taken me so long to come back to this question. Here's how I got things working.
Note: This method will NOT work for everyone, please read below before copy/pasting into your own code
public void connect(CommPortIdentifier portId) throws Failure {
if (portId == null)
throw new Failure("No port set");
try { port = (SerialPort) portId.open(getClass().getName(), 10000); }
catch (PortInUseException e) {
throw new Failure("Port in use by " + e.currentOwner,e); }
try {
port.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN
| SerialPort.FLOWCONTROL_RTSCTS_OUT);
} catch (UnsupportedCommOperationException e) { throw new Failure(e); }
port.setRTS(true);
// More setup
}
So, in my case, the problem was that my particular device requires RTS flow control. Other devices may require different things (CTS, XON/XOFF), so check that device's manual. By default, RXTX disables all flow control mechanisms (unlike Hypertrm or other programs). Enabling each one is a two-step process.
Once you have a SerialPort object, call the setFlowControlMode() method, and bitwise-OR ('|') the necessary SerialPort.FLOWCONTROL_ constants
Set the appropriate flow control to true or false (like I did with port.setRTS(true))
For the others with similar problems, if this doesn't work, I suggest
Using a serial port monitoring program like Serial Port Monitor and/or PortMon (both Windows) to see what is actually going on.
Emailing the RXTX developers at rxtx#qbang.org (they are very helpful)
There is a simpler solution to this problem. This is what I did:
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while (keepRunning) {
try {
while ((br.ready()) && (line = br.readLine()) != null) {
....
}
If you check that the buffer "is ready" before you read it there should be no problem.
Ok, I do realize this thread is extremely old, but none of these solutions worked for me. I had the same problem and I tried everything to fix it, to no avail. Then I did some research on what causes the problem, and, when not dealing with Serial Communication, it happens at the end of a file. So, I figured I needed to add an ending to whatever is being received by the Java Application, specifically, a line return (\n). And sure enough, it fixed the problem for me! Hopefully this helps someone new, as I'm not expecting this to help anyone already on this thread...
(might be too simple, but might as well start somewhere...)
Is the port in use? Rather than:
port = (SerialPort) CommPortIdentifier.getPortIdentifier(name)
.open(owner,1000)
what about:
CommPortIdentifier portIdentifier;
try {
portIdentifier = CommPortIdentifier.getPortIdentifier(name);
} catch (NoSuchPortException nspe) {
// handle?
}
if (portIdentifier.isCurrentlyOwned()) {
// handle?
}
port = portIdentifier.open(owner, 1000);
if (!(port instanceof SerialPort)) {
// handle?
}
Are you swallowing any exceptions?
I tried RXTX a few months ago and ran into similar problems. I suggest two things:
Create a virtual comport using com0com. Enable trace logging. Compare the logs for when you use Hyperterminal versus when you run your own program. The difference will highlight what you are doing wrong.
In my humble opinion, RXTX's design is flawed and its implementation is quite buggy (take a look at its source-code, what a mess!). I've published an alternative library at http://kenai.com/projects/jperipheral with the following caveats: It's Windows-only and there are no pre-built binaries. Both of these will change in the near future. If you are interested in trying it out send me an email using http://desktopbeautifier.com/Main/contactus and I'll send you a pre-built version.
If anyone is still getting java.io.IOException: Underlying input stream returned zero bytes after you've read your characters using br.readline() for RXTX (even when you are checking first to see if br.readline() == null), just do this simple fix with a try/catch:
String line;
while (true){
try{
line = br.readLine();
}catch(IOException e){
System.out.println("No more characters received");
break;
}
//Print the line read
if (line.length() != 0)
System.out.println(line);
}
I've done some searching and it appears that this is the best/easiest way to get around this problem.
EDIT : I take that back. I tried this and still ended up having some problems. I'd recommend working with the raw InputStream directly, and implementing your own read/readLine method using InputStream.read(). That worked for me.