在Processing中正确读取IRC数据

时间:2014-02-18 08:27:37

标签: java regex processing irc

我正在尝试读取IRC并从Processing中的单个IRC消息中提取数据。你可以看到代码(也有twitter库,忽略它),我需要一些关于如何以Nick:Message的格式提取数据的指针,以便它可以在可视化中显示。

    //Twitter

    import twitter4j.conf.*;
    import twitter4j.*;
    import twitter4j.auth.*;
    import twitter4j.api.*;
    import java.util.*;



// Import the net libraries
import processing.net.*;

// Declare a client
Client client;


Twitter twitter;
String searchString = "god";
List<Status> tweets;

String server = "irc.twitch.tv";
String nick = "NugShow";
//String user = "simple_bot";
int port = 6667;
String channel = "#nugshow";
String password = "xx";

String in = "butt";
String checkFor;

//bools
Boolean isLive = false;


    int privMsgIndex;
    int atIndex;
    String playerSubstring;



// The channel which the bot will joString channel = "#irchacks";

int currentTweet;

void setup()
{
    size(800,600);
    frameRate(60);

    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb.setOAuthConsumerKey("xx");
    cb.setOAuthConsumerSecret("xx");
    cb.setOAuthAccessToken("xx");
    cb.setOAuthAccessTokenSecret("xx");

    TwitterFactory tf = new TwitterFactory(cb.build());

    twitter = tf.getInstance();

    getNewTweets();

    currentTweet = 0;

    thread("refreshTweets");
    thread("loopChat");
    connectToServer();



    //IRC
}

void draw()
{ 
  if (client.available() > 0) {  
    String in = client.readString();
    println(in);

  }
  if (isLive == false){
    if (client.available() > 0) {


      }
    } else {

    }

  /*
    fill(0, 40);
    rect(0, 0, width, height);

    currentTweet = currentTweet + 1;

    if (currentTweet >= tweets.size())
    {
        currentTweet = 0;
    }

    Status status = tweets.get(currentTweet);

    fill(200);
    text(status.getText(), random(width), random(height), 300, 200);

    delay(100);

    */
}

void joinChannel() {
  String in = client.readString();
  client.write( "JOIN " + channel + "\n\r" );
  client.clear();
  in = client.readString();
  println(in);
  if (in != null){
     //println("Recieved data");
     println(in);
     //String inString = myClient.readStringUntil(""); 

     isLive = true;
     println(isLive);

  }
}

void connectToServer()
{
  client = new Client(this, server , 6667);
  client.write( "PASS " + password + "\n\r" );
  println(password  + " sent!");
  client.write( "NICK " + nick + "\n\r" );
  println(nick + " sent!");
  joinChannel(); 
}


void getNewTweets()
{
    try 
    {
        Query query = new Query(searchString);

        QueryResult result = twitter.search(query);

        tweets = result.getTweets();
    } 
    catch (TwitterException te) 
    {
        System.out.println("Failed to search tweets: " + te.getMessage());
        System.exit(-1);
    } 
}



void refreshTweets()
{
    while (true)
    {
        getNewTweets();

        println("Updated Tweets"); 

        delay(30000);
    }
}

void loopChat()
{
    while (true)
    {

      if (privMsgIndex != 0){

        println(privMsgIndex); 
        //privMsgIndex = privMsgIndex - 15;
        atIndex = in.indexOf("@");
        println(atIndex); 
        //atIndex = atIndex + 1;
        playerSubstring = in.substring(atIndex, privMsgIndex);
        println(playerSubstring);
      } else {
        println("looped"); 
      }



        delay(300);
        client.clear();
        in = null;
    }
}

void keyPressed()
{

}


void tweet()
{
    try 
    {
        Status status = twitter.updateStatus("This is a tweet sent from Processing!");
        System.out.println("Status updated to [" + status.getText() + "].");
    }
    catch (TwitterException te)
    {
        System.out.println("Error: "+ te.getMessage()); 
    }
}

聊天命令如下所示::nugshow!nugshow@nugshow.testserver.local PRIVMSG #nugshow :dddd其中nugshow是用户名,#nugshow是频道,dddd是消息。我需要把它变成nugshow格式:dddd。

有很多标题信息,我不知道如何剥离client.recieved缓冲区,它看起来像这样:

