2

I am trying to let my bot check if a command is issued by a moderator of the chat. The twitch IRC does use "@" as a prefix for moderators like any other irc.

This is the onMessage method which contains the checks:

public void onMessage(String channel, String sender,String login, String hostname,String message) {

String opStatus = getStatus(sender);

if (message.equalsIgnoreCase("+questions") && (opStatus = "@")) {
       sendMessage(channel, "Message");
       System.out.println(sender.toString());
       System.out.println(opStatus);
    }
}

As you can see i output the Status (opStatus) for debugging reasons. The name of the sender issuing the command appears, but the following line is completely empty.

And here i am trying to grab the status of the user:

private String getStatus(String nickname){

     String status = "";

     User userList[] = getUsers("channel");

     for(User user : userList ){

          if(nickname.equals(user.getNick())){
               status = user.getPrefix();
               break;
          }
     }
     return status;
}//end method getStatus

The following is documented for getPrefix():

Returns the prefix of the user. If the User object has been obtained from a list of users in a channel, then this will reflect the user's status in that channel.

I already tried isOp() too, but with no luck either. Can anyone help me out?

Edit: Appearently the IRC protocol is different for Twitch. The issue has not yet been fixeed.

anchuin
  • 33
  • 4
  • When comparing string's, you would need to use the `.equals()` method and not rely on `==` (which you posted as `=` above) – Anthony Forloney Jan 02 '15 at 22:59
  • I do already in nickname.equals(user.getNick()) @AnthonyForloney. The other "="'s are value assignments. – anchuin Jan 02 '15 at 23:06
  • Even the one within your `onMessage` function for `opStatus` inside of the `if` block? – Anthony Forloney Jan 02 '15 at 23:09
  • No, i should change that, but i excluded that check for testing purposes. The line `System.out.println(opStatus);` is only putting out an empty line anyway, which is my problem. – anchuin Jan 02 '15 at 23:14
  • What's the value of `opStatus` prior to the `if` block? – Anthony Forloney Jan 02 '15 at 23:24
  • None, the variable gets created with `String opStatus` and the value of `getStatus(sender)` assigned. I tried putting the line right before `System.out.println(opStatus);` but it still outputs an empty line. – anchuin Jan 02 '15 at 23:31
  • Due to the inability to validate the code myself, I would recommend adding a debugger into the code to make sure that the `getStatus` method is returning a list of `User` and you are properly extracting their nicknames. – Anthony Forloney Jan 02 '15 at 23:33
  • Checked for user, nickname and status in the getStatus method. user and nickname output "anchuin", status outputs nothing. (a blank space) – anchuin Jan 02 '15 at 23:39
  • Are you an operator? Would a blank status be appropriate for your username? – Anthony Forloney Jan 02 '15 at 23:43
  • Yes i am an operator with the prefix @. I am online with an IRC client. – anchuin Jan 02 '15 at 23:45
  • By reviewing the code for `getStatus` it appears that it'll return the status of when the user was instantiated. It's possible that prior to you becoming an operator, you were instantiated as an user without any status, ergo nothing displays next to your name. – Anthony Forloney Jan 03 '15 at 18:02

3 Answers3

1

Checking for operators through an IRC server brings with it some delay. To see if the IRC server in question recognizes a user as an operator, you'll need to wait for the MODE signals from Twitch. In Pircbot(assuming you're using that library) prints these signals in the console if you're using an IDE like Eclipse.

I have been looking for a similar method to quickly catch operators in the channel, but I've abandoned it because I found IRC not fast enough for my application. Instead, I just keep an operator list stored locally with the bot. If somebody executes a command, just check the Operator file. However, if the delay isn't a problem for you, then the following explanation may be of use.

The lines you should trigger on are:

1425158996453 :jtv MODE #yourchannel +o someuser

and:

1425159389131 :jtv MODE #yourchannel -o someuser

As you may have guessed, the +o and -o indicate if the person has gained or has lost operator status.

I am using a custom class which allows me to catch the print stream. Initially, I used it for a different purpose, but this might just be what you're looking for. The class is a JPanel which you can place somewhere in your interface and see the PrintStream it in action. The following code is all placed in one file.

I hope this helps you out. Cheers.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class Console extends JPanel implements Consumer 
{
    private static final long serialVersionUID = 1L;
    private JTextArea output;

    public Console() 
    {
        setLayout( new BorderLayout() );
        output = new JTextArea();
        add( new JScrollPane(output) );
        setLooks();

        PrintStream ps = System.out;
        System.setOut( new PrintStream( new StreamCapturer("OUT", this, ps) ) ); // print output
        System.setErr( new PrintStream( new StreamCapturer("ERR", this, ps) ) ); // print errors
        this.setFont( new Font( "Courier New" , Font.PLAIN ,10 ) );
    }

    @Override
    public void appendText(final String text) 
    {
        if (EventQueue.isDispatchThread()) 
        {
            output.append(text);
            output.setCaretPosition(output.getText().length());
        } 
        else 
        {
            EventQueue.invokeLater(new Runnable() 
            {
                @Override
                public void run() 
                {
                    appendText(text);
                }
            });
        }
    }       

    private static Color BACKGROUND = new Color(0.2f,0.2f,0.2f,1.0f);
    private static Color FOREGROUND = new Color(0.9f,0.9f,0.9f,1.0f);
    public void setLooks()
    {
        output.setBackground( BACKGROUND );
        output.setForeground( FOREGROUND );
        output.setFont( new Font( "Courier New" , Font.PLAIN , 12 ) );
        output.setCaretColor( FOREGROUND );
    }
}

interface Consumer 
{        
    public void appendText(String text);
}

class StreamCapturer extends OutputStream 
{
    private StringBuilder buffer;
    private Consumer consumer;
    private PrintStream old;

    public StreamCapturer(String prefix, Consumer consumer, PrintStream old) 
    {
        buffer = new StringBuilder(128);
        this.old = old;
        this.consumer = consumer;
    }

    @Override
    public void write(int b) throws IOException 
    {
        char c = (char) b;
        String value = Character.toString(c);
        buffer.append(value);
        if (value.equals("\n")) 
        {
            consumer.appendText(buffer.toString());
            buffer.delete(0, buffer.length());
        }
        old.print(c);
    }        
}
0

Maybe getUsers("channel"); returns an empty list, so the for loop doesn't execute at all. You should change the getStatus method to getStatus(String channel, String nickName) anyway or make a separate Channel-Class which in turn contains contains a getPrefix(String nickName) method.

Besides, you should also rename getStatus to getPrefix as it returns the prefix and not the status of a user. So the function should look like this:

private String getPrefix(String channel, String nickname){
    User userList[] = getUsers(channel);

    for(User user : userList ){        
        if(nickname.equals(user.getNick())){
            return user.getPrefix();
        }
    }

    return "";
}
magicmonty
  • 88
  • 6
0

I know that this post is long dead, buuut I thought for further reference and for education. Notice this: getUsers("channel"). He is trying to get the channel named "channel". What you instead would want to do is getUsers(channel). :)