我正在尝试读取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
答案 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));
}
希望有所帮助。