:testserver.local 001 nugshow :Welcome, GLHF!
:testserver.local 002 nugshow :Your host is testserver.local

:testserver.local 003 nugshow :This server is rather new
:testserver.local 004 nugshow :-
:testserver.local 375 nugshow :-
:testserver.local 372 nugshow :You are in a maze of twisty passages, all alike.
:testserver.local 376 nugshow :>

:nugshow!nugshow@nugshow.testserver.local JOIN #nugshow
:nugshow.testserver.local 353 nugshow = #nugshow :nugshow
:nugshow.testserver.local 366 nugshow #nugshow :End of /NAMES list

:jtv!jtv@jtv.testserver.local PRIVMSG nugshow :HISTORYEND nugshow

1 个答案:

答案 0 :(得分:1)

我不会在这里推荐正则表达式。至少不是如果你想能够捕获所有类型的IRC消息。关键是要查看消息代码,以了解您实际可以从消息中获得什么。因为我也在写一个IRC客户端(只是为了咯咯笑),我有一些笔记给你。

请务必回答服务器发送给您的任何PING,以免您被踢掉。由于PING与标识符一起发送,您需要捕获它并将其发回。一种简单的方法是检查从服务器发送的最后一行并将其子串。

String line = inputStream.readLine();
if(line.substring(0,4).equals("PING")){
    send("PONG " + line.substring(5)); // Assume you have some send-function.
}

这将确保您不会被开除,并且可以继续实际停留在服务器上。

正如我所提到的,我不建议使用正则表达式,因为它会变成RegEx-of-doom。所以,我所做的就是将你得到的行分开并将所有结果放在一个String数组中。

String[] arr = line.split(" ");

正如您所知道的,您已经发布了自己的消息行,IRC协议将事物与空格分开。所以在空间中分裂并不是所有那些破旧的(我们将在稍后处理实际文本)。 消息中始终相同的基本结构(据我所知)是PREFIX COMMAND PARAM PARAM / TRAILING。那么这是什么意思? PREFIX是发送消息的地方。示例&#34;:user!user@host.com"。 COMMAND就是这条线的实际内容。你在这里寻找PRIVMSG,但是你可能想要照顾很多很多其他的。比如JOIN,PART,QUIT,332(当前主题),353(通道中的刻痕,404(无法发送到频道)等等.PARAM和PARAM / TRAILING都将取决于命令。

那么,我们从空间分裂中获得了什么?这样:

arr[0] = :user!user@host.com
arr[1] = COMMAND
arr[2] = PARAM
arr[3 onwards] = rest

我们现在可以轻松地按照自己需要的方式管理每个命令。

不用再拖延,让我们来看看你的实际问题,即PRIVMSG。 我将使用这个字符串:&#34;:Chewtoy!chewtoy@stackoverflow.com PRIVMSG #stoveroverflow:Ty:我看到了你的问题,并认为我应该给你一个答案。&#34; 在空格处进行拆分后,我们得到数组

arr[0] = :Chewtoy!chewtoy@stackoverflow.com
arr[1] = PRIVMSG
arr[2] = #stackoverflow
arr[3] = :Ty:
arr[4] = I
arr[5] = saw
...

如您所见,3及以后的所有内容都是您想要的信息。 0-2是你需要知道谁发送了什么的东西。获取所有这些内容的代码如下所示:

String[] arr = receivedLine.split(" ");
if(arr[1].equals("PRIVMSG")){
    String[] usr = arr[0].split(!"); // Get the user, which is in usr[0]. Host in usr[1]
    StringBuilder msg = new StringBuilder();
    for(int i=3; i<arr.length; i++){ // We know the message starts at arr[3], so start counting from that.
        msg.append(arr[i] + " ");
    }

    String chan = "";
    if(arr[2].substring(0,1).equals("#")){ // We need to differentiate between sending to channel and sending a PM. The only difference in this is where the text is sent.
        chan = arr[2];
    } else{
        chan = usr[0].substring(1); // substring(1) because we want Chewtoy, not :Chewtoy
    }

    // The result here will be: 
    // <#stackoverflow> Chewtoy: Ty: I saw your question and thought I should give you an answer.
    sendItAllToWhereYouWantIt("<" + chan +"> " + usr[0].substring(1) + ": " + msg.substring(1));
}

希望有所帮助。