You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IRCParser.java 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (c) 2006-2007 Chris Smith, Shane Mc Cormack
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package dmdirc.parser;
  23. import java.io.*;
  24. import java.net.*;
  25. interface IDataInEvent { public void onDataIn(IRCParser parser, String data); }
  26. interface IDataOutEvent { public void onDataOut(IRCParser parser, String data); }
  27. public class IRCParser implements Runnable {
  28. class MyInfo {
  29. String sNickname = "IRCParser";
  30. String sRealname = "Java Test IRCParser";
  31. String sUsername = "IRCParser";
  32. }
  33. private Socket socket = null;
  34. private PrintWriter out = null;
  35. private BufferedReader in = null;
  36. public MyInfo me = new MyInfo();
  37. private boolean HasBegan = false;
  38. private boolean IsFirst = true;
  39. // Events
  40. public interface GeneralIRCEvent { public void GeneralEvent(String sName); }
  41. public interface LogEvent { public void LogEvent(String sName, String sData); }
  42. class AllEvents {
  43. GeneralIRCEvent EndOfMOTD = null;
  44. LogEvent DataIn = null;
  45. LogEvent DataOut = null;
  46. String sEndOfMOTD = "";
  47. String sDataIn = "";
  48. String sDataOut = "";
  49. }
  50. public AllEvents cb = new AllEvents();
  51. public void SetCallback(String sType, Object eMethod) throws Exception { try { SetCallback(sType,sType,eMethod); } catch (Exception e) { throw e; } }
  52. public void SetCallback(String sType, String sName, Object eMethod) throws Exception {
  53. if (sName.equals("")) { sName = sType; }
  54. sType = sType.toLowerCase();
  55. if (sType.equals("endofmotd")) { cb.EndOfMOTD = (GeneralIRCEvent)eMethod; cb.sEndOfMOTD = sName; }
  56. else if (sType.equals("datain")) { cb.DataIn = (LogEvent)eMethod; cb.sDataIn = sName; }
  57. else if (sType.equals("dataout")) { cb.DataOut = (LogEvent)eMethod; cb.sDataOut = sName; }
  58. else { throw new Exception("No such callback '"+sType+"'");}
  59. }
  60. // Constructor.
  61. IRCParser () {}
  62. public void connect(String sHost) throws Exception {
  63. try {
  64. connect(sHost,6667);
  65. } catch (Exception e) {
  66. throw e;
  67. }
  68. }
  69. public void connect(String sHost, int nPort) throws Exception {
  70. if (HasBegan) { return; }
  71. try {
  72. socket = new Socket(sHost,nPort);
  73. out = new PrintWriter(socket.getOutputStream(), true);
  74. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  75. } catch (UnknownHostException e) {
  76. throw new Exception("Socket Exception");
  77. } catch (Exception e) {
  78. throw new Exception("General Exception");
  79. }
  80. }
  81. public void run() {
  82. if (HasBegan) { return; } else { HasBegan = true; }
  83. // :HACK: While true loops really really suck.
  84. while(true){
  85. String line = "";
  86. try {
  87. line = in.readLine(); // Blocking :/
  88. if (IsFirst) {
  89. SendString("NICK "+me.sNickname);
  90. SendString("USER "+me.sUsername.toLowerCase()+" * * :"+me.sRealname);
  91. IsFirst = false;
  92. }
  93. ProcessLine(line);
  94. } catch (IOException e) {
  95. System.out.println("Socket read failed");
  96. System.exit(-1);
  97. }
  98. }
  99. }
  100. protected void finalize(){
  101. try{
  102. socket.close();
  103. } catch (IOException e) {
  104. System.out.println("Could not close socket");
  105. System.exit(-1);
  106. }
  107. }
  108. private String GetParam(String line) {
  109. String[] params = null;
  110. params = line.split(" :",2);
  111. return params[params.length-1];
  112. }
  113. private String[] IRCTokenise(String line) {
  114. String[] params = null;
  115. String[] tokens = null;
  116. params = line.split(" :",2);
  117. tokens = params[0].split(" ");
  118. String[] temp = new String[tokens.length+1];
  119. System.arraycopy(tokens, 0, temp, 0, tokens.length);
  120. tokens = temp;
  121. if (params.length == 2) { tokens[tokens.length-1] = params[1]; }
  122. return tokens;
  123. }
  124. public void SendLine(String line) {SendString(line);} // This should do some checks on stuff possible, public event!
  125. // Our Method
  126. private void SendString(String line) {
  127. if (!cb.sDataOut.equals("")) {cb.DataOut.LogEvent(cb.sDataOut,line);} // Ugly++
  128. out.printf("%s\r\n",line);
  129. }
  130. private void ProcessLine(String line) {
  131. String[] token = IRCTokenise(line);
  132. String sParam = token[token.length-1];
  133. int nParam;
  134. if (!cb.sDataIn.equals("")) {cb.DataIn.LogEvent(cb.sDataIn,line);} // Ugly++
  135. try {nParam = Integer.parseInt(token[1]);} catch (Exception e) { nParam = -1;}
  136. if (token[0].equals("PING") || token[1].equals("PING")) { SendString("PONG :"+sParam); }
  137. else {
  138. if (token[0].substring(0,1).equals(":")) {
  139. // Post Connect
  140. switch (nParam) {
  141. case -1:
  142. ProcessStringParam(sParam,token);
  143. break;
  144. case 1: // 001
  145. break;
  146. case 422: // No MOTD
  147. case 376: // End of MOTD
  148. ProcessEndOfMOTD(sParam,token);
  149. break;
  150. default: // Unknown
  151. break;
  152. }
  153. } else {
  154. // Pre Connect
  155. }
  156. }
  157. }
  158. private void ProcessStringParam(String sParam,String token[]) {
  159. // Process a line where the parameter is a string (IE PRIVMSG, NOTICE etc - Not including PING!)
  160. }
  161. private void ProcessEndOfMOTD(String sParam,String token[]) {
  162. // Process EndOfMOTD
  163. if (!cb.sEndOfMOTD.equals("")) {cb.EndOfMOTD.GeneralEvent(cb.sEndOfMOTD);} // Ugly++
  164. }
  165. //-------------------------------------------------------------------------
  166. public void JoinChannel(String sChannelName) {
  167. SendLine("JOIN "+sChannelName);
  168. }
  169. }