我正在尝试读取IRC,并在“处理”中从单个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());
}
}
聊天命令如下所示:
:[email protected] PRIVMSG #nugshow :dddd
其中,nugshow是用户名,#nugshow是频道,dddd是消息。我需要将其转换为nugshow的格式:dddd。还有很多标头信息,我不确定如何从client.receiveved缓冲区中删除,它看起来像这样:
: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 :>
:[email protected] JOIN #nugshow
:nugshow.testserver.local 353 nugshow = #nugshow :nugshow
:nugshow.testserver.local 366 nugshow #nugshow :End of /NAMES list
:[email protected] PRIVMSG nugshow :HISTORYEND nugshow
最佳答案
我不建议在这里使用正则表达式。如果您想捕获所有类型的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是消息发送的来源。例如“:user![email protected]”。该命令实际上就是该行。您在这里正在寻找PRIVMSG,但是您可能还要照顾很多很多其他人。像JOIN,PART,QUIT,332(当前主题),353(频道中的缺口,404(无法发送至频道)等)一样。PARAM和PARAM / TRAILING都取决于COMMAND。
那么,我们从空间分裂中得到什么呢?这个:
arr[0] = :[email protected]
arr[1] = COMMAND
arr[2] = PARAM
arr[3 onwards] = rest
现在,我们可以以自己需要的方式轻松管理每个命令。
不用再耽搁了,让我们开始您的实际问题PRIVMSG。
我将使用以下字符串:“:Chewtoy![email protected] PRIVMSG #stackoverflow:Ty:我看到了您的问题,并认为应该给您答案。”
在空格处分割后,我们得到数组
arr[0] = :[email protected]
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));
}
希望能有所帮助。